@qodalis/angular-cli
Version:
A lightweight and flexible command-line interface (CLI) tool designed to streamline workflows and automate tasks for developers.
346 lines • 54.5 kB
JavaScript
import { Inject, Injectable } from '@angular/core';
import { CliForegroundColor, DefaultLibraryAuthor, } from '@qodalis/cli-core';
import { CliProcessorsRegistry_TOKEN } from '../../tokens';
import * as i0 from "@angular/core";
import * as i1 from "../../services/script-loader.service";
import * as i2 from "../../services/cli-package-manager.service";
export class CliPackagesCommandProcessor {
constructor(scriptsLoader, packagesManager, registry) {
this.scriptsLoader = scriptsLoader;
this.packagesManager = packagesManager;
this.registry = registry;
this.command = 'packages';
this.description = 'Manage packages in the cli';
this.author = DefaultLibraryAuthor;
this.version = '1.0.2';
this.processors = [];
this.metadata = {
sealed: true,
icon: '📦',
module: 'system',
};
this.registeredDependencies = [];
const scope = this;
this.processors = [
{
command: 'ls',
description: 'List all packages in the cli',
author: DefaultLibraryAuthor,
async processCommand(_, context) {
const packages = await packagesManager.getPackages();
context.writer.writeln('Packages:');
if (packages.length === 0) {
context.writer.writeInfo('No packages installed');
context.writer.writeInfo("Use 'packages add <package>' to add a package");
return;
}
packages.forEach((pkg) => {
context.writer.writeInfo(`- ${pkg.name}@${pkg.version}`);
});
},
writeDescription(context) {
context.writer.writeln(' packages ls');
},
},
{
command: 'add',
description: 'Add a package to the cli, e.g. packages add guid.',
valueRequired: true,
async processCommand(command, context) {
const packages = command.value.split(' ');
for (const pkg of packages) {
await scope.addPackage(pkg, context);
}
},
writeDescription({ writer }) {
writer.writeInfo("Supoorts multiple packages, e.g. 'packages add guid server-logs'");
writer.writeln(' packages add <package> ' +
writer.wrapInColor('# Add a package', CliForegroundColor.Green));
writer.writeln(' packages add guid');
writer.writeln(' packages add @qodalis/cli-guid');
writer.writeln(' packages add @qodalis/cli-server-logs');
},
},
{
command: 'remove',
description: 'Remove a package from the cli',
valueRequired: true,
async processCommand(command, context) {
const packages = command.value.split(' ');
for (const pkg of packages) {
await scope.removePackage(pkg, context);
}
},
},
{
command: 'update',
description: 'Update a package in the cli to the latest version or update all packages',
allowUnlistedCommands: true,
valueRequired: false,
async processCommand(command, context) {
if (command.value) {
await scope.updatePackage(command.value, context);
}
else {
const packages = await packagesManager.getPackages();
for (const pkg of packages) {
await scope.updatePackage(pkg.name, context);
}
context.writer.writeSuccess('All packages updated');
}
},
writeDescription(context) {
context.writer.writeln(' packages update <package> ' +
context.writer.wrapInColor('# Update a specific package', CliForegroundColor.Green));
context.writer.writeln(' packages update ' +
context.writer.wrapInColor('# Update all packages', CliForegroundColor.Green));
},
},
];
}
async processCommand(command, context) {
await context.executor.showHelp(command, context);
}
writeDescription({ writer }) {
writer.writeln(this.description);
writer.writeInfo('Available packages can be found at https://www.npmjs.com/org/qodalis');
writer.writeln(' packages ls');
writer.writeln(' packages add <package>');
}
async initialize(context) {
const packages = await this.packagesManager.getPackages();
for (const pkg of packages) {
await this.registerPackageDependencies(pkg, context);
await this.scriptsLoader.injectScript(pkg.url);
}
}
async removePackage(name, context) {
context.progressBar.show();
try {
const pkg = await this.packagesManager.removePackage(name);
if (pkg) {
const module = window[pkg.name];
if (module) {
module.processors?.forEach((processor) => {
this.registry.unregisterProcessor(processor);
});
}
}
context.progressBar.complete();
context.writer.writeSuccess(`Package ${pkg.name}@${pkg.version} removed successfully`);
}
catch (e) {
context.progressBar.complete();
context.writer.writeError(e?.toString() || 'Unknown error');
}
}
async addPackage(name, context) {
const { progressBar, writer } = context;
const hasPackage = await this.packagesManager.hasPackage(name);
if (hasPackage) {
writer.writeInfo(`Package ${name} already installed`);
return;
}
progressBar.show();
progressBar.setText(`Fetching package ${name}`);
try {
const promises = [
this.scriptsLoader
.getScript(`https://unpkg.com/${name}` + '/package.json')
.catch((error) => ({
error,
content: null,
xhr: null,
}))
.finally(() => {
progressBar.update(10, {
type: 'increment',
});
}),
];
if (!name.startsWith(this.packagesManager.QODALIS_COMMAND_PREFIX)) {
promises.push(this.scriptsLoader
.getScript(`https://unpkg.com/${this.packagesManager.QODALIS_COMMAND_PREFIX}${name}` +
'/package.json')
.catch((error) => ({
error,
content: null,
xhr: null,
}))
.finally(() => {
progressBar.update(10, {
type: 'increment',
});
}));
}
progressBar.update(10);
const packages = await Promise.all(promises);
if (packages.every((p) => p.error)) {
progressBar.setText('Package not found');
throw packages[0].error;
}
const validResponses = packages
.filter((p) => p.content)
.map((p) => JSON.parse(p.content || '{}'));
progressBar.update(20, {
type: 'increment',
});
progressBar.setText("Checking package's dependencies");
const packgeInfo = validResponses.some((x) => x.name.startsWith(this.packagesManager.QODALIS_COMMAND_PREFIX))
? validResponses.find((x) => x.name.startsWith(this.packagesManager.QODALIS_COMMAND_PREFIX))
: validResponses[0];
const response = await this.scriptsLoader.getScript(`https://unpkg.com/${packgeInfo.name}`, {
onProgress: (progress) => {
context.progressBar.update(progress);
},
});
progressBar.update(20, {
type: 'increment',
});
progressBar.setText('Injecting package');
const pkg = {
name: packgeInfo.name,
version: packgeInfo.version || 'latest',
url: response.xhr.responseURL,
dependencies: packgeInfo.cliDependencies || [],
};
progressBar.update(80);
progressBar.setText('Registering dependencies');
await this.registerPackageDependencies(pkg, context);
progressBar.update(90);
progressBar.setText('Dependencies registered');
if (response.content) {
await this.scriptsLoader.injectBodyScript(response.content);
}
progressBar.update(95);
progressBar.setText('Saving package');
await this.packagesManager.addPackage(pkg);
context.progressBar.complete();
context.writer.writeSuccess(`Package ${packgeInfo.name}@${packgeInfo.version} added successfully`);
}
catch (e) {
context.progressBar.complete();
context.writer.writeError(e?.toString() || 'Unknown error');
}
}
async updatePackage(name, context) {
const { progressBar, writer } = context;
progressBar.show();
try {
progressBar.update(10, {
type: 'increment',
});
progressBar.setText(`Updating package ${name}`);
const currentPackage = await this.packagesManager.getPackage(name);
if (!currentPackage) {
progressBar.complete();
writer.writeError(`Package ${name} not found`);
return;
}
const packageUrl = `https://unpkg.com/${currentPackage.name}`;
const newPackage = await this.scriptsLoader
.getScript(packageUrl + '/package.json')
.then((response) => {
return JSON.parse(response.content || '{}');
});
progressBar.update(20, {
type: 'increment',
});
progressBar.setText(`Checking for updates for package ${currentPackage.name}`);
if (newPackage.version === currentPackage.version) {
context.progressBar.complete();
context.writer.writeInfo(`Package ${currentPackage.name} is already up to date with version ${currentPackage.version}`);
return;
}
const response = await this.scriptsLoader.getScript(packageUrl, {
onProgress: (progress) => {
context.progressBar.update(progress);
},
});
progressBar.update(20, {
type: 'increment',
});
progressBar.setText(`Updating package ${currentPackage.name}`);
const updatedPkg = {
name: newPackage.name,
version: newPackage.version || 'latest',
url: response.xhr.responseURL,
dependencies: newPackage.cliDependencies || [],
};
await this.registerPackageDependencies(updatedPkg, context);
progressBar.update(90);
progressBar.setText(`Injecting package ${currentPackage.name}`);
if (response.content) {
await this.scriptsLoader.injectBodyScript(response.content);
}
await this.packagesManager.updatePackage(updatedPkg);
progressBar.setText(`Package ${currentPackage.name} updated successfully`);
progressBar.complete();
writer.writeSuccess(`Package ${currentPackage.name} updated successfully to version ${newPackage.version} from ${currentPackage.version}`);
}
catch (e) {
progressBar.complete();
writer.writeError(e?.toString() || 'Unknown error');
}
}
async registerPackageDependencies(pkg, { logger }) {
if (pkg.dependencies && pkg.dependencies.length > 0) {
logger.info(`Injecting package ${pkg.name} dependencies`);
for (const dependency of pkg.dependencies) {
if (this.registeredDependencies.includes(dependency.name)) {
logger.info(`Dependency ${dependency.globalName} already registered`);
continue;
}
await this.scriptsLoader.injectScript(dependency.url);
if (dependency.globalName) {
const isAvailable = await this.waitForGlobal(dependency.globalName, 3000);
if (!isAvailable) {
logger.error(`Dependency ${dependency.globalName} not found in global scope within timeout`);
return;
}
else {
logger.info(`Dependency ${dependency.globalName} is available in global scope`);
}
}
this.registeredDependencies.push(dependency.name);
}
}
else {
logger.info(`Package ${pkg.name} has no dependencies`);
}
}
/**
* Waits until a global variable is available on the `window` object.
* @param globalName {string} The name of the global variable to check.
* @param timeout {number} The maximum time to wait in milliseconds.
* @returns {Promise<boolean>} Resolves to `true` if the variable is found, `false` otherwise.
*/
waitForGlobal(globalName, timeout) {
return new Promise((resolve) => {
const interval = 50; // Check every 50ms
let elapsed = 0;
const check = () => {
if (window[globalName]) {
resolve(true);
}
else if (elapsed >= timeout) {
resolve(false);
}
else {
elapsed += interval;
setTimeout(check, interval);
}
};
check();
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliPackagesCommandProcessor, deps: [{ token: i1.ScriptLoaderService }, { token: i2.CliPackageManagerService }, { token: CliProcessorsRegistry_TOKEN }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliPackagesCommandProcessor }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliPackagesCommandProcessor, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: i1.ScriptLoaderService }, { type: i2.CliPackageManagerService }, { type: undefined, decorators: [{
type: Inject,
args: [CliProcessorsRegistry_TOKEN]
}] }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLXBhY2thZ2VzLWNvbW1hbmQtcHJvY2Vzc29yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xpL3NyYy9saWIvY2xpL3Byb2Nlc3NvcnMvc3lzdGVtL2NsaS1wYWNrYWdlcy1jb21tYW5kLXByb2Nlc3Nvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQ0gsa0JBQWtCLEVBRWxCLG9CQUFvQixHQUV2QixNQUFNLG1CQUFtQixDQUFDO0FBVTNCLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7OztBQUczRCxNQUFNLE9BQU8sMkJBQTJCO0lBbUJwQyxZQUNxQixhQUFrQyxFQUNsQyxlQUF5QyxFQUV6QyxRQUFzQztRQUh0QyxrQkFBYSxHQUFiLGFBQWEsQ0FBcUI7UUFDbEMsb0JBQWUsR0FBZixlQUFlLENBQTBCO1FBRXpDLGFBQVEsR0FBUixRQUFRLENBQThCO1FBdEJsRCxZQUFPLEdBQUcsVUFBVSxDQUFDO1FBRTlCLGdCQUFXLEdBQUcsNEJBQTRCLENBQUM7UUFFM0MsV0FBTSxHQUFHLG9CQUFvQixDQUFDO1FBRXJCLFlBQU8sR0FBRyxPQUFPLENBQUM7UUFFbEIsZUFBVSxHQUF3QyxFQUFFLENBQUM7UUFFckQsYUFBUSxHQUFzQztZQUNuRCxNQUFNLEVBQUUsSUFBSTtZQUNaLElBQUksRUFBRSxJQUFJO1lBQ1YsTUFBTSxFQUFFLFFBQVE7U0FDbkIsQ0FBQztRQUVNLDJCQUFzQixHQUFhLEVBQUUsQ0FBQztRQVExQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUM7UUFFbkIsSUFBSSxDQUFDLFVBQVUsR0FBRztZQUNkO2dCQUNJLE9BQU8sRUFBRSxJQUFJO2dCQUNiLFdBQVcsRUFBRSw4QkFBOEI7Z0JBQzNDLE1BQU0sRUFBRSxvQkFBb0I7Z0JBQzVC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LENBQUMsSUFBSSxDQUFDLENBQUM7YUFDckQ7U0FDSjthQUFNO1lBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxJQUFJLHNCQUFzQixDQUFDLENBQUM7U0FDMUQ7SUFDTCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxhQUFhLENBQ2pCLFVBQWtCLEVBQ2xCLE9BQWU7UUFFZixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDM0IsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDLENBQUMsbUJBQW1CO1lBQ3hDLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztZQUVoQixNQUFNLEtBQUssR0FBRyxHQUFHLEVBQUU7Z0JBQ2YsSUFBSyxNQUFjLENBQUMsVUFBVSxDQUFDLEVBQUU7b0JBQzdCLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztpQkFDakI7cUJBQU0sSUFBSSxPQUFPLElBQUksT0FBTyxFQUFFO29CQUMzQixPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ2xCO3FCQUFNO29CQUNILE9BQU8sSUFBSSxRQUFRLENBQUM7b0JBQ3BCLFVBQVUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7aUJBQy9CO1lBQ0wsQ0FBQyxDQUFDO1lBRUYsS0FBSyxFQUFFLENBQUM7UUFDWixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7K0dBcmRRLDJCQUEyQiw2RkFzQnhCLDJCQUEyQjttSEF0QjlCLDJCQUEyQjs7NEZBQTNCLDJCQUEyQjtrQkFEdkMsVUFBVTs7MEJBdUJGLE1BQU07MkJBQUMsMkJBQTJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICAgIENsaUZvcmVncm91bmRDb2xvcixcbiAgICBDbGlQcm9jZXNzb3JNZXRhZGF0YSxcbiAgICBEZWZhdWx0TGlicmFyeUF1dGhvcixcbiAgICBJQ2xpQ29tbWFuZFByb2Nlc3NvclJlZ2lzdHJ5LFxufSBmcm9tICdAcW9kYWxpcy9jbGktY29yZSc7XG5pbXBvcnQge1xuICAgIENsaVByb2Nlc3NDb21tYW5kLFxuICAgIElDbGlDb21tYW5kUHJvY2Vzc29yLFxuICAgIElDbGlFeGVjdXRpb25Db250ZXh0LFxuICAgIElDbGlVbWRNb2R1bGUsXG4gICAgUGFja2FnZSxcbn0gZnJvbSAnQHFvZGFsaXMvY2xpLWNvcmUnO1xuaW1wb3J0IHsgU2NyaXB0TG9hZGVyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3NjcmlwdC1sb2FkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBDbGlQYWNrYWdlTWFuYWdlclNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9jbGktcGFja2FnZS1tYW5hZ2VyLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2xpUHJvY2Vzc29yc1JlZ2lzdHJ5X1RPS0VOIH0gZnJvbSAnLi4vLi4vdG9rZW5zJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENsaVBhY2thZ2VzQ29tbWFuZFByb2Nlc3NvciBpbXBsZW1lbnRzIElDbGlDb21tYW5kUHJvY2Vzc29yIHtcbiAgICByZWFkb25seSBjb21tYW5kID0gJ3BhY2thZ2VzJztcblxuICAgIGRlc2NyaXB0aW9uID0gJ01hbmFnZSBwYWNrYWdlcyBpbiB0aGUgY2xpJztcblxuICAgIGF1dGhvciA9IERlZmF1bHRMaWJyYXJ5QXV0aG9yO1xuXG4gICAgcmVhZG9ubHkgdmVyc2lvbiA9ICcxLjAuMic7XG5cbiAgICByZWFkb25seSBwcm9jZXNzb3JzPzogSUNsaUNvbW1hbmRQcm9jZXNzb3JbXSB8IHVuZGVmaW5lZCA9IFtdO1xuXG4gICAgcmVhZG9ubHkgbWV0YWRhdGE/OiBDbGlQcm9jZXNzb3JNZXRhZGF0YSB8IHVuZGVmaW5lZCA9IHtcbiAgICAgICAgc2VhbGVkOiB0cnVlLFxuICAgICAgICBpY29uOiAn8J+TpicsXG4gICAgICAgIG1vZHVsZTogJ3N5c3RlbScsXG4gICAgfTtcblxuICAgIHByaXZhdGUgcmVnaXN0ZXJlZERlcGVuZGVuY2llczogc3RyaW5nW10gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IHNjcmlwdHNMb2FkZXI6IFNjcmlwdExvYWRlclNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgcGFja2FnZXNNYW5hZ2VyOiBDbGlQYWNrYWdlTWFuYWdlclNlcnZpY2UsXG4gICAgICAgIEBJbmplY3QoQ2xpUHJvY2Vzc29yc1JlZ2lzdHJ5X1RPS0VOKVxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lzdHJ5OiBJQ2xpQ29tbWFuZFByb2Nlc3NvclJlZ2lzdHJ5LFxuICAgICkge1xuICAgICAgICBjb25zdCBzY29wZSA9IHRoaXM7XG5cbiAgICAgICAgdGhpcy5wcm9jZXNzb3JzID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbW1hbmQ6ICdscycsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdMaXN0IGFsbCBwYWNrYWdlcyBpbiB0aGUgY2xpJyxcbiAgICAgICAgICAgICAgICBhdXRob3I6IERlZmF1bHRMaWJyYXJ5QXV0aG9yLFxuICAgICAgICAgICAgICAgIGFzeW5jIHByb2Nlc3NDb21tYW5kKF8sIGNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFja2FnZXMgPSBhd2FpdCBwYWNrYWdlc01hbmFnZXIuZ2V0UGFja2FnZXMoKTtcblxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZWxuKCdQYWNrYWdlczonKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocGFja2FnZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZUluZm8oJ05vIHBhY2thZ2VzIGluc3RhbGxlZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVJbmZvKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiVXNlICdwYWNrYWdlcyBhZGQgPHBhY2thZ2U+JyB0byBhZGQgYSBwYWNrYWdlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcGFja2FnZXMuZm9yRWFjaCgocGtnKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZUluZm8oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYC0gJHtwa2cubmFtZX1AJHtwa2cudmVyc2lvbn1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB3cml0ZURlc2NyaXB0aW9uKGNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbignICBwYWNrYWdlcyBscycpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbW1hbmQ6ICdhZGQnLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAnQWRkIGEgcGFja2FnZSB0byB0aGUgY2xpLCBlLmcuIHBhY2thZ2VzIGFkZCBndWlkLicsXG4gICAgICAgICAgICAgICAgdmFsdWVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhc3luYyBwcm9jZXNzQ29tbWFuZChjb21tYW5kLCBjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhY2thZ2VzID0gY29tbWFuZC52YWx1ZSEuc3BsaXQoJyAnKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBwa2cgb2YgcGFja2FnZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHNjb3BlLmFkZFBhY2thZ2UocGtnLCBjb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgd3JpdGVEZXNjcmlwdGlvbih7IHdyaXRlciB9KSB7XG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZUluZm8oXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlN1cG9vcnRzIG11bHRpcGxlIHBhY2thZ2VzLCBlLmcuICdwYWNrYWdlcyBhZGQgZ3VpZCBzZXJ2ZXItbG9ncydcIixcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlbG4oXG4gICAgICAgICAgICAgICAgICAgICAgICAnICBwYWNrYWdlcyBhZGQgPHBhY2thZ2U+ICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cmFwSW5Db2xvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyMgQWRkIGEgcGFja2FnZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsaUZvcmVncm91bmRDb2xvci5HcmVlbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGVsbignICBwYWNrYWdlcyBhZGQgZ3VpZCcpO1xuICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGVsbignICBwYWNrYWdlcyBhZGQgQHFvZGFsaXMvY2xpLWd1aWQnKTtcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlbG4oJyAgcGFja2FnZXMgYWRkIEBxb2RhbGlzL2NsaS1zZXJ2ZXItbG9ncycpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbW1hbmQ6ICdyZW1vdmUnLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUmVtb3ZlIGEgcGFja2FnZSBmcm9tIHRoZSBjbGknLFxuICAgICAgICAgICAgICAgIHZhbHVlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgYXN5bmMgcHJvY2Vzc0NvbW1hbmQoY29tbWFuZCwgY29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYWNrYWdlcyA9IGNvbW1hbmQudmFsdWUhLnNwbGl0KCcgJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBwa2cgb2YgcGFja2FnZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHNjb3BlLnJlbW92ZVBhY2thZ2UocGtnLCBjb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbW1hbmQ6ICd1cGRhdGUnLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAnVXBkYXRlIGEgcGFja2FnZSBpbiB0aGUgY2xpIHRvIHRoZSBsYXRlc3QgdmVyc2lvbiBvciB1cGRhdGUgYWxsIHBhY2thZ2VzJyxcbiAgICAgICAgICAgICAgICBhbGxvd1VubGlzdGVkQ29tbWFuZHM6IHRydWUsXG4gICAgICAgICAgICAgICAgdmFsdWVSZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgYXN5bmMgcHJvY2Vzc0NvbW1hbmQoY29tbWFuZCwgY29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWFuZC52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgc2NvcGUudXBkYXRlUGFja2FnZShjb21tYW5kLnZhbHVlISwgY29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYWNrYWdlcyA9IGF3YWl0IHBhY2thZ2VzTWFuYWdlci5nZXRQYWNrYWdlcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBwa2cgb2YgcGFja2FnZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBzY29wZS51cGRhdGVQYWNrYWdlKHBrZy5uYW1lLCBjb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVTdWNjZXNzKCdBbGwgcGFja2FnZXMgdXBkYXRlZCcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB3cml0ZURlc2NyaXB0aW9uKGNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbihcbiAgICAgICAgICAgICAgICAgICAgICAgICcgIHBhY2thZ2VzIHVwZGF0ZSA8cGFja2FnZT4gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JhcEluQ29sb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcjIFVwZGF0ZSBhIHNwZWNpZmljIHBhY2thZ2UnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGlGb3JlZ3JvdW5kQ29sb3IuR3JlZW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbihcbiAgICAgICAgICAgICAgICAgICAgICAgICcgIHBhY2thZ2VzIHVwZGF0ZSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cmFwSW5Db2xvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyMgVXBkYXRlIGFsbCBwYWNrYWdlcycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsaUZvcmVncm91bmRDb2xvci5HcmVlbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgIH1cblxuICAgIGFzeW5jIHByb2Nlc3NDb21tYW5kKFxuICAgICAgICBjb21tYW5kOiBDbGlQcm9jZXNzQ29tbWFuZCxcbiAgICAgICAgY29udGV4dDogSUNsaUV4ZWN1dGlvbkNvbnRleHQsXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IGNvbnRleHQuZXhlY3V0b3Iuc2hvd0hlbHAoY29tbWFuZCwgY29udGV4dCk7XG4gICAgfVxuXG4gICAgd3JpdGVEZXNjcmlwdGlvbj8oeyB3cml0ZXIgfTogSUNsaUV4ZWN1dGlvbkNvbnRleHQpOiB2b2lkIHtcbiAgICAgICAgd3JpdGVyLndyaXRlbG4odGhpcy5kZXNjcmlwdGlvbik7XG5cbiAgICAgICAgd3JpdGVyLndyaXRlSW5mbyhcbiAgICAgICAgICAgICdBdmFpbGFibGUgcGFja2FnZXMgY2FuIGJlIGZvdW5kIGF0IGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9vcmcvcW9kYWxpcycsXG4gICAgICAgICk7XG5cbiAgICAgICAgd3JpdGVyLndyaXRlbG4oJyAgcGFja2FnZXMgbHMnKTtcbiAgICAgICAgd3JpdGVyLndyaXRlbG4oJyAgcGFja2FnZXMgYWRkIDxwYWNrYWdlPicpO1xuICAgIH1cblxuICAgIGFzeW5jIGluaXRpYWxpemUoY29udGV4dDogSUNsaUV4ZWN1dGlvbkNvbnRleHQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgcGFja2FnZXMgPSBhd2FpdCB0aGlzLnBhY2thZ2VzTWFuYWdlci5nZXRQYWNrYWdlcygpO1xuXG4gICAgICAgIGZvciAoY29uc3QgcGtnIG9mIHBhY2thZ2VzKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyUGFja2FnZURlcGVuZGVuY2llcyhwa2csIGNvbnRleHQpO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNjcmlwdHNMb2FkZXIuaW5qZWN0U2NyaXB0KHBrZy51cmwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZW1vdmVQYWNrYWdlKG5hbWU6IHN0cmluZywgY29udGV4dDogSUNsaUV4ZWN1dGlvbkNvbnRleHQpIHtcbiAgICAgICAgY29udGV4dC5wcm9ncmVzc0Jhci5zaG93KCk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHBrZyA9IGF3YWl0IHRoaXMucGFja2FnZXNNYW5hZ2VyLnJlbW92ZVBhY2thZ2UobmFtZSk7XG5cbiAgICAgICAgICAgIGlmIChwa2cpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBtb2R1bGUgPSAod2luZG93IGFzIGFueSlbcGtnLm5hbWVdIGFzIElDbGlVbWRNb2R1bGU7XG4gICAgICAgICAgICAgICAgaWYgKG1vZHVsZSkge1xuICAgICAgICAgICAgICAgICAgICBtb2R1bGUucHJvY2Vzc29ycz8uZm9yRWFjaCgocHJvY2Vzc29yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZ2lzdHJ5LnVucmVnaXN0ZXJQcm9jZXNzb3IocHJvY2Vzc29yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb250ZXh0LnByb2dyZXNzQmFyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZVN1Y2Nlc3MoXG4gICAgICAgICAgICAgICAgYFBhY2thZ2UgJHtwa2cubmFtZX1AJHtwa2cudmVyc2lvbn0gcmVtb3ZlZCBzdWNjZXNzZnVsbHlgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29udGV4dC5wcm9ncmVzc0Jhci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVFcnJvcihlPy50b1N0cmluZygpIHx8ICdVbmtub3duIGVycm9yJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGFkZFBhY2thZ2UobmFtZTogc3RyaW5nLCBjb250ZXh0OiBJQ2xpRXhlY3V0aW9uQ29udGV4dCkge1xuICAgICAgICBjb25zdCB7IHByb2dyZXNzQmFyLCB3cml0ZXIgfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgY29uc3QgaGFzUGFja2FnZSA9IGF3YWl0IHRoaXMucGFja2FnZXNNYW5hZ2VyLmhhc1BhY2thZ2UobmFtZSk7XG4gICAgICAgIGlmIChoYXNQYWNrYWdlKSB7XG4gICAgICAgICAgICB3cml0ZXIud3JpdGVJbmZvKGBQYWNrYWdlICR7bmFtZX0gYWxyZWFkeSBpbnN0YWxsZWRgKTtcblxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJvZ3Jlc3NCYXIuc2hvdygpO1xuICAgICAgICBwcm9ncmVzc0Jhci5zZXRUZXh0KGBGZXRjaGluZyBwYWNrYWdlICR7bmFtZX1gKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXG4gICAgICAgICAgICAgICAgdGhpcy5zY3JpcHRzTG9hZGVyXG4gICAgICAgICAgICAgICAgICAgIC5nZXRTY3JpcHQoYGh0dHBzOi8vdW5wa2cuY29tLyR7bmFtZX1gICsgJy9wYWNrYWdlLmpzb24nKVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgeGhyOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICB9KSlcbiAgICAgICAgICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3NCYXIudXBkYXRlKDEwLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2luY3JlbWVudCcsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBdO1xuXG4gICAgICAgICAgICBpZiAoIW5hbWUuc3RhcnRzV2l0aCh0aGlzLnBhY2thZ2VzTWFuYWdlci5RT0RBTElTX0NPTU1BTkRfUFJFRklYKSkge1xuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2NyaXB0c0xvYWRlclxuICAgICAgICAgICAgICAgICAgICAgICAgLmdldFNjcmlwdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgaHR0cHM6Ly91bnBrZy5jb20vJHt0aGlzLnBhY2thZ2VzTWFuYWdlci5RT0RBTElTX0NPTU1BTkRfUFJFRklYfSR7bmFtZX1gICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJy9wYWNrYWdlLmpzb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhocjogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyZXNzQmFyLnVwZGF0ZSgxMCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnaW5jcmVtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHByb2dyZXNzQmFyLnVwZGF0ZSgxMCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhY2thZ2VzID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuXG4gICAgICAgICAgICBpZiAocGFja2FnZXMuZXZlcnkoKHApID0+IHAuZXJyb3IpKSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NCYXIuc2V0VGV4dCgnUGFja2FnZSBub3QgZm91bmQnKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBwYWNrYWdlc1swXS5lcnJvcjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdmFsaWRSZXNwb25zZXMgPSBwYWNrYWdlc1xuICAgICAgICAgICAgICAgIC5maWx0ZXIoKHApID0+IHAuY29udGVudClcbiAgICAgICAgICAgICAgICAubWFwKChwKSA9PiBKU09OLnBhcnNlKHAuY29udGVudCB8fCAne30nKSk7XG5cbiAgICAgICAgICAgIHByb2dyZXNzQmFyLnVwZGF0ZSgyMCwge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdpbmNyZW1lbnQnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwcm9ncmVzc0Jhci5zZXRUZXh0KFwiQ2hlY2tpbmcgcGFja2FnZSdzIGRlcGVuZGVuY2llc1wiKTtcblxuICAgICAgICAgICAgY29uc3QgcGFja2dlSW5mbyA9IHZhbGlkUmVzcG9uc2VzLnNvbWUoKHgpID0+XG4gICAgICAgICAgICAgICAgeC5uYW1lLnN0YXJ0c1dpdGgodGhpcy5wYWNrYWdlc01hbmFnZXIuUU9EQUxJU19DT01NQU5EX1BSRUZJWCksXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgPyB2YWxpZFJlc3BvbnNlcy5maW5kKCh4KSA9PlxuICAgICAgICAgICAgICAgICAgICAgIHgubmFtZS5zdGFydHNXaXRoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBhY2thZ2VzTWFuYWdlci5RT0RBTElTX0NPTU1BTkRfUFJFRklYLFxuICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgOiB2YWxpZFJlc3BvbnNlc1swXTtcblxuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNjcmlwdHNMb2FkZXIuZ2V0U2NyaXB0KFxuICAgICAgICAgICAgICAgIGBodHRwczovL3VucGtnLmNvbS8ke3BhY2tnZUluZm8ubmFtZX1gLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb25Qcm9ncmVzczogKHByb2dyZXNzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnByb2dyZXNzQmFyLnVwZGF0ZShwcm9ncmVzcyk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHByb2dyZXNzQmFyLnVwZGF0ZSgyMCwge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdpbmNyZW1lbnQnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwcm9ncmVzc0Jhci5zZXRUZXh0KCdJbmplY3RpbmcgcGFja2FnZScpO1xuXG4gICAgICAgICAgICBjb25zdCBwa2c6IFBhY2thZ2UgPSB7XG4gICAgICAgICAgICAgICAgbmFtZTogcGFja2dlSW5mby5uYW1lLFxuICAgICAgICAgICAgICAgIHZlcnNpb246IHBhY2tnZUluZm8udmVyc2lvbiB8fCAnbGF0ZXN0JyxcbiAgICAgICAgICAgICAgICB1cmw6IHJlc3BvbnNlLnhoci5yZXNwb25zZVVSTCxcbiAgICAgICAgICAgICAgICBkZXBlbmRlbmNpZXM6IHBhY2tnZUluZm8uY2xpRGVwZW5kZW5jaWVzIHx8IFtdLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcHJvZ3Jlc3NCYXIudXBkYXRlKDgwKTtcbiAgICAgICAgICAgIHByb2dyZXNzQmFyLnNldFRleHQoJ1JlZ2lzdGVyaW5nIGRlcGVuZGVuY2llcycpO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyUGFja2FnZURlcGVuZGVuY2llcyhwa2csIGNvbnRleHQpO1xuXG4gICAgICAgICAgICBwcm9ncmVzc0Jhci51cGRhdGUoOTApO1xuICAgICAgICAgICAgcHJvZ3Jlc3NCYXIuc2V0VGV4dCgnRGVwZW5kZW5jaWVzIHJlZ2lzdGVyZWQnKTtcblxuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmNvbnRlbnQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNjcmlwdHNMb2FkZXIuaW5qZWN0Qm9keVNjcmlwdChyZXNwb25zZS5jb250ZW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHJvZ3Jlc3NCYXIudXBkYXRlKDk1KTtcbiAgICAgICAgICAgIHByb2dyZXNzQmFyLnNldFRleHQoJ1NhdmluZyBwYWNrYWdlJyk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGFja2FnZXNNYW5hZ2VyLmFkZFBhY2thZ2UocGtnKTtcblxuICAgICAgICAgICAgY29udGV4dC5wcm9ncmVzc0Jhci5jb21wbGV0ZSgpO1xuXG4gICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZVN1Y2Nlc3MoXG4gICAgICAgICAgICAgICAgYFBhY2thZ2UgJHtwYWNrZ2VJbmZvLm5hbWV9QCR7cGFja2dlSW5mby52ZXJzaW9ufSBhZGRlZCBzdWNjZXNzZnVsbHlgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29udGV4dC5wcm9ncmVzc0Jhci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVFcnJvcihlPy50b1N0cmluZygpIHx8ICdVbmtub3duIGVycm9yJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHVwZGF0ZVBhY2thZ2UoXG4gICAgICAgIG5hbWU6IHN0cmluZyxcbiAgICAgICAgY29udGV4dDogSUNsaUV4ZWN1dGlvbkNvbnRleHQsXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHsgcHJvZ3Jlc3NCYXIsIHdyaXRlciB9ID0gY29udGV4dDtcblxuICAgICAgICBwcm9ncmVzc0Jhci5zaG93KCk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHByb2dyZXNzQmFyLnVwZGF0ZSgxMCwge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdpbmNyZW1lbnQnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwcm9ncmVzc0Jhci5zZXRUZXh0KGBVcGRhdGluZyBwYWNrYWdlICR7bmFtZX1gKTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRQYWNrYWdlID0gYXdhaXQgdGhpcy5wYWNrYWdlc01hbmFnZXIuZ2V0UGFja2FnZShuYW1lKTtcblxuICAgICAgICAgICAgaWYgKCFjdXJyZW50UGFja2FnZSkge1xuICAgICAgICAgICAgICAgIHByb2dyZXNzQmFyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlRXJyb3IoYFBhY2thZ2UgJHtuYW1lfSBub3QgZm91bmRgKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHBhY2thZ2VVcmwgPSBgaHR0cHM6Ly91bnBrZy5jb20vJHtjdXJyZW50UGFja2FnZS5uYW1lfWA7XG5cbiAgICAgICAgICAgIGNvbnN0IG5ld1BhY2thZ2UgPSBhd2FpdCB0aGlzLnNjcmlwdHNMb2FkZXJcbiAgICAgICAgICAgICAgICAuZ2V0U2NyaXB0KHBhY2thZ2VVcmwgKyAnL3BhY2thZ2UuanNvbicpXG4gICAgICAgICAgICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3BvbnNlLmNvbnRlbnQgfHwgJ3t9Jyk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHByb2dyZXNzQmFyLnVwZGF0ZSgyMCwge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdpbmNyZW1lbnQnLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHByb2dyZXNzQmFyLnNldFRleHQoXG4gICAgICAgICAgICAgICAgYENoZWNraW5nIGZvciB1cGRhdGVzIGZvciBwYWNrYWdlICR7Y3VycmVudFBhY2thZ2UubmFtZX1gLFxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgaWYgKG5ld1BhY2thZ2UudmVyc2lvbiA9PT0gY3VycmVudFBhY2thZ2UudmVyc2lvbikge1xuICAgICAgICAgICAgICAgIGNvbnRleHQucHJvZ3Jlc3NCYXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZUluZm8oXG4gICAgICAgICAgICAgICAgICAgIGBQYWNrYWdlICR7Y3VycmVudFBhY2thZ2UubmFtZX0gaXMgYWxyZWFkeSB1cCB0byBkYXRlIHdpdGggdmVyc2lvbiAke2N1cnJlbnRQYWNrYWdlLnZlcnNpb259YCxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNjcmlwdHNMb2FkZXIuZ2V0U2NyaXB0KHBhY2thZ2VVcmwsIHtcbiAgICAgICAgICAgICAgICBvblByb2dyZXNzOiAocHJvZ3Jlc3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5wcm9ncmVzc0Jhci51cGRhdGUocHJvZ3Jlc3MpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcHJvZ3Jlc3NCYXIudXBkYXRlKDIwLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2luY3JlbWVudCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHByb2dyZXNzQmFyLnNldFRleHQoYFVwZGF0aW5nIHBhY2thZ2UgJHtjdXJyZW50UGFja2FnZS5uYW1lfWApO1xuXG4gICAgICAgICAgICBjb25zdCB1cGRhdGVkUGtnOiBQYWNrYWdlID0ge1xuICAgICAgICAgICAgICAgIG5hbWU6IG5ld1BhY2thZ2UubmFtZSxcbiAgICAgICAgICAgICAgICB2ZXJzaW9uOiBuZXdQYWNrYWdlLnZlcnNpb24gfHwgJ2xhdGVzdCcsXG4gICAgICAgICAgICAgICAgdXJsOiByZXNwb25zZS54aHIucmVzcG9uc2VVUkwsXG4gICAgICAgICAgICAgICAgZGVwZW5kZW5jaWVzOiBuZXdQYWNrYWdlLmNsaURlcGVuZGVuY2llcyB8fCBbXSxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJQYWNrYWdlRGVwZW5kZW5jaWVzKHVwZGF0ZWRQa2csIGNvbnRleHQpO1xuXG4gICAgICAgICAgICBwcm9ncmVzc0Jhci51cGRhdGUoOTApO1xuICAgICAgICAgICAgcHJvZ3Jlc3NCYXIuc2V0VGV4dChgSW5qZWN0aW5nIHBhY2thZ2UgJHtjdXJyZW50UGFja2FnZS5uYW1lfWApO1xuXG4gICAgICAgICAgICBpZiAocmVzcG9uc2UuY29udGVudCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc2NyaXB0c0xvYWRlci5pbmplY3RCb2R5U2NyaXB0KHJlc3BvbnNlLmNvbnRlbnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBhY2thZ2VzTWFuYWdlci51cGRhdGVQYWNrYWdlKHVwZGF0ZWRQa2cpO1xuXG4gICAgICAgICAgICBwcm9ncmVzc0Jhci5zZXRUZXh0KFxuICAgICAgICAgICAgICAgIGBQYWNrYWdlICR7Y3VycmVudFBhY2thZ2UubmFtZX0gdXBkYXRlZCBzdWNjZXNzZnVsbHlgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHByb2dyZXNzQmFyLmNvbXBsZXRlKCk7XG5cbiAgICAgICAgICAgIHdyaXRlci53cml0ZVN1Y2Nlc3MoXG4gICAgICAgICAgICAgICAgYFBhY2thZ2UgJHtjdXJyZW50UGFja2FnZS5uYW1lfSB1cGRhdGVkIHN1Y2Nlc3NmdWxseSB0byB2ZXJzaW9uICR7bmV3UGFja2FnZS52ZXJzaW9ufSBmcm9tICR7Y3VycmVudFBhY2thZ2UudmVyc2lvbn1gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcHJvZ3Jlc3NCYXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgIHdyaXRlci53cml0ZUVycm9yKGU/LnRvU3RyaW5nKCkgfHwgJ1Vua25vd24gZXJyb3InKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVnaXN0ZXJQYWNrYWdlRGVwZW5kZW5jaWVzKFxuICAgICAgICBwa2c6IFBhY2thZ2UsXG4gICAgICAgIHsgbG9nZ2VyIH06IElDbGlFeGVjdXRpb25Db250ZXh0LFxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAocGtnLmRlcGVuZGVuY2llcyAmJiBwa2cuZGVwZW5kZW5jaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBJbmplY3RpbmcgcGFja2FnZSAke3BrZy5uYW1lfSBkZXBlbmRlbmNpZXNgKTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBkZXBlbmRlbmN5IG9mIHBrZy5kZXBlbmRlbmNpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5yZWdpc3RlcmVkRGVwZW5kZW5jaWVzLmluY2x1ZGVzKGRlcGVuZGVuY3kubmFtZSEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAgICAgICAgICAgYERlcGVuZGVuY3kgJHtkZXBlbmRlbmN5Lmdsb2JhbE5hbWV9IGFscmVhZHkgcmVnaXN0ZXJlZGAsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc2NyaXB0c0xvYWRlci5pbmplY3RTY3JpcHQoZGVwZW5kZW5jeS51cmwpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGRlcGVuZGVuY3kuZ2xvYmFsTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpc0F2YWlsYWJsZSA9IGF3YWl0IHRoaXMud2FpdEZvckdsb2JhbChcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY3kuZ2xvYmFsTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIDMwMDAsXG4gICAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0F2YWlsYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBEZXBlbmRlbmN5ICR7ZGVwZW5kZW5jeS5nbG9iYWxOYW1lfSBub3QgZm91bmQgaW4gZ2xvYmFsIHNjb3BlIHdpdGhpbiB0aW1lb3V0YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBEZXBlbmRlbmN5ICR7ZGVwZW5kZW5jeS5nbG9iYWxOYW1lfSBpcyBhdmFpbGFibGUgaW4gZ2xvYmFsIHNjb3BlYCxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJlZ2lzdGVyZWREZXBlbmRlbmNpZXMucHVzaChkZXBlbmRlbmN5Lm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYFBhY2thZ2UgJHtwa2cubmFtZX0gaGFzIG5vIGRlcGVuZGVuY2llc2ApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2FpdHMgdW50aWwgYSBnbG9iYWwgdmFyaWFibGUgaXMgYXZhaWxhYmxlIG9uIHRoZSBgd2luZG93YCBvYmplY3QuXG4gICAgICogQHBhcmFtIGdsb2JhbE5hbWUge3N0cmluZ30gVGhlIG5hbWUgb2YgdGhlIGdsb2JhbCB2YXJpYWJsZSB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0gdGltZW91dCB7bnVtYmVyfSBUaGUgbWF4aW11bSB0aW1lIHRvIHdhaXQgaW4gbWlsbGlzZWNvbmRzLlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSBSZXNvbHZlcyB0byBgdHJ1ZWAgaWYgdGhlIHZhcmlhYmxlIGlzIGZvdW5kLCBgZmFsc2VgIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHdhaXRGb3JHbG9iYWwoXG4gICAgICAgIGdsb2JhbE5hbWU6IHN0cmluZyxcbiAgICAgICAgdGltZW91dDogbnVtYmVyLFxuICAgICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGludGVydmFsID0gNTA7IC8vIENoZWNrIGV2ZXJ5IDUwbXNcbiAgICAgICAgICAgIGxldCBlbGFwc2VkID0gMDtcblxuICAgICAgICAgICAgY29uc3QgY2hlY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCh3aW5kb3cgYXMgYW55KVtnbG9iYWxOYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZWxhcHNlZCA+PSB0aW1lb3V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVsYXBzZWQgKz0gaW50ZXJ2YWw7XG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoY2hlY2ssIGludGVydmFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjaGVjaygpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iXX0=