@cdktn/hcl2cdk 0.23.0-pre.4 → 0.23.0-pre.40

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