UNPKG

oidc-client

Version:

OpenID Connect (OIDC) & OAuth2 client library

353 lines 44.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license * */ const core_1 = require("@angular-devkit/core"); const interface_1 = require("./interface"); class ParseArgumentException extends core_1.BaseException { constructor(comments, parsed, ignored) { super(`One or more errors occured while parsing arguments:\n ${comments.join('\n ')}`); this.comments = comments; this.parsed = parsed; this.ignored = ignored; } } exports.ParseArgumentException = ParseArgumentException; function _coerceType(str, type, v) { switch (type) { case interface_1.OptionType.Any: if (Array.isArray(v)) { return v.concat(str || ''); } return _coerceType(str, interface_1.OptionType.Boolean, v) !== undefined ? _coerceType(str, interface_1.OptionType.Boolean, v) : _coerceType(str, interface_1.OptionType.Number, v) !== undefined ? _coerceType(str, interface_1.OptionType.Number, v) : _coerceType(str, interface_1.OptionType.String, v); case interface_1.OptionType.String: return str || ''; case interface_1.OptionType.Boolean: switch (str) { case 'false': return false; case undefined: case '': case 'true': return true; default: return undefined; } case interface_1.OptionType.Number: if (str === undefined) { return 0; } else if (str === '') { return undefined; } else if (Number.isFinite(+str)) { return +str; } else { return undefined; } case interface_1.OptionType.Array: return Array.isArray(v) ? v.concat(str || '') : v === undefined ? [str || ''] : [v + '', str || '']; default: return undefined; } } function _coerce(str, o, v) { if (!o) { return _coerceType(str, interface_1.OptionType.Any, v); } else { const types = o.types || [o.type]; // Try all the types one by one and pick the first one that returns a value contained in the // enum. If there's no enum, just return the first one that matches. for (const type of types) { const maybeResult = _coerceType(str, type, v); if (maybeResult !== undefined) { if (!o.enum || o.enum.includes(maybeResult)) { return maybeResult; } } } return undefined; } } function _getOptionFromName(name, options) { const camelName = /(-|_)/.test(name) ? core_1.strings.camelize(name) : name; for (const option of options) { if (option.name === name || option.name === camelName) { return option; } if (option.aliases.some(x => x === name || x === camelName)) { return option; } } return undefined; } function _removeLeadingDashes(key) { const from = key.startsWith('--') ? 2 : key.startsWith('-') ? 1 : 0; return key.substr(from); } function _assignOption(arg, nextArg, { options, parsedOptions, leftovers, ignored, errors, warnings }) { const from = arg.startsWith('--') ? 2 : 1; let consumedNextArg = false; let key = arg.substr(from); let option = null; let value = ''; const i = arg.indexOf('='); // If flag is --no-abc AND there's no equal sign. if (i == -1) { if (key.startsWith('no')) { // Only use this key if the option matching the rest is a boolean. const from = key.startsWith('no-') ? 3 : 2; const maybeOption = _getOptionFromName(core_1.strings.camelize(key.substr(from)), options); if (maybeOption && maybeOption.type == 'boolean') { value = 'false'; option = maybeOption; } } if (option === null) { // Set it to true if it's a boolean and the next argument doesn't match true/false. const maybeOption = _getOptionFromName(key, options); if (maybeOption) { value = nextArg; let shouldShift = true; if (value && value.startsWith('-')) { // Verify if not having a value results in a correct parse, if so don't shift. if (_coerce(undefined, maybeOption) !== undefined) { shouldShift = false; } } // Only absorb it if it leads to a better value. if (shouldShift && _coerce(value, maybeOption) !== undefined) { consumedNextArg = true; } else { value = ''; } option = maybeOption; } } } else { key = arg.substring(0, i); option = _getOptionFromName(_removeLeadingDashes(key), options) || null; if (option) { value = arg.substring(i + 1); } } if (option === null) { if (nextArg && !nextArg.startsWith('-')) { leftovers.push(arg, nextArg); consumedNextArg = true; } else { leftovers.push(arg); } } else { const v = _coerce(value, option, parsedOptions[option.name]); if (v !== undefined) { if (parsedOptions[option.name] !== v) { if (parsedOptions[option.name] !== undefined) { warnings.push(`Option ${JSON.stringify(option.name)} was already specified with value ` + `${JSON.stringify(parsedOptions[option.name])}. The new value ${JSON.stringify(v)} ` + `will override it.`); } parsedOptions[option.name] = v; if (option.deprecated !== undefined && option.deprecated !== false) { warnings.push(`Option ${JSON.stringify(option.name)} is deprecated${typeof option.deprecated == 'string' ? ': ' + option.deprecated : '.'}`); } } } else { let error = `Argument ${key} could not be parsed using value ${JSON.stringify(value)}.`; if (option.enum) { error += ` Valid values are: ${option.enum.map(x => JSON.stringify(x)).join(', ')}.`; } else { error += `Valid type(s) is: ${(option.types || [option.type]).join(', ')}`; } errors.push(error); ignored.push(arg); } } return consumedNextArg; } /** * Parse the arguments in a consistent way, but without having any option definition. This tries * to assess what the user wants in a free form. For example, using `--name=false` will set the * name properties to a boolean type. * This should only be used when there's no schema available or if a schema is "true" (anything is * valid). * * @param args Argument list to parse. * @returns An object that contains a property per flags from the args. */ function parseFreeFormArguments(args) { const parsedOptions = {}; const leftovers = []; for (let arg = args.shift(); arg !== undefined; arg = args.shift()) { if (arg == '--') { leftovers.push(...args); break; } if (arg.startsWith('--')) { const eqSign = arg.indexOf('='); let name; let value; if (eqSign !== -1) { name = arg.substring(2, eqSign); value = arg.substring(eqSign + 1); } else { name = arg.substr(2); value = args.shift(); } const v = _coerce(value, null, parsedOptions[name]); if (v !== undefined) { parsedOptions[name] = v; } } else if (arg.startsWith('-')) { arg.split('').forEach(x => parsedOptions[x] = true); } else { leftovers.push(arg); } } parsedOptions['--'] = leftovers; return parsedOptions; } exports.parseFreeFormArguments = parseFreeFormArguments; /** * Parse the arguments in a consistent way, from a list of standardized options. * The result object will have a key per option name, with the `_` key reserved for positional * arguments, and `--` will contain everything that did not match. Any key that don't have an * option will be pushed back in `--` and removed from the object. If you need to validate that * there's no additionalProperties, you need to check the `--` key. * * @param args The argument array to parse. * @param options List of supported options. {@see Option}. * @param logger Logger to use to warn users. * @returns An object that contains a property per option. */ function parseArguments(args, options, logger) { if (options === null) { options = []; } const leftovers = []; const positionals = []; const parsedOptions = {}; const ignored = []; const errors = []; const warnings = []; const state = { options, parsedOptions, positionals, leftovers, ignored, errors, warnings }; for (let argIndex = 0; argIndex < args.length; argIndex++) { const arg = args[argIndex]; let consumedNextArg = false; if (arg == '--') { // If we find a --, we're done. leftovers.push(...args.slice(argIndex + 1)); break; } if (arg.startsWith('--')) { consumedNextArg = _assignOption(arg, args[argIndex + 1], state); } else if (arg.startsWith('-')) { // Argument is of form -abcdef. Starts at 1 because we skip the `-`. for (let i = 1; i < arg.length; i++) { const flag = arg[i]; // If the next character is an '=', treat it as a long flag. if (arg[i + 1] == '=') { const f = '-' + flag + arg.slice(i + 1); consumedNextArg = _assignOption(f, args[argIndex + 1], state); break; } // Treat the last flag as `--a` (as if full flag but just one letter). We do this in // the loop because it saves us a check to see if the arg is just `-`. if (i == arg.length - 1) { const arg = '-' + flag; consumedNextArg = _assignOption(arg, args[argIndex + 1], state); } else { const maybeOption = _getOptionFromName(flag, options); if (maybeOption) { const v = _coerce(undefined, maybeOption, parsedOptions[maybeOption.name]); if (v !== undefined) { parsedOptions[maybeOption.name] = v; } } } } } else { positionals.push(arg); } if (consumedNextArg) { argIndex++; } } // Deal with positionals. // TODO(hansl): this is by far the most complex piece of code in this file. Try to refactor it // simpler. if (positionals.length > 0) { let pos = 0; for (let i = 0; i < positionals.length;) { let found = false; let incrementPos = false; let incrementI = true; // We do this with a found flag because more than 1 option could have the same positional. for (const option of options) { // If any option has this positional and no value, AND fit the type, we need to remove it. if (option.positional === pos) { const coercedValue = _coerce(positionals[i], option, parsedOptions[option.name]); if (parsedOptions[option.name] === undefined && coercedValue !== undefined) { parsedOptions[option.name] = coercedValue; found = true; } else { incrementI = false; } incrementPos = true; } } if (found) { positionals.splice(i--, 1); } if (incrementPos) { pos++; } if (incrementI) { i++; } } } if (positionals.length > 0 || leftovers.length > 0) { parsedOptions['--'] = [...positionals, ...leftovers]; } if (warnings.length > 0 && logger) { warnings.forEach(message => logger.warn(message)); } if (errors.length > 0) { throw new ParseArgumentException(errors, parsedOptions, ignored); } return parsedOptions; } exports.parseArguments = parseArguments; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VyLmpzIiwic291cmNlUm9vdCI6Ii4vIiwic291cmNlcyI6WyJwYWNrYWdlcy9hbmd1bGFyL2NsaS9tb2RlbHMvcGFyc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7Ozs7R0FPRztBQUNILCtDQUF1RTtBQUN2RSwyQ0FBbUU7QUFHbkUsTUFBYSxzQkFBdUIsU0FBUSxvQkFBYTtJQUN2RCxZQUNrQixRQUFrQixFQUNsQixNQUFpQixFQUNqQixPQUFpQjtRQUVqQyxLQUFLLENBQUMsMERBQTBELFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBSnpFLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsV0FBTSxHQUFOLE1BQU0sQ0FBVztRQUNqQixZQUFPLEdBQVAsT0FBTyxDQUFVO0lBR25DLENBQUM7Q0FDRjtBQVJELHdEQVFDO0FBR0QsU0FBUyxXQUFXLENBQUMsR0FBdUIsRUFBRSxJQUFnQixFQUFFLENBQVM7SUFDdkUsUUFBUSxJQUFJLEVBQUU7UUFDWixLQUFLLHNCQUFVLENBQUMsR0FBRztZQUNqQixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3BCLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLENBQUM7YUFDNUI7WUFFRCxPQUFPLFdBQVcsQ0FBQyxHQUFHLEVBQUUsc0JBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEtBQUssU0FBUztnQkFDMUQsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsc0JBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUN6QyxDQUFDLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxzQkFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsS0FBSyxTQUFTO29CQUNwRCxDQUFDLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxzQkFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7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QztxQkFDZDt5QkFBTTt3QkFDTCxVQUFVLEdBQUcsS0FBSyxDQUFDO3FCQUNwQjtvQkFDRCxZQUFZLEdBQUcsSUFBSSxDQUFDO2lCQUNyQjthQUNGO1lBRUQsSUFBSSxLQUFLLEVBQUU7Z0JBQ1QsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQzthQUM1QjtZQUNELElBQUksWUFBWSxFQUFFO2dCQUNoQixHQUFHLEVBQUUsQ0FBQzthQUNQO1lBQ0QsSUFBSSxVQUFVLEVBQUU7Z0JBQ2QsQ0FBQyxFQUFFLENBQUM7YUFDTDtTQUNGO0tBQ0Y7SUFFRCxJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ2xELGFBQWEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsV0FBVyxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUM7S0FDdEQ7SUFFRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLE1BQU0sRUFBRTtRQUNqQyxRQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0tBQ25EO0lBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtRQUNyQixNQUFNLElBQUksc0JBQXNCLENBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQztLQUNsRTtJQUVELE9BQU8sYUFBYSxDQUFDO0FBQ3ZCLENBQUM7QUFuSEQsd0NBbUhDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqXG4gKi9cbmltcG9ydCB7IEJhc2VFeGNlcHRpb24sIGxvZ2dpbmcsIHN0cmluZ3MgfSBmcm9tICdAYW5ndWxhci1kZXZraXQvY29yZSc7XG5pbXBvcnQgeyBBcmd1bWVudHMsIE9wdGlvbiwgT3B0aW9uVHlwZSwgVmFsdWUgfSBmcm9tICcuL2ludGVyZmFjZSc7XG5cblxuZXhwb3J0IGNsYXNzIFBhcnNlQXJndW1lbnRFeGNlcHRpb24gZXh0ZW5kcyBCYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGNvbW1lbnRzOiBzdHJpbmdbXSxcbiAgICBwdWJsaWMgcmVhZG9ubHkgcGFyc2VkOiBBcmd1bWVudHMsXG4gICAgcHVibGljIHJlYWRvbmx5IGlnbm9yZWQ6IHN0cmluZ1tdLFxuICApIHtcbiAgICBzdXBlcihgT25lIG9yIG1vcmUgZXJyb3JzIG9jY3VyZWQgd2hpbGUgcGFyc2luZyBhcmd1bWVudHM6XFxuICAke2NvbW1lbnRzLmpvaW4oJ1xcbiAgJyl9YCk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBfY29lcmNlVHlwZShzdHI6IHN0cmluZyB8IHVuZGVmaW5lZCwgdHlwZTogT3B0aW9uVHlwZSwgdj86IFZhbHVlKTogVmFsdWUgfCB1bmRlZmluZWQge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIE9wdGlvblR5cGUuQW55OlxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodikpIHtcbiAgICAgICAgcmV0dXJuIHYuY29uY2F0KHN0ciB8fCAnJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBfY29lcmNlVHlwZShzdHIsIE9wdGlvblR5cGUuQm9vbGVhbiwgdikgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IF9jb2VyY2VUeXBlKHN0ciwgT3B0aW9uVHlwZS5Cb29sZWFuLCB2KVxuICAgICAgICA6IF9jb2VyY2VUeXBlKHN0ciwgT3B0aW9uVHlwZS5OdW1iZXIsIHYpICE9PSB1bmRlZmluZWRcbiAgICAgICAgICA/IF9jb2VyY2VUeXBlKHN0ciwgT3B0aW9uVHlwZS5OdW1iZXIsIHYpXG4gICAgICAgICAgOiBfY29lcmNlVHlwZShzdHIsIE9wdGlvblR5cGUuU3RyaW5nLCB2KTtcblxuICAgIGNhc2UgT3B0aW9uVHlwZS5TdHJpbmc6XG4gICAgICByZXR1cm4gc3RyIHx8ICcnO1xuXG4gICAgY2FzZSBPcHRpb25UeXBlLkJvb2xlYW46XG4gICAgICBzd2l0Y2ggKHN0cikge1xuICAgICAgICBjYXNlICdmYWxzZSc6XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgICBjYXNlICcnOlxuICAgICAgICBjYXNlICd0cnVlJzpcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICBjYXNlIE9wdGlvblR5cGUuTnVtYmVyOlxuICAgICAgaWYgKHN0ciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfSBlbHNlIGlmIChzdHIgPT09ICcnKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2UgaWYgKE51bWJlci5pc0Zpbml0ZSgrc3RyKSkge1xuICAgICAgICByZXR1cm4gK3N0cjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICBjYXNlIE9wdGlvblR5cGUuQXJyYXk6XG4gICAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2KVxuICAgICAgICA/IHYuY29uY2F0KHN0ciB8fCAnJylcbiAgICAgICAgOiB2ID09PSB1bmRlZmluZWRcbiAgICAgICAgICA/IFtzdHIgfHwgJyddXG4gICAgICAgICAgOiBbdiArICcnLCBzdHIgfHwgJyddO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gX2NvZXJjZShzdHI6IHN0cmluZyB8IHVuZGVmaW5lZCwgbzogT3B0aW9uIHwgbnVsbCwgdj86IFZhbHVlKTogVmFsdWUgfCB1bmRlZmluZWQge1xuICBpZiAoIW8pIHtcbiAgICByZXR1cm4gX2NvZXJjZVR5cGUoc3RyLCBPcHRpb25UeXBlLkFueSwgdik7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgdHlwZXMgPSBvLnR5cGVzIHx8IFtvLnR5cGVdO1xuXG4gICAgLy8gVHJ5IGFsbCB0aGUgdHlwZXMgb25lIGJ5IG9uZSBhbmQgcGljayB0aGUgZmlyc3Qgb25lIHRoYXQgcmV0dXJucyBhIHZhbHVlIGNvbnRhaW5lZCBpbiB0aGVcbiAgICAvLyBlbnVtLiBJZiB0aGVyZSdzIG5vIGVudW0sIGp1c3QgcmV0dXJuIHRoZSBmaXJzdCBvbmUgdGhhdCBtYXRjaGVzLlxuICAgIGZvciAoY29uc3QgdHlwZSBvZiB0eXBlcykge1xuICAgICAgY29uc3QgbWF5YmVSZXN1bHQgPSBfY29lcmNlVHlwZShzdHIsIHR5cGUsIHYpO1xuICAgICAgaWYgKG1heWJlUmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFvLmVudW0gfHwgby5lbnVtLmluY2x1ZGVzKG1heWJlUmVzdWx0KSkge1xuICAgICAgICAgIHJldHVybiBtYXliZVJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBfZ2V0T3B0aW9uRnJvbU5hbWUobmFtZTogc3RyaW5nLCBvcHRpb25zOiBPcHRpb25bXSk6IE9wdGlvbiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGNhbWVsTmFtZSA9IC8oLXxfKS8udGVzdChuYW1lKVxuICAgID8gc3RyaW5ncy5jYW1lbGl6ZShuYW1lKVxuICAgIDogbmFtZTtcblxuICBmb3IgKGNvbnN0IG9wdGlvbiBvZiBvcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbi5uYW1lID09PSBuYW1lIHx8IG9wdGlvbi5uYW1lID09PSBjYW1lbE5hbWUpIHtcbiAgICAgIHJldHVybiBvcHRpb247XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbi5hbGlhc2VzLnNvbWUoeCA9PiB4ID09PSBuYW1lIHx8IHggPT09IGNhbWVsTmFtZSkpIHtcbiAgICAgIHJldHVybiBvcHRpb247XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gX3JlbW92ZUxlYWRpbmdEYXNoZXMoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBmcm9tID0ga2V5LnN0YXJ0c1dpdGgoJy0tJykgPyAyIDoga2V5LnN0YXJ0c1dpdGgoJy0nKSA/IDEgOiAwO1xuXG4gIHJldHVybiBrZXkuc3Vic3RyKGZyb20pO1xufVxuXG5mdW5jdGlvbiBfYXNzaWduT3B0aW9uKFxuICBhcmc6IHN0cmluZyxcbiAgbmV4dEFyZzogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICB7IG9wdGlvbnMsIHBhcnNlZE9wdGlvbnMsIGxlZnRvdmVycywgaWdub3JlZCwgZXJyb3JzLCB3YXJuaW5ncyB9OiB7XG4gICAgb3B0aW9uczogT3B0aW9uW10sXG4gICAgcGFyc2VkT3B0aW9uczogQXJndW1lbnRzLFxuICAgIHBvc2l0aW9uYWxzOiBzdHJpbmdbXSxcbiAgICBsZWZ0b3ZlcnM6IHN0cmluZ1tdLFxuICAgIGlnbm9yZWQ6IHN0cmluZ1tdLFxuICAgIGVycm9yczogc3RyaW5nW10sXG4gICAgd2FybmluZ3M6IHN0cmluZ1tdLFxuICB9LFxuKSB7XG4gIGNvbnN0IGZyb20gPSBhcmcuc3RhcnRzV2l0aCgnLS0nKSA/IDIgOiAxO1xuICBsZXQgY29uc3VtZWROZXh0QXJnID0gZmFsc2U7XG4gIGxldCBrZXkgPSBhcmcuc3Vic3RyKGZyb20pO1xuICBsZXQgb3B0aW9uOiBPcHRpb24gfCBudWxsID0gbnVsbDtcbiAgbGV0IHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQgPSAnJztcbiAgY29uc3QgaSA9IGFyZy5pbmRleE9mKCc9Jyk7XG5cbiAgLy8gSWYgZmxhZyBpcyAtLW5vLWFiYyBBTkQgdGhlcmUncyBubyBlcXVhbCBzaWduLlxuICBpZiAoaSA9PSAtMSkge1xuICAgIGlmIChrZXkuc3RhcnRzV2l0aCgnbm8nKSkge1xuICAgICAgLy8gT25seSB1c2UgdGhpcyBrZXkgaWYgdGhlIG9wdGlvbiBtYXRjaGluZyB0aGUgcmVzdCBpcyBhIGJvb2xlYW4uXG4gICAgICBjb25zdCBmcm9tID0ga2V5LnN0YXJ0c1dpdGgoJ25vLScpID8gMyA6IDI7XG4gICAgICBjb25zdCBtYXliZU9wdGlvbiA9IF9nZXRPcHRpb25Gcm9tTmFtZShzdHJpbmdzLmNhbWVsaXplKGtleS5zdWJzdHIoZnJvbSkpLCBvcHRpb25zKTtcbiAgICAgIGlmIChtYXliZU9wdGlvbiAmJiBtYXliZU9wdGlvbi50eXBlID09ICdib29sZWFuJykge1xuICAgICAgICB2YWx1ZSA9ICdmYWxzZSc7XG4gICAgICAgIG9wdGlvbiA9IG1heWJlT3B0aW9uO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvcHRpb24gPT09IG51bGwpIHtcbiAgICAgIC8vIFNldCBpdCB0byB0cnVlIGlmIGl0J3MgYSBib29sZWFuIGFuZCB0aGUgbmV4dCBhcmd1bWVudCBkb2Vzbid0IG1hdGNoIHRydWUvZmFsc2UuXG4gICAgICBjb25zdCBtYXliZU9wdGlvbiA9IF9nZXRPcHRpb25Gcm9tTmFtZShrZXksIG9wdGlvbnMpO1xuICAgICAgaWYgKG1heWJlT3B0aW9uKSB7XG4gICAgICAgIHZhbHVlID0gbmV4dEFyZztcbiAgICAgICAgbGV0IHNob3VsZFNoaWZ0ID0gdHJ1ZTtcblxuICAgICAgICBpZiAodmFsdWUgJiYgdmFsdWUuc3RhcnRzV2l0aCgnLScpKSB7XG4gICAgICAgICAgLy8gVmVyaWZ5IGlmIG5vdCBoYXZpbmcgYSB2YWx1ZSByZXN1bHRzIGluIGEgY29ycmVjdCBwYXJzZSwgaWYgc28gZG9uJ3Qgc2hpZnQuXG4gICAgICAgICAgaWYgKF9jb2VyY2UodW5kZWZpbmVkLCBtYXliZU9wdGlvbikgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc2hvdWxkU2hpZnQgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBPbmx5IGFic29yYiBpdCBpZiBpdCBsZWFkcyB0byBhIGJldHRlciB2YWx1ZS5cbiAgICAgICAgaWYgKHNob3VsZFNoaWZ0ICYmIF9jb2VyY2UodmFsdWUsIG1heWJlT3B0aW9uKSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgY29uc3VtZWROZXh0QXJnID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZSA9ICcnO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbiA9IG1heWJlT3B0aW9uO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBrZXkgPSBhcmcuc3Vic3RyaW5nKDAsIGkpO1xuICAgIG9wdGlvbiA9IF9nZXRPcHRpb25Gcm9tTmFtZShfcmVtb3ZlTGVhZGluZ0Rhc2hlcyhrZXkpLCBvcHRpb25zKSB8fCBudWxsO1xuICAgIGlmIChvcHRpb24pIHtcbiAgICAgIHZhbHVlID0gYXJnLnN1YnN0cmluZyhpICsgMSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wdGlvbiA9PT0gbnVsbCkge1xuICAgIGlmIChuZXh0QXJnICYmICFuZXh0QXJnLnN0YXJ0c1dpdGgoJy0nKSkge1xuICAgICAgbGVmdG92ZXJzLnB1c2goYXJnLCBuZXh0QXJnKTtcbiAgICAgIGNvbnN1bWVkTmV4dEFyZyA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxlZnRvdmVycy5wdXNoKGFyZyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNvbnN0IHYgPSBfY29lcmNlKHZhbHVlLCBvcHRpb24sIHBhcnNlZE9wdGlvbnNbb3B0aW9uLm5hbWVdKTtcbiAgICBpZiAodiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAocGFyc2VkT3B0aW9uc1tvcHRpb24ubmFtZV0gIT09IHYpIHtcbiAgICAgICAgaWYgKHBhcnNlZE9wdGlvbnNbb3B0aW9uLm5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB3YXJuaW5ncy5wdXNoKFxuICAgICAgICAgICAgYE9wdGlvbiAke0pTT04uc3RyaW5naWZ5KG9wdGlvbi5uYW1lKX0gd2FzIGFscmVhZHkgc3BlY2lmaWVkIHdpdGggdmFsdWUgYFxuICAgICAgICAgICAgKyBgJHtKU09OLnN0cmluZ2lmeShwYXJzZWRPcHRpb25zW29wdGlvbi5uYW1lXSl9LiBUaGUgbmV3IHZhbHVlICR7SlNPTi5zdHJpbmdpZnkodil9IGBcbiAgICAgICAgICAgICsgYHdpbGwgb3ZlcnJpZGUgaXQuYCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcGFyc2VkT3B0aW9uc1tvcHRpb24ubmFtZV0gPSB2O1xuXG4gICAgICAgIGlmIChvcHRpb24uZGVwcmVjYXRlZCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbi5kZXByZWNhdGVkICE9PSBmYWxzZSkge1xuICAgICAgICAgIHdhcm5pbmdzLnB1c2goYE9wdGlvbiAke0pTT04uc3RyaW5naWZ5KG9wdGlvbi5uYW1lKX0gaXMgZGVwcmVjYXRlZCR7XG4gICAgICAgICAgICB0eXBlb2Ygb3B0aW9uLmRlcHJlY2F0ZWQgPT0gJ3N0cmluZycgPyAnOiAnICsgb3B0aW9uLmRlcHJlY2F0ZWQgOiAnLid9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGVycm9yID0gYEFyZ3VtZW50ICR7a2V5fSBjb3VsZCBub3QgYmUgcGFyc2VkIHVzaW5nIHZhbHVlICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfS5gO1xuICAgICAgaWYgKG9wdGlvbi5lbnVtKSB7XG4gICAgICAgIGVycm9yICs9IGAgVmFsaWQgdmFsdWVzIGFyZTogJHtvcHRpb24uZW51bS5tYXAoeCA9PiBKU09OLnN0cmluZ2lmeSh4KSkuam9pbignLCAnKX0uYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yICs9IGBWYWxpZCB0eXBlKHMpIGlzOiAkeyhvcHRpb24udHlwZXMgfHwgW29wdGlvbi50eXBlXSkuam9pbignLCAnKX1gO1xuICAgICAgfVxuXG4gICAgICBlcnJvcnMucHVzaChlcnJvcik7XG4gICAgICBpZ25vcmVkLnB1c2goYXJnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29uc3VtZWROZXh0QXJnO1xufVxuXG5cbi8qKlxuICogUGFyc2UgdGhlIGFyZ3VtZW50cyBpbiBhIGNvbnNpc3RlbnQgd2F5LCBidXQgd2l0aG91dCBoYXZpbmcgYW55IG9wdGlvbiBkZWZpbml0aW9uLiBUaGlzIHRyaWVzXG4gKiB0byBhc3Nlc3Mgd2hhdCB0aGUgdXNlciB3YW50cyBpbiBhIGZyZWUgZm9ybS4gRm9yIGV4YW1wbGUsIHVzaW5nIGAtLW5hbWU9ZmFsc2VgIHdpbGwgc2V0IHRoZVxuICogbmFtZSBwcm9wZXJ0aWVzIHRvIGEgYm9vbGVhbiB0eXBlLlxuICogVGhpcyBzaG91bGQgb25seSBiZSB1c2VkIHdoZW4gdGhlcmUncyBubyBzY2hlbWEgYXZhaWxhYmxlIG9yIGlmIGEgc2NoZW1hIGlzIFwidHJ1ZVwiIChhbnl0aGluZyBpc1xuICogdmFsaWQpLlxuICpcbiAqIEBwYXJhbSBhcmdzIEFyZ3VtZW50IGxpc3QgdG8gcGFyc2UuXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgdGhhdCBjb250YWlucyBhIHByb3BlcnR5IHBlciBmbGFncyBmcm9tIHRoZSBhcmdzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VGcmVlRm9ybUFyZ3VtZW50cyhhcmdzOiBzdHJpbmdbXSk6IEFyZ3VtZW50cyB7XG4gIGNvbnN0IHBhcnNlZE9wdGlvbnM6IEFyZ3VtZW50cyA9IHt9O1xuICBjb25zdCBsZWZ0b3ZlcnMgPSBbXTtcblxuICBmb3IgKGxldCBhcmcgPSBhcmdzLnNoaWZ0KCk7IGFyZyAhPT0gdW5kZWZpbmVkOyBhcmcgPSBhcmdzLnNoaWZ0KCkpIHtcbiAgICBpZiAoYXJnID09ICctLScpIHtcbiAgICAgIGxlZnRvdmVycy5wdXNoKC4uLmFyZ3MpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKGFyZy5zdGFydHNXaXRoKCctLScpKSB7XG4gICAgICBjb25zdCBlcVNpZ24gPSBhcmcuaW5kZXhPZignPScpO1xuICAgICAgbGV0IG5hbWU6IHN0cmluZztcbiAgICAgIGxldCB2YWx1ZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGVxU2lnbiAhPT0gLTEpIHtcbiAgICAgICAgbmFtZSA9IGFyZy5zdWJzdHJpbmcoMiwgZXFTaWduKTtcbiAgICAgICAgdmFsdWUgPSBhcmcuc3Vic3RyaW5nKGVxU2lnbiArIDEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmFtZSA9IGFyZy5zdWJzdHIoMik7XG4gICAgICAgIHZhbHVlID0gYXJncy5zaGlmdCgpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB2ID0gX2NvZXJjZSh2YWx1ZSwgbnVsbCwgcGFyc2VkT3B0aW9uc1tuYW1lXSk7XG4gICAgICBpZiAodiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHBhcnNlZE9wdGlvbnNbbmFtZV0gPSB2O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYXJnLnN0YXJ0c1dpdGgoJy0nKSkge1xuICAgICAgYXJnLnNwbGl0KCcnKS5mb3JFYWNoKHggPT4gcGFyc2VkT3B0aW9uc1t4XSA9IHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZWZ0b3ZlcnMucHVzaChhcmcpO1xuICAgIH1cbiAgfVxuXG4gIHBhcnNlZE9wdGlvbnNbJy0tJ10gPSBsZWZ0b3ZlcnM7XG5cbiAgcmV0dXJuIHBhcnNlZE9wdGlvbnM7XG59XG5cblxuLyoqXG4gKiBQYXJzZSB0aGUgYXJndW1lbnRzIGluIGEgY29uc2lzdGVudCB3YXksIGZyb20gYSBsaXN0IG9mIHN0YW5kYXJkaXplZCBvcHRpb25zLlxuICogVGhlIHJlc3VsdCBvYmplY3Qgd2lsbCBoYXZlIGEga2V5IHBlciBvcHRpb24gbmFtZSwgd2l0aCB0aGUgYF9gIGtleSByZXNlcnZlZCBmb3IgcG9zaXRpb25hbFxuICogYXJndW1lbnRzLCBhbmQgYC0tYCB3aWxsIGNvbnRhaW4gZXZlcnl0aGluZyB0aGF0IGRpZCBub3QgbWF0Y2guIEFueSBrZXkgdGhhdCBkb24ndCBoYXZlIGFuXG4gKiBvcHRpb24gd2lsbCBiZSBwdXNoZWQgYmFjayBpbiBgLS1gIGFuZCByZW1vdmVkIGZyb20gdGhlIG9iamVjdC4gSWYgeW91IG5lZWQgdG8gdmFsaWRhdGUgdGhhdFxuICogdGhlcmUncyBubyBhZGRpdGlvbmFsUHJvcGVydGllcywgeW91IG5lZWQgdG8gY2hlY2sgdGhlIGAtLWAga2V5LlxuICpcbiAqIEBwYXJhbSBhcmdzIFRoZSBhcmd1bWVudCBhcnJheSB0byBwYXJzZS5cbiAqIEBwYXJhbSBvcHRpb25zIExpc3Qgb2Ygc3VwcG9ydGVkIG9wdGlvbnMuIHtAc2VlIE9wdGlvbn0uXG4gKiBAcGFyYW0gbG9nZ2VyIExvZ2dlciB0byB1c2UgdG8gd2FybiB1c2Vycy5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGEgcHJvcGVydHkgcGVyIG9wdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQXJndW1lbnRzKFxuICBhcmdzOiBzdHJpbmdbXSxcbiAgb3B0aW9uczogT3B0aW9uW10gfCBudWxsLFxuICBsb2dnZXI/OiBsb2dnaW5nLkxvZ2dlcixcbik6IEFyZ3VtZW50cyB7XG4gIGlmIChvcHRpb25zID09PSBudWxsKSB7XG4gICAgb3B0aW9ucyA9IFtdO1xuICB9XG5cbiAgY29uc3QgbGVmdG92ZXJzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBwb3NpdGlvbmFsczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgcGFyc2VkT3B0aW9uczogQXJndW1lbnRzID0ge307XG5cbiAgY29uc3QgaWdub3JlZDogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCB3YXJuaW5nczogc3RyaW5nW10gPSBbXTtcblxuICBjb25zdCBzdGF0ZSA9IHsgb3B0aW9ucywgcGFyc2VkT3B0aW9ucywgcG9zaXRpb25hbHMsIGxlZnRvdmVycywgaWdub3JlZCwgZXJyb3JzLCB3YXJuaW5ncyB9O1xuXG4gIGZvciAobGV0IGFyZ0luZGV4ID0gMDsgYXJnSW5kZXggPCBhcmdzLmxlbmd0aDsgYXJnSW5kZXgrKykge1xuICAgIGNvbnN0IGFyZyA9IGFyZ3NbYXJnSW5kZXhdO1xuICAgIGxldCBjb25zdW1lZE5leHRBcmcgPSBmYWxzZTtcblxuICAgIGlmIChhcmcgPT0gJy0tJykge1xuICAgICAgLy8gSWYgd2UgZmluZCBhIC0tLCB3ZSdyZSBkb25lLlxuICAgICAgbGVmdG92ZXJzLnB1c2goLi4uYXJncy5zbGljZShhcmdJbmRleCArIDEpKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmIChhcmcuc3RhcnRzV2l0aCgnLS0nKSkge1xuICAgICAgY29uc3VtZWROZXh0QXJnID0gX2Fzc2lnbk9wdGlvbihhcmcsIGFyZ3NbYXJnSW5kZXggKyAxXSwgc3RhdGUpO1xuICAgIH0gZWxzZSBpZiAoYXJnLnN0YXJ0c1dpdGgoJy0nKSkge1xuICAgICAgLy8gQXJndW1lbnQgaXMgb2YgZm9ybSAtYWJjZGVmLiAgU3RhcnRzIGF0IDEgYmVjYXVzZSB3ZSBza2lwIHRoZSBgLWAuXG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGFyZy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBmbGFnID0gYXJnW2ldO1xuICAgICAgICAvLyBJZiB0aGUgbmV4dCBjaGFyYWN0ZXIgaXMgYW4gJz0nLCB0cmVhdCBpdCBhcyBhIGxvbmcgZmxhZy5cbiAgICAgICAgaWYgKGFyZ1tpICsgMV0gPT0gJz0nKSB7XG4gICAgICAgICAgY29uc3QgZiA9ICctJyArIGZsYWcgKyBhcmcuc2xpY2UoaSArIDEpO1xuICAgICAgICAgIGNvbnN1bWVkTmV4dEFyZyA9IF9hc3NpZ25PcHRpb24oZiwgYXJnc1thcmdJbmRleCArIDFdLCBzdGF0ZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVHJlYXQgdGhlIGxhc3QgZmxhZyBhcyBgLS1hYCAoYXMgaWYgZnVsbCBmbGFnIGJ1dCBqdXN0IG9uZSBsZXR0ZXIpLiBXZSBkbyB0aGlzIGluXG4gICAgICAgIC8vIHRoZSBsb29wIGJlY2F1c2UgaXQgc2F2ZXMgdXMgYSBjaGVjayB0byBzZWUgaWYgdGhlIGFyZyBpcyBqdXN0IGAtYC5cbiAgICAgICAgaWYgKGkgPT0gYXJnLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICBjb25zdCBhcmcgPSAnLScgKyBmbGFnO1xuICAgICAgICAgIGNvbnN1bWVkTmV4dEFyZyA9IF9hc3NpZ25PcHRpb24oYXJnLCBhcmdzW2FyZ0luZGV4ICsgMV0sIHN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBtYXliZU9wdGlvbiA9IF9nZXRPcHRpb25Gcm9tTmFtZShmbGFnLCBvcHRpb25zKTtcbiAgICAgICAgICBpZiAobWF5YmVPcHRpb24pIHtcbiAgICAgICAgICAgIGNvbnN0IHYgPSBfY29lcmNlKHVuZGVmaW5lZCwgbWF5YmVPcHRpb24sIHBhcnNlZE9wdGlvbnNbbWF5YmVPcHRpb24ubmFtZV0pO1xuICAgICAgICAgICAgaWYgKHYgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICBwYXJzZWRPcHRpb25zW21heWJlT3B0aW9uLm5hbWVdID0gdjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcG9zaXRpb25hbHMucHVzaChhcmcpO1xuICAgIH1cblxuICAgIGlmIChjb25zdW1lZE5leHRBcmcpIHtcbiAgICAgIGFyZ0luZGV4Kys7XG4gICAgfVxuICB9XG5cbiAgLy8gRGVhbCB3aXRoIHBvc2l0aW9uYWxzLlxuICAvLyBUT0RPKGhhbnNsKTogdGhpcyBpcyBieSBmYXIgdGhlIG1vc3QgY29tcGxleCBwaWVjZSBvZiBjb2RlIGluIHRoaXMgZmlsZS4gVHJ5IHRvIHJlZmFjdG9yIGl0XG4gIC8vICAgc2ltcGxlci5cbiAgaWYgKHBvc2l0aW9uYWxzLmxlbmd0aCA+IDApIHtcbiAgICBsZXQgcG9zID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBvc2l0aW9uYWxzLmxlbmd0aDspIHtcbiAgICAgIGxldCBmb3VuZCA9IGZhbHNlO1xuICAgICAgbGV0IGluY3JlbWVudFBvcyA9IGZhbHNlO1xuICAgICAgbGV0IGluY3JlbWVudEkgPSB0cnVlO1xuXG4gICAgICAvLyBXZSBkbyB0aGlzIHdpdGggYSBmb3VuZCBmbGFnIGJlY2F1c2UgbW9yZSB0aGFuIDEgb3B0aW9uIGNvdWxkIGhhdmUgdGhlIHNhbWUgcG9zaXRpb25hbC5cbiAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdGlvbnMpIHtcbiAgICAgICAgLy8gSWYgYW55IG9wdGlvbiBoYXMgdGhpcyBwb3NpdGlvbmFsIGFuZCBubyB2YWx1ZSwgQU5EIGZpdCB0aGUgdHlwZSwgd2UgbmVlZCB0byByZW1vdmUgaXQuXG4gICAgICAgIGlmIChvcHRpb24ucG9zaXRpb25hbCA9PT0gcG9zKSB7XG4gICAgICAgICAgY29uc3QgY29lcmNlZFZhbHVlID0gX2NvZXJjZShwb3NpdGlvbmFsc1tpXSwgb3B0aW9uLCBwYXJzZWRPcHRpb25zW29wdGlvbi5uYW1lXSk7XG4gICAgICAgICAgaWYgKHBhcnNlZE9wdGlvbnNbb3B0aW9uLm5hbWVdID09PSB1bmRlZmluZWQgJiYgY29lcmNlZFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBhcnNlZE9wdGlvbnNbb3B0aW9uLm5hbWVdID0gY29lcmNlZFZhbHVlO1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbmNyZW1lbnRJID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGluY3JlbWVudFBvcyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgIHBvc2l0aW9uYWxzLnNwbGljZShpLS0sIDEpO1xuICAgICAgfVxuICAgICAgaWYgKGluY3JlbWVudFBvcykge1xuICAgICAgICBwb3MrKztcbiAgICAgIH1cbiAgICAgIGlmIChpbmNyZW1lbnRJKSB7XG4gICAgICAgIGkrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAocG9zaXRpb25hbHMubGVuZ3RoID4gMCB8fCBsZWZ0b3ZlcnMubGVuZ3RoID4gMCkge1xuICAgIHBhcnNlZE9wdGlvbnNbJy0tJ10gPSBbLi4ucG9zaXRpb25hbHMsIC4uLmxlZnRvdmVyc107XG4gIH1cblxuICBpZiAod2FybmluZ3MubGVuZ3RoID4gMCAmJiBsb2dnZXIpIHtcbiAgICB3YXJuaW5ncy5mb3JFYWNoKG1lc3NhZ2UgPT4gbG9nZ2VyLndhcm4obWVzc2FnZSkpO1xuICB9XG5cbiAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlQXJndW1lbnRFeGNlcHRpb24oZXJyb3JzLCBwYXJzZWRPcHRpb25zLCBpZ25vcmVkKTtcbiAgfVxuXG4gIHJldHVybiBwYXJzZWRPcHRpb25zO1xufVxuIl19