UNPKG

@aws/pdk

Version:

All documentation is located at: https://aws.github.io/aws-pdk

376 lines 55.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.NxConfigurator = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); /*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ const path = require("path"); const projen_1 = require("projen"); const java_1 = require("projen/lib/java"); const javascript_1 = require("projen/lib/javascript"); const python_1 = require("projen/lib/python"); const nx_project_1 = require("./nx-project"); const nx_workspace_1 = require("./nx-workspace"); const utils_1 = require("../utils"); const DEFAULT_PYTHON_VERSION = "3"; const DEFAULT_LICENSE = "Apache-2.0"; /** * Configues common NX related tasks and methods. */ class NxConfigurator extends projen_1.Component { constructor(project, options) { super(project); this.nxPlugins = {}; project.addGitIgnore(".nx/*"); project.addGitIgnore("!.nx/plugins"); project.addTask("run-many", { receiveArgs: true, exec: utils_1.NodePackageUtils.command.exec(utils_1.NodePackageUtils.getNodePackageManager(this.project, javascript_1.NodePackageManager.NPM), "nx", "run-many"), description: "Run task against multiple workspace projects", }); project.addTask("graph", { receiveArgs: true, exec: utils_1.NodePackageUtils.command.exec(utils_1.NodePackageUtils.getNodePackageManager(this.project, javascript_1.NodePackageManager.NPM), "nx", "graph"), description: "Generate dependency graph for monorepo", }); this.licenseOptions = options?.licenseOptions; this.nx = nx_workspace_1.NxWorkspace.of(project) || new nx_workspace_1.NxWorkspace(project); this.nx.affected.defaultBase = options?.defaultReleaseBranch ?? "mainline"; } patchPoetryEnv(project) { // Since the root monorepo is a poetry project and sets the VIRTUAL_ENV, and poetry env info -p will print // the virtual env set in the VIRTUAL_ENV variable if set, we need to unset it to ensure the local project's // env is used. if (utils_1.ProjectUtils.isNamedInstanceOf(project.depsManager, python_1.Poetry)) { ["install", "install:ci"].forEach((t) => { const task = project.tasks.tryFind(t); // Setup env const createVenvCmd = "poetry env use python$PYTHON_VERSION"; !task?.steps.find((s) => s.exec === createVenvCmd) && task?.prependExec(createVenvCmd); // Ensure the projen & pdk bins are removed from the venv as we always want to use the npx variant const removeBinsCmd = "rm -f `poetry env info -p`/bin/projen `poetry env info -p`/bin/pdk"; !task?.steps.find((s) => s.exec === removeBinsCmd) && task?.exec(removeBinsCmd); const pythonVersion = project.deps.tryGetDependency("python")?.version; task.env("PYTHON_VERSION", pythonVersion && !pythonVersion?.startsWith("^") ? pythonVersion : `$(pyenv latest ${pythonVersion?.substring(1).split(".")[0] || DEFAULT_PYTHON_VERSION} | cut -d '.' -f 1,2 || echo '')`); }); project.tasks.addEnvironment("VIRTUAL_ENV", "$(env -u VIRTUAL_ENV poetry env info -p || echo '')"); project.tasks.addEnvironment("PATH", "$(echo $(env -u VIRTUAL_ENV poetry env info -p || echo '')/bin:$PATH)"); } } patchPythonProjects(projects) { projects.forEach((p) => { if (utils_1.ProjectUtils.isNamedInstanceOf(p, python_1.PythonProject)) { this.patchPoetryEnv(p); } this.patchPythonProjects(p.subprojects); }); } /** * Overrides "build" related project tasks (build, compile, test, etc.) with `npx nx run-many` format. * @param task - The task or task name to override * @param options - Nx run-many options * @param overrideOptions - Options for overriding the task * @returns - The task that was overridden * @internal */ _overrideNxBuildTask(task, options, overrideOptions) { if (typeof task === "string") { task = this.project.tasks.tryFind(task); } if (task == null) { return; } if (overrideOptions?.force) { // @ts-ignore - private property task._locked = false; } task.reset(this.execNxRunManyCommand(options), { receiveArgs: true, }); task.description += " for all affected projects"; if (overrideOptions?.disableReset) { // Prevent any further resets of the task to force it to remain as the overridden nx build task task.reset = () => { }; } return task; } /** * Adds a command to upgrade all python subprojects to the given task * @param monorepo the monorepo project * @param task the task to add the command to * @internal */ _configurePythonSubprojectUpgradeDeps(monorepo, task) { // Upgrade deps for const pythonSubprojects = monorepo.subprojects.filter((p) => utils_1.ProjectUtils.isNamedInstanceOf(p, python_1.PythonProject)); if (pythonSubprojects.length > 0) { task.exec(this.execNxRunManyCommand({ target: "install", // TODO: remove in favour of the upgrade task if ever implemented for python projects: pythonSubprojects.map((p) => p.name), }), { receiveArgs: true }); } } /** * Returns the install task or creates one with nx installation command added. * * Note: this should only be called from non-node projects * * @param nxPlugins additional plugins to install * @returns install task */ ensureNxInstallTask(nxPlugins) { this.nxPlugins = nxPlugins; const installTask = this.project.tasks.tryFind("install") ?? this.project.addTask("install"); installTask.exec("pnpm i --no-frozen-lockfile"); (this.project.tasks.tryFind("install:ci") ?? this.project.addTask("install:ci")).exec("pnpm i --frozen-lockfile"); return installTask; } /** * Helper to format `npx nx run-many ...` style command execution in package manager. * @param options */ execNxRunManyCommand(options) { return utils_1.NodePackageUtils.command.exec(utils_1.NodePackageUtils.getNodePackageManager(this.project, javascript_1.NodePackageManager.NPM), ...this.composeNxRunManyCommand(options)); } /** * Helper to format `npx nx run-many ...` style command * @param options */ composeNxRunManyCommand(options) { const args = []; if (options.configuration) { args.push(`--configuration=${options.configuration}`); } if (options.runner) { args.push(`--runner=${options.runner}`); } if (options.parallel) { args.push(`--parallel=${options.parallel}`); } if (options.skipCache) { args.push("--skip-nx-cache"); } if (options.ignoreCycles) { args.push("--nx-ignore-cycles"); } if (options.noBail !== true) { args.push("--nx-bail"); } if (options.projects && options.projects.length) { args.push(`--projects=${options.projects.join(",")}`); } if (options.exclude) { args.push(`--exclude=${options.exclude}`); } if (options.verbose) { args.push("--verbose"); } return [ "nx", "run-many", `--target=${options.target}`, `--output-style=${options.outputStyle || "stream"}`, ...args, ]; } /** * Add project task that executes `npx nx run-many ...` style command. */ addNxRunManyTask(name, options) { return this.project.addTask(name, { receiveArgs: true, exec: this.execNxRunManyCommand(options), }); } /** * Create an implicit dependency between two Projects. This is typically * used in polygot repos where a Typescript project wants a build dependency * on a Python project as an example. * * @param dependent project you want to have the dependency. * @param dependee project you wish to depend on. * @throws error if this is called on a dependent which does not have a NXProject component attached. */ addImplicitDependency(dependent, dependee) { nx_project_1.NxProject.ensure(dependent).addImplicitDependency(dependee); } /** * Adds a dependency between two Java Projects in the monorepo. * @param dependent project you want to have the dependency * @param dependee project you wish to depend on */ addJavaDependency(dependent, dependee) { nx_project_1.NxProject.ensure(dependent).addJavaDependency(dependee); } /** * Adds a dependency between two Python Projects in the monorepo. The dependent must have Poetry enabled. * @param dependent project you want to have the dependency (must be a Poetry Python Project) * @param dependee project you wish to depend on * @throws error if the dependent does not have Poetry enabled */ addPythonPoetryDependency(dependent, dependee) { nx_project_1.NxProject.ensure(dependent).addPythonPoetryDependency(dependee); } /** * Ensures that all non-root projects have NxProject applied. * @internal */ _ensureNxProjectGraph() { function _ensure(_project) { if (_project.root === _project) return; nx_project_1.NxProject.ensure(_project); _project.subprojects.forEach((p) => { _ensure(p); }); } this.project.subprojects.forEach(_ensure); } /** * Emits package.json for non-node NX monorepos. * @internal */ _emitPackageJson() { if (!utils_1.ProjectUtils.isNamedInstanceOf(this.project, javascript_1.NodeProject) && !this.project.tryFindFile("package.json")) { new projen_1.JsonFile(this.project, "package.json", { obj: { devDependencies: { ...this.nxPlugins, nx: "19.8.14", "@nx/devkit": "19.8.14", }, private: true, engines: { node: ">=16", pnpm: ">=8", }, scripts: Object.fromEntries(this.project.tasks.all .filter((t) => t.name !== "install") .map((c) => [ c.name, !this.project.ejected ? utils_1.NodePackageUtils.command.projen(javascript_1.NodePackageManager.PNPM, c.name) : `scripts/run-task ${c.name}`, ])), }, }).synthesize(); } if (!utils_1.ProjectUtils.isNamedInstanceOf(this.project, javascript_1.NodeProject) && !this.project.tryFindFile("pnpm-workspace.yaml")) { new projen_1.YamlFile(this.project, "pnpm-workspace.yaml", { obj: { packages: this.project.subprojects .filter((p) => utils_1.ProjectUtils.isNamedInstanceOf(p, javascript_1.NodeProject)) .map((p) => path.relative(this.project.outdir, p.outdir)), }, }).synthesize(); } if (!utils_1.ProjectUtils.isNamedInstanceOf(this.project, javascript_1.NodeProject) && !this.project.tryFindFile(".npmrc")) { new projen_1.IniFile(this.project, ".npmrc", { obj: { "resolution-mode": "highest", yes: "true", "prefer-workspace-packages": "true", "link-workspace-packages": "true", }, }).synthesize(); } else if (utils_1.ProjectUtils.isNamedInstanceOf(this.project, javascript_1.NodeProject) && this.project.package.packageManager === javascript_1.NodePackageManager.PNPM) { this.project.npmrc.addConfig("prefer-workspace-packages", "true"); this.project.npmrc.addConfig("link-workspace-packages", "true"); this.project.npmrc.addConfig("yes", "true"); } } _invokeInstallCITasks() { const cmd = utils_1.NodePackageUtils.command.exec(utils_1.ProjectUtils.isNamedInstanceOf(this.project, javascript_1.NodeProject) ? this.project.package.packageManager : javascript_1.NodePackageManager.NPM, ...this.composeNxRunManyCommand({ target: "install:ci", })); const task = this.project.tasks.tryFind("install:ci"); task?.steps?.length && task.steps.length > 0 && !task?.steps.find((s) => s.exec === cmd) && task?.exec(cmd, { receiveArgs: true }); } /** * Add licenses to any subprojects which don't already have a license. */ _addLicenses() { [this.project, ...this.project.subprojects] .filter(() => !this.licenseOptions?.disableDefaultLicenses) .forEach((p) => { p.tryRemoveFile("LICENSE"); if (!this.licenseOptions) { new projen_1.License(p, { spdx: DEFAULT_LICENSE, }); if (utils_1.ProjectUtils.isNamedInstanceOf(p, java_1.JavaProject)) { // Force all Java projects to use Apache 2.0 p.tryFindObjectFile("pom.xml")?.addOverride("project.licenses", [ { license: { name: "Apache License 2.0", url: "https://www.apache.org/licenses/LICENSE-2.0", distribution: "repo", comments: "An OSI-approved license", }, }, ]); } } else if (!!this.licenseOptions?.licenseText) { new projen_1.TextFile(p, "LICENSE", { marker: false, committed: true, lines: this.licenseOptions.licenseText.split("\n"), }); } else if (this.licenseOptions.spdx) { new projen_1.License(p, { spdx: this.licenseOptions.spdx, copyrightOwner: this.licenseOptions?.copyrightOwner, }); } else { throw new Error("Either spdx or licenseText must be specified."); } }); } preSynthesize() { this._ensureNxProjectGraph(); this._emitPackageJson(); this._invokeInstallCITasks(); this.patchPythonProjects([this.project]); this._addLicenses(); } /** * @inheritDoc */ synth() { this.resetDefaultTask(); } /** * Ensures subprojects don't have a default task */ resetDefaultTask() { this.project.subprojects.forEach((subProject) => { // Disable default task on subprojects as this isn't supported in a monorepo subProject.defaultTask?.reset(); }); } } exports.NxConfigurator = NxConfigurator; _a = JSII_RTTI_SYMBOL_1; NxConfigurator[_a] = { fqn: "@aws/pdk.monorepo.NxConfigurator", version: "0.26.14" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibngtY29uZmlndXJhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibngtY29uZmlndXJhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUE7c0NBQ3NDO0FBQ3RDLDZCQUE2QjtBQUM3QixtQ0FTZ0I7QUFDaEIsMENBQThDO0FBQzlDLHNEQUF3RTtBQUN4RSw4Q0FBMEQ7QUFDMUQsNkNBQXlDO0FBQ3pDLGlEQUE2QztBQUU3QyxvQ0FBMEQ7QUFFMUQsTUFBTSxzQkFBc0IsR0FBRyxHQUFHLENBQUM7QUFDbkMsTUFBTSxlQUFlLEdBQUcsWUFBWSxDQUFDO0FBOEhyQzs7R0FFRztBQUNILE1BQWEsY0FBZSxTQUFRLGtCQUFTO0lBSzNDLFlBQVksT0FBZ0IsRUFBRSxPQUErQjtRQUMzRCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFIVCxjQUFTLEdBQThCLEVBQUUsQ0FBQztRQUloRCxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlCLE9BQU8sQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDckMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUU7WUFDMUIsV0FBVyxFQUFFLElBQUk7WUFDakIsSUFBSSxFQUFFLHdCQUFnQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQ2pDLHdCQUFnQixDQUFDLHFCQUFxQixDQUNwQyxJQUFJLENBQUMsT0FBTyxFQUNaLCtCQUFrQixDQUFDLEdBQUcsQ0FDdkIsRUFDRCxJQUFJLEVBQ0osVUFBVSxDQUNYO1lBQ0QsV0FBVyxFQUFFLDhDQUE4QztTQUM1RCxDQUFDLENBQUM7UUFFSCxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRTtZQUN2QixXQUFXLEVBQUUsSUFBSTtZQUNqQixJQUFJLEVBQUUsd0JBQWdCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FDakMsd0JBQWdCLENBQUMscUJBQXFCLENBQ3BDLElBQUksQ0FBQyxPQUFPLEVBQ1osK0JBQWtCLENB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QkFDbkQsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3BDLElBQUksZ0JBQU8sQ0FBQyxDQUFDLEVBQUU7b0JBQ2IsSUFBSSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSTtvQkFDOUIsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsY0FBYztpQkFDcEQsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMsK0NBQStDLENBQUMsQ0FBQztZQUNuRSxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLO1FBQ0gsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVEOztPQUVHO0lBQ0ssZ0JBQWdCO1FBQ3RCLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFVBQWUsRUFBRSxFQUFFO1lBQ25ELDRFQUE0RTtZQUM1RSxVQUFVLENBQUMsV0FBVyxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQ2xDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUFsY0gsd0NBbWNDIiwic291cmNlc0NvbnRlbnQiOlsiLyohIENvcHlyaWdodCBbQW1hem9uLmNvbV0oaHR0cDovL2FtYXpvbi5jb20vKSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wICovXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQge1xuICBDb21wb25lbnQsXG4gIEluaUZpbGUsXG4gIEpzb25GaWxlLFxuICBMaWNlbnNlLFxuICBQcm9qZWN0LFxuICBUYXNrLFxuICBUZXh0RmlsZSxcbiAgWWFtbEZpbGUsXG59IGZyb20gXCJwcm9qZW5cIjtcbmltcG9ydCB7IEphdmFQcm9qZWN0IH0gZnJvbSBcInByb2plbi9saWIvamF2YVwiO1xuaW1wb3J0IHsgTm9kZVBhY2thZ2VNYW5hZ2VyLCBOb2RlUHJvamVjdCB9IGZyb20gXCJwcm9qZW4vbGliL2phdmFzY3JpcHRcIjtcbmltcG9ydCB7IFBvZXRyeSwgUHl0aG9uUHJvamVjdCB9IGZyb20gXCJwcm9qZW4vbGliL3B5dGhvblwiO1xuaW1wb3J0IHsgTnhQcm9qZWN0IH0gZnJvbSBcIi4vbngtcHJvamVjdFwiO1xuaW1wb3J0IHsgTnhXb3Jrc3BhY2UgfSBmcm9tIFwiLi9ueC13b3Jrc3BhY2VcIjtcbmltcG9ydCB7IE54IH0gZnJvbSBcIi4uL254LXR5cGVzXCI7XG5pbXBvcnQgeyBOb2RlUGFja2FnZVV0aWxzLCBQcm9qZWN0VXRpbHMgfSBmcm9tIFwiLi4vdXRpbHNcIjtcblxuY29uc3QgREVGQVVMVF9QWVRIT05fVkVSU0lPTiA9IFwiM1wiO1xuY29uc3QgREVGQVVMVF9MSUNFTlNFID0gXCJBcGFjaGUtMi4wXCI7XG5cbi8qKlxuICogT3B0aW9ucyBmb3Igb3ZlcnJpZGluZyBueCBidWlsZCB0YXNrc1xuICogQGludGVybmFsXG4gKi9cbmludGVyZmFjZSBPdmVycmlkZU54QnVpbGRUYXNrT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBGb3JjZSB1bmxvY2tpbmcgdGFzayAoZWc6IGJ1aWxkIHRhc2sgaXMgbG9ja2VkKVxuICAgKi9cbiAgcmVhZG9ubHkgZm9yY2U/OiBib29sZWFuO1xuICAvKipcbiAgICogRGlzYWJsZSBmdXJ0aGVyIHJlc2V0cyBvZiB0aGUgdGFzayBieSBvdGhlciBjb21wb25lbnRzIGluIGZ1cnRoZXIgbGlmZWN5Y2xlIHN0YWdlc1xuICAgKiAoZWcgZXNsaW50IHJlc2V0cyBkdXJpbmcgcHJlU3ludGhlc2l6ZSlcbiAgICovXG4gIHJlYWRvbmx5IGRpc2FibGVSZXNldD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIHRoYXQgYWxsIE5YUHJvamVjdCBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGltcGxlbWVudC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJTnhQcm9qZWN0Q29yZSB7XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIE54V29ya3NwYWNlIGluc3RhbmNlLiBUaGlzIHNob3VsZCBiZSBpbXBsZW1lbnRlZCB1c2luZyBhIGdldHRlci5cbiAgICovXG4gIHJlYWRvbmx5IG54OiBOeFdvcmtzcGFjZTtcblxuICAvKipcbiAgICogSGVscGVyIHRvIGZvcm1hdCBgbnB4IG54IHJ1bi1tYW55IC4uLmAgc3R5bGUgY29tbWFuZCBleGVjdXRpb24gaW4gcGFja2FnZSBtYW5hZ2VyLlxuICAgKiBAcGFyYW0gb3B0aW9uc1xuICAgKi9cbiAgZXhlY054UnVuTWFueUNvbW1hbmQob3B0aW9uczogTnguUnVuTWFueU9wdGlvbnMpOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEhlbHBlciB0byBmb3JtYXQgYG5weCBueCBydW4tbWFueSAuLi5gIHN0eWxlIGNvbW1hbmRcbiAgICogQHBhcmFtIG9wdGlvbnNcbiAgICovXG4gIGNvbXBvc2VOeFJ1bk1hbnlDb21tYW5kKG9wdGlvbnM6IE54LlJ1bk1hbnlPcHRpb25zKTogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEFkZCBwcm9qZWN0IHRhc2sgdGhhdCBleGVjdXRlcyBgbnB4IG54IHJ1bi1tYW55IC4uLmAgc3R5bGUgY29tbWFuZC5cbiAgICpcbiAgICogQHBhcmFtIG5hbWUgdGFzayBuYW1lXG4gICAqIEBwYXJhbSBvcHRpb25zIG9wdGlvbnNcbiAgICovXG4gIGFkZE54UnVuTWFueVRhc2sobmFtZTogc3RyaW5nLCBvcHRpb25zOiBOeC5SdW5NYW55T3B0aW9ucyk6IFRhc2s7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbiBpbXBsaWNpdCBkZXBlbmRlbmN5IGJldHdlZW4gdHdvIFByb2plY3RzLiBUaGlzIGlzIHR5cGljYWxseVxuICAgKiB1c2VkIGluIHBvbHlnb3QgcmVwb3Mgd2hlcmUgYSBUeXBlc2NyaXB0IHByb2plY3Qgd2FudHMgYSBidWlsZCBkZXBlbmRlbmN5XG4gICAqIG9uIGEgUHl0aG9uIHByb2plY3QgYXMgYW4gZXhhbXBsZS5cbiAgICpcbiAgICogQHBhcmFtIGRlcGVuZGVudCBwcm9qZWN0IHlvdSB3YW50IHRvIGhhdmUgdGhlIGRlcGVuZGVuY3kuXG4gICAqIEBwYXJhbSBkZXBlbmRlZSBwcm9qZWN0IHlvdSB3aXNoIHRvIGRlcGVuZCBvbi5cbiAgICogQHRocm93cyBlcnJvciBpZiB0aGlzIGlzIGNhbGxlZCBvbiBhIGRlcGVuZGVudCB3aGljaCBkb2VzIG5vdCBoYXZlIGEgTlhQcm9qZWN0IGNvbXBvbmVudCBhdHRhY2hlZC5cbiAgICovXG4gIGFkZEltcGxpY2l0RGVwZW5kZW5jeShkZXBlbmRlbnQ6IFByb2plY3QsIGRlcGVuZGVlOiBQcm9qZWN0IHwgc3RyaW5nKTogdm9pZDtcblxuICAvKipcbiAgICogQWRkcyBhIGRlcGVuZGVuY3kgYmV0d2VlbiB0d28gSmF2YSBQcm9qZWN0cyBpbiB0aGUgbW9ub3JlcG8uXG4gICAqIEBwYXJhbSBkZXBlbmRlbnQgcHJvamVjdCB5b3Ugd2FudCB0byBoYXZlIHRoZSBkZXBlbmRlbmN5XG4gICAqIEBwYXJhbSBkZXBlbmRlZSBwcm9qZWN0IHlvdSB3aXNoIHRvIGRlcGVuZCBvblxuICAgKi9cbiAgYWRkSmF2YURlcGVuZGVuY3koZGVwZW5kZW50OiBKYXZhUHJvamVjdCwgZGVwZW5kZWU6IEphdmFQcm9qZWN0KTogdm9pZDtcblxuICAvKipcbiAgICogQWRkcyBhIGRlcGVuZGVuY3kgYmV0d2VlbiB0d28gUHl0aG9uIFByb2plY3RzIGluIHRoZSBtb25vcmVwby4gVGhlIGRlcGVuZGVudCBtdXN0IGhhdmUgUG9ldHJ5IGVuYWJsZWQuXG4gICAqIEBwYXJhbSBkZXBlbmRlbnQgcHJvamVjdCB5b3Ugd2FudCB0byBoYXZlIHRoZSBkZXBlbmRlbmN5IChtdXN0IGJlIGEgUG9ldHJ5IFB5dGhvbiBQcm9qZWN0KVxuICAgKiBAcGFyYW0gZGVwZW5kZWUgcHJvamVjdCB5b3Ugd2lzaCB0byBkZXBlbmQgb25cbiAgICogQHRocm93cyBlcnJvciBpZiB0aGUgZGVwZW5kZW50IGRvZXMgbm90IGhhdmUgUG9ldHJ5IGVuYWJsZWRcbiAgICovXG4gIGFkZFB5dGhvblBvZXRyeURlcGVuZGVuY3koXG4gICAgZGVwZW5kZW50OiBQeXRob25Qcm9qZWN0LFxuICAgIGRlcGVuZGVlOiBQeXRob25Qcm9qZWN0XG4gICk6IHZvaWQ7XG59XG5cbi8qKlxuICogTGljZW5zZSBvcHRpb25zLlxuICpcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMaWNlbnNlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBMaWNlbnNlIHR5cGUgKFNQRFgpLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9wcm9qZW4vcHJvamVuL3RyZWUvbWFpbi9saWNlbnNlLXRleHQgZm9yIGxpc3Qgb2Ygc3VwcG9ydGVkIGxpY2Vuc2VzXG4gICAqL1xuICByZWFkb25seSBzcGR4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDb3B5cmlnaHQgb3duZXIuXG4gICAqXG4gICAqIElmIHRoZSBsaWNlbnNlIHRleHQgZm9yIHRoZSBnaXZlbiBzcGR4IGhhcyAkY29weXJpZ2h0X293bmVyLCB0aGlzIG9wdGlvbiBtdXN0IGJlIHNwZWNpZmllZC5cbiAgICovXG4gIHJlYWRvbmx5IGNvcHlyaWdodE93bmVyPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBcmJpdHJhcnkgbGljZW5zZSB0ZXh0LlxuICAgKi9cbiAgcmVhZG9ubHkgbGljZW5zZVRleHQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gZGlzYWJsZSB0aGUgZ2VuZXJhdGlvbiBvZiBkZWZhdWx0IGxpY2Vuc2VzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZGlzYWJsZURlZmF1bHRMaWNlbnNlcz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogTlhDb25maWd1cmF0b3Igb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOeENvbmZpZ3VyYXRvck9wdGlvbnMge1xuICAvKipcbiAgICogQnJhbmNoIHRoYXQgTlggYWZmZWN0ZWQgc2hvdWxkIHJ1biBhZ2FpbnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdFJlbGVhc2VCcmFuY2g/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgcGFja2FnZSBsaWNlbnNlIGNvbmZpZy5cbiAgICpcbiAgICogSWYgbm90aGluZyBpcyBzcGVjaWZpZWQsIGFsbCBwYWNrYWdlcyB3aWxsIGRlZmF1bHQgdG8gQXBhY2hlLTIuMCAodW5sZXNzIHRoZXkgaGF2ZSB0aGVpciBvd24gTGljZW5zZSBjb21wb25lbnQpLlxuICAgKi9cbiAgcmVhZG9ubHkgbGljZW5zZU9wdGlvbnM/OiBMaWNlbnNlT3B0aW9ucztcbn1cblxuLyoqXG4gKiBDb25maWd1ZXMgY29tbW9uIE5YIHJlbGF0ZWQgdGFza3MgYW5kIG1ldGhvZHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBOeENvbmZpZ3VyYXRvciBleHRlbmRzIENvbXBvbmVudCBpbXBsZW1lbnRzIElOeFByb2plY3RDb3JlIHtcbiAgcHVibGljIHJlYWRvbmx5IG54OiBOeFdvcmtzcGFjZTtcbiAgcHJpdmF0ZSByZWFkb25seSBsaWNlbnNlT3B0aW9ucz86IExpY2Vuc2VPcHRpb25zO1xuICBwcml2YXRlIG54UGx1Z2luczogeyBbZGVwOiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKHByb2plY3Q6IFByb2plY3QsIG9wdGlvbnM/OiBOeENvbmZpZ3VyYXRvck9wdGlvbnMpIHtcbiAgICBzdXBlcihwcm9qZWN0KTtcbiAgICBwcm9qZWN0LmFkZEdpdElnbm9yZShcIi5ueC8qXCIpO1xuICAgIHByb2plY3QuYWRkR2l0SWdub3JlKFwiIS5ueC9wbHVnaW5zXCIpO1xuICAgIHByb2plY3QuYWRkVGFzayhcInJ1bi1tYW55XCIsIHtcbiAgICAgIHJlY2VpdmVBcmdzOiB0cnVlLFxuICAgICAgZXhlYzogTm9kZVBhY2thZ2VVdGlscy5jb21tYW5kLmV4ZWMoXG4gICAgICAgIE5vZGVQYWNrYWdlVXRpbHMuZ2V0Tm9kZVBhY2thZ2VNYW5hZ2VyKFxuICAgICAgICAgIHRoaXMucHJvamVjdCxcbiAgICAgICAgICBOb2RlUGFja2FnZU1hbmFnZXIuTlBNXG4gICAgICAgICksXG4gICAgICAgIFwibnhcIixcbiAgICAgICAgXCJydW4tbWFueVwiXG4gICAgICApLFxuICAgICAgZGVzY3JpcHRpb246IFwiUnVuIHRhc2sgYWdhaW5zdCBtdWx0aXBsZSB3b3Jrc3BhY2UgcHJvamVjdHNcIixcbiAgICB9KTtcblxuICAgIHByb2plY3QuYWRkVGFzayhcImdyYXBoXCIsIHtcbiAgICAgIHJlY2VpdmVBcmdzOiB0cnVlLFxuICAgICAgZXhlYzogTm9kZVBhY2thZ2VVdGlscy5jb21tYW5kLmV4ZWMoXG4gICAgICAgIE5vZGVQYWNrYWdlVXRpbHMuZ2V0Tm9kZVBhY2thZ2VNYW5hZ2VyKFxuICAgICAgICAgIHRoaXMucHJvamVjdCxcbiAgICAgICAgICBOb2RlUGFja2FnZU1hbmFnZXIuTlBNXG4gICAgICAgICksXG4gICAgICAgIFwibnhcIixcbiAgICAgICAgXCJncmFwaFwiXG4gICAgICApLFxuICAgICAgZGVzY3JpcHRpb246IFwiR2VuZXJhdGUgZGVwZW5kZW5jeSBncmFwaCBmb3IgbW9ub3JlcG9cIixcbiAgICB9KTtcblxuICAgIHRoaXMubGljZW5zZU9wdGlvbnMgPSBvcHRpb25zPy5saWNlbnNlT3B0aW9ucztcbiAgICB0aGlzLm54ID0gTnhXb3Jrc3BhY2Uub2YocHJvamVjdCkgfHwgbmV3IE54V29ya3NwYWNlKHByb2plY3QpO1xuICAgIHRoaXMubnguYWZmZWN0ZWQuZGVmYXVsdEJhc2UgPSBvcHRpb25zPy5kZWZhdWx0UmVsZWFzZUJyYW5jaCA/PyBcIm1haW5saW5lXCI7XG4gIH1cblxuICBwdWJsaWMgcGF0Y2hQb2V0cnlFbnYocHJvamVjdDogUHl0aG9uUHJvamVjdCk6IHZvaWQge1xuICAgIC8vIFNpbmNlIHRoZSByb290IG1vbm9yZXBvIGlzIGEgcG9ldHJ5IHByb2plY3QgYW5kIHNldHMgdGhlIFZJUlRVQUxfRU5WLCBhbmQgcG9ldHJ5IGVudiBpbmZvIC1wIHdpbGwgcHJpbnRcbiAgICAvLyB0aGUgdmlydHVhbCBlbnYgc2V0IGluIHRoZSBWSVJUVUFMX0VOViB2YXJpYWJsZSBpZiBzZXQsIHdlIG5lZWQgdG8gdW5zZXQgaXQgdG8gZW5zdXJlIHRoZSBsb2NhbCBwcm9qZWN0J3NcbiAgICAvLyBlbnYgaXMgdXNlZC5cbiAgICBpZiAoUHJvamVjdFV0aWxzLmlzTmFtZWRJbnN0YW5jZU9mKHByb2plY3QuZGVwc01hbmFnZXIgYXMgYW55LCBQb2V0cnkpKSB7XG4gICAgICBbXCJpbnN0YWxsXCIsIFwiaW5zdGFsbDpjaVwiXS5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICAgIGNvbnN0IHRhc2sgPSBwcm9qZWN0LnRhc2tzLnRyeUZpbmQodCk7XG5cbiAgICAgICAgLy8gU2V0dXAgZW52XG4gICAgICAgIGNvbnN0IGNyZWF0ZVZlbnZDbWQgPSBcInBvZXRyeSBlbnYgdXNlIHB5dGhvbiRQWVRIT05fVkVSU0lPTlwiO1xuICAgICAgICAhdGFzaz8uc3RlcHMuZmluZCgocykgPT4gcy5leGVjID09PSBjcmVhdGVWZW52Q21kKSAmJlxuICAgICAgICAgIHRhc2s/LnByZXBlbmRFeGVjKGNyZWF0ZVZlbnZDbWQpO1xuXG4gICAgICAgIC8vIEVuc3VyZSB0aGUgcHJvamVuICYgcGRrIGJpbnMgYXJlIHJlbW92ZWQgZnJvbSB0aGUgdmVudiBhcyB3ZSBhbHdheXMgd2FudCB0byB1c2UgdGhlIG5weCB2YXJpYW50XG4gICAgICAgIGNvbnN0IHJlbW92ZUJpbnNDbWQgPVxuICAgICAgICAgIFwicm0gLWYgYHBvZXRyeSBlbnYgaW5mbyAtcGAvYmluL3Byb2plbiBgcG9ldHJ5IGVudiBpbmZvIC1wYC9iaW4vcGRrXCI7XG4gICAgICAgICF0YXNrPy5zdGVwcy5maW5kKChzKSA9PiBzLmV4ZWMgPT09IHJlbW92ZUJpbnNDbWQpICYmXG4gICAgICAgICAgdGFzaz8uZXhlYyhyZW1vdmVCaW5zQ21kKTtcblxuICAgICAgICBjb25zdCBweXRob25WZXJzaW9uID0gcHJvamVjdC5kZXBzLnRyeUdldERlcGVuZGVuY3koXCJweXRob25cIik/LnZlcnNpb247XG4gICAgICAgIHRhc2shLmVudihcbiAgICAgICAgICBcIlBZVEhPTl9WRVJTSU9OXCIsXG4gICAgICAgICAgcHl0aG9uVmVyc2lvbiAmJiAhcHl0aG9uVmVyc2lvbj8uc3RhcnRzV2l0aChcIl5cIilcbiAgICAgICAgICAgID8gcHl0aG9uVmVyc2lvblxuICAgICAgICAgICAgOiBgJChweWVudiBsYXRlc3QgJHtcbiAgICAgICAgICAgICAgICBweXRob25WZXJzaW9uPy5zdWJzdHJpbmcoMSkuc3BsaXQoXCIuXCIpWzBdIHx8XG4gICAgICAgICAgICAgICAgREVGQVVMVF9QWVRIT05fVkVSU0lPTlxuICAgICAgICAgICAgICB9IHwgY3V0IC1kICcuJyAtZiAxLDIgfHwgZWNobyAnJylgXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgcHJvamVjdC50YXNrcy5hZGRFbnZpcm9ubWVudChcbiAgICAgICAgXCJWSVJUVUFMX0VOVlwiLFxuICAgICAgICBcIiQoZW52IC11IFZJUlRVQUxfRU5WIHBvZXRyeSBlbnYgaW5mbyAtcCB8fCBlY2hvICcnKVwiXG4gICAgICApO1xuICAgICAgcHJvamVjdC50YXNrcy5hZGRFbnZpcm9ubWVudChcbiAgICAgICAgXCJQQVRIXCIsXG4gICAgICAgIFwiJChlY2hvICQoZW52IC11IFZJUlRVQUxfRU5WIHBvZXRyeSBlbnYgaW5mbyAtcCB8fCBlY2hvICcnKS9iaW46JFBBVEgpXCJcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHBhdGNoUHl0aG9uUHJvamVjdHMocHJvamVjdHM6IFByb2plY3RbXSk6IHZvaWQge1xuICAgIHByb2plY3RzLmZvckVhY2goKHApID0+IHtcbiAgICAgIGlmIChQcm9qZWN0VXRpbHMuaXNOYW1lZEluc3RhbmNlT2YocCwgUHl0aG9uUHJvamVjdCkpIHtcbiAgICAgICAgdGhpcy5wYXRjaFBvZXRyeUVudihwKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucGF0Y2hQeXRob25Qcm9qZWN0cyhwLnN1YnByb2plY3RzKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPdmVycmlkZXMgXCJidWlsZFwiIHJlbGF0ZWQgcHJvamVjdCB0YXNrcyAoYnVpbGQsIGNvbXBpbGUsIHRlc3QsIGV0Yy4pIHdpdGggYG5weCBueCBydW4tbWFueWAgZm9ybWF0LlxuICAgKiBAcGFyYW0gdGFzayAtIFRoZSB0YXNrIG9yIHRhc2sgbmFtZSB0byBvdmVycmlkZVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE54IHJ1bi1tYW55IG9wdGlvbnNcbiAgICogQHBhcmFtIG92ZXJyaWRlT3B0aW9ucyAtIE9wdGlvbnMgZm9yIG92ZXJyaWRpbmcgdGhlIHRhc2tcbiAgICogQHJldHVybnMgLSBUaGUgdGFzayB0aGF0IHdhcyBvdmVycmlkZGVuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIF9vdmVycmlkZU54QnVpbGRUYXNrKFxuICAgIHRhc2s6IFRhc2sgfCBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgb3B0aW9uczogTnguUnVuTWFueU9wdGlvbnMsXG4gICAgb3ZlcnJpZGVPcHRpb25zPzogT3ZlcnJpZGVOeEJ1aWxkVGFza09wdGlvbnNcbiAgKTogVGFzayB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiB0YXNrID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0YXNrID0gdGhpcy5wcm9qZWN0LnRhc2tzLnRyeUZpbmQodGFzayk7XG4gICAgfVxuXG4gICAgaWYgKHRhc2sgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChvdmVycmlkZU9wdGlvbnM/LmZvcmNlKSB7XG4gICAgICAvLyBAdHMtaWdub3JlIC0gcHJpdmF0ZSBwcm9wZXJ0eVxuICAgICAgdGFzay5fbG9ja2VkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgdGFzay5yZXNldCh0aGlzLmV4ZWNOeFJ1bk1hbnlDb21tYW5kKG9wdGlvbnMpLCB7XG4gICAgICByZWNlaXZlQXJnczogdHJ1ZSxcbiAgICB9KTtcblxuICAgIHRhc2suZGVzY3JpcHRpb24gKz0gXCIgZm9yIGFsbCBhZmZlY3RlZCBwcm9qZWN0c1wiO1xuXG4gICAgaWYgKG92ZXJyaWRlT3B0aW9ucz8uZGlzYWJsZVJlc2V0KSB7XG4gICAgICAvLyBQcmV2ZW50IGFueSBmdXJ0aGVyIHJlc2V0cyBvZiB0aGUgdGFzayB0byBmb3JjZSBpdCB0byByZW1haW4gYXMgdGhlIG92ZXJyaWRkZW4gbnggYnVpbGQgdGFza1xuICAgICAgdGFzay5yZXNldCA9ICgpID0+IHt9O1xuICAgIH1cblxuICAgIHJldHVybiB0YXNrO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBjb21tYW5kIHRvIHVwZ3JhZGUgYWxsIHB5dGhvbiBzdWJwcm9qZWN0cyB0byB0aGUgZ2l2ZW4gdGFza1xuICAgKiBAcGFyYW0gbW9ub3JlcG8gdGhlIG1vbm9yZXBvIHByb2plY3RcbiAgICogQHBhcmFtIHRhc2sgdGhlIHRhc2sgdG8gYWRkIHRoZSBjb21tYW5kIHRvXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIF9jb25maWd1cmVQeXRob25TdWJwcm9qZWN0VXBncmFkZURlcHMobW9ub3JlcG86IFByb2plY3QsIHRhc2s6IFRhc2spIHtcbiAgICAvLyBVcGdyYWRlIGRlcHMgZm9yXG4gICAgY29uc3QgcHl0aG9uU3VicHJvamVjdHMgPSBtb25vcmVwby5zdWJwcm9qZWN0cy5maWx0ZXIoKHApID0+XG4gICAgICBQcm9qZWN0VXRpbHMuaXNOYW1lZEluc3RhbmNlT2YocCwgUHl0aG9uUHJvamVjdClcbiAgICApO1xuICAgIGlmIChweXRob25TdWJwcm9qZWN0cy5sZW5ndGggPiAwKSB7XG4gICAgICB0YXNrLmV4ZWMoXG4gICAgICAgIHRoaXMuZXhlY054UnVuTWFueUNvbW1hbmQoe1xuICAgICAgICAgIHRhcmdldDogXCJpbnN0YWxsXCIsIC8vIFRPRE86IHJlbW92ZSBpbiBmYXZvdXIgb2YgdGhlIHVwZ3JhZGUgdGFzayBpZiBldmVyIGltcGxlbWVudGVkIGZvciBweXRob25cbiAgICAgICAgICBwcm9qZWN0czogcHl0aG9uU3VicHJvamVjdHMubWFwKChwKSA9PiBwLm5hbWUpLFxuICAgICAgICB9KSxcbiAgICAgICAgeyByZWNlaXZlQXJnczogdHJ1ZSB9XG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBpbnN0YWxsIHRhc2sgb3IgY3JlYXRlcyBvbmUgd2l0aCBueCBpbnN0YWxsYXRpb24gY29tbWFuZCBhZGRlZC5cbiAgICpcbiAgICogTm90ZTogdGhpcyBzaG91bGQgb25seSBiZSBjYWxsZWQgZnJvbSBub24tbm9kZSBwcm9qZWN0c1xuICAgKlxuICAgKiBAcGFyYW0gbnhQbHVnaW5zIGFkZGl0aW9uYWwgcGx1Z2lucyB0byBpbnN0YWxsXG4gICAqIEByZXR1cm5zIGluc3RhbGwgdGFza1xuICAgKi9cbiAgcHVibGljIGVuc3VyZU54SW5zdGFsbFRhc2sobnhQbHVnaW5zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KTogVGFzayB7XG4gICAgdGhpcy5ueFBsdWdpbnMgPSBueFBsdWdpbnM7XG5cbiAgICBjb25zdCBpbnN0YWxsVGFzayA9XG4gICAgICB0aGlzLnByb2plY3QudGFza3MudHJ5RmluZChcImluc3RhbGxcIikgPz8gdGhpcy5wcm9qZWN0LmFkZFRhc2soXCJpbnN0YWxsXCIpO1xuICAgIGluc3RhbGxUYXNrLmV4ZWMoXCJwbnBtIGkgLS1uby1mcm96ZW4tbG9ja2ZpbGVcIik7XG5cbiAgICAoXG4gICAgICB0aGlzLnByb2plY3QudGFza3MudHJ5RmluZChcImluc3RhbGw6Y2lcIikgPz9cbiAgICAgIHRoaXMucHJvamVjdC5hZGRUYXNrKFwiaW5zdGFsbDpjaVwiKVxuICAgICkuZXhlYyhcInBucG0gaSAtLWZyb3plbi1sb2NrZmlsZVwiKTtcblxuICAgIHJldHVybiBpbnN0YWxsVGFzaztcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgdG8gZm9ybWF0IGBucHggbnggcnVuLW1hbnkgLi4uYCBzdHlsZSBjb21tYW5kIGV4ZWN1dGlvbiBpbiBwYWNrYWdlIG1hbmFnZXIuXG4gICAqIEBwYXJhbSBvcHRpb25zXG4gICAqL1xuICBwdWJsaWMgZXhlY054UnVuTWFueUNvbW1hbmQob3B0aW9uczogTnguUnVuTWFueU9wdGlvbnMpOiBzdHJpbmcge1xuICAgIHJldHVybiBOb2RlUGFja2FnZVV0aWxzLmNvbW1hbmQuZXhlYyhcbiAgICAgIE5vZGVQYWNrYWdlVXRpbHMuZ2V0Tm9kZVBhY2thZ2VNYW5hZ2VyKFxuICAgICAgICB0aGlzLnByb2plY3QsXG4gICAgICAgIE5vZGVQYWNrYWdlTWFuYWdlci5OUE1cbiAgICAgICksXG4gICAgICAuLi50aGlzLmNvbXBvc2VOeFJ1bk1hbnlDb21tYW5kKG9wdGlvbnMpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgdG8gZm9ybWF0IGBucHggbnggcnVuLW1hbnkgLi4uYCBzdHlsZSBjb21tYW5kXG4gICAqIEBwYXJhbSBvcHRpb25zXG4gICAqL1xuICBwdWJsaWMgY29tcG9zZU54UnVuTWFueUNvbW1hbmQob3B0aW9uczogTnguUnVuTWFueU9wdGlvbnMpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbXTtcbiAgICBpZiAob3B0aW9ucy5jb25maWd1cmF0aW9uKSB7XG4gICAgICBhcmdzLnB1c2goYC0tY29uZmlndXJhdGlvbj0ke29wdGlvbnMuY29uZmlndXJhdGlvbn1gKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMucnVubmVyKSB7XG4gICAgICBhcmdzLnB1c2goYC0tcnVubmVyPSR7b3B0aW9ucy5ydW5uZXJ9YCk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLnBhcmFsbGVsKSB7XG4gICAgICBhcmdzLnB1c2goYC0tcGFyYWxsZWw9JHtvcHRpb25zLnBhcmFsbGVsfWApO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5za2lwQ2FjaGUpIHtcbiAgICAgIGFyZ3MucHVzaChcIi0tc2tpcC1ueC1jYWNoZVwiKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMuaWdub3JlQ3ljbGVzKSB7XG4gICAgICBhcmdzLnB1c2goXCItLW54LWlnbm9yZS1jeWNsZXNcIik7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLm5vQmFpbCAhPT0gdHJ1ZSkge1xuICAgICAgYXJncy5wdXNoKFwiLS1ueC1iYWlsXCIpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5wcm9qZWN0cyAmJiBvcHRpb25zLnByb2plY3RzLmxlbmd0aCkge1xuICAgICAgYXJncy5wdXNoKGAtLXByb2plY3RzPSR7b3B0aW9ucy5wcm9qZWN0cy5qb2luKFwiLFwiKX1gKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMuZXhjbHVkZSkge1xuICAgICAgYXJncy5wdXNoKGAtLWV4Y2x1ZGU9JHtvcHRpb25zLmV4Y2x1ZGV9YCk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgIGFyZ3MucHVzaChcIi0tdmVyYm9zZVwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW1xuICAgICAgXCJueFwiLFxuICAgICAgXCJydW4tbWFueVwiLFxuICAgICAgYC0tdGFyZ2V0PSR7b3B0aW9ucy50YXJnZXR9YCxcbiAgICAgIGAtLW91dHB1dC1zdHlsZT0ke29wdGlvbnMub3V0cHV0U3R5bGUgfHwgXCJzdHJlYW1cIn1gLFxuICAgICAgLi4uYXJncyxcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBwcm9qZWN0IHRhc2sgdGhhdCBleGVjdXRlcyBgbnB4IG54IHJ1bi1tYW55IC4uLmAgc3R5bGUgY29tbWFuZC5cbiAgICovXG4gIHB1YmxpYyBhZGROeFJ1bk1hbnlUYXNrKG5hbWU6IHN0cmluZywgb3B0aW9uczogTnguUnVuTWFueU9wdGlvbnMpOiBUYXNrIHtcbiAgICByZXR1cm4gdGhpcy5wcm9qZWN0LmFkZFRhc2sobmFtZSwge1xuICAgICAgcmVjZWl2ZUFyZ3M6IHRydWUsXG4gICAgICBleGVjOiB0aGlzLmV4ZWNOeFJ1bk1hbnlDb21tYW5kKG9wdGlvbnMpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbiBpbXBsaWNpdCBkZXBlbmRlbmN5IGJldHdlZW4gdHdvIFByb2plY3RzLiBUaGlzIGlzIHR5cGljYWxseVxuICAgKiB1c2VkIGluIHBvbHlnb3QgcmVwb3Mgd2hlcmUgYSBUeXBlc2NyaXB0IHByb2plY3Qgd2FudHMgYSBidWlsZCBkZXBlbmRlbmN5XG4gICAqIG9uIGEgUHl0aG9uIHByb2plY3QgYXMgYW4gZXhhbXBsZS5cbiAgICpcbiAgICogQHBhcmFtIGRlcGVuZGVudCBwcm9qZWN0IHlvdSB3YW50IHRvIGhhdmUgdGhlIGRlcGVuZGVuY3kuXG4gICAqIEBwYXJhbSBkZXBlbmRlZSBwcm9qZWN0IHlvdSB3aXNoIHRvIGRlcGVuZCBvbi5cbiAgICogQHRocm93cyBlcnJvciBpZiB0aGlzIGlzIGNhbGxlZCBvbiBhIGRlcGVuZGVudCB3aGljaCBkb2VzIG5vdCBoYXZlIGEgTlhQcm9qZWN0IGNvbXBvbmVudCBhdHRhY2hlZC5cbiAgICovXG4gIHB1YmxpYyBhZGRJbXBsaWNpdERlcGVuZGVuY3koZGVwZW5kZW50OiBQcm9qZWN0LCBkZXBlbmRlZTogUHJvamVjdCB8IHN0cmluZykge1xuICAgIE54UHJvamVjdC5lbnN1cmUoZGVwZW5kZW50KS5hZGRJbXBsaWNpdERlcGVuZGVuY3koZGVwZW5kZWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBkZXBlbmRlbmN5IGJldHdlZW4gdHdvIEphdmEgUHJvamVjdHMgaW4gdGhlIG1vbm9yZXBvLlxuICAgKiBAcGFyYW0gZGVwZW5kZW50IHByb2plY3QgeW91IHdhbnQgdG8gaGF2ZSB0aGUgZGVwZW5kZW5jeVxuICAgKiBAcGFyYW0gZGVwZW5kZWUgcHJvamVjdCB5b3Ugd2lzaCB0byBkZXBlbmQgb25cbiAgICovXG4gIHB1YmxpYyBhZGRKYXZhRGVwZW5kZW5jeShkZXBlbmRlbnQ6IEphdmFQcm9qZWN0LCBkZXBlbmRlZTogSmF2YVByb2plY3QpIHtcbiAgICBOeFByb2plY3QuZW5zdXJlKGRlcGVuZGVudCkuYWRkSmF2YURlcGVuZGVuY3koZGVwZW5kZWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBkZXBlbmRlbmN5IGJldHdlZW4gdHdvIFB5dGhvbiBQcm9qZWN0cyBpbiB0aGUgbW9ub3JlcG8uIFRoZSBkZXBlbmRlbnQgbXVzdCBoYXZlIFBvZXRyeSBlbmFibGVkLlxuICAgKiBAcGFyYW0gZGVwZW5kZW50IHByb2plY3QgeW91IHdhbnQgdG8gaGF2ZSB0aGUgZGVwZW5kZW5jeSAobXVzdCBiZSBhIFBvZXRyeSBQeXRob24gUHJvamVjdClcbiAgICogQHBhcmFtIGRlcGVuZGVlIHByb2plY3QgeW91IHdpc2ggdG8gZGVwZW5kIG9uXG4gICAqIEB0aHJvd3MgZXJyb3IgaWYgdGhlIGRlcGVuZGVudCBkb2VzIG5vdCBoYXZlIFBvZXRyeSBlbmFibGVkXG4gICAqL1xuICBwdWJsaWMgYWRkUHl0aG9uUG9ldHJ5RGVwZW5kZW5jeShcbiAgICBkZXBlbmRlbnQ6IFB5dGhvblByb2plY3QsXG4gICAgZGVwZW5kZWU6IFB5dGhvblByb2plY3RcbiAgKSB7XG4gICAgTnhQcm9qZWN0LmVuc3VyZShkZXBlbmRlbnQpLmFkZFB5dGhvblBvZXRyeURlcGVuZGVuY3koZGVwZW5kZWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgdGhhdCBhbGwgbm9uLXJvb3QgcHJvamVjdHMgaGF2ZSBOeFByb2plY3QgYXBwbGllZC5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcm90ZWN0ZWQgX2Vuc3VyZU54UHJvamVjdEdyYXBoKCk6IHZvaWQge1xuICAgIGZ1bmN0aW9uIF9lbnN1cmUoX3Byb2plY3Q6IFByb2plY3QpIHtcbiAgICAgIGlmIChfcHJvamVjdC5yb290ID09PSBfcHJvamVjdCkgcmV0dXJuO1xuXG4gICAgICBOeFByb2plY3QuZW5zdXJlKF9wcm9qZWN0KTtcblxuICAgICAgX3Byb2plY3Quc3VicHJvamVjdHMuZm9yRWFjaCgocCkgPT4ge1xuICAgICAgICBfZW5zdXJlKHApO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5wcm9qZWN0LnN1YnByb2plY3RzLmZvckVhY2goX2Vuc3VyZSk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgcGFja2FnZS5qc29uIGZvciBub24tbm9kZSBOWCBtb25vcmVwb3MuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHJpdmF0ZSBfZW1pdFBhY2thZ2VKc29uKCkge1xuICAgIGlmIChcbiAgICAgICFQcm9qZWN0VXRpbHMuaXNOYW1lZEluc3RhbmNlT2YodGhpcy5wcm9qZWN0LCBOb2RlUHJvamVjdCkgJiZcbiAgICAgICF0aGlzLnByb2plY3QudHJ5RmluZEZpbGUoXCJwYWNrYWdlLmpzb25cIilcbiAgICApIHtcbiAgICAgIG5ldyBKc29uRmlsZSh0aGlzLnByb2plY3QsIFwicGFja2FnZS5qc29uXCIsIHtcbiAgICAgICAgb2JqOiB7XG4gICAgICAgICAgZGV2RGVwZW5kZW5jaWVzOiB7XG4gICAgICAgICAgICAuLi50aGlzLm54UGx1Z2lucyxcbiAgICAgICAgICAgIG54OiBcIjE5LjguMTRcIixcbiAgICAgICAgICAgIFwiQG54L2RldmtpdFwiOiBcIjE5LjguMTRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHByaXZhdGU6IHRydWUsXG4gICAgICAgICAgZW5naW5lczoge1xuICAgICAgICAgICAgbm9kZTogXCI+PTE2XCIsXG4gICAgICAgICAgICBwbnBtOiBcIj49OFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2NyaXB0czogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgICAgdGhpcy5wcm9qZWN0LnRhc2tzLmFsbFxuICAgICAgICAgICAgICAuZmlsdGVyKCh0KSA9PiB0Lm5hbWUgIT09IFwiaW5zdGFsbFwiKVxuICAgICAgICAgICAgICAubWFwKChjKSA9PiBbXG4gICAgICAgICAgICAgICAgYy5uYW1lLFxuICAgICAgICAgICAgICAgICF0aGlz