diff --git a/microscript/ILibDuktape_Polyfills.c b/microscript/ILibDuktape_Polyfills.c index fde4a9b..62d35b5 100644 --- a/microscript/ILibDuktape_Polyfills.c +++ b/microscript/ILibDuktape_Polyfills.c @@ -1985,7 +1985,7 @@ void ILibDuktape_Polyfills_JS_Init(duk_context *ctx) free(_taskscheduler); // message-box, refer to modules/message-box.js - duk_peval_string_noresult(ctx, "addModule('message-box', Buffer.from('LyoKQ29weXJpZ2h0IDIwMTkgSW50ZWwgQ29ycG9yYXRpb24KCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwp5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQpkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLApXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZApsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKi8NCg0KDQpjb25zdCBNQl9PSyA9IDB4MDAwMDAwMDA7DQpjb25zdCBNQl9PS0NBTkNFTCAgICAgICAgICAgICAgICA9IDB4MDAwMDAwMDE7DQpjb25zdCBNQl9BQk9SVFJFVFJZSUdOT1JFICAgICAgICA9IDB4MDAwMDAwMDI7DQpjb25zdCBNQl9ZRVNOT0NBTkNFTCAgICAgICAgICAgICA9IDB4MDAwMDAwMDM7DQpjb25zdCBNQl9ZRVNOTyAgICAgICAgICAgICAgICAgICA9IDB4MDAwMDAwMDQ7DQpjb25zdCBNQl9SRVRSWUNBTkNFTCAgICAgICAgICAgICA9IDB4MDAwMDAwMDU7DQoNCmNvbnN0IE1CX0RFRkJVVFRPTjEgICAgICAgICAgICAgID0gMHgwMDAwMDAwMDsNCmNvbnN0IE1CX0RFRkJVVFRPTjIgICAgICAgICAgICAgID0gMHgwMDAwMDEwMDsNCmNvbnN0IE1CX0RFRkJVVFRPTjMgICAgICAgICAgICAgID0gMHgwMDAwMDIwMDsNCmNvbnN0IE1CX0lDT05IQU5EICAgICAgICAgICAgICAgID0gMHgwMDAwMDAxMDsNCmNvbnN0IE1CX0lDT05RVUVTVElPTiAgICAgICAgICAgID0gMHgwMDAwMDAyMDsNCmNvbnN0IE1CX0lDT05FWENMQU1BVElPTiAgICAgICAgID0gMHgwMDAwMDAzMDsNCmNvbnN0IE1CX0lDT05BU1RFUklTSyAgICAgICAgICAgID0gMHgwMDAwMDA0MDsNCg0KY29uc3QgSURPSyAgICAgPSAxOw0KY29uc3QgSURDQU5DRUwgPSAyOw0KY29uc3QgSURBQk9SVCAgPSAzOw0KY29uc3QgSURSRVRSWSAgPSA0Ow0KY29uc3QgSURJR05PUkUgPSA1Ow0KY29uc3QgSURZRVMgICAgPSA2Ow0KY29uc3QgSUROTyAgICAgPSA3Ow0KDQp2YXIgcHJvbWlzZSA9IHJlcXVpcmUoJ3Byb21pc2UnKTsNCnZhciBjaGlsZFNjcmlwdCA9ICJcDQogICAgICAgIHJlcXVpcmUoJ1NjcmlwdENvbnRhaW5lcicpLm9uKCdkYXRhJywgZnVuY3Rpb24gKGopXA0KICAgICAgICB7XA0KICAgICAgICAgICAgc3dpdGNoKGouY29tbWFuZClcDQogICAgICAgICAgICB7XA0KICAgICAgICAgICAgICAgIGNhc2UgJ21lc3NhZ2VCb3gnOlwNCiAgICAgICAgICAgICAgICAgICAgaWYocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKVwNCiAgICAgICAgICAgICAgICAgICAge1wNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBHTSA9IHJlcXVpcmUoJ19HZW5lcmljTWFyc2hhbCcpO1wNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB1c2VyMzIgPSBHTS5DcmVhdGVOYXRpdmVQcm94eSgndXNlcjMyLmRsbCcpO1wNCiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXIzMi5DcmVhdGVNZXRob2QoJ01lc3NhZ2VCb3hBJyk7XA0KICAgICAgICAgICAgICAgICAgICAgICAgdXNlcjMyLk1lc3NhZ2VCb3hBLmFzeW5jKDAsIEdNLkNyZWF0ZVZhcmlhYmxlKGouY2FwdGlvbiksIEdNLkNyZWF0ZVZhcmlhYmxlKGoudGl0bGUpLCAiICsgKE1CX1lFU05PIHwgTUJfREVGQlVUVE9OMiB8IE1CX0lDT05FWENMQU1BVElPTikudG9TdHJpbmcoKSArICIpLnRoZW4oXA0KICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24ocilcDQogICAgICAgICAgICAgICAgICAgICAgICB7XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHIuVmFsID09ICIgKyBJRFlFUy50b1N0cmluZygpICsgIilcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAge1wNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZSgnU2NyaXB0Q29udGFpbmVyJykuc2VuZCgiICsgSURZRVMudG9TdHJpbmcoKSArICIpO1wNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAge1wNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZSgnU2NyaXB0Q29udGFpbmVyJykuc2VuZCgiICsgSUROTy50b1N0cmluZygpICsgIik7XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5leGl0KCk7XA0KICAgICAgICAgICAgICAgICAgICAgICAgfSk7XA0KICAgICAgICAgICAgICAgICAgICB9XA0KICAgICAgICAgICAgICAgICAgICBicmVhaztcDQogICAgICAgICAgICB9XA0KICAgICAgICB9KTtcDQogICAgIjsNCg0KZnVuY3Rpb24gbWVzc2FnZUJveCgpDQp7DQogICAgdGhpcy5fT2JqZWN0SUQgPSAnbWVzc2FnZS1ib3gnOw0KICAgIHRoaXMuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHRpdGxlLCBjYXB0aW9uLCB0aW1lb3V0KQ0KICAgIHsNCiAgICAgICAgdmFyIEdNID0gcmVxdWlyZSgnX0dlbmVyaWNNYXJzaGFsJyk7DQogICAgICAgIHZhciBrZXJuZWwzMiA9IEdNLkNyZWF0ZU5hdGl2ZVByb3h5KCdrZXJuZWwzMi5kbGwnKTsNCiAgICAgICAga2VybmVsMzIuQ3JlYXRlTWV0aG9kKCdQcm9jZXNzSWRUb1Nlc3Npb25JZCcpOw0KICAgICAgICB2YXIgcHNpZCA9IEdNLkNyZWF0ZVZhcmlhYmxlKDQpOw0KICAgICAgICBpZiAoa2VybmVsMzIuUHJvY2Vzc0lkVG9TZXNzaW9uSWQocHJvY2Vzcy5waWQsIHBzaWQpLlZhbCA9PSAwKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXQuX3JlaignSW50ZXJuYWwgRXJyb3InKTsNCiAgICAgICAgICAgIHJldHVybiAocmV0KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGlmICh0aW1lb3V0ID09IG51bGwpIHsgdGltZW91dCA9IDEwOyB9DQogICAgICAgIHZhciByZXQgPSBuZXcgcHJvbWlzZShmdW5jdGlvbiAocmVzLCByZWopIHsgdGhpcy5fcmVzID0gcmVzOyB0aGlzLl9yZWogPSByZWo7IH0pOw0KICAgICAgICB2YXIgb3B0aW9ucyA9IHsgZXhlY3V0aW9uVGltZW91dDogdGltZW91dCB9Ow0KDQogICAgICAgIHRyeQ0KICAgICAgICB7DQogICAgICAgICAgICBvcHRpb25zLnNlc3Npb25JZCA9IHJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5jb25zb2xlVWlkKCk7DQogICAgICAgICAgICBpZiAob3B0aW9ucy5zZXNzaW9uSWQgPT0gcHNpZC50b0J1ZmZlcigpLnJlYWRVSW50MzJMRSgpKSB7IGRlbGV0ZSBvcHRpb25zLnNlc3Npb25JZDsgfQ0KICAgICAgICB9DQogICAgICAgIGNhdGNoKGVlKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXQuX3JlaignTm8gbG9nZ2VkIG9uIHVzZXJzJyk7DQogICAgICAgICAgICByZXR1cm4gKHJldCk7DQogICAgICAgIH0NCiAgICAgICAgcmV0Ll90aXRsZSA9IHRpdGxlOw0KICAgICAgICByZXQuX2NhcHRpb24gPSBjYXB0aW9uOw0KICAgICAgICByZXQuX2NvbnRhaW5lciA9IHJlcXVpcmUoJ1NjcmlwdENvbnRhaW5lcicpLkNyZWF0ZShvcHRpb25zKTsNCiAgICAgICAgcmV0Ll9jb250YWluZXIucHJvbWlzZSA9IHJldDsNCiAgICAgICAgcmV0Ll9jb250YWluZXIub24oJ2RhdGEnLCBmdW5jdGlvbiAoaikNCiAgICAgICAgew0KICAgICAgICAgICAgaWYoaiA9PSBJRFlFUykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB0aGlzLnByb21pc2UuX3JlcygpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHRoaXMucHJvbWlzZS5fcmVqKCdEZW5pZWQnKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSk7DQogICAgICAgIHJldC5fY29udGFpbmVyLm9uKCdleGl0JywgZnVuY3Rpb24gKCkNCiAgICAgICAgew0KICAgICAgICAgICAgdGhpcy5wcm9taXNlLl9yZWooJ1RpbWVvdXQnKTsNCiAgICAgICAgfSk7DQogICAgICAgIHJldC5fY29udGFpbmVyLkV4ZWN1dGVTdHJpbmcoY2hpbGRTY3JpcHQpOwogICAgICAgIHJldC5fY29udGFpbmVyLnNlbmQoeyBjb21tYW5kOiAnbWVzc2FnZUJveCcsIGNhcHRpb246IGNhcHRpb24sIHRpdGxlOiB0aXRsZSB9KTsNCiAgICAgICAgcmV0dXJuIChyZXQpOw0KICAgIH07DQp9DQoNCmZ1bmN0aW9uIGxpbnV4X21lc3NhZ2VCb3goKQ0Kew0KICAgIHRoaXMuX09iamVjdElEID0gJ21lc3NhZ2UtYm94JzsNCiAgICB0aGlzLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZSh0aXRsZSwgY2FwdGlvbiwgdGltZW91dCkNCiAgICB7DQogICAgICAgIGlmICh0aW1lb3V0ID09IG51bGwpIHsgdGltZW91dCA9IDEwOyB9DQogICAgICAgIHZhciB6ZW5pdHkgPSAnJzsNCiAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOw0KICAgICAgICBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHsgdGhpcy5zdHIgKz0gY2h1bmsudG9TdHJpbmcoKTsgfSk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCJ3aGVyZWlzIHplbml0eSB8IGF3ayAneyBwcmludCAkMiB9J1xuZXhpdFxuIik7DQogICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgIHplbml0eSA9IGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpOw0KICAgICAgICBpZiAoemVuaXR5ID09ICcnKSB7IHRocm93ICgnWmVuaXR5IG5vdCBpbnN0YWxsZWQnKTsgfQ0KICAgICAgICB2YXIgdWlkID0gcmVxdWlyZSgndXNlci1zZXNzaW9ucycpLmNvbnNvbGVVaWQoKTsNCiAgICAgICAgdmFyIHhpbmZvID0gcmVxdWlyZSgnbW9uaXRvci1pbmZvJykuZ2V0WEluZm8odWlkKTsNCiAgICAgICAgdmFyIHJldCA9IG5ldyBwcm9taXNlKGZ1bmN0aW9uIChyZXMsIHJlaikgeyB0aGlzLl9yZXMgPSByZXM7IHRoaXMuX3JlaiA9IHJlajsgfSk7DQogICAgICAgIHJldC5jaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSh6ZW5pdHksIFsnemVuaXR5JywgJy0tcXVlc3Rpb24nLCAnLS10aXRsZT0nICsgdGl0bGUsICctLXRleHQ9JyArIGNhcHRpb24sICctLXRpbWVvdXQ9JyArIHRpbWVvdXRdLCB7IHVpZDogdWlkLCBlbnY6IHsgWEFVVEhPUklUWTogeGluZm8ueGF1dGhvcml0eSwgRElTUExBWTogeGluZm8uZGlzcGxheSB9IH0pOw0KICAgICAgICByZXQuY2hpbGQucHJvbWlzZSA9IHJldDsNCiAgICAgICAgcmV0LmNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykgeyB9KTsNCiAgICAgICAgcmV0LmNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykgeyB9KTsNCiAgICAgICAgcmV0LmNoaWxkLm9uKCdleGl0JywgZnVuY3Rpb24gKGNvZGUpDQogICAgICAgIHsNCiAgICAgICAgICAgIHN3aXRjaChjb2RlKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGNhc2UgMDoNCiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9taXNlLl9yZXMoKTsNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgY2FzZSAxOg0KICAgICAgICAgICAgICAgICAgICB0aGlzLnByb21pc2UuX3JlaignZGVuaWVkJyk7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGRlZmF1bHQ6DQogICAgICAgICAgICAgICAgICAgIHRoaXMucHJvbWlzZS5fcmVqKCd0aW1lb3V0Jyk7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9KTsNCg0KICAgICAgICByZXR1cm4gKHJldCk7DQoNCg0KICAgICAgICBjb25zb2xlLmxvZyhjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSA9PSAnJyk7DQoNCiAgICB9Ow0KfQ0KDQpzd2l0Y2gocHJvY2Vzcy5wbGF0Zm9ybSkNCnsNCiAgICBjYXNlICd3aW4zMic6DQogICAgICAgIG1vZHVsZS5leHBvcnRzID0gbmV3IG1lc3NhZ2VCb3goKTsNCiAgICAgICAgYnJlYWs7DQogICAgY2FzZSAnbGludXgnOg0KICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IG5ldyBsaW51eF9tZXNzYWdlQm94KCk7DQogICAgICAgIGJyZWFrOw0KfQ0KDQoNCg0KDQoNCg0K', 'base64').toString());"); + duk_peval_string_noresult(ctx, "addModule('message-box', Buffer.from('LyoNCkNvcHlyaWdodCAyMDE5IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQoNCmNvbnN0IE1CX09LID0gMHgwMDAwMDAwMDsNCmNvbnN0IE1CX09LQ0FOQ0VMICAgICAgICAgICAgICAgID0gMHgwMDAwMDAwMTsNCmNvbnN0IE1CX0FCT1JUUkVUUllJR05PUkUgICAgICAgID0gMHgwMDAwMDAwMjsNCmNvbnN0IE1CX1lFU05PQ0FOQ0VMICAgICAgICAgICAgID0gMHgwMDAwMDAwMzsNCmNvbnN0IE1CX1lFU05PICAgICAgICAgICAgICAgICAgID0gMHgwMDAwMDAwNDsNCmNvbnN0IE1CX1JFVFJZQ0FOQ0VMICAgICAgICAgICAgID0gMHgwMDAwMDAwNTsNCg0KY29uc3QgTUJfREVGQlVUVE9OMSAgICAgICAgICAgICAgPSAweDAwMDAwMDAwOw0KY29uc3QgTUJfREVGQlVUVE9OMiAgICAgICAgICAgICAgPSAweDAwMDAwMTAwOw0KY29uc3QgTUJfREVGQlVUVE9OMyAgICAgICAgICAgICAgPSAweDAwMDAwMjAwOw0KY29uc3QgTUJfSUNPTkhBTkQgICAgICAgICAgICAgICAgPSAweDAwMDAwMDEwOw0KY29uc3QgTUJfSUNPTlFVRVNUSU9OICAgICAgICAgICAgPSAweDAwMDAwMDIwOw0KY29uc3QgTUJfSUNPTkVYQ0xBTUFUSU9OICAgICAgICAgPSAweDAwMDAwMDMwOw0KY29uc3QgTUJfSUNPTkFTVEVSSVNLICAgICAgICAgICAgPSAweDAwMDAwMDQwOw0KDQpjb25zdCBJRE9LICAgICA9IDE7DQpjb25zdCBJRENBTkNFTCA9IDI7DQpjb25zdCBJREFCT1JUICA9IDM7DQpjb25zdCBJRFJFVFJZICA9IDQ7DQpjb25zdCBJRElHTk9SRSA9IDU7DQpjb25zdCBJRFlFUyAgICA9IDY7DQpjb25zdCBJRE5PICAgICA9IDc7DQoNCnZhciBwcm9taXNlID0gcmVxdWlyZSgncHJvbWlzZScpOw0KdmFyIGNoaWxkU2NyaXB0ID0gIlwNCiAgICAgICAgcmVxdWlyZSgnU2NyaXB0Q29udGFpbmVyJykub24oJ2RhdGEnLCBmdW5jdGlvbiAoailcDQogICAgICAgIHtcDQogICAgICAgICAgICBzd2l0Y2goai5jb21tYW5kKVwNCiAgICAgICAgICAgIHtcDQogICAgICAgICAgICAgICAgY2FzZSAnbWVzc2FnZUJveCc6XA0KICAgICAgICAgICAgICAgICAgICBpZihwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicpXA0KICAgICAgICAgICAgICAgICAgICB7XA0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIEdNID0gcmVxdWlyZSgnX0dlbmVyaWNNYXJzaGFsJyk7XA0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHVzZXIzMiA9IEdNLkNyZWF0ZU5hdGl2ZVByb3h5KCd1c2VyMzIuZGxsJyk7XA0KICAgICAgICAgICAgICAgICAgICAgICAgdXNlcjMyLkNyZWF0ZU1ldGhvZCgnTWVzc2FnZUJveEEnKTtcDQogICAgICAgICAgICAgICAgICAgICAgICB1c2VyMzIuTWVzc2FnZUJveEEuYXN5bmMoMCwgR00uQ3JlYXRlVmFyaWFibGUoai5jYXB0aW9uKSwgR00uQ3JlYXRlVmFyaWFibGUoai50aXRsZSksICIgKyAoTUJfWUVTTk8gfCBNQl9ERUZCVVRUT04yIHwgTUJfSUNPTkVYQ0xBTUFUSU9OKS50b1N0cmluZygpICsgIikudGhlbihcDQogICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihyKVwNCiAgICAgICAgICAgICAgICAgICAgICAgIHtcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoci5WYWwgPT0gIiArIElEWUVTLnRvU3RyaW5nKCkgKyAiKVwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlKCdTY3JpcHRDb250YWluZXInKS5zZW5kKCIgKyBJRFlFUy50b1N0cmluZygpICsgIik7XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlKCdTY3JpcHRDb250YWluZXInKS5zZW5kKCIgKyBJRE5PLnRvU3RyaW5nKCkgKyAiKTtcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmV4aXQoKTtcDQogICAgICAgICAgICAgICAgICAgICAgICB9KTtcDQogICAgICAgICAgICAgICAgICAgIH1cDQogICAgICAgICAgICAgICAgICAgIGJyZWFrO1wNCiAgICAgICAgICAgIH1cDQogICAgICAgIH0pO1wNCiAgICAiOw0KDQpmdW5jdGlvbiBtZXNzYWdlQm94KCkNCnsNCiAgICB0aGlzLl9PYmplY3RJRCA9ICdtZXNzYWdlLWJveCc7DQogICAgdGhpcy5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUodGl0bGUsIGNhcHRpb24sIHRpbWVvdXQpDQogICAgew0KICAgICAgICB2YXIgR00gPSByZXF1aXJlKCdfR2VuZXJpY01hcnNoYWwnKTsNCiAgICAgICAgdmFyIGtlcm5lbDMyID0gR00uQ3JlYXRlTmF0aXZlUHJveHkoJ2tlcm5lbDMyLmRsbCcpOw0KICAgICAgICBrZXJuZWwzMi5DcmVhdGVNZXRob2QoJ1Byb2Nlc3NJZFRvU2Vzc2lvbklkJyk7DQogICAgICAgIHZhciBwc2lkID0gR00uQ3JlYXRlVmFyaWFibGUoNCk7DQogICAgICAgIGlmIChrZXJuZWwzMi5Qcm9jZXNzSWRUb1Nlc3Npb25JZChwcm9jZXNzLnBpZCwgcHNpZCkuVmFsID09IDApDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldC5fcmVqKCdJbnRlcm5hbCBFcnJvcicpOw0KICAgICAgICAgICAgcmV0dXJuIChyZXQpOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKHRpbWVvdXQgPT0gbnVsbCkgeyB0aW1lb3V0ID0gMTA7IH0NCiAgICAgICAgdmFyIHJldCA9IG5ldyBwcm9taXNlKGZ1bmN0aW9uIChyZXMsIHJlaikgeyB0aGlzLl9yZXMgPSByZXM7IHRoaXMuX3JlaiA9IHJlajsgfSk7DQogICAgICAgIHZhciBvcHRpb25zID0geyBleGVjdXRpb25UaW1lb3V0OiB0aW1lb3V0IH07DQoNCiAgICAgICAgdHJ5DQogICAgICAgIHsNCiAgICAgICAgICAgIG9wdGlvbnMuc2Vzc2lvbklkID0gcmVxdWlyZSgndXNlci1zZXNzaW9ucycpLmNvbnNvbGVVaWQoKTsNCiAgICAgICAgICAgIGlmIChvcHRpb25zLnNlc3Npb25JZCA9PSBwc2lkLnRvQnVmZmVyKCkucmVhZFVJbnQzMkxFKCkpIHsgZGVsZXRlIG9wdGlvbnMuc2Vzc2lvbklkOyB9DQogICAgICAgIH0NCiAgICAgICAgY2F0Y2goZWUpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldC5fcmVqKCdObyBsb2dnZWQgb24gdXNlcnMnKTsNCiAgICAgICAgICAgIHJldHVybiAocmV0KTsNCiAgICAgICAgfQ0KICAgICAgICByZXQuX3RpdGxlID0gdGl0bGU7DQogICAgICAgIHJldC5fY2FwdGlvbiA9IGNhcHRpb247DQogICAgICAgIHJldC5fY29udGFpbmVyID0gcmVxdWlyZSgnU2NyaXB0Q29udGFpbmVyJykuQ3JlYXRlKG9wdGlvbnMpOw0KICAgICAgICByZXQuX2NvbnRhaW5lci5wcm9taXNlID0gcmV0Ow0KICAgICAgICByZXQuX2NvbnRhaW5lci5vbignZGF0YScsIGZ1bmN0aW9uIChqKQ0KICAgICAgICB7DQogICAgICAgICAgICBpZihqID09IElEWUVTKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHRoaXMucHJvbWlzZS5fcmVzKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhpcy5wcm9taXNlLl9yZWooJ0RlbmllZCcpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9KTsNCiAgICAgICAgcmV0Ll9jb250YWluZXIub24oJ2V4aXQnLCBmdW5jdGlvbiAoKQ0KICAgICAgICB7DQogICAgICAgICAgICB0aGlzLnByb21pc2UuX3JlaignVGltZW91dCcpOw0KICAgICAgICB9KTsNCiAgICAgICAgcmV0Ll9jb250YWluZXIuRXhlY3V0ZVN0cmluZyhjaGlsZFNjcmlwdCk7DQogICAgICAgIHJldC5fY29udGFpbmVyLnNlbmQoeyBjb21tYW5kOiAnbWVzc2FnZUJveCcsIGNhcHRpb246IGNhcHRpb24sIHRpdGxlOiB0aXRsZSB9KTsNCiAgICAgICAgcmV0dXJuIChyZXQpOw0KICAgIH07DQp9DQoNCmZ1bmN0aW9uIGxpbnV4X21lc3NhZ2VCb3goKQ0Kew0KICAgIHRoaXMuX09iamVjdElEID0gJ21lc3NhZ2UtYm94JzsNCiAgICB0aGlzLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZSh0aXRsZSwgY2FwdGlvbiwgdGltZW91dCkNCiAgICB7DQogICAgICAgIGlmICh0aW1lb3V0ID09IG51bGwpIHsgdGltZW91dCA9IDEwOyB9DQogICAgICAgIHZhciByZXQgPSBuZXcgcHJvbWlzZShmdW5jdGlvbiAocmVzLCByZWopIHsgdGhpcy5fcmVzID0gcmVzOyB0aGlzLl9yZWogPSByZWo7IH0pOw0KICAgICAgICB2YXIgemVuaXR5ID0gJycsIGtkaWFsb2cgPSAnJzsNCiAgICAgICAgdmFyIHVpZCA9IHJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5jb25zb2xlVWlkKCk7DQogICAgICAgIHZhciB4aW5mbyA9IHJlcXVpcmUoJ21vbml0b3ItaW5mbycpLmdldFhJbmZvKHVpZCk7DQogICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsNCiAgICAgICAgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7IHRoaXMuc3RyICs9IGNodW5rLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgid2hlcmVpcyB6ZW5pdHkgfCBhd2sgJ3sgcHJpbnQgJDIgfSdcbmV4aXRcbiIpOw0KICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgICAgICB6ZW5pdHkgPSBjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKTsNCiAgICAgICAgaWYgKHplbml0eSAhPSAnJykNCiAgICAgICAgew0KICAgICAgICAgICAgLy8gR05PTUUvWkVOSVRZDQogICAgICAgICAgICByZXQuY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoemVuaXR5LCBbJ3plbml0eScsICctLXF1ZXN0aW9uJywgJy0tdGl0bGU9JyArIHRpdGxlLCAnLS10ZXh0PScgKyBjYXB0aW9uLCAnLS10aW1lb3V0PScgKyB0aW1lb3V0XSwgeyB1aWQ6IHVpZCwgZW52OiB7IFhBVVRIT1JJVFk6IHhpbmZvLnhhdXRob3JpdHksIERJU1BMQVk6IHhpbmZvLmRpc3BsYXkgfSB9KTsNCiAgICAgICAgICAgIHJldC5jaGlsZC5wcm9taXNlID0gcmV0Ow0KICAgICAgICAgICAgcmV0LmNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykgeyB9KTsNCiAgICAgICAgICAgIHJldC5jaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHsgfSk7DQogICAgICAgICAgICByZXQuY2hpbGQub24oJ2V4aXQnLCBmdW5jdGlvbiAoY29kZSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzd2l0Y2ggKGNvZGUpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBjYXNlIDA6DQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb21pc2UuX3JlcygpOw0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgIGNhc2UgMToNCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvbWlzZS5fcmVqKCdkZW5pZWQnKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICBkZWZhdWx0Og0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9taXNlLl9yZWooJ3RpbWVvdXQnKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9DQogICAgICAgIGVsc2UNCiAgICAgICAgew0KICAgICAgICAgICAgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICAgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOw0KICAgICAgICAgICAgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7IHRoaXMuc3RyICs9IGNodW5rLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoIndoZXJlaXMga2RpYWxvZyB8IGF3ayAneyBwcmludCAkMiB9J1xuZXhpdFxuIik7DQogICAgICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgICAgICAgICAga2RpYWxvZyA9IGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpOw0KICAgICAgICAgICAgaWYgKGtkaWFsb2cgPT0gJycpIHsgcmV0Ll9yZWooJ1BsYXRmb3JtIG5vdCBzdXBwb3J0ZWQgKHplbml0eSBvciBrZGlhbG9nIG5vdCBmb3VuZCknKTsgcmV0dXJuIChyZXQpOyB9DQogICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnZbJ0RJU1BMQVknXSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICByZXQuY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoa2RpYWxvZywgWydrZGlhbG9nJywgJy0tdGl0bGUnLCB0aXRsZSwgJy0teWVzbm8nLCBjYXB0aW9uXSk7DQogICAgICAgICAgICAgICAgcmV0LmNoaWxkLnByb21pc2UgPSByZXQ7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIHhkZyA9IHJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5maW5kRW52KHVpZCwgJ1hER19SVU5USU1FX0RJUicpOw0KICAgICAgICAgICAgICAgIGlmICgheGluZm8gfHwgIXhpbmZvLmRpc3BsYXkgfHwgIXhpbmZvLnhhdXRob3JpdHkgfHwgIXhkZykgeyByZXQuX3JlaignSW50ZXJhbCBFcnJvciwgY291bGQgbm90IGRldGVybWluZSBYMTEvWERHIGVudicpOyByZXR1cm4gKHJldCk7IH0NCiAgICAgICAgICAgICAgICByZXQuY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoa2RpYWxvZywgWydrZGlhbG9nJywgJy0tdGl0bGUnLCB0aXRsZSwgJy0teWVzbm8nLCBjYXB0aW9uXSwgeyB1aWQ6IHVpZCwgZW52OiB7IERJU1BMQVk6IHhpbmZvLmRpc3BsYXksIFhBVVRIT1JJVFk6IHhpbmZvLnhhdXRob3JpdHksIFhER19SVU5USU1FX0RJUjogeGRnIH0gfSk7DQogICAgICAgICAgICAgICAgcmV0LmNoaWxkLnByb21pc2UgPSByZXQ7DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXQuY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7IH0pOw0KICAgICAgICAgICAgcmV0LmNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykgeyB9KTsNCiAgICAgICAgICAgIHJldC5jaGlsZC5vbignZXhpdCcsIGZ1bmN0aW9uIChjb2RlKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHN3aXRjaCAoY29kZSkgew0KICAgICAgICAgICAgICAgICAgICBjYXNlIDA6DQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb21pc2UuX3JlcygpOw0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgIGNhc2UgMToNCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvbWlzZS5fcmVqKCdkZW5pZWQnKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICBkZWZhdWx0Og0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9taXNlLl9yZWooJ3RpbWVvdXQnKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiAocmV0KTsNCg0KDQogICAgICAgIGNvbnNvbGUubG9nKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpID09ICcnKTsNCg0KICAgIH07DQp9DQoNCnN3aXRjaChwcm9jZXNzLnBsYXRmb3JtKQ0Kew0KICAgIGNhc2UgJ3dpbjMyJzoNCiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBuZXcgbWVzc2FnZUJveCgpOw0KICAgICAgICBicmVhazsNCiAgICBjYXNlICdsaW51eCc6DQogICAgICAgIG1vZHVsZS5leHBvcnRzID0gbmV3IGxpbnV4X21lc3NhZ2VCb3goKTsNCiAgICAgICAgYnJlYWs7DQp9DQoNCg0KDQoNCg0KDQo=', 'base64').toString());"); // wget: Refer to modules/wget.js for a human readable version. This is the only module that won't update, if you just past the .js file, because the module loader caches results, and the following does a require('wget') in the property definition duk_peval_string_noresult(ctx, "addModule('wget', Buffer.from('LyoNCkNvcHlyaWdodCAyMDE5IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQoNCnZhciBwcm9taXNlID0gcmVxdWlyZSgncHJvbWlzZScpOw0KdmFyIGh0dHAgPSByZXF1aXJlKCdodHRwJyk7DQp2YXIgd3JpdGFibGUgPSByZXF1aXJlKCdzdHJlYW0nKS5Xcml0YWJsZTsNCg0KDQpmdW5jdGlvbiB3Z2V0KHJlbW90ZVVyaSwgbG9jYWxGaWxlUGF0aCwgd2dldG9wdGlvbnMpDQp7DQogICAgdmFyIHJldCA9IG5ldyBwcm9taXNlKGZ1bmN0aW9uIChyZXMsIHJlaikgeyB0aGlzLl9yZXMgPSByZXM7IHRoaXMuX3JlaiA9IHJlajsgfSk7DQogICAgdmFyIGFnZW50Q29ubmVjdGVkID0gZmFsc2U7DQogICAgcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyLmNhbGwocmV0LCB0cnVlKQ0KICAgICAgICAuY3JlYXRlRXZlbnQoJ2J5dGVzJykNCiAgICAgICAgLmNyZWF0ZUV2ZW50KCdhYm9ydCcpDQogICAgICAgIC5hZGRNZXRob2QoJ2Fib3J0JywgZnVuY3Rpb24gKCkgeyB0aGlzLl9yZXF1ZXN0LmFib3J0KCk7IH0pOw0KDQogICAgdHJ5DQogICAgew0KICAgICAgICBhZ2VudENvbm5lY3RlZCA9IHJlcXVpcmUoJ01lc2hBZ2VudCcpLmlzQ29udHJvbENoYW5uZWxDb25uZWN0ZWQ7DQogICAgfQ0KICAgIGNhdGNoIChlKQ0KICAgIHsNCiAgICB9DQoNCiAgICAvLyBXZSBvbmx5IG5lZWQgdG8gY2hlY2sgcHJveHkgc2V0dGluZ3MgaWYgdGhlIGFnZW50IGlzIG5vdCBjb25uZWN0ZWQsIGJlY2F1c2Ugd2hlbiB0aGUgYWdlbnQNCiAgICAvLyBjb25uZWN0cywgaXQgYXV0b21hdGljYWxseSBjb25maWd1cmVzIHRoZSBwcm94eSBmb3IgSmF2YVNjcmlwdC4NCiAgICBpZiAoIWFnZW50Q29ubmVjdGVkKQ0KICAgIHsNCiAgICAgICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIHJlZyA9IHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpOw0KICAgICAgICAgICAgaWYgKHJlZy5RdWVyeUtleShyZWcuSEtFWS5DdXJyZW50VXNlciwgJ1NvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxJbnRlcm5ldCBTZXR0aW5ncycsICdQcm94eUVuYWJsZScpID09IDEpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIHByb3h5VXJpID0gcmVnLlF1ZXJ5S2V5KHJlZy5IS0VZLkN1cnJlbnRVc2VyLCAnU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXEludGVybmV0IFNldHRpbmdzJywgJ1Byb3h5U2VydmVyJyk7DQogICAgICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSByZXF1aXJlKCdodHRwJykucGFyc2VVcmkoJ2h0dHA6Ly8nICsgcHJveHlVcmkpOw0KDQogICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3Byb3h5ID0+ICcgKyBwcm94eVVyaSk7DQogICAgICAgICAgICAgICAgcmVxdWlyZSgnZ2xvYmFsLXR1bm5lbCcpLmluaXRpYWxpemUob3B0aW9ucyk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQoNCiAgICB2YXIgcmVxT3B0aW9ucyA9IHJlcXVpcmUoJ2h0dHAnKS5wYXJzZVVyaShyZW1vdGVVcmkpOw0KICAgIGlmICh3Z2V0b3B0aW9ucykNCiAgICB7DQogICAgICAgIGZvciAodmFyIGlucHV0T3B0aW9uIGluIHdnZXRvcHRpb25zKSB7DQogICAgICAgICAgICByZXFPcHRpb25zW2lucHV0T3B0aW9uXSA9IHdnZXRvcHRpb25zW2lucHV0T3B0aW9uXTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICByZXQuX3RvdGFsQnl0ZXMgPSAwOw0KICAgIHJldC5fcmVxdWVzdCA9IGh0dHAuZ2V0KHJlcU9wdGlvbnMpOw0KICAgIHJldC5fbG9jYWxGaWxlUGF0aCA9IGxvY2FsRmlsZVBhdGg7DQogICAgcmV0Ll9yZXF1ZXN0LnByb21pc2UgPSByZXQ7DQogICAgcmV0Ll9yZXF1ZXN0Lm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlKSB7IHRoaXMucHJvbWlzZS5fcmVqKGUpOyB9KTsNCiAgICByZXQuX3JlcXVlc3Qub24oJ2Fib3J0JywgZnVuY3Rpb24gKCkgeyB0aGlzLnByb21pc2UuZW1pdCgnYWJvcnQnKTsgfSk7DQogICAgcmV0Ll9yZXF1ZXN0Lm9uKCdyZXNwb25zZScsIGZ1bmN0aW9uIChpbXNnKQ0KICAgIHsNCiAgICAgICAgaWYoaW1zZy5zdGF0dXNDb2RlICE9IDIwMCkNCiAgICAgICAgew0KICAgICAgICAgICAgdGhpcy5wcm9taXNlLl9yZWooJ1NlcnZlciByZXNwb25zZWQgd2l0aCBTdGF0dXMgQ29kZTogJyArIGltc2cuc3RhdHVzQ29kZSk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZQ0KICAgICAgICB7DQogICAgICAgICAgICB0cnkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB0aGlzLl9maWxlID0gcmVxdWlyZSgnZnMnKS5jcmVhdGVXcml0ZVN0cmVhbSh0aGlzLnByb21pc2UuX2xvY2FsRmlsZVBhdGgsIHsgZmxhZ3M6ICd3YicgfSk7DQogICAgICAgICAgICAgICAgdGhpcy5fc2hhID0gcmVxdWlyZSgnU0hBMzg0U3RyZWFtJykuY3JlYXRlKCk7DQogICAgICAgICAgICAgICAgdGhpcy5fc2hhLnByb21pc2UgPSB0aGlzLnByb21pc2U7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBjYXRjaChlKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHRoaXMucHJvbWlzZS5fcmVqKGUpOw0KICAgICAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHRoaXMuX3NoYS5vbignaGFzaCcsIGZ1bmN0aW9uIChoKSB7IHRoaXMucHJvbWlzZS5fcmVzKGgudG9TdHJpbmcoJ2hleCcpKTsgfSk7DQogICAgICAgICAgICB0aGlzLl9hY2N1bXVsYXRvciA9IG5ldyB3cml0YWJsZSgNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHdyaXRlOiBmdW5jdGlvbihjaHVuaywgY2FsbGJhY2spDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvbWlzZS5fdG90YWxCeXRlcyArPSBjaHVuay5sZW5ndGg7DQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb21pc2UuZW1pdCgnYnl0ZXMnLCB0aGlzLnByb21pc2UuX3RvdGFsQnl0ZXMpOw0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0cnVlKTsNCiAgICAgICAgICAgICAgICAgICAgfSwNCiAgICAgICAgICAgICAgICAgICAgZmluYWw6IGZ1bmN0aW9uKGNhbGxiYWNrKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfSk7DQogICAgICAgICAgICB0aGlzLl9hY2N1bXVsYXRvci5wcm9taXNlID0gdGhpcy5wcm9taXNlOw0KICAgICAgICAgICAgaW1zZy5waXBlKHRoaXMuX2ZpbGUpOw0KICAgICAgICAgICAgaW1zZy5waXBlKHRoaXMuX2FjY3VtdWxhdG9yKTsNCiAgICAgICAgICAgIGltc2cucGlwZSh0aGlzLl9zaGEpOw0KICAgICAgICB9DQogICAgfSk7DQogICAgcmV0LnByb2dyZXNzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMuX3RvdGFsQnl0ZXMpOyB9Ow0KICAgIHJldHVybiAocmV0KTsNCn0NCg0KbW9kdWxlLmV4cG9ydHMgPSB3Z2V0Ow0KDQoNCv==', 'base64').toString());"); diff --git a/modules/message-box.js b/modules/message-box.js index 68a5e0a..098b997 100644 --- a/modules/message-box.js +++ b/modules/message-box.js @@ -129,37 +129,77 @@ function linux_messageBox() this.create = function create(title, caption, timeout) { if (timeout == null) { timeout = 10; } - var zenity = ''; + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + var zenity = '', kdialog = ''; + var uid = require('user-sessions').consoleUid(); + var xinfo = require('monitor-info').getXInfo(uid); var child = require('child_process').execFile('/bin/sh', ['sh']); child.stdout.str = ''; child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); child.stdin.write("whereis zenity | awk '{ print $2 }'\nexit\n"); child.waitExit(); zenity = child.stdout.str.trim(); - if (zenity == '') { throw ('Zenity not installed'); } - var uid = require('user-sessions').consoleUid(); - var xinfo = require('monitor-info').getXInfo(uid); - var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); - ret.child = require('child_process').execFile(zenity, ['zenity', '--question', '--title=' + title, '--text=' + caption, '--timeout=' + timeout], { uid: uid, env: { XAUTHORITY: xinfo.xauthority, DISPLAY: xinfo.display } }); - ret.child.promise = ret; - ret.child.stderr.on('data', function (chunk) { }); - ret.child.stdout.on('data', function (chunk) { }); - ret.child.on('exit', function (code) + if (zenity != '') { - switch(code) + // GNOME/ZENITY + ret.child = require('child_process').execFile(zenity, ['zenity', '--question', '--title=' + title, '--text=' + caption, '--timeout=' + timeout], { uid: uid, env: { XAUTHORITY: xinfo.xauthority, DISPLAY: xinfo.display } }); + ret.child.promise = ret; + ret.child.stderr.on('data', function (chunk) { }); + ret.child.stdout.on('data', function (chunk) { }); + ret.child.on('exit', function (code) { - case 0: - this.promise._res(); - break; - case 1: - this.promise._rej('denied'); - break; - default: - this.promise._rej('timeout'); - break; + switch (code) + { + case 0: + this.promise._res(); + break; + case 1: + this.promise._rej('denied'); + break; + default: + this.promise._rej('timeout'); + break; + } + }); + } + else + { + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write("whereis kdialog | awk '{ print $2 }'\nexit\n"); + child.waitExit(); + kdialog = child.stdout.str.trim(); + if (kdialog == '') { ret._rej('Platform not supported (zenity or kdialog not found)'); return (ret); } + if (process.env['DISPLAY']) + { + ret.child = require('child_process').execFile(kdialog, ['kdialog', '--title', title, '--yesno', caption]); + ret.child.promise = ret; } - }); - + else + { + var xdg = require('user-sessions').findEnv(uid, 'XDG_RUNTIME_DIR'); + if (!xinfo || !xinfo.display || !xinfo.xauthority || !xdg) { ret._rej('Interal Error, could not determine X11/XDG env'); return (ret); } + ret.child = require('child_process').execFile(kdialog, ['kdialog', '--title', title, '--yesno', caption], { uid: uid, env: { DISPLAY: xinfo.display, XAUTHORITY: xinfo.xauthority, XDG_RUNTIME_DIR: xdg } }); + ret.child.promise = ret; + } + ret.child.stdout.on('data', function (chunk) { }); + ret.child.stderr.on('data', function (chunk) { }); + ret.child.on('exit', function (code) + { + switch (code) { + case 0: + this.promise._res(); + break; + case 1: + this.promise._rej('denied'); + break; + default: + this.promise._rej('timeout'); + break; + } + }); + } return (ret); diff --git a/modules/toaster.js b/modules/toaster.js index 761dfef..718d59a 100644 --- a/modules/toaster.js +++ b/modules/toaster.js @@ -14,23 +14,33 @@ See the License for the specific language governing permissions and limitations under the License. */ -var toasters = {}; +var promise = require('promise'); + +if (process.platform == 'linux') +{ + function findPath(app) + { + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write("whereis " + app + " | awk '{ print $2 }'\nexit\n"); + child.waitExit(); + child.stdout.str = child.stdout.str.trim(); + return (child.stdout.str == '' ? null : child.stdout.str); + } +} function Toaster() { this._ObjectID = 'toaster'; this.Toast = function Toast(title, caption) { - var retVal = {}; - var emitter = require('events').inherits(retVal); - emitter.createEvent('Dismissed'); - + var retVal = new promise(function (res, rej) { this._res = res; this._rej = rej; }); retVal.title = title; retVal.caption = caption; if (process.platform == 'win32') { - emitter.createEvent('Clicked'); var GM = require('_GenericMarshal'); var kernel32 = GM.CreateNativeProxy('kernel32.dll'); kernel32.CreateMethod('ProcessIdToSessionId'); @@ -38,7 +48,7 @@ function Toaster() var consoleUid = require('user-sessions').consoleUid(); if (kernel32.ProcessIdToSessionId(process.pid, psid).Val == 0) { - throw ('Internal Error'); + retVal._rej('internal error'); return (retVal); } if (consoleUid == psid.toBuffer().readUInt32LE()) @@ -52,7 +62,7 @@ function Toaster() retVal._child = require('ScriptContainer').Create({ processIsolation: true, sessionId: consoleUid }); } retVal._child.parent = retVal; - retVal._child.on('exit', function (code) { this.parent.emit('Dismissed'); delete this.parent._child; }); + retVal._child.on('exit', function (code) { this.parent._res('DISMISSED'); }); retVal._child.addModule('win-console', getJSModule('win-console')); retVal._child.addModule('win-message-pump', getJSModule('win-message-pump')); @@ -69,76 +79,104 @@ function Toaster() require('ScriptContainer').send('done');\ "; retVal._child.ExecuteString(str); - toasters[retVal._hashCode()] = retVal; - retVal.on('Dismissed', function () { delete toasters[this._hashCode()]; }); - console.log('Returning'); return (retVal); } else { - var child = require('child_process').execFile('/bin/sh', ['sh']); - child.stdout.str = ''; - child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); - child.stdin.write("whereis notify-send | awk '{ print $2 }'\nexit\n"); - child.waitExit(); - if (child.stdout.str.trim() == '') { - // notify-send doesn't exist, lets check kdialog - child = require('child_process').execFile('/bin/sh', ['sh']); - child.stdout.str = ''; - child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); - child.stdin.write("whereis kdialog | awk '{ print $2 }'\nexit\n"); - child.waitExit(); - if (child.stdout.str.trim() == '') { throw ('Toast not supported on this platform'); } - // Let's use kdialog - if (process.env['DISPLAY']) + try + { + retVal.consoleUid = require('user-sessions').consoleUid(); + retVal.xinfo = require('monitor-info').getXInfo(retVal.consoleUid); + } + catch(xxe) + { + retVal._rej(xxe); + return (retVal); + } + var util = findPath('zenity'); + if (util) + { + // Use ZENITY + retVal.child = require('child_process').execFile(util, ['zenity', '--notification', '--title=' + title, '--text=' + caption, '--timeout=5'], { uid: retVal.consoleUid, env: { XAUTHORITY: retVal.xinfo.xauthority, DISPLAY: retVal.xinfo.display } }); + retVal.child.parent = retVal; + retVal.child.stderr.str = ''; + retVal.child.stderr.on('data', function (chunk) { this.str += chunk.toString(); this.parent.kill(); }); + retVal.child.stdout.on('data', function (chunk) { }); + retVal.child.on('exit', function (code) { - retVal._notify = require('child_process').execFile(child.stdout.str.trim(), ['kdialog', '--title', retVal.title, '--passivepopup', retVal.caption, '5']); - } - else - { - var consoleUid = require('user-sessions').consoleUid(); - var xinfo = require('monitor-info').getXInfo(consoleUid); - var xdg = require('user-sessions').findEnv(consoleUid, 'XDG_RUNTIME_DIR'); - if (!xinfo || !xinfo.display || !xinfo.xauthority || !xdg) + if(this.stderr.str.trim() != '') { - throw ('Internal Error'); + if ((util = findPath('notify-send')) && this.stderr.str.split('GLib-CRITICAL').length > 1) + { + // This is a bug in zenity, so we should try notify-send + if (process.env['DISPLAY']) + { + // DISPLAY is set, so we good to go + this.parent.child = require('child_process').execFile(util, ['notify-send', this.parent.title, this.parent.caption]); + this.parent.child.parent = this.parent; + } + else + { + // We need to find the DISPLAY to use + var username = require('user-sessions').getUsername(consoleUid); + this.parent.child = require('child_process').execFile('/bin/sh', ['sh']); + this.parent.child.parent = this.parent; + this.parent.child.stdin.write('su - ' + username + ' -c "DISPLAY=' + display + ' notify-send \'' + this.parent.title + '\' \'' + this.parent.caption + '\'"\n'); + this.parent.child.stdin.write('exit\n'); + } + this.parent.child.stdout.on('data', function (chunk) { }); + this.parent.child.waitExit(); + + // NOTIFY-SEND has a bug where timeouts don't work, so the default is 5 seconds + this.parent._timeout = setTimeout(function onFakeDismissed(obj) + { + obj._res('DISMISSED'); + }, 10000, this.parent); + } + else + { + // Fake a toast using zenity --info + util = findPath('zenity'); + this.parent.child = require('child_process').execFile(util, ['zenity', '--info', '--title=' + this.parent.title, '--text=' + this.parent.caption, '--timeout=5'], { uid: this.parent.consoleUid, env: { XAUTHORITY: this.parent.xinfo.xauthority, DISPLAY: this.parent.xinfo.display } }); + this.parent.child.parent = this.parent; + this.parent.child.stderr.on('data', function (chunk) { }); + this.parent.child.stdout.on('data', function (chunk) { }); + this.parent.child.on('exit', function (code) + { + this.parent._res('DISMISSED'); + }); + } } - retVal._notify = require('child_process').execFile(child.stdout.str.trim(), ['kdialog', '--title', retVal.title, '--passivepopup', retVal.caption, '5'], { uid: consoleUid, env: { DISPLAY: xinfo.display, XAUTHORITY: xinfo.xauthority, XDG_RUNTIME_DIR: xdg } }); - } - retVal._notify.stdout.on('data', function (chunk) { }); - retVal._notify.stderr.on('data', function (chunk) { }); - retVal._notify.waitExit(); + else + { + this.parent._res('DISMISSED'); + } + }); } else { - // Let's use notify-send - - if (process.env['DISPLAY']) + util = findPath('kdialog'); + if (util) { - // DISPLAY is set, so we good to go - retVal._notify = require('child_process').execFile(child.stdout.str.trim(), ['notify-send', retVal.title, retVal.caption]); + // use KDIALOG + var xdg = require('user-sessions').findEnv(retVal.consoleUid, 'XDG_RUNTIME_DIR'); + if (!retVal.xinfo || !retVal.xinfo.display || !retVal.xinfo.xauthority || !xdg) + { + retVal._rej('Internal Error'); + return (retVal); + } + retVal._notify = require('child_process').execFile(util, ['kdialog', '--title', retVal.title, '--passivepopup', retVal.caption, '5'], { uid: retVal.consoleUid, env: { DISPLAY: retVal.xinfo.display, XAUTHORITY: retVal.xinfo.xauthority, XDG_RUNTIME_DIR: xdg } }); + retVal._notify.parent = retVal; + retVal._notify.stdout.on('data', function (chunk) { }); + retVal._notify.stderr.on('data', function (chunk) { }); + retVal._notify.on('exit', function (code) { this.parent._res('DISMISSED'); }); } else { - // We need to find the DISPLAY to use - var consoleUid = require('user-sessions').consoleUid(); - var username = require('user-sessions').getUsername(consoleUid); - var display = require('monitor-info').getXInfo(consoleUid).display; - retVal._notify = require('child_process').execFile('/bin/sh', ['sh']); - retVal._notify.stdin.write('su - ' + username + ' -c "DISPLAY=' + display + ' notify-send \'' + retVal.title + '\' \'' + retVal.caption + '\'"\n'); - retVal._notify.stdin.write('exit\n'); + retVal._rej ('Zenity/KDialog not found'); } - retVal._notify.stdout.on('data', function (chunk) { }); - retVal._notify.waitExit(); - - // NOTIFY-SEND has a bug where timeouts don't work, so the default is 10 seconds - retVal._timeout = setTimeout(function onFakeDismissed(obj) { - obj.emit('Dismissed'); - }, 10000, retVal); - - toasters[retVal._hashCode()] = retVal; - retVal.on('Dismissed', function () { delete toasters[this._hashCode()]; }); } + return (retVal); } };