UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

236 lines 43.6 kB
"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=