"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = require("lodash"); const commander_1 = __importStar(require("commander")); const dedent_1 = __importDefault(require("dedent")); const runtime_1 = require("../../errors/runtime"); const types_1 = require("../../errors/types"); const type_assertions_1 = require("../../errors/runtime/type-assertions"); const get_viewport_width_1 = __importDefault(require("../../utils/get-viewport-width")); const string_1 = require("../../utils/string"); const get_options_1 = require("../../utils/get-options"); const get_filter_fn_1 = __importDefault(require("../../utils/get-filter-fn")); const screenshot_option_names_1 = __importDefault(require("../../configuration/screenshot-option-names")); const run_option_names_1 = __importDefault(require("../../configuration/run-option-names")); const quarantine_option_names_1 = __importDefault(require("../../configuration/quarantine-option-names")); const node_arguments_filter_1 = require("../node-arguments-filter"); const get_testcafe_version_1 = __importDefault(require("../../utils/get-testcafe-version")); const parse_utils_1 = require("./parse-utils"); const command_names_1 = __importDefault(require("./command-names")); const skip_js_errors_option_names_1 = require("../../configuration/skip-js-errors-option-names"); const REMOTE_ALIAS_RE = /^remote(?::(\d*))?$/; const DESCRIPTION = (0, dedent_1.default)(` To select a browser, specify an alias ("ie", "chrome", etc.) or the path to the browser executable. You can select more than one browser. Use the "all" alias to run tests against all available browsers. Use the "remote" alias to run tests on remote devices, like smartphones or tablets. Specify the number of remote browsers after the semicolon ("remote:3"). If you use a browser provider plugin, specify both the name of the plugin and the name of the browser. Separate the two with a semicolon ("saucelabs:chrome@51"). To execute multiple test files, specify multiple file paths or glob patterns. Full documentation: https://testcafe.io/documentation/402639/reference/command-line-interface `); class CLIArgumentParser { constructor(cwd) { this.cwd = cwd || process.cwd(); this.remoteCount = 0; this.opts = {}; this.args = []; this.isDashboardCommand = false; this.testCafeCommand = this._addTestCafeCommand(); this._patchHelpOutput(this.testCafeCommand); CLIArgumentParser._setupRootCommand(); } static _setupRootCommand() { // NOTE: We are forced to set the name of the root command to 'testcafe' // to avoid the automatic command name calculation using the executed file path. // It's necessary to correct command description for nested commands. commander_1.default.name(command_names_1.default.TestCafe); } static _removeCommandIfExists(name) { // NOTE: Bug in the 'commander' module. // It's possible to add a few commands with the same name. // Also, removing is a better than conditionally adding // because it allows avoiding the parsed option duplicates. const index = commander_1.default.commands.findIndex(cmd => cmd.name() === name); if (index > -1) commander_1.default.commands.splice(index, 1); } static _getDescription() { // NOTE: add empty line to workaround commander-forced indentation on the first line. return '\n' + (0, string_1.wordWrap)(DESCRIPTION, 2, (0, get_viewport_width_1.default)(process.stdout)); } _addTestCafeCommand() { CLIArgumentParser._removeCommandIfExists(command_names_1.default.TestCafe); return commander_1.default .command(command_names_1.default.TestCafe, { isDefault: true }) .version((0, get_testcafe_version_1.default)(), '-v, --version') .usage('[options] ') .description(CLIArgumentParser._getDescription()) .allowUnknownOption() .option('-b, --list-browsers [provider]', 'display the list of aliases for available browsers and browser providers') .option('-r, --reporter ', 'specify reporters and report filenames') .option('-s, --screenshots ', 'specify screenshot options') .option('-S, --screenshots-on-fails', 'take a screenshot on test failure') .option('-p, --screenshot-path-pattern ', 'specify the naming schema for screenshot filenames and paths: ${BROWSER}, ${BROWSER_VERSION}, ${OS}, etc.') .option('-q, --quarantine-mode [option=value,...]', 'enable and configure quarantine mode') .option('-d, --debug-mode', 'enable debug mode. When you run TestCafe in debug mode, it executes test steps one by one, and pauses the test after each step.') .option('-e, --skip-js-errors [option=value,...]', 'ignore JavaScript errors that match the specified criteria') .option('-u, --skip-uncaught-errors', 'ignore uncaught errors and unhandled promise rejections') .option('-t, --test ', 'filter tests by name') .option('-T, --test-grep ', 'filter tests by regular expression') .option('-f, --fixture ', 'filter fixtures by name') .option('-F, --fixture-grep ', 'filter fixtures by regular expression') .option('-a, --app ', 'execute a shell command on startup to launch a web application or perform other preparatory tasks') .option('-c, --concurrency ', 'run tests concurrently') .option('-L, --live', 'enable live mode. Live mode restarts tests when you make changes to test files.') .option('--test-meta ', 'filter tests by metadata') .option('--fixture-meta ', 'filter fixtures by metadata') .option('--debug-on-fail', 'pause tests on failure') .option('--experimental-proxyless', 'enable proxyless mode: https://testcafe.io/documentation/404237/guides/experimental-capabilities/proxyless-mode') .option('--app-init-delay ', 'specify your application`s initialization time') .option('--selector-timeout ', 'specify the maximum Selector resolution time') .option('--assertion-timeout ', 'specify the maximum Assertion resolution time') .option('--page-load-timeout ', 'specify the maximum time between the window.load event and the DOMContentLoaded event (ms)') .option('--page-request-timeout ', 'specify the maximum page request resolution time') .option('--ajax-request-timeout ', 'specify the maximum AJAX request resolution time') .option('--browser-init-timeout ', 'specify the maximum browser startup time') .option('--test-execution-timeout ', 'specify the maximum test execution time') .option('--run-execution-timeout ', 'specify the maximum test run time') .option('--speed ', 'set test execution speed (0.01 ... 1)') .option('--ports ', 'specify network ports to use during the test run. The second port is necessary to access cross-domain resources.') .option('--hostname ', `specify your hostname. Necessary to run tests in remote browsers.`) .option('--proxy ', 'specify the proxy server hostname or IP address') .option('--proxy-bypass ', 'specify URLs that bypass the proxy server') .option('--ssl ', 'specify SSL options to run TestCafe over HTTPS') .option('--video ', 'record videos of test runs') .option('--video-options ', 'specify video recording options') .option('--video-encoding-options ', 'specify video encoding options') .option('--dev', 'log and diagnose TestCafe errors') .option('--qr-code', 'output QR codes with URLs for remote browser connections') .option('--sf, --stop-on-first-fail', 'stop the test run if any test fails') .option('--config-file ', 'specify a custom path to the testcafe configuration file') .option('--ts-config-path ', 'specify the path to a custom TypeScript configuration file') .option('--cs, --client-scripts ', 'inject client-side scripts into the page', parse_utils_1.parseList, []) .option('--disable-page-caching', 'do not cache pages') .option('--disable-page-reloads', 'do not reload pages between tests') .option('--retry-test-pages', 'retry page requests in case of failure') .option('--disable-screenshots', 'disable screenshots') .option('--screenshots-full-page', 'enable full-page screenshots') .option('--compiler-options ', 'specify test compilation settings') .option('--disable-multiple-windows', 'disable the multi-window mode') .option('--disable-http2', 'force the proxy to issue HTTP/1.1 requests') .option('--cache', 'cache web assets between test runs') .option('--base-url ', 'set the base url for the test run') // NOTE: these options will be handled by chalk internally .option('--color', 'force TestCafe to format CLI output with color') .option('--no-color', 'disable text color formatting in the CLI') // NOTE: Temporarily exclude experimental options from --help output .addOption(new commander_1.Option('--experimental-debug', 'enable experimental the debug mode').hideHelp()) .addOption(new commander_1.Option('--experimental-esm', 'enable experimental the esm mode').hideHelp()) .addOption(new commander_1.Option('--disable-cross-domain', 'experimental').hideHelp()) .action((opts) => { this.opts = opts; }); } _patchHelpOutput(defaultSubCommand) { // NOTE: In the future versions of the 'commander' module // need to investigate how to remove this hack. commander_1.default.outputHelp = function () { const storedParent = defaultSubCommand.parent; defaultSubCommand.parent = null; defaultSubCommand.outputHelp(); defaultSubCommand.parent = storedParent; }; } _checkAndCountRemotes(browser) { const remoteMatch = browser.match(REMOTE_ALIAS_RE); if (remoteMatch) { this.remoteCount += parseInt(remoteMatch[1], 10) || 1; return false; } return true; } async _parseFilteringOptions() { if (this.opts.testGrep) this.opts.testGrep = (0, get_options_1.getGrepOptions)('--test-grep', this.opts.testGrep); if (this.opts.fixtureGrep) this.opts.fixtureGrep = (0, get_options_1.getGrepOptions)('--fixture-grep', this.opts.fixtureGrep); if (this.opts.testMeta) this.opts.testMeta = await (0, get_options_1.getMetaOptions)('--test-meta', this.opts.testMeta); if (this.opts.fixtureMeta) this.opts.fixtureMeta = await (0, get_options_1.getMetaOptions)('--fixture-meta', this.opts.fixtureMeta); this.opts.filter = (0, get_filter_fn_1.default)(this.opts); } _parseAppInitDelay() { if (this.opts.appInitDelay) { (0, type_assertions_1.assertType)(type_assertions_1.is.nonNegativeNumberString, null, 'The tested app initialization delay', this.opts.appInitDelay); this.opts.appInitDelay = parseInt(this.opts.appInitDelay, 10); } } _parseSelectorTimeout() { if (this.opts.selectorTimeout) { (0, type_assertions_1.assertType)(type_assertions_1.is.nonNegativeNumberString, null, 'The Selector timeout', this.opts.selectorTimeout); this.opts.selectorTimeout = parseInt(this.opts.selectorTimeout, 10); } } _parseAssertionTimeout() { if (this.opts.assertionTimeout) { (0, type_assertions_1.assertType)(type_assertions_1.is.nonNegativeNumberString, null, 'The assertion timeout', this.opts.assertionTimeout); this.opts.assertionTimeout = parseInt(this.opts.assertionTimeout, 10); } } _parsePageLoadTimeout() { if (this.opts.pageLoadTimeout) { (0, type_assertions_1.assertType)(type_assertions_1.is.nonNegativeNumberString, null, 'The page load timeout', this.opts.pageLoadTimeout); this.opts.pageLoadTimeout = parseInt(this.opts.pageLoadTimeout, 10); } } _parsePageRequestTimeout() { if (!this.opts.pageRequestTimeout) return; (0, type_assertions_1.assertType)(type_assertions_1.is.nonNegativeNumberString, null, 'The page request timeout', this.opts.pageRequestTimeout); this.opts.pageRequestTimeout = parseInt(this.opts.pageRequestTimeout, 10); } _parseAjaxRequestTimeout() { if (!this.opts.ajaxRequestTimeout) return; (0, type_assertions_1.assertType)(type_assertions_1.is.nonNegativeNumberString, null, 'The AJAX request timeout', this.opts.ajaxRequestTimeout); this.opts.ajaxRequestTimeout = parseInt(this.opts.ajaxRequestTimeout, 10); } _parseBrowserInitTimeout() { if (!this.opts.browserInitTimeout) return; (0, type_assertions_1.assertType)(type_assertions_1.is.nonNegativeNumberString, null, 'The browser initialization timeout', this.opts.browserInitTimeout); this.opts.browserInitTimeout = parseInt(this.opts.browserInitTimeout, 10); } _parseTestExecutionTimeout() { if (this.opts.testExecutionTimeout) { (0, type_assertions_1.assertType)(type_assertions_1.is.nonNegativeNumberString, null, 'The test execution timeout', this.opts.testExecutionTimeout); this.opts.testExecutionTimeout = parseInt(this.opts.testExecutionTimeout, 10); } } _parseRunExecutionTimeout() { if (this.opts.runExecutionTimeout) { (0, type_assertions_1.assertType)(type_assertions_1.is.nonNegativeNumberString, null, 'The run execution timeout', this.opts.runExecutionTimeout); this.opts.runExecutionTimeout = parseInt(this.opts.runExecutionTimeout, 10); } } _parseSpeed() { if (this.opts.speed) this.opts.speed = parseFloat(this.opts.speed); } _parseConcurrency() { if (this.opts.concurrency) this.opts.concurrency = parseInt(this.opts.concurrency, 10); } async _parseQuarantineOptions() { if (this.opts.quarantineMode) this.opts.quarantineMode = await (0, get_options_1.getQuarantineOptions)('--quarantine-mode', this.opts.quarantineMode); } async _parseSkipJsErrorsOptions() { if (this.opts.skipJsErrors) this.opts.skipJsErrors = await (0, get_options_1.getSkipJsErrorsOptions)('--skip-js-errors', this.opts.skipJsErrors); } _parsePorts() { if (this.opts.ports) { const parsedPorts = this.opts.ports /* eslint-disable-line no-extra-parens */ .split(',') .map(parse_utils_1.parsePortNumber); if (parsedPorts.length < 2) throw new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.portsOptionRequiresTwoNumbers); this.opts.ports = parsedPorts; } } _parseBrowsersFromArgs() { const browsersArg = this.testCafeCommand.args[0] || ''; this.opts.browsers = (0, string_1.splitQuotedText)(browsersArg, ',') .filter(browser => browser && this._checkAndCountRemotes(browser)); } async _parseSslOptions() { if (this.opts.ssl) this.opts.ssl = await (0, get_options_1.getSSLOptions)(this.opts.ssl); } async _parseReporters() { const reporters = this.opts.reporter ? this.opts.reporter.split(',') : []; /* eslint-disable-line no-extra-parens*/ this.opts.reporter = reporters.map((reporter) => { const separatorIndex = reporter.indexOf(':'); if (separatorIndex < 0) return { name: reporter }; const name = reporter.substring(0, separatorIndex); const output = reporter.substring(separatorIndex + 1); return { name, output }; }); } _parseFileList() { this.opts.src = this.testCafeCommand.args.slice(1); } async _parseScreenshotOptions() { if (this.opts.screenshots) this.opts.screenshots = await (0, get_options_1.getScreenshotOptions)(this.opts.screenshots); else this.opts.screenshots = {}; if (!(0, lodash_1.has)(this.opts.screenshots, screenshot_option_names_1.default.pathPattern) && this.opts.screenshotPathPattern) this.opts.screenshots[screenshot_option_names_1.default.pathPattern] = this.opts.screenshotPathPattern; if (!(0, lodash_1.has)(this.opts.screenshots, screenshot_option_names_1.default.takeOnFails) && this.opts.screenshotsOnFails) this.opts.screenshots[screenshot_option_names_1.default.takeOnFails] = this.opts.screenshotsOnFails; } async _parseVideoOptions() { if (this.opts.videoOptions) this.opts.videoOptions = await (0, get_options_1.getVideoOptions)(this.opts.videoOptions); if (this.opts.videoEncodingOptions) this.opts.videoEncodingOptions = await (0, get_options_1.getVideoOptions)(this.opts.videoEncodingOptions); } async _parseCompilerOptions() { if (!this.opts.compilerOptions) return; const parsedCompilerOptions = await (0, get_options_1.getCompilerOptions)(this.opts.compilerOptions); const resultCompilerOptions = Object.create(null); for (const [key, value] of Object.entries(parsedCompilerOptions)) (0, lodash_1.set)(resultCompilerOptions, key, value); this.opts.compilerOptions = resultCompilerOptions; } async _parseDashboardOptions() { if (this.opts.dashboardOptions) this.opts.dashboardOptions = await (0, get_options_1.getDashboardOptions)(this.opts.dashboardOptions); } _parseListBrowsers() { const listBrowserOption = this.opts.listBrowsers; this.opts.listBrowsers = !!this.opts.listBrowsers; if (!this.opts.listBrowsers) return; this.opts.providerName = typeof listBrowserOption === 'string' ? listBrowserOption : 'locally-installed'; } static _prepareBooleanOrObjectOption(argv, optionNames, subOptionsNames) { // NOTE: move options to the end of the array to correctly parse both Boolean and Object type arguments (GH-6231) const optionIndex = argv.findIndex(el => optionNames.some(opt => el.startsWith(opt))); if (optionIndex > -1) { const isNotLastOption = optionIndex < argv.length - 1; const shouldMoveOptionToEnd = isNotLastOption && !subOptionsNames.some(opt => argv[optionIndex + 1].startsWith(opt)); if (shouldMoveOptionToEnd) argv.push(argv.splice(optionIndex, 1)[0]); } } async parse(argv) { CLIArgumentParser._prepareBooleanOrObjectOption(argv, ['-q', '--quarantine-mode'], Object.values(quarantine_option_names_1.default)); CLIArgumentParser._prepareBooleanOrObjectOption(argv, ['-e', '--skip-js-errors'], Object.values(skip_js_errors_option_names_1.SKIP_JS_ERRORS_OPTIONS_OBJECT_OPTION_NAMES)); const { args, v8Flags } = (0, node_arguments_filter_1.extractNodeProcessArguments)(argv); commander_1.default.parse(args); this.args = commander_1.default.args; this.opts = Object.assign(this.opts, { v8Flags }); this._parseListBrowsers(); // NOTE: the '--list-browsers' option only lists browsers and immediately exits the app. // Therefore, we don't need to process other arguments. if (this.opts.listBrowsers) return; this._parseSelectorTimeout(); this._parseAssertionTimeout(); this._parsePageLoadTimeout(); this._parsePageRequestTimeout(); this._parseAjaxRequestTimeout(); this._parseBrowserInitTimeout(); this._parseTestExecutionTimeout(); this._parseRunExecutionTimeout(); this._parseAppInitDelay(); this._parseSpeed(); this._parsePorts(); this._parseBrowsersFromArgs(); this._parseConcurrency(); this._parseFileList(); await this._parseFilteringOptions(); await this._parseQuarantineOptions(); await this._parseSkipJsErrorsOptions(); await this._parseScreenshotOptions(); await this._parseVideoOptions(); await this._parseCompilerOptions(); await this._parseSslOptions(); await this._parseReporters(); await this._parseDashboardOptions(); } getRunOptions() { const result = Object.create(null); run_option_names_1.default.forEach(optionName => { if (optionName in this.opts) // @ts-ignore a hack to add an index signature to interface result[optionName] = this.opts[optionName]; }); return result; } } exports.default = CLIArgumentParser; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2FyZ3VtZW50LXBhcnNlci9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsbUNBQWtDO0FBRWxDLHVEQUdtQjtBQUVuQixvREFBNEI7QUFDNUIsa0RBQW9EO0FBQ3BELDhDQUFvRDtBQUNwRCwwRUFBc0U7QUFDdEUsd0ZBQThEO0FBQzlELCtDQUErRDtBQUMvRCx5REFVaUM7QUFFakMsOEVBQW9EO0FBQ3BELDBHQUFrRjtBQUNsRiw0RkFBb0U7QUFNcEUsMEdBQWtGO0FBQ2xGLG9FQUF1RTtBQUN2RSw0RkFBa0U7QUFDbEUsK0NBQTJEO0FBQzNELG9FQUE0QztBQUU1QyxpR0FBNkc7QUFFN0csTUFBTSxlQUFlLEdBQUcscUJBQXFCLENBQUM7QUFFOUMsTUFBTSxXQUFXLEdBQUcsSUFBQSxnQkFBTSxFQUFDOzs7Ozs7Ozs7OztDQVcxQixDQUFDLENBQUM7QUF5Q0gsTUFBcUIsaUJBQWlCO0lBU2xDLFlBQW9CLEdBQVk7UUFDNUIsSUFBSSxDQUFDLEdBQUcsR0FBVyxHQUFHLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxJQUFJLEdBQVUsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxJQUFJLEdBQVUsRUFBRSxDQUFDO1FBRXRCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7UUFDaEMsSUFBSSxDQUFDLGVBQWUsR0FBTSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUVyRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzVDLGlCQUFpQixDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVPLE1BQU0sQ0FBQyxpQkFBaUI7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cEMsTUFBTSxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUNyQyxNQUFNLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDckMsTUFBTSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUNoQyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQ25DLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDOUIsTUFBTSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDN0IsTUFBTSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztJQUN4QyxDQUFDO0lBRU0sYUFBYTtRQUNoQixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRW5DLDBCQUFnQixDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUNsQyxJQUFJLFVBQVUsSUFBSSxJQUFJLENBQUMsSUFBSTtnQkFDdkIsMkRBQTJEO2dCQUMzRCxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sTUFBMEIsQ0FBQztJQUN0QyxDQUFDO0NBQ0o7QUF6YUQsb0NBeWFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaGFzLCBzZXQgfSBmcm9tICdsb2Rhc2gnO1xuXG5pbXBvcnQgcHJvZ3JhbSwge1xuICAgIENvbW1hbmQsXG4gICAgT3B0aW9uLFxufSBmcm9tICdjb21tYW5kZXInO1xuXG5pbXBvcnQgZGVkZW50IGZyb20gJ2RlZGVudCc7XG5pbXBvcnQgeyBHZW5lcmFsRXJyb3IgfSBmcm9tICcuLi8uLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgeyBSVU5USU1FX0VSUk9SUyB9IGZyb20gJy4uLy4uL2Vycm9ycy90eXBlcyc7XG5pbXBvcnQgeyBhc3NlcnRUeXBlLCBpcyB9IGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lL3R5cGUtYXNzZXJ0aW9ucyc7XG5pbXBvcnQgZ2V0Vmlld1BvcnRXaWR0aCBmcm9tICcuLi8uLi91dGlscy9nZXQtdmlld3BvcnQtd2lkdGgnO1xuaW1wb3J0IHsgd29yZFdyYXAsIHNwbGl0UXVvdGVkVGV4dCB9IGZyb20gJy4uLy4uL3V0aWxzL3N0cmluZyc7XG5pbXBvcnQge1xuICAgIGdldFNTTE9wdGlvbnMsXG4gICAgZ2V0UXVhcmFudGluZU9wdGlvbnMsXG4gICAgZ2V0U2NyZWVuc2hvdE9wdGlvbnMsXG4gICAgZ2V0U2tpcEpzRXJyb3JzT3B0aW9ucyxcbiAgICBnZXRWaWRlb09wdGlvbnMsXG4gICAgZ2V0TWV0YU9wdGlvbnMsXG4gICAgZ2V0R3JlcE9wdGlvbnMsXG4gICAgZ2V0Q29tcGlsZXJPcHRpb25zLFxuICAgIGdldERhc2hib2FyZE9wdGlvbnMsXG59IGZyb20gJy4uLy4uL3V0aWxzL2dldC1vcHRpb25zJztcblxuaW1wb3J0IGdldEZpbHRlckZuIGZyb20gJy4uLy4uL3V0aWxzL2dldC1maWx0ZXItZm4nO1xuaW1wb3J0IFNDUkVFTlNIT1RfT1BUSU9OX05BTUVTIGZyb20gJy4uLy4uL2NvbmZpZ3VyYXRpb24vc2NyZWVuc2hvdC1vcHRpb24tbmFtZXMnO1xuaW1wb3J0IFJVTl9PUFRJT05fTkFNRVMgZnJvbSAnLi4vLi4vY29uZmlndXJhdGlvbi9ydW4tb3B0aW9uLW5hbWVzJztcbmltcG9ydCB7XG4gICAgRGljdGlvbmFyeSxcbiAgICBSZXBvcnRlck9wdGlvbixcbiAgICBSdW5uZXJSdW5PcHRpb25zLFxufSBmcm9tICcuLi8uLi9jb25maWd1cmF0aW9uL2ludGVyZmFjZXMnO1xuaW1wb3J0IFFVQVJBTlRJTkVfT1BUSU9OX05BTUVTIGZyb20gJy4uLy4uL2NvbmZpZ3VyYXRpb24vcXVhcmFudGluZS1vcHRpb24tbmFtZXMnO1xuaW1wb3J0IHsgZXh0cmFjdE5vZGVQcm9jZXNzQXJndW1lbnRzIH0gZnJvbSAnLi4vbm9kZS1hcmd1bWVudHMtZmlsdGVyJztcbmltcG9ydCBnZXRUZXN0Y2FmZVZlcnNpb24gZnJvbSAnLi4vLi4vdXRpbHMvZ2V0LXRlc3RjYWZlLXZlcnNpb24nO1xuaW1wb3J0IHsgcGFyc2VQb3J0TnVtYmVyLCBwYXJzZUxpc3QgfSBmcm9tICcuL3BhcnNlLXV0aWxzJztcbmltcG9ydCBDT01NQU5EX05BTUVTIGZyb20gJy4vY29tbWFuZC1uYW1lcyc7XG5pbXBvcnQgeyBTZW5kUmVwb3J0U3RhdGUgfSBmcm9tICcuLi8uLi9kYXNoYm9hcmQvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBTS0lQX0pTX0VSUk9SU19PUFRJT05TX09CSkVDVF9PUFRJT05fTkFNRVMgfSBmcm9tICcuLi8uLi9jb25maWd1cmF0aW9uL3NraXAtanMtZXJyb3JzLW9wdGlvbi1uYW1lcyc7XG5cbmNvbnN0IFJFTU9URV9BTElBU19SRSA9IC9ecmVtb3RlKD86OihcXGQqKSk/JC87XG5cbmNvbnN0IERFU0NSSVBUSU9OID0gZGVkZW50KGBcblxuICAgIFRvIHNlbGVjdCBhIGJyb3dzZXIsIHNwZWNpZnkgYW4gYWxpYXMgKFwiaWVcIiwgXCJjaHJvbWVcIiwgZXRjLikgb3IgdGhlIHBhdGggdG8gdGhlIGJyb3dzZXIgZXhlY3V0YWJsZS4gWW91IGNhbiBzZWxlY3QgbW9yZSB0aGFuIG9uZSBicm93c2VyLlxuICAgIFxuICAgIFVzZSB0aGUgXCJhbGxcIiBhbGlhcyB0byBydW4gdGVzdHMgYWdhaW5zdCBhbGwgYXZhaWxhYmxlIGJyb3dzZXJzLiAgIFxuICAgIFVzZSB0aGUgXCJyZW1vdGVcIiBhbGlhcyB0byBydW4gdGVzdHMgb24gcmVtb3RlIGRldmljZXMsIGxpa2Ugc21hcnRwaG9uZXMgb3IgdGFibGV0cy4gU3BlY2lmeSB0aGUgbnVtYmVyIG9mIHJlbW90ZSBicm93c2VycyBhZnRlciB0aGUgc2VtaWNvbG9uIChcInJlbW90ZTozXCIpLlxuICAgIElmIHlvdSB1c2UgYSBicm93c2VyIHByb3ZpZGVyIHBsdWdpbiwgc3BlY2lmeSBib3RoIHRoZSBuYW1lIG9mIHRoZSBwbHVnaW4gYW5kIHRoZSBuYW1lIG9mIHRoZSBicm93c2VyLiBTZXBhcmF0ZSB0aGUgdHdvIHdpdGggYSBzZW1pY29sb24gKFwic2F1Y2VsYWJzOmNocm9tZUA1MVwiKS5cblxuICAgIFRvIGV4ZWN1dGUgbXVsdGlwbGUgdGVzdCBmaWxlcywgc3BlY2lmeSBtdWx0aXBsZSBmaWxlIHBhdGhzIG9yIGdsb2IgcGF0dGVybnMuXG5cbiAgICBGdWxsIGRvY3VtZW50YXRpb246IGh0dHBzOi8vdGVzdGNhZmUuaW8vZG9jdW1lbnRhdGlvbi80MDI2MzkvcmVmZXJlbmNlL2NvbW1hbmQtbGluZS1pbnRlcmZhY2VcbmApO1xuXG5pbnRlcmZhY2UgQ29tbWFuZExpbmVPcHRpb25zIHtcbiAgICB0ZXN0R3JlcD86IHN0cmluZyB8IFJlZ0V4cDtcbiAgICBmaXh0dXJlR3JlcD86IHN0cmluZyB8IFJlZ0V4cDtcbiAgICBzcmM/OiBzdHJpbmdbXTtcbiAgICBicm93c2Vycz86IHN0cmluZ1tdO1xuICAgIGxpc3RCcm93c2Vycz86IGJvb2xlYW4gfCBzdHJpbmc7XG4gICAgdGVzdE1ldGE/OiBzdHJpbmcgfCBEaWN0aW9uYXJ5PHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4+O1xuICAgIGZpeHR1cmVNZXRhPzogc3RyaW5nIHwgRGljdGlvbmFyeTxzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPjtcbiAgICBmaWx0ZXI/OiBGdW5jdGlvbjtcbiAgICBhcHBJbml0RGVsYXk/OiBzdHJpbmcgfCBudW1iZXI7XG4gICAgYXNzZXJ0aW9uVGltZW91dD86IHN0cmluZyB8IG51bWJlcjtcbiAgICBzZWxlY3RvclRpbWVvdXQ/OiBzdHJpbmcgfCBudW1iZXI7XG4gICAgc3BlZWQ/OiBzdHJpbmcgfCBudW1iZXI7XG4gICAgcGFnZUxvYWRUaW1lb3V0Pzogc3RyaW5nIHwgbnVtYmVyO1xuICAgIHBhZ2VSZXF1ZXN0VGltZW91dD86IHN0cmluZyB8IG51bWJlcjtcbiAgICBhamF4UmVxdWVzdFRpbWVvdXQ/OiBzdHJpbmcgfCBudW1iZXI7XG4gICAgYnJvd3NlckluaXRUaW1lb3V0Pzogc3RyaW5nIHwgbnVtYmVyO1xuICAgIHRlc3RFeGVjdXRpb25UaW1lb3V0Pzogc3RyaW5nIHwgbnVtYmVyO1xuICAgIHJ1bkV4ZWN1dGlvblRpbWVvdXQ/OiBzdHJpbmcgfCBudW1iZXI7XG4gICAgY29uY3VycmVuY3k/OiBzdHJpbmcgfCBudW1iZXI7XG4gICAgcXVhcmFudGluZU1vZGU/OiBib29sZWFuIHwgRGljdGlvbmFyeTxzdHJpbmcgfCBudW1iZXI+O1xuICAgIHBvcnRzPzogc3RyaW5nIHwgbnVtYmVyW107XG4gICAgcHJvdmlkZXJOYW1lPzogc3RyaW5nO1xuICAgIHNzbD86IHN0cmluZyB8IERpY3Rpb25hcnk8c3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbj47XG4gICAgcmVwb3J0ZXI/OiBzdHJpbmcgfCBSZXBvcnRlck9wdGlvbltdO1xuICAgIHNjcmVlbnNob3RzPzogRGljdGlvbmFyeTxzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPiB8IHN0cmluZztcbiAgICBzY3JlZW5zaG90UGF0aFBhdHRlcm4/OiBzdHJpbmc7XG4gICAgc2NyZWVuc2hvdHNPbkZhaWxzPzogYm9vbGVhbjtcbiAgICB2aWRlb09wdGlvbnM/OiBzdHJpbmcgfCBEaWN0aW9uYXJ5PG51bWJlciB8IHN0cmluZyB8IGJvb2xlYW4+O1xuICAgIHZpZGVvRW5jb2RpbmdPcHRpb25zPzogc3RyaW5nIHwgRGljdGlvbmFyeTxudW1iZXIgfCBzdHJpbmcgfCBib29sZWFuPjtcbiAgICBjb21waWxlck9wdGlvbnM/OiBzdHJpbmcgfCBEaWN0aW9uYXJ5PG51bWJlciB8IHN0cmluZyB8IGJvb2xlYW4+O1xuICAgIGNvbmZpZ0ZpbGU/OiBzdHJpbmc7XG4gICAgcHJveHlsZXNzPzogYm9vbGVhbjtcbiAgICB2OEZsYWdzPzogc3RyaW5nW107XG4gICAgZGFzaGJvYXJkT3B0aW9ucz86IHN0cmluZyB8IERpY3Rpb25hcnk8c3RyaW5nIHwgYm9vbGVhbiB8IG51bWJlcj47XG4gICAgYmFzZVVybD86IHN0cmluZztcbiAgICBza2lwSnNFcnJvcnM/OiBib29sZWFuIHwgRGljdGlvbmFyeTxSZWdFeHAgfCBzdHJpbmc+O1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDTElBcmd1bWVudFBhcnNlciB7XG4gICAgcHJpdmF0ZSBjd2Q6IHN0cmluZztcbiAgICBwcml2YXRlIHJlbW90ZUNvdW50OiBudW1iZXI7XG4gICAgcHVibGljIGlzRGFzaGJvYXJkQ29tbWFuZDogYm9vbGVhbjtcbiAgICBwdWJsaWMgc2VuZFJlcG9ydFN0YXRlOiBTZW5kUmVwb3J0U3RhdGU7XG4gICAgcHVibGljIG9wdHM6IENvbW1hbmRMaW5lT3B0aW9ucztcbiAgICBwdWJsaWMgYXJnczogc3RyaW5nW107XG4gICAgcHJpdmF0ZSByZWFkb25seSB0ZXN0Q2FmZUNvbW1hbmQ6IENvbW1hbmQ7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IgKGN3ZD86IHN0cmluZykge1xuICAgICAgICB0aGlzLmN3ZCAgICAgICAgID0gY3dkIHx8IHByb2Nlc3MuY3dkKCk7XG4gICAgICAgIHRoaXMucmVtb3RlQ291bnQgPSAwO1xuICAgICAgICB0aGlzLm9wdHMgICAgICAgID0ge307XG4gICAgICAgIHRoaXMuYXJncyAgICAgICAgPSBbXTtcblxuICAgICAgICB0aGlzLmlzRGFzaGJvYXJkQ29tbWFuZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRlc3RDYWZlQ29tbWFuZCAgICA9IHRoaXMuX2FkZFRlc3RDYWZlQ29tbWFuZCgpO1xuXG4gICAgICAgIHRoaXMuX3BhdGNoSGVscE91dHB1dCh0aGlzLnRlc3RDYWZlQ29tbWFuZCk7XG4gICAgICAgIENMSUFyZ3VtZW50UGFyc2VyLl9zZXR1cFJvb3RDb21tYW5kKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgX3NldHVwUm9vdENvbW1hbmQgKCk6IHZvaWQge1xuICAgICAgICAvLyBOT1RFOiBXZSBhcmUgZm9yY2VkIHRvIHNldCB0aGUgbmFtZSBvZiB0aGUgcm9vdCBjb21tYW5kIHRvICd0ZXN0Y2FmZSdcbiAgICAgICAgLy8gdG8gYXZvaWQgdGhlIGF1dG9tYXRpYyBjb21tYW5kIG5hbWUgY2FsY3VsYXRpb24gdXNpbmcgdGhlIGV4ZWN1dGVkIGZpbGUgcGF0aC5cbiAgICAgICAgLy8gSXQncyBuZWNlc3NhcnkgdG8gY29ycmVjdCBjb21tYW5kIGRlc2NyaXB0aW9uIGZvciBuZXN0ZWQgY29tbWFuZHMuXG4gICAgICAgIChwcm9ncmFtIGFzIHVua25vd24gYXMgQ29tbWFuZCkubmFtZShDT01NQU5EX05BTUVTLlRlc3RDYWZlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBfcmVtb3ZlQ29tbWFuZElmRXhpc3RzIChuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgLy8gTk9URTogQnVnIGluIHRoZSAnY29tbWFuZGVyJyBtb2R1bGUuXG4gICAgICAgIC8vIEl0J3MgcG9zc2libGUgdG8gYWRkIGEgZmV3IGNvbW1hbmRzIHdpdGggdGhlIHNhbWUgbmFtZS5cbiAgICAgICAgLy8gQWxzbywgcmVtb3ZpbmcgaXMgYSBiZXR0ZXIgdGhhbiBjb25kaXRpb25hbGx5IGFkZGluZ1xuICAgICAgICAvLyBiZWNhdXNlIGl0IGFsbG93cyBhdm9pZGluZyB0aGUgcGFyc2VkIG9wdGlvbiBkdXBsaWNhdGVzLlxuICAgICAgICBjb25zdCBpbmRleCA9IChwcm9ncmFtIGFzIHVua25vd24gYXMgQ29tbWFuZCkuY29tbWFuZHMuZmluZEluZGV4KGNtZCA9PiBjbWQubmFtZSgpID09PSBuYW1lKTtcblxuICAgICAgICBpZiAoaW5kZXggPiAtMSlcbiAgICAgICAgICAgIChwcm9ncmFtIGFzIHVua25vd24gYXMgQ29tbWFuZCkuY29tbWFuZHMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBfZ2V0RGVzY3JpcHRpb24gKCk6IHN0cmluZyB7XG4gICAgICAgIC8vIE5PVEU6IGFkZCBlbXB0eSBsaW5lIHRvIHdvcmthcm91bmQgY29tbWFuZGVyLWZvcmNlZCBpbmRlbnRhdGlvbiBvbiB0aGUgZmlyc3QgbGluZS5cbiAgICAgICAgcmV0dXJuICdcXG4nICsgd29yZFdyYXAoREVTQ1JJUFRJT04sIDIsIGdldFZpZXdQb3J0V2lkdGgocHJvY2Vzcy5zdGRvdXQpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9hZGRUZXN0Q2FmZUNvbW1hbmQgKCk6IENvbW1hbmQge1xuICAgICAgICBDTElBcmd1bWVudFBhcnNlci5fcmVtb3ZlQ29tbWFuZElmRXhpc3RzKENPTU1BTkRfTkFNRVMuVGVzdENhZmUpO1xuXG4gICAgICAgIHJldHVybiAocHJvZ3JhbSBhcyB1bmtub3duIGFzIENvbW1hbmQpXG4gICAgICAgICAgICAuY29tbWFuZChDT01NQU5EX05BTUVTLlRlc3RDYWZlLCB7IGlzRGVmYXVsdDogdHJ1ZSB9KVxuICAgICAgICAgICAgLnZlcnNpb24oZ2V0VGVzdGNhZmVWZXJzaW9uKCksICctdiwgLS12ZXJzaW9uJylcbiAgICAgICAgICAgIC51c2FnZSgnW29wdGlvbnNdIDxjb21tYS1zZXBhcmF0ZWQtYnJvd3Nlci1saXN0PiA8ZmlsZS1vci1nbG9iIC4uLj4nKVxuICAgICAgICAgICAgLmRlc2NyaXB0aW9uKENMSUFyZ3VtZW50UGFyc2VyLl9nZXREZXNjcmlwdGlvbigpKVxuXG4gICAgICAgICAgICAuYWxsb3dVbmtub3duT3B0aW9uKClcbiAgICAgICAgICAgIC5vcHRpb24oJy1iLCAtLWxpc3QtYnJvd3NlcnMgW3Byb3ZpZGVyXScsICdkaXNwbGF5IHRoZSBsaXN0IG9mIGFsaWFzZXMgZm9yIGF2YWlsYWJsZSBicm93c2VycyBhbmQgYnJvd3NlciBwcm92aWRlcnMnKVxuICAgICAgICAgICAgLm9wdGlvbignLXIsIC0tcmVwb3J0ZXIgPG5hbWVbOm91dHB1dEZpbGVdWywuLi5dPicsICdzcGVjaWZ5IHJlcG9ydGVycyBhbmQgcmVwb3J0IGZpbGVuYW1lcycpXG4gICAgICAgICAgICAub3B0aW9uKCctcywgLS1zY3JlZW5zaG90cyA8b3B0aW9uPXZhbHVlWywuLi5dPicsICdzcGVjaWZ5IHNjcmVlbnNob3Qgb3B0aW9ucycpXG4gICAgICAgICAgICAub3B0aW9uKCctUywgLS1zY3JlZW5zaG90cy1vbi1mYWlscycsICd0YWtlIGEgc2NyZWVuc2hvdCBvbiB0ZXN0IGZhaWx1cmUnKVxuICAgICAgICAgICAgLm9wdGlvbignLXAsIC0tc2NyZWVuc2hvdC1wYXRoLXBhdHRlcm4gPHBhdHRlcm4+JywgJ3NwZWNpZnkgdGhlIG5hbWluZyBzY2hlbWEgZm9yIHNjcmVlbnNob3QgZmlsZW5hbWVzIGFuZCBwYXRoczogJHtCUk9XU0VSfSwgJHtCUk9XU0VSX1ZFUlNJT059LCAke09TfSwgZXRjLicpXG4gICAgICAgICAgICAub3B0aW9uKCctcSwgLS1xdWFyYW50aW5lLW1vZGUgW29wdGlvbj12YWx1ZSwuLi5dJywgJ2VuYWJsZSBhbmQgY29uZmlndXJlIHF1YXJhbnRpbmUgbW9kZScpXG4gICAgICAgICAgICAub3B0aW9uKCctZCwgLS1kZWJ1Zy1tb2RlJywgJ2VuYWJsZSBkZWJ1ZyBtb2RlLiBXaGVuIHlvdSBydW4gVGVzdENhZmUgaW4gZGVidWcgbW9kZSwgaXQgZXhlY3V0ZXMgdGVzdCBzdGVwcyBvbmUgYnkgb25lLCBhbmQgcGF1c2VzIHRoZSB0ZXN0IGFmdGVyIGVhY2ggc3RlcC4nKVxuICAgICAgICAgICAgLm9wdGlvbignLWUsIC0tc2tpcC1qcy1lcnJvcnMgW29wdGlvbj12YWx1ZSwuLi5dJywgJ2lnbm9yZSBKYXZhU2NyaXB0IGVycm9ycyB0aGF0IG1hdGNoIHRoZSBzcGVjaWZpZWQgY3JpdGVyaWEnKVxuICAgICAgICAgICAgLm9wdGlvbignLXUsIC0tc2tpcC11bmNhdWdodC1lcnJvcnMnLCAnaWdub3JlIHVuY2F1Z2h0IGVycm9ycyBhbmQgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9ucycpXG4gICAgICAgICAgICAub3B0aW9uKCctdCwgLS10ZXN0IDxuYW1lPicsICdmaWx0ZXIgdGVzdHMgYnkgbmFtZScpXG4gICAgICAgICAgICAub3B0aW9uKCctVCwgLS10ZXN0LWdyZXAgPHBhdHRlcm4+JywgJ2ZpbHRlciB0ZXN0cyBieSByZWd1bGFyIGV4cHJlc3Npb24nKVxuICAgICAgICAgICAgLm9wdGlvbignLWYsIC0tZml4dHVyZSA8bmFtZT4nLCAnZmlsdGVyIGZpeHR1cmVzIGJ5IG5hbWUnKVxuICAgICAgICAgICAgLm9wdGlvbignLUYsIC0tZml4dHVyZS1ncmVwIDxwYXR0ZXJuPicsICdmaWx0ZXIgZml4dHVyZXMgYnkgcmVndWxhciBleHByZXNzaW9uJylcbiAgICAgICAgICAgIC5vcHRpb24oJy1hLCAtLWFwcCA8Y29tbWFuZD4nLCAnZXhlY3V0ZSBhIHNoZWxsIGNvbW1hbmQgb24gc3RhcnR1cCB0byBsYXVuY2ggYSB3ZWIgYXBwbGljYXRpb24gb3IgcGVyZm9ybSBvdGhlciBwcmVwYXJhdG9yeSB0YXNrcycpXG4gICAgICAgICAgICAub3B0aW9uKCctYywgLS1jb25jdXJyZW5jeSA8bnVtYmVyPicsICdydW4gdGVzdHMgY29uY3VycmVudGx5JylcbiAgICAgICAgICAgIC5vcHRpb24oJy1MLCAtLWxpdmUnLCAnZW5hYmxlIGxpdmUgbW9kZS4gTGl2ZSBtb2RlIHJlc3RhcnRzIHRlc3RzIHdoZW4geW91IG1ha2UgY2hhbmdlcyB0byB0ZXN0IGZpbGVzLicpXG4gICAgICAgICAgICAub3B0aW9uKCctLXRlc3QtbWV0YSA8a2V5PXZhbHVlWyxrZXkyPXZhbHVlMiwuLi5dPicsICdmaWx0ZXIgdGVzdHMgYnkgbWV0YWRhdGEnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1maXh0dXJlLW1ldGEgPGtleT12YWx1ZVssa2V5Mj12YWx1ZTIsLi4uXT4nLCAnZmlsdGVyIGZpeHR1cmVzIGJ5IG1ldGFkYXRhJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tZGVidWctb24tZmFpbCcsICdwYXVzZSB0ZXN0cyBvbiBmYWlsdXJlJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tZXhwZXJpbWVudGFsLXByb3h5bGVzcycsICdlbmFibGUgcHJveHlsZXNzIG1vZGU6IGh0dHBzOi8vdGVzdGNhZmUuaW8vZG9jdW1lbnRhdGlvbi80MDQyMzcvZ3VpZGVzL2V4cGVyaW1lbnRhbC1jYXBhYmlsaXRpZXMvcHJveHlsZXNzLW1vZGUnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1hcHAtaW5pdC1kZWxheSA8bXM+JywgJ3NwZWNpZnkgeW91ciBhcHBsaWNhdGlvbmBzIGluaXRpYWxpemF0aW9uIHRpbWUnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1zZWxlY3Rvci10aW1lb3V0IDxtcz4nLCAnc3BlY2lmeSB0aGUgbWF4aW11bSBTZWxlY3RvciByZXNvbHV0aW9uIHRpbWUnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1hc3NlcnRpb24tdGltZW91dCA8bXM+JywgJ3NwZWNpZnkgdGhlIG1heGltdW0gQXNzZXJ0aW9uIHJlc29sdXRpb24gdGltZScpXG4gICAgICAgICAgICAub3B0aW9uKCctLXBhZ2UtbG9hZC10aW1lb3V0IDxtcz4nLCAnc3BlY2lmeSB0aGUgbWF4aW11bSB0aW1lIGJldHdlZW4gdGhlIHdpbmRvdy5sb2FkIGV2ZW50IGFuZCB0aGUgRE9NQ29udGVudExvYWRlZCBldmVudCAobXMpJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tcGFnZS1yZXF1ZXN0LXRpbWVvdXQgPG1zPicsICdzcGVjaWZ5IHRoZSBtYXhpbXVtIHBhZ2UgcmVxdWVzdCByZXNvbHV0aW9uIHRpbWUnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1hamF4LXJlcXVlc3QtdGltZW91dCA8bXM+JywgJ3NwZWNpZnkgdGhlIG1heGltdW0gQUpBWCByZXF1ZXN0IHJlc29sdXRpb24gdGltZScpXG4gICAgICAgICAgICAub3B0aW9uKCctLWJyb3dzZXItaW5pdC10aW1lb3V0IDxtcz4nLCAnc3BlY2lmeSB0aGUgbWF4aW11bSBicm93c2VyIHN0YXJ0dXAgdGltZScpXG4gICAgICAgICAgICAub3B0aW9uKCctLXRlc3QtZXhlY3V0aW9uLXRpbWVvdXQgPG1zPicsICdzcGVjaWZ5IHRoZSBtYXhpbXVtIHRlc3QgZXhlY3V0aW9uIHRpbWUnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1ydW4tZXhlY3V0aW9uLXRpbWVvdXQgPG1zPicsICdzcGVjaWZ5IHRoZSBtYXhpbXVtIHRlc3QgcnVuIHRpbWUnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1zcGVlZCA8ZmFjdG9yPicsICdzZXQgdGVzdCBleGVjdXRpb24gc3BlZWQgKDAuMDEgLi4uIDEpJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tcG9ydHMgPHBvcnQxLHBvcnQyPicsICdzcGVjaWZ5IG5ldHdvcmsgcG9ydHMgdG8gdXNlIGR1cmluZyB0aGUgdGVzdCBydW4uIFRoZSBzZWNvbmQgcG9ydCBpcyBuZWNlc3NhcnkgdG8gYWNjZXNzIGNyb3NzLWRvbWFpbiByZXNvdXJjZXMuJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0taG9zdG5hbWUgPG5hbWU+JywgYHNwZWNpZnkgeW91ciBob3N0bmFtZS4gTmVjZXNzYXJ5IHRvIHJ1biB0ZXN0cyBpbiByZW1vdGUgYnJvd3NlcnMuYClcbiAgICAgICAgICAgIC5vcHRpb24oJy0tcHJveHkgPGhvc3Q+JywgJ3NwZWNpZnkgdGhlIHByb3h5IHNlcnZlciBob3N0bmFtZSBvciBJUCBhZGRyZXNzJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tcHJveHktYnlwYXNzIDxydWxlcz4nLCAnc3BlY2lmeSBVUkxzIHRoYXQgYnlwYXNzIHRoZSBwcm94eSBzZXJ2ZXInKVxuICAgICAgICAgICAgLm9wdGlvbignLS1zc2wgPG9wdGlvbnM+JywgJ3NwZWNpZnkgU1NMIG9wdGlvbnMgdG8gcnVuIFRlc3RDYWZlIG92ZXIgSFRUUFMnKVxuICAgICAgICAgICAgLm9wdGlvbignLS12aWRlbyA8cGF0aD4nLCAncmVjb3JkIHZpZGVvcyBvZiB0ZXN0IHJ1bnMnKVxuICAgICAgICAgICAgLm9wdGlvbignLS12aWRlby1vcHRpb25zIDxvcHRpb249dmFsdWVbLC4uLl0+JywgJ3NwZWNpZnkgdmlkZW8gcmVjb3JkaW5nIG9wdGlvbnMnKVxuICAgICAgICAgICAgLm9wdGlvbignLS12aWRlby1lbmNvZGluZy1vcHRpb25zIDxvcHRpb249dmFsdWVbLC4uLl0+JywgJ3NwZWNpZnkgdmlkZW8gZW5jb2Rpbmcgb3B0aW9ucycpXG4gICAgICAgICAgICAub3B0aW9uKCctLWRldicsICdsb2cgYW5kIGRpYWdub3NlIFRlc3RDYWZlIGVycm9ycycpXG4gICAgICAgICAgICAub3B0aW9uKCctLXFyLWNvZGUnLCAnb3V0cHV0IFFSIGNvZGVzIHdpdGggVVJMcyBmb3IgcmVtb3RlIGJyb3dzZXIgY29ubmVjdGlvbnMnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1zZiwgLS1zdG9wLW9uLWZpcnN0LWZhaWwnLCAnc3RvcCB0aGUgdGVzdCBydW4gaWYgYW55IHRlc3QgZmFpbHMnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1jb25maWctZmlsZSA8cGF0aD4nLCAnc3BlY2lmeSBhIGN1c3RvbSBwYXRoIHRvIHRoZSB0ZXN0Y2FmZSBjb25maWd1cmF0aW9uIGZpbGUnKVxuICAgICAgICAgICAgLm9wdGlvbignLS10cy1jb25maWctcGF0aCA8cGF0aD4nLCAnc3BlY2lmeSB0aGUgcGF0aCB0byBhIGN1c3RvbSBUeXBlU2NyaXB0IGNvbmZpZ3VyYXRpb24gZmlsZScpXG4gICAgICAgICAgICAub3B0aW9uKCctLWNzLCAtLWNsaWVudC1zY3JpcHRzIDxwYXRocz4nLCAnaW5qZWN0IGNsaWVudC1zaWRlIHNjcmlwdHMgaW50byB0aGUgcGFnZScsIHBhcnNlTGlzdCwgW10pXG4gICAgICAgICAgICAub3B0aW9uKCctLWRpc2FibGUtcGFnZS1jYWNoaW5nJywgJ2RvIG5vdCBjYWNoZSBwYWdlcycpXG4gICAgICAgICAgICAub3B0aW9uKCctLWRpc2FibGUtcGFnZS1yZWxvYWRzJywgJ2RvIG5vdCByZWxvYWQgcGFnZXMgYmV0d2VlbiB0ZXN0cycpXG4gICAgICAgICAgICAub3B0aW9uKCctLXJldHJ5LXRlc3QtcGFnZXMnLCAncmV0cnkgcGFnZSByZXF1ZXN0cyBpbiBjYXNlIG9mIGZhaWx1cmUnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1kaXNhYmxlLXNjcmVlbnNob3RzJywgJ2Rpc2FibGUgc2NyZWVuc2hvdHMnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1zY3JlZW5zaG90cy1mdWxsLXBhZ2UnLCAnZW5hYmxlIGZ1bGwtcGFnZSBzY3JlZW5zaG90cycpXG4gICAgICAgICAgICAub3B0aW9uKCctLWNvbXBpbGVyLW9wdGlvbnMgPG9wdGlvbj12YWx1ZVssLi4uXT4nLCAnc3BlY2lmeSB0ZXN0IGNvbXBpbGF0aW9uIHNldHRpbmdzJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tZGlzYWJsZS1tdWx0aXBsZS13aW5kb3dzJywgJ2Rpc2FibGUgdGhlIG11bHRpLXdpbmRvdyBtb2RlJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tZGlzYWJsZS1odHRwMicsICdmb3JjZSB0aGUgcHJveHkgdG8gaXNzdWUgSFRUUC8xLjEgcmVxdWVzdHMnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1jYWNoZScsICdjYWNoZSB3ZWIgYXNzZXRzIGJldHdlZW4gdGVzdCBydW5zJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tYmFzZS11cmwgPHVybD4nLCAnc2V0IHRoZSBiYXNlIHVybCBmb3IgdGhlIHRlc3QgcnVuJylcblxuICAgICAgICAgICAgLy8gTk9URTogdGhlc2Ugb3B0aW9ucyB3aWxsIGJlIGhhbmRsZWQgYnkgY2hhbGsgaW50ZXJuYWxseVxuICAgICAgICAgICAgLm9wdGlvbignLS1jb2xvcicsICdmb3JjZSBUZXN0Q2FmZSB0byBmb3JtYXQgQ0xJIG91dHB1dCB3aXRoIGNvbG9yJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tbm8tY29sb3InLCAnZGlzYWJsZSB0ZXh0IGNvbG9yIGZvcm1hdHRpbmcgaW4gdGhlIENMSScpXG5cbiAgICAgICAgICAgIC8vIE5PVEU6IFRlbXBvcmFyaWx5IGV4Y2x1ZGUgZXhwZXJpbWVudGFsIG9wdGlvbnMgZnJvbSAtLWhlbHAgb3V0cHV0XG4gICAgICAgICAgICAuYWRkT3B0aW9uKG5ldyBPcHRpb24oJy0tZXhwZXJpbWVudGFsLWRlYnVnJywgJ2VuYWJsZSBleHBlcmltZW50YWwgdGhlIGRlYnVnIG1vZGUnKS5oaWRlSGVscCgpKVxuICAgICAgICAgICAgLmFkZE9wdGlvbihuZXcgT3B0aW9uKCctLWV4cGVyaW1lbnRhbC1lc20nLCAnZW5hYmxlIGV4cGVyaW1lbnRhbCB0aGUgZXNtIG1vZGUnKS5oaWRlSGVscCgpKVxuICAgICAgICAgICAgLmFkZE9wdGlvbihuZXcgT3B0aW9uKCctLWRpc2FibGUtY3Jvc3MtZG9tYWluJywgJ2V4cGVyaW1lbnRhbCcpLmhpZGVIZWxwKCkpXG4gICAgICAgICAgICAuYWN0aW9uKChvcHRzOiBDb21tYW5kTGluZU9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdHMgPSBvcHRzO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcGF0Y2hIZWxwT3V0cHV0IChkZWZhdWx0U3ViQ29tbWFuZDogQ29tbWFuZCk6IHZvaWQge1xuICAgICAgICAvLyBOT1RFOiBJbiB0aGUgZnV0dXJlIHZlcnNpb25zIG9mIHRoZSAnY29tbWFuZGVyJyBtb2R1bGVcbiAgICAgICAgLy8gbmVlZCB0byBpbnZlc3RpZ2F0ZSBob3cgdG8gcmVtb3ZlIHRoaXMgaGFjay5cbiAgICAgICAgKHByb2dyYW0gYXMgdW5rbm93biBhcyBDb21tYW5kKS5vdXRwdXRIZWxwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3Qgc3RvcmVkUGFyZW50ID0gZGVmYXVsdFN1YkNvbW1hbmQucGFyZW50O1xuXG4gICAgICAgICAgICBkZWZhdWx0U3ViQ29tbWFuZC5wYXJlbnQgPSBudWxsO1xuXG4gICAgICAgICAgICBkZWZhdWx0U3ViQ29tbWFuZC5vdXRwdXRIZWxwKCk7XG5cbiAgICAgICAgICAgIGRlZmF1bHRTdWJDb21tYW5kLnBhcmVudCA9IHN0b3JlZFBhcmVudDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9jaGVja0FuZENvdW50UmVtb3RlcyAoYnJvd3Nlcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHJlbW90ZU1hdGNoID0gYnJvd3Nlci5tYXRjaChSRU1PVEVfQUxJQVNfUkUpO1xuXG4gICAgICAgIGlmIChyZW1vdGVNYXRjaCkge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb3VudCArPSBwYXJzZUludChyZW1vdGVNYXRjaFsxXSwgMTApIHx8IDE7XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBfcGFyc2VGaWx0ZXJpbmdPcHRpb25zICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy50ZXN0R3JlcClcbiAgICAgICAgICAgIHRoaXMub3B0cy50ZXN0R3JlcCA9IGdldEdyZXBPcHRpb25zKCctLXRlc3QtZ3JlcCcsIHRoaXMub3B0cy50ZXN0R3JlcCBhcyBzdHJpbmcpO1xuXG4gICAgICAgIGlmICh0aGlzLm9wdHMuZml4dHVyZUdyZXApXG4gICAgICAgICAgICB0aGlzLm9wdHMuZml4dHVyZUdyZXAgPSBnZXRHcmVwT3B0aW9ucygnLS1maXh0dXJlLWdyZXAnLCB0aGlzLm9wdHMuZml4dHVyZUdyZXAgYXMgc3RyaW5nKTtcblxuICAgICAgICBpZiAodGhpcy5vcHRzLnRlc3RNZXRhKVxuICAgICAgICAgICAgdGhpcy5vcHRzLnRlc3RNZXRhID0gYXdhaXQgZ2V0TWV0YU9wdGlvbnMoJy0tdGVzdC1tZXRhJywgdGhpcy5vcHRzLnRlc3RNZXRhIGFzIHN0cmluZyk7XG5cbiAgICAgICAgaWYgKHRoaXMub3B0cy5maXh0dXJlTWV0YSlcbiAgICAgICAgICAgIHRoaXMub3B0cy5maXh0dXJlTWV0YSA9IGF3YWl0IGdldE1ldGFPcHRpb25zKCctLWZpeHR1cmUtbWV0YScsIHRoaXMub3B0cy5maXh0dXJlTWV0YSBhcyBzdHJpbmcpO1xuXG4gICAgICAgIHRoaXMub3B0cy5maWx0ZXIgPSBnZXRGaWx0ZXJGbih0aGlzLm9wdHMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3BhcnNlQXBwSW5pdERlbGF5ICgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy5hcHBJbml0RGVsYXkpIHtcbiAgICAgICAgICAgIGFzc2VydFR5cGUoaXMubm9uTmVnYXRpdmVOdW1iZXJTdHJpbmcsIG51bGwsICdUaGUgdGVzdGVkIGFwcCBpbml0aWFsaXphdGlvbiBkZWxheScsIHRoaXMub3B0cy5hcHBJbml0RGVsYXkpO1xuXG4gICAgICAgICAgICB0aGlzLm9wdHMuYXBwSW5pdERlbGF5ID0gcGFyc2VJbnQodGhpcy5vcHRzLmFwcEluaXREZWxheSBhcyBzdHJpbmcsIDEwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX3BhcnNlU2VsZWN0b3JUaW1lb3V0ICgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy5zZWxlY3RvclRpbWVvdXQpIHtcbiAgICAgICAgICAgIGFzc2VydFR5cGUoaXMubm9uTmVnYXRpdmVOdW1iZXJTdHJpbmcsIG51bGwsICdUaGUgU2VsZWN0b3IgdGltZW91dCcsIHRoaXMub3B0cy5zZWxlY3RvclRpbWVvdXQpO1xuXG4gICAgICAgICAgICB0aGlzLm9wdHMuc2VsZWN0b3JUaW1lb3V0ID0gcGFyc2VJbnQodGhpcy5vcHRzLnNlbGVjdG9yVGltZW91dCBhcyBzdHJpbmcsIDEwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX3BhcnNlQXNzZXJ0aW9uVGltZW91dCAoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMuYXNzZXJ0aW9uVGltZW91dCkge1xuICAgICAgICAgICAgYXNzZXJ0VHlwZShpcy5ub25OZWdhdGl2ZU51bWJlclN0cmluZywgbnVsbCwgJ1RoZSBhc3NlcnRpb24gdGltZW91dCcsIHRoaXMub3B0cy5hc3NlcnRpb25UaW1lb3V0KTtcblxuICAgICAgICAgICAgdGhpcy5vcHRzLmFzc2VydGlvblRpbWVvdXQgPSBwYXJzZUludCh0aGlzLm9wdHMuYXNzZXJ0aW9uVGltZW91dCBhcyBzdHJpbmcsIDEwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX3BhcnNlUGFnZUxvYWRUaW1lb3V0ICgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy5wYWdlTG9hZFRpbWVvdXQpIHtcbiAgICAgICAgICAgIGFzc2VydFR5cGUoaXMubm9uTmVnYXRpdmVOdW1iZXJTdHJpbmcsIG51bGwsICdUaGUgcGFnZSBsb2FkIHRpbWVvdXQnLCB0aGlzLm9wdHMucGFnZUxvYWRUaW1lb3V0KTtcblxuICAgICAgICAgICAgdGhpcy5vcHRzLnBhZ2VMb2FkVGltZW91dCA9IHBhcnNlSW50KHRoaXMub3B0cy5wYWdlTG9hZFRpbWVvdXQgYXMgc3RyaW5nLCAxMCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9wYXJzZVBhZ2VSZXF1ZXN0VGltZW91dCAoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5vcHRzLnBhZ2VSZXF1ZXN0VGltZW91dClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBhc3NlcnRUeXBlKGlzLm5vbk5lZ2F0aXZlTnVtYmVyU3RyaW5nLCBudWxsLCAnVGhlIHBhZ2UgcmVxdWVzdCB0aW1lb3V0JywgdGhpcy5vcHRzLnBhZ2VSZXF1ZXN0VGltZW91dCk7XG5cbiAgICAgICAgdGhpcy5vcHRzLnBhZ2VSZXF1ZXN0VGltZW91dCA9IHBhcnNlSW50KHRoaXMub3B0cy5wYWdlUmVxdWVzdFRpbWVvdXQgYXMgc3RyaW5nLCAxMCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcGFyc2VBamF4UmVxdWVzdFRpbWVvdXQgKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMub3B0cy5hamF4UmVxdWVzdFRpbWVvdXQpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgYXNzZXJ0VHlwZShpcy5ub25OZWdhdGl2ZU51bWJlclN0cmluZywgbnVsbCwgJ1RoZSBBSkFYIHJlcXVlc3QgdGltZW91dCcsIHRoaXMub3B0cy5hamF4UmVxdWVzdFRpbWVvdXQpO1xuXG4gICAgICAgIHRoaXMub3B0cy5hamF4UmVxdWVzdFRpbWVvdXQgPSBwYXJzZUludCh0aGlzLm9wdHMuYWpheFJlcXVlc3RUaW1lb3V0IGFzIHN0cmluZywgMTApO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3BhcnNlQnJvd3NlckluaXRUaW1lb3V0ICgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdHMuYnJvd3NlckluaXRUaW1lb3V0KVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGFzc2VydFR5cGUoaXMubm9uTmVnYXRpdmVOdW1iZXJTdHJpbmcsIG51bGwsICdUaGUgYnJvd3NlciBpbml0aWFsaXphdGlvbiB0aW1lb3V0JywgdGhpcy5vcHRzLmJyb3dzZXJJbml0VGltZW91dCk7XG5cbiAgICAgICAgdGhpcy5vcHRzLmJyb3dzZXJJbml0VGltZW91dCA9IHBhcnNlSW50KHRoaXMub3B0cy5icm93c2VySW5pdFRpbWVvdXQgYXMgc3RyaW5nLCAxMCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcGFyc2VUZXN0RXhlY3V0aW9uVGltZW91dCAoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMudGVzdEV4ZWN1dGlvblRpbWVvdXQpIHtcbiAgICAgICAgICAgIGFzc2VydFR5cGUoaXMubm9uTmVnYXRpdmVOdW1iZXJTdHJpbmcsIG51bGwsICdUaGUgdGVzdCBleGVjdXRpb24gdGltZW91dCcsIHRoaXMub3B0cy50ZXN0RXhlY3V0aW9uVGltZW91dCk7XG5cbiAgICAgICAgICAgIHRoaXMub3B0cy50ZXN0RXhlY3V0aW9uVGltZW91dCA9IHBhcnNlSW50KHRoaXMub3B0cy50ZXN0RXhlY3V0aW9uVGltZW91dCBhcyBzdHJpbmcsIDEwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX3BhcnNlUnVuRXhlY3V0aW9uVGltZW91dCAoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMucnVuRXhlY3V0aW9uVGltZW91dCkge1xuICAgICAgICAgICAgYXNzZXJ0VHlwZShpcy5ub25OZWdhdGl2ZU51bWJlclN0cmluZywgbnVsbCwgJ1RoZSBydW4gZXhlY3V0aW9uIHRpbWVvdXQnLCB0aGlzLm9wdHMucnVuRXhlY3V0aW9uVGltZW91dCk7XG5cbiAgICAgICAgICAgIHRoaXMub3B0cy5ydW5FeGVjdXRpb25UaW1lb3V0ID0gcGFyc2VJbnQodGhpcy5vcHRzLnJ1bkV4ZWN1dGlvblRpbWVvdXQgYXMgc3RyaW5nLCAxMCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9wYXJzZVNwZWVkICgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy5zcGVlZClcbiAgICAgICAgICAgIHRoaXMub3B0cy5zcGVlZCA9IHBhcnNlRmxvYXQodGhpcy5vcHRzLnNwZWVkIGFzIHN0cmluZyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcGFyc2VDb25jdXJyZW5jeSAoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMuY29uY3VycmVuY3kpXG4gICAgICAgICAgICB0aGlzLm9wdHMuY29uY3VycmVuY3kgPSBwYXJzZUludCh0aGlzLm9wdHMuY29uY3VycmVuY3kgYXMgc3RyaW5nLCAxMCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfcGFyc2VRdWFyYW50aW5lT3B0aW9ucyAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMucXVhcmFudGluZU1vZGUpXG4gICAgICAgICAgICB0aGlzLm9wdHMucXVhcmFudGluZU1vZGUgPSBhd2FpdCBnZXRRdWFyYW50aW5lT3B0aW9ucygnLS1xdWFyYW50aW5lLW1vZGUnLCB0aGlzLm9wdHMucXVhcmFudGluZU1vZGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX3BhcnNlU2tpcEpzRXJyb3JzT3B0aW9ucyAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMuc2tpcEpzRXJyb3JzKVxuICAgICAgICAgICAgdGhpcy5vcHRzLnNraXBKc0Vycm9ycyA9IGF3YWl0IGdldFNraXBKc0Vycm9yc09wdGlvbnMoJy0tc2tpcC1qcy1lcnJvcnMnLCB0aGlzLm9wdHMuc2tpcEpzRXJyb3JzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9wYXJzZVBvcnRzICgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy5wb3J0cykge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkUG9ydHMgPSAodGhpcy5vcHRzLnBvcnRzIGFzIHN0cmluZykgLyogZXNsaW50LWRpc2FibGUtbGluZSBuby1leHRyYS1wYXJlbnMgKi9cbiAgICAgICAgICAgICAgICAuc3BsaXQoJywnKVxuICAgICAgICAgICAgICAgIC5tYXAocGFyc2VQb3J0TnVtYmVyKTtcblxuICAgICAgICAgICAgaWYgKHBhcnNlZFBvcnRzLmxlbmd0aCA8IDIpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEdlbmVyYWxFcnJvcihSVU5USU1FX0VSUk9SUy5wb3J0c09wdGlvblJlcXVpcmVzVHdvTnVtYmVycyk7XG5cbiAgICAgICAgICAgIHRoaXMub3B0cy5wb3J0cyA9IHBhcnNlZFBvcnRzIGFzIG51bWJlcltdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcGFyc2VCcm93c2Vyc0Zyb21BcmdzICgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgYnJvd3NlcnNBcmcgPSB0aGlzLnRlc3RDYWZlQ29tbWFuZC5hcmdzWzBdIHx8ICcnO1xuXG4gICAgICAgIHRoaXMub3B0cy5icm93c2VycyA9IHNwbGl0UXVvdGVkVGV4dChicm93c2Vyc0FyZywgJywnKVxuICAgICAgICAgICAgLmZpbHRlcihicm93c2VyID0+IGJyb3dzZXIgJiYgdGhpcy5fY2hlY2tBbmRDb3VudFJlbW90ZXMoYnJvd3NlcikpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBfcGFyc2VTc2xPcHRpb25zICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy5zc2wpXG4gICAgICAgICAgICB0aGlzLm9wdHMuc3NsID0gYXdhaXQgZ2V0U1NMT3B0aW9ucyh0aGlzLm9wdHMuc3NsIGFzIHN0cmluZyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfcGFyc2VSZXBvcnRlcnMgKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCByZXBvcnRlcnMgPSB0aGlzLm9wdHMucmVwb3J0ZXIgPyAodGhpcy5vcHRzLnJlcG9ydGVyIGFzIHN0cmluZykuc3BsaXQoJywnKSA6IFtdOyAvKiBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWV4dHJhLXBhcmVucyovXG5cbiAgICAgICAgdGhpcy5vcHRzLnJlcG9ydGVyID0gcmVwb3J0ZXJzLm1hcCgocmVwb3J0ZXI6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc2VwYXJhdG9ySW5kZXggPSByZXBvcnRlci5pbmRleE9mKCc6Jyk7XG5cbiAgICAgICAgICAgIGlmIChzZXBhcmF0b3JJbmRleCA8IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgbmFtZTogcmVwb3J0ZXIgfTtcblxuICAgICAgICAgICAgY29uc3QgbmFtZSAgID0gcmVwb3J0ZXIuc3Vic3RyaW5nKDAsIHNlcGFyYXRvckluZGV4KTtcbiAgICAgICAgICAgIGNvbnN0IG91dHB1dCA9IHJlcG9ydGVyLnN1YnN0cmluZyhzZXBhcmF0b3JJbmRleCArIDEpO1xuXG4gICAgICAgICAgICByZXR1cm4geyBuYW1lLCBvdXRwdXQgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcGFyc2VGaWxlTGlzdCAoKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3B0cy5zcmMgPSB0aGlzLnRlc3RDYWZlQ29tbWFuZC5hcmdzLnNsaWNlKDEpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX3BhcnNlU2NyZWVuc2hvdE9wdGlvbnMgKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5vcHRzLnNjcmVlbnNob3RzKVxuICAgICAgICAgICAgdGhpcy5vcHRzLnNjcmVlbnNob3RzID0gYXdhaXQgZ2V0U2NyZWVuc2hvdE9wdGlvbnModGhpcy5vcHRzLnNjcmVlbnNob3RzKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5vcHRzLnNjcmVlbnNob3RzID0ge307XG5cbiAgICAgICAgaWYgKCFoYXModGhpcy5vcHRzLnNjcmVlbnNob3RzLCBTQ1JFRU5TSE9UX09QVElPTl9OQU1FUy5wYXRoUGF0dGVybikgJiYgdGhpcy5vcHRzLnNjcmVlbnNob3RQYXRoUGF0dGVybilcbiAgICAgICAgICAgIHRoaXMub3B0cy5zY3JlZW5zaG90c1tTQ1JFRU5TSE9UX09QVElPTl9OQU1FUy5wYXRoUGF0dGVybl0gPSB0aGlzLm9wdHMuc2NyZWVuc2hvdFBhdGhQYXR0ZXJuO1xuXG4gICAgICAgIGlmICghaGFzKHRoaXMub3B0cy5zY3JlZW5zaG90cywgU0NSRUVOU0hPVF9PUFRJT05fTkFNRVMudGFrZU9uRmFpbHMpICYmIHRoaXMub3B0cy5zY3JlZW5zaG90c09uRmFpbHMpXG4gICAgICAgICAgICB0aGlzLm9wdHMuc2NyZWVuc2hvdHNbU0NSRUVOU0hPVF9PUFRJT05fTkFNRVMudGFrZU9uRmFpbHNdID0gdGhpcy5vcHRzLnNjcmVlbnNob3RzT25GYWlscztcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9wYXJzZVZpZGVvT3B0aW9ucyAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMudmlkZW9PcHRpb25zKVxuICAgICAgICAgICAgdGhpcy5vcHRzLnZpZGVvT3B0aW9ucyA9IGF3YWl0IGdldFZpZGVvT3B0aW9ucyh0aGlzLm9wdHMudmlkZW9PcHRpb25zIGFzIHN0cmluZyk7XG5cbiAgICAgICAgaWYgKHRoaXMub3B0cy52aWRlb0VuY29kaW5nT3B0aW9ucylcbiAgICAgICAgICAgIHRoaXMub3B0cy52aWRlb0VuY29kaW5nT3B0aW9ucyA9IGF3YWl0IGdldFZpZGVvT3B0aW9ucyh0aGlzLm9wdHMudmlkZW9FbmNvZGluZ09wdGlvbnMgYXMgc3RyaW5nKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9wYXJzZUNvbXBpbGVyT3B0aW9ucyAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICghdGhpcy5vcHRzLmNvbXBpbGVyT3B0aW9ucylcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjb25zdCBwYXJzZWRDb21waWxlck9wdGlvbnMgPSBhd2FpdCBnZXRDb21waWxlck9wdGlvbnModGhpcy5vcHRzLmNvbXBpbGVyT3B0aW9ucyBhcyBzdHJpbmcpO1xuICAgICAgICBjb25zdCByZXN1bHRDb21waWxlck9wdGlvbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHBhcnNlZENvbXBpbGVyT3B0aW9ucykpXG4gICAgICAgICAgICBzZXQocmVzdWx0Q29tcGlsZXJPcHRpb25zLCBrZXksIHZhbHVlKTtcblxuICAgICAgICB0aGlzLm9wdHMuY29tcGlsZXJPcHRpb25zID0gcmVzdWx0Q29tcGlsZXJPcHRpb25zO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX3BhcnNlRGFzaGJvYXJkT3B0aW9ucyAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMuZGFzaGJvYXJkT3B0aW9ucylcbiAgICAgICAgICAgIHRoaXMub3B0cy5kYXNoYm9hcmRPcHRpb25zID0gYXdhaXQgZ2V0RGFzaGJvYXJkT3B0aW9ucyh0aGlzLm9wdHMuZGFzaGJvYXJkT3B0aW9ucyBhcyBzdHJpbmcpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3BhcnNlTGlzdEJyb3dzZXJzICgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbGlzdEJyb3dzZXJPcHRpb24gPSB0aGlzLm9wdHMubGlzdEJyb3dzZXJzO1xuXG4gICAgICAgIHRoaXMub3B0cy5saXN0QnJvd3NlcnMgPSAhIXRoaXMub3B0cy5saXN0QnJvd3NlcnM7XG5cbiAgICAgICAgaWYgKCF0aGlzLm9wdHMubGlzdEJyb3dzZXJzKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMub3B0cy5wcm92aWRlck5hbWUgPSB0eXBlb2YgbGlzdEJyb3dzZXJPcHRpb24gPT09ICdzdHJpbmcnID8gbGlzdEJyb3dzZXJPcHRpb24gOiAnbG9jYWxseS1pbnN0YWxsZWQnO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIF9wcmVwYXJlQm9vbGVhbk9yT2JqZWN0T3B0aW9uIChhcmd2OiBzdHJpbmdbXSwgb3B0aW9uTmFtZXM6IHN0cmluZ1tdLCBzdWJPcHRpb25zTmFtZXM6IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgICAgIC8vIE5PVEU6IG1vdmUgb3B0aW9ucyB0byB0aGUgZW5kIG9mIHRoZSBhcnJheSB0byBjb3JyZWN0bHkgcGFyc2UgYm90aCBCb29sZWFuIGFuZCBPYmplY3QgdHlwZSBhcmd1bWVudHMgKEdILTYyMzEpXG4gICAgICAgIGNvbnN0IG9wdGlvbkluZGV4ID0gYXJndi5maW5kSW5kZXgoXG4gICAgICAgICAgICBlbCA9PiBvcHRpb25OYW1lcy5zb21lKG9wdCA9PiBlbC5zdGFydHNXaXRoKG9wdCkpKTtcblxuICAgICAgICBpZiAob3B0aW9uSW5kZXggPiAtMSkge1xuICAgICAgICAgICAgY29uc3QgaXNOb3RMYXN0T3B0aW9uICAgICAgID0gb3B0aW9uSW5kZXggPCBhcmd2Lmxlbmd0aCAtIDE7XG4gICAgICAgICAgICBjb25zdCBzaG91bGRNb3ZlT3B0aW9uVG9FbmQgPSBpc05vdExhc3RPcHRpb24gJiZcbiAgICAgICAgICAgICAgICAhc3ViT3B0aW9uc05hbWVzLnNvbWUob3B0ID0+IGFyZ3Zbb3B0aW9uSW5kZXggKyAxXS5zdGFydHNXaXRoKG9wdCkpO1xuXG4gICAgICAgICAgICBpZiAoc2hvdWxkTW92ZU9wdGlvblRvRW5kKVxuICAgICAgICAgICAgICAgIGFyZ3YucHVzaChhcmd2LnNwbGljZShvcHRpb25JbmRleCwgMSlbMF0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHBhcnNlIChhcmd2OiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBDTElBcmd1bWVudFBhcnNlci5fcHJlcGFyZUJvb2xlYW5Pck9iamVjdE9wdGlvbihhcmd2LCBbJy1xJywgJy0tcXVhcmFudGluZS1tb2RlJ10sIE9iamVjdC52YWx1ZXMoUVVBUkFOVElORV9PUFRJT05fTkFNRVMpKTtcbiAgICAgICAgQ0xJQXJndW1lbnRQYXJzZXIuX3ByZXBhcmVCb29sZWFuT3JPYmplY3RPcHRpb24oYXJndiwgWyctZScsICctLXNraXAtanMtZXJyb3JzJ10sIE9iamVjdC52YWx1ZXMoU0tJUF9KU19FUlJPUlNfT1BUSU9OU19PQkpFQ1RfT1BUSU9OX05BTUVTKSk7XG5cbiAgICAgICAgY29uc3QgeyBhcmdzLCB2OEZsYWdzIH0gPSBleHRyYWN0Tm9kZVByb2Nlc3NBcmd1bWVudHMoYXJndik7XG5cbiAgICAgICAgKHByb2dyYW0gYXMgdW5rbm93biBhcyBDb21tYW5kKS5wYXJzZShhcmdzKTtcblxuICAgICAgICB0aGlzLmFyZ3MgPSAocHJvZ3JhbSBhcyB1bmtub3duIGFzIENvbW1hbmQpLmFyZ3M7XG4gICAgICAgIHRoaXMub3B0cyA9IE9iamVjdC5hc3NpZ24odGhpcy5vcHRzLCB7IHY4RmxhZ3MgfSk7XG5cbiAgICAgICAgdGhpcy5fcGFyc2VMaXN0QnJvd3NlcnMoKTtcblxuICAgICAgICAvLyBOT1RFOiB0aGUgJy0tbGlzdC1icm93c2Vycycgb3B0aW9uIG9ubHkgbGlzdHMgYnJvd3NlcnMgYW5kIGltbWVkaWF0ZWx5IGV4aXRzIHRoZSBhcHAuXG4gICAgICAgIC8vIFRoZXJlZm9yZSwgd2UgZG9uJ3QgbmVlZCB0byBwcm9jZXNzIG90aGVyIGFyZ3VtZW50cy5cbiAgICAgICAgaWYgKHRoaXMub3B0cy5saXN0QnJvd3NlcnMpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdGhpcy5fcGFyc2VTZWxlY3RvclRpbWVvdXQoKTtcbiAgICAgICAgdGhpcy5fcGFyc2VBc3NlcnRpb25UaW1lb3V0KCk7XG4gICAgICAgIHRoaXMuX3BhcnNlUGFnZUxvYWRUaW1lb3V0KCk7XG4gICAgICAgIHRoaXMuX3BhcnNlUGFnZVJlcXVlc3RUaW1lb3V0KCk7XG4gICAgICAgIHRoaXMuX3BhcnNlQWpheFJlcXVlc3RUaW1lb3V0KCk7XG4gICAgICAgIHRoaXMuX3BhcnNlQnJvd3NlckluaXRUaW1lb3V0KCk7XG4gICAgICAgIHRoaXMuX3BhcnNlVGVzdEV4ZWN1dGlvblRpbWVvdXQoKTtcbiAgICAgICAgdGhpcy5fcGFyc2VSdW5FeGVjdXRpb25UaW1lb3V0KCk7XG4gICAgICAgIHRoaXMuX3BhcnNlQXBwSW5pdERlbGF5KCk7XG4gICAgICAgIHRoaXMuX3BhcnNlU3BlZWQoKTtcbiAgICAgICAgdGhpcy5fcGFyc2VQb3J0cygpO1xuICAgICAgICB0aGlzLl9wYXJzZUJyb3dzZXJzRnJvbUFyZ3MoKTtcbiAgICAgICAgdGhpcy5fcGFyc2VDb25jdXJyZW5jeSgpO1xuICAgICAgICB0aGlzLl9wYXJzZUZpbGVMaXN0KCk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5fcGFyc2VGaWx0ZXJpbmdPcHRpb25zKCk7XG4gICAgICAgIGF3YWl0IHRoaXMuX3BhcnNlUXVhcmFudGluZU9wdGlvbnMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5fcGFyc2VTa2lwSnNFcnJvcnNPcHRpb25zKCk7XG4gICAgICAgIGF3YWl0IHRoaXMuX3BhcnNlU2NyZWVuc2hvdE9wdGlvbnMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5fcGFyc2VWaWRlb09wdGlvbnMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5fcGFyc2VDb21waWxlck9wdGlvbnMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5fcGFyc2VTc2xPcHRpb25zKCk7XG4gICAgICAgIGF3YWl0IHRoaXMuX3BhcnNlUmVwb3J0ZXJzKCk7XG4gICAgICAgIGF3YWl0IHRoaXMuX3BhcnNlRGFzaGJvYXJkT3B0aW9ucygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRSdW5PcHRpb25zICgpOiBSdW5uZXJSdW5PcHRpb25zIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgICAgICBSVU5fT1BUSU9OX05BTUVTLmZvckVhY2gob3B0aW9uTmFtZSA9PiB7XG4gICAgICAgICAgICBpZiAob3B0aW9uTmFtZSBpbiB0aGlzLm9wdHMpXG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZSBhIGhhY2sgdG8gYWRkIGFuIGluZGV4IHNpZ25hdHVyZSB0byBpbnRlcmZhY2VcbiAgICAgICAgICAgICAgICByZXN1bHRbb3B0aW9uTmFtZV0gPSB0aGlzLm9wdHNbb3B0aW9uTmFtZV07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQgYXMgUnVubmVyUnVuT3B0aW9ucztcbiAgICB9XG59XG4iXX0=