From fedd70072b5e644be45d0bc753a5c2d71cb3e344 Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Tue, 9 Jun 2020 14:25:28 -0700 Subject: [PATCH] Updated proxy support --- meshcore/agentcore.c | 219 ++------------- microscript/ILibDuktape_HttpStream.c | 7 + microscript/ILibDuktape_Polyfills.c | 10 +- modules/awk-helper.js | 32 +++ modules/linux-gnome-helpers.js | 40 ++- modules/proxy-helper.js | 404 +++++++++++++++++++++++---- 6 files changed, 432 insertions(+), 280 deletions(-) create mode 100644 modules/awk-helper.js diff --git a/meshcore/agentcore.c b/meshcore/agentcore.c index 09d59c3..9ee16d7 100644 --- a/meshcore/agentcore.c +++ b/meshcore/agentcore.c @@ -382,216 +382,23 @@ void MeshAgent_sendConsoleText(duk_context *ctx, char *format, ...) } -int MeshAgent_GetSystemProxy(MeshAgentHostContainer *agent, char *buffer, size_t bufferSize) +int MeshAgent_GetSystemProxy(MeshAgentHostContainer *agent, char *inBuffer, size_t inBufferLen) { -#ifndef __APPLE__ - int retVal = 0; -#endif - -#ifdef _POSIX - #ifndef __APPLE__ - // Linux and FreeBSD - for (char **env = environ; *env; ++env) - { - int envLen = (int)strnlen_s(*env, INT_MAX); - int i = ILibString_IndexOf(*env, envLen, "=", 1); - if (i > 0) - { - if (i == 11 && (strncmp(*env, "https_proxy", 11) == 0 || strncmp(*env, "HTTPS_PROXY", 11) == 0)) - { - if (ILibString_StartsWith(*env + i + 1, envLen - i - 1, "http://", 7) != 0) - { - strcpy_s(buffer, bufferSize, *env + i + 8); - retVal = envLen - i - 8; - } - else if(ILibString_StartsWith(*env + i + 1, envLen - i - 1, "https://", 8) != 0) - { - strcpy_s(buffer, bufferSize, *env + i + 9); - retVal = envLen - i - 9; - } - else - { - strcpy_s(buffer, bufferSize, *env + i + 1); - retVal = envLen - i - 1; - } - break; - } - } - } - if (retVal == 0) - { - // Check /etc/environment just in case it wasn't exported - #ifdef _FREEBSD - // FreeBSD Only - char getProxy[] = "(function getProxies(){\ - var child = require('child_process').execFile('/bin/sh', ['sh']);\ - child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });\ - child.stdin.write('cat /etc/login.conf | grep :setenv= | awk -F\":setenv=\" \\'{ if(!($1 ~ /^#/)) { print $2 } }\\' | tr \"\\,\" \"\\n\" | awk -F= \\'{ if($1==\"https_proxy\") { gsub(/\\\\\\\\c/, \":\", $2); print $2 } }\\'\\n\\exit\\n');\ - child.waitExit();\ - return(child.stdout.str.trim().split('\\n')[0].split('//')[1]);\ - })();"; - #else - // Linux Only - char getProxy[] = "require('proxy-helper').getProxy()"; - #endif - // Linux and FreeBSD - if (duk_peval_string(agent->meshCoreCtx, getProxy) == 0) - { - duk_size_t proxyLen; - char *proxy = (char*)duk_get_lstring(agent->meshCoreCtx, -1, &proxyLen); - if (proxy != NULL && proxyLen > 0) { strcpy_s(buffer, bufferSize, proxy); } - retVal = (int)proxyLen; - } - duk_pop(agent->meshCoreCtx); - } - return(retVal); -#else - // MacOS Only - char getProxyies[] = "(function getProxies(){\ - var ret = {};\ - 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('system_profiler SPNetworkDataType | grep \"Proxy\" \\nexit\\n');\ - child.waitExit();\ - var lines = child.stdout.str.split('\\n');\ - for (var i in lines)\ - {\ - if (lines[i])\ - {\ - var val = lines[i].split(':')[1].trim().toLowerCase();\ - var tokens = lines[i].split(':')[0].trim().split(' ');\ - var key = tokens[0].toLowerCase();\ - var t = tokens[2].toLowerCase();\ - if (!ret[key]) { ret[key] = {}; }\ - ret[key][t] = val;\ - }\ - }\ - return(ret);\ - })();"; - if (duk_peval_string(agent->meshCoreCtx, getProxyies) == 0) + duk_size_t bufferLen = 0; + if (duk_peval_string(agent->meshCoreCtx, "require('proxy-helper').getProxy();") == 0) // [string] { - if (duk_has_prop_string(agent->meshCoreCtx, -1, "http")) + char *buffer = (char*)duk_get_lstring(agent->meshCoreCtx, -1, &bufferLen); + if (bufferLen <= inBufferLen) { - duk_get_prop_string(agent->meshCoreCtx, -1, "http"); - } - else if (duk_has_prop_string(agent->meshCoreCtx, -1, "https")) - { - duk_get_prop_string(agent->meshCoreCtx, -1, "https"); + memcpy_s(inBuffer, inBufferLen, buffer, bufferLen); } else { - duk_pop(agent->meshCoreCtx); - return(0); // No Proxies detected - } - - if (strcmp(Duktape_GetStringPropertyValue(agent->meshCoreCtx, -1, "enabled", "no"), "yes") == 0) - { - char *proxyserver, *proxyport; - duk_size_t proxyserverLen, proxyportLen; - - proxyserver = (char*)Duktape_GetStringPropertyValueEx(agent->meshCoreCtx, -1, "server", NULL, &proxyserverLen); - proxyport = (char*)Duktape_GetStringPropertyValueEx(agent->meshCoreCtx, -1, "port", "8080", &proxyportLen); - - strncpy_s(buffer, bufferSize, proxyserver, proxyserverLen); - strncpy_s(buffer + proxyserverLen, bufferSize - proxyserverLen, ":", 1); - strncpy_s(buffer + proxyserverLen + 1, bufferSize - proxyserverLen - 1, proxyport, proxyportLen); - duk_pop(agent->meshCoreCtx); - return(proxyserverLen + 1 + proxyportLen); - } - else - { - // Proxy is disabled - duk_pop(agent->meshCoreCtx); - return(0); + bufferLen = 0; } } - else - { - return(0); - } - #endif -#else - // Windows Only - char getProxy[] = "(function () {\ - var isroot = false;\ - var servers = [];\ - /* First we need to see if we are running as admin */\ - var GM = require('_GenericMarshal');\ - var advapi = GM.CreateNativeProxy('Advapi32.dll');\ - advapi.CreateMethod('AllocateAndInitializeSid');\ - advapi.CreateMethod('CheckTokenMembership');\ - advapi.CreateMethod('FreeSid');\ - var NTAuthority = GM.CreateVariable(6);\ - NTAuthority.toBuffer().writeInt8(5, 5);\ - var AdministratorsGroup = GM.CreatePointer();\ - if (advapi.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0)\ - {\ - var member = GM.CreateInteger();\ - if (advapi.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0)\ - {\ - if (member.toBuffer().readUInt32LE() != 0) { isroot = true; }\ - }\ - advapi.FreeSid(AdministratorsGroup.Deref());\ - }\ - var reg = require('win-registry');\ - if (isroot)\ - {\ - /* If running as admin, enumerate the users to find proxy settings */\ - var users = reg.QueryKey(reg.HKEY.Users);\ - var keys;\ - for (var i in users.subkeys)\ - {\ - try\ - {\ - value = reg.QueryKey(reg.HKEY.Users, users.subkeys[i] + '\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings', 'ProxyEnable');\ - if (value == 1)\ - {\ - value = reg.QueryKey(reg.HKEY.Users, users.subkeys[i] + '\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings', 'ProxyServer');\ - servers.push(value);\ - }\ - }\ - catch (e)\ - {\ - }\ - }\ - return (servers);\ - }\ - else\ - {\ - /* We're not admin, so we can only check HKEY_LOCAL_USERS for proxy settings */\ - try\ - {\ - if (reg.QueryKey(reg.HKEY.CurrentUser, 'Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet Settings', 'ProxyEnable') == 1)\ - {\ - servers.push(reg.QueryKey(reg.HKEY.CurrentUser, 'Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet Settings', 'ProxyServer'));\ - }\ - }\ - catch (e)\ - {\ - }\ - return (servers);\ - }\ - })();"; - - if (duk_peval_string(agent->meshCoreCtx, getProxy) == 0) - { - if (duk_get_length(agent->meshCoreCtx, -1) > 0) // [array] - { - duk_get_prop_index(agent->meshCoreCtx, -1, 0); // [array][0]; - char *tmp; - duk_size_t tmpLen; - - tmp = (char*)duk_get_lstring(agent->meshCoreCtx, -1, &tmpLen); - strncpy_s(buffer, bufferSize, tmp, tmpLen); - duk_pop(agent->meshCoreCtx); // [array] - retVal = (int)tmpLen; - } - } - duk_pop(agent->meshCoreCtx); // ... - - return(retVal); -#endif + duk_pop(agent->meshCoreCtx); // ... + return((int)bufferLen); } #ifdef _POSIX size_t MeshAgent_Linux_ReadMemFile(char *path, char **buffer) @@ -3617,7 +3424,13 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent) agent->proxyServer = ILibWebClient_SetProxy(reqToken, proxyHost, proxyPort, proxyUsername, proxyPassword); if (agent->proxyServer != NULL) { - memcpy_s(&(ILibDuktape_GetNewGlobalTunnel(agent->meshCoreCtx)->proxyServer), sizeof(struct sockaddr_in6), agent->proxyServer, sizeof(struct sockaddr_in6)); + ILibDuktape_globalTunnel_data *proxy = ILibDuktape_GetNewGlobalTunnel(agent->meshCoreCtx); + memcpy_s(&(proxy->proxyServer), sizeof(struct sockaddr_in6), agent->proxyServer, sizeof(struct sockaddr_in6)); + if (proxyUsername != NULL && proxyPassword != NULL) + { + memcpy_s(proxy->proxyUser, sizeof(proxy->proxyUser), proxyUsername, strnlen_s(proxyUsername, sizeof(proxy->proxyUser))); + memcpy_s(proxy->proxyPass, sizeof(proxy->proxyPass), proxyPassword, strnlen_s(proxyPassword, sizeof(proxy->proxyPass))); + } } } } diff --git a/microscript/ILibDuktape_HttpStream.c b/microscript/ILibDuktape_HttpStream.c index 15ddda9..30fadb5 100644 --- a/microscript/ILibDuktape_HttpStream.c +++ b/microscript/ILibDuktape_HttpStream.c @@ -1309,7 +1309,14 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx) duk_put_prop_string(ctx, -2, "host"); duk_push_int(ctx, (int)ntohs(globalTunnel->proxyServer.sin6_port)); duk_put_prop_string(ctx, -2, "port"); // [options][proxy] + if (globalTunnel->proxyUser[0] != 0 && globalTunnel->proxyPass[0] != 0) + { + duk_push_string(ctx, globalTunnel->proxyUser); duk_put_prop_string(ctx, -2, "username"); + duk_push_string(ctx, globalTunnel->proxyPass); duk_put_prop_string(ctx, -2, "password"); + } + duk_put_prop_string(ctx, -2, "proxy"); // [options] + duk_pop(ctx); // ... } diff --git a/microscript/ILibDuktape_Polyfills.c b/microscript/ILibDuktape_Polyfills.c index 2cfa795..07d1a0a 100644 --- a/microscript/ILibDuktape_Polyfills.c +++ b/microscript/ILibDuktape_Polyfills.c @@ -2164,7 +2164,7 @@ void ILibDuktape_Polyfills_JS_Init(duk_context *ctx) duk_peval_string_noresult(ctx, "addModule('process-manager', Buffer.from('LyoNCkNvcHlyaWdodCAyMDE4IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQoNCnZhciBHTSA9IHJlcXVpcmUoJ19HZW5lcmljTWFyc2hhbCcpOw0KdmFyIFRIMzJDU19TTkFQUFJPQ0VTUyA9IDB4MDI7DQp2YXIgVEgzMkNTX1NOQVBNT0RVTEUzMiA9IDB4MTA7DQp2YXIgVEgzMkNTX1NOQVBNT0RVTEUgPSAweDA4Ow0KdmFyIFBST0NFU1NfUVVFUllfTElNSVRFRF9JTkZPUk1BVElPTiA9IDB4MTAwMDsNCg0KDQovLyBVc2VkIG9uIFdpbmRvd3MgYW5kIExpbnV4IHRvIGdldCBpbmZvcm1hdGlvbiBhYm91dCBydW5uaW5nIHByb2Nlc3Nlcw0KZnVuY3Rpb24gcHJvY2Vzc01hbmFnZXIoKSB7DQogICAgdGhpcy5fT2JqZWN0SUQgPSAncHJvY2Vzcy1tYW5hZ2VyJzsgLy8gVXNlZCBmb3IgZGVidWdnaW5nLCBhbGxvd3MgeW91IHRvIGdldCB0aGUgb2JqZWN0IHR5cGUgYXQgcnVudGltZS4NCiAgICANCiAgICAvLyBTZXR1cCB0aGUgcGxhdGZvcm0gc3BlY2lmaWMgY2FsbHMuDQogICAgc3dpdGNoIChwcm9jZXNzLnBsYXRmb3JtKQ0KICAgIHsNCiAgICAgICAgY2FzZSAnd2luMzInOg0KICAgICAgICAgICAgdGhpcy5fa2VybmVsMzIgPSBHTS5DcmVhdGVOYXRpdmVQcm94eSgna2VybmVsMzIuZGxsJyk7DQogICAgICAgICAgICB0aGlzLl9rZXJuZWwzMi5DcmVhdGVNZXRob2QoJ0Nsb3NlSGFuZGxlJyk7DQogICAgICAgICAgICB0aGlzLl9rZXJuZWwzMi5DcmVhdGVNZXRob2QoJ0dldExhc3RFcnJvcicpOw0KICAgICAgICAgICAgdGhpcy5fa2VybmVsMzIuQ3JlYXRlTWV0aG9kKCdDcmVhdGVUb29saGVscDMyU25hcHNob3QnKTsNCiAgICAgICAgICAgIHRoaXMuX2tlcm5lbDMyLkNyZWF0ZU1ldGhvZCgnTW9kdWxlMzJGaXJzdFcnKTsNCiAgICAgICAgICAgIHRoaXMuX2tlcm5lbDMyLkNyZWF0ZU1ldGhvZCgnTW9kdWxlMzJOZXh0VycpOw0KICAgICAgICAgICAgdGhpcy5fa2VybmVsMzIuQ3JlYXRlTWV0aG9kKCdPcGVuUHJvY2VzcycpOw0KICAgICAgICAgICAgdGhpcy5fa2VybmVsMzIuQ3JlYXRlTWV0aG9kKCdQcm9jZXNzMzJGaXJzdFcnKTsNCiAgICAgICAgICAgIHRoaXMuX2tlcm5lbDMyLkNyZWF0ZU1ldGhvZCgnUHJvY2VzczMyTmV4dFcnKTsNCiAgICAgICAgICAgIHRoaXMuX2tlcm5lbDMyLkNyZWF0ZU1ldGhvZCgnUXVlcnlGdWxsUHJvY2Vzc0ltYWdlTmFtZVcnKTsNCiAgICAgICAgICAgIGJyZWFrOw0KCWNhc2UgJ2ZyZWVic2QnOg0KICAgICAgICBjYXNlICdsaW51eCc6DQogICAgICAgIGNhc2UgJ2Rhcndpbic6DQogICAgICAgICAgICB0aGlzLl9jaGlsZFByb2Nlc3MgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJyk7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgZGVmYXVsdDoNCiAgICAgICAgICAgIHRocm93IChwcm9jZXNzLnBsYXRmb3JtICsgJyBub3Qgc3VwcG9ydGVkJyk7DQogICAgICAgICAgICBicmVhazsNCiAgICB9DQogICAgdGhpcy5lbnVtZXJhdGVQcm9jZXNzZXMgPSBmdW5jdGlvbiBlbnVtZXJhdGVQcm9jZXNzZXMoKQ0KICAgIHsNCiAgICAgICAgdmFyIHByb21pc2UgPSByZXF1aXJlKCdwcm9taXNlJyk7DQogICAgICAgIHZhciByZXQgPSBuZXcgcHJvbWlzZShmdW5jdGlvbiAocmVzLCByZWopIHsgdGhpcy5fcmVzID0gcmVzOyB0aGlzLl9yZWogPSByZWo7IH0pOw0KICAgICAgICByZXQuY2FsbGJhY2sgPSBmdW5jdGlvbiBjYWxsYmFjayhwcykNCiAgICAgICAgew0KICAgICAgICAgICAgY2FsbGJhY2sucHJvbS5fcmVzKHBzKTsNCiAgICAgICAgfQ0KICAgICAgICByZXQuY2FsbGJhY2sucHJvbSA9IHJldDsNCiAgICAgICAgdGhpcy5nZXRQcm9jZXNzZXMocmV0LmNhbGxiYWNrKTsNCiAgICAgICAgcmV0dXJuIChyZXQpOw0KICAgIH0NCiAgICAvLyBSZXR1cm4gYSBvYmplY3Qgb2Y6IHBpZCAtPiBwcm9jZXNzIGluZm9ybWF0aW9uLg0KICAgIHRoaXMuZ2V0UHJvY2Vzc2VzID0gZnVuY3Rpb24gZ2V0UHJvY2Vzc2VzKGNhbGxiYWNrKQ0KICAgIHsNCiAgICAgICAgc3dpdGNoKHByb2Nlc3MucGxhdGZvcm0pDQogICAgICAgIHsNCiAgICAgICAgICAgIGRlZmF1bHQ6DQogICAgICAgICAgICAgICAgdGhyb3cgKCdFbnVtZXJhdGluZyBwcm9jZXNzZXMgb24gJyArIHByb2Nlc3MucGxhdGZvcm0gKyAnIG5vdCBzdXBwb3J0ZWQnKTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGNhc2UgJ3dpbjMyJzogLy8gV2luZG93cyBwcm9jZXNzZXMNCiAgICAgICAgICAgICAgICB2YXIgcGlkOw0KICAgICAgICAgICAgICAgIHZhciByZXRWYWwgPSB7fTsNCiAgICAgICAgICAgICAgICB2YXIgaCA9IHRoaXMuX2tlcm5lbDMyLkNyZWF0ZVRvb2xoZWxwMzJTbmFwc2hvdChUSDMyQ1NfU05BUFBST0NFU1MsIDApOw0KICAgICAgICAgICAgICAgIHZhciBpbmZvID0gR00uQ3JlYXRlVmFyaWFibGUoR00uUG9pbnRlclNpemUgPT0gOCA/IDU2OCA6IDU1Nik7DQogICAgICAgICAgICAgICAgdmFyIGZ1bGxwYXRoID0gR00uQ3JlYXRlVmFyaWFibGUoMjA0OCk7DQogICAgICAgICAgICAgICAgdmFyIHBhdGhTaXplID0gR00uQ3JlYXRlVmFyaWFibGUoNCk7DQogICAgICAgICAgICAgICAgdmFyIHBoOw0KDQogICAgICAgICAgICAgICAgaW5mby50b0J1ZmZlcigpLndyaXRlVUludDMyTEUoaW5mby5fc2l6ZSwgMCk7DQogICAgICAgICAgICAgICAgdmFyIG5leHRQcm9jZXNzID0gdGhpcy5fa2VybmVsMzIuUHJvY2VzczMyRmlyc3RXKGgsIGluZm8pOw0KICAgICAgICAgICAgICAgIHdoaWxlIChuZXh0UHJvY2Vzcy5WYWwpIA0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgcGlkID0gaW5mby5EZXJlZig4LCA0KS50b0J1ZmZlcigpLnJlYWRVSW50MzJMRSgwKTsNCiAgICAgICAgICAgICAgICAgICAgcmV0VmFsW3BpZF0gPSB7IHBpZDogcGlkLCBjbWQ6IGluZm8uRGVyZWYoR00uUG9pbnRlclNpemUgPT0gNCA/IDM2IDogNDQsIDI2MCkuV2lkZTJVVEY4IH07DQoNCiAgICAgICAgICAgICAgICAgICAgaWYgKChwaCA9IHRoaXMuX2tlcm5lbDMyLk9wZW5Qcm9jZXNzKFBST0NFU1NfUVVFUllfTElNSVRFRF9JTkZPUk1BVElPTiwgMCwgcGlkKSkuVmFsICE9IC0xKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICBwYXRoU2l6ZS50b0J1ZmZlcigpLndyaXRlVUludDMyTEUoZnVsbHBhdGguX3NpemUpOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2tlcm5lbDMyLlF1ZXJ5RnVsbFByb2Nlc3NJbWFnZU5hbWVXKHBoLCAwLCBmdWxscGF0aCwgcGF0aFNpemUpLlZhbCAhPSAwKQ0KICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldFZhbFtwaWRdLnBhdGggPSBmdWxscGF0aC5XaWRlMlVURjg7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXJuZWwzMi5DbG9zZUhhbmRsZShwaCk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICByZXRWYWxbcGlkXS51c2VyID0gcmVxdWlyZSgndXNlci1zZXNzaW9ucycpLmdldFByb2Nlc3NPd25lck5hbWUocGlkKS5uYW1lOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGNhdGNoKGVlKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIG5leHRQcm9jZXNzID0gdGhpcy5fa2VybmVsMzIuUHJvY2VzczMyTmV4dFcoaCwgaW5mbyk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHRoaXMuX2tlcm5lbDMyLkNsb3NlSGFuZGxlKGgpOw0KICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykgeyBjYWxsYmFjay5hcHBseSh0aGlzLCBbcmV0VmFsXSk7IH0NCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGNhc2UgJ2xpbnV4JzogLy8gTGludXggcHJvY2Vzc2VzDQogICAgICAgICAgICAgICAgdmFyIHAgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICAgICAgICAgIHAuc3Rkb3V0LnN0ciA9ICcnOyBwLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICAgICAgcC5zdGRlcnIuc3RyID0gJyc7IHAuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICBwLnN0ZGluLndyaXRlKCdwcyAtYXggLW8gcGlkIC1vIHVzZXI6OTkgLW8gY29tbWFuZCB8IHRyICcgKyAiJ1xcbicgJ1xcdCcgfCBhd2sgLUYiICsgJyJcXHQiIFwneyBwcmludGYgInsiOyBmb3IoaT0yO2k8TkY7KytpKSB7IHNwbGl0KCRpLHRvaywiICIpOyBwaWQ9dG9rWzFdOyB1c2VyPXRva1syXTsgY21kPXN1YnN0cigkaSxsZW5ndGgodG9rWzFdKSsxMDIpOyBnc3ViKC9cXFxcLywiXFxcXFxcXFwmIixjbWQpOyBnc3ViKC8iLywiXFxcXFxcXFwmIixjbWQpOyBnc3ViKC9eWyBdKy8sIiIsY21kKTsgcHJpbnRmICIlc1xcIiVzXFwiOntcXCJwaWRcXCI6XFwiJXNcXCIsXFwidXNlclxcIjpcXCIlc1xcIixcXCJjbWRcXCI6XFwiJXNcXCJ9IiwoaSE9Mj8iLCI6IiIpLHBpZCxwaWQsdXNlcixjbWQ7IH0gcHJpbnRmICJ9IjsgfVwnXG5leGl0XG4nKTsNCiAgICAgICAgICAgICAgICBwLndhaXRFeGl0KCk7DQoNCiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2spDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBwLmFyZ3MgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyArK2kpIHsgcC5hcmdzLnB1c2goYXJndW1lbnRzW2ldKTsgfQ0KDQogICAgICAgICAgICAgICAgICAgIHAuYXJncy51bnNoaWZ0KEpTT04ucGFyc2UocC5zdGRvdXQuc3RyKSk7DQogICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KHRoaXMsIHAuYXJncyk7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBjYXNlICdkYXJ3aW4nOg0KICAgICAgICAgICAgY2FzZSAnZnJlZWJzZCc6DQogICAgICAgICAgICAgICAgdmFyIHAgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICAgICAgICAgIHAuc3Rkb3V0LnN0ciA9ICcnOyBwLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICAgICAgcC5zdGRlcnIuc3RyID0gJyc7IHAuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICBwLnN0ZGluLndyaXRlKCdwcyAtYXhvIHBpZCAtbyB1c2VyIC1vIGNvbW1hbmQgfCB0ciAnICsgIidcXG4nICdcXHQnIHwgYXdrIC1GIiArICciXFx0IiBcJ3sgcHJpbnRmICJ7IjsgZm9yKGk9MjtpPE5GOysraSkgeyBnc3ViKC9eWyBdKy8sIiIsJGkpOyBzcGxpdCgkaSx0b2ssIiAiKTsgcGlkPXRva1sxXTsgdXNlcj10b2tbMl07IGNtZD1zdWJzdHIoJGksbGVuZ3RoKHRva1sxXSkrbGVuZ3RoKHRva1syXSkrMik7IGdzdWIoL1xcXFwvLCJcXFxcXFxcXCYiLGNtZCk7IGdzdWIoLyIvLCJcXFxcXFxcXCYiLGNtZCk7IGdzdWIoL15bIF0rLywiIixjbWQpOyBwcmludGYgIiVzXFwiJXNcXCI6e1xcInBpZFxcIjpcXCIlc1xcIixcXCJ1c2VyXFwiOlxcIiVzXFwiLFxcImNtZFxcIjpcXCIlc1xcIn0iLChpIT0yPyIsIjoiIikscGlkLHBpZCx1c2VyLGNtZDsgfSBwcmludGYgIn0iOyB9XCdcbmV4aXRcbicpOw0KICAgICAgICAgICAgICAgIHAud2FpdEV4aXQoKTsNCg0KICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHAuYXJncyA9IFtdOw0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7ICsraSkgeyBwLmFyZ3MucHVzaChhcmd1bWVudHNbaV0pOyB9DQoNCiAgICAgICAgICAgICAgICAgICAgcC5hcmdzLnVuc2hpZnQoSlNPTi5wYXJzZShwLnN0ZG91dC5zdHIpKTsNCiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkodGhpcywgcC5hcmdzKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgIH07DQoNCiAgICAvLyBHZXQgaW5mb3JtYXRpb24gYWJvdXQgYSBzcGVjaWZpYyBwcm9jZXNzIG9uIExpbnV4DQogICAgdGhpcy5nZXRQcm9jZXNzSW5mbyA9IGZ1bmN0aW9uIGdldFByb2Nlc3NJbmZvKHBpZCkNCiAgICB7DQogICAgICAgIHN3aXRjaChwcm9jZXNzLnBsYXRmb3JtKQ0KICAgICAgICB7DQogICAgICAgICAgICBkZWZhdWx0Og0KICAgICAgICAgICAgICAgIHRocm93ICgnZ2V0UHJvY2Vzc0luZm8oKSBub3Qgc3VwcG9ydGVkIGZvciAnICsgcHJvY2Vzcy5wbGF0Zm9ybSk7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBjYXNlICdsaW51eCc6DQogICAgICAgICAgICAgICAgdmFyIHN0YXR1cyA9IHJlcXVpcmUoJ2ZzJykucmVhZEZpbGVTeW5jKCcvcHJvYy8nICsgcGlkICsgJy9zdGF0dXMnKTsNCiAgICAgICAgICAgICAgICB2YXIgaW5mbyA9IHt9Ow0KICAgICAgICAgICAgICAgIHZhciBsaW5lcyA9IHN0YXR1cy50b1N0cmluZygpLnNwbGl0KCdcbicpOw0KICAgICAgICAgICAgICAgIGZvcih2YXIgaT0wO2k8bGluZXMubGVuZ3RoOysraSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciB0b2tlbnMgPSBsaW5lc1tpXS5zcGxpdCgnOicpOw0KICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW5zLmxlbmd0aCA+IDEpIHsgdG9rZW5zWzFdID0gdG9rZW5zWzFdLnRyaW0oKTsgfQ0KICAgICAgICAgICAgICAgICAgICBpbmZvW3Rva2Vuc1swXV0gPSB0b2tlbnNbMV07DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHJldHVybiAoaW5mbyk7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICB9Ow0KDQogICAgaWYocHJvY2Vzcy5wbGF0Zm9ybSAhPSAnd2luMzInKQ0KICAgIHsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdfcGdyZXAnLCB7DQogICAgICAgICAgICB2YWx1ZTogKGZ1bmN0aW9uICgpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7DQogICAgICAgICAgICAgICAgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7IHRoaXMuc3RyICs9IGNodW5rLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCJ3aGVyZWlzIHBncmVwIHwgYXdrICd7IHByaW50ICQyIH0nXG5leGl0XG4iKTsNCiAgICAgICAgICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgICAgICAgICAgICAgIHJldHVybiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkpOw0KICAgICAgICAgICAgfSkoKQ0KICAgICAgICB9KTsNCg0KICAgICAgICBpZiAodGhpcy5fcGdyZXAgIT0gJycpDQogICAgICAgIHsNCiAgICAgICAgICAgIHRoaXMuZ2V0UHJvY2VzcyA9IGZ1bmN0aW9uIGdldFByb2Nlc3MoY21kKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgICAgICAgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOyBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGVyci5zdHIgPSAnJzsgY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgicGdyZXAgZ25vbWUtc2Vzc2lvbiB8IHRyICdcXG4nICdcXHQnIHwiICsgJyBhd2sgLUYiXFx0IiBcJ3sgcHJpbnRmICJbIjsgZm9yKGk9MTtpPE5GOysraSkgeyBpZihpPjEpIHsgcHJpbnRmICIsIjsgfSBwcmludGYgIiVkIiwgJGk7IH0gcHJpbnRmICJdIjsgfVwnJyk7DQogICAgICAgICAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ1xuZXhpdFxuJyk7DQogICAgICAgICAgICAgICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICAgICAgICAgICAgICBpZiAoY2hpbGQuc3RkZXJyLnN0ciAhPSAnJykgeyB0aHJvdyAoY2hpbGQuc3RkZXJyLnN0ci50cmltKCkpOyB9DQogICAgICAgICAgICAgICAgaWYgKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpID09ICcnKSB7IHRocm93IChjbWQgKyAnIG5vdCBmb3VuZCcpOyB9DQoNCiAgICAgICAgICAgICAgICByZXR1cm4gKEpTT04ucGFyc2UoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkpKTsNCiAgICAgICAgICAgIH07DQogICAgICAgIH0NCg0KICAgICAgICB0aGlzLmdldFByb2Nlc3NFeCA9IGZ1bmN0aW9uIGdldFByb2Nlc3NFeChjbWQpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICBjaGlsZC5zdGRlcnIuc3RyID0gJyc7IGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgncHMgLWF4IC1vIHBpZCAtbyBjb21tYW5kIHwgZ3JlcCAnICsgY21kICsgIiB8IHRyICdcXG4nICdcXHQnIHwgYXdrIC1GIiArICciXFx0IiBcJ3sgcHJpbnRmICJbIjsgZm9yKGk9MTtpPE5GOysraSkgeyBzcGxpdCgkaSxyLCIgIik7IGlmKHJbMl0hPSJncmVwIikgeyBpZihpPjEpIHsgcHJpbnRmICIsIjsgfSBwcmludGYgIiVzIiwgclsxXTsgfSB9IHByaW50ZiAiXSI7IH1cJycpOw0KICAgICAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ1xuZXhpdFxuJyk7DQogICAgICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KDQogICAgICAgICAgICBpZiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkgPT0gJycpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhyb3cgKGNtZCArICcgbm90IGZvdW5kJyk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgcmV0dXJuIChKU09OLnBhcnNlKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpKSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQp9DQoNCm1vZHVsZS5leHBvcnRzID0gbmV3IHByb2Nlc3NNYW5hZ2VyKCk7DQo=', 'base64').toString());"); #if defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD) duk_peval_string_noresult(ctx, "addModule('linux-dbus', Buffer.from('LyoNCkNvcHlyaWdodCAyMDE4IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQp0cnkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoQXJyYXkucHJvdG90eXBlLCAicGVlayIsIHsgdmFsdWU6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh0aGlzLmxlbmd0aCA+IDAgPyB0aGlzW3RoaXMubGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQpOyB9IH0pOyB9IGNhdGNoIChlKSB7IH0NCg0KDQoNCmZ1bmN0aW9uIGRidXMoYWRkcmVzcywgdWlkLCBlbnYpDQp7DQogICAgLy9jb25zb2xlLmxvZyhhZGRyZXNzLCB1aWQsIGVudik7DQogICAgdmFyIG9wdGlvbnMgPSB7IGVudjogZW52LCB1aWQ6IHVpZCA9PSBudWxsID8gLTEgOiB1aWQgfTsNCiAgICBpZiAodWlkID09IG51bGwgJiYgZW52ID09IG51bGwpIHsgb3B0aW9ucyA9IHt9OyB9DQoNCiAgICB0aGlzLl9PYmplY3RJRCA9ICdsaW51eC1kYnVzJzsNCiAgICByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXIuY2FsbCh0aGlzLCB0cnVlKQ0KICAgICAgICAuY3JlYXRlRXZlbnQoJ3NpZ25hbCcpOw0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAidWlkIiwgeyB2YWx1ZTogdWlkIH0pOw0KICAgIHRoaXMuX2NoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCIvYmluL3NoIiwgWyJzaCJdLCBvcHRpb25zKTsNCiAgICB0aGlzLl9jaGlsZC5kZXNjcmlwdG9yTWV0YWRhdGEgPSAnbGludXgtZGJ1cyB7dWlkOiAnICsgdWlkICsgJywgYWRkcmVzczogJyArIGFkZHJlc3MgKyAnfSc7DQoNCiAgICBpZiAodWlkICE9IG51bGwpDQogICAgew0KICAgICAgICB0aGlzLl9jaGlsZC5zdGRpbi53cml0ZSgnZGJ1cy1tb25pdG9yIC0tc2Vzc2lvbiAidHlwZT1cJ3NpZ25hbFwnLCBpbnRlcmZhY2U9XCcnICsgYWRkcmVzcyArICdcJyIgfCAoIHdoaWxlIHJlYWQgWDsgZG8gZWNobyAiJFgiOyBkb25lIClcbicpOw0KICAgIH0NCiAgICBlbHNlDQogICAgew0KICAgICAgICB0aGlzLl9jaGlsZC5zdGRpbi53cml0ZSgnZGJ1cy1tb25pdG9yIC0tc3lzdGVtICJ0eXBlPVwnc2lnbmFsXCcnICsgKGFkZHJlc3MhPW51bGw/KCcsIGludGVyZmFjZT1cJycgKyBhZGRyZXNzICsgJ1wnJyk6KCcnKSkgKyAnIiB8ICggd2hpbGUgcmVhZCBYOyBkbyBlY2hvICIkWCI7IGRvbmUgKVxuJyk7DQogICAgfQ0KICAgIHRoaXMuX2NoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7ICB9KTsNCiAgICB0aGlzLl9jaGlsZC5zdGRvdXQuZGJ1cyA9IHRoaXM7DQogICAgdGhpcy5fY2hpbGQuc3Rkb3V0Ll9zdHIgPSAnJzsNCiAgICB0aGlzLl9jaGlsZC5zdGRvdXQuX3BlbmRpbmcgPSBbXTsNCiAgICB0aGlzLl9jaGlsZC5vbignZXhpdCcsIGZ1bmN0aW9uICgpIHsgfSk7DQogICAgdGhpcy5fY2hpbGQuc3Rkb3V0Ll9wcm9jZXNzUGVuZGluZyA9IGZ1bmN0aW9uIF9wcm9jZXNzUGVuZGluZygpDQogICAgew0KICAgICAgICAvL2NvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHRoaXMuX3BlbmRpbmcsIG51bGwsIDEpKTsNCg0KICAgICAgICB0aGlzLl9wZW5kaW5nVGltZW91dCA9IG51bGw7DQogICAgICAgIHZhciBzaWcgPSB7fTsNCiAgICAgICAgdmFyIHRtcCwgdG1wMjsNCg0KICAgICAgICB2YXIgaW5mbyA9IHRoaXMuX3BlbmRpbmdbMF0uc3BsaXQoJzsnKTsNCiAgICAgICAgZm9yIChpID0gMTsgaSA8IGluZm8ubGVuZ3RoOyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBpbmZvMiA9IGluZm9baV0uc3BsaXQoJz0nKTsNCiAgICAgICAgICAgIGlmIChpbmZvMlswXSAmJiBpbmZvMlsxXSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzaWdbaW5mbzJbMF0udHJpbSgpXSA9IGluZm8yWzFdLnRyaW0oKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBmb3IgKGkgPSAxOyBpIDwgdGhpcy5fcGVuZGluZy5sZW5ndGg7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKHRoaXMuX3BlbmRpbmdbaV0uc3RhcnRzV2l0aCgnc3RyaW5nICcpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHNpZ1sndmFsdWUnXSA9IHRoaXMuX3BlbmRpbmdbaV0uc3BsaXQoJyInKVsxXTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3BlbmRpbmdbaV0uc3RhcnRzV2l0aCgnYm9vbGVhbiAnKSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzaWdbJ3ZhbHVlJ10gPSBKU09OLnBhcnNlKHRoaXMuX3BlbmRpbmdbaV0uc3BsaXQoJyAnKVsxXSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAodGhpcy5fcGVuZGluZ1tpXS5zdGFydHNXaXRoKCdhcnJheSAnKSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzaWdbJ2RhdGEnXSA9IFtdOw0KICAgICAgICAgICAgICAgIGZvciAoaSA9IGkgKyAxOyBpIDwgdGhpcy5fcGVuZGluZy5sZW5ndGg7ICsraSkNCiAgICAgICAgICAgICAgICB7DQoJCSAgICAgICAgICAgIGlmKHRoaXMuX3BlbmRpbmdbaV0uc3RhcnRzV2l0aCgnZGljdCBlbnRyeScpKQ0KCQkgICAgICAgICAgICB7DQoJCQkgICAgICAgICAgICB2YXIgZGljdEVudHJ5ID0ge307DQoJCQkgICAgICAgICAgICB2YXIgajsNCgkJCSAgICAgICAgICAgIGZvcihqPWk7dGhpcy5fcGVuZGluZ1tqXS5pbmRleE9mKCcpJyk8MDsrK2opIHt9DQoJCQkgICAgICAgICAgICB2YXIgdG1wU3RyaW5nID0gdGhpcy5fcGVuZGluZy5zbGljZShpLGopLmpvaW4oJyAnKTsNCgkJCSAgICAgICAgICAgIHZhciB0bXBLZXkgPSB0bXBTdHJpbmcuc3BsaXQoJyInKVsxXTsNCgkJCSAgICAgICAgICAgIHZhciB0bXBWYWw7DQoJCQkgICAgICAgICAgICB0cnkNCgkJCSAgICAgICAgICAgIHsJCQkNCgkJCQkgICAgICAgICAgICB0bXBWYWwgID0gdG1wU3RyaW5nLnNwbGl0KCd2YXJpYW50JylbMV0udHJpbSgpOw0KCQkJICAgICAgICAgICAgfQ0KCQkJICAgICAgICAgICAgY2F0Y2goZSkNCgkJCSAgICAgICAgICAgIHsNCgkJCQkgICAgICAgICAgICBjb25zb2xlLmxvZygnT09QUzogJyArIHRtcFN0cmluZyk7DQoJCQkJICAgICAgICAgICAgY29uc29sZS5sb2coJ1xuJyk7DQoJCQkgICAgICAgICAgICB9DQoJCQkgICAgICAgICAgICBpZih0bXBWYWwuc3RhcnRzV2l0aCgnc3RyaW5nICcpKQ0KCQkJICAgICAgICAgICAgew0KCQkJICAgICAgICAgICAgICAgdG1wVmFsID0gdG1wVmFsLnNwbGl0KCciJylbMV07DQoJCQkgICAgICAgICAgICB9DQoJCQkgICAgICAgICAgICBpZih0bXBWYWwuc3RhcnRzV2l0aCgndWludCcpIHx8IHRtcFZhbC5zdGFydHNXaXRoKCdpbnQnKSkNCgkJCSAgICAgICAgICAgIHsNCgkJCSAgICAgICAgICAgICAgIHRtcFZhbCA9IHRtcFZhbC5zcGxpdCgnICcpWzFdOw0KCQkJICAgICAgICAgICAgfQ0KCQkJICAgICAgICAgICAgZGljdEVudHJ5W3RtcFN0cmluZy5zcGxpdCgnIicpWzFdXSA9IHRtcFZhbDsNCgkJCSAgICAgICAgICAgIHNpZ1snZGF0YSddLnB1c2goZGljdEVudHJ5KTsNCgkJCSAgICAgICAgICAgIGkgPSBqIC0gMTsNCgkJICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9wZW5kaW5nW2ldLnN0YXJ0c1dpdGgoJ3N0cmluZyAnKSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gdGhpcy5fcGVuZGluZ1tpXS5zcGxpdCgnIicpWzFdLnNwbGl0KCc9Jyk7DQogICAgICAgICAgICAgICAgICAgICAgICBpZih0bXBbMV0pDQogICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wMiA9IHt9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcDJbdG1wWzBdLnRyaW0oKV0gPSB0bXBbMV0udHJpbSgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ1snZGF0YSddLnB1c2godG1wMik7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgdGhpcy5fcGVuZGluZyA9IFtdOw0KDQogICAgICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbiAoZSwgcykNCiAgICAgICAgew0KICAgICAgICAgICAgZS5kYnVzLmVtaXQoJ3NpZ25hbCcsIHMpOw0KICAgICAgICB9LCB0aGlzLCBzaWcpOw0KICAgIH07DQogICAgdGhpcy5fY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKQ0KICAgIHsNCiAgICAgICAgLy8gUGFyc2UgREJVUyBEYXRhDQogICAgICAgIGlmICh0aGlzLl9wZW5kaW5nVGltZW91dCkgeyBjbGVhclRpbWVvdXQodGhpcy5fcGVuZGluZ1RpbWVvdXQpOyB0aGlzLl9wZW5kaW5nVGltZW91dCA9IG51bGw7IH0NCiAgICAgICAgLy9jb25zb2xlLmxvZygnPT4nICsgY2h1bmsudG9TdHJpbmcoKSArICc8PScpOw0KDQogICAgICAgIHZhciBpOw0KICAgICAgICB2YXIgdG9rZW5zID0gY2h1bmsudG9TdHJpbmcoKS5zcGxpdCgnXG4nKTsNCiAgICAgICAgZm9yIChpIGluIHRva2VucykNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKHRva2Vuc1tpXS5zdGFydHNXaXRoKCdzaWduYWwgJykpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaWYgKHRoaXMuX3BlbmRpbmcubGVuZ3RoID4gMCkgeyB0aGlzLl9wcm9jZXNzUGVuZGluZygpOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB0aGlzLl9wZW5kaW5nLnB1c2godG9rZW5zW2ldKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGlmICh0aGlzLl9wZW5kaW5nLmxlbmd0aCA+IDApDQogICAgICAgIHsNCiAgICAgICAgICAgIHRoaXMuX3BlbmRpbmdUaW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoc2VsZikgeyBzZWxmLl9wcm9jZXNzUGVuZGluZygpOyB9LCA1MDAsIHRoaXMpOw0KICAgICAgICB9DQogICAgfSk7DQp9DQoNCm1vZHVsZS5leHBvcnRzID0gZGJ1czsNCm1vZHVsZS5leHBvcnRzLmhhc1NlcnZpY2UgPSBmdW5jdGlvbiBoYXNTZXJ2aWNlKG5hbWUpDQp7DQogICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICBjaGlsZC5zdGRlcnIuc3RyID0gJyc7IGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOyBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCdjYXQgL3Vzci9zaGFyZS9kYnVzLTEvc2VydmljZXMvKi5zZXJ2aWNlIHwgZ3JlcCAiJyArIG5hbWUgKyAnIiB8IGF3ayAtRj0gXCd7IGlmKCAkMj09IicgKyBuYW1lICsgJyIgKSB7IHByaW50ICQyOyB9IH1cJ1xuZXhpdFxuJyk7DQogICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICByZXR1cm4gKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpICE9ICcnKTsNCn07DQptb2R1bGUuZXhwb3J0cy5nZXRTZXJ2aWNlcyA9IGZ1bmN0aW9uIGdldFNlcnZpY2VzKCkNCnsNCiAgICB2YXIgZ3JlcCA9IG51bGw7DQogICAgdmFyIG9wdGlvbnMgPSBudWxsOw0KICAgIGZvciAodmFyIGF4IGluIGFyZ3VtZW50cykNCiAgICB7DQogICAgICAgIGlmKHR5cGVvZihhcmd1bWVudHNbYXhdKT09J3N0cmluZycpDQogICAgICAgIHsNCiAgICAgICAgICAgIGdyZXAgPSBhcmd1bWVudHNbYXhdOw0KICAgICAgICB9DQogICAgICAgIGlmKHR5cGVvZihhcmd1bWVudHNbYXhdKT09J29iamVjdCcpDQogICAgICAgIHsNCiAgICAgICAgICAgIG9wdGlvbnMgPSBhcmd1bWVudHNbYXhdOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgaWYgKGdyZXApIHsgZ3JlcCA9ICcgfCBncmVwICInICsgZ3JlcCArICciJzsgfSBlbHNlIHsgZ3JlcCA9ICcnOyB9DQogICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddLCBvcHRpb25zKTsNCiAgICBjaGlsZC5zdGRlcnIuc3RyID0gJyc7IGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOyBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCdkYnVzLXNlbmQgLS1zZXNzaW9uIC0tZGVzdD1vcmcuZnJlZWRlc2t0b3AuREJ1cyAtLXR5cGU9bWV0aG9kX2NhbGwgLS1wcmludC1yZXBseSAvb3JnL2ZyZWVkZXNrdG9wL0RCdXMgb3JnLmZyZWVkZXNrdG9wLkRCdXMuTGlzdE5hbWVzJyArIGdyZXAgKyAnXG5leGl0XG4nKTsNCiAgICBjaGlsZC53YWl0RXhpdCgpOw0KDQogICAgdmFyIHJldCA9IFtdOw0KICAgIHZhciBpLCB0bXA7DQogICAgdmFyIHRva2VucyA9IGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpLnNwbGl0KCdcbicpOw0KICAgIGZvciAoaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyArK2kpDQogICAgew0KICAgICAgICBpZiAoKHRtcCA9IHRva2Vuc1tpXS50cmltKCkpLnN0YXJ0c1dpdGgoJ2FycmF5ICcpKQ0KICAgICAgICB7DQogICAgICAgICAgICBmb3IgKGkgPSBpICsgMTsgaSA8IHRva2Vucy5sZW5ndGg7ICsraSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB0bXAgPSB0b2tlbnNbaV0udHJpbSgpOw0KICAgICAgICAgICAgICAgIGlmICh0bXAuc3RhcnRzV2l0aCgnc3RyaW5nICcpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0LnB1c2goSlNPTi5wYXJzZSh0bXAuc3BsaXQoJyAnKVsxXSkpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBlbHNlIGlmKHRtcC5zdGFydHNXaXRoKCdzdHJpbmcgJykpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldC5wdXNoKEpTT04ucGFyc2UodG1wLnNwbGl0KCcgJylbMV0pKTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gKHJldCk7DQp9DQo=', 'base64').toString());"); - duk_peval_string_noresult(ctx, "addModule('linux-gnome-helpers', Buffer.from('DQoNCmZ1bmN0aW9uIGdub21lX2dldFByb3h5U2V0dGluZ3ModWlkKQ0Kew0KICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSwgeyBlbnY6IHsgSE9NRTogcmVxdWlyZSgndXNlci1zZXNzaW9ucycpLmdldEhvbWVGb2xkZXIodWlkKSB9fSk7DQogICAgY2hpbGQuc3RkZXJyLnN0ciA9ICcnOyBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB9KTsNCiAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQoNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnZ3NldHRpbmdzIGxpc3QtcmVjdXJzaXZlbHkgb3JnLmdub21lLnN5c3RlbS5wcm94eSB8IHRyICJcXG4iICJcXHwiIHwgdHIgIlxcXCciICJcXGAiIHwgYXdrIFwneyBjb3VudD1zcGxpdCgkMCwgcmVzLCAifCIpOycpDQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ2V4Yz0iW10iOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCdmb3IoYT0wO2E8Y291bnQ7KythKScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCd7Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ3NwbGl0KHJlc1thXSwgbW9kZWNoZWNrLCAiICIpOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCdpZihtb2RlY2hlY2tbMl0gPT0gIm1vZGUiKScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCd7Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ3NwbGl0KG1vZGVjaGVja1szXSwgcHJ4LCAiYCIpOyBtb2RlID0gcHJ4WzJdOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCd9Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ2lmKG1vZGVjaGVja1sxXT09Im9yZy5nbm9tZS5zeXN0ZW0ucHJveHkuaHR0cCIgJiYgbW9kZWNoZWNrWzJdPT0iaG9zdCIpIHsgc3BsaXQobW9kZWNoZWNrWzNdLCBoc3QsICJgIik7IGhvc3QgPSBoc3RbMl07IH0nKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnaWYobW9kZWNoZWNrWzFdPT0ib3JnLmdub21lLnN5c3RlbS5wcm94eS5odHRwIiAmJiBtb2RlY2hlY2tbMl09PSJwb3J0IikgeyBwb3J0ID0gbW9kZWNoZWNrWzNdOyB9Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ2lmKG1vZGVjaGVja1sxXT09Im9yZy5nbm9tZS5zeXN0ZW0ucHJveHkiICYmIG1vZGVjaGVja1syXT09Imlnbm9yZS1ob3N0cyIpIHsgZXhjID0gc3Vic3RyKHJlc1thXSwgMzYpOyBnc3ViKCJgIiwgIlxcIiIsIGV4Yyk7IH0nKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnfScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCdwcmludGYgIntcXCJtb2RlXFwiOiBcXCIlc1xcIiwgXFwiaG9zdFxcIjogXFwiJXNcXCIsIFxcInBvcnRcXCI6ICVzLCBcXCJleGNlcHRpb25zXFwiOiAlc30iLCBtb2RlLCBob3N0LCBwb3J0LCBleGM7IH1cJ1xuZXhpdFxuJyk7DQogICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICB0cnkNCiAgICB7DQogICAgICAgIHJldHVybiAoSlNPTi5wYXJzZShjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSkpOw0KICAgIH0NCiAgICBjYXRjaChlKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuICh7fSk7DQogICAgfQ0KfQ0KDQpmdW5jdGlvbiBnbm9tZV9nZXREZXNrdG9wV2FsbHBhcGVyKHVpZCkNCnsNCiAgICB2YXIgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10sIHsgZW52OiB7IEhPTUU6IHJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5nZXRIb21lRm9sZGVyKHVpZCkgfSB9KTsNCiAgICBjaGlsZC5zdGRlcnIuc3RyID0gJyc7IGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IH0pOw0KICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnZ3NldHRpbmdzIGdldCBvcmcuZ25vbWUuZGVza3RvcC5iYWNrZ3JvdW5kIHBpY3R1cmUtdXJpXG5leGl0XG4nKTsNCiAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgIGNoaWxkLnN0ZG91dC5zdHIgPSBjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKS5zcGxpdCgnZmlsZTovLycpLnBvcCgpOw0KICAgIGlmIChjaGlsZC5zdGRvdXQuc3RyLmVuZHNXaXRoKCciJykgfHwgY2hpbGQuc3Rkb3V0LnN0ci5lbmRzV2l0aCgiJyIpKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnN1YnN0cmluZygwLCBjaGlsZC5zdGRvdXQuc3RyLmxlbmd0aCAtIDEpKTsNCiAgICB9DQogICAgZWxzZQ0KICAgIHsNCiAgICAgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyKTsNCiAgICB9DQp9DQoNCmZ1bmN0aW9uIGdub21lX3NldERlc2t0b3BXYWxscGFwZXIodWlkLCBmaWxlUGF0aCkNCnsNCiAgICBpZiAoIWZpbGVQYXRoKSB7IGZpbGVQYXRoID0gJy9kZXYvbnVsbCc7IH0NCg0KICAgIHZhciB2ID0geyBIT01FOiByZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuZ2V0SG9tZUZvbGRlcih1aWQpIH07DQogICAgdmFyIHBpZHMgPSByZXF1aXJlKCdwcm9jZXNzLW1hbmFnZXInKS5nZXRQcm9jZXNzKCdnbm9tZS1zZXNzaW9uJyk7DQogICAgZm9yICh2YXIgaSBpbiBwaWRzKQ0KICAgIHsNCiAgICAgICAgdmFyIGUgPSByZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuZ2V0RW52RnJvbVBpZChwaWRzW2ldKTsNCiAgICAgICAgaWYgKGUuVVNFUiAmJiByZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuZ2V0VWlkKGUuVVNFUikhPXVpZCkNCiAgICAgICAgew0KICAgICAgICAgICAgY29udGludWU7DQogICAgICAgIH0NCiAgICAgICAgdi5EQlVTX1NFU1NJT05fQlVTX0FERFJFU1MgPSBlLkRCVVNfU0VTU0lPTl9CVVNfQUREUkVTUzsNCiAgICAgICAgaWYgKHYuREJVU19TRVNTSU9OX0JVU19BRERSRVNTKSB7IGJyZWFrOyB9DQogICAgfQ0KDQogICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddLCB7IHVpZDogdWlkLCBlbnY6IHYgfSk7DQogICAgY2hpbGQuc3RkZXJyLnN0ciA9ICcnOyBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnZ3NldHRpbmdzIHNldCBvcmcuZ25vbWUuZGVza3RvcC5iYWNrZ3JvdW5kIHBpY3R1cmUtdXJpIGZpbGU6Ly8nICsgZmlsZVBhdGggKyAnXG5leGl0XG4nKTsNCiAgICBjaGlsZC53YWl0RXhpdCgpOw0KfQ0KDQpzd2l0Y2gocHJvY2Vzcy5wbGF0Zm9ybSkNCnsNCiAgICBjYXNlICdsaW51eCc6DQogICAgICAgIG1vZHVsZS5leHBvcnRzID0NCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBnZXRQcm94eVNldHRpbmdzOiBnbm9tZV9nZXRQcm94eVNldHRpbmdzLA0KICAgICAgICAgICAgICAgIGdldERlc2t0b3BXYWxscGFwZXI6IGdub21lX2dldERlc2t0b3BXYWxscGFwZXIsDQogICAgICAgICAgICAgICAgc2V0RGVza3RvcFdhbGxwYXBlcjogZ25vbWVfc2V0RGVza3RvcFdhbGxwYXBlcg0KICAgICAgICAgICAgfTsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnX2xvY2F0aW9uJywgew0KICAgICAgICAgICAgdmFsdWU6IChmdW5jdGlvbiAoKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgICAgICAgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOw0KICAgICAgICAgICAgICAgIGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykgeyB0aGlzLnN0ciArPSBjaHVuay50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgid2hlcmVpcyBnc2V0dGluZ3MgfCBhd2sgJ3sgcHJpbnQgJDIgfSdcbmV4aXRcbiIpOw0KICAgICAgICAgICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgICAgICAgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSk7DQogICAgICAgICAgICB9KSgpDQogICAgICAgIH0pOw0KICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLmV4cG9ydHMsICdhdmFpbGFibGUnLCB7IGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMuX2xvY2F0aW9uICE9ICcnID8gdHJ1ZSA6IGZhbHNlKTsgfSB9KTsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnc2NyaXB0VmVyc2lvbicsDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFsdWU6IChmdW5jdGlvbigpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICB2YXIgcmV0ID0geyBtYWpvcjogMCwgbWlub3I6IDAgfTsNCiAgICAgICAgICAgICAgICAgICAgaWYocmVxdWlyZSgnZnMnKS5leGlzdHNTeW5jKCcvdXNyL2Jpbi9zY3JpcHQnKSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uICgpIHsgfSk7DQogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnc2NyaXB0IC1WIHwgYXdrIFwneyBzcGxpdCgkTkYsIFQsICIuIik7IHByaW50ZiAie1xcIm1ham9yXFwiOiVzLCBcXCJtaW5vclxcIjolc30iLFRbMV0sVFsyXTsgfVwnXG5leGl0XG4nKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgICAgICAgICAgICAgICAgICB0cnkNCiAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBKU09OLnBhcnNlKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoICh4KQ0KICAgICAgICAgICAgICAgICAgICAgICAgeyB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChyZXQpOw0KICAgICAgICAgICAgICAgIH0pKCkNCiAgICAgICAgICAgIH0pOw0KICAgICAgICBicmVhazsNCn0=', 'base64').toString());"); + duk_peval_string_noresult(ctx, "addModule('linux-gnome-helpers', Buffer.from('DQoNCmZ1bmN0aW9uIGdub21lX2dldFByb3h5U2V0dGluZ3ModWlkKQ0Kew0KICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSwgeyBlbnY6IHsgSE9NRTogcmVxdWlyZSgndXNlci1zZXNzaW9ucycpLmdldEhvbWVGb2xkZXIodWlkKSB9fSk7DQogICAgY2hpbGQuc3RkZXJyLnN0ciA9ICcnOyBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB9KTsNCiAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQoNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnZ3NldHRpbmdzIGxpc3QtcmVjdXJzaXZlbHkgb3JnLmdub21lLnN5c3RlbS5wcm94eSB8IHRyICJcXG4iICJcXHwiIHwgYXdrIFwnJyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ3snKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgY291bnQ9c3BsaXQoJDAsIHJlcywgInwiKTsnKQ0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICBleGM9IltdIjsgYXV0aD0iIjsgcHdkPSIiOyB1c2VybmFtZT0iIjsgZW5hYmxlZD0iIjsnKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgZm9yKGE9MDthPGNvdW50OysrYSknKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgeycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBzcGxpdChyZXNbYV0sIG1vZGVjaGVjaywgIiAiKTsnKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgaWYobW9kZWNoZWNrWzJdID09ICJtb2RlIiknKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgeycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBzcGxpdChtb2RlY2hlY2tbM10sIHByeCwgIlxcMDQ3Iik7IG1vZGUgPSBwcnhbMl07Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIH0nKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgaWYobW9kZWNoZWNrWzFdPT0ib3JnLmdub21lLnN5c3RlbS5wcm94eS5odHRwIiAmJiBtb2RlY2hlY2tbMl09PSJob3N0IikgeyBzcGxpdChtb2RlY2hlY2tbM10sIGhzdCwgIlxcMDQ3Iik7IGhvc3QgPSBoc3RbMl07IH0nKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgaWYobW9kZWNoZWNrWzFdPT0ib3JnLmdub21lLnN5c3RlbS5wcm94eS5odHRwIiAmJiBtb2RlY2hlY2tbMl09PSJwb3J0IikgeyBwb3J0ID0gbW9kZWNoZWNrWzNdOyB9Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIGlmKG1vZGVjaGVja1sxXT09Im9yZy5nbm9tZS5zeXN0ZW0ucHJveHkuaHR0cCIgJiYgbW9kZWNoZWNrWzJdPT0idXNlLWF1dGhlbnRpY2F0aW9uIikgeyBhdXRoPW1vZGVjaGVja1szXTsgfScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBpZihtb2RlY2hlY2tbMV09PSJvcmcuZ25vbWUuc3lzdGVtLnByb3h5IiAmJiBtb2RlY2hlY2tbMl09PSJpZ25vcmUtaG9zdHMiKSB7IGV4YyA9IHN1YnN0cihyZXNbYV0sIDM2KTsgZ3N1YigiXFwwNDciLCAiXFwiIiwgZXhjKTsgfScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBpZihtb2RlY2hlY2tbMV09PSJvcmcuZ25vbWUuc3lzdGVtLnByb3h5Lmh0dHAiICYmIG1vZGVjaGVja1syXT09ImVuYWJsZWQiKSB7IGVuYWJsZWQgPSBtb2RlY2hlY2tbM107IH0nKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgaWYobW9kZWNoZWNrWzFdPT0ib3JnLmdub21lLnN5c3RlbS5wcm94eS5odHRwIiAmJiBtb2RlY2hlY2tbMl09PSJhdXRoZW50aWNhdGlvbi11c2VyIiknKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgeycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgc3BsaXQocmVzW2FdLGR1bW15LCJcXDA0NyIpOyB1c2VybmFtZT1kdW1teVsyXTsnKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgfScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBpZihtb2RlY2hlY2tbMV09PSJvcmcuZ25vbWUuc3lzdGVtLnByb3h5Lmh0dHAiICYmIG1vZGVjaGVja1syXT09ImF1dGhlbnRpY2F0aW9uLXBhc3N3b3JkIiknKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgeycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgcHdkPXN1YnN0cihyZXNbYV0sNTMpOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICB9Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIH0nKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgaWYocHdkfi9eXFwwNDcvKSB7IGdzdWIoIlxcIiIsICJcXFxcXFwiIiwgcHdkKTsgZ3N1YigiXFwwNDciLCAiXFwiIiwgcHdkKTsgfScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICBwcmludGYgIntcXCJtb2RlXFwiOiBcXCIlc1xcIiwgXFwiZW5hYmxlZFxcIjogJXMsIFxcImhvc3RcXCI6IFxcIiVzXFwiLCBcXCJwb3J0XFwiOiAlcywgXFwiYXV0aEVuYWJsZWRcXCI6ICVzLCBcXCJ1c2VybmFtZVxcIjogXFwiJXNcXCIsIFxcInBhc3N3b3JkXFwiOiAlcywgXFwiZXhjZXB0aW9uc1xcIjogJXN9IiwgbW9kZSwgZW5hYmxlZCwgaG9zdCwgcG9ydCwgYXV0aCwgdXNlcm5hbWUsIHB3ZCwgZXhjOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCJ9J1xuZXhpdFxuIik7DQogICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICB0cnkNCiAgICB7DQogICAgICAgIHJldHVybiAoSlNPTi5wYXJzZShjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSkpOw0KICAgIH0NCiAgICBjYXRjaChlKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuICh7fSk7DQogICAgfQ0KfQ0KDQpmdW5jdGlvbiBnbm9tZV9nZXREZXNrdG9wV2FsbHBhcGVyKHVpZCkNCnsNCiAgICB2YXIgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10sIHsgZW52OiB7IEhPTUU6IHJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5nZXRIb21lRm9sZGVyKHVpZCkgfSB9KTsNCiAgICBjaGlsZC5zdGRlcnIuc3RyID0gJyc7IGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IH0pOw0KICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnZ3NldHRpbmdzIGdldCBvcmcuZ25vbWUuZGVza3RvcC5iYWNrZ3JvdW5kIHBpY3R1cmUtdXJpXG5leGl0XG4nKTsNCiAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgIGNoaWxkLnN0ZG91dC5zdHIgPSBjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKS5zcGxpdCgnZmlsZTovLycpLnBvcCgpOw0KICAgIGlmIChjaGlsZC5zdGRvdXQuc3RyLmVuZHNXaXRoKCciJykgfHwgY2hpbGQuc3Rkb3V0LnN0ci5lbmRzV2l0aCgiJyIpKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnN1YnN0cmluZygwLCBjaGlsZC5zdGRvdXQuc3RyLmxlbmd0aCAtIDEpKTsNCiAgICB9DQogICAgZWxzZQ0KICAgIHsNCiAgICAgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyKTsNCiAgICB9DQp9DQoNCmZ1bmN0aW9uIGdub21lX3NldERlc2t0b3BXYWxscGFwZXIodWlkLCBmaWxlUGF0aCkNCnsNCiAgICBpZiAoIWZpbGVQYXRoKSB7IGZpbGVQYXRoID0gJy9kZXYvbnVsbCc7IH0NCg0KICAgIHZhciB2ID0geyBIT01FOiByZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuZ2V0SG9tZUZvbGRlcih1aWQpIH07DQogICAgdmFyIHBpZHMgPSByZXF1aXJlKCdwcm9jZXNzLW1hbmFnZXInKS5nZXRQcm9jZXNzKCdnbm9tZS1zZXNzaW9uJyk7DQogICAgZm9yICh2YXIgaSBpbiBwaWRzKQ0KICAgIHsNCiAgICAgICAgdmFyIGUgPSByZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuZ2V0RW52RnJvbVBpZChwaWRzW2ldKTsNCiAgICAgICAgaWYgKGUuVVNFUiAmJiByZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuZ2V0VWlkKGUuVVNFUikhPXVpZCkNCiAgICAgICAgew0KICAgICAgICAgICAgY29udGludWU7DQogICAgICAgIH0NCiAgICAgICAgdi5EQlVTX1NFU1NJT05fQlVTX0FERFJFU1MgPSBlLkRCVVNfU0VTU0lPTl9CVVNfQUREUkVTUzsNCiAgICAgICAgaWYgKHYuREJVU19TRVNTSU9OX0JVU19BRERSRVNTKSB7IGJyZWFrOyB9DQogICAgfQ0KDQogICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddLCB7IHVpZDogdWlkLCBlbnY6IHYgfSk7DQogICAgY2hpbGQuc3RkZXJyLnN0ciA9ICcnOyBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnZ3NldHRpbmdzIHNldCBvcmcuZ25vbWUuZGVza3RvcC5iYWNrZ3JvdW5kIHBpY3R1cmUtdXJpIGZpbGU6Ly8nICsgZmlsZVBhdGggKyAnXG5leGl0XG4nKTsNCiAgICBjaGlsZC53YWl0RXhpdCgpOw0KfQ0KDQpzd2l0Y2gocHJvY2Vzcy5wbGF0Zm9ybSkNCnsNCiAgICBjYXNlICdsaW51eCc6DQogICAgICAgIG1vZHVsZS5leHBvcnRzID0NCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBnZXRQcm94eVNldHRpbmdzOiBnbm9tZV9nZXRQcm94eVNldHRpbmdzLA0KICAgICAgICAgICAgICAgIGdldERlc2t0b3BXYWxscGFwZXI6IGdub21lX2dldERlc2t0b3BXYWxscGFwZXIsDQogICAgICAgICAgICAgICAgc2V0RGVza3RvcFdhbGxwYXBlcjogZ25vbWVfc2V0RGVza3RvcFdhbGxwYXBlcg0KICAgICAgICAgICAgfTsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnX2xvY2F0aW9uJywgew0KICAgICAgICAgICAgdmFsdWU6IChmdW5jdGlvbiAoKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgICAgICAgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOw0KICAgICAgICAgICAgICAgIGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykgeyB0aGlzLnN0ciArPSBjaHVuay50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgid2hlcmVpcyBnc2V0dGluZ3MgfCBhd2sgJ3sgcHJpbnQgJDIgfSdcbmV4aXRcbiIpOw0KICAgICAgICAgICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgICAgICAgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSk7DQogICAgICAgICAgICB9KSgpDQogICAgICAgIH0pOw0KICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLmV4cG9ydHMsICdhdmFpbGFibGUnLCB7IGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMuX2xvY2F0aW9uICE9ICcnID8gdHJ1ZSA6IGZhbHNlKTsgfSB9KTsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnc2NyaXB0VmVyc2lvbicsDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFsdWU6IChmdW5jdGlvbigpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICB2YXIgcmV0ID0geyBtYWpvcjogMCwgbWlub3I6IDAgfTsNCiAgICAgICAgICAgICAgICAgICAgaWYocmVxdWlyZSgnZnMnKS5leGlzdHNTeW5jKCcvdXNyL2Jpbi9zY3JpcHQnKSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uICgpIHsgfSk7DQogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnc2NyaXB0IC1WIHwgYXdrIFwneyBzcGxpdCgkTkYsIFQsICIuIik7IHByaW50ZiAie1xcIm1ham9yXFwiOiVzLCBcXCJtaW5vclxcIjolc30iLFRbMV0sVFsyXTsgfVwnXG5leGl0XG4nKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgICAgICAgICAgICAgICAgICB0cnkNCiAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBKU09OLnBhcnNlKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoICh4KQ0KICAgICAgICAgICAgICAgICAgICAgICAgeyB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChyZXQpOw0KICAgICAgICAgICAgICAgIH0pKCkNCiAgICAgICAgICAgIH0pOw0KICAgICAgICBicmVhazsNCn0=', 'base64').toString());"); duk_peval_string_noresult(ctx, "addModule('linux-cpuflags', Buffer.from('LyoKQ29weXJpZ2h0IDIwMTkgSW50ZWwgQ29ycG9yYXRpb24KCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwp5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQpkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLApXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZApsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKi8NCg0KdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCmNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCmNoaWxkLnN0ZGluLndyaXRlKCJjYXQgL3Byb2MvY3B1aW5mbyB8IGdyZXAgZmxhZ3MgfCB0ciAnXFxuJyAnficgfCBhd2sgLUZ+ICd7IHByaW50ZiAiICsgJyJbIjsgZm9yKGk9MTtpPD1ORi0xOysraSkgeyBzcGxpdCgkaSwgbGluZSwgIjoiKTsgeD1zcGxpdChsaW5lWzJdLCB2YWxzLCAiICIpOyBwcmludGYgIiVzeyIsIChpIT0xPyIsIjoiIik7IGZvcihqPTE7ajw9eDsrK2opIHsgcHJpbnRmICIlc1xcIiVzXFwiOiAxIiwgKGohPTE/IiwiOiIiKSwgdmFsc1tqXTsgIH0gcHJpbnRmICJ9IjsgIH0gcHJpbnRmICJdIjsgfVwnXG5leGl0XG4nKTsNCmNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IH0pOw0KY2hpbGQud2FpdEV4aXQoKTsNCg0KaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ2xpbnV4JykNCnsNCiAgICB0cnkNCiAgICB7DQogICAgICAgIG1vZHVsZS5leHBvcnRzID0gSlNPTi5wYXJzZShjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSk7DQogICAgfQ0KICAgIGNhdGNoICh4KQ0KICAgIHsNCiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBudWxsOw0KICAgIH0NCn0NCmVsc2UNCnsNCiAgICBtb2R1bGUuZXhwb3J0cyA9IG51bGw7DQp9DQoNCv==', 'base64').toString());"); duk_peval_string_noresult(ctx, "addModule('linux-acpi', Buffer.from('LyoNCkNvcHlyaWdodCAyMDIwIEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQoNCmZ1bmN0aW9uIGxpbnV4X2FjcGkoKQ0Kew0KICAgIHRoaXMuX09iamVjdElEID0gJ2xpbnV4LWFjcGknOw0KICAgIHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlci5jYWxsKHRoaXMsIHRydWUpDQogICAgICAgIC5jcmVhdGVFdmVudCgnYWNwaScpOw0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAic3VwcG9ydGVkIiwgeyB2YWx1ZTogcmVxdWlyZSgnZnMnKS5leGlzdHNTeW5jKCcvdmFyL3J1bi9hY3BpZC5zb2NrZXQnKSB9KTsNCiAgICBpZih0aGlzLnN1cHBvcnRlZCkNCiAgICB7DQogICAgICAgIHRoaXMuX2NsaWVudCA9IHJlcXVpcmUoJ25ldCcpLmNyZWF0ZUNvbm5lY3Rpb24oeyBwYXRoOiAnL3Zhci9ydW4vYWNwaWQuc29ja2V0JywgbWV0YWRhdGE6ICdsaW51eC1hY3BpJyB9LCBmdW5jdGlvbiAoKQ0KICAgICAgICB7DQogICAgICAgICAgICB0aGlzLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBibG9ja3M7DQogICAgICAgICAgICAgICAgdmFyIHVidWZmZXIgPSBudWxsOw0KICAgICAgICAgICAgICAgIHZhciB0b2tlbnMgPSBjaHVuay50b1N0cmluZygpLnNwbGl0KCdcbicpOw0KICAgICAgICAgICAgICAgIGlmICh0b2tlbnMubGVuZ3RoID09IDEpIHsgdGhpcy51bnNoaWZ0KGNodW5rKTsgfQ0KICAgICAgICAgICAgICAgIGlmICh0b2tlbnMucGVlaygpICE9ICcnKSB7IHVidWZmZXIgPSBCdWZmZXIuZnJvbSh0b2tlbnMucG9wKCkpOyB9DQogICAgICAgICAgICAgICAgZWxzZSB7IHRva2Vucy5wb3AoKTsgfQ0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gdG9rZW5zKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgYmxvY2tzID0gdG9rZW5zW2ldLnNwbGl0KCcgJyk7DQogICAgICAgICAgICAgICAgICAgIHRoaXMucmV0LmVtaXQoJ2FjcGknLCB7IG5hbWU6IGJsb2Nrc1swXSwgdHlwZTogQnVmZmVyLmZyb20oYmxvY2tzWzJdLCAnaGV4JykucmVhZFVJbnQzMkJFKCksIHZhbHVlOiBCdWZmZXIuZnJvbShibG9ja3NbM10sICdoZXgnKS5yZWFkVUludDMyQkUoKSB9KTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSk7DQogICAgICAgIHRoaXMuX2NsaWVudC5yZXQgPSB0aGlzOw0KICAgIH0NCn0NCg0KbW9kdWxlLmV4cG9ydHMgPSBuZXcgbGludXhfYWNwaSgpOw==', 'base64').toString());"); #endif @@ -2245,7 +2245,13 @@ void ILibDuktape_Polyfills_JS_Init(duk_context *ctx) free(_notifybardesktop); // proxy-helper, refer to modules/proxy-helper.js - duk_peval_string_noresult(ctx, "addModule('proxy-helper', Buffer.from('LyoNCkNvcHlyaWdodCAyMDE5IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQoNCmZ1bmN0aW9uIGxpbnV4X2dldFByb3h5KCkNCnsNCiAgICAvLyBDaGVjayBFbnZpcm9ubWVudCBWYXJpYWJlbHMNCiAgICBpZihyZXF1aXJlKCdmcycpLmV4aXN0c1N5bmMoJy9ldGMvZW52aXJvbm1lbnQnKSkNCiAgICB7DQoJICAgIHZhciBlID0gcmVxdWlyZSgnZnMnKS5yZWFkRmlsZVN5bmMoJy9ldGMvZW52aXJvbm1lbnQnKS50b1N0cmluZygpOw0KCSAgICB2YXIgdG9rZW5zID0gZS5zcGxpdCgnXFxuJyk7DQoJICAgIGZvcih2YXIgbGluZSBpbiB0b2tlbnMpDQoJICAgIHsNCgkJICAgIHZhciB2YWwgPSB0b2tlbnNbbGluZV0uc3BsaXQoJz0nKTsNCgkJICAgIGlmKHZhbC5sZW5ndGggPT0gMiAmJiAodmFsWzBdLnRyaW0oKSA9PSAnaHR0cF9wcm94eScgfHwgdmFsWzBdLnRyaW0oKSA9PSAnaHR0cHNfcHJveHknKSkNCgkJICAgIHsNCgkJCSAgICByZXR1cm4odmFsWzFdLnNwbGl0KCcvLycpWzFdKTsNCgkJICAgIH0NCgkgICAgfQ0KICAgIH0NCg0KICAgIC8vIENoZWNrIHByb2ZpbGUuZA0KICAgIGlmKHJlcXVpcmUoJ2ZzJykuZXhpc3RzU3luYygnL2V0Yy9wcm9maWxlLmQvcHJveHlfc2V0dXAnKSkNCiAgICB7DQoJICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQoJICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCgkgICAgY2hpbGQuc3RkaW4ud3JpdGUoImNhdCAvZXRjL3Byb2ZpbGUuZC9wcm94eV9zZXR1cCB8IGF3ayAnIiArICd7IHNwbGl0KCQyLCB0b2ssICI9Iik7IGlmKHRva1sxXT09Imh0dHBfcHJveHkiKSB7IHByaW50IHRva1syXTsgfX1cJ1xuZXhpdFxuJyk7DQoJICAgIGNoaWxkLndhaXRFeGl0KCk7DQoJICAgIGNoaWxkLnJldCA9IGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpLnNwbGl0KCdcbicpWzBdLnNwbGl0KCcvLycpWzFdOw0KCSAgICBpZihjaGlsZC5yZXQgIT0gJycpIHsgcmV0dXJuKGNoaWxkLnJldCk7IH0NCiAgICB9DQoNCiAgICAvLyBDaGVjayBnc2V0dGluZ3MNCiAgICBpZiAocmVxdWlyZSgnZnMnKS5leGlzdHNTeW5jKCcvdXNyL2Jpbi9nc2V0dGluZ3MnKSkNCiAgICB7DQoJICAgIHZhciBzZXR0aW5nOw0KCSAgICB2YXIgaWRzID0gcmVxdWlyZSgndXNlci1zZXNzaW9ucycpLmxvZ2luVWlkcygpOyANCgkgICAgZm9yICh2YXIgaSBpbiBpZHMpDQoJICAgIHsNCgkJICAgIHNldHRpbmcgPSByZXF1aXJlKCdsaW51eC1nbm9tZS1oZWxwZXJzJykuZ2V0UHJveHlTZXR0aW5ncyhpZHNbaV0pOw0KCQkgICAgaWYgKHNldHRpbmcubW9kZSA9PSAnbWFudWFsJykgeyByZXR1cm4oc2V0dGluZy5ob3N0ICsgJzonICsgc2V0dGluZy5wb3J0KTt9IA0KCSAgICB9DQogICAgfQ0KDQogICAgaWYgKHJlcXVpcmUoJ2ZzJykuZXhpc3RzU3luYygnL2V0Yy9hcHQvYXB0LmNvbmYuZC9wcm94eS5jb25mJykpDQogICAgew0KICAgICAgICB2YXIgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgIGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IGNvbnNvbGUubG9nKGMudG9TdHJpbmcoKSk7IH0pOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgiY2F0IC9ldGMvYXB0L2FwdC5jb25mLmQvcHJveHkuY29uZiB8IHRyICdcXG4nICdgJyB8IGF3ayAtRidgJyAneyIpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnZm9yKG49MTtuPE5GOysrbikgeyBsbj1zcGxpdCgkbix0b2ssIjo6Iik7IHNwbGl0KHRva1tsbl0scHgsIlxcIiIpOyBzcGxpdChweFsyXSx4LCI6Ly8iKTsgaWYoeFsyXSE9IiIpIHsgcHJpbnQgeFsyXTsgYnJlYWs7IH0gfScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgifSdcbmV4aXRcbiIpOw0KICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgICAgICBpZiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkgIT0gIiIpIHsgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSk7IH0NCiAgICB9DQogICAgaWYgKHJlcXVpcmUoJ2ZzJykuZXhpc3RzU3luYygnL2V0Yy95dW0uY29uZicpKQ0KICAgIHsNCiAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOyBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyBjb25zb2xlLmxvZyhjLnRvU3RyaW5nKCkpOyB9KTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ2NhdCAvZXRjL3l1bS5jb25mIHwgZ3JlcCAicHJveHk9IiB8ICcgKyAidHIgJ1xcbicgJ2AnIHwgYXdrIC1GJ2AnICd7Iik7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCdmb3Iobj0xO248TkY7KytuKSB7IGNsPXNwbGl0KCRuLGMsIiMiKTsgc3BsaXQoJG4scHgsIjovLyIpOyBpZihweFsyXSE9IiIgJiYgY2w9PTEpIHsgcHJpbnQgcHhbMl07IGJyZWFrOyB9IH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoIn0nXG5leGl0XG4iKTsNCiAgICAgICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICAgICAgaWYgKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpICE9ICIiKSB7IHJldHVybiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkpOyB9DQogICAgfQ0KICAgIGlmIChyZXF1aXJlKCdmcycpLmV4aXN0c1N5bmMoJy9ldGMvc3lzY29uZmlnL3Byb3h5JykpDQogICAgew0KICAgICAgICB2YXIgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgIGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IGNvbnNvbGUubG9nKGMudG9TdHJpbmcoKSk7IH0pOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnY2F0IC9ldGMvc3lzY29uZmlnL3Byb3h5IHwgZ3JlcCBQUk9YWV9FTkFCTEVEPSB8IGF3ayBcJ3snKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ3NwbGl0KCQwLHJlcywiXFwiIik7IGlmKHJlc1syXT09InllcyIpIHsgcHJpbnQgcmVzWzJdOyB9JykNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoIn0nXG5leGl0XG4iKTsNCiAgICAgICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICAgICAgaWYgKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpICE9ICIiKQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyBFbmFibGVkDQogICAgICAgICAgICBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyBjb25zb2xlLmxvZyhjLnRvU3RyaW5nKCkpOyB9KTsNCiAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCdjYXQgL2V0Yy9zeXNjb25maWcvcHJveHkgfCBncmVwIF9QUk9YWSB8ICcgKyAidHIgJ1xcbicgJ2AnIHwgYXdrIC1GJ2AnICd7Iik7DQogICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnZm9yKGk9MTtpPE5GOysraSkgeyBpZihzcGxpdCgkaSxyLCJIVFRQX1BST1hZPSIpPjEgfHwgc3BsaXQoJGksciwiSFRUUFNfUFJPWFk9Iik+MSkgeycpOw0KICAgICAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ2NsPXNwbGl0KCRpLGMsIiMiKTsnKTsNCiAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCdzcGxpdCgkaSxweCwiXFwiIik7IHNwbGl0KHB4WzJdLHB4eCwiOi8vIik7IGlmKHB4eFsyXSE9IiIgJiYgY2w9PTEpIHsgcHJpbnQgcHh4WzJdOyBicmVhazsgfScpOw0KICAgICAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ30gfScpOw0KICAgICAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoIn0nXG5leGl0XG4iKTsNCiAgICAgICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgICAgICBpZiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkgIT0gJycpIHsgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSk7IH0NCiAgICAgICAgfQ0KICAgIH0NCiAgICB0aHJvdyAoJ05vIHByb3hpZXMnKTsNCn0NCmZ1bmN0aW9uIHBvc2l4X3Byb3h5Q2hlY2sodWlkLCBjaGVja0FkZHIpDQp7DQogICAgdmFyIGc7DQogICAgdmFyIHggPSBwcm9jZXNzLmVudlsnbm9fcHJveHknXSA/IHByb2Nlc3MuZW52Wydub19wcm94eSddLnNwbGl0KCcsJykgOiBbXTsNCiAgICB2YXIgdDsNCg0KICAgIGlmIChyZXF1aXJlKCdsaW51eC1nbm9tZS1oZWxwZXJzJykuYXZhaWxhYmxlICYmIChnID0gcmVxdWlyZSgnbGludXgtZ25vbWUtaGVscGVycycpLmdldFByb3h5U2V0dGluZ3ModWlkKSkubW9kZSAhPSAnbm9uZScpDQogICAgew0KICAgICAgICB4ID0gZy5leGNlcHRpb25zOw0KICAgIH0NCg0KICAgIGZvcih2YXIgaSBpbiB4KQ0KICAgIHsNCiAgICAgICAgaWYgKHhbaV0gPT0gY2hlY2tBZGRyKSB7IHJldHVybiAodHJ1ZSk7IH0gICAgICAgICAgICAgICAvLyBEaXJlY3QgTWF0Y2gNCiAgICAgICAgaWYgKGNoZWNrQWRkci5lbmRzV2l0aCgnLicgKyB4W2ldKSkgeyByZXR1cm4gKHRydWUpOyB9ICAvLyBTdWJkb21haW4gTWF0Y2gNCiAgICAgICAgaWYgKCh2ID0geFtpXS5zcGxpdCgnLycpKS5sZW5ndGggPT0gMikNCiAgICAgICAgew0KICAgICAgICAgICAgdHJ5DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaWYocmVxdWlyZSgnaXAtYWRkcmVzcycpLkFkZHJlc3M0LmZyb21TdHJpbmcodlswXSkubWFzayhwYXJzZUludCh2WzFdKSkgPT0gcmVxdWlyZSgnaXAtYWRkcmVzcycpLkFkZHJlc3M0LmZyb21TdHJpbmcoY2hlY2tBZGRyKS5tYXNrKHBhcnNlSW50KHZbMV0pKSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHJldHVybih0cnVlKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBjYXRjaCAoZXgpDQogICAgICAgICAgICB7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIChmYWxzZSk7DQp9DQoNCmZ1bmN0aW9uIHdpbmRvd3NfcHJveHlDaGVjayhrZXksIGNoZWNrQWRkcikNCnsNCiAgICBpZigha2V5KQ0KICAgIHsNCiAgICAgICAgdmFyIGk7DQogICAgICAgIC8vIEtleSB3YXNuJ3Qgc3BlY2lmaWVkLCBzbyBsZXRzIHRyeSB0byBmaWd1cmUgaXQgb3V0DQogICAgICAgIGlmKChpPXJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5nZXRQcm9jZXNzT3duZXJOYW1lKHByb2Nlc3MucGlkKSkudHNpZCA9PSAwKQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyBXZSBhcmUgYSBzZXJ2aWNlLCBzbyB3ZSBzaG91bGQgY2hlY2sgdGhlIHVzZXIgdGhhdCBpbnN0YWxsZWQgdGhlIE1lc2ggQWdlbnQNCiAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGtleSA9IHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpLlF1ZXJ5S2V5KHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpLkhLRVkuTG9jYWxNYWNoaW5lLCAnU1lTVEVNXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXE1lc2ggQWdlbnQnLCAnX0luc3RhbGxlZEJ5Jyk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBjYXRjaCh4eCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvLyBUaGlzIGluZm8gaXNuJ3QgYXZhaWxhYmxlLCBzbyBsZXQncyB0cnkgdG8gdXNlIHRoZSBjdXJyZW50bHkgbG9nZ2VkIGluIHVzZXINCiAgICAgICAgICAgICAgICB0cnkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIGtleSA9IHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpLnVzZXJuYW1lVG9Vc2VyS2V5KHJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5nZXRVc2VybmFtZShyZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuY29uc29sZVVpZCgpKSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNhdGNoKHh4eCkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIC8vIE5vIHVzZXJzIGFyZSBsb2dnZWQgaW4sIHNvIGFzIGEgbGFzdCByZXNvcnQsIGxldCdzIHRyeSB0aGUgbGFzdCBsb2dnZWQgaW4gdXNlci4NCiAgICAgICAgICAgICAgICAgICAgdmFyIGVudHJpZXMgPSByZXF1aXJlKCd3aW4tcmVnaXN0cnknKS5RdWVyeUtleShyZXF1aXJlKCd3aW4tcmVnaXN0cnknKS5IS0VZLlVzZXJzKTsNCiAgICAgICAgICAgICAgICAgICAgZm9yKGkgaW4gZW50cmllcy5zdWJrZXlzKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZihlbnRyaWVzLnN1YmtleXNbaV0uc3BsaXQoJy0nKS5sZW5ndGg+NSAmJiAhZW50cmllcy5zdWJrZXlzW2ldLmVuZHNXaXRoKCdfQ2xhc3NlcycpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGVudHJpZXMuc3Via2V5c1tpXTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBlbHNlDQogICAgICAgIHsNCiAgICAgICAgICAgIC8vIFdlIGFyZSBhIGxvZ2dlZCBpbiB1c2VyDQogICAgICAgICAgICBrZXkgPSByZXF1aXJlKCd3aW4tcmVnaXN0cnknKS51c2VybmFtZVRvVXNlcktleShpLm5hbWUpOw0KICAgICAgICB9DQogICAgICAgIGlmKCFrZXkpIHt0aHJvdygnQ291bGQgbm90IGRldGVybWluZSB3aGljaCB1c2VyIHByb3h5IHNldHRpbmcgdG8gcXVlcnknKTt9DQogICAgfQ0KICAgIHZhciBwcm94eU92ZXJyaWRlID0gcmVxdWlyZSgnd2luLXJlZ2lzdHJ5JykuUXVlcnlLZXkocmVxdWlyZSgnd2luLXJlZ2lzdHJ5JykuSEtFWS5Vc2Vycywga2V5ICsgJ1xcU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXEludGVybmV0IFNldHRpbmdzJywgJ1Byb3h5T3ZlcnJpZGUnKS5zcGxpdCgnOycpOw0KICAgIGZvcih2YXIgaSBpbiBwcm94eU92ZXJyaWRlKQ0KICAgIHsNCiAgICAgICAgcHJveHlPdmVycmlkZVtpXSA9IHByb3h5T3ZlcnJpZGVbaV0udHJpbSgpOw0KICAgICAgICBpZiAoKGNoZWNrQWRkciA9PSAnMTI3LjAuMC4xJyB8fCBjaGVja0FkZHIgPT0gJzo6MScpICYmIHByb3h5T3ZlcnJpZGVbaV0gPT0gJzxsb2NhbD4nKSB7IHJldHVybiAodHJ1ZSk7IH0NCiAgICAgICAgaWYgKGNoZWNrQWRkciA9PSBwcm94eU92ZXJyaWRlW2ldKSB7IHJldHVybiAodHJ1ZSk7IH0gLy8gRXhhY3QgTWF0Y2gNCiAgICAgICAgaWYgKHByb3h5T3ZlcnJpZGVbaV0uc3RhcnRzV2l0aCgnKi4nKSAmJiBjaGVja0FkZHIuZW5kc1dpdGgocHJveHlPdmVycmlkZVtpXS5zdWJzdHJpbmcoMSkpKSB7IHJldHVybiAodHJ1ZSk7IH0NCiAgICAgICAgaWYgKHByb3h5T3ZlcnJpZGVbaV0uZW5kc1dpdGgoJy4qJykgJiYgY2hlY2tBZGRyLnN0YXJ0c1dpdGgocHJveHlPdmVycmlkZVtpXS5zdWJzdHJpbmcoMCwgcHJveHlPdmVycmlkZVtpXS5sZW5ndGggLSAxKSkpIHsgcmV0dXJuICh0cnVlKTsgfQ0KICAgIH0NCiAgICByZXR1cm4gKGZhbHNlKTsNCn0NCg0Kc3dpdGNoIChwcm9jZXNzLnBsYXRmb3JtKQ0Kew0KICAgIGNhc2UgJ2xpbnV4JzoNCiAgICBjYXNlICdmcmVlYnNkJzoNCiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSB7IGlnbm9yZVByb3h5OiBwb3NpeF9wcm94eUNoZWNrLCBnZXRQcm94eTogbGludXhfZ2V0UHJveHkgfTsNCiAgICAgICAgYnJlYWs7DQogICAgY2FzZSAnd2luMzInOg0KICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IHsgaWdub3JlUHJveHk6IHdpbmRvd3NfcHJveHlDaGVjayB9Ow0KICAgICAgICBicmVhazsNCiAgICBjYXNlICdkYXJ3aW4nOg0KICAgICAgICBicmVhazsNCn0NCg==', 'base64').toString());"); + char *_proxyhelper = ILibMemory_Allocate(49737, 0, NULL, NULL); + memcpy_s(_proxyhelper + 0, 28420, "LyoNCkNvcHlyaWdodCAyMDE5IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQoNCmZ1bmN0aW9uIGxpbnV4X2dldFByb3h5KCkNCnsNCiAgICAvLyBDaGVjayBFbnZpcm9ubWVudCBWYXJpYWJlbHMNCiAgICBpZihyZXF1aXJlKCdmcycpLmV4aXN0c1N5bmMoJy9ldGMvZW52aXJvbm1lbnQnKSkNCiAgICB7DQoJICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQoJICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCgkgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ2NhdCAvZXRjL2Vudmlyb25tZW50IHwgZ3JlcCA9IHwgJyArICJ0ciAnXFxuJyAnYCcgfCBhd2sgLUYnYCcgJyIpOw0KCSAgICBjaGlsZC5zdGRpbi53cml0ZSgneycpOw0KCSAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgaG9zdD0iIjsgcG9ydD0iIjsgdXNlcm5hbWU9IiI7IHBhc3N3b3JkPSIiOyAnKQ0KCSAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgZm9yKGk9MTtpPE5GOysraSknKTsNCgkgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIHsnKTsNCgkgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIGlmKCRpfi9eIy8pIHsgY29udGludWU7IH0nKTsNCgkgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIHNwbGl0KCRpLHRva2VucywiPSIpOycpOw0KCSAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgaWYodG9rZW5zWzFdPT0iSFRUUF9QUk9YWSIpJyk7DQoJICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICB7ICcpOw0KCSAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgcHJveHk9c3Vic3RyKCRpLDIrbGVuZ3RoKHRva2Vuc1sxXSkpOycpOw0KCSAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgcHJpbnRmICJodHRwOi8vJXMiLCBwcm94eTsnKTsNCgkgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIGJyZWFrOycpOw0KCSAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgfSAnKTsNCgkgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIH0nKTsNCgkgICAgY2hpbGQuc3RkaW4ud3JpdGUoIn0nXG5leGl0XG4iKTsNCgkgICAgY2hpbGQud2FpdEV4aXQoKTsNCgkgICAgaWYgKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpICE9ICcnKSB7IHJldHVybiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkpOyB9DQogICAgfQ0KDQogICAgLy8gQ2hlY2sgcHJvZmlsZS5kDQogICAgaWYocmVxdWlyZSgnZnMnKS5leGlzdHNTeW5jKCcvZXRjL3Byb2ZpbGUuZC9wcm94eV9zZXR1cCcpKQ0KICAgIHsNCgkgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCgkgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOyBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KCSAgICBjaGlsZC5zdGRpbi53cml0ZSgiY2F0IC9ldGMvcHJvZmlsZS5kL3Byb3h5X3NldHVwIHwgYXdrICciICsgJ3sgc3BsaXQoJDIsIHRvaywgIj0iKTsgaWYodG9rWzFdPT0iaHR0cF9wcm94eSIpIHsgcHJpbnQgdG9rWzJdOyB9fVwnXG5leGl0XG4nKTsNCgkgICAgY2hpbGQud2FpdEV4aXQoKTsNCgkgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKS5zcGxpdCgnXG4nKVswXSk7DQogICAgfQ0KDQogICAgLy8gQ2hlY2sgZ3NldHRpbmdzDQogICAgaWYgKHJlcXVpcmUoJ2ZzJykuZXhpc3RzU3luYygnL3Vzci9iaW4vZ3NldHRpbmdzJykpDQogICAgew0KCSAgICB2YXIgc2V0dGluZzsNCgkgICAgdmFyIGlkcyA9IHJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5sb2dpblVpZHMoKTsgDQoJICAgIGZvciAodmFyIGkgaW4gaWRzKQ0KCSAgICB7DQoJCSAgICBzZXR0aW5nID0gcmVxdWlyZSgnbGludXgtZ25vbWUtaGVscGVycycpLmdldFByb3h5U2V0dGluZ3MoaWRzW2ldKTsNCgkJICAgIGlmIChzZXR0aW5nLm1vZGUgPT0gJ21hbnVhbCcpDQoJCSAgICB7DQoJCSAgICAgICAgaWYgKHNldHRpbmcuYXV0aEVuYWJsZWQpDQoJCSAgICAgICAgew0KCQkgICAgICAgICAgICByZXR1cm4gKCdodHRwOi8vJyArIHNldHRpbmcudXNlcm5hbWUgKyAnOicgKyBzZXR0aW5nLnBhc3N3b3JkICsgJ0AnICsgc2V0dGluZy5ob3N0ICsgJzonICsgc2V0dGluZy5wb3J0KTsNCgkJICAgICAgICB9DQoJCSAgICAgICAgZWxzZQ0KCQkgICAgICAgIHsNCgkJICAgICAgICAgICAgcmV0dXJuICgnaHR0cDovLycgKyBzZXR0aW5nLmhvc3QgKyAnOicgKyBzZXR0aW5nLnBvcnQpOw0KCQkgICAgICAgIH0NCgkJICAgIH0NCgkgICAgfQ0KICAgIH0NCg0KICAgIC8vIGNoZWNrIGFwdCBwcm94eSBzZXR0aW5nIGZybyAvZXRjL2FwdC9hcHQuY29uZi5kL3Byb3h5LmNvbmYNCiAgICBpZiAocmVxdWlyZSgnZnMnKS5leGlzdHNTeW5jKCcvZXRjL2FwdC9hcHQuY29uZi5kL3Byb3h5LmNvbmYnKSkNCiAgICB7DQogICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgY29uc29sZS5sb2coYy50b1N0cmluZygpKTsgfSk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCJjYXQgL2V0Yy9hcHQvYXB0LmNvbmYuZC9wcm94eS5jb25mIHwgdHIgJ1xcbicgJ2AnIHwgYXdrIC1GJ2AnICciKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ3snKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIGZvcihuPTE7bjxORjsrK24pICcpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgeycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgaWYoJG5+L14jLykgeyBjb250aW51ZTsgfScpDQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBpZigkbn4vXkFjcXVpcmU6Omh0dHA6OnByb3h5IC8pJyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICB7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBzcGxpdCgkbiwgZHVtbXksICJBY3F1aXJlOjpodHRwOjpwcm94eSAiKTsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIHByaW50IHN1YnN0cihkdW1teVsyXSwyLGxlbmd0aChkdW1teVsyXSktMyk7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBicmVhazsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoIn0nXG5leGl0XG4iKTsNCiAgICAgICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICAgICAgaWYgKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpICE9ICIiKSB7IHJldHVybiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkpOyB9DQogICAgfQ0KDQogICAgLy8gY2hlY2sgYXB0IHByb3h5IHNldHRpbmcgZnJvIC9ldGMvYXB0L2FwdC9hcHQuY29uZg0KICAgIGlmIChyZXF1aXJlKCdmcycpLmV4aXN0c1N5bmMoJy9ldGMvYXB0L2FwdC5jb25mJykpDQogICAgew0KICAgICAgICB2YXIgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgIGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IGNvbnNvbGUubG9nKGMudG9TdHJpbmcoKSk7IH0pOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgiY2F0IC9ldGMvYXB0L2FwdC5jb25mIHwgdHIgJ1xcbicgJ2AnIHwgYXdrIC1GJ2AnICciKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ3snKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIGZvcihuPTE7bjxORjsrK24pICcpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgeycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgaWYoJG5+L14jLykgeyBjb250aW51ZTsgfScpDQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBpZigkbn4vXkFjcXVpcmU6Omh0dHA6OnByb3h5IC8pJyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICB7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBzcGxpdCgkbiwgZHVtbXksICJBY3F1aXJlOjpodHRwOjpwcm94eSAiKTsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIHByaW50IHN1YnN0cihkdW1teVsyXSwyLGxlbmd0aChkdW1teVsyXSktMyk7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBicmVhazsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoIn0nXG5leGl0XG4iKTsNCiAgICAgICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICAgICAgaWYgKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpICE9ICIiKSB7IHJldHVybiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkpOyB9DQogICAgfQ0KDQoNCiAgICAvLyBjaGVjayB5dW0gcHJveHkgc2V0dGluZw0KICAgIGlmIChyZXF1aXJlKCdmcycpLmV4aXN0c1N5bmMoJy9ldGMveXVtLmNvbmYnKSkNCiAgICB7DQogICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgY29uc29sZS5sb2coYy50b1N0cmluZygpKTsgfSk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCdjYXQgL2V0Yy95dW0uY29uZiB8IGdyZXAgInByb3h5IiB8ICcgKyAidHIgJ1xcbicgJ2AnIHwgYXdrIC1GJ2AnICciKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ3snKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIGhvc3Q9IiI7IHBvcnQ9IiI7IHVzZXJuYW1lPSIiOyBwYXNzd29yZD0iIjsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIGZvcihuPTE7bjxORjsrK24pJyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICB7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBpZigkbn4vXiMvKSB7IGNvbnRpbnVlOyB9Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBzcGxpdCgkbix0b2tlbnMsIj0iKTsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIGlmKHRva2Vuc1sxXT09InByb3h5IiknKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIHsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIHNwbGl0KHRva2Vuc1syXSxkdW1teSwiOi8vIik7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBzcGxpdChkdW1teVsyXSx1cmwsIjoiKTsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIGhvc3QgPSB1cmxbMV07Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBwb3J0ID0gdXJsWzJdOyBpZihwb3J0PT0iIikgeyBwb3J0ID0gIjgwODAiOyB9Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICB9Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBpZih0b2tlbnNbMV09PSJwcm94eV91c2VybmFtZSIpIHsgdXNlcm5hbWUgPSB0b2tlbnNbMl07IH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIGlmKHRva2Vuc1sxXT09InByb3h5X3Bhc3N3b3JkIikgeyBwYXNzd29yZCA9IHRva2Vuc1syXTsgfScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgfScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgaWYoaG9zdCE9IiIgJiYgcG9ydCE9IiIpJyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICB7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBpZih1c2VybmFtZSE9IiIgJiYgcGFzc3dvcmQhPSIiKScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgeycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgcHJpbnRmICJodHRwOi8vJXM6JXNAJXM6JXMiLCB1c2VybmFtZSwgcGFzc3dvcmQsIGhvc3QsIHBvcnQ7ICcpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgfScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgZWxzZScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgeycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgcHJpbnRmICJodHRwOi8vJXM6JXMiLCBob3N0LCBwb3J0OyAnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoIn0nXG5leGl0XG4iKTsNCiAgICAgICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICAgICAgaWYgKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpICE9ICIiKSB7IHJldHVybiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkpOyB9DQogICAgfQ0KDQogICAgLy8gb3BlblNVU0UgcHJveHkgc2V0dGluZw0KICAgIGlmIChyZXF1aXJlKCdmcycpLmV4aXN0c1N5bmMoJy9ldGMvc3lzY29uZmlnL3Byb3h5JykpDQogICAgew0KICAgICAgICB2YXIgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgIGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IH0pOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnY2F0IC9ldGMvc3lzY29uZmlnL3Byb3h5IC9yb290Ly5jdXJscmMgfCBncmVwID0gfCAnICsgInRyICdcXG4nICdgJyB8IGF3ayAtRidgJyAnIik7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCd7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICBwcm94eT0iIjsgZW5hYmxlZD0iIjsgdXNlcm5hbWU9IiI7IHBhc3N3b3JkPSIiOyAnKQ0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgZm9yKGk9MTtpPE5GOysraSknKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIHsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIGlmKCRpfi9eIy8pIHsgY29udGludWU7IH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIHNwbGl0KCRpLHRva2VucywiPSIpOycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgaWYodG9rZW5zWzFdPT0iUFJPWFlfRU5BQkxFRCIpJyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICB7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBzcGxpdCh0b2tlbnNbMl0sZHVtbXksIlxcIiIpOycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgZW5hYmxlZCA9IGR1bW15WzJdOycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgfScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgaWYodG9rZW5zWzFdPT0iSFRUUF9QUk9YWSIpJyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICB7ICcpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgc3BsaXQodG9rZW5zWzJdLGR1bW15LCJcXCIiKTsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIHByb3h5ID0gZHVtbXlbMl07Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICB9ICcpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgaWYodG9rZW5zWzFdfi9ecHJveHktdXNlci8pJyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICB7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBjcmVkID0gc3Vic3RyKCRpLDEraW5kZXgoJGksIj0iKSk7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBjcmVkID0gc3Vic3RyKGNyZWQsIGluZGV4KGNyZWQsICJcXCIiKSk7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBpZihjcmVkfi9eIi8pIHsgY3JlZCA9IHN1YnN0cihjcmVkLDIsbGVuZ3RoKGNyZWQpLTIpOyB9Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICB1c2VybmFtZT1zdWJzdHIoY3JlZCwwLGluZGV4KGNyZWQsIjoiKS0xKTsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIHBhc3N3b3JkPXN1YnN0cihjcmVkLDEraW5kZXgoY3JlZCwiOiIpKTsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIGlmKGVuYWJsZWQ9PSJ5ZXMiICYmIHByb3h5IT0iIikgJyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICB7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBpZih1c2VybmFtZT09IiIgfHwgcGFzc3dvcmQ9PSIiKSAnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIHsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIHByaW50IHByb3h5OycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgfScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgZWxzZSAnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIHsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIHNwbGl0KHByb3h5LGR1bW15LCAiOi8vIik7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICBwcmludGYgIiVzOi8vJXM6JXNAJXMiLCBkdW1teVsxXSwgdXNlcm5hbWUsIHBhc3N3b3JkLCBkdW1teVsyXTsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoIn0nXG5leGl0XG4iKTsNCiAgICAgICAgY2hpbGQud2FpdEV4aXQoKTsNCg0KICAgICAgICBpZiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkgIT0gJycpIHsgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSk7IH0NCiAgICB9DQoNCiAgICBpZihyZXF1aXJlKCdmcycpLmV4aXN0c1N5bmMoJy9ldGMvbG9naW4uY29uZicpKQ0KICAgIHsNCiAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOyBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgiY2F0IC9ldGMvbG9naW4uY29uZiB8IHRyICdcXG4nICdgJyB8IGF3ayAtRidgJyAnIik7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCd7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICBwcmludGYgInsiOycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgZ3JvdXA9IiI7IGZpcnN0PTE7IGZpcnN0cHJvcD0wOycpDQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICBmb3IoaT0xO2k8TkY7KytpKSAnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgIHsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICBhPXNwbGl0KCRpLHRvaywiOiIpOyAnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICBpZihzcGxpdCh0b2tbMV0sZHVtbXksIiMiKT09MSAmJiBzcGxpdCh0b2tbMV0sZHVtbXkyLCIgIik9PTEpJyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgeyAnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICAgaWYoZ3JvdXAgIT0gIiIpIHsgcHJpbnRmICJ9IjsgfScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICBncm91cCA9IHRva1sxXTsgZmlyc3Rwcm9wPTE7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgIHByaW50ZiAiJXNcXCIlc1xcIjogeyIsIChmaXJzdD09MD8iLCI6IiIpLCB0b2tbMV07Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgIGZpcnN0PTA7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgfScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgIGVsc2UgJyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgeycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgIGlmKGdyb3VwICE9ICIiICYmIHNwbGl0KCRpLGR1bW15MywiXFxcXCIpPjEgJiYgc3BsaXQoJGksIGR1bW15NCwgIiMiKT09MSknKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICB7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgICAgIGlmKHNwbGl0KCRpLGtleTEsIj0iKT09MSknKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICAgICAgeycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgICAgICAgc3BsaXQoJGksa2V5MiwiOiIpOycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgICAgICAgaWYoa2V5MlsyXSE9IlxcXFwiKScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgICAgICAgeycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgICAgICAgICAgcHJpbnRmICIlc1xcIiVzXFwiOiBudWxsIiwoZmlyc3Rwcm9wPT0wPyIsIjoiIiksa2V5MlsyXTsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICAgICAgICAgICAgIGZpcnN0cHJvcD0wOycpDQog", 16000); + memcpy_s(_proxyhelper + 16000, 12420, "ICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgICAgICAgICB9Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgICAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICAgICAgZWxzZScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgICB7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgICAgICAgIHRtcCA9IHN1YnN0cigkaSwyK2xlbmd0aChrZXkxWzFdKSk7Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgICAgICAgIHNwbGl0KHRtcCxkdW1teSwiXFxcXCIpOycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgICAgICB0bXA9c3Vic3RyKHRtcCwwLGxlbmd0aCh0bXApLTIpOycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgICAgICBzcGxpdChrZXkxWzFdLGtleW5hbWUsIjoiKTsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICAgICAgICAgcHJpbnRmICIlc1xcIiVzXFwiOiBcXCIlc1xcIiIsIChmaXJzdHByb3A9PTA/IiwiOiIiKSwga2V5bmFtZVsyXSwgdG1wOycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgICAgICBmaXJzdHByb3A9MDsnKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICAgICAgfScpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgIH0nKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICB9Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICB9Jyk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICBpZihncm91cCE9IiIpIHsgcHJpbnRmICJ9IjsgfScpDQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICBwcmludGYgIn0iOycpOw0KICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgifSciKTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ1xuZXhpdFxuJyk7DQogICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgIGlmIChjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSAhPSAnJykNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIGNvbmZpZyA9IG51bGw7DQogICAgICAgICAgICB0cnkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBjb25maWcgPSBKU09OLnBhcnNlKGNoaWxkLnN0ZG91dC5zdHIpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2F0Y2ggKGUpDQogICAgICAgICAgICB7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGlmKGNvbmZpZykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvLyBjaGVjayByb290DQogICAgICAgICAgICAgICAgaWYoY29uZmlnLnJvb3QgJiYgY29uZmlnLnJvb3Quc2V0ZW52KQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGksIHRva2VuczsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGl0ZW1zID0gY29uZmlnLnJvb3Quc2V0ZW52LnNwbGl0KCcsJyk7DQogICAgICAgICAgICAgICAgICAgIGZvcihpPTA7aTxpdGVtcy5sZW5ndGg7KytpKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICB0b2tlbnMgPSBpdGVtc1tpXS5zcGxpdCgnPScpOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYodG9rZW5zWzBdID09ICdodHRwc19wcm94eScgfHwgdG9rZW5zWzBdID09ICdodHRwX3Byb3h5JykNCiAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHRva2Vuc1sxXS50cmltKCkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8gY2hlY2sgZGVmYXVsdA0KICAgICAgICAgICAgICAgIGlmIChjb25maWcuZGVmYXVsdCAmJiBjb25maWcuZGVmYXVsdC5zZXRlbnYpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICB2YXIgaSwgdG9rZW5zOw0KICAgICAgICAgICAgICAgICAgICB2YXIgaXRlbXMgPSBjb25maWcuZGVmYXVsdC5zZXRlbnYuc3BsaXQoJywnKTsNCiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgKytpKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICB0b2tlbnMgPSBpdGVtc1tpXS5zcGxpdCgnPScpOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRva2Vuc1swXSA9PSAnaHR0cHNfcHJveHknIHx8IHRva2Vuc1swXSA9PSAnaHR0cF9wcm94eScpDQogICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0b2tlbnNbMV0udHJpbSgpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCg0KDQogICAgdGhyb3cgKCdObyBwcm94aWVzJyk7DQp9DQpmdW5jdGlvbiBwb3NpeF9wcm94eUNoZWNrKHVpZCwgY2hlY2tBZGRyKQ0Kew0KICAgIHZhciBnOw0KICAgIHZhciB4ID0gcHJvY2Vzcy5lbnZbJ25vX3Byb3h5J10gPyBwcm9jZXNzLmVudlsnbm9fcHJveHknXS5zcGxpdCgnLCcpIDogW107DQogICAgdmFyIHQ7DQoNCiAgICBpZiAocmVxdWlyZSgnbGludXgtZ25vbWUtaGVscGVycycpLmF2YWlsYWJsZSAmJiAoZyA9IHJlcXVpcmUoJ2xpbnV4LWdub21lLWhlbHBlcnMnKS5nZXRQcm94eVNldHRpbmdzKHVpZCkpLm1vZGUgIT0gJ25vbmUnKQ0KICAgIHsNCiAgICAgICAgeCA9IGcuZXhjZXB0aW9uczsNCiAgICB9DQoNCiAgICBmb3IodmFyIGkgaW4geCkNCiAgICB7DQogICAgICAgIGlmICh4W2ldID09IGNoZWNrQWRkcikgeyByZXR1cm4gKHRydWUpOyB9ICAgICAgICAgICAgICAgLy8gRGlyZWN0IE1hdGNoDQogICAgICAgIGlmIChjaGVja0FkZHIuZW5kc1dpdGgoJy4nICsgeFtpXSkpIHsgcmV0dXJuICh0cnVlKTsgfSAgLy8gU3ViZG9tYWluIE1hdGNoDQogICAgICAgIGlmICgodiA9IHhbaV0uc3BsaXQoJy8nKSkubGVuZ3RoID09IDIpDQogICAgICAgIHsNCiAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGlmKHJlcXVpcmUoJ2lwLWFkZHJlc3MnKS5BZGRyZXNzNC5mcm9tU3RyaW5nKHZbMF0pLm1hc2socGFyc2VJbnQodlsxXSkpID09IHJlcXVpcmUoJ2lwLWFkZHJlc3MnKS5BZGRyZXNzNC5mcm9tU3RyaW5nKGNoZWNrQWRkcikubWFzayhwYXJzZUludCh2WzFdKSkpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICByZXR1cm4odHJ1ZSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2F0Y2ggKGV4KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfQ0KICAgIHJldHVybiAoZmFsc2UpOw0KfQ0KDQpmdW5jdGlvbiB3aW5kb3dzX2dldFVzZXJSZWdpc3RyeUtleSgpDQp7DQogICAgdmFyIGk7DQogICAgaWYgKChpID0gcmVxdWlyZSgndXNlci1zZXNzaW9ucycpLmdldFByb2Nlc3NPd25lck5hbWUocHJvY2Vzcy5waWQpKS50c2lkID09IDApDQogICAgew0KICAgICAgICAvLyBXZSBhcmUgYSBzZXJ2aWNlLCBzbyB3ZSBzaG91bGQgY2hlY2sgdGhlIHVzZXIgdGhhdCBpbnN0YWxsZWQgdGhlIE1lc2ggQWdlbnQNCiAgICAgICAgdHJ5DQogICAgICAgIHsNCiAgICAgICAgICAgIGtleSA9IHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpLlF1ZXJ5S2V5KHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpLkhLRVkuTG9jYWxNYWNoaW5lLCAnU1lTVEVNXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXE1lc2ggQWdlbnQnLCAnX0luc3RhbGxlZEJ5Jyk7DQogICAgICAgIH0NCiAgICAgICAgY2F0Y2ggKHh4KQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyBUaGlzIGluZm8gaXNuJ3QgYXZhaWxhYmxlLCBzbyBsZXQncyB0cnkgdG8gdXNlIHRoZSBjdXJyZW50bHkgbG9nZ2VkIGluIHVzZXINCiAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGtleSA9IHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpLnVzZXJuYW1lVG9Vc2VyS2V5KHJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5nZXRVc2VybmFtZShyZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuY29uc29sZVVpZCgpKSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBjYXRjaCAoeHh4KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIC8vIE5vIHVzZXJzIGFyZSBsb2dnZWQgaW4sIHNvIGFzIGEgbGFzdCByZXNvcnQsIGxldCdzIHRyeSB0aGUgbGFzdCBsb2dnZWQgaW4gdXNlci4NCiAgICAgICAgICAgICAgICB2YXIgZW50cmllcyA9IHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpLlF1ZXJ5S2V5KHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpLkhLRVkuVXNlcnMpOw0KICAgICAgICAgICAgICAgIGZvciAoaSBpbiBlbnRyaWVzLnN1YmtleXMpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBpZiAoZW50cmllcy5zdWJrZXlzW2ldLnNwbGl0KCctJykubGVuZ3RoID4gNSAmJiAhZW50cmllcy5zdWJrZXlzW2ldLmVuZHNXaXRoKCdfQ2xhc3NlcycpKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBlbnRyaWVzLnN1YmtleXNbaV07DQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCiAgICBlbHNlDQogICAgew0KICAgICAgICAvLyBXZSBhcmUgYSBsb2dnZWQgaW4gdXNlcg0KICAgICAgICBrZXkgPSByZXF1aXJlKCd3aW4tcmVnaXN0cnknKS51c2VybmFtZVRvVXNlcktleShpLm5hbWUpOw0KICAgIH0NCiAgICBpZiAoIWtleSkgeyB0aHJvdyAoJ0NvdWxkIG5vdCBkZXRlcm1pbmUgd2hpY2ggdXNlciBwcm94eSBzZXR0aW5nIHRvIHF1ZXJ5Jyk7IH0NCiAgICByZXR1cm4gKGtleSk7DQp9DQpmdW5jdGlvbiB3aW5kb3dzX3Byb3h5Q2hlY2soa2V5LCBjaGVja0FkZHIpDQp7DQogICAgaWYgKCFrZXkpIHsga2V5ID0gd2luZG93c19nZXRVc2VyUmVnaXN0cnlLZXkoKTsgfQ0KDQogICAgdmFyIHByb3h5T3ZlcnJpZGUgPSByZXF1aXJlKCd3aW4tcmVnaXN0cnknKS5RdWVyeUtleShyZXF1aXJlKCd3aW4tcmVnaXN0cnknKS5IS0VZLlVzZXJzLCBrZXkgKyAnXFxTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50VmVyc2lvblxcSW50ZXJuZXQgU2V0dGluZ3MnLCAnUHJveHlPdmVycmlkZScpLnNwbGl0KCc7Jyk7DQogICAgZm9yKHZhciBpIGluIHByb3h5T3ZlcnJpZGUpDQogICAgew0KICAgICAgICBwcm94eU92ZXJyaWRlW2ldID0gcHJveHlPdmVycmlkZVtpXS50cmltKCk7DQogICAgICAgIGlmICgoY2hlY2tBZGRyID09ICcxMjcuMC4wLjEnIHx8IGNoZWNrQWRkciA9PSAnOjoxJykgJiYgcHJveHlPdmVycmlkZVtpXSA9PSAnPGxvY2FsPicpIHsgcmV0dXJuICh0cnVlKTsgfQ0KICAgICAgICBpZiAoY2hlY2tBZGRyID09IHByb3h5T3ZlcnJpZGVbaV0pIHsgcmV0dXJuICh0cnVlKTsgfSAvLyBFeGFjdCBNYXRjaA0KICAgICAgICBpZiAocHJveHlPdmVycmlkZVtpXS5zdGFydHNXaXRoKCcqLicpICYmIGNoZWNrQWRkci5lbmRzV2l0aChwcm94eU92ZXJyaWRlW2ldLnN1YnN0cmluZygxKSkpIHsgcmV0dXJuICh0cnVlKTsgfQ0KICAgICAgICBpZiAocHJveHlPdmVycmlkZVtpXS5lbmRzV2l0aCgnLionKSAmJiBjaGVja0FkZHIuc3RhcnRzV2l0aChwcm94eU92ZXJyaWRlW2ldLnN1YnN0cmluZygwLCBwcm94eU92ZXJyaWRlW2ldLmxlbmd0aCAtIDEpKSkgeyByZXR1cm4gKHRydWUpOyB9DQogICAgfQ0KICAgIHJldHVybiAoZmFsc2UpOw0KfQ0KDQpmdW5jdGlvbiBtYWNvc19nZXRQcm94eSgpDQp7DQogICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgY2hpbGQuc3RkZXJyLnN0ciA9ICcnOyBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCJzY3V0aWwgLS1wcm94eSB8IHRyICdcXG4nICdgJyB8IGF3ayAtRidgJyAnIik7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ3snKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgcHN0YXJ0PTA7JykNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgZm9yKGk9MTtpPE5GOysraSknKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgiICAgeyIpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICBpZihzcGxpdCgkaSxkdW1teSwiRXhjZXB0aW9uc0xpc3QgIik+MSknKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgiICAgICAgeyIpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgcHJpbnRmICJ7IFxcImV4Y2VwdGlvbnNcXCI6IFsiOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgKytpOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgZnN0YXJ0PTE7IHBzdGFydD0xOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgZm9yKDtpPE5GOysraSknKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgIHsnKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgIGlmKHNwbGl0KCRpLGR1bW15LCJ9Iik+MSkgeyBicmVhazsgfSAnKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgIHNwbGl0KCRpLCB2YWwsICIgOiAiKTsnKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgIHByaW50ZiAiJXNcXCIlc1xcIiIsIChmc3RhcnQ9PTA/IiwiOiIiKSwgdmFsWzJdOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgICAgZnN0YXJ0PTA7Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICB9Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICBwcmludGYgIl0iOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICAgY29udGludWU7Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoIiAgICAgIH0iKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgZWxzZScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICB7Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIGlmKHBzdGFydD09MSAmJiBzcGxpdCgkaSxkdW1teSwifSIpPT0xKScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCcgICAgICAgICB7Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICAgIHNwbGl0KCRpLHRvaywiIDogIik7Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgICAgIHNwbGl0KHRva1sxXSxrZXksIiAiKTsnKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgICAgICAgcHJpbnRmICIsXFwiJXNcXCI6IFxcIiVzXFwiIiwga2V5WzFdLCB0b2tbMl07Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJyAgICAgICAgIH0nKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgICAgfScpDQogICAgY2hpbGQuc3RkaW4ud3JpdGUoIiAgIH0iKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnICAgcHJpbnRmICJ9IjsnKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgifSdcbmV4aXRcbiIpOw0KICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgaWYoY2hpbGQuc3Rkb3V0LnN0ciAhPSAnJykNCiAgICB7DQogICAgICAgIHRyeQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgcCA9IEpTT04ucGFyc2UoY2hpbGQuc3Rkb3V0LnN0cik7DQogICAgICAgICAgICBpZihwLkhUVFBFbmFibGUgPT0gIjEiKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHJldHVybignaHR0cDovLycgKyBwLkhUVFBQcm94eSArICc6JyArIHAuSFRUUFBvcnQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGNhdGNoKGUpDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnNvbGUubG9nKGUpOw0KICAgICAgICB9DQogICAgfQ0KICAgIHRocm93ICgnTm8gUHJveGllcycpOw0KfQ0KDQpmdW5jdGlvbiB3aW5kb3dzX2dldFByb3h5KCkNCnsNCiAgICB2YXIgaXNyb290ID0gZmFsc2U7DQogICAgdmFyIGtleSwgdmFsdWU7DQoNCiAgICBrZXkgPSB3aW5kb3dzX2dldFVzZXJSZWdpc3RyeUtleSgpOw0KICAgIHRyeQ0KICAgIHsNCiAgICAgICAgaWYgKHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpLlF1ZXJ5S2V5KHJlcXVpcmUoJ3dpbi1yZWdpc3RyeScpLkhLRVkuVXNlcnMsIGtleSArICdcXFNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxJbnRlcm5ldCBTZXR0aW5ncycsICdQcm94eUVuYWJsZScpID09IDEpDQogICAgICAgIHsNCiAgICAgICAgICAgIC8vIFByb3h5IGlzIGVuYWJsZWQNCiAgICAgICAgICAgIHJldHVybiAocmVxdWlyZSgnd2luLXJlZ2lzdHJ5JykuUXVlcnlLZXkocmVxdWlyZSgnd2luLXJlZ2lzdHJ5JykuSEtFWS5Vc2Vycywga2V5ICsgJ1xcU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXEludGVybmV0IFNldHRpbmdzJywgJ1Byb3h5U2VydmVyJykpOw0KICAgICAgICB9DQogICAgfQ0KICAgIGNhdGNoKGUpDQogICAgew0KICAgICAgICB0aHJvdyAoJ05vIHByb3hpZXMnKTsNCiAgICB9DQp9DQpzd2l0Y2ggKHByb2Nlc3MucGxhdGZvcm0pDQp7DQogICAgY2FzZSAnbGludXgnOg0KICAgIGNhc2UgJ2ZyZWVic2QnOg0KICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IHsgaWdub3JlUHJveHk6IHBvc2l4X3Byb3h5Q2hlY2ssIGdldFByb3h5OiBsaW51eF9nZXRQcm94eSB9Ow0KICAgICAgICBicmVhazsNCiAgICBjYXNlICd3aW4zMic6DQogICAgICAgIG1vZHVsZS5leHBvcnRzID0geyBpZ25vcmVQcm94eTogd2luZG93c19wcm94eUNoZWNrLCBnZXRQcm94eTogd2luZG93c19nZXRQcm94eSB9Ow0KICAgICAgICBicmVhazsNCiAgICBjYXNlICdkYXJ3aW4nOg0KICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IHsgZ2V0UHJveHk6IG1hY29zX2dldFByb3h5IH07DQogICAgICAgIGJyZWFrOw0KfQ0K", 12420); + ILibBase64DecodeEx((unsigned char*)_proxyhelper, 28420, (unsigned char*)_proxyhelper + 28420); + duk_push_global_object(ctx); duk_get_prop_string(ctx, -1, "addModule"); duk_swap_top(ctx, -2); duk_push_string(ctx, "proxy-helper"); duk_push_string(ctx, _proxyhelper + 28420); + duk_pcall_method(ctx, 2); duk_pop(ctx); + free(_proxyhelper); #ifdef _POSIX duk_peval_string_noresult(ctx, "addModule('linux-pathfix', Buffer.from('LyoKQ29weXJpZ2h0IDIwMTkgSW50ZWwgQ29ycG9yYXRpb24KCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwp5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQpkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLApXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZApsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKi8NCg0KZnVuY3Rpb24gY2hlY2tQYXRoKCkNCnsNCiAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnbGludXgnKQ0KICAgIHsNCiAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgY2hpbGQuc3RkZXJyLnN0ciA9ICcnOyBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCdlY2hvICRQQVRIIHwgYXdrIFwneyB5ZXM9MDsgYT1zcGxpdCgkMCwgYiwgIjoiKTsgZm9yKHg9MTt4PD1hOysreCkgeyBpZihiW3hdPT0iL3NiaW4iKSB7IHllcz0xOyB9IH0gcHJpbnQgeWVzOyB9XCdcbmV4aXRcbicpOw0KICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KDQogICAgICAgIGlmIChwYXJzZUludChjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSkgPT0gMCkNCiAgICAgICAgew0KICAgICAgICAgICAgcHJvY2Vzcy5zZXRlbnYoJ1BBVEgnLCBwcm9jZXNzLmVudlsnUEFUSCddICsgJzovc2JpbicpOw0KICAgICAgICB9DQogICAgfQ0KfQ0KDQptb2R1bGUuZXhwb3J0cyA9IGNoZWNrUGF0aDsNCg0KDQo=', 'base64').toString());"); diff --git a/modules/awk-helper.js b/modules/awk-helper.js new file mode 100644 index 0000000..90420be --- /dev/null +++ b/modules/awk-helper.js @@ -0,0 +1,32 @@ +/* +Copyright 2020 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +var child = { stdin: { str: '', write: function (v) { this.str += v.trim(); } } }; + +//child.stdin.write('\nexit\n'); + +child.stdin.write('\n\n\n'); +require('clipboard')(child.stdin.str); + +if (process.platform == 'linux') +{ + console.log('clipboard active for 5 seconds'); + var t = setTimeout(function () { process.exit(); }, 5000); +} +else +{ + process.exit(); +} diff --git a/modules/linux-gnome-helpers.js b/modules/linux-gnome-helpers.js index e02253e..91741ac 100644 --- a/modules/linux-gnome-helpers.js +++ b/modules/linux-gnome-helpers.js @@ -6,20 +6,34 @@ function gnome_getProxySettings(uid) child.stderr.str = ''; child.stderr.on('data', function (c) { }); child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); - child.stdin.write('gsettings list-recursively org.gnome.system.proxy | tr "\\n" "\\|" | tr "\\\'" "\\`" | awk \'{ count=split($0, res, "|");') - child.stdin.write('exc="[]";'); - child.stdin.write('for(a=0;a1 && split($i, dummy4, "#")==1)'); + child.stdin.write(' {'); + child.stdin.write(' if(split($i,key1,"=")==1)'); + child.stdin.write(' {'); + child.stdin.write(' split($i,key2,":");'); + child.stdin.write(' if(key2[2]!="\\\\")'); + child.stdin.write(' {'); + child.stdin.write(' printf "%s\\"%s\\": null",(firstprop==0?",":""),key2[2];'); + child.stdin.write(' firstprop=0;') + child.stdin.write(' }'); + child.stdin.write(' }'); + child.stdin.write(' else'); + child.stdin.write(' {'); + child.stdin.write(' tmp = substr($i,2+length(key1[1]));'); + child.stdin.write(' split(tmp,dummy,"\\\\");'); + child.stdin.write(' tmp=substr(tmp,0,length(tmp)-2);'); + child.stdin.write(' split(key1[1],keyname,":");'); + child.stdin.write(' printf "%s\\"%s\\": \\"%s\\"", (firstprop==0?",":""), keyname[2], tmp;'); + child.stdin.write(' firstprop=0;'); + child.stdin.write(' }'); + child.stdin.write(' }'); + child.stdin.write(' }'); + child.stdin.write(' }'); + child.stdin.write(' if(group!="") { printf "}"; }') + child.stdin.write(' printf "}";'); + child.stdin.write("}'"); + child.stdin.write('\nexit\n'); + child.waitExit(); + if (child.stdout.str.trim() != '') { - // Enabled - child = require('child_process').execFile('/bin/sh', ['sh']); - child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); - child.stderr.on('data', function (c) { console.log(c.toString()); }); - child.stdin.write('cat /etc/sysconfig/proxy | grep _PROXY | ' + "tr '\\n' '`' | awk -F'`' '{"); - child.stdin.write('for(i=1;i 5 && !entries.subkeys[i].endsWith('_Classes')) { - if(entries.subkeys[i].split('-').length>5 && !entries.subkeys[i].endsWith('_Classes')) - { - key = entries.subkeys[i]; - break; - } + key = entries.subkeys[i]; + break; } } } } - else - { - // We are a logged in user - key = require('win-registry').usernameToUserKey(i.name); - } - if(!key) {throw('Could not determine which user proxy setting to query');} } + else + { + // We are a logged in user + key = require('win-registry').usernameToUserKey(i.name); + } + if (!key) { throw ('Could not determine which user proxy setting to query'); } + return (key); +} +function windows_proxyCheck(key, checkAddr) +{ + if (!key) { key = windows_getUserRegistryKey(); } + var proxyOverride = require('win-registry').QueryKey(require('win-registry').HKEY.Users, key + '\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings', 'ProxyOverride').split(';'); for(var i in proxyOverride) { @@ -190,6 +394,81 @@ function windows_proxyCheck(key, checkAddr) return (false); } +function macos_getProxy() +{ + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write("scutil --proxy | tr '\\n' '`' | awk -F'`' '"); + child.stdin.write('{'); + child.stdin.write(' pstart=0;') + child.stdin.write(' for(i=1;i1)'); + child.stdin.write(" {"); + child.stdin.write(' printf "{ \\"exceptions\\": [";'); + child.stdin.write(' ++i;'); + child.stdin.write(' fstart=1; pstart=1;'); + child.stdin.write(' for(;i1) { break; } '); + child.stdin.write(' split($i, val, " : ");'); + child.stdin.write(' printf "%s\\"%s\\"", (fstart==0?",":""), val[2];'); + child.stdin.write(' fstart=0;'); + child.stdin.write(' }'); + child.stdin.write(' printf "]";'); + child.stdin.write(' continue;'); + child.stdin.write(" }"); + child.stdin.write(' else'); + child.stdin.write(' {'); + child.stdin.write(' if(pstart==1 && split($i,dummy,"}")==1)'); + child.stdin.write(' {'); + child.stdin.write(' split($i,tok," : ");'); + child.stdin.write(' split(tok[1],key," ");'); + child.stdin.write(' printf ",\\"%s\\": \\"%s\\"", key[1], tok[2];'); + child.stdin.write(' }'); + child.stdin.write(' }') + child.stdin.write(" }"); + child.stdin.write(' printf "}";'); + child.stdin.write("}'\nexit\n"); + child.waitExit(); + if(child.stdout.str != '') + { + try + { + var p = JSON.parse(child.stdout.str); + if(p.HTTPEnable == "1") + { + return('http://' + p.HTTPProxy + ':' + p.HTTPPort); + } + } + catch(e) + { + console.log(e); + } + } + throw ('No Proxies'); +} + +function windows_getProxy() +{ + var isroot = false; + var key, value; + + key = windows_getUserRegistryKey(); + try + { + if (require('win-registry').QueryKey(require('win-registry').HKEY.Users, key + '\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings', 'ProxyEnable') == 1) + { + // Proxy is enabled + return (require('win-registry').QueryKey(require('win-registry').HKEY.Users, key + '\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings', 'ProxyServer')); + } + } + catch(e) + { + throw ('No proxies'); + } +} switch (process.platform) { case 'linux': @@ -197,8 +476,9 @@ switch (process.platform) module.exports = { ignoreProxy: posix_proxyCheck, getProxy: linux_getProxy }; break; case 'win32': - module.exports = { ignoreProxy: windows_proxyCheck }; + module.exports = { ignoreProxy: windows_proxyCheck, getProxy: windows_getProxy }; break; case 'darwin': + module.exports = { getProxy: macos_getProxy }; break; }