@cdktn/cli-core 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/ambient.d.ts +13 -0
- package/eslint.config.mjs +82 -0
- package/jest.config.js +20 -0
- package/package.json +139 -0
- package/src/lib/cdktf-config.d.ts +16 -0
- package/src/lib/cdktf-config.d.ts.map +1 -0
- package/src/lib/cdktf-config.js +108 -0
- package/src/lib/cdktf-project-io-handler.d.ts +20 -0
- package/src/lib/cdktf-project-io-handler.d.ts.map +1 -0
- package/src/lib/cdktf-project-io-handler.js +84 -0
- package/src/lib/cdktf-project.d.ts +111 -0
- package/src/lib/cdktf-project.d.ts.map +1 -0
- package/src/lib/cdktf-project.js +371 -0
- package/src/lib/cdktf-stack.d.ts +134 -0
- package/src/lib/cdktf-stack.d.ts.map +1 -0
- package/src/lib/cdktf-stack.js +386 -0
- package/src/lib/convert.d.ts +6 -0
- package/src/lib/convert.d.ts.map +1 -0
- package/src/lib/convert.js +51 -0
- package/src/lib/dependencies/cdktf-config-manager.d.ts +12 -0
- package/src/lib/dependencies/cdktf-config-manager.d.ts.map +1 -0
- package/src/lib/dependencies/cdktf-config-manager.js +36 -0
- package/src/lib/dependencies/dependency-manager.d.ts +95 -0
- package/src/lib/dependencies/dependency-manager.d.ts.map +1 -0
- package/src/lib/dependencies/dependency-manager.js +393 -0
- package/src/lib/dependencies/package-manager.d.ts +18 -0
- package/src/lib/dependencies/package-manager.d.ts.map +1 -0
- package/src/lib/dependencies/package-manager.js +581 -0
- package/src/lib/dependencies/prebuilt-providers.d.ts +23 -0
- package/src/lib/dependencies/prebuilt-providers.d.ts.map +1 -0
- package/src/lib/dependencies/prebuilt-providers.js +220 -0
- package/src/lib/dependencies/registry-api.d.ts +8 -0
- package/src/lib/dependencies/registry-api.d.ts.map +1 -0
- package/src/lib/dependencies/registry-api.js +77 -0
- package/src/lib/dependencies/version-constraints.d.ts +8 -0
- package/src/lib/dependencies/version-constraints.d.ts.map +1 -0
- package/src/lib/dependencies/version-constraints.js +95 -0
- package/src/lib/error-reporting.d.ts +10 -0
- package/src/lib/error-reporting.d.ts.map +1 -0
- package/src/lib/error-reporting.js +133 -0
- package/src/lib/errors.d.ts +6 -0
- package/src/lib/errors.d.ts.map +1 -0
- package/src/lib/errors.js +10 -0
- package/src/lib/execution-logs.d.ts +3 -0
- package/src/lib/execution-logs.d.ts.map +1 -0
- package/src/lib/execution-logs.js +47 -0
- package/src/lib/get.d.ts +25 -0
- package/src/lib/get.d.ts.map +1 -0
- package/src/lib/get.js +90 -0
- package/src/lib/helpers/stack-helpers.d.ts +16 -0
- package/src/lib/helpers/stack-helpers.d.ts.map +1 -0
- package/src/lib/helpers/stack-helpers.js +155 -0
- package/src/lib/index.d.ts +15 -0
- package/src/lib/index.d.ts.map +1 -0
- package/src/lib/index.js +44 -0
- package/src/lib/init.d.ts +37 -0
- package/src/lib/init.d.ts.map +1 -0
- package/src/lib/init.js +131 -0
- package/src/lib/local-provider-constraints.d.ts +28 -0
- package/src/lib/local-provider-constraints.d.ts.map +1 -0
- package/src/lib/local-provider-constraints.js +95 -0
- package/src/lib/local-provider-versions.d.ts +12 -0
- package/src/lib/local-provider-versions.d.ts.map +1 -0
- package/src/lib/local-provider-versions.js +73 -0
- package/src/lib/models/deploy-machine.d.ts +128 -0
- package/src/lib/models/deploy-machine.d.ts.map +1 -0
- package/src/lib/models/deploy-machine.js +280 -0
- package/src/lib/models/pty-process.d.ts +29 -0
- package/src/lib/models/pty-process.d.ts.map +1 -0
- package/src/lib/models/pty-process.js +132 -0
- package/src/lib/models/schema.d.ts +2307 -0
- package/src/lib/models/schema.d.ts.map +1 -0
- package/src/lib/models/schema.js +181 -0
- package/src/lib/models/terraform-cli.d.ts +72 -0
- package/src/lib/models/terraform-cli.d.ts.map +1 -0
- package/src/lib/models/terraform-cli.js +357 -0
- package/src/lib/models/terraform.d.ts +125 -0
- package/src/lib/models/terraform.d.ts.map +1 -0
- package/src/lib/models/terraform.js +72 -0
- package/src/lib/output.d.ts +23 -0
- package/src/lib/output.d.ts.map +1 -0
- package/src/lib/output.js +211 -0
- package/src/lib/provider-add.d.ts +15 -0
- package/src/lib/provider-add.d.ts.map +1 -0
- package/src/lib/provider-add.js +30 -0
- package/src/lib/server/terraform-logs.d.ts +2 -0
- package/src/lib/server/terraform-logs.d.ts.map +1 -0
- package/src/lib/server/terraform-logs.js +19 -0
- package/src/lib/synth-stack.d.ts +29 -0
- package/src/lib/synth-stack.d.ts.map +1 -0
- package/src/lib/synth-stack.js +251 -0
- package/src/lib/synth.d.ts +7 -0
- package/src/lib/synth.d.ts.map +1 -0
- package/src/lib/synth.js +67 -0
- package/src/lib/terraform-json.d.ts +1015 -0
- package/src/lib/terraform-json.d.ts.map +1 -0
- package/src/lib/terraform-json.js +82 -0
- package/src/lib/terraform-provider-lock.d.ts +25 -0
- package/src/lib/terraform-provider-lock.d.ts.map +1 -0
- package/src/lib/terraform-provider-lock.js +95 -0
- package/src/lib/watch.d.ts +16 -0
- package/src/lib/watch.d.ts.map +1 -0
- package/src/lib/watch.js +155 -0
- package/templates/csharp/.hooks.sscaff.js +63 -0
- package/templates/csharp/MainStack.cs +15 -0
- package/templates/csharp/MyTerraformStack.csproj +13 -0
- package/templates/csharp/Program.cs +17 -0
- package/templates/csharp/TestProgram.cs +42 -0
- package/templates/csharp/cdktf.json +11 -0
- package/templates/csharp/help +42 -0
- package/templates/csharp/{{}}.gitignore +345 -0
- package/templates/go/.hooks.sscaff.js +70 -0
- package/templates/go/cdktf.json +12 -0
- package/templates/go/go.mod +8 -0
- package/templates/go/help +32 -0
- package/templates/go/main.go +22 -0
- package/templates/go/main_test.go +42 -0
- package/templates/go/{{}}.gitignore +21 -0
- package/templates/java/.hooks.sscaff.js +64 -0
- package/templates/java/build.gradle +55 -0
- package/templates/java/cdktf.json +12 -0
- package/templates/java/gradle.properties +1 -0
- package/templates/java/gradlew +248 -0
- package/templates/java/gradlew.bat +92 -0
- package/templates/java/help +35 -0
- package/templates/java/settings.gradle +5 -0
- package/templates/java/src/main/java/com/mycompany/app/Main.java +16 -0
- package/templates/java/src/main/java/com/mycompany/app/MainStack.java +14 -0
- package/templates/java/src/test/java/com/company/app/MainTest.java +38 -0
- package/templates/java/{{}}.gitignore +14 -0
- package/templates/python/.hooks.sscaff.js +59 -0
- package/templates/python/Pipfile +7 -0
- package/templates/python/cdktf.json +12 -0
- package/templates/python/help +42 -0
- package/templates/python/main-test.py +26 -0
- package/templates/python/main.py +16 -0
- package/templates/python/{{}}.gitignore +7 -0
- package/templates/python-pip/.hooks.sscaff.js +63 -0
- package/templates/python-pip/cdktf.json +12 -0
- package/templates/python-pip/help +35 -0
- package/templates/python-pip/main-test.py +23 -0
- package/templates/python-pip/main.py +16 -0
- package/templates/python-pip/{{}}.gitignore +7 -0
- package/templates/typescript/.hooks.sscaff.js +78 -0
- package/templates/typescript/__tests__/main-test.ts +89 -0
- package/templates/typescript/cdktf.json +11 -0
- package/templates/typescript/help +51 -0
- package/templates/typescript/jest.config.js +187 -0
- package/templates/typescript/main.ts +14 -0
- package/templates/typescript/package.json +22 -0
- package/templates/typescript/setup.js +2 -0
- package/templates/typescript/tsconfig.json +35 -0
- package/templates/typescript/{{}}.gitignore +11 -0
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.PackageManager = void 0;
|
|
30
|
+
// Copyright (c) HashiCorp, Inc
|
|
31
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
32
|
+
const commons_1 = require("@cdktn/commons");
|
|
33
|
+
const fs_extra_1 = require("fs-extra");
|
|
34
|
+
const path_1 = __importDefault(require("path"));
|
|
35
|
+
const xml_js_1 = require("xml-js");
|
|
36
|
+
const fs = __importStar(require("fs-extra"));
|
|
37
|
+
const semver = __importStar(require("semver"));
|
|
38
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
39
|
+
const z = __importStar(require("zod"));
|
|
40
|
+
// Can't use CDKTF_ as prefix because yargs .env("CDKTF") in strict mode does not allow us to
|
|
41
|
+
// Refer to: https://github.com/yargs/yargs/issues/873
|
|
42
|
+
const { GITHUB_API_TOKEN_CDKTF } = process.env;
|
|
43
|
+
// {
|
|
44
|
+
// "version": "1.0.0",
|
|
45
|
+
// "name": "testUSHasF",
|
|
46
|
+
// "problems": [
|
|
47
|
+
// "extraneous: archiver-utils@2.1.0 /private/var/folders/z_/v03l33d55fb57nrr3b1q03ch0000gq/T/testUSHasF/node_modules/archiver-utils",
|
|
48
|
+
// ],
|
|
49
|
+
// "dependencies": {
|
|
50
|
+
// "@cdktf/provider-random": {
|
|
51
|
+
// "version": "3.0.11",
|
|
52
|
+
// "resolved": "https://registry.npmjs.org/@cdktf/provider-random/-/provider-random-3.0.11.tgz"
|
|
53
|
+
// },
|
|
54
|
+
const npmListSchema = z
|
|
55
|
+
.object({
|
|
56
|
+
dependencies: z.record(z
|
|
57
|
+
.object({
|
|
58
|
+
version: z.string(),
|
|
59
|
+
})
|
|
60
|
+
.nonstrict()),
|
|
61
|
+
})
|
|
62
|
+
.deepPartial()
|
|
63
|
+
.nonstrict();
|
|
64
|
+
// {
|
|
65
|
+
// "type": "tree",
|
|
66
|
+
// "data": {
|
|
67
|
+
// "type": "list",
|
|
68
|
+
// "trees": [
|
|
69
|
+
// {
|
|
70
|
+
// "name": "@cdktf/provider-random@3.0.11",
|
|
71
|
+
// "children": [],
|
|
72
|
+
// "hint": null,
|
|
73
|
+
// "color": "bold",
|
|
74
|
+
// "depth": 0
|
|
75
|
+
// }
|
|
76
|
+
// ]
|
|
77
|
+
// }
|
|
78
|
+
// }
|
|
79
|
+
const yarnListSchema = z
|
|
80
|
+
.object({
|
|
81
|
+
data: z
|
|
82
|
+
.object({
|
|
83
|
+
trees: z.array(z
|
|
84
|
+
.object({
|
|
85
|
+
name: z.string(),
|
|
86
|
+
})
|
|
87
|
+
.nonstrict()),
|
|
88
|
+
})
|
|
89
|
+
.nonstrict(),
|
|
90
|
+
})
|
|
91
|
+
.deepPartial()
|
|
92
|
+
.nonstrict();
|
|
93
|
+
// [
|
|
94
|
+
// {
|
|
95
|
+
// "name": "appdirs",
|
|
96
|
+
// "version": "1.4.4"
|
|
97
|
+
// },
|
|
98
|
+
// {
|
|
99
|
+
const pipPackageSchema = z.array(z.object({ name: z.string(), version: z.string() }).nonstrict());
|
|
100
|
+
/**
|
|
101
|
+
* manages installing, updating, and removing dependencies
|
|
102
|
+
* in the package system used by the target language of a CDKTN
|
|
103
|
+
* project
|
|
104
|
+
*/
|
|
105
|
+
class PackageManager {
|
|
106
|
+
constructor(workingDirectory) {
|
|
107
|
+
this.workingDirectory = workingDirectory;
|
|
108
|
+
}
|
|
109
|
+
static forLanguage(language, workingDirectory) {
|
|
110
|
+
switch (language) {
|
|
111
|
+
case commons_1.Language.GO:
|
|
112
|
+
return new GoPackageManager(workingDirectory);
|
|
113
|
+
case commons_1.Language.TYPESCRIPT:
|
|
114
|
+
return new NodePackageManager(workingDirectory);
|
|
115
|
+
case commons_1.Language.PYTHON:
|
|
116
|
+
return new PythonPackageManager(workingDirectory);
|
|
117
|
+
case commons_1.Language.CSHARP:
|
|
118
|
+
return new NugetPackageManager(workingDirectory);
|
|
119
|
+
case commons_1.Language.JAVA:
|
|
120
|
+
if (GradlePackageManager.isGradleProject(workingDirectory)) {
|
|
121
|
+
return new GradlePackageManager(workingDirectory);
|
|
122
|
+
}
|
|
123
|
+
return new MavenPackageManager(workingDirectory);
|
|
124
|
+
default:
|
|
125
|
+
throw new Error(`Unknown language: ${language}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
exports.PackageManager = PackageManager;
|
|
130
|
+
class NodePackageManager extends PackageManager {
|
|
131
|
+
hasYarnLockfile() {
|
|
132
|
+
return (0, fs_extra_1.existsSync)(path_1.default.join(this.workingDirectory, "yarn.lock"));
|
|
133
|
+
}
|
|
134
|
+
async addPackage(packageName, packageVersion, silent) {
|
|
135
|
+
console.log(`Adding package ${packageName} @ ${packageVersion}`);
|
|
136
|
+
// probe for package-lock.json or yarn.lock
|
|
137
|
+
let command = "npm";
|
|
138
|
+
let args = ["install"];
|
|
139
|
+
if (this.hasYarnLockfile()) {
|
|
140
|
+
command = "yarn";
|
|
141
|
+
args = ["add"];
|
|
142
|
+
}
|
|
143
|
+
args.push(packageVersion ? packageName + "@" + packageVersion : packageName);
|
|
144
|
+
if (silent) {
|
|
145
|
+
args.push("--silent");
|
|
146
|
+
args.push("--no-progress");
|
|
147
|
+
}
|
|
148
|
+
// Install exact version
|
|
149
|
+
// Yarn: https://classic.yarnpkg.com/lang/en/docs/cli/add/#toc-yarn-add-exact-e
|
|
150
|
+
// Npm: https://docs.npmjs.com/cli/v8/commands/npm-install#save-exact
|
|
151
|
+
args.push("-E");
|
|
152
|
+
commons_1.logger.info(`Installing package ${packageName} @ ${packageVersion} using ${command}.`);
|
|
153
|
+
await (0, commons_1.exec)(command, args, { cwd: this.workingDirectory });
|
|
154
|
+
commons_1.logger.info("Package installed.");
|
|
155
|
+
}
|
|
156
|
+
async isNpmVersionAvailable(_packageName, _packageVersion) {
|
|
157
|
+
// We get the list of available versions from npm, no need to check here
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
async listYarnPackages() {
|
|
161
|
+
var _a;
|
|
162
|
+
try {
|
|
163
|
+
const stdout = await (0, commons_1.exec)("yarn", ["list", "--json"], {
|
|
164
|
+
cwd: this.workingDirectory,
|
|
165
|
+
});
|
|
166
|
+
commons_1.logger.debug(`Listing yarn packages using "yarn list --json": ${stdout}`);
|
|
167
|
+
const json = yarnListSchema.parse(JSON.parse(stdout));
|
|
168
|
+
return (((_a = json === null || json === void 0 ? void 0 : json.data) === null || _a === void 0 ? void 0 : _a.trees) || [])
|
|
169
|
+
.filter((dep) => dep.name.startsWith("@cdktf/provider-") ||
|
|
170
|
+
dep.name.startsWith("@cdktn/provider-"))
|
|
171
|
+
.map((dep) => ({
|
|
172
|
+
name: `@${dep.name.split("@")[1]}`,
|
|
173
|
+
version: dep.name.split("@")[2],
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
throw new Error(`Could not determine installed packages using 'yarn list --json': ${e.message}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async listNpmPackages() {
|
|
181
|
+
try {
|
|
182
|
+
const stdout = await (0, commons_1.exec)("npm", ["list", "--json"], {
|
|
183
|
+
cwd: this.workingDirectory,
|
|
184
|
+
});
|
|
185
|
+
commons_1.logger.debug(`Listing npm packages using "npm list --json": ${stdout}`);
|
|
186
|
+
const json = npmListSchema.parse(JSON.parse(stdout));
|
|
187
|
+
return Object.entries((json === null || json === void 0 ? void 0 : json.dependencies) || {})
|
|
188
|
+
.filter(([depName]) => depName.startsWith("@cdktf/provider-") ||
|
|
189
|
+
depName.startsWith("@cdktn/provider-"))
|
|
190
|
+
.map(([name, dep]) => ({ name, version: dep.version }));
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
throw new Error(`Could not determine installed packages using 'npm list --json': ${e.message}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async listProviderPackages() {
|
|
197
|
+
return this.hasYarnLockfile()
|
|
198
|
+
? this.listYarnPackages()
|
|
199
|
+
: this.listNpmPackages();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
class PythonPackageManager extends PackageManager {
|
|
203
|
+
get appCommand() {
|
|
204
|
+
try {
|
|
205
|
+
return JSON.parse(fs.readFileSync(path_1.default.resolve(this.workingDirectory, "cdktf.json"), "utf8"))["app"];
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
throw commons_1.Errors.Usage(`Could not find find and parse cdktf.json in ${this.workingDirectory}`, e);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async addPackage(packageName, packageVersion) {
|
|
212
|
+
const usePipenv = this.appCommand.includes("pipenv");
|
|
213
|
+
if (usePipenv) {
|
|
214
|
+
console.log(`Installing package ${packageName} @ ${packageVersion} using pipenv.`);
|
|
215
|
+
await (0, commons_1.exec)("pipenv", ["install", `${packageName}~=${packageVersion}`], {
|
|
216
|
+
cwd: this.workingDirectory,
|
|
217
|
+
env: {
|
|
218
|
+
...process.env,
|
|
219
|
+
PIPENV_QUIET: "1",
|
|
220
|
+
},
|
|
221
|
+
stdio: ["inherit", 1, 1],
|
|
222
|
+
});
|
|
223
|
+
console.log("Package installed.");
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
console.log(`Installing package ${packageName} @ ${packageVersion} using pip.`);
|
|
227
|
+
const requirementsFilePath = path_1.default.join(this.workingDirectory, "requirements.txt");
|
|
228
|
+
if (!fs.existsSync(requirementsFilePath)) {
|
|
229
|
+
throw commons_1.Errors.Usage(`Could not find requirements.txt in ${this.workingDirectory}`);
|
|
230
|
+
}
|
|
231
|
+
const requirements = await fs.readFile(requirementsFilePath, "utf8");
|
|
232
|
+
const requirementLine = requirements
|
|
233
|
+
.split("\n")
|
|
234
|
+
.find((line) => line.includes(packageName));
|
|
235
|
+
commons_1.logger.debug(`Read requirements.txt file and found line including ${packageName}: ${requirementLine}`);
|
|
236
|
+
if (requirementLine) {
|
|
237
|
+
if (packageVersion ? requirementLine.includes(packageVersion) : true) {
|
|
238
|
+
commons_1.logger.info(`Package ${packageName} already installed. Skipping installation.`);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
commons_1.logger.debug(`Found the package but with a different version, continuing`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const newRequirements = requirements
|
|
246
|
+
.split("\n")
|
|
247
|
+
.filter((line) => !line.startsWith(packageName))
|
|
248
|
+
.join("\n") +
|
|
249
|
+
`\n${packageName}${packageVersion ? `~=${packageVersion}` : ""}`;
|
|
250
|
+
await fs.writeFile(requirementsFilePath, newRequirements, "utf8");
|
|
251
|
+
await (0, commons_1.exec)("pip", ["install", "-r", "requirements.txt"], {
|
|
252
|
+
cwd: this.workingDirectory,
|
|
253
|
+
stdio: ["inherit", 1, 1],
|
|
254
|
+
});
|
|
255
|
+
console.log("Package installed.");
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
async isNpmVersionAvailable(packageName, packageVersion) {
|
|
259
|
+
commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available for Python`);
|
|
260
|
+
const url = `https://pypi.org/pypi/${packageName}/${packageVersion}/json`;
|
|
261
|
+
commons_1.logger.debug(`Fetching package information for ${packageName} from ${url}`);
|
|
262
|
+
const response = await (0, node_fetch_1.default)(url);
|
|
263
|
+
const json = (await response.json());
|
|
264
|
+
commons_1.logger.debug(`Got response from PyPI for ${packageName}@${packageVersion}: ${JSON.stringify(json)}`);
|
|
265
|
+
if (json.info) {
|
|
266
|
+
// We found the version, so it exists
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
commons_1.logger.debug(`Could not get PyPI package info, got: ${JSON.stringify(json)}`);
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
async listPipenvPackages() {
|
|
275
|
+
try {
|
|
276
|
+
const stdout = await (0, commons_1.exec)("pipenv", ["run", "pip", "list", "--format=json"], {
|
|
277
|
+
cwd: this.workingDirectory,
|
|
278
|
+
});
|
|
279
|
+
commons_1.logger.debug(`Listing pipenv packages using "pipenv run pip list --format=json": ${stdout}`);
|
|
280
|
+
const list = pipPackageSchema.parse(JSON.parse(stdout));
|
|
281
|
+
return list.filter((item) => item.name.startsWith("cdktf-cdktf-provider") ||
|
|
282
|
+
item.name.startsWith("cdktn-provider"));
|
|
283
|
+
}
|
|
284
|
+
catch (e) {
|
|
285
|
+
throw new Error(`Could not determine installed packages using 'pipenv run pip list --format=json': ${e.message}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async listPipPackages() {
|
|
289
|
+
try {
|
|
290
|
+
const stdout = await (0, commons_1.exec)("pip", ["list", "--format=json"], {
|
|
291
|
+
cwd: this.workingDirectory,
|
|
292
|
+
});
|
|
293
|
+
commons_1.logger.debug(`Listing pip packages using "pip list --format=json": ${stdout}`);
|
|
294
|
+
const list = pipPackageSchema.parse(JSON.parse(stdout));
|
|
295
|
+
return list.filter((item) => item.name.startsWith("cdktf-cdktf-provider") ||
|
|
296
|
+
item.name.startsWith("cdktn-provider"));
|
|
297
|
+
}
|
|
298
|
+
catch (e) {
|
|
299
|
+
throw new Error(`Could not determine installed packages using 'pip list --format=json': ${e.message}`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
async listProviderPackages() {
|
|
303
|
+
return this.appCommand.includes("pipenv")
|
|
304
|
+
? this.listPipenvPackages()
|
|
305
|
+
: this.listPipPackages();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
class NugetPackageManager extends PackageManager {
|
|
309
|
+
async addPackage(packageName, packageVersion) {
|
|
310
|
+
const command = "dotnet";
|
|
311
|
+
const args = ["add", "package", packageName];
|
|
312
|
+
if (packageVersion) {
|
|
313
|
+
args.push("--version", packageVersion);
|
|
314
|
+
}
|
|
315
|
+
console.log(`Installing package ${packageName} @ ${packageVersion} using "${command} ${args.join(" ")}".`);
|
|
316
|
+
await (0, commons_1.exec)(command, args, { cwd: this.workingDirectory });
|
|
317
|
+
console.log("Package installed.");
|
|
318
|
+
}
|
|
319
|
+
async isNpmVersionAvailable(packageName, packageVersion) {
|
|
320
|
+
var _a, _b, _c;
|
|
321
|
+
commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available`);
|
|
322
|
+
const [owner, ...rest] = packageName.split(".");
|
|
323
|
+
const id = rest[rest.length - 1];
|
|
324
|
+
const url = `https://azuresearch-usnc.nuget.org/query?q=owner:${owner}%20id:${id}&prerelease=false&semVerLevel=2.0.0`;
|
|
325
|
+
commons_1.logger.debug(`Fetching package metadata from Nuget: '${url}'`);
|
|
326
|
+
const response = await (0, node_fetch_1.default)(url);
|
|
327
|
+
const json = (await response.json());
|
|
328
|
+
commons_1.logger.debug(`Got response from NuGet for ${packageName} : ${JSON.stringify(json)}`);
|
|
329
|
+
if (!((_a = json === null || json === void 0 ? void 0 : json.data) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
330
|
+
return false; // No package found
|
|
331
|
+
}
|
|
332
|
+
const packageVersions = (_c = (_b = json.data.find((p) => p.id === packageName)) === null || _b === void 0 ? void 0 : _b.versions) !== null && _c !== void 0 ? _c : [];
|
|
333
|
+
if (!packageVersions.length) {
|
|
334
|
+
return false; // No package release matching the id found
|
|
335
|
+
}
|
|
336
|
+
return packageVersions.some((v) => v.version === packageVersion);
|
|
337
|
+
}
|
|
338
|
+
async listProviderPackages() {
|
|
339
|
+
try {
|
|
340
|
+
const stdout = await (0, commons_1.exec)("dotnet", ["list", "package"], {
|
|
341
|
+
cwd: this.workingDirectory,
|
|
342
|
+
});
|
|
343
|
+
commons_1.logger.debug(`Listing nuget packages using "dotnet list package": ${stdout}`);
|
|
344
|
+
const regex = /^\s*>\s((?:HashiCorp\.Cdktf|Io\.Cdktn)\.Providers\.[\w.]+)\s+((?:\d+\.){2}\d+(?:-\S+)?)\s+((?:\d+\.){2}\d+(?:-\S+)?)\s*$/;
|
|
345
|
+
return stdout
|
|
346
|
+
.split("\n")
|
|
347
|
+
.map((line) => {
|
|
348
|
+
// Example output:
|
|
349
|
+
// Project 'MyTerraformStack' has the following package references
|
|
350
|
+
// [net6.0]:
|
|
351
|
+
// Top-level Package Requested Resolved
|
|
352
|
+
// > HashiCorp.Cdktf 0.0.0 0.0.0
|
|
353
|
+
// match[0] = full match
|
|
354
|
+
// match[1] = package name
|
|
355
|
+
// match[2] = requested version
|
|
356
|
+
// match[3] = resolved version
|
|
357
|
+
return regex.exec(line);
|
|
358
|
+
})
|
|
359
|
+
.filter((match) => !!match)
|
|
360
|
+
.map((match) => ({ name: match[1], version: match[3] }));
|
|
361
|
+
}
|
|
362
|
+
catch (e) {
|
|
363
|
+
throw new Error(`Could not determine installed packages using 'dotnet list package': ${e.message}`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
class JavaPackageManager extends PackageManager {
|
|
368
|
+
async isNpmVersionAvailable(packageName, packageVersion) {
|
|
369
|
+
var _a, _b;
|
|
370
|
+
commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available`);
|
|
371
|
+
const parts = packageName.split(".");
|
|
372
|
+
if (parts.length !== 3) {
|
|
373
|
+
throw commons_1.Errors.Internal(`Expected package name to be in format "group.artifact", e.g. "com.hashicorp.cdktf-provider-google", got: ${packageName}`);
|
|
374
|
+
}
|
|
375
|
+
const packageIdentifier = parts.pop();
|
|
376
|
+
const groupId = parts.join(".");
|
|
377
|
+
const url = `https://search.maven.org/solrsearch/select?q=g:${groupId}+AND+a:${packageIdentifier}+AND+v:${packageVersion}&rows=5&wt=json`;
|
|
378
|
+
commons_1.logger.debug(`Trying to find package version by querying Maven Central under '${url}'`);
|
|
379
|
+
const response = await (0, node_fetch_1.default)(url);
|
|
380
|
+
const json = (await response.json());
|
|
381
|
+
commons_1.logger.debug(`Got response from the Maven package search for ${packageName}: ${JSON.stringify(json)}`);
|
|
382
|
+
return ((_b = (_a = json === null || json === void 0 ? void 0 : json.response) === null || _a === void 0 ? void 0 : _a.numFound) !== null && _b !== void 0 ? _b : 0) > 0;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
class MavenPackageManager extends JavaPackageManager {
|
|
386
|
+
async addPackage(packageName, packageVersion = "LATEST") {
|
|
387
|
+
var _a, _b, _c, _d;
|
|
388
|
+
console.log(`Adding ${packageName} @ ${packageVersion} to pom.xml`);
|
|
389
|
+
// Assert pom.xml exists
|
|
390
|
+
const pomPath = path_1.default.join(this.workingDirectory, "pom.xml");
|
|
391
|
+
if (!(0, fs_extra_1.existsSync)(pomPath)) {
|
|
392
|
+
throw commons_1.Errors.Usage("No pom.xml found in current working directory. Please run the command from the root of your project.");
|
|
393
|
+
}
|
|
394
|
+
const pom = await fs.readFile(pomPath, "utf8");
|
|
395
|
+
const pomXml = (await (0, xml_js_1.xml2js)(pom, {}));
|
|
396
|
+
// Mutate dependencies
|
|
397
|
+
const nameParts = packageName.split(".");
|
|
398
|
+
const groupId = nameParts.slice(0, nameParts.length - 1).join(".");
|
|
399
|
+
const artifactId = nameParts[nameParts.length - 1];
|
|
400
|
+
const newDependency = (await (0, xml_js_1.xml2js)(`<dependency>
|
|
401
|
+
<groupId>${groupId}</groupId>
|
|
402
|
+
<artifactId>${artifactId}</artifactId>
|
|
403
|
+
<version>${packageVersion}</version>
|
|
404
|
+
</dependency>`));
|
|
405
|
+
const dependencies = (_c = (_b = (_a = pomXml.elements) === null || _a === void 0 ? void 0 : _a.find((el) => el.name === "project")) === null || _b === void 0 ? void 0 : _b.elements) === null || _c === void 0 ? void 0 : _c.find((el) => el.name === "dependencies");
|
|
406
|
+
if (!dependencies) {
|
|
407
|
+
throw commons_1.Errors.Usage(`Could not find dependencies section in the pom.xml`);
|
|
408
|
+
}
|
|
409
|
+
dependencies.elements = ((dependencies === null || dependencies === void 0 ? void 0 : dependencies.elements) || []).filter((el) => {
|
|
410
|
+
var _a, _b;
|
|
411
|
+
return ((_a = el.elements) === null || _a === void 0 ? void 0 : _a.some((group) => { var _a; return group.name === "groupId" && ((_a = group.elements) === null || _a === void 0 ? void 0 : _a[0].text) !== groupId; })) ||
|
|
412
|
+
((_b = el.elements) === null || _b === void 0 ? void 0 : _b.some((artifact) => {
|
|
413
|
+
var _a;
|
|
414
|
+
return artifact.name === "artifactId" &&
|
|
415
|
+
((_a = artifact.elements) === null || _a === void 0 ? void 0 : _a[0].text) !== artifactId;
|
|
416
|
+
}));
|
|
417
|
+
});
|
|
418
|
+
(_d = dependencies === null || dependencies === void 0 ? void 0 : dependencies.elements) === null || _d === void 0 ? void 0 : _d.push(newDependency.elements[0]);
|
|
419
|
+
// Write new pom.xml
|
|
420
|
+
await fs.writeFile(pomPath, (0, xml_js_1.js2xml)(pomXml, { spaces: 2 }));
|
|
421
|
+
// Install
|
|
422
|
+
await (0, commons_1.exec)("mvn", ["install"], { cwd: this.workingDirectory });
|
|
423
|
+
console.log("Package installed.");
|
|
424
|
+
}
|
|
425
|
+
async listProviderPackages() {
|
|
426
|
+
var _a, _b, _c, _d, _e;
|
|
427
|
+
try {
|
|
428
|
+
const pomPath = path_1.default.join(this.workingDirectory, "pom.xml");
|
|
429
|
+
if (!(0, fs_extra_1.existsSync)(pomPath)) {
|
|
430
|
+
throw commons_1.Errors.Usage("No pom.xml found in current working directory. Please run the command from the root of your project.");
|
|
431
|
+
}
|
|
432
|
+
const pom = await fs.readFile(pomPath, "utf8");
|
|
433
|
+
const pomXml = (await (0, xml_js_1.xml2js)(pom, {}));
|
|
434
|
+
const dependencies = (_e = (_d = (_c = (_b = (_a = pomXml.elements) === null || _a === void 0 ? void 0 : _a.find((el) => el.name === "project")) === null || _b === void 0 ? void 0 : _b.elements) === null || _c === void 0 ? void 0 : _c.find((el) => el.name === "dependencies")) === null || _d === void 0 ? void 0 : _d.elements) !== null && _e !== void 0 ? _e : [];
|
|
435
|
+
return dependencies
|
|
436
|
+
.map((dep) => {
|
|
437
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
438
|
+
return ({
|
|
439
|
+
name: `${(_c = (_b = (_a = dep.elements) === null || _a === void 0 ? void 0 : _a.find((el) => el.name === "groupId")) === null || _b === void 0 ? void 0 : _b.elements) === null || _c === void 0 ? void 0 : _c[0].text}.${(_f = (_e = (_d = dep.elements) === null || _d === void 0 ? void 0 : _d.find((el) => el.name === "artifactId")) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f[0].text}`,
|
|
440
|
+
version: (_j = (_h = (_g = dep.elements) === null || _g === void 0 ? void 0 : _g.find((el) => el.name === "version")) === null || _h === void 0 ? void 0 : _h.elements) === null || _j === void 0 ? void 0 : _j[0].text,
|
|
441
|
+
});
|
|
442
|
+
})
|
|
443
|
+
.filter((dep) => dep.name.startsWith("com.hashicorp.cdktf-provider-") ||
|
|
444
|
+
dep.name.startsWith("io.cdktn.cdktn-provider-"));
|
|
445
|
+
}
|
|
446
|
+
catch (e) {
|
|
447
|
+
throw new Error(`Could not determine installed packages reading the pom.xml: ${e.message}`);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
class GradlePackageManager extends JavaPackageManager {
|
|
452
|
+
static isGradleProject(workingDirectory) {
|
|
453
|
+
return (0, commons_1.isGradleProject)(workingDirectory);
|
|
454
|
+
}
|
|
455
|
+
async addPackage(packageFQN, packageVersion = "latest.release") {
|
|
456
|
+
const buildGradlePath = path_1.default.join(this.workingDirectory, "build.gradle");
|
|
457
|
+
const buildGradle = await fs.readFile(buildGradlePath, "utf8");
|
|
458
|
+
const buildGradleLines = buildGradle.split(/\r?\n/);
|
|
459
|
+
const dependenciesRegex = /dependencies\s+\{/i;
|
|
460
|
+
const dependencyBlockStart = buildGradleLines.findIndex((line) => dependenciesRegex.test(line));
|
|
461
|
+
if (dependencyBlockStart === -1) {
|
|
462
|
+
throw commons_1.Errors.Usage("Could not find dependencies section in the build.gradle");
|
|
463
|
+
}
|
|
464
|
+
const packageSegments = packageFQN.split(".");
|
|
465
|
+
const packageName = packageSegments.pop();
|
|
466
|
+
const groupName = packageSegments.join(".");
|
|
467
|
+
const dependencySpecifier = `${groupName}:${packageName}`;
|
|
468
|
+
const dependencyAndVersionSpecifier = `${dependencySpecifier}:${packageVersion}`;
|
|
469
|
+
const existingDependency = buildGradleLines.findIndex((line) => line.includes(dependencySpecifier));
|
|
470
|
+
if (existingDependency !== -1) {
|
|
471
|
+
buildGradleLines.splice(existingDependency, 1);
|
|
472
|
+
}
|
|
473
|
+
const newPackageDependency = `\timplementation '${dependencyAndVersionSpecifier}'`;
|
|
474
|
+
buildGradleLines.splice(dependencyBlockStart + 1, 0, newPackageDependency);
|
|
475
|
+
await fs.writeFile(buildGradlePath, buildGradleLines.join("\n"));
|
|
476
|
+
}
|
|
477
|
+
async listProviderPackages() {
|
|
478
|
+
const dependencies = await (0, commons_1.getGradleDependencies)();
|
|
479
|
+
if (!dependencies) {
|
|
480
|
+
throw commons_1.Errors.Usage("Could not find any dependencies");
|
|
481
|
+
}
|
|
482
|
+
const dependencyList = dependencies
|
|
483
|
+
.map((line) => (0, commons_1.getDependencyInformationFromLine)(line))
|
|
484
|
+
.filter((dep) => {
|
|
485
|
+
if (!dep) {
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
488
|
+
return (dep.name.includes("cdktf-provider-") ||
|
|
489
|
+
dep.name.includes("cdktn-provider-"));
|
|
490
|
+
})
|
|
491
|
+
.map((dep) => ({
|
|
492
|
+
name: `com.hashicorp.${dep.name}`,
|
|
493
|
+
version: dep.version,
|
|
494
|
+
}));
|
|
495
|
+
return dependencyList;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
class GoPackageManager extends PackageManager {
|
|
499
|
+
async addPackage(packageName, packageVersion) {
|
|
500
|
+
console.log(`Adding package ${packageName} @ ${packageVersion}`);
|
|
501
|
+
const majorVersion = packageVersion
|
|
502
|
+
? semver.major(packageVersion)
|
|
503
|
+
: undefined;
|
|
504
|
+
let versionPackageSuffix = "";
|
|
505
|
+
if (typeof majorVersion === "number" && majorVersion > 1) {
|
|
506
|
+
versionPackageSuffix = `/v${majorVersion}`;
|
|
507
|
+
}
|
|
508
|
+
commons_1.logger.debug(`Running 'go get ${packageName}${versionPackageSuffix}@v${packageVersion}'`);
|
|
509
|
+
// Install
|
|
510
|
+
await (0, commons_1.exec)("go", ["get", `${packageName}${versionPackageSuffix}@v${packageVersion}`], {
|
|
511
|
+
cwd: this.workingDirectory,
|
|
512
|
+
});
|
|
513
|
+
console.log("Package installed.");
|
|
514
|
+
}
|
|
515
|
+
async isNpmVersionAvailable(packageName, packageVersion) {
|
|
516
|
+
commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available`);
|
|
517
|
+
// e.g. github.com/cdktf/cdktf-provider-google-go/google
|
|
518
|
+
const parts = packageName.split("/");
|
|
519
|
+
if (parts.length !== 4) {
|
|
520
|
+
throw commons_1.Errors.Internal(`Expecting Go package name to be in the format of github.com/<org>/<repo>/<package>, got ${packageName}`);
|
|
521
|
+
}
|
|
522
|
+
const org = parts[1];
|
|
523
|
+
const repo = parts[2];
|
|
524
|
+
const packagePath = parts[3];
|
|
525
|
+
const url = `https://api.github.com/repos/${org}/${repo}/git/ref/tags/${packagePath}/v${packageVersion}`;
|
|
526
|
+
commons_1.logger.debug(`Fetching tags for ${org}/${repo} from '${url}'`);
|
|
527
|
+
const response = await (0, node_fetch_1.default)(url, {
|
|
528
|
+
headers: {
|
|
529
|
+
Accept: "application/vnd.github+json",
|
|
530
|
+
"User-Agent": "OpenConstructs/cdktn-cli",
|
|
531
|
+
...(GITHUB_API_TOKEN_CDKTF
|
|
532
|
+
? { Authorization: `Bearer ${GITHUB_API_TOKEN_CDKTF}` }
|
|
533
|
+
: {}),
|
|
534
|
+
},
|
|
535
|
+
});
|
|
536
|
+
const json = (await response.json());
|
|
537
|
+
commons_1.logger.debug(`Got response from GitHubs repository tag endpoint for ${packageName}: ${JSON.stringify(json)}`);
|
|
538
|
+
if (json && json.ref) {
|
|
539
|
+
return true;
|
|
540
|
+
}
|
|
541
|
+
commons_1.logger.info(`Could not find the tag ${packagePath}/v${packageVersion} in the repository ${org}/${repo}: ${JSON.stringify(json)}}`);
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
async listProviderPackages() {
|
|
545
|
+
try {
|
|
546
|
+
const goSumPath = path_1.default.join(this.workingDirectory, "go.sum");
|
|
547
|
+
if (!(0, fs_extra_1.existsSync)(goSumPath)) {
|
|
548
|
+
throw commons_1.Errors.Usage("No go.sum found in current working directory. Please run the command from the root of your project.");
|
|
549
|
+
}
|
|
550
|
+
const goSum = await fs.readFile(goSumPath, "utf8");
|
|
551
|
+
const dedupedProviderNames = new Set();
|
|
552
|
+
return goSum
|
|
553
|
+
.split("\n")
|
|
554
|
+
.filter((line) => line.startsWith("github.com/hashicorp/cdktf-provider") ||
|
|
555
|
+
line.startsWith("github.com/cdktf/cdktf-provider") ||
|
|
556
|
+
line.startsWith("github.com/cdktn-io/cdktn-provider"))
|
|
557
|
+
.map((line) => {
|
|
558
|
+
const parts = line.split(" ");
|
|
559
|
+
if (parts.length !== 3) {
|
|
560
|
+
throw commons_1.Errors.Internal(`Expected line in go.sum to be in the format of '<package> <version> <checksum>', got: ${line}`);
|
|
561
|
+
}
|
|
562
|
+
// part[0] could be github.com/aws/constructs-go/constructs/v10
|
|
563
|
+
const name = parts[0].split("/").slice(0, 4).join("/");
|
|
564
|
+
const version = parts[1].split("/")[0];
|
|
565
|
+
if (dedupedProviderNames.has(name)) {
|
|
566
|
+
return { name: "", version: "" };
|
|
567
|
+
}
|
|
568
|
+
dedupedProviderNames.add(name);
|
|
569
|
+
return {
|
|
570
|
+
name,
|
|
571
|
+
version,
|
|
572
|
+
};
|
|
573
|
+
})
|
|
574
|
+
.filter((providerInfo) => !!providerInfo.name && !!providerInfo.version);
|
|
575
|
+
}
|
|
576
|
+
catch (e) {
|
|
577
|
+
throw new Error(`Could not determine installed packages reading the go.sum: ${e.message}`);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFja2FnZS1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicGFja2FnZS1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsK0JBQStCO0FBQy9CLG1DQUFtQztBQUNuQyw0Q0FRd0I7QUFDeEIsdUNBQXNDO0FBQ3RDLGdEQUF3QjtBQUN4QixtQ0FBaUQ7QUFDakQsNkNBQStCO0FBQy9CLCtDQUFpQztBQUNqQyw0REFBK0I7QUFDL0IsdUNBQXlCO0FBRXpCLDZGQUE2RjtBQUM3RixzREFBc0Q7QUFDdEQsTUFBTSxFQUFFLHNCQUFzQixFQUFFLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQztBQUUvQyxJQUFJO0FBQ0osd0JBQXdCO0FBQ3hCLDBCQUEwQjtBQUMxQixrQkFBa0I7QUFDbEIsMElBQTBJO0FBQzFJLE9BQU87QUFDUCxzQkFBc0I7QUFDdEIsa0NBQWtDO0FBQ2xDLDZCQUE2QjtBQUM3QixxR0FBcUc7QUFDckcsU0FBUztBQUNULE1BQU0sYUFBYSxHQUFHLENBQUM7S0FDcEIsTUFBTSxDQUFDO0lBQ04sWUFBWSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQ3BCLENBQUM7U0FDRSxNQUFNLENBQUM7UUFDTixPQUFPLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtLQUNwQixDQUFDO1NBQ0QsU0FBUyxFQUFFLENBQ2Y7Q0FDRixDQUFDO0tBQ0QsV0FBVyxFQUFFO0tBQ2IsU0FBUyxFQUFFLENBQUM7QUFFZixJQUFJO0FBQ0osb0JBQW9CO0FBQ3BCLGNBQWM7QUFDZCxzQkFBc0I7QUFDdEIsaUJBQWlCO0FBQ2pCLFVBQVU7QUFDVixtREFBbUQ7QUFDbkQsMEJBQTBCO0FBQzFCLHdCQUF3QjtBQUN4QiwyQkFBMkI7QUFDM0IscUJBQXFCO0FBQ3JCLFVBQVU7QUFDVixRQUFRO0FBQ1IsTUFBTTtBQUNOLElBQUk7QUFDSixNQUFNLGNBQWMsR0FBRyxDQUFDO0tBQ3JCLE1B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Q0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUV2QyxJQUFJLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNuQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQUM7Z0JBQ25DLENBQUM7Z0JBRUQsb0JBQW9CLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUUvQixPQUFPO29CQUNMLElBQUk7b0JBQ0osT0FBTztpQkFDUixDQUFDO1lBQ0osQ0FBQyxDQUFDO2lCQUNELE1BQU0sQ0FDTCxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQ2hFLENBQUM7UUFDTixDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksS0FBSyxDQUNiLDhEQUE4RCxDQUFDLENBQUMsT0FBTyxFQUFFLENBQzFFLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSBIYXNoaUNvcnAsIEluY1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1QTC0yLjBcbmltcG9ydCB7XG4gIExhbmd1YWdlLFxuICBleGVjLFxuICBFcnJvcnMsXG4gIGxvZ2dlcixcbiAgaXNHcmFkbGVQcm9qZWN0LFxuICBnZXRHcmFkbGVEZXBlbmRlbmNpZXMsXG4gIGdldERlcGVuZGVuY3lJbmZvcm1hdGlvbkZyb21MaW5lLFxufSBmcm9tIFwiQGNka3RuL2NvbW1vbnNcIjtcbmltcG9ydCB7IGV4aXN0c1N5bmMgfSBmcm9tIFwiZnMtZXh0cmFcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyB4bWwyanMsIGpzMnhtbCwgRWxlbWVudCB9IGZyb20gXCJ4bWwtanNcIjtcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJmcy1leHRyYVwiO1xuaW1wb3J0ICogYXMgc2VtdmVyIGZyb20gXCJzZW12ZXJcIjtcbmltcG9ydCBmZXRjaCBmcm9tIFwibm9kZS1mZXRjaFwiO1xuaW1wb3J0ICogYXMgeiBmcm9tIFwiem9kXCI7XG5cbi8vIENhbid0IHVzZSBDREtURl8gYXMgcHJlZml4IGJlY2F1c2UgeWFyZ3MgLmVudihcIkNES1RGXCIpIGluIHN0cmljdCBtb2RlIGRvZXMgbm90IGFsbG93IHVzIHRvXG4vLyBSZWZlciB0bzogaHR0cHM6Ly9naXRodWIuY29tL3lhcmdzL3lhcmdzL2lzc3Vlcy84NzNcbmNvbnN0IHsgR0lUSFVCX0FQSV9UT0tFTl9DREtURiB9ID0gcHJvY2Vzcy5lbnY7XG5cbi8vIHtcbi8vICAgXCJ2ZXJzaW9uXCI6IFwiMS4wLjBcIixcbi8vICAgXCJuYW1lXCI6IFwidGVzdFVTSGFzRlwiLFxuLy8gICBcInByb2JsZW1zXCI6IFtcbi8vICAgICBcImV4dHJhbmVvdXM6IGFyY2hpdmVyLXV0aWxzQDIuMS4wIC9wcml2YXRlL3Zhci9mb2xkZXJzL3pfL3YwM2wzM2Q1NWZiNTducnIzYjFxMDNjaDAwMDBncS9UL3Rlc3RVU0hhc0Yvbm9kZV9tb2R1bGVzL2FyY2hpdmVyLXV0aWxzXCIsXG4vLyAgIF0sXG4vLyAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbi8vICAgICBcIkBjZGt0Zi9wcm92aWRlci1yYW5kb21cIjoge1xuLy8gICAgICAgXCJ2ZXJzaW9uXCI6IFwiMy4wLjExXCIsXG4vLyAgICAgICBcInJlc29sdmVkXCI6IFwiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvQGNka3RmL3Byb3ZpZGVyLXJhbmRvbS8tL3Byb3ZpZGVyLXJhbmRvbS0zLjAuMTEudGd6XCJcbi8vICAgICB9LFxuY29uc3QgbnBtTGlzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZGVwZW5kZW5jaWVzOiB6LnJlY29yZChcbiAgICAgIHpcbiAgICAgICAgLm9iamVjdCh7XG4gICAgICAgICAgdmVyc2lvbjogei5zdHJpbmcoKSxcbiAgICAgICAgfSlcbiAgICAgICAgLm5vbnN0cmljdCgpLFxuICAgICksXG4gIH0pXG4gIC5kZWVwUGFydGlhbCgpXG4gIC5ub25zdHJpY3QoKTtcblxuLy8ge1xuLy8gICBcInR5cGVcIjogXCJ0cmVlXCIsXG4vLyAgIFwiZGF0YVwiOiB7XG4vLyAgICAgXCJ0eXBlXCI6IFwibGlzdFwiLFxuLy8gICAgIFwidHJlZXNcIjogW1xuLy8gICAgICAge1xuLy8gICAgICAgICBcIm5hbWVcIjogXCJAY2RrdGYvcHJvdmlkZXItcmFuZG9tQDMuMC4xMVwiLFxuLy8gICAgICAgICBcImNoaWxkcmVuXCI6IFtdLFxuLy8gICAgICAgICBcImhpbnRcIjogbnVsbCxcbi8vICAgICAgICAgXCJjb2xvclwiOiBcImJvbGRcIixcbi8vICAgICAgICAgXCJkZXB0aFwiOiAwXG4vLyAgICAgICB9XG4vLyAgICAgXVxuLy8gICB9XG4vLyB9XG5jb25zdCB5YXJuTGlzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZGF0YTogelxuICAgICAgLm9iamVjdCh7XG4gICAgICAgIHRyZWVzOiB6LmFycmF5KFxuICAgICAgICAgIHpcbiAgICAgICAgICAgIC5vYmplY3Qoe1xuICAgICAgICAgICAgICBuYW1lOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5ub25zdHJpY3QoKSxcbiAgICAgICAgKSxcbiAgICAgIH0pXG4gICAgICAubm9uc3RyaWN0KCksXG4gIH0pXG4gIC5kZWVwUGFydGlhbCgpXG4gIC5ub25zdHJpY3QoKTtcblxuLy8gW1xuLy8gICB7XG4vLyAgICAgXCJuYW1lXCI6IFwiYXBwZGlyc1wiLFxuLy8gICAgIFwidmVyc2lvblwiOiBcIjEuNC40XCJcbi8vICAgfSxcbi8vICAge1xuY29uc3QgcGlwUGFja2FnZVNjaGVtYSA9IHouYXJyYXkoXG4gIHoub2JqZWN0KHsgbmFtZTogei5zdHJpbmcoKSwgdmVyc2lvbjogei5zdHJpbmcoKSB9KS5ub25zdHJpY3QoKSxcbik7XG5cbi8qKlxuICogbWFuYWdlcyBpbnN0YWxsaW5nLCB1cGRhdGluZywgYW5kIHJlbW92aW5nIGRlcGVuZGVuY2llc1xuICogaW4gdGhlIHBhY2thZ2Ugc3lzdGVtIHVzZWQgYnkgdGhlIHRhcmdldCBsYW5ndWFnZSBvZiBhIENES1ROXG4gKiBwcm9qZWN0XG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBQYWNrYWdlTWFuYWdlciB7XG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCByZWFkb25seSB3b3JraW5nRGlyZWN0b3J5OiBzdHJpbmcpIHt9XG5cbiAgcHVibGljIHN0YXRpYyBmb3JMYW5ndWFnZShcbiAgICBsYW5ndWFnZTogTGFuZ3VhZ2UsXG4gICAgd29ya2luZ0RpcmVjdG9yeTogc3RyaW5nLFxuICApOiBQYWNrYWdlTWFuYWdlciB7XG4gICAgc3dpdGNoIChsYW5ndWFnZSkge1xuICAgICAgY2FzZSBMYW5ndWFnZS5HTzpcbiAgICAgICAgcmV0dXJuIG5ldyBHb1BhY2thZ2VNYW5hZ2VyKHdvcmtpbmdEaXJlY3RvcnkpO1xuICAgICAgY2FzZSBMYW5ndWFnZS5UWVBFU0NSSVBUOlxuICAgICAgICByZXR1cm4gbmV3IE5vZGVQYWNrYWdlTWFuYWdlcih3b3JraW5nRGlyZWN0b3J5KTtcbiAgICAgIGNhc2UgTGFuZ3VhZ2UuUFlUSE9OOlxuICAgICAgICByZXR1cm4gbmV3IFB5dGhvblBhY2thZ2VNYW5hZ2VyKHdvcmtpbmdEaXJlY3RvcnkpO1xuICAgICAgY2FzZSBMYW5ndWFnZS5DU0hBUlA6XG4gICAgICAgIHJldHVybiBuZXcgTnVnZXRQYWNrYWdlTWFuYWdlcih3b3JraW5nRGlyZWN0b3J5KTtcbiAgICAgIGNhc2UgTGFuZ3VhZ2UuSkFWQTpcbiAgICAgICAgaWYgKEdyYWRsZVBhY2thZ2VNYW5hZ2VyLmlzR3JhZGxlUHJvamVjdCh3b3JraW5nRGlyZWN0b3J5KSkge1xuICAgICAgICAgIHJldHVybiBuZXcgR3JhZGxlUGFja2FnZU1hbmFnZXIod29ya2luZ0RpcmVjdG9yeSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBNYXZlblBhY2thZ2VNYW5hZ2VyKHdvcmtpbmdEaXJlY3RvcnkpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGxhbmd1YWdlOiAke2xhbmd1YWdlfWApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhYnN0cmFjdCBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICAgc2lsZW50PzogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPjtcbiAgLy8gYWRkIGNoZWNrIGlmIHBhY2thZ2UgZXhpc3RzIGFscmVhZHkuIG1pZ2h0IHF1ZXJ5IHZlcnNpb24gaW4gdGhlIGZ1dHVyZSBhbmQgb2ZmZXIgdG8gdXBncmFkZT9cblxuICBwdWJsaWMgYWJzdHJhY3QgaXNOcG1WZXJzaW9uQXZhaWxhYmxlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPjtcblxuICBwdWJsaWMgYWJzdHJhY3QgbGlzdFByb3ZpZGVyUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+O1xufVxuXG5jbGFzcyBOb2RlUGFja2FnZU1hbmFnZXIgZXh0ZW5kcyBQYWNrYWdlTWFuYWdlciB7XG4gIHByaXZhdGUgaGFzWWFybkxvY2tmaWxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBleGlzdHNTeW5jKHBhdGguam9pbih0aGlzLndvcmtpbmdEaXJlY3RvcnksIFwieWFybi5sb2NrXCIpKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICAgc2lsZW50PzogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc29sZS5sb2coYEFkZGluZyBwYWNrYWdlICR7cGFja2FnZU5hbWV9IEAgJHtwYWNrYWdlVmVyc2lvbn1gKTtcblxuICAgIC8vIHByb2JlIGZvciBwYWNrYWdlLWxvY2suanNvbiBvciB5YXJuLmxvY2tcbiAgICBsZXQgY29tbWFuZCA9IFwibnBtXCI7XG4gICAgbGV0IGFyZ3MgPSBbXCJpbnN0YWxsXCJdO1xuXG4gICAgaWYgKHRoaXMuaGFzWWFybkxvY2tmaWxlKCkpIHtcbiAgICAgIGNvbW1hbmQgPSBcInlhcm5cIjtcbiAgICAgIGFyZ3MgPSBbXCJhZGRcIl07XG4gICAgfVxuICAgIGFyZ3MucHVzaChcbiAgICAgIHBhY2thZ2VWZXJzaW9uID8gcGFja2FnZU5hbWUgKyBcIkBcIiArIHBhY2thZ2VWZXJzaW9uIDogcGFja2FnZU5hbWUsXG4gICAgKTtcblxuICAgIGlmIChzaWxlbnQpIHtcbiAgICAgIGFyZ3MucHVzaChcIi0tc2lsZW50XCIpO1xuICAgICAgYXJncy5wdXNoKFwiLS1uby1wcm9ncmVzc1wiKTtcbiAgICB9XG5cbiAgICAvLyBJbnN0YWxsIGV4YWN0IHZlcnNpb25cbiAgICAvLyBZYXJuOiBodHRwczovL2NsYXNzaWMueWFybnBrZy5jb20vbGFuZy9lbi9kb2NzL2NsaS9hZGQvI3RvYy15YXJuLWFkZC1leGFjdC1lXG4gICAgLy8gTnBtOiBodHRwczovL2RvY3MubnBtanMuY29tL2NsaS92OC9jb21tYW5kcy9ucG0taW5zdGFsbCNzYXZlLWV4YWN0XG4gICAgYXJncy5wdXNoKFwiLUVcIik7XG5cbiAgICBsb2dnZXIuaW5mbyhcbiAgICAgIGBJbnN0YWxsaW5nIHBhY2thZ2UgJHtwYWNrYWdlTmFtZX0gQCAke3BhY2thZ2VWZXJzaW9ufSB1c2luZyAke2NvbW1hbmR9LmAsXG4gICAgKTtcblxuICAgIGF3YWl0IGV4ZWMoY29tbWFuZCwgYXJncywgeyBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSB9KTtcblxuICAgIGxvZ2dlci5pbmZvKFwiUGFja2FnZSBpbnN0YWxsZWQuXCIpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGlzTnBtVmVyc2lvbkF2YWlsYWJsZShcbiAgICBfcGFja2FnZU5hbWU6IHN0cmluZyxcbiAgICBfcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgLy8gV2UgZ2V0IHRoZSBsaXN0IG9mIGF2YWlsYWJsZSB2ZXJzaW9ucyBmcm9tIG5wbSwgbm8gbmVlZCB0byBjaGVjayBoZXJlXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxpc3RZYXJuUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcInlhcm5cIiwgW1wibGlzdFwiLCBcIi0tanNvblwiXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIH0pO1xuXG4gICAgICBsb2dnZXIuZGVidWcoYExpc3RpbmcgeWFybiBwYWNrYWdlcyB1c2luZyBcInlhcm4gbGlzdCAtLWpzb25cIjogJHtzdGRvdXR9YCk7XG5cbiAgICAgIGNvbnN0IGpzb24gPSB5YXJuTGlzdFNjaGVtYS5wYXJzZShKU09OLnBhcnNlKHN0ZG91dCkpO1xuXG4gICAgICByZXR1cm4gKGpzb24/LmRhdGE/LnRyZWVzIHx8IFtdKVxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChkZXA6IGFueSkgPT5cbiAgICAgICAgICAgIGRlcC5uYW1lLnN0YXJ0c1dpdGgoXCJAY2RrdGYvcHJvdmlkZXItXCIpIHx8XG4gICAgICAgICAgICBkZXAubmFtZS5zdGFydHNXaXRoKFwiQGNka3RuL3Byb3ZpZGVyLVwiKSxcbiAgICAgICAgKVxuICAgICAgICAubWFwKChkZXA6IGFueSkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBgQCR7ZGVwLm5hbWUuc3BsaXQoXCJAXCIpWzFdfWAsXG4gICAgICAgICAgdmVyc2lvbjogZGVwLm5hbWUuc3BsaXQoXCJAXCIpWzJdLFxuICAgICAgICB9KSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZGV0ZXJtaW5lIGluc3RhbGxlZCBwYWNrYWdlcyB1c2luZyAneWFybiBsaXN0IC0tanNvbic6ICR7ZS5tZXNzYWdlfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbGlzdE5wbVBhY2thZ2VzKCk6IFByb21pc2U8XG4gICAgeyBuYW1lOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZyB9W11cbiAgPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0ZG91dCA9IGF3YWl0IGV4ZWMoXCJucG1cIiwgW1wibGlzdFwiLCBcIi0tanNvblwiXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIH0pO1xuXG4gICAgICBsb2dnZXIuZGVidWcoYExpc3RpbmcgbnBtIHBhY2thZ2VzIHVzaW5nIFwibnBtIGxpc3QgLS1qc29uXCI6ICR7c3Rkb3V0fWApO1xuICAgICAgY29uc3QganNvbiA9IG5wbUxpc3RTY2hlbWEucGFyc2UoSlNPTi5wYXJzZShzdGRvdXQpKTtcblxuICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGpzb24/LmRlcGVuZGVuY2llcyB8fCB7fSlcbiAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAoW2RlcE5hbWVdKSA9PlxuICAgICAgICAgICAgZGVwTmFtZS5zdGFydHNXaXRoKFwiQGNka3RmL3Byb3ZpZGVyLVwiKSB8fFxuICAgICAgICAgICAgZGVwTmFtZS5zdGFydHNXaXRoKFwiQGNka3RuL3Byb3ZpZGVyLVwiKSxcbiAgICAgICAgKVxuICAgICAgICAubWFwKChbbmFtZSwgZGVwXSkgPT4gKHsgbmFtZSwgdmVyc2lvbjogZGVwLnZlcnNpb24gfSkpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ291bGQgbm90IGRldGVybWluZSBpbnN0YWxsZWQgcGFja2FnZXMgdXNpbmcgJ25wbSBsaXN0IC0tanNvbic6ICR7ZS5tZXNzYWdlfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UHJvdmlkZXJQYWNrYWdlcygpOiBQcm9taXNlPFxuICAgIHsgbmFtZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfVtdXG4gID4ge1xuICAgIHJldHVybiB0aGlzLmhhc1lhcm5Mb2NrZmlsZSgpXG4gICAgICA/IHRoaXMubGlzdFlhcm5QYWNrYWdlcygpXG4gICAgICA6IHRoaXMubGlzdE5wbVBhY2thZ2VzKCk7XG4gIH1cbn1cblxuY2xhc3MgUHl0aG9uUGFja2FnZU1hbmFnZXIgZXh0ZW5kcyBQYWNrYWdlTWFuYWdlciB7XG4gIHByaXZhdGUgZ2V0IGFwcENvbW1hbmQoKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKFxuICAgICAgICBmcy5yZWFkRmlsZVN5bmMoXG4gICAgICAgICAgcGF0aC5yZXNvbHZlKHRoaXMud29ya2luZ0RpcmVjdG9yeSwgXCJjZGt0Zi5qc29uXCIpLFxuICAgICAgICAgIFwidXRmOFwiLFxuICAgICAgICApLFxuICAgICAgKVtcImFwcFwiXTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IEVycm9ycy5Vc2FnZShcbiAgICAgICAgYENvdWxkIG5vdCBmaW5kIGZpbmQgYW5kIHBhcnNlIGNka3RmLmpzb24gaW4gJHt0aGlzLndvcmtpbmdEaXJlY3Rvcnl9YCxcbiAgICAgICAgZSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGFkZFBhY2thZ2UoXG4gICAgcGFja2FnZU5hbWU6IHN0cmluZyxcbiAgICBwYWNrYWdlVmVyc2lvbj86IHN0cmluZyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdXNlUGlwZW52ID0gdGhpcy5hcHBDb21tYW5kLmluY2x1ZGVzKFwicGlwZW52XCIpO1xuXG4gICAgaWYgKHVzZVBpcGVudikge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGBJbnN0YWxsaW5nIHBhY2thZ2UgJHtwYWNrYWdlTmFtZX0gQCAke3BhY2thZ2VWZXJzaW9ufSB1c2luZyBwaXBlbnYuYCxcbiAgICAgICk7XG5cbiAgICAgIGF3YWl0IGV4ZWMoXCJwaXBlbnZcIiwgW1wiaW5zdGFsbFwiLCBgJHtwYWNrYWdlTmFtZX1+PSR7cGFja2FnZVZlcnNpb259YF0sIHtcbiAgICAgICAgY3dkOiB0aGlzLndvcmtpbmdEaXJlY3RvcnksXG4gICAgICAgIGVudjoge1xuICAgICAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgICAgIFBJUEVOVl9RVUlFVDogXCIxXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHN0ZGlvOiBbXCJpbmhlcml0XCIsIDEsIDFdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnNvbGUubG9nKFwiUGFja2FnZSBpbnN0YWxsZWQuXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgYEluc3RhbGxpbmcgcGFja2FnZSAke3BhY2thZ2VOYW1lfSBAICR7cGFja2FnZVZlcnNpb259IHVzaW5nIHBpcC5gLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgcmVxdWlyZW1lbnRzRmlsZVBhdGggPSBwYXRoLmpvaW4oXG4gICAgICAgIHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgICAgXCJyZXF1aXJlbWVudHMudHh0XCIsXG4gICAgICApO1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHJlcXVpcmVtZW50c0ZpbGVQYXRoKSkge1xuICAgICAgICB0aHJvdyBFcnJvcnMuVXNhZ2UoXG4gICAgICAgICAgYENvdWxkIG5vdCBmaW5kIHJlcXVpcmVtZW50cy50eHQgaW4gJHt0aGlzLndvcmtpbmdEaXJlY3Rvcnl9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVxdWlyZW1lbnRzID0gYXdhaXQgZnMucmVhZEZpbGUocmVxdWlyZW1lbnRzRmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgIGNvbnN0IHJlcXVpcmVtZW50TGluZSA9IHJlcXVpcmVtZW50c1xuICAgICAgICAuc3BsaXQoXCJcXG5cIilcbiAgICAgICAgLmZpbmQoKGxpbmUpID0+IGxpbmUuaW5jbHVkZXMocGFja2FnZU5hbWUpKTtcblxuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgUmVhZCByZXF1aXJlbWVudHMudHh0IGZpbGUgYW5kIGZvdW5kIGxpbmUgaW5jbHVkaW5nICR7cGFja2FnZU5hbWV9OiAke3JlcXVpcmVtZW50TGluZX1gLFxuICAgICAgKTtcblxuICAgICAgaWYgKHJlcXVpcmVtZW50TGluZSkge1xuICAgICAgICBpZiAocGFja2FnZVZlcnNpb24gPyByZXF1aXJlbWVudExpbmUuaW5jbHVkZXMocGFja2FnZVZlcnNpb24pIDogdHJ1ZSkge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgYFBhY2thZ2UgJHtwYWNrYWdlTmFtZX0gYWxyZWFkeSBpbnN0YWxsZWQuIFNraXBwaW5nIGluc3RhbGxhdGlvbi5gLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgIGBGb3VuZCB0aGUgcGFja2FnZSBidXQgd2l0aCBhIGRpZmZlcmVudCB2ZXJzaW9uLCBjb250aW51aW5nYCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5ld1JlcXVpcmVtZW50cyA9XG4gICAgICAgIHJlcXVpcmVtZW50c1xuICAgICAgICAgIC5zcGxpdChcIlxcblwiKVxuICAgICAgICAgIC5maWx0ZXIoKGxpbmUpID0+ICFsaW5lLnN0YXJ0c1dpdGgocGFja2FnZU5hbWUpKVxuICAgICAgICAgIC5qb2luKFwiXFxuXCIpICtcbiAgICAgICAgYFxcbiR7cGFja2FnZU5hbWV9JHtwYWNrYWdlVmVyc2lvbiA/IGB+PSR7cGFja2FnZVZlcnNpb259YCA6IFwiXCJ9YDtcbiAgICAgIGF3YWl0IGZzLndyaXRlRmlsZShyZXF1aXJlbWVudHNGaWxlUGF0aCwgbmV3UmVxdWlyZW1lbnRzLCBcInV0ZjhcIik7XG5cbiAgICAgIGF3YWl0IGV4ZWMoXCJwaXBcIiwgW1wiaW5zdGFsbFwiLCBcIi1yXCIsIFwicmVxdWlyZW1lbnRzLnR4dFwiXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgICAgc3RkaW86IFtcImluaGVyaXRcIiwgMSwgMV0sXG4gICAgICB9KTtcblxuICAgICAgY29uc29sZS5sb2coXCJQYWNrYWdlIGluc3RhbGxlZC5cIik7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGlzTnBtVmVyc2lvbkF2YWlsYWJsZShcbiAgICBwYWNrYWdlTmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uOiBzdHJpbmcsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBDaGVja2luZyBpZiAke3BhY2thZ2VOYW1lfUAke3BhY2thZ2VWZXJzaW9ufSBpcyBhdmFpbGFibGUgZm9yIFB5dGhvbmAsXG4gICAgKTtcbiAgICBjb25zdCB1cmwgPSBgaHR0cHM6Ly9weXBpLm9yZy9weXBpLyR7cGFja2FnZU5hbWV9LyR7cGFja2FnZVZlcnNpb259L2pzb25gO1xuICAgIGxvZ2dlci5kZWJ1ZyhgRmV0Y2hpbmcgcGFja2FnZSBpbmZvcm1hdGlvbiBmb3IgJHtwYWNrYWdlTmFtZX0gZnJvbSAke3VybH1gKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICBjb25zdCBqc29uID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMgYW55O1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBHb3QgcmVzcG9uc2UgZnJvbSBQeVBJIGZvciAke3BhY2thZ2VOYW1lfUAke3BhY2thZ2VWZXJzaW9ufTogJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAganNvbixcbiAgICAgICl9YCxcbiAgICApO1xuXG4gICAgaWYgKGpzb24uaW5mbykge1xuICAgICAgLy8gV2UgZm91bmQgdGhlIHZlcnNpb24sIHNvIGl0IGV4aXN0c1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYENvdWxkIG5vdCBnZXQgUHlQSSBwYWNrYWdlIGluZm8sIGdvdDogJHtKU09OLnN0cmluZ2lmeShqc29uKX1gLFxuICAgICAgKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdFBpcGVudlBhY2thZ2VzKCk6IFByb21pc2U8XG4gICAgeyBuYW1lOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZyB9W11cbiAgPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0ZG91dCA9IGF3YWl0IGV4ZWMoXG4gICAgICAgIFwicGlwZW52XCIsXG4gICAgICAgIFtcInJ1blwiLCBcInBpcFwiLCBcImxpc3RcIiwgXCItLWZvcm1hdD1qc29uXCJdLFxuICAgICAgICB7XG4gICAgICAgICAgY3dkOiB0aGlzLndvcmtpbmdEaXJlY3RvcnksXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgTGlzdGluZyBwaXBlbnYgcGFja2FnZXMgdXNpbmcgXCJwaXBlbnYgcnVuIHBpcCBsaXN0IC0tZm9ybWF0PWpzb25cIjogJHtzdGRvdXR9YCxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGxpc3QgPSBwaXBQYWNrYWdlU2NoZW1hLnBhcnNlKEpTT04ucGFyc2Uoc3Rkb3V0KSk7XG4gICAgICByZXR1cm4gbGlzdC5maWx0ZXIoXG4gICAgICAgIChpdGVtKSA9PlxuICAgICAgICAgIGl0ZW0ubmFtZS5zdGFydHNXaXRoKFwiY2RrdGYtY2RrdGYtcHJvdmlkZXJcIikgfHxcbiAgICAgICAgICBpdGVtLm5hbWUuc3RhcnRzV2l0aChcImNka3RuLXByb3ZpZGVyXCIpLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENvdWxkIG5vdCBkZXRlcm1pbmUgaW5zdGFsbGVkIHBhY2thZ2VzIHVzaW5nICdwaXBlbnYgcnVuIHBpcCBsaXN0IC0tZm9ybWF0PWpzb24nOiAke2UubWVzc2FnZX1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdFBpcFBhY2thZ2VzKCk6IFByb21pc2U8eyBuYW1lOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZyB9W10+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcInBpcFwiLCBbXCJsaXN0XCIsIFwiLS1mb3JtYXQ9anNvblwiXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIH0pO1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgTGlzdGluZyBwaXAgcGFja2FnZXMgdXNpbmcgXCJwaXAgbGlzdCAtLWZvcm1hdD1qc29uXCI6ICR7c3Rkb3V0fWAsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBsaXN0ID0gcGlwUGFja2FnZVNjaGVtYS5wYXJzZShKU09OLnBhcnNlKHN0ZG91dCkpO1xuICAgICAgcmV0dXJuIGxpc3QuZmlsdGVyKFxuICAgICAgICAoaXRlbSkgPT5cbiAgICAgICAgICBpdGVtLm5hbWUuc3RhcnRzV2l0aChcImNka3RmLWNka3RmLXByb3ZpZGVyXCIpIHx8XG4gICAgICAgICAgaXRlbS5uYW1lLnN0YXJ0c1dpdGgoXCJjZGt0bi1wcm92aWRlclwiKSxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZGV0ZXJtaW5lIGluc3RhbGxlZCBwYWNrYWdlcyB1c2luZyAncGlwIGxpc3QgLS1mb3JtYXQ9anNvbic6ICR7ZS5tZXNzYWdlfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UHJvdmlkZXJQYWNrYWdlcygpOiBQcm9taXNlPFxuICAgIHsgbmFtZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfVtdXG4gID4ge1xuICAgIHJldHVybiB0aGlzLmFwcENvbW1hbmQuaW5jbHVkZXMoXCJwaXBlbnZcIilcbiAgICAgID8gdGhpcy5saXN0UGlwZW52UGFja2FnZXMoKVxuICAgICAgOiB0aGlzLmxpc3RQaXBQYWNrYWdlcygpO1xuICB9XG59XG5cbmNsYXNzIE51Z2V0UGFja2FnZU1hbmFnZXIgZXh0ZW5kcyBQYWNrYWdlTWFuYWdlciB7XG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbW1hbmQgPSBcImRvdG5ldFwiO1xuICAgIGNvbnN0IGFyZ3MgPSBbXCJhZGRcIiwgXCJwYWNrYWdlXCIsIHBhY2thZ2VOYW1lXTtcbiAgICBpZiAocGFja2FnZVZlcnNpb24pIHtcbiAgICAgIGFyZ3MucHVzaChcIi0tdmVyc2lvblwiLCBwYWNrYWdlVmVyc2lvbik7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYEluc3RhbGxpbmcgcGFja2FnZSAke3BhY2thZ2VOYW1lfSBAICR7cGFja2FnZVZlcnNpb259IHVzaW5nIFwiJHtjb21tYW5kfSAke2FyZ3Muam9pbihcbiAgICAgICAgXCIgXCIsXG4gICAgICApfVwiLmAsXG4gICAgKTtcblxuICAgIGF3YWl0IGV4ZWMoY29tbWFuZCwgYXJncywgeyBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSB9KTtcblxuICAgIGNvbnNvbGUubG9nKFwiUGFja2FnZSBpbnN0YWxsZWQuXCIpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGlzTnBtVmVyc2lvbkF2YWlsYWJsZShcbiAgICBwYWNrYWdlTmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uOiBzdHJpbmcsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2hlY2tpbmcgaWYgJHtwYWNrYWdlTmFtZX1AJHtwYWNrYWdlVmVyc2lvbn0gaXMgYXZhaWxhYmxlYCk7XG5cbiAgICBjb25zdCBbb3duZXIsIC4uLnJlc3RdID0gcGFja2FnZU5hbWUuc3BsaXQoXCIuXCIpO1xuICAgIGNvbnN0IGlkID0gcmVzdFtyZXN0Lmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IHVybCA9IGBodHRwczovL2F6dXJlc2VhcmNoLXVzbmMubnVnZXQub3JnL3F1ZXJ5P3E9b3duZXI6JHtvd25lcn0lMjBpZDoke2lkfSZwcmVyZWxlYXNlPWZhbHNlJnNlbVZlckxldmVsPTIuMC4wYDtcbiAgICBsb2dnZXIuZGVidWcoYEZldGNoaW5nIHBhY2thZ2UgbWV0YWRhdGEgZnJvbSBOdWdldDogJyR7dXJsfSdgKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICBjb25zdCBqc29uID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMge1xuICAgICAgZGF0YTogeyBpZDogc3RyaW5nOyB2ZXJzaW9uczogeyB2ZXJzaW9uOiBzdHJpbmcgfVtdIH1bXTtcbiAgICB9O1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBHb3QgcmVzcG9uc2UgZnJvbSBOdUdldCBmb3IgJHtwYWNrYWdlTmFtZX0gOiAke0pTT04uc3RyaW5naWZ5KGpzb24pfWAsXG4gICAgKTtcblxuICAgIGlmICghanNvbj8uZGF0YT8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7IC8vIE5vIHBhY2thZ2UgZm91bmRcbiAgICB9XG5cbiAgICBjb25zdCBwYWNrYWdlVmVyc2lvbnMgPVxuICAgICAganNvbi5kYXRhLmZpbmQoKHApID0+IHAuaWQgPT09IHBhY2thZ2VOYW1lKT8udmVyc2lvbnMgPz8gW107XG5cbiAgICBpZiAoIXBhY2thZ2VWZXJzaW9ucy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTsgLy8gTm8gcGFja2FnZSByZWxlYXNlIG1hdGNoaW5nIHRoZSBpZCBmb3VuZFxuICAgIH1cblxuICAgIHJldHVybiBwYWNrYWdlVmVyc2lvbnMuc29tZSgodikgPT4gdi52ZXJzaW9uID09PSBwYWNrYWdlVmVyc2lvbik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdFByb3ZpZGVyUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcImRvdG5ldFwiLCBbXCJsaXN0XCIsIFwicGFja2FnZVwiXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIH0pO1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgTGlzdGluZyBudWdldCBwYWNrYWdlcyB1c2luZyBcImRvdG5ldCBsaXN0IHBhY2thZ2VcIjogJHtzdGRvdXR9YCxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHJlZ2V4ID1cbiAgICAgICAgL15cXHMqPlxccygoPzpIYXNoaUNvcnBcXC5DZGt0ZnxJb1xcLkNka3RuKVxcLlByb3ZpZGVyc1xcLltcXHcuXSspXFxzKygoPzpcXGQrXFwuKXsyfVxcZCsoPzotXFxTKyk/KVxccysoKD86XFxkK1xcLil7Mn1cXGQrKD86LVxcUyspPylcXHMqJC87XG5cbiAgICAgIHJldHVybiBzdGRvdXRcbiAgICAgICAgLnNwbGl0KFwiXFxuXCIpXG4gICAgICAgIC5tYXAoKGxpbmU6IHN0cmluZykgPT4ge1xuICAgICAgICAgIC8vIEV4YW1wbGUgb3V0cHV0OlxuICAgICAgICAgIC8vIFByb2plY3QgJ015VGVycmFmb3JtU3RhY2snIGhhcyB0aGUgZm9sbG93aW5nIHBhY2thZ2UgcmVmZXJlbmNlc1xuICAgICAgICAgIC8vICBbbmV0Ni4wXTpcbiAgICAgICAgICAvLyAgVG9wLWxldmVsIFBhY2thZ2UgICAgICBSZXF1ZXN0ZWQgICBSZXNvbHZlZFxuICAgICAgICAgIC8vICA+IEhhc2hpQ29ycC5DZGt0ZiAgICAgIDAuMC4wICAgICAgIDAuMC4wXG4gICAgICAgICAgLy8gbWF0Y2hbMF0gPSBmdWxsIG1hdGNoXG4gICAgICAgICAgLy8gbWF0Y2hbMV0gPSBwYWNrYWdlIG5hbWVcbiAgICAgICAgICAvLyBtYXRjaFsyXSA9IHJlcXVlc3RlZCB2ZXJzaW9uXG4gICAgICAgICAgLy8gbWF0Y2hbM10gPSByZXNvbHZlZCB2ZXJzaW9uXG4gICAgICAgICAgcmV0dXJuIHJlZ2V4LmV4ZWMobGluZSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5maWx0ZXIoKG1hdGNoKSA9PiAhIW1hdGNoKVxuICAgICAgICAubWFwKChtYXRjaCkgPT4gKHsgbmFtZTogbWF0Y2ghWzFdLCB2ZXJzaW9uOiBtYXRjaCFbM10gfSkpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ291bGQgbm90IGRldGVybWluZSBpbnN0YWxsZWQgcGFja2FnZXMgdXNpbmcgJ2RvdG5ldCBsaXN0IHBhY2thZ2UnOiAke2UubWVzc2FnZX1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuYWJzdHJhY3QgY2xhc3MgSmF2YVBhY2thZ2VNYW5hZ2VyIGV4dGVuZHMgUGFja2FnZU1hbmFnZXIge1xuICBwdWJsaWMgYXN5bmMgaXNOcG1WZXJzaW9uQXZhaWxhYmxlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDaGVja2luZyBpZiAke3BhY2thZ2VOYW1lfUAke3BhY2thZ2VWZXJzaW9ufSBpcyBhdmFpbGFibGVgKTtcblxuICAgIGNvbnN0IHBhcnRzID0gcGFja2FnZU5hbWUuc3BsaXQoXCIuXCIpO1xuICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IDMpIHtcbiAgICAgIHRocm93IEVycm9ycy5JbnRlcm5hbChcbiAgICAgICAgYEV4cGVjdGVkIHBhY2thZ2UgbmFtZSB0byBiZSBpbiBmb3JtYXQgXCJncm91cC5hcnRpZmFjdFwiLCBlLmcuIFwiY29tLmhhc2hpY29ycC5jZGt0Zi1wcm92aWRlci1nb29nbGVcIiwgZ290OiAke3BhY2thZ2VOYW1lfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHBhY2thZ2VJZGVudGlmaWVyID0gcGFydHMucG9wKCk7XG4gICAgY29uc3QgZ3JvdXBJZCA9IHBhcnRzLmpvaW4oXCIuXCIpO1xuXG4gICAgY29uc3QgdXJsID0gYGh0dHBzOi8vc2VhcmNoLm1hdmVuLm9yZy9zb2xyc2VhcmNoL3NlbGVjdD9xPWc6JHtncm91cElkfStBTkQrYToke3BhY2thZ2VJZGVudGlmaWVyfStBTkQrdjoke3BhY2thZ2VWZXJzaW9ufSZyb3dzPTUmd3Q9anNvbmA7XG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYFRyeWluZyB0byBmaW5kIHBhY2thZ2UgdmVyc2lvbiBieSBxdWVyeWluZyBNYXZlbiBDZW50cmFsIHVuZGVyICcke3VybH0nYCxcbiAgICApO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcblxuICAgIGNvbnN0IGpzb24gPSAoYXdhaXQgcmVzcG9uc2UuanNvbigpKSBhcyBhbnk7XG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYEdvdCByZXNwb25zZSBmcm9tIHRoZSBNYXZlbiBwYWNrYWdlIHNlYXJjaCBmb3IgJHtwYWNrYWdlTmFtZX06ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIGpzb24sXG4gICAgICApfWAsXG4gICAgKTtcblxuICAgIHJldHVybiAoanNvbj8ucmVzcG9uc2U/Lm51bUZvdW5kID8/IDApID4gMDtcbiAgfVxufVxuXG5jbGFzcyBNYXZlblBhY2thZ2VNYW5hZ2VyIGV4dGVuZHMgSmF2YVBhY2thZ2VNYW5hZ2VyIHtcbiAgcHVibGljIGFzeW5jIGFkZFBhY2thZ2UoXG4gICAgcGFja2FnZU5hbWU6IHN0cmluZyxcbiAgICBwYWNrYWdlVmVyc2lvbiA9IFwiTEFURVNUXCIsIC8vIHRoZSBsYXRlc3Qgb3B0aW9uIGlzIGRlcHJlY2F0ZWQgaW4gbWF2ZW4gMy41XG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnNvbGUubG9nKGBBZGRpbmcgJHtwYWNrYWdlTmFtZX0gQCAke3BhY2thZ2VWZXJzaW9ufSB0byBwb20ueG1sYCk7XG4gICAgLy8gQXNzZXJ0IHBvbS54bWwgZXhpc3RzXG4gICAgY29uc3QgcG9tUGF0aCA9IHBhdGguam9pbih0aGlzLndvcmtpbmdEaXJlY3RvcnksIFwicG9tLnhtbFwiKTtcbiAgICBpZiAoIWV4aXN0c1N5bmMocG9tUGF0aCkpIHtcbiAgICAgIHRocm93IEVycm9ycy5Vc2FnZShcbiAgICAgICAgXCJObyBwb20ueG1sIGZvdW5kIGluIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuIFBsZWFzZSBydW4gdGhlIGNvbW1hbmQgZnJvbSB0aGUgcm9vdCBvZiB5b3VyIHByb2plY3QuXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHBvbSA9IGF3YWl0IGZzLnJlYWRGaWxlKHBvbVBhdGgsIFwidXRmOFwiKTtcbiAgICBjb25zdCBwb21YbWwgPSAoYXdhaXQgeG1sMmpzKHBvbSwge30pKSBhcyBFbGVtZW50O1xuXG4gICAgLy8gTXV0YXRlIGRlcGVuZGVuY2llc1xuICAgIGNvbnN0IG5hbWVQYXJ0cyA9IHBhY2thZ2VOYW1lLnNwbGl0KFwiLlwiKTtcbiAgICBjb25zdCBncm91cElkID0gbmFtZVBhcnRzLnNsaWNlKDAsIG5hbWVQYXJ0cy5sZW5ndGggLSAxKS5qb2luKFwiLlwiKTtcbiAgICBjb25zdCBhcnRpZmFjdElkID0gbmFtZVBhcnRzW25hbWVQYXJ0cy5sZW5ndGggLSAxXTtcblxuICAgIGNvbnN0IG5ld0RlcGVuZGVuY3kgPSAoYXdhaXQgeG1sMmpzKFxuICAgICAgYDxkZXBlbmRlbmN5PlxuICAgIDxncm91cElkPiR7Z3JvdXBJZH08L2dyb3VwSWQ+XG4gICAgPGFydGlmYWN0SWQ+JHthcnRpZmFjdElkfTwvYXJ0aWZhY3RJZD5cbiAgICA8dmVyc2lvbj4ke3BhY2thZ2VWZXJzaW9ufTwvdmVyc2lvbj5cbjwvZGVwZW5kZW5jeT5gLFxuICAgICkpIGFzIEVsZW1lbnQ7XG5cbiAgICBjb25zdCBkZXBlbmRlbmNpZXMgPSBwb21YbWwuZWxlbWVudHNcbiAgICAgID8uZmluZCgoZWwpID0+IGVsLm5hbWUgPT09IFwicHJvamVjdFwiKVxuICAgICAgPy5lbGVtZW50cz8uZmluZCgoZWwpID0+IGVsLm5hbWUgPT09IFwiZGVwZW5kZW5jaWVzXCIpO1xuXG4gICAgaWYgKCFkZXBlbmRlbmNpZXMpIHtcbiAgICAgIHRocm93IEVycm9ycy5Vc2FnZShgQ291bGQgbm90IGZpbmQgZGVwZW5kZW5jaWVzIHNlY3Rpb24gaW4gdGhlIHBvbS54bWxgKTtcbiAgICB9XG4gICAgZGVwZW5kZW5jaWVzLmVsZW1lbnRzID0gKGRlcGVuZGVuY2llcz8uZWxlbWVudHMgfHwgW10pLmZpbHRlcihcbiAgICAgIChlbCkgPT5cbiAgICAgICAgZWwuZWxlbWVudHM/LnNvbWUoXG4gICAgICAgICAgKGdyb3VwKSA9PlxuICAgICAgICAgICAgZ3JvdXAubmFtZSA9PT0gXCJncm91cElkXCIgJiYgZ3JvdXAuZWxlbWVudHM/LlswXS50ZXh0ICE9PSBncm91cElkLFxuICAgICAgICApIHx8XG4gICAgICAgIGVsLmVsZW1lbnRzPy5zb21lKFxuICAgICAgICAgIChhcnRpZmFjdCkgPT5cbiAgICAgICAgICAgIGFydGlmYWN0Lm5hbWUgPT09IFwiYXJ0aWZhY3RJZFwiICYmXG4gICAgICAgICAgICBhcnRpZmFjdC5lbGVtZW50cz8uWzBdLnRleHQgIT09IGFydGlmYWN0SWQsXG4gICAgICAgICksXG4gICAgKTtcbiAgICBkZXBlbmRlbmNpZXM/LmVsZW1lbnRzPy5wdXNoKG5ld0RlcGVuZGVuY3kuZWxlbWVudHMhWzBdKTtcblxuICAgIC8vIFdyaXRlIG5ldyBwb20ueG1sXG4gICAgYXdhaXQgZnMud3JpdGVGaWxlKHBvbVBhdGgsIGpzMnhtbChwb21YbWwsIHsgc3BhY2VzOiAyIH0pKTtcblxuICAgIC8vIEluc3RhbGxcbiAgICBhd2FpdCBleGVjKFwibXZuXCIsIFtcImluc3RhbGxcIl0sIHsgY3dkOiB0aGlzLndvcmtpbmdEaXJlY3RvcnkgfSk7XG4gICAgY29uc29sZS5sb2coXCJQYWNrYWdlIGluc3RhbGxlZC5cIik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdFByb3ZpZGVyUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcG9tUGF0aCA9IHBhdGguam9pbih0aGlzLndvcmtpbmdEaXJlY3RvcnksIFwicG9tLnhtbFwiKTtcbiAgICAgIGlmICghZXhpc3RzU3luYyhwb21QYXRoKSkge1xuICAgICAgICB0aHJvdyBFcnJvcnMuVXNhZ2UoXG4gICAgICAgICAgXCJObyBwb20ueG1sIGZvdW5kIGluIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuIFBsZWFzZSBydW4gdGhlIGNvbW1hbmQgZnJvbSB0aGUgcm9vdCBvZiB5b3VyIHByb2plY3QuXCIsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBvbSA9IGF3YWl0IGZzLnJlYWRGaWxlKHBvbVBhdGgsIFwidXRmOFwiKTtcbiAgICAgIGNvbnN0IHBvbVhtbCA9IChhd2FpdCB4bWwyanMocG9tLCB7fSkpIGFzIEVsZW1lbnQ7XG5cbiAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9XG4gICAgICAgIHBvbVhtbC5lbGVtZW50c1xuICAgICAgICAgID8uZmluZCgoZWwpID0+IGVsLm5hbWUgPT09IFwicHJvamVjdFwiKVxuICAgICAgICAgID8uZWxlbWVudHM/LmZpbmQoKGVsKSA9PiBlbC5uYW1lID09PSBcImRlcGVuZGVuY2llc1wiKT8uZWxlbWVudHMgPz8gW107XG5cbiAgICAgIHJldHVybiBkZXBlbmRlbmNpZXNcbiAgICAgICAgLm1hcCgoZGVwKSA9PiAoe1xuICAgICAgICAgIG5hbWU6IGAke1xuICAgICAgICAgICAgZGVwLmVsZW1lbnRzPy5maW5kKChlbCkgPT4gZWwubmFtZSA9PT0gXCJncm91cElkXCIpPy5lbGVtZW50cz8uWzBdXG4gICAgICAgICAgICAgIC50ZXh0XG4gICAgICAgICAgfS4ke1xuICAgICAgICAgICAgZGVwLmVsZW1lbnRzPy5maW5kKChlbCkgPT4gZWwubmFtZSA9PT0gXCJhcnRpZmFjdElkXCIpPy5lbGVtZW50cz8uWzBdXG4gICAgICAgICAgICAgIC50ZXh0XG4gICAgICAgICAgfWAsXG4gICAgICAgICAgdmVyc2lvbjogZGVwLmVsZW1lbnRzPy5maW5kKChlbCkgPT4gZWwubmFtZSA9PT0gXCJ2ZXJzaW9uXCIpXG4gICAgICAgICAgICA/LmVsZW1lbnRzPy5bMF0udGV4dCBhcyBzdHJpbmcsXG4gICAgICAgIH0pKVxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChkZXApID0+XG4gICAgICAgICAgICBkZXAubmFtZS5zdGFydHNXaXRoKFwiY29tLmhhc2hpY29ycC5jZGt0Zi1wcm92aWRlci1cIikgfHxcbiAgICAgICAgICAgIGRlcC5uYW1lLnN0YXJ0c1dpdGgoXCJpby5jZGt0bi5jZGt0bi1wcm92aWRlci1cIiksXG4gICAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZGV0ZXJtaW5lIGluc3RhbGxlZCBwYWNrYWdlcyByZWFkaW5nIHRoZSBwb20ueG1sOiAke2UubWVzc2FnZX1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuY2xhc3MgR3JhZGxlUGFja2FnZU1hbmFnZXIgZXh0ZW5kcyBKYXZhUGFja2FnZU1hbmFnZXIge1xuICBwdWJsaWMgc3RhdGljIGlzR3JhZGxlUHJvamVjdCh3b3JraW5nRGlyZWN0b3J5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNHcmFkbGVQcm9qZWN0KHdvcmtpbmdEaXJlY3RvcnkpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGFkZFBhY2thZ2UoXG4gICAgcGFja2FnZUZRTjogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uID0gXCJsYXRlc3QucmVsZWFzZVwiLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBidWlsZEdyYWRsZVBhdGggPSBwYXRoLmpvaW4odGhpcy53b3JraW5nRGlyZWN0b3J5LCBcImJ1aWxkLmdyYWRsZVwiKTtcbiAgICBjb25zdCBidWlsZEdyYWRsZSA9IGF3YWl0IGZzLnJlYWRGaWxlKGJ1aWxkR3JhZGxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgIGNvbnN0IGJ1aWxkR3JhZGxlTGluZXMgPSBidWlsZEdyYWRsZS5zcGxpdCgvXFxyP1xcbi8pO1xuXG4gICAgY29uc3QgZGVwZW5kZW5jaWVzUmVnZXggPSAvZGVwZW5kZW5jaWVzXFxzK1xcey9pO1xuICAgIGNvbnN0IGRlcGVuZGVuY3lCbG9ja1N0YXJ0ID0gYnVpbGRHcmFkbGVMaW5lcy5maW5kSW5kZXgoKGxpbmUpID0+XG4gICAgICBkZXBlbmRlbmNpZXNSZWdleC50ZXN0KGxpbmUpLFxuICAgICk7XG4gICAgaWYgKGRlcGVuZGVuY3lCbG9ja1N0YXJ0ID09PSAtMSkge1xuICAgICAgdGhyb3cgRXJyb3JzLlVzYWdlKFxuICAgICAgICBcIkNvdWxkIG5vdCBmaW5kIGRlcGVuZGVuY2llcyBzZWN0aW9uIGluIHRoZSBidWlsZC5ncmFkbGVcIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcGFja2FnZVNlZ21lbnRzID0gcGFja2FnZUZRTi5zcGxpdChcIi5cIik7XG4gICAgY29uc3QgcGFja2FnZU5hbWUgPSBwYWNrYWdlU2VnbWVudHMucG9wKCk7XG4gICAgY29uc3QgZ3JvdXBOYW1lID0gcGFja2FnZVNlZ21lbnRzLmpvaW4oXCIuXCIpO1xuICAgIGNvbnN0IGRlcGVuZGVuY3lTcGVjaWZpZXIgPSBgJHtncm91cE5hbWV9OiR7cGFja2FnZU5hbWV9YDtcbiAgICBjb25zdCBkZXBlbmRlbmN5QW5kVmVyc2lvblNwZWNpZmllciA9IGAke2RlcGVuZGVuY3lTcGVjaWZpZXJ9OiR7cGFja2FnZVZlcnNpb259YDtcblxuICAgIGNvbnN0IGV4aXN0aW5nRGVwZW5kZW5jeSA9IGJ1aWxkR3JhZGxlTGluZXMuZmluZEluZGV4KChsaW5lKSA9PlxuICAgICAgbGluZS5pbmNsdWRlcyhkZXBlbmRlbmN5U3BlY2lmaWVyKSxcbiAgICApO1xuICAgIGlmIChleGlzdGluZ0RlcGVuZGVuY3kgIT09IC0xKSB7XG4gICAgICBidWlsZEdyYWRsZUxpbmVzLnNwbGljZShleGlzdGluZ0RlcGVuZGVuY3ksIDEpO1xuICAgIH1cblxuICAgIGNvbnN0IG5ld1BhY2thZ2VEZXBlbmRlbmN5ID0gYFxcdGltcGxlbWVudGF0aW9uICcke2RlcGVuZGVuY3lBbmRWZXJzaW9uU3BlY2lmaWVyfSdgO1xuICAgIGJ1aWxkR3JhZGxlTGluZXMuc3BsaWNlKGRlcGVuZGVuY3lCbG9ja1N0YXJ0ICsgMSwgMCwgbmV3UGFja2FnZURlcGVuZGVuY3kpO1xuXG4gICAgYXdhaXQgZnMud3JpdGVGaWxlKGJ1aWxkR3JhZGxlUGF0aCwgYnVpbGRHcmFkbGVMaW5lcy5qb2luKFwiXFxuXCIpKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UHJvdmlkZXJQYWNrYWdlcygpOiBQcm9taXNlPFxuICAgIHsgbmFtZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfVtdXG4gID4ge1xuICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IGF3YWl0IGdldEdyYWRsZURlcGVuZGVuY2llcygpO1xuICAgIGlmICghZGVwZW5kZW5jaWVzKSB7XG4gICAgICB0aHJvdyBFcnJvcnMuVXNhZ2UoXCJDb3VsZCBub3QgZmluZCBhbnkgZGVwZW5kZW5jaWVzXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlcGVuZGVuY3lMaXN0ID0gZGVwZW5kZW5jaWVzXG4gICAgICAubWFwKChsaW5lKSA9PiBnZXREZXBlbmRlbmN5SW5mb3JtYXRpb25Gcm9tTGluZShsaW5lKSlcbiAgICAgIC5maWx0ZXIoKGRlcCkgPT4ge1xuICAgICAgICBpZiAoIWRlcCkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIGRlcC5uYW1lLmluY2x1ZGVzKFwiY2RrdGYtcHJvdmlkZXItXCIpIHx8XG4gICAgICAgICAgZGVwLm5hbWUuaW5jbHVkZXMoXCJjZGt0bi1wcm92aWRlci1cIilcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAubWFwKChkZXApID0+ICh7XG4gICAgICAgIG5hbWU6IGBjb20uaGFzaGljb3JwLiR7ZGVwIS5uYW1lfWAsXG4gICAgICAgIHZlcnNpb246IGRlcCEudmVyc2lvbixcbiAgICAgIH0pKTtcblxuICAgIHJldHVybiBkZXBlbmRlbmN5TGlzdDtcbiAgfVxufVxuXG5jbGFzcyBHb1BhY2thZ2VNYW5hZ2VyIGV4dGVuZHMgUGFja2FnZU1hbmFnZXIge1xuICBwdWJsaWMgYXN5bmMgYWRkUGFja2FnZShcbiAgICBwYWNrYWdlTmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uPzogc3RyaW5nLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zb2xlLmxvZyhgQWRkaW5nIHBhY2thZ2UgJHtwYWNrYWdlTmFtZX0gQCAke3BhY2thZ2VWZXJzaW9ufWApO1xuXG4gICAgY29uc3QgbWFqb3JWZXJzaW9uOiBudW1iZXIgfCB1bmRlZmluZWQgPSBwYWNrYWdlVmVyc2lvblxuICAgICAgPyBzZW12ZXIubWFqb3IocGFja2FnZVZlcnNpb24pXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIGxldCB2ZXJzaW9uUGFja2FnZVN1ZmZpeCA9IFwiXCI7XG4gICAgaWYgKHR5cGVvZiBtYWpvclZlcnNpb24gPT09IFwibnVtYmVyXCIgJiYgbWFqb3JWZXJzaW9uID4gMSkge1xuICAgICAgdmVyc2lvblBhY2thZ2VTdWZmaXggPSBgL3Yke21ham9yVmVyc2lvbn1gO1xuICAgIH1cblxuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBSdW5uaW5nICdnbyBnZXQgJHtwYWNrYWdlTmFtZX0ke3ZlcnNpb25QYWNrYWdlU3VmZml4fUB2JHtwYWNrYWdlVmVyc2lvbn0nYCxcbiAgICApO1xuICAgIC8vIEluc3RhbGxcbiAgICBhd2FpdCBleGVjKFxuICAgICAgXCJnb1wiLFxuICAgICAgW1wiZ2V0XCIsIGAke3BhY2thZ2VOYW1lfSR7dmVyc2lvblBhY2thZ2VTdWZmaXh9QHYke3BhY2thZ2VWZXJzaW9ufWBdLFxuICAgICAge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGNvbnNvbGUubG9nKFwiUGFja2FnZSBpbnN0YWxsZWQuXCIpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGlzTnBtVmVyc2lvbkF2YWlsYWJsZShcbiAgICBwYWNrYWdlTmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uOiBzdHJpbmcsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2hlY2tpbmcgaWYgJHtwYWNrYWdlTmFtZX1AJHtwYWNrYWdlVmVyc2lvbn0gaXMgYXZhaWxhYmxlYCk7XG5cbiAgICAvLyBlLmcuIGdpdGh1Yi5jb20vY2RrdGYvY2RrdGYtcHJvdmlkZXItZ29vZ2xlLWdvL2dvb2dsZVxuICAgIGNvbnN0IHBhcnRzID0gcGFja2FnZU5hbWUuc3BsaXQoXCIvXCIpO1xuICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IEVycm9ycy5JbnRlcm5hbChcbiAgICAgICAgYEV4cGVjdGluZyBHbyBwYWNrYWdlIG5hbWUgdG8gYmUgaW4gdGhlIGZvcm1hdCBvZiBnaXRodWIuY29tLzxvcmc+LzxyZXBvPi88cGFja2FnZT4sIGdvdCAke3BhY2thZ2VOYW1lfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IG9yZyA9IHBhcnRzWzFdO1xuICAgIGNvbnN0IHJlcG8gPSBwYXJ0c1syXTtcbiAgICBjb25zdCBwYWNrYWdlUGF0aCA9IHBhcnRzWzNdO1xuXG4gICAgY29uc3QgdXJsID0gYGh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvJHtvcmd9LyR7cmVwb30vZ2l0L3JlZi90YWdzLyR7cGFja2FnZVBhdGh9L3Yke3BhY2thZ2VWZXJzaW9ufWA7XG4gICAgbG9nZ2VyLmRlYnVnKGBGZXRjaGluZyB0YWdzIGZvciAke29yZ30vJHtyZXBvfSBmcm9tICcke3VybH0nYCk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgQWNjZXB0OiBcImFwcGxpY2F0aW9uL3ZuZC5naXRodWIranNvblwiLFxuICAgICAgICBcIlVzZXItQWdlbnRcIjogXCJPcGVuQ29uc3RydWN0cy9jZGt0bi1jbGlcIixcbiAgICAgICAgLi4uKEdJVEhVQl9BUElfVE9LRU5fQ0RLVEZcbiAgICAgICAgICA/IHsgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke0dJVEhVQl9BUElfVE9LRU5fQ0RLVEZ9YCB9XG4gICAgICAgICAgOiB7fSksXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QganNvbiA9IChhd2FpdCByZXNwb25zZS5qc29uKCkpIGFzIGFueTtcbiAgICBsb2dnZXIuZGVidWcoXG4gICAgICBgR290IHJlc3BvbnNlIGZyb20gR2l0SHVicyByZXBvc2l0b3J5IHRhZyBlbmRwb2ludCBmb3IgJHtwYWNrYWdlTmFtZX06ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIGpzb24sXG4gICAgICApfWAsXG4gICAgKTtcblxuICAgIGlmIChqc29uICYmIGpzb24ucmVmKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBsb2dnZXIuaW5mbyhcbiAgICAgIGBDb3VsZCBub3QgZmluZCB0aGUgdGFnICR7cGFja2FnZVBhdGh9L3Yke3BhY2thZ2VWZXJzaW9ufSBpbiB0aGUgcmVwb3NpdG9yeSAke29yZ30vJHtyZXBvfTogJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAganNvbixcbiAgICAgICl9fWAsXG4gICAgKTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UHJvdmlkZXJQYWNrYWdlcygpOiBQcm9taXNlPFxuICAgIHsgbmFtZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfVtdXG4gID4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBnb1N1bVBhdGggPSBwYXRoLmpvaW4odGhpcy53b3JraW5nRGlyZWN0b3J5LCBcImdvLnN1bVwiKTtcbiAgICAgIGlmICghZXhpc3RzU3luYyhnb1N1bVBhdGgpKSB7XG4gICAgICAgIHRocm93IEVycm9ycy5Vc2FnZShcbiAgICAgICAgICBcIk5vIGdvLnN1bSBmb3VuZCBpbiBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LiBQbGVhc2UgcnVuIHRoZSBjb21tYW5kIGZyb20gdGhlIHJvb3Qgb2YgeW91ciBwcm9qZWN0LlwiLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBnb1N1bSA9IGF3YWl0IGZzLnJlYWRGaWxlKGdvU3VtUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgZGVkdXBlZFByb3ZpZGVyTmFtZXMgPSBuZXcgU2V0KCk7XG5cbiAgICAgIHJldHVybiBnb1N1bVxuICAgICAgICAuc3BsaXQoXCJcXG5cIilcbiAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAobGluZSkgPT5cbiAgICAgICAgICAgIGxpbmUuc3RhcnRzV2l0aChcImdpdGh1Yi5jb20vaGFzaGljb3JwL2Nka3RmLXByb3ZpZGVyXCIpIHx8XG4gICAgICAgICAgICBsaW5lLnN0YXJ0c1dpdGgoXCJnaXRodWIuY29tL2Nka3RmL2Nka3RmLXByb3ZpZGVyXCIpIHx8XG4gICAgICAgICAgICBsaW5lLnN0YXJ0c1dpdGgoXCJnaXRodWIuY29tL2Nka3RuLWlvL2Nka3RuLXByb3ZpZGVyXCIpLFxuICAgICAgICApXG4gICAgICAgIC5tYXAoKGxpbmUpID0+IHtcbiAgICAgICAgICBjb25zdCBwYXJ0cyA9IGxpbmUuc3BsaXQoXCIgXCIpO1xuICAgICAgICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IDMpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9ycy5JbnRlcm5hbChcbiAgICAgICAgICAgICAgYEV4cGVjdGVkIGxpbmUgaW4gZ28uc3VtIHRvIGJlIGluIHRoZSBmb3JtYXQgb2YgJzxwYWNrYWdlPiA8dmVyc2lvbj4gPGNoZWNrc3VtPicsIGdvdDogJHtsaW5lfWAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIHBhcnRbMF0gY291bGQgYmUgZ2l0aHViLmNvbS9hd3MvY29uc3RydWN0cy1nby9jb25zdHJ1Y3RzL3YxMFxuICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJ0c1swXS5zcGxpdChcIi9cIikuc2xpY2UoMCwgNCkuam9pbihcIi9cIik7XG5cbiAgICAgICAgICBjb25zdCB2ZXJzaW9uID0gcGFydHNbMV0uc3BsaXQoXCIvXCIpWzBdO1xuXG4gICAgICAgICAgaWYgKGRlZHVwZWRQcm92aWRlck5hbWVzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgbmFtZTogXCJcIiwgdmVyc2lvbjogXCJcIiB9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRlZHVwZWRQcm92aWRlck5hbWVzLmFkZChuYW1lKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgdmVyc2lvbixcbiAgICAgICAgICB9O1xuICAgICAgICB9KVxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChwcm92aWRlckluZm8pID0+ICEhcHJvdmlkZXJJbmZvLm5hbWUgJiYgISFwcm92aWRlckluZm8udmVyc2lvbixcbiAgICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENvdWxkIG5vdCBkZXRlcm1pbmUgaW5zdGFsbGVkIHBhY2thZ2VzIHJlYWRpbmcgdGhlIGdvLnN1bTogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG4iXX0=
|