Innovenergy_trunk/frontend/node_modules/testcafe/lib/proxyless/resource-injector.js

162 lines
26 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const testcafe_hammerhead_1 = require("testcafe-hammerhead");
const injectables_1 = require("../assets/injectables");
const empty_page_markup_1 = __importDefault(require("./empty-page-markup"));
const http_status_codes_1 = require("http-status-codes");
const test_run_1 = require("../errors/test-run");
const cdp_1 = require("./utils/cdp");
const debug_loggers_1 = require("../utils/debug-loggers");
const string_1 = require("./utils/string");
const safe_api_1 = require("./request-pipeline/safe-api");
const RESPONSE_REMOVED_HEADERS = [
'cross-origin-embedder-policy',
'cross-origin-opener-policy',
'cross-origin-resource-policy',
];
class ResourceInjector {
constructor(testRunBridge, specialServiceRoutes) {
this._specialServiceRoutes = specialServiceRoutes;
this._testRunBridge = testRunBridge;
}
_getRestoreContextStorageScript(contextStorage) {
const currentTestRun = this._testRunBridge.getCurrentTestRun();
const value = JSON.stringify((contextStorage === null || contextStorage === void 0 ? void 0 : contextStorage[currentTestRun.id]) || '');
return `Object.defineProperty(window, '%proxylessContextStorage%', { configurable: true, value: ${value} });`;
}
_getRestoreStoragesScript(restoringStorages) {
if (!restoringStorages)
return '(function() {})()';
return `(function() {
window.localStorage.clear();
window.sessionStorage.clear();
const snapshot = ${JSON.stringify(restoringStorages)};
const ls = JSON.parse(snapshot.localStorage);
const ss = JSON.parse(snapshot.sessionStorage);
for (let i = 0; i < ls[0].length; i++)
window.localStorage.setItem(ls[0][i], ls[1][i]);
for (let i = 0; i < ss[0].length; i++)
window.sessionStorage.setItem(ss[0][i], ss[1][i]);
})();
`;
}
_resolveRelativeUrls(proxy, relativeUrls) {
return relativeUrls.map(url => proxy.resolveRelativeServiceUrl(url));
}
async _prepareInjectableResources({ isIframe, restoringStorages, contextStorage, userScripts }) {
if (!this._testRunBridge.getCurrentTestRun())
return null;
const taskScript = await this._testRunBridge.getTaskScript({ isIframe, restoringStorages, contextStorage, userScripts });
const proxy = this._testRunBridge.getBrowserConnection().browserConnectionGateway.proxy;
const injectableResources = {
stylesheets: [
injectables_1.TESTCAFE_UI_STYLES,
],
scripts: [
...testcafe_hammerhead_1.INJECTABLE_SCRIPTS.map(hs => (0, testcafe_hammerhead_1.getAssetPath)(hs, proxy.options.developmentMode)),
...injectables_1.SCRIPTS.map(s => (0, testcafe_hammerhead_1.getAssetPath)(s, proxy.options.developmentMode)),
],
embeddedScripts: [this._getRestoreStoragesScript(restoringStorages), this._getRestoreContextStorageScript(contextStorage), taskScript],
userScripts: userScripts || [],
};
injectableResources.scripts = this._resolveRelativeUrls(proxy, injectableResources.scripts);
injectableResources.userScripts = this._resolveRelativeUrls(proxy, injectableResources.userScripts);
injectableResources.stylesheets = this._resolveRelativeUrls(proxy, injectableResources.stylesheets);
return injectableResources;
}
_processResponseHeaders(headers) {
if (!headers)
return [];
headers = headers.filter(header => !RESPONSE_REMOVED_HEADERS.includes(header.name.toLowerCase()));
return (0, string_1.stringifyHeaderValues)(headers);
}
async _fulfillRequest(client, fulfillRequestInfo, body) {
await (0, safe_api_1.safeFulfillRequest)(client, {
requestId: fulfillRequestInfo.requestId,
responseCode: fulfillRequestInfo.responseCode || http_status_codes_1.StatusCodes.OK,
responsePhrase: fulfillRequestInfo.responsePhrase,
responseHeaders: this._processResponseHeaders(fulfillRequestInfo.responseHeaders),
body: (0, string_1.toBase64String)(body),
});
}
async redirectToErrorPage(client, err, url) {
const currentTestRun = this._testRunBridge.getCurrentTestRun();
if (!currentTestRun)
return;
currentTestRun.pendingPageError = new test_run_1.PageLoadError(err, url);
await (0, cdp_1.navigateTo)(client, this._specialServiceRoutes.errorPage1);
}
async getDocumentResourceInfo(event, client) {
const { requestId, request, responseErrorReason, resourceType, } = event;
if (resourceType !== 'Document') {
return {
error: null,
body: null,
};
}
try {
if (responseErrorReason === 'NameNotResolved') {
const err = new Error(`Failed to find a DNS-record for the resource at "${event.request.url}"`);
return {
error: err,
body: null,
};
}
const responseObj = await client.Fetch.getResponseBody({ requestId });
const responseStr = (0, string_1.getResponseAsString)(responseObj);
return {
error: null,
body: Buffer.from(responseStr),
};
}
catch (err) {
(0, debug_loggers_1.resourceInjectorLogger)('Failed to process request: %s', request.url);
return {
error: err,
body: null,
};
}
}
async processAboutBlankPage(event, userScripts, client) {
(0, debug_loggers_1.resourceInjectorLogger)('Handle page as about:blank. Origin url: %s', event.frame.url);
const injectableResources = await this._prepareInjectableResources({ isIframe: false, userScripts });
const html = (0, testcafe_hammerhead_1.injectResources)(empty_page_markup_1.default, injectableResources);
await client.Page.setDocumentContent({
frameId: event.frame.id,
html,
});
}
async processHTMLPageContent(fulfillRequestInfo, injectableResourcesOptions, client) {
const injectableResources = await this._prepareInjectableResources(injectableResourcesOptions);
// NOTE: an unhandled exception interrupts the test execution,
// and we are force to redirect manually to the idle page.
if (!injectableResources)
await (0, cdp_1.redirect)(client, fulfillRequestInfo.requestId, this._specialServiceRoutes.idlePage);
else {
const updatedResponseStr = (0, testcafe_hammerhead_1.injectResources)(fulfillRequestInfo.body, injectableResources, this._getPageInjectableResourcesOptions(injectableResourcesOptions));
await this._fulfillRequest(client, fulfillRequestInfo, updatedResponseStr);
}
}
async processNonProxiedContent(fulfillRequestInfo, client) {
await this._fulfillRequest(client, fulfillRequestInfo, fulfillRequestInfo.body);
}
_getPageInjectableResourcesOptions(injectableResourcesOptions) {
const { url, restoringStorages } = injectableResourcesOptions;
if (url && restoringStorages) {
return {
host: new URL(url).host,
sessionId: this._testRunBridge.getSessionId(),
};
}
return void 0;
}
}
exports.default = ResourceInjector;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb3VyY2UtaW5qZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJveHlsZXNzL3Jlc291cmNlLWluamVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBTUEsNkRBUTZCO0FBQzdCLHVEQUFvRTtBQUNwRSw0RUFBb0Q7QUFDcEQseURBQWdEO0FBQ2hELGlEQUFtRDtBQUNuRCxxQ0FBbUQ7QUFTbkQsMERBQWdFO0FBQ2hFLDJDQUl3QjtBQUN4QiwwREFBaUU7QUFHakUsTUFBTSx3QkFBd0IsR0FBRztJQUM3Qiw4QkFBOEI7SUFDOUIsNEJBQTRCO0lBQzVCLDhCQUE4QjtDQUNqQyxDQUFDO0FBRUYsTUFBcUIsZ0JBQWdCO0lBSWpDLFlBQW9CLGFBQTRCLEVBQUUsb0JBQTBDO1FBQ3hGLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxvQkFBb0IsQ0FBQztRQUNsRCxJQUFJLENBQUMsY0FBYyxHQUFVLGFBQWEsQ0FBQztJQUMvQyxDQUFDO0lBRU8sK0JBQStCLENBQUUsY0FBMEM7UUFDL0UsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQy9ELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQSxjQUFjLGFBQWQsY0FBYyx1QkFBZCxjQUFjLENBQUcsY0FBYyxDQUFDLEVBQUUsQ0FBQyxLQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXhFLE9BQU8sMkZBQTJGLEtBQUssTUFBTSxDQUFDO0lBQ2xILENBQUM7SUFFTyx5QkFBeUIsQ0FBRSxpQkFBc0Q7UUFDckYsSUFBSSxDQUFDLGlCQUFpQjtZQUNsQixPQUFPLG1CQUFtQixDQUFDO1FBRS9CLE9BQU87Ozs7K0JBSWdCLElBQUksQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUM7Ozs7Ozs7Ozs7U0FVdkQsQ0FBQztJQUNOLENBQUM7SUFFTyxvQkFBb0IsQ0FBRSxLQUFZLEVBQUUsWUFBc0I7UUFDOUQs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QUNqQyxtQkFBbUIsRUFDbkIsSUFBSSxDQUFDLGtDQUFrQyxDQUFDLDBCQUEwQixDQUFDLENBQ3RFLENBQUM7WUFFRixNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLGtCQUFrQixFQUFFLGtCQUFrQixDQUFDLENBQUM7U0FDOUU7SUFDTCxDQUFDO0lBRU0sS0FBSyxDQUFDLHdCQUF3QixDQUFFLGtCQUF5QyxFQUFFLE1BQW1CO1FBQ2pHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsa0JBQWtCLENBQUMsSUFBYyxDQUFDLENBQUM7SUFDOUYsQ0FBQztJQUVPLGtDQUFrQyxDQUFFLDBCQUFzRDtRQUM5RixNQUFNLEVBQUUsR0FBRyxFQUFFLGlCQUFpQixFQUFFLEdBQUcsMEJBQTBCLENBQUM7UUFFOUQsSUFBSSxHQUFHLElBQUksaUJBQWlCLEVBQUU7WUFDMUIsT0FBTztnQkFDSCxJQUFJLEVBQU8sSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSTtnQkFDNUIsU0FBUyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFO2FBQ2hELENBQUM7U0FDTDtRQUVELE9BQU8sS0FBSyxDQUFDLENBQUM7SUFDbEIsQ0FBQztDQUNKO0FBMUxELG1DQTBMQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFByb3RvY29sQXBpIH0gZnJvbSAnY2hyb21lLXJlbW90ZS1pbnRlcmZhY2UnO1xuaW1wb3J0IFByb3RvY29sIGZyb20gJ2RldnRvb2xzLXByb3RvY29sJztcbmltcG9ydCBSZXF1ZXN0UGF1c2VkRXZlbnQgPSBQcm90b2NvbC5GZXRjaC5SZXF1ZXN0UGF1c2VkRXZlbnQ7XG5pbXBvcnQgRnJhbWVOYXZpZ2F0ZWRFdmVudCA9IFByb3RvY29sLlBhZ2UuRnJhbWVOYXZpZ2F0ZWRFdmVudDtcbmltcG9ydCBGdWxmaWxsUmVxdWVzdFJlcXVlc3QgPSBQcm90b2NvbC5GZXRjaC5GdWxmaWxsUmVxdWVzdFJlcXVlc3Q7XG5pbXBvcnQgSGVhZGVyRW50cnkgPSBQcm90b2NvbC5GZXRjaC5IZWFkZXJFbnRyeTtcbmltcG9ydCB7XG4gICAgaW5qZWN0UmVzb3VyY2VzLFxuICAgIFBhZ2VJbmplY3RhYmxlUmVzb3VyY2VzLFxuICAgIElOSkVDVEFCTEVfU0NSSVBUUyBhcyBIQU1NRVJIRUFEX0lOSkVDVEFCTEVfU0NSSVBUUyxcbiAgICBnZXRBc3NldFBhdGgsXG4gICAgUGFnZVJlc3RvcmVTdG9yYWdlc09wdGlvbnMsXG4gICAgU3RvcmFnZXNTbmFwc2hvdCxcbiAgICBQcm94eSxcbn0gZnJvbSAndGVzdGNhZmUtaGFtbWVyaGVhZCc7XG5pbXBvcnQgeyBTQ1JJUFRTLCBURVNUQ0FGRV9VSV9TVFlMRVMgfSBmcm9tICcuLi9hc3NldHMvaW5qZWN0YWJsZXMnO1xuaW1wb3J0IEVNUFRZX1BBR0VfTUFSS1VQIGZyb20gJy4vZW1wdHktcGFnZS1tYXJrdXAnO1xuaW1wb3J0IHsgU3RhdHVzQ29kZXMgfSBmcm9tICdodHRwLXN0YXR1cy1jb2Rlcyc7XG5pbXBvcnQgeyBQYWdlTG9hZEVycm9yIH0gZnJvbSAnLi4vZXJyb3JzL3Rlc3QtcnVuJztcbmltcG9ydCB7IHJlZGlyZWN0LCBuYXZpZ2F0ZVRvIH0gZnJvbSAnLi91dGlscy9jZHAnO1xuXG5pbXBvcnQge1xuICAgIERvY3VtZW50UmVzb3VyY2VJbmZvLFxuICAgIEluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zLFxuICAgIFNlc3Npb25TdG9yYWdlSW5mbyxcbiAgICBTcGVjaWFsU2VydmljZVJvdXRlcyxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbmltcG9ydCB7IHJlc291cmNlSW5qZWN0b3JMb2dnZXIgfSBmcm9tICcuLi91dGlscy9kZWJ1Zy1sb2dnZXJzJztcbmltcG9ydCB7XG4gICAgZ2V0UmVzcG9uc2VBc1N0cmluZyxcbiAgICBzdHJpbmdpZnlIZWFkZXJWYWx1ZXMsXG4gICAgdG9CYXNlNjRTdHJpbmcsXG59IGZyb20gJy4vdXRpbHMvc3RyaW5nJztcbmltcG9ydCB7IHNhZmVGdWxmaWxsUmVxdWVzdCB9IGZyb20gJy4vcmVxdWVzdC1waXBlbGluZS9zYWZlLWFwaSc7XG5pbXBvcnQgVGVzdFJ1bkJyaWRnZSBmcm9tICcuL3JlcXVlc3QtcGlwZWxpbmUvdGVzdC1ydW4tYnJpZGdlJztcblxuY29uc3QgUkVTUE9OU0VfUkVNT1ZFRF9IRUFERVJTID0gW1xuICAgICdjcm9zcy1vcmlnaW4tZW1iZWRkZXItcG9saWN5JyxcbiAgICAnY3Jvc3Mtb3JpZ2luLW9wZW5lci1wb2xpY3knLFxuICAgICdjcm9zcy1vcmlnaW4tcmVzb3VyY2UtcG9saWN5Jyxcbl07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc291cmNlSW5qZWN0b3Ige1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3NwZWNpYWxTZXJ2aWNlUm91dGVzOiBTcGVjaWFsU2VydmljZVJvdXRlcztcbiAgICBwcml2YXRlIHJlYWRvbmx5IF90ZXN0UnVuQnJpZGdlOiBUZXN0UnVuQnJpZGdlO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yICh0ZXN0UnVuQnJpZGdlOiBUZXN0UnVuQnJpZGdlLCBzcGVjaWFsU2VydmljZVJvdXRlczogU3BlY2lhbFNlcnZpY2VSb3V0ZXMpIHtcbiAgICAgICAgdGhpcy5fc3BlY2lhbFNlcnZpY2VSb3V0ZXMgPSBzcGVjaWFsU2VydmljZVJvdXRlcztcbiAgICAgICAgdGhpcy5fdGVzdFJ1bkJyaWRnZSAgICAgICAgPSB0ZXN0UnVuQnJpZGdlO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dldFJlc3RvcmVDb250ZXh0U3RvcmFnZVNjcmlwdCAoY29udGV4dFN0b3JhZ2U/OiBTZXNzaW9uU3RvcmFnZUluZm8gfCBudWxsKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgY3VycmVudFRlc3RSdW4gPSB0aGlzLl90ZXN0UnVuQnJpZGdlLmdldEN1cnJlbnRUZXN0UnVuKCk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gSlNPTi5zdHJpbmdpZnkoY29udGV4dFN0b3JhZ2U/LltjdXJyZW50VGVzdFJ1bi5pZF0gfHwgJycpO1xuXG4gICAgICAgIHJldHVybiBgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdywgJyVwcm94eWxlc3NDb250ZXh0U3RvcmFnZSUnLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6ICR7dmFsdWV9IH0pO2A7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0UmVzdG9yZVN0b3JhZ2VzU2NyaXB0IChyZXN0b3JpbmdTdG9yYWdlczogU3RvcmFnZXNTbmFwc2hvdCB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICAgICAgICBpZiAoIXJlc3RvcmluZ1N0b3JhZ2VzKVxuICAgICAgICAgICAgcmV0dXJuICcoZnVuY3Rpb24oKSB7fSkoKSc7XG5cbiAgICAgICAgcmV0dXJuIGAoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLmNsZWFyKCk7XG4gICAgICAgICAgICB3aW5kb3cuc2Vzc2lvblN0b3JhZ2UuY2xlYXIoKTtcblxuICAgICAgICAgICAgY29uc3Qgc25hcHNob3QgPSAke0pTT04uc3RyaW5naWZ5KHJlc3RvcmluZ1N0b3JhZ2VzKX07XG4gICAgICAgICAgICBjb25zdCBscyAgICAgICA9IEpTT04ucGFyc2Uoc25hcHNob3QubG9jYWxTdG9yYWdlKTtcbiAgICAgICAgICAgIGNvbnN0IHNzICAgICAgID0gSlNPTi5wYXJzZShzbmFwc2hvdC5zZXNzaW9uU3RvcmFnZSk7XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbHNbMF0ubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKGxzWzBdW2ldLCBsc1sxXVtpXSk7XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3NbMF0ubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgd2luZG93LnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oc3NbMF1baV0sIHNzWzFdW2ldKTtcbiAgICAgICAgfSkoKTtcbiAgICAgICAgYDtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9yZXNvbHZlUmVsYXRpdmVVcmxzIChwcm94eTogUHJveHksIHJlbGF0aXZlVXJsczogc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gICAgICAgIHJldHVybiByZWxhdGl2ZVVybHMubWFwKHVybCA9PiBwcm94eS5yZXNvbHZlUmVsYXRpdmVTZXJ2aWNlVXJsKHVybCkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX3ByZXBhcmVJbmplY3RhYmxlUmVzb3VyY2VzICh7IGlzSWZyYW1lLCByZXN0b3JpbmdTdG9yYWdlcywgY29udGV4dFN0b3JhZ2UsIHVzZXJTY3JpcHRzIH06IEluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zKTogUHJvbWlzZTxQYWdlSW5qZWN0YWJsZVJlc291cmNlcyB8IG51bGw+IHtcbiAgICAgICAgaWYgKCF0aGlzLl90ZXN0UnVuQnJpZGdlLmdldEN1cnJlbnRUZXN0UnVuKCkpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICBjb25zdCB0YXNrU2NyaXB0ID0gYXdhaXQgdGhpcy5fdGVzdFJ1bkJyaWRnZS5nZXRUYXNrU2NyaXB0KHsgaXNJZnJhbWUsIHJlc3RvcmluZ1N0b3JhZ2VzLCBjb250ZXh0U3RvcmFnZSwgdXNlclNjcmlwdHMgfSk7XG4gICAgICAgIGNvbnN0IHByb3h5ICAgICAgPSB0aGlzLl90ZXN0UnVuQnJpZGdlLmdldEJyb3dzZXJDb25uZWN0aW9uKCkuYnJvd3NlckNvbm5lY3Rpb25HYXRld2F5LnByb3h5O1xuXG4gICAgICAgIGNvbnN0IGluamVjdGFibGVSZXNvdXJjZXMgPSB7XG4gICAgICAgICAgICBzdHlsZXNoZWV0czogW1xuICAgICAgICAgICAgICAgIFRFU1RDQUZFX1VJX1NUWUxFUyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBzY3JpcHRzOiBbXG4gICAgICAgICAgICAgICAgLi4uSEFNTUVSSEVBRF9JTkpFQ1RBQkxFX1NDUklQVFMubWFwKGhzID0+IGdldEFzc2V0UGF0aChocywgcHJveHkub3B0aW9ucy5kZXZlbG9wbWVudE1vZGUpKSxcbiAgICAgICAgICAgICAgICAuLi5TQ1JJUFRTLm1hcChzID0+IGdldEFzc2V0UGF0aChzLCBwcm94eS5vcHRpb25zLmRldmVsb3BtZW50TW9kZSkpLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGVtYmVkZGVkU2NyaXB0czogWyB0aGlzLl9nZXRSZXN0b3JlU3RvcmFnZXNTY3JpcHQocmVzdG9yaW5nU3RvcmFnZXMpLCB0aGlzLl9nZXRSZXN0b3JlQ29udGV4dFN0b3JhZ2VTY3JpcHQoY29udGV4dFN0b3JhZ2UpLCB0YXNrU2NyaXB0XSxcbiAgICAgICAgICAgIHVzZXJTY3JpcHRzOiAgICAgdXNlclNjcmlwdHMgfHwgW10sXG4gICAgICAgIH07XG5cbiAgICAgICAgaW5qZWN0YWJsZVJlc291cmNlcy5zY3JpcHRzICAgICA9IHRoaXMuX3Jlc29sdmVSZWxhdGl2ZVVybHMocHJveHksIGluamVjdGFibGVSZXNvdXJjZXMuc2NyaXB0cyk7XG4gICAgICAgIGluamVjdGFibGVSZXNvdXJjZXMudXNlclNjcmlwdHMgPSB0aGlzLl9yZXNvbHZlUmVsYXRpdmVVcmxzKHByb3h5LCBpbmplY3RhYmxlUmVzb3VyY2VzLnVzZXJTY3JpcHRzKTtcbiAgICAgICAgaW5qZWN0YWJsZVJlc291cmNlcy5zdHlsZXNoZWV0cyA9IHRoaXMuX3Jlc29sdmVSZWxhdGl2ZVVybHMocHJveHksIGluamVjdGFibGVSZXNvdXJjZXMuc3R5bGVzaGVldHMpO1xuXG4gICAgICAgIHJldHVybiBpbmplY3RhYmxlUmVzb3VyY2VzO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3Byb2Nlc3NSZXNwb25zZUhlYWRlcnMgKGhlYWRlcnM6IEhlYWRlckVudHJ5W10gfCB1bmRlZmluZWQpOiBIZWFkZXJFbnRyeVtdIHtcbiAgICAgICAgaWYgKCFoZWFkZXJzKVxuICAgICAgICAgICAgcmV0dXJuIFtdO1xuXG4gICAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLmZpbHRlcihoZWFkZXIgPT4gIVJFU1BPTlNFX1JFTU9WRURfSEVBREVSUy5pbmNsdWRlcyhoZWFkZXIubmFtZS50b0xvd2VyQ2FzZSgpKSk7XG5cbiAgICAgICAgcmV0dXJuIHN0cmluZ2lmeUhlYWRlclZhbHVlcyhoZWFkZXJzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9mdWxmaWxsUmVxdWVzdCAoY2xpZW50OiBQcm90b2NvbEFwaSwgZnVsZmlsbFJlcXVlc3RJbmZvOiBGdWxmaWxsUmVxdWVzdFJlcXVlc3QsIGJvZHk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCBzYWZlRnVsZmlsbFJlcXVlc3QoY2xpZW50LCB7XG4gICAgICAgICAgICByZXF1ZXN0SWQ6ICAgICAgIGZ1bGZpbGxSZXF1ZXN0SW5mby5yZXF1ZXN0SWQsXG4gICAgICAgICAgICByZXNwb25zZUNvZGU6ICAgIGZ1bGZpbGxSZXF1ZXN0SW5mby5yZXNwb25zZUNvZGUgfHwgU3RhdHVzQ29kZXMuT0ssXG4gICAgICAgICAgICByZXNwb25zZVBocmFzZTogIGZ1bGZpbGxSZXF1ZXN0SW5mby5yZXNwb25zZVBocmFzZSxcbiAgICAgICAgICAgIHJlc3BvbnNlSGVhZGVyczogdGhpcy5fcHJvY2Vzc1Jlc3BvbnNlSGVhZGVycyhmdWxmaWxsUmVxdWVzdEluZm8ucmVzcG9uc2VIZWFkZXJzKSxcbiAgICAgICAgICAgIGJvZHk6ICAgICAgICAgICAgdG9CYXNlNjRTdHJpbmcoYm9keSksXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyByZWRpcmVjdFRvRXJyb3JQYWdlIChjbGllbnQ6IFByb3RvY29sQXBpLCBlcnI6IEVycm9yLCB1cmw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBjdXJyZW50VGVzdFJ1biA9IHRoaXMuX3Rlc3RSdW5CcmlkZ2UuZ2V0Q3VycmVudFRlc3RSdW4oKTtcblxuICAgICAgICBpZiAoIWN1cnJlbnRUZXN0UnVuKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGN1cnJlbnRUZXN0UnVuLnBlbmRpbmdQYWdlRXJyb3IgPSBuZXcgUGFnZUxvYWRFcnJvcihlcnIsIHVybCk7XG5cbiAgICAgICAgYXdhaXQgbmF2aWdhdGVUbyhjbGllbnQsIHRoaXMuX3NwZWNpYWxTZXJ2aWNlUm91dGVzLmVycm9yUGFnZTEpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXREb2N1bWVudFJlc291cmNlSW5mbyAoZXZlbnQ6IFJlcXVlc3RQYXVzZWRFdmVudCwgY2xpZW50OiBQcm90b2NvbEFwaSk6IFByb21pc2U8RG9jdW1lbnRSZXNvdXJjZUluZm8+IHtcbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgcmVxdWVzdElkLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIHJlc3BvbnNlRXJyb3JSZWFzb24sXG4gICAgICAgICAgICByZXNvdXJjZVR5cGUsXG4gICAgICAgIH0gPSBldmVudDtcblxuICAgICAgICBpZiAocmVzb3VyY2VUeXBlICE9PSAnRG9jdW1lbnQnKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGVycm9yOiBudWxsLFxuICAgICAgICAgICAgICAgIGJvZHk6ICBudWxsLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2VFcnJvclJlYXNvbiA9PT0gJ05hbWVOb3RSZXNvbHZlZCcpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgRXJyb3IoYEZhaWxlZCB0byBmaW5kIGEgRE5TLXJlY29yZCBmb3IgdGhlIHJlc291cmNlIGF0IFwiJHtldmVudC5yZXF1ZXN0LnVybH1cImApO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVycixcbiAgICAgICAgICAgICAgICAgICAgYm9keTogIG51bGwsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2VPYmogPSBhd2FpdCBjbGllbnQuRmV0Y2guZ2V0UmVzcG9uc2VCb2R5KHsgcmVxdWVzdElkIH0pO1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2VTdHIgPSBnZXRSZXNwb25zZUFzU3RyaW5nKHJlc3BvbnNlT2JqKTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBlcnJvcjogbnVsbCxcbiAgICAgICAgICAgICAgICBib2R5OiAgQnVmZmVyLmZyb20ocmVzcG9uc2VTdHIpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICByZXNvdXJjZUluamVjdG9yTG9nZ2VyKCdGYWlsZWQgdG8gcHJvY2VzcyByZXF1ZXN0OiAlcycsIHJlcXVlc3QudXJsKTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyLFxuICAgICAgICAgICAgICAgIGJvZHk6ICBudWxsLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBwcm9jZXNzQWJvdXRCbGFua1BhZ2UgKGV2ZW50OiBGcmFtZU5hdmlnYXRlZEV2ZW50LCB1c2VyU2NyaXB0czogc3RyaW5nW10sIGNsaWVudDogUHJvdG9jb2xBcGkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmVzb3VyY2VJbmplY3RvckxvZ2dlcignSGFuZGxlIHBhZ2UgYXMgYWJvdXQ6YmxhbmsuIE9yaWdpbiB1cmw6ICVzJywgZXZlbnQuZnJhbWUudXJsKTtcblxuICAgICAgICBjb25zdCBpbmplY3RhYmxlUmVzb3VyY2VzID0gYXdhaXQgdGhpcy5fcHJlcGFyZUluamVjdGFibGVSZXNvdXJjZXMoeyBpc0lmcmFtZTogZmFsc2UsIHVzZXJTY3JpcHRzIH0pIGFzIFBhZ2VJbmplY3RhYmxlUmVzb3VyY2VzO1xuICAgICAgICBjb25zdCBodG1sICAgICAgICAgICAgICAgID0gaW5qZWN0UmVzb3VyY2VzKEVNUFRZX1BBR0VfTUFSS1VQLCBpbmplY3RhYmxlUmVzb3VyY2VzKTtcblxuICAgICAgICBhd2FpdCBjbGllbnQuUGFnZS5zZXREb2N1bWVudENvbnRlbnQoe1xuICAgICAgICAgICAgZnJhbWVJZDogZXZlbnQuZnJhbWUuaWQsXG4gICAgICAgICAgICBodG1sLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcHJvY2Vzc0hUTUxQYWdlQ29udGVudCAoZnVsZmlsbFJlcXVlc3RJbmZvOiBGdWxmaWxsUmVxdWVzdFJlcXVlc3QsIGluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zOiBJbmplY3RhYmxlUmVzb3VyY2VzT3B0aW9ucywgY2xpZW50OiBQcm90b2NvbEFwaSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBpbmplY3RhYmxlUmVzb3VyY2VzID0gYXdhaXQgdGhpcy5fcHJlcGFyZUluamVjdGFibGVSZXNvdXJjZXMoaW5qZWN0YWJsZVJlc291cmNlc09wdGlvbnMpO1xuXG4gICAgICAgIC8vIE5PVEU6IGFuIHVuaGFuZGxlZCBleGNlcHRpb24gaW50ZXJydXB0cyB0aGUgdGVzdCBleGVjdXRpb24sXG4gICAgICAgIC8vIGFuZCB3ZSBhcmUgZm9yY2UgdG8gcmVkaXJlY3QgbWFudWFsbHkgdG8gdGhlIGlkbGUgcGFnZS5cbiAgICAgICAgaWYgKCFpbmplY3RhYmxlUmVzb3VyY2VzKVxuICAgICAgICAgICAgYXdhaXQgcmVkaXJlY3QoY2xpZW50LCBmdWxmaWxsUmVxdWVzdEluZm8ucmVxdWVzdElkLCB0aGlzLl9zcGVjaWFsU2VydmljZVJvdXRlcy5pZGxlUGFnZSk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlZFJlc3BvbnNlU3RyID0gaW5qZWN0UmVzb3VyY2VzKFxuICAgICAgICAgICAgICAgIGZ1bGZpbGxSZXF1ZXN0SW5mby5ib2R5IGFzIHN0cmluZyxcbiAgICAgICAgICAgICAgICBpbmplY3RhYmxlUmVzb3VyY2VzLFxuICAgICAgICAgICAgICAgIHRoaXMuX2dldFBhZ2VJbmplY3RhYmxlUmVzb3VyY2VzT3B0aW9ucyhpbmplY3RhYmxlUmVzb3VyY2VzT3B0aW9ucyksXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9mdWxmaWxsUmVxdWVzdChjbGllbnQsIGZ1bGZpbGxSZXF1ZXN0SW5mbywgdXBkYXRlZFJlc3BvbnNlU3RyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBwcm9jZXNzTm9uUHJveGllZENvbnRlbnQgKGZ1bGZpbGxSZXF1ZXN0SW5mbzogRnVsZmlsbFJlcXVlc3RSZXF1ZXN0LCBjbGllbnQ6IFByb3RvY29sQXBpKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuX2Z1bGZpbGxSZXF1ZXN0KGNsaWVudCwgZnVsZmlsbFJlcXVlc3RJbmZvLCBmdWxmaWxsUmVxdWVzdEluZm8uYm9keSBhcyBzdHJpbmcpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dldFBhZ2VJbmplY3RhYmxlUmVzb3VyY2VzT3B0aW9ucyAoaW5qZWN0YWJsZVJlc291cmNlc09wdGlvbnM6IEluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zKTogUGFnZVJlc3RvcmVTdG9yYWdlc09wdGlvbnMgfCB1bmRlZmluZWQge1xuICAgICAgICBjb25zdCB7IHVybCwgcmVzdG9yaW5nU3RvcmFnZXMgfSA9IGluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zO1xuXG4gICAgICAgIGlmICh1cmwgJiYgcmVzdG9yaW5nU3RvcmFnZXMpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgaG9zdDogICAgICBuZXcgVVJMKHVybCkuaG9zdCxcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuX3Rlc3RSdW5CcmlkZ2UuZ2V0U2Vzc2lvbklkKCksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHZvaWQgMDtcbiAgICB9XG59XG4iXX0=