wdio-lambdatest-service
Version:
A WebdriverIO service that manages tunnel and job metadata for LambdaTest.
426 lines • 59.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
require("source-map-support/register");
var _logger = _interopRequireDefault(require("@wdio/logger"));
var _util = require("./util.js");
var _constants = require("./constants.js");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const log = (0, _logger.default)('@wdio/lambdatest-service');
const DEFAULT_OPTIONS = {
setSessionName: true,
setSessionStatus: true,
ignoreTestCountInName: false
};
class LambdaRestService {
constructor(options = {}, capabilities = {}, config = {}) {
var _this$_config, _this$_config2;
_defineProperty(this, "_api", void 0);
_defineProperty(this, "_browser", void 0);
_defineProperty(this, "_capabilities", void 0);
_defineProperty(this, "_config", void 0);
_defineProperty(this, "_failReasons", []);
_defineProperty(this, "_failures", 0);
_defineProperty(this, "_retryFailures", 0);
_defineProperty(this, "_failureStatuses", ['failed', 'ambiguous', 'undefined', 'unknown']);
_defineProperty(this, "_fullTitle", void 0);
_defineProperty(this, "_isServiceEnabled", true);
_defineProperty(this, "_options", DEFAULT_OPTIONS);
_defineProperty(this, "_scenariosThatRan", []);
_defineProperty(this, "_specsRan", false);
_defineProperty(this, "_suiteTitle", void 0);
_defineProperty(this, "_testCnt", 0);
_defineProperty(this, "_testTitle", void 0);
_defineProperty(this, "_error", void 0);
_defineProperty(this, "_ltErrorRemark", void 0);
_defineProperty(this, "_useScenarioName", void 0);
_defineProperty(this, "_lambdaCredentials", void 0);
_defineProperty(this, "_currentTestTitle", void 0);
_defineProperty(this, "_lastReloadedSession", void 0);
this._options = {
...DEFAULT_OPTIONS,
...options
};
this._capabilities = capabilities;
this._config = config;
this._testCnt = 0;
this._failures = 0;
const strict = Boolean(((_this$_config = this._config) === null || _this$_config === void 0 ? void 0 : _this$_config.cucumberOpts) && ((_this$_config2 = this._config) === null || _this$_config2 === void 0 || (_this$_config2 = _this$_config2.cucumberOpts) === null || _this$_config2 === void 0 ? void 0 : _this$_config2.strict));
if (strict) {
this._failureStatuses.push('pending');
}
}
before(caps, specs, browser) {
this._browser = browser;
this._scenariosThatRan = [];
}
beforeSession(config, capabilities) {
this._config = {
...this._config,
...config
};
this._capabilities = {
...this._capabilities,
...capabilities
};
const lambdaCredentials = {
username: this._config.user,
accessKey: this._config.key,
isApp: false
};
if (this._config.product === 'appAutomation') {
lambdaCredentials.isApp = true;
}
if (this._config.logFile) {
lambdaCredentials.logFile = this._config.logFile;
}
if (this._config.ltErrorRemark === true) {
this._ltErrorRemark = true;
}
if (this._config.useScenarioName === true) {
this._useScenarioName = true;
}
this._isServiceEnabled = lambdaCredentials.username && lambdaCredentials.accessKey;
this._lambdaCredentials = lambdaCredentials;
}
async beforeScenario(world, context) {
if (this._useScenarioName) {
var _world$pickle;
this._testTitle = (world === null || world === void 0 || (_world$pickle = world.pickle) === null || _world$pickle === void 0 ? void 0 : _world$pickle.name) || 'unknown scenario';
} else if (!this._suiteTitle) {
var _world$gherkinDocumen, _context$document, _world$pickle2;
this._suiteTitle = (world === null || world === void 0 || (_world$gherkinDocumen = world.gherkinDocument) === null || _world$gherkinDocumen === void 0 || (_world$gherkinDocumen = _world$gherkinDocumen.feature) === null || _world$gherkinDocumen === void 0 ? void 0 : _world$gherkinDocumen.name) || (context === null || context === void 0 || (_context$document = context.document) === null || _context$document === void 0 || (_context$document = _context$document.feature) === null || _context$document === void 0 ? void 0 : _context$document.name) || (world === null || world === void 0 || (_world$pickle2 = world.pickle) === null || _world$pickle2 === void 0 ? void 0 : _world$pickle2.name) || 'unknown scenario';
}
await this.setSessionName(this._testTitle || this._suiteTitle);
}
async beforeSuite(suite) {
this._suiteTitle = suite.title;
if (suite.title && suite.title !== 'Jasmine__TopLevel__Suite') {
await this.setSessionName(suite.title);
}
}
async beforeTest(test) {
if (!this._isServiceEnabled) {
return;
}
if (test && (test === null || test === void 0 ? void 0 : test.parent) !== undefined) {
this._currentTestTitle = test === null || test === void 0 ? void 0 : test.parent;
this._currentTestTitle = `${this._currentTestTitle} - ${test === null || test === void 0 ? void 0 : test.title}`;
} else if (test && (test === null || test === void 0 ? void 0 : test.fullName) !== undefined) {
this._currentTestTitle = test === null || test === void 0 ? void 0 : test.fullName;
}
if (test.title && !this._testTitle) {
this._testTitle = test.title;
}
let suiteTitle = this._suiteTitle;
if (test.fullName) {
const testSuiteName = test.fullName;
if (this._suiteTitle === 'Jasmine__TopLevel__Suite') {
suiteTitle = testSuiteName;
} else if (this._suiteTitle) {
suiteTitle = (0, _util.getParentSuiteName)(this._suiteTitle, testSuiteName);
}
}
await this.setSessionName(suiteTitle, test);
}
async beforeFeature(uri, feature) {
this._suiteTitle = feature.name;
await this.setSessionName(this._suiteTitle);
}
async beforeStep(step) {
if (!this._suiteTitle || this._suiteTitle == 'unknown scenario') {
var _step$document, _step$step;
this._suiteTitle = ((_step$document = step.document) === null || _step$document === void 0 || (_step$document = _step$document.feature) === null || _step$document === void 0 ? void 0 : _step$document.name) || ((_step$step = step.step) === null || _step$step === void 0 || (_step$step = _step$step.scenario) === null || _step$step === void 0 ? void 0 : _step$step.name) || 'unknown scenario';
await this.setSessionName(this._suiteTitle);
}
}
afterSuite(suite) {
if (Object.prototype.hasOwnProperty.call(suite, 'error')) {
++this._failures;
}
}
afterTest(test, context, {
error,
passed
}) {
this._specsRan = true;
if (test._retriedTest && passed) {
--this._failures;
this._retryFailures = 0;
return;
}
if (test._retriedTest && !passed && typeof test._currentRetry === 'number' && typeof test._retries === 'number' && test._currentRetry < test._retries) {
++this._retryFailures;
return;
}
const isJasminePendingError = typeof error === 'string' && error.includes('marked Pending');
if (!passed && !isJasminePendingError) {
++this._failures;
++this._retryFailures;
this._failReasons.push(error && error.message || 'Unknown Error');
this._error = (error === null || error === void 0 ? void 0 : error.message) || 'Unknown Error';
if (this._ltErrorRemark && this._error !== null && this._error !== undefined) {
this._setSessionRemarks(this._error);
}
}
}
afterScenario(world, result) {
var _world$result;
const {
passed
} = result || {};
this._specsRan = true;
const status = (_world$result = world.result) === null || _world$result === void 0 ? void 0 : _world$result.status.toLowerCase();
if (status !== 'skipped') {
this._scenariosThatRan.push(world.pickle.name || 'unknown pickle name');
}
if (status && this._failureStatuses.includes(status)) {
const exception = world.result && world.result.message || (status === 'pending' ? `Some steps/hooks are pending for scenario "${world.pickle.name}"` : 'Unknown Error');
++this._failures;
this._failReasons.push(exception);
} else if (typeof passed !== 'undefined' && !passed) {
++this._failures;
}
}
after(result) {
if (!this._isServiceEnabled) {
return;
}
let failures = this._failures;
if (this._config.mochaOpts && this._config.mochaOpts.bail && Boolean(result)) {
failures = 1;
}
if (result === 0) {
failures = 0;
}
const {
preferScenarioName
} = this._options;
if (preferScenarioName && this._scenariosThatRan.length === 1) {
this._fullTitle = this._scenariosThatRan.pop();
}
const status = 'status: ' + (result > 0 ? 'failed' : 'passed');
if (!this._browser.isMultiremote) {
log.info(`Update job with sessionId ${this._browser.sessionId}, ${status}`);
if (process.env.LOG_SESSION_URL === "true") {
const sessionURL = this.getSessionURL(this._browser.sessionId, this._config.product);
log.info(`Session URL: ${sessionURL}`);
}
if (this._lastReloadedSession == this._browser.sessionId) {
return this._update({
sessionId: this._browser.sessionId,
failures: failures
});
}
return this._update({
sessionId: this._browser.sessionId,
failures: result
});
}
return Promise.all(Object.keys(this._capabilities).map(browserName => {
log.info(`Update multiremote job for browser '${browserName}' and sessionId ${this._browser[browserName].sessionId}, ${status}`);
if (process.env.LOG_SESSION_URL === "true") {
const sessionURL = this.getSessionURL(this._browser[browserName].sessionId, this._config.product);
log.info(`Session URL for ${browserName}: ${sessionURL}`);
}
return this._update({
sessionId: this._browser[browserName].sessionId,
failures: failures,
calledOnReload: false,
browserName: browserName
});
}));
}
async onReload(oldSessionId, newSessionId) {
this._lastReloadedSession = newSessionId;
if (!this._isServiceEnabled) {
return;
}
const status = this._failures > 0 || this._retryFailures > 0 ? 'failed' : 'passed';
if (!this._browser.isMultiremote) {
log.info(`Update (reloaded) job with sessionId ${oldSessionId}, ${status}`);
if (process.env.LOG_SESSION_URL === "true") {
const sessionURL = this.getSessionURL(this._browser.sessionId, this._config.product);
log.info(`Session URL: ${sessionURL}`);
}
await this._update({
sessionId: oldSessionId,
fullTitle: this._fullTitle,
status: status,
calledOnReload: true
});
} else {
const browserName = this._browser.instances.filter(browserName => this._browser[browserName].sessionId === newSessionId)[0];
log.info(`Update (reloaded) multiremote job for browser '${browserName}' and sessionId ${oldSessionId}, ${status}`);
if (process.env.LOG_SESSION_URL === "true") {
const sessionURL = this.getSessionURL(this._browser[browserName].sessionId, this._config.product);
log.info(`Session URL for ${browserName}: ${sessionURL}`);
}
await this._update({
sessionId: oldSessionId,
failures: this._failures,
calledOnReload: true,
browserName: browserName
});
}
this._failReasons = [];
this._scenariosThatRan = [];
delete this._fullTitle;
}
async _update({
sessionId,
fullTitle,
status,
failures,
calledOnReload = false,
browserName
}) {
if (!this._options.setSessionStatus) {
return;
}
const sleep = ms => new Promise(r => setTimeout(r, ms));
await sleep(5000);
if (calledOnReload) {
return await this.updateJob({
sessionId,
fullTitle,
status,
calledOnReload,
browserName
});
}
return await this.updateJob({
sessionId,
_failures: failures,
calledOnReload,
browserName
});
}
async updateJob({
sessionId,
fullTitle,
status,
_failures,
calledOnReload = false,
browserName
}) {
let body;
if (calledOnReload) {
body = this.getBody({
fullTitle,
status,
calledOnReload,
browserName
});
} else {
body = this.getBody({
_failures,
calledOnReload,
browserName
});
}
try {
await (0, _util.updateSessionById)(sessionId, body, this._lambdaCredentials);
} catch (ex) {
console.log(ex);
}
this._failures = 0;
this._retryFailures = 0;
}
getBody({
fullTitle,
status,
_failures,
calledOnReload = false,
browserName
}) {
let body = {};
if (!(!this._browser.isMultiremote && this._capabilities.name || this._browser.isMultiremote && this._capabilities[browserName].capabilities.name)) {
body.name = this._fullTitle;
if (calledOnReload) {
body.name = fullTitle;
}
if (this._capabilities['LT:Options'] && this._capabilities['LT:Options'].name) {
body.name = this._capabilities['LT:Options'].name;
}
if (browserName) {
body.name = `${browserName}: ${body.name}`;
}
if (calledOnReload || this._testCnt) {
let testCnt = ++this._testCnt;
if (this._browser.isMultiremote) {
testCnt = Math.ceil(testCnt / this._browser.instances.length);
}
if (!calledOnReload && !this._options.ignoreTestCountInName) {
body.name += ` (${testCnt})`;
}
}
}
body.status_ind = _failures > 0 ? 'failed' : 'passed';
if (calledOnReload) {
body.status_ind = status;
}
return body;
}
async setSessionName(suiteTitle, test) {
if (!this._options.setSessionName || !suiteTitle) {
return;
}
let name = this._useScenarioName && this._testTitle ? this._testTitle : suiteTitle;
if (this._options.sessionNameFormat) {
name = this._options.sessionNameFormat(this._config, this._capabilities, suiteTitle, test === null || test === void 0 ? void 0 : test.title);
} else if (test && !test.fullName) {
const pre = this._options.sessionNamePrependTopLevelSuiteTitle ? `${suiteTitle} - ` : '';
const post = !this._options.sessionNameOmitTestTitle ? ` - ${test.title}` : '';
name = `${pre}${test.parent}${post}`;
}
if (name !== this._fullTitle) {
this._fullTitle = name;
await this._setSessionName(name);
}
}
async _setSessionRemarks(err) {
try {
const hookObject = {
action: "setTestStatus",
arguments: {
status: "failed",
remark: err
}
};
const errorCustom = `lambda-hook: ${JSON.stringify(hookObject)}`;
await this._browser.executeScript(errorCustom.toString(), []);
} catch (error) {
console.log("Error setting session remarks:", error);
}
}
async _setSessionName(sessionName) {
await this._executeCommand(`lambda-name=${sessionName}`);
}
async _executeCommand(cmd) {
if (!this._browser) {
return;
}
if (this._browser.isMultiremote) {
return Promise.all(Object.keys(this._capabilities).map(async browserName => {
const browser = this._browser[browserName];
return await browser.executeScript(cmd.toString(), []);
}));
}
return await this._browser.executeScript(cmd.toString(), []);
}
getSessionURL(sessionId, product) {
if (product === 'appAutomation') {
return `${_constants.appSessionURL}=${sessionId}`;
}
return `${_constants.webSessionURL}=${sessionId}`;
}
}
exports.default = LambdaRestService;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9nZ2VyIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfdXRpbCIsIl9jb25zdGFudHMiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJfZGVmaW5lUHJvcGVydHkiLCJyIiwidCIsIl90b1Byb3BlcnR5S2V5IiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJ2YWx1ZSIsImVudW1lcmFibGUiLCJjb25maWd1cmFibGUiLCJ3cml0YWJsZSIsImkiLCJfdG9QcmltaXRpdmUiLCJTeW1ib2wiLCJ0b1ByaW1pdGl2ZSIsImNhbGwiLCJUeXBlRXJyb3IiLCJTdHJpbmciLCJOdW1iZXIiLCJsb2ciLCJsb2dnZXIiLCJERUZBVUxUX09QVElPTlMiLCJzZXRTZXNzaW9uTmFtZSIsInNldFNlc3Npb25TdGF0dXMiLCJpZ25vcmVUZXN0Q291bnRJbk5hbWUiLCJMYW1iZGFSZXN0U2VydmljZSIsImNvbnN0cnVjdG9yIiwib3B0aW9ucyIsImNhcGFiaWxpdGllcyIsImNvbmZpZyIsIl90aGlzJF9jb25maWciLCJfdGhpcyRfY29uZmlnMiIsIl9vcHRpb25zIiwiX2NhcGFiaWxpdGllcyIsIl9jb25maWciLCJfdGVzdENudCIsIl9mYWlsdXJlcyIsInN0cmljdCIsIkJvb2xlYW4iLCJjdWN1bWJlck9wdHMiLCJfZmFpbHVyZVN0YXR1c2VzIiwicHVzaCIsImJlZm9yZSIsImNhcHMiLCJzcGVjcyIsImJyb3dzZXIiLCJfYnJvd3NlciIsIl9zY2VuYXJpb3NUaGF0UmFuIiwiYmVmb3JlU2Vzc2lvbiIsImxhbWJkYUNyZWRlbnRpYWxzIiwidXNlcm5hbWUiLCJ1c2VyIiwiYWNjZXNzS2V5Iiwia2V5IiwiaXNBcHAiLCJwcm9kdWN0IiwibG9nRmlsZSIsImx0RXJyb3JSZW1hcmsiLCJfbHRFcnJvclJlbWFyayIsInVzZVNjZW5hcmlvTmFtZSIsIl91c2VTY2VuYXJpb05hbWUiLCJfaXNTZXJ2aWNlRW5hYmxlZCIsIl9sYW1iZGFDcmVkZW50aWFscyIsImJlZm9yZVNjZW5hcmlvIiwid29ybGQiLCJjb250ZXh0IiwiX3dvcmxkJHBpY2tsZSIsIl90ZXN0VGl0bGUiLCJwaWNrbGUiLCJuYW1lIiwiX3N1aXRlVGl0bGUiLCJfd29ybGQkZ2hlcmtpbkRvY3VtZW4iLCJfY29udGV4dCRkb2N1bWVudCIsIl93b3JsZCRwaWNrbGUyIiwiZ2hlcmtpbkRvY3VtZW50IiwiZmVhdHVyZSIsImRvY3VtZW50IiwiYmVmb3JlU3VpdGUiLCJzdWl0ZSIsInRpdGxlIiwiYmVmb3JlVGVzdCIsInRlc3QiLCJwYXJlbnQiLCJ1bmRlZmluZWQiLCJfY3VycmVudFRlc3RUaXRsZSIsImZ1bGxOYW1lIiwic3VpdGVUaXRsZSIsInRlc3RTdWl0ZU5hbWUiLCJnZXRQYXJlbnRTdWl0ZU5hbWUiLCJiZWZvcmVGZWF0dXJlIiwidXJpIiwiYmVmb3JlU3RlcCIsInN0ZXAiLCJfc3RlcCRkb2N1bWVudCIsIl9zdGVwJHN0ZXAiLCJzY2VuYXJpbyIsImFmdGVyU3VpdGUiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImFmdGVyVGVzdCIsImVycm9yIiwicGFzc2VkIiwiX3NwZWNzUmFuIiwiX3JldHJpZWRUZXN0IiwiX3JldHJ5RmFpbHVyZXMiLCJfY3VycmVudFJldHJ5IiwiX3JldHJpZXMiLCJpc0phc21pbmVQZW5kaW5nRXJyb3IiLCJpbmNsdWRlcyIsIl9mYWlsUmVhc29ucyIsIm1lc3NhZ2UiLCJfZXJyb3IiLCJfc2V0U2Vzc2lvblJlbWFya3MiLCJhZnRlclNjZW5hcmlvIiwicmVzdWx0IiwiX3dvcmxkJHJlc3VsdCIsInN0YXR1cyIsInRvTG93ZXJDYXNlIiwiZXhjZXB0aW9uIiwiYWZ0ZXIiLCJmYWlsdXJlcyIsIm1vY2hhT3B0cyIsImJhaWwiLCJwcmVmZXJTY2VuYXJpb05hbWUiLCJsZW5ndGgiLCJfZnVsbFRpdGxlIiwicG9wIiwiaXNNdWx0aXJlbW90ZSIsImluZm8iLCJzZXNzaW9uSWQiLCJwcm9jZXNzIiwiZW52IiwiTE9HX1NFU1NJT05fVVJMIiwic2Vzc2lvblVSTCIsImdldFNlc3Npb25VUkwiLCJfbGFzdFJlbG9hZGVkU2Vzc2lvbiIsIl91cGRhdGUiLCJQcm9taXNlIiwiYWxsIiwia2V5cyIsIm1hcCIsImJyb3dzZXJOYW1lIiwiY2FsbGVkT25SZWxvYWQiLCJvblJlbG9hZCIsIm9sZFNlc3Npb25JZCIsIm5ld1Nlc3Npb25JZCIsImZ1bGxUaXRsZSIsImluc3RhbmNlcyIsImZpbHRlciIsInNsZWVwIiwibXMiLCJzZXRUaW1lb3V0IiwidXBkYXRlSm9iIiwiYm9keSIsImdldEJvZHkiLCJ1cGRhdGVTZXNzaW9uQnlJZCIsImV4IiwiY29uc29sZSIsInRlc3RDbnQiLCJNYXRoIiwiY2VpbCIsInN0YXR1c19pbmQiLCJzZXNzaW9uTmFtZUZvcm1hdCIsInByZSIsInNlc3Npb25OYW1lUHJlcGVuZFRvcExldmVsU3VpdGVUaXRsZSIsInBvc3QiLCJzZXNzaW9uTmFtZU9taXRUZXN0VGl0bGUiLCJfc2V0U2Vzc2lvbk5hbWUiLCJlcnIiLCJob29rT2JqZWN0IiwiYWN0aW9uIiwiYXJndW1lbnRzIiwicmVtYXJrIiwiZXJyb3JDdXN0b20iLCJKU09OIiwic3RyaW5naWZ5IiwiZXhlY3V0ZVNjcmlwdCIsInRvU3RyaW5nIiwic2Vzc2lvbk5hbWUiLCJfZXhlY3V0ZUNvbW1hbmQiLCJjbWQiLCJhcHBTZXNzaW9uVVJMIiwid2ViU2Vzc2lvblVSTCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi9zcmMvc2VydmljZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbG9nZ2VyIGZyb20gJ0B3ZGlvL2xvZ2dlcidcblxuaW1wb3J0IHsgZ2V0UGFyZW50U3VpdGVOYW1lLCB1cGRhdGVTZXNzaW9uQnlJZCB9IGZyb20gJy4vdXRpbC5qcydcbmltcG9ydCB7IGFwcFNlc3Npb25VUkwsIHdlYlNlc3Npb25VUkwgfSBmcm9tICcuL2NvbnN0YW50cy5qcyc7XG5cbmNvbnN0IGxvZyA9IGxvZ2dlcignQHdkaW8vbGFtYmRhdGVzdC1zZXJ2aWNlJylcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vdHlwZXMuanMnKS5MVE9wdGlvbnMgJiBpbXBvcnQoJy4vdHlwZXMuanMnKS5TZXNzaW9uTmFtZU9wdGlvbnN9ICovXG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gIHNldFNlc3Npb25OYW1lOiB0cnVlLFxuICBzZXRTZXNzaW9uU3RhdHVzOiB0cnVlLFxuICBpZ25vcmVUZXN0Q291bnRJbk5hbWU6ZmFsc2UsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMYW1iZGFSZXN0U2VydmljZSB7XG4gIF9hcGk7XG4gIF9icm93c2VyO1xuICBfY2FwYWJpbGl0aWVzO1xuICBfY29uZmlnO1xuICBfZmFpbFJlYXNvbnMgPSBbXTtcbiAgX2ZhaWx1cmVzID0gMDtcbiAgX3JldHJ5RmFpbHVyZXMgPSAwO1xuICBfZmFpbHVyZVN0YXR1c2VzID0gWydmYWlsZWQnLCAnYW1iaWd1b3VzJywgJ3VuZGVmaW5lZCcsICd1bmtub3duJ107XG4gIF9mdWxsVGl0bGU7XG4gIF9pc1NlcnZpY2VFbmFibGVkID0gdHJ1ZTtcbiAgX29wdGlvbnMgPSBERUZBVUxUX09QVElPTlM7XG4gIF9zY2VuYXJpb3NUaGF0UmFuID0gW107XG4gIF9zcGVjc1JhbiA9IGZhbHNlO1xuICBfc3VpdGVUaXRsZTtcbiAgX3Rlc3RDbnQgPSAwO1xuICBfdGVzdFRpdGxlO1xuICBfZXJyb3I7XG4gIF9sdEVycm9yUmVtYXJrO1xuICBfdXNlU2NlbmFyaW9OYW1lO1xuICBfbGFtYmRhQ3JlZGVudGlhbHM7XG4gIF9jdXJyZW50VGVzdFRpdGxlO1xuICAvL2tlZXAgdHJhY2sgb2YgbGFzdCByZWxvYWRlZCBzZXNzaW9uIHdpdGhpbiBhIGxhcmdlciB0ZXN0LXN1aXRlXG4gIF9sYXN0UmVsb2FkZWRTZXNzaW9uO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSwgY2FwYWJpbGl0aWVzID0ge30sIGNvbmZpZyA9IHt9KSB7XG4gICAgdGhpcy5fb3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgdGhpcy5fY2FwYWJpbGl0aWVzID0gY2FwYWJpbGl0aWVzO1xuICAgIHRoaXMuX2NvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLl90ZXN0Q250ID0gMDtcbiAgICB0aGlzLl9mYWlsdXJlcyA9IDA7XG4gICAgLy8gQ3VjdW1iZXIgc3BlY2lmaWNcbiAgICBjb25zdCBzdHJpY3QgPSBCb29sZWFuKHRoaXMuX2NvbmZpZz8uY3VjdW1iZXJPcHRzICYmIHRoaXMuX2NvbmZpZz8uY3VjdW1iZXJPcHRzPy5zdHJpY3QpO1xuICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vY3VjdW1iZXIvY3VjdW1iZXItanMvYmxvYi9tYXN0ZXIvc3JjL3J1bnRpbWUvaW5kZXgudHMjTDEzNlxuICAgIGlmIChzdHJpY3QpIHtcbiAgICAgIHRoaXMuX2ZhaWx1cmVTdGF0dXNlcy5wdXNoKCdwZW5kaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgYmVmb3JlKGNhcHMsIHNwZWNzLCBicm93c2VyKSB7XG4gICAgdGhpcy5fYnJvd3NlciA9IGJyb3dzZXI7XG4gICAgdGhpcy5fc2NlbmFyaW9zVGhhdFJhbiA9IFtdO1xuICB9XG5cbiAgYmVmb3JlU2Vzc2lvbihjb25maWcsIGNhcGFiaWxpdGllcykge1xuICAgIHRoaXMuX2NvbmZpZyA9IHsgLi4udGhpcy5fY29uZmlnLCAuLi5jb25maWcgfTtcbiAgICB0aGlzLl9jYXBhYmlsaXRpZXMgPSB7IC4uLnRoaXMuX2NhcGFiaWxpdGllcywgLi4uY2FwYWJpbGl0aWVzIH07XG4gICAgY29uc3QgbGFtYmRhQ3JlZGVudGlhbHMgPSB7XG4gICAgICB1c2VybmFtZTogdGhpcy5fY29uZmlnLnVzZXIsXG4gICAgICBhY2Nlc3NLZXk6IHRoaXMuX2NvbmZpZy5rZXksXG4gICAgICBpc0FwcCA6IGZhbHNlXG4gICAgfTtcblxuICAgIGlmICh0aGlzLl9jb25maWcucHJvZHVjdCA9PT0gJ2FwcEF1dG9tYXRpb24nKSB7XG4gICAgICBsYW1iZGFDcmVkZW50aWFscy5pc0FwcCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2NvbmZpZy5sb2dGaWxlKSB7XG4gICAgICBsYW1iZGFDcmVkZW50aWFscy5sb2dGaWxlID0gdGhpcy5fY29uZmlnLmxvZ0ZpbGU7XG4gICAgfVxuICAgIGlmKHRoaXMuX2NvbmZpZy5sdEVycm9yUmVtYXJrID09PXRydWUpXG4gICAge1xuICAgICAgdGhpcy5fbHRFcnJvclJlbWFyaz10cnVlO1xuICAgIH1cbiAgICAvLyBDdWN1bWJlciBzcGVjaWZpYyBvcHRpb24gdG8gc2V0IHRlc3QgbmFtZSBmcm9tIHNjZW5hcmlvXG4gICAgaWYodGhpcy5fY29uZmlnLnVzZVNjZW5hcmlvTmFtZSA9PT0gdHJ1ZSlcbiAgICB7XG4gICAgICB0aGlzLl91c2VTY2VuYXJpb05hbWU9dHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLl9pc1NlcnZpY2VFbmFibGVkID0gbGFtYmRhQ3JlZGVudGlhbHMudXNlcm5hbWUgJiYgbGFtYmRhQ3JlZGVudGlhbHMuYWNjZXNzS2V5O1xuICAgIHRoaXMuX2xhbWJkYUNyZWRlbnRpYWxzPWxhbWJkYUNyZWRlbnRpYWxzO1xuICAgIFxuICB9XG5cbiAgYXN5bmMgYmVmb3JlU2NlbmFyaW8od29ybGQsIGNvbnRleHQpIHtcbiAgICBpZiAodGhpcy5fdXNlU2NlbmFyaW9OYW1lKSB7XG4gICAgICB0aGlzLl90ZXN0VGl0bGUgPSB3b3JsZD8ucGlja2xlPy5uYW1lIHx8ICd1bmtub3duIHNjZW5hcmlvJztcbiAgICB9IGVsc2UgaWYgKCF0aGlzLl9zdWl0ZVRpdGxlKSB7XG4gICAgICB0aGlzLl9zdWl0ZVRpdGxlID1cbiAgICAgICAgd29ybGQ/LmdoZXJraW5Eb2N1bWVudD8uZmVhdHVyZT8ubmFtZSB8fFxuICAgICAgICBjb250ZXh0Py5kb2N1bWVudD8uZmVhdHVyZT8ubmFtZSB8fFxuICAgICAgICB3b3JsZD8ucGlja2xlPy5uYW1lIHx8XG4gICAgICAgICd1bmtub3duIHNjZW5hcmlvJztcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5zZXRTZXNzaW9uTmFtZSh0aGlzLl90ZXN0VGl0bGUgfHwgdGhpcy5fc3VpdGVUaXRsZSk7XG4gIH1cblxuICBhc3luYyBiZWZvcmVTdWl0ZShzdWl0ZSkge1xuICAgIHRoaXMuX3N1aXRlVGl0bGUgPSBzdWl0ZS50aXRsZTtcblxuICAgIGlmIChzdWl0ZS50aXRsZSAmJiBzdWl0ZS50aXRsZSAhPT0gJ0phc21pbmVfX1RvcExldmVsX19TdWl0ZScpIHtcbiAgICAgIGF3YWl0IHRoaXMuc2V0U2Vzc2lvbk5hbWUoc3VpdGUudGl0bGUpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGJlZm9yZVRlc3QodGVzdCkge1xuICAgIGlmICghdGhpcy5faXNTZXJ2aWNlRW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0ZXN0ICYmIHRlc3Q/LnBhcmVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLl9jdXJyZW50VGVzdFRpdGxlID0gdGVzdD8ucGFyZW50O1xuICAgICAgdGhpcy5fY3VycmVudFRlc3RUaXRsZSA9IGAke3RoaXMuX2N1cnJlbnRUZXN0VGl0bGV9IC0gJHt0ZXN0Py50aXRsZX1gO1xuICB9IGVsc2UgaWYgKHRlc3QgJiYgdGVzdD8uZnVsbE5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5fY3VycmVudFRlc3RUaXRsZSA9IHRlc3Q/LmZ1bGxOYW1lO1xuICB9XG5cbiAgICBpZiAodGVzdC50aXRsZSAmJiAhdGhpcy5fdGVzdFRpdGxlKSB7XG4gICAgICB0aGlzLl90ZXN0VGl0bGUgPSB0ZXN0LnRpdGxlO1xuICAgIH1cblxuICAgIGxldCBzdWl0ZVRpdGxlID0gdGhpcy5fc3VpdGVUaXRsZTtcblxuICAgIGlmICh0ZXN0LmZ1bGxOYW1lKSB7XG4gICAgICAvLyBGb3IgSmFzbWluZSwgYHN1aXRlLnRpdGxlYCBpcyBgSmFzbWluZV9fVG9wTGV2ZWxfX1N1aXRlYC5cbiAgICAgIC8vIFRoaXMgdHdlYWsgYWxsb3dzIHVzIHRvIHNldCB0aGUgcmVhbCBzdWl0ZSBuYW1lLlxuICAgICAgY29uc3QgdGVzdFN1aXRlTmFtZSA9IHRlc3QuZnVsbE5hbWU7XG4gICAgICBpZiAodGhpcy5fc3VpdGVUaXRsZSA9PT0gJ0phc21pbmVfX1RvcExldmVsX19TdWl0ZScpIHtcbiAgICAgICAgc3VpdGVUaXRsZSA9IHRlc3RTdWl0ZU5hbWU7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX3N1aXRlVGl0bGUpIHtcbiAgICAgICAgc3VpdGVUaXRsZSA9IGdldFBhcmVudFN1aXRlTmFtZSh0aGlzLl9zdWl0ZVRpdGxlLCB0ZXN0U3VpdGVOYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnNldFNlc3Npb25OYW1lKHN1aXRlVGl0bGUsIHRlc3QpO1xuICB9XG5cbiAgYXN5bmMgYmVmb3JlRmVhdHVyZSh1cmksIGZlYXR1cmUpIHtcbiAgICB0aGlzLl9zdWl0ZVRpdGxlID0gZmVhdHVyZS5uYW1lO1xuICAgIGF3YWl0IHRoaXMuc2V0U2Vzc2lvbk5hbWUodGhpcy5fc3VpdGVUaXRsZSk7XG4gIH1cblxuICBhc3luYyBiZWZvcmVTdGVwKHN0ZXApIHtcbiAgICBpZiAoIXRoaXMuX3N1aXRlVGl0bGUgfHwgdGhpcy5fc3VpdGVUaXRsZSA9PSAndW5rbm93biBzY2VuYXJpbycpIHtcbiAgICAgIHRoaXMuX3N1aXRlVGl0bGUgPVxuICAgICAgICBzdGVwLmRvY3VtZW50Py5mZWF0dXJlPy5uYW1lIHx8XG4gICAgICAgIHN0ZXAuc3RlcD8uc2NlbmFyaW8/Lm5hbWUgfHxcbiAgICAgICAgJ3Vua25vd24gc2NlbmFyaW8nO1xuICAgICAgYXdhaXQgdGhpcy5zZXRTZXNzaW9uTmFtZSh0aGlzLl9zdWl0ZVRpdGxlKTtcbiAgICB9XG4gIH1cblxuICBhZnRlclN1aXRlKHN1aXRlKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzdWl0ZSwgJ2Vycm9yJykpIHtcbiAgICAgICsrdGhpcy5fZmFpbHVyZXM7XG4gICAgfVxuICB9XG5cbiAgYWZ0ZXJUZXN0KHRlc3QsIGNvbnRleHQsIHsgZXJyb3IsIHBhc3NlZCB9KSB7XG4gICAgdGhpcy5fc3BlY3NSYW4gPSB0cnVlO1xuICAgIC8vIHJlbW92ZSBmYWlsdXJlIGlmIHRlc3Qgd2FzIHJldHJpZWQgYW5kIHBhc3NlZFxuICAgIC8vIChNb2NoYSBvbmx5KVxuICAgIGlmICh0ZXN0Ll9yZXRyaWVkVGVzdCAmJiBwYXNzZWQpIHtcbiAgICAgIC0tdGhpcy5fZmFpbHVyZXM7XG4gICAgICB0aGlzLl9yZXRyeUZhaWx1cmVzID0gMDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBkb24ndCBidW1wIGZhaWx1cmUgbnVtYmVyIGlmIHRlc3Qgd2FzIHJldHJpZWQgYW5kIHN0aWxsIGZhaWxlZFxuICAgIC8vIChNb2NoYSBvbmx5KVxuICAgIGlmIChcbiAgICAgIHRlc3QuX3JldHJpZWRUZXN0ICYmXG4gICAgICAhcGFzc2VkICYmXG4gICAgICAoXG4gICAgICAgIHR5cGVvZiB0ZXN0Ll9jdXJyZW50UmV0cnkgPT09ICdudW1iZXInICYmXG4gICAgICAgIHR5cGVvZiB0ZXN0Ll9yZXRyaWVzID09PSAnbnVtYmVyJyAmJlxuICAgICAgICB0ZXN0Ll9jdXJyZW50UmV0cnkgPCB0ZXN0Ll9yZXRyaWVzXG4gICAgICApXG4gICAgKSB7XG4gICAgICArK3RoaXMuX3JldHJ5RmFpbHVyZXM7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaXNKYXNtaW5lUGVuZGluZ0Vycm9yID0gdHlwZW9mIGVycm9yID09PSAnc3RyaW5nJyAmJiBlcnJvci5pbmNsdWRlcygnbWFya2VkIFBlbmRpbmcnKTtcbiAgICBpZiAoIXBhc3NlZCAmJiAhaXNKYXNtaW5lUGVuZGluZ0Vycm9yKSB7XG4gICAgICArK3RoaXMuX2ZhaWx1cmVzO1xuICAgICAgKyt0aGlzLl9yZXRyeUZhaWx1cmVzO1xuICAgICAgdGhpcy5fZmFpbFJlYXNvbnMucHVzaCgoZXJyb3IgJiYgZXJyb3IubWVzc2FnZSkgfHwgJ1Vua25vd24gRXJyb3InKVxuICAgICAgdGhpcy5fZXJyb3I9ZXJyb3I/Lm1lc3NhZ2UgfHwgJ1Vua25vd24gRXJyb3InO1xuICAgICAgaWYgKHRoaXMuX2x0RXJyb3JSZW1hcmsgJiYgdGhpcy5fZXJyb3IgIT09IG51bGwgJiYgdGhpcy5fZXJyb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9zZXRTZXNzaW9uUmVtYXJrcyh0aGlzLl9lcnJvcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYWZ0ZXJTY2VuYXJpbyh3b3JsZCwgcmVzdWx0KSB7XG4gICAgY29uc3QgeyBwYXNzZWQgfSA9IHJlc3VsdCB8fCB7fTtcbiAgICB0aGlzLl9zcGVjc1JhbiA9IHRydWU7XG4gICAgY29uc3Qgc3RhdHVzID0gd29ybGQucmVzdWx0Py5zdGF0dXMudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoc3RhdHVzICE9PSAnc2tpcHBlZCcpIHtcbiAgICAgIHRoaXMuX3NjZW5hcmlvc1RoYXRSYW4ucHVzaCh3b3JsZC5waWNrbGUubmFtZSB8fCAndW5rbm93biBwaWNrbGUgbmFtZScpO1xuICAgIH1cbiAgICBpZiAoc3RhdHVzICYmIHRoaXMuX2ZhaWx1cmVTdGF0dXNlcy5pbmNsdWRlcyhzdGF0dXMpKSB7XG4gICAgICBjb25zdCBleGNlcHRpb24gPSAoXG4gICAgICAgICh3b3JsZC5yZXN1bHQgJiYgd29ybGQucmVzdWx0Lm1lc3NhZ2UpIHx8XG4gICAgICAgIChzdGF0dXMgPT09ICdwZW5kaW5nJ1xuICAgICAgICAgID8gYFNvbWUgc3RlcHMvaG9va3MgYXJlIHBlbmRpbmcgZm9yIHNjZW5hcmlvIFwiJHt3b3JsZC5waWNrbGUubmFtZX1cImBcbiAgICAgICAgICA6ICdVbmtub3duIEVycm9yJ1xuICAgICAgICApXG4gICAgICApXG4gICAgICArK3RoaXMuX2ZhaWx1cmVzO1xuICAgICAgdGhpcy5fZmFpbFJlYXNvbnMucHVzaChleGNlcHRpb24pXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGFzc2VkICE9PSAndW5kZWZpbmVkJyAmJiAhcGFzc2VkKSB7XG4gICAgICArK3RoaXMuX2ZhaWx1cmVzO1xuICAgIH1cbiAgfVxuXG4gIGFmdGVyKHJlc3VsdCkge1xuICAgIGlmICghdGhpcy5faXNTZXJ2aWNlRW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBmYWlsdXJlcyA9IHRoaXMuX2ZhaWx1cmVzO1xuXG4gICAgLy8gc2V0IF9mYWlsdXJlcyBpZiB1c2VyIGhhcyBiYWlsIG9wdGlvbiBzZXQgaW4gd2hpY2ggY2FzZSBhZnRlclRlc3QgYW5kXG4gICAgLy8gYWZ0ZXJTdWl0ZSBhcmVuJ3QgZXhlY3V0ZWQgYmVmb3JlIGFmdGVyIGhvb2tcbiAgICBpZiAodGhpcy5fY29uZmlnLm1vY2hhT3B0cyAmJiB0aGlzLl9jb25maWcubW9jaGFPcHRzLmJhaWwgJiYgQm9vbGVhbihyZXN1bHQpKSB7XG4gICAgICBmYWlsdXJlcyA9IDE7XG4gICAgfVxuXG4gICAgaWYgKHJlc3VsdCA9PT0gMCkge1xuICAgICAgZmFpbHVyZXMgPSAwO1xuICAgIH1cblxuICAgIGNvbnN0IHsgcHJlZmVyU2NlbmFyaW9OYW1lIH0gPSB0aGlzLl9vcHRpb25zO1xuICAgIC8vIEZvciBDdWN1bWJlcjogQ2hlY2tzIHNjZW5hcmlvcyB0aGF0IHJhbiAoaS5lLiBub3Qgc2tpcHBlZCkgb24gdGhlIHNlc3Npb25cbiAgICAvLyBPbmx5IDEgU2NlbmFyaW8gcmFuIGFuZCBvcHRpb24gZW5hYmxlZCA9PiBSZWRlZmluZSBzZXNzaW9uIG5hbWUgdG8gU2NlbmFyaW8ncyBuYW1lXG4gICAgaWYgKHByZWZlclNjZW5hcmlvTmFtZSAmJiB0aGlzLl9zY2VuYXJpb3NUaGF0UmFuLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdGhpcy5fZnVsbFRpdGxlID0gdGhpcy5fc2NlbmFyaW9zVGhhdFJhbi5wb3AoKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdGF0dXMgPSAnc3RhdHVzOiAnICsgKHJlc3VsdCA+IDAgPyAnZmFpbGVkJyA6ICdwYXNzZWQnKTtcblxuICAgIGlmICghdGhpcy5fYnJvd3Nlci5pc011bHRpcmVtb3RlKSB7XG4gICAgICBsb2cuaW5mbyhgVXBkYXRlIGpvYiB3aXRoIHNlc3Npb25JZCAke3RoaXMuX2Jyb3dzZXIuc2Vzc2lvbklkfSwgJHtzdGF0dXN9YCk7XG5cbiAgICAgIC8vIFByaW50IHNlc3Npb24gVVJMIGZvciBzaW5nbGUgcmVtb3RlIGJyb3dzZXJcbiAgICAgIGlmKHByb2Nlc3MuZW52LkxPR19TRVNTSU9OX1VSTCA9PT0gXCJ0cnVlXCIpIHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvblVSTCA9IHRoaXMuZ2V0U2Vzc2lvblVSTCh0aGlzLl9icm93c2VyLnNlc3Npb25JZCwgdGhpcy5fY29uZmlnLnByb2R1Y3QpO1xuICAgICAgICBsb2cuaW5mbyhgU2Vzc2lvbiBVUkw6ICR7c2Vzc2lvblVSTH1gKTtcbiAgICAgIH1cblxuICAgICAgLy8gVXNlIHRoZSBmYWlsdXJlIHZhbHVlIGZvciByZXN1bHQgaW4gY2FzZSBvZiByZWxvYWRlZCBzZXNzaW9uc1xuICAgICAgaWYgKHRoaXMuX2xhc3RSZWxvYWRlZFNlc3Npb249PXRoaXMuX2Jyb3dzZXIuc2Vzc2lvbklkKXtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZSh7IHNlc3Npb25JZDogdGhpcy5fYnJvd3Nlci5zZXNzaW9uSWQsIGZhaWx1cmVzOiBmYWlsdXJlcyB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZSh7IHNlc3Npb25JZDogdGhpcy5fYnJvd3Nlci5zZXNzaW9uSWQsIGZhaWx1cmVzOiByZXN1bHQgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFByb21pc2UuYWxsKE9iamVjdC5rZXlzKHRoaXMuX2NhcGFiaWxpdGllcykubWFwKGJyb3dzZXJOYW1lID0+IHtcbiAgICAgIGxvZy5pbmZvKGBVcGRhdGUgbXVsdGlyZW1vdGUgam9iIGZvciBicm93c2VyICcke2Jyb3dzZXJOYW1lfScgYW5kIHNlc3Npb25JZCAke3RoaXMuX2Jyb3dzZXJbYnJvd3Nlck5hbWVdLnNlc3Npb25JZH0sICR7c3RhdHVzfWApO1xuXG4gICAgICAvLyBQcmludCBzZXNzaW9uIFVSTCBmb3IgZWFjaCByZW1vdGUgYnJvd3NlclxuICAgICAgaWYocHJvY2Vzcy5lbnYuTE9HX1NFU1NJT05fVVJMID09PSBcInRydWVcIikge1xuICAgICAgICBjb25zdCBzZXNzaW9uVVJMID0gdGhpcy5nZXRTZXNzaW9uVVJMKHRoaXMuX2Jyb3dzZXJbYnJvd3Nlck5hbWVdLnNlc3Npb25JZCwgdGhpcy5fY29uZmlnLnByb2R1Y3QpO1xuICAgICAgICBsb2cuaW5mbyhgU2Vzc2lvbiBVUkwgZm9yICR7YnJvd3Nlck5hbWV9OiAke3Nlc3Npb25VUkx9YCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLl91cGRhdGUoeyBzZXNzaW9uSWQ6IHRoaXMuX2Jyb3dzZXJbYnJvd3Nlck5hbWVdLnNlc3Npb25JZCwgZmFpbHVyZXM6IGZhaWx1cmVzLCBjYWxsZWRPblJlbG9hZDogZmFsc2UsIGJyb3dzZXJOYW1lOiBicm93c2VyTmFtZSB9KTtcbiAgICB9KSk7XG4gIH1cblxuICBhc3luYyBvblJlbG9hZChvbGRTZXNzaW9uSWQsIG5ld1Nlc3Npb25JZCkge1xuICAgIHRoaXMuX2xhc3RSZWxvYWRlZFNlc3Npb24gPSBuZXdTZXNzaW9uSWQ7XG4gICAgaWYgKCF0aGlzLl9pc1NlcnZpY2VFbmFibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhdHVzID0gKHRoaXMuX2ZhaWx1cmVzID4gMCB8fCB0aGlzLl9yZXRyeUZhaWx1cmVzPjApID8gJ2ZhaWxlZCcgOiAncGFzc2VkJztcblxuICAgIGlmICghdGhpcy5fYnJvd3Nlci5pc011bHRpcmVtb3RlKSB7XG4gICAgICBsb2cuaW5mbyhgVXBkYXRlIChyZWxvYWRlZCkgam9iIHdpdGggc2Vzc2lvbklkICR7b2xkU2Vzc2lvbklkfSwgJHtzdGF0dXN9YCk7XG5cbiAgICAgIC8vIFByaW50IHNlc3Npb24gVVJMIGZvciBzaW5nbGUgcmVtb3RlIGJyb3dzZXJcbiAgICAgIGlmKHByb2Nlc3MuZW52LkxPR19TRVNTSU9OX1VSTCA9PT0gXCJ0cnVlXCIpIHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvblVSTCA9IHRoaXMuZ2V0U2Vzc2lvblVSTCh0aGlzLl9icm93c2VyLnNlc3Npb25JZCwgdGhpcy5fY29uZmlnLnByb2R1Y3QpO1xuICAgICAgICBsb2cuaW5mbyhgU2Vzc2lvbiBVUkw6ICR7c2Vzc2lvblVSTH1gKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdGhpcy5fdXBkYXRlKHsgc2Vzc2lvbklkOiBvbGRTZXNzaW9uSWQsIGZ1bGxUaXRsZTogdGhpcy5fZnVsbFRpdGxlLCBzdGF0dXM6IHN0YXR1cywgY2FsbGVkT25SZWxvYWQ6IHRydWUgfSk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYnJvd3Nlck5hbWUgPSB0aGlzLl9icm93c2VyLmluc3RhbmNlcy5maWx0ZXIoYnJvd3Nlck5hbWUgPT4gdGhpcy5fYnJvd3Nlclticm93c2VyTmFtZV0uc2Vzc2lvbklkID09PSBuZXdTZXNzaW9uSWQpWzBdO1xuICAgICAgbG9nLmluZm8oYFVwZGF0ZSAocmVsb2FkZWQpIG11bHRpcmVtb3RlIGpvYiBmb3IgYnJvd3NlciAnJHticm93c2VyTmFtZX0nIGFuZCBzZXNzaW9uSWQgJHtvbGRTZXNzaW9uSWR9LCAke3N0YXR1c31gKTtcblxuICAgICAgLy8gUHJpbnQgc2Vzc2lvbiBVUkwgZm9yIGVhY2ggcmVtb3RlIGJyb3dzZXJcbiAgICAgIGlmKHByb2Nlc3MuZW52LkxPR19TRVNTSU9OX1VSTCA9PT0gXCJ0cnVlXCIpIHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvblVSTCA9IHRoaXMuZ2V0U2Vzc2lvblVSTCh0aGlzLl9icm93c2VyW2Jyb3dzZXJOYW1lXS5zZXNzaW9uSWQsIHRoaXMuX2NvbmZpZy5wcm9kdWN0KTtcbiAgICAgICAgbG9nLmluZm8oYFNlc3Npb24gVVJMIGZvciAke2Jyb3dzZXJOYW1lfTogJHtzZXNzaW9uVVJMfWApO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLl91cGRhdGUoeyBzZXNzaW9uSWQgOiBvbGRTZXNzaW9uSWQsIGZhaWx1cmVzOnRoaXMuX2ZhaWx1cmVzLCBjYWxsZWRPblJlbG9hZDogdHJ1ZSwgYnJvd3Nlck5hbWU6IGJyb3dzZXJOYW1lIH0pO1xuICAgIH1cblxuICAgIHRoaXMuX2ZhaWxSZWFzb25zID0gW107XG4gICAgdGhpcy5fc2NlbmFyaW9zVGhhdFJhbiA9IFtdO1xuICAgIGRlbGV0ZSB0aGlzLl9mdWxsVGl0bGU7XG4gIH1cblxuICBhc3luYyBfdXBkYXRlKHsgc2Vzc2lvbklkLCBmdWxsVGl0bGUsIHN0YXR1cywgZmFpbHVyZXMsIGNhbGxlZE9uUmVsb2FkID0gZmFsc2UsIGJyb3dzZXJOYW1lIH0pIHtcbiAgICBpZiAoIXRoaXMuX29wdGlvbnMuc2V0U2Vzc2lvblN0YXR1cykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzbGVlcCA9IG1zID0+IG5ldyBQcm9taXNlKHIgPT4gc2V0VGltZW91dChyLCBtcykpO1xuICAgIGF3YWl0IHNsZWVwKDUwMDApO1xuICAgIGlmIChjYWxsZWRPblJlbG9hZCl7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy51cGRhdGVKb2IoeyBzZXNzaW9uSWQsIGZ1bGxUaXRsZSwgc3RhdHVzLCBjYWxsZWRPblJlbG9hZCwgYnJvd3Nlck5hbWUgfSk7XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCB0aGlzLnVwZGF0ZUpvYih7IHNlc3Npb25JZCwgX2ZhaWx1cmVzOiBmYWlsdXJlcywgY2FsbGVkT25SZWxvYWQsIGJyb3dzZXJOYW1lIH0pO1xuICBcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZUpvYih7IHNlc3Npb25JZCwgZnVsbFRpdGxlLCBzdGF0dXMsIF9mYWlsdXJlcywgY2FsbGVkT25SZWxvYWQgPSBmYWxzZSwgYnJvd3Nlck5hbWUgfSkge1xuICAgIFxuICAgIGxldCBib2R5O1xuICAgIGlmKGNhbGxlZE9uUmVsb2FkKXtcbiAgICAgICBib2R5ID0gdGhpcy5nZXRCb2R5KHsgZnVsbFRpdGxlLCBzdGF0dXMsIGNhbGxlZE9uUmVsb2FkLCBicm93c2VyTmFtZSB9KTtcbiAgICB9XG4gICAgZWxzZXtcbiAgICAgIGJvZHkgPSB0aGlzLmdldEJvZHkoeyBfZmFpbHVyZXMsIGNhbGxlZE9uUmVsb2FkLCBicm93c2VyTmFtZSB9KTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHVwZGF0ZVNlc3Npb25CeUlkKHNlc3Npb25JZCwgYm9keSwgdGhpcy5fbGFtYmRhQ3JlZGVudGlhbHMpO1xuICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICBjb25zb2xlLmxvZyhleCk7XG4gICAgfVxuICAgIHRoaXMuX2ZhaWx1cmVzID0gMDtcbiAgICB0aGlzLl9yZXRyeUZhaWx1cmVzPTA7XG4gIH1cblxuICBnZXRCb2R5KHsgZnVsbFRpdGxlLCBzdGF0dXMsIF9mYWlsdXJlcywgY2FsbGVkT25SZWxvYWQgPSBmYWxzZSwgYnJvd3Nlck5hbWUgfSkge1xuICAgIGxldCBib2R5ID0ge307XG4gICAgaWYgKFxuICAgICAgIShcbiAgICAgICAgKCF0aGlzLl9icm93c2VyLmlzTXVsdGlyZW1vdGUgJiYgdGhpcy5fY2FwYWJpbGl0aWVzLm5hbWUpIHx8XG4gICAgICAgICh0aGlzLl9icm93c2VyLmlzTXVsdGlyZW1vdGUgJiZcbiAgICAgICAgICB0aGlzLl9jYXBhYmlsaXRpZXNbYnJvd3Nlck5hbWVdLmNhcGFiaWxpdGllcy5uYW1lKVxuICAgICAgKVxuICAgICkge1xuICAgICAgYm9keS5uYW1lID0gdGhpcy5fZnVsbFRpdGxlO1xuICAgICAgaWYoY2FsbGVkT25SZWxvYWQpe1xuICAgICAgICBib2R5Lm5hbWU9ZnVsbFRpdGxlO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fY2FwYWJpbGl0aWVzWydMVDpPcHRpb25zJ10gJiYgdGhpcy5fY2FwYWJpbGl0aWVzWydMVDpPcHRpb25zJ10ubmFtZSkge1xuICAgICAgICBib2R5Lm5hbWUgPSB0aGlzLl9jYXBhYmlsaXRpZXNbJ0xUOk9wdGlvbnMnXS5uYW1lO1xuICAgICAgfVxuXG4gICAgICBpZiAoYnJvd3Nlck5hbWUpIHtcbiAgICAgICAgYm9keS5uYW1lID0gYCR7YnJvd3Nlck5hbWV9OiAke2JvZHkubmFtZX1gO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2FsbGVkT25SZWxvYWQgfHwgdGhpcy5fdGVzdENudCkge1xuICAgICAgICBsZXQgdGVzdENudCA9ICsrdGhpcy5fdGVzdENudDtcblxuICAgICAgICBpZiAodGhpcy5fYnJvd3Nlci5pc011bHRpcmVtb3RlKSB7XG4gICAgICAgICAgdGVzdENudCA9IE1hdGguY2VpbCh0ZXN0Q250IC8gdGhpcy5fYnJvd3Nlci5pbnN0YW5jZXMubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNhbGxlZE9uUmVsb2FkICYmICF0aGlzLl9vcHRpb25zLmlnbm9yZVRlc3RDb3VudEluTmFtZSl7XG4gICAgICAgICAgYm9keS5uYW1lICs9IGAgKCR7dGVzdENudH0pYDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBib2R5LnN0YXR1c19pbmQgPSBfZmFpbHVyZXMgPiAwID8gJ2ZhaWxlZCcgOiAncGFzc2VkJztcbiAgICBpZiAoY2FsbGVkT25SZWxvYWQpe1xuICAgICAgYm9keS5zdGF0dXNfaW5kID0gc3RhdHVzO1xuICAgIH1cbiAgICByZXR1cm4gYm9keTtcbiAgfVxuXG4gIGFzeW5jIHNldFNlc3Npb25OYW1lKHN1aXRlVGl0bGUsIHRlc3QpIHtcbiAgICBpZiAoIXRoaXMuX29wdGlvbnMuc2V0U2Vzc2lvbk5hbWUgfHwgIXN1aXRlVGl0bGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgbmFtZSA9IHRoaXMuX3VzZVNjZW5hcmlvTmFtZSAmJiB0aGlzLl90ZXN0VGl0bGUgPyB0aGlzLl90ZXN0VGl0bGUgOiBzdWl0ZVRpdGxlO1xuICAgIGlmICh0aGlzLl9vcHRpb25zLnNlc3Npb25OYW1lRm9ybWF0KSB7XG4gICAgICBuYW1lID0gdGhpcy5fb3B0aW9ucy5zZXNzaW9uTmFtZUZvcm1hdChcbiAgICAgICAgICB0aGlzLl9jb25maWcsXG4gICAgICAgICAgdGhpcy5fY2FwYWJpbGl0aWVzLFxuICAgICAgICAgIHN1aXRlVGl0bGUsXG4gICAgICAgICAgdGVzdD8udGl0bGVcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmICh0ZXN0ICYmICF0ZXN0LmZ1bGxOYW1lKSB7XG4gICAgICAvLyBNb2NoYVxuICAgICAgY29uc3QgcHJlID0gdGhpcy5fb3B0aW9ucy5zZXNzaW9uTmFtZVByZXBlbmRUb3BMZXZlbFN1aXRlVGl0bGUgPyBgJHtzdWl0ZVRpdGxlfSAtIGAgOiAnJztcbiAgICAgIGNvbnN0IHBvc3QgPSAhdGhpcy5fb3B0aW9ucy5zZXNzaW9uTmFtZU9taXRUZXN0VGl0bGUgPyBgIC0gJHt0ZXN0LnRpdGxlfWAgOiAnJztcbiAgICAgIG5hbWUgPSBgJHtwcmV9JHt0ZXN0LnBhcmVudH0ke3Bvc3R9YDtcbiAgICB9XG5cbiAgICBpZiAobmFtZSAhPT0gdGhpcy5fZnVsbFRpdGxlKSB7XG4gICAgICB0aGlzLl9mdWxsVGl0bGUgPSBuYW1lO1xuICAgICAgYXdhaXQgdGhpcy5fc2V0U2Vzc2lvbk5hbWUobmFtZSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgX3NldFNlc3Npb25SZW1hcmtzKGVycikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBob29rT2JqZWN0ID0ge1xuICAgICAgICBhY3Rpb246IFwic2V0VGVzdFN0YXR1c1wiLFxuICAgICAgICBhcmd1bWVudHM6IHtcbiAgICAgICAgICBzdGF0dXM6IFwiZmFpbGVkXCIsXG4gICAgICAgICAgcmVtYXJrOiBlcnJcbiAgICAgICAgfVxuICAgICAgfTtcbiAgXG4gICAgICBjb25zdCBlcnJvckN1c3RvbSA9IGBsYW1iZGEtaG9vazogJHtKU09OLnN0cmluZ2lmeShob29rT2JqZWN0KX1gO1xuICAgICAgYXdhaXQgdGhpcy5fYnJvd3Nlci5leGVjdXRlU2NyaXB0KGVycm9yQ3VzdG9tLnRvU3RyaW5nKCksIFtdKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5sb2coXCJFcnJvciBzZXR0aW5nIHNlc3Npb24gcmVtYXJrczpcIiwgZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9zZXRTZXNzaW9uTmFtZShzZXNzaW9uTmFtZSkge1xuICAgIGF3YWl0IHRoaXMuX2V4ZWN1dGVDb21tYW5kKGBsYW1iZGEtbmFtZT0ke3Nlc3Npb25OYW1lfWApO1xuICB9XG5cbiAgYXN5bmMgX2V4ZWN1dGVDb21tYW5kKGNtZCkge1xuICAgIGlmICghdGhpcy5fYnJvd3Nlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5fYnJvd3Nlci5pc011bHRpcmVtb3RlKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwoT2JqZWN0LmtleXModGhpcy5fY2FwYWJpbGl0aWVzKS5tYXAoYXN5bmMgKGJyb3dzZXJOYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IGJyb3dzZXIgPSB0aGlzLl9icm93c2VyW2Jyb3dzZXJOYW1lXTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGJyb3dzZXIuZXhlY3V0ZVNjcmlwdChjbWQudG9TdHJpbmcoKSwgW10pO1xuICAgICAgfSkpO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5fYnJvd3Nlci5leGVjdXRlU2NyaXB0KGNtZC50b1N0cmluZygpLCBbXSk7XG4gIH1cblxuICBnZXRTZXNzaW9uVVJMKHNlc3Npb25JZCwgcHJvZHVjdCkge1xuICAgIGlmIChwcm9kdWN0ID09PSAnYXBwQXV0b21hdGlvbicpIHtcbiAgICAgIHJldHVybiBgJHthcHBTZXNzaW9uVVJMfT0ke3Nlc3Npb25JZH1gO1xuICAgIH1cbiAgICByZXR1cm4gYCR7d2ViU2Vzc2lvblVSTH09JHtzZXNzaW9uSWR9YDtcbiAgfVxufVxuIl0sIm1hcHBpbmdz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