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

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,693 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) HashiCorp, Inc.
4
+ * SPDX-License-Identifier: MPL-2.0
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const expressions_1 = require("../expressions");
8
+ const testHelpers_1 = require("./testHelpers");
9
+ const awsProviderSchema = {
10
+ format_version: "1.0",
11
+ provider_schemas: {
12
+ "registry.terraform.io/hashicorp/aws": {
13
+ provider: {},
14
+ resource_schemas: {
15
+ aws_s3_bucket: {
16
+ block: {
17
+ attributes: {
18
+ foo: {
19
+ type: ["map", "string"],
20
+ description_kind: "plain",
21
+ },
22
+ },
23
+ },
24
+ },
25
+ },
26
+ data_source_schemas: {
27
+ aws_availability_zones: {
28
+ version: 0,
29
+ block: {
30
+ attributes: {
31
+ all_availability_zones: {
32
+ type: "bool",
33
+ description_kind: "plain",
34
+ optional: true,
35
+ },
36
+ exclude_names: {
37
+ type: ["set", "string"],
38
+ description_kind: "plain",
39
+ optional: true,
40
+ },
41
+ exclude_zone_ids: {
42
+ type: ["set", "string"],
43
+ description_kind: "plain",
44
+ optional: true,
45
+ },
46
+ group_names: {
47
+ type: ["set", "string"],
48
+ description_kind: "plain",
49
+ computed: true,
50
+ },
51
+ id: {
52
+ type: "string",
53
+ description_kind: "plain",
54
+ optional: true,
55
+ computed: true,
56
+ },
57
+ names: {
58
+ type: ["list", "string"],
59
+ description_kind: "plain",
60
+ computed: true,
61
+ },
62
+ state: {
63
+ type: "string",
64
+ description_kind: "plain",
65
+ optional: true,
66
+ },
67
+ zone_ids: {
68
+ type: ["list", "string"],
69
+ description_kind: "plain",
70
+ computed: true,
71
+ },
72
+ testing_map: {
73
+ type: ["map", "string"],
74
+ description_kind: "plain",
75
+ computed: true,
76
+ },
77
+ },
78
+ block_types: {
79
+ filter: {
80
+ nesting_mode: "set",
81
+ block: {
82
+ attributes: {
83
+ name: {
84
+ type: "string",
85
+ description_kind: "plain",
86
+ required: true,
87
+ },
88
+ values: {
89
+ type: ["set", "string"],
90
+ description_kind: "plain",
91
+ required: true,
92
+ },
93
+ },
94
+ description_kind: "plain",
95
+ },
96
+ },
97
+ timeouts: {
98
+ nesting_mode: "single",
99
+ block: {
100
+ attributes: {
101
+ read: {
102
+ type: "string",
103
+ description_kind: "plain",
104
+ optional: true,
105
+ },
106
+ },
107
+ description_kind: "plain",
108
+ },
109
+ },
110
+ },
111
+ description_kind: "plain",
112
+ },
113
+ },
114
+ },
115
+ },
116
+ },
117
+ };
118
+ const externalProviderSchema = {
119
+ format_version: "1.0",
120
+ provider_schemas: {
121
+ "registry.terraform.io/hashicorp/external": {
122
+ provider: {},
123
+ resource_schemas: {},
124
+ data_source_schemas: {
125
+ external: {
126
+ version: 0,
127
+ block: {
128
+ attributes: {
129
+ id: {
130
+ type: "string",
131
+ description: "The id of the data source. This will always be set to `-`",
132
+ description_kind: "plain",
133
+ computed: true,
134
+ },
135
+ program: {
136
+ type: ["list", "string"],
137
+ description: "A list of strings, whose first element is the program to run and whose subsequent elements are optional command line arguments to the program. Terraform does not execute the program through a shell, so it is not necessary to escape shell metacharacters nor add quotes around arguments containing spaces.",
138
+ description_kind: "plain",
139
+ required: true,
140
+ },
141
+ query: {
142
+ type: ["map", "string"],
143
+ description: "A map of string values to pass to the external program as the query arguments. If not supplied, the program will receive an empty object as its input.",
144
+ description_kind: "plain",
145
+ optional: true,
146
+ },
147
+ result: {
148
+ type: ["map", "string"],
149
+ description: "A map of string values returned from the external program.",
150
+ description_kind: "plain",
151
+ computed: true,
152
+ },
153
+ working_dir: {
154
+ type: "string",
155
+ description: "Working directory of the program. If not supplied, the program will run in the current directory.",
156
+ description_kind: "plain",
157
+ optional: true,
158
+ },
159
+ },
160
+ description: 'The `external` data source allows an external program implementing a specific protocol (defined below) to act as a data source, exposing arbitrary data for use elsewhere in the Terraform configuration.\n\n**Warning** This mechanism is provided as an "escape hatch" for exceptional situations where a first-class Terraform provider is not more appropriate. Its capabilities are limited in comparison to a true data source, and implementing a data source via an external program is likely to hurt the portability of your Terraform configuration by creating dependencies on external programs and libraries that may not be available (or may need to be used differently) on different operating systems.\n\n**Warning** Terraform Enterprise does not guarantee availability of any particular language runtimes or external programs beyond standard shell utilities, so it is not recommended to use this data source within configurations that are applied within Terraform Enterprise.',
161
+ description_kind: "plain",
162
+ },
163
+ },
164
+ },
165
+ },
166
+ },
167
+ };
168
+ function getScope({ provider, resources, data, variables, locals, forEachIteratorName, scopedVariables, withinOverrideExpression = false, } = {}) {
169
+ const scopeVariables = {};
170
+ resources === null || resources === void 0 ? void 0 : resources.forEach((varName) => {
171
+ let [resourceType, resourceName] = varName.split(".");
172
+ if (!resourceName) {
173
+ resourceName = varName;
174
+ resourceType = "aws_s3_bucket";
175
+ }
176
+ scopeVariables[varName] = {
177
+ resource: resourceType,
178
+ variableName: resourceName,
179
+ };
180
+ });
181
+ data === null || data === void 0 ? void 0 : data.forEach((varName) => {
182
+ scopeVariables[varName] = {
183
+ resource: "data.aws_s3_bucket",
184
+ variableName: varName,
185
+ };
186
+ });
187
+ variables === null || variables === void 0 ? void 0 : variables.forEach((varName) => {
188
+ scopeVariables[varName] = {
189
+ resource: "var",
190
+ variableName: varName,
191
+ };
192
+ });
193
+ locals === null || locals === void 0 ? void 0 : locals.forEach((varName) => {
194
+ scopeVariables[varName] = {
195
+ resource: "local",
196
+ variableName: varName,
197
+ };
198
+ });
199
+ const scope = {
200
+ providerSchema: provider !== null && provider !== void 0 ? provider : {},
201
+ providerGenerator: {},
202
+ constructs: new Set(),
203
+ variables: scopeVariables,
204
+ hasTokenBasedTypeCoercion: true,
205
+ scopedVariables: scopedVariables || {},
206
+ forEachIteratorName,
207
+ withinOverrideExpression,
208
+ nodeIds: [],
209
+ importables: [],
210
+ topLevelConfig: {},
211
+ };
212
+ return scope;
213
+ }
214
+ const getType = () => "string";
215
+ describe("expressionToTs", () => {
216
+ test("converts a simple string to a string", async () => {
217
+ const expression = "hello";
218
+ const scope = getScope();
219
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
220
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""hello""`);
221
+ });
222
+ test("converts a simple expression with a template", async () => {
223
+ const expression = "${22}";
224
+ const scope = getScope();
225
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
226
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(22)"`);
227
+ });
228
+ test("converts a variable reference", async () => {
229
+ const expression = "${var.foo}";
230
+ const scope = getScope();
231
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
232
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"foo.stringValue"`);
233
+ });
234
+ test("convert a variable reference with snake case", async () => {
235
+ const expression = "${var.foo_bar}";
236
+ const scope = getScope({ variables: ["foo_bar"] });
237
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
238
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(fooBar.value)"`);
239
+ });
240
+ test("convert a function call", async () => {
241
+ const expression = `\${replace("hello", "l", "w")}`;
242
+ const scope = getScope();
243
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
244
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.replace("hello", "l", "w"))"`);
245
+ });
246
+ test("converts a function call with an expression", async () => {
247
+ const expression = `\${replace("hello-\${22+22}", "44", "world")}`;
248
+ const scope = getScope();
249
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
250
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.replace("hello-" + Token.asString(Op.add(22, 22)), "44", "world"))"`);
251
+ });
252
+ test("converts string concatenation of iterator key", async () => {
253
+ const expression = '${"dynamic-ingress-${ingress.key}"}';
254
+ const scope = getScope({
255
+ scopedVariables: {
256
+ ingress: "dynamic_iterator0",
257
+ },
258
+ });
259
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
260
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""dynamic-ingress-\${" + Token.asString(dynamic_iterator0.key) + "}""`);
261
+ });
262
+ test("convert a variable reference", async () => {
263
+ const expression = `\${var.foo_bar}`;
264
+ const scope = getScope({ variables: ["foo_bar"] });
265
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
266
+ // TODO: This seems broken
267
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(fooBar.value)"`);
268
+ });
269
+ test("convert a resource reference", async () => {
270
+ const expression = `"simple-\${aws_s3_bucket.foo.id}"`;
271
+ const scope = getScope({ resources: ["aws_s3_bucket.foo"] });
272
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
273
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""simple-\${" + foo.id + "}""`);
274
+ });
275
+ test("convert a resource reference with nested properties", async () => {
276
+ const expression = `"simple-\${aws_s3_bucket.foo.prop.test}"`;
277
+ const scope = getScope({ resources: ["aws_s3_bucket.foo"] });
278
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
279
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""simple-\${" + foo.prop.test + "}""`);
280
+ });
281
+ test("convert a local reference", async () => {
282
+ const expression = `"simple-\${local.foo}"`;
283
+ const scope = getScope({ locals: ["foo"] });
284
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
285
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""simple-\${" + foo + "}""`);
286
+ });
287
+ test("plain resource references in arithmetics", async () => {
288
+ const expression = "${aws_s3_bucket.examplebucket.count + aws_s3_bucket.otherbucket.count }";
289
+ const scope = getScope({
290
+ resources: ["aws_s3_bucket.examplebucket", "aws_s3_bucket.otherbucket"],
291
+ });
292
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
293
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Op.add(examplebucket.count, otherbucket.count))"`);
294
+ });
295
+ test("use fqn for splat reference", async () => {
296
+ const expression = `\${aws_s3_bucket.foo.*.id}`;
297
+ const scope = getScope({ resources: ["aws_s3_bucket.foo"] });
298
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
299
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(foo, ["*", "id"]))"`);
300
+ });
301
+ test("use fqn if property is present on numeric access using dot notation", async () => {
302
+ const expression = "${aws_s3_bucket.examplebucket.network_interface.0.access_config.0.assigned_nat_ip}";
303
+ const scope = getScope({ resources: ["aws_s3_bucket.examplebucket"] });
304
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
305
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(examplebucket.networkInterface, ["0", "access_config", "0", "assigned_nat_ip"]))"`);
306
+ });
307
+ test("use fqn if property is present on numeric access", async () => {
308
+ const expression = "${aws_s3_bucket.examplebucket.network_interface[0].access_config[0].assigned_nat_ip}";
309
+ const scope = getScope({ resources: ["aws_s3_bucket.examplebucket"] });
310
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
311
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(examplebucket.networkInterface, ["0", "access_config", "0", "assigned_nat_ip"]))"`);
312
+ });
313
+ test("use no fqn if property is present on numeric access using []", async () => {
314
+ const expression = "${aws_s3_bucket.examplebucket.network_interface[0].access_config[0].assigned_nat_ip}";
315
+ const scope = getScope({ resources: ["aws_s3_bucket.examplebucket"] });
316
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
317
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(examplebucket.networkInterface, ["0", "access_config", "0", "assigned_nat_ip"]))"`);
318
+ });
319
+ test("detects splat reference within function", async () => {
320
+ const expression = "${toset(aws_s3_bucket.examplebucket.*)}";
321
+ const scope = getScope({ resources: ["aws_s3_bucket.examplebucket"] });
322
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
323
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.toset(Fn.lookupNested(examplebucket, ["*"])))"`);
324
+ });
325
+ test("convert conditional", async () => {
326
+ const expression = "${aws_kms_key.key.deletion_window_in_days > 3 ? aws_s3_bucket.examplebucket.id : []}";
327
+ const scope = getScope({ resources: ["aws_kms_key.key", "examplebucket"] });
328
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
329
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(conditional(Op.gt(key.deletionWindowInDays, 3), examplebucket.id, []))"`);
330
+ });
331
+ test("converts a function with references", async () => {
332
+ const expression = "${element(aws_s3_bucket.examplebucket, 0).id}";
333
+ const scope = getScope({ resources: ["aws_s3_bucket.examplebucket"] });
334
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
335
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(Fn.element(examplebucket, 0), ["id"]))"`);
336
+ });
337
+ test("converts a function with splat reference", async () => {
338
+ const expression = "${element(aws_s3_bucket.examplebucket.*.id, 0)}";
339
+ const scope = getScope({ resources: ["aws_s3_bucket.examplebucket"] });
340
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
341
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.element(Fn.lookupNested(examplebucket, ["*", "id"]), 0))"`);
342
+ });
343
+ test("convert for loops", async () => {
344
+ const expression = "${{ for name, user in var.users : user.role => name...}}";
345
+ const scope = getScope();
346
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
347
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""\${{ for name, user in \${" + users.value + "} : user.role => name...}}""`);
348
+ });
349
+ test("for expressions", async () => {
350
+ const expression = "{for s in var.list : s => upper(s)}";
351
+ const scope = getScope();
352
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
353
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""\${{ for s in \${" + list.value + "} : s => upper(s)}}""`);
354
+ });
355
+ test("for list expression ", async () => {
356
+ const expression = "[for s in var.list : upper(s)]";
357
+ const scope = getScope();
358
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
359
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""\${[ for s in \${" + list.value + "} : upper(s)]}""`);
360
+ });
361
+ test("for list with conditional", async () => {
362
+ const expression = '[for s in var.list : upper(s) if s != ""]';
363
+ const scope = getScope();
364
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
365
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""\${[ for s in \${" + list.value + "} : upper(s) if s != \\"\\"]}""`);
366
+ });
367
+ test("convert property access resources", async () => {
368
+ const expression = "${aws_s3_bucket.examplebucket[0].id}";
369
+ const scope = getScope({ resources: ["aws_s3_bucket.examplebucket"] });
370
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
371
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(examplebucket, ["0", "id"]))"`);
372
+ });
373
+ test("convert unary operators", async () => {
374
+ const expression = `\${!var.enabled}`;
375
+ const scope = getScope({ variables: ["enabled"] });
376
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, () => "bool");
377
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asBoolean(Op.not(enabled.value))"`);
378
+ });
379
+ test("convert function with arrays and comments", async () => {
380
+ const expression = `\${compact([
381
+ # The example "bucket"
382
+ aws_s3_bucket.examplebucket,
383
+
384
+ # The "Learn" single page application. This is not configured in all environments.
385
+ var.input,
386
+ ])}`;
387
+ const scope = getScope({
388
+ resources: ["aws_s3_bucket.examplebucket"],
389
+ variables: ["input"],
390
+ });
391
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
392
+ // TODO: See if we have a way to preserve comments
393
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.compact(Token.asList([examplebucket, input.value])))"`);
394
+ });
395
+ test("convert references for same reference", async () => {
396
+ const expression = `\${var.input == "test" ? "azure-ad-int" : "azure-ad-\${var.input}"}`;
397
+ const scope = getScope({ variables: ["input"] });
398
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
399
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(conditional(Op.eq(input.value, "test"), "azure-ad-int", "azure-ad-\${" + input.value + "}"))"`);
400
+ });
401
+ test("nested variable access", async () => {
402
+ const expression = `\${element(var.test2["val1"], 0)}`;
403
+ const scope = getScope({ variables: ["test2"] });
404
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
405
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.element(Fn.lookupNested(test2.value, ["\\"val1\\""]), 0))"`);
406
+ });
407
+ test("complicated nested local value", async () => {
408
+ const expression = "${flatten(var.vnets[*].subnets[*].name)}";
409
+ const scope = getScope({ variables: ["vnets"] });
410
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
411
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.flatten(Fn.lookupNested(vnets.value, ["*", "subnets", "*", "name"])))"`);
412
+ });
413
+ // TOIMPROVE: I don't think we can handle this case yet, since the variable
414
+ // needs to be wrapped in an iterator. I'm leaving this in, but it's broken
415
+ test("complicated nested variable access with map", async () => {
416
+ const expression = `{
417
+ for vnet in var.vnets[*]:
418
+ (vnet.vnet_name) => vnet.subnets[*].name
419
+ }`;
420
+ const scope = getScope({ variables: ["vnets"] });
421
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
422
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""\${{ for vnet in \${" + Fn.lookupNested(vnets.value, ["*"]) + "} : (vnet.vnet_name) => vnet.subnets[*].name}}""`);
423
+ });
424
+ test("complicated nested variable access with list", async () => {
425
+ const expression = `\${flatten([
426
+ for k, v in var.route : [
427
+ for n, s in v : [
428
+ {
429
+ key = k,
430
+ name = n,
431
+ svc_url = s
432
+ }
433
+ ]
434
+ ]
435
+ ])}`;
436
+ const scope = getScope({ variables: ["route"] });
437
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
438
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.flatten("\${[ for k, v in \${" + route.value + "} : [\\n for n, s in v : [\\n {\\n key = k,\\n name = n,\\n svc_url = s\\n }\\n ]\\n ]]}"))"`);
439
+ });
440
+ test("simple local variable access", async () => {
441
+ const expression = "${!local.enabled}";
442
+ const scope = getScope({ locals: ["enabled"] });
443
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
444
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Op.not(enabled))"`);
445
+ });
446
+ test("multi local access", async () => {
447
+ const expression = '"${local.service_name},${local.owner},${local.is_it_great},${local.how_many}"';
448
+ const scope = getScope({
449
+ locals: ["service_name", "owner", "is_it_great", "how_many"],
450
+ });
451
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
452
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""\${" + serviceName + "},\${" + owner + "},\${" + isItGreat + "},\${" + howMany + "}""`);
453
+ });
454
+ test("binary operations within literals and variables", async () => {
455
+ const expression = '"${var.test} + 1"';
456
+ const scope = getScope({ variables: ["test"] });
457
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
458
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""\${" + test.value + "} + 1""`);
459
+ });
460
+ test("local variable access", async () => {
461
+ const expression = '"${local.enabled}"';
462
+ const scope = getScope({ locals: ["enabled"] });
463
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
464
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"enabled"`);
465
+ });
466
+ test("converts traversals that cannot be references", async () => {
467
+ const expression = "${self.path}";
468
+ const scope = getScope();
469
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
470
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(TerraformSelf.getAny("path"))"`);
471
+ });
472
+ test("converts join function with variables", async () => {
473
+ const expression = '${join("-", [var.tags.app, var.tags.env])}';
474
+ const scope = getScope({ variables: ["tags"] });
475
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
476
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.join("-", Token.asList([Fn.lookupNested(tags.value, ["app"]), Fn.lookupNested(tags.value, ["env"])])))"`);
477
+ });
478
+ test("converts join function with many arguments variables", async () => {
479
+ const expression = '${join("-", var.tags.app, var.tags.env, var.tags.other)}';
480
+ const scope = getScope({ variables: ["tags"] });
481
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
482
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.join("-", Token.asList(Fn.concat([Fn.lookupNested(tags.value, ["app"]), Fn.lookupNested(tags.value, ["env"]), Fn.lookupNested(tags.value, ["other"])]))))"`);
483
+ });
484
+ test("doesn't wrap any extra templates", async () => {
485
+ const expression = `"app-\${terraform.workspace}"`;
486
+ const scope = getScope();
487
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
488
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""app-\${terraform.workspace}""`);
489
+ });
490
+ test("converts a for expression", async () => {
491
+ const expression = `[for record in aws_route53_record.example : record.fqdn]`;
492
+ const scope = getScope();
493
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
494
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""\${[ for record in \${" + example.fqn + "} : record.fqdn]}""`);
495
+ });
496
+ test("converts a data source", async () => {
497
+ const expression = `"\${data.aws_route53_zone.example.zone_id}"`;
498
+ const scope = getScope();
499
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
500
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(example.zoneId)"`);
501
+ });
502
+ test("convert an each expression", async () => {
503
+ const expression = `"\${each.value.name}"`;
504
+ const scope = getScope({ forEachIteratorName: "myIterator" });
505
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
506
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(myIterator.value, ["name"]))"`);
507
+ });
508
+ test("converts a property of a function containing a resource", async () => {
509
+ const expression = `"\${element(aws_s3_bucket.examplebucket, 0).id}"`;
510
+ const scope = getScope();
511
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
512
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(Fn.element(examplebucket, 0), ["id"]))"`);
513
+ });
514
+ test("convert a function with references with splats", async () => {
515
+ const expression = `"\${concat(var.private_subnets.*.id, var.public_subnets.*.id)}"`;
516
+ const scope = getScope({
517
+ variables: ["private_subnets", "public_subnets"],
518
+ });
519
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
520
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.concat([Fn.lookupNested(privateSubnets.value, ["*", "id"]), Fn.lookupNested(publicSubnets.value, ["*", "id"])]))"`);
521
+ });
522
+ test("convert a iterator variable", async () => {
523
+ const expression = `"\${each.key}"`;
524
+ const scope = getScope({
525
+ variables: ["private_subnets", "public_subnets"],
526
+ forEachIteratorName: "myIterator",
527
+ });
528
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
529
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(myIterator.key)"`);
530
+ });
531
+ test("convert a self reference", async () => {
532
+ const expression = `"\${self.subnet.id}"`;
533
+ const scope = getScope({
534
+ variables: ["private_subnets", "public_subnets"],
535
+ forEachIteratorName: "myIterator",
536
+ });
537
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
538
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(TerraformSelf.getAny("subnet.id"))"`);
539
+ });
540
+ test("convert heredocs", async () => {
541
+ const expression = `<<EOF
542
+ [{
543
+ "Condition": {
544
+ "KeyPrefixEquals": "docs/"
545
+ },
546
+ "Redirect": {
547
+ "ReplaceKeyPrefixWith": "documents/"
548
+ }
549
+ }]
550
+ EOF
551
+ `;
552
+ const scope = getScope();
553
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
554
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""[{\\n \\"Condition\\": {\\n \\"KeyPrefixEquals\\": \\"docs/\\"\\n },\\n \\"Redirect\\": {\\n \\"ReplaceKeyPrefixWith\\": \\"documents/\\"\\n }\\n}]\\n""`);
555
+ });
556
+ test("convert heredocs without a trailing newline", async () => {
557
+ const expression = `<<EOF
558
+ hello world
559
+ EOF`;
560
+ const scope = getScope();
561
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
562
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""hello world\\n""`);
563
+ });
564
+ test("convert indented heredocs", async () => {
565
+ const expression = `<<-EOF
566
+ hello world
567
+ EOF`;
568
+ const scope = getScope();
569
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
570
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""hello world\\n""`);
571
+ });
572
+ test("convert override expressions", async () => {
573
+ const expression = '"${required_resource_access.value["resource_access"]}"';
574
+ const scope = getScope({
575
+ withinOverrideExpression: true,
576
+ scopedVariables: {
577
+ required_resource_access: "dynamic-block",
578
+ },
579
+ });
580
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
581
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`""\${required_resource_access.value[\\"resource_access\\"]}""`);
582
+ });
583
+ test("convert using operations while containing substring", async () => {
584
+ const expression =
585
+ // prettier-ignore
586
+ '"${length(var.image_id) > 4 && substr(var.image_id, 0, 4) == \"ami-\"}"';
587
+ const scope = getScope({});
588
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
589
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Op.and(Op.gt(Fn.lengthOf(imageId.value), 4), Op.eq(Fn.substr(imageId.stringValue, 0, 4), "ami-")))"`);
590
+ });
591
+ test("convert a data source with numeric access", async () => {
592
+ const expression = `"\${data.aws_availability_zones.changeme_az_list_ebs_snapshot.names[0]}"`;
593
+ const scope = getScope({
594
+ provider: awsProviderSchema,
595
+ data: ["aws_subnet_ids"],
596
+ });
597
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
598
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(changemeAzListEbsSnapshot.names, ["0"]))"`);
599
+ });
600
+ test("convert a reference to a map access", async () => {
601
+ const expression = `"\${data.aws_availability_zones.changeme_az_list_ebs_snapshot.testing_map.foo}"`;
602
+ const scope = getScope({
603
+ provider: awsProviderSchema,
604
+ data: ["aws_subnet_ids"],
605
+ });
606
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
607
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(changemeAzListEbsSnapshot, ["testing_map", "foo"]))"`);
608
+ });
609
+ test("convert attribute up to a map and not within attribute reference", async () => {
610
+ const expression = `"\${data.aws_availability_zones.changeme_az_list_ebs_snapshot.testing_map}"`;
611
+ const scope = getScope({
612
+ provider: awsProviderSchema,
613
+ });
614
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, () => ["map", "string"]);
615
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asStringMap(changemeAzListEbsSnapshot.testingMap)"`);
616
+ });
617
+ test("don't convert external unknown fields", async () => {
618
+ const expression = `"\${data.external.changeme_external_thumbprint_data.result.thumbprint}"`;
619
+ const scope = getScope({
620
+ provider: externalProviderSchema,
621
+ data: ["aws_subnet_ids"],
622
+ });
623
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, () => ["map", "string"]);
624
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asStringMap(Fn.lookupNested(changemeExternalThumbprintData, ["result", "thumbprint"]))"`);
625
+ });
626
+ test("convert resource reference with map attribute", async () => {
627
+ const expression = `"\${aws_s3_bucket.examplebucket.foo.bar}"`;
628
+ const scope = getScope({
629
+ provider: awsProviderSchema,
630
+ resources: ["aws_s3_bucket"],
631
+ });
632
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, () => "string");
633
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(examplebucket, ["foo", "bar"]))"`);
634
+ });
635
+ test("convert complex variable reference in template", async () => {
636
+ const expression = `"\${var.default_tags.project}-client-tg"`;
637
+ const scope = getScope({
638
+ provider: awsProviderSchema,
639
+ resources: ["aws_s3_bucket"],
640
+ variables: ["default_tags"],
641
+ });
642
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, () => "string");
643
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(defaultTags.value, ["project"])) + "-client-tg""`);
644
+ });
645
+ test("convert boolean values", async () => {
646
+ const expression = `"\${false}"`;
647
+ const scope = getScope({
648
+ provider: awsProviderSchema,
649
+ });
650
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, () => "bool");
651
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"false"`);
652
+ });
653
+ test("convert a data source with count", async () => {
654
+ const expression = `"\${data.aws_availability_zones.available.names[count.index]}"`;
655
+ const scope = getScope({
656
+ provider: awsProviderSchema,
657
+ data: ["aws_availability_zones"],
658
+ });
659
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
660
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.lookupNested(available.names, ["\${count.index}"]))"`);
661
+ });
662
+ test("accept escaped quotes within string", async () => {
663
+ const expression = `"\${jsonencode({
664
+ "Statement" = [{
665
+ "Action" = "s3:*",
666
+ "Effect" = "Allow",
667
+ }],
668
+ })}"`;
669
+ const scope = getScope();
670
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
671
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`
672
+ "Token.asString(Fn.jsonencode({
673
+ "Statement": [{
674
+ "Action": "s3:*",
675
+ "Effect": "Allow"
676
+ }]
677
+ }))"
678
+ `);
679
+ });
680
+ test("support variadic parameters in any position", async () => {
681
+ const expression = `"\${cidrsubnets("fd00:fd12:3456:7890::/56", 16, 16, 16, 32)}"`;
682
+ const scope = getScope();
683
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
684
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"Token.asString(Fn.cidrsubnets("fd00:fd12:3456:7890::/56", [16, 16, 16, 32]))"`);
685
+ });
686
+ test("converts template expression with escaped ${} expression", async () => {
687
+ const expression = '["$${path:name.givenName}"]'; // from aws_ssoadmin_instance_access_control_attributes example
688
+ const scope = getScope();
689
+ const result = await (0, expressions_1.convertTerraformExpressionToTs)(scope, expression, getType);
690
+ expect((0, testHelpers_1.astToCode)(result)).toMatchInlineSnapshot(`"["$\${path:name.givenName}"]"`);
691
+ });
692
+ });
693
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzc2lvblRvVHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9fX3Rlc3RzX18vZXhwcmVzc2lvblRvVHMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztHQUdHOztBQUVILGdEQUFnRTtBQUdoRSwrQ0FBa0Q7QUFFbEQsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixjQUFjLEVBQUUsS0FBSztJQUNyQixnQkFBZ0IsRUFBRTtRQUNoQixxQ0FBcUMsRUFBRTtZQUNyQyxRQUFRLEVBQUUsRUFBRTtZQUNaLGdCQUFnQixFQUFFO2dCQUNoQixhQUFhLEVBQUU7b0JBQ2IsS0FBSyxFQUFFO3dCQUNMLFVBQVUsRUFBRTs0QkFDVixHQUFHLEVBQUU7Z0NBQ0gsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQztnQ0FDdkIsZ0JBQWdCLEVBQUUsT0FBTzs2QkFDMUI7eUJBQ0Y7cUJBQ0Y7aUJBQ0Y7YUFDRjtZQUNELG1CQUFtQixFQUFFO2dCQUNuQixzQkFBc0IsRUFBRTtvQkFDdEIsT0FBTyxFQUFFLENBQUM7b0JBQ1YsS0FBSyxFQUFFO3dCQUNMLFVBQVUsRUFBRTs0QkFDVixzQkFBc0IsRUFBRTtnQ0FDdEIsSUFBSSxFQUFFLE1BQU07Z0NBQ1osZ0JBQWdCLEVBQUUsT0FBTztnQ0FDekIsUUFBUSxFQUFFLElBQUk7NkJBQ2Y7NEJBQ0QsYUFBYSxFQUFFO2dDQUNiLElBQUksRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUM7Z0NBQ3ZCLGdCQUFnQixFQUFFLE9BQU87Z0NBQ3pCLFFBQVEsRUFBRSxJQUFJOzZCQUNmOzRCQUNELGdCQUFnQixFQUFFO2dDQUNoQixJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDO2dDQUN2QixnQkFBZ0IsRUFBRSxPQUFPO2dDQUN6QixRQUFRLEVBQUUsSUFBSTs2QkFDZjs0QkFDRCxXQUFXLEVBQUU7Z0NBQ1gsSUFBSSxFQUFFLENBQUMsS0FB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YykgSGFzaGlDb3JwLCBJbmMuXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTVBMLTIuMFxuICovXG5cbmltcG9ydCB7IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyB9IGZyb20gXCIuLi9leHByZXNzaW9uc1wiO1xuaW1wb3J0IHsgUmVzb3VyY2VTY29wZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgQXR0cmlidXRlVHlwZSB9IGZyb20gXCJAY2RrdG4vY29tbW9uc1wiO1xuaW1wb3J0IHsgYXN0VG9Db2RlIGFzIGNvZGUgfSBmcm9tIFwiLi90ZXN0SGVscGVyc1wiO1xuXG5jb25zdCBhd3NQcm92aWRlclNjaGVtYSA9IHtcbiAgZm9ybWF0X3ZlcnNpb246IFwiMS4wXCIsXG4gIHByb3ZpZGVyX3NjaGVtYXM6IHtcbiAgICBcInJlZ2lzdHJ5LnRlcnJhZm9ybS5pby9oYXNoaWNvcnAvYXdzXCI6IHtcbiAgICAgIHByb3ZpZGVyOiB7fSxcbiAgICAgIHJlc291cmNlX3NjaGVtYXM6IHtcbiAgICAgICAgYXdzX3MzX2J1Y2tldDoge1xuICAgICAgICAgIGJsb2NrOiB7XG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFtcIm1hcFwiLCBcInN0cmluZ1wiXSxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbl9raW5kOiBcInBsYWluXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgZGF0YV9zb3VyY2Vfc2NoZW1hczoge1xuICAgICAgICBhd3NfYXZhaWxhYmlsaXR5X3pvbmVzOiB7XG4gICAgICAgICAgdmVyc2lvbjogMCxcbiAgICAgICAgICBibG9jazoge1xuICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICBhbGxfYXZhaWxhYmlsaXR5X3pvbmVzOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJib29sXCIsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb25fa2luZDogXCJwbGFpblwiLFxuICAgICAgICAgICAgICAgIG9wdGlvbmFsOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBleGNsdWRlX25hbWVzOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogW1wic2V0XCIsIFwic3RyaW5nXCJdLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uX2tpbmQ6IFwicGxhaW5cIixcbiAgICAgICAgICAgICAgICBvcHRpb25hbDogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZXhjbHVkZV96b25lX2lkczoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFtcInNldFwiLCBcInN0cmluZ1wiXSxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbl9raW5kOiBcInBsYWluXCIsXG4gICAgICAgICAgICAgICAgb3B0aW9uYWw6IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGdyb3VwX25hbWVzOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogW1wic2V0XCIsIFwic3RyaW5nXCJdLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uX2tpbmQ6IFwicGxhaW5cIixcbiAgICAgICAgICAgICAgICBjb21wdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgaWQ6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uX2tpbmQ6IFwicGxhaW5cIixcbiAgICAgICAgICAgICAgICBvcHRpb25hbDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjb21wdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbmFtZXM6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBbXCJsaXN0XCIsIFwic3RyaW5nXCJdLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uX2tpbmQ6IFwicGxhaW5cIixcbiAgICAgICAgICAgICAgICBjb21wdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgc3RhdGU6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uX2tpbmQ6IFwicGxhaW5cIixcbiAgICAgICAgICAgICAgICBvcHRpb25hbDogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgem9uZV9pZHM6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBbXCJsaXN0XCIsIFwic3RyaW5nXCJdLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uX2tpbmQ6IFwicGxhaW5cIixcbiAgICAgICAgICAgICAgICBjb21wdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdGVzdGluZ19tYXA6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBbXCJtYXBcIiwgXCJzdHJpbmdcIl0sXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb25fa2luZDogXCJwbGFpblwiLFxuICAgICAgICAgICAgICAgIGNvbXB1dGVkOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJsb2NrX3R5cGVzOiB7XG4gICAgICAgICAgICAgIGZpbHRlcjoge1xuICAgICAgICAgICAgICAgIG5lc3RpbmdfbW9kZTogXCJzZXRcIixcbiAgICAgICAgICAgICAgICBibG9jazoge1xuICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiB7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbl9raW5kOiBcInBsYWluXCIsXG4gICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlczoge1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFtcInNldFwiLCBcInN0cmluZ1wiXSxcbiAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbl9raW5kOiBcInBsYWluXCIsXG4gICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb25fa2luZDogXCJwbGFpblwiLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHRpbWVvdXRzOiB7XG4gICAgICAgICAgICAgICAgbmVzdGluZ19tb2RlOiBcInNpbmdsZVwiLFxuICAgICAgICAgICAgICAgIGJsb2NrOiB7XG4gICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgIHJlYWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uX2tpbmQ6IFwicGxhaW5cIixcbiAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbl9raW5kOiBcInBsYWluXCIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZXNjcmlwdGlvbl9raW5kOiBcInBsYWluXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbn07XG5cbmNvbnN0IGV4dGVybmFsUHJvdmlkZXJTY2hlbWEgPSB7XG4gIGZvcm1hdF92ZXJzaW9uOiBcIjEuMFwiLFxuICBwcm92aWRlcl9zY2hlbWFzOiB7XG4gICAgXCJyZWdpc3RyeS50ZXJyYWZvcm0uaW8vaGFzaGljb3JwL2V4dGVybmFsXCI6IHtcbiAgICAgIHByb3ZpZGVyOiB7fSxcbiAgICAgIHJlc291cmNlX3NjaGVtYXM6IHt9LFxuICAgICAgZGF0YV9zb3VyY2Vfc2NoZW1hczoge1xuICAgICAgICBleHRlcm5hbDoge1xuICAgICAgICAgIHZlcnNpb246IDAsXG4gICAgICAgICAgYmxvY2s6IHtcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgaWQ6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgXCJUaGUgaWQgb2YgdGhlIGRhdGEgc291cmNlLiBUaGlzIHdpbGwgYWx3YXlzIGJlIHNldCB0byBgLWBcIixcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbl9raW5kOiBcInBsYWluXCIsXG4gICAgICAgICAgICAgICAgY29tcHV0ZWQ6IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHByb2dyYW06IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBbXCJsaXN0XCIsIFwic3RyaW5nXCJdLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgXCJBIGxpc3Qgb2Ygc3RyaW5ncywgd2hvc2UgZmlyc3QgZWxlbWVudCBpcyB0aGUgcHJvZ3JhbSB0byBydW4gYW5kIHdob3NlIHN1YnNlcXVlbnQgZWxlbWVudHMgYXJlIG9wdGlvbmFsIGNvbW1hbmQgbGluZSBhcmd1bWVudHMgdG8gdGhlIHByb2dyYW0uIFRlcnJhZm9ybSBkb2VzIG5vdCBleGVjdXRlIHRoZSBwcm9ncmFtIHRocm91Z2ggYSBzaGVsbCwgc28gaXQgaXMgbm90IG5lY2Vzc2FyeSB0byBlc2NhcGUgc2hlbGwgbWV0YWNoYXJhY3RlcnMgbm9yIGFkZCBxdW90ZXMgYXJvdW5kIGFyZ3VtZW50cyBjb250YWluaW5nIHNwYWNlcy5cIixcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbl9raW5kOiBcInBsYWluXCIsXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHF1ZXJ5OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogW1wibWFwXCIsIFwic3RyaW5nXCJdLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgXCJBIG1hcCBvZiBzdHJpbmcgdmFsdWVzIHRvIHBhc3MgdG8gdGhlIGV4dGVybmFsIHByb2dyYW0gYXMgdGhlIHF1ZXJ5IGFyZ3VtZW50cy4gSWYgbm90IHN1cHBsaWVkLCB0aGUgcHJvZ3JhbSB3aWxsIHJlY2VpdmUgYW4gZW1wdHkgb2JqZWN0IGFzIGl0cyBpbnB1dC5cIixcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbl9raW5kOiBcInBsYWluXCIsXG4gICAgICAgICAgICAgICAgb3B0aW9uYWw6IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHJlc3VsdDoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFtcIm1hcFwiLCBcInN0cmluZ1wiXSxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgICAgIFwiQSBtYXAgb2Ygc3RyaW5nIHZhbHVlcyByZXR1cm5lZCBmcm9tIHRoZSBleHRlcm5hbCBwcm9ncmFtLlwiLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uX2tpbmQ6IFwicGxhaW5cIixcbiAgICAgICAgICAgICAgICBjb21wdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgd29ya2luZ19kaXI6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgXCJXb3JraW5nIGRpcmVjdG9yeSBvZiB0aGUgcHJvZ3JhbS4gSWYgbm90IHN1cHBsaWVkLCB0aGUgcHJvZ3JhbSB3aWxsIHJ1biBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuXCIsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb25fa2luZDogXCJwbGFpblwiLFxuICAgICAgICAgICAgICAgIG9wdGlvbmFsOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAnVGhlIGBleHRlcm5hbGAgZGF0YSBzb3VyY2UgYWxsb3dzIGFuIGV4dGVybmFsIHByb2dyYW0gaW1wbGVtZW50aW5nIGEgc3BlY2lmaWMgcHJvdG9jb2wgKGRlZmluZWQgYmVsb3cpIHRvIGFjdCBhcyBhIGRhdGEgc291cmNlLCBleHBvc2luZyBhcmJpdHJhcnkgZGF0YSBmb3IgdXNlIGVsc2V3aGVyZSBpbiB0aGUgVGVycmFmb3JtIGNvbmZpZ3VyYXRpb24uXFxuXFxuKipXYXJuaW5nKiogVGhpcyBtZWNoYW5pc20gaXMgcHJvdmlkZWQgYXMgYW4gXCJlc2NhcGUgaGF0Y2hcIiBmb3IgZXhjZXB0aW9uYWwgc2l0dWF0aW9ucyB3aGVyZSBhIGZpcnN0LWNsYXNzIFRlcnJhZm9ybSBwcm92aWRlciBpcyBub3QgbW9yZSBhcHByb3ByaWF0ZS4gSXRzIGNhcGFiaWxpdGllcyBhcmUgbGltaXRlZCBpbiBjb21wYXJpc29uIHRvIGEgdHJ1ZSBkYXRhIHNvdXJjZSwgYW5kIGltcGxlbWVudGluZyBhIGRhdGEgc291cmNlIHZpYSBhbiBleHRlcm5hbCBwcm9ncmFtIGlzIGxpa2VseSB0byBodXJ0IHRoZSBwb3J0YWJpbGl0eSBvZiB5b3VyIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uIGJ5IGNyZWF0aW5nIGRlcGVuZGVuY2llcyBvbiBleHRlcm5hbCBwcm9ncmFtcyBhbmQgbGlicmFyaWVzIHRoYXQgbWF5IG5vdCBiZSBhdmFpbGFibGUgKG9yIG1heSBuZWVkIHRvIGJlIHVzZWQgZGlmZmVyZW50bHkpIG9uIGRpZmZlcmVudCBvcGVyYXRpbmcgc3lzdGVtcy5cXG5cXG4qKldhcm5pbmcqKiBUZXJyYWZvcm0gRW50ZXJwcmlzZSBkb2VzIG5vdCBndWFyYW50ZWUgYXZhaWxhYmlsaXR5IG9mIGFueSBwYXJ0aWN1bGFyIGxhbmd1YWdlIHJ1bnRpbWVzIG9yIGV4dGVybmFsIHByb2dyYW1zIGJleW9uZCBzdGFuZGFyZCBzaGVsbCB1dGlsaXRpZXMsIHNvIGl0IGlzIG5vdCByZWNvbW1lbmRlZCB0byB1c2UgdGhpcyBkYXRhIHNvdXJjZSB3aXRoaW4gY29uZmlndXJhdGlvbnMgdGhhdCBhcmUgYXBwbGllZCB3aXRoaW4gVGVycmFmb3JtIEVudGVycHJpc2UuJyxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uX2tpbmQ6IFwicGxhaW5cIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxufTtcblxudHlwZSBHZXRTY29wZVBhcmFtcyA9IHtcbiAgcHJvdmlkZXI/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICByZXNvdXJjZXM/OiBzdHJpbmdbXTtcbiAgZGF0YT86IHN0cmluZ1tdO1xuICB2YXJpYWJsZXM/OiBzdHJpbmdbXTtcbiAgbG9jYWxzPzogc3RyaW5nW107XG4gIGZvckVhY2hJdGVyYXRvck5hbWU/OiBzdHJpbmc7XG4gIHdpdGhpbk92ZXJyaWRlRXhwcmVzc2lvbj86IGJvb2xlYW47XG4gIHNjb3BlZFZhcmlhYmxlcz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59O1xuXG5mdW5jdGlvbiBnZXRTY29wZSh7XG4gIHByb3ZpZGVyLFxuICByZXNvdXJjZXMsXG4gIGRhdGEsXG4gIHZhcmlhYmxlcyxcbiAgbG9jYWxzLFxuICBmb3JFYWNoSXRlcmF0b3JOYW1lLFxuICBzY29wZWRWYXJpYWJsZXMsXG4gIHdpdGhpbk92ZXJyaWRlRXhwcmVzc2lvbiA9IGZhbHNlLFxufTogR2V0U2NvcGVQYXJhbXMgPSB7fSk6IFJlc291cmNlU2NvcGUge1xuICBjb25zdCBzY29wZVZhcmlhYmxlczogUmVzb3VyY2VTY29wZVtcInZhcmlhYmxlc1wiXSA9IHt9O1xuXG4gIHJlc291cmNlcz8uZm9yRWFjaCgodmFyTmFtZSkgPT4ge1xuICAgIGxldCBbcmVzb3VyY2VUeXBlLCByZXNvdXJjZU5hbWVdID0gdmFyTmFtZS5zcGxpdChcIi5cIik7XG4gICAgaWYgKCFyZXNvdXJjZU5hbWUpIHtcbiAgICAgIHJlc291cmNlTmFtZSA9IHZhck5hbWU7XG4gICAgICByZXNvdXJjZVR5cGUgPSBcImF3c19zM19idWNrZXRcIjtcbiAgICB9XG5cbiAgICBzY29wZVZhcmlhYmxlc1t2YXJOYW1lXSA9IHtcbiAgICAgIHJlc291cmNlOiByZXNvdXJjZVR5cGUsXG4gICAgICB2YXJpYWJsZU5hbWU6IHJlc291cmNlTmFtZSxcbiAgICB9O1xuICB9KTtcblxuICBkYXRhPy5mb3JFYWNoKCh2YXJOYW1lKSA9PiB7XG4gICAgc2NvcGVWYXJpYWJsZXNbdmFyTmFtZV0gPSB7XG4gICAgICByZXNvdXJjZTogXCJkYXRhLmF3c19zM19idWNrZXRcIixcbiAgICAgIHZhcmlhYmxlTmFtZTogdmFyTmFtZSxcbiAgICB9O1xuICB9KTtcblxuICB2YXJpYWJsZXM/LmZvckVhY2goKHZhck5hbWUpID0+IHtcbiAgICBzY29wZVZhcmlhYmxlc1t2YXJOYW1lXSA9IHtcbiAgICAgIHJlc291cmNlOiBcInZhclwiLFxuICAgICAgdmFyaWFibGVOYW1lOiB2YXJOYW1lLFxuICAgIH07XG4gIH0pO1xuXG4gIGxvY2Fscz8uZm9yRWFjaCgodmFyTmFtZSkgPT4ge1xuICAgIHNjb3BlVmFyaWFibGVzW3Zhck5hbWVdID0ge1xuICAgICAgcmVzb3VyY2U6IFwibG9jYWxcIixcbiAgICAgIHZhcmlhYmxlTmFtZTogdmFyTmFtZSxcbiAgICB9O1xuICB9KTtcblxuICBjb25zdCBzY29wZSA9IHtcbiAgICBwcm92aWRlclNjaGVtYTogcHJvdmlkZXIgPz8ge30sXG4gICAgcHJvdmlkZXJHZW5lcmF0b3I6IHt9LFxuICAgIGNvbnN0cnVjdHM6IG5ldyBTZXQ8c3RyaW5nPigpLFxuICAgIHZhcmlhYmxlczogc2NvcGVWYXJpYWJsZXMsXG4gICAgaGFzVG9rZW5CYXNlZFR5cGVDb2VyY2lvbjogdHJ1ZSxcbiAgICBzY29wZWRWYXJpYWJsZXM6IHNjb3BlZFZhcmlhYmxlcyB8fCB7fSxcbiAgICBmb3JFYWNoSXRlcmF0b3JOYW1lLFxuICAgIHdpdGhpbk92ZXJyaWRlRXhwcmVzc2lvbixcbiAgICBub2RlSWRzOiBbXSxcbiAgICBpbXBvcnRhYmxlczogW10sXG4gICAgdG9wTGV2ZWxDb25maWc6IHt9LFxuICB9O1xuXG4gIHJldHVybiBzY29wZTtcbn1cblxuY29uc3QgZ2V0VHlwZSA9ICgpOiBBdHRyaWJ1dGVUeXBlID0+IFwic3RyaW5nXCI7XG5cbmRlc2NyaWJlKFwiZXhwcmVzc2lvblRvVHNcIiwgKCkgPT4ge1xuICB0ZXN0KFwiY29udmVydHMgYSBzaW1wbGUgc3RyaW5nIHRvIGEgc3RyaW5nXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gXCJoZWxsb1wiO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KGBcIlwiaGVsbG9cIlwiYCk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0cyBhIHNpbXBsZSBleHByZXNzaW9uIHdpdGggYSB0ZW1wbGF0ZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IFwiJHsyMn1cIjtcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKCk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChgXCJUb2tlbi5hc1N0cmluZygyMilcImApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydHMgYSB2YXJpYWJsZSByZWZlcmVuY2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBcIiR7dmFyLmZvb31cIjtcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKCk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChgXCJmb28uc3RyaW5nVmFsdWVcImApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydCBhIHZhcmlhYmxlIHJlZmVyZW5jZSB3aXRoIHNuYWtlIGNhc2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBcIiR7dmFyLmZvb19iYXJ9XCI7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IHZhcmlhYmxlczogW1wiZm9vX2JhclwiXSB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiVG9rZW4uYXNTdHJpbmcoZm9vQmFyLnZhbHVlKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydCBhIGZ1bmN0aW9uIGNhbGxcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBgXFwke3JlcGxhY2UoXCJoZWxsb1wiLCBcImxcIiwgXCJ3XCIpfWA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5yZXBsYWNlKFwiaGVsbG9cIiwgXCJsXCIsIFwid1wiKSlcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnRzIGEgZnVuY3Rpb24gY2FsbCB3aXRoIGFuIGV4cHJlc3Npb25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBgXFwke3JlcGxhY2UoXCJoZWxsby1cXCR7MjIrMjJ9XCIsIFwiNDRcIiwgXCJ3b3JsZFwiKX1gO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiVG9rZW4uYXNTdHJpbmcoRm4ucmVwbGFjZShcImhlbGxvLVwiICsgVG9rZW4uYXNTdHJpbmcoT3AuYWRkKDIyLCAyMikpLCBcIjQ0XCIsIFwid29ybGRcIikpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0cyBzdHJpbmcgY29uY2F0ZW5hdGlvbiBvZiBpdGVyYXRvciBrZXlcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnJHtcImR5bmFtaWMtaW5ncmVzcy0ke2luZ3Jlc3Mua2V5fVwifSc7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7XG4gICAgICBzY29wZWRWYXJpYWJsZXM6IHtcbiAgICAgICAgaW5ncmVzczogXCJkeW5hbWljX2l0ZXJhdG9yMFwiLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiXCJkeW5hbWljLWluZ3Jlc3MtXFwke1wiICsgVG9rZW4uYXNTdHJpbmcoZHluYW1pY19pdGVyYXRvcjAua2V5KSArIFwifVwiXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0IGEgdmFyaWFibGUgcmVmZXJlbmNlXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFxcJHt2YXIuZm9vX2Jhcn1gO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoeyB2YXJpYWJsZXM6IFtcImZvb19iYXJcIl0gfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIC8vIFRPRE86IFRoaXMgc2VlbXMgYnJva2VuXG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiVG9rZW4uYXNTdHJpbmcoZm9vQmFyLnZhbHVlKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydCBhIHJlc291cmNlIHJlZmVyZW5jZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGBcInNpbXBsZS1cXCR7YXdzX3MzX2J1Y2tldC5mb28uaWR9XCJgO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoeyByZXNvdXJjZXM6IFtcImF3c19zM19idWNrZXQuZm9vXCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoYFwiXCJzaW1wbGUtXFwke1wiICsgZm9vLmlkICsgXCJ9XCJcImApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydCBhIHJlc291cmNlIHJlZmVyZW5jZSB3aXRoIG5lc3RlZCBwcm9wZXJ0aWVzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFwic2ltcGxlLVxcJHthd3NfczNfYnVja2V0LmZvby5wcm9wLnRlc3R9XCJgO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoeyByZXNvdXJjZXM6IFtcImF3c19zM19idWNrZXQuZm9vXCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJcInNpbXBsZS1cXCR7XCIgKyBmb28ucHJvcC50ZXN0ICsgXCJ9XCJcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgYSBsb2NhbCByZWZlcmVuY2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBgXCJzaW1wbGUtXFwke2xvY2FsLmZvb31cImA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IGxvY2FsczogW1wiZm9vXCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoYFwiXCJzaW1wbGUtXFwke1wiICsgZm9vICsgXCJ9XCJcImApO1xuICB9KTtcblxuICB0ZXN0KFwicGxhaW4gcmVzb3VyY2UgcmVmZXJlbmNlcyBpbiBhcml0aG1ldGljc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9XG4gICAgICBcIiR7YXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0LmNvdW50ICsgYXdzX3MzX2J1Y2tldC5vdGhlcmJ1Y2tldC5jb3VudCB9XCI7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7XG4gICAgICByZXNvdXJjZXM6IFtcImF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldFwiLCBcImF3c19zM19idWNrZXQub3RoZXJidWNrZXRcIl0sXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nKE9wLmFkZChleGFtcGxlYnVja2V0LmNvdW50LCBvdGhlcmJ1Y2tldC5jb3VudCkpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJ1c2UgZnFuIGZvciBzcGxhdCByZWZlcmVuY2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBgXFwke2F3c19zM19idWNrZXQuZm9vLiouaWR9YDtcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKHsgcmVzb3VyY2VzOiBbXCJhd3NfczNfYnVja2V0LmZvb1wiXSB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiVG9rZW4uYXNTdHJpbmcoRm4ubG9va3VwTmVzdGVkKGZvbywgW1wiKlwiLCBcImlkXCJdKSlcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcInVzZSBmcW4gaWYgcHJvcGVydHkgaXMgcHJlc2VudCBvbiBudW1lcmljIGFjY2VzcyB1c2luZyBkb3Qgbm90YXRpb25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPVxuICAgICAgXCIke2F3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldC5uZXR3b3JrX2ludGVyZmFjZS4wLmFjY2Vzc19jb25maWcuMC5hc3NpZ25lZF9uYXRfaXB9XCI7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IHJlc291cmNlczogW1wiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5sb29rdXBOZXN0ZWQoZXhhbXBsZWJ1Y2tldC5uZXR3b3JrSW50ZXJmYWNlLCBbXCIwXCIsIFwiYWNjZXNzX2NvbmZpZ1wiLCBcIjBcIiwgXCJhc3NpZ25lZF9uYXRfaXBcIl0pKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwidXNlIGZxbiBpZiBwcm9wZXJ0eSBpcyBwcmVzZW50IG9uIG51bWVyaWMgYWNjZXNzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID1cbiAgICAgIFwiJHthd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXQubmV0d29ya19pbnRlcmZhY2VbMF0uYWNjZXNzX2NvbmZpZ1swXS5hc3NpZ25lZF9uYXRfaXB9XCI7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IHJlc291cmNlczogW1wiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5sb29rdXBOZXN0ZWQoZXhhbXBsZWJ1Y2tldC5uZXR3b3JrSW50ZXJmYWNlLCBbXCIwXCIsIFwiYWNjZXNzX2NvbmZpZ1wiLCBcIjBcIiwgXCJhc3NpZ25lZF9uYXRfaXBcIl0pKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwidXNlIG5vIGZxbiBpZiBwcm9wZXJ0eSBpcyBwcmVzZW50IG9uIG51bWVyaWMgYWNjZXNzIHVzaW5nIFtdXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID1cbiAgICAgIFwiJHthd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXQubmV0d29ya19pbnRlcmZhY2VbMF0uYWNjZXNzX2NvbmZpZ1swXS5hc3NpZ25lZF9uYXRfaXB9XCI7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IHJlc291cmNlczogW1wiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5sb29rdXBOZXN0ZWQoZXhhbXBsZWJ1Y2tldC5uZXR3b3JrSW50ZXJmYWNlLCBbXCIwXCIsIFwiYWNjZXNzX2NvbmZpZ1wiLCBcIjBcIiwgXCJhc3NpZ25lZF9uYXRfaXBcIl0pKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiZGV0ZWN0cyBzcGxhdCByZWZlcmVuY2Ugd2l0aGluIGZ1bmN0aW9uXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gXCIke3Rvc2V0KGF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldC4qKX1cIjtcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKHsgcmVzb3VyY2VzOiBbXCJhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRcIl0gfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nKEZuLnRvc2V0KEZuLmxvb2t1cE5lc3RlZChleGFtcGxlYnVja2V0LCBbXCIqXCJdKSkpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0IGNvbmRpdGlvbmFsXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID1cbiAgICAgIFwiJHthd3Nfa21zX2tleS5rZXkuZGVsZXRpb25fd2luZG93X2luX2RheXMgPiAzID8gYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0LmlkIDogW119XCI7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IHJlc291cmNlczogW1wiYXdzX2ttc19rZXkua2V5XCIsIFwiZXhhbXBsZWJ1Y2tldFwiXSB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiVG9rZW4uYXNTdHJpbmcoY29uZGl0aW9uYWwoT3AuZ3Qoa2V5LmRlbGV0aW9uV2luZG93SW5EYXlzLCAzKSwgZXhhbXBsZWJ1Y2tldC5pZCwgW10pKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydHMgYSBmdW5jdGlvbiB3aXRoIHJlZmVyZW5jZXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBcIiR7ZWxlbWVudChhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXQsIDApLmlkfVwiO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoeyByZXNvdXJjZXM6IFtcImF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldFwiXSB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiVG9rZW4uYXNTdHJpbmcoRm4ubG9va3VwTmVzdGVkKEZuLmVsZW1lbnQoZXhhbXBsZWJ1Y2tldCwgMCksIFtcImlkXCJdKSlcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnRzIGEgZnVuY3Rpb24gd2l0aCBzcGxhdCByZWZlcmVuY2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBcIiR7ZWxlbWVudChhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXQuKi5pZCwgMCl9XCI7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IHJlc291cmNlczogW1wiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5lbGVtZW50KEZuLmxvb2t1cE5lc3RlZChleGFtcGxlYnVja2V0LCBbXCIqXCIsIFwiaWRcIl0pLCAwKSlcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgZm9yIGxvb3BzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID1cbiAgICAgIFwiJHt7IGZvciBuYW1lLCB1c2VyIGluIHZhci51c2VycyA6IHVzZXIucm9sZSA9PiBuYW1lLi4ufX1cIjtcblxuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiXCJcXCR7eyBmb3IgbmFtZSwgdXNlciBpbiBcXCR7XCIgKyB1c2Vycy52YWx1ZSArIFwifSA6IHVzZXIucm9sZSA9PiBuYW1lLi4ufX1cIlwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiZm9yIGV4cHJlc3Npb25zXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gXCJ7Zm9yIHMgaW4gdmFyLmxpc3QgOiBzID0+IHVwcGVyKHMpfVwiO1xuXG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJcIlxcJHt7IGZvciBzIGluIFxcJHtcIiArIGxpc3QudmFsdWUgKyBcIn0gOiBzID0+IHVwcGVyKHMpfX1cIlwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiZm9yIGxpc3QgZXhwcmVzc2lvbiBcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBcIltmb3IgcyBpbiB2YXIubGlzdCA6IHVwcGVyKHMpXVwiO1xuXG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJcIlxcJHtbIGZvciBzIGluIFxcJHtcIiArIGxpc3QudmFsdWUgKyBcIn0gOiB1cHBlcihzKV19XCJcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImZvciBsaXN0IHdpdGggY29uZGl0aW9uYWxcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnW2ZvciBzIGluIHZhci5saXN0IDogdXBwZXIocykgaWYgcyAhPSBcIlwiXSc7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJcIlxcJHtbIGZvciBzIGluIFxcJHtcIiArIGxpc3QudmFsdWUgKyBcIn0gOiB1cHBlcihzKSBpZiBzICE9IFxcXFxcIlxcXFxcIl19XCJcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgcHJvcGVydHkgYWNjZXNzIHJlc291cmNlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IFwiJHthd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRbMF0uaWR9XCI7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IHJlc291cmNlczogW1wiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5sb29rdXBOZXN0ZWQoZXhhbXBsZWJ1Y2tldCwgW1wiMFwiLCBcImlkXCJdKSlcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgdW5hcnkgb3BlcmF0b3JzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFxcJHshdmFyLmVuYWJsZWR9YDtcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKHsgdmFyaWFibGVzOiBbXCJlbmFibGVkXCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgICgpID0+IFwiYm9vbFwiLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiVG9rZW4uYXNCb29sZWFuKE9wLm5vdChlbmFibGVkLnZhbHVlKSlcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgZnVuY3Rpb24gd2l0aCBhcnJheXMgYW5kIGNvbW1lbnRzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFxcJHtjb21wYWN0KFtcbiAgICAgICAgICAgICMgVGhlIGV4YW1wbGUgXCJidWNrZXRcIlxuICAgICAgICAgICAgYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0LFxuICAgICAgICBcbiAgICAgICAgICAgICMgVGhlIFwiTGVhcm5cIiBzaW5nbGUgcGFnZSBhcHBsaWNhdGlvbi4gVGhpcyBpcyBub3QgY29uZmlndXJlZCBpbiBhbGwgZW52aXJvbm1lbnRzLlxuICAgICAgICAgICAgdmFyLmlucHV0LFxuICAgICAgICAgIF0pfWA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7XG4gICAgICByZXNvdXJjZXM6IFtcImF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldFwiXSxcbiAgICAgIHZhcmlhYmxlczogW1wiaW5wdXRcIl0sXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIC8vIFRPRE86IFNlZSBpZiB3ZSBoYXZlIGEgd2F5IHRvIHByZXNlcnZlIGNvbW1lbnRzXG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiVG9rZW4uYXNTdHJpbmcoRm4uY29tcGFjdChUb2tlbi5hc0xpc3QoW2V4YW1wbGVidWNrZXQsIGlucHV0LnZhbHVlXSkpKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydCByZWZlcmVuY2VzIGZvciBzYW1lIHJlZmVyZW5jZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGBcXCR7dmFyLmlucHV0ID09IFwidGVzdFwiID8gXCJhenVyZS1hZC1pbnRcIiA6IFwiYXp1cmUtYWQtXFwke3Zhci5pbnB1dH1cIn1gO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoeyB2YXJpYWJsZXM6IFtcImlucHV0XCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhjb25kaXRpb25hbChPcC5lcShpbnB1dC52YWx1ZSwgXCJ0ZXN0XCIpLCBcImF6dXJlLWFkLWludFwiLCBcImF6dXJlLWFkLVxcJHtcIiArIGlucHV0LnZhbHVlICsgXCJ9XCIpKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwibmVzdGVkIHZhcmlhYmxlIGFjY2Vzc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGBcXCR7ZWxlbWVudCh2YXIudGVzdDJbXCJ2YWwxXCJdLCAwKX1gO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoeyB2YXJpYWJsZXM6IFtcInRlc3QyXCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5lbGVtZW50KEZuLmxvb2t1cE5lc3RlZCh0ZXN0Mi52YWx1ZSwgW1wiXFxcXFwidmFsMVxcXFxcIlwiXSksIDApKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29tcGxpY2F0ZWQgbmVzdGVkIGxvY2FsIHZhbHVlXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gXCIke2ZsYXR0ZW4odmFyLnZuZXRzWypdLnN1Ym5ldHNbKl0ubmFtZSl9XCI7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IHZhcmlhYmxlczogW1widm5ldHNcIl0gfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nKEZuLmZsYXR0ZW4oRm4ubG9va3VwTmVzdGVkKHZuZXRzLnZhbHVlLCBbXCIqXCIsIFwic3VibmV0c1wiLCBcIipcIiwgXCJuYW1lXCJdKSkpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIC8vIFRPSU1QUk9WRTogSSBkb24ndCB0aGluayB3ZSBjYW4gaGFuZGxlIHRoaXMgY2FzZSB5ZXQsIHNpbmNlIHRoZSB2YXJpYWJsZVxuICAvLyBuZWVkcyB0byBiZSB3cmFwcGVkIGluIGFuIGl0ZXJhdG9yLiBJJ20gbGVhdmluZyB0aGlzIGluLCBidXQgaXQncyBicm9rZW5cbiAgdGVzdChcImNvbXBsaWNhdGVkIG5lc3RlZCB2YXJpYWJsZSBhY2Nlc3Mgd2l0aCBtYXBcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBgeyBcbiAgICBmb3Igdm5ldCBpbiB2YXIudm5ldHNbKl06XG4gICAgKHZuZXQudm5ldF9uYW1lKSA9PiB2bmV0LnN1Ym5ldHNbKl0ubmFtZVxuICB9YDtcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKHsgdmFyaWFibGVzOiBbXCJ2bmV0c1wiXSB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiXCJcXCR7eyBmb3Igdm5ldCBpbiBcXCR7XCIgKyBGbi5sb29rdXBOZXN0ZWQodm5ldHMudmFsdWUsIFtcIipcIl0pICsgXCJ9IDogKHZuZXQudm5ldF9uYW1lKSA9PiB2bmV0LnN1Ym5ldHNbKl0ubmFtZX19XCJcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbXBsaWNhdGVkIG5lc3RlZCB2YXJpYWJsZSBhY2Nlc3Mgd2l0aCBsaXN0XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFxcJHtmbGF0dGVuKFtcbiAgICBmb3IgaywgdiBpbiB2YXIucm91dGUgOiBbXG4gICAgICBmb3IgbiwgcyBpbiB2IDogW1xuICAgICAgICB7XG4gICAgICAgICAga2V5ID0gayxcbiAgICAgICAgICBuYW1lID0gbixcbiAgICAgICAgICBzdmNfdXJsID0gc1xuICAgICAgICB9XG4gICAgICBdXG4gICAgXVxuICBdKX1gO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoeyB2YXJpYWJsZXM6IFtcInJvdXRlXCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5mbGF0dGVuKFwiXFwke1sgZm9yIGssIHYgaW4gXFwke1wiICsgcm91dGUudmFsdWUgKyBcIn0gOiBbXFxcXG4gICAgICBmb3IgbiwgcyBpbiB2IDogW1xcXFxuICAgICAgICB7XFxcXG4gICAgICAgICAga2V5ID0gayxcXFxcbiAgICAgICAgICBuYW1lID0gbixcXFxcbiAgICAgICAgICBzdmNfdXJsID0gc1xcXFxuICAgICAgICB9XFxcXG4gICAgICBdXFxcXG4gICAgXV19XCIpKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwic2ltcGxlIGxvY2FsIHZhcmlhYmxlIGFjY2Vzc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IFwiJHshbG9jYWwuZW5hYmxlZH1cIjtcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKHsgbG9jYWxzOiBbXCJlbmFibGVkXCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhPcC5ub3QoZW5hYmxlZCkpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJtdWx0aSBsb2NhbCBhY2Nlc3NcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPVxuICAgICAgJ1wiJHtsb2NhbC5zZXJ2aWNlX25hbWV9LCR7bG9jYWwub3duZXJ9LCR7bG9jYWwuaXNfaXRfZ3JlYXR9LCR7bG9jYWwuaG93X21hbnl9XCInO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoe1xuICAgICAgbG9jYWxzOiBbXCJzZXJ2aWNlX25hbWVcIiwgXCJvd25lclwiLCBcImlzX2l0X2dyZWF0XCIsIFwiaG93X21hbnlcIl0sXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlwiXFwke1wiICsgc2VydmljZU5hbWUgKyBcIn0sXFwke1wiICsgb3duZXIgKyBcIn0sXFwke1wiICsgaXNJdEdyZWF0ICsgXCJ9LFxcJHtcIiArIGhvd01hbnkgKyBcIn1cIlwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiYmluYXJ5IG9wZXJhdGlvbnMgd2l0aGluIGxpdGVyYWxzIGFuZCB2YXJpYWJsZXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnXCIke3Zhci50ZXN0fSArIDFcIic7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IHZhcmlhYmxlczogW1widGVzdFwiXSB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiXCJcXCR7XCIgKyB0ZXN0LnZhbHVlICsgXCJ9ICsgMVwiXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJsb2NhbCB2YXJpYWJsZSBhY2Nlc3NcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnXCIke2xvY2FsLmVuYWJsZWR9XCInO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoeyBsb2NhbHM6IFtcImVuYWJsZWRcIl0gfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChgXCJlbmFibGVkXCJgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnRzIHRyYXZlcnNhbHMgdGhhdCBjYW5ub3QgYmUgcmVmZXJlbmNlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IFwiJHtzZWxmLnBhdGh9XCI7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhUZXJyYWZvcm1TZWxmLmdldEFueShcInBhdGhcIikpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0cyBqb2luIGZ1bmN0aW9uIHdpdGggdmFyaWFibGVzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gJyR7am9pbihcIi1cIiwgW3Zhci50YWdzLmFwcCwgdmFyLnRhZ3MuZW52XSl9JztcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKHsgdmFyaWFibGVzOiBbXCJ0YWdzXCJdIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5qb2luKFwiLVwiLCBUb2tlbi5hc0xpc3QoW0ZuLmxvb2t1cE5lc3RlZCh0YWdzLnZhbHVlLCBbXCJhcHBcIl0pLCBGbi5sb29rdXBOZXN0ZWQodGFncy52YWx1ZSwgW1wiZW52XCJdKV0pKSlcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnRzIGpvaW4gZnVuY3Rpb24gd2l0aCBtYW55IGFyZ3VtZW50cyB2YXJpYWJsZXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPVxuICAgICAgJyR7am9pbihcIi1cIiwgdmFyLnRhZ3MuYXBwLCB2YXIudGFncy5lbnYsIHZhci50YWdzLm90aGVyKX0nO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoeyB2YXJpYWJsZXM6IFtcInRhZ3NcIl0gfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nKEZuLmpvaW4oXCItXCIsIFRva2VuLmFzTGlzdChGbi5jb25jYXQoW0ZuLmxvb2t1cE5lc3RlZCh0YWdzLnZhbHVlLCBbXCJhcHBcIl0pLCBGbi5sb29rdXBOZXN0ZWQodGFncy52YWx1ZSwgW1wiZW52XCJdKSwgRm4ubG9va3VwTmVzdGVkKHRhZ3MudmFsdWUsIFtcIm90aGVyXCJdKV0pKSkpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJkb2Vzbid0IHdyYXAgYW55IGV4dHJhIHRlbXBsYXRlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGBcImFwcC1cXCR7dGVycmFmb3JtLndvcmtzcGFjZX1cImA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJcImFwcC1cXCR7dGVycmFmb3JtLndvcmtzcGFjZX1cIlwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydHMgYSBmb3IgZXhwcmVzc2lvblwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGBbZm9yIHJlY29yZCBpbiBhd3Nfcm91dGU1M19yZWNvcmQuZXhhbXBsZSA6IHJlY29yZC5mcWRuXWA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJcIlxcJHtbIGZvciByZWNvcmQgaW4gXFwke1wiICsgZXhhbXBsZS5mcW4gKyBcIn0gOiByZWNvcmQuZnFkbl19XCJcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnRzIGEgZGF0YSBzb3VyY2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBgXCJcXCR7ZGF0YS5hd3Nfcm91dGU1M196b25lLmV4YW1wbGUuem9uZV9pZH1cImA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhleGFtcGxlLnpvbmVJZClcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgYW4gZWFjaCBleHByZXNzaW9uXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFwiXFwke2VhY2gudmFsdWUubmFtZX1cImA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7IGZvckVhY2hJdGVyYXRvck5hbWU6IFwibXlJdGVyYXRvclwiIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5sb29rdXBOZXN0ZWQobXlJdGVyYXRvci52YWx1ZSwgW1wibmFtZVwiXSkpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0cyBhIHByb3BlcnR5IG9mIGEgZnVuY3Rpb24gY29udGFpbmluZyBhIHJlc291cmNlXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFwiXFwke2VsZW1lbnQoYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0LCAwKS5pZH1cImA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhGbi5sb29rdXBOZXN0ZWQoRm4uZWxlbWVudChleGFtcGxlYnVja2V0LCAwKSwgW1wiaWRcIl0pKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydCBhIGZ1bmN0aW9uIHdpdGggcmVmZXJlbmNlcyB3aXRoIHNwbGF0c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGBcIlxcJHtjb25jYXQodmFyLnByaXZhdGVfc3VibmV0cy4qLmlkLCB2YXIucHVibGljX3N1Ym5ldHMuKi5pZCl9XCJgO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoe1xuICAgICAgdmFyaWFibGVzOiBbXCJwcml2YXRlX3N1Ym5ldHNcIiwgXCJwdWJsaWNfc3VibmV0c1wiXSxcbiAgICB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiVG9rZW4uYXNTdHJpbmcoRm4uY29uY2F0KFtGbi5sb29rdXBOZXN0ZWQocHJpdmF0ZVN1Ym5ldHMudmFsdWUsIFtcIipcIiwgXCJpZFwiXSksIEZuLmxvb2t1cE5lc3RlZChwdWJsaWNTdWJuZXRzLnZhbHVlLCBbXCIqXCIsIFwiaWRcIl0pXSkpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0IGEgaXRlcmF0b3IgdmFyaWFibGVcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBgXCJcXCR7ZWFjaC5rZXl9XCJgO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoe1xuICAgICAgdmFyaWFibGVzOiBbXCJwcml2YXRlX3N1Ym5ldHNcIiwgXCJwdWJsaWNfc3VibmV0c1wiXSxcbiAgICAgIGZvckVhY2hJdGVyYXRvck5hbWU6IFwibXlJdGVyYXRvclwiLFxuICAgIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhteUl0ZXJhdG9yLmtleSlcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgYSBzZWxmIHJlZmVyZW5jZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGBcIlxcJHtzZWxmLnN1Ym5ldC5pZH1cImA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7XG4gICAgICB2YXJpYWJsZXM6IFtcInByaXZhdGVfc3VibmV0c1wiLCBcInB1YmxpY19zdWJuZXRzXCJdLFxuICAgICAgZm9yRWFjaEl0ZXJhdG9yTmFtZTogXCJteUl0ZXJhdG9yXCIsXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nKFRlcnJhZm9ybVNlbGYuZ2V0QW55KFwic3VibmV0LmlkXCIpKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydCBoZXJlZG9jc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGA8PEVPRlxuW3tcbiAgICBcIkNvbmRpdGlvblwiOiB7XG4gICAgICAgIFwiS2V5UHJlZml4RXF1YWxzXCI6IFwiZG9jcy9cIlxuICAgIH0sXG4gICAgXCJSZWRpcmVjdFwiOiB7XG4gICAgICAgIFwiUmVwbGFjZUtleVByZWZpeFdpdGhcIjogXCJkb2N1bWVudHMvXCJcbiAgICB9XG59XVxuRU9GXG5gO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiXCJbe1xcXFxuICAgIFxcXFxcIkNvbmRpdGlvblxcXFxcIjoge1xcXFxuICAgICAgICBcXFxcXCJLZXlQcmVmaXhFcXVhbHNcXFxcXCI6IFxcXFxcImRvY3MvXFxcXFwiXFxcXG4gICAgfSxcXFxcbiAgICBcXFxcXCJSZWRpcmVjdFxcXFxcIjoge1xcXFxuICAgICAgICBcXFxcXCJSZXBsYWNlS2V5UHJlZml4V2l0aFxcXFxcIjogXFxcXFwiZG9jdW1lbnRzL1xcXFxcIlxcXFxuICAgIH1cXFxcbn1dXFxcXG5cIlwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydCBoZXJlZG9jcyB3aXRob3V0IGEgdHJhaWxpbmcgbmV3bGluZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGA8PEVPRlxuaGVsbG8gd29ybGRcbkVPRmA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoYFwiXCJoZWxsbyB3b3JsZFxcXFxuXCJcImApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydCBpbmRlbnRlZCBoZXJlZG9jc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGA8PC1FT0ZcbiAgICAgICAgICAgICAgaGVsbG8gd29ybGRcbiAgICAgICAgICBFT0ZgO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICBnZXRUeXBlLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KGBcIlwiaGVsbG8gd29ybGRcXFxcblwiXCJgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgb3ZlcnJpZGUgZXhwcmVzc2lvbnNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnXCIke3JlcXVpcmVkX3Jlc291cmNlX2FjY2Vzcy52YWx1ZVtcInJlc291cmNlX2FjY2Vzc1wiXX1cIic7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7XG4gICAgICB3aXRoaW5PdmVycmlkZUV4cHJlc3Npb246IHRydWUsXG4gICAgICBzY29wZWRWYXJpYWJsZXM6IHtcbiAgICAgICAgcmVxdWlyZWRfcmVzb3VyY2VfYWNjZXNzOiBcImR5bmFtaWMtYmxvY2tcIixcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlwiXFwke3JlcXVpcmVkX3Jlc291cmNlX2FjY2Vzcy52YWx1ZVtcXFxcXCJyZXNvdXJjZV9hY2Nlc3NcXFxcXCJdfVwiXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0IHVzaW5nIG9wZXJhdGlvbnMgd2hpbGUgY29udGFpbmluZyBzdWJzdHJpbmdcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPVxuICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAnXCIke2xlbmd0aCh2YXIuaW1hZ2VfaWQpID4gNCAmJiBzdWJzdHIodmFyLmltYWdlX2lkLCAwLCA0KSA9PSBcXFwiYW1pLVxcXCJ9XCInO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoe30pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoXG4gICAgICBgXCJUb2tlbi5hc1N0cmluZyhPcC5hbmQoT3AuZ3QoRm4ubGVuZ3RoT2YoaW1hZ2VJZC52YWx1ZSksIDQpLCBPcC5lcShGbi5zdWJzdHIoaW1hZ2VJZC5zdHJpbmdWYWx1ZSwgMCwgNCksIFwiYW1pLVwiKSkpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0IGEgZGF0YSBzb3VyY2Ugd2l0aCBudW1lcmljIGFjY2Vzc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IGBcIlxcJHtkYXRhLmF3c19hdmFpbGFiaWxpdHlfem9uZXMuY2hhbmdlbWVfYXpfbGlzdF9lYnNfc25hcHNob3QubmFtZXNbMF19XCJgO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoe1xuICAgICAgcHJvdmlkZXI6IGF3c1Byb3ZpZGVyU2NoZW1hLFxuICAgICAgZGF0YTogW1wiYXdzX3N1Ym5ldF9pZHNcIl0sXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nKEZuLmxvb2t1cE5lc3RlZChjaGFuZ2VtZUF6TGlzdEVic1NuYXBzaG90Lm5hbWVzLCBbXCIwXCJdKSlcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgYSByZWZlcmVuY2UgdG8gYSBtYXAgYWNjZXNzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFwiXFwke2RhdGEuYXdzX2F2YWlsYWJpbGl0eV96b25lcy5jaGFuZ2VtZV9hel9saXN0X2Vic19zbmFwc2hvdC50ZXN0aW5nX21hcC5mb299XCJgO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoe1xuICAgICAgcHJvdmlkZXI6IGF3c1Byb3ZpZGVyU2NoZW1hLFxuICAgICAgZGF0YTogW1wiYXdzX3N1Ym5ldF9pZHNcIl0sXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nKEZuLmxvb2t1cE5lc3RlZChjaGFuZ2VtZUF6TGlzdEVic1NuYXBzaG90LCBbXCJ0ZXN0aW5nX21hcFwiLCBcImZvb1wiXSkpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0IGF0dHJpYnV0ZSB1cCB0byBhIG1hcCBhbmQgbm90IHdpdGhpbiBhdHRyaWJ1dGUgcmVmZXJlbmNlXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFwiXFwke2RhdGEuYXdzX2F2YWlsYWJpbGl0eV96b25lcy5jaGFuZ2VtZV9hel9saXN0X2Vic19zbmFwc2hvdC50ZXN0aW5nX21hcH1cImA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSh7XG4gICAgICBwcm92aWRlcjogYXdzUHJvdmlkZXJTY2hlbWEsXG4gICAgfSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICAoKSA9PiBbXCJtYXBcIiwgXCJzdHJpbmdcIl0sXG4gICAgKTtcblxuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nTWFwKGNoYW5nZW1lQXpMaXN0RWJzU25hcHNob3QudGVzdGluZ01hcClcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImRvbid0IGNvbnZlcnQgZXh0ZXJuYWwgdW5rbm93biBmaWVsZHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBgXCJcXCR7ZGF0YS5leHRlcm5hbC5jaGFuZ2VtZV9leHRlcm5hbF90aHVtYnByaW50X2RhdGEucmVzdWx0LnRodW1icHJpbnR9XCJgO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoe1xuICAgICAgcHJvdmlkZXI6IGV4dGVybmFsUHJvdmlkZXJTY2hlbWEsXG4gICAgICBkYXRhOiBbXCJhd3Nfc3VibmV0X2lkc1wiXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgICgpID0+IFtcIm1hcFwiLCBcInN0cmluZ1wiXSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nTWFwKEZuLmxvb2t1cE5lc3RlZChjaGFuZ2VtZUV4dGVybmFsVGh1bWJwcmludERhdGEsIFtcInJlc3VsdFwiLCBcInRodW1icHJpbnRcIl0pKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydCByZXNvdXJjZSByZWZlcmVuY2Ugd2l0aCBtYXAgYXR0cmlidXRlXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFwiXFwke2F3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldC5mb28uYmFyfVwiYDtcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKHtcbiAgICAgIHByb3ZpZGVyOiBhd3NQcm92aWRlclNjaGVtYSxcbiAgICAgIHJlc291cmNlczogW1wiYXdzX3MzX2J1Y2tldFwiXSxcbiAgICB9KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICAoKSA9PiBcInN0cmluZ1wiLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiVG9rZW4uYXNTdHJpbmcoRm4ubG9va3VwTmVzdGVkKGV4YW1wbGVidWNrZXQsIFtcImZvb1wiLCBcImJhclwiXSkpXCJgLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJjb252ZXJ0IGNvbXBsZXggdmFyaWFibGUgcmVmZXJlbmNlIGluIHRlbXBsYXRlXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFwiXFwke3Zhci5kZWZhdWx0X3RhZ3MucHJvamVjdH0tY2xpZW50LXRnXCJgO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoe1xuICAgICAgcHJvdmlkZXI6IGF3c1Byb3ZpZGVyU2NoZW1hLFxuICAgICAgcmVzb3VyY2VzOiBbXCJhd3NfczNfYnVja2V0XCJdLFxuICAgICAgdmFyaWFibGVzOiBbXCJkZWZhdWx0X3RhZ3NcIl0sXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgKCkgPT4gXCJzdHJpbmdcIixcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nKEZuLmxvb2t1cE5lc3RlZChkZWZhdWx0VGFncy52YWx1ZSwgW1wicHJvamVjdFwiXSkpICsgXCItY2xpZW50LXRnXCJcImAsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgYm9vbGVhbiB2YWx1ZXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBgXCJcXCR7ZmFsc2V9XCJgO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0U2NvcGUoe1xuICAgICAgcHJvdmlkZXI6IGF3c1Byb3ZpZGVyU2NoZW1hLFxuICAgIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgICgpID0+IFwiYm9vbFwiLFxuICAgICk7XG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KGBcImZhbHNlXCJgKTtcbiAgfSk7XG5cbiAgdGVzdChcImNvbnZlcnQgYSBkYXRhIHNvdXJjZSB3aXRoIGNvdW50XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFwiXFwke2RhdGEuYXdzX2F2YWlsYWJpbGl0eV96b25lcy5hdmFpbGFibGUubmFtZXNbY291bnQuaW5kZXhdfVwiYDtcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKHtcbiAgICAgIHByb3ZpZGVyOiBhd3NQcm92aWRlclNjaGVtYSxcbiAgICAgIGRhdGE6IFtcImF3c19hdmFpbGFiaWxpdHlfem9uZXNcIl0sXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nKEZuLmxvb2t1cE5lc3RlZChhdmFpbGFibGUubmFtZXMsIFtcIlxcJHtjb3VudC5pbmRleH1cIl0pKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiYWNjZXB0IGVzY2FwZWQgcXVvdGVzIHdpdGhpbiBzdHJpbmdcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBgXCJcXCR7anNvbmVuY29kZSh7XG4gICAgICAgICAgXCJTdGF0ZW1lbnRcIiA9IFt7XG4gICAgICAgICAgICBcIkFjdGlvblwiID0gXCJzMzoqXCIsXG4gICAgICAgICAgICBcIkVmZmVjdFwiID0gXCJBbGxvd1wiLFxuICAgICAgICAgIH1dLFxuICAgICAgICB9KX1cImA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcbiAgICBleHBlY3QoY29kZShyZXN1bHQpKS50b01hdGNoSW5saW5lU25hcHNob3QoYFxuICAgICAgXCJUb2tlbi5hc1N0cmluZyhGbi5qc29uZW5jb2RlKHtcbiAgICAgICAgXCJTdGF0ZW1lbnRcIjogW3tcbiAgICAgICAgICBcIkFjdGlvblwiOiBcInMzOipcIixcbiAgICAgICAgICBcIkVmZmVjdFwiOiBcIkFsbG93XCJcbiAgICAgICAgfV1cbiAgICAgIH0pKVwiXG4gICAgYCk7XG4gIH0pO1xuXG4gIHRlc3QoXCJzdXBwb3J0IHZhcmlhZGljIHBhcmFtZXRlcnMgaW4gYW55IHBvc2l0aW9uXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gYFwiXFwke2NpZHJzdWJuZXRzKFwiZmQwMDpmZDEyOjM0NTY6Nzg5MDo6LzU2XCIsIDE2LCAxNiwgMTYsIDMyKX1cImA7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGdldFR5cGUsXG4gICAgKTtcblxuICAgIGV4cGVjdChjb2RlKHJlc3VsdCkpLnRvTWF0Y2hJbmxpbmVTbmFwc2hvdChcbiAgICAgIGBcIlRva2VuLmFzU3RyaW5nKEZuLmNpZHJzdWJuZXRzKFwiZmQwMDpmZDEyOjM0NTY6Nzg5MDo6LzU2XCIsIFsxNiwgMTYsIDE2LCAzMl0pKVwiYCxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KFwiY29udmVydHMgdGVtcGxhdGUgZXhwcmVzc2lvbiB3aXRoIGVzY2FwZWQgJHt9IGV4cHJlc3Npb25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSAnW1wiJCR7cGF0aDpuYW1lLmdpdmVuTmFtZX1cIl0nOyAvLyBmcm9tIGF3c19zc29hZG1pbl9pbnN0YW5jZV9hY2Nlc3NfY29udHJvbF9hdHRyaWJ1dGVzIGV4YW1wbGVcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKCk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICAgICAgc2NvcGUsXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgZ2V0VHlwZSxcbiAgICApO1xuXG4gICAgZXhwZWN0KGNvZGUocmVzdWx0KSkudG9NYXRjaElubGluZVNuYXBzaG90KFxuICAgICAgYFwiW1wiJFxcJHtwYXRoOm5hbWUuZ2l2ZW5OYW1lfVwiXVwiYCxcbiAgICApO1xuICB9KTtcbn0pO1xuIl19