testcafe
Version:
Automated browser testing for the modern web development stack.
236 lines • 43.6 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const configuration_base_1 = __importDefault(require("./configuration-base"));
const lodash_1 = require("lodash");
const get_options_1 = require("../utils/get-options");
const option_names_1 = __importDefault(require("./option-names"));
const get_filter_fn_1 = __importDefault(require("../utils/get-filter-fn"));
const prepare_reporters_1 = __importDefault(require("../utils/prepare-reporters"));
const string_1 = require("../utils/string");
const render_template_1 = __importDefault(require("../utils/render-template"));
const warning_message_1 = __importDefault(require("../notifications/warning-message"));
const resolve_path_relatively_cwd_1 = __importDefault(require("../utils/resolve-path-relatively-cwd"));
const default_values_1 = require("./default-values");
const option_source_1 = __importDefault(require("./option-source"));
const customizable_compilers_1 = __importDefault(require("./customizable-compilers"));
const deprecated_1 = require("../notifications/deprecated");
const pool_1 = __importDefault(require("../browser/provider/pool"));
const formats_1 = __importDefault(require("./formats"));
const runtime_1 = require("../errors/runtime");
const types_1 = require("../errors/types");
const localhost_names_1 = require("../utils/localhost-names");
const utils_1 = require("./utils");
const BASE_CONFIGURATION_FILENAME = '.testcaferc';
const CONFIGURATION_FILENAMES = Object.keys(formats_1.default).map(ext => `${BASE_CONFIGURATION_FILENAME}${formats_1.default[ext]}`);
const DEFAULT_SCREENSHOTS_DIRECTORY = 'screenshots';
const OPTION_FLAG_NAMES = [
option_names_1.default.debugMode,
option_names_1.default.debugOnFail,
option_names_1.default.skipUncaughtErrors,
option_names_1.default.stopOnFirstFail,
option_names_1.default.takeScreenshotsOnFails,
option_names_1.default.disablePageCaching,
option_names_1.default.disablePageReloads,
option_names_1.default.disableScreenshots,
option_names_1.default.disableMultipleWindows,
];
const OPTION_INIT_FLAG_NAMES = [
option_names_1.default.developmentMode,
option_names_1.default.retryTestPages,
option_names_1.default.cache,
option_names_1.default.disableHttp2,
option_names_1.default.disableNativeAutomation,
option_names_1.default.disableCrossDomain,
option_names_1.default.experimentalMultipleWindows,
];
class TestCafeConfiguration extends configuration_base_1.default {
constructor(configFile = '') {
super(configFile || CONFIGURATION_FILENAMES);
this._isExplicitConfig = !!configFile;
}
async init(options) {
await super.init();
const opts = await this._load();
if (opts) {
this._options = configuration_base_1.default._fromObj(opts);
await this._normalizeOptionsAfterLoad();
}
await this.asyncMergeOptions(options);
}
async asyncMergeOptions(options) {
options = options || {};
super.mergeOptions(options);
if (!options.isCli && this._options.browsers)
this._options.browsers.value = await this._getBrowserInfo();
}
prepare() {
this._prepareFlags();
this._setDefaultValues();
this._prepareCompilerOptions();
}
notifyAboutOverriddenOptions(warningLog) {
if (!this._overriddenOptions.length)
return;
const optionsStr = (0, string_1.getConcatenatedValuesString)(this._overriddenOptions);
const optionsSuffix = (0, string_1.getPluralSuffix)(this._overriddenOptions);
const renderedMessage = (0, render_template_1.default)(warning_message_1.default.configOptionsWereOverridden, optionsStr, optionsSuffix);
configuration_base_1.default._showConsoleWarning(renderedMessage);
if (warningLog)
warningLog.addWarning(renderedMessage);
this._overriddenOptions = [];
}
notifyAboutDeprecatedOptions(warningLog) {
const deprecatedOptions = this.getOptions((name, option) => name in deprecated_1.DEPRECATED && option.value !== void 0);
for (const optionName in deprecatedOptions)
warningLog.addWarning((0, deprecated_1.getDeprecationMessage)(deprecated_1.DEPRECATED[optionName]));
}
get startOptions() {
return {
hostname: this.getOption(option_names_1.default.hostname),
port1: this.getOption(option_names_1.default.port1),
port2: this.getOption(option_names_1.default.port2),
ssl: this.getOption(option_names_1.default.ssl),
developmentMode: this.getOption(option_names_1.default.developmentMode),
retryTestPages: this.getOption(option_names_1.default.retryTestPages),
cache: this.getOption(option_names_1.default.cache),
disableHttp2: this.getOption(option_names_1.default.disableHttp2),
disableCrossDomain: this.getOption(option_names_1.default.disableCrossDomain),
nativeAutomation: !this.getOption(option_names_1.default.disableNativeAutomation),
};
}
get browserConnectionGatewayOptions() {
return {
retryTestPages: this.getOption(option_names_1.default.retryTestPages),
};
}
get remoteBrowserConnectionOptions() {
return {
disableMultipleWindows: true,
nativeAutomation: false,
developmentMode: this.getOption(option_names_1.default.developmentMode),
};
}
_prepareFlag(name, source = option_source_1.default.Configuration) {
const option = this._ensureOption(name, void 0, source);
option.value = !!option.value;
}
_prepareFlags() {
OPTION_FLAG_NAMES.forEach(name => this._prepareFlag(name));
}
_prepareInitFlags() {
OPTION_INIT_FLAG_NAMES.forEach(name => this._prepareFlag(name, option_source_1.default.Default));
}
async _normalizeOptionsAfterLoad() {
await this._prepareSslOptions();
this._prepareInitFlags();
this._prepareFilterFn();
this._ensureArrayOption(option_names_1.default.src);
this._ensureArrayOption(option_names_1.default.browsers);
this._ensureArrayOption(option_names_1.default.clientScripts);
this._prepareReporters();
}
_prepareFilterFn() {
const filterOption = this._ensureOption(option_names_1.default.filter, default_values_1.DEFAULT_FILTER_FN, option_source_1.default.Default);
if (!filterOption.value)
return;
const filterOptionValue = filterOption.value;
if (filterOptionValue.testGrep)
filterOptionValue.testGrep = (0, get_options_1.getGrepOptions)(option_names_1.default.filterTestGrep, filterOptionValue.testGrep);
if (filterOptionValue.fixtureGrep)
filterOptionValue.fixtureGrep = (0, get_options_1.getGrepOptions)(option_names_1.default.filterFixtureGrep, filterOptionValue.fixtureGrep);
filterOption.value = (0, get_filter_fn_1.default)(filterOption.value);
filterOption.source = option_source_1.default.Configuration;
}
_ensureScreenshotOptions() {
const path = (0, resolve_path_relatively_cwd_1.default)(DEFAULT_SCREENSHOTS_DIRECTORY);
const screenshots = this._ensureOption(option_names_1.default.screenshots, {}, option_source_1.default.Configuration).value;
if (!screenshots.path)
screenshots.path = path;
if (screenshots.thumbnails === void 0)
screenshots.thumbnails = default_values_1.DEFAULT_SCREENSHOT_THUMBNAILS;
}
_ensureSkipJsOptions() {
const option = this._ensureOption(option_names_1.default.skipJsErrors, void 0, option_source_1.default.Configuration);
if (option.value === void 0)
option.value = !!option.value;
}
_prepareReporters() {
const reporterOption = this._options[option_names_1.default.reporter];
if (!reporterOption)
return;
const optionValue = (0, lodash_1.castArray)(reporterOption.value);
reporterOption.value = (0, prepare_reporters_1.default)(optionValue);
}
async _prepareSslOptions() {
const sslOptions = this._options[option_names_1.default.ssl];
if (!sslOptions)
return;
sslOptions.value = await (0, get_options_1.getSSLOptions)(sslOptions.value);
}
_setDefaultValues() {
this._ensureOptionWithValue(option_names_1.default.selectorTimeout, default_values_1.DEFAULT_TIMEOUT.selector, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.assertionTimeout, default_values_1.DEFAULT_TIMEOUT.assertion, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.pageLoadTimeout, default_values_1.DEFAULT_TIMEOUT.pageLoad, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.speed, default_values_1.DEFAULT_SPEED_VALUE, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.appInitDelay, default_values_1.DEFAULT_APP_INIT_DELAY, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.concurrency, default_values_1.DEFAULT_CONCURRENCY_VALUE, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.src, default_values_1.DEFAULT_SOURCE_DIRECTORIES, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.developmentMode, default_values_1.DEFAULT_DEVELOPMENT_MODE, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.retryTestPages, default_values_1.DEFAULT_RETRY_TEST_PAGES, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.disableHttp2, default_values_1.DEFAULT_DISABLE_HTTP2, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.disableNativeAutomation, default_values_1.DEFAULT_DISABLE_NATIVE_AUTOMATION, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.experimentalMultipleWindows, default_values_1.DEFAULT_EXPERIMENTAL_MULTIPLE_WINDOWS, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.disableCrossDomain, default_values_1.DEFAULT_DISABLE_CROSS_DOMAIN, option_source_1.default.Configuration);
this._ensureScreenshotOptions();
this._ensureSkipJsOptions();
}
_prepareCompilerOptions() {
const compilerOptions = this._ensureOption(option_names_1.default.compilerOptions, (0, default_values_1.getDefaultCompilerOptions)(), option_source_1.default.Configuration);
compilerOptions.value = compilerOptions.value || (0, default_values_1.getDefaultCompilerOptions)();
const tsConfigPath = this.getOption(option_names_1.default.tsConfigPath);
if (tsConfigPath) {
const compilerOptionValue = compilerOptions.value;
let typeScriptCompilerOptions = compilerOptionValue[customizable_compilers_1.default.typescript];
typeScriptCompilerOptions = Object.assign({
configPath: tsConfigPath,
}, typeScriptCompilerOptions);
compilerOptions.value[customizable_compilers_1.default.typescript] = typeScriptCompilerOptions;
}
}
async _getBrowserInfo() {
if (!this._options.browsers.value)
return [];
const browsers = Array.isArray(this._options.browsers.value) ? [...this._options.browsers.value] : [this._options.browsers.value];
const browserInfo = await Promise.all(browsers.map(browser => pool_1.default.getBrowserInfo(browser)));
return (0, lodash_1.flatten)(browserInfo);
}
async _isConfigurationFileExists(filePath = this.filePath) {
const fileExists = await super._isConfigurationFileExists(filePath);
if (!fileExists && this._isExplicitConfig)
throw new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.cannotFindTestcafeConfigurationFile, filePath);
return fileExists;
}
static get FILENAMES() {
return CONFIGURATION_FILENAMES;
}
async ensureHostname(calculateFn = utils_1.getValidHostname) {
let hostname = this.getOption(option_names_1.default.hostname);
hostname = await calculateFn(hostname);
this.mergeOptions({ hostname });
}
async calculateHostname({ nativeAutomation } = { nativeAutomation: false }) {
await this.ensureHostname(async (hostname) => {
if (nativeAutomation)
hostname = localhost_names_1.LOCALHOST_NAMES.LOCALHOST;
else
hostname = await (0, utils_1.getValidHostname)(hostname);
return hostname;
});
}
}
exports.default = TestCafeConfiguration;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdGNhZmUtY29uZmlndXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWd1cmF0aW9uL3Rlc3RjYWZlLWNvbmZpZ3VyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4RUFBaUQ7QUFDakQsbUNBQTRDO0FBQzVDLHNEQUFxRTtBQUNyRSxrRUFBMEM7QUFDMUMsMkVBQWlEO0FBQ2pELG1GQUEwRDtBQUMxRCw0Q0FBK0U7QUFDL0UsK0VBQXNEO0FBQ3RELHVGQUFnRTtBQUNoRSx1R0FBNEU7QUFFNUUscURBZTBCO0FBRTFCLG9FQUEyQztBQVMzQyxzRkFBNkQ7QUFDN0QsNERBQWdGO0FBRWhGLG9FQUEyRDtBQUUzRCx3REFBbUM7QUFDbkMsK0NBQWlEO0FBQ2pELDJDQUFpRDtBQUNqRCw4REFBMkQ7QUFFM0QsbUNBQTJDO0FBRTNDLE1BQU0sMkJBQTJCLEdBQUcsYUFBYSxDQUFDO0FBQ2xELE1BQU0sdUJBQXVCLEdBQVEsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBVSxDQUFvQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsMkJBQTJCLEdBQUcsaUJBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDL0osTUFBTSw2QkFBNkIsR0FBRyxhQUFhLENBQUM7QUFFcEQsTUFBTSxpQkFBaUIsR0FBRztJQUN0QixzQkFBWSxDQUFDLFNBQVM7SUFDdEIsc0JBQVksQ0FBQyxXQUFXO0lBQ3hCLHNCQUFZLENBQUMsa0JBQWtCO0lBQy9CLHNCQUFZLENBQUMsZUFBZTtJQUM1QixzQkFBWSxDQUFDLHNCQUFzQjtJQUNuQyxzQkFBWSxDQUFDLGtCQUFrQjtJQUMvQixzQkFBWSxDQUFDLGtCQUFrQjtJQUMvQixzQkFBWSxDQUFDLGtCQUFrQjtJQUMvQixzQkFBWSxDQUFDLHNCQUFzQjtDQUN0QyxDQUFDO0FBRUYsTUFBTSxzQkFBc0IsR0FBRztJQUMzQixzQkFB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b3J0IENvbmZpZ3VyYXRpb24gZnJvbSAnLi9jb25maWd1cmF0aW9uLWJhc2UnO1xuaW1wb3J0IHsgY2FzdEFycmF5LCBmbGF0dGVuIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGdldEdyZXBPcHRpb25zLCBnZXRTU0xPcHRpb25zIH0gZnJvbSAnLi4vdXRpbHMvZ2V0LW9wdGlvbnMnO1xuaW1wb3J0IE9QVElPTl9OQU1FUyBmcm9tICcuL29wdGlvbi1uYW1lcyc7XG5pbXBvcnQgZ2V0RmlsdGVyRm4gZnJvbSAnLi4vdXRpbHMvZ2V0LWZpbHRlci1mbic7XG5pbXBvcnQgcHJlcGFyZVJlcG9ydGVycyBmcm9tICcuLi91dGlscy9wcmVwYXJlLXJlcG9ydGVycyc7XG5pbXBvcnQgeyBnZXRDb25jYXRlbmF0ZWRWYWx1ZXNTdHJpbmcsIGdldFBsdXJhbFN1ZmZpeCB9IGZyb20gJy4uL3V0aWxzL3N0cmluZyc7XG5pbXBvcnQgcmVuZGVyVGVtcGxhdGUgZnJvbSAnLi4vdXRpbHMvcmVuZGVyLXRlbXBsYXRlJztcbmltcG9ydCBXQVJOSU5HX01FU1NBR0VTIGZyb20gJy4uL25vdGlmaWNhdGlvbnMvd2FybmluZy1tZXNzYWdlJztcbmltcG9ydCByZXNvbHZlUGF0aFJlbGF0aXZlbHlDd2QgZnJvbSAnLi4vdXRpbHMvcmVzb2x2ZS1wYXRoLXJlbGF0aXZlbHktY3dkJztcblxuaW1wb3J0IHtcbiAgICBERUZBVUxUX0FQUF9JTklUX0RFTEFZLFxuICAgIERFRkFVTFRfQ09OQ1VSUkVOQ1lfVkFMVUUsXG4gICAgREVGQVVMVF9ERVZFTE9QTUVOVF9NT0RFLFxuICAgIERFRkFVTFRfRElTQUJMRV9DUk9TU19ET01BSU4sXG4gICAgREVGQVVMVF9ESVNBQkxFX0hUVFAyLFxuICAgIERFRkFVTFRfRklMVEVSX0ZOLFxuICAgIERFRkFVTFRfRElTQUJMRV9OQVRJVkVfQVVUT01BVElPTixcbiAgICBERUZBVUxUX1JFVFJZX1RFU1RfUEFHRVMsXG4gICAgREVGQVVMVF9TQ1JFRU5TSE9UX1RIVU1CTkFJTFMsXG4gICAgREVGQVVMVF9TT1VSQ0VfRElSRUNUT1JJRVMsXG4gICAgREVGQVVMVF9TUEVFRF9WQUxVRSxcbiAgICBERUZBVUxUX1RJTUVPVVQsXG4gICAgREVGQVVMVF9FWFBFUklNRU5UQUxfTVVMVElQTEVfV0lORE9XUyxcbiAgICBnZXREZWZhdWx0Q29tcGlsZXJPcHRpb25zLFxufSBmcm9tICcuL2RlZmF1bHQtdmFsdWVzJztcblxuaW1wb3J0IE9wdGlvblNvdXJjZSBmcm9tICcuL29wdGlvbi1zb3VyY2UnO1xuXG5pbXBvcnQge1xuICAgIERpY3Rpb25hcnksXG4gICAgRmlsdGVyT3B0aW9uLFxuICAgIFJlcG9ydGVyT3B0aW9uLFxuICAgIFR5cGVTY3JpcHRDb21waWxlck9wdGlvbnMsXG59IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5cbmltcG9ydCBDdXN0b21pemFibGVDb21waWxlcnMgZnJvbSAnLi9jdXN0b21pemFibGUtY29tcGlsZXJzJztcbmltcG9ydCB7IERFUFJFQ0FURUQsIGdldERlcHJlY2F0aW9uTWVzc2FnZSB9IGZyb20gJy4uL25vdGlmaWNhdGlvbnMvZGVwcmVjYXRlZCc7XG5pbXBvcnQgV2FybmluZ0xvZyBmcm9tICcuLi9ub3RpZmljYXRpb25zL3dhcm5pbmctbG9nJztcbmltcG9ydCBicm93c2VyUHJvdmlkZXJQb29sIGZyb20gJy4uL2Jyb3dzZXIvcHJvdmlkZXIvcG9vbCc7XG5pbXBvcnQgQnJvd3NlckNvbm5lY3Rpb24sIHsgQnJvd3NlckNvbm5lY3Rpb25PcHRpb25zLCBCcm93c2VySW5mbyB9IGZyb20gJy4uL2Jyb3dzZXIvY29ubmVjdGlvbic7XG5pbXBvcnQgRXh0ZW5zaW9ucyBmcm9tICcuL2Zvcm1hdHMnO1xuaW1wb3J0IHsgR2VuZXJhbEVycm9yIH0gZnJvbSAnLi4vZXJyb3JzL3J1bnRpbWUnO1xuaW1wb3J0IHsgUlVOVElNRV9FUlJPUlMgfSBmcm9tICcuLi9lcnJvcnMvdHlwZXMnO1xuaW1wb3J0IHsgTE9DQUxIT1NUX05BTUVTIH0gZnJvbSAnLi4vdXRpbHMvbG9jYWxob3N0LW5hbWVzJztcbmltcG9ydCB7IEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheU9wdGlvbnMgfSBmcm9tICcuLi9icm93c2VyL2Nvbm5lY3Rpb24vZ2F0ZXdheSc7XG5pbXBvcnQgeyBnZXRWYWxpZEhvc3RuYW1lIH0gZnJvbSAnLi91dGlscyc7XG5cbmNvbnN0IEJBU0VfQ09ORklHVVJBVElPTl9GSUxFTkFNRSA9ICcudGVzdGNhZmVyYyc7XG5jb25zdCBDT05GSUdVUkFUSU9OX0ZJTEVOQU1FUyAgICAgPSAoT2JqZWN0LmtleXMoRXh0ZW5zaW9ucykgYXMgQXJyYXk8a2V5b2YgdHlwZW9mIEV4dGVuc2lvbnM+KS5tYXAoZXh0ID0+IGAke0JBU0VfQ09ORklHVVJBVElPTl9GSUxFTkFNRX0ke0V4dGVuc2lvbnNbZXh0XX1gKTtcbmNvbnN0IERFRkFVTFRfU0NSRUVOU0hPVFNfRElSRUNUT1JZID0gJ3NjcmVlbnNob3RzJztcblxuY29uc3QgT1BUSU9OX0ZMQUdfTkFNRVMgPSBbXG4gICAgT1BUSU9OX05BTUVTLmRlYnVnTW9kZSxcbiAgICBPUFRJT05fTkFNRVMuZGVidWdPbkZhaWwsXG4gICAgT1BUSU9OX05BTUVTLnNraXBVbmNhdWdodEVycm9ycyxcbiAgICBPUFRJT05fTkFNRVMuc3RvcE9uRmlyc3RGYWlsLFxuICAgIE9QVElPTl9OQU1FUy50YWtlU2NyZWVuc2hvdHNPbkZhaWxzLFxuICAgIE9QVElPTl9OQU1FUy5kaXNhYmxlUGFnZUNhY2hpbmcsXG4gICAgT1BUSU9OX05BTUVTLmRpc2FibGVQYWdlUmVsb2FkcyxcbiAgICBPUFRJT05fTkFNRVMuZGlzYWJsZVNjcmVlbnNob3RzLFxuICAgIE9QVElPTl9OQU1FUy5kaXNhYmxlTXVsdGlwbGVXaW5kb3dzLFxuXTtcblxuY29uc3QgT1BUSU9OX0lOSVRfRkxBR19OQU1FUyA9IFtcbiAgICBPUFRJT05fTkFNRVMuZGV2ZWxvcG1lbnRNb2RlLFxuICAgIE9QVElPTl9OQU1FUy5yZXRyeVRlc3RQYWdlcyxcbiAgICBPUFRJT05fTkFNRVMuY2FjaGUsXG4gICAgT1BUSU9OX05BTUVTLmRpc2FibGVIdHRwMixcbiAgICBPUFRJT05fTkFNRVMuZGlzYWJsZU5hdGl2ZUF1dG9tYXRpb24sXG4gICAgT1BUSU9OX05BTUVTLmRpc2FibGVDcm9zc0RvbWFpbixcbiAgICBPUFRJT05fTkFNRVMuZXhwZXJpbWVudGFsTXVsdGlwbGVXaW5kb3dzLFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBUZXN0Q2FmZVN0YXJ0T3B0aW9ucyB7XG4gICAgaG9zdG5hbWU6IHN0cmluZztcbiAgICBwb3J0MTogbnVtYmVyO1xuICAgIHBvcnQyOiBudW1iZXI7XG4gICAgcmV0cnlUZXN0UGFnZXM6IGJvb2xlYW47XG4gICAgc3NsOiBvYmplY3Q7XG4gICAgZGV2ZWxvcG1lbnRNb2RlOiBib29sZWFuO1xuICAgIGNhY2hlOiBib29sZWFuO1xuICAgIGRpc2FibGVIdHRwMjogYm9vbGVhbjtcbiAgICBuYXRpdmVBdXRvbWF0aW9uOiBib29sZWFuO1xuICAgIGRpc2FibGVDcm9zc0RvbWFpbjogYm9vbGVhbjtcbn1cblxudHlwZSBCcm93c2VySW5mb1NvdXJjZSA9IEJyb3dzZXJJbmZvIHwgQnJvd3NlckNvbm5lY3Rpb247XG5cbnR5cGUgQ2FsY3VsYXRlSG9zdG5hbWVGbiA9IChob3N0bmFtZTogc3RyaW5nKSA9PiBQcm9taXNlPHN0cmluZz47XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlc3RDYWZlQ29uZmlndXJhdGlvbiBleHRlbmRzIENvbmZpZ3VyYXRpb24ge1xuICAgIHByb3RlY3RlZCByZWFkb25seSBfaXNFeHBsaWNpdENvbmZpZzogYm9vbGVhbjtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvciAoY29uZmlnRmlsZSA9ICcnKSB7XG4gICAgICAgIHN1cGVyKGNvbmZpZ0ZpbGUgfHwgQ09ORklHVVJBVElPTl9GSUxFTkFNRVMpO1xuXG4gICAgICAgIHRoaXMuX2lzRXhwbGljaXRDb25maWcgPSAhIWNvbmZpZ0ZpbGU7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGluaXQgKG9wdGlvbnM/OiBEaWN0aW9uYXJ5PG9iamVjdD4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgc3VwZXIuaW5pdCgpO1xuXG4gICAgICAgIGNvbnN0IG9wdHMgPSBhd2FpdCB0aGlzLl9sb2FkKCk7XG5cbiAgICAgICAgaWYgKG9wdHMpIHtcbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMgPSBDb25maWd1cmF0aW9uLl9mcm9tT2JqKG9wdHMpO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9ub3JtYWxpemVPcHRpb25zQWZ0ZXJMb2FkKCk7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLmFzeW5jTWVyZ2VPcHRpb25zKG9wdGlvbnMpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBhc3luY01lcmdlT3B0aW9ucyAob3B0aW9ucz86IERpY3Rpb25hcnk8b2JqZWN0Pik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgICAgICBzdXBlci5tZXJnZU9wdGlvbnMob3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKCFvcHRpb25zLmlzQ2xpICYmIHRoaXMuX29wdGlvbnMuYnJvd3NlcnMpXG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zLmJyb3dzZXJzLnZhbHVlID0gYXdhaXQgdGhpcy5fZ2V0QnJvd3NlckluZm8oKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcHJlcGFyZSAoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX3ByZXBhcmVGbGFncygpO1xuICAgICAgICB0aGlzLl9zZXREZWZhdWx0VmFsdWVzKCk7XG4gICAgICAgIHRoaXMuX3ByZXBhcmVDb21waWxlck9wdGlvbnMoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbm90aWZ5QWJvdXRPdmVycmlkZGVuT3B0aW9ucyAod2FybmluZ0xvZz86IFdhcm5pbmdMb2cpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLl9vdmVycmlkZGVuT3B0aW9ucy5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3Qgb3B0aW9uc1N0ciAgICA9IGdldENvbmNhdGVuYXRlZFZhbHVlc1N0cmluZyh0aGlzLl9vdmVycmlkZGVuT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnNTdWZmaXggPSBnZXRQbHVyYWxTdWZmaXgodGhpcy5fb3ZlcnJpZGRlbk9wdGlvbnMpO1xuICAgICAgICBjb25zdCByZW5kZXJlZE1lc3NhZ2UgPSByZW5kZXJUZW1wbGF0ZShXQVJOSU5HX01FU1NBR0VTLmNvbmZpZ09wdGlvbnNXZXJlT3ZlcnJpZGRlbiwgb3B0aW9uc1N0ciwgb3B0aW9uc1N1ZmZpeCk7XG5cbiAgICAgICAgQ29uZmlndXJhdGlvbi5fc2hvd0NvbnNvbGVXYXJuaW5nKHJlbmRlcmVkTWVzc2FnZSk7XG5cbiAgICAgICAgaWYgKHdhcm5pbmdMb2cpXG4gICAgICAgICAgICB3YXJuaW5nTG9nLmFkZFdhcm5pbmcocmVuZGVyZWRNZXNzYWdlKTtcblxuICAgICAgICB0aGlzLl9vdmVycmlkZGVuT3B0aW9ucyA9IFtdO1xuICAgIH1cblxuICAgIHB1YmxpYyBub3RpZnlBYm91dERlcHJlY2F0ZWRPcHRpb25zICh3YXJuaW5nTG9nOiBXYXJuaW5nTG9nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGRlcHJlY2F0ZWRPcHRpb25zID0gdGhpcy5nZXRPcHRpb25zKChuYW1lLCBvcHRpb24pID0+IG5hbWUgaW4gREVQUkVDQVRFRCAmJiBvcHRpb24udmFsdWUgIT09IHZvaWQgMCk7XG5cbiAgICAgICAgZm9yIChjb25zdCBvcHRpb25OYW1lIGluIGRlcHJlY2F0ZWRPcHRpb25zKVxuICAgICAgICAgICAgd2FybmluZ0xvZy5hZGRXYXJuaW5nKGdldERlcHJlY2F0aW9uTWVzc2FnZShERVBSRUNBVEVEW29wdGlvbk5hbWVdKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzdGFydE9wdGlvbnMgKCk6IFRlc3RDYWZlU3RhcnRPcHRpb25zIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGhvc3RuYW1lOiAgICAgICAgICAgdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLmhvc3RuYW1lKSxcbiAgICAgICAgICAgIHBvcnQxOiAgICAgICAgICAgICAgdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLnBvcnQxKSxcbiAgICAgICAgICAgIHBvcnQyOiAgICAgICAgICAgICAgdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLnBvcnQyKSxcbiAgICAgICAgICAgIHNzbDogICAgICAgICAgICAgICAgdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLnNzbCksXG4gICAgICAgICAgICBkZXZlbG9wbWVudE1vZGU6ICAgIHRoaXMuZ2V0T3B0aW9uKE9QVElPTl9OQU1FUy5kZXZlbG9wbWVudE1vZGUpLFxuICAgICAgICAgICAgcmV0cnlUZXN0UGFnZXM6ICAgICB0aGlzLmdldE9wdGlvbihPUFRJT05fTkFNRVMucmV0cnlUZXN0UGFnZXMpLFxuICAgICAgICAgICAgY2FjaGU6ICAgICAgICAgICAgICB0aGlzLmdldE9wdGlvbihPUFRJT05fTkFNRVMuY2FjaGUpLFxuICAgICAgICAgICAgZGlzYWJsZUh0dHAyOiAgICAgICB0aGlzLmdldE9wdGlvbihPUFRJT05fTkFNRVMuZGlzYWJsZUh0dHAyKSxcbiAgICAgICAgICAgIGRpc2FibGVDcm9zc0RvbWFpbjogdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLmRpc2FibGVDcm9zc0RvbWFpbiksXG4gICAgICAgICAgICBuYXRpdmVBdXRvbWF0aW9uOiAgICF0aGlzLmdldE9wdGlvbihPUFRJT05fTkFNRVMuZGlzYWJsZU5hdGl2ZUF1dG9tYXRpb24pLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgYnJvd3NlckNvbm5lY3Rpb25HYXRld2F5T3B0aW9ucyAoKTogQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5T3B0aW9ucyB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXRyeVRlc3RQYWdlczogdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLnJldHJ5VGVzdFBhZ2VzKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHJlbW90ZUJyb3dzZXJDb25uZWN0aW9uT3B0aW9ucyAoKTogQnJvd3NlckNvbm5lY3Rpb25PcHRpb25zIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRpc2FibGVNdWx0aXBsZVdpbmRvd3M6IHRydWUsXG4gICAgICAgICAgICBuYXRpdmVBdXRvbWF0aW9uOiAgICAgICBmYWxzZSxcbiAgICAgICAgICAgIGRldmVsb3BtZW50TW9kZTogICAgICAgIHRoaXMuZ2V0T3B0aW9uKE9QVElPTl9OQU1FUy5kZXZlbG9wbWVudE1vZGUpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgX3ByZXBhcmVGbGFnIChuYW1lOiBzdHJpbmcsIHNvdXJjZSA9IE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuX2Vuc3VyZU9wdGlvbihuYW1lLCB2b2lkIDAsIHNvdXJjZSk7XG5cbiAgICAgICAgb3B0aW9uLnZhbHVlID0gISFvcHRpb24udmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcHJlcGFyZUZsYWdzICgpOiB2b2lkIHtcbiAgICAgICAgT1BUSU9OX0ZMQUdfTkFNRVMuZm9yRWFjaChuYW1lID0+IHRoaXMuX3ByZXBhcmVGbGFnKG5hbWUpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9wcmVwYXJlSW5pdEZsYWdzICgpOiB2b2lkIHtcbiAgICAgICAgT1BUSU9OX0lOSVRfRkxBR19OQU1FUy5mb3JFYWNoKG5hbWUgPT4gdGhpcy5fcHJlcGFyZUZsYWcobmFtZSwgT3B0aW9uU291cmNlLkRlZmF1bHQpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9ub3JtYWxpemVPcHRpb25zQWZ0ZXJMb2FkICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5fcHJlcGFyZVNzbE9wdGlvbnMoKTtcbiAgICAgICAgdGhpcy5fcHJlcGFyZUluaXRGbGFncygpO1xuICAgICAgICB0aGlzLl9wcmVwYXJlRmlsdGVyRm4oKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlQXJyYXlPcHRpb24oT1BUSU9OX05BTUVTLnNyYyk7XG4gICAgICAgIHRoaXMuX2Vuc3VyZUFycmF5T3B0aW9uKE9QVElPTl9OQU1FUy5icm93c2Vycyk7XG4gICAgICAgIHRoaXMuX2Vuc3VyZUFycmF5T3B0aW9uKE9QVElPTl9OQU1FUy5jbGllbnRTY3JpcHRzKTtcbiAgICAgICAgdGhpcy5fcHJlcGFyZVJlcG9ydGVycygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3ByZXBhcmVGaWx0ZXJGbiAoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGZpbHRlck9wdGlvbiA9IHRoaXMuX2Vuc3VyZU9wdGlvbihPUFRJT05fTkFNRVMuZmlsdGVyLCBERUZBVUxUX0ZJTFRFUl9GTiwgT3B0aW9uU291cmNlLkRlZmF1bHQpO1xuXG4gICAgICAgIGlmICghZmlsdGVyT3B0aW9uLnZhbHVlKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IGZpbHRlck9wdGlvblZhbHVlID0gZmlsdGVyT3B0aW9uLnZhbHVlIGFzIEZpbHRlck9wdGlvbjtcblxuICAgICAgICBpZiAoZmlsdGVyT3B0aW9uVmFsdWUudGVzdEdyZXApXG4gICAgICAgICAgICBmaWx0ZXJPcHRpb25WYWx1ZS50ZXN0R3JlcCA9IGdldEdyZXBPcHRpb25zKE9QVElPTl9OQU1FUy5maWx0ZXJUZXN0R3JlcCwgZmlsdGVyT3B0aW9uVmFsdWUudGVzdEdyZXAgYXMgc3RyaW5nKTtcblxuICAgICAgICBpZiAoZmlsdGVyT3B0aW9uVmFsdWUuZml4dHVyZUdyZXApXG4gICAgICAgICAgICBmaWx0ZXJPcHRpb25WYWx1ZS5maXh0dXJlR3JlcCA9IGdldEdyZXBPcHRpb25zKE9QVElPTl9OQU1FUy5maWx0ZXJGaXh0dXJlR3JlcCwgZmlsdGVyT3B0aW9uVmFsdWUuZml4dHVyZUdyZXAgYXMgc3RyaW5nKTtcblxuICAgICAgICBmaWx0ZXJPcHRpb24udmFsdWUgID0gZ2V0RmlsdGVyRm4oZmlsdGVyT3B0aW9uLnZhbHVlKSBhcyBGdW5jdGlvbjtcbiAgICAgICAgZmlsdGVyT3B0aW9uLnNvdXJjZSA9IE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2Vuc3VyZVNjcmVlbnNob3RPcHRpb25zICgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcGF0aCAgICAgICAgPSByZXNvbHZlUGF0aFJlbGF0aXZlbHlDd2QoREVGQVVMVF9TQ1JFRU5TSE9UU19ESVJFQ1RPUlkpO1xuICAgICAgICBjb25zdCBzY3JlZW5zaG90cyA9IHRoaXMuX2Vuc3VyZU9wdGlvbihPUFRJT05fTkFNRVMuc2NyZWVuc2hvdHMsIHt9LCBPcHRpb25Tb3VyY2UuQ29uZmlndXJhdGlvbikudmFsdWUgYXMgRGljdGlvbmFyeTxzdHJpbmd8Ym9vbGVhbj47XG5cbiAgICAgICAgaWYgKCFzY3JlZW5zaG90cy5wYXRoKVxuICAgICAgICAgICAgc2NyZWVuc2hvdHMucGF0aCA9IHBhdGg7XG5cbiAgICAgICAgaWYgKHNjcmVlbnNob3RzLnRodW1ibmFpbHMgPT09IHZvaWQgMClcbiAgICAgICAgICAgIHNjcmVlbnNob3RzLnRodW1ibmFpbHMgPSBERUZBVUxUX1NDUkVFTlNIT1RfVEhVTUJOQUlMUztcbiAgICB9XG5cbiAgICBwcml2YXRlIF9lbnN1cmVTa2lwSnNPcHRpb25zICgpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uID0gdGhpcy5fZW5zdXJlT3B0aW9uKE9QVElPTl9OQU1FUy5za2lwSnNFcnJvcnMsIHZvaWQgMCwgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuXG4gICAgICAgIGlmIChvcHRpb24udmFsdWUgPT09IHZvaWQgMClcbiAgICAgICAgICAgIG9wdGlvbi52YWx1ZSA9ICEhb3B0aW9uLnZhbHVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3ByZXBhcmVSZXBvcnRlcnMgKCk6IHZvaWQge1xuICAgICAgICBjb25zdCByZXBvcnRlck9wdGlvbiA9IHRoaXMuX29wdGlvbnNbT1BUSU9OX05BTUVTLnJlcG9ydGVyXTtcblxuICAgICAgICBpZiAoIXJlcG9ydGVyT3B0aW9uKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IG9wdGlvblZhbHVlID0gY2FzdEFycmF5KHJlcG9ydGVyT3B0aW9uLnZhbHVlIGFzIFJlcG9ydGVyT3B0aW9uKTtcblxuICAgICAgICByZXBvcnRlck9wdGlvbi52YWx1ZSA9IHByZXBhcmVSZXBvcnRlcnMob3B0aW9uVmFsdWUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX3ByZXBhcmVTc2xPcHRpb25zICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3Qgc3NsT3B0aW9ucyA9IHRoaXMuX29wdGlvbnNbT1BUSU9OX05BTUVTLnNzbF07XG5cbiAgICAgICAgaWYgKCFzc2xPcHRpb25zKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHNzbE9wdGlvbnMudmFsdWUgPSBhd2FpdCBnZXRTU0xPcHRpb25zKHNzbE9wdGlvbnMudmFsdWUgYXMgc3RyaW5nKSBhcyBEaWN0aW9uYXJ5PHN0cmluZyB8IGJvb2xlYW4gfCBudW1iZXI+O1xuICAgIH1cblxuICAgIHByaXZhdGUgX3NldERlZmF1bHRWYWx1ZXMgKCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9lbnN1cmVPcHRpb25XaXRoVmFsdWUoT1BUSU9OX05BTUVTLnNlbGVjdG9yVGltZW91dCwgREVGQVVMVF9USU1FT1VULnNlbGVjdG9yLCBPcHRpb25Tb3VyY2UuQ29uZmlndXJhdGlvbik7XG4gICAgICAgIHRoaXMuX2Vuc3VyZU9wdGlvbldpdGhWYWx1ZShPUFRJT05fTkFNRVMuYXNzZXJ0aW9uVGltZW91dCwgREVGQVVMVF9USU1FT1VULmFzc2VydGlvbiwgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuICAgICAgICB0aGlzLl9lbnN1cmVPcHRpb25XaXRoVmFsdWUoT1BUSU9OX05BTUVTLnBhZ2VMb2FkVGltZW91dCwgREVGQVVMVF9USU1FT1VULnBhZ2VMb2FkLCBPcHRpb25Tb3VyY2UuQ29uZmlndXJhdGlvbik7XG4gICAgICAgIHRoaXMuX2Vuc3VyZU9wdGlvbldpdGhWYWx1ZShPUFRJT05fTkFNRVMuc3BlZWQsIERFRkFVTFRfU1BFRURfVkFMVUUsIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlT3B0aW9uV2l0aFZhbHVlKE9QVElPTl9OQU1FUy5hcHBJbml0RGVsYXksIERFRkFVTFRfQVBQX0lOSVRfREVMQVksIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlT3B0aW9uV2l0aFZhbHVlKE9QVElPTl9OQU1FUy5jb25jdXJyZW5jeSwgREVGQVVMVF9DT05DVVJSRU5DWV9WQUxVRSwgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuICAgICAgICB0aGlzLl9lbnN1cmVPcHRpb25XaXRoVmFsdWUoT1BUSU9OX05BTUVTLnNyYywgREVGQVVMVF9TT1VSQ0VfRElSRUNUT1JJRVMsIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlT3B0aW9uV2l0aFZhbHVlKE9QVElPTl9OQU1FUy5kZXZlbG9wbWVudE1vZGUsIERFRkFVTFRfREVWRUxPUE1FTlRfTU9ERSwgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuICAgICAgICB0aGlzLl9lbnN1cmVPcHRpb25XaXRoVmFsdWUoT1BUSU9OX05BTUVTLnJldHJ5VGVzdFBhZ2VzLCBERUZBVUxUX1JFVFJZX1RFU1RfUEFHRVMsIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlT3B0aW9uV2l0aFZhbHVlKE9QVElPTl9OQU1FUy5kaXNhYmxlSHR0cDIsIERFRkFVTFRfRElTQUJMRV9IVFRQMiwgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuICAgICAgICB0aGlzLl9lbnN1cmVPcHRpb25XaXRoVmFsdWUoT1BUSU9OX05BTUVTLmRpc2FibGVOYXRpdmVBdXRvbWF0aW9uLCBERUZBVUxUX0RJU0FCTEVfTkFUSVZFX0FVVE9NQVRJT04sIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlT3B0aW9uV2l0aFZhbHVlKE9QVElPTl9OQU1FUy5leHBlcmltZW50YWxNdWx0aXBsZVdpbmRvd3MsIERFRkFVTFRfRVhQRVJJTUVOVEFMX01VTFRJUExFX1dJTkRPV1MsIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlT3B0aW9uV2l0aFZhbHVlKE9QVElPTl9OQU1FUy5kaXNhYmxlQ3Jvc3NEb21haW4sIERFRkFVTFRfRElTQUJMRV9DUk9TU19ET01BSU4sIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTtcblxuICAgICAgICB0aGlzLl9lbnN1cmVTY3JlZW5zaG90T3B0aW9ucygpO1xuICAgICAgICB0aGlzLl9lbnN1cmVTa2lwSnNPcHRpb25zKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcHJlcGFyZUNvbXBpbGVyT3B0aW9ucyAoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbXBpbGVyT3B0aW9ucyA9IHRoaXMuX2Vuc3VyZU9wdGlvbihPUFRJT05fTkFNRVMuY29tcGlsZXJPcHRpb25zLCBnZXREZWZhdWx0Q29tcGlsZXJPcHRpb25zKCksIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTtcblxuICAgICAgICBjb21waWxlck9wdGlvbnMudmFsdWUgPSBjb21waWxlck9wdGlvbnMudmFsdWUgfHwgZ2V0RGVmYXVsdENvbXBpbGVyT3B0aW9ucygpO1xuXG4gICAgICAgIGNvbnN0IHRzQ29uZmlnUGF0aCA9IHRoaXMuZ2V0T3B0aW9uKE9QVElPTl9OQU1FUy50c0NvbmZpZ1BhdGgpO1xuXG4gICAgICAgIGlmICh0c0NvbmZpZ1BhdGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXBpbGVyT3B0aW9uVmFsdWUgICAgID0gY29tcGlsZXJPcHRpb25zLnZhbHVlIGFzIENvbXBpbGVyT3B0aW9ucztcbiAgICAgICAgICAgIGxldCB0eXBlU2NyaXB0Q29tcGlsZXJPcHRpb25zID0gY29tcGlsZXJPcHRpb25WYWx1ZVtDdXN0b21pemFibGVDb21waWxlcnMudHlwZXNjcmlwdF0gYXMgVHlwZVNjcmlwdENvbXBpbGVyT3B0aW9ucztcblxuICAgICAgICAgICAgdHlwZVNjcmlwdENvbXBpbGVyT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgICAgIGNvbmZpZ1BhdGg6IHRzQ29uZmlnUGF0aCxcbiAgICAgICAgICAgIH0sIHR5cGVTY3JpcHRDb21waWxlck9wdGlvbnMpO1xuXG4gICAgICAgICAgICAoY29tcGlsZXJPcHRpb25zLnZhbHVlIGFzIENvbXBpbGVyT3B0aW9ucylbQ3VzdG9taXphYmxlQ29tcGlsZXJzLnR5cGVzY3JpcHRdID0gdHlwZVNjcmlwdENvbXBpbGVyT3B0aW9ucztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX2dldEJyb3dzZXJJbmZvICgpOiBQcm9taXNlPEJyb3dzZXJJbmZvU291cmNlW10+IHtcbiAgICAgICAgaWYgKCF0aGlzLl9vcHRpb25zLmJyb3dzZXJzLnZhbHVlKVxuICAgICAgICAgICAgcmV0dXJuIFtdO1xuXG4gICAgICAgIGNvbnN0IGJyb3dzZXJzID0gQXJyYXkuaXNBcnJheSh0aGlzLl9vcHRpb25zLmJyb3dzZXJzLnZhbHVlKSA/IFsuLi50aGlzLl9vcHRpb25zLmJyb3dzZXJzLnZhbHVlXSA6IFt0aGlzLl9vcHRpb25zLmJyb3dzZXJzLnZhbHVlXTtcblxuICAgICAgICBjb25zdCBicm93c2VySW5mbyA9IGF3YWl0IFByb21pc2UuYWxsKGJyb3dzZXJzLm1hcChicm93c2VyID0+IGJyb3dzZXJQcm92aWRlclBvb2wuZ2V0QnJvd3NlckluZm8oYnJvd3NlcikpKTtcblxuICAgICAgICByZXR1cm4gZmxhdHRlbihicm93c2VySW5mbyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGFzeW5jIF9pc0NvbmZpZ3VyYXRpb25GaWxlRXhpc3RzIChmaWxlUGF0aCA9IHRoaXMuZmlsZVBhdGgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgY29uc3QgZmlsZUV4aXN0cyA9IGF3YWl0IHN1cGVyLl9pc0NvbmZpZ3VyYXRpb25GaWxlRXhpc3RzKGZpbGVQYXRoKTtcblxuICAgICAgICBpZiAoIWZpbGVFeGlzdHMgJiYgdGhpcy5faXNFeHBsaWNpdENvbmZpZylcbiAgICAgICAgICAgIHRocm93IG5ldyBHZW5lcmFsRXJyb3IoUlVOVElNRV9FUlJPUlMuY2Fubm90RmluZFRlc3RjYWZlQ29uZmlndXJhdGlvbkZpbGUsIGZpbGVQYXRoKTtcblxuICAgICAgICByZXR1cm4gZmlsZUV4aXN0cztcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGdldCBGSUxFTkFNRVMgKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIENPTkZJR1VSQVRJT05fRklMRU5BTUVTO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBlbnN1cmVIb3N0bmFtZSAoY2FsY3VsYXRlRm46IENhbGN1bGF0ZUhvc3RuYW1lRm4gPSBnZXRWYWxpZEhvc3RuYW1lKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCBob3N0bmFtZSA9IHRoaXMuZ2V0T3B0aW9uPHN0cmluZz4oT1BUSU9OX05BTUVTLmhvc3RuYW1lKTtcblxuICAgICAgICBob3N0bmFtZSA9IGF3YWl0IGNhbGN1bGF0ZUZuKGhvc3RuYW1lKTtcblxuICAgICAgICB0aGlzLm1lcmdlT3B0aW9ucyh7IGhvc3RuYW1lIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBjYWxjdWxhdGVIb3N0bmFtZSAoeyBuYXRpdmVBdXRvbWF0aW9uIH0gPSB7IG5hdGl2ZUF1dG9tYXRpb246IGZhbHNlIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5lbnN1cmVIb3N0bmFtZShhc3luYyBob3N0bmFtZSA9PiB7XG4gICAgICAgICAgICBpZiAobmF0aXZlQXV0b21hdGlvbilcbiAgICAgICAgICAgICAgICBob3N0bmFtZSA9IExPQ0FMSE9TVF9OQU1FUy5MT0NBTEhPU1Q7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgaG9zdG5hbWUgPSBhd2FpdCBnZXRWYWxpZEhvc3RuYW1lKGhvc3RuYW1lKTtcblxuICAgICAgICAgICAgcmV0dXJuIGhvc3RuYW1lO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iXX0=