@aws-mdaa/dataops-job-l3-construct 1.5.0 → 1.6.0

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 (90) hide show
  1. package/.jsii +38 -28
  2. package/README.md +5 -0
  3. package/lib/dataops-job-l3-construct.d.ts +8 -1
  4. package/lib/dataops-job-l3-construct.js +40 -13
  5. package/node_modules/@aws-mdaa/config/README.md +3 -0
  6. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.d.ts +20 -0
  7. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.js +70 -0
  8. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.ts +88 -0
  9. package/node_modules/@aws-mdaa/config/lib/config.d.ts +87 -0
  10. package/node_modules/@aws-mdaa/config/lib/config.js +7 -0
  11. package/node_modules/@aws-mdaa/config/lib/config.ts +92 -0
  12. package/node_modules/@aws-mdaa/config/lib/index.d.ts +11 -0
  13. package/node_modules/@aws-mdaa/config/lib/index.js +28 -0
  14. package/node_modules/@aws-mdaa/config/lib/index.ts +12 -0
  15. package/node_modules/@aws-mdaa/config/lib/param-transformer.d.ts +49 -0
  16. package/node_modules/@aws-mdaa/config/lib/param-transformer.js +160 -0
  17. package/node_modules/@aws-mdaa/config/lib/param-transformer.ts +159 -0
  18. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.d.ts +10 -0
  19. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.js +30 -0
  20. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.ts +27 -0
  21. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.d.ts +44 -0
  22. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.js +243 -0
  23. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.ts +302 -0
  24. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.d.ts +8 -0
  25. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.js +22 -0
  26. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.ts +21 -0
  27. package/node_modules/@aws-mdaa/config/lib/transformer.d.ts +35 -0
  28. package/node_modules/@aws-mdaa/config/lib/transformer.js +66 -0
  29. package/node_modules/@aws-mdaa/config/lib/transformer.ts +74 -0
  30. package/node_modules/@aws-mdaa/config/package.json +42 -0
  31. package/node_modules/@aws-mdaa/config/test/blueprint-value-transformer.test.js +224 -0
  32. package/node_modules/@aws-mdaa/config/test/blueprint-value-transformer.test.ts +259 -0
  33. package/node_modules/@aws-mdaa/config/test/config-nt.test.d.ts +5 -0
  34. package/node_modules/@aws-mdaa/config/test/config-nt.test.js +129 -0
  35. package/node_modules/@aws-mdaa/config/test/config-nt.test.ts +163 -0
  36. package/node_modules/@aws-mdaa/config/test/config.test.d.ts +5 -0
  37. package/node_modules/@aws-mdaa/config/test/config.test.js +409 -0
  38. package/node_modules/@aws-mdaa/config/test/config.test.ts +517 -0
  39. package/node_modules/@aws-mdaa/config/test/param-transformer.test.d.ts +5 -0
  40. package/node_modules/@aws-mdaa/config/test/param-transformer.test.js +216 -0
  41. package/node_modules/@aws-mdaa/config/test/param-transformer.test.ts +234 -0
  42. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.d.ts +5 -0
  43. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.js +59 -0
  44. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.ts +68 -0
  45. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.d.ts +5 -0
  46. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.js +254 -0
  47. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.ts +304 -0
  48. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.d.ts +5 -0
  49. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.js +66 -0
  50. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.ts +79 -0
  51. package/node_modules/@aws-mdaa/config/tsconfig.tsbuildinfo +1 -0
  52. package/node_modules/lodash/README.md +2 -2
  53. package/node_modules/lodash/_baseOrderBy.js +1 -1
  54. package/node_modules/lodash/_baseUnset.js +7 -20
  55. package/node_modules/lodash/_setCacheHas.js +1 -1
  56. package/node_modules/lodash/compact.js +1 -1
  57. package/node_modules/lodash/core.js +3 -3
  58. package/node_modules/lodash/core.min.js +26 -25
  59. package/node_modules/lodash/fromPairs.js +3 -1
  60. package/node_modules/lodash/lodash.js +38 -27
  61. package/node_modules/lodash/lodash.min.js +125 -129
  62. package/node_modules/lodash/package.json +4 -2
  63. package/node_modules/lodash/random.js +9 -0
  64. package/node_modules/lodash/template.js +16 -4
  65. package/node_modules/lodash/templateSettings.js +4 -0
  66. package/package.json +27 -32
  67. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/README.md +0 -185
  68. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.d.ts +0 -57
  69. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.js +0 -198
  70. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.ts +0 -241
  71. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/package.json +0 -44
  72. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/test/bucketpolicy-helper.test.js +0 -200
  73. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/test/bucketpolicy-helper.test.ts +0 -215
  74. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/tsconfig.tsbuildinfo +0 -1
  75. package/node_modules/@aws-mdaa/s3-inventory-helper/.npmignore +0 -34
  76. package/node_modules/@aws-mdaa/s3-inventory-helper/README.md +0 -3
  77. package/node_modules/@aws-mdaa/s3-inventory-helper/jest.config.js +0 -5
  78. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.d.ts +0 -48
  79. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.js +0 -213
  80. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.ts +0 -241
  81. package/node_modules/@aws-mdaa/s3-inventory-helper/package.json +0 -44
  82. package/node_modules/@aws-mdaa/s3-inventory-helper/test/TODO +0 -0
  83. package/node_modules/@aws-mdaa/s3-inventory-helper/tsconfig.json +0 -40
  84. package/node_modules/@aws-mdaa/s3-inventory-helper/tsconfig.tsbuildinfo +0 -1
  85. package/node_modules/@aws-mdaa/s3-inventory-helper/typedoc.json +0 -7
  86. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/.npmignore +0 -0
  87. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/jest.config.js +0 -0
  88. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper/test/bucketpolicy-helper.test.d.ts → config/test/blueprint-value-transformer.test.d.ts} +0 -0
  89. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/tsconfig.json +0 -0
  90. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/typedoc.json +0 -0
@@ -0,0 +1,68 @@
1
+ /*!
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import * as path from 'path';
7
+ import { ConfigConfigPathValueTransformer } from '../lib';
8
+
9
+ describe('ConfigConfigPathValueTransformer', () => {
10
+ const baseDir = '/home/user/project/configs';
11
+
12
+ test('returns unchanged value for non-relative paths', () => {
13
+ const transformer = new ConfigConfigPathValueTransformer(baseDir);
14
+ expect(transformer.transformValue('some-value')).toBe('some-value');
15
+ });
16
+
17
+ test('returns unchanged value for absolute paths', () => {
18
+ const transformer = new ConfigConfigPathValueTransformer(baseDir);
19
+ expect(transformer.transformValue('/absolute/path/to/file')).toBe('/absolute/path/to/file');
20
+ });
21
+
22
+ test('resolves parent relative path (../) to baseDir parent', () => {
23
+ const transformer = new ConfigConfigPathValueTransformer(baseDir);
24
+ const result = transformer.transformValue('../sibling/file.yaml');
25
+ expect(result).toBe(path.resolve(baseDir, '../sibling/file.yaml'));
26
+ });
27
+
28
+ test('resolves current relative path (./) relative to baseDir', () => {
29
+ const transformer = new ConfigConfigPathValueTransformer(baseDir);
30
+ const result = transformer.transformValue('./subdir/file.yaml');
31
+ expect(result).toBe(path.resolve(baseDir + '/subdir/file.yaml'));
32
+ });
33
+
34
+ test('handles multiple parent traversals', () => {
35
+ const transformer = new ConfigConfigPathValueTransformer(baseDir);
36
+ const result = transformer.transformValue('../../other/file.yaml');
37
+ expect(result).toBe(path.resolve(baseDir, '../../other/file.yaml'));
38
+ });
39
+
40
+ test('handles nested current directory paths', () => {
41
+ const transformer = new ConfigConfigPathValueTransformer(baseDir);
42
+ const result = transformer.transformValue('./a/b/c/file.yaml');
43
+ expect(result).toBe(path.resolve(baseDir + '/a/b/c/file.yaml'));
44
+ });
45
+
46
+ test('handles empty baseDir', () => {
47
+ const transformer = new ConfigConfigPathValueTransformer('');
48
+ const result = transformer.transformValue('../file.yaml');
49
+ expect(result).toBe(path.resolve('', '../file.yaml'));
50
+ });
51
+
52
+ test('returns empty string unchanged', () => {
53
+ const transformer = new ConfigConfigPathValueTransformer(baseDir);
54
+ expect(transformer.transformValue('')).toBe('');
55
+ });
56
+
57
+ test('handles baseDir with trailing slash', () => {
58
+ const transformer = new ConfigConfigPathValueTransformer('/home/user/project/');
59
+ const result = transformer.transformValue('../file.yaml');
60
+ expect(result).toBe(path.resolve('/home/user/project/', '../file.yaml'));
61
+ });
62
+
63
+ test('handles Windows-style paths in value', () => {
64
+ const transformer = new ConfigConfigPathValueTransformer(baseDir);
65
+ // Non-relative path should be returned unchanged
66
+ expect(transformer.transformValue('C:\\Windows\\file.txt')).toBe('C:\\Windows\\file.txt');
67
+ });
68
+ });
@@ -0,0 +1,5 @@
1
+ /*!
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ export {};
@@ -0,0 +1,254 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
8
+ const ref_value_transformer_1 = require("../lib/ref-value-transformer");
9
+ describe('MdaaConfigRefValueTransformer', () => {
10
+ const baseProps = {
11
+ org: 'test-org',
12
+ env: 'dev',
13
+ domain: 'test-domain',
14
+ module_name: 'test-module',
15
+ };
16
+ test('returns unchanged value without refs', () => {
17
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
18
+ expect(transformer.transformValue('plain-value')).toBe('plain-value');
19
+ });
20
+ test('transforms org ref', () => {
21
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
22
+ expect(transformer.transformValue('{{org}}')).toBe('test-org');
23
+ });
24
+ test('transforms env ref', () => {
25
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
26
+ expect(transformer.transformValue('{{env}}')).toBe('dev');
27
+ });
28
+ test('transforms domain ref', () => {
29
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
30
+ expect(transformer.transformValue('{{domain}}')).toBe('test-domain');
31
+ });
32
+ test('transforms module_name ref', () => {
33
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
34
+ expect(transformer.transformValue('{{module_name}}')).toBe('test-module');
35
+ });
36
+ test('transforms partition ref with scope', () => {
37
+ const stack = new aws_cdk_lib_1.Stack();
38
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
39
+ const result = transformer.transformValue('{{partition}}');
40
+ expect(result).toBeDefined();
41
+ });
42
+ test('transforms region ref with scope', () => {
43
+ const stack = new aws_cdk_lib_1.Stack();
44
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
45
+ const result = transformer.transformValue('{{region}}');
46
+ expect(result).toBeDefined();
47
+ });
48
+ test('transforms account ref with scope', () => {
49
+ const stack = new aws_cdk_lib_1.Stack();
50
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
51
+ const result = transformer.transformValue('{{account}}');
52
+ expect(result).toBeDefined();
53
+ });
54
+ test('transforms env_var ref', () => {
55
+ process.env.TEST_VAR = 'test-value';
56
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
57
+ expect(transformer.transformValue('{{env_var:TEST_VAR}}')).toBe('test-value');
58
+ delete process.env.TEST_VAR;
59
+ });
60
+ test('transforms context ref from scope', () => {
61
+ const stack = new aws_cdk_lib_1.Stack();
62
+ stack.node.setContext('test_key', 'test-value');
63
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
64
+ expect(transformer.transformValue('{{context:test_key}}')).toBe('test-value');
65
+ });
66
+ test('transforms context ref from context prop', () => {
67
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, context: { test_key: 'test-value' } });
68
+ expect(transformer.transformValue('{{context:test_key}}')).toBe('test-value');
69
+ });
70
+ test('throws when context ref not found', () => {
71
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
72
+ expect(() => transformer.transformValue('{{context:missing_key}}')).toThrow('Failed to resolve context: missing_key');
73
+ });
74
+ test('throws when org ref without naming', () => {
75
+ const stack = new aws_cdk_lib_1.Stack();
76
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
77
+ expect(() => transformer.transformValue('{{ssm-org:param}}')).toThrow('Unable to resolve ssm-org:param ssm param outside of a naming context');
78
+ });
79
+ test('throws when resolve:ssm without scope', () => {
80
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
81
+ expect(() => transformer.transformValue('{{resolve:ssm:/test/param}}')).toThrow('Unable to resolve ssm param outside of a Construct');
82
+ });
83
+ test('handles nested refs', () => {
84
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
85
+ expect(transformer.transformValue('prefix-{{org}}-{{env}}-suffix')).toBe('prefix-test-org-dev-suffix');
86
+ });
87
+ test('transforms partition ref with awsEnvironment', () => {
88
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({
89
+ ...baseProps,
90
+ awsEnvironment: { partition: 'aws-us-gov' },
91
+ });
92
+ expect(transformer.transformValue('{{partition}}')).toBe('aws-us-gov');
93
+ });
94
+ test('transforms region ref with awsEnvironment', () => {
95
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({
96
+ ...baseProps,
97
+ awsEnvironment: { region: 'us-west-2' },
98
+ });
99
+ expect(transformer.transformValue('{{region}}')).toBe('us-west-2');
100
+ });
101
+ test('transforms account ref with awsEnvironment', () => {
102
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({
103
+ ...baseProps,
104
+ awsEnvironment: { account: '123456789012' },
105
+ });
106
+ expect(transformer.transformValue('{{account}}')).toBe('123456789012');
107
+ });
108
+ test('returns undefined for missing env_var', () => {
109
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
110
+ expect(transformer.transformValue('{{env_var:MISSING_VAR}}')).toBe('{{env_var:MISSING_VAR}}');
111
+ });
112
+ test('resolves env_var JSON array to actual array', () => {
113
+ process.env.TEST_JSON_ARRAY = '["subnet-aaa","subnet-bbb"]';
114
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
115
+ expect(transformer.transformValue('{{env_var:TEST_JSON_ARRAY}}')).toEqual(['subnet-aaa', 'subnet-bbb']);
116
+ delete process.env.TEST_JSON_ARRAY;
117
+ });
118
+ test('resolves env_var JSON object to actual object', () => {
119
+ process.env.TEST_JSON_OBJ = '{"key":"value"}';
120
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
121
+ expect(transformer.transformValue('{{env_var:TEST_JSON_OBJ}}')).toEqual({ key: 'value' });
122
+ delete process.env.TEST_JSON_OBJ;
123
+ });
124
+ test('falls through to string for invalid JSON starting with [', () => {
125
+ process.env.TEST_BAD_JSON = '[not valid json';
126
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
127
+ expect(transformer.transformValue('{{env_var:TEST_BAD_JSON}}')).toBe('[not valid json');
128
+ delete process.env.TEST_BAD_JSON;
129
+ });
130
+ test('handles naked reference with object context', () => {
131
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({
132
+ ...baseProps,
133
+ context: { test_obj: { key: 'value' } },
134
+ });
135
+ const result = transformer.transformValue('{{context:test_obj}}');
136
+ expect(result).toEqual({ key: 'value' });
137
+ });
138
+ test('handles naked reference with array context', () => {
139
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({
140
+ ...baseProps,
141
+ context: { test_array: ['item1', 'item2'] },
142
+ });
143
+ const result = transformer.transformValue('{{context:test_array}}');
144
+ expect(result).toEqual(['item1', 'item2']);
145
+ });
146
+ test('throws when embedding object context in string', () => {
147
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({
148
+ ...baseProps,
149
+ context: { test_obj: { key: 'value' } },
150
+ });
151
+ expect(() => transformer.transformValue('prefix-{{context:test_obj}}-suffix')).toThrow('Cannot embed array or object context value in string');
152
+ });
153
+ test('throws when embedding array context in string', () => {
154
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({
155
+ ...baseProps,
156
+ context: { test_array: ['item1', 'item2'] },
157
+ });
158
+ expect(() => transformer.transformValue('prefix-{{context:test_array}}-suffix')).toThrow('Cannot embed array or object context value in string');
159
+ });
160
+ test('handles context with encoded object string', () => {
161
+ const stack = new aws_cdk_lib_1.Stack();
162
+ stack.node.setContext('test_key', '"obj:{"key":"value"}"');
163
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
164
+ const result = transformer.transformValue('{{context:test_key}}');
165
+ expect(result).toEqual({ key: 'value' });
166
+ });
167
+ test('handles context with encoded list string', () => {
168
+ const stack = new aws_cdk_lib_1.Stack();
169
+ stack.node.setContext('test_key', '"list:["item1","item2"]"');
170
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
171
+ const result = transformer.transformValue('{{context:test_key}}');
172
+ expect(result).toEqual(['item1', 'item2']);
173
+ });
174
+ test('converts number to string in substitution', () => {
175
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({
176
+ ...baseProps,
177
+ context: { test_num: 42 },
178
+ });
179
+ const result = transformer.transformValue('value-{{context:test_num}}');
180
+ expect(result).toBe('value-42');
181
+ });
182
+ test('converts boolean to string in substitution', () => {
183
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({
184
+ ...baseProps,
185
+ context: { test_bool: true },
186
+ });
187
+ const result = transformer.transformValue('value-{{context:test_bool}}');
188
+ expect(result).toBe('value-true');
189
+ });
190
+ test('handles ref: with attribute', () => {
191
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
192
+ const result = transformer.transformValue('{{ref:MyResource:Arn}}');
193
+ expect(result).toBeDefined();
194
+ expect(typeof result).toBe('string');
195
+ });
196
+ test('handles ref: without attribute', () => {
197
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
198
+ const result = transformer.transformValue('{{ref:MyResource}}');
199
+ expect(result).toBeDefined();
200
+ expect(typeof result).toBe('string');
201
+ });
202
+ test('handles ref: with leading slash', () => {
203
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
204
+ const result = transformer.transformValue('{{ref:/MyResource}}');
205
+ expect(result).toBeDefined();
206
+ expect(typeof result).toBe('string');
207
+ });
208
+ test('handles ref: with nested path', () => {
209
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
210
+ const result = transformer.transformValue('{{ref:Parent/Child}}');
211
+ expect(result).toBeDefined();
212
+ });
213
+ test('handles ssm-domain ref with naming', () => {
214
+ const mockNaming = {
215
+ ssmDomainPath: jest.fn().mockReturnValue('/test/domain/path'),
216
+ };
217
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
218
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, naming: mockNaming });
219
+ const result = transformer.transformValue('{{ssm-domain:param}}');
220
+ expect(result).toBe('{{resolve:ssm:/test/domain/path}}');
221
+ expect(mockNaming.ssmDomainPath).toHaveBeenCalledWith('param');
222
+ });
223
+ test('handles ssm-env ref with naming', () => {
224
+ const mockNaming = {
225
+ ssmEnvPath: jest.fn().mockReturnValue('/test/env/path'),
226
+ };
227
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
228
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, naming: mockNaming });
229
+ const result = transformer.transformValue('{{ssm-env:param}}');
230
+ expect(result).toBe('{{resolve:ssm:/test/env/path}}');
231
+ expect(mockNaming.ssmEnvPath).toHaveBeenCalledWith('param');
232
+ });
233
+ test('handles ssm-org ref with leading slash', () => {
234
+ const mockNaming = {
235
+ ssmOrgPath: jest.fn().mockReturnValue('/test/org/path'),
236
+ };
237
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
238
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, naming: mockNaming });
239
+ const result = transformer.transformValue('{{ssm-org:/param}}');
240
+ expect(result).toBe('{{resolve:ssm:/test/org/path}}');
241
+ expect(mockNaming.ssmOrgPath).toHaveBeenCalledWith('param');
242
+ });
243
+ test('handles resolve:ssm with ARN path', () => {
244
+ const stack = new aws_cdk_lib_1.Stack();
245
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer({ ...baseProps, scope: stack });
246
+ const result = transformer.transformValue('{{resolve:ssm:arn:aws:ssm:us-east-1:123456789012:parameter/test}}');
247
+ expect(result).toBeDefined();
248
+ });
249
+ test('throws when getSsmValue called without scope', () => {
250
+ const transformer = new ref_value_transformer_1.MdaaConfigRefValueTransformer(baseProps);
251
+ expect(() => transformer.transformValue('{{resolve:ssm:/test/param}}')).toThrow('Unable to resolve ssm param outside of a Construct');
252
+ });
253
+ });
254
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmLXZhbHVlLXRyYW5zZm9ybWVyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJyZWYtdmFsdWUtdHJhbnNmb3JtZXIudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztHQUdHOztBQUVILDZDQUFvQztBQUNwQyx3RUFBNkU7QUFFN0UsUUFBUSxDQUFDLCtCQUErQixFQUFFLEdBQUcsRUFBRTtJQUM3QyxNQUFNLFNBQVMsR0FBRztRQUNoQixHQUFHLEVBQUUsVUFBVTtRQUNmLEdBQUcsRUFBRSxLQUFLO1FBQ1YsTUFBTSxFQUFFLGFBQWE7UUFDckIsV0FBVyxFQUFFLGFBQWE7S0FDM0IsQ0FBQztJQUVGLElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN4RSxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxvQkFBb0IsRUFBRSxHQUFHLEVBQUU7UUFDOUIsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNqRSxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxvQkFBb0IsRUFBRSxHQUFHLEVBQUU7UUFDOUIsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1RCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyx1QkFBdUIsRUFBRSxHQUFHLEVBQUU7UUFDakMsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN2RSxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyw0QkFBNEIsRUFBRSxHQUFHLEVBQUU7UUFDdEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzVFLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLHFDQUFxQyxFQUFFLEdBQUcsRUFBRTtRQUMvQyxNQUFNLEtBQUssR0FBRyxJQUFJLG1CQUFLLEVBQUUsQ0FBQztRQUMxQixNQUFNLFdBQVcsR0FBRyxJQUFJLHFEQUE2QixDQUFDLEVBQUUsR0FBRyxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDdEYsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUMzRCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDL0IsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsa0NBQWtDLEVBQUUsR0FBRyxFQUFFO1FBQzVDLE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO1FBQzFCLE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUMsRUFBRSxHQUFHLFNBQVMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN0RixNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3hELE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUMvQixDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxtQ0FBbUMsRUFBRSxHQUFHLEVBQUU7UUFDN0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7UUFDMUIsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxFQUFFLEdBQUcsU0FBUyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3RGLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDekQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQy9CLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLHdCQUF3QixFQUFFLEdBQUcsRUFBRTtRQUNsQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxZQUFZLENBQUM7UUFDcEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzlFLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUM7SUFDOUIsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxFQUFFO1FBQzdDLE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO1FBQzFCLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNoRCxNQUFNLFdBQVcsR0FBRyxJQUFJLHFEQUE2QixDQUFDLEVBQUUsR0FBRyxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDdEYsTUFBTSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNoRixDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQywwQ0FBMEMsRUFBRSxHQUFHLEVBQUU7UUFDcEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxFQUFFLEdBQUcsU0FBUyxFQUFFLE9BQU8sRUFBRSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDN0csTUFBTSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNoRixDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxtQ0FBbUMsRUFBRSxHQUFHLEVBQUU7UUFDN0MsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUN6RSx3Q0FBd0MsQ0FDekMsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLG9DQUFvQyxFQUFFLEdBQUcsRUFBRTtRQUM5QyxNQUFNLEtBQUssR0FBRyxJQUFJLG1CQUFLLEVBQUUsQ0FBQztRQUMxQixNQUFNLFdBQVcsR0FBRyxJQUFJLHFEQUE2QixDQUFDLEVBQUUsR0FBRyxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDdEYsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FDbkUsdUVBQXVFLENBQ3hFLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyx1Q0FBdUMsRUFBRSxHQUFHLEVBQUU7UUFDakQsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUM3RSxvREFBb0QsQ0FDckQsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLHFCQUFxQixFQUFFLEdBQUcsRUFBRTtRQUMvQixNQUFNLFdBQVcsR0FBRyxJQUFJLHFEQUE2QixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLCtCQUErQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLENBQUMsQ0FBQztJQUN6RyxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyw4Q0FBOEMsRUFBRSxHQUFHLEVBQUU7UUFDeEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQztZQUNwRCxHQUFHLFNBQVM7WUFDWixjQUFjLEVBQUUsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFO1NBQzVDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3pFLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDJDQUEyQyxFQUFFLEdBQUcsRUFBRTtRQUNyRCxNQUFNLFdBQVcsR0FBRyxJQUFJLHFEQUE2QixDQUFDO1lBQ3BELEdBQUcsU0FBUztZQUNaLGNBQWMsRUFBRSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUU7U0FDeEMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDckUsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO1FBQ3RELE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUM7WUFDcEQsR0FBRyxTQUFTO1lBQ1osY0FBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRTtTQUM1QyxDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN6RSxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyx1Q0FBdUMsRUFBRSxHQUFHLEVBQUU7UUFDakQsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDaEcsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsNkNBQTZDLEVBQUUsR0FBRyxFQUFFO1FBQ3ZELE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxHQUFHLDZCQUE2QixDQUFDO1FBQzVELE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsNkJBQTZCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQ3hHLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUM7SUFDckMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsK0NBQStDLEVBQUUsR0FBRyxFQUFFO1FBQ3pELE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxHQUFHLGlCQUFpQixDQUFDO1FBQzlDLE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzFGLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUM7SUFDbkMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsMERBQTBELEVBQUUsR0FBRyxFQUFFO1FBQ3BFLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxHQUFHLGlCQUFpQixDQUFDO1FBQzlDLE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3hGLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUM7SUFDbkMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsNkNBQTZDLEVBQUUsR0FBRyxFQUFFO1FBQ3ZELE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUM7WUFDcEQsR0FBRyxTQUFTO1lBQ1osT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxFQUFFO1NBQ3hDLENBQUMsQ0FBQztRQUNILE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUNsRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDM0MsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO1FBQ3RELE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUM7WUFDcEQsR0FBRyxTQUFTO1lBQ1osT0FBTyxFQUFFLEVBQUUsVUFBVSxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFO1NBQzVDLENBQUMsQ0FBQztRQUNILE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUNwRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDN0MsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsZ0RBQWdELEVBQUUsR0FBRyxFQUFFO1FBQzFELE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUM7WUFDcEQsR0FBRyxTQUFTO1lBQ1osT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxFQUFFO1NBQ3hDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLG9DQUFvQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQ3BGLHNEQUFzRCxDQUN2RCxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsK0NBQStDLEVBQUUsR0FBRyxFQUFFO1FBQ3pELE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUM7WUFDcEQsR0FBRyxTQUFTO1lBQ1osT0FBTyxFQUFFLEVBQUUsVUFBVSxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFO1NBQzVDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLHNDQUFzQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQ3RGLHNEQUFzRCxDQUN2RCxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO1FBQ3RELE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO1FBQzFCLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1FBQzNELE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUMsRUFBRSxHQUFHLFNBQVMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN0RixNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsY0FBYyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbEUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDBDQUEwQyxFQUFFLEdBQUcsRUFBRTtRQUNwRCxNQUFNLEtBQUssR0FBRyxJQUFJLG1CQUFLLEVBQUUsQ0FBQztRQUMxQixLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztRQUM5RCxNQUFNLFdBQVcsR0FBRyxJQUFJLHFEQUE2QixDQUFDLEVBQUUsR0FBRyxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDdEYsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLGNBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ2xFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUM3QyxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQywyQ0FBMkMsRUFBRSxHQUFHLEVBQUU7UUFDckQsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQztZQUNwRCxHQUFHLFNBQVM7WUFDWixPQUFPLEVBQUUsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFO1NBQzFCLENBQUMsQ0FBQztRQUNILE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUN4RSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2xDLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDRDQUE0QyxFQUFFLEdBQUcsRUFBRTtRQUN0RCxNQUFNLFdBQVcsR0FBRyxJQUFJLHFEQUE2QixDQUFDO1lBQ3BELEdBQUcsU0FBUztZQUNaLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUU7U0FDN0IsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLGNBQWMsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1FBQ3pFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDcEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsNkJBQTZCLEVBQUUsR0FBRyxFQUFFO1FBQ3ZDLE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakUsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLGNBQWMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM3QixNQUFNLENBQUMsT0FBTyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdkMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsZ0NBQWdDLEVBQUUsR0FBRyxFQUFFO1FBQzFDLE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakUsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLGNBQWMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM3QixNQUFNLENBQUMsT0FBTyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdkMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsaUNBQWlDLEVBQUUsR0FBRyxFQUFFO1FBQzNDLE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakUsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLGNBQWMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM3QixNQUFNLENBQUMsT0FBTyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdkMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsK0JBQStCLEVBQUUsR0FBRyxFQUFFO1FBQ3pDLE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakUsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLGNBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ2xFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUMvQixDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxvQ0FBb0MsRUFBRSxHQUFHLEVBQUU7UUFDOUMsTUFBTSxVQUFVLEdBQUc7WUFDakIsYUFBYSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsbUJBQW1CLENBQUM7U0FDOUQsQ0FBQztRQUNGLDhEQUE4RDtRQUM5RCxNQUFNLFdBQVcsR0FBRyxJQUFJLHFEQUE2QixDQUFDLEVBQUUsR0FBRyxTQUFTLEVBQUUsTUFBTSxFQUFFLFVBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBQ25HLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUNsRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7UUFDekQsTUFBTSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqRSxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxHQUFHLEVBQUU7UUFDM0MsTUFBTSxVQUFVLEdBQUc7WUFDakIsVUFBVSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLENBQUM7U0FDeEQsQ0FBQztRQUNGLDhEQUE4RDtRQUM5RCxNQUFNLFdBQVcsR0FBRyxJQUFJLHFEQUE2QixDQUFDLEVBQUUsR0FBRyxTQUFTLEVBQUUsTUFBTSxFQUFFLFVBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBQ25HLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUMvRCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLENBQUM7UUFDdEQsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5RCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyx3Q0FBd0MsRUFBRSxHQUFHLEVBQUU7UUFDbEQsTUFBTSxVQUFVLEdBQUc7WUFDakIsVUFBVSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLENBQUM7U0FDeEQsQ0FBQztRQUNGLDhEQUE4RDtRQUM5RCxNQUFNLFdBQVcsR0FBRyxJQUFJLHFEQUE2QixDQUFDLEVBQUUsR0FBRyxTQUFTLEVBQUUsTUFBTSxFQUFFLFVBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBQ25HLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUNoRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLENBQUM7UUFDdEQsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5RCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxtQ0FBbUMsRUFBRSxHQUFHLEVBQUU7UUFDN0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7UUFDMUIsTUFBTSxXQUFXLEdBQUcsSUFBSSxxREFBNkIsQ0FBQyxFQUFFLEdBQUcsU0FBUyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3RGLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUMsbUVBQW1FLENBQUMsQ0FBQztRQUMvRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDL0IsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsOENBQThDLEVBQUUsR0FBRyxFQUFFO1FBQ3hELE1BQU0sV0FBVyxHQUFHLElBQUkscURBQTZCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakUsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsNkJBQTZCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FDN0Usb0RBQW9ELENBQ3JELENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cblxuaW1wb3J0IHsgU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lciB9IGZyb20gJy4uL2xpYi9yZWYtdmFsdWUtdHJhbnNmb3JtZXInO1xuXG5kZXNjcmliZSgnTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXInLCAoKSA9PiB7XG4gIGNvbnN0IGJhc2VQcm9wcyA9IHtcbiAgICBvcmc6ICd0ZXN0LW9yZycsXG4gICAgZW52OiAnZGV2JyxcbiAgICBkb21haW46ICd0ZXN0LWRvbWFpbicsXG4gICAgbW9kdWxlX25hbWU6ICd0ZXN0LW1vZHVsZScsXG4gIH07XG5cbiAgdGVzdCgncmV0dXJucyB1bmNoYW5nZWQgdmFsdWUgd2l0aG91dCByZWZzJywgKCkgPT4ge1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKGJhc2VQcm9wcyk7XG4gICAgZXhwZWN0KHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCdwbGFpbi12YWx1ZScpKS50b0JlKCdwbGFpbi12YWx1ZScpO1xuICB9KTtcblxuICB0ZXN0KCd0cmFuc2Zvcm1zIG9yZyByZWYnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBleHBlY3QodHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7b3JnfX0nKSkudG9CZSgndGVzdC1vcmcnKTtcbiAgfSk7XG5cbiAgdGVzdCgndHJhbnNmb3JtcyBlbnYgcmVmJywgKCkgPT4ge1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKGJhc2VQcm9wcyk7XG4gICAgZXhwZWN0KHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCd7e2Vudn19JykpLnRvQmUoJ2RldicpO1xuICB9KTtcblxuICB0ZXN0KCd0cmFuc2Zvcm1zIGRvbWFpbiByZWYnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBleHBlY3QodHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7ZG9tYWlufX0nKSkudG9CZSgndGVzdC1kb21haW4nKTtcbiAgfSk7XG5cbiAgdGVzdCgndHJhbnNmb3JtcyBtb2R1bGVfbmFtZSByZWYnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBleHBlY3QodHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7bW9kdWxlX25hbWV9fScpKS50b0JlKCd0ZXN0LW1vZHVsZScpO1xuICB9KTtcblxuICB0ZXN0KCd0cmFuc2Zvcm1zIHBhcnRpdGlvbiByZWYgd2l0aCBzY29wZScsICgpID0+IHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKHsgLi4uYmFzZVByb3BzLCBzY29wZTogc3RhY2sgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7cGFydGl0aW9ufX0nKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlRGVmaW5lZCgpO1xuICB9KTtcblxuICB0ZXN0KCd0cmFuc2Zvcm1zIHJlZ2lvbiByZWYgd2l0aCBzY29wZScsICgpID0+IHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKHsgLi4uYmFzZVByb3BzLCBzY29wZTogc3RhY2sgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7cmVnaW9ufX0nKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlRGVmaW5lZCgpO1xuICB9KTtcblxuICB0ZXN0KCd0cmFuc2Zvcm1zIGFjY291bnQgcmVmIHdpdGggc2NvcGUnLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IG5ldyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lcih7IC4uLmJhc2VQcm9wcywgc2NvcGU6IHN0YWNrIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCd7e2FjY291bnR9fScpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmVEZWZpbmVkKCk7XG4gIH0pO1xuXG4gIHRlc3QoJ3RyYW5zZm9ybXMgZW52X3ZhciByZWYnLCAoKSA9PiB7XG4gICAgcHJvY2Vzcy5lbnYuVEVTVF9WQVIgPSAndGVzdC12YWx1ZSc7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBleHBlY3QodHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7ZW52X3ZhcjpURVNUX1ZBUn19JykpLnRvQmUoJ3Rlc3QtdmFsdWUnKTtcbiAgICBkZWxldGUgcHJvY2Vzcy5lbnYuVEVTVF9WQVI7XG4gIH0pO1xuXG4gIHRlc3QoJ3RyYW5zZm9ybXMgY29udGV4dCByZWYgZnJvbSBzY29wZScsICgpID0+IHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIHN0YWNrLm5vZGUuc2V0Q29udGV4dCgndGVzdF9rZXknLCAndGVzdC12YWx1ZScpO1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKHsgLi4uYmFzZVByb3BzLCBzY29wZTogc3RhY2sgfSk7XG4gICAgZXhwZWN0KHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCd7e2NvbnRleHQ6dGVzdF9rZXl9fScpKS50b0JlKCd0ZXN0LXZhbHVlJyk7XG4gIH0pO1xuXG4gIHRlc3QoJ3RyYW5zZm9ybXMgY29udGV4dCByZWYgZnJvbSBjb250ZXh0IHByb3AnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoeyAuLi5iYXNlUHJvcHMsIGNvbnRleHQ6IHsgdGVzdF9rZXk6ICd0ZXN0LXZhbHVlJyB9IH0pO1xuICAgIGV4cGVjdCh0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3tjb250ZXh0OnRlc3Rfa2V5fX0nKSkudG9CZSgndGVzdC12YWx1ZScpO1xuICB9KTtcblxuICB0ZXN0KCd0aHJvd3Mgd2hlbiBjb250ZXh0IHJlZiBub3QgZm91bmQnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBleHBlY3QoKCkgPT4gdHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7Y29udGV4dDptaXNzaW5nX2tleX19JykpLnRvVGhyb3coXG4gICAgICAnRmFpbGVkIHRvIHJlc29sdmUgY29udGV4dDogbWlzc2luZ19rZXknLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoJ3Rocm93cyB3aGVuIG9yZyByZWYgd2l0aG91dCBuYW1pbmcnLCAoKSA9PiB7XG4gICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IG5ldyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lcih7IC4uLmJhc2VQcm9wcywgc2NvcGU6IHN0YWNrIH0pO1xuICAgIGV4cGVjdCgoKSA9PiB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3tzc20tb3JnOnBhcmFtfX0nKSkudG9UaHJvdyhcbiAgICAgICdVbmFibGUgdG8gcmVzb2x2ZSBzc20tb3JnOnBhcmFtIHNzbSBwYXJhbSBvdXRzaWRlIG9mIGEgbmFtaW5nIGNvbnRleHQnLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoJ3Rocm93cyB3aGVuIHJlc29sdmU6c3NtIHdpdGhvdXQgc2NvcGUnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBleHBlY3QoKCkgPT4gdHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7cmVzb2x2ZTpzc206L3Rlc3QvcGFyYW19fScpKS50b1Rocm93KFxuICAgICAgJ1VuYWJsZSB0byByZXNvbHZlIHNzbSBwYXJhbSBvdXRzaWRlIG9mIGEgQ29uc3RydWN0JyxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KCdoYW5kbGVzIG5lc3RlZCByZWZzJywgKCkgPT4ge1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKGJhc2VQcm9wcyk7XG4gICAgZXhwZWN0KHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCdwcmVmaXgte3tvcmd9fS17e2Vudn19LXN1ZmZpeCcpKS50b0JlKCdwcmVmaXgtdGVzdC1vcmctZGV2LXN1ZmZpeCcpO1xuICB9KTtcblxuICB0ZXN0KCd0cmFuc2Zvcm1zIHBhcnRpdGlvbiByZWYgd2l0aCBhd3NFbnZpcm9ubWVudCcsICgpID0+IHtcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IG5ldyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lcih7XG4gICAgICAuLi5iYXNlUHJvcHMsXG4gICAgICBhd3NFbnZpcm9ubWVudDogeyBwYXJ0aXRpb246ICdhd3MtdXMtZ292JyB9LFxuICAgIH0pO1xuICAgIGV4cGVjdCh0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3twYXJ0aXRpb259fScpKS50b0JlKCdhd3MtdXMtZ292Jyk7XG4gIH0pO1xuXG4gIHRlc3QoJ3RyYW5zZm9ybXMgcmVnaW9uIHJlZiB3aXRoIGF3c0Vudmlyb25tZW50JywgKCkgPT4ge1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKHtcbiAgICAgIC4uLmJhc2VQcm9wcyxcbiAgICAgIGF3c0Vudmlyb25tZW50OiB7IHJlZ2lvbjogJ3VzLXdlc3QtMicgfSxcbiAgICB9KTtcbiAgICBleHBlY3QodHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7cmVnaW9ufX0nKSkudG9CZSgndXMtd2VzdC0yJyk7XG4gIH0pO1xuXG4gIHRlc3QoJ3RyYW5zZm9ybXMgYWNjb3VudCByZWYgd2l0aCBhd3NFbnZpcm9ubWVudCcsICgpID0+IHtcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IG5ldyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lcih7XG4gICAgICAuLi5iYXNlUHJvcHMsXG4gICAgICBhd3NFbnZpcm9ubWVudDogeyBhY2NvdW50OiAnMTIzNDU2Nzg5MDEyJyB9LFxuICAgIH0pO1xuICAgIGV4cGVjdCh0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3thY2NvdW50fX0nKSkudG9CZSgnMTIzNDU2Nzg5MDEyJyk7XG4gIH0pO1xuXG4gIHRlc3QoJ3JldHVybnMgdW5kZWZpbmVkIGZvciBtaXNzaW5nIGVudl92YXInLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBleHBlY3QodHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7ZW52X3ZhcjpNSVNTSU5HX1ZBUn19JykpLnRvQmUoJ3t7ZW52X3ZhcjpNSVNTSU5HX1ZBUn19Jyk7XG4gIH0pO1xuXG4gIHRlc3QoJ3Jlc29sdmVzIGVudl92YXIgSlNPTiBhcnJheSB0byBhY3R1YWwgYXJyYXknLCAoKSA9PiB7XG4gICAgcHJvY2Vzcy5lbnYuVEVTVF9KU09OX0FSUkFZID0gJ1tcInN1Ym5ldC1hYWFcIixcInN1Ym5ldC1iYmJcIl0nO1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKGJhc2VQcm9wcyk7XG4gICAgZXhwZWN0KHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCd7e2Vudl92YXI6VEVTVF9KU09OX0FSUkFZfX0nKSkudG9FcXVhbChbJ3N1Ym5ldC1hYWEnLCAnc3VibmV0LWJiYiddKTtcbiAgICBkZWxldGUgcHJvY2Vzcy5lbnYuVEVTVF9KU09OX0FSUkFZO1xuICB9KTtcblxuICB0ZXN0KCdyZXNvbHZlcyBlbnZfdmFyIEpTT04gb2JqZWN0IHRvIGFjdHVhbCBvYmplY3QnLCAoKSA9PiB7XG4gICAgcHJvY2Vzcy5lbnYuVEVTVF9KU09OX09CSiA9ICd7XCJrZXlcIjpcInZhbHVlXCJ9JztcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IG5ldyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lcihiYXNlUHJvcHMpO1xuICAgIGV4cGVjdCh0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3tlbnZfdmFyOlRFU1RfSlNPTl9PQkp9fScpKS50b0VxdWFsKHsga2V5OiAndmFsdWUnIH0pO1xuICAgIGRlbGV0ZSBwcm9jZXNzLmVudi5URVNUX0pTT05fT0JKO1xuICB9KTtcblxuICB0ZXN0KCdmYWxscyB0aHJvdWdoIHRvIHN0cmluZyBmb3IgaW52YWxpZCBKU09OIHN0YXJ0aW5nIHdpdGggWycsICgpID0+IHtcbiAgICBwcm9jZXNzLmVudi5URVNUX0JBRF9KU09OID0gJ1tub3QgdmFsaWQganNvbic7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBleHBlY3QodHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3t7ZW52X3ZhcjpURVNUX0JBRF9KU09OfX0nKSkudG9CZSgnW25vdCB2YWxpZCBqc29uJyk7XG4gICAgZGVsZXRlIHByb2Nlc3MuZW52LlRFU1RfQkFEX0pTT047XG4gIH0pO1xuXG4gIHRlc3QoJ2hhbmRsZXMgbmFrZWQgcmVmZXJlbmNlIHdpdGggb2JqZWN0IGNvbnRleHQnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoe1xuICAgICAgLi4uYmFzZVByb3BzLFxuICAgICAgY29udGV4dDogeyB0ZXN0X29iajogeyBrZXk6ICd2YWx1ZScgfSB9LFxuICAgIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCd7e2NvbnRleHQ6dGVzdF9vYmp9fScpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoeyBrZXk6ICd2YWx1ZScgfSk7XG4gIH0pO1xuXG4gIHRlc3QoJ2hhbmRsZXMgbmFrZWQgcmVmZXJlbmNlIHdpdGggYXJyYXkgY29udGV4dCcsICgpID0+IHtcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IG5ldyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lcih7XG4gICAgICAuLi5iYXNlUHJvcHMsXG4gICAgICBjb250ZXh0OiB7IHRlc3RfYXJyYXk6IFsnaXRlbTEnLCAnaXRlbTInXSB9LFxuICAgIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCd7e2NvbnRleHQ6dGVzdF9hcnJheX19Jyk7XG4gICAgZXhwZWN0KHJlc3VsdCkudG9FcXVhbChbJ2l0ZW0xJywgJ2l0ZW0yJ10pO1xuICB9KTtcblxuICB0ZXN0KCd0aHJvd3Mgd2hlbiBlbWJlZGRpbmcgb2JqZWN0IGNvbnRleHQgaW4gc3RyaW5nJywgKCkgPT4ge1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKHtcbiAgICAgIC4uLmJhc2VQcm9wcyxcbiAgICAgIGNvbnRleHQ6IHsgdGVzdF9vYmo6IHsga2V5OiAndmFsdWUnIH0gfSxcbiAgICB9KTtcbiAgICBleHBlY3QoKCkgPT4gdHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3ByZWZpeC17e2NvbnRleHQ6dGVzdF9vYmp9fS1zdWZmaXgnKSkudG9UaHJvdyhcbiAgICAgICdDYW5ub3QgZW1iZWQgYXJyYXkgb3Igb2JqZWN0IGNvbnRleHQgdmFsdWUgaW4gc3RyaW5nJyxcbiAgICApO1xuICB9KTtcblxuICB0ZXN0KCd0aHJvd3Mgd2hlbiBlbWJlZGRpbmcgYXJyYXkgY29udGV4dCBpbiBzdHJpbmcnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoe1xuICAgICAgLi4uYmFzZVByb3BzLFxuICAgICAgY29udGV4dDogeyB0ZXN0X2FycmF5OiBbJ2l0ZW0xJywgJ2l0ZW0yJ10gfSxcbiAgICB9KTtcbiAgICBleHBlY3QoKCkgPT4gdHJhbnNmb3JtZXIudHJhbnNmb3JtVmFsdWUoJ3ByZWZpeC17e2NvbnRleHQ6dGVzdF9hcnJheX19LXN1ZmZpeCcpKS50b1Rocm93KFxuICAgICAgJ0Nhbm5vdCBlbWJlZCBhcnJheSBvciBvYmplY3QgY29udGV4dCB2YWx1ZSBpbiBzdHJpbmcnLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoJ2hhbmRsZXMgY29udGV4dCB3aXRoIGVuY29kZWQgb2JqZWN0IHN0cmluZycsICgpID0+IHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIHN0YWNrLm5vZGUuc2V0Q29udGV4dCgndGVzdF9rZXknLCAnXCJvYmo6e1wia2V5XCI6XCJ2YWx1ZVwifVwiJyk7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoeyAuLi5iYXNlUHJvcHMsIHNjb3BlOiBzdGFjayB9KTtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3tjb250ZXh0OnRlc3Rfa2V5fX0nKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0VxdWFsKHsga2V5OiAndmFsdWUnIH0pO1xuICB9KTtcblxuICB0ZXN0KCdoYW5kbGVzIGNvbnRleHQgd2l0aCBlbmNvZGVkIGxpc3Qgc3RyaW5nJywgKCkgPT4ge1xuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgc3RhY2subm9kZS5zZXRDb250ZXh0KCd0ZXN0X2tleScsICdcImxpc3Q6W1wiaXRlbTFcIixcIml0ZW0yXCJdXCInKTtcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IG5ldyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lcih7IC4uLmJhc2VQcm9wcywgc2NvcGU6IHN0YWNrIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCd7e2NvbnRleHQ6dGVzdF9rZXl9fScpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoWydpdGVtMScsICdpdGVtMiddKTtcbiAgfSk7XG5cbiAgdGVzdCgnY29udmVydHMgbnVtYmVyIHRvIHN0cmluZyBpbiBzdWJzdGl0dXRpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoe1xuICAgICAgLi4uYmFzZVByb3BzLFxuICAgICAgY29udGV4dDogeyB0ZXN0X251bTogNDIgfSxcbiAgICB9KTtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgndmFsdWUte3tjb250ZXh0OnRlc3RfbnVtfX0nKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlKCd2YWx1ZS00MicpO1xuICB9KTtcblxuICB0ZXN0KCdjb252ZXJ0cyBib29sZWFuIHRvIHN0cmluZyBpbiBzdWJzdGl0dXRpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoe1xuICAgICAgLi4uYmFzZVByb3BzLFxuICAgICAgY29udGV4dDogeyB0ZXN0X2Jvb2w6IHRydWUgfSxcbiAgICB9KTtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgndmFsdWUte3tjb250ZXh0OnRlc3RfYm9vbH19Jyk7XG4gICAgZXhwZWN0KHJlc3VsdCkudG9CZSgndmFsdWUtdHJ1ZScpO1xuICB9KTtcblxuICB0ZXN0KCdoYW5kbGVzIHJlZjogd2l0aCBhdHRyaWJ1dGUnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3tyZWY6TXlSZXNvdXJjZTpBcm59fScpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmVEZWZpbmVkKCk7XG4gICAgZXhwZWN0KHR5cGVvZiByZXN1bHQpLnRvQmUoJ3N0cmluZycpO1xuICB9KTtcblxuICB0ZXN0KCdoYW5kbGVzIHJlZjogd2l0aG91dCBhdHRyaWJ1dGUnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3tyZWY6TXlSZXNvdXJjZX19Jyk7XG4gICAgZXhwZWN0KHJlc3VsdCkudG9CZURlZmluZWQoKTtcbiAgICBleHBlY3QodHlwZW9mIHJlc3VsdCkudG9CZSgnc3RyaW5nJyk7XG4gIH0pO1xuXG4gIHRlc3QoJ2hhbmRsZXMgcmVmOiB3aXRoIGxlYWRpbmcgc2xhc2gnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoYmFzZVByb3BzKTtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3tyZWY6L015UmVzb3VyY2V9fScpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmVEZWZpbmVkKCk7XG4gICAgZXhwZWN0KHR5cGVvZiByZXN1bHQpLnRvQmUoJ3N0cmluZycpO1xuICB9KTtcblxuICB0ZXN0KCdoYW5kbGVzIHJlZjogd2l0aCBuZXN0ZWQgcGF0aCcsICgpID0+IHtcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IG5ldyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lcihiYXNlUHJvcHMpO1xuICAgIGNvbnN0IHJlc3VsdCA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCd7e3JlZjpQYXJlbnQvQ2hpbGR9fScpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmVEZWZpbmVkKCk7XG4gIH0pO1xuXG4gIHRlc3QoJ2hhbmRsZXMgc3NtLWRvbWFpbiByZWYgd2l0aCBuYW1pbmcnLCAoKSA9PiB7XG4gICAgY29uc3QgbW9ja05hbWluZyA9IHtcbiAgICAgIHNzbURvbWFpblBhdGg6IGplc3QuZm4oKS5tb2NrUmV0dXJuVmFsdWUoJy90ZXN0L2RvbWFpbi9wYXRoJyksXG4gICAgfTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKHsgLi4uYmFzZVByb3BzLCBuYW1pbmc6IG1vY2tOYW1pbmcgYXMgYW55IH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCd7e3NzbS1kb21haW46cGFyYW19fScpO1xuICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoJ3t7cmVzb2x2ZTpzc206L3Rlc3QvZG9tYWluL3BhdGh9fScpO1xuICAgIGV4cGVjdChtb2NrTmFtaW5nLnNzbURvbWFpblBhdGgpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdwYXJhbScpO1xuICB9KTtcblxuICB0ZXN0KCdoYW5kbGVzIHNzbS1lbnYgcmVmIHdpdGggbmFtaW5nJywgKCkgPT4ge1xuICAgIGNvbnN0IG1vY2tOYW1pbmcgPSB7XG4gICAgICBzc21FbnZQYXRoOiBqZXN0LmZuKCkubW9ja1JldHVyblZhbHVlKCcvdGVzdC9lbnYvcGF0aCcpLFxuICAgIH07XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IG5ldyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lcih7IC4uLmJhc2VQcm9wcywgbmFtaW5nOiBtb2NrTmFtaW5nIGFzIGFueSB9KTtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3tzc20tZW52OnBhcmFtfX0nKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlKCd7e3Jlc29sdmU6c3NtOi90ZXN0L2Vudi9wYXRofX0nKTtcbiAgICBleHBlY3QobW9ja05hbWluZy5zc21FbnZQYXRoKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgncGFyYW0nKTtcbiAgfSk7XG5cbiAgdGVzdCgnaGFuZGxlcyBzc20tb3JnIHJlZiB3aXRoIGxlYWRpbmcgc2xhc2gnLCAoKSA9PiB7XG4gICAgY29uc3QgbW9ja05hbWluZyA9IHtcbiAgICAgIHNzbU9yZ1BhdGg6IGplc3QuZm4oKS5tb2NrUmV0dXJuVmFsdWUoJy90ZXN0L29yZy9wYXRoJyksXG4gICAgfTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gbmV3IE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyKHsgLi4uYmFzZVByb3BzLCBuYW1pbmc6IG1vY2tOYW1pbmcgYXMgYW55IH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVZhbHVlKCd7e3NzbS1vcmc6L3BhcmFtfX0nKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlKCd7e3Jlc29sdmU6c3NtOi90ZXN0L29yZy9wYXRofX0nKTtcbiAgICBleHBlY3QobW9ja05hbWluZy5zc21PcmdQYXRoKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgncGFyYW0nKTtcbiAgfSk7XG5cbiAgdGVzdCgnaGFuZGxlcyByZXNvbHZlOnNzbSB3aXRoIEFSTiBwYXRoJywgKCkgPT4ge1xuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgY29uc3QgdHJhbnNmb3JtZXIgPSBuZXcgTWRhYUNvbmZpZ1JlZlZhbHVlVHJhbnNmb3JtZXIoeyAuLi5iYXNlUHJvcHMsIHNjb3BlOiBzdGFjayB9KTtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3tyZXNvbHZlOnNzbTphcm46YXdzOnNzbTp1cy1lYXN0LTE6MTIzNDU2Nzg5MDEyOnBhcmFtZXRlci90ZXN0fX0nKTtcbiAgICBleHBlY3QocmVzdWx0KS50b0JlRGVmaW5lZCgpO1xuICB9KTtcblxuICB0ZXN0KCd0aHJvd3Mgd2hlbiBnZXRTc21WYWx1ZSBjYWxsZWQgd2l0aG91dCBzY29wZScsICgpID0+IHtcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IG5ldyBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lcihiYXNlUHJvcHMpO1xuICAgIGV4cGVjdCgoKSA9PiB0cmFuc2Zvcm1lci50cmFuc2Zvcm1WYWx1ZSgne3tyZXNvbHZlOnNzbTovdGVzdC9wYXJhbX19JykpLnRvVGhyb3coXG4gICAgICAnVW5hYmxlIHRvIHJlc29sdmUgc3NtIHBhcmFtIG91dHNpZGUgb2YgYSBDb25zdHJ1Y3QnLFxuICAgICk7XG4gIH0pO1xufSk7XG4iXX0=