@cdktn/cli-core 0.22.0-pre.2
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 +84 -0
- package/src/lib/dependencies/dependency-manager.d.ts.map +1 -0
- package/src/lib/dependencies/dependency-manager.js +365 -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 +574 -0
- package/src/lib/dependencies/prebuilt-providers.d.ts +18 -0
- package/src/lib/dependencies/prebuilt-providers.d.ts.map +1 -0
- package/src/lib/dependencies/prebuilt-providers.js +204 -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,574 @@
|
|
|
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
|
+
.map((dep) => ({
|
|
171
|
+
name: `@${dep.name.split("@")[1]}`,
|
|
172
|
+
version: dep.name.split("@")[2],
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
throw new Error(`Could not determine installed packages using 'yarn list --json': ${e.message}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async listNpmPackages() {
|
|
180
|
+
try {
|
|
181
|
+
const stdout = await (0, commons_1.exec)("npm", ["list", "--json"], {
|
|
182
|
+
cwd: this.workingDirectory,
|
|
183
|
+
});
|
|
184
|
+
commons_1.logger.debug(`Listing npm packages using "npm list --json": ${stdout}`);
|
|
185
|
+
const json = npmListSchema.parse(JSON.parse(stdout));
|
|
186
|
+
return Object.entries((json === null || json === void 0 ? void 0 : json.dependencies) || {})
|
|
187
|
+
.filter(([depName]) => depName.startsWith("@cdktf/provider-"))
|
|
188
|
+
.map(([name, dep]) => ({ name, version: dep.version }));
|
|
189
|
+
}
|
|
190
|
+
catch (e) {
|
|
191
|
+
throw new Error(`Could not determine installed packages using 'npm list --json': ${e.message}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async listProviderPackages() {
|
|
195
|
+
return this.hasYarnLockfile()
|
|
196
|
+
? this.listYarnPackages()
|
|
197
|
+
: this.listNpmPackages();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
class PythonPackageManager extends PackageManager {
|
|
201
|
+
get appCommand() {
|
|
202
|
+
try {
|
|
203
|
+
return JSON.parse(fs.readFileSync(path_1.default.resolve(this.workingDirectory, "cdktf.json"), "utf8"))["app"];
|
|
204
|
+
}
|
|
205
|
+
catch (e) {
|
|
206
|
+
throw commons_1.Errors.Usage(`Could not find find and parse cdktf.json in ${this.workingDirectory}`, e);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
async addPackage(packageName, packageVersion) {
|
|
210
|
+
const usePipenv = this.appCommand.includes("pipenv");
|
|
211
|
+
if (usePipenv) {
|
|
212
|
+
console.log(`Installing package ${packageName} @ ${packageVersion} using pipenv.`);
|
|
213
|
+
await (0, commons_1.exec)("pipenv", ["install", `${packageName}~=${packageVersion}`], {
|
|
214
|
+
cwd: this.workingDirectory,
|
|
215
|
+
env: {
|
|
216
|
+
...process.env,
|
|
217
|
+
PIPENV_QUIET: "1",
|
|
218
|
+
},
|
|
219
|
+
stdio: ["inherit", 1, 1],
|
|
220
|
+
});
|
|
221
|
+
console.log("Package installed.");
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
console.log(`Installing package ${packageName} @ ${packageVersion} using pip.`);
|
|
225
|
+
const requirementsFilePath = path_1.default.join(this.workingDirectory, "requirements.txt");
|
|
226
|
+
if (!fs.existsSync(requirementsFilePath)) {
|
|
227
|
+
throw commons_1.Errors.Usage(`Could not find requirements.txt in ${this.workingDirectory}`);
|
|
228
|
+
}
|
|
229
|
+
const requirements = await fs.readFile(requirementsFilePath, "utf8");
|
|
230
|
+
const requirementLine = requirements
|
|
231
|
+
.split("\n")
|
|
232
|
+
.find((line) => line.includes(packageName));
|
|
233
|
+
commons_1.logger.debug(`Read requirements.txt file and found line including ${packageName}: ${requirementLine}`);
|
|
234
|
+
if (requirementLine) {
|
|
235
|
+
if (packageVersion ? requirementLine.includes(packageVersion) : true) {
|
|
236
|
+
commons_1.logger.info(`Package ${packageName} already installed. Skipping installation.`);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
commons_1.logger.debug(`Found the package but with a different version, continuing`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
const newRequirements = requirements
|
|
244
|
+
.split("\n")
|
|
245
|
+
.filter((line) => !line.startsWith(packageName))
|
|
246
|
+
.join("\n") +
|
|
247
|
+
`\n${packageName}${packageVersion ? `~=${packageVersion}` : ""}`;
|
|
248
|
+
await fs.writeFile(requirementsFilePath, newRequirements, "utf8");
|
|
249
|
+
await (0, commons_1.exec)("pip", ["install", "-r", "requirements.txt"], {
|
|
250
|
+
cwd: this.workingDirectory,
|
|
251
|
+
stdio: ["inherit", 1, 1],
|
|
252
|
+
});
|
|
253
|
+
console.log("Package installed.");
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async isNpmVersionAvailable(packageName, packageVersion) {
|
|
257
|
+
commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available for Python`);
|
|
258
|
+
const url = `https://pypi.org/pypi/${packageName}/${packageVersion}/json`;
|
|
259
|
+
commons_1.logger.debug(`Fetching package information for ${packageName} from ${url}`);
|
|
260
|
+
const response = await (0, node_fetch_1.default)(url);
|
|
261
|
+
const json = (await response.json());
|
|
262
|
+
commons_1.logger.debug(`Got response from PyPI for ${packageName}@${packageVersion}: ${JSON.stringify(json)}`);
|
|
263
|
+
if (json.info) {
|
|
264
|
+
// We found the version, so it exists
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
commons_1.logger.debug(`Could not get PyPI package info, got: ${JSON.stringify(json)}`);
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async listPipenvPackages() {
|
|
273
|
+
try {
|
|
274
|
+
const stdout = await (0, commons_1.exec)("pipenv", ["run", "pip", "list", "--format=json"], {
|
|
275
|
+
cwd: this.workingDirectory,
|
|
276
|
+
});
|
|
277
|
+
commons_1.logger.debug(`Listing pipenv packages using "pipenv run pip list --format=json": ${stdout}`);
|
|
278
|
+
const list = pipPackageSchema.parse(JSON.parse(stdout));
|
|
279
|
+
return list.filter((item) => item.name.startsWith("cdktf-cdktf-provider"));
|
|
280
|
+
}
|
|
281
|
+
catch (e) {
|
|
282
|
+
throw new Error(`Could not determine installed packages using 'pipenv run pip list --format=json': ${e.message}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
async listPipPackages() {
|
|
286
|
+
try {
|
|
287
|
+
const stdout = await (0, commons_1.exec)("pip", ["list", "--format=json"], {
|
|
288
|
+
cwd: this.workingDirectory,
|
|
289
|
+
});
|
|
290
|
+
commons_1.logger.debug(`Listing pipenv packages using "pip list --format=json": ${stdout}`);
|
|
291
|
+
const list = pipPackageSchema.parse(JSON.parse(stdout));
|
|
292
|
+
return list.filter((item) => item.name.startsWith("cdktf-cdktf-provider"));
|
|
293
|
+
}
|
|
294
|
+
catch (e) {
|
|
295
|
+
throw new Error(`Could not determine installed packages using 'pip list --format=json': ${e.message}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
async listProviderPackages() {
|
|
299
|
+
return this.appCommand.includes("pipenv")
|
|
300
|
+
? this.listPipenvPackages()
|
|
301
|
+
: this.listPipPackages();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
class NugetPackageManager extends PackageManager {
|
|
305
|
+
async addPackage(packageName, packageVersion) {
|
|
306
|
+
const command = "dotnet";
|
|
307
|
+
const args = ["add", "package", packageName];
|
|
308
|
+
if (packageVersion) {
|
|
309
|
+
args.push("--version", packageVersion);
|
|
310
|
+
}
|
|
311
|
+
console.log(`Installing package ${packageName} @ ${packageVersion} using "${command} ${args.join(" ")}".`);
|
|
312
|
+
await (0, commons_1.exec)(command, args, { cwd: this.workingDirectory });
|
|
313
|
+
console.log("Package installed.");
|
|
314
|
+
}
|
|
315
|
+
async isNpmVersionAvailable(packageName, packageVersion) {
|
|
316
|
+
var _a, _b, _c;
|
|
317
|
+
commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available`);
|
|
318
|
+
const [owner, ...rest] = packageName.split(".");
|
|
319
|
+
const id = rest[rest.length - 1];
|
|
320
|
+
const url = `https://azuresearch-usnc.nuget.org/query?q=owner:${owner}%20id:${id}&prerelease=false&semVerLevel=2.0.0`;
|
|
321
|
+
commons_1.logger.debug(`Fetching package metadata from Nuget: '${url}'`);
|
|
322
|
+
const response = await (0, node_fetch_1.default)(url);
|
|
323
|
+
const json = (await response.json());
|
|
324
|
+
commons_1.logger.debug(`Got response from NuGet for ${packageName} : ${JSON.stringify(json)}`);
|
|
325
|
+
if (!((_a = json === null || json === void 0 ? void 0 : json.data) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
326
|
+
return false; // No package found
|
|
327
|
+
}
|
|
328
|
+
const packageVersions = (_c = (_b = json.data.find((p) => p.id === packageName)) === null || _b === void 0 ? void 0 : _b.versions) !== null && _c !== void 0 ? _c : [];
|
|
329
|
+
if (!packageVersions.length) {
|
|
330
|
+
return false; // No package release matching the id found
|
|
331
|
+
}
|
|
332
|
+
return packageVersions.some((v) => v.version === packageVersion);
|
|
333
|
+
}
|
|
334
|
+
async listProviderPackages() {
|
|
335
|
+
try {
|
|
336
|
+
const stdout = await (0, commons_1.exec)("dotnet", ["list", "package"], {
|
|
337
|
+
cwd: this.workingDirectory,
|
|
338
|
+
});
|
|
339
|
+
commons_1.logger.debug(`Listing pipenv packages using "dotnet list package": ${stdout}`);
|
|
340
|
+
const regex = /^\s*>\s(HashiCorp\.Cdktf\.Providers\.[\w.]+)\s+((?:\d+\.){2}\d+(?:-\S+)?)\s+((?:\d+\.){2}\d+(?:-\S+)?)\s*$/;
|
|
341
|
+
return stdout
|
|
342
|
+
.split("\n")
|
|
343
|
+
.map((line) => {
|
|
344
|
+
// Example output:
|
|
345
|
+
// Project 'MyTerraformStack' has the following package references
|
|
346
|
+
// [net6.0]:
|
|
347
|
+
// Top-level Package Requested Resolved
|
|
348
|
+
// > HashiCorp.Cdktf 0.0.0 0.0.0
|
|
349
|
+
// match[0] = full match
|
|
350
|
+
// match[1] = package name
|
|
351
|
+
// match[2] = requested version
|
|
352
|
+
// match[3] = resolved version
|
|
353
|
+
return regex.exec(line);
|
|
354
|
+
})
|
|
355
|
+
.filter((match) => !!match)
|
|
356
|
+
.map((match) => ({ name: match[1], version: match[3] }));
|
|
357
|
+
}
|
|
358
|
+
catch (e) {
|
|
359
|
+
throw new Error(`Could not determine installed packages using 'dotnet list package': ${e.message}`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
class JavaPackageManager extends PackageManager {
|
|
364
|
+
async isNpmVersionAvailable(packageName, packageVersion) {
|
|
365
|
+
var _a, _b;
|
|
366
|
+
commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available`);
|
|
367
|
+
const parts = packageName.split(".");
|
|
368
|
+
if (parts.length !== 3) {
|
|
369
|
+
throw commons_1.Errors.Internal(`Expected package name to be in format "group.artifact", e.g. "com.hashicorp.cdktf-provider-google", got: ${packageName}`);
|
|
370
|
+
}
|
|
371
|
+
const packageIdentifier = parts.pop();
|
|
372
|
+
const groupId = parts.join(".");
|
|
373
|
+
const url = `https://search.maven.org/solrsearch/select?q=g:${groupId}+AND+a:${packageIdentifier}+AND+v:${packageVersion}&rows=5&wt=json`;
|
|
374
|
+
commons_1.logger.debug(`Trying to find package version by querying Maven Central under '${url}'`);
|
|
375
|
+
const response = await (0, node_fetch_1.default)(url);
|
|
376
|
+
const json = (await response.json());
|
|
377
|
+
commons_1.logger.debug(`Got response from the Maven package search for ${packageName}: ${JSON.stringify(json)}`);
|
|
378
|
+
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;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
class MavenPackageManager extends JavaPackageManager {
|
|
382
|
+
async addPackage(packageName, packageVersion = "LATEST") {
|
|
383
|
+
var _a, _b, _c, _d;
|
|
384
|
+
console.log(`Adding ${packageName} @ ${packageVersion} to pom.xml`);
|
|
385
|
+
// Assert pom.xml exists
|
|
386
|
+
const pomPath = path_1.default.join(this.workingDirectory, "pom.xml");
|
|
387
|
+
if (!(0, fs_extra_1.existsSync)(pomPath)) {
|
|
388
|
+
throw commons_1.Errors.Usage("No pom.xml found in current working directory. Please run the command from the root of your project.");
|
|
389
|
+
}
|
|
390
|
+
const pom = await fs.readFile(pomPath, "utf8");
|
|
391
|
+
const pomXml = (await (0, xml_js_1.xml2js)(pom, {}));
|
|
392
|
+
// Mutate dependencies
|
|
393
|
+
const nameParts = packageName.split(".");
|
|
394
|
+
const groupId = nameParts.slice(0, nameParts.length - 1).join(".");
|
|
395
|
+
const artifactId = nameParts[nameParts.length - 1];
|
|
396
|
+
const newDependency = (await (0, xml_js_1.xml2js)(`<dependency>
|
|
397
|
+
<groupId>${groupId}</groupId>
|
|
398
|
+
<artifactId>${artifactId}</artifactId>
|
|
399
|
+
<version>${packageVersion}</version>
|
|
400
|
+
</dependency>`));
|
|
401
|
+
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");
|
|
402
|
+
if (!dependencies) {
|
|
403
|
+
throw commons_1.Errors.Usage(`Could not find dependencies section in the pom.xml`);
|
|
404
|
+
}
|
|
405
|
+
dependencies.elements = ((dependencies === null || dependencies === void 0 ? void 0 : dependencies.elements) || []).filter((el) => {
|
|
406
|
+
var _a, _b;
|
|
407
|
+
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; })) ||
|
|
408
|
+
((_b = el.elements) === null || _b === void 0 ? void 0 : _b.some((artifact) => {
|
|
409
|
+
var _a;
|
|
410
|
+
return artifact.name === "artifactId" &&
|
|
411
|
+
((_a = artifact.elements) === null || _a === void 0 ? void 0 : _a[0].text) !== artifactId;
|
|
412
|
+
}));
|
|
413
|
+
});
|
|
414
|
+
(_d = dependencies === null || dependencies === void 0 ? void 0 : dependencies.elements) === null || _d === void 0 ? void 0 : _d.push(newDependency.elements[0]);
|
|
415
|
+
// Write new pom.xml
|
|
416
|
+
await fs.writeFile(pomPath, (0, xml_js_1.js2xml)(pomXml, { spaces: 2 }));
|
|
417
|
+
// Install
|
|
418
|
+
await (0, commons_1.exec)("mvn", ["install"], { cwd: this.workingDirectory });
|
|
419
|
+
console.log("Package installed.");
|
|
420
|
+
}
|
|
421
|
+
async listProviderPackages() {
|
|
422
|
+
var _a, _b, _c, _d, _e;
|
|
423
|
+
try {
|
|
424
|
+
const pomPath = path_1.default.join(this.workingDirectory, "pom.xml");
|
|
425
|
+
if (!(0, fs_extra_1.existsSync)(pomPath)) {
|
|
426
|
+
throw commons_1.Errors.Usage("No pom.xml found in current working directory. Please run the command from the root of your project.");
|
|
427
|
+
}
|
|
428
|
+
const pom = await fs.readFile(pomPath, "utf8");
|
|
429
|
+
const pomXml = (await (0, xml_js_1.xml2js)(pom, {}));
|
|
430
|
+
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 : [];
|
|
431
|
+
return dependencies
|
|
432
|
+
.map((dep) => {
|
|
433
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
434
|
+
return ({
|
|
435
|
+
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}`,
|
|
436
|
+
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,
|
|
437
|
+
});
|
|
438
|
+
})
|
|
439
|
+
.filter((dep) => dep.name.startsWith("com.hashicorp.cdktf-provider-"));
|
|
440
|
+
}
|
|
441
|
+
catch (e) {
|
|
442
|
+
throw new Error(`Could not determine installed packages reading the pom.xml: ${e.message}`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
class GradlePackageManager extends JavaPackageManager {
|
|
447
|
+
static isGradleProject(workingDirectory) {
|
|
448
|
+
return (0, commons_1.isGradleProject)(workingDirectory);
|
|
449
|
+
}
|
|
450
|
+
async addPackage(packageFQN, packageVersion = "latest.release") {
|
|
451
|
+
const buildGradlePath = path_1.default.join(this.workingDirectory, "build.gradle");
|
|
452
|
+
const buildGradle = await fs.readFile(buildGradlePath, "utf8");
|
|
453
|
+
const buildGradleLines = buildGradle.split(/\r?\n/);
|
|
454
|
+
const dependenciesRegex = /dependencies\s+\{/i;
|
|
455
|
+
const dependencyBlockStart = buildGradleLines.findIndex((line) => dependenciesRegex.test(line));
|
|
456
|
+
if (dependencyBlockStart === -1) {
|
|
457
|
+
throw commons_1.Errors.Usage("Could not find dependencies section in the build.gradle");
|
|
458
|
+
}
|
|
459
|
+
const packageSegments = packageFQN.split(".");
|
|
460
|
+
const packageName = packageSegments.pop();
|
|
461
|
+
const groupName = packageSegments.join(".");
|
|
462
|
+
const dependencySpecifier = `${groupName}:${packageName}`;
|
|
463
|
+
const dependencyAndVersionSpecifier = `${dependencySpecifier}:${packageVersion}`;
|
|
464
|
+
const existingDependency = buildGradleLines.findIndex((line) => line.includes(dependencySpecifier));
|
|
465
|
+
if (existingDependency !== -1) {
|
|
466
|
+
buildGradleLines.splice(existingDependency, 1);
|
|
467
|
+
}
|
|
468
|
+
const newPackageDependency = `\timplementation '${dependencyAndVersionSpecifier}'`;
|
|
469
|
+
buildGradleLines.splice(dependencyBlockStart + 1, 0, newPackageDependency);
|
|
470
|
+
await fs.writeFile(buildGradlePath, buildGradleLines.join("\n"));
|
|
471
|
+
}
|
|
472
|
+
async listProviderPackages() {
|
|
473
|
+
const dependencies = await (0, commons_1.getGradleDependencies)();
|
|
474
|
+
if (!dependencies) {
|
|
475
|
+
throw commons_1.Errors.Usage("Could not find any dependencies");
|
|
476
|
+
}
|
|
477
|
+
const dependencyList = dependencies
|
|
478
|
+
.map((line) => (0, commons_1.getDependencyInformationFromLine)(line))
|
|
479
|
+
.filter((dep) => {
|
|
480
|
+
if (!dep) {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
return dep.name.includes("cdktf-provider-");
|
|
484
|
+
})
|
|
485
|
+
.map((dep) => ({
|
|
486
|
+
name: `com.hashicorp.${dep.name}`,
|
|
487
|
+
version: dep.version,
|
|
488
|
+
}));
|
|
489
|
+
return dependencyList;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
class GoPackageManager extends PackageManager {
|
|
493
|
+
async addPackage(packageName, packageVersion) {
|
|
494
|
+
console.log(`Adding package ${packageName} @ ${packageVersion}`);
|
|
495
|
+
const majorVersion = packageVersion
|
|
496
|
+
? semver.major(packageVersion)
|
|
497
|
+
: undefined;
|
|
498
|
+
let versionPackageSuffix = "";
|
|
499
|
+
if (typeof majorVersion === "number" && majorVersion > 1) {
|
|
500
|
+
versionPackageSuffix = `/v${majorVersion}`;
|
|
501
|
+
}
|
|
502
|
+
commons_1.logger.debug(`Running 'go get ${packageName}${versionPackageSuffix}@v${packageVersion}'`);
|
|
503
|
+
// Install
|
|
504
|
+
await (0, commons_1.exec)("go", ["get", `${packageName}${versionPackageSuffix}@v${packageVersion}`], {
|
|
505
|
+
cwd: this.workingDirectory,
|
|
506
|
+
});
|
|
507
|
+
console.log("Package installed.");
|
|
508
|
+
}
|
|
509
|
+
async isNpmVersionAvailable(packageName, packageVersion) {
|
|
510
|
+
commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available`);
|
|
511
|
+
// e.g. github.com/cdktf/cdktf-provider-google-go/google
|
|
512
|
+
const parts = packageName.split("/");
|
|
513
|
+
if (parts.length !== 4) {
|
|
514
|
+
throw commons_1.Errors.Internal(`Expecting Go package name to be in the format of github.com/<org>/<repo>/<package>, got ${packageName}`);
|
|
515
|
+
}
|
|
516
|
+
const org = parts[1];
|
|
517
|
+
const repo = parts[2];
|
|
518
|
+
const packagePath = parts[3];
|
|
519
|
+
const url = `https://api.github.com/repos/${org}/${repo}/git/ref/tags/${packagePath}/v${packageVersion}`;
|
|
520
|
+
commons_1.logger.debug(`Fetching tags for ${org}/${repo} from '${url}'`);
|
|
521
|
+
const response = await (0, node_fetch_1.default)(url, {
|
|
522
|
+
headers: {
|
|
523
|
+
Accept: "application/vnd.github+json",
|
|
524
|
+
"User-Agent": "OpenConstructs/cdktn-cli",
|
|
525
|
+
...(GITHUB_API_TOKEN_CDKTF
|
|
526
|
+
? { Authorization: `Bearer ${GITHUB_API_TOKEN_CDKTF}` }
|
|
527
|
+
: {}),
|
|
528
|
+
},
|
|
529
|
+
});
|
|
530
|
+
const json = (await response.json());
|
|
531
|
+
commons_1.logger.debug(`Got response from GitHubs repository tag endpoint for ${packageName}: ${JSON.stringify(json)}`);
|
|
532
|
+
if (json && json.ref) {
|
|
533
|
+
return true;
|
|
534
|
+
}
|
|
535
|
+
commons_1.logger.info(`Could not find the tag ${packagePath}/v${packageVersion} in the repository ${org}/${repo}: ${JSON.stringify(json)}}`);
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
async listProviderPackages() {
|
|
539
|
+
try {
|
|
540
|
+
const goSumPath = path_1.default.join(this.workingDirectory, "go.sum");
|
|
541
|
+
if (!(0, fs_extra_1.existsSync)(goSumPath)) {
|
|
542
|
+
throw commons_1.Errors.Usage("No go.sum found in current working directory. Please run the command from the root of your project.");
|
|
543
|
+
}
|
|
544
|
+
const goSum = await fs.readFile(goSumPath, "utf8");
|
|
545
|
+
const dedupedProviderNames = new Set();
|
|
546
|
+
return goSum
|
|
547
|
+
.split("\n")
|
|
548
|
+
.filter((line) => line.startsWith("github.com/hashicorp/cdktf-provider") ||
|
|
549
|
+
line.startsWith("github.com/cdktf/cdktf-provider"))
|
|
550
|
+
.map((line) => {
|
|
551
|
+
const parts = line.split(" ");
|
|
552
|
+
if (parts.length !== 3) {
|
|
553
|
+
throw commons_1.Errors.Internal(`Expected line in go.sum to be in the format of '<package> <version> <checksum>', got: ${line}`);
|
|
554
|
+
}
|
|
555
|
+
// part[0] could be github.com/aws/constructs-go/constructs/v10
|
|
556
|
+
const name = parts[0].split("/").slice(0, 4).join("/");
|
|
557
|
+
const version = parts[1].split("/")[0];
|
|
558
|
+
if (dedupedProviderNames.has(name)) {
|
|
559
|
+
return { name: "", version: "" };
|
|
560
|
+
}
|
|
561
|
+
dedupedProviderNames.add(name);
|
|
562
|
+
return {
|
|
563
|
+
name,
|
|
564
|
+
version,
|
|
565
|
+
};
|
|
566
|
+
})
|
|
567
|
+
.filter((providerInfo) => !!providerInfo.name && !!providerInfo.version);
|
|
568
|
+
}
|
|
569
|
+
catch (e) {
|
|
570
|
+
throw new Error(`Could not determine installed packages reading the go.sum: ${e.message}`);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFja2FnZS1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicGFja2FnZS1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsK0JBQStCO0FBQy9CLG1DQUFtQztBQUNuQyw0Q0FRd0I7QUFDeEIsdUNBQXNDO0FBQ3RDLGdEQUF3QjtBQUN4QixtQ0FBaUQ7QUFDakQsNkNBQStCO0FBQy9CLCtDQUFpQztBQUNqQyw0REFBK0I7QUFDL0IsdUNBQXlCO0FBRXpCLDZGQUE2RjtBQUM3RixzREFBc0Q7QUFDdEQsTUFBTSxFQUFFLHNCQUFzQixFQUFFLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQztBQUUvQyxJQUFJO0FBQ0osd0JBQXdCO0FBQ3hCLDBCQUEwQjtBQUMxQixrQkFBa0I7QUFDbEIsMElBQTBJO0FBQzFJLE9BQU87QUFDUCxzQkFBc0I7QUFDdEIsa0NBQWtDO0FBQ2xDLDZCQUE2QjtBQUM3QixxR0FBcUc7QUFDckcsU0FBUztBQUNULE1BQU0sYUFBYSxHQUFHLENBQUM7S0FDcEIsTUFBTSxDQUFDO0lBQ04sWUFBWSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQ3BCLENBQUM7U0FDRSxNQUFNLENBQUM7UUFDTixPQUFPLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtLQUNwQixDQUFDO1NBQ0QsU0FBUyxFQUFFLENBQ2Y7Q0FDRixDQUFDO0tBQ0QsV0FBVyxFQUFFO0tBQ2IsU0FBUyxFQUFFLENBQUM7QUFFZixJQUFJO0FBQ0osb0JBQW9CO0FBQ3BCLGNBQWM7QUFDZCxzQkFBc0I7QUFDdEIsaUJBQWlCO0FBQ2pCLFVBQVU7QUFDVixtREFBbUQ7QUFDbkQsMEJBQTBCO0FBQzFCLHdCQUF3QjtBQUN4QiwyQkFBMkI7QUFDM0IscUJBQXFCO0FBQ3JCLFVBQVU7QUFDVixRQUFRO0FBQ1IsTUFBTTtBQUNOLElBQUk7QUFDSixNQUFNLGNBQWMsR0FBRyxDQUFDO0tBQ3JCLE1B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QUFDLFlBQVksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQ2hFLENBQUM7UUFDTixDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksS0FBSyxDQUNiLDhEQUE4RCxDQUFDLENBQUMsT0FBTyxFQUFFLENBQzFFLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSBIYXNoaUNvcnAsIEluY1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1QTC0yLjBcbmltcG9ydCB7XG4gIExhbmd1YWdlLFxuICBleGVjLFxuICBFcnJvcnMsXG4gIGxvZ2dlcixcbiAgaXNHcmFkbGVQcm9qZWN0LFxuICBnZXRHcmFkbGVEZXBlbmRlbmNpZXMsXG4gIGdldERlcGVuZGVuY3lJbmZvcm1hdGlvbkZyb21MaW5lLFxufSBmcm9tIFwiQGNka3RuL2NvbW1vbnNcIjtcbmltcG9ydCB7IGV4aXN0c1N5bmMgfSBmcm9tIFwiZnMtZXh0cmFcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyB4bWwyanMsIGpzMnhtbCwgRWxlbWVudCB9IGZyb20gXCJ4bWwtanNcIjtcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJmcy1leHRyYVwiO1xuaW1wb3J0ICogYXMgc2VtdmVyIGZyb20gXCJzZW12ZXJcIjtcbmltcG9ydCBmZXRjaCBmcm9tIFwibm9kZS1mZXRjaFwiO1xuaW1wb3J0ICogYXMgeiBmcm9tIFwiem9kXCI7XG5cbi8vIENhbid0IHVzZSBDREtURl8gYXMgcHJlZml4IGJlY2F1c2UgeWFyZ3MgLmVudihcIkNES1RGXCIpIGluIHN0cmljdCBtb2RlIGRvZXMgbm90IGFsbG93IHVzIHRvXG4vLyBSZWZlciB0bzogaHR0cHM6Ly9naXRodWIuY29tL3lhcmdzL3lhcmdzL2lzc3Vlcy84NzNcbmNvbnN0IHsgR0lUSFVCX0FQSV9UT0tFTl9DREtURiB9ID0gcHJvY2Vzcy5lbnY7XG5cbi8vIHtcbi8vICAgXCJ2ZXJzaW9uXCI6IFwiMS4wLjBcIixcbi8vICAgXCJuYW1lXCI6IFwidGVzdFVTSGFzRlwiLFxuLy8gICBcInByb2JsZW1zXCI6IFtcbi8vICAgICBcImV4dHJhbmVvdXM6IGFyY2hpdmVyLXV0aWxzQDIuMS4wIC9wcml2YXRlL3Zhci9mb2xkZXJzL3pfL3YwM2wzM2Q1NWZiNTducnIzYjFxMDNjaDAwMDBncS9UL3Rlc3RVU0hhc0Yvbm9kZV9tb2R1bGVzL2FyY2hpdmVyLXV0aWxzXCIsXG4vLyAgIF0sXG4vLyAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbi8vICAgICBcIkBjZGt0Zi9wcm92aWRlci1yYW5kb21cIjoge1xuLy8gICAgICAgXCJ2ZXJzaW9uXCI6IFwiMy4wLjExXCIsXG4vLyAgICAgICBcInJlc29sdmVkXCI6IFwiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvQGNka3RmL3Byb3ZpZGVyLXJhbmRvbS8tL3Byb3ZpZGVyLXJhbmRvbS0zLjAuMTEudGd6XCJcbi8vICAgICB9LFxuY29uc3QgbnBtTGlzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZGVwZW5kZW5jaWVzOiB6LnJlY29yZChcbiAgICAgIHpcbiAgICAgICAgLm9iamVjdCh7XG4gICAgICAgICAgdmVyc2lvbjogei5zdHJpbmcoKSxcbiAgICAgICAgfSlcbiAgICAgICAgLm5vbnN0cmljdCgpLFxuICAgICksXG4gIH0pXG4gIC5kZWVwUGFydGlhbCgpXG4gIC5ub25zdHJpY3QoKTtcblxuLy8ge1xuLy8gICBcInR5cGVcIjogXCJ0cmVlXCIsXG4vLyAgIFwiZGF0YVwiOiB7XG4vLyAgICAgXCJ0eXBlXCI6IFwibGlzdFwiLFxuLy8gICAgIFwidHJlZXNcIjogW1xuLy8gICAgICAge1xuLy8gICAgICAgICBcIm5hbWVcIjogXCJAY2RrdGYvcHJvdmlkZXItcmFuZG9tQDMuMC4xMVwiLFxuLy8gICAgICAgICBcImNoaWxkcmVuXCI6IFtdLFxuLy8gICAgICAgICBcImhpbnRcIjogbnVsbCxcbi8vICAgICAgICAgXCJjb2xvclwiOiBcImJvbGRcIixcbi8vICAgICAgICAgXCJkZXB0aFwiOiAwXG4vLyAgICAgICB9XG4vLyAgICAgXVxuLy8gICB9XG4vLyB9XG5jb25zdCB5YXJuTGlzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZGF0YTogelxuICAgICAgLm9iamVjdCh7XG4gICAgICAgIHRyZWVzOiB6LmFycmF5KFxuICAgICAgICAgIHpcbiAgICAgICAgICAgIC5vYmplY3Qoe1xuICAgICAgICAgICAgICBuYW1lOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5ub25zdHJpY3QoKSxcbiAgICAgICAgKSxcbiAgICAgIH0pXG4gICAgICAubm9uc3RyaWN0KCksXG4gIH0pXG4gIC5kZWVwUGFydGlhbCgpXG4gIC5ub25zdHJpY3QoKTtcblxuLy8gW1xuLy8gICB7XG4vLyAgICAgXCJuYW1lXCI6IFwiYXBwZGlyc1wiLFxuLy8gICAgIFwidmVyc2lvblwiOiBcIjEuNC40XCJcbi8vICAgfSxcbi8vICAge1xuY29uc3QgcGlwUGFja2FnZVNjaGVtYSA9IHouYXJyYXkoXG4gIHoub2JqZWN0KHsgbmFtZTogei5zdHJpbmcoKSwgdmVyc2lvbjogei5zdHJpbmcoKSB9KS5ub25zdHJpY3QoKSxcbik7XG5cbi8qKlxuICogbWFuYWdlcyBpbnN0YWxsaW5nLCB1cGRhdGluZywgYW5kIHJlbW92aW5nIGRlcGVuZGVuY2llc1xuICogaW4gdGhlIHBhY2thZ2Ugc3lzdGVtIHVzZWQgYnkgdGhlIHRhcmdldCBsYW5ndWFnZSBvZiBhIENES1ROXG4gKiBwcm9qZWN0XG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBQYWNrYWdlTWFuYWdlciB7XG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCByZWFkb25seSB3b3JraW5nRGlyZWN0b3J5OiBzdHJpbmcpIHt9XG5cbiAgcHVibGljIHN0YXRpYyBmb3JMYW5ndWFnZShcbiAgICBsYW5ndWFnZTogTGFuZ3VhZ2UsXG4gICAgd29ya2luZ0RpcmVjdG9yeTogc3RyaW5nLFxuICApOiBQYWNrYWdlTWFuYWdlciB7XG4gICAgc3dpdGNoIChsYW5ndWFnZSkge1xuICAgICAgY2FzZSBMYW5ndWFnZS5HTzpcbiAgICAgICAgcmV0dXJuIG5ldyBHb1BhY2thZ2VNYW5hZ2VyKHdvcmtpbmdEaXJlY3RvcnkpO1xuICAgICAgY2FzZSBMYW5ndWFnZS5UWVBFU0NSSVBUOlxuICAgICAgICByZXR1cm4gbmV3IE5vZGVQYWNrYWdlTWFuYWdlcih3b3JraW5nRGlyZWN0b3J5KTtcbiAgICAgIGNhc2UgTGFuZ3VhZ2UuUFlUSE9OOlxuICAgICAgICByZXR1cm4gbmV3IFB5dGhvblBhY2thZ2VNYW5hZ2VyKHdvcmtpbmdEaXJlY3RvcnkpO1xuICAgICAgY2FzZSBMYW5ndWFnZS5DU0hBUlA6XG4gICAgICAgIHJldHVybiBuZXcgTnVnZXRQYWNrYWdlTWFuYWdlcih3b3JraW5nRGlyZWN0b3J5KTtcbiAgICAgIGNhc2UgTGFuZ3VhZ2UuSkFWQTpcbiAgICAgICAgaWYgKEdyYWRsZVBhY2thZ2VNYW5hZ2VyLmlzR3JhZGxlUHJvamVjdCh3b3JraW5nRGlyZWN0b3J5KSkge1xuICAgICAgICAgIHJldHVybiBuZXcgR3JhZGxlUGFja2FnZU1hbmFnZXIod29ya2luZ0RpcmVjdG9yeSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBNYXZlblBhY2thZ2VNYW5hZ2VyKHdvcmtpbmdEaXJlY3RvcnkpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGxhbmd1YWdlOiAke2xhbmd1YWdlfWApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhYnN0cmFjdCBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICAgc2lsZW50PzogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPjtcbiAgLy8gYWRkIGNoZWNrIGlmIHBhY2thZ2UgZXhpc3RzIGFscmVhZHkuIG1pZ2h0IHF1ZXJ5IHZlcnNpb24gaW4gdGhlIGZ1dHVyZSBhbmQgb2ZmZXIgdG8gdXBncmFkZT9cblxuICBwdWJsaWMgYWJzdHJhY3QgaXNOcG1WZXJzaW9uQXZhaWxhYmxlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPjtcblxuICBwdWJsaWMgYWJzdHJhY3QgbGlzdFByb3ZpZGVyUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+O1xufVxuXG5jbGFzcyBOb2RlUGFja2FnZU1hbmFnZXIgZXh0ZW5kcyBQYWNrYWdlTWFuYWdlciB7XG4gIHByaXZhdGUgaGFzWWFybkxvY2tmaWxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBleGlzdHNTeW5jKHBhdGguam9pbih0aGlzLndvcmtpbmdEaXJlY3RvcnksIFwieWFybi5sb2NrXCIpKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICAgc2lsZW50PzogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc29sZS5sb2coYEFkZGluZyBwYWNrYWdlICR7cGFja2FnZU5hbWV9IEAgJHtwYWNrYWdlVmVyc2lvbn1gKTtcblxuICAgIC8vIHByb2JlIGZvciBwYWNrYWdlLWxvY2suanNvbiBvciB5YXJuLmxvY2tcbiAgICBsZXQgY29tbWFuZCA9IFwibnBtXCI7XG4gICAgbGV0IGFyZ3MgPSBbXCJpbnN0YWxsXCJdO1xuXG4gICAgaWYgKHRoaXMuaGFzWWFybkxvY2tmaWxlKCkpIHtcbiAgICAgIGNvbW1hbmQgPSBcInlhcm5cIjtcbiAgICAgIGFyZ3MgPSBbXCJhZGRcIl07XG4gICAgfVxuICAgIGFyZ3MucHVzaChcbiAgICAgIHBhY2thZ2VWZXJzaW9uID8gcGFja2FnZU5hbWUgKyBcIkBcIiArIHBhY2thZ2VWZXJzaW9uIDogcGFja2FnZU5hbWUsXG4gICAgKTtcblxuICAgIGlmIChzaWxlbnQpIHtcbiAgICAgIGFyZ3MucHVzaChcIi0tc2lsZW50XCIpO1xuICAgICAgYXJncy5wdXNoKFwiLS1uby1wcm9ncmVzc1wiKTtcbiAgICB9XG5cbiAgICAvLyBJbnN0YWxsIGV4YWN0IHZlcnNpb25cbiAgICAvLyBZYXJuOiBodHRwczovL2NsYXNzaWMueWFybnBrZy5jb20vbGFuZy9lbi9kb2NzL2NsaS9hZGQvI3RvYy15YXJuLWFkZC1leGFjdC1lXG4gICAgLy8gTnBtOiBodHRwczovL2RvY3MubnBtanMuY29tL2NsaS92OC9jb21tYW5kcy9ucG0taW5zdGFsbCNzYXZlLWV4YWN0XG4gICAgYXJncy5wdXNoKFwiLUVcIik7XG5cbiAgICBsb2dnZXIuaW5mbyhcbiAgICAgIGBJbnN0YWxsaW5nIHBhY2thZ2UgJHtwYWNrYWdlTmFtZX0gQCAke3BhY2thZ2VWZXJzaW9ufSB1c2luZyAke2NvbW1hbmR9LmAsXG4gICAgKTtcblxuICAgIGF3YWl0IGV4ZWMoY29tbWFuZCwgYXJncywgeyBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSB9KTtcblxuICAgIGxvZ2dlci5pbmZvKFwiUGFja2FnZSBpbnN0YWxsZWQuXCIpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGlzTnBtVmVyc2lvbkF2YWlsYWJsZShcbiAgICBfcGFja2FnZU5hbWU6IHN0cmluZyxcbiAgICBfcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgLy8gV2UgZ2V0IHRoZSBsaXN0IG9mIGF2YWlsYWJsZSB2ZXJzaW9ucyBmcm9tIG5wbSwgbm8gbmVlZCB0byBjaGVjayBoZXJlXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxpc3RZYXJuUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcInlhcm5cIiwgW1wibGlzdFwiLCBcIi0tanNvblwiXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIH0pO1xuXG4gICAgICBsb2dnZXIuZGVidWcoYExpc3RpbmcgeWFybiBwYWNrYWdlcyB1c2luZyBcInlhcm4gbGlzdCAtLWpzb25cIjogJHtzdGRvdXR9YCk7XG5cbiAgICAgIGNvbnN0IGpzb24gPSB5YXJuTGlzdFNjaGVtYS5wYXJzZShKU09OLnBhcnNlKHN0ZG91dCkpO1xuXG4gICAgICByZXR1cm4gKGpzb24/LmRhdGE/LnRyZWVzIHx8IFtdKVxuICAgICAgICAuZmlsdGVyKChkZXA6IGFueSkgPT4gZGVwLm5hbWUuc3RhcnRzV2l0aChcIkBjZGt0Zi9wcm92aWRlci1cIikpXG4gICAgICAgIC5tYXAoKGRlcDogYW55KSA9PiAoe1xuICAgICAgICAgIG5hbWU6IGBAJHtkZXAubmFtZS5zcGxpdChcIkBcIilbMV19YCxcbiAgICAgICAgICB2ZXJzaW9uOiBkZXAubmFtZS5zcGxpdChcIkBcIilbMl0sXG4gICAgICAgIH0pKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENvdWxkIG5vdCBkZXRlcm1pbmUgaW5zdGFsbGVkIHBhY2thZ2VzIHVzaW5nICd5YXJuIGxpc3QgLS1qc29uJzogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBsaXN0TnBtUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcIm5wbVwiLCBbXCJsaXN0XCIsIFwiLS1qc29uXCJdLCB7XG4gICAgICAgIGN3ZDogdGhpcy53b3JraW5nRGlyZWN0b3J5LFxuICAgICAgfSk7XG5cbiAgICAgIGxvZ2dlci5kZWJ1ZyhgTGlzdGluZyBucG0gcGFja2FnZXMgdXNpbmcgXCJucG0gbGlzdCAtLWpzb25cIjogJHtzdGRvdXR9YCk7XG4gICAgICBjb25zdCBqc29uID0gbnBtTGlzdFNjaGVtYS5wYXJzZShKU09OLnBhcnNlKHN0ZG91dCkpO1xuXG4gICAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoanNvbj8uZGVwZW5kZW5jaWVzIHx8IHt9KVxuICAgICAgICAuZmlsdGVyKChbZGVwTmFtZV0pID0+IGRlcE5hbWUuc3RhcnRzV2l0aChcIkBjZGt0Zi9wcm92aWRlci1cIikpXG4gICAgICAgIC5tYXAoKFtuYW1lLCBkZXBdKSA9PiAoeyBuYW1lLCB2ZXJzaW9uOiBkZXAudmVyc2lvbiB9KSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZGV0ZXJtaW5lIGluc3RhbGxlZCBwYWNrYWdlcyB1c2luZyAnbnBtIGxpc3QgLS1qc29uJzogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQcm92aWRlclBhY2thZ2VzKCk6IFByb21pc2U8XG4gICAgeyBuYW1lOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZyB9W11cbiAgPiB7XG4gICAgcmV0dXJuIHRoaXMuaGFzWWFybkxvY2tmaWxlKClcbiAgICAgID8gdGhpcy5saXN0WWFyblBhY2thZ2VzKClcbiAgICAgIDogdGhpcy5saXN0TnBtUGFja2FnZXMoKTtcbiAgfVxufVxuXG5jbGFzcyBQeXRob25QYWNrYWdlTWFuYWdlciBleHRlbmRzIFBhY2thZ2VNYW5hZ2VyIHtcbiAgcHJpdmF0ZSBnZXQgYXBwQ29tbWFuZCgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoXG4gICAgICAgIGZzLnJlYWRGaWxlU3luYyhcbiAgICAgICAgICBwYXRoLnJlc29sdmUodGhpcy53b3JraW5nRGlyZWN0b3J5LCBcImNka3RmLmpzb25cIiksXG4gICAgICAgICAgXCJ1dGY4XCIsXG4gICAgICAgICksXG4gICAgICApW1wiYXBwXCJdO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgRXJyb3JzLlVzYWdlKFxuICAgICAgICBgQ291bGQgbm90IGZpbmQgZmluZCBhbmQgcGFyc2UgY2RrdGYuanNvbiBpbiAke3RoaXMud29ya2luZ0RpcmVjdG9yeX1gLFxuICAgICAgICBlLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgYWRkUGFja2FnZShcbiAgICBwYWNrYWdlTmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uPzogc3RyaW5nLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB1c2VQaXBlbnYgPSB0aGlzLmFwcENvbW1hbmQuaW5jbHVkZXMoXCJwaXBlbnZcIik7XG5cbiAgICBpZiAodXNlUGlwZW52KSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgYEluc3RhbGxpbmcgcGFja2FnZSAke3BhY2thZ2VOYW1lfSBAICR7cGFja2FnZVZlcnNpb259IHVzaW5nIHBpcGVudi5gLFxuICAgICAgKTtcblxuICAgICAgYXdhaXQgZXhlYyhcInBpcGVudlwiLCBbXCJpbnN0YWxsXCIsIGAke3BhY2thZ2VOYW1lfX49JHtwYWNrYWdlVmVyc2lvbn1gXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgICAgZW52OiB7XG4gICAgICAgICAgLi4ucHJvY2Vzcy5lbnYsXG4gICAgICAgICAgUElQRU5WX1FVSUVUOiBcIjFcIixcbiAgICAgICAgfSxcbiAgICAgICAgc3RkaW86IFtcImluaGVyaXRcIiwgMSwgMV0sXG4gICAgICB9KTtcblxuICAgICAgY29uc29sZS5sb2coXCJQYWNrYWdlIGluc3RhbGxlZC5cIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBgSW5zdGFsbGluZyBwYWNrYWdlICR7cGFja2FnZU5hbWV9IEAgJHtwYWNrYWdlVmVyc2lvbn0gdXNpbmcgcGlwLmAsXG4gICAgICApO1xuXG4gICAgICBjb25zdCByZXF1aXJlbWVudHNGaWxlUGF0aCA9IHBhdGguam9pbihcbiAgICAgICAgdGhpcy53b3JraW5nRGlyZWN0b3J5LFxuICAgICAgICBcInJlcXVpcmVtZW50cy50eHRcIixcbiAgICAgICk7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVxdWlyZW1lbnRzRmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IEVycm9ycy5Vc2FnZShcbiAgICAgICAgICBgQ291bGQgbm90IGZpbmQgcmVxdWlyZW1lbnRzLnR4dCBpbiAke3RoaXMud29ya2luZ0RpcmVjdG9yeX1gLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXF1aXJlbWVudHMgPSBhd2FpdCBmcy5yZWFkRmlsZShyZXF1aXJlbWVudHNGaWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgcmVxdWlyZW1lbnRMaW5lID0gcmVxdWlyZW1lbnRzXG4gICAgICAgIC5zcGxpdChcIlxcblwiKVxuICAgICAgICAuZmluZCgobGluZSkgPT4gbGluZS5pbmNsdWRlcyhwYWNrYWdlTmFtZSkpO1xuXG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBSZWFkIHJlcXVpcmVtZW50cy50eHQgZmlsZSBhbmQgZm91bmQgbGluZSBpbmNsdWRpbmcgJHtwYWNrYWdlTmFtZX06ICR7cmVxdWlyZW1lbnRMaW5lfWAsXG4gICAgICApO1xuXG4gICAgICBpZiAocmVxdWlyZW1lbnRMaW5lKSB7XG4gICAgICAgIGlmIChwYWNrYWdlVmVyc2lvbiA/IHJlcXVpcmVtZW50TGluZS5pbmNsdWRlcyhwYWNrYWdlVmVyc2lvbikgOiB0cnVlKSB7XG4gICAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICBgUGFja2FnZSAke3BhY2thZ2VOYW1lfSBhbHJlYWR5IGluc3RhbGxlZC4gU2tpcHBpbmcgaW5zdGFsbGF0aW9uLmAsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgYEZvdW5kIHRoZSBwYWNrYWdlIGJ1dCB3aXRoIGEgZGlmZmVyZW50IHZlcnNpb24sIGNvbnRpbnVpbmdgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgbmV3UmVxdWlyZW1lbnRzID1cbiAgICAgICAgcmVxdWlyZW1lbnRzXG4gICAgICAgICAgLnNwbGl0KFwiXFxuXCIpXG4gICAgICAgICAgLmZpbHRlcigobGluZSkgPT4gIWxpbmUuc3RhcnRzV2l0aChwYWNrYWdlTmFtZSkpXG4gICAgICAgICAgLmpvaW4oXCJcXG5cIikgK1xuICAgICAgICBgXFxuJHtwYWNrYWdlTmFtZX0ke3BhY2thZ2VWZXJzaW9uID8gYH49JHtwYWNrYWdlVmVyc2lvbn1gIDogXCJcIn1gO1xuICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKHJlcXVpcmVtZW50c0ZpbGVQYXRoLCBuZXdSZXF1aXJlbWVudHMsIFwidXRmOFwiKTtcblxuICAgICAgYXdhaXQgZXhlYyhcInBpcFwiLCBbXCJpbnN0YWxsXCIsIFwiLXJcIiwgXCJyZXF1aXJlbWVudHMudHh0XCJdLCB7XG4gICAgICAgIGN3ZDogdGhpcy53b3JraW5nRGlyZWN0b3J5LFxuICAgICAgICBzdGRpbzogW1wiaW5oZXJpdFwiLCAxLCAxXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zb2xlLmxvZyhcIlBhY2thZ2UgaW5zdGFsbGVkLlwiKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgaXNOcG1WZXJzaW9uQXZhaWxhYmxlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYENoZWNraW5nIGlmICR7cGFja2FnZU5hbWV9QCR7cGFja2FnZVZlcnNpb259IGlzIGF2YWlsYWJsZSBmb3IgUHl0aG9uYCxcbiAgICApO1xuICAgIGNvbnN0IHVybCA9IGBodHRwczovL3B5cGkub3JnL3B5cGkvJHtwYWNrYWdlTmFtZX0vJHtwYWNrYWdlVmVyc2lvbn0vanNvbmA7XG4gICAgbG9nZ2VyLmRlYnVnKGBGZXRjaGluZyBwYWNrYWdlIGluZm9ybWF0aW9uIGZvciAke3BhY2thZ2VOYW1lfSBmcm9tICR7dXJsfWApO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgIGNvbnN0IGpzb24gPSAoYXdhaXQgcmVzcG9uc2UuanNvbigpKSBhcyBhbnk7XG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYEdvdCByZXNwb25zZSBmcm9tIFB5UEkgZm9yICR7cGFja2FnZU5hbWV9QCR7cGFja2FnZVZlcnNpb259OiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICBqc29uLFxuICAgICAgKX1gLFxuICAgICk7XG5cbiAgICBpZiAoanNvbi5pbmZvKSB7XG4gICAgICAvLyBXZSBmb3VuZCB0aGUgdmVyc2lvbiwgc28gaXQgZXhpc3RzXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgQ291bGQgbm90IGdldCBQeVBJIHBhY2thZ2UgaW5mbywgZ290OiAke0pTT04uc3RyaW5naWZ5KGpzb24pfWAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UGlwZW52UGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcbiAgICAgICAgXCJwaXBlbnZcIixcbiAgICAgICAgW1wicnVuXCIsIFwicGlwXCIsIFwibGlzdFwiLCBcIi0tZm9ybWF0PWpzb25cIl0sXG4gICAgICAgIHtcbiAgICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBMaXN0aW5nIHBpcGVudiBwYWNrYWdlcyB1c2luZyBcInBpcGVudiBydW4gcGlwIGxpc3QgLS1mb3JtYXQ9anNvblwiOiAke3N0ZG91dH1gLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgbGlzdCA9IHBpcFBhY2thZ2VTY2hlbWEucGFyc2UoSlNPTi5wYXJzZShzdGRvdXQpKTtcbiAgICAgIHJldHVybiBsaXN0LmZpbHRlcigoaXRlbSkgPT5cbiAgICAgICAgaXRlbS5uYW1lLnN0YXJ0c1dpdGgoXCJjZGt0Zi1jZGt0Zi1wcm92aWRlclwiKSxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZGV0ZXJtaW5lIGluc3RhbGxlZCBwYWNrYWdlcyB1c2luZyAncGlwZW52IHJ1biBwaXAgbGlzdCAtLWZvcm1hdD1qc29uJzogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQaXBQYWNrYWdlcygpOiBQcm9taXNlPHsgbmFtZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfVtdPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0ZG91dCA9IGF3YWl0IGV4ZWMoXCJwaXBcIiwgW1wibGlzdFwiLCBcIi0tZm9ybWF0PWpzb25cIl0sIHtcbiAgICAgICAgY3dkOiB0aGlzLndvcmtpbmdEaXJlY3RvcnksXG4gICAgICB9KTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYExpc3RpbmcgcGlwZW52IHBhY2thZ2VzIHVzaW5nIFwicGlwIGxpc3QgLS1mb3JtYXQ9anNvblwiOiAke3N0ZG91dH1gLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgbGlzdCA9IHBpcFBhY2thZ2VTY2hlbWEucGFyc2UoSlNPTi5wYXJzZShzdGRvdXQpKTtcbiAgICAgIHJldHVybiBsaXN0LmZpbHRlcigoaXRlbSkgPT5cbiAgICAgICAgaXRlbS5uYW1lLnN0YXJ0c1dpdGgoXCJjZGt0Zi1jZGt0Zi1wcm92aWRlclwiKSxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZGV0ZXJtaW5lIGluc3RhbGxlZCBwYWNrYWdlcyB1c2luZyAncGlwIGxpc3QgLS1mb3JtYXQ9anNvbic6ICR7ZS5tZXNzYWdlfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UHJvdmlkZXJQYWNrYWdlcygpOiBQcm9taXNlPFxuICAgIHsgbmFtZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfVtdXG4gID4ge1xuICAgIHJldHVybiB0aGlzLmFwcENvbW1hbmQuaW5jbHVkZXMoXCJwaXBlbnZcIilcbiAgICAgID8gdGhpcy5saXN0UGlwZW52UGFja2FnZXMoKVxuICAgICAgOiB0aGlzLmxpc3RQaXBQYWNrYWdlcygpO1xuICB9XG59XG5cbmNsYXNzIE51Z2V0UGFja2FnZU1hbmFnZXIgZXh0ZW5kcyBQYWNrYWdlTWFuYWdlciB7XG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbW1hbmQgPSBcImRvdG5ldFwiO1xuICAgIGNvbnN0IGFyZ3MgPSBbXCJhZGRcIiwgXCJwYWNrYWdlXCIsIHBhY2thZ2VOYW1lXTtcbiAgICBpZiAocGFja2FnZVZlcnNpb24pIHtcbiAgICAgIGFyZ3MucHVzaChcIi0tdmVyc2lvblwiLCBwYWNrYWdlVmVyc2lvbik7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYEluc3RhbGxpbmcgcGFja2FnZSAke3BhY2thZ2VOYW1lfSBAICR7cGFja2FnZVZlcnNpb259IHVzaW5nIFwiJHtjb21tYW5kfSAke2FyZ3Muam9pbihcbiAgICAgICAgXCIgXCIsXG4gICAgICApfVwiLmAsXG4gICAgKTtcblxuICAgIGF3YWl0IGV4ZWMoY29tbWFuZCwgYXJncywgeyBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSB9KTtcblxuICAgIGNvbnNvbGUubG9nKFwiUGFja2FnZSBpbnN0YWxsZWQuXCIpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGlzTnBtVmVyc2lvbkF2YWlsYWJsZShcbiAgICBwYWNrYWdlTmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uOiBzdHJpbmcsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2hlY2tpbmcgaWYgJHtwYWNrYWdlTmFtZX1AJHtwYWNrYWdlVmVyc2lvbn0gaXMgYXZhaWxhYmxlYCk7XG5cbiAgICBjb25zdCBbb3duZXIsIC4uLnJlc3RdID0gcGFja2FnZU5hbWUuc3BsaXQoXCIuXCIpO1xuICAgIGNvbnN0IGlkID0gcmVzdFtyZXN0Lmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IHVybCA9IGBodHRwczovL2F6dXJlc2VhcmNoLXVzbmMubnVnZXQub3JnL3F1ZXJ5P3E9b3duZXI6JHtvd25lcn0lMjBpZDoke2lkfSZwcmVyZWxlYXNlPWZhbHNlJnNlbVZlckxldmVsPTIuMC4wYDtcbiAgICBsb2dnZXIuZGVidWcoYEZldGNoaW5nIHBhY2thZ2UgbWV0YWRhdGEgZnJvbSBOdWdldDogJyR7dXJsfSdgKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICBjb25zdCBqc29uID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMge1xuICAgICAgZGF0YTogeyBpZDogc3RyaW5nOyB2ZXJzaW9uczogeyB2ZXJzaW9uOiBzdHJpbmcgfVtdIH1bXTtcbiAgICB9O1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBHb3QgcmVzcG9uc2UgZnJvbSBOdUdldCBmb3IgJHtwYWNrYWdlTmFtZX0gOiAke0pTT04uc3RyaW5naWZ5KGpzb24pfWAsXG4gICAgKTtcblxuICAgIGlmICghanNvbj8uZGF0YT8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7IC8vIE5vIHBhY2thZ2UgZm91bmRcbiAgICB9XG5cbiAgICBjb25zdCBwYWNrYWdlVmVyc2lvbnMgPVxuICAgICAganNvbi5kYXRhLmZpbmQoKHApID0+IHAuaWQgPT09IHBhY2thZ2VOYW1lKT8udmVyc2lvbnMgPz8gW107XG5cbiAgICBpZiAoIXBhY2thZ2VWZXJzaW9ucy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTsgLy8gTm8gcGFja2FnZSByZWxlYXNlIG1hdGNoaW5nIHRoZSBpZCBmb3VuZFxuICAgIH1cblxuICAgIHJldHVybiBwYWNrYWdlVmVyc2lvbnMuc29tZSgodikgPT4gdi52ZXJzaW9uID09PSBwYWNrYWdlVmVyc2lvbik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdFByb3ZpZGVyUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcImRvdG5ldFwiLCBbXCJsaXN0XCIsIFwicGFja2FnZVwiXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIH0pO1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgTGlzdGluZyBwaXBlbnYgcGFja2FnZXMgdXNpbmcgXCJkb3RuZXQgbGlzdCBwYWNrYWdlXCI6ICR7c3Rkb3V0fWAsXG4gICAgICApO1xuXG4gICAgICBjb25zdCByZWdleCA9XG4gICAgICAgIC9eXFxzKj5cXHMoSGFzaGlDb3JwXFwuQ2RrdGZcXC5Qcm92aWRlcnNcXC5bXFx3Ll0rKVxccysoKD86XFxkK1xcLil7Mn1cXGQrKD86LVxcUyspPylcXHMrKCg/OlxcZCtcXC4pezJ9XFxkKyg/Oi1cXFMrKT8pXFxzKiQvO1xuXG4gICAgICByZXR1cm4gc3Rkb3V0XG4gICAgICAgIC5zcGxpdChcIlxcblwiKVxuICAgICAgICAubWFwKChsaW5lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAvLyBFeGFtcGxlIG91dHB1dDpcbiAgICAgICAgICAvLyBQcm9qZWN0ICdNeVRlcnJhZm9ybVN0YWNrJyBoYXMgdGhlIGZvbGxvd2luZyBwYWNrYWdlIHJlZmVyZW5jZXNcbiAgICAgICAgICAvLyAgW25ldDYuMF06XG4gICAgICAgICAgLy8gIFRvcC1sZXZlbCBQYWNrYWdlICAgICAgUmVxdWVzdGVkICAgUmVzb2x2ZWRcbiAgICAgICAgICAvLyAgPiBIYXNoaUNvcnAuQ2RrdGYgICAgICAwLjAuMCAgICAgICAwLjAuMFxuICAgICAgICAgIC8vIG1hdGNoWzBdID0gZnVsbCBtYXRjaFxuICAgICAgICAgIC8vIG1hdGNoWzFdID0gcGFja2FnZSBuYW1lXG4gICAgICAgICAgLy8gbWF0Y2hbMl0gPSByZXF1ZXN0ZWQgdmVyc2lvblxuICAgICAgICAgIC8vIG1hdGNoWzNdID0gcmVzb2x2ZWQgdmVyc2lvblxuICAgICAgICAgIHJldHVybiByZWdleC5leGVjKGxpbmUpO1xuICAgICAgICB9KVxuICAgICAgICAuZmlsdGVyKChtYXRjaCkgPT4gISFtYXRjaClcbiAgICAgICAgLm1hcCgobWF0Y2gpID0+ICh7IG5hbWU6IG1hdGNoIVsxXSwgdmVyc2lvbjogbWF0Y2ghWzNdIH0pKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENvdWxkIG5vdCBkZXRlcm1pbmUgaW5zdGFsbGVkIHBhY2thZ2VzIHVzaW5nICdkb3RuZXQgbGlzdCBwYWNrYWdlJzogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmFic3RyYWN0IGNsYXNzIEphdmFQYWNrYWdlTWFuYWdlciBleHRlbmRzIFBhY2thZ2VNYW5hZ2VyIHtcbiAgcHVibGljIGFzeW5jIGlzTnBtVmVyc2lvbkF2YWlsYWJsZShcbiAgICBwYWNrYWdlTmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uOiBzdHJpbmcsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2hlY2tpbmcgaWYgJHtwYWNrYWdlTmFtZX1AJHtwYWNrYWdlVmVyc2lvbn0gaXMgYXZhaWxhYmxlYCk7XG5cbiAgICBjb25zdCBwYXJ0cyA9IHBhY2thZ2VOYW1lLnNwbGl0KFwiLlwiKTtcbiAgICBpZiAocGFydHMubGVuZ3RoICE9PSAzKSB7XG4gICAgICB0aHJvdyBFcnJvcnMuSW50ZXJuYWwoXG4gICAgICAgIGBFeHBlY3RlZCBwYWNrYWdlIG5hbWUgdG8gYmUgaW4gZm9ybWF0IFwiZ3JvdXAuYXJ0aWZhY3RcIiwgZS5nLiBcImNvbS5oYXNoaWNvcnAuY2RrdGYtcHJvdmlkZXItZ29vZ2xlXCIsIGdvdDogJHtwYWNrYWdlTmFtZX1gLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYWNrYWdlSWRlbnRpZmllciA9IHBhcnRzLnBvcCgpO1xuICAgIGNvbnN0IGdyb3VwSWQgPSBwYXJ0cy5qb2luKFwiLlwiKTtcblxuICAgIGNvbnN0IHVybCA9IGBodHRwczovL3NlYXJjaC5tYXZlbi5vcmcvc29scnNlYXJjaC9zZWxlY3Q/cT1nOiR7Z3JvdXBJZH0rQU5EK2E6JHtwYWNrYWdlSWRlbnRpZmllcn0rQU5EK3Y6JHtwYWNrYWdlVmVyc2lvbn0mcm93cz01Jnd0PWpzb25gO1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBUcnlpbmcgdG8gZmluZCBwYWNrYWdlIHZlcnNpb24gYnkgcXVlcnlpbmcgTWF2ZW4gQ2VudHJhbCB1bmRlciAnJHt1cmx9J2AsXG4gICAgKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG5cbiAgICBjb25zdCBqc29uID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMgYW55O1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBHb3QgcmVzcG9uc2UgZnJvbSB0aGUgTWF2ZW4gcGFja2FnZSBzZWFyY2ggZm9yICR7cGFja2FnZU5hbWV9OiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICBqc29uLFxuICAgICAgKX1gLFxuICAgICk7XG5cbiAgICByZXR1cm4gKGpzb24/LnJlc3BvbnNlPy5udW1Gb3VuZCA/PyAwKSA+IDA7XG4gIH1cbn1cblxuY2xhc3MgTWF2ZW5QYWNrYWdlTWFuYWdlciBleHRlbmRzIEphdmFQYWNrYWdlTWFuYWdlciB7XG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24gPSBcIkxBVEVTVFwiLCAvLyB0aGUgbGF0ZXN0IG9wdGlvbiBpcyBkZXByZWNhdGVkIGluIG1hdmVuIDMuNVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zb2xlLmxvZyhgQWRkaW5nICR7cGFja2FnZU5hbWV9IEAgJHtwYWNrYWdlVmVyc2lvbn0gdG8gcG9tLnhtbGApO1xuICAgIC8vIEFzc2VydCBwb20ueG1sIGV4aXN0c1xuICAgIGNvbnN0IHBvbVBhdGggPSBwYXRoLmpvaW4odGhpcy53b3JraW5nRGlyZWN0b3J5LCBcInBvbS54bWxcIik7XG4gICAgaWYgKCFleGlzdHNTeW5jKHBvbVBhdGgpKSB7XG4gICAgICB0aHJvdyBFcnJvcnMuVXNhZ2UoXG4gICAgICAgIFwiTm8gcG9tLnhtbCBmb3VuZCBpbiBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LiBQbGVhc2UgcnVuIHRoZSBjb21tYW5kIGZyb20gdGhlIHJvb3Qgb2YgeW91ciBwcm9qZWN0LlwiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBwb20gPSBhd2FpdCBmcy5yZWFkRmlsZShwb21QYXRoLCBcInV0ZjhcIik7XG4gICAgY29uc3QgcG9tWG1sID0gKGF3YWl0IHhtbDJqcyhwb20sIHt9KSkgYXMgRWxlbWVudDtcblxuICAgIC8vIE11dGF0ZSBkZXBlbmRlbmNpZXNcbiAgICBjb25zdCBuYW1lUGFydHMgPSBwYWNrYWdlTmFtZS5zcGxpdChcIi5cIik7XG4gICAgY29uc3QgZ3JvdXBJZCA9IG5hbWVQYXJ0cy5zbGljZSgwLCBuYW1lUGFydHMubGVuZ3RoIC0gMSkuam9pbihcIi5cIik7XG4gICAgY29uc3QgYXJ0aWZhY3RJZCA9IG5hbWVQYXJ0c1tuYW1lUGFydHMubGVuZ3RoIC0gMV07XG5cbiAgICBjb25zdCBuZXdEZXBlbmRlbmN5ID0gKGF3YWl0IHhtbDJqcyhcbiAgICAgIGA8ZGVwZW5kZW5jeT5cbiAgICA8Z3JvdXBJZD4ke2dyb3VwSWR9PC9ncm91cElkPlxuICAgIDxhcnRpZmFjdElkPiR7YXJ0aWZhY3RJZH08L2FydGlmYWN0SWQ+XG4gICAgPHZlcnNpb24+JHtwYWNrYWdlVmVyc2lvbn08L3ZlcnNpb24+XG48L2RlcGVuZGVuY3k+YCxcbiAgICApKSBhcyBFbGVtZW50O1xuXG4gICAgY29uc3QgZGVwZW5kZW5jaWVzID0gcG9tWG1sLmVsZW1lbnRzXG4gICAgICA/LmZpbmQoKGVsKSA9PiBlbC5uYW1lID09PSBcInByb2plY3RcIilcbiAgICAgID8uZWxlbWVudHM/LmZpbmQoKGVsKSA9PiBlbC5uYW1lID09PSBcImRlcGVuZGVuY2llc1wiKTtcblxuICAgIGlmICghZGVwZW5kZW5jaWVzKSB7XG4gICAgICB0aHJvdyBFcnJvcnMuVXNhZ2UoYENvdWxkIG5vdCBmaW5kIGRlcGVuZGVuY2llcyBzZWN0aW9uIGluIHRoZSBwb20ueG1sYCk7XG4gICAgfVxuICAgIGRlcGVuZGVuY2llcy5lbGVtZW50cyA9IChkZXBlbmRlbmNpZXM/LmVsZW1lbnRzIHx8IFtdKS5maWx0ZXIoXG4gICAgICAoZWwpID0+XG4gICAgICAgIGVsLmVsZW1lbnRzPy5zb21lKFxuICAgICAgICAgIChncm91cCkgPT5cbiAgICAgICAgICAgIGdyb3VwLm5hbWUgPT09IFwiZ3JvdXBJZFwiICYmIGdyb3VwLmVsZW1lbnRzPy5bMF0udGV4dCAhPT0gZ3JvdXBJZCxcbiAgICAgICAgKSB8fFxuICAgICAgICBlbC5lbGVtZW50cz8uc29tZShcbiAgICAgICAgICAoYXJ0aWZhY3QpID0+XG4gICAgICAgICAgICBhcnRpZmFjdC5uYW1lID09PSBcImFydGlmYWN0SWRcIiAmJlxuICAgICAgICAgICAgYXJ0aWZhY3QuZWxlbWVudHM/LlswXS50ZXh0ICE9PSBhcnRpZmFjdElkLFxuICAgICAgICApLFxuICAgICk7XG4gICAgZGVwZW5kZW5jaWVzPy5lbGVtZW50cz8ucHVzaChuZXdEZXBlbmRlbmN5LmVsZW1lbnRzIVswXSk7XG5cbiAgICAvLyBXcml0ZSBuZXcgcG9tLnhtbFxuICAgIGF3YWl0IGZzLndyaXRlRmlsZShwb21QYXRoLCBqczJ4bWwocG9tWG1sLCB7IHNwYWNlczogMiB9KSk7XG5cbiAgICAvLyBJbnN0YWxsXG4gICAgYXdhaXQgZXhlYyhcIm12blwiLCBbXCJpbnN0YWxsXCJdLCB7IGN3ZDogdGhpcy53b3JraW5nRGlyZWN0b3J5IH0pO1xuICAgIGNvbnNvbGUubG9nKFwiUGFja2FnZSBpbnN0YWxsZWQuXCIpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQcm92aWRlclBhY2thZ2VzKCk6IFByb21pc2U8XG4gICAgeyBuYW1lOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZyB9W11cbiAgPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBvbVBhdGggPSBwYXRoLmpvaW4odGhpcy53b3JraW5nRGlyZWN0b3J5LCBcInBvbS54bWxcIik7XG4gICAgICBpZiAoIWV4aXN0c1N5bmMocG9tUGF0aCkpIHtcbiAgICAgICAgdGhyb3cgRXJyb3JzLlVzYWdlKFxuICAgICAgICAgIFwiTm8gcG9tLnhtbCBmb3VuZCBpbiBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LiBQbGVhc2UgcnVuIHRoZSBjb21tYW5kIGZyb20gdGhlIHJvb3Qgb2YgeW91ciBwcm9qZWN0LlwiLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwb20gPSBhd2FpdCBmcy5yZWFkRmlsZShwb21QYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCBwb21YbWwgPSAoYXdhaXQgeG1sMmpzKHBvbSwge30pKSBhcyBFbGVtZW50O1xuXG4gICAgICBjb25zdCBkZXBlbmRlbmNpZXMgPVxuICAgICAgICBwb21YbWwuZWxlbWVudHNcbiAgICAgICAgICA/LmZpbmQoKGVsKSA9PiBlbC5uYW1lID09PSBcInByb2plY3RcIilcbiAgICAgICAgICA/LmVsZW1lbnRzPy5maW5kKChlbCkgPT4gZWwubmFtZSA9PT0gXCJkZXBlbmRlbmNpZXNcIik/LmVsZW1lbnRzID8/IFtdO1xuXG4gICAgICByZXR1cm4gZGVwZW5kZW5jaWVzXG4gICAgICAgIC5tYXAoKGRlcCkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBgJHtcbiAgICAgICAgICAgIGRlcC5lbGVtZW50cz8uZmluZCgoZWwpID0+IGVsLm5hbWUgPT09IFwiZ3JvdXBJZFwiKT8uZWxlbWVudHM/LlswXVxuICAgICAgICAgICAgICAudGV4dFxuICAgICAgICAgIH0uJHtcbiAgICAgICAgICAgIGRlcC5lbGVtZW50cz8uZmluZCgoZWwpID0+IGVsLm5hbWUgPT09IFwiYXJ0aWZhY3RJZFwiKT8uZWxlbWVudHM/LlswXVxuICAgICAgICAgICAgICAudGV4dFxuICAgICAgICAgIH1gLFxuICAgICAgICAgIHZlcnNpb246IGRlcC5lbGVtZW50cz8uZmluZCgoZWwpID0+IGVsLm5hbWUgPT09IFwidmVyc2lvblwiKVxuICAgICAgICAgICAgPy5lbGVtZW50cz8uWzBdLnRleHQgYXMgc3RyaW5nLFxuICAgICAgICB9KSlcbiAgICAgICAgLmZpbHRlcigoZGVwKSA9PiBkZXAubmFtZS5zdGFydHNXaXRoKFwiY29tLmhhc2hpY29ycC5jZGt0Zi1wcm92aWRlci1cIikpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ291bGQgbm90IGRldGVybWluZSBpbnN0YWxsZWQgcGFja2FnZXMgcmVhZGluZyB0aGUgcG9tLnhtbDogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIEdyYWRsZVBhY2thZ2VNYW5hZ2VyIGV4dGVuZHMgSmF2YVBhY2thZ2VNYW5hZ2VyIHtcbiAgcHVibGljIHN0YXRpYyBpc0dyYWRsZVByb2plY3Qod29ya2luZ0RpcmVjdG9yeTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzR3JhZGxlUHJvamVjdCh3b3JraW5nRGlyZWN0b3J5KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VGUU46IHN0cmluZyxcbiAgICBwYWNrYWdlVmVyc2lvbiA9IFwibGF0ZXN0LnJlbGVhc2VcIixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYnVpbGRHcmFkbGVQYXRoID0gcGF0aC5qb2luKHRoaXMud29ya2luZ0RpcmVjdG9yeSwgXCJidWlsZC5ncmFkbGVcIik7XG4gICAgY29uc3QgYnVpbGRHcmFkbGUgPSBhd2FpdCBmcy5yZWFkRmlsZShidWlsZEdyYWRsZVBhdGgsIFwidXRmOFwiKTtcbiAgICBjb25zdCBidWlsZEdyYWRsZUxpbmVzID0gYnVpbGRHcmFkbGUuc3BsaXQoL1xccj9cXG4vKTtcblxuICAgIGNvbnN0IGRlcGVuZGVuY2llc1JlZ2V4ID0gL2RlcGVuZGVuY2llc1xccytcXHsvaTtcbiAgICBjb25zdCBkZXBlbmRlbmN5QmxvY2tTdGFydCA9IGJ1aWxkR3JhZGxlTGluZXMuZmluZEluZGV4KChsaW5lKSA9PlxuICAgICAgZGVwZW5kZW5jaWVzUmVnZXgudGVzdChsaW5lKSxcbiAgICApO1xuICAgIGlmIChkZXBlbmRlbmN5QmxvY2tTdGFydCA9PT0gLTEpIHtcbiAgICAgIHRocm93IEVycm9ycy5Vc2FnZShcbiAgICAgICAgXCJDb3VsZCBub3QgZmluZCBkZXBlbmRlbmNpZXMgc2VjdGlvbiBpbiB0aGUgYnVpbGQuZ3JhZGxlXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHBhY2thZ2VTZWdtZW50cyA9IHBhY2thZ2VGUU4uc3BsaXQoXCIuXCIpO1xuICAgIGNvbnN0IHBhY2thZ2VOYW1lID0gcGFja2FnZVNlZ21lbnRzLnBvcCgpO1xuICAgIGNvbnN0IGdyb3VwTmFtZSA9IHBhY2thZ2VTZWdtZW50cy5qb2luKFwiLlwiKTtcbiAgICBjb25zdCBkZXBlbmRlbmN5U3BlY2lmaWVyID0gYCR7Z3JvdXBOYW1lfToke3BhY2thZ2VOYW1lfWA7XG4gICAgY29uc3QgZGVwZW5kZW5jeUFuZFZlcnNpb25TcGVjaWZpZXIgPSBgJHtkZXBlbmRlbmN5U3BlY2lmaWVyfToke3BhY2thZ2VWZXJzaW9ufWA7XG5cbiAgICBjb25zdCBleGlzdGluZ0RlcGVuZGVuY3kgPSBidWlsZEdyYWRsZUxpbmVzLmZpbmRJbmRleCgobGluZSkgPT5cbiAgICAgIGxpbmUuaW5jbHVkZXMoZGVwZW5kZW5jeVNwZWNpZmllciksXG4gICAgKTtcbiAgICBpZiAoZXhpc3RpbmdEZXBlbmRlbmN5ICE9PSAtMSkge1xuICAgICAgYnVpbGRHcmFkbGVMaW5lcy5zcGxpY2UoZXhpc3RpbmdEZXBlbmRlbmN5LCAxKTtcbiAgICB9XG5cbiAgICBjb25zdCBuZXdQYWNrYWdlRGVwZW5kZW5jeSA9IGBcXHRpbXBsZW1lbnRhdGlvbiAnJHtkZXBlbmRlbmN5QW5kVmVyc2lvblNwZWNpZmllcn0nYDtcbiAgICBidWlsZEdyYWRsZUxpbmVzLnNwbGljZShkZXBlbmRlbmN5QmxvY2tTdGFydCArIDEsIDAsIG5ld1BhY2thZ2VEZXBlbmRlbmN5KTtcblxuICAgIGF3YWl0IGZzLndyaXRlRmlsZShidWlsZEdyYWRsZVBhdGgsIGJ1aWxkR3JhZGxlTGluZXMuam9pbihcIlxcblwiKSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdFByb3ZpZGVyUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICBjb25zdCBkZXBlbmRlbmNpZXMgPSBhd2FpdCBnZXRHcmFkbGVEZXBlbmRlbmNpZXMoKTtcbiAgICBpZiAoIWRlcGVuZGVuY2llcykge1xuICAgICAgdGhyb3cgRXJyb3JzLlVzYWdlKFwiQ291bGQgbm90IGZpbmQgYW55IGRlcGVuZGVuY2llc1wiKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZXBlbmRlbmN5TGlzdCA9IGRlcGVuZGVuY2llc1xuICAgICAgLm1hcCgobGluZSkgPT4gZ2V0RGVwZW5kZW5jeUluZm9ybWF0aW9uRnJvbUxpbmUobGluZSkpXG4gICAgICAuZmlsdGVyKChkZXApID0+IHtcbiAgICAgICAgaWYgKCFkZXApIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlcC5uYW1lLmluY2x1ZGVzKFwiY2RrdGYtcHJvdmlkZXItXCIpO1xuICAgICAgfSlcbiAgICAgIC5tYXAoKGRlcCkgPT4gKHtcbiAgICAgICAgbmFtZTogYGNvbS5oYXNoaWNvcnAuJHtkZXAhLm5hbWV9YCxcbiAgICAgICAgdmVyc2lvbjogZGVwIS52ZXJzaW9uLFxuICAgICAgfSkpO1xuXG4gICAgcmV0dXJuIGRlcGVuZGVuY3lMaXN0O1xuICB9XG59XG5cbmNsYXNzIEdvUGFja2FnZU1hbmFnZXIgZXh0ZW5kcyBQYWNrYWdlTWFuYWdlciB7XG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnNvbGUubG9nKGBBZGRpbmcgcGFja2FnZSAke3BhY2thZ2VOYW1lfSBAICR7cGFja2FnZVZlcnNpb259YCk7XG5cbiAgICBjb25zdCBtYWpvclZlcnNpb246IG51bWJlciB8IHVuZGVmaW5lZCA9IHBhY2thZ2VWZXJzaW9uXG4gICAgICA/IHNlbXZlci5tYWpvcihwYWNrYWdlVmVyc2lvbilcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgbGV0IHZlcnNpb25QYWNrYWdlU3VmZml4ID0gXCJcIjtcbiAgICBpZiAodHlwZW9mIG1ham9yVmVyc2lvbiA9PT0gXCJudW1iZXJcIiAmJiBtYWpvclZlcnNpb24gPiAxKSB7XG4gICAgICB2ZXJzaW9uUGFja2FnZVN1ZmZpeCA9IGAvdiR7bWFqb3JWZXJzaW9ufWA7XG4gICAgfVxuXG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYFJ1bm5pbmcgJ2dvIGdldCAke3BhY2thZ2VOYW1lfSR7dmVyc2lvblBhY2thZ2VTdWZmaXh9QHYke3BhY2thZ2VWZXJzaW9ufSdgLFxuICAgICk7XG4gICAgLy8gSW5zdGFsbFxuICAgIGF3YWl0IGV4ZWMoXG4gICAgICBcImdvXCIsXG4gICAgICBbXCJnZXRcIiwgYCR7cGFja2FnZU5hbWV9JHt2ZXJzaW9uUGFja2FnZVN1ZmZpeH1AdiR7cGFja2FnZVZlcnNpb259YF0sXG4gICAgICB7XG4gICAgICAgIGN3ZDogdGhpcy53b3JraW5nRGlyZWN0b3J5LFxuICAgICAgfSxcbiAgICApO1xuXG4gICAgY29uc29sZS5sb2coXCJQYWNrYWdlIGluc3RhbGxlZC5cIik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgaXNOcG1WZXJzaW9uQXZhaWxhYmxlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDaGVja2luZyBpZiAke3BhY2thZ2VOYW1lfUAke3BhY2thZ2VWZXJzaW9ufSBpcyBhdmFpbGFibGVgKTtcblxuICAgIC8vIGUuZy4gZ2l0aHViLmNvbS9jZGt0Zi9jZGt0Zi1wcm92aWRlci1nb29nbGUtZ28vZ29vZ2xlXG4gICAgY29uc3QgcGFydHMgPSBwYWNrYWdlTmFtZS5zcGxpdChcIi9cIik7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gNCkge1xuICAgICAgdGhyb3cgRXJyb3JzLkludGVybmFsKFxuICAgICAgICBgRXhwZWN0aW5nIEdvIHBhY2thZ2UgbmFtZSB0byBiZSBpbiB0aGUgZm9ybWF0IG9mIGdpdGh1Yi5jb20vPG9yZz4vPHJlcG8+LzxwYWNrYWdlPiwgZ290ICR7cGFja2FnZU5hbWV9YCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3JnID0gcGFydHNbMV07XG4gICAgY29uc3QgcmVwbyA9IHBhcnRzWzJdO1xuICAgIGNvbnN0IHBhY2thZ2VQYXRoID0gcGFydHNbM107XG5cbiAgICBjb25zdCB1cmwgPSBgaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8ke29yZ30vJHtyZXBvfS9naXQvcmVmL3RhZ3MvJHtwYWNrYWdlUGF0aH0vdiR7cGFja2FnZVZlcnNpb259YDtcbiAgICBsb2dnZXIuZGVidWcoYEZldGNoaW5nIHRhZ3MgZm9yICR7b3JnfS8ke3JlcG99IGZyb20gJyR7dXJsfSdgKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCwge1xuICAgICAgaGVhZGVyczoge1xuICAgICAgICBBY2NlcHQ6IFwiYXBwbGljYXRpb24vdm5kLmdpdGh1Yitqc29uXCIsXG4gICAgICAgIFwiVXNlci1BZ2VudFwiOiBcIk9wZW5Db25zdHJ1Y3RzL2Nka3RuLWNsaVwiLFxuICAgICAgICAuLi4oR0lUSFVCX0FQSV9UT0tFTl9DREtURlxuICAgICAgICAgID8geyBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7R0lUSFVCX0FQSV9UT0tFTl9DREtURn1gIH1cbiAgICAgICAgICA6IHt9KSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBqc29uID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMgYW55O1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBHb3QgcmVzcG9uc2UgZnJvbSBHaXRIdWJzIHJlcG9zaXRvcnkgdGFnIGVuZHBvaW50IGZvciAke3BhY2thZ2VOYW1lfTogJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAganNvbixcbiAgICAgICl9YCxcbiAgICApO1xuXG4gICAgaWYgKGpzb24gJiYganNvbi5yZWYpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGxvZ2dlci5pbmZvKFxuICAgICAgYENvdWxkIG5vdCBmaW5kIHRoZSB0YWcgJHtwYWNrYWdlUGF0aH0vdiR7cGFja2FnZVZlcnNpb259IGluIHRoZSByZXBvc2l0b3J5ICR7b3JnfS8ke3JlcG99OiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICBqc29uLFxuICAgICAgKX19YCxcbiAgICApO1xuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQcm92aWRlclBhY2thZ2VzKCk6IFByb21pc2U8XG4gICAgeyBuYW1lOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZyB9W11cbiAgPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGdvU3VtUGF0aCA9IHBhdGguam9pbih0aGlzLndvcmtpbmdEaXJlY3RvcnksIFwiZ28uc3VtXCIpO1xuICAgICAgaWYgKCFleGlzdHNTeW5jKGdvU3VtUGF0aCkpIHtcbiAgICAgICAgdGhyb3cgRXJyb3JzLlVzYWdlKFxuICAgICAgICAgIFwiTm8gZ28uc3VtIGZvdW5kIGluIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuIFBsZWFzZSBydW4gdGhlIGNvbW1hbmQgZnJvbSB0aGUgcm9vdCBvZiB5b3VyIHByb2plY3QuXCIsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGdvU3VtID0gYXdhaXQgZnMucmVhZEZpbGUoZ29TdW1QYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCBkZWR1cGVkUHJvdmlkZXJOYW1lcyA9IG5ldyBTZXQoKTtcblxuICAgICAgcmV0dXJuIGdvU3VtXG4gICAgICAgIC5zcGxpdChcIlxcblwiKVxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChsaW5lKSA9PlxuICAgICAgICAgICAgbGluZS5zdGFydHNXaXRoKFwiZ2l0aHViLmNvbS9oYXNoaWNvcnAvY2RrdGYtcHJvdmlkZXJcIikgfHxcbiAgICAgICAgICAgIGxpbmUuc3RhcnRzV2l0aChcImdpdGh1Yi5jb20vY2RrdGYvY2RrdGYtcHJvdmlkZXJcIiksXG4gICAgICAgIClcbiAgICAgICAgLm1hcCgobGluZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHBhcnRzID0gbGluZS5zcGxpdChcIiBcIik7XG4gICAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gMykge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3JzLkludGVybmFsKFxuICAgICAgICAgICAgICBgRXhwZWN0ZWQgbGluZSBpbiBnby5zdW0gdG8gYmUgaW4gdGhlIGZvcm1hdCBvZiAnPHBhY2thZ2U+IDx2ZXJzaW9uPiA8Y2hlY2tzdW0+JywgZ290OiAke2xpbmV9YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gcGFydFswXSBjb3VsZCBiZSBnaXRodWIuY29tL2F3cy9jb25zdHJ1Y3RzLWdvL2NvbnN0cnVjdHMvdjEwXG4gICAgICAgICAgY29uc3QgbmFtZSA9IHBhcnRzWzBdLnNwbGl0KFwiL1wiKS5zbGljZSgwLCA0KS5qb2luKFwiL1wiKTtcblxuICAgICAgICAgIGNvbnN0IHZlcnNpb24gPSBwYXJ0c1sxXS5zcGxpdChcIi9cIilbMF07XG5cbiAgICAgICAgICBpZiAoZGVkdXBlZFByb3ZpZGVyTmFtZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICByZXR1cm4geyBuYW1lOiBcIlwiLCB2ZXJzaW9uOiBcIlwiIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVkdXBlZFByb3ZpZGVyTmFtZXMuYWRkKG5hbWUpO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICB2ZXJzaW9uLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pXG4gICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgKHByb3ZpZGVySW5mbykgPT4gISFwcm92aWRlckluZm8ubmFtZSAmJiAhIXByb3ZpZGVySW5mby52ZXJzaW9uLFxuICAgICAgICApO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ291bGQgbm90IGRldGVybWluZSBpbnN0YWxsZWQgcGFja2FnZXMgcmVhZGluZyB0aGUgZ28uc3VtOiAke2UubWVzc2FnZX1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|