@aws-cdk-testing/cli-integ 2.61.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 (165) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +16 -0
  3. package/README.md +151 -0
  4. package/bin/apply-patches +19 -0
  5. package/bin/download-and-run-old-tests +52 -0
  6. package/bin/query-github +2 -0
  7. package/bin/query-github.d.ts +1 -0
  8. package/bin/query-github.js +55 -0
  9. package/bin/run-suite +2 -0
  10. package/bin/run-suite.d.ts +1 -0
  11. package/bin/run-suite.js +126 -0
  12. package/bin/stage-distribution +2 -0
  13. package/bin/stage-distribution.d.ts +1 -0
  14. package/bin/stage-distribution.js +209 -0
  15. package/bin/test-root +2 -0
  16. package/bin/test-root.d.ts +1 -0
  17. package/bin/test-root.js +6 -0
  18. package/entrypoints/test-cli-regression-against-current-code.sh +11 -0
  19. package/entrypoints/test-cli-regression-against-latest-release.sh +11 -0
  20. package/entrypoints/test-cli-regression.bash +83 -0
  21. package/entrypoints/test.sh +12 -0
  22. package/lib/aws.d.ts +55 -0
  23. package/lib/aws.js +243 -0
  24. package/lib/corking.d.ts +13 -0
  25. package/lib/corking.js +34 -0
  26. package/lib/files.d.ts +15 -0
  27. package/lib/files.js +80 -0
  28. package/lib/github.d.ts +4 -0
  29. package/lib/github.js +43 -0
  30. package/lib/index.d.ts +12 -0
  31. package/lib/index.js +25 -0
  32. package/lib/integ-test.d.ts +11 -0
  33. package/lib/integ-test.js +55 -0
  34. package/lib/lists.d.ts +1 -0
  35. package/lib/lists.js +12 -0
  36. package/lib/memoize.d.ts +6 -0
  37. package/lib/memoize.js +19 -0
  38. package/lib/npm.d.ts +4 -0
  39. package/lib/npm.js +15 -0
  40. package/lib/package-sources/release-source.d.ts +22 -0
  41. package/lib/package-sources/release-source.js +67 -0
  42. package/lib/package-sources/repo-source.d.ts +23 -0
  43. package/lib/package-sources/repo-source.js +92 -0
  44. package/lib/package-sources/repo-tools/npm +2 -0
  45. package/lib/package-sources/repo-tools/npm.d.ts +1 -0
  46. package/lib/package-sources/repo-tools/npm.js +42 -0
  47. package/lib/package-sources/source.d.ts +24 -0
  48. package/lib/package-sources/source.js +3 -0
  49. package/lib/package-sources/subprocess.d.ts +3 -0
  50. package/lib/package-sources/subprocess.js +18 -0
  51. package/lib/resource-pool.d.ts +54 -0
  52. package/lib/resource-pool.js +120 -0
  53. package/lib/resources.d.ts +1 -0
  54. package/lib/resources.js +6 -0
  55. package/lib/shell.d.ts +59 -0
  56. package/lib/shell.js +118 -0
  57. package/lib/staging/codeartifact.d.ts +44 -0
  58. package/lib/staging/codeartifact.js +258 -0
  59. package/lib/staging/maven.d.ts +5 -0
  60. package/lib/staging/maven.js +83 -0
  61. package/lib/staging/npm.d.ts +4 -0
  62. package/lib/staging/npm.js +56 -0
  63. package/lib/staging/nuget.d.ts +4 -0
  64. package/lib/staging/nuget.js +71 -0
  65. package/lib/staging/parallel-shell.d.ts +6 -0
  66. package/lib/staging/parallel-shell.js +46 -0
  67. package/lib/staging/pypi.d.ts +4 -0
  68. package/lib/staging/pypi.js +49 -0
  69. package/lib/staging/usage-dir.d.ts +31 -0
  70. package/lib/staging/usage-dir.js +87 -0
  71. package/lib/with-aws.d.ts +13 -0
  72. package/lib/with-aws.js +60 -0
  73. package/lib/with-cdk-app.d.ts +146 -0
  74. package/lib/with-cdk-app.js +398 -0
  75. package/lib/with-packages.d.ts +5 -0
  76. package/lib/with-packages.js +14 -0
  77. package/lib/with-sam.d.ts +33 -0
  78. package/lib/with-sam.js +240 -0
  79. package/lib/with-temporary-directory.d.ts +5 -0
  80. package/lib/with-temporary-directory.js +32 -0
  81. package/lib/xpmutex.d.ts +43 -0
  82. package/lib/xpmutex.js +207 -0
  83. package/package.json +73 -0
  84. package/resources/cdk-apps/app/app.js +463 -0
  85. package/resources/cdk-apps/app/cdk.json +7 -0
  86. package/resources/cdk-apps/app/docker/Dockerfile +2 -0
  87. package/resources/cdk-apps/app/docker/Dockerfile.Custom +2 -0
  88. package/resources/cdk-apps/app/lambda/index.js +4 -0
  89. package/resources/cdk-apps/app/lambda/response.json +3 -0
  90. package/resources/cdk-apps/app/nested-stack.js +49 -0
  91. package/resources/cdk-apps/cfn-include-app/.gitignore +1 -0
  92. package/resources/cdk-apps/cfn-include-app/cdk.json +4 -0
  93. package/resources/cdk-apps/cfn-include-app/cfn-include-app.js +21 -0
  94. package/resources/cdk-apps/cfn-include-app/example-template.json +13 -0
  95. package/resources/cdk-apps/sam_cdk_integ_app/bin/test-app.js +11 -0
  96. package/resources/cdk-apps/sam_cdk_integ_app/cdk.json +6 -0
  97. package/resources/cdk-apps/sam_cdk_integ_app/lib/nested-stack.js +19 -0
  98. package/resources/cdk-apps/sam_cdk_integ_app/lib/test-stack.js +134 -0
  99. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/.no-packagejson-validator +0 -0
  100. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/Dockerfile +9 -0
  101. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/app.js +22 -0
  102. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/package.json +18 -0
  103. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.mod +5 -0
  104. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.sum +17 -0
  105. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/main.go +17 -0
  106. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/.no-packagejson-validator +0 -0
  107. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/app.ts +16 -0
  108. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package-lock.json +12 -0
  109. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package.json +5 -0
  110. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/app.py +15 -0
  111. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/requirements.txt +1 -0
  112. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/layer_version_dependency.py +5 -0
  113. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/requirements.txt +1 -0
  114. package/resources/cdk-apps/sam_cdk_integ_app/src/rest-api-definition.yaml +12 -0
  115. package/resources/cli-regression-patches/v1.119.0/NOTES.md +5 -0
  116. package/resources/cli-regression-patches/v1.119.0/cli.integtest.js +659 -0
  117. package/resources/cli-regression-patches/v1.130.0/NOTES.md +12 -0
  118. package/resources/cli-regression-patches/v1.130.0/app/app.js +378 -0
  119. package/resources/cli-regression-patches/v1.130.0/bootstrapping.integtest.js +220 -0
  120. package/resources/cli-regression-patches/v1.44.0/NOTES.md +18 -0
  121. package/resources/cli-regression-patches/v1.44.0/bootstrapping.integtest.js +126 -0
  122. package/resources/cli-regression-patches/v1.44.0/test.sh +26 -0
  123. package/resources/cli-regression-patches/v1.61.1/NOTES.md +2 -0
  124. package/resources/cli-regression-patches/v1.61.1/skip-tests.txt +16 -0
  125. package/resources/cli-regression-patches/v1.62.0/NOTES.md +2 -0
  126. package/resources/cli-regression-patches/v1.62.0/aws-helpers.js +245 -0
  127. package/resources/cli-regression-patches/v1.63.0/NOTES.md +1 -0
  128. package/resources/cli-regression-patches/v1.63.0/skip-tests.txt +7 -0
  129. package/resources/cli-regression-patches/v1.64.0/NOTES.md +3 -0
  130. package/resources/cli-regression-patches/v1.64.0/cdk-helpers.js +325 -0
  131. package/resources/cli-regression-patches/v1.64.0/cli.integtest.js +599 -0
  132. package/resources/cli-regression-patches/v1.64.1/NOTES.md +3 -0
  133. package/resources/cli-regression-patches/v1.64.1/cdk-helpers.js +324 -0
  134. package/resources/cli-regression-patches/v1.64.1/cli.integtest.js +599 -0
  135. package/resources/cli-regression-patches/v1.67.0/NOTES.md +2 -0
  136. package/resources/cli-regression-patches/v1.67.0/cdk-helpers.js +331 -0
  137. package/resources/cloud-assemblies/0.36.0/InitStack.template.json +1 -0
  138. package/resources/cloud-assemblies/0.36.0/manifest.json +19 -0
  139. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/InitStack.template.json +2 -0
  140. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/manifest.json.js +37 -0
  141. package/resources/cloud-assemblies/1.10.0-request-azs/InitStack.template.json +2 -0
  142. package/resources/cloud-assemblies/1.10.0-request-azs/manifest.json.js +34 -0
  143. package/resources/integ.jest.config.js +25 -0
  144. package/skip-tests.txt +8 -0
  145. package/tests/cli-integ-tests/README.md +47 -0
  146. package/tests/cli-integ-tests/bootstrapping.integtest.d.ts +1 -0
  147. package/tests/cli-integ-tests/bootstrapping.integtest.js +271 -0
  148. package/tests/cli-integ-tests/cli.integtest.d.ts +1 -0
  149. package/tests/cli-integ-tests/cli.integtest.js +1029 -0
  150. package/tests/init-csharp/init-csharp.integtest.d.ts +1 -0
  151. package/tests/init-csharp/init-csharp.integtest.js +14 -0
  152. package/tests/init-fsharp/init-fsharp.integtest.d.ts +1 -0
  153. package/tests/init-fsharp/init-fsharp.integtest.js +14 -0
  154. package/tests/init-java/init-java.integtest.d.ts +1 -0
  155. package/tests/init-java/init-java.integtest.js +14 -0
  156. package/tests/init-javascript/init-javascript.integtest.d.ts +1 -0
  157. package/tests/init-javascript/init-javascript.integtest.js +15 -0
  158. package/tests/init-python/init-python.integtest.d.ts +1 -0
  159. package/tests/init-python/init-python.integtest.js +19 -0
  160. package/tests/init-typescript-app/init-typescript-app.integtest.d.ts +1 -0
  161. package/tests/init-typescript-app/init-typescript-app.integtest.js +49 -0
  162. package/tests/init-typescript-lib/init-typescript-lib.integtest.d.ts +1 -0
  163. package/tests/init-typescript-lib/init-typescript-lib.integtest.js +13 -0
  164. package/tests/uberpackage/uberpackage.integtest.d.ts +1 -0
  165. package/tests/uberpackage/uberpackage.integtest.js +11 -0
@@ -0,0 +1,1029 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fs_1 = require("fs");
4
+ const os = require("os");
5
+ const path = require("path");
6
+ const lib_1 = require("../../lib");
7
+ jest.setTimeout(60 * 60000); // Includes the time to acquire locks
8
+ describe('ci', () => {
9
+ lib_1.integTest('output to stderr', lib_1.withDefaultFixture(async (fixture) => {
10
+ const deployOutput = await fixture.cdkDeploy('test-2', { captureStderr: true, onlyStderr: true });
11
+ const diffOutput = await fixture.cdk(['diff', fixture.fullStackName('test-2')], { captureStderr: true, onlyStderr: true });
12
+ const destroyOutput = await fixture.cdkDestroy('test-2', { captureStderr: true, onlyStderr: true });
13
+ expect(deployOutput).not.toEqual('');
14
+ expect(destroyOutput).not.toEqual('');
15
+ expect(diffOutput).not.toEqual('');
16
+ }));
17
+ describe('ci=true', () => {
18
+ lib_1.integTest('output to stdout', lib_1.withDefaultFixture(async (fixture) => {
19
+ const execOptions = {
20
+ captureStderr: true,
21
+ onlyStderr: true,
22
+ modEnv: { CI: 'true' },
23
+ };
24
+ const deployOutput = await fixture.cdkDeploy('test-2', execOptions);
25
+ const diffOutput = await fixture.cdk(['diff', fixture.fullStackName('test-2')], execOptions);
26
+ const destroyOutput = await fixture.cdkDestroy('test-2', execOptions);
27
+ expect(deployOutput).toEqual('');
28
+ expect(destroyOutput).toEqual('');
29
+ expect(diffOutput).toEqual('');
30
+ }));
31
+ });
32
+ });
33
+ lib_1.integTest('VPC Lookup', lib_1.withDefaultFixture(async (fixture) => {
34
+ fixture.log('Making sure we are clean before starting.');
35
+ await fixture.cdkDestroy('define-vpc', { modEnv: { ENABLE_VPC_TESTING: 'DEFINE' } });
36
+ fixture.log('Setting up: creating a VPC with known tags');
37
+ await fixture.cdkDeploy('define-vpc', { modEnv: { ENABLE_VPC_TESTING: 'DEFINE' } });
38
+ fixture.log('Setup complete!');
39
+ fixture.log('Verifying we can now import that VPC');
40
+ await fixture.cdkDeploy('import-vpc', { modEnv: { ENABLE_VPC_TESTING: 'IMPORT' } });
41
+ }));
42
+ // testing a construct with a builtin Nodejs Lambda Function.
43
+ // In this case we are testing the s3.Bucket construct with the
44
+ // autoDeleteObjects prop set to true, which creates a Lambda backed
45
+ // CustomResource. Since the compiled Lambda code (e.g. __entrypoint__.js)
46
+ // is bundled as part of the CDK package, we want to make sure we don't
47
+ // introduce changes to the compiled code that could prevent the Lambda from
48
+ // executing. If we do, this test will timeout and fail.
49
+ lib_1.integTest('Construct with builtin Lambda function', lib_1.withDefaultFixture(async (fixture) => {
50
+ await fixture.cdkDeploy('builtin-lambda-function');
51
+ fixture.log('Setup complete!');
52
+ await fixture.cdkDestroy('builtin-lambda-function');
53
+ }));
54
+ // this is to ensure that asset bundling for apps under a stage does not break
55
+ lib_1.integTest('Stage with bundled Lambda function', lib_1.withDefaultFixture(async (fixture) => {
56
+ await fixture.cdkDeploy('bundling-stage/BundlingStack');
57
+ fixture.log('Setup complete!');
58
+ await fixture.cdkDestroy('bundling-stage/BundlingStack');
59
+ }));
60
+ lib_1.integTest('Two ways of showing the version', lib_1.withDefaultFixture(async (fixture) => {
61
+ const version1 = await fixture.cdk(['version'], { verbose: false });
62
+ const version2 = await fixture.cdk(['--version'], { verbose: false });
63
+ expect(version1).toEqual(version2);
64
+ }));
65
+ lib_1.integTest('Termination protection', lib_1.withDefaultFixture(async (fixture) => {
66
+ const stackName = 'termination-protection';
67
+ await fixture.cdkDeploy(stackName);
68
+ // Try a destroy that should fail
69
+ await expect(fixture.cdkDestroy(stackName)).rejects.toThrow('exited with error');
70
+ // Can update termination protection even though the change set doesn't contain changes
71
+ await fixture.cdkDeploy(stackName, { modEnv: { TERMINATION_PROTECTION: 'FALSE' } });
72
+ await fixture.cdkDestroy(stackName);
73
+ }));
74
+ lib_1.integTest('cdk synth', lib_1.withDefaultFixture(async (fixture) => {
75
+ await fixture.cdk(['synth', fixture.fullStackName('test-1')]);
76
+ expect(fixture.template('test-1')).toEqual(expect.objectContaining({
77
+ Resources: {
78
+ topic69831491: {
79
+ Type: 'AWS::SNS::Topic',
80
+ Metadata: {
81
+ 'aws:cdk:path': `${fixture.stackNamePrefix}-test-1/topic/Resource`,
82
+ },
83
+ },
84
+ },
85
+ }));
86
+ await fixture.cdk(['synth', fixture.fullStackName('test-2')], { verbose: false });
87
+ expect(fixture.template('test-2')).toEqual(expect.objectContaining({
88
+ Resources: {
89
+ topic152D84A37: {
90
+ Type: 'AWS::SNS::Topic',
91
+ Metadata: {
92
+ 'aws:cdk:path': `${fixture.stackNamePrefix}-test-2/topic1/Resource`,
93
+ },
94
+ },
95
+ topic2A4FB547F: {
96
+ Type: 'AWS::SNS::Topic',
97
+ Metadata: {
98
+ 'aws:cdk:path': `${fixture.stackNamePrefix}-test-2/topic2/Resource`,
99
+ },
100
+ },
101
+ },
102
+ }));
103
+ }));
104
+ lib_1.integTest('ssm parameter provider error', lib_1.withDefaultFixture(async (fixture) => {
105
+ await expect(fixture.cdk(['synth',
106
+ fixture.fullStackName('missing-ssm-parameter'),
107
+ '-c', 'test:ssm-parameter-name=/does/not/exist'], {
108
+ allowErrExit: true,
109
+ })).resolves.toContain('SSM parameter not available in account');
110
+ }));
111
+ lib_1.integTest('automatic ordering', lib_1.withDefaultFixture(async (fixture) => {
112
+ // Deploy the consuming stack which will include the producing stack
113
+ await fixture.cdkDeploy('order-consuming');
114
+ // Destroy the providing stack which will include the consuming stack
115
+ await fixture.cdkDestroy('order-providing');
116
+ }));
117
+ lib_1.integTest('automatic ordering with concurrency', lib_1.withDefaultFixture(async (fixture) => {
118
+ // Deploy the consuming stack which will include the producing stack
119
+ await fixture.cdkDeploy('order-consuming', { options: ['--concurrency', '2'] });
120
+ // Destroy the providing stack which will include the consuming stack
121
+ await fixture.cdkDestroy('order-providing');
122
+ }));
123
+ lib_1.integTest('--exclusively selects only selected stack', lib_1.withDefaultFixture(async (fixture) => {
124
+ // Deploy the "depends-on-failed" stack, with --exclusively. It will NOT fail (because
125
+ // of --exclusively) and it WILL create an output we can check for to confirm that it did
126
+ // get deployed.
127
+ const outputsFile = path.join(fixture.integTestDir, 'outputs', 'outputs.json');
128
+ await fs_1.promises.mkdir(path.dirname(outputsFile), { recursive: true });
129
+ await fixture.cdkDeploy('depends-on-failed', {
130
+ options: [
131
+ '--exclusively',
132
+ '--outputs-file', outputsFile,
133
+ ],
134
+ });
135
+ // Verify the output to see that the stack deployed
136
+ const outputs = JSON.parse((await fs_1.promises.readFile(outputsFile, { encoding: 'utf-8' })).toString());
137
+ expect(outputs).toEqual({
138
+ [`${fixture.stackNamePrefix}-depends-on-failed`]: {
139
+ TopicName: `${fixture.stackNamePrefix}-depends-on-failedMyTopic`,
140
+ },
141
+ });
142
+ }));
143
+ lib_1.integTest('context setting', lib_1.withDefaultFixture(async (fixture) => {
144
+ await fs_1.promises.writeFile(path.join(fixture.integTestDir, 'cdk.context.json'), JSON.stringify({
145
+ contextkey: 'this is the context value',
146
+ }));
147
+ try {
148
+ await expect(fixture.cdk(['context'])).resolves.toContain('this is the context value');
149
+ // Test that deleting the contextkey works
150
+ await fixture.cdk(['context', '--reset', 'contextkey']);
151
+ await expect(fixture.cdk(['context'])).resolves.not.toContain('this is the context value');
152
+ // Test that forced delete of the context key does not throw
153
+ await fixture.cdk(['context', '-f', '--reset', 'contextkey']);
154
+ }
155
+ finally {
156
+ await fs_1.promises.unlink(path.join(fixture.integTestDir, 'cdk.context.json'));
157
+ }
158
+ }));
159
+ lib_1.integTest('context in stage propagates to top', lib_1.withDefaultFixture(async (fixture) => {
160
+ await expect(fixture.cdkSynth({
161
+ // This will make it error to prove that the context bubbles up, and also that we can fail on command
162
+ options: ['--no-lookups'],
163
+ modEnv: {
164
+ INTEG_STACK_SET: 'stage-using-context',
165
+ },
166
+ allowErrExit: true,
167
+ })).resolves.toContain('Context lookups have been disabled');
168
+ }));
169
+ lib_1.integTest('deploy', lib_1.withDefaultFixture(async (fixture) => {
170
+ const stackArn = await fixture.cdkDeploy('test-2', { captureStderr: false });
171
+ // verify the number of resources in the stack
172
+ const response = await fixture.aws.cloudFormation('describeStackResources', {
173
+ StackName: stackArn,
174
+ });
175
+ expect(response.StackResources?.length).toEqual(2);
176
+ }));
177
+ lib_1.integTest('deploy --method=direct', lib_1.withDefaultFixture(async (fixture) => {
178
+ const stackArn = await fixture.cdkDeploy('test-2', {
179
+ options: ['--method=direct'],
180
+ captureStderr: false,
181
+ });
182
+ // verify the number of resources in the stack
183
+ const response = await fixture.aws.cloudFormation('describeStackResources', {
184
+ StackName: stackArn,
185
+ });
186
+ expect(response.StackResources?.length).toBeGreaterThan(0);
187
+ }));
188
+ lib_1.integTest('deploy all', lib_1.withDefaultFixture(async (fixture) => {
189
+ const arns = await fixture.cdkDeploy('test-*', { captureStderr: false });
190
+ // verify that we only deployed both stacks (there are 2 ARNs in the output)
191
+ expect(arns.split('\n').length).toEqual(2);
192
+ }));
193
+ lib_1.integTest('deploy all concurrently', lib_1.withDefaultFixture(async (fixture) => {
194
+ const arns = await fixture.cdkDeploy('test-*', {
195
+ captureStderr: false,
196
+ options: ['--concurrency', '2'],
197
+ });
198
+ // verify that we only deployed both stacks (there are 2 ARNs in the output)
199
+ expect(arns.split('\n').length).toEqual(2);
200
+ }));
201
+ lib_1.integTest('nested stack with parameters', lib_1.withDefaultFixture(async (fixture) => {
202
+ // STACK_NAME_PREFIX is used in MyTopicParam to allow multiple instances
203
+ // of this test to run in parallel, othewise they will attempt to create the same SNS topic.
204
+ const stackArn = await fixture.cdkDeploy('with-nested-stack-using-parameters', {
205
+ options: ['--parameters', `MyTopicParam=${fixture.stackNamePrefix}ThereIsNoSpoon`],
206
+ captureStderr: false,
207
+ });
208
+ // verify that we only deployed a single stack (there's a single ARN in the output)
209
+ expect(stackArn.split('\n').length).toEqual(1);
210
+ // verify the number of resources in the stack
211
+ const response = await fixture.aws.cloudFormation('describeStackResources', {
212
+ StackName: stackArn,
213
+ });
214
+ expect(response.StackResources?.length).toEqual(1);
215
+ }));
216
+ lib_1.integTest('deploy without execute a named change set', lib_1.withDefaultFixture(async (fixture) => {
217
+ const changeSetName = 'custom-change-set-name';
218
+ const stackArn = await fixture.cdkDeploy('test-2', {
219
+ options: ['--no-execute', '--change-set-name', changeSetName],
220
+ captureStderr: false,
221
+ });
222
+ // verify that we only deployed a single stack (there's a single ARN in the output)
223
+ expect(stackArn.split('\n').length).toEqual(1);
224
+ const response = await fixture.aws.cloudFormation('describeStacks', {
225
+ StackName: stackArn,
226
+ });
227
+ expect(response.Stacks?.[0].StackStatus).toEqual('REVIEW_IN_PROGRESS');
228
+ //verify a change set was created with the provided name
229
+ const changeSetResponse = await fixture.aws.cloudFormation('listChangeSets', {
230
+ StackName: stackArn,
231
+ });
232
+ const changeSets = changeSetResponse.Summaries || [];
233
+ expect(changeSets.length).toEqual(1);
234
+ expect(changeSets[0].ChangeSetName).toEqual(changeSetName);
235
+ expect(changeSets[0].Status).toEqual('CREATE_COMPLETE');
236
+ }));
237
+ lib_1.integTest('security related changes without a CLI are expected to fail', lib_1.withDefaultFixture(async (fixture) => {
238
+ // redirect /dev/null to stdin, which means there will not be tty attached
239
+ // since this stack includes security-related changes, the deployment should
240
+ // immediately fail because we can't confirm the changes
241
+ const stackName = 'iam-test';
242
+ await expect(fixture.cdkDeploy(stackName, {
243
+ options: ['<', '/dev/null'],
244
+ neverRequireApproval: false,
245
+ })).rejects.toThrow('exited with error');
246
+ // Ensure stack was not deployed
247
+ await expect(fixture.aws.cloudFormation('describeStacks', {
248
+ StackName: fixture.fullStackName(stackName),
249
+ })).rejects.toThrow('does not exist');
250
+ }));
251
+ lib_1.integTest('deploy wildcard with outputs', lib_1.withDefaultFixture(async (fixture) => {
252
+ const outputsFile = path.join(fixture.integTestDir, 'outputs', 'outputs.json');
253
+ await fs_1.promises.mkdir(path.dirname(outputsFile), { recursive: true });
254
+ await fixture.cdkDeploy(['outputs-test-*'], {
255
+ options: ['--outputs-file', outputsFile],
256
+ });
257
+ const outputs = JSON.parse((await fs_1.promises.readFile(outputsFile, { encoding: 'utf-8' })).toString());
258
+ expect(outputs).toEqual({
259
+ [`${fixture.stackNamePrefix}-outputs-test-1`]: {
260
+ TopicName: `${fixture.stackNamePrefix}-outputs-test-1MyTopic`,
261
+ },
262
+ [`${fixture.stackNamePrefix}-outputs-test-2`]: {
263
+ TopicName: `${fixture.stackNamePrefix}-outputs-test-2MyOtherTopic`,
264
+ },
265
+ });
266
+ }));
267
+ lib_1.integTest('deploy with parameters', lib_1.withDefaultFixture(async (fixture) => {
268
+ const stackArn = await fixture.cdkDeploy('param-test-1', {
269
+ options: [
270
+ '--parameters', `TopicNameParam=${fixture.stackNamePrefix}bazinga`,
271
+ ],
272
+ captureStderr: false,
273
+ });
274
+ const response = await fixture.aws.cloudFormation('describeStacks', {
275
+ StackName: stackArn,
276
+ });
277
+ expect(response.Stacks?.[0].Parameters).toContainEqual({
278
+ ParameterKey: 'TopicNameParam',
279
+ ParameterValue: `${fixture.stackNamePrefix}bazinga`,
280
+ });
281
+ }));
282
+ lib_1.integTest('update to stack in ROLLBACK_COMPLETE state will delete stack and create a new one', lib_1.withDefaultFixture(async (fixture) => {
283
+ // GIVEN
284
+ await expect(fixture.cdkDeploy('param-test-1', {
285
+ options: [
286
+ '--parameters', `TopicNameParam=${fixture.stackNamePrefix}@aww`,
287
+ ],
288
+ captureStderr: false,
289
+ })).rejects.toThrow('exited with error');
290
+ const response = await fixture.aws.cloudFormation('describeStacks', {
291
+ StackName: fixture.fullStackName('param-test-1'),
292
+ });
293
+ const stackArn = response.Stacks?.[0].StackId;
294
+ expect(response.Stacks?.[0].StackStatus).toEqual('ROLLBACK_COMPLETE');
295
+ // WHEN
296
+ const newStackArn = await fixture.cdkDeploy('param-test-1', {
297
+ options: [
298
+ '--parameters', `TopicNameParam=${fixture.stackNamePrefix}allgood`,
299
+ ],
300
+ captureStderr: false,
301
+ });
302
+ const newStackResponse = await fixture.aws.cloudFormation('describeStacks', {
303
+ StackName: newStackArn,
304
+ });
305
+ // THEN
306
+ expect(stackArn).not.toEqual(newStackArn); // new stack was created
307
+ expect(newStackResponse.Stacks?.[0].StackStatus).toEqual('CREATE_COMPLETE');
308
+ expect(newStackResponse.Stacks?.[0].Parameters).toContainEqual({
309
+ ParameterKey: 'TopicNameParam',
310
+ ParameterValue: `${fixture.stackNamePrefix}allgood`,
311
+ });
312
+ }));
313
+ lib_1.integTest('stack in UPDATE_ROLLBACK_COMPLETE state can be updated', lib_1.withDefaultFixture(async (fixture) => {
314
+ // GIVEN
315
+ const stackArn = await fixture.cdkDeploy('param-test-1', {
316
+ options: [
317
+ '--parameters', `TopicNameParam=${fixture.stackNamePrefix}nice`,
318
+ ],
319
+ captureStderr: false,
320
+ });
321
+ let response = await fixture.aws.cloudFormation('describeStacks', {
322
+ StackName: stackArn,
323
+ });
324
+ expect(response.Stacks?.[0].StackStatus).toEqual('CREATE_COMPLETE');
325
+ // bad parameter name with @ will put stack into UPDATE_ROLLBACK_COMPLETE
326
+ await expect(fixture.cdkDeploy('param-test-1', {
327
+ options: [
328
+ '--parameters', `TopicNameParam=${fixture.stackNamePrefix}@aww`,
329
+ ],
330
+ captureStderr: false,
331
+ })).rejects.toThrow('exited with error');
332
+ ;
333
+ response = await fixture.aws.cloudFormation('describeStacks', {
334
+ StackName: stackArn,
335
+ });
336
+ expect(response.Stacks?.[0].StackStatus).toEqual('UPDATE_ROLLBACK_COMPLETE');
337
+ // WHEN
338
+ await fixture.cdkDeploy('param-test-1', {
339
+ options: [
340
+ '--parameters', `TopicNameParam=${fixture.stackNamePrefix}allgood`,
341
+ ],
342
+ captureStderr: false,
343
+ });
344
+ response = await fixture.aws.cloudFormation('describeStacks', {
345
+ StackName: stackArn,
346
+ });
347
+ // THEN
348
+ expect(response.Stacks?.[0].StackStatus).toEqual('UPDATE_COMPLETE');
349
+ expect(response.Stacks?.[0].Parameters).toContainEqual({
350
+ ParameterKey: 'TopicNameParam',
351
+ ParameterValue: `${fixture.stackNamePrefix}allgood`,
352
+ });
353
+ }));
354
+ lib_1.integTest('deploy with wildcard and parameters', lib_1.withDefaultFixture(async (fixture) => {
355
+ await fixture.cdkDeploy('param-test-*', {
356
+ options: [
357
+ '--parameters', `${fixture.stackNamePrefix}-param-test-1:TopicNameParam=${fixture.stackNamePrefix}bazinga`,
358
+ '--parameters', `${fixture.stackNamePrefix}-param-test-2:OtherTopicNameParam=${fixture.stackNamePrefix}ThatsMySpot`,
359
+ '--parameters', `${fixture.stackNamePrefix}-param-test-3:DisplayNameParam=${fixture.stackNamePrefix}HeyThere`,
360
+ '--parameters', `${fixture.stackNamePrefix}-param-test-3:OtherDisplayNameParam=${fixture.stackNamePrefix}AnotherOne`,
361
+ ],
362
+ });
363
+ }));
364
+ lib_1.integTest('deploy with parameters multi', lib_1.withDefaultFixture(async (fixture) => {
365
+ const paramVal1 = `${fixture.stackNamePrefix}bazinga`;
366
+ const paramVal2 = `${fixture.stackNamePrefix}=jagshemash`;
367
+ const stackArn = await fixture.cdkDeploy('param-test-3', {
368
+ options: [
369
+ '--parameters', `DisplayNameParam=${paramVal1}`,
370
+ '--parameters', `OtherDisplayNameParam=${paramVal2}`,
371
+ ],
372
+ captureStderr: false,
373
+ });
374
+ const response = await fixture.aws.cloudFormation('describeStacks', {
375
+ StackName: stackArn,
376
+ });
377
+ expect(response.Stacks?.[0].Parameters).toContainEqual({
378
+ ParameterKey: 'DisplayNameParam',
379
+ ParameterValue: paramVal1,
380
+ });
381
+ expect(response.Stacks?.[0].Parameters).toContainEqual({
382
+ ParameterKey: 'OtherDisplayNameParam',
383
+ ParameterValue: paramVal2,
384
+ });
385
+ }));
386
+ lib_1.integTest('deploy with notification ARN', lib_1.withDefaultFixture(async (fixture) => {
387
+ const topicName = `${fixture.stackNamePrefix}-test-topic`;
388
+ const response = await fixture.aws.sns('createTopic', { Name: topicName });
389
+ const topicArn = response.TopicArn;
390
+ try {
391
+ await fixture.cdkDeploy('test-2', {
392
+ options: ['--notification-arns', topicArn],
393
+ });
394
+ // verify that the stack we deployed has our notification ARN
395
+ const describeResponse = await fixture.aws.cloudFormation('describeStacks', {
396
+ StackName: fixture.fullStackName('test-2'),
397
+ });
398
+ expect(describeResponse.Stacks?.[0].NotificationARNs).toEqual([topicArn]);
399
+ }
400
+ finally {
401
+ await fixture.aws.sns('deleteTopic', {
402
+ TopicArn: topicArn,
403
+ });
404
+ }
405
+ }));
406
+ // NOTE: this doesn't currently work with modern-style synthesis, as the bootstrap
407
+ // role by default will not have permission to iam:PassRole the created role.
408
+ lib_1.integTest('deploy with role', lib_1.withDefaultFixture(async (fixture) => {
409
+ if (fixture.packages.majorVersion() !== '1') {
410
+ return; // Nothing to do
411
+ }
412
+ const roleName = `${fixture.stackNamePrefix}-test-role`;
413
+ await deleteRole();
414
+ const createResponse = await fixture.aws.iam('createRole', {
415
+ RoleName: roleName,
416
+ AssumeRolePolicyDocument: JSON.stringify({
417
+ Version: '2012-10-17',
418
+ Statement: [{
419
+ Action: 'sts:AssumeRole',
420
+ Principal: { Service: 'cloudformation.amazonaws.com' },
421
+ Effect: 'Allow',
422
+ }, {
423
+ Action: 'sts:AssumeRole',
424
+ Principal: { AWS: (await fixture.aws.sts('getCallerIdentity', {})).Arn },
425
+ Effect: 'Allow',
426
+ }],
427
+ }),
428
+ });
429
+ const roleArn = createResponse.Role.Arn;
430
+ try {
431
+ await fixture.aws.iam('putRolePolicy', {
432
+ RoleName: roleName,
433
+ PolicyName: 'DefaultPolicy',
434
+ PolicyDocument: JSON.stringify({
435
+ Version: '2012-10-17',
436
+ Statement: [{
437
+ Action: '*',
438
+ Resource: '*',
439
+ Effect: 'Allow',
440
+ }],
441
+ }),
442
+ });
443
+ await lib_1.retry(fixture.output, 'Trying to assume fresh role', lib_1.retry.forSeconds(300), async () => {
444
+ await fixture.aws.sts('assumeRole', {
445
+ RoleArn: roleArn,
446
+ RoleSessionName: 'testing',
447
+ });
448
+ });
449
+ // In principle, the role has replicated from 'us-east-1' to wherever we're testing.
450
+ // Give it a little more sleep to make sure CloudFormation is not hitting a box
451
+ // that doesn't have it yet.
452
+ await lib_1.sleep(5000);
453
+ await fixture.cdkDeploy('test-2', {
454
+ options: ['--role-arn', roleArn],
455
+ });
456
+ // Immediately delete the stack again before we delete the role.
457
+ //
458
+ // Since roles are sticky, if we delete the role before the stack, subsequent DeleteStack
459
+ // operations will fail when CloudFormation tries to assume the role that's already gone.
460
+ await fixture.cdkDestroy('test-2');
461
+ }
462
+ finally {
463
+ await deleteRole();
464
+ }
465
+ async function deleteRole() {
466
+ try {
467
+ for (const policyName of (await fixture.aws.iam('listRolePolicies', { RoleName: roleName })).PolicyNames) {
468
+ await fixture.aws.iam('deleteRolePolicy', {
469
+ RoleName: roleName,
470
+ PolicyName: policyName,
471
+ });
472
+ }
473
+ await fixture.aws.iam('deleteRole', { RoleName: roleName });
474
+ }
475
+ catch (e) {
476
+ if (e.message.indexOf('cannot be found') > -1) {
477
+ return;
478
+ }
479
+ throw e;
480
+ }
481
+ }
482
+ }));
483
+ lib_1.integTest('cdk diff', lib_1.withDefaultFixture(async (fixture) => {
484
+ const diff1 = await fixture.cdk(['diff', fixture.fullStackName('test-1')]);
485
+ expect(diff1).toContain('AWS::SNS::Topic');
486
+ const diff2 = await fixture.cdk(['diff', fixture.fullStackName('test-2')]);
487
+ expect(diff2).toContain('AWS::SNS::Topic');
488
+ // We can make it fail by passing --fail
489
+ await expect(fixture.cdk(['diff', '--fail', fixture.fullStackName('test-1')]))
490
+ .rejects.toThrow('exited with error');
491
+ }));
492
+ lib_1.integTest('enableDiffNoFail', lib_1.withDefaultFixture(async (fixture) => {
493
+ await diffShouldSucceedWith({ fail: false, enableDiffNoFail: false });
494
+ await diffShouldSucceedWith({ fail: false, enableDiffNoFail: true });
495
+ await diffShouldFailWith({ fail: true, enableDiffNoFail: false });
496
+ await diffShouldFailWith({ fail: true, enableDiffNoFail: true });
497
+ await diffShouldFailWith({ fail: undefined, enableDiffNoFail: false });
498
+ await diffShouldSucceedWith({ fail: undefined, enableDiffNoFail: true });
499
+ async function diffShouldSucceedWith(props) {
500
+ await expect(diff(props)).resolves.not.toThrowError();
501
+ }
502
+ async function diffShouldFailWith(props) {
503
+ await expect(diff(props)).rejects.toThrow('exited with error');
504
+ }
505
+ async function diff(props) {
506
+ await updateContext(props.enableDiffNoFail);
507
+ const flag = props.fail != null
508
+ ? (props.fail ? '--fail' : '--no-fail')
509
+ : '';
510
+ return fixture.cdk(['diff', flag, fixture.fullStackName('test-1')]);
511
+ }
512
+ async function updateContext(enableDiffNoFail) {
513
+ const cdkJson = JSON.parse(await fs_1.promises.readFile(path.join(fixture.integTestDir, 'cdk.json'), 'utf8'));
514
+ cdkJson.context = {
515
+ ...cdkJson.context,
516
+ 'aws-cdk:enableDiffNoFail': enableDiffNoFail,
517
+ };
518
+ await fs_1.promises.writeFile(path.join(fixture.integTestDir, 'cdk.json'), JSON.stringify(cdkJson));
519
+ }
520
+ }));
521
+ lib_1.integTest('cdk diff --fail on multiple stacks exits with error if any of the stacks contains a diff', lib_1.withDefaultFixture(async (fixture) => {
522
+ // GIVEN
523
+ const diff1 = await fixture.cdk(['diff', fixture.fullStackName('test-1')]);
524
+ expect(diff1).toContain('AWS::SNS::Topic');
525
+ await fixture.cdkDeploy('test-2');
526
+ const diff2 = await fixture.cdk(['diff', fixture.fullStackName('test-2')]);
527
+ expect(diff2).toContain('There were no differences');
528
+ // WHEN / THEN
529
+ await expect(fixture.cdk(['diff', '--fail', fixture.fullStackName('test-1'), fixture.fullStackName('test-2')])).rejects.toThrow('exited with error');
530
+ }));
531
+ lib_1.integTest('cdk diff --fail with multiple stack exits with if any of the stacks contains a diff', lib_1.withDefaultFixture(async (fixture) => {
532
+ // GIVEN
533
+ await fixture.cdkDeploy('test-1');
534
+ const diff1 = await fixture.cdk(['diff', fixture.fullStackName('test-1')]);
535
+ expect(diff1).toContain('There were no differences');
536
+ const diff2 = await fixture.cdk(['diff', fixture.fullStackName('test-2')]);
537
+ expect(diff2).toContain('AWS::SNS::Topic');
538
+ // WHEN / THEN
539
+ await expect(fixture.cdk(['diff', '--fail', fixture.fullStackName('test-1'), fixture.fullStackName('test-2')])).rejects.toThrow('exited with error');
540
+ }));
541
+ lib_1.integTest('cdk diff --security-only --fail exits when security changes are present', lib_1.withDefaultFixture(async (fixture) => {
542
+ const stackName = 'iam-test';
543
+ await expect(fixture.cdk(['diff', '--security-only', '--fail', fixture.fullStackName(stackName)])).rejects.toThrow('exited with error');
544
+ }));
545
+ lib_1.integTest('deploy stack with docker asset', lib_1.withDefaultFixture(async (fixture) => {
546
+ await fixture.cdkDeploy('docker');
547
+ }));
548
+ lib_1.integTest('deploy and test stack with lambda asset', lib_1.withDefaultFixture(async (fixture) => {
549
+ const stackArn = await fixture.cdkDeploy('lambda', { captureStderr: false });
550
+ const response = await fixture.aws.cloudFormation('describeStacks', {
551
+ StackName: stackArn,
552
+ });
553
+ const lambdaArn = response.Stacks?.[0].Outputs?.[0].OutputValue;
554
+ if (lambdaArn === undefined) {
555
+ throw new Error('Stack did not have expected Lambda ARN output');
556
+ }
557
+ const output = await fixture.aws.lambda('invoke', {
558
+ FunctionName: lambdaArn,
559
+ });
560
+ expect(JSON.stringify(output.Payload)).toContain('dear asset');
561
+ }));
562
+ lib_1.integTest('cdk ls', lib_1.withDefaultFixture(async (fixture) => {
563
+ const listing = await fixture.cdk(['ls'], { captureStderr: false });
564
+ const expectedStacks = [
565
+ 'conditional-resource',
566
+ 'docker',
567
+ 'docker-with-custom-file',
568
+ 'failed',
569
+ 'iam-test',
570
+ 'lambda',
571
+ 'missing-ssm-parameter',
572
+ 'order-providing',
573
+ 'outputs-test-1',
574
+ 'outputs-test-2',
575
+ 'param-test-1',
576
+ 'param-test-2',
577
+ 'param-test-3',
578
+ 'termination-protection',
579
+ 'test-1',
580
+ 'test-2',
581
+ 'with-nested-stack',
582
+ 'with-nested-stack-using-parameters',
583
+ 'order-consuming',
584
+ ];
585
+ for (const stack of expectedStacks) {
586
+ expect(listing).toContain(fixture.fullStackName(stack));
587
+ }
588
+ }));
589
+ lib_1.integTest('synthing a stage with errors leads to failure', lib_1.withDefaultFixture(async (fixture) => {
590
+ const output = await fixture.cdk(['synth'], {
591
+ allowErrExit: true,
592
+ modEnv: {
593
+ INTEG_STACK_SET: 'stage-with-errors',
594
+ },
595
+ });
596
+ expect(output).toContain('This is an error');
597
+ }));
598
+ lib_1.integTest('synthing a stage with errors can be suppressed', lib_1.withDefaultFixture(async (fixture) => {
599
+ await fixture.cdk(['synth', '--no-validation'], {
600
+ modEnv: {
601
+ INTEG_STACK_SET: 'stage-with-errors',
602
+ },
603
+ });
604
+ }));
605
+ lib_1.integTest('deploy stack without resource', lib_1.withDefaultFixture(async (fixture) => {
606
+ // Deploy the stack without resources
607
+ await fixture.cdkDeploy('conditional-resource', { modEnv: { NO_RESOURCE: 'TRUE' } });
608
+ // This should have succeeded but not deployed the stack.
609
+ await expect(fixture.aws.cloudFormation('describeStacks', { StackName: fixture.fullStackName('conditional-resource') }))
610
+ .rejects.toThrow('conditional-resource does not exist');
611
+ // Deploy the stack with resources
612
+ await fixture.cdkDeploy('conditional-resource');
613
+ // Then again WITHOUT resources (this should destroy the stack)
614
+ await fixture.cdkDeploy('conditional-resource', { modEnv: { NO_RESOURCE: 'TRUE' } });
615
+ await expect(fixture.aws.cloudFormation('describeStacks', { StackName: fixture.fullStackName('conditional-resource') }))
616
+ .rejects.toThrow('conditional-resource does not exist');
617
+ }));
618
+ lib_1.integTest('IAM diff', lib_1.withDefaultFixture(async (fixture) => {
619
+ const output = await fixture.cdk(['diff', fixture.fullStackName('iam-test')]);
620
+ // Roughly check for a table like this:
621
+ //
622
+ // ┌───┬─────────────────┬────────┬────────────────┬────────────────────────────-──┬───────────┐
623
+ // │ │ Resource │ Effect │ Action │ Principal │ Condition │
624
+ // ├───┼─────────────────┼────────┼────────────────┼───────────────────────────────┼───────────┤
625
+ // │ + │ ${SomeRole.Arn} │ Allow │ sts:AssumeRole │ Service:ec2.amazonaws.com │ │
626
+ // └───┴─────────────────┴────────┴────────────────┴───────────────────────────────┴───────────┘
627
+ expect(output).toContain('${SomeRole.Arn}');
628
+ expect(output).toContain('sts:AssumeRole');
629
+ expect(output).toContain('ec2.amazonaws.com');
630
+ }));
631
+ lib_1.integTest('fast deploy', lib_1.withDefaultFixture(async (fixture) => {
632
+ // we are using a stack with a nested stack because CFN will always attempt to
633
+ // update a nested stack, which will allow us to verify that updates are actually
634
+ // skipped unless --force is specified.
635
+ const stackArn = await fixture.cdkDeploy('with-nested-stack', { captureStderr: false });
636
+ const changeSet1 = await getLatestChangeSet();
637
+ // Deploy the same stack again, there should be no new change set created
638
+ await fixture.cdkDeploy('with-nested-stack');
639
+ const changeSet2 = await getLatestChangeSet();
640
+ expect(changeSet2.ChangeSetId).toEqual(changeSet1.ChangeSetId);
641
+ // Deploy the stack again with --force, now we should create a changeset
642
+ await fixture.cdkDeploy('with-nested-stack', { options: ['--force'] });
643
+ const changeSet3 = await getLatestChangeSet();
644
+ expect(changeSet3.ChangeSetId).not.toEqual(changeSet2.ChangeSetId);
645
+ // Deploy the stack again with tags, expected to create a new changeset
646
+ // even though the resources didn't change.
647
+ await fixture.cdkDeploy('with-nested-stack', { options: ['--tags', 'key=value'] });
648
+ const changeSet4 = await getLatestChangeSet();
649
+ expect(changeSet4.ChangeSetId).not.toEqual(changeSet3.ChangeSetId);
650
+ async function getLatestChangeSet() {
651
+ const response = await fixture.aws.cloudFormation('describeStacks', { StackName: stackArn });
652
+ if (!response.Stacks?.[0]) {
653
+ throw new Error('Did not get a ChangeSet at all');
654
+ }
655
+ fixture.log(`Found Change Set ${response.Stacks?.[0].ChangeSetId}`);
656
+ return response.Stacks?.[0];
657
+ }
658
+ }));
659
+ lib_1.integTest('failed deploy does not hang', lib_1.withDefaultFixture(async (fixture) => {
660
+ // this will hang if we introduce https://github.com/aws/aws-cdk/issues/6403 again.
661
+ await expect(fixture.cdkDeploy('failed')).rejects.toThrow('exited with error');
662
+ }));
663
+ lib_1.integTest('can still load old assemblies', lib_1.withDefaultFixture(async (fixture) => {
664
+ const cxAsmDir = path.join(os.tmpdir(), 'cdk-integ-cx');
665
+ const testAssembliesDirectory = path.join(lib_1.RESOURCES_DIR, 'cloud-assemblies');
666
+ for (const asmdir of await listChildDirs(testAssembliesDirectory)) {
667
+ fixture.log(`ASSEMBLY ${asmdir}`);
668
+ await lib_1.cloneDirectory(asmdir, cxAsmDir);
669
+ // Some files in the asm directory that have a .js extension are
670
+ // actually treated as templates. Evaluate them using NodeJS.
671
+ const templates = await listChildren(cxAsmDir, fullPath => Promise.resolve(fullPath.endsWith('.js')));
672
+ for (const template of templates) {
673
+ const targetName = template.replace(/.js$/, '');
674
+ await lib_1.shell([process.execPath, template, '>', targetName], {
675
+ cwd: cxAsmDir,
676
+ output: fixture.output,
677
+ modEnv: {
678
+ TEST_ACCOUNT: await fixture.aws.account(),
679
+ TEST_REGION: fixture.aws.region,
680
+ },
681
+ });
682
+ }
683
+ // Use this directory as a Cloud Assembly
684
+ const output = await fixture.cdk([
685
+ '--app', cxAsmDir,
686
+ '-v',
687
+ 'synth',
688
+ ]);
689
+ // Assert that there was no providerError in CDK's stderr
690
+ // Because we rely on the app/framework to actually error in case the
691
+ // provider fails, we inspect the logs here.
692
+ expect(output).not.toContain('$providerError');
693
+ }
694
+ }));
695
+ lib_1.integTest('generating and loading assembly', lib_1.withDefaultFixture(async (fixture) => {
696
+ const asmOutputDir = `${fixture.integTestDir}-cdk-integ-asm`;
697
+ await fixture.shell(['rm', '-rf', asmOutputDir]);
698
+ // Synthesize a Cloud Assembly tothe default directory (cdk.out) and a specific directory.
699
+ await fixture.cdk(['synth']);
700
+ await fixture.cdk(['synth', '--output', asmOutputDir]);
701
+ // cdk.out in the current directory and the indicated --output should be the same
702
+ await fixture.shell(['diff', 'cdk.out', asmOutputDir]);
703
+ // Check that we can 'ls' the synthesized asm.
704
+ // Change to some random directory to make sure we're not accidentally loading cdk.json
705
+ const list = await fixture.cdk(['--app', asmOutputDir, 'ls'], { cwd: os.tmpdir() });
706
+ // Same stacks we know are in the app
707
+ expect(list).toContain(`${fixture.stackNamePrefix}-lambda`);
708
+ expect(list).toContain(`${fixture.stackNamePrefix}-test-1`);
709
+ expect(list).toContain(`${fixture.stackNamePrefix}-test-2`);
710
+ // Check that we can use '.' and just synth ,the generated asm
711
+ const stackTemplate = await fixture.cdk(['--app', '.', 'synth', fixture.fullStackName('test-2')], {
712
+ cwd: asmOutputDir,
713
+ });
714
+ expect(stackTemplate).toContain('topic152D84A37');
715
+ // Deploy a Lambda from the copied asm
716
+ await fixture.cdkDeploy('lambda', { options: ['-a', '.'], cwd: asmOutputDir });
717
+ // Remove (rename) the original custom docker file that was used during synth.
718
+ // this verifies that the assemly has a copy of it and that the manifest uses
719
+ // relative paths to reference to it.
720
+ const customDockerFile = path.join(fixture.integTestDir, 'docker', 'Dockerfile.Custom');
721
+ await fs_1.promises.rename(customDockerFile, `${customDockerFile}~`);
722
+ try {
723
+ // deploy a docker image with custom file without synth (uses assets)
724
+ await fixture.cdkDeploy('docker-with-custom-file', { options: ['-a', '.'], cwd: asmOutputDir });
725
+ }
726
+ finally {
727
+ // Rename back to restore fixture to original state
728
+ await fs_1.promises.rename(`${customDockerFile}~`, customDockerFile);
729
+ }
730
+ }));
731
+ lib_1.integTest('templates on disk contain metadata resource, also in nested assemblies', lib_1.withDefaultFixture(async (fixture) => {
732
+ // Synth first, and switch on version reporting because cdk.json is disabling it
733
+ await fixture.cdk(['synth', '--version-reporting=true']);
734
+ // Load template from disk from root assembly
735
+ const templateContents = await fixture.shell(['cat', 'cdk.out/*-lambda.template.json']);
736
+ expect(JSON.parse(templateContents).Resources.CDKMetadata).toBeTruthy();
737
+ // Load template from nested assembly
738
+ const nestedTemplateContents = await fixture.shell(['cat', 'cdk.out/assembly-*-stage/*StackInStage*.template.json']);
739
+ expect(JSON.parse(nestedTemplateContents).Resources.CDKMetadata).toBeTruthy();
740
+ }));
741
+ lib_1.integTest('CDK synth add the metadata properties expected by sam', lib_1.withSamIntegrationFixture(async (fixture) => {
742
+ // Synth first
743
+ await fixture.cdkSynth();
744
+ const template = fixture.template('TestStack');
745
+ const expectedResources = [
746
+ {
747
+ // Python Layer Version
748
+ id: 'PythonLayerVersion39495CEF',
749
+ cdkId: 'PythonLayerVersion',
750
+ isBundled: true,
751
+ property: 'Content',
752
+ },
753
+ {
754
+ // Layer Version
755
+ id: 'LayerVersion3878DA3A',
756
+ cdkId: 'LayerVersion',
757
+ isBundled: false,
758
+ property: 'Content',
759
+ },
760
+ {
761
+ // Bundled layer version
762
+ id: 'BundledLayerVersionPythonRuntime6BADBD6E',
763
+ cdkId: 'BundledLayerVersionPythonRuntime',
764
+ isBundled: true,
765
+ property: 'Content',
766
+ },
767
+ {
768
+ // Python Function
769
+ id: 'PythonFunction0BCF77FD',
770
+ cdkId: 'PythonFunction',
771
+ isBundled: true,
772
+ property: 'Code',
773
+ },
774
+ {
775
+ // Log Retention Function
776
+ id: 'LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A',
777
+ cdkId: 'LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a',
778
+ isBundled: false,
779
+ property: 'Code',
780
+ },
781
+ {
782
+ // Function
783
+ id: 'FunctionPythonRuntime28CBDA05',
784
+ cdkId: 'FunctionPythonRuntime',
785
+ isBundled: false,
786
+ property: 'Code',
787
+ },
788
+ {
789
+ // Bundled Function
790
+ id: 'BundledFunctionPythonRuntime4D9A0918',
791
+ cdkId: 'BundledFunctionPythonRuntime',
792
+ isBundled: true,
793
+ property: 'Code',
794
+ },
795
+ {
796
+ // NodeJs Function
797
+ id: 'NodejsFunction09C1F20F',
798
+ cdkId: 'NodejsFunction',
799
+ isBundled: true,
800
+ property: 'Code',
801
+ },
802
+ {
803
+ // Go Function
804
+ id: 'GoFunctionCA95FBAA',
805
+ cdkId: 'GoFunction',
806
+ isBundled: true,
807
+ property: 'Code',
808
+ },
809
+ {
810
+ // Docker Image Function
811
+ id: 'DockerImageFunction28B773E6',
812
+ cdkId: 'DockerImageFunction',
813
+ dockerFilePath: 'Dockerfile',
814
+ property: 'Code.ImageUri',
815
+ },
816
+ {
817
+ // Spec Rest Api
818
+ id: 'SpecRestAPI7D4B3A34',
819
+ cdkId: 'SpecRestAPI',
820
+ property: 'BodyS3Location',
821
+ },
822
+ ];
823
+ for (const resource of expectedResources) {
824
+ fixture.output.write(`validate assets metadata for resource ${resource}`);
825
+ expect(resource.id in template.Resources).toBeTruthy();
826
+ expect(template.Resources[resource.id]).toEqual(expect.objectContaining({
827
+ Metadata: {
828
+ 'aws:cdk:path': `${fixture.fullStackName('TestStack')}/${resource.cdkId}/Resource`,
829
+ 'aws:asset:path': expect.stringMatching(/asset\.[0-9a-zA-Z]{64}/),
830
+ 'aws:asset:is-bundled': resource.isBundled,
831
+ 'aws:asset:dockerfile-path': resource.dockerFilePath,
832
+ 'aws:asset:property': resource.property,
833
+ },
834
+ }));
835
+ }
836
+ // Nested Stack
837
+ fixture.output.write('validate assets metadata for nested stack resource');
838
+ expect('NestedStackNestedStackNestedStackNestedStackResourceB70834FD' in template.Resources).toBeTruthy();
839
+ expect(template.Resources.NestedStackNestedStackNestedStackNestedStackResourceB70834FD).toEqual(expect.objectContaining({
840
+ Metadata: {
841
+ 'aws:cdk:path': `${fixture.fullStackName('TestStack')}/NestedStack.NestedStack/NestedStack.NestedStackResource`,
842
+ 'aws:asset:path': expect.stringMatching(`${fixture.stackNamePrefix.replace(/-/, '')}TestStackNestedStack[0-9A-Z]{8}\.nested\.template\.json`),
843
+ 'aws:asset:property': 'TemplateURL',
844
+ },
845
+ }));
846
+ }));
847
+ lib_1.integTest('CDK synth bundled functions as expected', lib_1.withSamIntegrationFixture(async (fixture) => {
848
+ // Synth first
849
+ await fixture.cdkSynth();
850
+ const template = fixture.template('TestStack');
851
+ const expectedBundledAssets = [
852
+ {
853
+ // Python Layer Version
854
+ id: 'PythonLayerVersion39495CEF',
855
+ files: [
856
+ 'python/layer_version_dependency.py',
857
+ 'python/geonamescache/__init__.py',
858
+ 'python/geonamescache-1.3.0.dist-info',
859
+ ],
860
+ },
861
+ {
862
+ // Layer Version
863
+ id: 'LayerVersion3878DA3A',
864
+ files: [
865
+ 'layer_version_dependency.py',
866
+ 'requirements.txt',
867
+ ],
868
+ },
869
+ {
870
+ // Bundled layer version
871
+ id: 'BundledLayerVersionPythonRuntime6BADBD6E',
872
+ files: [
873
+ 'python/layer_version_dependency.py',
874
+ 'python/geonamescache/__init__.py',
875
+ 'python/geonamescache-1.3.0.dist-info',
876
+ ],
877
+ },
878
+ {
879
+ // Python Function
880
+ id: 'PythonFunction0BCF77FD',
881
+ files: [
882
+ 'app.py',
883
+ 'geonamescache/__init__.py',
884
+ 'geonamescache-1.3.0.dist-info',
885
+ ],
886
+ },
887
+ {
888
+ // Function
889
+ id: 'FunctionPythonRuntime28CBDA05',
890
+ files: [
891
+ 'app.py',
892
+ 'requirements.txt',
893
+ ],
894
+ },
895
+ {
896
+ // Bundled Function
897
+ id: 'BundledFunctionPythonRuntime4D9A0918',
898
+ files: [
899
+ 'app.py',
900
+ 'geonamescache/__init__.py',
901
+ 'geonamescache-1.3.0.dist-info',
902
+ ],
903
+ },
904
+ {
905
+ // NodeJs Function
906
+ id: 'NodejsFunction09C1F20F',
907
+ files: [
908
+ 'index.js',
909
+ ],
910
+ },
911
+ {
912
+ // Go Function
913
+ id: 'GoFunctionCA95FBAA',
914
+ files: [
915
+ 'bootstrap',
916
+ ],
917
+ },
918
+ {
919
+ // Docker Image Function
920
+ id: 'DockerImageFunction28B773E6',
921
+ files: [
922
+ 'app.js',
923
+ 'Dockerfile',
924
+ 'package.json',
925
+ ],
926
+ },
927
+ ];
928
+ for (const resource of expectedBundledAssets) {
929
+ const assetPath = template.Resources[resource.id].Metadata['aws:asset:path'];
930
+ for (const file of resource.files) {
931
+ fixture.output.write(`validate Path ${file} for resource ${resource}`);
932
+ expect(fs_1.existsSync(path.join(fixture.integTestDir, 'cdk.out', assetPath, file))).toBeTruthy();
933
+ }
934
+ }
935
+ }));
936
+ lib_1.integTest('sam can locally test the synthesized cdk application', lib_1.withSamIntegrationFixture(async (fixture) => {
937
+ // Synth first
938
+ await fixture.cdkSynth();
939
+ const result = await fixture.samLocalStartApi('TestStack', false, lib_1.randomInteger(30000, 40000), '/restapis/spec/pythonFunction');
940
+ expect(result.actionSucceeded).toBeTruthy();
941
+ expect(result.actionOutput).toEqual(expect.objectContaining({
942
+ message: 'Hello World',
943
+ }));
944
+ }));
945
+ lib_1.integTest('skips notice refresh', lib_1.withDefaultFixture(async (fixture) => {
946
+ const output = await fixture.cdkSynth({
947
+ options: ['--no-notices'],
948
+ modEnv: {
949
+ INTEG_STACK_SET: 'stage-using-context',
950
+ },
951
+ allowErrExit: true,
952
+ });
953
+ // Neither succeeds nor fails, but skips the refresh
954
+ await expect(output).not.toContain('Notices refreshed');
955
+ await expect(output).not.toContain('Notices refresh failed');
956
+ }));
957
+ /**
958
+ * Create a queue with a fresh name, redeploy orphaning the queue, then import it again
959
+ */
960
+ lib_1.integTest('test resource import', lib_1.withDefaultFixture(async (fixture) => {
961
+ const outputsFile = path.join(fixture.integTestDir, 'outputs', 'outputs.json');
962
+ await fs_1.promises.mkdir(path.dirname(outputsFile), { recursive: true });
963
+ // Initial deploy
964
+ await fixture.cdkDeploy('importable-stack', {
965
+ modEnv: { ORPHAN_TOPIC: '1' },
966
+ options: ['--outputs-file', outputsFile],
967
+ });
968
+ const outputs = JSON.parse((await fs_1.promises.readFile(outputsFile, { encoding: 'utf-8' })).toString());
969
+ const queueName = outputs.QueueName;
970
+ const queueLogicalId = outputs.QueueLogicalId;
971
+ fixture.log(`Setup complete, created queue ${queueName}`);
972
+ try {
973
+ // Deploy again, orphaning the queue
974
+ await fixture.cdkDeploy('importable-stack', {
975
+ modEnv: { OMIT_TOPIC: '1' },
976
+ });
977
+ // Write a resource mapping file based on the ID from step one, then run an import
978
+ const mappingFile = path.join(fixture.integTestDir, 'outputs', 'mapping.json');
979
+ await fs_1.promises.writeFile(mappingFile, JSON.stringify({ [queueLogicalId]: { QueueName: queueName } }), { encoding: 'utf-8' });
980
+ await fixture.cdk(['import',
981
+ '--resource-mapping', mappingFile,
982
+ fixture.fullStackName('importable-stack')]);
983
+ }
984
+ finally {
985
+ // Cleanup
986
+ await fixture.cdkDestroy('importable-stack');
987
+ }
988
+ }));
989
+ lib_1.integTest('hotswap deployment supports Lambda function\'s description and environment variables', lib_1.withDefaultFixture(async (fixture) => {
990
+ // GIVEN
991
+ const stackArn = await fixture.cdkDeploy('lambda-hotswap', {
992
+ captureStderr: false,
993
+ modEnv: {
994
+ DYNAMIC_LAMBDA_PROPERTY_VALUE: 'original value',
995
+ },
996
+ });
997
+ // WHEN
998
+ const deployOutput = await fixture.cdkDeploy('lambda-hotswap', {
999
+ options: ['--hotswap'],
1000
+ captureStderr: true,
1001
+ onlyStderr: true,
1002
+ modEnv: {
1003
+ DYNAMIC_LAMBDA_PROPERTY_VALUE: 'new value',
1004
+ },
1005
+ });
1006
+ const response = await fixture.aws.cloudFormation('describeStacks', {
1007
+ StackName: stackArn,
1008
+ });
1009
+ const functionName = response.Stacks?.[0].Outputs?.[0].OutputValue;
1010
+ // THEN
1011
+ // The deployment should not trigger a full deployment, thus the stack's status must remains
1012
+ // "CREATE_COMPLETE"
1013
+ expect(response.Stacks?.[0].StackStatus).toEqual('CREATE_COMPLETE');
1014
+ expect(deployOutput).toContain(`Lambda Function '${functionName}' hotswapped!`);
1015
+ }));
1016
+ async function listChildren(parent, pred) {
1017
+ const ret = new Array();
1018
+ for (const child of await fs_1.promises.readdir(parent, { encoding: 'utf-8' })) {
1019
+ const fullPath = path.join(parent, child.toString());
1020
+ if (await pred(fullPath)) {
1021
+ ret.push(fullPath);
1022
+ }
1023
+ }
1024
+ return ret;
1025
+ }
1026
+ async function listChildDirs(parent) {
1027
+ return listChildren(parent, async (fullPath) => (await fs_1.promises.stat(fullPath)).isDirectory());
1028
+ }
1029
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmludGVndGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNsaS5pbnRlZ3Rlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwyQkFBZ0Q7QUFDaEQseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3QixtQ0FBd0o7QUFFeEosSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLEdBQUcsS0FBTSxDQUFDLENBQUMsQ0FBQyxxQ0FBcUM7QUFFbkUsUUFBUSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUU7SUFDbEIsZUFBUyxDQUFDLGtCQUFrQixFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtRQUNqRSxNQUFNLFlBQVksR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNsRyxNQUFNLFVBQVUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMzSCxNQUFNLGFBQWEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNwRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FB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QyxDQUFDO0FBRUosS0FBSyxVQUFVLFlBQVksQ0FBQyxNQUFjLEVBQUUsSUFBcUM7SUFDL0UsTUFBTSxHQUFHLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQztJQUNoQyxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sYUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRTtRQUNuRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNyRCxJQUFJLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQ3hCLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDcEI7S0FDRjtJQUNELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVELEtBQUssVUFBVSxhQUFhLENBQUMsTUFBYztJQUN6QyxPQUFPLFlBQVksQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQWdCLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxhQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUNuRyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcHJvbWlzZXMgYXMgZnMsIGV4aXN0c1N5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBvcyBmcm9tICdvcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgaW50ZWdUZXN0LCBjbG9uZURpcmVjdG9yeSwgc2hlbGwsIHdpdGhEZWZhdWx0Rml4dHVyZSwgcmV0cnksIHNsZWVwLCByYW5kb21JbnRlZ2VyLCB3aXRoU2FtSW50ZWdyYXRpb25GaXh0dXJlLCBSRVNPVVJDRVNfRElSIH0gZnJvbSAnLi4vLi4vbGliJztcblxuamVzdC5zZXRUaW1lb3V0KDYwICogNjBfMDAwKTsgLy8gSW5jbHVkZXMgdGhlIHRpbWUgdG8gYWNxdWlyZSBsb2Nrc1xuXG5kZXNjcmliZSgnY2knLCAoKSA9PiB7XG4gIGludGVnVGVzdCgnb3V0cHV0IHRvIHN0ZGVycicsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICAgIGNvbnN0IGRlcGxveU91dHB1dCA9IGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCd0ZXN0LTInLCB7IGNhcHR1cmVTdGRlcnI6IHRydWUsIG9ubHlTdGRlcnI6IHRydWUgfSk7XG4gICAgY29uc3QgZGlmZk91dHB1dCA9IGF3YWl0IGZpeHR1cmUuY2RrKFsnZGlmZicsIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0yJyldLCB7IGNhcHR1cmVTdGRlcnI6IHRydWUsIG9ubHlTdGRlcnI6IHRydWUgfSk7XG4gICAgY29uc3QgZGVzdHJveU91dHB1dCA9IGF3YWl0IGZpeHR1cmUuY2RrRGVzdHJveSgndGVzdC0yJywgeyBjYXB0dXJlU3RkZXJyOiB0cnVlLCBvbmx5U3RkZXJyOiB0cnVlIH0pO1xuICAgIGV4cGVjdChkZXBsb3lPdXRwdXQpLm5vdC50b0VxdWFsKCcnKTtcbiAgICBleHBlY3QoZGVzdHJveU91dHB1dCkubm90LnRvRXF1YWwoJycpO1xuICAgIGV4cGVjdChkaWZmT3V0cHV0KS5ub3QudG9FcXVhbCgnJyk7XG4gIH0pKTtcbiAgZGVzY3JpYmUoJ2NpPXRydWUnLCAoKSA9PiB7XG4gICAgaW50ZWdUZXN0KCdvdXRwdXQgdG8gc3Rkb3V0Jywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG5cbiAgICAgIGNvbnN0IGV4ZWNPcHRpb25zID0ge1xuICAgICAgICBjYXB0dXJlU3RkZXJyOiB0cnVlLFxuICAgICAgICBvbmx5U3RkZXJyOiB0cnVlLFxuICAgICAgICBtb2RFbnY6IHsgQ0k6ICd0cnVlJyB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgZGVwbG95T3V0cHV0ID0gYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ3Rlc3QtMicsIGV4ZWNPcHRpb25zKTtcbiAgICAgIGNvbnN0IGRpZmZPdXRwdXQgPSBhd2FpdCBmaXh0dXJlLmNkayhbJ2RpZmYnLCBmaXh0dXJlLmZ1bGxTdGFja05hbWUoJ3Rlc3QtMicpXSwgZXhlY09wdGlvbnMpO1xuICAgICAgY29uc3QgZGVzdHJveU91dHB1dCA9IGF3YWl0IGZpeHR1cmUuY2RrRGVzdHJveSgndGVzdC0yJywgZXhlY09wdGlvbnMpO1xuICAgICAgZXhwZWN0KGRlcGxveU91dHB1dCkudG9FcXVhbCgnJyk7XG4gICAgICBleHBlY3QoZGVzdHJveU91dHB1dCkudG9FcXVhbCgnJyk7XG4gICAgICBleHBlY3QoZGlmZk91dHB1dCkudG9FcXVhbCgnJyk7XG4gICAgfSkpO1xuICB9KTtcbn0pO1xuXG5pbnRlZ1Rlc3QoJ1ZQQyBMb29rdXAnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgZml4dHVyZS5sb2coJ01ha2luZyBzdXJlIHdlIGFyZSBjbGVhbiBiZWZvcmUgc3RhcnRpbmcuJyk7XG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVzdHJveSgnZGVmaW5lLXZwYycsIHsgbW9kRW52OiB7IEVOQUJMRV9WUENfVEVTVElORzogJ0RFRklORScgfSB9KTtcblxuICBmaXh0dXJlLmxvZygnU2V0dGluZyB1cDogY3JlYXRpbmcgYSBWUEMgd2l0aCBrbm93biB0YWdzJyk7XG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdkZWZpbmUtdnBjJywgeyBtb2RFbnY6IHsgRU5BQkxFX1ZQQ19URVNUSU5HOiAnREVGSU5FJyB9IH0pO1xuICBmaXh0dXJlLmxvZygnU2V0dXAgY29tcGxldGUhJyk7XG5cbiAgZml4dHVyZS5sb2coJ1ZlcmlmeWluZyB3ZSBjYW4gbm93IGltcG9ydCB0aGF0IFZQQycpO1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnaW1wb3J0LXZwYycsIHsgbW9kRW52OiB7IEVOQUJMRV9WUENfVEVTVElORzogJ0lNUE9SVCcgfSB9KTtcbn0pKTtcblxuLy8gdGVzdGluZyBhIGNvbnN0cnVjdCB3aXRoIGEgYnVpbHRpbiBOb2RlanMgTGFtYmRhIEZ1bmN0aW9uLlxuLy8gSW4gdGhpcyBjYXNlIHdlIGFyZSB0ZXN0aW5nIHRoZSBzMy5CdWNrZXQgY29uc3RydWN0IHdpdGggdGhlXG4vLyBhdXRvRGVsZXRlT2JqZWN0cyBwcm9wIHNldCB0byB0cnVlLCB3aGljaCBjcmVhdGVzIGEgTGFtYmRhIGJhY2tlZFxuLy8gQ3VzdG9tUmVzb3VyY2UuIFNpbmNlIHRoZSBjb21waWxlZCBMYW1iZGEgY29kZSAoZS5nLiBfX2VudHJ5cG9pbnRfXy5qcylcbi8vIGlzIGJ1bmRsZWQgYXMgcGFydCBvZiB0aGUgQ0RLIHBhY2thZ2UsIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHdlIGRvbid0XG4vLyBpbnRyb2R1Y2UgY2hhbmdlcyB0byB0aGUgY29tcGlsZWQgY29kZSB0aGF0IGNvdWxkIHByZXZlbnQgdGhlIExhbWJkYSBmcm9tXG4vLyBleGVjdXRpbmcuIElmIHdlIGRvLCB0aGlzIHRlc3Qgd2lsbCB0aW1lb3V0IGFuZCBmYWlsLlxuaW50ZWdUZXN0KCdDb25zdHJ1Y3Qgd2l0aCBidWlsdGluIExhbWJkYSBmdW5jdGlvbicsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnYnVpbHRpbi1sYW1iZGEtZnVuY3Rpb24nKTtcbiAgZml4dHVyZS5sb2coJ1NldHVwIGNvbXBsZXRlIScpO1xuICBhd2FpdCBmaXh0dXJlLmNka0Rlc3Ryb3koJ2J1aWx0aW4tbGFtYmRhLWZ1bmN0aW9uJyk7XG59KSk7XG5cbi8vIHRoaXMgaXMgdG8gZW5zdXJlIHRoYXQgYXNzZXQgYnVuZGxpbmcgZm9yIGFwcHMgdW5kZXIgYSBzdGFnZSBkb2VzIG5vdCBicmVha1xuaW50ZWdUZXN0KCdTdGFnZSB3aXRoIGJ1bmRsZWQgTGFtYmRhIGZ1bmN0aW9uJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdidW5kbGluZy1zdGFnZS9CdW5kbGluZ1N0YWNrJyk7XG4gIGZpeHR1cmUubG9nKCdTZXR1cCBjb21wbGV0ZSEnKTtcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXN0cm95KCdidW5kbGluZy1zdGFnZS9CdW5kbGluZ1N0YWNrJyk7XG59KSk7XG5cbmludGVnVGVzdCgnVHdvIHdheXMgb2Ygc2hvd2luZyB0aGUgdmVyc2lvbicsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCB2ZXJzaW9uMSA9IGF3YWl0IGZpeHR1cmUuY2RrKFsndmVyc2lvbiddLCB7IHZlcmJvc2U6IGZhbHNlIH0pO1xuICBjb25zdCB2ZXJzaW9uMiA9IGF3YWl0IGZpeHR1cmUuY2RrKFsnLS12ZXJzaW9uJ10sIHsgdmVyYm9zZTogZmFsc2UgfSk7XG5cbiAgZXhwZWN0KHZlcnNpb24xKS50b0VxdWFsKHZlcnNpb24yKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdUZXJtaW5hdGlvbiBwcm90ZWN0aW9uJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IHN0YWNrTmFtZSA9ICd0ZXJtaW5hdGlvbi1wcm90ZWN0aW9uJztcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koc3RhY2tOYW1lKTtcblxuICAvLyBUcnkgYSBkZXN0cm95IHRoYXQgc2hvdWxkIGZhaWxcbiAgYXdhaXQgZXhwZWN0KGZpeHR1cmUuY2RrRGVzdHJveShzdGFja05hbWUpKS5yZWplY3RzLnRvVGhyb3coJ2V4aXRlZCB3aXRoIGVycm9yJyk7XG5cbiAgLy8gQ2FuIHVwZGF0ZSB0ZXJtaW5hdGlvbiBwcm90ZWN0aW9uIGV2ZW4gdGhvdWdoIHRoZSBjaGFuZ2Ugc2V0IGRvZXNuJ3QgY29udGFpbiBjaGFuZ2VzXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KHN0YWNrTmFtZSwgeyBtb2RFbnY6IHsgVEVSTUlOQVRJT05fUFJPVEVDVElPTjogJ0ZBTFNFJyB9IH0pO1xuICBhd2FpdCBmaXh0dXJlLmNka0Rlc3Ryb3koc3RhY2tOYW1lKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjZGsgc3ludGgnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgYXdhaXQgZml4dHVyZS5jZGsoWydzeW50aCcsIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0xJyldKTtcbiAgZXhwZWN0KGZpeHR1cmUudGVtcGxhdGUoJ3Rlc3QtMScpKS50b0VxdWFsKGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICBSZXNvdXJjZXM6IHtcbiAgICAgIHRvcGljNjk4MzE0OTE6IHtcbiAgICAgICAgVHlwZTogJ0FXUzo6U05TOjpUb3BpYycsXG4gICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgJ2F3czpjZGs6cGF0aCc6IGAke2ZpeHR1cmUuc3RhY2tOYW1lUHJlZml4fS10ZXN0LTEvdG9waWMvUmVzb3VyY2VgLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KSk7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGsoWydzeW50aCcsIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0yJyldLCB7IHZlcmJvc2U6IGZhbHNlIH0pO1xuICBleHBlY3QoZml4dHVyZS50ZW1wbGF0ZSgndGVzdC0yJykpLnRvRXF1YWwoZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgIFJlc291cmNlczoge1xuICAgICAgdG9waWMxNTJEODRBMzc6IHtcbiAgICAgICAgVHlwZTogJ0FXUzo6U05TOjpUb3BpYycsXG4gICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgJ2F3czpjZGs6cGF0aCc6IGAke2ZpeHR1cmUuc3RhY2tOYW1lUHJlZml4fS10ZXN0LTIvdG9waWMxL1Jlc291cmNlYCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB0b3BpYzJBNEZCNTQ3Rjoge1xuICAgICAgICBUeXBlOiAnQVdTOjpTTlM6OlRvcGljJyxcbiAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAnYXdzOmNkazpwYXRoJzogYCR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9LXRlc3QtMi90b3BpYzIvUmVzb3VyY2VgLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KSk7XG59KSk7XG5cbmludGVnVGVzdCgnc3NtIHBhcmFtZXRlciBwcm92aWRlciBlcnJvcicsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBhd2FpdCBleHBlY3QoZml4dHVyZS5jZGsoWydzeW50aCcsXG4gICAgZml4dHVyZS5mdWxsU3RhY2tOYW1lKCdtaXNzaW5nLXNzbS1wYXJhbWV0ZXInKSxcbiAgICAnLWMnLCAndGVzdDpzc20tcGFyYW1ldGVyLW5hbWU9L2RvZXMvbm90L2V4aXN0J10sIHtcbiAgICBhbGxvd0VyckV4aXQ6IHRydWUsXG4gIH0pKS5yZXNvbHZlcy50b0NvbnRhaW4oJ1NTTSBwYXJhbWV0ZXIgbm90IGF2YWlsYWJsZSBpbiBhY2NvdW50Jyk7XG59KSk7XG5cbmludGVnVGVzdCgnYXV0b21hdGljIG9yZGVyaW5nJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIC8vIERlcGxveSB0aGUgY29uc3VtaW5nIHN0YWNrIHdoaWNoIHdpbGwgaW5jbHVkZSB0aGUgcHJvZHVjaW5nIHN0YWNrXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdvcmRlci1jb25zdW1pbmcnKTtcblxuICAvLyBEZXN0cm95IHRoZSBwcm92aWRpbmcgc3RhY2sgd2hpY2ggd2lsbCBpbmNsdWRlIHRoZSBjb25zdW1pbmcgc3RhY2tcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXN0cm95KCdvcmRlci1wcm92aWRpbmcnKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdhdXRvbWF0aWMgb3JkZXJpbmcgd2l0aCBjb25jdXJyZW5jeScsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICAvLyBEZXBsb3kgdGhlIGNvbnN1bWluZyBzdGFjayB3aGljaCB3aWxsIGluY2x1ZGUgdGhlIHByb2R1Y2luZyBzdGFja1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnb3JkZXItY29uc3VtaW5nJywgeyBvcHRpb25zOiBbJy0tY29uY3VycmVuY3knLCAnMiddIH0pO1xuXG4gIC8vIERlc3Ryb3kgdGhlIHByb3ZpZGluZyBzdGFjayB3aGljaCB3aWxsIGluY2x1ZGUgdGhlIGNvbnN1bWluZyBzdGFja1xuICBhd2FpdCBmaXh0dXJlLmNka0Rlc3Ryb3koJ29yZGVyLXByb3ZpZGluZycpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJy0tZXhjbHVzaXZlbHkgc2VsZWN0cyBvbmx5IHNlbGVjdGVkIHN0YWNrJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIC8vIERlcGxveSB0aGUgXCJkZXBlbmRzLW9uLWZhaWxlZFwiIHN0YWNrLCB3aXRoIC0tZXhjbHVzaXZlbHkuIEl0IHdpbGwgTk9UIGZhaWwgKGJlY2F1c2VcbiAgLy8gb2YgLS1leGNsdXNpdmVseSkgYW5kIGl0IFdJTEwgY3JlYXRlIGFuIG91dHB1dCB3ZSBjYW4gY2hlY2sgZm9yIHRvIGNvbmZpcm0gdGhhdCBpdCBkaWRcbiAgLy8gZ2V0IGRlcGxveWVkLlxuICBjb25zdCBvdXRwdXRzRmlsZSA9IHBhdGguam9pbihmaXh0dXJlLmludGVnVGVzdERpciwgJ291dHB1dHMnLCAnb3V0cHV0cy5qc29uJyk7XG4gIGF3YWl0IGZzLm1rZGlyKHBhdGguZGlybmFtZShvdXRwdXRzRmlsZSksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdkZXBlbmRzLW9uLWZhaWxlZCcsIHtcbiAgICBvcHRpb25zOiBbXG4gICAgICAnLS1leGNsdXNpdmVseScsXG4gICAgICAnLS1vdXRwdXRzLWZpbGUnLCBvdXRwdXRzRmlsZSxcbiAgICBdLFxuICB9KTtcblxuICAvLyBWZXJpZnkgdGhlIG91dHB1dCB0byBzZWUgdGhhdCB0aGUgc3RhY2sgZGVwbG95ZWRcbiAgY29uc3Qgb3V0cHV0cyA9IEpTT04ucGFyc2UoKGF3YWl0IGZzLnJlYWRGaWxlKG91dHB1dHNGaWxlLCB7IGVuY29kaW5nOiAndXRmLTgnIH0pKS50b1N0cmluZygpKTtcbiAgZXhwZWN0KG91dHB1dHMpLnRvRXF1YWwoe1xuICAgIFtgJHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH0tZGVwZW5kcy1vbi1mYWlsZWRgXToge1xuICAgICAgVG9waWNOYW1lOiBgJHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH0tZGVwZW5kcy1vbi1mYWlsZWRNeVRvcGljYCxcbiAgICB9LFxuICB9KTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjb250ZXh0IHNldHRpbmcnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgYXdhaXQgZnMud3JpdGVGaWxlKHBhdGguam9pbihmaXh0dXJlLmludGVnVGVzdERpciwgJ2Nkay5jb250ZXh0Lmpzb24nKSwgSlNPTi5zdHJpbmdpZnkoe1xuICAgIGNvbnRleHRrZXk6ICd0aGlzIGlzIHRoZSBjb250ZXh0IHZhbHVlJyxcbiAgfSkpO1xuICB0cnkge1xuICAgIGF3YWl0IGV4cGVjdChmaXh0dXJlLmNkayhbJ2NvbnRleHQnXSkpLnJlc29sdmVzLnRvQ29udGFpbigndGhpcyBpcyB0aGUgY29udGV4dCB2YWx1ZScpO1xuXG4gICAgLy8gVGVzdCB0aGF0IGRlbGV0aW5nIHRoZSBjb250ZXh0a2V5IHdvcmtzXG4gICAgYXdhaXQgZml4dHVyZS5jZGsoWydjb250ZXh0JywgJy0tcmVzZXQnLCAnY29udGV4dGtleSddKTtcbiAgICBhd2FpdCBleHBlY3QoZml4dHVyZS5jZGsoWydjb250ZXh0J10pKS5yZXNvbHZlcy5ub3QudG9Db250YWluKCd0aGlzIGlzIHRoZSBjb250ZXh0IHZhbHVlJyk7XG5cbiAgICAvLyBUZXN0IHRoYXQgZm9yY2VkIGRlbGV0ZSBvZiB0aGUgY29udGV4dCBrZXkgZG9lcyBub3QgdGhyb3dcbiAgICBhd2FpdCBmaXh0dXJlLmNkayhbJ2NvbnRleHQnLCAnLWYnLCAnLS1yZXNldCcsICdjb250ZXh0a2V5J10pO1xuXG4gIH0gZmluYWxseSB7XG4gICAgYXdhaXQgZnMudW5saW5rKHBhdGguam9pbihmaXh0dXJlLmludGVnVGVzdERpciwgJ2Nkay5jb250ZXh0Lmpzb24nKSk7XG4gIH1cbn0pKTtcblxuaW50ZWdUZXN0KCdjb250ZXh0IGluIHN0YWdlIHByb3BhZ2F0ZXMgdG8gdG9wJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGF3YWl0IGV4cGVjdChmaXh0dXJlLmNka1N5bnRoKHtcbiAgICAvLyBUaGlzIHdpbGwgbWFrZSBpdCBlcnJvciB0byBwcm92ZSB0aGF0IHRoZSBjb250ZXh0IGJ1YmJsZXMgdXAsIGFuZCBhbHNvIHRoYXQgd2UgY2FuIGZhaWwgb24gY29tbWFuZFxuICAgIG9wdGlvbnM6IFsnLS1uby1sb29rdXBzJ10sXG4gICAgbW9kRW52OiB7XG4gICAgICBJTlRFR19TVEFDS19TRVQ6ICdzdGFnZS11c2luZy1jb250ZXh0JyxcbiAgICB9LFxuICAgIGFsbG93RXJyRXhpdDogdHJ1ZSxcbiAgfSkpLnJlc29sdmVzLnRvQ29udGFpbignQ29udGV4dCBsb29rdXBzIGhhdmUgYmVlbiBkaXNhYmxlZCcpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2RlcGxveScsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBzdGFja0FybiA9IGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCd0ZXN0LTInLCB7IGNhcHR1cmVTdGRlcnI6IGZhbHNlIH0pO1xuXG4gIC8vIHZlcmlmeSB0aGUgbnVtYmVyIG9mIHJlc291cmNlcyBpbiB0aGUgc3RhY2tcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbignZGVzY3JpYmVTdGFja1Jlc291cmNlcycsIHtcbiAgICBTdGFja05hbWU6IHN0YWNrQXJuLFxuICB9KTtcbiAgZXhwZWN0KHJlc3BvbnNlLlN0YWNrUmVzb3VyY2VzPy5sZW5ndGgpLnRvRXF1YWwoMik7XG59KSk7XG5cbmludGVnVGVzdCgnZGVwbG95IC0tbWV0aG9kPWRpcmVjdCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBzdGFja0FybiA9IGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCd0ZXN0LTInLCB7XG4gICAgb3B0aW9uczogWyctLW1ldGhvZD1kaXJlY3QnXSxcbiAgICBjYXB0dXJlU3RkZXJyOiBmYWxzZSxcbiAgfSk7XG5cbiAgLy8gdmVyaWZ5IHRoZSBudW1iZXIgb2YgcmVzb3VyY2VzIGluIHRoZSBzdGFja1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrUmVzb3VyY2VzJywge1xuICAgIFN0YWNrTmFtZTogc3RhY2tBcm4sXG4gIH0pO1xuICBleHBlY3QocmVzcG9uc2UuU3RhY2tSZXNvdXJjZXM/Lmxlbmd0aCkudG9CZUdyZWF0ZXJUaGFuKDApO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2RlcGxveSBhbGwnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYXJucyA9IGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCd0ZXN0LSonLCB7IGNhcHR1cmVTdGRlcnI6IGZhbHNlIH0pO1xuXG4gIC8vIHZlcmlmeSB0aGF0IHdlIG9ubHkgZGVwbG95ZWQgYm90aCBzdGFja3MgKHRoZXJlIGFyZSAyIEFSTnMgaW4gdGhlIG91dHB1dClcbiAgZXhwZWN0KGFybnMuc3BsaXQoJ1xcbicpLmxlbmd0aCkudG9FcXVhbCgyKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdkZXBsb3kgYWxsIGNvbmN1cnJlbnRseScsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBhcm5zID0gYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ3Rlc3QtKicsIHtcbiAgICBjYXB0dXJlU3RkZXJyOiBmYWxzZSxcbiAgICBvcHRpb25zOiBbJy0tY29uY3VycmVuY3knLCAnMiddLFxuICB9KTtcblxuICAvLyB2ZXJpZnkgdGhhdCB3ZSBvbmx5IGRlcGxveWVkIGJvdGggc3RhY2tzICh0aGVyZSBhcmUgMiBBUk5zIGluIHRoZSBvdXRwdXQpXG4gIGV4cGVjdChhcm5zLnNwbGl0KCdcXG4nKS5sZW5ndGgpLnRvRXF1YWwoMik7XG59KSk7XG5cbmludGVnVGVzdCgnbmVzdGVkIHN0YWNrIHdpdGggcGFyYW1ldGVycycsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICAvLyBTVEFDS19OQU1FX1BSRUZJWCBpcyB1c2VkIGluIE15VG9waWNQYXJhbSB0byBhbGxvdyBtdWx0aXBsZSBpbnN0YW5jZXNcbiAgLy8gb2YgdGhpcyB0ZXN0IHRvIHJ1biBpbiBwYXJhbGxlbCwgb3RoZXdpc2UgdGhleSB3aWxsIGF0dGVtcHQgdG8gY3JlYXRlIHRoZSBzYW1lIFNOUyB0b3BpYy5cbiAgY29uc3Qgc3RhY2tBcm4gPSBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnd2l0aC1uZXN0ZWQtc3RhY2stdXNpbmctcGFyYW1ldGVycycsIHtcbiAgICBvcHRpb25zOiBbJy0tcGFyYW1ldGVycycsIGBNeVRvcGljUGFyYW09JHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH1UaGVyZUlzTm9TcG9vbmBdLFxuICAgIGNhcHR1cmVTdGRlcnI6IGZhbHNlLFxuICB9KTtcblxuICAvLyB2ZXJpZnkgdGhhdCB3ZSBvbmx5IGRlcGxveWVkIGEgc2luZ2xlIHN0YWNrICh0aGVyZSdzIGEgc2luZ2xlIEFSTiBpbiB0aGUgb3V0cHV0KVxuICBleHBlY3Qoc3RhY2tBcm4uc3BsaXQoJ1xcbicpLmxlbmd0aCkudG9FcXVhbCgxKTtcblxuICAvLyB2ZXJpZnkgdGhlIG51bWJlciBvZiByZXNvdXJjZXMgaW4gdGhlIHN0YWNrXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24oJ2Rlc2NyaWJlU3RhY2tSZXNvdXJjZXMnLCB7XG4gICAgU3RhY2tOYW1lOiBzdGFja0FybixcbiAgfSk7XG4gIGV4cGVjdChyZXNwb25zZS5TdGFja1Jlc291cmNlcz8ubGVuZ3RoKS50b0VxdWFsKDEpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2RlcGxveSB3aXRob3V0IGV4ZWN1dGUgYSBuYW1lZCBjaGFuZ2Ugc2V0Jywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGNoYW5nZVNldE5hbWUgPSAnY3VzdG9tLWNoYW5nZS1zZXQtbmFtZSc7XG4gIGNvbnN0IHN0YWNrQXJuID0gYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ3Rlc3QtMicsIHtcbiAgICBvcHRpb25zOiBbJy0tbm8tZXhlY3V0ZScsICctLWNoYW5nZS1zZXQtbmFtZScsIGNoYW5nZVNldE5hbWVdLFxuICAgIGNhcHR1cmVTdGRlcnI6IGZhbHNlLFxuICB9KTtcbiAgLy8gdmVyaWZ5IHRoYXQgd2Ugb25seSBkZXBsb3llZCBhIHNpbmdsZSBzdGFjayAodGhlcmUncyBhIHNpbmdsZSBBUk4gaW4gdGhlIG91dHB1dClcbiAgZXhwZWN0KHN0YWNrQXJuLnNwbGl0KCdcXG4nKS5sZW5ndGgpLnRvRXF1YWwoMSk7XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbignZGVzY3JpYmVTdGFja3MnLCB7XG4gICAgU3RhY2tOYW1lOiBzdGFja0FybixcbiAgfSk7XG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5TdGFja1N0YXR1cykudG9FcXVhbCgnUkVWSUVXX0lOX1BST0dSRVNTJyk7XG5cbiAgLy92ZXJpZnkgYSBjaGFuZ2Ugc2V0IHdhcyBjcmVhdGVkIHdpdGggdGhlIHByb3ZpZGVkIG5hbWVcbiAgY29uc3QgY2hhbmdlU2V0UmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbignbGlzdENoYW5nZVNldHMnLCB7XG4gICAgU3RhY2tOYW1lOiBzdGFja0FybixcbiAgfSk7XG4gIGNvbnN0IGNoYW5nZVNldHMgPSBjaGFuZ2VTZXRSZXNwb25zZS5TdW1tYXJpZXMgfHwgW107XG4gIGV4cGVjdChjaGFuZ2VTZXRzLmxlbmd0aCkudG9FcXVhbCgxKTtcbiAgZXhwZWN0KGNoYW5nZVNldHNbMF0uQ2hhbmdlU2V0TmFtZSkudG9FcXVhbChjaGFuZ2VTZXROYW1lKTtcbiAgZXhwZWN0KGNoYW5nZVNldHNbMF0uU3RhdHVzKS50b0VxdWFsKCdDUkVBVEVfQ09NUExFVEUnKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdzZWN1cml0eSByZWxhdGVkIGNoYW5nZXMgd2l0aG91dCBhIENMSSBhcmUgZXhwZWN0ZWQgdG8gZmFpbCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICAvLyByZWRpcmVjdCAvZGV2L251bGwgdG8gc3RkaW4sIHdoaWNoIG1lYW5zIHRoZXJlIHdpbGwgbm90IGJlIHR0eSBhdHRhY2hlZFxuICAvLyBzaW5jZSB0aGlzIHN0YWNrIGluY2x1ZGVzIHNlY3VyaXR5LXJlbGF0ZWQgY2hhbmdlcywgdGhlIGRlcGxveW1lbnQgc2hvdWxkXG4gIC8vIGltbWVkaWF0ZWx5IGZhaWwgYmVjYXVzZSB3ZSBjYW4ndCBjb25maXJtIHRoZSBjaGFuZ2VzXG4gIGNvbnN0IHN0YWNrTmFtZSA9ICdpYW0tdGVzdCc7XG4gIGF3YWl0IGV4cGVjdChmaXh0dXJlLmNka0RlcGxveShzdGFja05hbWUsIHtcbiAgICBvcHRpb25zOiBbJzwnLCAnL2Rldi9udWxsJ10sIC8vIEg0eCwgdGhpcyBvbmx5IHdvcmtzIGJlY2F1c2UgSSBoYXBwZW4gdG8ga25vdyB3ZSBwYXNzIHNoZWxsOiB0cnVlLlxuICAgIG5ldmVyUmVxdWlyZUFwcHJvdmFsOiBmYWxzZSxcbiAgfSkpLnJlamVjdHMudG9UaHJvdygnZXhpdGVkIHdpdGggZXJyb3InKTtcblxuICAvLyBFbnN1cmUgc3RhY2sgd2FzIG5vdCBkZXBsb3llZFxuICBhd2FpdCBleHBlY3QoZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24oJ2Rlc2NyaWJlU3RhY2tzJywge1xuICAgIFN0YWNrTmFtZTogZml4dHVyZS5mdWxsU3RhY2tOYW1lKHN0YWNrTmFtZSksXG4gIH0pKS5yZWplY3RzLnRvVGhyb3coJ2RvZXMgbm90IGV4aXN0Jyk7XG59KSk7XG5cbmludGVnVGVzdCgnZGVwbG95IHdpbGRjYXJkIHdpdGggb3V0cHV0cycsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBvdXRwdXRzRmlsZSA9IHBhdGguam9pbihmaXh0dXJlLmludGVnVGVzdERpciwgJ291dHB1dHMnLCAnb3V0cHV0cy5qc29uJyk7XG4gIGF3YWl0IGZzLm1rZGlyKHBhdGguZGlybmFtZShvdXRwdXRzRmlsZSksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KFsnb3V0cHV0cy10ZXN0LSonXSwge1xuICAgIG9wdGlvbnM6IFsnLS1vdXRwdXRzLWZpbGUnLCBvdXRwdXRzRmlsZV0sXG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dHMgPSBKU09OLnBhcnNlKChhd2FpdCBmcy5yZWFkRmlsZShvdXRwdXRzRmlsZSwgeyBlbmNvZGluZzogJ3V0Zi04JyB9KSkudG9TdHJpbmcoKSk7XG4gIGV4cGVjdChvdXRwdXRzKS50b0VxdWFsKHtcbiAgICBbYCR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9LW91dHB1dHMtdGVzdC0xYF06IHtcbiAgICAgIFRvcGljTmFtZTogYCR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9LW91dHB1dHMtdGVzdC0xTXlUb3BpY2AsXG4gICAgfSxcbiAgICBbYCR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9LW91dHB1dHMtdGVzdC0yYF06IHtcbiAgICAgIFRvcGljTmFtZTogYCR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9LW91dHB1dHMtdGVzdC0yTXlPdGhlclRvcGljYCxcbiAgICB9LFxuICB9KTtcbn0pKTtcblxuaW50ZWdUZXN0KCdkZXBsb3kgd2l0aCBwYXJhbWV0ZXJzJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IHN0YWNrQXJuID0gYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ3BhcmFtLXRlc3QtMScsIHtcbiAgICBvcHRpb25zOiBbXG4gICAgICAnLS1wYXJhbWV0ZXJzJywgYFRvcGljTmFtZVBhcmFtPSR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9YmF6aW5nYWAsXG4gICAgXSxcbiAgICBjYXB0dXJlU3RkZXJyOiBmYWxzZSxcbiAgfSk7XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbignZGVzY3JpYmVTdGFja3MnLCB7XG4gICAgU3RhY2tOYW1lOiBzdGFja0FybixcbiAgfSk7XG5cbiAgZXhwZWN0KHJlc3BvbnNlLlN0YWNrcz8uWzBdLlBhcmFtZXRlcnMpLnRvQ29udGFpbkVxdWFsKFxuICAgIHtcbiAgICAgIFBhcmFtZXRlcktleTogJ1RvcGljTmFtZVBhcmFtJyxcbiAgICAgIFBhcmFtZXRlclZhbHVlOiBgJHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH1iYXppbmdhYCxcbiAgICB9LFxuICApO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ3VwZGF0ZSB0byBzdGFjayBpbiBST0xMQkFDS19DT01QTEVURSBzdGF0ZSB3aWxsIGRlbGV0ZSBzdGFjayBhbmQgY3JlYXRlIGEgbmV3IG9uZScsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICAvLyBHSVZFTlxuICBhd2FpdCBleHBlY3QoZml4dHVyZS5jZGtEZXBsb3koJ3BhcmFtLXRlc3QtMScsIHtcbiAgICBvcHRpb25zOiBbXG4gICAgICAnLS1wYXJhbWV0ZXJzJywgYFRvcGljTmFtZVBhcmFtPSR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9QGF3d2AsXG4gICAgXSxcbiAgICBjYXB0dXJlU3RkZXJyOiBmYWxzZSxcbiAgfSkpLnJlamVjdHMudG9UaHJvdygnZXhpdGVkIHdpdGggZXJyb3InKTtcblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHtcbiAgICBTdGFja05hbWU6IGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgncGFyYW0tdGVzdC0xJyksXG4gIH0pO1xuXG4gIGNvbnN0IHN0YWNrQXJuID0gcmVzcG9uc2UuU3RhY2tzPy5bMF0uU3RhY2tJZDtcbiAgZXhwZWN0KHJlc3BvbnNlLlN0YWNrcz8uWzBdLlN0YWNrU3RhdHVzKS50b0VxdWFsKCdST0xMQkFDS19DT01QTEVURScpO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgbmV3U3RhY2tBcm4gPSBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgncGFyYW0tdGVzdC0xJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgICctLXBhcmFtZXRlcnMnLCBgVG9waWNOYW1lUGFyYW09JHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH1hbGxnb29kYCxcbiAgICBdLFxuICAgIGNhcHR1cmVTdGRlcnI6IGZhbHNlLFxuICB9KTtcblxuICBjb25zdCBuZXdTdGFja1Jlc3BvbnNlID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24oJ2Rlc2NyaWJlU3RhY2tzJywge1xuICAgIFN0YWNrTmFtZTogbmV3U3RhY2tBcm4sXG4gIH0pO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KHN0YWNrQXJuKS5ub3QudG9FcXVhbChuZXdTdGFja0Fybik7IC8vIG5ldyBzdGFjayB3YXMgY3JlYXRlZFxuICBleHBlY3QobmV3U3RhY2tSZXNwb25zZS5TdGFja3M/LlswXS5TdGFja1N0YXR1cykudG9FcXVhbCgnQ1JFQVRFX0NPTVBMRVRFJyk7XG4gIGV4cGVjdChuZXdTdGFja1Jlc3BvbnNlLlN0YWNrcz8uWzBdLlBhcmFtZXRlcnMpLnRvQ29udGFpbkVxdWFsKFxuICAgIHtcbiAgICAgIFBhcmFtZXRlcktleTogJ1RvcGljTmFtZVBhcmFtJyxcbiAgICAgIFBhcmFtZXRlclZhbHVlOiBgJHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH1hbGxnb29kYCxcbiAgICB9LFxuICApO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ3N0YWNrIGluIFVQREFURV9ST0xMQkFDS19DT01QTEVURSBzdGF0ZSBjYW4gYmUgdXBkYXRlZCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBzdGFja0FybiA9IGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdwYXJhbS10ZXN0LTEnLCB7XG4gICAgb3B0aW9uczogW1xuICAgICAgJy0tcGFyYW1ldGVycycsIGBUb3BpY05hbWVQYXJhbT0ke2ZpeHR1cmUuc3RhY2tOYW1lUHJlZml4fW5pY2VgLFxuICAgIF0sXG4gICAgY2FwdHVyZVN0ZGVycjogZmFsc2UsXG4gIH0pO1xuXG4gIGxldCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHtcbiAgICBTdGFja05hbWU6IHN0YWNrQXJuLFxuICB9KTtcblxuICBleHBlY3QocmVzcG9uc2UuU3RhY2tzPy5bMF0uU3RhY2tTdGF0dXMpLnRvRXF1YWwoJ0NSRUFURV9DT01QTEVURScpO1xuXG4gIC8vIGJhZCBwYXJhbWV0ZXIgbmFtZSB3aXRoIEAgd2lsbCBwdXQgc3RhY2sgaW50byBVUERBVEVfUk9MTEJBQ0tfQ09NUExFVEVcbiAgYXdhaXQgZXhwZWN0KGZpeHR1cmUuY2RrRGVwbG95KCdwYXJhbS10ZXN0LTEnLCB7XG4gICAgb3B0aW9uczogW1xuICAgICAgJy0tcGFyYW1ldGVycycsIGBUb3BpY05hbWVQYXJhbT0ke2ZpeHR1cmUuc3RhY2tOYW1lUHJlZml4fUBhd3dgLFxuICAgIF0sXG4gICAgY2FwdHVyZVN0ZGVycjogZmFsc2UsXG4gIH0pKS5yZWplY3RzLnRvVGhyb3coJ2V4aXRlZCB3aXRoIGVycm9yJyk7O1xuXG4gIHJlc3BvbnNlID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24oJ2Rlc2NyaWJlU3RhY2tzJywge1xuICAgIFN0YWNrTmFtZTogc3RhY2tBcm4sXG4gIH0pO1xuXG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5TdGFja1N0YXR1cykudG9FcXVhbCgnVVBEQVRFX1JPTExCQUNLX0NPTVBMRVRFJyk7XG5cbiAgLy8gV0hFTlxuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgncGFyYW0tdGVzdC0xJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgICctLXBhcmFtZXRlcnMnLCBgVG9waWNOYW1lUGFyYW09JHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH1hbGxnb29kYCxcbiAgICBdLFxuICAgIGNhcHR1cmVTdGRlcnI6IGZhbHNlLFxuICB9KTtcblxuICByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHtcbiAgICBTdGFja05hbWU6IHN0YWNrQXJuLFxuICB9KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5TdGFja1N0YXR1cykudG9FcXVhbCgnVVBEQVRFX0NPTVBMRVRFJyk7XG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5QYXJhbWV0ZXJzKS50b0NvbnRhaW5FcXVhbChcbiAgICB7XG4gICAgICBQYXJhbWV0ZXJLZXk6ICdUb3BpY05hbWVQYXJhbScsXG4gICAgICBQYXJhbWV0ZXJWYWx1ZTogYCR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9YWxsZ29vZGAsXG4gICAgfSxcbiAgKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdkZXBsb3kgd2l0aCB3aWxkY2FyZCBhbmQgcGFyYW1ldGVycycsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgncGFyYW0tdGVzdC0qJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgICctLXBhcmFtZXRlcnMnLCBgJHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH0tcGFyYW0tdGVzdC0xOlRvcGljTmFtZVBhcmFtPSR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9YmF6aW5nYWAsXG4gICAgICAnLS1wYXJhbWV0ZXJzJywgYCR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9LXBhcmFtLXRlc3QtMjpPdGhlclRvcGljTmFtZVBhcmFtPSR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9VGhhdHNNeVNwb3RgLFxuICAgICAgJy0tcGFyYW1ldGVycycsIGAke2ZpeHR1cmUuc3RhY2tOYW1lUHJlZml4fS1wYXJhbS10ZXN0LTM6RGlzcGxheU5hbWVQYXJhbT0ke2ZpeHR1cmUuc3RhY2tOYW1lUHJlZml4fUhleVRoZXJlYCxcbiAgICAgICctLXBhcmFtZXRlcnMnLCBgJHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH0tcGFyYW0tdGVzdC0zOk90aGVyRGlzcGxheU5hbWVQYXJhbT0ke2ZpeHR1cmUuc3RhY2tOYW1lUHJlZml4fUFub3RoZXJPbmVgLFxuICAgIF0sXG4gIH0pO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2RlcGxveSB3aXRoIHBhcmFtZXRlcnMgbXVsdGknLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgcGFyYW1WYWwxID0gYCR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9YmF6aW5nYWA7XG4gIGNvbnN0IHBhcmFtVmFsMiA9IGAke2ZpeHR1cmUuc3RhY2tOYW1lUHJlZml4fT1qYWdzaGVtYXNoYDtcblxuICBjb25zdCBzdGFja0FybiA9IGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdwYXJhbS10ZXN0LTMnLCB7XG4gICAgb3B0aW9uczogW1xuICAgICAgJy0tcGFyYW1ldGVycycsIGBEaXNwbGF5TmFtZVBhcmFtPSR7cGFyYW1WYWwxfWAsXG4gICAgICAnLS1wYXJhbWV0ZXJzJywgYE90aGVyRGlzcGxheU5hbWVQYXJhbT0ke3BhcmFtVmFsMn1gLFxuICAgIF0sXG4gICAgY2FwdHVyZVN0ZGVycjogZmFsc2UsXG4gIH0pO1xuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24oJ2Rlc2NyaWJlU3RhY2tzJywge1xuICAgIFN0YWNrTmFtZTogc3RhY2tBcm4sXG4gIH0pO1xuXG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5QYXJhbWV0ZXJzKS50b0NvbnRhaW5FcXVhbChcbiAgICB7XG4gICAgICBQYXJhbWV0ZXJLZXk6ICdEaXNwbGF5TmFtZVBhcmFtJyxcbiAgICAgIFBhcmFtZXRlclZhbHVlOiBwYXJhbVZhbDEsXG4gICAgfSxcbiAgKTtcbiAgZXhwZWN0KHJlc3BvbnNlLlN0YWNrcz8uWzBdLlBhcmFtZXRlcnMpLnRvQ29udGFpbkVxdWFsKFxuICAgIHtcbiAgICAgIFBhcmFtZXRlcktleTogJ090aGVyRGlzcGxheU5hbWVQYXJhbScsXG4gICAgICBQYXJhbWV0ZXJWYWx1ZTogcGFyYW1WYWwyLFxuICAgIH0sXG4gICk7XG59KSk7XG5cbmludGVnVGVzdCgnZGVwbG95IHdpdGggbm90aWZpY2F0aW9uIEFSTicsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCB0b3BpY05hbWUgPSBgJHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH0tdGVzdC10b3BpY2A7XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5zbnMoJ2NyZWF0ZVRvcGljJywgeyBOYW1lOiB0b3BpY05hbWUgfSk7XG4gIGNvbnN0IHRvcGljQXJuID0gcmVzcG9uc2UuVG9waWNBcm4hO1xuICB0cnkge1xuICAgIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCd0ZXN0LTInLCB7XG4gICAgICBvcHRpb25zOiBbJy0tbm90aWZpY2F0aW9uLWFybnMnLCB0b3BpY0Fybl0sXG4gICAgfSk7XG5cbiAgICAvLyB2ZXJpZnkgdGhhdCB0aGUgc3RhY2sgd2UgZGVwbG95ZWQgaGFzIG91ciBub3RpZmljYXRpb24gQVJOXG4gICAgY29uc3QgZGVzY3JpYmVSZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHtcbiAgICAgIFN0YWNrTmFtZTogZml4dHVyZS5mdWxsU3RhY2tOYW1lKCd0ZXN0LTInKSxcbiAgICB9KTtcbiAgICBleHBlY3QoZGVzY3JpYmVSZXNwb25zZS5TdGFja3M/LlswXS5Ob3RpZmljYXRpb25BUk5zKS50b0VxdWFsKFt0b3BpY0Fybl0pO1xuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IGZpeHR1cmUuYXdzLnNucygnZGVsZXRlVG9waWMnLCB7XG4gICAgICBUb3BpY0FybjogdG9waWNBcm4sXG4gICAgfSk7XG4gIH1cbn0pKTtcblxuLy8gTk9URTogdGhpcyBkb2Vzbid0IGN1cnJlbnRseSB3b3JrIHdpdGggbW9kZXJuLXN0eWxlIHN5bnRoZXNpcywgYXMgdGhlIGJvb3RzdHJhcFxuLy8gcm9sZSBieSBkZWZhdWx0IHdpbGwgbm90IGhhdmUgcGVybWlzc2lvbiB0byBpYW06UGFzc1JvbGUgdGhlIGNyZWF0ZWQgcm9sZS5cbmludGVnVGVzdCgnZGVwbG95IHdpdGggcm9sZScsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBpZiAoZml4dHVyZS5wYWNrYWdlcy5tYWpvclZlcnNpb24oKSAhPT0gJzEnKSB7XG4gICAgcmV0dXJuOyAvLyBOb3RoaW5nIHRvIGRvXG4gIH1cblxuICBjb25zdCByb2xlTmFtZSA9IGAke2ZpeHR1cmUuc3RhY2tOYW1lUHJlZml4fS10ZXN0LXJvbGVgO1xuXG4gIGF3YWl0IGRlbGV0ZVJvbGUoKTtcblxuICBjb25zdCBjcmVhdGVSZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmlhbSgnY3JlYXRlUm9sZScsIHtcbiAgICBSb2xlTmFtZTogcm9sZU5hbWUsXG4gICAgQXNzdW1lUm9sZVBvbGljeURvY3VtZW50OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBWZXJzaW9uOiAnMjAxMi0xMC0xNycsXG4gICAgICBTdGF0ZW1lbnQ6IFt7XG4gICAgICAgIEFjdGlvbjogJ3N0czpBc3N1bWVSb2xlJyxcbiAgICAgICAgUHJpbmNpcGFsOiB7IFNlcnZpY2U6ICdjbG91ZGZvcm1hdGlvbi5hbWF6b25hd3MuY29tJyB9LFxuICAgICAgICBFZmZlY3Q6ICdBbGxvdycsXG4gICAgICB9LCB7XG4gICAgICAgIEFjdGlvbjogJ3N0czpBc3N1bWVSb2xlJyxcbiAgICAgICAgUHJpbmNpcGFsOiB7IEFXUzogKGF3YWl0IGZpeHR1cmUuYXdzLnN0cygnZ2V0Q2FsbGVySWRlbnRpdHknLCB7fSkpLkFybiB9LFxuICAgICAgICBFZmZlY3Q6ICdBbGxvdycsXG4gICAgICB9XSxcbiAgICB9KSxcbiAgfSk7XG4gIGNvbnN0IHJvbGVBcm4gPSBjcmVhdGVSZXNwb25zZS5Sb2xlLkFybjtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmaXh0dXJlLmF3cy5pYW0oJ3B1dFJvbGVQb2xpY3knLCB7XG4gICAgICBSb2xlTmFtZTogcm9sZU5hbWUsXG4gICAgICBQb2xpY3lOYW1lOiAnRGVmYXVsdFBvbGljeScsXG4gICAgICBQb2xpY3lEb2N1bWVudDogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBWZXJzaW9uOiAnMjAxMi0xMC0xNycsXG4gICAgICAgIFN0YXRlbWVudDogW3tcbiAgICAgICAgICBBY3Rpb246ICcqJyxcbiAgICAgICAgICBSZXNvdXJjZTogJyonLFxuICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgfV0sXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIGF3YWl0IHJldHJ5KGZpeHR1cmUub3V0cHV0LCAnVHJ5aW5nIHRvIGFzc3VtZSBmcmVzaCByb2xlJywgcmV0cnkuZm9yU2Vjb25kcygzMDApLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBmaXh0dXJlLmF3cy5zdHMoJ2Fzc3VtZVJvbGUnLCB7XG4gICAgICAgIFJvbGVBcm46IHJvbGVBcm4sXG4gICAgICAgIFJvbGVTZXNzaW9uTmFtZTogJ3Rlc3RpbmcnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBJbiBwcmluY2lwbGUsIHRoZSByb2xlIGhhcyByZXBsaWNhdGVkIGZyb20gJ3VzLWVhc3QtMScgdG8gd2hlcmV2ZXIgd2UncmUgdGVzdGluZy5cbiAgICAvLyBHaXZlIGl0IGEgbGl0dGxlIG1vcmUgc2xlZXAgdG8gbWFrZSBzdXJlIENsb3VkRm9ybWF0aW9uIGlzIG5vdCBoaXR0aW5nIGEgYm94XG4gICAgLy8gdGhhdCBkb2Vzbid0IGhhdmUgaXQgeWV0LlxuICAgIGF3YWl0IHNsZWVwKDUwMDApO1xuXG4gICAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ3Rlc3QtMicsIHtcbiAgICAgIG9wdGlvbnM6IFsnLS1yb2xlLWFybicsIHJvbGVBcm5dLFxuICAgIH0pO1xuXG4gICAgLy8gSW1tZWRpYXRlbHkgZGVsZXRlIHRoZSBzdGFjayBhZ2FpbiBiZWZvcmUgd2UgZGVsZXRlIHRoZSByb2xlLlxuICAgIC8vXG4gICAgLy8gU2luY2Ugcm9sZXMgYXJlIHN0aWNreSwgaWYgd2UgZGVsZXRlIHRoZSByb2xlIGJlZm9yZSB0aGUgc3RhY2ssIHN1YnNlcXVlbnQgRGVsZXRlU3RhY2tcbiAgICAvLyBvcGVyYXRpb25zIHdpbGwgZmFpbCB3aGVuIENsb3VkRm9ybWF0aW9uIHRyaWVzIHRvIGFzc3VtZSB0aGUgcm9sZSB0aGF0J3MgYWxyZWFkeSBnb25lLlxuICAgIGF3YWl0IGZpeHR1cmUuY2RrRGVzdHJveSgndGVzdC0yJyk7XG5cbiAgfSBmaW5hbGx5IHtcbiAgICBhd2FpdCBkZWxldGVSb2xlKCk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBkZWxldGVSb2xlKCkge1xuICAgIHRyeSB7XG4gICAgICBmb3IgKGNvbnN0IHBvbGljeU5hbWUgb2YgKGF3YWl0IGZpeHR1cmUuYXdzLmlhbSgnbGlzdFJvbGVQb2xpY2llcycsIHsgUm9sZU5hbWU6IHJvbGVOYW1lIH0pKS5Qb2xpY3lOYW1lcykge1xuICAgICAgICBhd2FpdCBmaXh0dXJlLmF3cy5pYW0oJ2RlbGV0ZVJvbGVQb2xpY3knLCB7XG4gICAgICAgICAgUm9sZU5hbWU6IHJvbGVOYW1lLFxuICAgICAgICAgIFBvbGljeU5hbWU6IHBvbGljeU5hbWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYXdhaXQgZml4dHVyZS5hd3MuaWFtKCdkZWxldGVSb2xlJywgeyBSb2xlTmFtZTogcm9sZU5hbWUgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUubWVzc2FnZS5pbmRleE9mKCdjYW5ub3QgYmUgZm91bmQnKSA+IC0xKSB7IHJldHVybjsgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cbn0pKTtcblxuaW50ZWdUZXN0KCdjZGsgZGlmZicsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBkaWZmMSA9IGF3YWl0IGZpeHR1cmUuY2RrKFsnZGlmZicsIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0xJyldKTtcbiAgZXhwZWN0KGRpZmYxKS50b0NvbnRhaW4oJ0FXUzo6U05TOjpUb3BpYycpO1xuXG4gIGNvbnN0IGRpZmYyID0gYXdhaXQgZml4dHVyZS5jZGsoWydkaWZmJywgZml4dHVyZS5mdWxsU3RhY2tOYW1lKCd0ZXN0LTInKV0pO1xuICBleHBlY3QoZGlmZjIpLnRvQ29udGFpbignQVdTOjpTTlM6OlRvcGljJyk7XG5cbiAgLy8gV2UgY2FuIG1ha2UgaXQgZmFpbCBieSBwYXNzaW5nIC0tZmFpbFxuICBhd2FpdCBleHBlY3QoZml4dHVyZS5jZGsoWydkaWZmJywgJy0tZmFpbCcsIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0xJyldKSlcbiAgICAucmVqZWN0cy50b1Rocm93KCdleGl0ZWQgd2l0aCBlcnJvcicpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2VuYWJsZURpZmZOb0ZhaWwnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgYXdhaXQgZGlmZlNob3VsZFN1Y2NlZWRXaXRoKHsgZmFpbDogZmFsc2UsIGVuYWJsZURpZmZOb0ZhaWw6IGZhbHNlIH0pO1xuICBhd2FpdCBkaWZmU2hvdWxkU3VjY2VlZFdpdGgoeyBmYWlsOiBmYWxzZSwgZW5hYmxlRGlmZk5vRmFpbDogdHJ1ZSB9KTtcbiAgYXdhaXQgZGlmZlNob3VsZEZhaWxXaXRoKHsgZmFpbDogdHJ1ZSwgZW5hYmxlRGlmZk5vRmFpbDogZmFsc2UgfSk7XG4gIGF3YWl0IGRpZmZTaG91bGRGYWlsV2l0aCh7IGZhaWw6IHRydWUsIGVuYWJsZURpZmZOb0ZhaWw6IHRydWUgfSk7XG4gIGF3YWl0IGRpZmZTaG91bGRGYWlsV2l0aCh7IGZhaWw6IHVuZGVmaW5lZCwgZW5hYmxlRGlmZk5vRmFpbDogZmFsc2UgfSk7XG4gIGF3YWl0IGRpZmZTaG91bGRTdWNjZWVkV2l0aCh7IGZhaWw6IHVuZGVmaW5lZCwgZW5hYmxlRGlmZk5vRmFpbDogdHJ1ZSB9KTtcblxuICBhc3luYyBmdW5jdGlvbiBkaWZmU2hvdWxkU3VjY2VlZFdpdGgocHJvcHM6IERpZmZQYXJhbWV0ZXJzKSB7XG4gICAgYXdhaXQgZXhwZWN0KGRpZmYocHJvcHMpKS5yZXNvbHZlcy5ub3QudG9UaHJvd0Vycm9yKCk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBkaWZmU2hvdWxkRmFpbFdpdGgocHJvcHM6IERpZmZQYXJhbWV0ZXJzKSB7XG4gICAgYXdhaXQgZXhwZWN0KGRpZmYocHJvcHMpKS5yZWplY3RzLnRvVGhyb3coJ2V4aXRlZCB3aXRoIGVycm9yJyk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBkaWZmKHByb3BzOiBEaWZmUGFyYW1ldGVycyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgYXdhaXQgdXBkYXRlQ29udGV4dChwcm9wcy5lbmFibGVEaWZmTm9GYWlsKTtcbiAgICBjb25zdCBmbGFnID0gcHJvcHMuZmFpbCAhPSBudWxsXG4gICAgICA/IChwcm9wcy5mYWlsID8gJy0tZmFpbCcgOiAnLS1uby1mYWlsJylcbiAgICAgIDogJyc7XG5cbiAgICByZXR1cm4gZml4dHVyZS5jZGsoWydkaWZmJywgZmxhZywgZml4dHVyZS5mdWxsU3RhY2tOYW1lKCd0ZXN0LTEnKV0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gdXBkYXRlQ29udGV4dChlbmFibGVEaWZmTm9GYWlsOiBib29sZWFuKSB7XG4gICAgY29uc3QgY2RrSnNvbiA9IEpTT04ucGFyc2UoYXdhaXQgZnMucmVhZEZpbGUocGF0aC5qb2luKGZpeHR1cmUuaW50ZWdUZXN0RGlyLCAnY2RrLmpzb24nKSwgJ3V0ZjgnKSk7XG4gICAgY2RrSnNvbi5jb250ZXh0ID0ge1xuICAgICAgLi4uY2RrSnNvbi5jb250ZXh0LFxuICAgICAgJ2F3cy1jZGs6ZW5hYmxlRGlmZk5vRmFpbCc6IGVuYWJsZURpZmZOb0ZhaWwsXG4gICAgfTtcbiAgICBhd2FpdCBmcy53cml0ZUZpbGUocGF0aC5qb2luKGZpeHR1cmUuaW50ZWdUZXN0RGlyLCAnY2RrLmpzb24nKSwgSlNPTi5zdHJpbmdpZnkoY2RrSnNvbikpO1xuICB9XG5cbiAgdHlwZSBEaWZmUGFyYW1ldGVycyA9IHsgZmFpbD86IGJvb2xlYW4sIGVuYWJsZURpZmZOb0ZhaWw6IGJvb2xlYW4gfTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjZGsgZGlmZiAtLWZhaWwgb24gbXVsdGlwbGUgc3RhY2tzIGV4aXRzIHdpdGggZXJyb3IgaWYgYW55IG9mIHRoZSBzdGFja3MgY29udGFpbnMgYSBkaWZmJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IGRpZmYxID0gYXdhaXQgZml4dHVyZS5jZGsoWydkaWZmJywgZml4dHVyZS5mdWxsU3RhY2tOYW1lKCd0ZXN0LTEnKV0pO1xuICBleHBlY3QoZGlmZjEpLnRvQ29udGFpbignQVdTOjpTTlM6OlRvcGljJyk7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ3Rlc3QtMicpO1xuICBjb25zdCBkaWZmMiA9IGF3YWl0IGZpeHR1cmUuY2RrKFsnZGlmZicsIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0yJyldKTtcbiAgZXhwZWN0KGRpZmYyKS50b0NvbnRhaW4oJ1RoZXJlIHdlcmUgbm8gZGlmZmVyZW5jZXMnKTtcblxuICAvLyBXSEVOIC8gVEhFTlxuICBhd2FpdCBleHBlY3QoZml4dHVyZS5jZGsoWydkaWZmJywgJy0tZmFpbCcsIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0xJyksIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0yJyldKSkucmVqZWN0cy50b1Rocm93KCdleGl0ZWQgd2l0aCBlcnJvcicpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2NkayBkaWZmIC0tZmFpbCB3aXRoIG11bHRpcGxlIHN0YWNrIGV4aXRzIHdpdGggaWYgYW55IG9mIHRoZSBzdGFja3MgY29udGFpbnMgYSBkaWZmJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCd0ZXN0LTEnKTtcbiAgY29uc3QgZGlmZjEgPSBhd2FpdCBmaXh0dXJlLmNkayhbJ2RpZmYnLCBmaXh0dXJlLmZ1bGxTdGFja05hbWUoJ3Rlc3QtMScpXSk7XG4gIGV4cGVjdChkaWZmMSkudG9Db250YWluKCdUaGVyZSB3ZXJlIG5vIGRpZmZlcmVuY2VzJyk7XG5cbiAgY29uc3QgZGlmZjIgPSBhd2FpdCBmaXh0dXJlLmNkayhbJ2RpZmYnLCBmaXh0dXJlLmZ1bGxTdGFja05hbWUoJ3Rlc3QtMicpXSk7XG4gIGV4cGVjdChkaWZmMikudG9Db250YWluKCdBV1M6OlNOUzo6VG9waWMnKTtcblxuICAvLyBXSEVOIC8gVEhFTlxuICBhd2FpdCBleHBlY3QoZml4dHVyZS5jZGsoWydkaWZmJywgJy0tZmFpbCcsIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0xJyksIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0yJyldKSkucmVqZWN0cy50b1Rocm93KCdleGl0ZWQgd2l0aCBlcnJvcicpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2NkayBkaWZmIC0tc2VjdXJpdHktb25seSAtLWZhaWwgZXhpdHMgd2hlbiBzZWN1cml0eSBjaGFuZ2VzIGFyZSBwcmVzZW50Jywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IHN0YWNrTmFtZSA9ICdpYW0tdGVzdCc7XG4gIGF3YWl0IGV4cGVjdChmaXh0dXJlLmNkayhbJ2RpZmYnLCAnLS1zZWN1cml0eS1vbmx5JywgJy0tZmFpbCcsIGZpeHR1cmUuZnVsbFN0YWNrTmFtZShzdGFja05hbWUpXSkpLnJlamVjdHMudG9UaHJvdygnZXhpdGVkIHdpdGggZXJyb3InKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdkZXBsb3kgc3RhY2sgd2l0aCBkb2NrZXIgYXNzZXQnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2RvY2tlcicpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2RlcGxveSBhbmQgdGVzdCBzdGFjayB3aXRoIGxhbWJkYSBhc3NldCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBzdGFja0FybiA9IGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdsYW1iZGEnLCB7IGNhcHR1cmVTdGRlcnI6IGZhbHNlIH0pO1xuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24oJ2Rlc2NyaWJlU3RhY2tzJywge1xuICAgIFN0YWNrTmFtZTogc3RhY2tBcm4sXG4gIH0pO1xuICBjb25zdCBsYW1iZGFBcm4gPSByZXNwb25zZS5TdGFja3M/LlswXS5PdXRwdXRzPy5bMF0uT3V0cHV0VmFsdWU7XG4gIGlmIChsYW1iZGFBcm4gPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3RhY2sgZGlkIG5vdCBoYXZlIGV4cGVjdGVkIExhbWJkYSBBUk4gb3V0cHV0Jyk7XG4gIH1cblxuICBjb25zdCBvdXRwdXQgPSBhd2FpdCBmaXh0dXJlLmF3cy5sYW1iZGEoJ2ludm9rZScsIHtcbiAgICBGdW5jdGlvbk5hbWU6IGxhbWJkYUFybixcbiAgfSk7XG5cbiAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KG91dHB1dC5QYXlsb2FkKSkudG9Db250YWluKCdkZWFyIGFzc2V0Jyk7XG59KSk7XG5cbmludGVnVGVzdCgnY2RrIGxzJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGxpc3RpbmcgPSBhd2FpdCBmaXh0dXJlLmNkayhbJ2xzJ10sIHsgY2FwdHVyZVN0ZGVycjogZmFsc2UgfSk7XG5cbiAgY29uc3QgZXhwZWN0ZWRTdGFja3MgPSBbXG4gICAgJ2NvbmRpdGlvbmFsLXJlc291cmNlJyxcbiAgICAnZG9ja2VyJyxcbiAgICAnZG9ja2VyLXdpdGgtY3VzdG9tLWZpbGUnLFxuICAgICdmYWlsZWQnLFxuICAgICdpYW0tdGVzdCcsXG4gICAgJ2xhbWJkYScsXG4gICAgJ21pc3Npbmctc3NtLXBhcmFtZXRlcicsXG4gICAgJ29yZGVyLXByb3ZpZGluZycsXG4gICAgJ291dHB1dHMtdGVzdC0xJyxcbiAgICAnb3V0cHV0cy10ZXN0LTInLFxuICAgICdwYXJhbS10ZXN0LTEnLFxuICAgICdwYXJhbS10ZXN0LTInLFxuICAgICdwYXJhbS10ZXN0LTMnLFxuICAgICd0ZXJtaW5hdGlvbi1wcm90ZWN0aW9uJyxcbiAgICAndGVzdC0xJyxcbiAgICAndGVzdC0yJyxcbiAgICAnd2l0aC1uZXN0ZWQtc3RhY2snLFxuICAgICd3aXRoLW5lc3RlZC1zdGFjay11c2luZy1wYXJhbWV0ZXJzJyxcbiAgICAnb3JkZXItY29uc3VtaW5nJyxcbiAgXTtcblxuICBmb3IgKGNvbnN0IHN0YWNrIG9mIGV4cGVjdGVkU3RhY2tzKSB7XG4gICAgZXhwZWN0KGxpc3RpbmcpLnRvQ29udGFpbihmaXh0dXJlLmZ1bGxTdGFja05hbWUoc3RhY2spKTtcbiAgfVxufSkpO1xuXG5pbnRlZ1Rlc3QoJ3N5bnRoaW5nIGEgc3RhZ2Ugd2l0aCBlcnJvcnMgbGVhZHMgdG8gZmFpbHVyZScsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBvdXRwdXQgPSBhd2FpdCBmaXh0dXJlLmNkayhbJ3N5bnRoJ10sIHtcbiAgICBhbGxvd0VyckV4aXQ6IHRydWUsXG4gICAgbW9kRW52OiB7XG4gICAgICBJTlRFR19TVEFDS19TRVQ6ICdzdGFnZS13aXRoLWVycm9ycycsXG4gICAgfSxcbiAgfSk7XG5cbiAgZXhwZWN0KG91dHB1dCkudG9Db250YWluKCdUaGlzIGlzIGFuIGVycm9yJyk7XG59KSk7XG5cbmludGVnVGVzdCgnc3ludGhpbmcgYSBzdGFnZSB3aXRoIGVycm9ycyBjYW4gYmUgc3VwcHJlc3NlZCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBhd2FpdCBmaXh0dXJlLmNkayhbJ3N5bnRoJywgJy0tbm8tdmFsaWRhdGlvbiddLCB7XG4gICAgbW9kRW52OiB7XG4gICAgICBJTlRFR19TVEFDS19TRVQ6ICdzdGFnZS13aXRoLWVycm9ycycsXG4gICAgfSxcbiAgfSk7XG59KSk7XG5cbmludGVnVGVzdCgnZGVwbG95IHN0YWNrIHdpdGhvdXQgcmVzb3VyY2UnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgLy8gRGVwbG95IHRoZSBzdGFjayB3aXRob3V0IHJlc291cmNlc1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnY29uZGl0aW9uYWwtcmVzb3VyY2UnLCB7IG1vZEVudjogeyBOT19SRVNPVVJDRTogJ1RSVUUnIH0gfSk7XG5cbiAgLy8gVGhpcyBzaG91bGQgaGF2ZSBzdWNjZWVkZWQgYnV0IG5vdCBkZXBsb3llZCB0aGUgc3RhY2suXG4gIGF3YWl0IGV4cGVjdChmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbignZGVzY3JpYmVTdGFja3MnLCB7IFN0YWNrTmFtZTogZml4dHVyZS5mdWxsU3RhY2tOYW1lKCdjb25kaXRpb25hbC1yZXNvdXJjZScpIH0pKVxuICAgIC5yZWplY3RzLnRvVGhyb3coJ2NvbmRpdGlvbmFsLXJlc291cmNlIGRvZXMgbm90IGV4aXN0Jyk7XG5cbiAgLy8gRGVwbG95IHRoZSBzdGFjayB3aXRoIHJlc291cmNlc1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnY29uZGl0aW9uYWwtcmVzb3VyY2UnKTtcblxuICAvLyBUaGVuIGFnYWluIFdJVEhPVVQgcmVzb3VyY2VzICh0aGlzIHNob3VsZCBkZXN0cm95IHRoZSBzdGFjaylcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2NvbmRpdGlvbmFsLXJlc291cmNlJywgeyBtb2RFbnY6IHsgTk9fUkVTT1VSQ0U6ICdUUlVFJyB9IH0pO1xuXG4gIGF3YWl0IGV4cGVjdChmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbignZGVzY3JpYmVTdGFja3MnLCB7IFN0YWNrTmFtZTogZml4dHVyZS5mdWxsU3RhY2tOYW1lKCdjb25kaXRpb25hbC1yZXNvdXJjZScpIH0pKVxuICAgIC5yZWplY3RzLnRvVGhyb3coJ2NvbmRpdGlvbmFsLXJlc291cmNlIGRvZXMgbm90IGV4aXN0Jyk7XG59KSk7XG5cbmludGVnVGVzdCgnSUFNIGRpZmYnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3Qgb3V0cHV0ID0gYXdhaXQgZml4dHVyZS5jZGsoWydkaWZmJywgZml4dHVyZS5mdWxsU3RhY2tOYW1lKCdpYW0tdGVzdCcpXSk7XG5cbiAgLy8gUm91Z2hseSBjaGVjayBmb3IgYSB0YWJsZSBsaWtlIHRoaXM6XG4gIC8vXG4gIC8vIOKUjOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgC3ilIDilIDilKzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJBcbiAgLy8g4pSCICAg4pSCIFJlc291cmNlICAgICAgICDilIIgRWZmZWN0IOKUgiBBY3Rpb24gICAgICAgICDilIIgUHJpbmNpcGFsICAgICAgICAgICAgICAgICAgICAg4pSCIENvbmRpdGlvbiDilIJcbiAgLy8g4pSc4pSA4pSA4pSA4pS84pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS84pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS84pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS84pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS84pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSkXG4gIC8vIOKUgiArIOKUgiAke1NvbWVSb2xlLkFybn0g4pSCIEFsbG93ICDilIIgc3RzOkFzc3VtZVJvbGUg4pSCIFNlcnZpY2U6ZWMyLmFtYXpvbmF3cy5jb20gICAgIOKUgiAgICAgICAgICAg4pSCXG4gIC8vIOKUlOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmFxuXG4gIGV4cGVjdChvdXRwdXQpLnRvQ29udGFpbignJHtTb21lUm9sZS5Bcm59Jyk7XG4gIGV4cGVjdChvdXRwdXQpLnRvQ29udGFpbignc3RzOkFzc3VtZVJvbGUnKTtcbiAgZXhwZWN0KG91dHB1dCkudG9Db250YWluKCdlYzIuYW1hem9uYXdzLmNvbScpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2Zhc3QgZGVwbG95Jywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIC8vIHdlIGFyZSB1c2luZyBhIHN0YWNrIHdpdGggYSBuZXN0ZWQgc3RhY2sgYmVjYXVzZSBDRk4gd2lsbCBhbHdheXMgYXR0ZW1wdCB0b1xuICAvLyB1cGRhdGUgYSBuZXN0ZWQgc3RhY2ssIHdoaWNoIHdpbGwgYWxsb3cgdXMgdG8gdmVyaWZ5IHRoYXQgdXBkYXRlcyBhcmUgYWN0dWFsbHlcbiAgLy8gc2tpcHBlZCB1bmxlc3MgLS1mb3JjZSBpcyBzcGVjaWZpZWQuXG4gIGNvbnN0IHN0YWNrQXJuID0gYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ3dpdGgtbmVzdGVkLXN0YWNrJywgeyBjYXB0dXJlU3RkZXJyOiBmYWxzZSB9KTtcbiAgY29uc3QgY2hhbmdlU2V0MSA9IGF3YWl0IGdldExhdGVzdENoYW5nZVNldCgpO1xuXG4gIC8vIERlcGxveSB0aGUgc2FtZSBzdGFjayBhZ2FpbiwgdGhlcmUgc2hvdWxkIGJlIG5vIG5ldyBjaGFuZ2Ugc2V0IGNyZWF0ZWRcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ3dpdGgtbmVzdGVkLXN0YWNrJyk7XG4gIGNvbnN0IGNoYW5nZVNldDIgPSBhd2FpdCBnZXRMYXRlc3RDaGFuZ2VTZXQoKTtcbiAgZXhwZWN0KGNoYW5nZVNldDIuQ2hhbmdlU2V0SWQpLnRvRXF1YWwoY2hhbmdlU2V0MS5DaGFuZ2VTZXRJZCk7XG5cbiAgLy8gRGVwbG95IHRoZSBzdGFjayBhZ2FpbiB3aXRoIC0tZm9yY2UsIG5vdyB3ZSBzaG91bGQgY3JlYXRlIGEgY2hhbmdlc2V0XG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCd3aXRoLW5lc3RlZC1zdGFjaycsIHsgb3B0aW9uczogWyctLWZvcmNlJ10gfSk7XG4gIGNvbnN0IGNoYW5nZVNldDMgPSBhd2FpdCBnZXRMYXRlc3RDaGFuZ2VTZXQoKTtcbiAgZXhwZWN0KGNoYW5nZVNldDMuQ2hhbmdlU2V0SWQpLm5vdC50b0VxdWFsKGNoYW5nZVNldDIuQ2hhbmdlU2V0SWQpO1xuXG4gIC8vIERlcGxveSB0aGUgc3RhY2sgYWdhaW4gd2l0aCB0YWdzLCBleHBlY3RlZCB0byBjcmVhdGUgYSBuZXcgY2hhbmdlc2V0XG4gIC8vIGV2ZW4gdGhvdWdoIHRoZSByZXNvdXJjZXMgZGlkbid0IGNoYW5nZS5cbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ3dpdGgtbmVzdGVkLXN0YWNrJywgeyBvcHRpb25zOiBbJy0tdGFncycsICdrZXk9dmFsdWUnXSB9KTtcbiAgY29uc3QgY2hhbmdlU2V0NCA9IGF3YWl0IGdldExhdGVzdENoYW5nZVNldCgpO1xuICBleHBlY3QoY2hhbmdlU2V0NC5DaGFuZ2VTZXRJZCkubm90LnRvRXF1YWwoY2hhbmdlU2V0My5DaGFuZ2VTZXRJZCk7XG5cbiAgYXN5bmMgZnVuY3Rpb24gZ2V0TGF0ZXN0Q2hhbmdlU2V0KCkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24oJ2Rlc2NyaWJlU3RhY2tzJywgeyBTdGFja05hbWU6IHN0YWNrQXJuIH0pO1xuICAgIGlmICghcmVzcG9uc2UuU3RhY2tzPy5bMF0pIHsgdGhyb3cgbmV3IEVycm9yKCdEaWQgbm90IGdldCBhIENoYW5nZVNldCBhdCBhbGwnKTsgfVxuICAgIGZpeHR1cmUubG9nKGBGb3VuZCBDaGFuZ2UgU2V0ICR7cmVzcG9uc2UuU3RhY2tzPy5bMF0uQ2hhbmdlU2V0SWR9YCk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLlN0YWNrcz8uWzBdO1xuICB9XG59KSk7XG5cbmludGVnVGVzdCgnZmFpbGVkIGRlcGxveSBkb2VzIG5vdCBoYW5nJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIC8vIHRoaXMgd2lsbCBoYW5nIGlmIHdlIGludHJvZHVjZSBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvaXNzdWVzLzY0MDMgYWdhaW4uXG4gIGF3YWl0IGV4cGVjdChmaXh0dXJlLmNka0RlcGxveSgnZmFpbGVkJykpLnJlamVjdHMudG9UaHJvdygnZXhpdGVkIHdpdGggZXJyb3InKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gc3RpbGwgbG9hZCBvbGQgYXNzZW1ibGllcycsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBjeEFzbURpciA9IHBhdGguam9pbihvcy50bXBkaXIoKSwgJ2Nkay1pbnRlZy1jeCcpO1xuXG4gIGNvbnN0IHRlc3RBc3NlbWJsaWVzRGlyZWN0b3J5ID0gcGF0aC5qb2luKFJFU09VUkNFU19ESVIsICdjbG91ZC1hc3NlbWJsaWVzJyk7XG4gIGZvciAoY29uc3QgYXNtZGlyIG9mIGF3YWl0IGxpc3RDaGlsZERpcnModGVzdEFzc2VtYmxpZXNEaXJlY3RvcnkpKSB7XG4gICAgZml4dHVyZS5sb2coYEFTU0VNQkxZICR7YXNtZGlyfWApO1xuICAgIGF3YWl0IGNsb25lRGlyZWN0b3J5KGFzbWRpciwgY3hBc21EaXIpO1xuXG4gICAgLy8gU29tZSBmaWxlcyBpbiB0aGUgYXNtIGRpcmVjdG9yeSB0aGF0IGhhdmUgYSAuanMgZXh0ZW5zaW9uIGFyZVxuICAgIC8vIGFjdHVhbGx5IHRyZWF0ZWQgYXMgdGVtcGxhdGVzLiBFdmFsdWF0ZSB0aGVtIHVzaW5nIE5vZGVKUy5cbiAgICBjb25zdCB0ZW1wbGF0ZXMgPSBhd2FpdCBsaXN0Q2hpbGRyZW4oY3hBc21EaXIsIGZ1bGxQYXRoID0+IFByb21pc2UucmVzb2x2ZShmdWxsUGF0aC5lbmRzV2l0aCgnLmpzJykpKTtcbiAgICBmb3IgKGNvbnN0IHRlbXBsYXRlIG9mIHRlbXBsYXRlcykge1xuICAgICAgY29uc3QgdGFyZ2V0TmFtZSA9IHRlbXBsYXRlLnJlcGxhY2UoLy5qcyQvLCAnJyk7XG4gICAgICBhd2FpdCBzaGVsbChbcHJvY2Vzcy5leGVjUGF0aCwgdGVtcGxhdGUsICc+JywgdGFyZ2V0TmFtZV0sIHtcbiAgICAgICAgY3dkOiBjeEFzbURpcixcbiAgICAgICAgb3V0cHV0OiBmaXh0dXJlLm91dHB1dCxcbiAgICAgICAgbW9kRW52OiB7XG4gICAgICAgICAgVEVTVF9BQ0NPVU5UOiBhd2FpdCBmaXh0dXJlLmF3cy5hY2NvdW50KCksXG4gICAgICAgICAgVEVTVF9SRUdJT046IGZpeHR1cmUuYXdzLnJlZ2lvbixcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIFVzZSB0aGlzIGRpcmVjdG9yeSBhcyBhIENsb3VkIEFzc2VtYmx5XG4gICAgY29uc3Qgb3V0cHV0ID0gYXdhaXQgZml4dHVyZS5jZGsoW1xuICAgICAgJy0tYXBwJywgY3hBc21EaXIsXG4gICAgICAnLXYnLFxuICAgICAgJ3N5bnRoJyxcbiAgICBdKTtcblxuICAgIC8vIEFzc2VydCB0aGF0IHRoZXJlIHdhcyBubyBwcm92aWRlckVycm9yIGluIENESydzIHN0ZGVyclxuICAgIC8vIEJlY2F1c2Ugd2UgcmVseSBvbiB0aGUgYXBwL2ZyYW1ld29yayB0byBhY3R1YWxseSBlcnJvciBpbiBjYXNlIHRoZVxuICAgIC8vIHByb3ZpZGVyIGZhaWxzLCB3ZSBpbnNwZWN0IHRoZSBsb2dzIGhlcmUuXG4gICAgZXhwZWN0KG91dHB1dCkubm90LnRvQ29udGFpbignJHByb3ZpZGVyRXJyb3InKTtcbiAgfVxufSkpO1xuXG5pbnRlZ1Rlc3QoJ2dlbmVyYXRpbmcgYW5kIGxvYWRpbmcgYXNzZW1ibHknLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYXNtT3V0cHV0RGlyID0gYCR7Zml4dHVyZS5pbnRlZ1Rlc3REaXJ9LWNkay1pbnRlZy1hc21gO1xuICBhd2FpdCBmaXh0dXJlLnNoZWxsKFsncm0nLCAnLXJmJywgYXNtT3V0cHV0RGlyXSk7XG5cbiAgLy8gU3ludGhlc2l6ZSBhIENsb3VkIEFzc2VtYmx5IHRvdGhlIGRlZmF1bHQgZGlyZWN0b3J5IChjZGsub3V0KSBhbmQgYSBzcGVjaWZpYyBkaXJlY3RvcnkuXG4gIGF3YWl0IGZpeHR1cmUuY2RrKFsnc3ludGgnXSk7XG4gIGF3YWl0IGZpeHR1cmUuY2RrKFsnc3ludGgnLCAnLS1vdXRwdXQnLCBhc21PdXRwdXREaXJdKTtcblxuICAvLyBjZGsub3V0IGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBhbmQgdGhlIGluZGljYXRlZCAtLW91dHB1dCBzaG91bGQgYmUgdGhlIHNhbWVcbiAgYXdhaXQgZml4dHVyZS5zaGVsbChbJ2RpZmYnLCAnY2RrLm91dCcsIGFzbU91dHB1dERpcl0pO1xuXG4gIC8vIENoZWNrIHRoYXQgd2UgY2FuICdscycgdGhlIHN5bnRoZXNpemVkIGFzbS5cbiAgLy8gQ2hhbmdlIHRvIHNvbWUgcmFuZG9tIGRpcmVjdG9yeSB0byBtYWtlIHN1cmUgd2UncmUgbm90IGFjY2lkZW50YWxseSBsb2FkaW5nIGNkay5qc29uXG4gIGNvbnN0IGxpc3QgPSBhd2FpdCBmaXh0dXJlLmNkayhbJy0tYXBwJywgYXNtT3V0cHV0RGlyLCAnbHMnXSwgeyBjd2Q6IG9zLnRtcGRpcigpIH0pO1xuICAvLyBTYW1lIHN0YWNrcyB3ZSBrbm93IGFyZSBpbiB0aGUgYXBwXG4gIGV4cGVjdChsaXN0KS50b0NvbnRhaW4oYCR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXh9LWxhbWJkYWApO1xuICBleHBlY3QobGlzdCkudG9Db250YWluKGAke2ZpeHR1cmUuc3RhY2tOYW1lUHJlZml4fS10ZXN0LTFgKTtcbiAgZXhwZWN0KGxpc3QpLnRvQ29udGFpbihgJHtmaXh0dXJlLnN0YWNrTmFtZVByZWZpeH0tdGVzdC0yYCk7XG5cbiAgLy8gQ2hlY2sgdGhhdCB3ZSBjYW4gdXNlICcuJyBhbmQganVzdCBzeW50aCAsdGhlIGdlbmVyYXRlZCBhc21cbiAgY29uc3Qgc3RhY2tUZW1wbGF0ZSA9IGF3YWl0IGZpeHR1cmUuY2RrKFsnLS1hcHAnLCAnLicsICdzeW50aCcsIGZpeHR1cmUuZnVsbFN0YWNrTmFtZSgndGVzdC0yJyldLCB7XG4gICAgY3dkOiBhc21PdXRwdXREaXIsXG4gIH0pO1xuICBleHBlY3Qoc3RhY2tUZW1wbGF0ZSkudG9Db250YWluKCd0b3BpYzE1MkQ4NEEzNycpO1xuXG4gIC8vIERlcGxveSBhIExhbWJkYSBmcm9tIHRoZSBjb3BpZWQgYXNtXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdsYW1iZGEnLCB7IG9wdGlvbnM6IFsnLWEnLCAnLiddLCBjd2Q6IGFzbU91dHB1dERpciB9KTtcblxuICAvLyBSZW1vdmUgKHJlbmFtZSkgdGhlIG9yaWdpbmFsIGN1c3RvbSBkb2NrZXIgZmlsZSB0aGF0IHdhcyB1c2VkIGR1cmluZyBzeW50aC5cbiAgLy8gdGhpcyB2ZXJpZmllcyB0aGF0IHRoZSBhc3NlbWx5IGhhcyBhIGNvcHkgb2YgaXQgYW5kIHRoYXQgdGhlIG1hbmlmZXN0IHVzZXNcbiAgLy8gcmVsYXRpdmUgcGF0aHMgdG8gcmVmZXJlbmNlIHRvIGl0LlxuICBjb25zdCBjdXN0b21Eb2NrZXJGaWxlID0gcGF0aC5qb2luKGZpeHR1cmUuaW50ZWdUZXN0RGlyLCAnZG9ja2VyJywgJ0RvY2tlcmZpbGUuQ3VzdG9tJyk7XG4gIGF3YWl0IGZzLnJlbmFtZShjdXN0b21Eb2NrZXJGaWxlLCBgJHtjdXN0b21Eb2NrZXJGaWxlfX5gKTtcbiAgdHJ5IHtcblxuICAgIC8vIGRlcGxveSBhIGRvY2tlciBpbWFnZSB3aXRoIGN1c3RvbSBmaWxlIHdpdGhvdXQgc3ludGggKHVzZXMgYXNzZXRzKVxuICAgIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdkb2NrZXItd2l0aC1jdXN0b20tZmlsZScsIHsgb3B0aW9uczogWyctYScsICcuJ10sIGN3ZDogYXNtT3V0cHV0RGlyIH0pO1xuXG4gIH0gZmluYWxseSB7XG4gICAgLy8gUmVuYW1lIGJhY2sgdG8gcmVzdG9yZSBmaXh0dXJlIHRvIG9yaWdpbmFsIHN0YXRlXG4gICAgYXdhaXQgZnMucmVuYW1lKGAke2N1c3RvbURvY2tlckZpbGV9fmAsIGN1c3RvbURvY2tlckZpbGUpO1xuICB9XG59KSk7XG5cbmludGVnVGVzdCgndGVtcGxhdGVzIG9uIGRpc2sgY29udGFpbiBtZXRhZGF0YSByZXNvdXJjZSwgYWxzbyBpbiBuZXN0ZWQgYXNzZW1ibGllcycsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICAvLyBTeW50aCBmaXJzdCwgYW5kIHN3aXRjaCBvbiB2ZXJzaW9uIHJlcG9ydGluZyBiZWNhdXNlIGNkay5qc29uIGlzIGRpc2FibGluZyBpdFxuICBhd2FpdCBmaXh0dXJlLmNkayhbJ3N5bnRoJywgJy0tdmVyc2lvbi1yZXBvcnRpbmc9dHJ1ZSddKTtcblxuICAvLyBMb2FkIHRlbXBsYXRlIGZyb20gZGlzayBmcm9tIHJvb3QgYXNzZW1ibHlcbiAgY29uc3QgdGVtcGxhdGVDb250ZW50cyA9IGF3YWl0IGZpeHR1cmUuc2hlbGwoWydjYXQnLCAnY2RrLm91dC8qLWxhbWJkYS50ZW1wbGF0ZS5qc29uJ10pO1xuXG4gIGV4cGVjdChKU09OLnBhcnNlKHRlbXBsYXRlQ29udGVudHMpLlJlc291cmNlcy5DREtNZXRhZGF0YSkudG9CZVRydXRoeSgpO1xuXG4gIC8vIExvYWQgdGVtcGxhdGUgZnJvbSBuZXN0ZWQgYXNzZW1ibHlcbiAgY29uc3QgbmVzdGVkVGVtcGxhdGVDb250ZW50cyA9IGF3YWl0IGZpeHR1cmUuc2hlbGwoWydjYXQnLCAnY2RrLm91dC9hc3NlbWJseS0qLXN0YWdlLypTdGFja0luU3RhZ2UqLnRlbXBsYXRlLmpzb24nXSk7XG5cbiAgZXhwZWN0KEpTT04ucGFyc2UobmVzdGVkVGVtcGxhdGVDb250ZW50cykuUmVzb3VyY2VzLkNES01ldGFkYXRhKS50b0JlVHJ1dGh5KCk7XG59KSk7XG5cbmludGVnVGVzdCgnQ0RLIHN5bnRoIGFkZCB0aGUgbWV0YWRhdGEgcHJvcGVydGllcyBleHBlY3RlZCBieSBzYW0nLCB3aXRoU2FtSW50ZWdyYXRpb25GaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIC8vIFN5bnRoIGZpcnN0XG4gIGF3YWl0IGZpeHR1cmUuY2RrU3ludGgoKTtcblxuICBjb25zdCB0ZW1wbGF0ZSA9IGZpeHR1cmUudGVtcGxhdGUoJ1Rlc3RTdGFjaycpO1xuXG4gIGNvbnN0IGV4cGVjdGVkUmVzb3VyY2VzID0gW1xuICAgIHtcbiAgICAgIC8vIFB5dGhvbiBMYXllciBWZXJzaW9uXG4gICAgICBpZDogJ1B5dGhvbkxheWVyVmVyc2lvbjM5NDk1Q0VGJyxcbiAgICAgIGNka0lkOiAnUHl0aG9uTGF5ZXJWZXJzaW9uJyxcbiAgICAgIGlzQnVuZGxlZDogdHJ1ZSxcbiAgICAgIHByb3BlcnR5OiAnQ29udGVudCcsXG4gICAgfSxcbiAgICB7XG4gICAgICAvLyBMYXllciBWZXJzaW9uXG4gICAgICBpZDogJ0xheWVyVmVyc2lvbjM4NzhEQTNBJyxcbiAgICAgIGNka0lkOiAnTGF5ZXJWZXJzaW9uJyxcbiAgICAgIGlzQnVuZGxlZDogZmFsc2UsXG4gICAgICBwcm9wZXJ0eTogJ0NvbnRlbnQnLFxuICAgIH0sXG4gICAge1xuICAgICAgLy8gQnVuZGxlZCBsYXllciB2ZXJzaW9uXG4gICAgICBpZDogJ0J1bmRsZWRMYXllclZlcnNpb25QeXRob25SdW50aW1lNkJBREJENkUnLFxuICAgICAgY2RrSWQ6ICdCdW5kbGVkTGF5ZXJWZXJzaW9uUHl0aG9uUnVudGltZScsXG4gICAgICBpc0J1bmRsZWQ6IHRydWUsXG4gICAgICBwcm9wZXJ0eTogJ0NvbnRlbnQnLFxuICAgIH0sXG4gICAge1xuICAgICAgLy8gUHl0aG9uIEZ1bmN0aW9uXG4gICAgICBpZDogJ1B5dGhvbkZ1bmN0aW9uMEJDRjc3RkQnLFxuICAgICAgY2RrSWQ6ICdQeXRob25GdW5jdGlvbicsXG4gICAgICBpc0J1bmRsZWQ6IHRydWUsXG4gICAgICBwcm9wZXJ0eTogJ0NvZGUnLFxuICAgIH0sXG4gICAge1xuICAgICAgLy8gTG9nIFJldGVudGlvbiBGdW5jdGlvblxuICAgICAgaWQ6ICdMb2dSZXRlbnRpb25hYWUwYWEzYzViNGQ0Zjg3YjAyZDg1YjIwMWVmZGQ4YUZENEJGQzhBJyxcbiAgICAgIGNka0lkOiAnTG9nUmV0ZW50aW9uYWFlMGFhM2M1YjRkNGY4N2IwMmQ4NWIyMDFlZmRkOGEnLFxuICAgICAgaXNCdW5kbGVkOiBmYWxzZSxcbiAgICAgIHByb3BlcnR5OiAnQ29kZScsXG4gICAgfSxcbiAgICB7XG4gICAgICAvLyBGdW5jdGlvblxuICAgICAgaWQ6ICdGdW5jdGlvblB5dGhvblJ1bnRpbWUyOENCREEwNScsXG4gICAgICBjZGtJZDogJ0Z1bmN0aW9uUHl0aG9uUnVudGltZScsXG4gICAgICBpc0J1bmRsZWQ6IGZhbHNlLFxuICAgICAgcHJvcGVydHk6ICdDb2RlJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIC8vIEJ1bmRsZWQgRnVuY3Rpb25cbiAgICAgIGlkOiAnQnVuZGxlZEZ1bmN0aW9uUHl0aG9uUnVudGltZTREOUEwOTE4JyxcbiAgICAgIGNka0lkOiAnQnVuZGxlZEZ1bmN0aW9uUHl0aG9uUnVudGltZScsXG4gICAgICBpc0J1bmRsZWQ6IHRydWUsXG4gICAgICBwcm9wZXJ0eTogJ0NvZGUnLFxuICAgIH0sXG4gICAge1xuICAgICAgLy8gTm9kZUpzIEZ1bmN0aW9uXG4gICAgICBpZDogJ05vZGVqc0Z1bmN0aW9uMDlDMUYyMEYnLFxuICAgICAgY2RrSWQ6ICdOb2RlanNGdW5jdGlvbicsXG4gICAgICBpc0J1bmRsZWQ6IHRydWUsXG4gICAgICBwcm9wZXJ0eTogJ0NvZGUnLFxuICAgIH0sXG4gICAge1xuICAgICAgLy8gR28gRnVuY3Rpb25cbiAgICAgIGlkOiAnR29GdW5jdGlvbkNBOTVGQkFBJyxcbiAgICAgIGNka0lkOiAnR29GdW5jdGlvbicsXG4gICAgICBpc0J1bmRsZWQ6IHRydWUsXG4gICAgICBwcm9wZXJ0eTogJ0NvZGUnLFxuICAgIH0sXG4gICAge1xuICAgICAgLy8gRG9ja2VyIEltYWdlIEZ1bmN0aW9uXG4gICAgICBpZDogJ0RvY2tlckltYWdlRnVuY3Rpb24yOEI3NzNFNicsXG4gICAgICBjZGtJZDogJ0RvY2tlckltYWdlRnVuY3Rpb24nLFxuICAgICAgZG9ja2VyRmlsZVBhdGg6ICdEb2NrZXJmaWxlJyxcbiAgICAgIHByb3BlcnR5OiAnQ29kZS5JbWFnZVVyaScsXG4gICAgfSxcbiAgICB7XG4gICAgICAvLyBTcGVjIFJlc3QgQXBpXG4gICAgICBpZDogJ1NwZWNSZXN0QVBJN0Q0QjNBMzQnLFxuICAgICAgY2RrSWQ6ICdTcGVjUmVzdEFQSScsXG4gICAgICBwcm9wZXJ0eTogJ0JvZHlTM0xvY2F0aW9uJyxcbiAgICB9LFxuICBdO1xuXG4gIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgZXhwZWN0ZWRSZXNvdXJjZXMpIHtcbiAgICBmaXh0dXJlLm91dHB1dC53cml0ZShgdmFsaWRhdGUgYXNzZXRzIG1ldGFkYXRhIGZvciByZXNvdXJjZSAke3Jlc291cmNlfWApO1xuICAgIGV4cGVjdChyZXNvdXJjZS5pZCBpbiB0ZW1wbGF0ZS5SZXNvdXJjZXMpLnRvQmVUcnV0aHkoKTtcbiAgICBleHBlY3QodGVtcGxhdGUuUmVzb3VyY2VzW3Jlc291cmNlLmlkXSkudG9FcXVhbChleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICBNZXRhZGF0YToge1xuICAgICAgICAnYXdzOmNkazpwYXRoJzogYCR7Zml4dHVyZS5mdWxsU3RhY2tOYW1lKCdUZXN0U3RhY2snKX0vJHtyZXNvdXJjZS5jZGtJZH0vUmVzb3VyY2VgLFxuICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiBleHBlY3Quc3RyaW5nTWF0Y2hpbmcoL2Fzc2V0XFwuWzAtOWEtekEtWl17NjR9LyksXG4gICAgICAgICdhd3M6YXNzZXQ6aXMtYnVuZGxlZCc6IHJlc291cmNlLmlzQnVuZGxlZCxcbiAgICAgICAgJ2F3czphc3NldDpkb2NrZXJmaWxlLXBhdGgnOiByZXNvdXJjZS5kb2NrZXJGaWxlUGF0aCxcbiAgICAgICAgJ2F3czphc3NldDpwcm9wZXJ0eSc6IHJlc291cmNlLnByb3BlcnR5LFxuICAgICAgfSxcbiAgICB9KSk7XG4gIH1cblxuICAvLyBOZXN0ZWQgU3RhY2tcbiAgZml4dHVyZS5vdXRwdXQud3JpdGUoJ3ZhbGlkYXRlIGFzc2V0cyBtZXRhZGF0YSBmb3IgbmVzdGVkIHN0YWNrIHJlc291cmNlJyk7XG4gIGV4cGVjdCgnTmVzdGVkU3RhY2tOZXN0ZWRTdGFja05lc3RlZFN0YWNrTmVzdGVkU3RhY2tSZXNvdXJjZUI3MDgzNEZEJyBpbiB0ZW1wbGF0ZS5SZXNvdXJjZXMpLnRvQmVUcnV0aHkoKTtcbiAgZXhwZWN0KHRlbXBsYXRlLlJlc291cmNlcy5OZXN0ZWRTdGFja05lc3RlZFN0YWNrTmVzdGVkU3RhY2tOZXN0ZWRTdGFja1Jlc291cmNlQjcwODM0RkQpLnRvRXF1YWwoZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgIE1ldGFkYXRhOiB7XG4gICAgICAnYXdzOmNkazpwYXRoJzogYCR7Zml4dHVyZS5mdWxsU3RhY2tOYW1lKCdUZXN0U3RhY2snKX0vTmVzdGVkU3RhY2suTmVzdGVkU3RhY2svTmVzdGVkU3RhY2suTmVzdGVkU3RhY2tSZXNvdXJjZWAsXG4gICAgICAnYXdzOmFzc2V0OnBhdGgnOiBleHBlY3Quc3RyaW5nTWF0Y2hpbmcoYCR7Zml4dHVyZS5zdGFja05hbWVQcmVmaXgucmVwbGFjZSgvLS8sICcnKX1UZXN0U3RhY2tOZXN0ZWRTdGFja1swLTlBLVpdezh9XFwubmVzdGVkXFwudGVtcGxhdGVcXC5qc29uYCksXG4gICAgICAnYXdzOmFzc2V0OnByb3BlcnR5JzogJ1RlbXBsYXRlVVJMJyxcbiAgICB9LFxuICB9KSk7XG59KSk7XG5cbmludGVnVGVzdCgnQ0RLIHN5bnRoIGJ1bmRsZWQgZnVuY3Rpb25zIGFzIGV4cGVjdGVkJywgd2l0aFNhbUludGVncmF0aW9uRml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICAvLyBTeW50aCBmaXJzdFxuICBhd2FpdCBmaXh0dXJlLmNka1N5bnRoKCk7XG5cbiAgY29uc3QgdGVtcGxhdGUgPSBmaXh0dXJlLnRlbXBsYXRlKCdUZXN0U3RhY2snKTtcblxuICBjb25zdCBleHBlY3RlZEJ1bmRsZWRBc3NldHMgPSBbXG4gICAge1xuICAgICAgLy8gUHl0aG9uIExheWVyIFZlcnNpb25cbiAgICAgIGlkOiAnUHl0aG9uTGF5ZXJWZXJzaW9uMzk0OTVDRUYnLFxuICAgICAgZmlsZXM6IFtcbiAgICAgICAgJ3B5dGhvbi9sYXllcl92ZXJzaW9uX2RlcGVuZGVuY3kucHknLFxuICAgICAgICAncHl0aG9uL2dlb25hbWVzY2FjaGUvX19pbml0X18ucHknLFxuICAgICAgICAncHl0aG9uL2dlb25hbWVzY2FjaGUtMS4zLjAuZGlzdC1pbmZvJyxcbiAgICAgIF0sXG4gICAgfSxcbiAgICB7XG4gICAgICAvLyBMYXllciBWZXJzaW9uXG4gICAgICBpZDogJ0xheWVyVmVyc2lvbjM4NzhEQTNBJyxcbiAgICAgIGZpbGVzOiBbXG4gICAgICAgICdsYXllcl92ZXJzaW9uX2RlcGVuZGVuY3kucHknLFxuICAgICAgICAncmVxdWlyZW1lbnRzLnR4dCcsXG4gICAgICBdLFxuICAgIH0sXG4gICAge1xuICAgICAgLy8gQnVuZGxlZCBsYXllciB2ZXJzaW9uXG4gICAgICBpZDogJ0J1bmRsZWRMYXllclZlcnNpb25QeXRob25SdW50aW1lNkJBREJENkUnLFxuICAgICAgZmlsZXM6IFtcbiAgICAgICAgJ3B5dGhvbi9sYXllcl92ZXJzaW9uX2RlcGVuZGVuY3kucHknLFxuICAgICAgICAncHl0aG9uL2dlb25hbWVzY2FjaGUvX19pbml0X18ucHknLFxuICAgICAgICAncHl0aG9uL2dlb25hbWVzY2FjaGUtMS4zLjAuZGlzdC1pbmZvJyxcbiAgICAgIF0sXG4gICAgfSxcbiAgICB7XG4gICAgICAvLyBQeXRob24gRnVuY3Rpb25cbiAgICAgIGlkOiAnUHl0aG9uRnVuY3Rpb24wQkNGNzdGRCcsXG4gICAgICBmaWxlczogW1xuICAgICAgICAnYXBwLnB5JyxcbiAgICAgICAgJ2dlb25hbWVzY2FjaGUvX19pbml0X18ucHknLFxuICAgICAgICAnZ2VvbmFtZXNjYWNoZS0xLjMuMC5kaXN0LWluZm8nLFxuICAgICAgXSxcbiAgICB9LFxuICAgIHtcbiAgICAgIC8vIEZ1bmN0aW9uXG4gICAgICBpZDogJ0Z1bmN0aW9uUHl0aG9uUnVudGltZTI4Q0JEQTA1JyxcbiAgICAgIGZpbGVzOiBbXG4gICAgICAgICdhcHAucHknLFxuICAgICAgICAncmVxdWlyZW1lbnRzLnR4dCcsXG4gICAgICBdLFxuICAgIH0sXG4gICAge1xuICAgICAgLy8gQnVuZGxlZCBGdW5jdGlvblxuICAgICAgaWQ6ICdCdW5kbGVkRnVuY3Rpb25QeXRob25SdW50aW1lNEQ5QTA5MTgnLFxuICAgICAgZmlsZXM6IFtcbiAgICAgICAgJ2FwcC5weScsXG4gICAgICAgICdnZW9uYW1lc2NhY2hlL19faW5pdF9fLnB5JyxcbiAgICAgICAgJ2dlb25hbWVzY2FjaGUtMS4zLjAuZGlzdC1pbmZvJyxcbiAgICAgIF0sXG4gICAgfSxcbiAgICB7XG4gICAgICAvLyBOb2RlSnMgRnVuY3Rpb25cbiAgICAgIGlkOiAnTm9kZWpzRnVuY3Rpb24wOUMxRjIwRicsXG4gICAgICBmaWxlczogW1xuICAgICAgICAnaW5kZXguanMnLFxuICAgICAgXSxcbiAgICB9LFxuICAgIHtcbiAgICAgIC8vIEdvIEZ1bmN0aW9uXG4gICAgICBpZDogJ0dvRnVuY3Rpb25DQTk1RkJBQScsXG4gICAgICBmaWxlczogW1xuICAgICAgICAnYm9vdHN0cmFwJyxcbiAgICAgIF0sXG4gICAgfSxcbiAgICB7XG4gICAgICAvLyBEb2NrZXIgSW1hZ2UgRnVuY3Rpb25cbiAgICAgIGlkOiAnRG9ja2VySW1hZ2VGdW5jdGlvbjI4Qjc3M0U2JyxcbiAgICAgIGZpbGVzOiBbXG4gICAgICAgICdhcHAuanMnLFxuICAgICAgICAnRG9ja2VyZmlsZScsXG4gICAgICAgICdwYWNrYWdlLmpzb24nLFxuICAgICAgXSxcbiAgICB9LFxuICBdO1xuXG4gIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgZXhwZWN0ZWRCdW5kbGVkQXNzZXRzKSB7XG4gICAgY29uc3QgYXNzZXRQYXRoID0gdGVtcGxhdGUuUmVzb3VyY2VzW3Jlc291cmNlLmlkXS5NZXRhZGF0YVsnYXdzOmFzc2V0OnBhdGgnXTtcbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgcmVzb3VyY2UuZmlsZXMpIHtcbiAgICAgIGZpeHR1cmUub3V0cHV0LndyaXRlKGB2YWxpZGF0ZSBQYXRoICR7ZmlsZX0gZm9yIHJlc291cmNlICR7cmVzb3VyY2V9YCk7XG4gICAgICBleHBlY3QoZXhpc3RzU3luYyhwYXRoLmpvaW4oZml4dHVyZS5pbnRlZ1Rlc3REaXIsICdjZGsub3V0JywgYXNzZXRQYXRoLCBmaWxlKSkpLnRvQmVUcnV0aHkoKTtcbiAgICB9XG4gIH1cbn0pKTtcblxuaW50ZWdUZXN0KCdzYW0gY2FuIGxvY2FsbHkgdGVzdCB0aGUgc3ludGhlc2l6ZWQgY2RrIGFwcGxpY2F0aW9uJywgd2l0aFNhbUludGVncmF0aW9uRml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICAvLyBTeW50aCBmaXJzdFxuICBhd2FpdCBmaXh0dXJlLmNka1N5bnRoKCk7XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZml4dHVyZS5zYW1Mb2NhbFN0YXJ0QXBpKFxuICAgICdUZXN0U3RhY2snLCBmYWxzZSwgcmFuZG9tSW50ZWdlcigzMDAwMCwgNDAwMDApLCAnL3Jlc3RhcGlzL3NwZWMvcHl0aG9uRnVuY3Rpb24nKTtcbiAgZXhwZWN0KHJlc3VsdC5hY3Rpb25TdWNjZWVkZWQpLnRvQmVUcnV0aHkoKTtcbiAgZXhwZWN0KHJlc3VsdC5hY3Rpb25PdXRwdXQpLnRvRXF1YWwoZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgIG1lc3NhZ2U6ICdIZWxsbyBXb3JsZCcsXG4gIH0pKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdza2lwcyBub3RpY2UgcmVmcmVzaCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBvdXRwdXQgPSBhd2FpdCBmaXh0dXJlLmNka1N5bnRoKHtcbiAgICBvcHRpb25zOiBbJy0tbm8tbm90aWNlcyddLFxuICAgIG1vZEVudjoge1xuICAgICAgSU5URUdfU1RBQ0tfU0VUOiAnc3RhZ2UtdXNpbmctY29udGV4dCcsXG4gICAgfSxcbiAgICBhbGxvd0VyckV4aXQ6IHRydWUsXG4gIH0pO1xuXG4gIC8vIE5laXRoZXIgc3VjY2VlZHMgbm9yIGZhaWxzLCBidXQgc2tpcHMgdGhlIHJlZnJlc2hcbiAgYXdhaXQgZXhwZWN0KG91dHB1dCkubm90LnRvQ29udGFpbignTm90aWNlcyByZWZyZXNoZWQnKTtcbiAgYXdhaXQgZXhwZWN0KG91dHB1dCkubm90LnRvQ29udGFpbignTm90aWNlcyByZWZyZXNoIGZhaWxlZCcpO1xufSkpO1xuXG4vKipcbiAqIENyZWF0ZSBhIHF1ZXVlIHdpdGggYSBmcmVzaCBuYW1lLCByZWRlcGxveSBvcnBoYW5pbmcgdGhlIHF1ZXVlLCB0aGVuIGltcG9ydCBpdCBhZ2FpblxuICovXG5pbnRlZ1Rlc3QoJ3Rlc3QgcmVzb3VyY2UgaW1wb3J0Jywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IG91dHB1dHNGaWxlID0gcGF0aC5qb2luKGZpeHR1cmUuaW50ZWdUZXN0RGlyLCAnb3V0cHV0cycsICdvdXRwdXRzLmpzb24nKTtcbiAgYXdhaXQgZnMubWtkaXIocGF0aC5kaXJuYW1lKG91dHB1dHNGaWxlKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgLy8gSW5pdGlhbCBkZXBsb3lcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2ltcG9ydGFibGUtc3RhY2snLCB7XG4gICAgbW9kRW52OiB7IE9SUEhBTl9UT1BJQzogJzEnIH0sXG4gICAgb3B0aW9uczogWyctLW91dHB1dHMtZmlsZScsIG91dHB1dHNGaWxlXSxcbiAgfSk7XG5cbiAgY29uc3Qgb3V0cHV0cyA9IEpTT04ucGFyc2UoKGF3YWl0IGZzLnJlYWRGaWxlKG91dHB1dHNGaWxlLCB7IGVuY29kaW5nOiAndXRmLTgnIH0pKS50b1N0cmluZygpKTtcbiAgY29uc3QgcXVldWVOYW1lID0gb3V0cHV0cy5RdWV1ZU5hbWU7XG4gIGNvbnN0IHF1ZXVlTG9naWNhbElkID0gb3V0cHV0cy5RdWV1ZUxvZ2ljYWxJZDtcbiAgZml4dHVyZS5sb2coYFNldHVwIGNvbXBsZXRlLCBjcmVhdGVkIHF1ZXVlICR7cXVldWVOYW1lfWApO1xuICB0cnkge1xuICAgIC8vIERlcGxveSBhZ2Fpbiwgb3JwaGFuaW5nIHRoZSBxdWV1ZVxuICAgIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdpbXBvcnRhYmxlLXN0YWNrJywge1xuICAgICAgbW9kRW52OiB7IE9NSVRfVE9QSUM6ICcxJyB9LFxuICAgIH0pO1xuXG4gICAgLy8gV3JpdGUgYSByZXNvdXJjZSBtYXBwaW5nIGZpbGUgYmFzZWQgb24gdGhlIElEIGZyb20gc3RlcCBvbmUsIHRoZW4gcnVuIGFuIGltcG9ydFxuICAgIGNvbnN0IG1hcHBpbmdGaWxlID0gcGF0aC5qb2luKGZpeHR1cmUuaW50ZWdUZXN0RGlyLCAnb3V0cHV0cycsICdtYXBwaW5nLmpzb24nKTtcbiAgICBhd2FpdCBmcy53cml0ZUZpbGUobWFwcGluZ0ZpbGUsIEpTT04uc3RyaW5naWZ5KHsgW3F1ZXVlTG9naWNhbElkXTogeyBRdWV1ZU5hbWU6IHF1ZXVlTmFtZSB9IH0pLCB7IGVuY29kaW5nOiAndXRmLTgnIH0pO1xuXG4gICAgYXdhaXQgZml4dHVyZS5jZGsoWydpbXBvcnQnLFxuICAgICAgJy0tcmVzb3VyY2UtbWFwcGluZycsIG1hcHBpbmdGaWxlLFxuICAgICAgZml4dHVyZS5mdWxsU3RhY2tOYW1lKCdpbXBvcnRhYmxlLXN0YWNrJyldKTtcbiAgfSBmaW5hbGx5IHtcbiAgICAvLyBDbGVhbnVwXG4gICAgYXdhaXQgZml4dHVyZS5jZGtEZXN0cm95KCdpbXBvcnRhYmxlLXN0YWNrJyk7XG4gIH1cbn0pKTtcblxuaW50ZWdUZXN0KCdob3Rzd2FwIGRlcGxveW1lbnQgc3VwcG9ydHMgTGFtYmRhIGZ1bmN0aW9uXFwncyBkZXNjcmlwdGlvbiBhbmQgZW52aXJvbm1lbnQgdmFyaWFibGVzJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IHN0YWNrQXJuID0gYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2xhbWJkYS1ob3Rzd2FwJywge1xuICAgIGNhcHR1cmVTdGRlcnI6IGZhbHNlLFxuICAgIG1vZEVudjoge1xuICAgICAgRFlOQU1JQ19MQU1CREFfUFJPUEVSVFlfVkFMVUU6ICdvcmlnaW5hbCB2YWx1ZScsXG4gICAgfSxcbiAgfSk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCBkZXBsb3lPdXRwdXQgPSBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnbGFtYmRhLWhvdHN3YXAnLCB7XG4gICAgb3B0aW9uczogWyctLWhvdHN3YXAnXSxcbiAgICBjYXB0dXJlU3RkZXJyOiB0cnVlLFxuICAgIG9ubHlTdGRlcnI6IHRydWUsXG4gICAgbW9kRW52OiB7XG4gICAgICBEWU5BTUlDX0xBTUJEQV9QUk9QRVJUWV9WQUxVRTogJ25ldyB2YWx1ZScsXG4gICAgfSxcbiAgfSk7XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbignZGVzY3JpYmVTdGFja3MnLCB7XG4gICAgU3RhY2tOYW1lOiBzdGFja0FybixcbiAgfSk7XG4gIGNvbnN0IGZ1bmN0aW9uTmFtZSA9IHJlc3BvbnNlLlN0YWNrcz8uWzBdLk91dHB1dHM/LlswXS5PdXRwdXRWYWx1ZTtcblxuICAvLyBUSEVOXG5cbiAgLy8gVGhlIGRlcGxveW1lbnQgc2hvdWxkIG5vdCB0cmlnZ2VyIGEgZnVsbCBkZXBsb3ltZW50LCB0aHVzIHRoZSBzdGFjaydzIHN0YXR1cyBtdXN0IHJlbWFpbnNcbiAgLy8gXCJDUkVBVEVfQ09NUExFVEVcIlxuICBleHBlY3QocmVzcG9uc2UuU3RhY2tzPy5bMF0uU3RhY2tTdGF0dXMpLnRvRXF1YWwoJ0NSRUFURV9DT01QTEVURScpO1xuICBleHBlY3QoZGVwbG95T3V0cHV0KS50b0NvbnRhaW4oYExhbWJkYSBGdW5jdGlvbiAnJHtmdW5jdGlvbk5hbWV9JyBob3Rzd2FwcGVkIWApO1xufSkpO1xuXG5hc3luYyBmdW5jdGlvbiBsaXN0Q2hpbGRyZW4ocGFyZW50OiBzdHJpbmcsIHByZWQ6ICh4OiBzdHJpbmcpID0+IFByb21pc2U8Ym9vbGVhbj4pIHtcbiAgY29uc3QgcmV0ID0gbmV3IEFycmF5PHN0cmluZz4oKTtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBhd2FpdCBmcy5yZWFkZGlyKHBhcmVudCwgeyBlbmNvZGluZzogJ3V0Zi04JyB9KSkge1xuICAgIGNvbnN0IGZ1bGxQYXRoID0gcGF0aC5qb2luKHBhcmVudCwgY2hpbGQudG9TdHJpbmcoKSk7XG4gICAgaWYgKGF3YWl0IHByZWQoZnVsbFBhdGgpKSB7XG4gICAgICByZXQucHVzaChmdWxsUGF0aCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGxpc3RDaGlsZERpcnMocGFyZW50OiBzdHJpbmcpIHtcbiAgcmV0dXJuIGxpc3RDaGlsZHJlbihwYXJlbnQsIGFzeW5jIChmdWxsUGF0aDogc3RyaW5nKSA9PiAoYXdhaXQgZnMuc3RhdChmdWxsUGF0aCkpLmlzRGlyZWN0b3J5KCkpO1xufVxuIl19