@cdktn/hcl2cdk 0.23.0-pre.36 → 0.23.0-pre.39
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/build/__tests__/coerceType.test.js +165 -0
- package/build/__tests__/expressionToTs.test.js +693 -0
- package/build/__tests__/expressions.test.js +415 -0
- package/build/__tests__/findExpressionType.test.js +105 -0
- package/build/__tests__/functions.test.js +605 -0
- package/build/__tests__/generation.test.js +45 -0
- package/build/__tests__/jsii-rosetta-workarounds.test.js +86 -0
- package/build/__tests__/partialCode.test.js +390 -0
- package/build/__tests__/terraformSchema.test.js +105 -0
- package/build/__tests__/testHelpers.js +16 -0
- package/build/coerceType.js +240 -0
- package/build/dynamic-blocks.js +44 -0
- package/build/expressions.js +633 -0
- package/build/function-bindings/functions.generated.js +1142 -0
- package/build/function-bindings/functions.js +73 -0
- package/build/generation.js +676 -0
- package/{lib → build}/index.d.ts +2 -2
- package/build/index.js +364 -0
- package/build/iteration.js +87 -0
- package/build/jsii-rosetta-workarounds.js +126 -0
- package/build/partialCode.js +116 -0
- package/build/provider.js +40 -0
- package/build/references.js +141 -0
- package/build/schema.js +81 -0
- package/build/telemetryAllowList.json +24 -0
- package/build/terraformSchema.js +136 -0
- package/build/types.js +3 -0
- package/build/utils.js +25 -0
- package/build/variables.js +172 -0
- package/package.json +8 -8
- package/tsconfig.json +4 -2
- package/lib/__tests__/coerceType.test.js +0 -165
- package/lib/__tests__/expressionToTs.test.js +0 -693
- package/lib/__tests__/expressions.test.js +0 -415
- package/lib/__tests__/findExpressionType.test.js +0 -105
- package/lib/__tests__/functions.test.js +0 -605
- package/lib/__tests__/generation.test.js +0 -45
- package/lib/__tests__/jsii-rosetta-workarounds.test.js +0 -86
- package/lib/__tests__/partialCode.test.js +0 -390
- package/lib/__tests__/terraformSchema.test.js +0 -105
- package/lib/__tests__/testHelpers.js +0 -16
- package/lib/coerceType.js +0 -240
- package/lib/dynamic-blocks.js +0 -44
- package/lib/expressions.js +0 -634
- package/lib/function-bindings/functions.generated.js +0 -1142
- package/lib/function-bindings/functions.js +0 -73
- package/lib/generation.js +0 -676
- package/lib/index.js +0 -364
- package/lib/iteration.js +0 -87
- package/lib/jsii-rosetta-workarounds.js +0 -126
- package/lib/partialCode.js +0 -116
- package/lib/provider.js +0 -40
- package/lib/references.js +0 -141
- package/lib/schema.js +0 -81
- package/lib/terraformSchema.js +0 -136
- package/lib/types.js +0 -3
- package/lib/utils.js +0 -25
- package/lib/variables.js +0 -172
- /package/{lib → build}/__tests__/coerceType.test.d.ts +0 -0
- /package/{lib → build}/__tests__/expressionToTs.test.d.ts +0 -0
- /package/{lib → build}/__tests__/expressions.test.d.ts +0 -0
- /package/{lib → build}/__tests__/findExpressionType.test.d.ts +0 -0
- /package/{lib → build}/__tests__/functions.test.d.ts +0 -0
- /package/{lib → build}/__tests__/generation.test.d.ts +0 -0
- /package/{lib → build}/__tests__/jsii-rosetta-workarounds.test.d.ts +0 -0
- /package/{lib → build}/__tests__/partialCode.test.d.ts +0 -0
- /package/{lib → build}/__tests__/terraformSchema.test.d.ts +0 -0
- /package/{lib → build}/__tests__/testHelpers.d.ts +0 -0
- /package/{lib → build}/coerceType.d.ts +0 -0
- /package/{lib → build}/dynamic-blocks.d.ts +0 -0
- /package/{lib → build}/expressions.d.ts +0 -0
- /package/{lib → build}/function-bindings/functions.d.ts +0 -0
- /package/{lib → build}/function-bindings/functions.generated.d.ts +0 -0
- /package/{lib → build}/generation.d.ts +0 -0
- /package/{lib → build}/iteration.d.ts +0 -0
- /package/{lib → build}/jsii-rosetta-workarounds.d.ts +0 -0
- /package/{lib → build}/partialCode.d.ts +0 -0
- /package/{lib → build}/provider.d.ts +0 -0
- /package/{lib → build}/references.d.ts +0 -0
- /package/{lib → build}/schema.d.ts +0 -0
- /package/{lib → build}/terraformSchema.d.ts +0 -0
- /package/{lib → build}/types.d.ts +0 -0
- /package/{lib → build}/utils.d.ts +0 -0
- /package/{lib → build}/variables.d.ts +0 -0
- /package/{lib → src}/telemetryAllowList.json +0 -0
|
@@ -0,0 +1,676 @@
|
|
|
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.generateConfigType = exports.buildImports = exports.providerConstructImports = exports.wrapCodeInConstructor = exports.addImportForCodeContainer = exports.gen = exports.moduleImports = exports.providerImports = exports.constructsImport = exports.cdktfImport = exports.provider = exports.imports = exports.modules = exports.local = exports.variable = exports.variableTypeToAst = exports.output = exports.resource = exports.backendToExpression = exports.valueToTs = exports.attributeNameToCdktfName = void 0;
|
|
30
|
+
// Copyright (c) HashiCorp, Inc
|
|
31
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
32
|
+
const generator_1 = __importDefault(require("@babel/generator"));
|
|
33
|
+
const template_1 = __importDefault(require("@babel/template"));
|
|
34
|
+
const t = __importStar(require("@babel/types"));
|
|
35
|
+
const prettier_1 = __importDefault(require("prettier"));
|
|
36
|
+
const utils_1 = require("./utils");
|
|
37
|
+
const expressions_1 = require("./expressions");
|
|
38
|
+
const references_1 = require("./references");
|
|
39
|
+
const provider_generator_1 = require("@cdktn/provider-generator");
|
|
40
|
+
const terraformSchema_1 = require("./terraformSchema");
|
|
41
|
+
const commons_1 = require("@cdktn/commons");
|
|
42
|
+
const hcl2json_1 = require("@cdktn/hcl2json");
|
|
43
|
+
const dynamic_blocks_1 = require("./dynamic-blocks");
|
|
44
|
+
const variables_1 = require("./variables");
|
|
45
|
+
const util_1 = require("cdktn/lib/util");
|
|
46
|
+
const partialCode_1 = require("./partialCode");
|
|
47
|
+
function getReference(graph, id) {
|
|
48
|
+
utils_1.logger.debug(`Finding reference for ${id}`);
|
|
49
|
+
const neighbors = graph.outNeighbors(id);
|
|
50
|
+
if (neighbors.length > 0) {
|
|
51
|
+
utils_1.logger.debug(`Found neighbors ${neighbors} for ${id}`);
|
|
52
|
+
const edge = graph.directedEdge(id, neighbors[0]);
|
|
53
|
+
if (edge) {
|
|
54
|
+
utils_1.logger.debug(`Found first edge ${edge} for ${id}`);
|
|
55
|
+
utils_1.logger.debug(`Returning reference ${graph.getEdgeAttribute(edge, "ref")}`);
|
|
56
|
+
return graph.getEdgeAttribute(edge, "ref");
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
utils_1.logger.debug(`Found no edge for ${id}`);
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function attributeNameToCdktfName(name) {
|
|
68
|
+
return (0, provider_generator_1.escapeAttributeName)((0, utils_1.camelCase)(name));
|
|
69
|
+
}
|
|
70
|
+
exports.attributeNameToCdktfName = attributeNameToCdktfName;
|
|
71
|
+
const valueToTs = async (scope, item, path, isModule = false) => {
|
|
72
|
+
switch (typeof item) {
|
|
73
|
+
case "string":
|
|
74
|
+
if ((await (0, references_1.findUsedReferences)(scope.nodeIds, item)).some((ref) => path.startsWith(ref.referencee.id))) {
|
|
75
|
+
return t.stringLiteral(item);
|
|
76
|
+
}
|
|
77
|
+
return await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${item}"`, () => (0, terraformSchema_1.getDesiredType)(scope, path));
|
|
78
|
+
case "boolean":
|
|
79
|
+
return await (0, expressions_1.convertTerraformExpressionToTs)(scope, `${item}`, () => (0, terraformSchema_1.getDesiredType)(scope, path));
|
|
80
|
+
case "number":
|
|
81
|
+
return await (0, expressions_1.convertTerraformExpressionToTs)(scope, `${item}`, () => (0, terraformSchema_1.getDesiredType)(scope, path));
|
|
82
|
+
case "object": {
|
|
83
|
+
if (item === undefined || item === null) {
|
|
84
|
+
return t.nullLiteral();
|
|
85
|
+
}
|
|
86
|
+
// For iterators and dynamic blocks we put the correct TS expression in the config ahead of time
|
|
87
|
+
if (t.isNode(item) && t.isExpression(item)) {
|
|
88
|
+
return item;
|
|
89
|
+
}
|
|
90
|
+
const attributeType = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, path);
|
|
91
|
+
function shouldRemoveArrayBasedOnType(attributeType) {
|
|
92
|
+
if (!attributeType) {
|
|
93
|
+
return false; // The default assumption is we need the array
|
|
94
|
+
}
|
|
95
|
+
// maps and object don't need to be wrapped in an array
|
|
96
|
+
if (Array.isArray(attributeType) &&
|
|
97
|
+
(attributeType[0] === "map" || attributeType[0] === "object")) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
// If it's a block type with max_items = 1 we don't need to wrap it in an array
|
|
101
|
+
if (typeof attributeType === "object" &&
|
|
102
|
+
"max_items" in attributeType &&
|
|
103
|
+
attributeType.max_items === 1) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
const unwrappedItem = Array.isArray(item) &&
|
|
109
|
+
(shouldRemoveArrayBasedOnType(attributeType) ||
|
|
110
|
+
path.endsWith("lifecycle") ||
|
|
111
|
+
path.endsWith("connection"))
|
|
112
|
+
? item[0]
|
|
113
|
+
: item;
|
|
114
|
+
if (Array.isArray(unwrappedItem)) {
|
|
115
|
+
return t.arrayExpression(await Promise.all(unwrappedItem.map((i) => (0, exports.valueToTs)(scope, i, `${path}.[]`))));
|
|
116
|
+
}
|
|
117
|
+
return t.objectExpression((await Promise.all(Object.entries(unwrappedItem).map(async ([key, value]) => {
|
|
118
|
+
if (value === undefined) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
if (key === "dynamic") {
|
|
122
|
+
const { for_each, ...others } = value;
|
|
123
|
+
const dynamicRef = Object.keys(others)[0];
|
|
124
|
+
return t.objectProperty(t.identifier(scope.withinOverrideExpression
|
|
125
|
+
? dynamicRef
|
|
126
|
+
: (0, provider_generator_1.escapeAttributeName)((0, utils_1.camelCase)(dynamicRef))), t.arrayExpression());
|
|
127
|
+
}
|
|
128
|
+
const itemPath = `${path}.${key}`;
|
|
129
|
+
const itemAttributeType = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, itemPath);
|
|
130
|
+
const typeMetadata = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, itemPath);
|
|
131
|
+
const isSingleItemBlock = typeMetadata &&
|
|
132
|
+
typeof typeMetadata === "object" &&
|
|
133
|
+
Object.prototype.hasOwnProperty.call(typeMetadata, "max_items")
|
|
134
|
+
? typeMetadata.max_items === 1
|
|
135
|
+
: false;
|
|
136
|
+
const shouldBeArray = typeof value === "object" &&
|
|
137
|
+
!Array.isArray(value) &&
|
|
138
|
+
!(t.isNode(value) && t.isExpression(value)) &&
|
|
139
|
+
!isSingleItemBlock &&
|
|
140
|
+
// Map type attributes must not be wrapped in arrays
|
|
141
|
+
!(0, terraformSchema_1.isMapAttribute)(itemAttributeType) &&
|
|
142
|
+
key !== "tags" &&
|
|
143
|
+
key !== "forEach" &&
|
|
144
|
+
key !== "lifecycle";
|
|
145
|
+
const keepKeyName = !isModule &&
|
|
146
|
+
key !== "depends_on" &&
|
|
147
|
+
!path.includes("lifecycle") &&
|
|
148
|
+
(key === "for_each" ||
|
|
149
|
+
!typeMetadata ||
|
|
150
|
+
(0, terraformSchema_1.isMapAttribute)(attributeType)) &&
|
|
151
|
+
!(path.startsWith("var.") && path.includes("validation"));
|
|
152
|
+
return t.objectProperty(t.stringLiteral(keepKeyName ? key : attributeNameToCdktfName(key)), shouldBeArray
|
|
153
|
+
? t.arrayExpression([await (0, exports.valueToTs)(scope, value, itemPath)])
|
|
154
|
+
: await (0, exports.valueToTs)(scope, value, itemPath));
|
|
155
|
+
}))).filter((expr) => expr !== undefined));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
throw new Error("Unsupported type " + item);
|
|
159
|
+
};
|
|
160
|
+
exports.valueToTs = valueToTs;
|
|
161
|
+
async function backendToExpression(scope, tf) {
|
|
162
|
+
return (await Promise.all(Object.entries(tf || {}).map(async ([type, [config]]) => {
|
|
163
|
+
const backendIdentifier = (0, utils_1.pascalCase)(`${type}Backend`);
|
|
164
|
+
scope.importables.push({
|
|
165
|
+
constructName: backendIdentifier,
|
|
166
|
+
provider: "cdktn",
|
|
167
|
+
});
|
|
168
|
+
return t.expressionStatement(t.newExpression(t.identifier(backendIdentifier), [
|
|
169
|
+
t.thisExpression(),
|
|
170
|
+
t.objectExpression((await Promise.all(Object.entries(config).map(async ([property, value]) => t.objectProperty(t.identifier((0, utils_1.camelCase)(property)), await (0, exports.valueToTs)(scope, value, "path-for-backends-can-be-ignored"))))).reduce((carry, item) => [...carry, item], [])),
|
|
171
|
+
]));
|
|
172
|
+
}))).reduce((carry, item) => [...carry, item], []);
|
|
173
|
+
}
|
|
174
|
+
exports.backendToExpression = backendToExpression;
|
|
175
|
+
function addOverrideExpression(variable, path, value, explanatoryComment) {
|
|
176
|
+
const ast = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(variable), t.identifier("addOverride")), [t.stringLiteral(path), value]));
|
|
177
|
+
if (explanatoryComment) {
|
|
178
|
+
t.addComment(ast, "leading", explanatoryComment);
|
|
179
|
+
}
|
|
180
|
+
return ast;
|
|
181
|
+
}
|
|
182
|
+
function addOverrideLogicalIdExpression(variable, logicalId) {
|
|
183
|
+
const ast = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(variable), t.identifier("overrideLogicalId")), [t.stringLiteral(logicalId)]));
|
|
184
|
+
t.addComment(ast, "leading", "This allows the Terraform resource name to match the original name. You can remove the call if you don't need them to match.");
|
|
185
|
+
return ast;
|
|
186
|
+
}
|
|
187
|
+
function getRemoteStateType(item) {
|
|
188
|
+
const backendRecord = item.find((val) => val.backend);
|
|
189
|
+
if (backendRecord) {
|
|
190
|
+
const backend = backendRecord.backend;
|
|
191
|
+
switch (backend) {
|
|
192
|
+
case "remote":
|
|
193
|
+
return "";
|
|
194
|
+
case "etcdv3":
|
|
195
|
+
return "_etcd_v3";
|
|
196
|
+
default:
|
|
197
|
+
return `_${backend}`;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
return "";
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function resourceType(provider, name, item) {
|
|
205
|
+
switch (provider) {
|
|
206
|
+
case "data.terraform":
|
|
207
|
+
return `cdktn.data_terraform_${name.join("_")}${getRemoteStateType(item)}`;
|
|
208
|
+
case "null":
|
|
209
|
+
return `NullProvider.${name.join("_")}`;
|
|
210
|
+
default:
|
|
211
|
+
return `${provider}.${name.join("_")}`;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function mapConfigPerResourceType(resource, item) {
|
|
215
|
+
// Backends have a slightly different API
|
|
216
|
+
if (resource.startsWith("cdktn.data_terraform_")) {
|
|
217
|
+
return item.config;
|
|
218
|
+
}
|
|
219
|
+
return item;
|
|
220
|
+
}
|
|
221
|
+
const loopComment = `In most cases loops should be handled in the programming language context and
|
|
222
|
+
not inside of the Terraform context. If you are looping over something external, e.g. a variable or a file input
|
|
223
|
+
you should consider using a for loop. If you are looping over something only known to Terraform, e.g. a result of a data source
|
|
224
|
+
you need to keep this like it is.`;
|
|
225
|
+
async function resource(scope, type, key, id, item, graph) {
|
|
226
|
+
const [provider, ...name] = type.split("_");
|
|
227
|
+
const resource = resourceType(provider, name, item);
|
|
228
|
+
if (!provider) {
|
|
229
|
+
throw new Error(`Could not parse resource type '${type}'`);
|
|
230
|
+
}
|
|
231
|
+
let expressions = [];
|
|
232
|
+
const varName = (0, variables_1.variableName)(scope, resource, key);
|
|
233
|
+
const { for_each, count, provisioner, ...config } = item[0];
|
|
234
|
+
const mappedConfig = mapConfigPerResourceType(resource, config);
|
|
235
|
+
let forEachIteratorName;
|
|
236
|
+
if (for_each) {
|
|
237
|
+
forEachIteratorName = (0, variables_1.variableName)(scope, resource, `${key}_for_each_iterator`);
|
|
238
|
+
const referenceAst = await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${for_each}"`, () => ["list", "dynamic"]);
|
|
239
|
+
scope.importables.push({
|
|
240
|
+
provider: "cdktn",
|
|
241
|
+
constructName: "TerraformIterator",
|
|
242
|
+
});
|
|
243
|
+
const iterator = t.variableDeclaration("const", [
|
|
244
|
+
t.variableDeclarator(t.identifier(forEachIteratorName), t.callExpression(t.memberExpression(t.identifier("TerraformIterator"), t.identifier("fromList")), [referenceAst])),
|
|
245
|
+
]);
|
|
246
|
+
t.addComment(iterator, "leading", loopComment);
|
|
247
|
+
expressions.push(iterator);
|
|
248
|
+
mappedConfig.forEach = t.identifier(forEachIteratorName);
|
|
249
|
+
}
|
|
250
|
+
let countIteratorName;
|
|
251
|
+
if (count) {
|
|
252
|
+
countIteratorName = (0, variables_1.variableName)(scope, resource, `${key}_count`);
|
|
253
|
+
const referenceAst = await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${count}"`, () => "number");
|
|
254
|
+
scope.importables.push({
|
|
255
|
+
provider: "cdktn",
|
|
256
|
+
constructName: "TerraformCount",
|
|
257
|
+
});
|
|
258
|
+
const iterator = t.variableDeclaration("const", [
|
|
259
|
+
t.variableDeclarator(t.identifier(countIteratorName), t.callExpression(t.memberExpression(t.identifier("TerraformCount"), t.identifier("of")), [referenceAst])),
|
|
260
|
+
]);
|
|
261
|
+
t.addComment(iterator, "leading", loopComment);
|
|
262
|
+
mappedConfig.count = t.identifier(countIteratorName);
|
|
263
|
+
expressions.push(iterator);
|
|
264
|
+
}
|
|
265
|
+
const dynBlocks = (0, dynamic_blocks_1.extractDynamicBlocks)(mappedConfig);
|
|
266
|
+
const nestedDynamicBlocks = dynBlocks.filter((block) => (0, dynamic_blocks_1.isNestedDynamicBlock)(dynBlocks, block));
|
|
267
|
+
const dynamicBlocksUsingOverrides = dynBlocks.filter((block) =>
|
|
268
|
+
// nested blocks need overrides
|
|
269
|
+
nestedDynamicBlocks.includes(block) ||
|
|
270
|
+
// blocks that contain nested blocks need them as well
|
|
271
|
+
nestedDynamicBlocks.some((nestedBlock) => nestedBlock.path.startsWith(block.path)));
|
|
272
|
+
// all others can be handled by the CDKTN runtime
|
|
273
|
+
const dynamicBlocksUsingRuntime = dynBlocks.filter((block) => !dynamicBlocksUsingOverrides.includes(block));
|
|
274
|
+
for (const [i, block] of dynamicBlocksUsingRuntime.entries()) {
|
|
275
|
+
const dynamicBlockIteratorName = (0, variables_1.variableName)(scope, resource, `${key}_dynamic_iterator_${i}`);
|
|
276
|
+
const referenceAst = await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${block.for_each}"`, () => ["list", "dynamic"]);
|
|
277
|
+
scope.importables.push({
|
|
278
|
+
provider: "cdktn",
|
|
279
|
+
constructName: "TerraformIterator",
|
|
280
|
+
});
|
|
281
|
+
const iterator = t.variableDeclaration("const", [
|
|
282
|
+
t.variableDeclarator(t.identifier(dynamicBlockIteratorName), t.callExpression(t.memberExpression(t.identifier("TerraformIterator"), t.identifier("fromList")), [referenceAst])),
|
|
283
|
+
]);
|
|
284
|
+
t.addComment(iterator, "leading", loopComment);
|
|
285
|
+
expressions.push(iterator);
|
|
286
|
+
const dynamicCallExpression = t.callExpression(t.memberExpression(t.identifier(dynamicBlockIteratorName), t.identifier("dynamic")), [
|
|
287
|
+
await (0, exports.valueToTs)({
|
|
288
|
+
...scope,
|
|
289
|
+
scopedVariables: {
|
|
290
|
+
[block.scopedVar]: dynamicBlockIteratorName,
|
|
291
|
+
},
|
|
292
|
+
}, (0, partialCode_1.fillWithConfigAccessors)(scope, Array.isArray(block.content) ? block.content[0] : block.content, block.path.replace(block.scopedVar, "")), block.path.replace(block.scopedVar, ""), false),
|
|
293
|
+
]);
|
|
294
|
+
const parts = block.path
|
|
295
|
+
.replace(`dynamic.${block.scopedVar}`, "")
|
|
296
|
+
.split(".")
|
|
297
|
+
.filter((p) => p.length > 0);
|
|
298
|
+
const parent = parts.reduce((acc, part) => {
|
|
299
|
+
if (Array.isArray(acc) && !Number.isNaN(parseInt(part, 10))) {
|
|
300
|
+
return acc[parseInt(part, 10)];
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
return acc[part];
|
|
304
|
+
}
|
|
305
|
+
}, mappedConfig);
|
|
306
|
+
parent[block.scopedVar] = dynamicCallExpression;
|
|
307
|
+
delete parent.dynamic;
|
|
308
|
+
}
|
|
309
|
+
const overrideReference = dynamicBlocksUsingOverrides.length
|
|
310
|
+
? {
|
|
311
|
+
start: 0,
|
|
312
|
+
end: 0,
|
|
313
|
+
referencee: {
|
|
314
|
+
id: `${type}.${key}`,
|
|
315
|
+
full: `${type}.${key}`,
|
|
316
|
+
},
|
|
317
|
+
}
|
|
318
|
+
: undefined;
|
|
319
|
+
if (provisioner) {
|
|
320
|
+
mappedConfig.provisioners = await Promise.all(Object.entries(provisioner).flatMap(([type, p]) => p.map((pp) => (0, exports.valueToTs)(scope, { type, ...pp }, "path-for-provisioners-can-be-ignored"))));
|
|
321
|
+
}
|
|
322
|
+
const importGraphId = `import.${resource.replace(".", "_")}.${key}`;
|
|
323
|
+
const importDefinition = graph.hasNode(importGraphId)
|
|
324
|
+
? graph.getNodeAttribute(importGraphId, "value")
|
|
325
|
+
: undefined;
|
|
326
|
+
expressions = expressions.concat(await asExpression({ ...scope, forEachIteratorName, countIteratorName }, resource, key, mappedConfig, false, false, getReference(graph, id) || overrideReference, importDefinition));
|
|
327
|
+
// Check for dynamic blocks
|
|
328
|
+
expressions = expressions.concat(await Promise.all(dynamicBlocksUsingOverrides.map(async ({ path, for_each, content }) => {
|
|
329
|
+
// We need to let the expression conversion know all available
|
|
330
|
+
// dynamic block names, so we don't replace them. The "dynamic-block"
|
|
331
|
+
// scoped variable indicates to the expression conversion to use the
|
|
332
|
+
// key name instead of an iterator
|
|
333
|
+
const scopedVariablesInPath = Object.fromEntries(path
|
|
334
|
+
.substring(1) // The path starts with a dot that results in an empty split
|
|
335
|
+
.split(".")
|
|
336
|
+
.filter((p) => !["dynamic", "content"].includes(p) && isNaN(parseInt(p)))
|
|
337
|
+
.map((p) => [p, "dynamic-block"]));
|
|
338
|
+
return addOverrideExpression(varName, path.substring(1), // The path starts with a dot that we don't want
|
|
339
|
+
await (0, exports.valueToTs)({
|
|
340
|
+
...scope,
|
|
341
|
+
withinOverrideExpression: true,
|
|
342
|
+
scopedVariables: scopedVariablesInPath,
|
|
343
|
+
}, {
|
|
344
|
+
for_each,
|
|
345
|
+
content,
|
|
346
|
+
}, "path-for-dynamic-blocks-can-be-ignored"), loopComment);
|
|
347
|
+
})));
|
|
348
|
+
return expressions;
|
|
349
|
+
}
|
|
350
|
+
exports.resource = resource;
|
|
351
|
+
async function asExpression(scope, type, name, config, isModuleImport, isProvider, reference, imported) {
|
|
352
|
+
const { providers, ...otherOptions } = config;
|
|
353
|
+
const constructId = (0, utils_1.uniqueId)(scope.constructs, name);
|
|
354
|
+
const overrideId = !isProvider && constructId !== name;
|
|
355
|
+
const completeObject = (0, partialCode_1.fillWithConfigAccessors)(scope, otherOptions, type);
|
|
356
|
+
const expression = t.newExpression((0, variables_1.constructAst)(scope, type, isModuleImport), [
|
|
357
|
+
t.thisExpression(),
|
|
358
|
+
t.stringLiteral(constructId),
|
|
359
|
+
await (0, exports.valueToTs)(scope, {
|
|
360
|
+
...completeObject,
|
|
361
|
+
providers: providers && Object.keys(providers).length
|
|
362
|
+
? Object.entries(providers).map(([key, value]) => ({
|
|
363
|
+
moduleAlias: key,
|
|
364
|
+
provider: value,
|
|
365
|
+
}))
|
|
366
|
+
: undefined,
|
|
367
|
+
}, `${type}`, isModuleImport),
|
|
368
|
+
]);
|
|
369
|
+
const statements = [];
|
|
370
|
+
const varName = reference
|
|
371
|
+
? (0, variables_1.referenceToVariableName)(scope, reference)
|
|
372
|
+
: (0, variables_1.variableName)(scope, type, name);
|
|
373
|
+
if (reference || overrideId || imported) {
|
|
374
|
+
statements.push(t.variableDeclaration("const", [
|
|
375
|
+
t.variableDeclarator(t.identifier(varName), expression),
|
|
376
|
+
]));
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
statements.push(t.expressionStatement(expression));
|
|
380
|
+
}
|
|
381
|
+
if (overrideId) {
|
|
382
|
+
statements.push(addOverrideLogicalIdExpression(varName, name));
|
|
383
|
+
}
|
|
384
|
+
if (imported) {
|
|
385
|
+
// Adds myVar.importFrom("my-arn")
|
|
386
|
+
const importExpression = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(varName), t.identifier("importFrom")), [t.stringLiteral(imported.id)]));
|
|
387
|
+
if (imported.provider) {
|
|
388
|
+
t.addComment(importExpression, "leading", `This import was configured with a provider. CDKTN does support this, but the cdktn convert command does not yet. Please add the provider reference manually. See https://cdktn.io/docs/concepts/resources#importing-resources for more information.`);
|
|
389
|
+
}
|
|
390
|
+
statements.push(importExpression);
|
|
391
|
+
}
|
|
392
|
+
return statements;
|
|
393
|
+
}
|
|
394
|
+
async function output(scope, key, _id, item, _graph) {
|
|
395
|
+
const [{ value, description, sensitive }] = item;
|
|
396
|
+
return asExpression(scope, "cdktn.TerraformOutput", key, {
|
|
397
|
+
value,
|
|
398
|
+
description,
|
|
399
|
+
sensitive,
|
|
400
|
+
}, false, false, undefined, undefined);
|
|
401
|
+
}
|
|
402
|
+
exports.output = output;
|
|
403
|
+
async function variableTypeToAst(scope, type) {
|
|
404
|
+
const addVariableTypeToImports = () => scope.importables.push({
|
|
405
|
+
constructName: "VariableType",
|
|
406
|
+
provider: "cdktn",
|
|
407
|
+
});
|
|
408
|
+
function parsedTypeToAst(type) {
|
|
409
|
+
if (hcl2json_1.TFExpressionSyntaxTree.isScopeTraversalExpression(type)) {
|
|
410
|
+
addVariableTypeToImports();
|
|
411
|
+
switch (type.meta.value) {
|
|
412
|
+
case "string":
|
|
413
|
+
return t.identifier("VariableType.STRING");
|
|
414
|
+
case "number":
|
|
415
|
+
return t.identifier("VariableType.NUMBER");
|
|
416
|
+
case "bool":
|
|
417
|
+
return t.identifier("VariableType.BOOL");
|
|
418
|
+
case "any":
|
|
419
|
+
default:
|
|
420
|
+
return t.identifier("VariableType.ANY");
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (hcl2json_1.TFExpressionSyntaxTree.isFunctionCallExpression(type)) {
|
|
424
|
+
addVariableTypeToImports();
|
|
425
|
+
switch (type.meta.name) {
|
|
426
|
+
case "list":
|
|
427
|
+
case "set":
|
|
428
|
+
case "map":
|
|
429
|
+
case "tuple":
|
|
430
|
+
case "object":
|
|
431
|
+
return t.callExpression(t.identifier(`VariableType.${type.meta.name}`), type.children.map((child) => parsedTypeToAst(child)));
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (hcl2json_1.TFExpressionSyntaxTree.isObjectExpression(type)) {
|
|
435
|
+
return t.objectExpression(Object.entries(type.meta.items).map(([key, value]) => t.objectProperty(t.stringLiteral(key),
|
|
436
|
+
// This does not deal with complex types nested within objects
|
|
437
|
+
// If such a type is found it will result in an Any type
|
|
438
|
+
// e.g. { foo: list(string) } will result in { foo: any }
|
|
439
|
+
parsedTypeToAst({
|
|
440
|
+
type: "scopeTraversal",
|
|
441
|
+
meta: { value },
|
|
442
|
+
}))));
|
|
443
|
+
}
|
|
444
|
+
addVariableTypeToImports();
|
|
445
|
+
return t.identifier("VariableType.ANY");
|
|
446
|
+
}
|
|
447
|
+
return parsedTypeToAst(await (0, expressions_1.expressionAst)(type));
|
|
448
|
+
}
|
|
449
|
+
exports.variableTypeToAst = variableTypeToAst;
|
|
450
|
+
async function variable(scope, key, id, item, graph) {
|
|
451
|
+
const [{ type, ...props }] = item;
|
|
452
|
+
if (!getReference(graph, id)) {
|
|
453
|
+
return [];
|
|
454
|
+
}
|
|
455
|
+
return asExpression(scope, id, key, { ...props, type: type ? await variableTypeToAst(scope, type) : undefined }, false, false, getReference(graph, id), undefined);
|
|
456
|
+
}
|
|
457
|
+
exports.variable = variable;
|
|
458
|
+
async function local(scope, key, id, item, graph) {
|
|
459
|
+
utils_1.logger.debug(`Initializing local resource ${key} with id ${id}`);
|
|
460
|
+
if (!getReference(graph, id)) {
|
|
461
|
+
utils_1.logger.debug(`No reference found for ${key}`);
|
|
462
|
+
return [];
|
|
463
|
+
}
|
|
464
|
+
return [
|
|
465
|
+
t.variableDeclaration("const", [
|
|
466
|
+
t.variableDeclarator(t.identifier((0, variables_1.variableName)(scope, "local", key)), await (0, exports.valueToTs)(scope, item, "path-for-local-blocks-can-be-ignored")),
|
|
467
|
+
]),
|
|
468
|
+
];
|
|
469
|
+
}
|
|
470
|
+
exports.local = local;
|
|
471
|
+
async function modules(scope, key, id, item, graph) {
|
|
472
|
+
const [{ source, version, ...props }] = item;
|
|
473
|
+
const moduleConstraint = new provider_generator_1.TerraformModuleConstraint(source);
|
|
474
|
+
return asExpression(scope, moduleConstraint.className, key, props, true, false, getReference(graph, id), undefined);
|
|
475
|
+
}
|
|
476
|
+
exports.modules = modules;
|
|
477
|
+
async function imports(scope, _id, item, graph) {
|
|
478
|
+
// Move from ${aws_instance.example} to aws_instance.example
|
|
479
|
+
const target = item.to.startsWith("${") && item.to.endsWith("}")
|
|
480
|
+
? item.to.substring(2, item.to.length - 1)
|
|
481
|
+
: item.to;
|
|
482
|
+
// Check if the import goes into a module
|
|
483
|
+
if (target.startsWith("module.")) {
|
|
484
|
+
return [
|
|
485
|
+
t.addComment(t.emptyStatement(), "leading", `CDKTN does not support imports into modules yet, please remove the import block importing ${item.id} into ${target} from your configuration`),
|
|
486
|
+
];
|
|
487
|
+
}
|
|
488
|
+
// We now know that the import goes into a resource, e.g. aws_instance.example
|
|
489
|
+
const [resourceTypeIdentifier, resourceName] = target.split(".");
|
|
490
|
+
if (resourceName.includes("[")) {
|
|
491
|
+
return [
|
|
492
|
+
t.addComment(t.emptyStatement(), "leading", `CDKTN does not support imports into resources with count or for_each yet, please remove the import block importing ${item.id} into ${target} from your configuration`),
|
|
493
|
+
];
|
|
494
|
+
}
|
|
495
|
+
// Check if we have a existing resource config with the given name
|
|
496
|
+
if (graph.hasNode(target)) {
|
|
497
|
+
// We will handle this case in the resource function
|
|
498
|
+
// so we can skip over it
|
|
499
|
+
return [];
|
|
500
|
+
}
|
|
501
|
+
const [provider, ...resourceTypeNameParts] = resourceTypeIdentifier.split("_");
|
|
502
|
+
const constructId = (0, utils_1.uniqueId)(scope.constructs, (0, utils_1.camelCase)(resourceName));
|
|
503
|
+
const constructClass = (0, variables_1.constructAst)(scope, `${provider}.${resourceTypeNameParts.join("_")}`, false);
|
|
504
|
+
return [
|
|
505
|
+
t.expressionStatement(t.callExpression(t.memberExpression(constructClass, t.identifier("generateConfigForImport")), [
|
|
506
|
+
t.thisExpression(),
|
|
507
|
+
t.stringLiteral(constructId),
|
|
508
|
+
t.stringLiteral(item.id),
|
|
509
|
+
])),
|
|
510
|
+
];
|
|
511
|
+
}
|
|
512
|
+
exports.imports = imports;
|
|
513
|
+
async function provider(scope, key, id, item, graph) {
|
|
514
|
+
const { version, ...props } = item;
|
|
515
|
+
const importKey = key === "null" ? "NullProvider" : key;
|
|
516
|
+
return asExpression(scope, `${importKey}.${(0, utils_1.pascalCase)(key)}Provider`, key, props, false, true, getReference(graph, id), undefined);
|
|
517
|
+
}
|
|
518
|
+
exports.provider = provider;
|
|
519
|
+
exports.cdktfImport = (0, template_1.default)(`import * as cdktn from "cdktn"`)();
|
|
520
|
+
exports.constructsImport = (0, template_1.default)(`import * as constructs from "constructs"`)();
|
|
521
|
+
const providerImports = (providers) => providers.map((providerName) => {
|
|
522
|
+
const parts = providerName.split("/");
|
|
523
|
+
const name = parts.length > 1 ? parts[1] : parts[0];
|
|
524
|
+
const importName = name === "null" ? "NullProvider" : name;
|
|
525
|
+
return (0, template_1.default)(`import * as ${importName} from "./.gen/providers/${name.replace("./", "")}"`)();
|
|
526
|
+
});
|
|
527
|
+
exports.providerImports = providerImports;
|
|
528
|
+
const moduleImports = (modules) => {
|
|
529
|
+
const uniqueModules = new Set();
|
|
530
|
+
Object.values(modules || {}).map(([module]) => uniqueModules.add(module.source));
|
|
531
|
+
const imports = [];
|
|
532
|
+
uniqueModules.forEach((m) => {
|
|
533
|
+
const moduleConstraint = new provider_generator_1.TerraformModuleConstraint(m);
|
|
534
|
+
imports.push(template_1.default.ast(`import * as ${moduleConstraint.className} from "./.gen/modules/${moduleConstraint.fileName}"`));
|
|
535
|
+
});
|
|
536
|
+
return imports;
|
|
537
|
+
};
|
|
538
|
+
exports.moduleImports = moduleImports;
|
|
539
|
+
async function gen(statements) {
|
|
540
|
+
utils_1.logger.debug(`Generating code for ${JSON.stringify(statements, null, 2)}`);
|
|
541
|
+
const code = prettier_1.default.format((0, generator_1.default)(t.program(statements)).code, {
|
|
542
|
+
parser: "babel",
|
|
543
|
+
});
|
|
544
|
+
utils_1.logger.debug(`Generated code:\n${code}`);
|
|
545
|
+
return code;
|
|
546
|
+
}
|
|
547
|
+
exports.gen = gen;
|
|
548
|
+
function addImportForCodeContainer(scope, codeContainer) {
|
|
549
|
+
switch (codeContainer) {
|
|
550
|
+
case "constructs.Construct":
|
|
551
|
+
scope.importables.push({
|
|
552
|
+
provider: "constructs",
|
|
553
|
+
constructName: "Construct",
|
|
554
|
+
});
|
|
555
|
+
break;
|
|
556
|
+
case "cdktn.TerraformStack":
|
|
557
|
+
scope.importables.push({
|
|
558
|
+
provider: "cdktn",
|
|
559
|
+
constructName: "TerraformStack",
|
|
560
|
+
});
|
|
561
|
+
break;
|
|
562
|
+
case "cdktf.TerraformStack":
|
|
563
|
+
scope.importables.push({
|
|
564
|
+
provider: "cdktf",
|
|
565
|
+
constructName: "TerraformStack",
|
|
566
|
+
});
|
|
567
|
+
break;
|
|
568
|
+
default:
|
|
569
|
+
throw commons_1.Errors.Internal("Unsupported code container: " + codeContainer);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
exports.addImportForCodeContainer = addImportForCodeContainer;
|
|
573
|
+
function wrapCodeInConstructor(codeContainer, code, className, configTypeName) {
|
|
574
|
+
let baseContainerClass;
|
|
575
|
+
switch (codeContainer) {
|
|
576
|
+
case "constructs.Construct":
|
|
577
|
+
baseContainerClass = t.identifier("Construct");
|
|
578
|
+
break;
|
|
579
|
+
case "cdktn.TerraformStack":
|
|
580
|
+
baseContainerClass = t.identifier("TerraformStack");
|
|
581
|
+
break;
|
|
582
|
+
default:
|
|
583
|
+
throw commons_1.Errors.Internal("Unsupported code container: " + codeContainer);
|
|
584
|
+
}
|
|
585
|
+
if (configTypeName) {
|
|
586
|
+
return template_1.default.statement(`
|
|
587
|
+
class %%className%% extends %%base%% {
|
|
588
|
+
constructor(scope: Construct, name: string, config: ${configTypeName}) {
|
|
589
|
+
super(scope, name);
|
|
590
|
+
%%code%%
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
`, { syntacticPlaceholders: true, plugins: ["typescript"] })({
|
|
594
|
+
code,
|
|
595
|
+
base: baseContainerClass,
|
|
596
|
+
className: t.identifier(className),
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
return template_1.default.statement(`
|
|
600
|
+
class %%className%% extends %%base%% {
|
|
601
|
+
constructor(scope: Construct, name: string) {
|
|
602
|
+
super(scope, name);
|
|
603
|
+
%%code%%
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
`, { syntacticPlaceholders: true, plugins: ["typescript"] })({
|
|
607
|
+
code,
|
|
608
|
+
base: baseContainerClass,
|
|
609
|
+
className: t.identifier(className),
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
exports.wrapCodeInConstructor = wrapCodeInConstructor;
|
|
613
|
+
const providerConstructImports = (importable) => {
|
|
614
|
+
let provider = importable[0].provider;
|
|
615
|
+
let namespace = importable[0].namespace;
|
|
616
|
+
const names = importable.map((i) => i.constructName);
|
|
617
|
+
if (provider === "cdktn" || provider === "constructs") {
|
|
618
|
+
return (0, template_1.default)(`import { ${names.join(", ")} } from "${provider}"`)();
|
|
619
|
+
}
|
|
620
|
+
if (namespace) {
|
|
621
|
+
namespace = (0, util_1.snakeCase)(namespace).replace(/_/g, "-");
|
|
622
|
+
}
|
|
623
|
+
// Special cases to undo provider names that we override
|
|
624
|
+
if (provider === "NullProvider") {
|
|
625
|
+
provider = "null";
|
|
626
|
+
}
|
|
627
|
+
return (0, template_1.default)(`import { ${names.join(", ")} } from "./.gen/providers/${provider}/${namespace}"`)();
|
|
628
|
+
};
|
|
629
|
+
exports.providerConstructImports = providerConstructImports;
|
|
630
|
+
function buildImports(importables) {
|
|
631
|
+
const groupedImportables = importables.reduce((acc, importable) => {
|
|
632
|
+
const ns = importable.namespace || "";
|
|
633
|
+
// Doing some hacky ordering of the imports to make them look a bit nicer
|
|
634
|
+
const prefix = importable.provider === "constructs"
|
|
635
|
+
? "1"
|
|
636
|
+
: importable.provider === "cdktn"
|
|
637
|
+
? "2"
|
|
638
|
+
: importable.provider === "cdktf"
|
|
639
|
+
? "3"
|
|
640
|
+
: "4";
|
|
641
|
+
const groupName = `${prefix}.${importable.provider}.${ns}`;
|
|
642
|
+
const fullName = `${importable.provider}.${ns}.${importable.constructName}`;
|
|
643
|
+
if (acc[groupName]) {
|
|
644
|
+
const existsAlready = acc[groupName].some((importable) => `${importable.provider}.${ns}.${importable.constructName}` ===
|
|
645
|
+
fullName);
|
|
646
|
+
if (existsAlready) {
|
|
647
|
+
return acc;
|
|
648
|
+
}
|
|
649
|
+
acc[groupName].push(importable);
|
|
650
|
+
acc[groupName].sort();
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
acc[groupName] = [importable];
|
|
654
|
+
}
|
|
655
|
+
return acc;
|
|
656
|
+
}, {});
|
|
657
|
+
let commentAdded = false;
|
|
658
|
+
const constructImports = Object.keys(groupedImportables)
|
|
659
|
+
.sort()
|
|
660
|
+
.map((groupName) => {
|
|
661
|
+
const importStatement = (0, exports.providerConstructImports)(groupedImportables[groupName]);
|
|
662
|
+
if (groupName.startsWith("4.") && !commentAdded) {
|
|
663
|
+
commentAdded = true;
|
|
664
|
+
t.addComment(importStatement, "leading", `\n* Provider bindings are generated by running \`cdktn get\`.
|
|
665
|
+
* See https://cdk.tf/provider-generation for more details.\n`);
|
|
666
|
+
}
|
|
667
|
+
return importStatement;
|
|
668
|
+
});
|
|
669
|
+
return constructImports;
|
|
670
|
+
}
|
|
671
|
+
exports.buildImports = buildImports;
|
|
672
|
+
function generateConfigType(name, config) {
|
|
673
|
+
return t.tsInterfaceDeclaration(t.identifier(name), undefined, undefined, t.tsInterfaceBody(Object.entries(config).map(([key, _value]) => t.tsPropertySignature(t.identifier(key), t.tSTypeAnnotation(t.tsAnyKeyword())))));
|
|
674
|
+
}
|
|
675
|
+
exports.generateConfigType = generateConfigType;
|
|
676
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9nZW5lcmF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsK0JBQStCO0FBQy9CLG1DQUFtQztBQUNuQyxpRUFBd0M7QUFDeEMsK0RBQXVDO0FBQ3ZDLGdEQUFrQztBQUVsQyx3REFBZ0M7QUFTaEMsbUNBQWtFO0FBVWxFLCtDQUE4RTtBQUU5RSw2Q0FBa0Q7QUFDbEQsa0VBR21DO0FBQ25DLHVEQUkyQjtBQUMzQiw0Q0FBMEU7QUFDMUUsOENBQWdFO0FBQ2hFLHFEQUE4RTtBQUM5RSwyQ0FJcUI7QUFDckIseUNBQTJDO0FBQzNDLCtDQUF3RDtBQUV4RCxTQUFTLFlBQVksQ0FBQyxLQUFvQixFQUFFLEVBQVU7SUFDcEQsY0FBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUM1QyxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRXpDLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN6QixjQUFNLENBQUMsS0FBSyxDQUFDLG1CQUFtQixTQUFTLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN2RCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLEVBQUUsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVsRCxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsY0FBTSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsSUFBSSxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbkQsY0FBTSxDQUFDLEtBQUssQ0FDVix1QkFBdUIsS0FBSyxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxDQUM3RCxDQUFDO1lBQ0YsT0FBTyxLQUFLLENBQUMsZ0JBQWdC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RCxTQUFnQixrQkFBa0IsQ0FDaEMsSUFBWSxFQUNaLE1BQXFDO0lBRXJDLE9BQU8sQ0FBQyxDQUFDLHNCQUFzQixDQUM3QixDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUNsQixTQUFTLEVBQ1QsU0FBUyxFQUNULENBQUMsQ0FBQyxlQUFlLENBQ2YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsRUFBRSxFQUFFLENBQzNDLENBQUMsQ0FBQyxtQkFBbUIsQ0FDbkIsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFDakIsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUNyQyxDQUNGLENBQ0YsQ0FDRixDQUFDO0FBQ0osQ0FBQztBQWpCRCxnREFpQkMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIEhhc2hpQ29ycCwgSW5jXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTVBMLTIuMFxuaW1wb3J0IGdlbmVyYXRlIGZyb20gXCJAYmFiZWwvZ2VuZXJhdG9yXCI7XG5pbXBvcnQgdGVtcGxhdGUgZnJvbSBcIkBiYWJlbC90ZW1wbGF0ZVwiO1xuaW1wb3J0ICogYXMgdCBmcm9tIFwiQGJhYmVsL3R5cGVzXCI7XG5pbXBvcnQgeyBEaXJlY3RlZEdyYXBoIH0gZnJvbSBcImdyYXBob2xvZ3lcIjtcbmltcG9ydCBwcmV0dGllciBmcm9tIFwicHJldHRpZXJcIjtcblxuaW1wb3J0IHtcbiAgVGVycmFmb3JtUmVzb3VyY2VCbG9jayxcbiAgUHJvZ3JhbVNjb3BlLFxuICBSZXNvdXJjZVNjb3BlLFxuICBJbXBvcnRhYmxlQ29uc3RydWN0LFxuICBBdHRyaWJ1dGVQYXRoLFxufSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgY2FtZWxDYXNlLCBsb2dnZXIsIHBhc2NhbENhc2UsIHVuaXF1ZUlkIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7XG4gIFJlc291cmNlLFxuICBUZXJyYWZvcm1Db25maWcsXG4gIE1vZHVsZSxcbiAgUHJvdmlkZXIsXG4gIFZhcmlhYmxlLFxuICBPdXRwdXQsXG4gIEltcG9ydCxcbn0gZnJvbSBcIi4vc2NoZW1hXCI7XG5pbXBvcnQgeyBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMsIGV4cHJlc3Npb25Bc3QgfSBmcm9tIFwiLi9leHByZXNzaW9uc1wiO1xuaW1wb3J0IHsgUmVmZXJlbmNlIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IGZpbmRVc2VkUmVmZXJlbmNlcyB9IGZyb20gXCIuL3JlZmVyZW5jZXNcIjtcbmltcG9ydCB7XG4gIFRlcnJhZm9ybU1vZHVsZUNvbnN0cmFpbnQsXG4gIGVzY2FwZUF0dHJpYnV0ZU5hbWUsXG59IGZyb20gXCJAY2RrdG4vcHJvdmlkZXItZ2VuZXJhdG9yXCI7XG5pbXBvcnQge1xuICBnZXRUeXBlQXRQYXRoLFxuICBpc01hcEF0dHJpYnV0ZSxcbiAgZ2V0RGVzaXJlZFR5cGUsXG59IGZyb20gXCIuL3RlcnJhZm9ybVNjaGVtYVwiO1xuaW1wb3J0IHsgRXJyb3JzLCBBdHRyaWJ1dGVUeXBlLCBCbG9ja1R5cGUsIFNjaGVtYSB9IGZyb20gXCJAY2RrdG4vY29tbW9uc1wiO1xuaW1wb3J0IHsgVEZFeHByZXNzaW9uU3ludGF4VHJlZSBhcyB0ZXggfSBmcm9tIFwiQGNka3RuL2hjbDJqc29uXCI7XG5pbXBvcnQgeyBleHRyYWN0RHluYW1pY0Jsb2NrcywgaXNOZXN0ZWREeW5hbWljQmxvY2sgfSBmcm9tIFwiLi9keW5hbWljLWJsb2Nrc1wiO1xuaW1wb3J0IHtcbiAgY29uc3RydWN0QXN0LFxuICByZWZlcmVuY2VUb1ZhcmlhYmxlTmFtZSxcbiAgdmFyaWFibGVOYW1lLFxufSBmcm9tIFwiLi92YXJpYWJsZXNcIjtcbmltcG9ydCB7IHNuYWtlQ2FzZSB9IGZyb20gXCJjZGt0bi9saWIvdXRpbFwiO1xuaW1wb3J0IHsgZmlsbFdpdGhDb25maWdBY2Nlc3NvcnMgfSBmcm9tIFwiLi9wYXJ0aWFsQ29kZVwiO1xuXG5mdW5jdGlvbiBnZXRSZWZlcmVuY2UoZ3JhcGg6IERpcmVjdGVkR3JhcGgsIGlkOiBzdHJpbmcpIHtcbiAgbG9nZ2VyLmRlYnVnKGBGaW5kaW5nIHJlZmVyZW5jZSBmb3IgJHtpZH1gKTtcbiAgY29uc3QgbmVpZ2hib3JzID0gZ3JhcGgub3V0TmVpZ2hib3JzKGlkKTtcblxuICBpZiAobmVpZ2hib3JzLmxlbmd0aCA+IDApIHtcbiAgICBsb2dnZXIuZGVidWcoYEZvdW5kIG5laWdoYm9ycyAke25laWdoYm9yc30gZm9yICR7aWR9YCk7XG4gICAgY29uc3QgZWRnZSA9IGdyYXBoLmRpcmVjdGVkRWRnZShpZCwgbmVpZ2hib3JzWzBdKTtcblxuICAgIGlmIChlZGdlKSB7XG4gICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGZpcnN0IGVkZ2UgJHtlZGdlfSBmb3IgJHtpZH1gKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYFJldHVybmluZyByZWZlcmVuY2UgJHtncmFwaC5nZXRFZGdlQXR0cmlidXRlKGVkZ2UsIFwicmVmXCIpfWAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIGdyYXBoLmdldEVkZ2VBdHRyaWJ1dGUoZWRnZSwgXCJyZWZcIikgYXMgUmVmZXJlbmNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIG5vIGVkZ2UgZm9yICR7aWR9YCk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhdHRyaWJ1dGVOYW1lVG9DZGt0Zk5hbWUobmFtZTogc3RyaW5nKSB7XG4gIHJldHVybiBlc2NhcGVBdHRyaWJ1dGVOYW1lKGNhbWVsQ2FzZShuYW1lKSk7XG59XG5cbmV4cG9ydCBjb25zdCB2YWx1ZVRvVHMgPSBhc3luYyAoXG4gIHNjb3BlOiBSZXNvdXJjZVNjb3BlLFxuICBpdGVtOiBUZXJyYWZvcm1SZXNvdXJjZUJsb2NrLFxuICBwYXRoOiBzdHJpbmcsXG4gIGlzTW9kdWxlID0gZmFsc2UsXG4pOiBQcm9taXNlPHQuRXhwcmVzc2lvbj4gPT4ge1xuICBzd2l0Y2ggKHR5cGVvZiBpdGVtKSB7XG4gICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgaWYgKFxuICAgICAgICAoYXdhaXQgZmluZFVzZWRSZWZlcmVuY2VzKHNjb3BlLm5vZGVJZHMsIGl0ZW0pKS5zb21lKChyZWYpID0+XG4gICAgICAgICAgcGF0aC5zdGFydHNXaXRoKHJlZi5yZWZlcmVuY2VlLmlkKSxcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB0LnN0cmluZ0xpdGVyYWwoaXRlbSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoc2NvcGUsIGBcIiR7aXRlbX1cImAsICgpID0+XG4gICAgICAgIGdldERlc2lyZWRUeXBlKHNjb3BlLCBwYXRoKSxcbiAgICAgICk7XG5cbiAgICBjYXNlIFwiYm9vbGVhblwiOlxuICAgICAgcmV0dXJuIGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhzY29wZSwgYCR7aXRlbX1gLCAoKSA9PlxuICAgICAgICBnZXREZXNpcmVkVHlwZShzY29wZSwgcGF0aCksXG4gICAgICApO1xuICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIHJldHVybiBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoc2NvcGUsIGAke2l0ZW19YCwgKCkgPT5cbiAgICAgICAgZ2V0RGVzaXJlZFR5cGUoc2NvcGUsIHBhdGgpLFxuICAgICAgKTtcbiAgICBjYXNlIFwib2JqZWN0XCI6IHtcbiAgICAgIGlmIChpdGVtID09PSB1bmRlZmluZWQgfHwgaXRlbSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdC5udWxsTGl0ZXJhbCgpO1xuICAgICAgfVxuXG4gICAgICAvLyBGb3IgaXRlcmF0b3JzIGFuZCBkeW5hbWljIGJsb2NrcyB3ZSBwdXQgdGhlIGNvcnJlY3QgVFMgZXhwcmVzc2lvbiBpbiB0aGUgY29uZmlnIGFoZWFkIG9mIHRpbWVcbiAgICAgIGlmICh0LmlzTm9kZShpdGVtKSAmJiB0LmlzRXhwcmVzc2lvbihpdGVtKSkge1xuICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYXR0cmlidXRlVHlwZSA9IGdldFR5cGVBdFBhdGgoc2NvcGUucHJvdmlkZXJTY2hlbWEsIHBhdGgpO1xuXG4gICAgICBmdW5jdGlvbiBzaG91bGRSZW1vdmVBcnJheUJhc2VkT25UeXBlKFxuICAgICAgICBhdHRyaWJ1dGVUeXBlOiBTY2hlbWEgfCBBdHRyaWJ1dGVUeXBlIHwgQmxvY2tUeXBlIHwgbnVsbCxcbiAgICAgICk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIWF0dHJpYnV0ZVR5cGUpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFRoZSBkZWZhdWx0IGFzc3VtcHRpb24gaXMgd2UgbmVlZCB0aGUgYXJyYXlcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIG1hcHMgYW5kIG9iamVjdCBkb24ndCBuZWVkIHRvIGJlIHdyYXBwZWQgaW4gYW4gYXJyYXlcbiAgICAgICAgaWYgKFxuICAgICAgICAgIEFycmF5LmlzQXJyYXkoYXR0cmlidXRlVHlwZSkgJiZcbiAgICAgICAgICAoYXR0cmlidXRlVHlwZVswXSA9PT0gXCJtYXBcIiB8fCBhdHRyaWJ1dGVUeXBlWzBdID09PSBcIm9iamVjdFwiKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIGl0J3MgYSBibG9jayB0eXBlIHdpdGggbWF4X2l0ZW1zID0gMSB3ZSBkb24ndCBuZWVkIHRvIHdyYXAgaXQgaW4gYW4gYXJyYXlcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHR5cGVvZiBhdHRyaWJ1dGVUeXBlID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgXCJtYXhfaXRlbXNcIiBpbiBhdHRyaWJ1dGVUeXBlICYmXG4gICAgICAgICAgYXR0cmlidXRlVHlwZS5tYXhfaXRlbXMgPT09IDFcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVud3JhcHBlZEl0ZW0gPVxuICAgICAgICBBcnJheS5pc0FycmF5KGl0ZW0pICYmXG4gICAgICAgIChzaG91bGRSZW1vdmVBcnJheUJhc2VkT25UeXBlKGF0dHJpYnV0ZVR5cGUpIHx8XG4gICAgICAgICAgcGF0aC5lbmRzV2l0aChcImxpZmVjeWNsZVwiKSB8fFxuICAgICAgICAgIHBhdGguZW5kc1dpdGgoXCJjb25uZWN0aW9uXCIpKVxuICAgICAgICAgID8gaXRlbVswXVxuICAgICAgICAgIDogaXRlbTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodW53cmFwcGVkSXRlbSkpIHtcbiAgICAgICAgcmV0dXJuIHQuYXJyYXlFeHByZXNzaW9uKFxuICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgdW53cmFwcGVkSXRlbS5tYXAoKGkpID0+IHZhbHVlVG9UcyhzY29wZSwgaSwgYCR7cGF0aH0uW11gKSksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHQub2JqZWN0RXhwcmVzc2lvbihcbiAgICAgICAgKFxuICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgT2JqZWN0LmVudHJpZXModW53cmFwcGVkSXRlbSkubWFwKGFzeW5jIChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKGtleSA9PT0gXCJkeW5hbWljXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IGZvcl9lYWNoLCAuLi5vdGhlcnMgfSA9IHZhbHVlIGFzIGFueTtcbiAgICAgICAgICAgICAgICBjb25zdCBkeW5hbWljUmVmID0gT2JqZWN0LmtleXMob3RoZXJzKVswXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdC5vYmplY3RQcm9wZXJ0eShcbiAgICAgICAgICAgICAgICAgIHQuaWRlbnRpZmllcihcbiAgICAgICAgICAgICAgICAgICAgc2NvcGUud2l0aGluT3ZlcnJpZGVFeHByZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgPyBkeW5hbWljUmVmXG4gICAgICAgICAgICAgICAgICAgICAgOiBlc2NhcGVBdHRyaWJ1dGVOYW1lKGNhbWVsQ2FzZShkeW5hbWljUmVmKSksXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgdC5hcnJheUV4cHJlc3Npb24oKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3QgaXRlbVBhdGggPSBgJHtwYXRofS4ke2tleX1gO1xuICAgICAgICAgICAgICBjb25zdCBpdGVtQXR0cmlidXRlVHlwZSA9IGdldFR5cGVBdFBhdGgoXG4gICAgICAgICAgICAgICAgc2NvcGUucHJvdmlkZXJTY2hlbWEsXG4gICAgICAgICAgICAgICAgaXRlbVBhdGgsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgY29uc3QgdHlwZU1ldGFkYXRhID0gZ2V0VHlwZUF0UGF0aChcbiAgICAgICAgICAgICAgICBzY29wZS5wcm92aWRlclNjaGVtYSxcbiAgICAgICAgICAgICAgICBpdGVtUGF0aCxcbiAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICBjb25zdCBpc1NpbmdsZUl0ZW1CbG9jayA9XG4gICAgICAgICAgICAgICAgdHlwZU1ldGFkYXRhICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIHR5cGVNZXRhZGF0YSA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0eXBlTWV0YWRhdGEsIFwibWF4X2l0ZW1zXCIpXG4gICAgICAgICAgICAgICAgICA/ICh0eXBlTWV0YWRhdGEgYXMgYW55KS5tYXhfaXRlbXMgPT09IDFcbiAgICAgICAgICAgICAgICAgIDogZmFsc2U7XG5cbiAgICAgICAgICAgICAgY29uc3Qgc2hvdWxkQmVBcnJheSA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICAgICAgIUFycmF5LmlzQXJyYXkodmFsdWUpICYmXG4gICAgICAgICAgICAgICAgISh0LmlzTm9kZSh2YWx1ZSkgJiYgdC5pc0V4cHJlc3Npb24odmFsdWUpKSAmJlxuICAgICAgICAgICAgICAgICFpc1NpbmdsZUl0ZW1CbG9jayAmJlxuICAgICAgICAgICAgICAgIC8vIE1hcCB0eXBlIGF0dHJpYnV0ZXMgbXVzdCBub3QgYmUgd3JhcHBlZCBpbiBhcnJheXNcbiAgICAgICAgICAgICAgICAhaXNNYXBBdHRyaWJ1dGUoaXRlbUF0dHJpYnV0ZVR5cGUpICYmXG4gICAgICAgICAgICAgICAga2V5ICE9PSBcInRhZ3NcIiAmJlxuICAgICAgICAgICAgICAgIGtleSAhPT0gXCJmb3JFYWNoXCIgJiZcbiAgICAgICAgICAgICAgICBrZXkgIT09IFwibGlmZWN5Y2xlXCI7XG5cbiAgICAgICAgICAgICAgY29uc3Qga2VlcEtleU5hbWU6IGJvb2xlYW4gPVxuICAgICAgICAgICAgICAgICFpc01vZHVsZSAmJlxuICAgICAgICAgICAgICAgIGtleSAhPT0gXCJkZXBlbmRzX29uXCIgJiZcbiAgICAgICAgICAgICAgICAhcGF0aC5pbmNsdWRlcyhcImxpZmVjeWNsZVwiKSAmJlxuICAgICAgICAgICAgICAgIChrZXkgPT09IFwiZm9yX2VhY2hcIiB8fFxuICAgICAgICAgICAgICAgICAgIXR5cGVNZXRhZGF0YSB8fFxuICAgICAgICAgICAgICAgICAgaXNNYXBBdHRyaWJ1dGUoYXR0cmlidXRlVHlwZSkpICYmXG4gICAgICAgICAgICAgICAgIShwYXRoLnN0YXJ0c1dpdGgoXCJ2YXIuXCIpICYmIHBhdGguaW5jbHVkZXMoXCJ2YWxpZGF0aW9uXCIpKTtcblxuICAgICAgICAgICAgICByZXR1cm4gdC5vYmplY3RQcm9wZXJ0eShcbiAgICAgICAgICAgICAgICB0LnN0cmluZ0xpdGVyYWwoXG4gICAgICAgICAgICAgICAgICBrZWVwS2V5TmFtZSA/IGtleSA6IGF0dHJpYnV0ZU5hbWVUb0Nka3RmTmFtZShrZXkpLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgc2hvdWxkQmVBcnJheVxuICAgICAgICAgICAgICAgICAgPyB0LmFycmF5RXhwcmVzc2lvbihbYXdhaXQgdmFsdWVUb1RzKHNjb3BlLCB2YWx1ZSwgaXRlbVBhdGgpXSlcbiAgICAgICAgICAgICAgICAgIDogYXdhaXQgdmFsdWVUb1RzKHNjb3BlLCB2YWx1ZSwgaXRlbVBhdGgpLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKVxuICAgICAgICApLmZpbHRlcigoZXhwcikgPT4gZXhwciAhPT0gdW5kZWZpbmVkKSBhcyB0Lk9iamVjdFByb3BlcnR5W10sXG4gICAgICApO1xuICAgIH1cbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCB0eXBlIFwiICsgaXRlbSk7XG59O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYmFja2VuZFRvRXhwcmVzc2lvbihcbiAgc2NvcGU6IFByb2dyYW1TY29wZSxcbiAgdGY6IFRlcnJhZm9ybUNvbmZpZ1tcImJhY2tlbmRcIl0sXG4pOiBQcm9taXNlPHQuU3RhdGVtZW50W10+IHtcbiAgcmV0dXJuIChcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIE9iamVjdC5lbnRyaWVzKHRmIHx8IHt9KS5tYXAoYXN5bmMgKFt0eXBlLCBbY29uZmlnXV0pID0+IHtcbiAgICAgICAgY29uc3QgYmFja2VuZElkZW50aWZpZXIgPSBwYXNjYWxDYXNlKGAke3R5cGV9QmFja2VuZGApO1xuICAgICAgICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICAgICAgICBjb25zdHJ1Y3ROYW1lOiBiYWNrZW5kSWRlbnRpZmllcixcbiAgICAgICAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHQuZXhwcmVzc2lvblN0YXRlbWVudChcbiAgICAgICAgICB0Lm5ld0V4cHJlc3Npb24odC5pZGVudGlmaWVyKGJhY2tlbmRJZGVudGlmaWVyKSwgW1xuICAgICAgICAgICAgdC50aGlzRXhwcmVzc2lvbigpLFxuICAgICAgICAgICAgdC5vYmplY3RFeHByZXNzaW9uKFxuICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICAgICAgICBPYmplY3QuZW50cmllcyhjb25maWcpLm1hcChhc3luYyAoW3Byb3BlcnR5LCB2YWx1ZV0pID0+XG4gICAgICAgICAgICAgICAgICAgIHQub2JqZWN0UHJvcGVydHkoXG4gICAgICAgICAgICAgICAgICAgICAgdC5pZGVudGlmaWVyKGNhbWVsQ2FzZShwcm9wZXJ0eSkpLFxuICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHZhbHVlVG9UcyhcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBcInBhdGgtZm9yLWJhY2tlbmRzLWNhbi1iZS1pZ25vcmVkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApLnJlZHVjZShcbiAgICAgICAgICAgICAgICAoY2FycnksIGl0ZW0pID0+IFsuLi5jYXJyeSwgaXRlbV0sXG4gICAgICAgICAgICAgICAgW10gYXMgdC5PYmplY3RQcm9wZXJ0eVtdLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICBdKSxcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICAgIClcbiAgKS5yZWR1Y2UoKGNhcnJ5LCBpdGVtKSA9PiBbLi4uY2FycnksIGl0ZW1dLCBbXSBhcyB0LlN0YXRlbWVudFtdKTtcbn1cblxuZnVuY3Rpb24gYWRkT3ZlcnJpZGVFeHByZXNzaW9uKFxuICB2YXJpYWJsZTogc3RyaW5nLFxuICBwYXRoOiBzdHJpbmcsXG4gIHZhbHVlOiB0LkV4cHJlc3Npb24sXG4gIGV4cGxhbmF0b3J5Q29tbWVudD86IHN0cmluZyxcbikge1xuICBjb25zdCBhc3QgPSB0LmV4cHJlc3Npb25TdGF0ZW1lbnQoXG4gICAgdC5jYWxsRXhwcmVzc2lvbihcbiAgICAgIHQubWVtYmVyRXhwcmVzc2lvbih0LmlkZW50aWZpZXIodmFyaWFibGUpLCB0LmlkZW50aWZpZXIoXCJhZGRPdmVycmlkZVwiKSksXG4gICAgICBbdC5zdHJpbmdMaXRlcmFsKHBhdGgpLCB2YWx1ZV0sXG4gICAgKSxcbiAgKTtcblxuICBpZiAoZXhwbGFuYXRvcnlDb21tZW50KSB7XG4gICAgdC5hZGRDb21tZW50KGFzdCwgXCJsZWFkaW5nXCIsIGV4cGxhbmF0b3J5Q29tbWVudCk7XG4gIH1cblxuICByZXR1cm4gYXN0O1xufVxuXG5mdW5jdGlvbiBhZGRPdmVycmlkZUxvZ2ljYWxJZEV4cHJlc3Npb24odmFyaWFibGU6IHN0cmluZywgbG9naWNhbElkOiBzdHJpbmcpIHtcbiAgY29uc3QgYXN0ID0gdC5leHByZXNzaW9uU3RhdGVtZW50KFxuICAgIHQuY2FsbEV4cHJlc3Npb24oXG4gICAgICB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICAgIHQuaWRlbnRpZmllcih2YXJpYWJsZSksXG4gICAgICAgIHQuaWRlbnRpZmllcihcIm92ZXJyaWRlTG9naWNhbElkXCIpLFxuICAgICAgKSxcbiAgICAgIFt0LnN0cmluZ0xpdGVyYWwobG9naWNhbElkKV0sXG4gICAgKSxcbiAgKTtcblxuICB0LmFkZENvbW1lbnQoXG4gICAgYXN0LFxuICAgIFwibGVhZGluZ1wiLFxuICAgIFwiVGhpcyBhbGxvd3MgdGhlIFRlcnJhZm9ybSByZXNvdXJjZSBuYW1lIHRvIG1hdGNoIHRoZSBvcmlnaW5hbCBuYW1lLiBZb3UgY2FuIHJlbW92ZSB0aGUgY2FsbCBpZiB5b3UgZG9uJ3QgbmVlZCB0aGVtIHRvIG1hdGNoLlwiLFxuICApO1xuXG4gIHJldHVybiBhc3Q7XG59XG5cbmZ1bmN0aW9uIGdldFJlbW90ZVN0YXRlVHlwZShpdGVtOiBSZXNvdXJjZSkge1xuICBjb25zdCBiYWNrZW5kUmVjb3JkID0gaXRlbS5maW5kKCh2YWwpID0+IHZhbC5iYWNrZW5kKTtcbiAgaWYgKGJhY2tlbmRSZWNvcmQpIHtcbiAgICBjb25zdCBiYWNrZW5kID0gYmFja2VuZFJlY29yZC5iYWNrZW5kO1xuICAgIHN3aXRjaCAoYmFja2VuZCkge1xuICAgICAgY2FzZSBcInJlbW90ZVwiOlxuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgIGNhc2UgXCJldGNkdjNcIjpcbiAgICAgICAgcmV0dXJuIFwiX2V0Y2RfdjNcIjtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBgXyR7YmFja2VuZH1gO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gXCJcIjtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNvdXJjZVR5cGUocHJvdmlkZXI6IHN0cmluZywgbmFtZTogc3RyaW5nW10sIGl0ZW06IFJlc291cmNlKSB7XG4gIHN3aXRjaCAocHJvdmlkZXIpIHtcbiAgICBjYXNlIFwiZGF0YS50ZXJyYWZvcm1cIjpcbiAgICAgIHJldHVybiBgY2RrdG4uZGF0YV90ZXJyYWZvcm1fJHtuYW1lLmpvaW4oXCJfXCIpfSR7Z2V0UmVtb3RlU3RhdGVUeXBlKFxuICAgICAgICBpdGVtLFxuICAgICAgKX1gO1xuICAgIGNhc2UgXCJudWxsXCI6XG4gICAgICByZXR1cm4gYE51bGxQcm92aWRlci4ke25hbWUuam9pbihcIl9cIil9YDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGAke3Byb3ZpZGVyfS4ke25hbWUuam9pbihcIl9cIil9YDtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXBDb25maWdQZXJSZXNvdXJjZVR5cGUocmVzb3VyY2U6IHN0cmluZywgaXRlbTogUmVzb3VyY2VbMF0pIHtcbiAgLy8gQmFja2VuZHMgaGF2ZSBhIHNsaWdodGx5IGRpZmZlcmVudCBBUElcbiAgaWYgKHJlc291cmNlLnN0YXJ0c1dpdGgoXCJjZGt0bi5kYXRhX3RlcnJhZm9ybV9cIikpIHtcbiAgICByZXR1cm4gaXRlbS5jb25maWc7XG4gIH1cbiAgcmV0dXJuIGl0ZW07XG59XG5cbmNvbnN0IGxvb3BDb21tZW50ID0gYEluIG1vc3QgY2FzZXMgbG9vcHMgc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIHByb2dyYW1taW5nIGxhbmd1YWdlIGNvbnRleHQgYW5kXG5ub3QgaW5zaWRlIG9mIHRoZSBUZXJyYWZvcm0gY29udGV4dC4gSWYgeW91IGFyZSBsb29waW5nIG92ZXIgc29tZXRoaW5nIGV4dGVybmFsLCBlLmcuIGEgdmFyaWFibGUgb3IgYSBmaWxlIGlucHV0XG55b3Ugc2hvdWxkIGNvbnNpZGVyIHVzaW5nIGEgZm9yIGxvb3AuIElmIHlvdSBhcmUgbG9vcGluZyBvdmVyIHNvbWV0aGluZyBvbmx5IGtub3duIHRvIFRlcnJhZm9ybSwgZS5nLiBhIHJlc3VsdCBvZiBhIGRhdGEgc291cmNlXG55b3UgbmVlZCB0byBrZWVwIHRoaXMgbGlrZSBpdCBpcy5gO1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc291cmNlKFxuICBzY29wZTogUHJvZ3JhbVNjb3BlLFxuICB0eXBlOiBzdHJpbmcsXG4gIGtleTogc3RyaW5nLFxuICBpZDogc3RyaW5nLFxuICBpdGVtOiBSZXNvdXJjZSxcbiAgZ3JhcGg6IERpcmVjdGVkR3JhcGgsXG4pOiBQcm9taXNlPHQuU3RhdGVtZW50W10+IHtcbiAgY29uc3QgW3Byb3ZpZGVyLCAuLi5uYW1lXSA9IHR5cGUuc3BsaXQoXCJfXCIpO1xuICBjb25zdCByZXNvdXJjZSA9IHJlc291cmNlVHlwZShwcm92aWRlciwgbmFtZSwgaXRlbSk7XG5cbiAgaWYgKCFwcm92aWRlcikge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IHBhcnNlIHJlc291cmNlIHR5cGUgJyR7dHlwZX0nYCk7XG4gIH1cbiAgbGV0IGV4cHJlc3Npb25zOiB0LlN0YXRlbWVudFtdID0gW107XG4gIGNvbnN0IHZhck5hbWUgPSB2YXJpYWJsZU5hbWUoc2NvcGUsIHJlc291cmNlLCBrZXkpO1xuICBjb25zdCB7IGZvcl9lYWNoLCBjb3VudCwgcHJvdmlzaW9uZXIsIC4uLmNvbmZpZyB9ID0gaXRlbVswXTtcbiAgY29uc3QgbWFwcGVkQ29uZmlnID0gbWFwQ29uZmlnUGVyUmVzb3VyY2VUeXBlKHJlc291cmNlLCBjb25maWcpO1xuXG4gIGxldCBmb3JFYWNoSXRlcmF0b3JOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGlmIChmb3JfZWFjaCkge1xuICAgIGZvckVhY2hJdGVyYXRvck5hbWUgPSB2YXJpYWJsZU5hbWUoXG4gICAgICBzY29wZSxcbiAgICAgIHJlc291cmNlLFxuICAgICAgYCR7a2V5fV9mb3JfZWFjaF9pdGVyYXRvcmAsXG4gICAgKTtcbiAgICBjb25zdCByZWZlcmVuY2VBc3QgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGBcIiR7Zm9yX2VhY2h9XCJgLFxuICAgICAgKCkgPT4gW1wibGlzdFwiLCBcImR5bmFtaWNcIl0sXG4gICAgKTtcblxuICAgIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgICAgIGNvbnN0cnVjdE5hbWU6IFwiVGVycmFmb3JtSXRlcmF0b3JcIixcbiAgICB9KTtcblxuICAgIGNvbnN0IGl0ZXJhdG9yID0gdC52YXJpYWJsZURlY2xhcmF0aW9uKFwiY29uc3RcIiwgW1xuICAgICAgdC52YXJpYWJsZURlY2xhcmF0b3IoXG4gICAgICAgIHQuaWRlbnRpZmllcihmb3JFYWNoSXRlcmF0b3JOYW1lKSxcbiAgICAgICAgdC5jYWxsRXhwcmVzc2lvbihcbiAgICAgICAgICB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICAgICAgICB0LmlkZW50aWZpZXIoXCJUZXJyYWZvcm1JdGVyYXRvclwiKSxcbiAgICAgICAgICAgIHQuaWRlbnRpZmllcihcImZyb21MaXN0XCIpLFxuICAgICAgICAgICksXG5cbiAgICAgICAgICBbcmVmZXJlbmNlQXN0XSxcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgXSk7XG4gICAgdC5hZGRDb21tZW50KGl0ZXJhdG9yLCBcImxlYWRpbmdcIiwgbG9vcENvbW1lbnQpO1xuICAgIGV4cHJlc3Npb25zLnB1c2goaXRlcmF0b3IpO1xuXG4gICAgbWFwcGVkQ29uZmlnLmZvckVhY2ggPSB0LmlkZW50aWZpZXIoZm9yRWFjaEl0ZXJhdG9yTmFtZSk7XG4gIH1cblxuICBsZXQgY291bnRJdGVyYXRvck5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgaWYgKGNvdW50KSB7XG4gICAgY291bnRJdGVyYXRvck5hbWUgPSB2YXJpYWJsZU5hbWUoc2NvcGUsIHJlc291cmNlLCBgJHtrZXl9X2NvdW50YCk7XG4gICAgY29uc3QgcmVmZXJlbmNlQXN0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBgXCIke2NvdW50fVwiYCxcbiAgICAgICgpID0+IFwibnVtYmVyXCIsXG4gICAgKTtcblxuICAgIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgICAgIGNvbnN0cnVjdE5hbWU6IFwiVGVycmFmb3JtQ291bnRcIixcbiAgICB9KTtcblxuICAgIGNvbnN0IGl0ZXJhdG9yID0gdC52YXJpYWJsZURlY2xhcmF0aW9uKFwiY29uc3RcIiwgW1xuICAgICAgdC52YXJpYWJsZURlY2xhcmF0b3IoXG4gICAgICAgIHQuaWRlbnRpZmllcihjb3VudEl0ZXJhdG9yTmFtZSksXG4gICAgICAgIHQuY2FsbEV4cHJlc3Npb24oXG4gICAgICAgICAgdC5tZW1iZXJFeHByZXNzaW9uKFxuICAgICAgICAgICAgdC5pZGVudGlmaWVyKFwiVGVycmFmb3JtQ291bnRcIiksXG4gICAgICAgICAgICB0LmlkZW50aWZpZXIoXCJvZlwiKSxcbiAgICAgICAgICApLFxuICAgICAgICAgIFtyZWZlcmVuY2VBc3RdLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICBdKTtcbiAgICB0LmFkZENvbW1lbnQoaXRlcmF0b3IsIFwibGVhZGluZ1wiLCBsb29wQ29tbWVudCk7XG4gICAgbWFwcGVkQ29uZmlnLmNvdW50ID0gdC5pZGVudGlmaWVyKGNvdW50SXRlcmF0b3JOYW1lKTtcbiAgICBleHByZXNzaW9ucy5wdXNoKGl0ZXJhdG9yKTtcbiAgfVxuXG4gIGNvbnN0IGR5bkJsb2NrcyA9IGV4dHJhY3REeW5hbWljQmxvY2tzKG1hcHBlZENvbmZpZyk7XG4gIGNvbnN0IG5lc3RlZER5bmFtaWNCbG9ja3MgPSBkeW5CbG9ja3MuZmlsdGVyKChibG9jaykgPT5cbiAgICBpc05lc3RlZER5bmFtaWNCbG9jayhkeW5CbG9ja3MsIGJsb2NrKSxcbiAgKTtcbiAgY29uc3QgZHluYW1pY0Jsb2Nrc1VzaW5nT3ZlcnJpZGVzID0gZHluQmxvY2tzLmZpbHRlcihcbiAgICAoYmxvY2spID0+XG4gICAgICAvLyBuZXN0ZWQgYmxvY2tzIG5lZWQgb3ZlcnJpZGVzXG4gICAgICBuZXN0ZWREeW5hbWljQmxvY2tzLmluY2x1ZGVzKGJsb2NrKSB8fFxuICAgICAgLy8gYmxvY2tzIHRoYXQgY29udGFpbiBuZXN0ZWQgYmxvY2tzIG5lZWQgdGhlbSBhcyB3ZWxsXG4gICAgICBuZXN0ZWREeW5hbWljQmxvY2tzLnNvbWUoKG5lc3RlZEJsb2NrKSA9PlxuICAgICAgICBuZXN0ZWRCbG9jay5wYXRoLnN0YXJ0c1dpdGgoYmxvY2sucGF0aCksXG4gICAgICApLFxuICApO1xuICAvLyBhbGwgb3RoZXJzIGNhbiBiZSBoYW5kbGVkIGJ5IHRoZSBDREtUTiBydW50aW1lXG4gIGNvbnN0IGR5bmFtaWNCbG9ja3NVc2luZ1J1bnRpbWUgPSBkeW5CbG9ja3MuZmlsdGVyKFxuICAgIChibG9jaykgPT4gIWR5bmFtaWNCbG9ja3NVc2luZ092ZXJyaWRlcy5pbmNsdWRlcyhibG9jayksXG4gICk7XG5cbiAgZm9yIChjb25zdCBbaSwgYmxvY2tdIG9mIGR5bmFtaWNCbG9ja3NVc2luZ1J1bnRpbWUuZW50cmllcygpKSB7XG4gICAgY29uc3QgZHluYW1pY0Jsb2NrSXRlcmF0b3JOYW1lID0gdmFyaWFibGVOYW1lKFxuICAgICAgc2NvcGUsXG4gICAgICByZXNvdXJjZSxcbiAgICAgIGAke2tleX1fZHluYW1pY19pdGVyYXRvcl8ke2l9YCxcbiAgICApO1xuXG4gICAgY29uc3QgcmVmZXJlbmNlQXN0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBgXCIke2Jsb2NrLmZvcl9lYWNofVwiYCxcbiAgICAgICgpID0+IFtcImxpc3RcIiwgXCJkeW5hbWljXCJdLFxuICAgICk7XG5cbiAgICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICAgIHByb3ZpZGVyOiBcImNka3RuXCIsXG4gICAgICBjb25zdHJ1Y3ROYW1lOiBcIlRlcnJhZm9ybUl0ZXJhdG9yXCIsXG4gICAgfSk7XG5cbiAgICBjb25zdCBpdGVyYXRvciA9IHQudmFyaWFibGVEZWNsYXJhdGlvbihcImNvbnN0XCIsIFtcbiAgICAgIHQudmFyaWFibGVEZWNsYXJhdG9yKFxuICAgICAgICB0LmlkZW50aWZpZXIoZHluYW1pY0Jsb2NrSXRlcmF0b3JOYW1lKSxcbiAgICAgICAgdC5jYWxsRXhwcmVzc2lvbihcbiAgICAgICAgICB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICAgICAgICB0LmlkZW50aWZpZXIoXCJUZXJyYWZvcm1JdGVyYXRvclwiKSxcbiAgICAgICAgICAgIHQuaWRlbnRpZmllcihcImZyb21MaXN0XCIpLFxuICAgICAgICAgICksXG4gICAgICAgICAgW3JlZmVyZW5jZUFzdF0sXG4gICAgICAgICksXG4gICAgICApLFxuICAgIF0pO1xuICAgIHQuYWRkQ29tbWVudChpdGVyYXRvciwgXCJsZWFkaW5nXCIsIGxvb3BDb21tZW50KTtcbiAgICBleHByZXNzaW9ucy5wdXNoKGl0ZXJhdG9yKTtcbiAgICBjb25zdCBkeW5hbWljQ2FsbEV4cHJlc3Npb24gPSB0LmNhbGxFeHByZXNzaW9uKFxuICAgICAgdC5tZW1iZXJFeHByZXNzaW9uKFxuICAgICAgICB0LmlkZW50aWZpZXIoZHluYW1pY0Jsb2NrSXRlcmF0b3JOYW1lKSxcbiAgICAgICAgdC5pZGVudGlmaWVyKFwiZHluYW1pY1wiKSxcbiAgICAgICksXG4gICAgICBbXG4gICAgICAgIGF3YWl0IHZhbHVlVG9UcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5zY29wZSxcbiAgICAgICAgICAgIHNjb3BlZFZhcmlhYmxlczoge1xuICAgICAgICAgICAgICBbYmxvY2suc2NvcGVkVmFyXTogZHluYW1pY0Jsb2NrSXRlcmF0b3JOYW1lLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGZpbGxXaXRoQ29uZmlnQWNjZXNzb3JzKFxuICAgICAgICAgICAgc2NvcGUsXG4gICAgICAgICAgICBBcnJheS5pc0FycmF5KGJsb2NrLmNvbnRlbnQpID8gYmxvY2suY29udGVudFswXSA6IGJsb2NrLmNvbnRlbnQsXG4gICAgICAgICAgICBibG9jay5wYXRoLnJlcGxhY2UoYmxvY2suc2NvcGVkVmFyLCBcIlwiKSxcbiAgICAgICAgICApLFxuICAgICAgICAgIGJsb2NrLnBhdGgucmVwbGFjZShibG9jay5zY29wZWRWYXIsIFwiXCIpLFxuICAgICAgICAgIGZhbHNlLFxuICAgICAgICApLFxuICAgICAgXSxcbiAgICApO1xuXG4gICAgY29uc3QgcGFydHMgPSBibG9jay5wYXRoXG4gICAgICAucmVwbGFjZShgZHluYW1pYy4ke2Jsb2NrLnNjb3BlZFZhcn1gLCBcIlwiKVxuICAgICAgLnNwbGl0KFwiLlwiKVxuICAgICAgLmZpbHRlcigocCkgPT4gcC5sZW5ndGggPiAwKTtcblxuICAgIGNvbnN0IHBhcmVudCA9IHBhcnRzLnJlZHVjZSgoYWNjLCBwYXJ0KSA9PiB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShhY2MpICYmICFOdW1iZXIuaXNOYU4ocGFyc2VJbnQocGFydCwgMTApKSkge1xuICAgICAgICByZXR1cm4gYWNjW3BhcnNlSW50KHBhcnQsIDEwKV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gYWNjW3BhcnRdO1xuICAgICAgfVxuICAgIH0sIG1hcHBlZENvbmZpZyk7XG4gICAgcGFyZW50W2Jsb2NrLnNjb3BlZFZhcl0gPSBkeW5hbWljQ2FsbEV4cHJlc3Npb247XG4gICAgZGVsZXRlIHBhcmVudC5keW5hbWljO1xuICB9XG5cbiAgY29uc3Qgb3ZlcnJpZGVSZWZlcmVuY2UgPSBkeW5hbWljQmxvY2tzVXNpbmdPdmVycmlkZXMubGVuZ3RoXG4gICAgPyB7XG4gICAgICAgIHN0YXJ0OiAwLFxuICAgICAgICBlbmQ6IDAsXG4gICAgICAgIHJlZmVyZW5jZWU6IHtcbiAgICAgICAgICBpZDogYCR7dHlwZX0uJHtrZXl9YCxcbiAgICAgICAgICBmdWxsOiBgJHt0eXBlfS4ke2tleX1gLFxuICAgICAgICB9LFxuICAgICAgfVxuICAgIDogdW5kZWZpbmVkO1xuXG4gIGlmIChwcm92aXNpb25lcikge1xuICAgIG1hcHBlZENvbmZpZy5wcm92aXNpb25lcnMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIE9iamVjdC5lbnRyaWVzKHByb3Zpc2lvbmVyKS5mbGF0TWFwKChbdHlwZSwgcF06IFtzdHJpbmcsIGFueV0pID0+XG4gICAgICAgIHAubWFwKChwcDogUmVjb3JkPHN0cmluZywgYW55PikgPT5cbiAgICAgICAgICB2YWx1ZVRvVHMoXG4gICAgICAgICAgICBzY29wZSxcbiAgICAgICAgICAgIHsgdHlwZSwgLi4ucHAgfSxcbiAgICAgICAgICAgIFwicGF0aC1mb3ItcHJvdmlzaW9uZXJzLWNhbi1iZS1pZ25vcmVkXCIsXG4gICAgICAgICAgKSxcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGltcG9ydEdyYXBoSWQgPSBgaW1wb3J0LiR7cmVzb3VyY2UucmVwbGFjZShcIi5cIiwgXCJfXCIpfS4ke2tleX1gO1xuICBjb25zdCBpbXBvcnREZWZpbml0aW9uOiBJbXBvcnQgfCB1bmRlZmluZWQgPSBncmFwaC5oYXNOb2RlKGltcG9ydEdyYXBoSWQpXG4gICAgPyBncmFwaC5nZXROb2RlQXR0cmlidXRlKGltcG9ydEdyYXBoSWQsIFwidmFsdWVcIilcbiAgICA6IHVuZGVmaW5lZDtcblxuICBleHByZXNzaW9ucyA9IGV4cHJlc3Npb25zLmNvbmNhdChcbiAgICBhd2FpdCBhc0V4cHJlc3Npb24oXG4gICAgICB7IC4uLnNjb3BlLCBmb3JFYWNoSXRlcmF0b3JOYW1lLCBjb3VudEl0ZXJhdG9yTmFtZSB9LFxuICAgICAgcmVzb3VyY2UsXG4gICAgICBrZXksXG4gICAgICBtYXBwZWRDb25maWcsXG4gICAgICBmYWxzZSxcbiAgICAgIGZhbHNlLFxuICAgICAgZ2V0UmVmZXJlbmNlKGdyYXBoLCBpZCkgfHwgb3ZlcnJpZGVSZWZlcmVuY2UsXG4gICAgICBpbXBvcnREZWZpbml0aW9uLFxuICAgICksXG4gICk7XG5cbiAgLy8gQ2hlY2sgZm9yIGR5bmFtaWMgYmxvY2tzXG4gIGV4cHJlc3Npb25zID0gZXhwcmVzc2lvbnMuY29uY2F0KFxuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgZHluYW1pY0Jsb2Nrc1VzaW5nT3ZlcnJpZGVzLm1hcChhc3luYyAoeyBwYXRoLCBmb3JfZWFjaCwgY29udGVudCB9KSA9PiB7XG4gICAgICAgIC8vIFdlIG5lZWQgdG8gbGV0IHRoZSBleHByZXNzaW9uIGNvbnZlcnNpb24ga25vdyBhbGwgYXZhaWxhYmxlXG4gICAgICAgIC8vIGR5bmFtaWMgYmxvY2sgbmFtZXMsIHNvIHdlIGRvbid0IHJlcGxhY2UgdGhlbS4gVGhlIFwiZHluYW1pYy1ibG9ja1wiXG4gICAgICAgIC8vIHNjb3BlZCB2YXJpYWJsZSBpbmRpY2F0ZXMgdG8gdGhlIGV4cHJlc3Npb24gY29udmVyc2lvbiB0byB1c2UgdGhlXG4gICAgICAgIC8vIGtleSBuYW1lIGluc3RlYWQgb2YgYW4gaXRlcmF0b3JcbiAgICAgICAgY29uc3Qgc2NvcGVkVmFyaWFibGVzSW5QYXRoID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIHBhdGhcbiAgICAgICAgICAgIC5zdWJzdHJpbmcoMSkgLy8gVGhlIHBhdGggc3RhcnRzIHdpdGggYSBkb3QgdGhhdCByZXN1bHRzIGluIGFuIGVtcHR5IHNwbGl0XG4gICAgICAgICAgICAuc3BsaXQoXCIuXCIpXG4gICAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgICAocCkgPT4gIVtcImR5bmFtaWNcIiwgXCJjb250ZW50XCJdLmluY2x1ZGVzKHApICYmIGlzTmFOKHBhcnNlSW50KHApKSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5tYXAoKHApID0+IFtwLCBcImR5bmFtaWMtYmxvY2tcIl0pLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiBhZGRPdmVycmlkZUV4cHJlc3Npb24oXG4gICAgICAgICAgdmFyTmFtZSxcbiAgICAgICAgICBwYXRoLnN1YnN0cmluZygxKSwgLy8gVGhlIHBhdGggc3RhcnRzIHdpdGggYSBkb3QgdGhhdCB3ZSBkb24ndCB3YW50XG4gICAgICAgICAgYXdhaXQgdmFsdWVUb1RzKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAuLi5zY29wZSxcbiAgICAgICAgICAgICAgd2l0aGluT3ZlcnJpZGVFeHByZXNzaW9uOiB0cnVlLFxuICAgICAgICAgICAgICBzY29wZWRWYXJpYWJsZXM6IHNjb3BlZFZhcmlhYmxlc0luUGF0aCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGZvcl9lYWNoLFxuICAgICAgICAgICAgICBjb250ZW50LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFwicGF0aC1mb3ItZHluYW1pYy1ibG9ja3MtY2FuLWJlLWlnbm9yZWRcIixcbiAgICAgICAgICApLFxuICAgICAgICAgIGxvb3BDb21tZW50LFxuICAgICAgICApO1xuICAgICAgfSksXG4gICAgKSxcbiAgKTtcblxuICByZXR1cm4gZXhwcmVzc2lvbnM7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFzRXhwcmVzc2lvbihcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIHR5cGU6IHN0cmluZyxcbiAgbmFtZTogc3RyaW5nLFxuICBjb25maWc6IFRlcnJhZm9ybVJlc291cmNlQmxvY2ssXG4gIGlzTW9kdWxlSW1wb3J0OiBib29sZWFuLFxuICBpc1Byb3ZpZGVyOiBib29sZWFuLFxuICByZWZlcmVuY2U/OiBSZWZlcmVuY2UsXG4gIGltcG9ydGVkPzogSW1wb3J0LFxuKSB7XG4gIGNvbnN0IHsgcHJvdmlkZXJzLCAuLi5vdGhlck9wdGlvbnMgfSA9IGNvbmZpZyBhcyBhbnk7XG5cbiAgY29uc3QgY29uc3RydWN0SWQgPSB1bmlxdWVJZChzY29wZS5jb25zdHJ1Y3RzLCBuYW1lKTtcbiAgY29uc3Qgb3ZlcnJpZGVJZCA9ICFpc1Byb3ZpZGVyICYmIGNvbnN0cnVjdElkICE9PSBuYW1lO1xuXG4gIGNvbnN0IGNvbXBsZXRlT2JqZWN0ID0gZmlsbFdpdGhDb25maWdBY2Nlc3NvcnMoc2NvcGUsIG90aGVyT3B0aW9ucywgdHlwZSk7XG5cbiAgY29uc3QgZXhwcmVzc2lvbiA9IHQubmV3RXhwcmVzc2lvbihcbiAgICBjb25zdHJ1Y3RBc3Qoc2NvcGUsIHR5cGUsIGlzTW9kdWxlSW1wb3J0KSxcbiAgICBbXG4gICAgICB0LnRoaXNFeHByZXNzaW9uKCksXG4gICAgICB0LnN0cmluZ0xpdGVyYWwoY29uc3RydWN0SWQpLFxuXG4gICAgICBhd2FpdCB2YWx1ZVRvVHMoXG4gICAgICAgIHNjb3BlLFxuICAgICAgICB7XG4gICAgICAgICAgLi4uY29tcGxldGVPYmplY3QsXG4gICAgICAgICAgcHJvdmlkZXJzOlxuICAgICAgICAgICAgcHJvdmlkZXJzICYmIE9iamVjdC5rZXlzKHByb3ZpZGVycykubGVuZ3RoXG4gICAgICAgICAgICAgID8gT2JqZWN0LmVudHJpZXMocHJvdmlkZXJzKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gKHtcbiAgICAgICAgICAgICAgICAgIG1vZHVsZUFsaWFzOiBrZXksXG4gICAgICAgICAgICAgICAgICBwcm92aWRlcjogdmFsdWUsXG4gICAgICAgICAgICAgICAgfSkpXG4gICAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICB9LFxuICAgICAgICBgJHt0eXBlfWAsXG4gICAgICAgIGlzTW9kdWxlSW1wb3J0LFxuICAgICAgKSxcbiAgICBdLFxuICApO1xuXG4gIGNvbnN0IHN0YXRlbWVudHMgPSBbXTtcbiAgY29uc3QgdmFyTmFtZSA9IHJlZmVyZW5jZVxuICAgID8gcmVmZXJlbmNlVG9WYXJpYWJsZU5hbWUoc2NvcGUsIHJlZmVyZW5jZSlcbiAgICA6IHZhcmlhYmxlTmFtZShzY29wZSwgdHlwZSwgbmFtZSk7XG5cbiAgaWYgKHJlZmVyZW5jZSB8fCBvdmVycmlkZUlkIHx8IGltcG9ydGVkKSB7XG4gICAgc3RhdGVtZW50cy5wdXNoKFxuICAgICAgdC52YXJpYWJsZURlY2xhcmF0aW9uKFwiY29uc3RcIiwgW1xuICAgICAgICB0LnZhcmlhYmxlRGVjbGFyYXRvcih0LmlkZW50aWZpZXIodmFyTmFtZSksIGV4cHJlc3Npb24pLFxuICAgICAgXSksXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICBzdGF0ZW1lbnRzLnB1c2godC5leHByZXNzaW9uU3RhdGVtZW50KGV4cHJlc3Npb24pKTtcbiAgfVxuXG4gIGlmIChvdmVycmlkZUlkKSB7XG4gICAgc3RhdGVtZW50cy5wdXNoKGFkZE92ZXJyaWRlTG9naWNhbElkRXhwcmVzc2lvbih2YXJOYW1lLCBuYW1lKSk7XG4gIH1cblxuICBpZiAoaW1wb3J0ZWQpIHtcbiAgICAvLyBBZGRzIG15VmFyLmltcG9ydEZyb20oXCJteS1hcm5cIilcbiAgICBjb25zdCBpbXBvcnRFeHByZXNzaW9uID0gdC5leHByZXNzaW9uU3RhdGVtZW50KFxuICAgICAgdC5jYWxsRXhwcmVzc2lvbihcbiAgICAgICAgdC5tZW1iZXJFeHByZXNzaW9uKHQuaWRlbnRpZmllcih2YXJOYW1lKSwgdC5pZGVudGlmaWVyKFwiaW1wb3J0RnJvbVwiKSksXG4gICAgICAgIFt0LnN0cmluZ0xpdGVyYWwoaW1wb3J0ZWQuaWQpXSxcbiAgICAgICksXG4gICAgKTtcblxuICAgIGlmIChpbXBvcnRlZC5wcm92aWRlcikge1xuICAgICAgdC5hZGRDb21tZW50KFxuICAgICAgICBpbXBvcnRFeHByZXNzaW9uLFxuICAgICAgICBcImxlYWRpbmdcIixcbiAgICAgICAgYFRoaXMgaW1wb3J0IHdhcyBjb25maWd1cmVkIHdpdGggYSBwcm92aWRlci4gQ0RLVE4gZG9lcyBzdXBwb3J0IHRoaXMsIGJ1dCB0aGUgY2RrdG4gY29udmVydCBjb21tYW5kIGRvZXMgbm90IHlldC4gUGxlYXNlIGFkZCB0aGUgcHJvdmlkZXIgcmVmZXJlbmNlIG1hbnVhbGx5LiBTZWUgaHR0cHM6Ly9jZGt0bi5pby9kb2NzL2NvbmNlcHRzL3Jlc291cmNlcyNpbXBvcnRpbmctcmVzb3VyY2VzIGZvciBtb3JlIGluZm9ybWF0aW9uLmAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHN0YXRlbWVudHMucHVzaChpbXBvcnRFeHByZXNzaW9uKTtcbiAgfVxuXG4gIHJldHVybiBzdGF0ZW1lbnRzO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb3V0cHV0KFxuICBzY29wZTogUHJvZ3JhbVNjb3BlLFxuICBrZXk6IHN0cmluZyxcbiAgX2lkOiBzdHJpbmcsXG4gIGl0ZW06IE91dHB1dCxcbiAgX2dyYXBoOiBEaXJlY3RlZEdyYXBoLFxuKSB7XG4gIGNvbnN0IFt7IHZhbHVlLCBkZXNjcmlwdGlvbiwgc2Vuc2l0aXZlIH1dID0gaXRlbTtcblxuICByZXR1cm4gYXNFeHByZXNzaW9uKFxuICAgIHNjb3BlLFxuICAgIFwiY2RrdG4uVGVycmFmb3JtT3V0cHV0XCIsXG4gICAga2V5LFxuICAgIHtcbiAgICAgIHZhbHVlLFxuICAgICAgZGVzY3JpcHRpb24sXG4gICAgICBzZW5zaXRpdmUsXG4gICAgfSxcbiAgICBmYWxzZSxcbiAgICBmYWxzZSxcbiAgICB1bmRlZmluZWQsXG4gICAgdW5kZWZpbmVkLFxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdmFyaWFibGVUeXBlVG9Bc3QoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIHR5cGU6IHN0cmluZyxcbik6IFByb21pc2U8dC5FeHByZXNzaW9uPiB7XG4gIGNvbnN0IGFkZFZhcmlhYmxlVHlwZVRvSW1wb3J0cyA9ICgpID0+XG4gICAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgICBjb25zdHJ1Y3ROYW1lOiBcIlZhcmlhYmxlVHlwZVwiLFxuICAgICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgICB9KTtcblxuICBmdW5jdGlvbiBwYXJzZWRUeXBlVG9Bc3QodHlwZTogdGV4LkV4cHJlc3Npb25UeXBlKTogdC5FeHByZXNzaW9uIHtcbiAgICBpZiAodGV4LmlzU2NvcGVUcmF2ZXJzYWxFeHByZXNzaW9uKHR5cGUpKSB7XG4gICAgICBhZGRWYXJpYWJsZVR5cGVUb0ltcG9ydHMoKTtcbiAgICAgIHN3aXRjaCAodHlwZS5tZXRhLnZhbHVlKSB7XG4gICAgICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgICAgICByZXR1cm4gdC5pZGVudGlmaWVyKFwiVmFyaWFibGVUeXBlLlNUUklOR1wiKTtcbiAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgIHJldHVybiB0LmlkZW50aWZpZXIoXCJWYXJpYWJsZVR5cGUuTlVNQkVSXCIpO1xuICAgICAgICBjYXNlIFwiYm9vbFwiOlxuICAgICAgICAgIHJldHVybiB0LmlkZW50aWZpZXIoXCJWYXJpYWJsZVR5cGUuQk9PTFwiKTtcbiAgICAgICAgY2FzZSBcImFueVwiOlxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiB0LmlkZW50aWZpZXIoXCJWYXJpYWJsZVR5cGUuQU5ZXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0ZXguaXNGdW5jdGlvbkNhbGxFeHByZXNzaW9uKHR5cGUpKSB7XG4gICAgICBhZGRWYXJpYWJsZVR5cGVUb0ltcG9ydHMoKTtcbiAgICAgIHN3aXRjaCAodHlwZS5tZXRhLm5hbWUpIHtcbiAgICAgICAgY2FzZSBcImxpc3RcIjpcbiAgICAgICAgY2FzZSBcInNldFwiOlxuICAgICAgICBjYXNlIFwibWFwXCI6XG4gICAgICAgIGNhc2UgXCJ0dXBsZVwiOlxuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgcmV0dXJuIHQuY2FsbEV4cHJlc3Npb24oXG4gICAgICAgICAgICB0LmlkZW50aWZpZXIoYFZhcmlhYmxlVHlwZS4ke3R5cGUubWV0YS5uYW1lfWApLFxuICAgICAgICAgICAgdHlwZS5jaGlsZHJlbi5tYXAoKGNoaWxkKSA9PiBwYXJzZWRUeXBlVG9Bc3QoY2hpbGQpKSxcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0ZXguaXNPYmplY3RFeHByZXNzaW9uKHR5cGUpKSB7XG4gICAgICByZXR1cm4gdC5vYmplY3RFeHByZXNzaW9uKFxuICAgICAgICBPYmplY3QuZW50cmllcyh0eXBlLm1ldGEuaXRlbXMpLm1hcCgoW2tleSwgdmFsdWVdKSA9PlxuICAgICAgICAgIHQub2JqZWN0UHJvcGVydHkoXG4gICAgICAgICAgICB0LnN0cmluZ0xpdGVyYWwoa2V5KSxcbiAgICAgICAgICAgIC8vIFRoaXMgZG9lcyBub3QgZGVhbCB3aXRoIGNvbXBsZXggdHlwZXMgbmVzdGVkIHdpdGhpbiBvYmplY3RzXG4gICAgICAgICAgICAvLyBJZiBzdWNoIGEgdHlwZSBpcyBmb3VuZCBpdCB3aWxsIHJlc3VsdCBpbiBhbiBBbnkgdHlwZVxuICAgICAgICAgICAgLy8gZS5nLiB7IGZvbzogbGlzdChzdHJpbmcpIH0gd2lsbCByZXN1bHQgaW4geyBmb286IGFueSB9XG4gICAgICAgICAgICBwYXJzZWRUeXBlVG9Bc3Qoe1xuICAgICAgICAgICAgICB0eXBlOiBcInNjb3BlVHJhdmVyc2FsXCIsXG4gICAgICAgICAgICAgIG1ldGE6IHsgdmFsdWUgfSxcbiAgICAgICAgICAgIH0gYXMgYW55KSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBhZGRWYXJpYWJsZVR5cGVUb0ltcG9ydHMoKTtcbiAgICByZXR1cm4gdC5pZGVudGlmaWVyKFwiVmFyaWFibGVUeXBlLkFOWVwiKTtcbiAgfVxuXG4gIHJldHVybiBwYXJzZWRUeXBlVG9Bc3QoYXdhaXQgZXhwcmVzc2lvbkFzdCh0eXBlKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB2YXJpYWJsZShcbiAgc2NvcGU6IFByb2dyYW1TY29wZSxcbiAga2V5OiBzdHJpbmcsXG4gIGlkOiBzdHJpbmcsXG4gIGl0ZW06IFZhcmlhYmxlLFxuICBncmFwaDogRGlyZWN0ZWRHcmFwaCxcbikge1xuICBjb25zdCBbeyB0eXBlLCAuLi5wcm9wcyB9XSA9IGl0ZW07XG5cbiAgaWYgKCFnZXRSZWZlcmVuY2UoZ3JhcGgsIGlkKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHJldHVybiBhc0V4cHJlc3Npb24oXG4gICAgc2NvcGUsXG4gICAgaWQsXG4gICAga2V5LFxuICAgIHsgLi4ucHJvcHMsIHR5cGU6IHR5cGUgPyBhd2FpdCB2YXJpYWJsZVR5cGVUb0FzdChzY29wZSwgdHlwZSkgOiB1bmRlZmluZWQgfSxcbiAgICBmYWxzZSxcbiAgICBmYWxzZSxcbiAgICBnZXRSZWZlcmVuY2UoZ3JhcGgsIGlkKSxcbiAgICB1bmRlZmluZWQsXG4gICk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2NhbChcbiAgc2NvcGU6IFByb2dyYW1TY29wZSxcbiAga2V5OiBzdHJpbmcsXG4gIGlkOiBzdHJpbmcsXG4gIGl0ZW06IFRlcnJhZm9ybVJlc291cmNlQmxvY2ssXG4gIGdyYXBoOiBEaXJlY3RlZEdyYXBoLFxuKTogUHJvbWlzZTx0LlZhcmlhYmxlRGVjbGFyYXRpb25bXT4ge1xuICBsb2dnZXIuZGVidWcoYEluaXRpYWxpemluZyBsb2NhbCByZXNvdXJjZSAke2tleX0gd2l0aCBpZCAke2lkfWApO1xuICBpZiAoIWdldFJlZmVyZW5jZShncmFwaCwgaWQpKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBObyByZWZlcmVuY2UgZm91bmQgZm9yICR7a2V5fWApO1xuICAgIHJldHVybiBbXTtcbiAgfVxuICByZXR1cm4gW1xuICAgIHQudmFyaWFibGVEZWNsYXJhdGlvbihcImNvbnN0XCIsIFtcbiAgICAgIHQudmFyaWFibGVEZWNsYXJhdG9yKFxuICAgICAgICB0LmlkZW50aWZpZXIodmFyaWFibGVOYW1lKHNjb3BlLCBcImxvY2FsXCIsIGtleSkpLFxuICAgICAgICBhd2FpdCB2YWx1ZVRvVHMoc2NvcGUsIGl0ZW0sIFwicGF0aC1mb3ItbG9jYWwtYmxvY2tzLWNhbi1iZS1pZ25vcmVkXCIpLFxuICAgICAgKSxcbiAgICBdKSxcbiAgXTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1vZHVsZXMoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIGtleTogc3RyaW5nLFxuICBpZDogc3RyaW5nLFxuICBpdGVtOiBNb2R1bGUsXG4gIGdyYXBoOiBEaXJlY3RlZEdyYXBoLFxuKSB7XG4gIGNvbnN0IFt7IHNvdXJjZSwgdmVyc2lvbiwgLi4ucHJvcHMgfV0gPSBpdGVtO1xuXG4gIGNvbnN0IG1vZHVsZUNvbnN0cmFpbnQgPSBuZXcgVGVycmFmb3JtTW9kdWxlQ29uc3RyYWludChzb3VyY2UpO1xuXG4gIHJldHVybiBhc0V4cHJlc3Npb24oXG4gICAgc2NvcGUsXG4gICAgbW9kdWxlQ29uc3RyYWludC5jbGFzc05hbWUsXG4gICAga2V5LFxuICAgIHByb3BzLFxuICAgIHRydWUsXG4gICAgZmFsc2UsXG4gICAgZ2V0UmVmZXJlbmNlKGdyYXBoLCBpZCksXG4gICAgdW5kZWZpbmVkLFxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW1wb3J0cyhcbiAgc2NvcGU6IFByb2dyYW1TY29wZSxcbiAgX2lkOiBzdHJpbmcsXG4gIGl0ZW06IEltcG9ydCxcbiAgZ3JhcGg6IERpcmVjdGVkR3JhcGgsXG4pIHtcbiAgLy8gTW92ZSBmcm9tICR7YXdzX2luc3RhbmNlLmV4YW1wbGV9IHRvIGF3c19pbnN0YW5jZS5leGFtcGxlXG4gIGNvbnN0IHRhcmdldCA9XG4gICAgaXRlbS50by5zdGFydHNXaXRoKFwiJHtcIikgJiYgaXRlbS50by5lbmRzV2l0aChcIn1cIilcbiAgICAgID8gaXRlbS50by5zdWJzdHJpbmcoMiwgaXRlbS50by5sZW5ndGggLSAxKVxuICAgICAgOiBpdGVtLnRvO1xuXG4gIC8vIENoZWNrIGlmIHRoZSBpbXBvcnQgZ29lcyBpbnRvIGEgbW9kdWxlXG4gIGlmICh0YXJnZXQuc3RhcnRzV2l0aChcIm1vZHVsZS5cIikpIHtcbiAgICByZXR1cm4gW1xuICAgICAgdC5hZGRDb21tZW50KFxuICAgICAgICB0LmVtcHR5U3RhdGVtZW50KCksXG4gICAgICAgIFwibGVhZGluZ1wiLFxuICAgICAgICBgQ0RLVE4gZG9lcyBub3Qgc3VwcG9ydCBpbXBvcnRzIGludG8gbW9kdWxlcyB5ZXQsIHBsZWFzZSByZW1vdmUgdGhlIGltcG9ydCBibG9jayBpbXBvcnRpbmcgJHtpdGVtLmlkfSBpbnRvICR7dGFyZ2V0fSBmcm9tIHlvdXIgY29uZmlndXJhdGlvbmAsXG4gICAgICApLFxuICAgIF07XG4gIH1cblxuICAvLyBXZSBub3cga25vdyB0aGF0IHRoZSBpbXBvcnQgZ29lcyBpbnRvIGEgcmVzb3VyY2UsIGUuZy4gYXdzX2luc3RhbmNlLmV4YW1wbGVcbiAgY29uc3QgW3Jlc291cmNlVHlwZUlkZW50aWZpZXIsIHJlc291cmNlTmFtZV0gPSB0YXJnZXQuc3BsaXQoXCIuXCIpO1xuICBpZiAocmVzb3VyY2VOYW1lLmluY2x1ZGVzKFwiW1wiKSkge1xuICAgIHJldHVybiBbXG4gICAgICB0LmFkZENvbW1lbnQoXG4gICAgICAgIHQuZW1wdHlTdGF0ZW1lbnQoKSxcbiAgICAgICAgXCJsZWFkaW5nXCIsXG4gICAgICAgIGBDREtUTiBkb2VzIG5vdCBzdXBwb3J0IGltcG9ydHMgaW50byByZXNvdXJjZXMgd2l0aCBjb3VudCBvciBmb3JfZWFjaCB5ZXQsIHBsZWFzZSByZW1vdmUgdGhlIGltcG9ydCBibG9jayBpbXBvcnRpbmcgJHtpdGVtLmlkfSBpbnRvICR7dGFyZ2V0fSBmcm9tIHlvdXIgY29uZmlndXJhdGlvbmAsXG4gICAgICApLFxuICAgIF07XG4gIH1cblxuICAvLyBDaGVjayBpZiB3ZSBoYXZlIGEgZXhpc3RpbmcgcmVzb3VyY2UgY29uZmlnIHdpdGggdGhlIGdpdmVuIG5hbWVcbiAgaWYgKGdyYXBoLmhhc05vZGUodGFyZ2V0KSkge1xuICAgIC8vIFdlIHdpbGwgaGFuZGxlIHRoaXMgY2FzZSBpbiB0aGUgcmVzb3VyY2UgZnVuY3Rpb25cbiAgICAvLyBzbyB3ZSBjYW4gc2tpcCBvdmVyIGl0XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgW3Byb3ZpZGVyLCAuLi5yZXNvdXJjZVR5cGVOYW1lUGFydHNdID1cbiAgICByZXNvdXJjZVR5cGVJZGVudGlmaWVyLnNwbGl0KFwiX1wiKTtcblxuICBjb25zdCBjb25zdHJ1Y3RJZCA9IHVuaXF1ZUlkKHNjb3BlLmNvbnN0cnVjdHMsIGNhbWVsQ2FzZShyZXNvdXJjZU5hbWUpKTtcbiAgY29uc3QgY29uc3RydWN0Q2xhc3MgPSBjb25zdHJ1Y3RBc3QoXG4gICAgc2NvcGUsXG4gICAgYCR7cHJvdmlkZXJ9LiR7cmVzb3VyY2VUeXBlTmFtZVBhcnRzLmpvaW4oXCJfXCIpfWAsXG4gICAgZmFsc2UsXG4gICk7XG4gIHJldHVybiBbXG4gICAgdC5leHByZXNzaW9uU3RhdGVtZW50KFxuICAgICAgdC5jYWxsRXhwcmVzc2lvbihcbiAgICAgICAgdC5tZW1iZXJFeHByZXNzaW9uKFxuICAgICAgICAgIGNvbnN0cnVjdENsYXNzLFxuICAgICAgICAgIHQuaWRlbnRpZmllcihcImdlbmVyYXRlQ29uZmlnRm9ySW1wb3J0XCIpLFxuICAgICAgICApLFxuICAgICAgICBbXG4gICAgICAgICAgdC50aGlzRXhwcmVzc2lvbigpLFxuICAgICAgICAgIHQuc3RyaW5nTGl0ZXJhbChjb25zdHJ1Y3RJZCksXG4gICAgICAgICAgdC5zdHJpbmdMaXRlcmFsKGl0ZW0uaWQpLFxuICAgICAgICBdLFxuICAgICAgKSxcbiAgICApLFxuICBdO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvdmlkZXIoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIGtleTogc3RyaW5nLFxuICBpZDogc3RyaW5nLFxuICBpdGVtOiBQcm92aWRlclswXSxcbiAgZ3JhcGg6IERpcmVjdGVkR3JhcGgsXG4pIHtcbiAgY29uc3QgeyB2ZXJzaW9uLCAuLi5wcm9wcyB9ID0gaXRlbTtcblxuICBjb25zdCBpbXBvcnRLZXkgPSBrZXkgPT09IFwibnVsbFwiID8gXCJOdWxsUHJvdmlkZXJcIiA6IGtleTtcblxuICByZXR1cm4gYXNFeHByZXNzaW9uKFxuICAgIHNjb3BlLFxuICAgIGAke2ltcG9ydEtleX0uJHtwYXNjYWxDYXNlKGtleSl9UHJvdmlkZXJgLFxuICAgIGtleSxcbiAgICBwcm9wcyxcbiAgICBmYWxzZSxcbiAgICB0cnVlLFxuICAgIGdldFJlZmVyZW5jZShncmFwaCwgaWQpLFxuICAgIHVuZGVmaW5lZCxcbiAgKTtcbn1cblxuZXhwb3J0IGNvbnN0IGNka3RmSW1wb3J0ID0gdGVtcGxhdGUoXG4gIGBpbXBvcnQgKiBhcyBjZGt0biBmcm9tIFwiY2RrdG5cImAsXG4pKCkgYXMgdC5TdGF0ZW1lbnQ7XG5cbmV4cG9ydCBjb25zdCBjb25zdHJ1Y3RzSW1wb3J0ID0gdGVtcGxhdGUoXG4gIGBpbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gXCJjb25zdHJ1Y3RzXCJgLFxuKSgpIGFzIHQuU3RhdGVtZW50O1xuXG5leHBvcnQgY29uc3QgcHJvdmlkZXJJbXBvcnRzID0gKHByb3ZpZGVyczogc3RyaW5nW10pID0+XG4gIHByb3ZpZGVycy5tYXAoKHByb3ZpZGVyTmFtZSkgPT4ge1xuICAgIGNvbnN0IHBhcnRzID0gcHJvdmlkZXJOYW1lLnNwbGl0KFwiL1wiKTtcbiAgICBjb25zdCBuYW1lID0gcGFydHMubGVuZ3RoID4gMSA/IHBhcnRzWzFdIDogcGFydHNbMF07XG4gICAgY29uc3QgaW1wb3J0TmFtZSA9IG5hbWUgPT09IFwibnVsbFwiID8gXCJOdWxsUHJvdmlkZXJcIiA6IG5hbWU7XG4gICAgcmV0dXJuIHRlbXBsYXRlKFxuICAgICAgYGltcG9ydCAqIGFzICR7aW1wb3J0TmFtZX0gZnJvbSBcIi4vLmdlbi9wcm92aWRlcnMvJHtuYW1lLnJlcGxhY2UoXG4gICAgICAgIFwiLi9cIixcbiAgICAgICAgXCJcIixcbiAgICAgICl9XCJgLFxuICAgICkoKSBhcyB0LlN0YXRlbWVudDtcbiAgfSk7XG5cbmV4cG9ydCBjb25zdCBtb2R1bGVJbXBvcnRzID0gKG1vZHVsZXM6IFJlY29yZDxzdHJpbmcsIE1vZHVsZT4gfCB1bmRlZmluZWQpID0+IHtcbiAgY29uc3QgdW5pcXVlTW9kdWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBPYmplY3QudmFsdWVzKG1vZHVsZXMgfHwge30pLm1hcCgoW21vZHVsZV0pID0+XG4gICAgdW5pcXVlTW9kdWxlcy5hZGQobW9kdWxlLnNvdXJjZSksXG4gICk7XG5cbiAgY29uc3QgaW1wb3J0czogdC5TdGF0ZW1lbnRbXSA9IFtdO1xuICB1bmlxdWVNb2R1bGVzLmZvckVhY2goKG0pID0+IHtcbiAgICBjb25zdCBtb2R1bGVDb25zdHJhaW50ID0gbmV3IFRlcnJhZm9ybU1vZHVsZUNvbnN0cmFpbnQobSk7XG4gICAgaW1wb3J0cy5wdXNoKFxuICAgICAgdGVtcGxhdGUuYXN0KFxuICAgICAgICBgaW1wb3J0ICogYXMgJHttb2R1bGVDb25zdHJhaW50LmNsYXNzTmFtZX0gZnJvbSBcIi4vLmdlbi9tb2R1bGVzLyR7bW9kdWxlQ29uc3RyYWludC5maWxlTmFtZX1cImAsXG4gICAgICApIGFzIHQuU3RhdGVtZW50LFxuICAgICk7XG4gIH0pO1xuICByZXR1cm4gaW1wb3J0cztcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW4oc3RhdGVtZW50czogdC5TdGF0ZW1lbnRbXSkge1xuICBsb2dnZXIuZGVidWcoYEdlbmVyYXRpbmcgY29kZSBmb3IgJHtKU09OLnN0cmluZ2lmeShzdGF0ZW1lbnRzLCBudWxsLCAyKX1gKTtcbiAgY29uc3QgY29kZSA9IHByZXR0aWVyLmZvcm1hdChnZW5lcmF0ZSh0LnByb2dyYW0oc3RhdGVtZW50cykgYXMgYW55KS5jb2RlLCB7XG4gICAgcGFyc2VyOiBcImJhYmVsXCIsXG4gIH0pO1xuXG4gIGxvZ2dlci5kZWJ1ZyhgR2VuZXJhdGVkIGNvZGU6XFxuJHtjb2RlfWApO1xuXG4gIHJldHVybiBjb2RlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkSW1wb3J0Rm9yQ29kZUNvbnRhaW5lcihcbiAgc2NvcGU6IFByb2dyYW1TY29wZSxcbiAgY29kZUNvbnRhaW5lcjogc3RyaW5nLFxuKSB7XG4gIHN3aXRjaCAoY29kZUNvbnRhaW5lcikge1xuICAgIGNhc2UgXCJjb25zdHJ1Y3RzLkNvbnN0cnVjdFwiOlxuICAgICAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgICAgIHByb3ZpZGVyOiBcImNvbnN0cnVjdHNcIixcbiAgICAgICAgY29uc3RydWN0TmFtZTogXCJDb25zdHJ1Y3RcIixcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFwiY2RrdG4uVGVycmFmb3JtU3RhY2tcIjpcbiAgICAgIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgICAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICAgICAgICBjb25zdHJ1Y3ROYW1lOiBcIlRlcnJhZm9ybVN0YWNrXCIsXG4gICAgICB9KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcImNka3RmLlRlcnJhZm9ybVN0YWNrXCI6XG4gICAgICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICAgICAgcHJvdmlkZXI6IFwiY2RrdGZcIixcbiAgICAgICAgY29uc3RydWN0TmFtZTogXCJUZXJyYWZvcm1TdGFja1wiLFxuICAgICAgfSk7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgRXJyb3JzLkludGVybmFsKFwiVW5zdXBwb3J0ZWQgY29kZSBjb250YWluZXI6IFwiICsgY29kZUNvbnRhaW5lcik7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBDb2RlSW5Db25zdHJ1Y3RvcihcbiAgY29kZUNvbnRhaW5lcjogc3RyaW5nLFxuICBjb2RlOiB0LlN0YXRlbWVudFtdLFxuICBjbGFzc05hbWU6IHN0cmluZyxcbiAgY29uZmlnVHlwZU5hbWU/OiBzdHJpbmcsXG4pOiB0LlN0YXRlbWVudCB7XG4gIGxldCBiYXNlQ29udGFpbmVyQ2xhc3M6IHQuSWRlbnRpZmllcjtcbiAgc3dpdGNoIChjb2RlQ29udGFpbmVyKSB7XG4gICAgY2FzZSBcImNvbnN0cnVjdHMuQ29uc3RydWN0XCI6XG4gICAgICBiYXNlQ29udGFpbmVyQ2xhc3MgPSB0LmlkZW50aWZpZXIoXCJDb25zdHJ1Y3RcIik7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJjZGt0bi5UZXJyYWZvcm1TdGFja1wiOlxuICAgICAgYmFzZUNvbnRhaW5lckNsYXNzID0gdC5pZGVudGlmaWVyKFwiVGVycmFmb3JtU3RhY2tcIik7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgRXJyb3JzLkludGVybmFsKFwiVW5zdXBwb3J0ZWQgY29kZSBjb250YWluZXI6IFwiICsgY29kZUNvbnRhaW5lcik7XG4gIH1cbiAgaWYgKGNvbmZpZ1R5cGVOYW1lKSB7XG4gICAgcmV0dXJuIHRlbXBsYXRlLnN0YXRlbWVudChcbiAgICAgIGBcbiAgY2xhc3MgJSVjbGFzc05hbWUlJSBleHRlbmRzICUlYmFzZSUlIHtcbiAgICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBuYW1lOiBzdHJpbmcsIGNvbmZpZzogJHtjb25maWdUeXBlTmFtZX0pIHtcbiAgICAgIHN1cGVyKHNjb3BlLCBuYW1lKTtcbiAgICAgICUlY29kZSUlXG4gICAgfVxuICB9XG5gLFxuICAgICAgeyBzeW50YWN0aWNQbGFjZWhvbGRlcnM6IHRydWUsIHBsdWdpbnM6IFtcInR5cGVzY3JpcHRcIl0gfSxcbiAgICApKHtcbiAgICAgIGNvZGUsXG4gICAgICBiYXNlOiBiYXNlQ29udGFpbmVyQ2xhc3MsXG4gICAgICBjbGFzc05hbWU6IHQuaWRlbnRpZmllcihjbGFzc05hbWUpLFxuICAgIH0pIGFzIHQuU3RhdGVtZW50O1xuICB9XG4gIHJldHVybiB0ZW1wbGF0ZS5zdGF0ZW1lbnQoXG4gICAgYFxuICBjbGFzcyAlJWNsYXNzTmFtZSUlIGV4dGVuZHMgJSViYXNlJSUge1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIG5hbWU6IHN0cmluZykge1xuICAgICAgc3VwZXIoc2NvcGUsIG5hbWUpO1xuICAgICAgJSVjb2RlJSVcbiAgICB9XG4gIH1cbmAsXG4gICAgeyBzeW50YWN0aWNQbGFjZWhvbGRlcnM6IHRydWUsIHBsdWdpbnM6IFtcInR5cGVzY3JpcHRcIl0gfSxcbiAgKSh7XG4gICAgY29kZSxcbiAgICBiYXNlOiBiYXNlQ29udGFpbmVyQ2xhc3MsXG4gICAgY2xhc3NOYW1lOiB0LmlkZW50aWZpZXIoY2xhc3NOYW1lKSxcbiAgfSkgYXMgdC5TdGF0ZW1lbnQ7XG59XG5cbmV4cG9ydCBjb25zdCBwcm92aWRlckNvbnN0cnVjdEltcG9ydHMgPSAoaW1wb3J0YWJsZTogSW1wb3J0YWJsZUNvbnN0cnVjdFtdKSA9PiB7XG4gIGxldCBwcm92aWRlciA9IGltcG9ydGFibGVbMF0ucHJvdmlkZXI7XG4gIGxldCBuYW1lc3BhY2UgPSBpbXBvcnRhYmxlWzBdLm5hbWVzcGFjZTtcbiAgY29uc3QgbmFtZXMgPSBpbXBvcnRhYmxlLm1hcCgoaSkgPT4gaS5jb25zdHJ1Y3ROYW1lKTtcblxuICBpZiAocHJvdmlkZXIgPT09IFwiY2RrdG5cIiB8fCBwcm92aWRlciA9PT0gXCJjb25zdHJ1Y3RzXCIpIHtcbiAgICByZXR1cm4gdGVtcGxhdGUoXG4gICAgICBgaW1wb3J0IHsgJHtuYW1lcy5qb2luKFwiLCBcIil9IH0gZnJvbSBcIiR7cHJvdmlkZXJ9XCJgLFxuICAgICkoKSBhcyB0LlN0YXRlbWVudDtcbiAgfVxuXG4gIGlmIChuYW1lc3BhY2UpIHtcbiAgICBuYW1lc3BhY2UgPSBzbmFrZUNhc2UobmFtZXNwYWNlKS5yZXBsYWNlKC9fL2csIFwiLVwiKTtcbiAgfVxuXG4gIC8vIFNwZWNpYWwgY2FzZXMgdG8gdW5kbyBwcm92aWRlciBuYW1lcyB0aGF0IHdlIG92ZXJyaWRlXG4gIGlmIChwcm92aWRlciA9PT0gXCJOdWxsUHJvdmlkZXJcIikge1xuICAgIHByb3ZpZGVyID0gXCJudWxsXCI7XG4gIH1cblxuICByZXR1cm4gdGVtcGxhdGUoXG4gICAgYGltcG9ydCB7ICR7bmFtZXMuam9pbihcbiAgICAgIFwiLCBcIixcbiAgICApfSB9IGZyb20gXCIuLy5nZW4vcHJvdmlkZXJzLyR7cHJvdmlkZXJ9LyR7bmFtZXNwYWNlfVwiYCxcbiAgKSgpIGFzIHQuU3RhdGVtZW50O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkSW1wb3J0cyhpbXBvcnRhYmxlczogSW1wb3J0YWJsZUNvbnN0cnVjdFtdKSB7XG4gIGNvbnN0IGdyb3VwZWRJbXBvcnRhYmxlcyA9IGltcG9ydGFibGVzLnJlZHVjZShcbiAgICAoYWNjLCBpbXBvcnRhYmxlKSA9PiB7XG4gICAgICBjb25zdCBucyA9IGltcG9ydGFibGUubmFtZXNwYWNlIHx8IFwiXCI7XG4gICAgICAvLyBEb2luZyBzb21lIGhhY2t5IG9yZGVyaW5nIG9mIHRoZSBpbXBvcnRzIHRvIG1ha2UgdGhlbSBsb29rIGEgYml0IG5pY2VyXG4gICAgICBjb25zdCBwcmVmaXggPVxuICAgICAgICBpbXBvcnRhYmxlLnByb3ZpZGVyID09PSBcImNvbnN0cnVjdHNcIlxuICAgICAgICAgID8gXCIxXCJcbiAgICAgICAgICA6IGltcG9ydGFibGUucHJvdmlkZXIgPT09IFwiY2RrdG5cIlxuICAgICAgICAgICAgPyBcIjJcIlxuICAgICAgICAgICAgOiBpbXBvcnRhYmxlLnByb3ZpZGVyID09PSBcImNka3RmXCJcbiAgICAgICAgICAgICAgPyBcIjNcIlxuICAgICAgICAgICAgICA6IFwiNFwiO1xuICAgICAgY29uc3QgZ3JvdXBOYW1lID0gYCR7cHJlZml4fS4ke2ltcG9ydGFibGUucHJvdmlkZXJ9LiR7bnN9YDtcbiAgICAgIGNvbnN0IGZ1bGxOYW1lID0gYCR7aW1wb3J0YWJsZS5wcm92aWRlcn0uJHtuc30uJHtpbXBvcnRhYmxlLmNvbnN0cnVjdE5hbWV9YDtcblxuICAgICAgaWYgKGFjY1tncm91cE5hbWVdKSB7XG4gICAgICAgIGNvbnN0IGV4aXN0c0FscmVhZHkgPSBhY2NbZ3JvdXBOYW1lXS5zb21lKFxuICAgICAgICAgIChpbXBvcnRhYmxlKSA9PlxuICAgICAgICAgICAgYCR7aW1wb3J0YWJsZS5wcm92aWRlcn0uJHtuc30uJHtpbXBvcnRhYmxlLmNvbnN0cnVjdE5hbWV9YCA9PT1cbiAgICAgICAgICAgIGZ1bGxOYW1lLFxuICAgICAgICApO1xuICAgICAgICBpZiAoZXhpc3RzQWxyZWFkeSkge1xuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH1cbiAgICAgICAgYWNjW2dyb3VwTmFtZV0ucHVzaChpbXBvcnRhYmxlKTtcbiAgICAgICAgYWNjW2dyb3VwTmFtZV0uc29ydCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWNjW2dyb3VwTmFtZV0gPSBbaW1wb3J0YWJsZV07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSxcbiAgICB7fSBhcyBSZWNvcmQ8c3RyaW5nLCBJbXBvcnRhYmxlQ29uc3RydWN0W10+LFxuICApO1xuXG4gIGxldCBjb21tZW50QWRkZWQgPSBmYWxzZTtcbiAgY29uc3QgY29uc3RydWN0SW1wb3J0cyA9IE9iamVjdC5rZXlzKGdyb3VwZWRJbXBvcnRhYmxlcylcbiAgICAuc29ydCgpXG4gICAgLm1hcCgoZ3JvdXBOYW1lKSA9PiB7XG4gICAgICBjb25zdCBpbXBvcnRTdGF0ZW1lbnQgPSBwcm92aWRlckNvbnN0cnVjdEltcG9ydHMoXG4gICAgICAgIGdyb3VwZWRJbXBvcnRhYmxlc1tncm91cE5hbWVdLFxuICAgICAgKTtcblxuICAgICAgaWYgKGdyb3VwTmFtZS5zdGFydHNXaXRoKFwiNC5cIikgJiYgIWNvbW1lbnRBZGRlZCkge1xuICAgICAgICBjb21tZW50QWRkZWQgPSB0cnVlO1xuICAgICAgICB0LmFkZENvbW1lbnQoXG4gICAgICAgICAgaW1wb3J0U3RhdGVtZW50LFxuICAgICAgICAgIFwibGVhZGluZ1wiLFxuICAgICAgICAgIGBcXG4qIFByb3ZpZGVyIGJpbmRpbmdzIGFyZSBnZW5lcmF0ZWQgYnkgcnVubmluZyBcXGBjZGt0biBnZXRcXGAuXG4qIFNlZSBodHRwczovL2Nkay50Zi9wcm92aWRlci1nZW5lcmF0aW9uIGZvciBtb3JlIGRldGFpbHMuXFxuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpbXBvcnRTdGF0ZW1lbnQ7XG4gICAgfSk7XG5cbiAgcmV0dXJuIGNvbnN0cnVjdEltcG9ydHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUNvbmZpZ1R5cGUoXG4gIG5hbWU6IHN0cmluZyxcbiAgY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVQYXRoPixcbik6IHQuU3RhdGVtZW50IHtcbiAgcmV0dXJuIHQudHNJbnRlcmZhY2VEZWNsYXJhdGlvbihcbiAgICB0LmlkZW50aWZpZXIobmFtZSksXG4gICAgdW5kZWZpbmVkLFxuICAgIHVuZGVmaW5lZCxcbiAgICB0LnRzSW50ZXJmYWNlQm9keShcbiAgICAgIE9iamVjdC5lbnRyaWVzKGNvbmZpZykubWFwKChba2V5LCBfdmFsdWVdKSA9PlxuICAgICAgICB0LnRzUHJvcGVydHlTaWduYXR1cmUoXG4gICAgICAgICAgdC5pZGVudGlmaWVyKGtleSksXG4gICAgICAgICAgdC50U1R5cGVBbm5vdGF0aW9uKHQudHNBbnlLZXl3b3JkKCkpLCAvLyBUT0RPOiBUcnkgdG8gbWFrZSB0aGlzIGJldHRlciB0aGFuIGFueVxuICAgICAgICApLFxuICAgICAgKSxcbiAgICApLFxuICApO1xufVxuIl19
|