@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
package/lib/expressions.js
DELETED
|
@@ -1,634 +0,0 @@
|
|
|
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.dynamicVariableToAst = exports.extractIteratorVariablesFromExpression = exports.convertTerraformExpressionToTs = exports.expressionAst = void 0;
|
|
30
|
-
// Copyright (c) HashiCorp, Inc
|
|
31
|
-
// SPDX-License-Identifier: MPL-2.0
|
|
32
|
-
const t = __importStar(require("@babel/types"));
|
|
33
|
-
const template_1 = __importDefault(require("@babel/template"));
|
|
34
|
-
const utils_1 = require("./utils");
|
|
35
|
-
const hcl2json_1 = require("@cdktn/hcl2json");
|
|
36
|
-
const hcl2json_2 = require("@cdktn/hcl2json");
|
|
37
|
-
const functions_1 = require("./function-bindings/functions");
|
|
38
|
-
const coerceType_1 = require("./coerceType");
|
|
39
|
-
const terraformSchema_1 = require("./terraformSchema");
|
|
40
|
-
const references_1 = require("./references");
|
|
41
|
-
const variables_1 = require("./variables");
|
|
42
|
-
const syntax_tree_1 = require("@cdktn/hcl2json/lib/syntax-tree");
|
|
43
|
-
const tfBinaryOperatorsToCdktf = {
|
|
44
|
-
logicalOr: "or",
|
|
45
|
-
logicalAnd: "and",
|
|
46
|
-
greaterThan: "gt",
|
|
47
|
-
greaterThanOrEqual: "gte",
|
|
48
|
-
lessThan: "lt",
|
|
49
|
-
lessThanOrEqual: "lte",
|
|
50
|
-
equal: "eq",
|
|
51
|
-
notEqual: "neq",
|
|
52
|
-
add: "add",
|
|
53
|
-
subtract: "sub",
|
|
54
|
-
multiply: "mul",
|
|
55
|
-
divide: "div",
|
|
56
|
-
modulo: "mod",
|
|
57
|
-
};
|
|
58
|
-
const tfUnaryOperatorsToCdktf = {
|
|
59
|
-
logicalNot: "not",
|
|
60
|
-
negate: "negate",
|
|
61
|
-
};
|
|
62
|
-
function traversalPartsToString(traversals, asSuffix = false) {
|
|
63
|
-
let seed = "";
|
|
64
|
-
if (asSuffix && hcl2json_2.TFExpressionSyntaxTree.isNameTraversalPart(traversals[0])) {
|
|
65
|
-
seed = ".";
|
|
66
|
-
}
|
|
67
|
-
return traversals.reduce((acc, part) => {
|
|
68
|
-
if (part.type === "nameTraversal") {
|
|
69
|
-
if (acc === seed) {
|
|
70
|
-
return `${acc}${part.segment}`;
|
|
71
|
-
}
|
|
72
|
-
return `${acc}.${part.segment}`;
|
|
73
|
-
}
|
|
74
|
-
return `${acc}[${part.segment}]`;
|
|
75
|
-
}, seed);
|
|
76
|
-
}
|
|
77
|
-
function canUseFqn(expression) {
|
|
78
|
-
if (!hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(expression)) {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
const rootSegment = expression.meta.traversal[0].segment;
|
|
82
|
-
return !["var", "local"].includes(rootSegment);
|
|
83
|
-
}
|
|
84
|
-
function traversalToVariableName(scope, node) {
|
|
85
|
-
if (!hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(node)) {
|
|
86
|
-
utils_1.logger.error(`Unexpected expression type ${node.type} with value ${node.meta.value} passed to convert to a variable.
|
|
87
|
-
${utils_1.leaveCommentText}`);
|
|
88
|
-
return "";
|
|
89
|
-
}
|
|
90
|
-
const segments = node.meta.traversal;
|
|
91
|
-
if (segments.length === 1) {
|
|
92
|
-
return node.meta.fullAccessor;
|
|
93
|
-
}
|
|
94
|
-
const rootSegment = segments[0].segment;
|
|
95
|
-
const resource = rootSegment === "data"
|
|
96
|
-
? `${segments[0].segment}.${segments[1].segment}`
|
|
97
|
-
: rootSegment;
|
|
98
|
-
const name = rootSegment === "data" ? segments[2].segment : segments[1].segment;
|
|
99
|
-
return (0, variables_1.variableName)(scope, resource, name);
|
|
100
|
-
}
|
|
101
|
-
function expressionForSerialStringConcatenation(scope, nodes) {
|
|
102
|
-
const reducedNodes = nodes.reduce((acc, node) => {
|
|
103
|
-
const prev = acc[acc.length - 1];
|
|
104
|
-
if (!prev)
|
|
105
|
-
return [node];
|
|
106
|
-
if (t.isStringLiteral(prev) && t.isStringLiteral(node)) {
|
|
107
|
-
acc.pop();
|
|
108
|
-
acc.push(t.stringLiteral(prev.value + node.value));
|
|
109
|
-
return acc;
|
|
110
|
-
}
|
|
111
|
-
acc.push(node);
|
|
112
|
-
return acc;
|
|
113
|
-
}, []);
|
|
114
|
-
return reducedNodes.reduce((acc, node) => {
|
|
115
|
-
if (!acc) {
|
|
116
|
-
return node;
|
|
117
|
-
}
|
|
118
|
-
// wrap access to dynamic blocks in Token.asString() as they return a Lazy
|
|
119
|
-
// for .key and .value which can't be concatenated in languages like Python
|
|
120
|
-
// because JSII currently has no support for the toString() method in
|
|
121
|
-
// languages other than TypeScript: https://github.com/aws/jsii/issues/380
|
|
122
|
-
// example: dynamic_iterator0.key / dynamic_iterator0.value
|
|
123
|
-
if (t.isMemberExpression(node) &&
|
|
124
|
-
t.isIdentifier(node.object) &&
|
|
125
|
-
Object.values(scope.scopedVariables || {}).includes(node.object.name) &&
|
|
126
|
-
t.isIdentifier(node.property) &&
|
|
127
|
-
["key", "value"].includes(node.property.name)) {
|
|
128
|
-
node = (0, coerceType_1.coerceType)(scope, node, "dynamic", "string");
|
|
129
|
-
}
|
|
130
|
-
return t.binaryExpression("+", acc, node);
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
function getTfResourcePathFromNode(node) {
|
|
134
|
-
const segments = node.meta.traversal;
|
|
135
|
-
let resource = segments[0].segment;
|
|
136
|
-
let result = [];
|
|
137
|
-
let attributes = [];
|
|
138
|
-
if (segments[0].segment === "data") {
|
|
139
|
-
result.push(segments[0].segment);
|
|
140
|
-
resource = segments[1].segment;
|
|
141
|
-
attributes = segments.slice(3); // we want to skip the variable name
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
attributes = segments.slice(2); // we want to skip the variable name
|
|
145
|
-
}
|
|
146
|
-
const [provider, ...resourceNameFragments] = resource.split("_");
|
|
147
|
-
// Hack: This happens in the case of `external` provider
|
|
148
|
-
// where the data source does not have a provider name prefix
|
|
149
|
-
if (resourceNameFragments.length === 0) {
|
|
150
|
-
resourceNameFragments.push(provider);
|
|
151
|
-
}
|
|
152
|
-
result.push(provider);
|
|
153
|
-
result.push(resourceNameFragments.join("_"));
|
|
154
|
-
result = [
|
|
155
|
-
...result,
|
|
156
|
-
...attributes.map((seg) => {
|
|
157
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isIndexTraversalPart(seg)) {
|
|
158
|
-
return `[${seg.segment}]`;
|
|
159
|
-
}
|
|
160
|
-
return seg.segment;
|
|
161
|
-
}),
|
|
162
|
-
];
|
|
163
|
-
return result.join(".");
|
|
164
|
-
}
|
|
165
|
-
function convertLiteralValueExpressionToTs(_scope, node) {
|
|
166
|
-
const literalType = node.meta.type;
|
|
167
|
-
if (literalType === "number") {
|
|
168
|
-
return t.numericLiteral(Number(node.meta.value));
|
|
169
|
-
}
|
|
170
|
-
if (literalType === "bool") {
|
|
171
|
-
return t.booleanLiteral(node.meta.value === "true" ? true : false);
|
|
172
|
-
}
|
|
173
|
-
return t.stringLiteral(node.meta.value);
|
|
174
|
-
}
|
|
175
|
-
function convertScopeTraversalExpressionToTs(scope, node) {
|
|
176
|
-
var _a;
|
|
177
|
-
const hasReference = (0, references_1.containsReference)(node);
|
|
178
|
-
const segments = node.meta.traversal;
|
|
179
|
-
if (segments[0].segment === "each" && scope.forEachIteratorName) {
|
|
180
|
-
return dynamicVariableToAst(scope, node, scope.forEachIteratorName);
|
|
181
|
-
}
|
|
182
|
-
if (segments[0].segment === "count" && scope.countIteratorName) {
|
|
183
|
-
return dynamicVariableToAst(scope, node, scope.countIteratorName, "count");
|
|
184
|
-
}
|
|
185
|
-
if (segments[0].segment === "self") {
|
|
186
|
-
scope.importables.push({
|
|
187
|
-
constructName: "TerraformSelf",
|
|
188
|
-
provider: "cdktn",
|
|
189
|
-
});
|
|
190
|
-
return t.callExpression(t.memberExpression(t.identifier("TerraformSelf"), t.identifier("getAny")), [t.stringLiteral(traversalPartsToString(segments.slice(1)))]);
|
|
191
|
-
}
|
|
192
|
-
// setting.value, setting.value[1].id
|
|
193
|
-
const dynamicBlock = (_a = scope.scopedVariables) === null || _a === void 0 ? void 0 : _a[segments[0].segment];
|
|
194
|
-
if (dynamicBlock) {
|
|
195
|
-
if (dynamicBlock === "dynamic-block") {
|
|
196
|
-
return dynamicVariableToAst(scope, node, dynamicBlock, traversalPartsToString(segments));
|
|
197
|
-
}
|
|
198
|
-
return dynamicVariableToAst(scope, node, dynamicBlock, segments[0].segment);
|
|
199
|
-
}
|
|
200
|
-
// This may be a variable reference that we don't understand yet, so we wrap it in a template string
|
|
201
|
-
// for Terraform to handle
|
|
202
|
-
let varIdentifier = t.stringLiteral(`\${${node.meta.fullAccessor}}`);
|
|
203
|
-
if (hasReference) {
|
|
204
|
-
varIdentifier = t.identifier((0, utils_1.camelCase)(traversalToVariableName(scope, node)));
|
|
205
|
-
}
|
|
206
|
-
if (["var", "local"].includes(segments[0].segment)) {
|
|
207
|
-
const variableAccessor = segments[0].segment === "var"
|
|
208
|
-
? t.memberExpression(varIdentifier, t.identifier("value"))
|
|
209
|
-
: varIdentifier;
|
|
210
|
-
if (segments.length > 2) {
|
|
211
|
-
scope.importables.push({
|
|
212
|
-
constructName: "Fn",
|
|
213
|
-
provider: "cdktn",
|
|
214
|
-
});
|
|
215
|
-
const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
|
|
216
|
-
return t.callExpression(callee, [
|
|
217
|
-
variableAccessor,
|
|
218
|
-
t.arrayExpression(segments.slice(2).map((s) => t.stringLiteral(s.segment))),
|
|
219
|
-
]);
|
|
220
|
-
}
|
|
221
|
-
return variableAccessor;
|
|
222
|
-
}
|
|
223
|
-
if (!hasReference || scope.withinOverrideExpression) {
|
|
224
|
-
return varIdentifier;
|
|
225
|
-
}
|
|
226
|
-
const rootSegment = segments[0].segment;
|
|
227
|
-
const attributeIndex = rootSegment === "data" ? 3 : 2;
|
|
228
|
-
const attributeSegments = segments.slice(attributeIndex);
|
|
229
|
-
const numericAccessorIndex = attributeSegments.findIndex((seg) => hcl2json_2.TFExpressionSyntaxTree.isIndexTraversalPart(seg));
|
|
230
|
-
let minAccessorIndex = numericAccessorIndex;
|
|
231
|
-
let mapAccessorIndex = -1;
|
|
232
|
-
if (numericAccessorIndex === -1) {
|
|
233
|
-
// only do this if we have to, if we already have a
|
|
234
|
-
// numeric accessor, we don't have to do this additional work
|
|
235
|
-
const resourcePath = getTfResourcePathFromNode(node);
|
|
236
|
-
let usingSubPathType = false;
|
|
237
|
-
const parts = resourcePath.split(".").filter((p) => p !== "");
|
|
238
|
-
const minParts = attributeIndex; // we need to stop before data.aws.resource_name or aws.resource_name
|
|
239
|
-
const originalParts = parts.length;
|
|
240
|
-
let hasMapAccessor = false;
|
|
241
|
-
while (parts.length >= minParts) {
|
|
242
|
-
const type = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, parts.join("."));
|
|
243
|
-
if (type !== null) {
|
|
244
|
-
if (Array.isArray(type) && type[0] === "map" && usingSubPathType) {
|
|
245
|
-
hasMapAccessor = true;
|
|
246
|
-
break;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
parts.pop();
|
|
250
|
-
usingSubPathType = true;
|
|
251
|
-
}
|
|
252
|
-
if (hasMapAccessor) {
|
|
253
|
-
mapAccessorIndex = originalParts - parts.length - 1;
|
|
254
|
-
minAccessorIndex = mapAccessorIndex;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
const needsPropertyAccess = minAccessorIndex >= 0;
|
|
258
|
-
const refSegments = needsPropertyAccess
|
|
259
|
-
? attributeSegments.slice(0, minAccessorIndex)
|
|
260
|
-
: attributeSegments;
|
|
261
|
-
const nonRefSegments = needsPropertyAccess
|
|
262
|
-
? attributeSegments.slice(minAccessorIndex)
|
|
263
|
-
: [];
|
|
264
|
-
const ref = refSegments.reduce((acc, seg, index) => t.memberExpression(acc, t.identifier(index === 0 && rootSegment === "module"
|
|
265
|
-
? (0, utils_1.camelCase)(seg.segment + "Output")
|
|
266
|
-
: (0, utils_1.camelCase)(seg.segment))), varIdentifier);
|
|
267
|
-
if (nonRefSegments.length === 0) {
|
|
268
|
-
return ref;
|
|
269
|
-
}
|
|
270
|
-
scope.importables.push({
|
|
271
|
-
constructName: "Fn",
|
|
272
|
-
provider: "cdktn",
|
|
273
|
-
});
|
|
274
|
-
const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
|
|
275
|
-
return t.callExpression(callee, [
|
|
276
|
-
ref,
|
|
277
|
-
t.arrayExpression(nonRefSegments.map((s) => t.stringLiteral(s.segment))),
|
|
278
|
-
]);
|
|
279
|
-
}
|
|
280
|
-
function convertUnaryOpExpressionToTs(scope, node) {
|
|
281
|
-
const operand = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.valueExpression));
|
|
282
|
-
let fnName = node.meta.operator;
|
|
283
|
-
if (tfUnaryOperatorsToCdktf[fnName]) {
|
|
284
|
-
fnName = tfUnaryOperatorsToCdktf[fnName];
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
throw new Error(`Cannot convert unknown operator ${node.meta.operator}`);
|
|
288
|
-
}
|
|
289
|
-
scope.importables.push({
|
|
290
|
-
constructName: "Op",
|
|
291
|
-
provider: "cdktn",
|
|
292
|
-
});
|
|
293
|
-
const fn = t.memberExpression(t.identifier("Op"), t.identifier(fnName));
|
|
294
|
-
return t.callExpression(fn, [operand]);
|
|
295
|
-
}
|
|
296
|
-
function convertBinaryOpExpressionToTs(scope, node) {
|
|
297
|
-
const left = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.lhsExpression));
|
|
298
|
-
const right = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.rhsExpression));
|
|
299
|
-
let fnName = node.meta.operator;
|
|
300
|
-
if (tfBinaryOperatorsToCdktf[fnName]) {
|
|
301
|
-
fnName = tfBinaryOperatorsToCdktf[fnName];
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
throw new Error(`Cannot convert unknown operator ${node.meta.operator}`);
|
|
305
|
-
}
|
|
306
|
-
scope.importables.push({
|
|
307
|
-
constructName: "Op",
|
|
308
|
-
provider: "cdktn",
|
|
309
|
-
});
|
|
310
|
-
const fn = t.memberExpression(t.identifier("Op"), t.identifier(fnName));
|
|
311
|
-
return t.callExpression(fn, [left, right]);
|
|
312
|
-
}
|
|
313
|
-
function convertTemplateExpressionToTs(scope, node) {
|
|
314
|
-
const parts = node.children.map((child) => ({
|
|
315
|
-
node: child,
|
|
316
|
-
expr: convertTFExpressionAstToTs(scope, child),
|
|
317
|
-
}));
|
|
318
|
-
const lastPart = parts[parts.length - 1];
|
|
319
|
-
if (t.isStringLiteral(lastPart.expr) && lastPart.expr.value === "\n") {
|
|
320
|
-
// This is a bit of a hack, but the trailing newline we add due to
|
|
321
|
-
// heredocs looks ugly and unnecessary in the generated code, so we
|
|
322
|
-
// try to remove it
|
|
323
|
-
parts.pop();
|
|
324
|
-
}
|
|
325
|
-
if (parts.length === 0) {
|
|
326
|
-
return t.stringLiteral(node.meta.value);
|
|
327
|
-
}
|
|
328
|
-
if (parts.length === 1) {
|
|
329
|
-
return parts[0].expr;
|
|
330
|
-
}
|
|
331
|
-
let isScopedTraversal = false;
|
|
332
|
-
const expressions = [];
|
|
333
|
-
for (const { node, expr } of parts) {
|
|
334
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(node) &&
|
|
335
|
-
!t.isStringLiteral(expr) &&
|
|
336
|
-
!t.isCallExpression(expr)) {
|
|
337
|
-
expressions.push(t.stringLiteral("${"));
|
|
338
|
-
isScopedTraversal = true;
|
|
339
|
-
}
|
|
340
|
-
else if (
|
|
341
|
-
// we should ideally be doing type coercion more
|
|
342
|
-
// carefully here, because it may not always be needed
|
|
343
|
-
t.isCallExpression(expr)) {
|
|
344
|
-
scope.importables.push({
|
|
345
|
-
constructName: "Token",
|
|
346
|
-
provider: "cdktn",
|
|
347
|
-
});
|
|
348
|
-
expressions.push(template_1.default.expression(`Token.asString(%%expr%%)`)({
|
|
349
|
-
expr,
|
|
350
|
-
}));
|
|
351
|
-
continue;
|
|
352
|
-
}
|
|
353
|
-
else {
|
|
354
|
-
if (isScopedTraversal) {
|
|
355
|
-
expressions.push(t.stringLiteral("}"));
|
|
356
|
-
isScopedTraversal = false;
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
expressions.push(expr);
|
|
360
|
-
}
|
|
361
|
-
if (isScopedTraversal) {
|
|
362
|
-
expressions.push(t.stringLiteral("}"));
|
|
363
|
-
}
|
|
364
|
-
return expressionForSerialStringConcatenation(scope, expressions);
|
|
365
|
-
}
|
|
366
|
-
function convertObjectExpressionToTs(scope, node) {
|
|
367
|
-
return t.objectExpression(Object.entries(node.meta.items)
|
|
368
|
-
.map(([key, value]) => {
|
|
369
|
-
const valueChild = (0, syntax_tree_1.getChildWithValue)(node, value);
|
|
370
|
-
if (!valueChild) {
|
|
371
|
-
utils_1.logger.error(`Unable to value for object key '${key}': ${value}`);
|
|
372
|
-
return null;
|
|
373
|
-
}
|
|
374
|
-
return t.objectProperty(t.identifier(key), convertTFExpressionAstToTs(scope, valueChild));
|
|
375
|
-
})
|
|
376
|
-
.filter((s) => s !== null));
|
|
377
|
-
}
|
|
378
|
-
function convertFunctionCallExpressionToTs(scope, node) {
|
|
379
|
-
const functionName = node.meta.name;
|
|
380
|
-
const mapping = functions_1.functionsMap[functionName];
|
|
381
|
-
if (!mapping) {
|
|
382
|
-
utils_1.logger.error(`Unknown function ${functionName} encountered. ${utils_1.leaveCommentText}`);
|
|
383
|
-
const argumentExpressions = node.children.map((child) => convertTFExpressionAstToTs(scope, child));
|
|
384
|
-
return t.callExpression(t.identifier(functionName), argumentExpressions);
|
|
385
|
-
}
|
|
386
|
-
const transformedNode = mapping.transformer
|
|
387
|
-
? mapping.transformer(node)
|
|
388
|
-
: node;
|
|
389
|
-
const argumentExpressions = transformedNode.children.map((child) => convertTFExpressionAstToTs(scope, child));
|
|
390
|
-
scope.importables.push({
|
|
391
|
-
constructName: "Fn",
|
|
392
|
-
provider: "cdktn",
|
|
393
|
-
});
|
|
394
|
-
const callee = t.memberExpression(t.identifier("Fn"), t.identifier(mapping.name));
|
|
395
|
-
if (mapping.parameters.length > 0 &&
|
|
396
|
-
mapping.parameters[mapping.parameters.length - 1].variadic) {
|
|
397
|
-
const lastParameterType = mapping.parameters[mapping.parameters.length - 1].type;
|
|
398
|
-
const nonVariadicArguments = argumentExpressions.slice(0, mapping.parameters.length - 1);
|
|
399
|
-
const fnCallArguments = [
|
|
400
|
-
...nonVariadicArguments.map((argExpr, index) => (0, coerceType_1.coerceType)(scope, argExpr, (0, coerceType_1.findExpressionType)(scope, argExpr), mapping.parameters[index].type)),
|
|
401
|
-
t.arrayExpression(argumentExpressions
|
|
402
|
-
.slice(mapping.parameters.length - 1)
|
|
403
|
-
.map((argExpr) => (0, coerceType_1.coerceType)(scope, argExpr, (0, coerceType_1.findExpressionType)(scope, argExpr), lastParameterType))),
|
|
404
|
-
];
|
|
405
|
-
return t.callExpression(callee, fnCallArguments);
|
|
406
|
-
}
|
|
407
|
-
return t.callExpression(callee, argumentExpressions.map((argExpr, index) => (0, coerceType_1.coerceType)(scope, argExpr, (0, coerceType_1.findExpressionType)(scope, argExpr), mapping.parameters[index].type)));
|
|
408
|
-
}
|
|
409
|
-
function convertIndexExpressionToTs(scope, node) {
|
|
410
|
-
const collectionExpressionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.collectionExpression);
|
|
411
|
-
const keyExpressionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.keyExpression);
|
|
412
|
-
const collectionExpression = convertTFExpressionAstToTs(scope, collectionExpressionChild);
|
|
413
|
-
const keyExpression = convertTFExpressionAstToTs(scope, keyExpressionChild);
|
|
414
|
-
scope.importables.push({
|
|
415
|
-
constructName: "Fn",
|
|
416
|
-
provider: "cdktn",
|
|
417
|
-
});
|
|
418
|
-
const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
|
|
419
|
-
return t.callExpression(callee, [
|
|
420
|
-
collectionExpression,
|
|
421
|
-
t.arrayExpression([keyExpression]),
|
|
422
|
-
]);
|
|
423
|
-
}
|
|
424
|
-
function convertSplatExpressionToTs(scope, node) {
|
|
425
|
-
const sourceExpressionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.sourceExpression);
|
|
426
|
-
const sourceExpression = convertTFExpressionAstToTs(scope, sourceExpressionChild);
|
|
427
|
-
// We don't convert the relative expression because everything after the splat is going to be
|
|
428
|
-
// a string
|
|
429
|
-
const relativeExpression = node.meta.eachExpression.startsWith(node.meta.anonSymbolExpression)
|
|
430
|
-
? node.meta.eachExpression.slice(node.meta.anonSymbolExpression.length)
|
|
431
|
-
: node.meta.eachExpression;
|
|
432
|
-
const segments = relativeExpression.split(/\.|\[|\]/).filter((s) => s);
|
|
433
|
-
scope.importables.push({
|
|
434
|
-
constructName: "Fn",
|
|
435
|
-
provider: "cdktn",
|
|
436
|
-
});
|
|
437
|
-
const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
|
|
438
|
-
return t.callExpression(callee, [
|
|
439
|
-
sourceExpression,
|
|
440
|
-
t.arrayExpression([
|
|
441
|
-
// we don't need to use the anonSymbolExpression here because
|
|
442
|
-
// it only changes between .* and [*] which we don't care about
|
|
443
|
-
t.stringLiteral("*"),
|
|
444
|
-
...segments.map(t.stringLiteral),
|
|
445
|
-
]),
|
|
446
|
-
]);
|
|
447
|
-
}
|
|
448
|
-
function convertConditionalExpressionToTs(scope, node) {
|
|
449
|
-
const conditionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.conditionExpression);
|
|
450
|
-
let condition = convertTFExpressionAstToTs(scope, conditionChild);
|
|
451
|
-
if (t.isIdentifier(condition) && canUseFqn(conditionChild)) {
|
|
452
|
-
// We have a resource or data source here, which we would need to
|
|
453
|
-
// reference using fqn
|
|
454
|
-
condition = t.memberExpression(condition, t.identifier("fqn"));
|
|
455
|
-
}
|
|
456
|
-
const trueExpression = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.trueExpression));
|
|
457
|
-
const falseExpression = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.falseExpression));
|
|
458
|
-
scope.importables.push({
|
|
459
|
-
constructName: "conditional",
|
|
460
|
-
provider: "cdktn",
|
|
461
|
-
});
|
|
462
|
-
return t.callExpression(t.identifier("conditional"), [
|
|
463
|
-
condition,
|
|
464
|
-
trueExpression,
|
|
465
|
-
falseExpression,
|
|
466
|
-
]);
|
|
467
|
-
}
|
|
468
|
-
function convertTupleExpressionToTs(scope, node) {
|
|
469
|
-
const expressions = node.children.map((child) => convertTFExpressionAstToTs(scope, child));
|
|
470
|
-
return t.arrayExpression(expressions);
|
|
471
|
-
}
|
|
472
|
-
function convertRelativeTraversalExpressionToTs(scope, node) {
|
|
473
|
-
const segments = node.meta.traversal;
|
|
474
|
-
// The left hand side / source of a relative traversal is not a proper
|
|
475
|
-
// object / resource / data thing that is being referenced
|
|
476
|
-
const source = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.sourceExpression));
|
|
477
|
-
scope.importables.push({
|
|
478
|
-
constructName: "Fn",
|
|
479
|
-
provider: "cdktn",
|
|
480
|
-
});
|
|
481
|
-
const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
|
|
482
|
-
return t.callExpression(callee, [
|
|
483
|
-
source,
|
|
484
|
-
t.arrayExpression(segments.map((s) => t.stringLiteral(s.segment))),
|
|
485
|
-
]);
|
|
486
|
-
}
|
|
487
|
-
function convertForExpressionToTs(scope, node) {
|
|
488
|
-
const collectionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.collectionExpression);
|
|
489
|
-
let collectionExpression = convertTFExpressionAstToTs(scope, collectionChild);
|
|
490
|
-
if (t.isIdentifier(collectionExpression) && canUseFqn(collectionChild)) {
|
|
491
|
-
// We have a resource or data source here, which we would need to
|
|
492
|
-
// reference using fqn
|
|
493
|
-
collectionExpression = t.memberExpression(collectionExpression, t.identifier("fqn"));
|
|
494
|
-
}
|
|
495
|
-
const collectionRequiresWrapping = !t.isStringLiteral(collectionExpression);
|
|
496
|
-
const expressions = [];
|
|
497
|
-
const conditionBody = node.meta.keyVar
|
|
498
|
-
? `${node.meta.keyVar}, ${node.meta.valVar}`
|
|
499
|
-
: node.meta.valVar;
|
|
500
|
-
const openBrace = node.meta.openRangeValue;
|
|
501
|
-
const closeBrace = node.meta.closeRangeValue;
|
|
502
|
-
const grouped = node.meta.groupedValue ? "..." : "";
|
|
503
|
-
const valueExpression = `${node.meta.valueExpression}${grouped}`;
|
|
504
|
-
const prefix = `\${${openBrace} for ${conditionBody} in `;
|
|
505
|
-
const keyValue = node.meta.keyExpression
|
|
506
|
-
? ` : ${node.meta.keyExpression} => ${valueExpression}`
|
|
507
|
-
: ` : ${valueExpression}`;
|
|
508
|
-
const conditional = node.meta.conditionalExpression;
|
|
509
|
-
const suffix = `${keyValue}${conditional ? ` if ${conditional}` : ""}${closeBrace}}`;
|
|
510
|
-
expressions.push(t.stringLiteral(prefix));
|
|
511
|
-
if (collectionRequiresWrapping) {
|
|
512
|
-
expressions.push(t.stringLiteral("${"));
|
|
513
|
-
}
|
|
514
|
-
expressions.push(collectionExpression);
|
|
515
|
-
if (collectionRequiresWrapping) {
|
|
516
|
-
expressions.push(t.stringLiteral("}"));
|
|
517
|
-
}
|
|
518
|
-
expressions.push(t.stringLiteral(suffix));
|
|
519
|
-
return expressionForSerialStringConcatenation(scope, expressions);
|
|
520
|
-
}
|
|
521
|
-
function convertTFExpressionAstToTs(scope, node) {
|
|
522
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isLiteralValueExpression(node)) {
|
|
523
|
-
return convertLiteralValueExpressionToTs(scope, node);
|
|
524
|
-
}
|
|
525
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(node)) {
|
|
526
|
-
return convertScopeTraversalExpressionToTs(scope, node);
|
|
527
|
-
}
|
|
528
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isUnaryOpExpression(node)) {
|
|
529
|
-
return convertUnaryOpExpressionToTs(scope, node);
|
|
530
|
-
}
|
|
531
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isBinaryOpExpression(node)) {
|
|
532
|
-
return convertBinaryOpExpressionToTs(scope, node);
|
|
533
|
-
}
|
|
534
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isTemplateExpression(node) || hcl2json_2.TFExpressionSyntaxTree.isTemplateWrapExpression(node)) {
|
|
535
|
-
return convertTemplateExpressionToTs(scope, node);
|
|
536
|
-
}
|
|
537
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isObjectExpression(node)) {
|
|
538
|
-
return convertObjectExpressionToTs(scope, node);
|
|
539
|
-
}
|
|
540
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isFunctionCallExpression(node)) {
|
|
541
|
-
return convertFunctionCallExpressionToTs(scope, node);
|
|
542
|
-
}
|
|
543
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isIndexExpression(node)) {
|
|
544
|
-
return convertIndexExpressionToTs(scope, node);
|
|
545
|
-
}
|
|
546
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isSplatExpression(node)) {
|
|
547
|
-
return convertSplatExpressionToTs(scope, node);
|
|
548
|
-
}
|
|
549
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isConditionalExpression(node)) {
|
|
550
|
-
return convertConditionalExpressionToTs(scope, node);
|
|
551
|
-
}
|
|
552
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isTupleExpression(node)) {
|
|
553
|
-
return convertTupleExpressionToTs(scope, node);
|
|
554
|
-
}
|
|
555
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isRelativeTraversalExpression(node)) {
|
|
556
|
-
return convertRelativeTraversalExpressionToTs(scope, node);
|
|
557
|
-
}
|
|
558
|
-
if (hcl2json_2.TFExpressionSyntaxTree.isForExpression(node)) {
|
|
559
|
-
return convertForExpressionToTs(scope, node);
|
|
560
|
-
}
|
|
561
|
-
return t.stringLiteral("");
|
|
562
|
-
}
|
|
563
|
-
async function expressionAst(input) {
|
|
564
|
-
const { wrap, wrapOffset } = (0, hcl2json_2.wrapTerraformExpression)(input);
|
|
565
|
-
const ast = await (0, hcl2json_1.getExpressionAst)("main.tf", wrap);
|
|
566
|
-
if (!ast) {
|
|
567
|
-
throw new Error(`Unable to parse terraform expression: ${input}`);
|
|
568
|
-
}
|
|
569
|
-
if (wrapOffset != 0 && hcl2json_2.TFExpressionSyntaxTree.isTemplateWrapExpression(ast)) {
|
|
570
|
-
return ast.children[0];
|
|
571
|
-
}
|
|
572
|
-
return ast;
|
|
573
|
-
}
|
|
574
|
-
exports.expressionAst = expressionAst;
|
|
575
|
-
async function convertTerraformExpressionToTs(scope, input, targetType) {
|
|
576
|
-
utils_1.logger.debug(`convertTerraformExpressionToTs(${input})`);
|
|
577
|
-
const tsExpression = convertTFExpressionAstToTs(scope, await expressionAst(input));
|
|
578
|
-
return (0, coerceType_1.coerceType)(scope, tsExpression, (0, coerceType_1.findExpressionType)(scope, tsExpression), targetType());
|
|
579
|
-
}
|
|
580
|
-
exports.convertTerraformExpressionToTs = convertTerraformExpressionToTs;
|
|
581
|
-
async function extractIteratorVariablesFromExpression(input) {
|
|
582
|
-
const possibleVariableSpots = await (0, hcl2json_1.getReferencesInExpression)("main.tf", input);
|
|
583
|
-
return possibleVariableSpots
|
|
584
|
-
.filter((spot) => spot.value.startsWith("each."))
|
|
585
|
-
.map((spot) => ({
|
|
586
|
-
start: spot.startPosition,
|
|
587
|
-
end: spot.endPosition,
|
|
588
|
-
value: spot.value,
|
|
589
|
-
}));
|
|
590
|
-
}
|
|
591
|
-
exports.extractIteratorVariablesFromExpression = extractIteratorVariablesFromExpression;
|
|
592
|
-
function dynamicVariableToAst(scope, node, iteratorName, block = "each") {
|
|
593
|
-
if (iteratorName === "dynamic-block") {
|
|
594
|
-
return expressionForSerialStringConcatenation(scope, [
|
|
595
|
-
t.stringLiteral("${"),
|
|
596
|
-
t.stringLiteral(block),
|
|
597
|
-
t.stringLiteral("}"),
|
|
598
|
-
]);
|
|
599
|
-
}
|
|
600
|
-
if (node.meta.value === `${block}.key`) {
|
|
601
|
-
return t.memberExpression(t.identifier(iteratorName), t.identifier("key"));
|
|
602
|
-
}
|
|
603
|
-
if (node.meta.value === `${block}.value`) {
|
|
604
|
-
return t.memberExpression(t.identifier(iteratorName), t.identifier("value"));
|
|
605
|
-
}
|
|
606
|
-
if (block === "count" && node.meta.value === `${block}.index`) {
|
|
607
|
-
return t.memberExpression(t.identifier(iteratorName), t.identifier("index"));
|
|
608
|
-
}
|
|
609
|
-
const segments = node.meta.traversal;
|
|
610
|
-
if (segments.length > 2 &&
|
|
611
|
-
segments[0].segment === block &&
|
|
612
|
-
segments[1].segment === "value") {
|
|
613
|
-
const segmentsAfterEachValue = segments.slice(2);
|
|
614
|
-
scope.importables.push({
|
|
615
|
-
constructName: "Fn",
|
|
616
|
-
provider: "cdktn",
|
|
617
|
-
});
|
|
618
|
-
const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
|
|
619
|
-
return t.callExpression(callee, [
|
|
620
|
-
t.memberExpression(t.identifier(iteratorName), t.identifier("value")),
|
|
621
|
-
t.arrayExpression(segmentsAfterEachValue.map((part) => {
|
|
622
|
-
if (part.type === "nameTraversal") {
|
|
623
|
-
return t.stringLiteral(part.segment);
|
|
624
|
-
}
|
|
625
|
-
else {
|
|
626
|
-
return t.stringLiteral(`[${part.segment}]`);
|
|
627
|
-
}
|
|
628
|
-
})),
|
|
629
|
-
]);
|
|
630
|
-
}
|
|
631
|
-
throw new Error(`Can not create AST for iterator variable of '${node.meta.value}'`);
|
|
632
|
-
}
|
|
633
|
-
exports.dynamicVariableToAst = dynamicVariableToAst;
|
|
634
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzc2lvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJleHByZXNzaW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtCQUErQjtBQUMvQixtQ0FBbUM7QUFDbkMsZ0RBQWtDO0FBQ2xDLCtEQUF1QztBQUN2QyxtQ0FBOEQ7QUFNOUQsOENBQThFO0FBQzlFLDhDQUd5QjtBQUN6Qiw2REFBNkQ7QUFDN0QsNkNBQThEO0FBRTlELHVEQUFrRDtBQUNsRCw2Q0FBaUQ7QUFDakQsMkNBQTJDO0FBQzNDLGlFQUFvRTtBQUVwRSxNQUFNLHdCQUF3QixHQUFHO0lBQy9CLFNBQVMsRUFBRSxJQUFJO0lBQ2YsVUFBVSxFQUFFLEtBQUs7SUFDakIsV0FBVyxFQUFFLElBQUk7SUFDakIsa0JBQWtCLEVBQUUsS0FBSztJQUN6QixRQUFRLEVBQUUsSUFBSTtJQUNkLGVBQWUsRUFBRSxLQUFLO0lBQ3RCLEtBQUssRUFBRSxJQUFJO0lBQ1gsUUFBUSxFQUFFLEtBQUs7SUFDZixHQUFHLEVBQUUsS0FBSztJQUNWLFFBQVEsRUFBRSxLQUFLO0lBQ2YsUUFBUSxFQUFFLEtBQUs7SUFDZixNQUFNLEVBQUUsS0FBSztJQUNiLE1BQU0sRUFBRSxLQUFLO0NBQ2QsQ0FBQztBQUVGLE1BQU0sdUJBQXVCLEdBQUc7SUFDOUIsVUFBVSxFQUFFLEtBQUs7SUFDakIsTUFBTSxFQUFFLFFBQVE7Q0FDakIsQ0FBQztBQUtGLFNBQVMsc0JBQXNCLENBQzdCLFVBQXdDLEVBQ3hDLFFBQVEsR0FBRyxLQUFLO0lBRWhCLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNkLElBQUksUUFBUSxJQUFJLGlDQUFHLENBQUMsbUJBQW1CLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN2RCxJQUFJLEdBQUcsR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDLE1BQU0sQ0FB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cUJBQU0sQ0FBQztvQkFDTixPQUFPLENBQUMsQ0FBQyxhQUFhLENBQUMsSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztnQkFDOUMsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUNIO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELE1BQU0sSUFBSSxLQUFLLENBQ2IsZ0RBQWdELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQ25FLENBQUM7QUFDSixDQUFDO0FBL0RELG9EQStEQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgSGFzaGlDb3JwLCBJbmNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNUEwtMi4wXG5pbXBvcnQgKiBhcyB0IGZyb20gXCJAYmFiZWwvdHlwZXNcIjtcbmltcG9ydCB0ZW1wbGF0ZSBmcm9tIFwiQGJhYmVsL3RlbXBsYXRlXCI7XG5pbXBvcnQgeyBjYW1lbENhc2UsIGxlYXZlQ29tbWVudFRleHQsIGxvZ2dlciB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQge1xuICBJdGVyYXRvclZhcmlhYmxlUmVmZXJlbmNlLFxuICBQcm9ncmFtU2NvcGUsXG4gIFJlc291cmNlU2NvcGUsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRSZWZlcmVuY2VzSW5FeHByZXNzaW9uLCBnZXRFeHByZXNzaW9uQXN0IH0gZnJvbSBcIkBjZGt0bi9oY2wyanNvblwiO1xuaW1wb3J0IHtcbiAgVEZFeHByZXNzaW9uU3ludGF4VHJlZSBhcyB0ZXgsXG4gIHdyYXBUZXJyYWZvcm1FeHByZXNzaW9uLFxufSBmcm9tIFwiQGNka3RuL2hjbDJqc29uXCI7XG5pbXBvcnQgeyBmdW5jdGlvbnNNYXAgfSBmcm9tIFwiLi9mdW5jdGlvbi1iaW5kaW5ncy9mdW5jdGlvbnNcIjtcbmltcG9ydCB7IGNvZXJjZVR5cGUsIGZpbmRFeHByZXNzaW9uVHlwZSB9IGZyb20gXCIuL2NvZXJjZVR5cGVcIjtcbmltcG9ydCB7IEF0dHJpYnV0ZVR5cGUgfSBmcm9tIFwiQGNka3RuL2NvbW1vbnNcIjtcbmltcG9ydCB7IGdldFR5cGVBdFBhdGggfSBmcm9tIFwiLi90ZXJyYWZvcm1TY2hlbWFcIjtcbmltcG9ydCB7IGNvbnRhaW5zUmVmZXJlbmNlIH0gZnJvbSBcIi4vcmVmZXJlbmNlc1wiO1xuaW1wb3J0IHsgdmFyaWFibGVOYW1lIH0gZnJvbSBcIi4vdmFyaWFibGVzXCI7XG5pbXBvcnQgeyBnZXRDaGlsZFdpdGhWYWx1ZSB9IGZyb20gXCJAY2RrdG4vaGNsMmpzb24vbGliL3N5bnRheC10cmVlXCI7XG5cbmNvbnN0IHRmQmluYXJ5T3BlcmF0b3JzVG9DZGt0ZiA9IHtcbiAgbG9naWNhbE9yOiBcIm9yXCIsXG4gIGxvZ2ljYWxBbmQ6IFwiYW5kXCIsXG4gIGdyZWF0ZXJUaGFuOiBcImd0XCIsXG4gIGdyZWF0ZXJUaGFuT3JFcXVhbDogXCJndGVcIixcbiAgbGVzc1RoYW46IFwibHRcIixcbiAgbGVzc1RoYW5PckVxdWFsOiBcImx0ZVwiLFxuICBlcXVhbDogXCJlcVwiLFxuICBub3RFcXVhbDogXCJuZXFcIixcbiAgYWRkOiBcImFkZFwiLFxuICBzdWJ0cmFjdDogXCJzdWJcIixcbiAgbXVsdGlwbHk6IFwibXVsXCIsXG4gIGRpdmlkZTogXCJkaXZcIixcbiAgbW9kdWxvOiBcIm1vZFwiLFxufTtcblxuY29uc3QgdGZVbmFyeU9wZXJhdG9yc1RvQ2RrdGYgPSB7XG4gIGxvZ2ljYWxOb3Q6IFwibm90XCIsXG4gIG5lZ2F0ZTogXCJuZWdhdGVcIixcbn07XG5cbnR5cGUgc3VwcG9ydGVkQmluYXJ5T3BlcmF0b3JzID0ga2V5b2YgdHlwZW9mIHRmQmluYXJ5T3BlcmF0b3JzVG9DZGt0ZjtcbnR5cGUgc3VwcG9ydGVkVW5hcnlPcGVyYXRvcnMgPSBrZXlvZiB0eXBlb2YgdGZVbmFyeU9wZXJhdG9yc1RvQ2RrdGY7XG5cbmZ1bmN0aW9uIHRyYXZlcnNhbFBhcnRzVG9TdHJpbmcoXG4gIHRyYXZlcnNhbHM6IHRleC5UZXJyYWZvcm1UcmF2ZXJzYWxQYXJ0W10sXG4gIGFzU3VmZml4ID0gZmFsc2UsXG4pIHtcbiAgbGV0IHNlZWQgPSBcIlwiO1xuICBpZiAoYXNTdWZmaXggJiYgdGV4LmlzTmFtZVRyYXZlcnNhbFBhcnQodHJhdmVyc2Fsc1swXSkpIHtcbiAgICBzZWVkID0gXCIuXCI7XG4gIH1cbiAgcmV0dXJuIHRyYXZlcnNhbHMucmVkdWNlKChhY2MsIHBhcnQpID0+IHtcbiAgICBpZiAocGFydC50eXBlID09PSBcIm5hbWVUcmF2ZXJzYWxcIikge1xuICAgICAgaWYgKGFjYyA9PT0gc2VlZCkge1xuICAgICAgICByZXR1cm4gYCR7YWNjfSR7cGFydC5zZWdtZW50fWA7XG4gICAgICB9XG4gICAgICByZXR1cm4gYCR7YWNjfS4ke3BhcnQuc2VnbWVudH1gO1xuICAgIH1cbiAgICByZXR1cm4gYCR7YWNjfVske3BhcnQuc2VnbWVudH1dYDtcbiAgfSwgc2VlZCk7XG59XG5cbmZ1bmN0aW9uIGNhblVzZUZxbihleHByZXNzaW9uOiB0ZXguRXhwcmVzc2lvblR5cGUpIHtcbiAgaWYgKCF0ZXguaXNTY29wZVRyYXZlcnNhbEV4cHJlc3Npb24oZXhwcmVzc2lvbikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCByb290U2VnbWVudCA9IGV4cHJlc3Npb24ubWV0YS50cmF2ZXJzYWxbMF0uc2VnbWVudDtcblxuICByZXR1cm4gIVtcInZhclwiLCBcImxvY2FsXCJdLmluY2x1ZGVzKHJvb3RTZWdtZW50KTtcbn1cblxuZnVuY3Rpb24gdHJhdmVyc2FsVG9WYXJpYWJsZU5hbWUoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIG5vZGU6IHRleC5FeHByZXNzaW9uVHlwZSxcbikge1xuICBpZiAoIXRleC5pc1Njb3BlVHJhdmVyc2FsRXhwcmVzc2lvbihub2RlKSkge1xuICAgIGxvZ2dlci5lcnJvcihcbiAgICAgIGBVbmV4cGVjdGVkIGV4cHJlc3Npb24gdHlwZSAke25vZGUudHlwZX0gd2l0aCB2YWx1ZSAke25vZGUubWV0YS52YWx1ZX0gcGFzc2VkIHRvIGNvbnZlcnQgdG8gYSB2YXJpYWJsZS4gXG4gICAgICAgICR7bGVhdmVDb21tZW50VGV4dH1gLFxuICAgICk7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cblxuICBjb25zdCBzZWdtZW50cyA9IG5vZGUubWV0YS50cmF2ZXJzYWw7XG4gIGlmIChzZWdtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gbm9kZS5tZXRhLmZ1bGxBY2Nlc3NvcjtcbiAgfVxuICBjb25zdCByb290U2VnbWVudCA9IHNlZ21lbnRzWzBdLnNlZ21lbnQ7XG4gIGNvbnN0IHJlc291cmNlID1cbiAgICByb290U2VnbWVudCA9PT0gXCJkYXRhXCJcbiAgICAgID8gYCR7c2VnbWVudHNbMF0uc2VnbWVudH0uJHtzZWdtZW50c1sxXS5zZWdtZW50fWBcbiAgICAgIDogcm9vdFNlZ21lbnQ7XG4gIGNvbnN0IG5hbWUgPVxuICAgIHJvb3RTZWdtZW50ID09PSBcImRhdGFcIiA/IHNlZ21lbnRzWzJdLnNlZ21lbnQgOiBzZWdtZW50c1sxXS5zZWdtZW50O1xuXG4gIHJldHVybiB2YXJpYWJsZU5hbWUoc2NvcGUsIHJlc291cmNlLCBuYW1lKTtcbn1cblxuZnVuY3Rpb24gZXhwcmVzc2lvbkZvclNlcmlhbFN0cmluZ0NvbmNhdGVuYXRpb24oXG4gIHNjb3BlOiBSZXNvdXJjZVNjb3BlLFxuICBub2RlczogdC5FeHByZXNzaW9uW10sXG4pIHtcbiAgY29uc3QgcmVkdWNlZE5vZGVzID0gbm9kZXMucmVkdWNlKChhY2MsIG5vZGUpID0+IHtcbiAgICBjb25zdCBwcmV2ID0gYWNjW2FjYy5sZW5ndGggLSAxXTtcbiAgICBpZiAoIXByZXYpIHJldHVybiBbbm9kZV07XG5cbiAgICBpZiAodC5pc1N0cmluZ0xpdGVyYWwocHJldikgJiYgdC5pc1N0cmluZ0xpdGVyYWwobm9kZSkpIHtcbiAgICAgIGFjYy5wb3AoKTtcbiAgICAgIGFjYy5wdXNoKHQuc3RyaW5nTGl0ZXJhbChwcmV2LnZhbHVlICsgbm9kZS52YWx1ZSkpO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9XG5cbiAgICBhY2MucHVzaChub2RlKTtcbiAgICByZXR1cm4gYWNjO1xuICB9LCBbXSBhcyB0LkV4cHJlc3Npb25bXSk7XG5cbiAgcmV0dXJuIHJlZHVjZWROb2Rlcy5yZWR1Y2UoXG4gICAgKGFjYzogdC5FeHByZXNzaW9uIHwgdW5kZWZpbmVkLCBub2RlOiB0LkV4cHJlc3Npb24pID0+IHtcbiAgICAgIGlmICghYWNjKSB7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgICAgfVxuXG4gICAgICAvLyB3cmFwIGFjY2VzcyB0byBkeW5hbWljIGJsb2NrcyBpbiBUb2tlbi5hc1N0cmluZygpIGFzIHRoZXkgcmV0dXJuIGEgTGF6eVxuICAgICAgLy8gZm9yIC5rZXkgYW5kIC52YWx1ZSB3aGljaCBjYW4ndCBiZSBjb25jYXRlbmF0ZWQgaW4gbGFuZ3VhZ2VzIGxpa2UgUHl0aG9uXG4gICAgICAvLyBiZWNhdXNlIEpTSUkgY3VycmVudGx5IGhhcyBubyBzdXBwb3J0IGZvciB0aGUgdG9TdHJpbmcoKSBtZXRob2QgaW5cbiAgICAgIC8vIGxhbmd1YWdlcyBvdGhlciB0aGFuIFR5cGVTY3JpcHQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvanNpaS9pc3N1ZXMvMzgwXG4gICAgICAvLyBleGFtcGxlOiBkeW5hbWljX2l0ZXJhdG9yMC5rZXkgLyBkeW5hbWljX2l0ZXJhdG9yMC52YWx1ZVxuICAgICAgaWYgKFxuICAgICAgICB0LmlzTWVtYmVyRXhwcmVzc2lvbihub2RlKSAmJlxuICAgICAgICB0LmlzSWRlbnRpZmllcihub2RlLm9iamVjdCkgJiZcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhzY29wZS5zY29wZWRWYXJpYWJsZXMgfHwge30pLmluY2x1ZGVzKG5vZGUub2JqZWN0Lm5hbWUpICYmXG4gICAgICAgIHQuaXNJZGVudGlmaWVyKG5vZGUucHJvcGVydHkpICYmXG4gICAgICAgIFtcImtleVwiLCBcInZhbHVlXCJdLmluY2x1ZGVzKG5vZGUucHJvcGVydHkubmFtZSlcbiAgICAgICkge1xuICAgICAgICBub2RlID0gY29lcmNlVHlwZShzY29wZSwgbm9kZSwgXCJkeW5hbWljXCIsIFwic3RyaW5nXCIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdC5iaW5hcnlFeHByZXNzaW9uKFwiK1wiLCBhY2MgYXMgdC5FeHByZXNzaW9uLCBub2RlKTtcbiAgICB9LFxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRUZlJlc291cmNlUGF0aEZyb21Ob2RlKG5vZGU6IHRleC5TY29wZVRyYXZlcnNhbEV4cHJlc3Npb24pIHtcbiAgY29uc3Qgc2VnbWVudHMgPSBub2RlLm1ldGEudHJhdmVyc2FsO1xuICBsZXQgcmVzb3VyY2UgPSBzZWdtZW50c1swXS5zZWdtZW50O1xuICBsZXQgcmVzdWx0ID0gW107XG4gIGxldCBhdHRyaWJ1dGVzID0gW107XG5cbiAgaWYgKHNlZ21lbnRzWzBdLnNlZ21lbnQgPT09IFwiZGF0YVwiKSB7XG4gICAgcmVzdWx0LnB1c2goc2VnbWVudHNbMF0uc2VnbWVudCk7XG4gICAgcmVzb3VyY2UgPSBzZWdtZW50c1sxXS5zZWdtZW50O1xuICAgIGF0dHJpYnV0ZXMgPSBzZWdtZW50cy5zbGljZSgzKTsgLy8gd2Ugd2FudCB0byBza2lwIHRoZSB2YXJpYWJsZSBuYW1lXG4gIH0gZWxzZSB7XG4gICAgYXR0cmlidXRlcyA9IHNlZ21lbnRzLnNsaWNlKDIpOyAvLyB3ZSB3YW50IHRvIHNraXAgdGhlIHZhcmlhYmxlIG5hbWVcbiAgfVxuXG4gIGNvbnN0IFtwcm92aWRlciwgLi4ucmVzb3VyY2VOYW1lRnJhZ21lbnRzXSA9IHJlc291cmNlLnNwbGl0KFwiX1wiKTtcblxuICAvLyBIYWNrOiBUaGlzIGhhcHBlbnMgaW4gdGhlIGNhc2Ugb2YgYGV4dGVybmFsYCBwcm92aWRlclxuICAvLyB3aGVyZSB0aGUgZGF0YSBzb3VyY2UgZG9lcyBub3QgaGF2ZSBhIHByb3ZpZGVyIG5hbWUgcHJlZml4XG4gIGlmIChyZXNvdXJjZU5hbWVGcmFnbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgcmVzb3VyY2VOYW1lRnJhZ21lbnRzLnB1c2gocHJvdmlkZXIpO1xuICB9XG5cbiAgcmVzdWx0LnB1c2gocHJvdmlkZXIpO1xuICByZXN1bHQucHVzaChyZXNvdXJjZU5hbWVGcmFnbWVudHMuam9pbihcIl9cIikpO1xuICByZXN1bHQgPSBbXG4gICAgLi4ucmVzdWx0LFxuICAgIC4uLmF0dHJpYnV0ZXMubWFwKChzZWcpID0+IHtcbiAgICAgIGlmICh0ZXguaXNJbmRleFRyYXZlcnNhbFBhcnQoc2VnKSkge1xuICAgICAgICByZXR1cm4gYFske3NlZy5zZWdtZW50fV1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNlZy5zZWdtZW50O1xuICAgIH0pLFxuICBdO1xuXG4gIHJldHVybiByZXN1bHQuam9pbihcIi5cIik7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRMaXRlcmFsVmFsdWVFeHByZXNzaW9uVG9UcyhcbiAgX3Njb3BlOiBSZXNvdXJjZVNjb3BlLFxuICBub2RlOiB0ZXguTGl0ZXJhbFZhbHVlRXhwcmVzc2lvbixcbikge1xuICBjb25zdCBsaXRlcmFsVHlwZSA9IG5vZGUubWV0YS50eXBlO1xuICBpZiAobGl0ZXJhbFR5cGUgPT09IFwibnVtYmVyXCIpIHtcbiAgICByZXR1cm4gdC5udW1lcmljTGl0ZXJhbChOdW1iZXIobm9kZS5tZXRhLnZhbHVlKSk7XG4gIH1cbiAgaWYgKGxpdGVyYWxUeXBlID09PSBcImJvb2xcIikge1xuICAgIHJldHVybiB0LmJvb2xlYW5MaXRlcmFsKG5vZGUubWV0YS52YWx1ZSA9PT0gXCJ0cnVlXCIgPyB0cnVlIDogZmFsc2UpO1xuICB9XG5cbiAgcmV0dXJuIHQuc3RyaW5nTGl0ZXJhbChub2RlLm1ldGEudmFsdWUpO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0U2NvcGVUcmF2ZXJzYWxFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5TY29wZVRyYXZlcnNhbEV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3QgaGFzUmVmZXJlbmNlID0gY29udGFpbnNSZWZlcmVuY2Uobm9kZSk7XG5cbiAgY29uc3Qgc2VnbWVudHMgPSBub2RlLm1ldGEudHJhdmVyc2FsO1xuXG4gIGlmIChzZWdtZW50c1swXS5zZWdtZW50ID09PSBcImVhY2hcIiAmJiBzY29wZS5mb3JFYWNoSXRlcmF0b3JOYW1lKSB7XG4gICAgcmV0dXJuIGR5bmFtaWNWYXJpYWJsZVRvQXN0KHNjb3BlLCBub2RlLCBzY29wZS5mb3JFYWNoSXRlcmF0b3JOYW1lKTtcbiAgfVxuXG4gIGlmIChzZWdtZW50c1swXS5zZWdtZW50ID09PSBcImNvdW50XCIgJiYgc2NvcGUuY291bnRJdGVyYXRvck5hbWUpIHtcbiAgICByZXR1cm4gZHluYW1pY1ZhcmlhYmxlVG9Bc3Qoc2NvcGUsIG5vZGUsIHNjb3BlLmNvdW50SXRlcmF0b3JOYW1lLCBcImNvdW50XCIpO1xuICB9XG5cbiAgaWYgKHNlZ21lbnRzWzBdLnNlZ21lbnQgPT09IFwic2VsZlwiKSB7XG4gICAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgICBjb25zdHJ1Y3ROYW1lOiBcIlRlcnJhZm9ybVNlbGZcIixcbiAgICAgIHByb3ZpZGVyOiBcImNka3RuXCIsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdC5jYWxsRXhwcmVzc2lvbihcbiAgICAgIHQubWVtYmVyRXhwcmVzc2lvbih0LmlkZW50aWZpZXIoXCJUZXJyYWZvcm1TZWxmXCIpLCB0LmlkZW50aWZpZXIoXCJnZXRBbnlcIikpLFxuXG4gICAgICBbdC5zdHJpbmdMaXRlcmFsKHRyYXZlcnNhbFBhcnRzVG9TdHJpbmcoc2VnbWVudHMuc2xpY2UoMSkpKV0sXG4gICAgKTtcbiAgfVxuXG4gIC8vIHNldHRpbmcudmFsdWUsIHNldHRpbmcudmFsdWVbMV0uaWRcbiAgY29uc3QgZHluYW1pY0Jsb2NrID0gc2NvcGUuc2NvcGVkVmFyaWFibGVzPy5bc2VnbWVudHNbMF0uc2VnbWVudF07XG4gIGlmIChkeW5hbWljQmxvY2spIHtcbiAgICBpZiAoZHluYW1pY0Jsb2NrID09PSBcImR5bmFtaWMtYmxvY2tcIikge1xuICAgICAgcmV0dXJuIGR5bmFtaWNWYXJpYWJsZVRvQXN0KFxuICAgICAgICBzY29wZSxcbiAgICAgICAgbm9kZSxcbiAgICAgICAgZHluYW1pY0Jsb2NrLFxuICAgICAgICB0cmF2ZXJzYWxQYXJ0c1RvU3RyaW5nKHNlZ21lbnRzKSxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBkeW5hbWljVmFyaWFibGVUb0FzdChzY29wZSwgbm9kZSwgZHluYW1pY0Jsb2NrLCBzZWdtZW50c1swXS5zZWdtZW50KTtcbiAgfVxuXG4gIC8vIFRoaXMgbWF5IGJlIGEgdmFyaWFibGUgcmVmZXJlbmNlIHRoYXQgd2UgZG9uJ3QgdW5kZXJzdGFuZCB5ZXQsIHNvIHdlIHdyYXAgaXQgaW4gYSB0ZW1wbGF0ZSBzdHJpbmdcbiAgLy8gZm9yIFRlcnJhZm9ybSB0byBoYW5kbGVcbiAgbGV0IHZhcklkZW50aWZpZXI6IHQuRXhwcmVzc2lvbiA9IHQuc3RyaW5nTGl0ZXJhbChcbiAgICBgXFwkeyR7bm9kZS5tZXRhLmZ1bGxBY2Nlc3Nvcn19YCxcbiAgKTtcblxuICBpZiAoaGFzUmVmZXJlbmNlKSB7XG4gICAgdmFySWRlbnRpZmllciA9IHQuaWRlbnRpZmllcihcbiAgICAgIGNhbWVsQ2FzZSh0cmF2ZXJzYWxUb1ZhcmlhYmxlTmFtZShzY29wZSwgbm9kZSkpLFxuICAgICk7XG4gIH1cblxuICBpZiAoW1widmFyXCIsIFwibG9jYWxcIl0uaW5jbHVkZXMoc2VnbWVudHNbMF0uc2VnbWVudCkpIHtcbiAgICBjb25zdCB2YXJpYWJsZUFjY2Vzc29yID1cbiAgICAgIHNlZ21lbnRzWzBdLnNlZ21lbnQgPT09IFwidmFyXCJcbiAgICAgICAgPyB0Lm1lbWJlckV4cHJlc3Npb24odmFySWRlbnRpZmllciwgdC5pZGVudGlmaWVyKFwidmFsdWVcIikpXG4gICAgICAgIDogdmFySWRlbnRpZmllcjtcblxuICAgIGlmIChzZWdtZW50cy5sZW5ndGggPiAyKSB7XG4gICAgICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICAgICAgY29uc3RydWN0TmFtZTogXCJGblwiLFxuICAgICAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBjYWxsZWUgPSB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICAgIHQuaWRlbnRpZmllcihcIkZuXCIpLFxuICAgICAgICB0LmlkZW50aWZpZXIoXCJsb29rdXBOZXN0ZWRcIiksXG4gICAgICApO1xuICAgICAgcmV0dXJuIHQuY2FsbEV4cHJlc3Npb24oY2FsbGVlLCBbXG4gICAgICAgIHZhcmlhYmxlQWNjZXNzb3IsXG4gICAgICAgIHQuYXJyYXlFeHByZXNzaW9uKFxuICAgICAgICAgIHNlZ21lbnRzLnNsaWNlKDIpLm1hcCgocykgPT4gdC5zdHJpbmdMaXRlcmFsKHMuc2VnbWVudCkpLFxuICAgICAgICApLFxuICAgICAgXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhcmlhYmxlQWNjZXNzb3I7XG4gIH1cblxuICBpZiAoIWhhc1JlZmVyZW5jZSB8fCBzY29wZS53aXRoaW5PdmVycmlkZUV4cHJlc3Npb24pIHtcbiAgICByZXR1cm4gdmFySWRlbnRpZmllcjtcbiAgfVxuXG4gIGNvbnN0IHJvb3RTZWdtZW50ID0gc2VnbWVudHNbMF0uc2VnbWVudDtcbiAgY29uc3QgYXR0cmlidXRlSW5kZXggPSByb290U2VnbWVudCA9PT0gXCJkYXRhXCIgPyAzIDogMjtcbiAgY29uc3QgYXR0cmlidXRlU2VnbWVudHMgPSBzZWdtZW50cy5zbGljZShhdHRyaWJ1dGVJbmRleCk7XG4gIGNvbnN0IG51bWVyaWNBY2Nlc3NvckluZGV4ID0gYXR0cmlidXRlU2VnbWVudHMuZmluZEluZGV4KChzZWcpID0+XG4gICAgdGV4LmlzSW5kZXhUcmF2ZXJzYWxQYXJ0KHNlZyksXG4gICk7XG4gIGxldCBtaW5BY2Nlc3NvckluZGV4ID0gbnVtZXJpY0FjY2Vzc29ySW5kZXg7XG4gIGxldCBtYXBBY2Nlc3NvckluZGV4ID0gLTE7XG4gIGlmIChudW1lcmljQWNjZXNzb3JJbmRleCA9PT0gLTEpIHtcbiAgICAvLyBvbmx5IGRvIHRoaXMgaWYgd2UgaGF2ZSB0bywgaWYgd2UgYWxyZWFkeSBoYXZlIGFcbiAgICAvLyBudW1lcmljIGFjY2Vzc29yLCB3ZSBkb24ndCBoYXZlIHRvIGRvIHRoaXMgYWRkaXRpb25hbCB3b3JrXG4gICAgY29uc3QgcmVzb3VyY2VQYXRoID0gZ2V0VGZSZXNvdXJjZVBhdGhGcm9tTm9kZShub2RlKTtcbiAgICBsZXQgdXNpbmdTdWJQYXRoVHlwZSA9IGZhbHNlO1xuICAgIGNvbnN0IHBhcnRzID0gcmVzb3VyY2VQYXRoLnNwbGl0KFwiLlwiKS5maWx0ZXIoKHApID0+IHAgIT09IFwiXCIpO1xuICAgIGNvbnN0IG1pblBhcnRzID0gYXR0cmlidXRlSW5kZXg7IC8vIHdlIG5lZWQgdG8gc3RvcCBiZWZvcmUgZGF0YS5hd3MucmVzb3VyY2VfbmFtZSBvciBhd3MucmVzb3VyY2VfbmFtZVxuICAgIGNvbnN0IG9yaWdpbmFsUGFydHMgPSBwYXJ0cy5sZW5ndGg7XG4gICAgbGV0IGhhc01hcEFjY2Vzc29yID0gZmFsc2U7XG4gICAgd2hpbGUgKHBhcnRzLmxlbmd0aCA+PSBtaW5QYXJ0cykge1xuICAgICAgY29uc3QgdHlwZSA9IGdldFR5cGVBdFBhdGgoc2NvcGUucHJvdmlkZXJTY2hlbWEsIHBhcnRzLmpvaW4oXCIuXCIpKTtcbiAgICAgIGlmICh0eXBlICE9PSBudWxsKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHR5cGUpICYmIHR5cGVbMF0gPT09IFwibWFwXCIgJiYgdXNpbmdTdWJQYXRoVHlwZSkge1xuICAgICAgICAgIGhhc01hcEFjY2Vzc29yID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcGFydHMucG9wKCk7XG4gICAgICB1c2luZ1N1YlBhdGhUeXBlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoaGFzTWFwQWNjZXNzb3IpIHtcbiAgICAgIG1hcEFjY2Vzc29ySW5kZXggPSBvcmlnaW5hbFBhcnRzIC0gcGFydHMubGVuZ3RoIC0gMTtcbiAgICAgIG1pbkFjY2Vzc29ySW5kZXggPSBtYXBBY2Nlc3NvckluZGV4O1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG5lZWRzUHJvcGVydHlBY2Nlc3MgPSBtaW5BY2Nlc3NvckluZGV4ID49IDA7XG5cbiAgY29uc3QgcmVmU2VnbWVudHMgPSBuZWVkc1Byb3BlcnR5QWNjZXNzXG4gICAgPyBhdHRyaWJ1dGVTZWdtZW50cy5zbGljZSgwLCBtaW5BY2Nlc3NvckluZGV4KVxuICAgIDogYXR0cmlidXRlU2VnbWVudHM7XG4gIGNvbnN0IG5vblJlZlNlZ21lbnRzID0gbmVlZHNQcm9wZXJ0eUFjY2Vzc1xuICAgID8gYXR0cmlidXRlU2VnbWVudHMuc2xpY2UobWluQWNjZXNzb3JJbmRleClcbiAgICA6IFtdO1xuXG4gIGNvbnN0IHJlZiA9IHJlZlNlZ21lbnRzLnJlZHVjZShcbiAgICAoYWNjOiB0LkV4cHJlc3Npb24sIHNlZywgaW5kZXgpID0+XG4gICAgICB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICAgIGFjYyxcbiAgICAgICAgdC5pZGVudGlmaWVyKFxuICAgICAgICAgIGluZGV4ID09PSAwICYmIHJvb3RTZWdtZW50ID09PSBcIm1vZHVsZVwiXG4gICAgICAgICAgICA/IGNhbWVsQ2FzZShzZWcuc2VnbWVudCArIFwiT3V0cHV0XCIpXG4gICAgICAgICAgICA6IGNhbWVsQ2FzZShzZWcuc2VnbWVudCksXG4gICAgICAgICksXG4gICAgICApLFxuICAgIHZhcklkZW50aWZpZXIsXG4gICk7XG5cbiAgaWYgKG5vblJlZlNlZ21lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiByZWY7XG4gIH1cblxuICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICBjb25zdHJ1Y3ROYW1lOiBcIkZuXCIsXG4gICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgfSk7XG4gIGNvbnN0IGNhbGxlZSA9IHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICB0LmlkZW50aWZpZXIoXCJGblwiKSxcbiAgICB0LmlkZW50aWZpZXIoXCJsb29rdXBOZXN0ZWRcIiksXG4gICk7XG4gIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKGNhbGxlZSwgW1xuICAgIHJlZixcbiAgICB0LmFycmF5RXhwcmVzc2lvbihub25SZWZTZWdtZW50cy5tYXAoKHMpID0+IHQuc3RyaW5nTGl0ZXJhbChzLnNlZ21lbnQpKSksXG4gIF0pO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0VW5hcnlPcEV4cHJlc3Npb25Ub1RzKFxuICBzY29wZTogUmVzb3VyY2VTY29wZSxcbiAgbm9kZTogdGV4LlVuYXJ5T3BFeHByZXNzaW9uLFxuKSB7XG4gIGNvbnN0IG9wZXJhbmQgPSBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhcbiAgICBzY29wZSxcbiAgICB0ZXguZ2V0Q2hpbGRXaXRoVmFsdWUobm9kZSwgbm9kZS5tZXRhLnZhbHVlRXhwcmVzc2lvbikhLFxuICApO1xuXG4gIGxldCBmbk5hbWUgPSBub2RlLm1ldGEub3BlcmF0b3I7XG4gIGlmICh0ZlVuYXJ5T3BlcmF0b3JzVG9DZGt0Zltmbk5hbWUgYXMgc3VwcG9ydGVkVW5hcnlPcGVyYXRvcnNdKSB7XG4gICAgZm5OYW1lID0gdGZVbmFyeU9wZXJhdG9yc1RvQ2RrdGZbZm5OYW1lIGFzIHN1cHBvcnRlZFVuYXJ5T3BlcmF0b3JzXTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb252ZXJ0IHVua25vd24gb3BlcmF0b3IgJHtub2RlLm1ldGEub3BlcmF0b3J9YCk7XG4gIH1cblxuICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICBjb25zdHJ1Y3ROYW1lOiBcIk9wXCIsXG4gICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgfSk7XG5cbiAgY29uc3QgZm4gPSB0Lm1lbWJlckV4cHJlc3Npb24odC5pZGVudGlmaWVyKFwiT3BcIiksIHQuaWRlbnRpZmllcihmbk5hbWUpKTtcblxuICByZXR1cm4gdC5jYWxsRXhwcmVzc2lvbihmbiwgW29wZXJhbmRdKTtcbn1cblxuZnVuY3Rpb24gY29udmVydEJpbmFyeU9wRXhwcmVzc2lvblRvVHMoXG4gIHNjb3BlOiBSZXNvdXJjZVNjb3BlLFxuICBub2RlOiB0ZXguQmluYXJ5T3BFeHByZXNzaW9uLFxuKSB7XG4gIGNvbnN0IGxlZnQgPSBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhcbiAgICBzY29wZSxcbiAgICB0ZXguZ2V0Q2hpbGRXaXRoVmFsdWUobm9kZSwgbm9kZS5tZXRhLmxoc0V4cHJlc3Npb24pISxcbiAgKTtcbiAgY29uc3QgcmlnaHQgPSBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhcbiAgICBzY29wZSxcbiAgICB0ZXguZ2V0Q2hpbGRXaXRoVmFsdWUobm9kZSwgbm9kZS5tZXRhLnJoc0V4cHJlc3Npb24pISxcbiAgKTtcblxuICBsZXQgZm5OYW1lID0gbm9kZS5tZXRhLm9wZXJhdG9yO1xuICBpZiAodGZCaW5hcnlPcGVyYXRvcnNUb0Nka3RmW2ZuTmFtZSBhcyBzdXBwb3J0ZWRCaW5hcnlPcGVyYXRvcnNdKSB7XG4gICAgZm5OYW1lID0gdGZCaW5hcnlPcGVyYXRvcnNUb0Nka3RmW2ZuTmFtZSBhcyBzdXBwb3J0ZWRCaW5hcnlPcGVyYXRvcnNdO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGNvbnZlcnQgdW5rbm93biBvcGVyYXRvciAke25vZGUubWV0YS5vcGVyYXRvcn1gKTtcbiAgfVxuXG4gIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgIGNvbnN0cnVjdE5hbWU6IFwiT3BcIixcbiAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICB9KTtcblxuICBjb25zdCBmbiA9IHQubWVtYmVyRXhwcmVzc2lvbih0LmlkZW50aWZpZXIoXCJPcFwiKSwgdC5pZGVudGlmaWVyKGZuTmFtZSkpO1xuICByZXR1cm4gdC5jYWxsRXhwcmVzc2lvbihmbiwgW2xlZnQsIHJpZ2h0XSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUZW1wbGF0ZUV4cHJlc3Npb25Ub1RzKFxuICBzY29wZTogUmVzb3VyY2VTY29wZSxcbiAgbm9kZTogdGV4LlRlbXBsYXRlRXhwcmVzc2lvbiB8IHRleC5UZW1wbGF0ZVdyYXBFeHByZXNzaW9uLFxuKSB7XG4gIGNvbnN0IHBhcnRzID0gbm9kZS5jaGlsZHJlbi5tYXAoKGNoaWxkKSA9PiAoe1xuICAgIG5vZGU6IGNoaWxkLFxuICAgIGV4cHI6IGNvbnZlcnRURkV4cHJlc3Npb25Bc3RUb1RzKHNjb3BlLCBjaGlsZCksXG4gIH0pKTtcblxuICBjb25zdCBsYXN0UGFydCA9IHBhcnRzW3BhcnRzLmxlbmd0aCAtIDFdO1xuICBpZiAodC5pc1N0cmluZ0xpdGVyYWwobGFzdFBhcnQuZXhwcikgJiYgbGFzdFBhcnQuZXhwci52YWx1ZSA9PT0gXCJcXG5cIikge1xuICAgIC8vIFRoaXMgaXMgYSBiaXQgb2YgYSBoYWNrLCBidXQgdGhlIHRyYWlsaW5nIG5ld2xpbmUgd2UgYWRkIGR1ZSB0b1xuICAgIC8vIGhlcmVkb2NzIGxvb2tzIHVnbHkgYW5kIHVubmVjZXNzYXJ5IGluIHRoZSBnZW5lcmF0ZWQgY29kZSwgc28gd2VcbiAgICAvLyB0cnkgdG8gcmVtb3ZlIGl0XG4gICAgcGFydHMucG9wKCk7XG4gIH1cblxuICBpZiAocGFydHMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHQuc3RyaW5nTGl0ZXJhbChub2RlLm1ldGEudmFsdWUpO1xuICB9XG5cbiAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBwYXJ0c1swXS5leHByO1xuICB9XG5cbiAgbGV0IGlzU2NvcGVkVHJhdmVyc2FsID0gZmFsc2U7XG4gIGNvbnN0IGV4cHJlc3Npb25zOiB0LkV4cHJlc3Npb25bXSA9IFtdO1xuICBmb3IgKGNvbnN0IHsgbm9kZSwgZXhwciB9IG9mIHBhcnRzKSB7XG4gICAgaWYgKFxuICAgICAgdGV4LmlzU2NvcGVUcmF2ZXJzYWxFeHByZXNzaW9uKG5vZGUpICYmXG4gICAgICAhdC5pc1N0cmluZ0xpdGVyYWwoZXhwcikgJiZcbiAgICAgICF0LmlzQ2FsbEV4cHJlc3Npb24oZXhwcilcbiAgICApIHtcbiAgICAgIGV4cHJlc3Npb25zLnB1c2godC5zdHJpbmdMaXRlcmFsKFwiJHtcIikpO1xuICAgICAgaXNTY29wZWRUcmF2ZXJzYWwgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAvLyB3ZSBzaG91bGQgaWRlYWxseSBiZSBkb2luZyB0eXBlIGNvZXJjaW9uIG1vcmVcbiAgICAgIC8vIGNhcmVmdWxseSBoZXJlLCBiZWNhdXNlIGl0IG1heSBub3QgYWx3YXlzIGJlIG5lZWRlZFxuICAgICAgdC5pc0NhbGxFeHByZXNzaW9uKGV4cHIpXG4gICAgKSB7XG4gICAgICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICAgICAgY29uc3RydWN0TmFtZTogXCJUb2tlblwiLFxuICAgICAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cHJlc3Npb25zLnB1c2goXG4gICAgICAgIHRlbXBsYXRlLmV4cHJlc3Npb24oYFRva2VuLmFzU3RyaW5nKCUlZXhwciUlKWApKHtcbiAgICAgICAgICBleHByLFxuICAgICAgICB9KSBhcyB0LkV4cHJlc3Npb24sXG4gICAgICApO1xuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc1Njb3BlZFRyYXZlcnNhbCkge1xuICAgICAgICBleHByZXNzaW9ucy5wdXNoKHQuc3RyaW5nTGl0ZXJhbChcIn1cIikpO1xuICAgICAgICBpc1Njb3BlZFRyYXZlcnNhbCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBleHByZXNzaW9ucy5wdXNoKGV4cHIpO1xuICB9XG5cbiAgaWYgKGlzU2NvcGVkVHJhdmVyc2FsKSB7XG4gICAgZXhwcmVzc2lvbnMucHVzaCh0LnN0cmluZ0xpdGVyYWwoXCJ9XCIpKTtcbiAgfVxuXG4gIHJldHVybiBleHByZXNzaW9uRm9yU2VyaWFsU3RyaW5nQ29uY2F0ZW5hdGlvbihzY29wZSwgZXhwcmVzc2lvbnMpO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0T2JqZWN0RXhwcmVzc2lvblRvVHMoXG4gIHNjb3BlOiBSZXNvdXJjZVNjb3BlLFxuICBub2RlOiB0ZXguT2JqZWN0RXhwcmVzc2lvbixcbikge1xuICByZXR1cm4gdC5vYmplY3RFeHByZXNzaW9uKFxuICAgIE9iamVjdC5lbnRyaWVzKG5vZGUubWV0YS5pdGVtcylcbiAgICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZUNoaWxkID0gZ2V0Q2hpbGRXaXRoVmFsdWUobm9kZSwgdmFsdWUpO1xuICAgICAgICBpZiAoIXZhbHVlQ2hpbGQpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoYFVuYWJsZSB0byB2YWx1ZSBmb3Igb2JqZWN0IGtleSAnJHtrZXl9JzogJHt2YWx1ZX1gKTtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0Lm9iamVjdFByb3BlcnR5KFxuICAgICAgICAgIHQuaWRlbnRpZmllcihrZXkpLFxuICAgICAgICAgIGNvbnZlcnRURkV4cHJlc3Npb25Bc3RUb1RzKHNjb3BlLCB2YWx1ZUNoaWxkKSxcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKChzKSA9PiBzICE9PSBudWxsKSBhcyB0Lk9iamVjdFByb3BlcnR5W10sXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRGdW5jdGlvbkNhbGxFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5GdW5jdGlvbkNhbGxFeHByZXNzaW9uLFxuKSB7XG4gIGNvbnN0IGZ1bmN0aW9uTmFtZSA9IG5vZGUubWV0YS5uYW1lO1xuICBjb25zdCBtYXBwaW5nID0gZnVuY3Rpb25zTWFwW2Z1bmN0aW9uTmFtZV07XG5cbiAgaWYgKCFtYXBwaW5nKSB7XG4gICAgbG9nZ2VyLmVycm9yKFxuICAgICAgYFVua25vd24gZnVuY3Rpb24gJHtmdW5jdGlvbk5hbWV9IGVuY291bnRlcmVkLiAke2xlYXZlQ29tbWVudFRleHR9YCxcbiAgICApO1xuICAgIGNvbnN0IGFyZ3VtZW50RXhwcmVzc2lvbnMgPSBub2RlLmNoaWxkcmVuLm1hcCgoY2hpbGQpID0+XG4gICAgICBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhzY29wZSwgY2hpbGQpLFxuICAgICk7XG5cbiAgICByZXR1cm4gdC5jYWxsRXhwcmVzc2lvbih0LmlkZW50aWZpZXIoZnVuY3Rpb25OYW1lKSwgYXJndW1lbnRFeHByZXNzaW9ucyk7XG4gIH1cblxuICBjb25zdCB0cmFuc2Zvcm1lZE5vZGU6IHRleC5GdW5jdGlvbkNhbGxFeHByZXNzaW9uID0gbWFwcGluZy50cmFuc2Zvcm1lclxuICAgID8gbWFwcGluZy50cmFuc2Zvcm1lcihub2RlKVxuICAgIDogbm9kZTtcblxuICBjb25zdCBhcmd1bWVudEV4cHJlc3Npb25zID0gdHJhbnNmb3JtZWROb2RlLmNoaWxkcmVuLm1hcCgoY2hpbGQpID0+XG4gICAgY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoc2NvcGUsIGNoaWxkKSxcbiAgKTtcblxuICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICBjb25zdHJ1Y3ROYW1lOiBcIkZuXCIsXG4gICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgfSk7XG5cbiAgY29uc3QgY2FsbGVlID0gdC5tZW1iZXJFeHByZXNzaW9uKFxuICAgIHQuaWRlbnRpZmllcihcIkZuXCIpLFxuICAgIHQuaWRlbnRpZmllcihtYXBwaW5nLm5hbWUpLFxuICApO1xuXG4gIGlmIChcbiAgICBtYXBwaW5nLnBhcmFtZXRlcnMubGVuZ3RoID4gMCAmJlxuICAgIG1hcHBpbmcucGFyYW1ldGVyc1ttYXBwaW5nLnBhcmFtZXRlcnMubGVuZ3RoIC0gMV0udmFyaWFkaWNcbiAgKSB7XG4gICAgY29uc3QgbGFzdFBhcmFtZXRlclR5cGUgPVxuICAgICAgbWFwcGluZy5wYXJhbWV0ZXJzW21hcHBpbmcucGFyYW1ldGVycy5sZW5ndGggLSAxXS50eXBlO1xuICAgIGNvbnN0IG5vblZhcmlhZGljQXJndW1lbnRzID0gYXJndW1lbnRFeHByZXNzaW9ucy5zbGljZShcbiAgICAgIDAsXG4gICAgICBtYXBwaW5nLnBhcmFtZXRlcnMubGVuZ3RoIC0gMSxcbiAgICApO1xuXG4gICAgY29uc3QgZm5DYWxsQXJndW1lbnRzID0gW1xuICAgICAgLi4ubm9uVmFyaWFkaWNBcmd1bWVudHMubWFwKChhcmdFeHByLCBpbmRleCkgPT5cbiAgICAgICAgY29lcmNlVHlwZShcbiAgICAgICAgICBzY29wZSxcbiAgICAgICAgICBhcmdFeHByLFxuICAgICAgICAgIGZpbmRFeHByZXNzaW9uVHlwZShzY29wZSwgYXJnRXhwciksXG4gICAgICAgICAgbWFwcGluZy5wYXJhbWV0ZXJzW2luZGV4XS50eXBlLFxuICAgICAgICApLFxuICAgICAgKSxcblxuICAgICAgdC5hcnJheUV4cHJlc3Npb24oXG4gICAgICAgIGFyZ3VtZW50RXhwcmVzc2lvbnNcbiAgICAgICAgICAuc2xpY2UobWFwcGluZy5wYXJhbWV0ZXJzLmxlbmd0aCAtIDEpXG4gICAgICAgICAgLm1hcCgoYXJnRXhwcikgPT5cbiAgICAgICAgICAgIGNvZXJjZVR5cGUoXG4gICAgICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgICAgICBhcmdFeHByLFxuICAgICAgICAgICAgICBmaW5kRXhwcmVzc2lvblR5cGUoc2NvcGUsIGFyZ0V4cHIpLFxuICAgICAgICAgICAgICBsYXN0UGFyYW1ldGVyVHlwZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKSxcbiAgICAgICksXG4gICAgXTtcblxuICAgIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKGNhbGxlZSwgZm5DYWxsQXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKFxuICAgIGNhbGxlZSxcbiAgICBhcmd1bWVudEV4cHJlc3Npb25zLm1hcCgoYXJnRXhwciwgaW5kZXgpID0+XG4gICAgICBjb2VyY2VUeXBlKFxuICAgICAgICBzY29wZSxcbiAgICAgICAgYXJnRXhwcixcbiAgICAgICAgZmluZEV4cHJlc3Npb25UeXBlKHNjb3BlLCBhcmdFeHByKSxcbiAgICAgICAgbWFwcGluZy5wYXJhbWV0ZXJzW2luZGV4XS50eXBlLFxuICAgICAgKSxcbiAgICApLFxuICApO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0SW5kZXhFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5JbmRleEV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3QgY29sbGVjdGlvbkV4cHJlc3Npb25DaGlsZCA9IHRleC5nZXRDaGlsZFdpdGhWYWx1ZShcbiAgICBub2RlLFxuICAgIG5vZGUubWV0YS5jb2xsZWN0aW9uRXhwcmVzc2lvbixcbiAgKTtcbiAgY29uc3Qga2V5RXhwcmVzc2lvbkNoaWxkID0gdGV4LmdldENoaWxkV2l0aFZhbHVlKFxuICAgIG5vZGUsXG4gICAgbm9kZS5tZXRhLmtleUV4cHJlc3Npb24sXG4gICk7XG5cbiAgY29uc3QgY29sbGVjdGlvbkV4cHJlc3Npb24gPSBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhcbiAgICBzY29wZSxcbiAgICBjb2xsZWN0aW9uRXhwcmVzc2lvbkNoaWxkISxcbiAgKTtcbiAgY29uc3Qga2V5RXhwcmVzc2lvbiA9IGNvbnZlcnRURkV4cHJlc3Npb25Bc3RUb1RzKHNjb3BlLCBrZXlFeHByZXNzaW9uQ2hpbGQhKTtcblxuICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICBjb25zdHJ1Y3ROYW1lOiBcIkZuXCIsXG4gICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgfSk7XG4gIGNvbnN0IGNhbGxlZSA9IHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICB0LmlkZW50aWZpZXIoXCJGblwiKSxcbiAgICB0LmlkZW50aWZpZXIoXCJsb29rdXBOZXN0ZWRcIiksXG4gICk7XG4gIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKGNhbGxlZSwgW1xuICAgIGNvbGxlY3Rpb25FeHByZXNzaW9uLFxuICAgIHQuYXJyYXlFeHByZXNzaW9uKFtrZXlFeHByZXNzaW9uXSksXG4gIF0pO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0U3BsYXRFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5TcGxhdEV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3Qgc291cmNlRXhwcmVzc2lvbkNoaWxkID0gdGV4LmdldENoaWxkV2l0aFZhbHVlKFxuICAgIG5vZGUsXG4gICAgbm9kZS5tZXRhLnNvdXJjZUV4cHJlc3Npb24sXG4gICkhO1xuICBjb25zdCBzb3VyY2VFeHByZXNzaW9uID0gY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoXG4gICAgc2NvcGUsXG4gICAgc291cmNlRXhwcmVzc2lvbkNoaWxkLFxuICApO1xuXG4gIC8vIFdlIGRvbid0IGNvbnZlcnQgdGhlIHJlbGF0aXZlIGV4cHJlc3Npb24gYmVjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBzcGxhdCBpcyBnb2luZyB0byBiZVxuICAvLyBhIHN0cmluZ1xuICBjb25zdCByZWxhdGl2ZUV4cHJlc3Npb24gPSBub2RlLm1ldGEuZWFjaEV4cHJlc3Npb24uc3RhcnRzV2l0aChcbiAgICBub2RlLm1ldGEuYW5vblN5bWJvbEV4cHJlc3Npb24sXG4gIClcbiAgICA/IG5vZGUubWV0YS5lYWNoRXhwcmVzc2lvbi5zbGljZShub2RlLm1ldGEuYW5vblN5bWJvbEV4cHJlc3Npb24ubGVuZ3RoKVxuICAgIDogbm9kZS5tZXRhLmVhY2hFeHByZXNzaW9uO1xuXG4gIGNvbnN0IHNlZ21lbnRzID0gcmVsYXRpdmVFeHByZXNzaW9uLnNwbGl0KC9cXC58XFxbfFxcXS8pLmZpbHRlcigocykgPT4gcyk7XG4gIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgIGNvbnN0cnVjdE5hbWU6IFwiRm5cIixcbiAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICB9KTtcbiAgY29uc3QgY2FsbGVlID0gdC5tZW1iZXJFeHByZXNzaW9uKFxuICAgIHQuaWRlbnRpZmllcihcIkZuXCIpLFxuICAgIHQuaWRlbnRpZmllcihcImxvb2t1cE5lc3RlZFwiKSxcbiAgKTtcblxuICByZXR1cm4gdC5jYWxsRXhwcmVzc2lvbihjYWxsZWUsIFtcbiAgICBzb3VyY2VFeHByZXNzaW9uLFxuICAgIHQuYXJyYXlFeHByZXNzaW9uKFtcbiAgICAgIC8vIHdlIGRvbid0IG5lZWQgdG8gdXNlIHRoZSBhbm9uU3ltYm9sRXhwcmVzc2lvbiBoZXJlIGJlY2F1c2VcbiAgICAgIC8vIGl0IG9ubHkgY2hhbmdlcyBiZXR3ZWVuIC4qIGFuZCBbKl0gd2hpY2ggd2UgZG9uJ3QgY2FyZSBhYm91dFxuICAgICAgdC5zdHJpbmdMaXRlcmFsKFwiKlwiKSxcbiAgICAgIC4uLnNlZ21lbnRzLm1hcCh0LnN0cmluZ0xpdGVyYWwpLFxuICAgIF0pLFxuICBdKTtcbn1cblxuZnVuY3Rpb24gY29udmVydENvbmRpdGlvbmFsRXhwcmVzc2lvblRvVHMoXG4gIHNjb3BlOiBSZXNvdXJjZVNjb3BlLFxuICBub2RlOiB0ZXguQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuKSB7XG4gIGNvbnN0IGNvbmRpdGlvbkNoaWxkID0gdGV4LmdldENoaWxkV2l0aFZhbHVlKFxuICAgIG5vZGUsXG4gICAgbm9kZS5tZXRhLmNvbmRpdGlvbkV4cHJlc3Npb24sXG4gICkhO1xuICBsZXQgY29uZGl0aW9uID0gY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoc2NvcGUsIGNvbmRpdGlvbkNoaWxkKTtcbiAgaWYgKHQuaXNJZGVudGlmaWVyKGNvbmRpdGlvbikgJiYgY2FuVXNlRnFuKGNvbmRpdGlvbkNoaWxkKSkge1xuICAgIC8vIFdlIGhhdmUgYSByZXNvdXJjZSBvciBkYXRhIHNvdXJjZSBoZXJlLCB3aGljaCB3ZSB3b3VsZCBuZWVkIHRvXG4gICAgLy8gcmVmZXJlbmNlIHVzaW5nIGZxblxuICAgIGNvbmRpdGlvbiA9IHQubWVtYmVyRXhwcmVzc2lvbihjb25kaXRpb24sIHQuaWRlbnRpZmllcihcImZxblwiKSk7XG4gIH1cblxuICBjb25zdCB0cnVlRXhwcmVzc2lvbiA9IGNvbnZlcnRURkV4cHJlc3Npb25Bc3RUb1RzKFxuICAgIHNjb3BlLFxuICAgIHRleC5nZXRDaGlsZFdpdGhWYWx1ZShub2RlLCBub2RlLm1ldGEudHJ1ZUV4cHJlc3Npb24pISxcbiAgKTtcblxuICBjb25zdCBmYWxzZUV4cHJlc3Npb24gPSBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhcbiAgICBzY29wZSxcbiAgICB0ZXguZ2V0Q2hpbGRXaXRoVmFsdWUobm9kZSwgbm9kZS5tZXRhLmZhbHNlRXhwcmVzc2lvbikhLFxuICApO1xuXG4gIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgIGNvbnN0cnVjdE5hbWU6IFwiY29uZGl0aW9uYWxcIixcbiAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICB9KTtcblxuICByZXR1cm4gdC5jYWxsRXhwcmVzc2lvbih0LmlkZW50aWZpZXIoXCJjb25kaXRpb25hbFwiKSwgW1xuICAgIGNvbmRpdGlvbixcbiAgICB0cnVlRXhwcmVzc2lvbixcbiAgICBmYWxzZUV4cHJlc3Npb24sXG4gIF0pO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0VHVwbGVFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5UdXBsZUV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3QgZXhwcmVzc2lvbnMgPSBub2RlLmNoaWxkcmVuLm1hcCgoY2hpbGQpID0+XG4gICAgY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoc2NvcGUsIGNoaWxkKSxcbiAgKTtcblxuICByZXR1cm4gdC5hcnJheUV4cHJlc3Npb24oZXhwcmVzc2lvbnMpO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0UmVsYXRpdmVUcmF2ZXJzYWxFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5SZWxhdGl2ZVRyYXZlcnNhbEV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3Qgc2VnbWVudHMgPSBub2RlLm1ldGEudHJhdmVyc2FsO1xuXG4gIC8vIFRoZSBsZWZ0IGhhbmQgc2lkZSAvIHNvdXJjZSBvZiBhIHJlbGF0aXZlIHRyYXZlcnNhbCBpcyBub3QgYSBwcm9wZXJcbiAgLy8gb2JqZWN0IC8gcmVzb3VyY2UgLyBkYXRhIHRoaW5nIHRoYXQgaXMgYmVpbmcgcmVmZXJlbmNlZFxuICBjb25zdCBzb3VyY2UgPSBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhcbiAgICBzY29wZSxcbiAgICB0ZXguZ2V0Q2hpbGRXaXRoVmFsdWUobm9kZSwgbm9kZS5tZXRhLnNvdXJjZUV4cHJlc3Npb24pISxcbiAgKTtcblxuICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICBjb25zdHJ1Y3ROYW1lOiBcIkZuXCIsXG4gICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgfSk7XG4gIGNvbnN0IGNhbGxlZSA9IHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICB0LmlkZW50aWZpZXIoXCJGblwiKSxcbiAgICB0LmlkZW50aWZpZXIoXCJsb29rdXBOZXN0ZWRcIiksXG4gICk7XG5cbiAgcmV0dXJuIHQuY2FsbEV4cHJlc3Npb24oY2FsbGVlLCBbXG4gICAgc291cmNlLFxuICAgIHQuYXJyYXlFeHByZXNzaW9uKHNlZ21lbnRzLm1hcCgocykgPT4gdC5zdHJpbmdMaXRlcmFsKHMuc2VnbWVudCkpKSxcbiAgXSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRGb3JFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5Gb3JFeHByZXNzaW9uLFxuKSB7XG4gIGNvbnN0IGNvbGxlY3Rpb25DaGlsZCA9IHRleC5nZXRDaGlsZFdpdGhWYWx1ZShcbiAgICBub2RlLFxuICAgIG5vZGUubWV0YS5jb2xsZWN0aW9uRXhwcmVzc2lvbixcbiAgKSE7XG5cbiAgbGV0IGNvbGxlY3Rpb25FeHByZXNzaW9uID0gY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoc2NvcGUsIGNvbGxlY3Rpb25DaGlsZCk7XG5cbiAgaWYgKHQuaXNJZGVudGlmaWVyKGNvbGxlY3Rpb25FeHByZXNzaW9uKSAmJiBjYW5Vc2VGcW4oY29sbGVjdGlvbkNoaWxkKSkge1xuICAgIC8vIFdlIGhhdmUgYSByZXNvdXJjZSBvciBkYXRhIHNvdXJjZSBoZXJlLCB3aGljaCB3ZSB3b3VsZCBuZWVkIHRvXG4gICAgLy8gcmVmZXJlbmNlIHVzaW5nIGZxblxuICAgIGNvbGxlY3Rpb25FeHByZXNzaW9uID0gdC5tZW1iZXJFeHByZXNzaW9uKFxuICAgICAgY29sbGVjdGlvbkV4cHJlc3Npb24sXG4gICAgICB0LmlkZW50aWZpZXIoXCJmcW5cIiksXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGNvbGxlY3Rpb25SZXF1aXJlc1dyYXBwaW5nID0gIXQuaXNTdHJpbmdMaXRlcmFsKGNvbGxlY3Rpb25FeHByZXNzaW9uKTtcbiAgY29uc3QgZXhwcmVzc2lvbnMgPSBbXTtcbiAgY29uc3QgY29uZGl0aW9uQm9keSA9IG5vZGUubWV0YS5rZXlWYXJcbiAgICA/IGAke25vZGUubWV0YS5rZXlWYXJ9LCAke25vZGUubWV0YS52YWxWYXJ9YFxuICAgIDogbm9kZS5tZXRhLnZhbFZhcjtcblxuICBjb25zdCBvcGVuQnJhY2UgPSBub2RlLm1ldGEub3BlblJhbmdlVmFsdWU7XG4gIGNvbnN0IGNsb3NlQnJhY2UgPSBub2RlLm1ldGEuY2xvc2VSYW5nZVZhbHVlO1xuICBjb25zdCBncm91cGVkID0gbm9kZS5tZXRhLmdyb3VwZWRWYWx1ZSA/IFwiLi4uXCIgOiBcIlwiO1xuICBjb25zdCB2YWx1ZUV4cHJlc3Npb24gPSBgJHtub2RlLm1ldGEudmFsdWVFeHByZXNzaW9ufSR7Z3JvdXBlZH1gO1xuXG4gIGNvbnN0IHByZWZpeCA9IGBcXCR7JHtvcGVuQnJhY2V9IGZvciAke2NvbmRpdGlvbkJvZHl9IGluIGA7XG4gIGNvbnN0IGtleVZhbHVlID0gbm9kZS5tZXRhLmtleUV4cHJlc3Npb25cbiAgICA/IGAgOiAke25vZGUubWV0YS5rZXlFeHByZXNzaW9ufSA9PiAke3ZhbHVlRXhwcmVzc2lvbn1gXG4gICAgOiBgIDogJHt2YWx1ZUV4cHJlc3Npb259YDtcbiAgY29uc3QgY29uZGl0aW9uYWwgPSBub2RlLm1ldGEuY29uZGl0aW9uYWxFeHByZXNzaW9uO1xuICBjb25zdCBzdWZmaXggPSBgJHtrZXlWYWx1ZX0ke1xuICAgIGNvbmRpdGlvbmFsID8gYCBpZiAke2NvbmRpdGlvbmFsfWAgOiBcIlwiXG4gIH0ke2Nsb3NlQnJhY2V9fWA7XG5cbiAgZXhwcmVzc2lvbnMucHVzaCh0LnN0cmluZ0xpdGVyYWwocHJlZml4KSk7XG4gIGlmIChjb2xsZWN0aW9uUmVxdWlyZXNXcmFwcGluZykge1xuICAgIGV4cHJlc3Npb25zLnB1c2godC5zdHJpbmdMaXRlcmFsKFwiJHtcIikpO1xuICB9XG4gIGV4cHJlc3Npb25zLnB1c2goY29sbGVjdGlvbkV4cHJlc3Npb24pO1xuICBpZiAoY29sbGVjdGlvblJlcXVpcmVzV3JhcHBpbmcpIHtcbiAgICBleHByZXNzaW9ucy5wdXNoKHQuc3RyaW5nTGl0ZXJhbChcIn1cIikpO1xuICB9XG4gIGV4cHJlc3Npb25zLnB1c2godC5zdHJpbmdMaXRlcmFsKHN1ZmZpeCkpO1xuXG4gIHJldHVybiBleHByZXNzaW9uRm9yU2VyaWFsU3RyaW5nQ29uY2F0ZW5hdGlvbihzY29wZSwgZXhwcmVzc2lvbnMpO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5FeHByZXNzaW9uVHlwZSxcbik6IHQuRXhwcmVzc2lvbiB7XG4gIGlmICh0ZXguaXNMaXRlcmFsVmFsdWVFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRMaXRlcmFsVmFsdWVFeHByZXNzaW9uVG9UcyhzY29wZSwgbm9kZSk7XG4gIH1cblxuICBpZiAodGV4LmlzU2NvcGVUcmF2ZXJzYWxFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRTY29wZVRyYXZlcnNhbEV4cHJlc3Npb25Ub1RzKHNjb3BlLCBub2RlKTtcbiAgfVxuXG4gIGlmICh0ZXguaXNVbmFyeU9wRXhwcmVzc2lvbihub2RlKSkge1xuICAgIHJldHVybiBjb252ZXJ0VW5hcnlPcEV4cHJlc3Npb25Ub1RzKHNjb3BlLCBub2RlKTtcbiAgfVxuXG4gIGlmICh0ZXguaXNCaW5hcnlPcEV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gY29udmVydEJpbmFyeU9wRXhwcmVzc2lvblRvVHMoc2NvcGUsIG5vZGUpO1xuICB9XG5cbiAgaWYgKHRleC5pc1RlbXBsYXRlRXhwcmVzc2lvbihub2RlKSB8fCB0ZXguaXNUZW1wbGF0ZVdyYXBFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRUZW1wbGF0ZUV4cHJlc3Npb25Ub1RzKHNjb3BlLCBub2RlKTtcbiAgfVxuXG4gIGlmICh0ZXguaXNPYmplY3RFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRPYmplY3RFeHByZXNzaW9uVG9UcyhzY29wZSwgbm9kZSk7XG4gIH1cblxuICBpZiAodGV4LmlzRnVuY3Rpb25DYWxsRXhwcmVzc2lvbihub2RlKSkge1xuICAgIHJldHVybiBjb252ZXJ0RnVuY3Rpb25DYWxsRXhwcmVzc2lvblRvVHMoc2NvcGUsIG5vZGUpO1xuICB9XG5cbiAgaWYgKHRleC5pc0luZGV4RXhwcmVzc2lvbihub2RlKSkge1xuICAgIHJldHVybiBjb252ZXJ0SW5kZXhFeHByZXNzaW9uVG9UcyhzY29wZSwgbm9kZSk7XG4gIH1cblxuICBpZiAodGV4LmlzU3BsYXRFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRTcGxhdEV4cHJlc3Npb25Ub1RzKHNjb3BlLCBub2RlKTtcbiAgfVxuXG4gIGlmICh0ZXguaXNDb25kaXRpb25hbEV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gY29udmVydENvbmRpdGlvbmFsRXhwcmVzc2lvblRvVHMoc2NvcGUsIG5vZGUpO1xuICB9XG5cbiAgaWYgKHRleC5pc1R1cGxlRXhwcmVzc2lvbihub2RlKSkge1xuICAgIHJldHVybiBjb252ZXJ0VHVwbGVFeHByZXNzaW9uVG9UcyhzY29wZSwgbm9kZSk7XG4gIH1cblxuICBpZiAodGV4LmlzUmVsYXRpdmVUcmF2ZXJzYWxFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRSZWxhdGl2ZVRyYXZlcnNhbEV4cHJlc3Npb25Ub1RzKHNjb3BlLCBub2RlKTtcbiAgfVxuXG4gIGlmICh0ZXguaXNGb3JFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRGb3JFeHByZXNzaW9uVG9UcyhzY29wZSwgbm9kZSk7XG4gIH1cblxuICByZXR1cm4gdC5zdHJpbmdMaXRlcmFsKFwiXCIpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXhwcmVzc2lvbkFzdChcbiAgaW5wdXQ6IHN0cmluZyxcbik6IFByb21pc2U8dGV4LkV4cHJlc3Npb25UeXBlPiB7XG4gIGNvbnN0IHsgd3JhcCwgd3JhcE9mZnNldCB9ID0gd3JhcFRlcnJhZm9ybUV4cHJlc3Npb24oaW5wdXQpO1xuICBjb25zdCBhc3QgPSBhd2FpdCBnZXRFeHByZXNzaW9uQXN0KFwibWFpbi50ZlwiLCB3cmFwKTtcblxuICBpZiAoIWFzdCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHBhcnNlIHRlcnJhZm9ybSBleHByZXNzaW9uOiAke2lucHV0fWApO1xuICB9XG5cbiAgaWYgKHdyYXBPZmZzZXQgIT0gMCAmJiB0ZXguaXNUZW1wbGF0ZVdyYXBFeHByZXNzaW9uKGFzdCkpIHtcbiAgICByZXR1cm4gYXN0LmNoaWxkcmVuWzBdO1xuICB9XG5cbiAgcmV0dXJuIGFzdDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIGlucHV0OiBzdHJpbmcsXG4gIHRhcmdldFR5cGU6ICgpID0+IEF0dHJpYnV0ZVR5cGUsXG4pOiBQcm9taXNlPHQuRXhwcmVzc2lvbj4ge1xuICBsb2dnZXIuZGVidWcoYGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9Ucygke2lucHV0fSlgKTtcbiAgY29uc3QgdHNFeHByZXNzaW9uID0gY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoXG4gICAgc2NvcGUsXG4gICAgYXdhaXQgZXhwcmVzc2lvbkFzdChpbnB1dCksXG4gICk7XG5cbiAgcmV0dXJuIGNvZXJjZVR5cGUoXG4gICAgc2NvcGUsXG4gICAgdHNFeHByZXNzaW9uLFxuICAgIGZpbmRFeHByZXNzaW9uVHlwZShzY29wZSwgdHNFeHByZXNzaW9uKSxcbiAgICB0YXJnZXRUeXBlKCksXG4gICk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleHRyYWN0SXRlcmF0b3JWYXJpYWJsZXNGcm9tRXhwcmVzc2lvbihcbiAgaW5wdXQ6IHN0cmluZyxcbik6IFByb21pc2U8SXRlcmF0b3JWYXJpYWJsZVJlZmVyZW5jZVtdPiB7XG4gIGNvbnN0IHBvc3NpYmxlVmFyaWFibGVTcG90cyA9IGF3YWl0IGdldFJlZmVyZW5jZXNJbkV4cHJlc3Npb24oXG4gICAgXCJtYWluLnRmXCIsXG4gICAgaW5wdXQsXG4gICk7XG5cbiAgcmV0dXJuIHBvc3NpYmxlVmFyaWFibGVTcG90c1xuICAgIC5maWx0ZXIoKHNwb3QpID0+IHNwb3QudmFsdWUuc3RhcnRzV2l0aChcImVhY2guXCIpKVxuICAgIC5tYXAoKHNwb3QpID0+ICh7XG4gICAgICBzdGFydDogc3BvdC5zdGFydFBvc2l0aW9uLFxuICAgICAgZW5kOiBzcG90LmVuZFBvc2l0aW9uLFxuICAgICAgdmFsdWU6IHNwb3QudmFsdWUsXG4gICAgfSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZHluYW1pY1ZhcmlhYmxlVG9Bc3QoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIG5vZGU6IHRleC5TY29wZVRyYXZlcnNhbEV4cHJlc3Npb24sXG4gIGl0ZXJhdG9yTmFtZTogc3RyaW5nLFxuICBibG9jazogc3RyaW5nID0gXCJlYWNoXCIsXG4pOiB0LkV4cHJlc3Npb24ge1xuICBpZiAoaXRlcmF0b3JOYW1lID09PSBcImR5bmFtaWMtYmxvY2tcIikge1xuICAgIHJldHVybiBleHByZXNzaW9uRm9yU2VyaWFsU3RyaW5nQ29uY2F0ZW5hdGlvbihzY29wZSwgW1xuICAgICAgdC5zdHJpbmdMaXRlcmFsKFwiJHtcIiksXG4gICAgICB0LnN0cmluZ0xpdGVyYWwoYmxvY2spLFxuICAgICAgdC5zdHJpbmdMaXRlcmFsKFwifVwiKSxcbiAgICBdKTtcbiAgfVxuICBpZiAobm9kZS5tZXRhLnZhbHVlID09PSBgJHtibG9ja30ua2V5YCkge1xuICAgIHJldHVybiB0Lm1lbWJlckV4cHJlc3Npb24odC5pZGVudGlmaWVyKGl0ZXJhdG9yTmFtZSksIHQuaWRlbnRpZmllcihcImtleVwiKSk7XG4gIH1cbiAgaWYgKG5vZGUubWV0YS52YWx1ZSA9PT0gYCR7YmxvY2t9LnZhbHVlYCkge1xuICAgIHJldHVybiB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICB0LmlkZW50aWZpZXIoaXRlcmF0b3JOYW1lKSxcbiAgICAgIHQuaWRlbnRpZmllcihcInZhbHVlXCIpLFxuICAgICk7XG4gIH1cblxuICBpZiAoYmxvY2sgPT09IFwiY291bnRcIiAmJiBub2RlLm1ldGEudmFsdWUgPT09IGAke2Jsb2NrfS5pbmRleGApIHtcbiAgICByZXR1cm4gdC5tZW1iZXJFeHByZXNzaW9uKFxuICAgICAgdC5pZGVudGlmaWVyKGl0ZXJhdG9yTmFtZSksXG4gICAgICB0LmlkZW50aWZpZXIoXCJpbmRleFwiKSxcbiAgICApO1xuICB9XG5cbiAgY29uc3Qgc2VnbWVudHMgPSBub2RlLm1ldGEudHJhdmVyc2FsO1xuXG4gIGlmIChcbiAgICBzZWdtZW50cy5sZW5ndGggPiAyICYmXG4gICAgc2VnbWVudHNbMF0uc2VnbWVudCA9PT0gYmxvY2sgJiZcbiAgICBzZWdtZW50c1sxXS5zZWdtZW50ID09PSBcInZhbHVlXCJcbiAgKSB7XG4gICAgY29uc3Qgc2VnbWVudHNBZnRlckVhY2hWYWx1ZSA9IHNlZ21lbnRzLnNsaWNlKDIpO1xuICAgIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgICAgY29uc3RydWN0TmFtZTogXCJGblwiLFxuICAgICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgICB9KTtcbiAgICBjb25zdCBjYWxsZWUgPSB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICB0LmlkZW50aWZpZXIoXCJGblwiKSxcbiAgICAgIHQuaWRlbnRpZmllcihcImxvb2t1cE5lc3RlZFwiKSxcbiAgICApO1xuICAgIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKGNhbGxlZSwgW1xuICAgICAgdC5tZW1iZXJFeHByZXNzaW9uKHQuaWRlbnRpZmllcihpdGVyYXRvck5hbWUpLCB0LmlkZW50aWZpZXIoXCJ2YWx1ZVwiKSksXG4gICAgICB0LmFycmF5RXhwcmVzc2lvbihcbiAgICAgICAgc2VnbWVudHNBZnRlckVhY2hWYWx1ZS5tYXAoKHBhcnQpID0+IHtcbiAgICAgICAgICBpZiAocGFydC50eXBlID09PSBcIm5hbWVUcmF2ZXJzYWxcIikge1xuICAgICAgICAgICAgcmV0dXJuIHQuc3RyaW5nTGl0ZXJhbChwYXJ0LnNlZ21lbnQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdC5zdHJpbmdMaXRlcmFsKGBbJHtwYXJ0LnNlZ21lbnR9XWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICApLFxuICAgIF0pO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKFxuICAgIGBDYW4gbm90IGNyZWF0ZSBBU1QgZm9yIGl0ZXJhdG9yIHZhcmlhYmxlIG9mICcke25vZGUubWV0YS52YWx1ZX0nYCxcbiAgKTtcbn1cbiJdfQ==
|