UNPKG

aws-cdk

Version:

AWS CDK CLI, the command line tool for CDK apps

305 lines 42.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StackCollection = exports.CloudAssembly = exports.ExtendedStackSelection = exports.DefaultSelection = void 0; exports.sanitizePatterns = sanitizePatterns; const cx_api_1 = require("@aws-cdk/cx-api"); const chalk = require("chalk"); const minimatch_1 = require("minimatch"); const semver = require("semver"); const api_1 = require("../../../../@aws-cdk/tmp-toolkit-helpers/src/api"); const private_1 = require("../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private"); const util_1 = require("../../util"); var DefaultSelection; (function (DefaultSelection) { /** * Returns an empty selection in case there are no selectors. */ DefaultSelection["None"] = "none"; /** * If the app includes a single stack, returns it. Otherwise throws an exception. * This behavior is used by "deploy". */ DefaultSelection["OnlySingle"] = "single"; /** * Returns all stacks in the main (top level) assembly only. */ DefaultSelection["MainAssembly"] = "main"; /** * If no selectors are provided, returns all stacks in the app, * including stacks inside nested assemblies. */ DefaultSelection["AllStacks"] = "all"; })(DefaultSelection || (exports.DefaultSelection = DefaultSelection = {})); /** * When selecting stacks, what other stacks to include because of dependencies */ var ExtendedStackSelection; (function (ExtendedStackSelection) { /** * Don't select any extra stacks */ ExtendedStackSelection[ExtendedStackSelection["None"] = 0] = "None"; /** * Include stacks that this stack depends on */ ExtendedStackSelection[ExtendedStackSelection["Upstream"] = 1] = "Upstream"; /** * Include stacks that depend on this stack */ ExtendedStackSelection[ExtendedStackSelection["Downstream"] = 2] = "Downstream"; })(ExtendedStackSelection || (exports.ExtendedStackSelection = ExtendedStackSelection = {})); /** * A single Cloud Assembly and the operations we do on it to deploy the artifacts inside */ class CloudAssembly { constructor(assembly, ioHelper) { this.assembly = assembly; this.directory = assembly.directory; this.ioHelper = ioHelper; } async selectStacks(selector, options) { const asm = this.assembly; const topLevelStacks = asm.stacks; const stacks = semver.major(asm.version) < 10 ? asm.stacks : asm.stacksRecursively; const allTopLevel = selector.allTopLevel ?? false; const patterns = sanitizePatterns(selector.patterns); if (stacks.length === 0) { if (options.ignoreNoStacks) { return new StackCollection(this, []); } throw new api_1.ToolkitError('This app contains no stacks'); } if (allTopLevel) { return this.selectTopLevelStacks(stacks, topLevelStacks, options.extend); } else if (patterns.length > 0) { return this.selectMatchingStacks(stacks, patterns, options.extend); } else { return this.selectDefaultStacks(stacks, topLevelStacks, options.defaultBehavior); } } async selectTopLevelStacks(stacks, topLevelStacks, extend = ExtendedStackSelection.None) { if (topLevelStacks.length > 0) { return this.extendStacks(topLevelStacks, stacks, extend); } else { throw new api_1.ToolkitError('No stack found in the main cloud assembly. Use "list" to print manifest'); } } async selectMatchingStacks(stacks, patterns, extend = ExtendedStackSelection.None) { const matchingPattern = (pattern) => (stack) => (0, minimatch_1.minimatch)(stack.hierarchicalId, pattern); const matchedStacks = (0, util_1.flatten)(patterns.map(pattern => stacks.filter(matchingPattern(pattern)))); return this.extendStacks(matchedStacks, stacks, extend); } selectDefaultStacks(stacks, topLevelStacks, defaultSelection) { switch (defaultSelection) { case DefaultSelection.MainAssembly: return new StackCollection(this, topLevelStacks); case DefaultSelection.AllStacks: return new StackCollection(this, stacks); case DefaultSelection.None: return new StackCollection(this, []); case DefaultSelection.OnlySingle: if (topLevelStacks.length === 1) { return new StackCollection(this, topLevelStacks); } else { throw new api_1.ToolkitError('Since this app includes more than a single stack, specify which stacks to use (wildcards are supported) or specify `--all`\n' + `Stacks: ${stacks.map(x => x.hierarchicalId).join(' · ')}`); } default: throw new api_1.ToolkitError(`invalid default behavior: ${defaultSelection}`); } } async extendStacks(matched, all, extend = ExtendedStackSelection.None) { const allStacks = new Map(); for (const stack of all) { allStacks.set(stack.hierarchicalId, stack); } const index = indexByHierarchicalId(matched); switch (extend) { case ExtendedStackSelection.Downstream: await includeDownstreamStacks(this.ioHelper, index, allStacks); break; case ExtendedStackSelection.Upstream: await includeUpstreamStacks(this.ioHelper, index, allStacks); break; } // Filter original array because it is in the right order const selectedList = all.filter(s => index.has(s.hierarchicalId)); return new StackCollection(this, selectedList); } /** * Select a single stack by its ID */ stackById(stackId) { return new StackCollection(this, [this.assembly.getStackArtifact(stackId)]); } } exports.CloudAssembly = CloudAssembly; /** * A collection of stacks and related artifacts * * In practice, not all artifacts in the CloudAssembly are created equal; * stacks can be selected independently, but other artifacts such as asset * bundles cannot. */ class StackCollection { constructor(assembly, stackArtifacts) { this.assembly = assembly; this.stackArtifacts = stackArtifacts; } get stackCount() { return this.stackArtifacts.length; } get firstStack() { if (this.stackCount < 1) { throw new api_1.ToolkitError('StackCollection contains no stack artifacts (trying to access the first one)'); } return this.stackArtifacts[0]; } get stackIds() { return this.stackArtifacts.map(s => s.id); } get hierarchicalIds() { return this.stackArtifacts.map(s => s.hierarchicalId); } withDependencies() { const allData = []; for (const stack of this.stackArtifacts) { const data = { id: stack.displayName ?? stack.id, name: stack.stackName, environment: stack.environment, dependencies: [], }; for (const dependencyId of stack.dependencies.map(x => x.id)) { if (dependencyId.includes('.assets')) { continue; } const depStack = this.assembly.stackById(dependencyId); if (depStack.firstStack.dependencies.filter((dep) => !(dep.id).includes('.assets')).length > 0) { for (const stackDetail of depStack.withDependencies()) { data.dependencies.push({ id: stackDetail.id, dependencies: stackDetail.dependencies, }); } } else { data.dependencies.push({ id: depStack.firstStack.displayName ?? depStack.firstStack.id, dependencies: [], }); } } allData.push(data); } return allData; } reversed() { const arts = [...this.stackArtifacts]; arts.reverse(); return new StackCollection(this.assembly, arts); } filter(predicate) { return new StackCollection(this.assembly, this.stackArtifacts.filter(predicate)); } concat(...others) { return new StackCollection(this.assembly, this.stackArtifacts.concat(...others.map(o => o.stackArtifacts))); } /** * Extracts 'aws:cdk:warning|info|error' metadata entries from the stack synthesis */ async validateMetadata(failAt = 'error', logger = async () => { }) { let warnings = false; let errors = false; for (const stack of this.stackArtifacts) { for (const message of stack.messages) { switch (message.level) { case cx_api_1.SynthesisMessageLevel.WARNING: warnings = true; await logger('warn', message); break; case cx_api_1.SynthesisMessageLevel.ERROR: errors = true; await logger('error', message); break; case cx_api_1.SynthesisMessageLevel.INFO: await logger('info', message); break; } } } if (errors && failAt != 'none') { throw api_1.AssemblyError.withStacks('Found errors', this.stackArtifacts); } if (warnings && failAt === 'warn') { throw api_1.AssemblyError.withStacks('Found warnings (--strict mode)', this.stackArtifacts); } } } exports.StackCollection = StackCollection; function indexByHierarchicalId(stacks) { const result = new Map(); for (const stack of stacks) { result.set(stack.hierarchicalId, stack); } return result; } /** * Calculate the transitive closure of stack dependents. * * Modifies `selectedStacks` in-place. */ async function includeDownstreamStacks(ioHelper, selectedStacks, allStacks) { const added = new Array(); let madeProgress; do { madeProgress = false; for (const [id, stack] of allStacks) { // Select this stack if it's not selected yet AND it depends on a stack that's in the selected set if (!selectedStacks.has(id) && (stack.dependencies || []).some(dep => selectedStacks.has(dep.id))) { selectedStacks.set(id, stack); added.push(id); madeProgress = true; } } } while (madeProgress); if (added.length > 0) { await ioHelper.notify(private_1.IO.DEFAULT_ASSEMBLY_INFO.msg(`Including depending stacks: ${chalk.bold(added.join(', '))}`)); } } /** * Calculate the transitive closure of stack dependencies. * * Modifies `selectedStacks` in-place. */ async function includeUpstreamStacks(ioHelper, selectedStacks, allStacks) { const added = new Array(); let madeProgress = true; while (madeProgress) { madeProgress = false; for (const stack of selectedStacks.values()) { // Select an additional stack if it's not selected yet and a dependency of a selected stack (and exists, obviously) for (const dependencyId of stack.dependencies.map(x => x.manifest.displayName ?? x.id)) { if (!selectedStacks.has(dependencyId) && allStacks.has(dependencyId)) { added.push(dependencyId); selectedStacks.set(dependencyId, allStacks.get(dependencyId)); madeProgress = true; } } } } if (added.length > 0) { await ioHelper.notify(private_1.IO.DEFAULT_ASSEMBLY_INFO.msg(`Including dependency stacks: ${chalk.bold(added.join(', '))}`)); } } function sanitizePatterns(patterns) { let sanitized = patterns.filter(s => s != null); // filter null/undefined sanitized = [...new Set(sanitized)]; // make them unique return sanitized; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWQtYXNzZW1ibHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjbG91ZC1hc3NlbWJseS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUE2YUEsNENBSUM7QUFoYkQsNENBQXdEO0FBQ3hELCtCQUErQjtBQUMvQix5Q0FBc0M7QUFDdEMsaUNBQWlDO0FBRWpDLDBFQUErRjtBQUMvRix5RkFBZ0c7QUFDaEcscUNBQXFDO0FBRXJDLElBQVksZ0JBc0JYO0FBdEJELFdBQVksZ0JBQWdCO0lBQzFCOztPQUVHO0lBQ0gsaUNBQWEsQ0FBQTtJQUViOzs7T0FHRztJQUNILHlDQUFxQixDQUFBO0lBRXJCOztPQUVHO0lBQ0gseUNBQXFCLENBQUE7SUFFckI7OztPQUdHO0lBQ0gscUNBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQXRCVyxnQkFBZ0IsZ0NBQWhCLGdCQUFnQixRQXNCM0I7QUFzQkQ7O0dBRUc7QUFDSCxJQUFZLHNCQWVYO0FBZkQsV0FBWSxzQkFBc0I7SUFDaEM7O09BRUc7SUFDSCxtRUFBSSxDQUFBO0lBRUo7O09BRUc7SUFDSCwyRUFBUSxDQUFBO0lBRVI7O09BRUc7SUFDSCwrRUFBVSxDQUFBO0FBQ1osQ0FBQyxFQWZXLHNCQUFzQixzQ0FBdEIsc0JBQXNCLFFBZWpDO0FBa0JEOztHQUVHO0FBQ0gsTUFBYSxhQUFhO0lBUXhCLFlBQTRCLFFBQTZCLEVBQUUsUUFBa0I7UUFBakQsYUFBUSxHQUFSLFFBQVEsQ0FBcUI7UUFDdkQsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO0lBQzNCLENBQUM7SUFFTSxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQXVCLEVBQUUsT0FBNEI7UUFDN0UsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUMxQixNQUFNLGNBQWMsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO1FBQ2xDLE1BQU0sTUFBTSxH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LFFBQWtCO0lBQ2pELElBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyx3QkFBd0I7SUFDekUsU0FBUyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsbUJBQW1CO0lBQ3hELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSAqIGFzIGN4YXBpIGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgeyBTeW50aGVzaXNNZXNzYWdlTGV2ZWwgfSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0ICogYXMgY2hhbGsgZnJvbSAnY2hhbGsnO1xuaW1wb3J0IHsgbWluaW1hdGNoIH0gZnJvbSAnbWluaW1hdGNoJztcbmltcG9ydCAqIGFzIHNlbXZlciBmcm9tICdzZW12ZXInO1xuaW1wb3J0IHsgdHlwZSBTdGFja0RldGFpbHMgfSBmcm9tICcuLi8uLi8uLi8uLi9AYXdzLWNkay90bXAtdG9vbGtpdC1oZWxwZXJzJztcbmltcG9ydCB7IEFzc2VtYmx5RXJyb3IsIFRvb2xraXRFcnJvciB9IGZyb20gJy4uLy4uLy4uLy4uL0Bhd3MtY2RrL3RtcC10b29sa2l0LWhlbHBlcnMvc3JjL2FwaSc7XG5pbXBvcnQgeyBJTywgdHlwZSBJb0hlbHBlciB9IGZyb20gJy4uLy4uLy4uLy4uL0Bhd3MtY2RrL3RtcC10b29sa2l0LWhlbHBlcnMvc3JjL2FwaS9pby9wcml2YXRlJztcbmltcG9ydCB7IGZsYXR0ZW4gfSBmcm9tICcuLi8uLi91dGlsJztcblxuZXhwb3J0IGVudW0gRGVmYXVsdFNlbGVjdGlvbiB7XG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGVtcHR5IHNlbGVjdGlvbiBpbiBjYXNlIHRoZXJlIGFyZSBubyBzZWxlY3RvcnMuXG4gICAqL1xuICBOb25lID0gJ25vbmUnLFxuXG4gIC8qKlxuICAgKiBJZiB0aGUgYXBwIGluY2x1ZGVzIGEgc2luZ2xlIHN0YWNrLCByZXR1cm5zIGl0LiBPdGhlcndpc2UgdGhyb3dzIGFuIGV4Y2VwdGlvbi5cbiAgICogVGhpcyBiZWhhdmlvciBpcyB1c2VkIGJ5IFwiZGVwbG95XCIuXG4gICAqL1xuICBPbmx5U2luZ2xlID0gJ3NpbmdsZScsXG5cbiAgLyoqXG4gICAqIFJldHVybnMgYWxsIHN0YWNrcyBpbiB0aGUgbWFpbiAodG9wIGxldmVsKSBhc3NlbWJseSBvbmx5LlxuICAgKi9cbiAgTWFpbkFzc2VtYmx5ID0gJ21haW4nLFxuXG4gIC8qKlxuICAgKiBJZiBubyBzZWxlY3RvcnMgYXJlIHByb3ZpZGVkLCByZXR1cm5zIGFsbCBzdGFja3MgaW4gdGhlIGFwcCxcbiAgICogaW5jbHVkaW5nIHN0YWNrcyBpbnNpZGUgbmVzdGVkIGFzc2VtYmxpZXMuXG4gICAqL1xuICBBbGxTdGFja3MgPSAnYWxsJyxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZWxlY3RTdGFja3NPcHRpb25zIHtcbiAgLyoqXG4gICAqIEV4dGVuZCB0aGUgc2VsZWN0aW9uIHRvIHVwc3RyZWFkL2Rvd25zdHJlYW0gc3RhY2tzXG4gICAqIEBkZWZhdWx0IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uTm9uZSBvbmx5IHNlbGVjdCB0aGUgc3BlY2lmaWVkIHN0YWNrcy5cbiAgICovXG4gIGV4dGVuZD86IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb247XG5cbiAgLyoqXG4gICAqIFRoZSBiZWhhdmlvciBpZiBubyBzZWxlY3RvcnMgYXJlIHByb3ZpZGVkLlxuICAgKi9cbiAgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGRlcGxveSBpZiB0aGUgYXBwIGNvbnRhaW5zIG5vIHN0YWNrcy5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGlnbm9yZU5vU3RhY2tzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBXaGVuIHNlbGVjdGluZyBzdGFja3MsIHdoYXQgb3RoZXIgc3RhY2tzIHRvIGluY2x1ZGUgYmVjYXVzZSBvZiBkZXBlbmRlbmNpZXNcbiAqL1xuZXhwb3J0IGVudW0gRXh0ZW5kZWRTdGFja1NlbGVjdGlvbiB7XG4gIC8qKlxuICAgKiBEb24ndCBzZWxlY3QgYW55IGV4dHJhIHN0YWNrc1xuICAgKi9cbiAgTm9uZSxcblxuICAvKipcbiAgICogSW5jbHVkZSBzdGFja3MgdGhhdCB0aGlzIHN0YWNrIGRlcGVuZHMgb25cbiAgICovXG4gIFVwc3RyZWFtLFxuXG4gIC8qKlxuICAgKiBJbmNsdWRlIHN0YWNrcyB0aGF0IGRlcGVuZCBvbiB0aGlzIHN0YWNrXG4gICAqL1xuICBEb3duc3RyZWFtLFxufVxuXG4vKipcbiAqIEEgc3BlY2lmaWNhdGlvbiBvZiB3aGljaCBzdGFja3Mgc2hvdWxkIGJlIHNlbGVjdGVkXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhY2tTZWxlY3RvciB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIGFsbCBzdGFja3MgYXQgdGhlIHRvcCBsZXZlbCBhc3NlbWJseSBzaG91bGRcbiAgICogYmUgc2VsZWN0ZWQgYW5kIG5vdGhpbmcgZWxzZVxuICAgKi9cbiAgYWxsVG9wTGV2ZWw/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgcGF0dGVybnMgdG8gbWF0Y2ggdGhlIHN0YWNrIGhpZXJhcmNoaWNhbCBpZHNcbiAgICovXG4gIHBhdHRlcm5zOiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBBIHNpbmdsZSBDbG91ZCBBc3NlbWJseSBhbmQgdGhlIG9wZXJhdGlvbnMgd2UgZG8gb24gaXQgdG8gZGVwbG95IHRoZSBhcnRpZmFjdHMgaW5zaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBDbG91ZEFzc2VtYmx5IHtcbiAgLyoqXG4gICAqIFRoZSBkaXJlY3RvcnkgdGhpcyBDbG91ZEFzc2VtYmx5IHdhcyByZWFkIGZyb21cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkaXJlY3Rvcnk6IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IGlvSGVscGVyOiBJb0hlbHBlcjtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgYXNzZW1ibHk6IGN4YXBpLkNsb3VkQXNzZW1ibHksIGlvSGVscGVyOiBJb0hlbHBlcikge1xuICAgIHRoaXMuZGlyZWN0b3J5ID0gYXNzZW1ibHkuZGlyZWN0b3J5O1xuICAgIHRoaXMuaW9IZWxwZXIgPSBpb0hlbHBlcjtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZWxlY3RTdGFja3Moc2VsZWN0b3I6IFN0YWNrU2VsZWN0b3IsIG9wdGlvbnM6IFNlbGVjdFN0YWNrc09wdGlvbnMpOiBQcm9taXNlPFN0YWNrQ29sbGVjdGlvbj4ge1xuICAgIGNvbnN0IGFzbSA9IHRoaXMuYXNzZW1ibHk7XG4gICAgY29uc3QgdG9wTGV2ZWxTdGFja3MgPSBhc20uc3RhY2tzO1xuICAgIGNvbnN0IHN0YWNrcyA9IHNlbXZlci5tYWpvcihhc20udmVyc2lvbikgPCAxMCA/IGFzbS5zdGFja3MgOiBhc20uc3RhY2tzUmVjdXJzaXZlbHk7XG4gICAgY29uc3QgYWxsVG9wTGV2ZWwgPSBzZWxlY3Rvci5hbGxUb3BMZXZlbCA/PyBmYWxzZTtcbiAgICBjb25zdCBwYXR0ZXJucyA9IHNhbml0aXplUGF0dGVybnMoc2VsZWN0b3IucGF0dGVybnMpO1xuXG4gICAgaWYgKHN0YWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmIChvcHRpb25zLmlnbm9yZU5vU3RhY2tzKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMsIFtdKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ1RoaXMgYXBwIGNvbnRhaW5zIG5vIHN0YWNrcycpO1xuICAgIH1cblxuICAgIGlmIChhbGxUb3BMZXZlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0VG9wTGV2ZWxTdGFja3Moc3RhY2tzLCB0b3BMZXZlbFN0YWNrcywgb3B0aW9ucy5leHRlbmQpO1xuICAgIH0gZWxzZSBpZiAocGF0dGVybnMubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0TWF0Y2hpbmdTdGFja3Moc3RhY2tzLCBwYXR0ZXJucywgb3B0aW9ucy5leHRlbmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5zZWxlY3REZWZhdWx0U3RhY2tzKHN0YWNrcywgdG9wTGV2ZWxTdGFja3MsIG9wdGlvbnMuZGVmYXVsdEJlaGF2aW9yKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbGVjdFRvcExldmVsU3RhY2tzKFxuICAgIHN0YWNrczogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0W10sXG4gICAgdG9wTGV2ZWxTdGFja3M6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdFtdLFxuICAgIGV4dGVuZDogRXh0ZW5kZWRTdGFja1NlbGVjdGlvbiA9IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uTm9uZSxcbiAgKTogUHJvbWlzZTxTdGFja0NvbGxlY3Rpb24+IHtcbiAgICBpZiAodG9wTGV2ZWxTdGFja3MubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuZXh0ZW5kU3RhY2tzKHRvcExldmVsU3RhY2tzLCBzdGFja3MsIGV4dGVuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ05vIHN0YWNrIGZvdW5kIGluIHRoZSBtYWluIGNsb3VkIGFzc2VtYmx5LiBVc2UgXCJsaXN0XCIgdG8gcHJpbnQgbWFuaWZlc3QnKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0TWF0Y2hpbmdTdGFja3MoXG4gICAgc3RhY2tzOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3RbXSxcbiAgICBwYXR0ZXJuczogc3RyaW5nW10sXG4gICAgZXh0ZW5kOiBFeHRlbmRlZFN0YWNrU2VsZWN0aW9uID0gRXh0ZW5kZWRTdGFja1NlbGVjdGlvbi5Ob25lLFxuICApOiBQcm9taXNlPFN0YWNrQ29sbGVjdGlvbj4ge1xuICAgIGNvbnN0IG1hdGNoaW5nUGF0dGVybiA9IChwYXR0ZXJuOiBzdHJpbmcpID0+IChzdGFjazogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0KSA9PiBtaW5pbWF0Y2goc3RhY2suaGllcmFyY2hpY2FsSWQsIHBhdHRlcm4pO1xuICAgIGNvbnN0IG1hdGNoZWRTdGFja3MgPSBmbGF0dGVuKHBhdHRlcm5zLm1hcChwYXR0ZXJuID0+IHN0YWNrcy5maWx0ZXIobWF0Y2hpbmdQYXR0ZXJuKHBhdHRlcm4pKSkpO1xuXG4gICAgcmV0dXJuIHRoaXMuZXh0ZW5kU3RhY2tzKG1hdGNoZWRTdGFja3MsIHN0YWNrcywgZXh0ZW5kKTtcbiAgfVxuXG4gIHByaXZhdGUgc2VsZWN0RGVmYXVsdFN0YWNrcyhcbiAgICBzdGFja3M6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdFtdLFxuICAgIHRvcExldmVsU3RhY2tzOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3RbXSxcbiAgICBkZWZhdWx0U2VsZWN0aW9uOiBEZWZhdWx0U2VsZWN0aW9uLFxuICApIHtcbiAgICBzd2l0Y2ggKGRlZmF1bHRTZWxlY3Rpb24pIHtcbiAgICAgIGNhc2UgRGVmYXVsdFNlbGVjdGlvbi5NYWluQXNzZW1ibHk6XG4gICAgICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMsIHRvcExldmVsU3RhY2tzKTtcbiAgICAgIGNhc2UgRGVmYXVsdFNlbGVjdGlvbi5BbGxTdGFja3M6XG4gICAgICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMsIHN0YWNrcyk7XG4gICAgICBjYXNlIERlZmF1bHRTZWxlY3Rpb24uTm9uZTpcbiAgICAgICAgcmV0dXJuIG5ldyBTdGFja0NvbGxlY3Rpb24odGhpcywgW10pO1xuICAgICAgY2FzZSBEZWZhdWx0U2VsZWN0aW9uLk9ubHlTaW5nbGU6XG4gICAgICAgIGlmICh0b3BMZXZlbFN0YWNrcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFN0YWNrQ29sbGVjdGlvbih0aGlzLCB0b3BMZXZlbFN0YWNrcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignU2luY2UgdGhpcyBhcHAgaW5jbHVkZXMgbW9yZSB0aGFuIGEgc2luZ2xlIHN0YWNrLCBzcGVjaWZ5IHdoaWNoIHN0YWNrcyB0byB1c2UgKHdpbGRjYXJkcyBhcmUgc3VwcG9ydGVkKSBvciBzcGVjaWZ5IGAtLWFsbGBcXG4nICtcbiAgICAgICAgICBgU3RhY2tzOiAke3N0YWNrcy5tYXAoeCA9PiB4LmhpZXJhcmNoaWNhbElkKS5qb2luKCcgwrcgJyl9YCk7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoYGludmFsaWQgZGVmYXVsdCBiZWhhdmlvcjogJHtkZWZhdWx0U2VsZWN0aW9ufWApO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBleHRlbmRTdGFja3MoXG4gICAgbWF0Y2hlZDogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0W10sXG4gICAgYWxsOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3RbXSxcbiAgICBleHRlbmQ6IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24gPSBFeHRlbmRlZFN0YWNrU2VsZWN0aW9uLk5vbmUsXG4gICkge1xuICAgIGNvbnN0IGFsbFN0YWNrcyA9IG5ldyBNYXA8c3RyaW5nLCBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Q+KCk7XG4gICAgZm9yIChjb25zdCBzdGFjayBvZiBhbGwpIHtcbiAgICAgIGFsbFN0YWNrcy5zZXQoc3RhY2suaGllcmFyY2hpY2FsSWQsIHN0YWNrKTtcbiAgICB9XG5cbiAgICBjb25zdCBpbmRleCA9IGluZGV4QnlIaWVyYXJjaGljYWxJZChtYXRjaGVkKTtcblxuICAgIHN3aXRjaCAoZXh0ZW5kKSB7XG4gICAgICBjYXNlIEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uRG93bnN0cmVhbTpcbiAgICAgICAgYXdhaXQgaW5jbHVkZURvd25zdHJlYW1TdGFja3ModGhpcy5pb0hlbHBlciwgaW5kZXgsIGFsbFN0YWNrcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBFeHRlbmRlZFN0YWNrU2VsZWN0aW9uLlVwc3RyZWFtOlxuICAgICAgICBhd2FpdCBpbmNsdWRlVXBzdHJlYW1TdGFja3ModGhpcy5pb0hlbHBlciwgaW5kZXgsIGFsbFN0YWNrcyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIEZpbHRlciBvcmlnaW5hbCBhcnJheSBiZWNhdXNlIGl0IGlzIGluIHRoZSByaWdodCBvcmRlclxuICAgIGNvbnN0IHNlbGVjdGVkTGlzdCA9IGFsbC5maWx0ZXIocyA9PiBpbmRleC5oYXMocy5oaWVyYXJjaGljYWxJZCkpO1xuXG4gICAgcmV0dXJuIG5ldyBTdGFja0NvbGxlY3Rpb24odGhpcywgc2VsZWN0ZWRMaXN0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3QgYSBzaW5nbGUgc3RhY2sgYnkgaXRzIElEXG4gICAqL1xuICBwdWJsaWMgc3RhY2tCeUlkKHN0YWNrSWQ6IHN0cmluZykge1xuICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMsIFt0aGlzLmFzc2VtYmx5LmdldFN0YWNrQXJ0aWZhY3Qoc3RhY2tJZCldKTtcbiAgfVxufVxuXG4vKipcbiAqIEEgY29sbGVjdGlvbiBvZiBzdGFja3MgYW5kIHJlbGF0ZWQgYXJ0aWZhY3RzXG4gKlxuICogSW4gcHJhY3RpY2UsIG5vdCBhbGwgYXJ0aWZhY3RzIGluIHRoZSBDbG91ZEFzc2VtYmx5IGFyZSBjcmVhdGVkIGVxdWFsO1xuICogc3RhY2tzIGNhbiBiZSBzZWxlY3RlZCBpbmRlcGVuZGVudGx5LCBidXQgb3RoZXIgYXJ0aWZhY3RzIHN1Y2ggYXMgYXNzZXRcbiAqIGJ1bmRsZXMgY2Fubm90LlxuICovXG5leHBvcnQgY2xhc3MgU3RhY2tDb2xsZWN0aW9uIHtcbiAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IGFzc2VtYmx5OiBDbG91ZEFzc2VtYmx5LCBwdWJsaWMgcmVhZG9ubHkgc3RhY2tBcnRpZmFjdHM6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdFtdKSB7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHN0YWNrQ291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhY2tBcnRpZmFjdHMubGVuZ3RoO1xuICB9XG5cbiAgcHVibGljIGdldCBmaXJzdFN0YWNrKCkge1xuICAgIGlmICh0aGlzLnN0YWNrQ291bnQgPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCdTdGFja0NvbGxlY3Rpb24gY29udGFpbnMgbm8gc3RhY2sgYXJ0aWZhY3RzICh0cnlpbmcgdG8gYWNjZXNzIHRoZSBmaXJzdCBvbmUpJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN0YWNrQXJ0aWZhY3RzWzBdO1xuICB9XG5cbiAgcHVibGljIGdldCBzdGFja0lkcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhY2tBcnRpZmFjdHMubWFwKHMgPT4gcy5pZCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGhpZXJhcmNoaWNhbElkcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhY2tBcnRpZmFjdHMubWFwKHMgPT4gcy5oaWVyYXJjaGljYWxJZCk7XG4gIH1cblxuICBwdWJsaWMgd2l0aERlcGVuZGVuY2llcygpOiBTdGFja0RldGFpbHNbXSB7XG4gICAgY29uc3QgYWxsRGF0YTogU3RhY2tEZXRhaWxzW10gPSBbXTtcblxuICAgIGZvciAoY29uc3Qgc3RhY2sgb2YgdGhpcy5zdGFja0FydGlmYWN0cykge1xuICAgICAgY29uc3QgZGF0YTogU3RhY2tEZXRhaWxzID0ge1xuICAgICAgICBpZDogc3RhY2suZGlzcGxheU5hbWUgPz8gc3RhY2suaWQsXG4gICAgICAgIG5hbWU6IHN0YWNrLnN0YWNrTmFtZSxcbiAgICAgICAgZW52aXJvbm1lbnQ6IHN0YWNrLmVudmlyb25tZW50LFxuICAgICAgICBkZXBlbmRlbmNpZXM6IFtdLFxuICAgICAgfTtcblxuICAgICAgZm9yIChjb25zdCBkZXBlbmRlbmN5SWQgb2Ygc3RhY2suZGVwZW5kZW5jaWVzLm1hcCh4ID0+IHguaWQpKSB7XG4gICAgICAgIGlmIChkZXBlbmRlbmN5SWQuaW5jbHVkZXMoJy5hc3NldHMnKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGVwU3RhY2sgPSB0aGlzLmFzc2VtYmx5LnN0YWNrQnlJZChkZXBlbmRlbmN5SWQpO1xuXG4gICAgICAgIGlmIChkZXBTdGFjay5maXJzdFN0YWNrLmRlcGVuZGVuY2llcy5maWx0ZXIoKGRlcCkgPT4gIShkZXAuaWQpLmluY2x1ZGVzKCcuYXNzZXRzJykpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IHN0YWNrRGV0YWlsIG9mIGRlcFN0YWNrLndpdGhEZXBlbmRlbmNpZXMoKSkge1xuICAgICAgICAgICAgZGF0YS5kZXBlbmRlbmNpZXMucHVzaCh7XG4gICAgICAgICAgICAgIGlkOiBzdGFja0RldGFpbC5pZCxcbiAgICAgICAgICAgICAgZGVwZW5kZW5jaWVzOiBzdGFja0RldGFpbC5kZXBlbmRlbmNpZXMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGF0YS5kZXBlbmRlbmNpZXMucHVzaCh7XG4gICAgICAgICAgICBpZDogZGVwU3RhY2suZmlyc3RTdGFjay5kaXNwbGF5TmFtZSA/PyBkZXBTdGFjay5maXJzdFN0YWNrLmlkLFxuICAgICAgICAgICAgZGVwZW5kZW5jaWVzOiBbXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhbGxEYXRhLnB1c2goZGF0YSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFsbERhdGE7XG4gIH1cblxuICBwdWJsaWMgcmV2ZXJzZWQoKSB7XG4gICAgY29uc3QgYXJ0cyA9IFsuLi50aGlzLnN0YWNrQXJ0aWZhY3RzXTtcbiAgICBhcnRzLnJldmVyc2UoKTtcbiAgICByZXR1cm4gbmV3IFN0YWNrQ29sbGVjdGlvbih0aGlzLmFzc2VtYmx5LCBhcnRzKTtcbiAgfVxuXG4gIHB1YmxpYyBmaWx0ZXIocHJlZGljYXRlOiAoYXJ0OiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QpID0+IGJvb2xlYW4pOiBTdGFja0NvbGxlY3Rpb24ge1xuICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMuYXNzZW1ibHksIHRoaXMuc3RhY2tBcnRpZmFjdHMuZmlsdGVyKHByZWRpY2F0ZSkpO1xuICB9XG5cbiAgcHVibGljIGNvbmNhdCguLi5vdGhlcnM6IFN0YWNrQ29sbGVjdGlvbltdKTogU3RhY2tDb2xsZWN0aW9uIHtcbiAgICByZXR1cm4gbmV3IFN0YWNrQ29sbGVjdGlvbih0aGlzLmFzc2VtYmx5LCB0aGlzLnN0YWNrQXJ0aWZhY3RzLmNvbmNhdCguLi5vdGhlcnMubWFwKG8gPT4gby5zdGFja0FydGlmYWN0cykpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0cyAnYXdzOmNkazp3YXJuaW5nfGluZm98ZXJyb3InIG1ldGFkYXRhIGVudHJpZXMgZnJvbSB0aGUgc3RhY2sgc3ludGhlc2lzXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdmFsaWRhdGVNZXRhZGF0YShcbiAgICBmYWlsQXQ6ICd3YXJuJyB8ICdlcnJvcicgfCAnbm9uZScgPSAnZXJyb3InLFxuICAgIGxvZ2dlcjogKGxldmVsOiAnaW5mbycgfCAnZXJyb3InIHwgJ3dhcm4nLCBtc2c6IGN4YXBpLlN5bnRoZXNpc01lc3NhZ2UpID0+IFByb21pc2U8dm9pZD4gPSBhc3luYyAoKSA9PiB7XG4gICAgfSxcbiAgKSB7XG4gICAgbGV0IHdhcm5pbmdzID0gZmFsc2U7XG4gICAgbGV0IGVycm9ycyA9IGZhbHNlO1xuXG4gICAgZm9yIChjb25zdCBzdGFjayBvZiB0aGlzLnN0YWNrQXJ0aWZhY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2Ygc3RhY2subWVzc2FnZXMpIHtcbiAgICAgICAgc3dpdGNoIChtZXNzYWdlLmxldmVsKSB7XG4gICAgICAgICAgY2FzZSBTeW50aGVzaXNNZXNzYWdlTGV2ZWwuV0FSTklORzpcbiAgICAgICAgICAgIHdhcm5pbmdzID0gdHJ1ZTtcbiAgICAgICAgICAgIGF3YWl0IGxvZ2dlcignd2FybicsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBTeW50aGVzaXNNZXNzYWdlTGV2ZWwuRVJST1I6XG4gICAgICAgICAgICBlcnJvcnMgPSB0cnVlO1xuICAgICAgICAgICAgYXdhaXQgbG9nZ2VyKCdlcnJvcicsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBTeW50aGVzaXNNZXNzYWdlTGV2ZWwuSU5GTzpcbiAgICAgICAgICAgIGF3YWl0IGxvZ2dlcignaW5mbycsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJyb3JzICYmIGZhaWxBdCAhPSAnbm9uZScpIHtcbiAgICAgIHRocm93IEFzc2VtYmx5RXJyb3Iud2l0aFN0YWNrcygnRm91bmQgZXJyb3JzJywgdGhpcy5zdGFja0FydGlmYWN0cyk7XG4gICAgfVxuXG4gICAgaWYgKHdhcm5pbmdzICYmIGZhaWxBdCA9PT0gJ3dhcm4nKSB7XG4gICAgICB0aHJvdyBBc3NlbWJseUVycm9yLndpdGhTdGFja3MoJ0ZvdW5kIHdhcm5pbmdzICgtLXN0cmljdCBtb2RlKScsIHRoaXMuc3RhY2tBcnRpZmFjdHMpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1ldGFkYXRhTWVzc2FnZU9wdGlvbnMge1xuICAvKipcbiAgICogV2hldGhlciB0byBiZSB2ZXJib3NlXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICB2ZXJib3NlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRG9uJ3Qgc3RvcCBvbiBlcnJvciBtZXRhZGF0YVxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgaWdub3JlRXJyb3JzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVHJlYXQgd2FybmluZ3MgaW4gbWV0YWRhdGEgYXMgZXJyb3JzXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBzdHJpY3Q/OiBib29sZWFuO1xufVxuXG5mdW5jdGlvbiBpbmRleEJ5SGllcmFyY2hpY2FsSWQoc3RhY2tzOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3RbXSk6IE1hcDxzdHJpbmcsIGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdD4ge1xuICBjb25zdCByZXN1bHQgPSBuZXcgTWFwPHN0cmluZywgY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0PigpO1xuXG4gIGZvciAoY29uc3Qgc3RhY2sgb2Ygc3RhY2tzKSB7XG4gICAgcmVzdWx0LnNldChzdGFjay5oaWVyYXJjaGljYWxJZCwgc3RhY2spO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHRyYW5zaXRpdmUgY2xvc3VyZSBvZiBzdGFjayBkZXBlbmRlbnRzLlxuICpcbiAqIE1vZGlmaWVzIGBzZWxlY3RlZFN0YWNrc2AgaW4tcGxhY2UuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGluY2x1ZGVEb3duc3RyZWFtU3RhY2tzKFxuICBpb0hlbHBlcjogSW9IZWxwZXIsXG4gIHNlbGVjdGVkU3RhY2tzOiBNYXA8c3RyaW5nLCBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Q+LFxuICBhbGxTdGFja3M6IE1hcDxzdHJpbmcsIGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdD4sXG4pIHtcbiAgY29uc3QgYWRkZWQgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuXG4gIGxldCBtYWRlUHJvZ3Jlc3M7XG4gIGRvIHtcbiAgICBtYWRlUHJvZ3Jlc3MgPSBmYWxzZTtcblxuICAgIGZvciAoY29uc3QgW2lkLCBzdGFja10gb2YgYWxsU3RhY2tzKSB7XG4gICAgICAvLyBTZWxlY3QgdGhpcyBzdGFjayBpZiBpdCdzIG5vdCBzZWxlY3RlZCB5ZXQgQU5EIGl0IGRlcGVuZHMgb24gYSBzdGFjayB0aGF0J3MgaW4gdGhlIHNlbGVjdGVkIHNldFxuICAgICAgaWYgKCFzZWxlY3RlZFN0YWNrcy5oYXMoaWQpICYmIChzdGFjay5kZXBlbmRlbmNpZXMgfHwgW10pLnNvbWUoZGVwID0+IHNlbGVjdGVkU3RhY2tzLmhhcyhkZXAuaWQpKSkge1xuICAgICAgICBzZWxlY3RlZFN0YWNrcy5zZXQoaWQsIHN0YWNrKTtcbiAgICAgICAgYWRkZWQucHVzaChpZCk7XG4gICAgICAgIG1hZGVQcm9ncmVzcyA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9IHdoaWxlIChtYWRlUHJvZ3Jlc3MpO1xuXG4gIGlmIChhZGRlZC5sZW5ndGggPiAwKSB7XG4gICAgYXdhaXQgaW9IZWxwZXIubm90aWZ5KElPLkRFRkFVTFRfQVNTRU1CTFlfSU5GTy5tc2coYEluY2x1ZGluZyBkZXBlbmRpbmcgc3RhY2tzOiAke2NoYWxrLmJvbGQoYWRkZWQuam9pbignLCAnKSl9YCkpO1xuICB9XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSB0cmFuc2l0aXZlIGNsb3N1cmUgb2Ygc3RhY2sgZGVwZW5kZW5jaWVzLlxuICpcbiAqIE1vZGlmaWVzIGBzZWxlY3RlZFN0YWNrc2AgaW4tcGxhY2UuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGluY2x1ZGVVcHN0cmVhbVN0YWNrcyhcbiAgaW9IZWxwZXI6IElvSGVscGVyLFxuICBzZWxlY3RlZFN0YWNrczogTWFwPHN0cmluZywgY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0PixcbiAgYWxsU3RhY2tzOiBNYXA8c3RyaW5nLCBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Q+LFxuKSB7XG4gIGNvbnN0IGFkZGVkID0gbmV3IEFycmF5PHN0cmluZz4oKTtcbiAgbGV0IG1hZGVQcm9ncmVzcyA9IHRydWU7XG4gIHdoaWxlIChtYWRlUHJvZ3Jlc3MpIHtcbiAgICBtYWRlUHJvZ3Jlc3MgPSBmYWxzZTtcblxuICAgIGZvciAoY29uc3Qgc3RhY2sgb2Ygc2VsZWN0ZWRTdGFja3MudmFsdWVzKCkpIHtcbiAgICAgIC8vIFNlbGVjdCBhbiBhZGRpdGlvbmFsIHN0YWNrIGlmIGl0J3Mgbm90IHNlbGVjdGVkIHlldCBhbmQgYSBkZXBlbmRlbmN5IG9mIGEgc2VsZWN0ZWQgc3RhY2sgKGFuZCBleGlzdHMsIG9idmlvdXNseSlcbiAgICAgIGZvciAoY29uc3QgZGVwZW5kZW5jeUlkIG9mIHN0YWNrLmRlcGVuZGVuY2llcy5tYXAoeCA9PiB4Lm1hbmlmZXN0LmRpc3BsYXlOYW1lID8/IHguaWQpKSB7XG4gICAgICAgIGlmICghc2VsZWN0ZWRTdGFja3MuaGFzKGRlcGVuZGVuY3lJZCkgJiYgYWxsU3RhY2tzLmhhcyhkZXBlbmRlbmN5SWQpKSB7XG4gICAgICAgICAgYWRkZWQucHVzaChkZXBlbmRlbmN5SWQpO1xuICAgICAgICAgIHNlbGVjdGVkU3RhY2tzLnNldChkZXBlbmRlbmN5SWQsIGFsbFN0YWNrcy5nZXQoZGVwZW5kZW5jeUlkKSEpO1xuICAgICAgICAgIG1hZGVQcm9ncmVzcyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoYWRkZWQubGVuZ3RoID4gMCkge1xuICAgIGF3YWl0IGlvSGVscGVyLm5vdGlmeShJTy5ERUZBVUxUX0FTU0VNQkxZX0lORk8ubXNnKGBJbmNsdWRpbmcgZGVwZW5kZW5jeSBzdGFja3M6ICR7Y2hhbGsuYm9sZChhZGRlZC5qb2luKCcsICcpKX1gKSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhbml0aXplUGF0dGVybnMocGF0dGVybnM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICBsZXQgc2FuaXRpemVkID0gcGF0dGVybnMuZmlsdGVyKHMgPT4gcyAhPSBudWxsKTsgLy8gZmlsdGVyIG51bGwvdW5kZWZpbmVkXG4gIHNhbml0aXplZCA9IFsuLi5uZXcgU2V0KHNhbml0aXplZCldOyAvLyBtYWtlIHRoZW0gdW5pcXVlXG4gIHJldHVybiBzYW5pdGl6ZWQ7XG59XG4iXX0=