@aws-cdk/integ-runner 2.202.2 → 2.202.3

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 (38) hide show
  1. package/lib/cli.d.ts.map +1 -1
  2. package/lib/cli.js +3 -2
  3. package/lib/engines/toolkit-lib.d.ts +1 -1
  4. package/lib/engines/toolkit-lib.d.ts.map +1 -1
  5. package/lib/engines/toolkit-lib.js +11 -11
  6. package/lib/files.d.ts +9 -0
  7. package/lib/files.d.ts.map +1 -0
  8. package/lib/files.js +51 -0
  9. package/lib/index.js +218 -182
  10. package/lib/runner/{cdk-integ-helper.d.ts → cdk-test-app.d.ts} +90 -114
  11. package/lib/runner/cdk-test-app.d.ts.map +1 -0
  12. package/lib/runner/cdk-test-app.js +584 -0
  13. package/lib/runner/engine.d.ts +2 -2
  14. package/lib/runner/engine.d.ts.map +1 -1
  15. package/lib/runner/engine.js +2 -2
  16. package/lib/runner/index.d.ts +1 -1
  17. package/lib/runner/index.d.ts.map +1 -1
  18. package/lib/runner/index.js +2 -2
  19. package/lib/runner/integ-test-runner.d.ts +36 -36
  20. package/lib/runner/integ-test-runner.d.ts.map +1 -1
  21. package/lib/runner/integ-test-runner.js +172 -235
  22. package/lib/runner/integ-test-suite.d.ts +6 -11
  23. package/lib/runner/integ-test-suite.d.ts.map +1 -1
  24. package/lib/runner/integ-test-suite.js +14 -20
  25. package/lib/runner/integration-tests.d.ts +12 -3
  26. package/lib/runner/integration-tests.d.ts.map +1 -1
  27. package/lib/runner/integration-tests.js +32 -8
  28. package/lib/runner/snapshot-test-runner.d.ts +19 -22
  29. package/lib/runner/snapshot-test-runner.d.ts.map +1 -1
  30. package/lib/runner/snapshot-test-runner.js +47 -75
  31. package/lib/workers/extract/extract_worker.d.ts.map +1 -1
  32. package/lib/workers/extract/extract_worker.js +65 -78
  33. package/lib/workers/extract/index.js +226955 -226979
  34. package/lib/workers/integ-test-worker.d.ts.map +1 -1
  35. package/lib/workers/integ-test-worker.js +3 -2
  36. package/package.json +3 -3
  37. package/lib/runner/cdk-integ-helper.d.ts.map +0 -1
  38. package/lib/runner/cdk-integ-helper.js +0 -525
@@ -40,9 +40,9 @@ const chokidar = __importStar(require("chokidar"));
40
40
  const handler_js_1 = require("chokidar/handler.js");
41
41
  const fs = __importStar(require("fs-extra"));
42
42
  const workerpool = __importStar(require("workerpool"));
43
- const cdk_integ_helper_1 = require("./cdk-integ-helper");
44
43
  const logger = __importStar(require("../logger"));
45
44
  const utils_1 = require("../utils");
45
+ const cdk_test_app_1 = require("./cdk-test-app");
46
46
  const common_1 = require("../workers/common");
47
47
  /**
48
48
  * File events that we care about from chokidar.
@@ -61,59 +61,123 @@ function isFileEvent(event) {
61
61
  * integration tests
62
62
  */
63
63
  class IntegTestRunner {
64
- helper;
65
- constructor(options, destructiveChanges) {
66
- this.helper = cdk_integ_helper_1.CdkIntegHelper.create(options);
67
- this.helper._destructiveChanges = destructiveChanges;
68
- // We need to have given this a value, but we don't actually care about it initially,
69
- // because we only synth to get the test definition.
70
- // FIXME: This is unfortunate -- in order to start running the test "for real" we
71
- // already have created a real snapshot with the real test definition, but we've thrown
72
- // that away already. So we need to synth again just to get the test definition, AGAIN.
73
- //
74
- // We will rewrite this later when it comes time to generate the actual
75
- // golden snapshot, to match the requested value in the test definition.
76
- this.helper.configureLegacyEnableLookups('dont-care');
64
+ appOptions;
65
+ destructiveChanges;
66
+ test;
67
+ constructor(appOptions, destructiveChanges) {
68
+ this.appOptions = appOptions;
69
+ this.destructiveChanges = destructiveChanges;
70
+ this.test = appOptions.test;
77
71
  }
78
72
  /**
79
- * Compatibility shim with old API
80
- */
81
- get testName() {
82
- return this.helper.testName;
83
- }
84
- /**
85
- * Compatibility shim with old API
73
+ * Orchestrates running integration tests. Currently this includes
74
+ *
75
+ * 1. (if update workflow is enabled) Deploying the snapshot test stacks
76
+ * 2. Deploying the integration test stacks
77
+ * 2. Saving the snapshot (if successful)
78
+ * 3. Destroying the integration test stacks (if clean=false)
79
+ *
80
+ * The update workflow exists to check for cases where a change would cause
81
+ * a failure to an existing stack, but not for a newly created stack.
86
82
  */
87
- async actualTestSuite() {
88
- return (await this.helper.actualSnapshot()).testDefinition;
89
- }
90
- async actualTests() {
91
- const actualTestSuite = await this.actualTestSuite();
92
- // We don't want new tests written in the legacy mode.
93
- // If there is no existing snapshot _and_ this is a legacy
94
- // test then point the user to the new `IntegTest` construct
95
- if (!this.helper.hasSnapshot() && actualTestSuite.type === 'legacy-test-suite') {
96
- throw new Error(`${this.helper.testName} is a new test. Please use the IntegTest construct ` +
83
+ async runIntegTestCase(runOptions) {
84
+ let assertionResults;
85
+ // Set up actual
86
+ let actual = await cdk_test_app_1.CdkTestApp.forDeployment(this.appOptions);
87
+ if (this.appOptions.TESTING_useComparisonOutputDirectory) {
88
+ actual = await cdk_test_app_1.CdkTestApp.forComparison(this.appOptions);
89
+ }
90
+ const previousVersion = await cdk_test_app_1.CdkTestApp.forGoldenSnapshot(this.appOptions);
91
+ const actualTestSuite = await actual.synthForDeployment();
92
+ if (actualTestSuite.type === 'legacy-test-suite' && !previousVersion.hasOutput()) {
93
+ throw new Error(`${this.test.testName} is a new test. Please use the IntegTest construct ` +
97
94
  'to configure the test\n' +
98
95
  'https://github.com/aws/aws-cdk/tree/main/packages/%40aws-cdk/integ-tests-alpha');
99
96
  }
100
- return actualTestSuite.testSuite;
97
+ const clean = runOptions.clean ?? true;
98
+ try {
99
+ for (const [testCaseName, actualTestCase] of Object.entries(actualTestSuite.testSuite)) {
100
+ const updateWorkflowEnabled = (runOptions.updateWorkflow ?? false)
101
+ && (actualTestCase.stackUpdateWorkflow ?? false);
102
+ const allowDeleteFailures = actualTestCase.allowDeleteFailures ?? runOptions.allowDeleteFailures ?? false;
103
+ const verbosity = analyzeVerbosity(runOptions.verbosity);
104
+ if (!runOptions.dryRun && (actualTestCase.cdkCommandOptions?.deploy?.enabled ?? true)) {
105
+ try {
106
+ assertionResults = await this.deployTestAndAssertions(actual, previousVersion, actualTestCase, {
107
+ roleArn: runOptions.roleArn ?? actualTestCase.cdkCommandOptions?.deploy?.args?.roleArn,
108
+ verbose: verbosity.verbose,
109
+ debug: verbosity.debug,
110
+ }, updateWorkflowEnabled, testCaseName, allowDeleteFailures, runOptions.updateFromTags);
111
+ }
112
+ finally {
113
+ if (!runOptions.dryRun && clean && (actualTestCase.cdkCommandOptions?.destroy?.enabled ?? true)) {
114
+ await this.destroyTestAndAssertions(actual, actualTestCase, {
115
+ ...actualTestCase.cdkCommandOptions?.destroy?.args,
116
+ roleArn: runOptions.roleArn ?? actualTestCase.cdkCommandOptions?.destroy?.args?.roleArn,
117
+ verbose: verbosity.verbose,
118
+ debug: verbosity.debug,
119
+ });
120
+ }
121
+ }
122
+ }
123
+ }
124
+ // only create the snapshot if there are no failed assertion results
125
+ // (i.e. no failures)
126
+ if (!Object.values(assertionResults ?? {}).some(result => result.status === 'fail')) {
127
+ await this.createSnapshot(actualTestSuite.enableLookups);
128
+ }
129
+ }
130
+ finally {
131
+ actual.cleanup();
132
+ }
133
+ return assertionResults;
134
+ }
135
+ async createSnapshot(enableLookups) {
136
+ const expected = await cdk_test_app_1.CdkTestApp.forGoldenSnapshot(this.appOptions);
137
+ await expected.synthForGoldenSnapshot(this.destructiveChanges ?? [], enableLookups);
101
138
  }
102
- createCdkContextJson() {
103
- if (!fs.existsSync(this.helper.cdkContextPath)) {
104
- fs.writeFileSync(this.helper.cdkContextPath, JSON.stringify({
105
- watch: {},
106
- }, undefined, 2));
139
+ /**
140
+ * Runs cdk deploy --watch for an integration test
141
+ *
142
+ * This is meant to be run on a single test and will not create a snapshot
143
+ */
144
+ async watchIntegTest(options) {
145
+ // Set up actual
146
+ const actual = await cdk_test_app_1.CdkTestApp.forDeployment(this.appOptions);
147
+ await actual.synthForDeployment();
148
+ // Just take the first test case, that's the one we watch.
149
+ // Not even sure how better behavior here is possible, but watch isn't used that often.
150
+ const firstTestCaseName = Object.keys(actual.testCases())[0];
151
+ const verbosity = analyzeVerbosity(options.verbosity);
152
+ try {
153
+ await this.watch(actual, firstTestCaseName, {
154
+ ...cdk_test_app_1.DEFAULT_ARGS,
155
+ deploymentMethod: {
156
+ method: 'hotswap',
157
+ fallback: {
158
+ method: 'change-set',
159
+ },
160
+ },
161
+ profile: this.appOptions.profile,
162
+ requireApproval: cloud_assembly_schema_1.RequireApproval.NEVER,
163
+ traceLogs: verbosity.traceLogs ?? false,
164
+ verbose: verbosity.verbose,
165
+ debug: verbosity.debug,
166
+ roleArn: options.roleArn,
167
+ }, options.verbosity ?? 0);
168
+ }
169
+ catch (e) {
170
+ throw e;
107
171
  }
108
172
  }
109
173
  /**
110
174
  * Checkout the snapshot directory at a specific git ref (tag, commit, branch).
111
175
  * Fails fast if the snapshot does not exist at the given ref.
112
176
  */
113
- checkoutSnapshotAtRef(ref) {
114
- const gitCwd = path.dirname(this.helper.goldenSnapshotDir);
177
+ checkoutSnapshotAtRef(snapshotApp, ref) {
178
+ const gitCwd = path.dirname(snapshotApp.outputDirectory);
115
179
  const git = ['git', '-C', gitCwd];
116
- const relativeSnapshotDir = path.relative(gitCwd, this.helper.goldenSnapshotDir);
180
+ const relativeSnapshotDir = path.relative(gitCwd, snapshotApp.outputDirectory);
117
181
  try {
118
182
  (0, utils_1.exec)([...git, 'checkout', ref, '--', relativeSnapshotDir]);
119
183
  }
@@ -127,24 +191,22 @@ class IntegTestRunner {
127
191
  * Deploy the snapshot from each git tag in sequence, then let the caller
128
192
  * deploy the current code as the final update.
129
193
  */
130
- async deployFromTags(deployArgs, testCaseName, tags, allowDeleteFailures) {
194
+ async deployFromTags(actualApp, deployArgs, testCaseName, tags, allowDeleteFailures) {
131
195
  const totalTags = tags.length;
132
196
  for (let i = 0; i < totalTags; i++) {
133
197
  const tag = tags[i];
134
- logger.highlight(`${this.helper.testName}/${testCaseName}: deploying tag ${tag} (${i + 1}/${totalTags})`);
135
- this.checkoutSnapshotAtRef(tag);
136
- const expectedTestSuite = await this.helper.expectedTestSuite();
198
+ logger.highlight(`${this.test.testName}/${testCaseName}: deploying tag ${tag} (${i + 1}/${totalTags})`);
199
+ this.checkoutSnapshotAtRef(actualApp, tag);
200
+ const expectedTestSuite = actualApp.testSuite;
137
201
  if (!expectedTestSuite || !(testCaseName in expectedTestSuite.testSuite)) {
138
202
  throw new Error(`Test case '${testCaseName}' does not exist in snapshot at tag '${tag}'`);
139
203
  }
140
204
  const expectedTestCase = expectedTestSuite.testSuite[testCaseName];
141
- const deployResult = await this.helper.cdk.deploy({
205
+ const deployResult = await actualApp.deploy({
142
206
  ...deployArgs,
143
207
  stacks: expectedTestCase.stacks,
144
208
  ...expectedTestCase?.cdkCommandOptions?.deploy?.args,
145
- context: this.helper.getContext(expectedTestCase?.cdkCommandOptions?.deploy?.args?.context),
146
- app: path.relative(this.helper.directory, this.helper.goldenSnapshotDir),
147
- lookups: expectedTestSuite?.enableLookups,
209
+ context: expectedTestCase?.cdkCommandOptions?.deploy?.args?.context,
148
210
  });
149
211
  if (deployResult.deleteFailures.length > 0) {
150
212
  const details = deployResult.deleteFailures
@@ -159,7 +221,7 @@ class IntegTestRunner {
159
221
  }
160
222
  }
161
223
  }
162
- logger.highlight(`${this.helper.testName}/${testCaseName}: deploying current branch (final)`);
224
+ logger.highlight(`${actualApp.test.testName}/${testCaseName}: deploying current branch (final)`);
163
225
  }
164
226
  /**
165
227
  * When running integration tests with the update path workflow
@@ -172,13 +234,13 @@ class IntegTestRunner {
172
234
  * This assumes that there is an 'origin'. `git remote show origin` returns a list of
173
235
  * all branches and we then search for one that starts with `HEAD branch: `
174
236
  */
175
- checkoutSnapshot() {
237
+ checkoutSnapshot(actualApp) {
176
238
  // We use the directory that contains the snapshot to run git commands in
177
239
  // We don't change the cwd for executing git, but instead use the -C flag
178
240
  // @see https://git-scm.com/docs/git#Documentation/git.txt--Cltpathgt
179
241
  // This way we are guaranteed to operate under the correct git repo, even
180
242
  // when executing integ-runner from outside the repo under test.
181
- const gitCwd = path.dirname(this.helper.goldenSnapshotDir);
243
+ const gitCwd = path.dirname(actualApp.outputDirectory);
182
244
  const git = ['git', '-C', gitCwd];
183
245
  // https://git-scm.com/docs/git-merge-base
184
246
  let baseBranch = undefined;
@@ -193,156 +255,47 @@ class IntegTestRunner {
193
255
  }
194
256
  }
195
257
  catch (e) {
196
- logger.warning('%s\n%s', 'Could not determine git origin branch.', `You need to manually checkout the snapshot directory ${this.helper.goldenSnapshotDir}` +
258
+ logger.warning('%s\n%s', 'Could not determine git origin branch.', `You need to manually checkout the snapshot directory ${actualApp.outputDirectory}` +
197
259
  'from the merge-base (https://git-scm.com/docs/git-merge-base)');
198
260
  logger.warning('error: %s', (0, common_1.formatError)(e));
199
261
  }
200
262
  // if we found the base branch then get the merge-base (most recent common commit)
201
263
  // and checkout the snapshot using that commit
202
264
  if (baseBranch) {
203
- const relativeSnapshotDir = path.relative(gitCwd, this.helper.goldenSnapshotDir);
265
+ const relativeSnapshotDir = path.relative(gitCwd, actualApp.outputDirectory);
204
266
  const checkoutCommand = [...git, 'checkout', [...git, 'merge-base', 'HEAD', baseBranch], '--', relativeSnapshotDir];
205
267
  try {
206
268
  (0, utils_1.execWithSubShell)(checkoutCommand);
207
269
  }
208
270
  catch (e) {
209
- logger.warning('%s\n%s', `Could not checkout snapshot directory '${this.helper.goldenSnapshotDir}'. Please verify the following command completes correctly:`, (0, utils_1.renderCommand)(checkoutCommand), '');
271
+ logger.warning('%s\n%s', `Could not checkout snapshot directory '${actualApp.outputDirectory}'. Please verify the following command completes correctly:`, (0, utils_1.renderCommand)(checkoutCommand), '');
210
272
  logger.warning('error: %s', (0, common_1.formatError)(e));
211
273
  }
212
274
  }
213
275
  }
214
- /**
215
- * Runs cdk deploy --watch for an integration test
216
- *
217
- * This is meant to be run on a single test and will not create a snapshot
218
- */
219
- async watchIntegTest(options) {
220
- const actualTestSuite = await this.actualTestSuite();
221
- const actualTestCase = actualTestSuite.testSuite[options.testCaseName];
222
- if (!actualTestCase) {
223
- throw new Error(`Did not find test case name '${options.testCaseName}' in '${Object.keys(actualTestSuite.testSuite)}'`);
224
- }
225
- const enableForVerbosityLevel = (needed = 1) => {
226
- const verbosity = options.verbosity ?? 0;
227
- return (verbosity >= needed) ? true : undefined;
228
- };
229
- try {
230
- await this.watch({
231
- ...this.helper.defaultArgs,
232
- deploymentMethod: {
233
- method: 'hotswap',
234
- fallback: {
235
- method: 'change-set',
236
- },
237
- },
238
- profile: this.helper.profile,
239
- requireApproval: cloud_assembly_schema_1.RequireApproval.NEVER,
240
- traceLogs: enableForVerbosityLevel(2) ?? false,
241
- verbose: enableForVerbosityLevel(3),
242
- debug: enableForVerbosityLevel(4),
243
- roleArn: options.roleArn,
244
- }, options.testCaseName, options.verbosity ?? 0);
245
- }
246
- catch (e) {
247
- throw e;
248
- }
249
- }
250
- /**
251
- * Orchestrates running integration tests. Currently this includes
252
- *
253
- * 1. (if update workflow is enabled) Deploying the snapshot test stacks
254
- * 2. Deploying the integration test stacks
255
- * 2. Saving the snapshot (if successful)
256
- * 3. Destroying the integration test stacks (if clean=false)
257
- *
258
- * The update workflow exists to check for cases where a change would cause
259
- * a failure to an existing stack, but not for a newly created stack.
260
- */
261
- async runIntegTestCase(options) {
262
- let assertionResults;
263
- const actualTestSuite = await this.actualTestSuite();
264
- const actualTestCase = actualTestSuite.testSuite[options.testCaseName];
265
- if (!actualTestCase) {
266
- throw new Error(`Did not find test case name '${options.testCaseName}' in '${Object.keys(actualTestSuite.testSuite)}'`);
267
- }
268
- // Ideally we would force `enableLookups` to `true`, always, because that's what we would like to converge on for the snapshots.
269
- //
270
- // HOWEVER!
271
- //
272
- // In order to do that, to validate the snapshot correctly we need to match what's in `integ.json`. In order to ratchet
273
- // that value to `true`, we would need to rewrite `integ.json` to have `enableLookups: true`. We don't currently
274
- // have code to reliably rewrite that file, so we just leave the value at whatever the test requested.
275
- this.helper.configureLegacyEnableLookups(actualTestSuite.enableLookups ?? false);
276
- const clean = options.clean ?? true;
277
- const updateWorkflowEnabled = (options.updateWorkflow ?? true)
278
- && (actualTestCase.stackUpdateWorkflow ?? true);
279
- const allowDeleteFailures = actualTestCase.allowDeleteFailures ?? options.allowDeleteFailures ?? false;
280
- const enableForVerbosityLevel = (needed = 1) => {
281
- const verbosity = options.verbosity ?? 0;
282
- return (verbosity >= needed) ? true : undefined;
283
- };
284
- try {
285
- if (!options.dryRun && (actualTestCase.cdkCommandOptions?.deploy?.enabled ?? true)) {
286
- assertionResults = await this.deploy({
287
- ...this.helper.defaultArgs,
288
- profile: this.helper.profile,
289
- requireApproval: cloud_assembly_schema_1.RequireApproval.NEVER,
290
- verbose: enableForVerbosityLevel(3),
291
- debug: enableForVerbosityLevel(4),
292
- roleArn: options.roleArn,
293
- }, updateWorkflowEnabled, options.testCaseName, allowDeleteFailures, options.updateFromTags);
294
- }
295
- // only create the snapshot if there are no failed assertion results
296
- // (i.e. no failures)
297
- if (!Object.values(assertionResults ?? {}).some(result => result.status === 'fail')) {
298
- await this.helper.createSnapshot();
299
- }
300
- }
301
- catch (e) {
302
- throw e;
303
- }
304
- finally {
305
- if (!options.dryRun) {
306
- if (clean && (actualTestCase.cdkCommandOptions?.destroy?.enabled ?? true)) {
307
- await this.destroy(options.testCaseName, {
308
- ...this.helper.defaultArgs,
309
- profile: this.helper.profile,
310
- all: true,
311
- force: true,
312
- app: this.helper.cdkApp,
313
- output: path.relative(this.helper.directory, this.helper.temporarySnapshotDir),
314
- ...actualTestCase.cdkCommandOptions?.destroy?.args,
315
- context: this.helper.getContext(actualTestCase.cdkCommandOptions?.destroy?.args?.context),
316
- roleArn: options.roleArn ?? actualTestCase.cdkCommandOptions?.destroy?.args?.roleArn,
317
- verbose: enableForVerbosityLevel(3),
318
- debug: enableForVerbosityLevel(4),
319
- });
320
- }
321
- }
322
- this.helper.cleanup();
323
- }
324
- return assertionResults;
325
- }
326
276
  /**
327
277
  * Perform a integ test case stack destruction
328
278
  */
329
- async destroy(testCaseName, destroyArgs) {
330
- const actualTestCase = (await this.actualTestSuite()).testSuite[testCaseName];
279
+ async destroyTestAndAssertions(actualApp, actualTestCase, destroyArgs) {
331
280
  try {
332
281
  if (actualTestCase.hooks?.preDestroy) {
333
282
  actualTestCase.hooks.preDestroy.forEach(cmd => {
334
283
  (0, utils_1.exec)((0, utils_1.chunks)(cmd), {
335
- cwd: path.dirname(this.helper.goldenSnapshotDir),
284
+ cwd: path.dirname(actualApp.outputDirectory),
336
285
  });
337
286
  });
338
287
  }
339
- await this.helper.cdk.destroy({
288
+ await actualApp.destroy({
289
+ stacks: [
290
+ ...actualTestCase.stacks,
291
+ ...(actualTestCase.assertionStack ? [actualTestCase.assertionStack] : []),
292
+ ],
340
293
  ...destroyArgs,
341
294
  });
342
295
  if (actualTestCase.hooks?.postDestroy) {
343
296
  actualTestCase.hooks.postDestroy.forEach(cmd => {
344
297
  (0, utils_1.exec)((0, utils_1.chunks)(cmd), {
345
- cwd: path.dirname(this.helper.goldenSnapshotDir),
298
+ cwd: path.dirname(actualApp.outputDirectory),
346
299
  });
347
300
  });
348
301
  }
@@ -351,13 +304,13 @@ class IntegTestRunner {
351
304
  this.parseError(e, actualTestCase.cdkCommandOptions?.destroy?.expectError ?? false, actualTestCase.cdkCommandOptions?.destroy?.expectedMessage);
352
305
  }
353
306
  }
354
- async watch(options, testCaseName, verbosity) {
355
- const actualTestSuite = await this.actualTestSuite();
356
- const actualTestCase = actualTestSuite.testSuite[testCaseName];
307
+ async watch(actualApp, testCaseName, options, verbosity) {
308
+ const actualTestSuite = actualApp.testSuite;
309
+ const actualTestCase = actualApp.testCases()[testCaseName];
357
310
  if (actualTestCase.hooks?.preDeploy) {
358
311
  actualTestCase.hooks.preDeploy.forEach(cmd => {
359
312
  (0, utils_1.exec)((0, utils_1.chunks)(cmd), {
360
- cwd: path.dirname(this.helper.goldenSnapshotDir),
313
+ cwd: path.dirname(actualApp.outputDirectory),
361
314
  });
362
315
  });
363
316
  }
@@ -368,13 +321,10 @@ class IntegTestRunner {
368
321
  ...actualTestCase.stacks,
369
322
  ...actualTestCase.assertionStack ? [actualTestCase.assertionStack] : [],
370
323
  ],
371
- output: path.relative(this.helper.directory, this.helper.temporarySnapshotDir),
372
- outputsFile: path.relative(this.helper.directory, path.join(this.helper.temporarySnapshotDir, 'assertion-results.json')),
324
+ output: actualApp.outputDirectory,
325
+ outputsFile: path.join(actualApp.outputDirectory, 'assertion-results.json'),
373
326
  ...actualTestCase?.cdkCommandOptions?.deploy?.args,
374
- context: {
375
- ...this.helper.getContext(actualTestCase?.cdkCommandOptions?.deploy?.args?.context),
376
- },
377
- app: this.helper.cdkApp,
327
+ context: actualTestCase?.cdkCommandOptions?.deploy?.args?.context,
378
328
  };
379
329
  const destroyMessage = {
380
330
  additionalMessages: [
@@ -382,7 +332,7 @@ class IntegTestRunner {
382
332
  ` ${[
383
333
  ...process.env.AWS_REGION ? [`AWS_REGION=${process.env.AWS_REGION}`] : [],
384
334
  'cdk destroy',
385
- `-a '${this.helper.cdkApp}'`,
335
+ `-a '${actualApp.appCommand}'`,
386
336
  watchArgs.stacks.join(' '),
387
337
  `--profile ${watchArgs.profile}`,
388
338
  ].join(' ')}`,
@@ -395,22 +345,13 @@ class IntegTestRunner {
395
345
  workerpool.workerEmit({
396
346
  additionalMessages: [
397
347
  'Repro:',
398
- ` ${[
399
- 'cdk synth',
400
- `-a '${this.helper.cdkApp}'`,
401
- `-o '${this.helper.temporarySnapshotDir}'`,
402
- ...Object.entries(this.helper.getContext()).flatMap(([k, v]) => typeof v !== 'object' ? [`-c '${k}=${v}'`] : []),
403
- watchArgs.stacks.join(' '),
404
- `--outputs-file ${watchArgs.outputsFile}`,
405
- `--profile ${watchArgs.profile}`,
406
- '--hotswap-fallback',
407
- ].join(' ')}`,
348
+ ` ${actualApp.synthReproCommand}`,
408
349
  ],
409
350
  });
410
351
  }
411
- const assertionResults = path.join(this.helper.temporarySnapshotDir, 'assertion-results.json');
412
- const watcher = chokidar.watch([this.helper.temporarySnapshotDir], {
413
- cwd: this.helper.directory,
352
+ const assertionResults = path.join(actualApp.outputDirectory, 'assertion-results.json');
353
+ const watcher = chokidar.watch([actualApp.outputDirectory], {
354
+ cwd: actualApp.outputDirectory,
414
355
  });
415
356
  watcher.on('all', (event, file) => {
416
357
  if (!isFileEvent(event)) {
@@ -423,7 +364,7 @@ class IntegTestRunner {
423
364
  if (actualTestCase.hooks?.postDeploy) {
424
365
  actualTestCase.hooks.postDeploy.forEach(cmd => {
425
366
  (0, utils_1.exec)((0, utils_1.chunks)(cmd), {
426
- cwd: path.dirname(this.helper.goldenSnapshotDir),
367
+ cwd: path.dirname(actualApp.outputDirectory),
427
368
  });
428
369
  });
429
370
  }
@@ -457,7 +398,7 @@ class IntegTestRunner {
457
398
  });
458
399
  });
459
400
  const { promise: waiter, resolve } = (0, utils_1.promiseWithResolvers)();
460
- await this.helper.cdk.watch(watchArgs, {
401
+ await actualApp.watch(watchArgs, {
461
402
  // if `-v` (or above) is passed then stream the logs
462
403
  onStdout: (message) => {
463
404
  if (verbosity > 0) {
@@ -484,48 +425,40 @@ class IntegTestRunner {
484
425
  * Perform a integ test case deployment, including
485
426
  * performing the update workflow
486
427
  */
487
- async deploy(deployArgs, updateWorkflowEnabled, testCaseName, allowDeleteFailures, updateFromTags) {
488
- const actualTestCase = (await this.actualTestSuite()).testSuite[testCaseName];
428
+ async deployTestAndAssertions(app, previousVersion, testCase, deployArgs, updateWorkflowEnabled, testCaseName, allowDeleteFailures, updateFromTags) {
489
429
  try {
490
- if (actualTestCase.hooks?.preDeploy) {
491
- actualTestCase.hooks.preDeploy.forEach(cmd => {
430
+ if (testCase.hooks?.preDeploy) {
431
+ testCase.hooks.preDeploy.forEach(cmd => {
492
432
  (0, utils_1.exec)((0, utils_1.chunks)(cmd), {
493
- cwd: path.dirname(this.helper.goldenSnapshotDir),
433
+ cwd: path.dirname(app.outputDirectory),
494
434
  });
495
435
  });
496
436
  }
497
437
  if (updateFromTags && updateFromTags.length > 0) {
498
438
  // Tag-sequence update workflow: deploy each tag's snapshot in order
499
- await this.deployFromTags(deployArgs, testCaseName, updateFromTags, allowDeleteFailures);
439
+ await this.deployFromTags(app, deployArgs, testCaseName, updateFromTags, allowDeleteFailures);
500
440
  }
501
- else if (updateWorkflowEnabled && this.helper.hasSnapshot()) {
441
+ else if (updateWorkflowEnabled && await previousVersion.hasOutput()) {
502
442
  // Normal merge-base update workflow
503
- const expectedTestSuite = await this.helper.expectedTestSuite();
443
+ const expectedTestSuite = await previousVersion.loadExistingSuite();
504
444
  if (expectedTestSuite && testCaseName in expectedTestSuite?.testSuite) {
505
- this.checkoutSnapshot();
445
+ this.checkoutSnapshot(previousVersion);
506
446
  const expectedTestCase = expectedTestSuite.testSuite[testCaseName];
507
- await this.helper.cdk.deploy({
447
+ await previousVersion.deploy({
508
448
  ...deployArgs,
509
449
  stacks: expectedTestCase.stacks,
510
450
  ...expectedTestCase?.cdkCommandOptions?.deploy?.args,
511
- context: this.helper.getContext(expectedTestCase?.cdkCommandOptions?.deploy?.args?.context),
512
- app: path.relative(this.helper.directory, this.helper.goldenSnapshotDir),
513
- lookups: expectedTestSuite?.enableLookups,
451
+ context: expectedTestCase?.cdkCommandOptions?.deploy?.args?.context,
514
452
  });
515
453
  }
516
454
  }
517
455
  // now deploy the "actual" test.
518
456
  // This is the stack update if the update workflow ran above.
519
- const actualDeployResult = await this.helper.cdk.deploy({
457
+ const actualDeployResult = await app.deploy({
520
458
  ...deployArgs,
521
- lookups: (await this.actualTestSuite()).enableLookups,
522
- stacks: [
523
- ...actualTestCase.stacks,
524
- ],
525
- output: path.relative(this.helper.directory, this.helper.temporarySnapshotDir),
526
- ...actualTestCase?.cdkCommandOptions?.deploy?.args,
527
- context: this.helper.getContext(actualTestCase?.cdkCommandOptions?.deploy?.args?.context),
528
- app: this.helper.cdkApp,
459
+ stacks: testCase.stacks,
460
+ ...testCase?.cdkCommandOptions?.deploy?.args,
461
+ context: testCase?.cdkCommandOptions?.deploy?.args?.context,
529
462
  });
530
463
  if (actualDeployResult.deleteFailures.length > 0) {
531
464
  const details = actualDeployResult.deleteFailures
@@ -546,34 +479,31 @@ class IntegTestRunner {
546
479
  // set `rollback: false`. This allows the assertion stack to deploy all the
547
480
  // assertions instead of failing at the first failed assertion
548
481
  // combining it with the above deployment would prevent any replacement updates
549
- if (actualTestCase.assertionStack) {
550
- await this.helper.cdk.deploy({
482
+ if (testCase.assertionStack) {
483
+ await app.deploy({
551
484
  ...deployArgs,
552
- lookups: (await this.actualTestSuite()).enableLookups,
553
485
  stacks: [
554
- actualTestCase.assertionStack,
486
+ testCase.assertionStack,
555
487
  ],
556
488
  rollback: false,
557
- output: path.relative(this.helper.directory, this.helper.temporarySnapshotDir),
558
- ...actualTestCase?.cdkCommandOptions?.deploy?.args,
559
- outputsFile: path.relative(this.helper.directory, path.join(this.helper.temporarySnapshotDir, 'assertion-results.json')),
560
- context: this.helper.getContext(actualTestCase?.cdkCommandOptions?.deploy?.args?.context),
561
- app: this.helper.cdkApp,
489
+ ...testCase?.cdkCommandOptions?.deploy?.args,
490
+ outputsFile: path.join(app.outputDirectory, 'assertion-results.json'),
491
+ context: testCase?.cdkCommandOptions?.deploy?.args?.context,
562
492
  });
563
493
  }
564
- if (actualTestCase.hooks?.postDeploy) {
565
- actualTestCase.hooks.postDeploy.forEach(cmd => {
494
+ if (testCase.hooks?.postDeploy) {
495
+ testCase.hooks.postDeploy.forEach(cmd => {
566
496
  (0, utils_1.exec)((0, utils_1.chunks)(cmd), {
567
- cwd: path.dirname(this.helper.goldenSnapshotDir),
497
+ cwd: path.dirname(app.outputDirectory),
568
498
  });
569
499
  });
570
500
  }
571
- if (actualTestCase.assertionStack && actualTestCase.assertionStackName) {
572
- return this.processAssertionResults(path.join(this.helper.temporarySnapshotDir, 'assertion-results.json'), actualTestCase.assertionStackName, actualTestCase.assertionStack);
501
+ if (testCase.assertionStack && testCase.assertionStackName) {
502
+ return this.processAssertionResults(path.join(app.outputDirectory, 'assertion-results.json'), testCase.assertionStackName, testCase.assertionStack);
573
503
  }
574
504
  }
575
505
  catch (e) {
576
- this.parseError(e, actualTestCase.cdkCommandOptions?.deploy?.expectError ?? false, actualTestCase.cdkCommandOptions?.deploy?.expectedMessage);
506
+ this.parseError(e, testCase.cdkCommandOptions?.deploy?.expectError ?? false, testCase.cdkCommandOptions?.deploy?.expectedMessage);
577
507
  }
578
508
  return;
579
509
  }
@@ -632,4 +562,11 @@ class IntegTestRunner {
632
562
  }
633
563
  }
634
564
  exports.IntegTestRunner = IntegTestRunner;
635
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZWctdGVzdC1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbnRlZy10ZXN0LXJ1bm5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFFN0IsMEVBQWlFO0FBQ2pFLG1EQUFxQztBQUNyQyxvREFBNkQ7QUFDN0QsNkNBQStCO0FBQy9CLHVEQUF5QztBQUV6Qyx5REFBb0Q7QUFFcEQsa0RBQW9DO0FBQ3BDLG9DQUErRjtBQUUvRiw4Q0FBMEY7QUFFMUY7Ozs7R0FJRztBQUNILE1BQU0sV0FBVyxHQUFHLENBQUMsbUJBQU0sQ0FBQyxHQUFHLEVBQUUsbUJBQU0sQ0FBQyxNQUFNLENBQVUsQ0FBQztBQUd6RDs7R0FFRztBQUNILFNBQVMsV0FBVyxDQUFDLEtBQWdCO0lBQ25DLE9BQVEsV0FBaUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDNUQsQ0FBQztBQXdGRDs7O0dBR0c7QUFDSCxNQUFhLGVBQWU7SUFDVCxNQUFNLENBQWlCO0lBQ3hDLFlBQVksT0FBOEIsRUFBRSxrQkFBd0M7UUFDbEYsSUFBSSxDQUFDLE1BQU0sR0FBRyxpQ0FBYyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixHQUFHLGtCQUFrQixDQUFDO1FBRXJELHFGQUFxRjtRQUNyRixvREFBb0Q7UUFDcEQsaUZBQWlGO1FBQ2pGLHVGQUF1RjtRQUN2Rix1RkFBdUY7UUFDdkYsRUFBRTtRQUNGLHVFQUF1RTtRQUN2RSx3RUFBd0U7UUFDeEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyw0QkFBNEIsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFXLFFBQVE7UUFDakIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztJQUM5QixDQUFDO0lBRUQ7O09B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ZSxDQUFDLEVBQUUsQ0FBQztvQkFDcEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNaLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLENBQUMsQ0FBQztRQUNWLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUF0b0JELDBDQXNvQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHR5cGUgeyBEZXN0cm95T3B0aW9ucywgVGVzdENhc2UgfSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnO1xuaW1wb3J0IHsgUmVxdWlyZUFwcHJvdmFsIH0gZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCAqIGFzIGNob2tpZGFyIGZyb20gJ2Nob2tpZGFyJztcbmltcG9ydCB7IHR5cGUgRXZlbnROYW1lLCBFVkVOVFMgfSBmcm9tICdjaG9raWRhci9oYW5kbGVyLmpzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCAqIGFzIHdvcmtlcnBvb2wgZnJvbSAnd29ya2VycG9vbCc7XG5pbXBvcnQgdHlwZSB7IENka0ludGVnSGVscGVyT3B0aW9ucyB9IGZyb20gJy4vY2RrLWludGVnLWhlbHBlcic7XG5pbXBvcnQgeyBDZGtJbnRlZ0hlbHBlciB9IGZyb20gJy4vY2RrLWludGVnLWhlbHBlcic7XG5pbXBvcnQgdHlwZSAqIGFzIGNkayBmcm9tICcuLi9lbmdpbmVzL2Nkay1pbnRlcmZhY2UnO1xuaW1wb3J0ICogYXMgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBjaHVua3MsIGV4ZWMsIGV4ZWNXaXRoU3ViU2hlbGwsIHByb21pc2VXaXRoUmVzb2x2ZXJzLCByZW5kZXJDb21tYW5kIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHR5cGUgeyBEZXN0cnVjdGl2ZUNoYW5nZSwgQXNzZXJ0aW9uUmVzdWx0cywgQXNzZXJ0aW9uUmVzdWx0IH0gZnJvbSAnLi4vd29ya2Vycy9jb21tb24nO1xuaW1wb3J0IHsgRGlhZ25vc3RpY1JlYXNvbiwgZm9ybWF0QXNzZXJ0aW9uUmVzdWx0cywgZm9ybWF0RXJyb3IgfSBmcm9tICcuLi93b3JrZXJzL2NvbW1vbic7XG5cbi8qKlxuICogRmlsZSBldmVudHMgdGhhdCB3ZSBjYXJlIGFib3V0IGZyb20gY2hva2lkYXIuXG4gKiBJbiBjaG9raWRhciB2NCwgRXZlbnROYW1lIGluY2x1ZGVzIGFkZGl0aW9uYWwgZXZlbnRzIGxpa2UgJ2Vycm9yJywgJ3JhdycsICdyZWFkeScsICdhbGwnXG4gKiB0aGF0IHdlIG5lZWQgdG8gZmlsdGVyIG91dCBpbiB0aGUgJ2FsbCcgaGFuZGxlci5cbiAqL1xuY29uc3QgRklMRV9FVkVOVFMgPSBbRVZFTlRTLkFERCwgRVZFTlRTLkNIQU5HRV0gYXMgY29uc3Q7XG50eXBlIEZpbGVFdmVudCA9IHR5cGVvZiBGSUxFX0VWRU5UU1tudW1iZXJdO1xuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYW4gZXZlbnQgaXMgYSBmaWxlIGV2ZW50IHdlIHNob3VsZCBwcm9jZXNzLlxuICovXG5mdW5jdGlvbiBpc0ZpbGVFdmVudChldmVudDogRXZlbnROYW1lKTogZXZlbnQgaXMgRmlsZUV2ZW50IHtcbiAgcmV0dXJuIChGSUxFX0VWRU5UUyBhcyByZWFkb25seSBzdHJpbmdbXSkuaW5jbHVkZXMoZXZlbnQpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbW1vbk9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIHRlc3QgY2FzZVxuICAgKi9cbiAgcmVhZG9ubHkgdGVzdENhc2VOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBsZXZlbCBvZiB2ZXJib3NpdHkgZm9yIGxvZ2dpbmcuXG4gICAqXG4gICAqIEBkZWZhdWx0IDBcbiAgICovXG4gIHJlYWRvbmx5IHZlcmJvc2l0eT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXYXRjaE9wdGlvbnMgZXh0ZW5kcyBDb21tb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIEFSTiBvZiB0aGUgSUFNIHJvbGUgZm9yIENsb3VkRm9ybWF0aW9uIHRvIGFzc3VtZSBkdXJpbmcgZGVwbG95L2Rlc3Ryb3lcbiAgICpcbiAgICogQGRlZmF1bHQgLSB1c2UgdGhlIGJvb3RzdHJhcCBjZm4tZXhlYyByb2xlXG4gICAqL1xuICByZWFkb25seSByb2xlQXJuPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSBpbnRlZ3JhdGlvbiB0ZXN0IHJ1bm5lclxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJ1bk9wdGlvbnMgZXh0ZW5kcyBDb21tb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IHRvIHJ1biBgY2RrIGRlc3Ryb3lgIGFuZCBjbGVhbnVwIHRoZVxuICAgKiBpbnRlZ3JhdGlvbiB0ZXN0IHN0YWNrcy5cbiAgICpcbiAgICogU2V0IHRoaXMgdG8gZmFsc2UgaWYgeW91IG5lZWQgdG8gcGVyZm9ybSBhbnkgdmFsaWRhdGlvblxuICAgKiBvciB0cm91Ymxlc2hvb3RpbmcgYWZ0ZXIgZGVwbG95bWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgY2xlYW4/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gdHJ1ZSwgdGhlIGludGVncmF0aW9uIHRlc3Qgd2lsbCBub3QgZGVwbG95XG4gICAqIGFueXRoaW5nIGFuZCB3aWxsIHNpbXBseSB1cGRhdGUgdGhlIHNuYXBzaG90LlxuICAgKlxuICAgKiBZb3Ugc2hvdWxkIE5PVCB1c2UgdGhpcyBtZXRob2Qgc2luY2UgeW91IGFyZSBlc3NlbnRpYWxseVxuICAgKiBieXBhc3NpbmcgdGhlIGludGVncmF0aW9uIHRlc3QuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBkcnlSdW4/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJZiB0aGlzIGlzIHNldCB0byBmYWxzZSB0aGVuIHRoZSBzdGFjayB1cGRhdGUgd29ya2Zsb3cgd2lsbFxuICAgKiBub3QgYmUgcnVuXG4gICAqXG4gICAqIFRoZSB1cGRhdGUgd29ya2Zsb3cgZXhpc3RzIHRvIGNoZWNrIGZvciBjYXNlcyB3aGVyZSBhIGNoYW5nZSB3b3VsZCBjYXVzZVxuICAgKiBhIGZhaWx1cmUgdG8gYW4gZXhpc3Rpbmcgc3RhY2ssIGJ1dCBub3QgZm9yIGEgbmV3bHkgY3JlYXRlZCBzdGFjay5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgdXBkYXRlV29ya2Zsb3c/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGdpdCB0YWdzIHRvIGRlcGxveSBpbiBzZXF1ZW5jZSBiZWZvcmUgZGVwbG95aW5nIHRoZSBjdXJyZW50IGNvZGUuXG4gICAqIFdoZW4gcHJvdmlkZWQsIHJlcGxhY2VzIHRoZSBub3JtYWwgbWVyZ2UtYmFzZSB1cGRhdGUgd29ya2Zsb3cuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdXNlIHRoZSBub3JtYWwgdXBkYXRlIHdvcmtmbG93XG4gICAqL1xuICByZWFkb25seSB1cGRhdGVGcm9tVGFncz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBBUk4gb2YgdGhlIElBTSByb2xlIGZvciBDbG91ZEZvcm1hdGlvbiB0byBhc3N1bWUgZHVyaW5nIGRlcGxveS9kZXN0cm95XG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdXNlIHRoZSBib290c3RyYXAgY2ZuLWV4ZWMgcm9sZVxuICAgKi9cbiAgcmVhZG9ubHkgcm9sZUFybj86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0byBhbGxvdyByZXNvdXJjZXMgdGhhdCBmYWlsIHRvIGRlbGV0ZSBkdXJpbmcgYSBzdGFjayB1cGRhdGUuXG4gICAqXG4gICAqIFdoZW4gZmFsc2UsIHRoZSB0ZXN0IHdpbGwgZmFpbCBpZiBDbG91ZEZvcm1hdGlvbiBza2lwcyBkZWxldGluZyBhIHJlc291cmNlXG4gICAqIGR1cmluZyBhIHN0YWNrIHVwZGF0ZS4gV2hlbiB0cnVlLCBvbmx5IGEgd2FybmluZyBpcyBwcmludGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgYWxsb3dEZWxldGVGYWlsdXJlcz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQW4gaW50ZWdyYXRpb24gdGVzdCBydW5uZXIgdGhhdCBvcmNoZXN0cmF0ZXMgZXhlY3V0aW5nXG4gKiBpbnRlZ3JhdGlvbiB0ZXN0c1xuICovXG5leHBvcnQgY2xhc3MgSW50ZWdUZXN0UnVubmVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBoZWxwZXI6IENka0ludGVnSGVscGVyO1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBDZGtJbnRlZ0hlbHBlck9wdGlvbnMsIGRlc3RydWN0aXZlQ2hhbmdlcz86IERlc3RydWN0aXZlQ2hhbmdlW10pIHtcbiAgICB0aGlzLmhlbHBlciA9IENka0ludGVnSGVscGVyLmNyZWF0ZShvcHRpb25zKTtcbiAgICB0aGlzLmhlbHBlci5fZGVzdHJ1Y3RpdmVDaGFuZ2VzID0gZGVzdHJ1Y3RpdmVDaGFuZ2VzO1xuXG4gICAgLy8gV2UgbmVlZCB0byBoYXZlIGdpdmVuIHRoaXMgYSB2YWx1ZSwgYnV0IHdlIGRvbid0IGFjdHVhbGx5IGNhcmUgYWJvdXQgaXQgaW5pdGlhbGx5LFxuICAgIC8vIGJlY2F1c2Ugd2Ugb25seSBzeW50aCB0byBnZXQgdGhlIHRlc3QgZGVmaW5pdGlvbi5cbiAgICAvLyBGSVhNRTogVGhpcyBpcyB1bmZvcnR1bmF0ZSAtLSBpbiBvcmRlciB0byBzdGFydCBydW5uaW5nIHRoZSB0ZXN0IFwiZm9yIHJlYWxcIiB3ZVxuICAgIC8vIGFscmVhZHkgaGF2ZSBjcmVhdGVkIGEgcmVhbCBzbmFwc2hvdCB3aXRoIHRoZSByZWFsIHRlc3QgZGVmaW5pdGlvbiwgYnV0IHdlJ3ZlIHRocm93blxuICAgIC8vIHRoYXQgYXdheSBhbHJlYWR5LiBTbyB3ZSBuZWVkIHRvIHN5bnRoIGFnYWluIGp1c3QgdG8gZ2V0IHRoZSB0ZXN0IGRlZmluaXRpb24sIEFHQUlOLlxuICAgIC8vXG4gICAgLy8gV2Ugd2lsbCByZXdyaXRlIHRoaXMgbGF0ZXIgd2hlbiBpdCBjb21lcyB0aW1lIHRvIGdlbmVyYXRlIHRoZSBhY3R1YWxcbiAgICAvLyBnb2xkZW4gc25hcHNob3QsIHRvIG1hdGNoIHRoZSByZXF1ZXN0ZWQgdmFsdWUgaW4gdGhlIHRlc3QgZGVmaW5pdGlvbi5cbiAgICB0aGlzLmhlbHBlci5jb25maWd1cmVMZWdhY3lFbmFibGVMb29rdXBzKCdkb250LWNhcmUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wYXRpYmlsaXR5IHNoaW0gd2l0aCBvbGQgQVBJXG4gICAqL1xuICBwdWJsaWMgZ2V0IHRlc3ROYW1lKCkge1xuICAgIHJldHVybiB0aGlzLmhlbHBlci50ZXN0TmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wYXRpYmlsaXR5IHNoaW0gd2l0aCBvbGQgQVBJXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGFjdHVhbFRlc3RTdWl0ZSgpIHtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuaGVscGVyLmFjdHVhbFNuYXBzaG90KCkpLnRlc3REZWZpbml0aW9uO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGFjdHVhbFRlc3RzKCk6IFByb21pc2U8eyBbdGVzdE5hbWU6IHN0cmluZ106IFRlc3RDYXNlIH0gfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBhY3R1YWxUZXN0U3VpdGUgPSBhd2FpdCB0aGlzLmFjdHVhbFRlc3RTdWl0ZSgpO1xuICAgIC8vIFdlIGRvbid0IHdhbnQgbmV3IHRlc3RzIHdyaXR0ZW4gaW4gdGhlIGxlZ2FjeSBtb2RlLlxuICAgIC8vIElmIHRoZXJlIGlzIG5vIGV4aXN0aW5nIHNuYXBzaG90IF9hbmRfIHRoaXMgaXMgYSBsZWdhY3lcbiAgICAvLyB0ZXN0IHRoZW4gcG9pbnQgdGhlIHVzZXIgdG8gdGhlIG5ldyBgSW50ZWdUZXN0YCBjb25zdHJ1Y3RcbiAgICBpZiAoIXRoaXMuaGVscGVyLmhhc1NuYXBzaG90KCkgJiYgYWN0dWFsVGVzdFN1aXRlLnR5cGUgPT09ICdsZWdhY3ktdGVzdC1zdWl0ZScpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmhlbHBlci50ZXN0TmFtZX0gaXMgYSBuZXcgdGVzdC4gUGxlYXNlIHVzZSB0aGUgSW50ZWdUZXN0IGNvbnN0cnVjdCBgICtcbiAgICAgICAgJ3RvIGNvbmZpZ3VyZSB0aGUgdGVzdFxcbicgK1xuICAgICAgICAnaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL3RyZWUvbWFpbi9wYWNrYWdlcy8lNDBhd3MtY2RrL2ludGVnLXRlc3RzLWFscGhhJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFjdHVhbFRlc3RTdWl0ZS50ZXN0U3VpdGU7XG4gIH1cblxuICBwdWJsaWMgY3JlYXRlQ2RrQ29udGV4dEpzb24oKTogdm9pZCB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHRoaXMuaGVscGVyLmNka0NvbnRleHRQYXRoKSkge1xuICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLmhlbHBlci5jZGtDb250ZXh0UGF0aCwgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICB3YXRjaDogeyB9LFxuICAgICAgfSwgdW5kZWZpbmVkLCAyKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrb3V0IHRoZSBzbmFwc2hvdCBkaXJlY3RvcnkgYXQgYSBzcGVjaWZpYyBnaXQgcmVmICh0YWcsIGNvbW1pdCwgYnJhbmNoKS5cbiAgICogRmFpbHMgZmFzdCBpZiB0aGUgc25hcHNob3QgZG9lcyBub3QgZXhpc3QgYXQgdGhlIGdpdmVuIHJlZi5cbiAgICovXG4gIHByaXZhdGUgY2hlY2tvdXRTbmFwc2hvdEF0UmVmKHJlZjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZ2l0Q3dkID0gcGF0aC5kaXJuYW1lKHRoaXMuaGVscGVyLmdvbGRlblNuYXBzaG90RGlyKTtcbiAgICBjb25zdCBnaXQgPSBbJ2dpdCcsICctQycsIGdpdEN3ZF07XG4gICAgY29uc3QgcmVsYXRpdmVTbmFwc2hvdERpciA9IHBhdGgucmVsYXRpdmUoZ2l0Q3dkLCB0aGlzLmhlbHBlci5nb2xkZW5TbmFwc2hvdERpcik7XG5cbiAgICB0cnkge1xuICAgICAgZXhlYyhbLi4uZ2l0LCAnY2hlY2tvdXQnLCByZWYsICctLScsIHJlbGF0aXZlU25hcHNob3REaXJdKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBTbmFwc2hvdCBkb2VzIG5vdCBleGlzdCBhdCB0YWcgJyR7cmVmfScuIGAgK1xuICAgICAgICBgUGF0aDogJHtyZWxhdGl2ZVNuYXBzaG90RGlyfVxcbmAgK1xuICAgICAgICBgVW5kZXJseWluZyBlcnJvcjogJHtmb3JtYXRFcnJvcihlKX1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVwbG95IHRoZSBzbmFwc2hvdCBmcm9tIGVhY2ggZ2l0IHRhZyBpbiBzZXF1ZW5jZSwgdGhlbiBsZXQgdGhlIGNhbGxlclxuICAgKiBkZXBsb3kgdGhlIGN1cnJlbnQgY29kZSBhcyB0aGUgZmluYWwgdXBkYXRlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBkZXBsb3lGcm9tVGFncyhcbiAgICBkZXBsb3lBcmdzOiBjZGsuRGVwbG95T3B0aW9ucyxcbiAgICB0ZXN0Q2FzZU5hbWU6IHN0cmluZyxcbiAgICB0YWdzOiBzdHJpbmdbXSxcbiAgICBhbGxvd0RlbGV0ZUZhaWx1cmVzOiBib29sZWFuLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0b3RhbFRhZ3MgPSB0YWdzLmxlbmd0aDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdG90YWxUYWdzOyBpKyspIHtcbiAgICAgIGNvbnN0IHRhZyA9IHRhZ3NbaV07XG4gICAgICBsb2dnZXIuaGlnaGxpZ2h0KGAke3RoaXMuaGVscGVyLnRlc3ROYW1lfS8ke3Rlc3RDYXNlTmFtZX06IGRlcGxveWluZyB0YWcgJHt0YWd9ICgke2kgKyAxfS8ke3RvdGFsVGFnc30pYCk7XG5cbiAgICAgIHRoaXMuY2hlY2tvdXRTbmFwc2hvdEF0UmVmKHRhZyk7XG5cbiAgICAgIGNvbnN0IGV4cGVjdGVkVGVzdFN1aXRlID0gYXdhaXQgdGhpcy5oZWxwZXIuZXhwZWN0ZWRUZXN0U3VpdGUoKTtcbiAgICAgIGlmICghZXhwZWN0ZWRUZXN0U3VpdGUgfHwgISh0ZXN0Q2FzZU5hbWUgaW4gZXhwZWN0ZWRUZXN0U3VpdGUudGVzdFN1aXRlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFRlc3QgY2FzZSAnJHt0ZXN0Q2FzZU5hbWV9JyBkb2VzIG5vdCBleGlzdCBpbiBzbmFwc2hvdCBhdCB0YWcgJyR7dGFnfSdgLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBleHBlY3RlZFRlc3RDYXNlID0gZXhwZWN0ZWRUZXN0U3VpdGUudGVzdFN1aXRlW3Rlc3RDYXNlTmFtZV07XG4gICAgICBjb25zdCBkZXBsb3lSZXN1bHQgPSBhd2FpdCB0aGlzLmhlbHBlci5jZGsuZGVwbG95KHtcbiAgICAgICAgLi4uZGVwbG95QXJncyxcbiAgICAgICAgc3RhY2tzOiBleHBlY3RlZFRlc3RDYXNlLnN0YWNrcyxcbiAgICAgICAgLi4uZXhwZWN0ZWRUZXN0Q2FzZT8uY2RrQ29tbWFuZE9wdGlvbnM/LmRlcGxveT8uYXJncyxcbiAgICAgICAgY29udGV4dDogdGhpcy5oZWxwZXIuZ2V0Q29udGV4dChleHBlY3RlZFRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzPy5jb250ZXh0KSxcbiAgICAgICAgYXBwOiBwYXRoLnJlbGF0aXZlKHRoaXMuaGVscGVyLmRpcmVjdG9yeSwgdGhpcy5oZWxwZXIuZ29sZGVuU25hcHNob3REaXIpLFxuICAgICAgICBsb29rdXBzOiBleHBlY3RlZFRlc3RTdWl0ZT8uZW5hYmxlTG9va3VwcyxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoZGVwbG95UmVzdWx0LmRlbGV0ZUZhaWx1cmVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgZGV0YWlscyA9IGRlcGxveVJlc3VsdC5kZWxldGVGYWlsdXJlc1xuICAgICAgICAgIC5tYXAoZiA9PiBgICAtICR7Zi5sb2dpY2FsUmVzb3VyY2VJZH0gKCR7Zi5yZXNvdXJjZVR5cGV9KTogJHtmLnJlYXNvbn1gKVxuICAgICAgICAgIC5qb2luKCdcXG4nKTtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9XG4gICAgICAgICAgYFVwZGF0ZSBmcm9tIHRhZyAnJHt0YWd9JzogJHtkZXBsb3lSZXN1bHQuZGVsZXRlRmFpbHVyZXMubGVuZ3RofSByZXNvdXJjZShzKSBmYWlsZWQgdG8gZGVsZXRlOlxcbiR7ZGV0YWlsc31gO1xuICAgICAgICBpZiAoYWxsb3dEZWxldGVGYWlsdXJlcykge1xuICAgICAgICAgIGxvZ2dlci53YXJuaW5nKG1lc3NhZ2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGxvZ2dlci5oaWdobGlnaHQoYCR7dGhpcy5oZWxwZXIudGVzdE5hbWV9LyR7dGVzdENhc2VOYW1lfTogZGVwbG95aW5nIGN1cnJlbnQgYnJhbmNoIChmaW5hbClgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGVuIHJ1bm5pbmcgaW50ZWdyYXRpb24gdGVzdHMgd2l0aCB0aGUgdXBkYXRlIHBhdGggd29ya2Zsb3dcbiAgICogaXQgaXMgaW1wb3J0YW50IHRoYXQgdGhlIHNuYXBzaG90IHRoYXQgaXMgZGVwbG95ZWQgaXMgdGhlIGN1cnJlbnQgc25hcHNob3RcbiAgICogZnJvbSB0aGUgdXBzdHJlYW0gYnJhbmNoLiBJbiBvcmRlciB0byBndWFyYW50ZWUgdGhhdCwgZmlyc3QgY2hlY2tvdXQgdGhlIGxhdGVzdFxuICAgKiAodG8gdGhlIHVzZXIpIHNuYXBzaG90IGZyb20gdXBzdHJlYW1cbiAgICpcbiAgICogSXQgaXMgbm90IHN0cmFpZ2h0Zm9yd2FyZCB0byBmaWd1cmUgb3V0IHdoYXQgYnJhbmNoIHRoZSBjdXJyZW50XG4gICAqIHdvcmtpbmcgYnJhbmNoIHdhcyBjcmVhdGVkIGZyb20uIFRoaXMgaXMgYSBiZXN0IGVmZm9ydCBhdHRlbXB0IHRvIGRvIHNvLlxuICAgKiBUaGlzIGFzc3VtZXMgdGhhdCB0aGVyZSBpcyBhbiAnb3JpZ2luJy4gYGdpdCByZW1vdGUgc2hvdyBvcmlnaW5gIHJldHVybnMgYSBsaXN0IG9mXG4gICAqIGFsbCBicmFuY2hlcyBhbmQgd2UgdGhlbiBzZWFyY2ggZm9yIG9uZSB0aGF0IHN0YXJ0cyB3aXRoIGBIRUFEIGJyYW5jaDogYFxuICAgKi9cbiAgcHJpdmF0ZSBjaGVja291dFNuYXBzaG90KCk6IHZvaWQge1xuICAgIC8vIFdlIHVzZSB0aGUgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgdGhlIHNuYXBzaG90IHRvIHJ1biBnaXQgY29tbWFuZHMgaW5cbiAgICAvLyBXZSBkb24ndCBjaGFuZ2UgdGhlIGN3ZCBmb3IgZXhlY3V0aW5nIGdpdCwgYnV0IGluc3RlYWQgdXNlIHRoZSAtQyBmbGFnXG4gICAgLy8gQHNlZSBodHRwczovL2dpdC1zY20uY29tL2RvY3MvZ2l0I0RvY3VtZW50YXRpb24vZ2l0LnR4dC0tQ2x0cGF0aGd0XG4gICAgLy8gVGhpcyB3YXkgd2UgYXJlIGd1YXJhbnRlZWQgdG8gb3BlcmF0ZSB1bmRlciB0aGUgY29ycmVjdCBnaXQgcmVwbywgZXZlblxuICAgIC8vIHdoZW4gZXhlY3V0aW5nIGludGVnLXJ1bm5lciBmcm9tIG91dHNpZGUgdGhlIHJlcG8gdW5kZXIgdGVzdC5cbiAgICBjb25zdCBnaXRDd2QgPSBwYXRoLmRpcm5hbWUodGhpcy5oZWxwZXIuZ29sZGVuU25hcHNob3REaXIpO1xuICAgIGNvbnN0IGdpdCA9IFsnZ2l0JywgJy1DJywgZ2l0Q3dkXTtcblxuICAgIC8vIGh0dHBzOi8vZ2l0LXNjbS5jb20vZG9jcy9naXQtbWVyZ2UtYmFzZVxuICAgIGxldCBiYXNlQnJhbmNoOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLy8gdHJ5IHRvIGZpbmQgdGhlIGJhc2UgYnJhbmNoIHRoYXQgdGhlIHdvcmtpbmcgYnJhbmNoIHdhcyBjcmVhdGVkIGZyb21cbiAgICB0cnkge1xuICAgICAgY29uc3Qgb3JpZ2luOiBzdHJpbmcgPSBleGVjKFsuLi5naXQsICdyZW1vdGUnLCAnc2hvdycsICdvcmlnaW4nXSk7XG4gICAgICBjb25zdCBvcmlnaW5MaW5lcyA9IG9yaWdpbi5zcGxpdCgnXFxuJyk7XG4gICAgICBmb3IgKGNvbnN0IGxpbmUgb2Ygb3JpZ2luTGluZXMpIHtcbiAgICAgICAgaWYgKGxpbmUudHJpbSgpLnN0YXJ0c1dpdGgoJ0hFQUQgYnJhbmNoOiAnKSkge1xuICAgICAgICAgIGJhc2VCcmFuY2ggPSBsaW5lLnRyaW0oKS5zcGxpdCgnSEVBRCBicmFuY2g6ICcpWzFdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nZ2VyLndhcm5pbmcoJyVzXFxuJXMnLFxuICAgICAgICAnQ291bGQgbm90IGRldGVybWluZSBnaXQgb3JpZ2luIGJyYW5jaC4nLFxuICAgICAgICBgWW91IG5lZWQgdG8gbWFudWFsbHkgY2hlY2tvdXQgdGhlIHNuYXBzaG90IGRpcmVjdG9yeSAke3RoaXMuaGVscGVyLmdvbGRlblNuYXBzaG90RGlyfWAgK1xuICAgICAgICAnZnJvbSB0aGUgbWVyZ2UtYmFzZSAoaHR0cHM6Ly9naXQtc2NtLmNvbS9kb2NzL2dpdC1tZXJnZS1iYXNlKScsXG4gICAgICApO1xuICAgICAgbG9nZ2VyLndhcm5pbmcoJ2Vycm9yOiAlcycsIGZvcm1hdEVycm9yKGUpKTtcbiAgICB9XG5cbiAgICAvLyBpZiB3ZSBmb3VuZCB0aGUgYmFzZSBicmFuY2ggdGhlbiBnZXQgdGhlIG1lcmdlLWJhc2UgKG1vc3QgcmVjZW50IGNvbW1vbiBjb21taXQpXG4gICAgLy8gYW5kIGNoZWNrb3V0IHRoZSBzbmFwc2hvdCB1c2luZyB0aGF0IGNvbW1pdFxuICAgIGlmIChiYXNlQnJhbmNoKSB7XG4gICAgICBjb25zdCByZWxhdGl2ZVNuYXBzaG90RGlyID0gcGF0aC5yZWxhdGl2ZShnaXRDd2QsIHRoaXMuaGVscGVyLmdvbGRlblNuYXBzaG90RGlyKTtcblxuICAgICAgY29uc3QgY2hlY2tvdXRDb21tYW5kID0gWy4uLmdpdCwgJ2NoZWNrb3V0JywgWy4uLmdpdCwgJ21lcmdlLWJhc2UnLCAnSEVBRCcsIGJhc2VCcmFuY2hdLCAnLS0nLCByZWxhdGl2ZVNuYXBzaG90RGlyXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGV4ZWNXaXRoU3ViU2hlbGwoY2hlY2tvdXRDb21tYW5kKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbG9nZ2VyLndhcm5pbmcoJyVzXFxuJXMnLFxuICAgICAgICAgIGBDb3VsZCBub3QgY2hlY2tvdXQgc25hcHNob3QgZGlyZWN0b3J5ICcke3RoaXMuaGVscGVyLmdvbGRlblNuYXBzaG90RGlyfScuIFBsZWFzZSB2ZXJpZnkgdGhlIGZvbGxvd2luZyBjb21tYW5kIGNvbXBsZXRlcyBjb3JyZWN0bHk6YCxcbiAgICAgICAgICByZW5kZXJDb21tYW5kKGNoZWNrb3V0Q29tbWFuZCksXG4gICAgICAgICAgJycsXG4gICAgICAgICk7XG4gICAgICAgIGxvZ2dlci53YXJuaW5nKCdlcnJvcjogJXMnLCBmb3JtYXRFcnJvcihlKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY2RrIGRlcGxveSAtLXdhdGNoIGZvciBhbiBpbnRlZ3JhdGlvbiB0ZXN0XG4gICAqXG4gICAqIFRoaXMgaXMgbWVhbnQgdG8gYmUgcnVuIG9uIGEgc2luZ2xlIHRlc3QgYW5kIHdpbGwgbm90IGNyZWF0ZSBhIHNuYXBzaG90XG4gICAqL1xuICBwdWJsaWMgYXN5bmMgd2F0Y2hJbnRlZ1Rlc3Qob3B0aW9uczogV2F0Y2hPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYWN0dWFsVGVzdFN1aXRlID0gYXdhaXQgdGhpcy5hY3R1YWxUZXN0U3VpdGUoKTtcbiAgICBjb25zdCBhY3R1YWxUZXN0Q2FzZSA9IGFjdHVhbFRlc3RTdWl0ZS50ZXN0U3VpdGVbb3B0aW9ucy50ZXN0Q2FzZU5hbWVdO1xuICAgIGlmICghYWN0dWFsVGVzdENhc2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRGlkIG5vdCBmaW5kIHRlc3QgY2FzZSBuYW1lICcke29wdGlvbnMudGVzdENhc2VOYW1lfScgaW4gJyR7T2JqZWN0LmtleXMoYWN0dWFsVGVzdFN1aXRlLnRlc3RTdWl0ZSl9J2ApO1xuICAgIH1cbiAgICBjb25zdCBlbmFibGVGb3JWZXJib3NpdHlMZXZlbCA9IChuZWVkZWQgPSAxKSA9PiB7XG4gICAgICBjb25zdCB2ZXJib3NpdHkgPSBvcHRpb25zLnZlcmJvc2l0eSA/PyAwO1xuICAgICAgcmV0dXJuICh2ZXJib3NpdHkgPj0gbmVlZGVkKSA/IHRydWUgOiB1bmRlZmluZWQ7XG4gICAgfTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy53YXRjaChcbiAgICAgICAge1xuICAgICAgICAgIC4uLnRoaXMuaGVscGVyLmRlZmF1bHRBcmdzLFxuICAgICAgICAgIGRlcGxveW1lbnRNZXRob2Q6IHtcbiAgICAgICAgICAgIG1ldGhvZDogJ2hvdHN3YXAnLFxuICAgICAgICAgICAgZmFsbGJhY2s6IHtcbiAgICAgICAgICAgICAgbWV0aG9kOiAnY2hhbmdlLXNldCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJvZmlsZTogdGhpcy5oZWxwZXIucHJvZmlsZSxcbiAgICAgICAgICByZXF1aXJlQXBwcm92YWw6IFJlcXVpcmVBcHByb3ZhbC5ORVZFUixcbiAgICAgICAgICB0cmFjZUxvZ3M6IGVuYWJsZUZvclZlcmJvc2l0eUxldmVsKDIpID8/IGZhbHNlLFxuICAgICAgICAgIHZlcmJvc2U6IGVuYWJsZUZvclZlcmJvc2l0eUxldmVsKDMpLFxuICAgICAgICAgIGRlYnVnOiBlbmFibGVGb3JWZXJib3NpdHlMZXZlbCg0KSxcbiAgICAgICAgICByb2xlQXJuOiBvcHRpb25zLnJvbGVBcm4sXG4gICAgICAgIH0sXG4gICAgICAgIG9wdGlvbnMudGVzdENhc2VOYW1lLFxuICAgICAgICBvcHRpb25zLnZlcmJvc2l0eSA/PyAwLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBPcmNoZXN0cmF0ZXMgcnVubmluZyBpbnRlZ3JhdGlvbiB0ZXN0cy4gQ3VycmVudGx5IHRoaXMgaW5jbHVkZXNcbiAgICpcbiAgICogMS4gKGlmIHVwZGF0ZSB3b3JrZmxvdyBpcyBlbmFibGVkKSBEZXBsb3lpbmcgdGhlIHNuYXBzaG90IHRlc3Qgc3RhY2tzXG4gICAqIDIuIERlcGxveWluZyB0aGUgaW50ZWdyYXRpb24gdGVzdCBzdGFja3NcbiAgICogMi4gU2F2aW5nIHRoZSBzbmFwc2hvdCAoaWYgc3VjY2Vzc2Z1bClcbiAgICogMy4gRGVzdHJveWluZyB0aGUgaW50ZWdyYXRpb24gdGVzdCBzdGFja3MgKGlmIGNsZWFuPWZhbHNlKVxuICAgKlxuICAgKiBUaGUgdXBkYXRlIHdvcmtmbG93IGV4aXN0cyB0byBjaGVjayBmb3IgY2FzZXMgd2hlcmUgYSBjaGFuZ2Ugd291bGQgY2F1c2VcbiAgICogYSBmYWlsdXJlIHRvIGFuIGV4aXN0aW5nIHN0YWNrLCBidXQgbm90IGZvciBhIG5ld2x5IGNyZWF0ZWQgc3RhY2suXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcnVuSW50ZWdUZXN0Q2FzZShvcHRpb25zOiBSdW5PcHRpb25zKTogUHJvbWlzZTxBc3NlcnRpb25SZXN1bHRzIHwgdW5kZWZpbmVkPiB7XG4gICAgbGV0IGFzc2VydGlvblJlc3VsdHM6IEFzc2VydGlvblJlc3VsdHMgfCB1bmRlZmluZWQ7XG4gICAgY29uc3QgYWN0dWFsVGVzdFN1aXRlID0gYXdhaXQgdGhpcy5hY3R1YWxUZXN0U3VpdGUoKTtcbiAgICBjb25zdCBhY3R1YWxUZXN0Q2FzZSA9IGFjdHVhbFRlc3RTdWl0ZS50ZXN0U3VpdGVbb3B0aW9ucy50ZXN0Q2FzZU5hbWVdO1xuICAgIGlmICghYWN0dWFsVGVzdENhc2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRGlkIG5vdCBmaW5kIHRlc3QgY2FzZSBuYW1lICcke29wdGlvbnMudGVzdENhc2VOYW1lfScgaW4gJyR7T2JqZWN0LmtleXMoYWN0dWFsVGVzdFN1aXRlLnRlc3RTdWl0ZSl9J2ApO1xuICAgIH1cblxuICAgIC8vIElkZWFsbHkgd2Ugd291bGQgZm9yY2UgYGVuYWJsZUxvb2t1cHNgIHRvIGB0cnVlYCwgYWx3YXlzLCBiZWNhdXNlIHRoYXQncyB3aGF0IHdlIHdvdWxkIGxpa2UgdG8gY29udmVyZ2Ugb24gZm9yIHRoZSBzbmFwc2hvdHMuXG4gICAgLy9cbiAgICAvLyBIT1dFVkVSIVxuICAgIC8vXG4gICAgLy8gSW4gb3JkZXIgdG8gZG8gdGhhdCwgdG8gdmFsaWRhdGUgdGhlIHNuYXBzaG90IGNvcnJlY3RseSB3ZSBuZWVkIHRvIG1hdGNoIHdoYXQncyBpbiBgaW50ZWcuanNvbmAuIEluIG9yZGVyIHRvIHJhdGNoZXRcbiAgICAvLyB0aGF0IHZhbHVlIHRvIGB0cnVlYCwgd2Ugd291bGQgbmVlZCB0byByZXdyaXRlIGBpbnRlZy5qc29uYCB0byBoYXZlIGBlbmFibGVMb29rdXBzOiB0cnVlYC4gV2UgZG9uJ3QgY3VycmVudGx5XG4gICAgLy8gaGF2ZSBjb2RlIHRvIHJlbGlhYmx5IHJld3JpdGUgdGhhdCBmaWxlLCBzbyB3ZSBqdXN0IGxlYXZlIHRoZSB2YWx1ZSBhdCB3aGF0ZXZlciB0aGUgdGVzdCByZXF1ZXN0ZWQuXG4gICAgdGhpcy5oZWxwZXIuY29uZmlndXJlTGVnYWN5RW5hYmxlTG9va3VwcyhhY3R1YWxUZXN0U3VpdGUuZW5hYmxlTG9va3VwcyA/PyBmYWxzZSk7XG5cbiAgICBjb25zdCBjbGVhbiA9IG9wdGlvbnMuY2xlYW4gPz8gdHJ1ZTtcbiAgICBjb25zdCB1cGRhdGVXb3JrZmxvd0VuYWJsZWQgPSAob3B0aW9ucy51cGRhdGVXb3JrZmxvdyA/PyB0cnVlKVxuICAgICAgJiYgKGFjdHVhbFRlc3RDYXNlLnN0YWNrVXBkYXRlV29ya2Zsb3cgPz8gdHJ1ZSk7XG4gICAgY29uc3QgYWxsb3dEZWxldGVGYWlsdXJlcyA9IGFjdHVhbFRlc3RDYXNlLmFsbG93RGVsZXRlRmFpbHVyZXMgPz8gb3B0aW9ucy5hbGxvd0RlbGV0ZUZhaWx1cmVzID8/IGZhbHNlO1xuICAgIGNvbnN0IGVuYWJsZUZvclZlcmJvc2l0eUxldmVsID0gKG5lZWRlZCA9IDEpID0+IHtcbiAgICAgIGNvbnN0IHZlcmJvc2l0eSA9IG9wdGlvbnMudmVyYm9zaXR5ID8/IDA7XG4gICAgICByZXR1cm4gKHZlcmJvc2l0eSA+PSBuZWVkZWQpID8gdHJ1ZSA6IHVuZGVmaW5lZDtcbiAgICB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIGlmICghb3B0aW9ucy5kcnlSdW4gJiYgKGFjdHVhbFRlc3RDYXNlLmNka0NvbW1hbmRPcHRpb25zPy5kZXBsb3k/LmVuYWJsZWQgPz8gdHJ1ZSkpIHtcbiAgICAgICAgYXNzZXJ0aW9uUmVzdWx0cyA9IGF3YWl0IHRoaXMuZGVwbG95KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnRoaXMuaGVscGVyLmRlZmF1bHRBcmdzLFxuICAgICAgICAgICAgcHJvZmlsZTogdGhpcy5oZWxwZXIucHJvZmlsZSxcbiAgICAgICAgICAgIHJlcXVpcmVBcHByb3ZhbDogUmVxdWlyZUFwcHJvdmFsLk5FVkVSLFxuICAgICAgICAgICAgdmVyYm9zZTogZW5hYmxlRm9yVmVyYm9zaXR5TGV2ZWwoMyksXG4gICAgICAgICAgICBkZWJ1ZzogZW5hYmxlRm9yVmVyYm9zaXR5TGV2ZWwoNCksXG4gICAgICAgICAgICByb2xlQXJuOiBvcHRpb25zLnJvbGVBcm4sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB1cGRhdGVXb3JrZmxvd0VuYWJsZWQsXG4gICAgICAgICAgb3B0aW9ucy50ZXN0Q2FzZU5hbWUsXG4gICAgICAgICAgYWxsb3dEZWxldGVGYWlsdXJlcyxcbiAgICAgICAgICBvcHRpb25zLnVwZGF0ZUZyb21UYWdzLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBvbmx5IGNyZWF0ZSB0aGUgc25hcHNob3QgaWYgdGhlcmUgYXJlIG5vIGZhaWxlZCBhc3NlcnRpb24gcmVzdWx0c1xuICAgICAgLy8gKGkuZS4gbm8gZmFpbHVyZXMpXG4gICAgICBpZiAoIU9iamVjdC52YWx1ZXMoYXNzZXJ0aW9uUmVzdWx0cyA/PyB7fSkuc29tZShyZXN1bHQgPT4gcmVzdWx0LnN0YXR1cyA9PT0gJ2ZhaWwnKSkge1xuICAgICAgICBhd2FpdCB0aGlzLmhlbHBlci5jcmVhdGVTbmFwc2hvdCgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IGU7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmICghb3B0aW9ucy5kcnlSdW4pIHtcbiAgICAgICAgaWYgKGNsZWFuICYmIChhY3R1YWxUZXN0Q2FzZS5jZGtDb21tYW5kT3B0aW9ucz8uZGVzdHJveT8uZW5hYmxlZCA/PyB0cnVlKSkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuZGVzdHJveShvcHRpb25zLnRlc3RDYXNlTmFtZSwge1xuICAgICAgICAgICAgLi4udGhpcy5oZWxwZXIuZGVmYXVsdEFyZ3MsXG4gICAgICAgICAgICBwcm9maWxlOiB0aGlzLmhlbHBlci5wcm9maWxlLFxuICAgICAgICAgICAgYWxsOiB0cnVlLFxuICAgICAgICAgICAgZm9yY2U6IHRydWUsXG4gICAgICAgICAgICBhcHA6IHRoaXMuaGVscGVyLmNka0FwcCxcbiAgICAgICAgICAgIG91dHB1dDogcGF0aC5yZWxhdGl2ZSh0aGlzLmhlbHBlci5kaXJlY3RvcnksIHRoaXMuaGVscGVyLnRlbXBvcmFyeVNuYXBzaG90RGlyKSxcbiAgICAgICAgICAgIC4uLmFjdHVhbFRlc3RDYXNlLmNka0NvbW1hbmRPcHRpb25zPy5kZXN0cm95Py5hcmdzLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5oZWxwZXIuZ2V0Q29udGV4dChhY3R1YWxUZXN0Q2FzZS5jZGtDb21tYW5kT3B0aW9ucz8uZGVzdHJveT8uYXJncz8uY29udGV4dCksXG4gICAgICAgICAgICByb2xlQXJuOiBvcHRpb25zLnJvbGVBcm4gPz8gYWN0dWFsVGVzdENhc2UuY2RrQ29tbWFuZE9wdGlvbnM/LmRlc3Ryb3k/LmFyZ3M/LnJvbGVBcm4sXG4gICAgICAgICAgICB2ZXJib3NlOiBlbmFibGVGb3JWZXJib3NpdHlMZXZlbCgzKSxcbiAgICAgICAgICAgIGRlYnVnOiBlbmFibGVGb3JWZXJib3NpdHlMZXZlbCg0KSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5oZWxwZXIuY2xlYW51cCgpO1xuICAgIH1cbiAgICByZXR1cm4gYXNzZXJ0aW9uUmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIGEgaW50ZWcgdGVzdCBjYXNlIHN0YWNrIGRlc3RydWN0aW9uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRlc3Ryb3kodGVzdENhc2VOYW1lOiBzdHJpbmcsIGRlc3Ryb3lBcmdzOiBEZXN0cm95T3B0aW9ucykge1xuICAgIGNvbnN0IGFjdHVhbFRlc3RDYXNlID0gKGF3YWl0IHRoaXMuYWN0dWFsVGVzdFN1aXRlKCkpLnRlc3RTdWl0ZVt0ZXN0Q2FzZU5hbWVdO1xuICAgIHRyeSB7XG4gICAgICBpZiAoYWN0dWFsVGVzdENhc2UuaG9va3M/LnByZURlc3Ryb3kpIHtcbiAgICAgICAgYWN0dWFsVGVzdENhc2UuaG9va3MucHJlRGVzdHJveS5mb3JFYWNoKGNtZCA9PiB7XG4gICAgICAgICAgZXhlYyhjaHVua3MoY21kKSwge1xuICAgICAgICAgICAgY3dkOiBwYXRoLmRpcm5hbWUodGhpcy5oZWxwZXIuZ29sZGVuU25hcHNob3REaXIpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMuaGVscGVyLmNkay5kZXN0cm95KHtcbiAgICAgICAgLi4uZGVzdHJveUFyZ3MsXG4gICAgICB9KTtcblxuICAgICAgaWYgKGFjdHVhbFRlc3RDYXNlLmhvb2tzPy5wb3N0RGVzdHJveSkge1xuICAgICAgICBhY3R1YWxUZXN0Q2FzZS5ob29rcy5wb3N0RGVzdHJveS5mb3JFYWNoKGNtZCA9PiB7XG4gICAgICAgICAgZXhlYyhjaHVua3MoY21kKSwge1xuICAgICAgICAgICAgY3dkOiBwYXRoLmRpcm5hbWUodGhpcy5oZWxwZXIuZ29sZGVuU25hcHNob3REaXIpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLnBhcnNlRXJyb3IoZSxcbiAgICAgICAgYWN0dWFsVGVzdENhc2UuY2RrQ29tbWFuZE9wdGlvbnM/LmRlc3Ryb3k/LmV4cGVjdEVycm9yID8/IGZhbHNlLFxuICAgICAgICBhY3R1YWxUZXN0Q2FzZS5jZGtDb21tYW5kT3B0aW9ucz8uZGVzdHJveT8uZXhwZWN0ZWRNZXNzYWdlLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHdhdGNoKG9wdGlvbnM6IGNkay5XYXRjaE9wdGlvbnMsIHRlc3RDYXNlTmFtZTogc3RyaW5nLCB2ZXJib3NpdHk6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFjdHVhbFRlc3RTdWl0ZSA9IGF3YWl0IHRoaXMuYWN0dWFsVGVzdFN1aXRlKCk7XG4gICAgY29uc3QgYWN0dWFsVGVzdENhc2UgPSBhY3R1YWxUZXN0U3VpdGUudGVzdFN1aXRlW3Rlc3RDYXNlTmFtZV07XG4gICAgaWYgKGFjdHVhbFRlc3RDYXNlLmhvb2tzPy5wcmVEZXBsb3kpIHtcbiAgICAgIGFjdHVhbFRlc3RDYXNlLmhvb2tzLnByZURlcGxveS5mb3JFYWNoKGNtZCA9PiB7XG4gICAgICAgIGV4ZWMoY2h1bmtzKGNtZCksIHtcbiAgICAgICAgICBjd2Q6IHBhdGguZGlybmFtZSh0aGlzLmhlbHBlci5nb2xkZW5TbmFwc2hvdERpciksXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IHdhdGNoQXJncyA9IHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBsb29rdXBzOiBhY3R1YWxUZXN0U3VpdGUuZW5hYmxlTG9va3VwcyxcbiAgICAgIHN0YWNrczogW1xuICAgICAgICAuLi5hY3R1YWxUZXN0Q2FzZS5zdGFja3MsXG4gICAgICAgIC4uLmFjdHVhbFRlc3RDYXNlLmFzc2VydGlvblN0YWNrID8gW2FjdHVhbFRlc3RDYXNlLmFzc2VydGlvblN0YWNrXSA6IFtdLFxuICAgICAgXSxcbiAgICAgIG91dHB1dDogcGF0aC5yZWxhdGl2ZSh0aGlzLmhlbHBlci5kaXJlY3RvcnksIHRoaXMuaGVscGVyLnRlbXBvcmFyeVNuYXBzaG90RGlyKSxcbiAgICAgIG91dHB1dHNGaWxlOiBwYXRoLnJlbGF0aXZlKHRoaXMuaGVscGVyLmRpcmVjdG9yeSwgcGF0aC5qb2luKHRoaXMuaGVscGVyLnRlbXBvcmFyeVNuYXBzaG90RGlyLCAnYXNzZXJ0aW9uLXJlc3VsdHMuanNvbicpKSxcbiAgICAgIC4uLmFjdHVhbFRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzLFxuICAgICAgY29udGV4dDoge1xuICAgICAgICAuLi50aGlzLmhlbHBlci5nZXRDb250ZXh0KGFjdHVhbFRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzPy5jb250ZXh0KSxcbiAgICAgIH0sXG4gICAgICBhcHA6IHRoaXMuaGVscGVyLmNka0FwcCxcbiAgICB9O1xuICAgIGNvbnN0IGRlc3Ryb3lNZXNzYWdlID0ge1xuICAgICAgYWRkaXRpb25hbE1lc3NhZ2VzOiBbXG4gICAgICAgICdBZnRlciB5b3UgYXJlIGRvbmUgeW91IG11c3QgbWFudWFsbHkgZGVzdHJveSB0aGUgZGVwbG95ZWQgc3RhY2tzJyxcbiAgICAgICAgYCAgJHtbXG4gICAgICAgICAgLi4ucHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiA/IFtgQVdTX1JFR0lPTj0ke3Byb2Nlc3MuZW52LkFXU19SRUdJT059YF0gOiBbXSxcbiAgICAgICAgICAnY2RrIGRlc3Ryb3knLFxuICAgICAgICAgIGAtYSAnJHt0aGlzLmhlbHBlci5jZGtBcHB9J2AsXG4gICAgICAgICAgd2F0Y2hBcmdzLnN0YWNrcy5qb2luKCcgJyksXG4gICAgICAgICAgYC0tcHJvZmlsZSAke3dhdGNoQXJncy5wcm9maWxlfWAsXG4gICAgICAgIF0uam9pbignICcpfWAsXG4gICAgICBdLFxuICAgIH07XG4gICAgd29ya2VycG9vbC53b3JrZXJFbWl0KGRlc3Ryb3lNZXNzYWdlKTtcbiAgICBpZiAod2F0Y2hBcmdzLnZlcmJvc2UpIHtcbiAgICAgIC8vIGlmIGAtdnZ2YCAob3IgYWJvdmUpIGlzIHVzZWQgdGhlbiBwcmludCBvdXQgdGhlIGNvbW1hbmQgdGhhdCB3YXMgdXNlZFxuICAgICAgLy8gdGhpcyBhbGxvd3MgdXNlcnMgdG8gbWFudWFsbHkgcnVuIHRoZSBjb21tYW5kXG4gICAgICB3b3JrZXJwb29sLndvcmtlckVtaXQoe1xuICAgICAgICBhZGRpdGlvbmFsTWVzc2FnZXM6IFtcbiAgICAgICAgICAnUmVwcm86JyxcbiAgICAgICAgICBgICAke1tcbiAgICAgICAgICAgICdjZGsgc3ludGgnLFxuICAgICAgICAgICAgYC1hICcke3RoaXMuaGVscGVyLmNka0FwcH0nYCxcbiAgICAgICAgICAgIGAtbyAnJHt0aGlzLmhlbHBlci50ZW1wb3JhcnlTbmFwc2hvdERpcn0nYCxcbiAgICAgICAgICAgIC4uLk9iamVjdC5lbnRyaWVzKHRoaXMuaGVscGVyLmdldENvbnRleHQoKSkuZmxhdE1hcCgoW2ssIHZdKSA9PiB0eXBlb2YgdiAhPT0gJ29iamVjdCcgPyBbYC1jICcke2t9PSR7dn0nYF0gOiBbXSksXG4gICAgICAgICAgICB3YXRjaEFyZ3Muc3RhY2tzLmpvaW4oJyAnKSxcbiAgICAgICAgICAgIGAtLW91dHB1dHMtZmlsZSAke3dhdGNoQXJncy5vdXRwdXRzRmlsZX1gLFxuICAgICAgICAgICAgYC0tcHJvZmlsZSAke3dhdGNoQXJncy5wcm9maWxlfWAsXG4gICAgICAgICAgICAnLS1ob3Rzd2FwLWZhbGxiYWNrJyxcbiAgICAgICAgICBdLmpvaW4oJyAnKX1gLFxuICAgICAgICBdLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgYXNzZXJ0aW9uUmVzdWx0cyA9IHBhdGguam9pbih0aGlzLmhlbHBlci50ZW1wb3JhcnlTbmFwc2hvdERpciwgJ2Fzc2VydGlvbi1yZXN1bHRzLmpzb24nKTtcbiAgICBjb25zdCB3YXRjaGVyID0gY2hva2lkYXIud2F0Y2goW3RoaXMuaGVscGVyLnRlbXBvcmFyeVNuYXBzaG90RGlyXSwge1xuICAgICAgY3dkOiB0aGlzLmhlbHBlci5kaXJlY3RvcnksXG4gICAgfSk7XG4gICAgd2F0Y2hlci5vbignYWxsJywgKGV2ZW50OiBFdmVudE5hbWUsIGZpbGU6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKCFpc0ZpbGVFdmVudChldmVudCkpIHtcbiAgICAgICAgcmV0dXJuOyAvLyBJZ25vcmUgbm9uLWZpbGUgZXZlbnRzIGxpa2UgJ2Vycm9yJywgJ3JhdycsICdyZWFkeScsICdhbGwnXG4gICAgICB9XG4gICAgICAvLyB3ZSBvbmx5IGNhcmUgYWJvdXQgY2hhbmdlcyB0byB0aGUgYGFzc2VydGlvbi1yZXN1bHRzLmpzb25gIGZpbGUuIElmIHRoZXJlXG4gICAgICAvLyBhcmUgYXNzZXJ0aW9ucyB0aGVuIHRoaXMgd2lsbCBjaGFuZ2Ugb24gZXZlcnkgZGVwbG95bWVudFxuICAgICAgaWYgKGFzc2VydGlvblJlc3VsdHMuZW5kc1dpdGgoZmlsZSkgJiYgKGV2ZW50ID09PSAnYWRkJyB8fCBldmVudCA9PT0gJ2NoYW5nZScpKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgaWYgKGFjdHVhbFRlc3RDYXNlLmhvb2tzPy5wb3N0RGVwbG95KSB7XG4gICAgICAgICAgYWN0dWFsVGVzdENhc2UuaG9va3MucG9zdERlcGxveS5mb3JFYWNoKGNtZCA9PiB7XG4gICAgICAgICAgICBleGVjKGNodW5rcyhjbWQpLCB7XG4gICAgICAgICAgICAgIGN3ZDogcGF0aC5kaXJuYW1lKHRoaXMuaGVscGVyLmdvbGRlblNuYXBzaG90RGlyKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFjdHVhbFRlc3RDYXNlLmFzc2VydGlvblN0YWNrICYmIGFjdHVhbFRlc3RDYXNlLmFzc2VydGlvblN0YWNrTmFtZSkge1xuICAgICAgICAgIGNvbnN0IHJlcyA9IHRoaXMucHJvY2Vzc0Fzc2VydGlvblJlc3VsdHMoXG4gICAgICAgICAgICBhc3NlcnRpb25SZXN1bHRzLFxuICAgICAgICAgICAgYWN0dWFsVGVzdENhc2UuYXNzZXJ0aW9uU3RhY2tOYW1lLFxuICAgICAgICAgICAgYWN0dWFsVGVzdENhc2UuYXNzZXJ0aW9uU3RhY2ssXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAocmVzICYmIE9iamVjdC52YWx1ZXMocmVzKS5zb21lKHIgPT4gci5zdGF0dXMgPT09ICdmYWlsJykpIHtcbiAgICAgICAgICAgIHdvcmtlcnBvb2wud29ya2VyRW1pdCh7XG4gICAgICAgICAgICAgIHJlYXNvbjogRGlhZ25vc3RpY1JlYXNvbi5BU1NFUlRJT05fRkFJTEVELFxuICAgICAgICAgICAgICB0ZXN0TmFtZTogYCR7dGVzdENhc2VOYW1lfSAoJHt3YXRjaEFyZ3MucHJvZmlsZX1gLFxuICAgICAgICAgICAgICBtZXNzYWdlOiBmb3JtYXRBc3NlcnRpb25SZXN1bHRzKHJlcyksXG4gICAgICAgICAgICAgIGR1cmF0aW9uOiAoRGF0ZS5ub3coKSAtIHN0YXJ0KSAvIDEwMDAsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd29ya2VycG9vbC53b3JrZXJFbWl0KHtcbiAgICAgICAgICAgICAgcmVhc29uOiBEaWFnbm9zdGljUmVhc29uLlRFU1RfU1VDQ0VTUyxcbiAgICAgICAgICAgICAgdGVzdE5hbWU6IGAke3Rlc3RDYXNlTmFtZX1gLFxuICAgICAgICAgICAgICBtZXNzYWdlOiByZXMgPyBmb3JtYXRBc3NlcnRpb25SZXN1bHRzKHJlcykgOiAnTk8gQVNTRVJUSU9OUycsXG4gICAgICAgICAgICAgIGR1cmF0aW9uOiAoRGF0ZS5ub3coKSAtIHN0YXJ0KSAvIDEwMDAsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZW1pdCB0aGUgZGVzdHJveSBtZXNzYWdlIGFmdGVyIGV2ZXJ5IHJ1blxuICAgICAgICAgIC8vIHNvIHRoYXQgaXQncyB2aXNpYmxlIHRvIHRoZSB1c2VyXG4gICAgICAgICAgd29ya2VycG9vbC53b3JrZXJFbWl0KGRlc3Ryb3lNZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgd2F0Y2hlci5vbigncmVhZHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJlc29sdmUoe30pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCB7IHByb21pc2U6IHdhaXRlciwgcmVzb2x2ZSB9ID0gcHJvbWlzZVdpdGhSZXNvbHZlcnM8bnVtYmVyIHwgbnVsbD4oKTtcblxuICAgIGF3YWl0IHRoaXMuaGVscGVyLmNkay53YXRjaCh3YXRjaEFyZ3MsIHtcbiAgICAgIC8vIGlmIGAtdmAgKG9yIGFib3ZlKSBpcyBwYXNzZWQgdGhlbiBzdHJlYW0gdGhlIGxvZ3NcbiAgICAgIG9uU3Rkb3V0OiAobWVzc2FnZSkgPT4ge1xuICAgICAgICBpZiAodmVyYm9zaXR5ID4gMCkge1xuICAgICAgICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgLy8gaWYgYC12YCAob3IgYWJvdmUpIGlzIHBhc3NlZCB0aGVuIHN0cmVhbSB0aGUgbG9nc1xuICAgICAgb25TdGRlcnI6IChtZXNzYWdlKSA9PiB7XG4gICAgICAgIGlmICh2ZXJib3NpdHkgPiAwKSB7XG4gICAgICAgICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBvbkNsb3NlOiBhc3luYyAoY29kZSkgPT4ge1xuICAgICAgICBpZiAoY29kZSAhPT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV2F0Y2ggZXhpdGVkIHdpdGggZXJyb3InKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB3YXRjaGVyLmNsb3NlKCk7XG4gICAgICAgIHJlc29sdmUoY29kZSk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgYXdhaXQgd2FpdGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gYSBpbnRlZyB0ZXN0IGNhc2UgZGVwbG95bWVudCwgaW5jbHVkaW5nXG4gICAqIHBlcmZvcm1pbmcgdGhlIHVwZGF0ZSB3b3JrZmxvd1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBkZXBsb3koXG4gICAgZGVwbG95QXJnczogY2RrLkRlcGxveU9wdGlvbnMsXG4gICAgdXBkYXRlV29ya2Zsb3dFbmFibGVkOiBib29sZWFuLFxuICAgIHRlc3RDYXNlTmFtZTogc3RyaW5nLFxuICAgIGFsbG93RGVsZXRlRmFpbHVyZXM6IGJvb2xlYW4sXG4gICAgdXBkYXRlRnJvbVRhZ3M/OiBzdHJpbmdbXSxcbiAgKTogUHJvbWlzZTxBc3NlcnRpb25SZXN1bHRzIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgYWN0dWFsVGVzdENhc2UgPSAoYXdhaXQgdGhpcy5hY3R1YWxUZXN0U3VpdGUoKSkudGVzdFN1aXRlW3Rlc3RDYXNlTmFtZV07XG4gICAgdHJ5IHtcbiAgICAgIGlmIChhY3R1YWxUZXN0Q2FzZS5ob29rcz8ucHJlRGVwbG95KSB7XG4gICAgICAgIGFjdHVhbFRlc3RDYXNlLmhvb2tzLnByZURlcGxveS5mb3JFYWNoKGNtZCA9PiB7XG4gICAgICAgICAgZXhlYyhjaHVua3MoY21kKSwge1xuICAgICAgICAgICAgY3dkOiBwYXRoLmRpcm5hbWUodGhpcy5oZWxwZXIuZ29sZGVuU25hcHNob3REaXIpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHVwZGF0ZUZyb21UYWdzICYmIHVwZGF0ZUZyb21UYWdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gVGFnLXNlcXVlbmNlIHVwZGF0ZSB3b3JrZmxvdzogZGVwbG95IGVhY2ggdGFnJ3Mgc25hcHNob3QgaW4gb3JkZXJcbiAgICAgICAgYXdhaXQgdGhpcy5kZXBsb3lGcm9tVGFncyhkZXBsb3lBcmdzLCB0ZXN0Q2FzZU5hbWUsIHVwZGF0ZUZyb21UYWdzLCBhbGxvd0RlbGV0ZUZhaWx1cmVzKTtcbiAgICAgIH0gZWxzZSBpZiAodXBkYXRlV29ya2Zsb3dFbmFibGVkICYmIHRoaXMuaGVscGVyLmhhc1NuYXBzaG90KCkpIHtcbiAgICAgICAgLy8gTm9ybWFsIG1lcmdlLWJhc2UgdXBkYXRlIHdvcmtmbG93XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkVGVzdFN1aXRlID0gYXdhaXQgdGhpcy5oZWxwZXIuZXhwZWN0ZWRUZXN0U3VpdGUoKTtcbiAgICAgICAgaWYgKGV4cGVjdGVkVGVzdFN1aXRlICYmIHRlc3RDYXNlTmFtZSBpbiBleHBlY3RlZFRlc3RTdWl0ZT8udGVzdFN1aXRlKSB7XG4gICAgICAgICAgdGhpcy5jaGVja291dFNuYXBzaG90KCk7XG4gICAgICAgICAgY29uc3QgZXhwZWN0ZWRUZXN0Q2FzZSA9IGV4cGVjdGVkVGVzdFN1aXRlLnRlc3RTdWl0ZVt0ZXN0Q2FzZU5hbWVdO1xuICAgICAgICAgIGF3YWl0IHRoaXMuaGVscGVyLmNkay5kZXBsb3koe1xuICAgICAgICAgICAgLi4uZGVwbG95QXJncyxcbiAgICAgICAgICAgIHN0YWNrczogZXhwZWN0ZWRUZXN0Q2FzZS5zdGFja3MsXG4gICAgICAgICAgICAuLi5leHBlY3RlZFRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5oZWxwZXIuZ2V0Q29udGV4dChleHBlY3RlZFRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzPy5jb250ZXh0KSxcbiAgICAgICAgICAgIGFwcDogcGF0aC5yZWxhdGl2ZSh0aGlzLmhlbHBlci5kaXJlY3RvcnksIHRoaXMuaGVscGVyLmdvbGRlblNuYXBzaG90RGlyKSxcbiAgICAgICAgICAgIGxvb2t1cHM6IGV4cGVjdGVkVGVzdFN1aXRlPy5lbmFibGVMb29rdXBzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBub3cgZGVwbG95IHRoZSBcImFjdHVhbFwiIHRlc3QuXG4gICAgICAvLyBUaGlzIGlzIHRoZSBzdGFjayB1cGRhdGUgaWYgdGhlIHVwZGF0ZSB3b3JrZmxvdyByYW4gYWJvdmUuXG4gICAgICBjb25zdCBhY3R1YWxEZXBsb3lSZXN1bHQgPSBhd2FpdCB0aGlzLmhlbHBlci5jZGsuZGVwbG95KHtcbiAgICAgICAgLi4uZGVwbG95QXJncyxcbiAgICAgICAgbG9va3VwczogKGF3YWl0IHRoaXMuYWN0dWFsVGVzdFN1aXRlKCkpLmVuYWJsZUxvb2t1cHMsXG4gICAgICAgIHN0YWNrczogW1xuICAgICAgICAgIC4uLmFjdHVhbFRlc3RDYXNlLnN0YWNrcyxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0OiBwYXRoLnJlbGF0aXZlKHRoaXMuaGVscGVyLmRpcmVjdG9yeSwgdGhpcy5oZWxwZXIudGVtcG9yYXJ5U25hcHNob3REaXIpLFxuICAgICAgICAuLi5hY3R1YWxUZXN0Q2FzZT8uY2RrQ29tbWFuZE9wdGlvbnM/LmRlcGxveT8uYXJncyxcbiAgICAgICAgY29udGV4dDogdGhpcy5oZWxwZXIuZ2V0Q29udGV4dChhY3R1YWxUZXN0Q2FzZT8uY2RrQ29tbWFuZE9wdGlvbnM/LmRlcGxveT8uYXJncz8uY29udGV4dCksXG4gICAgICAgIGFwcDogdGhpcy5oZWxwZXIuY2RrQXBwLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChhY3R1YWxEZXBsb3lSZXN1bHQuZGVsZXRlRmFpbHVyZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBkZXRhaWxzID0gYWN0dWFsRGVwbG95UmVzdWx0LmRlbGV0ZUZhaWx1cmVzXG4gICAgICAgICAgLm1hcChmID0+IGAgIC0gJHtmLmxvZ2ljYWxSZXNvdXJjZUlkfSAoJHtmLnJlc291cmNlVHlwZX0pOiAke2YucmVhc29ufWApXG4gICAgICAgICAgLmpvaW4oJ1xcbicpO1xuICAgICAgICBjb25zdCBtZXNzYWdlID1cbiAgICAgICAgICBgJHthY3R1YWxEZXBsb3lSZXN1bHQuZGVsZXRlRmFpbHVyZXMubGVuZ3RofSByZXNvdXJjZShzKSBmYWlsZWQgdG8gZGVsZXRlIGR1cmluZyBzdGFjayB1cGRhdGU6XFxuJHtkZXRhaWxzfVxcbmAgK1xuICAgICAgICAgICdUaGVzZSByZXNvdXJjZXMgYXJlIG5vIGxvbmdlciBtYW5hZ2VkIGJ5IENsb3VkRm9ybWF0aW9uIGJ1dCBzdGlsbCBleGlzdCBhbmQgbWF5IGluY3VyIGNoYXJnZXMuJztcbiAgICAgICAgaWYgKGFsbG93RGVsZXRlRmFpbHVyZXMpIHtcbiAgICAgICAgICBsb2dnZXIud2FybmluZyhtZXNzYWdlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhlcmUgYXJlIGFueSBhc3NlcnRpb25zXG4gICAgICAvLyBkZXBsb3kgdGhlIGFzc2VydGlvbiBzdGFjayBhcyB3ZWxsXG4gICAgICAvLyBUaGlzIGlzIHNlcGFyYXRlIGZyb20gdGhlIGFib3ZlIGRlcGxveW1lbnQgYmVjYXVzZSB3ZSB3YW50IHRvXG4gICAgICAvLyBzZXQgYHJvbGxiYWNrOiBmYWxzZWAuIFRoaXMgYWxsb3dzIHRoZSBhc3NlcnRpb24gc3RhY2sgdG8gZGVwbG95IGFsbCB0aGVcbiAgICAgIC8vIGFzc2VydGlvbnMgaW5zdGVhZCBvZiBmYWlsaW5nIGF0IHRoZSBmaXJzdCBmYWlsZWQgYXNzZXJ0aW9uXG4gICAgICAvLyBjb21iaW5pbmcgaXQgd2l0aCB0aGUgYWJvdmUgZGVwbG95bWVudCB3b3VsZCBwcmV2ZW50IGFueSByZXBsYWNlbWVudCB1cGRhdGVzXG4gICAgICBpZiAoYWN0dWFsVGVzdENhc2UuYXNzZXJ0aW9uU3RhY2spIHtcbiAgICAgICAgYXdhaXQgdGhpcy5oZWxwZXIuY2RrLmRlcGxveSh7XG4gICAgICAgICAgLi4uZGVwbG95QXJncyxcbiAgICAgICAgICBsb29rdXBzOiAoYXdhaXQgdGhpcy5hY3R1YWxUZXN0U3VpdGUoKSkuZW5hYmxlTG9va3VwcyxcbiAgICAgICAgICBzdGFja3M6IFtcbiAgICAgICAgICAgIGFjdHVhbFRlc3RDYXNlLmFzc2VydGlvblN0YWNrLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgcm9sbGJhY2s6IGZhbHNlLFxuICAgICAgICAgIG91dHB1dDogcGF0aC5yZWxhdGl2ZSh0aGlzLmhlbHBlci5kaXJlY3RvcnksIHRoaXMuaGVscGVyLnRlbXBvcmFyeVNuYXBzaG90RGlyKSxcbiAgICAgICAgICAuLi5hY3R1YWxUZXN0Q2FzZT8uY2RrQ29tbWFuZE9wdGlvbnM/LmRlcGxveT8uYXJncyxcbiAgICAgICAgICBvdXRwdXRzRmlsZTogcGF0aC5yZWxhdGl2ZSh0aGlzLmhlbHBlci5kaXJlY3RvcnksIHBhdGguam9pbih0aGlzLmhlbHBlci50ZW1wb3JhcnlTbmFwc2hvdERpciwgJ2Fzc2VydGlvbi1yZXN1bHRzLmpzb24nKSksXG4gICAgICAgICAgY29udGV4dDogdGhpcy5oZWxwZXIuZ2V0Q29udGV4dChhY3R1YWxUZXN0Q2FzZT8uY2RrQ29tbWFuZE9wdGlvbnM/LmRlcGxveT8uYXJncz8uY29udGV4dCksXG4gICAgICAgICAgYXBwOiB0aGlzLmhlbHBlci5jZGtBcHAsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWN0dWFsVGVzdENhc2UuaG9va3M/LnBvc3REZXBsb3kpIHtcbiAgICAgICAgYWN0dWFsVGVzdENhc2UuaG9va3MucG9zdERlcGxveS5mb3JFYWNoKGNtZCA9PiB7XG4gICAgICAgICAgZXhlYyhjaHVua3MoY21kKSwge1xuICAgICAgICAgICAgY3dkOiBwYXRoLmRpcm5hbWUodGhpcy5oZWxwZXIuZ29sZGVuU25hcHNob3REaXIpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFjdHVhbFRlc3RDYXNlLmFzc2VydGlvblN0YWNrICYmIGFjdHVhbFRlc3RDYXNlLmFzc2VydGlvblN0YWNrTmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzQXNzZXJ0aW9uUmVzdWx0cyhcbiAgICAgICAgICBwYXRoLmpvaW4odGhpcy5oZWxwZXIudGVtcG9yYXJ5U25hcHNob3REaXIsICdhc3NlcnRpb24tcmVzdWx0cy5qc29uJyksXG4gICAgICAgICAgYWN0dWFsVGVzdENhc2UuYXNzZXJ0aW9uU3RhY2tOYW1lLFxuICAgICAgICAgIGFjdHVhbFRlc3RDYXNlLmFzc2VydGlvblN0YWNrLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMucGFyc2VFcnJvcihlLFxuICAgICAgICBhY3R1YWxUZXN0Q2FzZS5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5leHBlY3RFcnJvciA/PyBmYWxzZSxcbiAgICAgICAgYWN0dWFsVGVzdENhc2UuY2RrQ29tbWFuZE9wdGlvbnM/LmRlcGxveT8uZXhwZWN0ZWRNZXNzYWdlLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2Nlc3MgdGhlIG91dHB1dHNGaWxlIHdoaWNoIGNvbnRhaW5zIHRoZSBhc3NlcnRpb25zIHJlc3VsdHMgYXMgc3RhY2tcbiAgICogb3V0cHV0c1xuICAgKi9cbiAgcHJpdmF0ZSBwcm9jZXNzQXNzZXJ0aW9uUmVzdWx0cyhmaWxlOiBzdHJpbmcsIGFzc2VydGlvblN0YWNrTmFtZTogc3RyaW5nLCBhc3NlcnRpb25TdGFja0lkOiBzdHJpbmcpOiBBc3NlcnRpb25SZXN1bHRzIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCByZXN1bHRzOiBBc3NlcnRpb25SZXN1bHRzID0ge307XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoZmlsZSkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG91dHB1dHM6IHsgW2tleTogc3RyaW5nXTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB9ID0gZnMucmVhZEpTT05TeW5jKGZpbGUpO1xuXG4gICAgICAgIGlmIChhc3NlcnRpb25TdGFja05hbWUgaW4gb3V0cHV0cykge1xuICAgICAgICAgIGZvciAoY29uc3QgW2Fzc2VydGlvbklkLCByZXN1bHRdIG9mIE9iamVjdC5lbnRyaWVzKG91dHB1dHNbYXNzZXJ0aW9uU3RhY2tOYW1lXSkpIHtcbiAgICAgICAgICAgIGlmIChhc3NlcnRpb25JZC5zdGFydHNXaXRoKCdBc3NlcnRpb25SZXN1bHRzJykpIHtcbiAgICAgICAgICAgICAgY29uc3QgYXNzZXJ0aW9uUmVzdWx0OiBBc3NlcnRpb25SZXN1bHQgPSBKU09OLnBhcnNlKHJlc3VsdC5yZXBsYWNlKC9cXG4vZywgJ1xcXFxuJykpO1xuICAgICAgICAgICAgICBpZiAoYXNzZXJ0aW9uUmVzdWx0LnN0YXR1cyA9PT0gJ2ZhaWwnIHx8IGFzc2VydGlvblJlc3VsdC5zdGF0dXMgPT09ICdzdWNjZXNzJykge1xuICAgICAgICAgICAgICAgIHJlc3VsdHNbYXNzZXJ0aW9uSWRdID0gYXNzZXJ0aW9uUmVzdWx0O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGlmIHRoZXJlIGFyZSBvdXRwdXRzLCBidXQgdGhleSBjYW5ub3QgYmUgcHJvY2Vzc2VkLCB0aGVuIHRocm93IGFuIGVycm9yXG4gICAgICAgIC8vIHNvIHRoYXQgdGhlIHRlc3QgZmFpbHNcbiAgICAgICAgcmVzdWx0c1thc3NlcnRpb25TdGFja0lkXSA9IHtcbiAgICAgICAgICBzdGF0dXM6ICdmYWlsJyxcbiAgICAgICAgICBtZXNzYWdlOiBgZXJyb3IgcHJvY2Vzc2luZyBhc3NlcnRpb24gcmVzdWx0czogJHtlfWAsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICAvLyByZW1vdmUgdGhlIG91dHB1dHMgZmlsZSBzbyBpdCBpcyBub3QgcGFydCBvZiB0aGUgc25hcHNob3RcbiAgICAgICAgLy8gaXQgd2lsbCBjb250YWluIGVudiBzcGVjaWZpYyBpbmZvcm1hdGlvbiBmcm9tIHZhbHVlc1xuICAgICAgICAvLyByZXNvbHZlZCBhdCBkZXBsb3kgdGltZVxuICAgICAgICBmcy51bmxpbmtTeW5jKGZpbGUpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmtleXMocmVzdWx0cykubGVuZ3RoID4gMCA/IHJlc3VsdHMgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIGFuIGVycm9yIG1lc3NhZ2UgcmV0dXJuZWQgZnJvbSBhIENESyBjb21tYW5kXG4gICAqL1xuICBwcml2YXRlIHBhcnNlRXJyb3IoZTogdW5rbm93biwgZXhwZWN0RXJyb3I6IGJvb2xlYW4sIGV4cGVjdGVkTWVzc2FnZT86IHN0cmluZykge1xuICAgIGlmIChleHBlY3RFcnJvcikge1xuICAgICAgaWYgKGV4cGVjdGVkTWVzc2FnZSkge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gKGUgYXMgRXJyb3IpLm1lc3NhZ2U7XG4gICAgICAgIGlmICghbWVzc2FnZS5tYXRjaChleHBlY3RlZE1lc3NhZ2UpKSB7XG4gICAgICAgICAgdGhyb3cgKGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG59XG4iXX0=
565
+ function analyzeVerbosity(verbosity = 0) {
566
+ return {
567
+ verbose: verbosity >= 3 ? true : undefined,
568
+ debug: verbosity >= 4 ? true : undefined,
569
+ traceLogs: verbosity >= 2 ? true : false,
570
+ };
571
+ }
572
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZWctdGVzdC1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbnRlZy10ZXN0LXJ1bm5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFFN0IsMEVBQWlFO0FBQ2pFLG1EQUFxQztBQUNyQyxvREFBNkQ7QUFDN0QsNkNBQStCO0FBQy9CLHVEQUF5QztBQUV6QyxrREFBb0M7QUFDcEMsb0NBQStGO0FBRS9GLGlEQUEwRDtBQUcxRCw4Q0FBMEY7QUFFMUY7Ozs7R0FJRztBQUNILE1BQU0sV0FBVyxHQUFHLENBQUMsbUJBQU0sQ0FBQyxHQUFHLEVBQUUsbUJBQU0sQ0FBQyxNQUFNLENBQVUsQ0FBQztBQUd6RDs7R0FFRztBQUNILFNBQVMsV0FBVyxDQUFDLEtBQWdCO0lBQ25DLE9BQVEsV0FBaUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDNUQsQ0FBQztBQWlHRDs7O0dBR0c7QUFDSCxNQUFhLGVBQWU7SUFHRztJQUE0QztJQUZ4RCxJQUFJLENBQVk7SUFFakMsWUFBNkIsVUFBeUIsRUFBbUIsa0JBQXdDO1FBQXBGLGVBQVUsR0FBVixVQUFVLENBQWU7UUFBbUIsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFzQjtRQUMvRyxJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUM7SUFDOUIsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsVUFBc0I7UUFDbEQsSUFBSSxnQkFBOEMsQ0FBQztRQUVuRCxnQkFBZ0I7UUFDaEIsSUFBSSxNQUFNLEdBQUcsTUFBTSx5QkFBVSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDN0QsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLG9DQUFvQyxFQUFFLENBQUM7WUFDekQsTUFBTSxHQUFHLE1BQU0seUJBQVUs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b3J0IHR5cGUgeyBEZXN0cm95T3B0aW9ucywgVGVzdENhc2UgfSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnO1xuaW1wb3J0IHsgUmVxdWlyZUFwcHJvdmFsIH0gZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCAqIGFzIGNob2tpZGFyIGZyb20gJ2Nob2tpZGFyJztcbmltcG9ydCB7IHR5cGUgRXZlbnROYW1lLCBFVkVOVFMgfSBmcm9tICdjaG9raWRhci9oYW5kbGVyLmpzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCAqIGFzIHdvcmtlcnBvb2wgZnJvbSAnd29ya2VycG9vbCc7XG5pbXBvcnQgdHlwZSAqIGFzIGNkayBmcm9tICcuLi9lbmdpbmVzL2Nkay1pbnRlcmZhY2UnO1xuaW1wb3J0ICogYXMgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBjaHVua3MsIGV4ZWMsIGV4ZWNXaXRoU3ViU2hlbGwsIHByb21pc2VXaXRoUmVzb2x2ZXJzLCByZW5kZXJDb21tYW5kIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHR5cGUgeyBDZGtUZXN0QXBwT3B0aW9ucywgTGVnYWN5RW5hYmxlTG9va3VwcyB9IGZyb20gJy4vY2RrLXRlc3QtYXBwJztcbmltcG9ydCB7IENka1Rlc3RBcHAsIERFRkFVTFRfQVJHUyB9IGZyb20gJy4vY2RrLXRlc3QtYXBwJztcbmltcG9ydCB0eXBlIHsgSW50ZWdUZXN0IH0gZnJvbSAnLi9pbnRlZ3JhdGlvbi10ZXN0cyc7XG5pbXBvcnQgdHlwZSB7IERlc3RydWN0aXZlQ2hhbmdlLCBBc3NlcnRpb25SZXN1bHRzLCBBc3NlcnRpb25SZXN1bHQgfSBmcm9tICcuLi93b3JrZXJzL2NvbW1vbic7XG5pbXBvcnQgeyBEaWFnbm9zdGljUmVhc29uLCBmb3JtYXRBc3NlcnRpb25SZXN1bHRzLCBmb3JtYXRFcnJvciB9IGZyb20gJy4uL3dvcmtlcnMvY29tbW9uJztcblxuLyoqXG4gKiBGaWxlIGV2ZW50cyB0aGF0IHdlIGNhcmUgYWJvdXQgZnJvbSBjaG9raWRhci5cbiAqIEluIGNob2tpZGFyIHY0LCBFdmVudE5hbWUgaW5jbHVkZXMgYWRkaXRpb25hbCBldmVudHMgbGlrZSAnZXJyb3InLCAncmF3JywgJ3JlYWR5JywgJ2FsbCdcbiAqIHRoYXQgd2UgbmVlZCB0byBmaWx0ZXIgb3V0IGluIHRoZSAnYWxsJyBoYW5kbGVyLlxuICovXG5jb25zdCBGSUxFX0VWRU5UUyA9IFtFVkVOVFMuQURELCBFVkVOVFMuQ0hBTkdFXSBhcyBjb25zdDtcbnR5cGUgRmlsZUV2ZW50ID0gdHlwZW9mIEZJTEVfRVZFTlRTW251bWJlcl07XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhbiBldmVudCBpcyBhIGZpbGUgZXZlbnQgd2Ugc2hvdWxkIHByb2Nlc3MuXG4gKi9cbmZ1bmN0aW9uIGlzRmlsZUV2ZW50KGV2ZW50OiBFdmVudE5hbWUpOiBldmVudCBpcyBGaWxlRXZlbnQge1xuICByZXR1cm4gKEZJTEVfRVZFTlRTIGFzIHJlYWRvbmx5IHN0cmluZ1tdKS5pbmNsdWRlcyhldmVudCk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tbW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgbGV2ZWwgb2YgdmVyYm9zaXR5IGZvciBsb2dnaW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdCAwXG4gICAqL1xuICByZWFkb25seSB2ZXJib3NpdHk/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2F0Y2hPcHRpb25zIGV4dGVuZHMgQ29tbW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBUk4gb2YgdGhlIElBTSByb2xlIGZvciBDbG91ZEZvcm1hdGlvbiB0byBhc3N1bWUgZHVyaW5nIGRlcGxveS9kZXN0cm95XG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdXNlIHRoZSBib290c3RyYXAgY2ZuLWV4ZWMgcm9sZVxuICAgKi9cbiAgcmVhZG9ubHkgcm9sZUFybj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciB0aGUgaW50ZWdyYXRpb24gdGVzdCBydW5uZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSdW5PcHRpb25zIGV4dGVuZHMgQ29tbW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIG9yIG5vdCB0byBydW4gYGNkayBkZXN0cm95YCBhbmQgY2xlYW51cCB0aGVcbiAgICogaW50ZWdyYXRpb24gdGVzdCBzdGFja3MuXG4gICAqXG4gICAqIFNldCB0aGlzIHRvIGZhbHNlIGlmIHlvdSBuZWVkIHRvIHBlcmZvcm0gYW55IHZhbGlkYXRpb25cbiAgICogb3IgdHJvdWJsZXNob290aW5nIGFmdGVyIGRlcGxveW1lbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNsZWFuPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSWYgc2V0IHRvIHRydWUsIHRoZSBpbnRlZ3JhdGlvbiB0ZXN0IHdpbGwgbm90IGRlcGxveVxuICAgKiBhbnl0aGluZyBhbmQgd2lsbCBzaW1wbHkgdXBkYXRlIHRoZSBzbmFwc2hvdC5cbiAgICpcbiAgICogWW91IHNob3VsZCBOT1QgdXNlIHRoaXMgbWV0aG9kIHNpbmNlIHlvdSBhcmUgZXNzZW50aWFsbHlcbiAgICogYnlwYXNzaW5nIHRoZSBpbnRlZ3JhdGlvbiB0ZXN0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZHJ5UnVuPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSWYgdGhpcyBpcyBzZXQgdG8gZmFsc2UgdGhlbiB0aGUgc3RhY2sgdXBkYXRlIHdvcmtmbG93IHdpbGxcbiAgICogbm90IGJlIHJ1blxuICAgKlxuICAgKiBUaGUgdXBkYXRlIHdvcmtmbG93IGV4aXN0cyB0byBjaGVjayBmb3IgY2FzZXMgd2hlcmUgYSBjaGFuZ2Ugd291bGQgY2F1c2VcbiAgICogYSBmYWlsdXJlIHRvIGFuIGV4aXN0aW5nIHN0YWNrLCBidXQgbm90IGZvciBhIG5ld2x5IGNyZWF0ZWQgc3RhY2suXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHVwZGF0ZVdvcmtmbG93PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogTGlzdCBvZiBnaXQgdGFncyB0byBkZXBsb3kgaW4gc2VxdWVuY2UgYmVmb3JlIGRlcGxveWluZyB0aGUgY3VycmVudCBjb2RlLlxuICAgKiBXaGVuIHByb3ZpZGVkLCByZXBsYWNlcyB0aGUgbm9ybWFsIG1lcmdlLWJhc2UgdXBkYXRlIHdvcmtmbG93LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHVzZSB0aGUgbm9ybWFsIHVwZGF0ZSB3b3JrZmxvd1xuICAgKi9cbiAgcmVhZG9ubHkgdXBkYXRlRnJvbVRhZ3M/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogQVJOIG9mIHRoZSBJQU0gcm9sZSBmb3IgQ2xvdWRGb3JtYXRpb24gdG8gYXNzdW1lIGR1cmluZyBkZXBsb3kvZGVzdHJveVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHVzZSB0aGUgYm9vdHN0cmFwIGNmbi1leGVjIHJvbGVcbiAgICovXG4gIHJlYWRvbmx5IHJvbGVBcm4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gYWxsb3cgcmVzb3VyY2VzIHRoYXQgZmFpbCB0byBkZWxldGUgZHVyaW5nIGEgc3RhY2sgdXBkYXRlLlxuICAgKlxuICAgKiBXaGVuIGZhbHNlLCB0aGUgdGVzdCB3aWxsIGZhaWwgaWYgQ2xvdWRGb3JtYXRpb24gc2tpcHMgZGVsZXRpbmcgYSByZXNvdXJjZVxuICAgKiBkdXJpbmcgYSBzdGFjayB1cGRhdGUuIFdoZW4gdHJ1ZSwgb25seSBhIHdhcm5pbmcgaXMgcHJpbnRlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGFsbG93RGVsZXRlRmFpbHVyZXM/OiBib29sZWFuO1xufVxuXG50eXBlIFJ1bm5lck9wdGlvbnMgPSBPbWl0PENka1Rlc3RBcHBPcHRpb25zLCAnb3V0cHV0RGlyZWN0b3J5TmFtZVRlbXBsYXRlJz4gJiB7XG4gIC8qKlxuICAgKiBKdXN0IGZvciB0ZXN0aW5nXG4gICAqXG4gICAqIFVzZSB0aGUgY29tcGFyaXNvbiBvdXRwdXQgZGlyZWN0b3J5IGZvciBkZXBsb3ltZW50cywgaW5zdGVhZCBvZiBhIHNlcGFyYXRlIG91dHB1dFxuICAgKiBkaXJlY3RvcnkuXG4gICAqXG4gICAqIFByZWZlcmFibHksIHdlIHN5bnRoIGludG8gYSBzZXBhcmF0ZSBkaXJlY3Rvcnkgc28gdGhhdCBzbmFwc2hvdCBjb21wYXJpc29uIGFzc2VtYmx5IGFuZFxuICAgKiBkZXBsb3ltZW50IGFzc2VtYmx5IGRvbid0IHRyYW1wbGUgb24gZWFjaCBvdGhlciwgYnV0IHRoZSB0ZXN0cyBpbiB0aGlzIHJlcG9zaXRvcnkgaGF2ZVxuICAgKiBiZWVuIHNldCB1cCB0byB1c2UgdGhlIHNhbWUgZGlyZWN0b3J5LlxuICAgKi9cbiAgVEVTVElOR191c2VDb21wYXJpc29uT3V0cHV0RGlyZWN0b3J5PzogYm9vbGVhbjtcbn07XG5cbi8qKlxuICogQW4gaW50ZWdyYXRpb24gdGVzdCBydW5uZXIgdGhhdCBvcmNoZXN0cmF0ZXMgZXhlY3V0aW5nXG4gKiBpbnRlZ3JhdGlvbiB0ZXN0c1xuICovXG5leHBvcnQgY2xhc3MgSW50ZWdUZXN0UnVubmVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSB0ZXN0OiBJbnRlZ1Rlc3Q7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBhcHBPcHRpb25zOiBSdW5uZXJPcHRpb25zLCBwcml2YXRlIHJlYWRvbmx5IGRlc3RydWN0aXZlQ2hhbmdlcz86IERlc3RydWN0aXZlQ2hhbmdlW10pIHtcbiAgICB0aGlzLnRlc3QgPSBhcHBPcHRpb25zLnRlc3Q7XG4gIH1cblxuICAvKipcbiAgICogT3JjaGVzdHJhdGVzIHJ1bm5pbmcgaW50ZWdyYXRpb24gdGVzdHMuIEN1cnJlbnRseSB0aGlzIGluY2x1ZGVzXG4gICAqXG4gICAqIDEuIChpZiB1cGRhdGUgd29ya2Zsb3cgaXMgZW5hYmxlZCkgRGVwbG95aW5nIHRoZSBzbmFwc2hvdCB0ZXN0IHN0YWNrc1xuICAgKiAyLiBEZXBsb3lpbmcgdGhlIGludGVncmF0aW9uIHRlc3Qgc3RhY2tzXG4gICAqIDIuIFNhdmluZyB0aGUgc25hcHNob3QgKGlmIHN1Y2Nlc3NmdWwpXG4gICAqIDMuIERlc3Ryb3lpbmcgdGhlIGludGVncmF0aW9uIHRlc3Qgc3RhY2tzIChpZiBjbGVhbj1mYWxzZSlcbiAgICpcbiAgICogVGhlIHVwZGF0ZSB3b3JrZmxvdyBleGlzdHMgdG8gY2hlY2sgZm9yIGNhc2VzIHdoZXJlIGEgY2hhbmdlIHdvdWxkIGNhdXNlXG4gICAqIGEgZmFpbHVyZSB0byBhbiBleGlzdGluZyBzdGFjaywgYnV0IG5vdCBmb3IgYSBuZXdseSBjcmVhdGVkIHN0YWNrLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHJ1bkludGVnVGVzdENhc2UocnVuT3B0aW9uczogUnVuT3B0aW9ucyk6IFByb21pc2U8QXNzZXJ0aW9uUmVzdWx0cyB8IHVuZGVmaW5lZD4ge1xuICAgIGxldCBhc3NlcnRpb25SZXN1bHRzOiBBc3NlcnRpb25SZXN1bHRzIHwgdW5kZWZpbmVkO1xuXG4gICAgLy8gU2V0IHVwIGFjdHVhbFxuICAgIGxldCBhY3R1YWwgPSBhd2FpdCBDZGtUZXN0QXBwLmZvckRlcGxveW1lbnQodGhpcy5hcHBPcHRpb25zKTtcbiAgICBpZiAodGhpcy5hcHBPcHRpb25zLlRFU1RJTkdfdXNlQ29tcGFyaXNvbk91dHB1dERpcmVjdG9yeSkge1xuICAgICAgYWN0dWFsID0gYXdhaXQgQ2RrVGVzdEFwcC5mb3JDb21wYXJpc29uKHRoaXMuYXBwT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJldmlvdXNWZXJzaW9uID0gYXdhaXQgQ2RrVGVzdEFwcC5mb3JHb2xkZW5TbmFwc2hvdCh0aGlzLmFwcE9wdGlvbnMpO1xuXG4gICAgY29uc3QgYWN0dWFsVGVzdFN1aXRlID0gYXdhaXQgYWN0dWFsLnN5bnRoRm9yRGVwbG95bWVudCgpO1xuXG4gICAgaWYgKGFjdHVhbFRlc3RTdWl0ZS50eXBlID09PSAnbGVnYWN5LXRlc3Qtc3VpdGUnICYmICFwcmV2aW91c1ZlcnNpb24uaGFzT3V0cHV0KCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLnRlc3QudGVzdE5hbWV9IGlzIGEgbmV3IHRlc3QuIFBsZWFzZSB1c2UgdGhlIEludGVnVGVzdCBjb25zdHJ1Y3QgYCArXG4gICAgICAgICd0byBjb25maWd1cmUgdGhlIHRlc3RcXG4nICtcbiAgICAgICAgJ2h0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay90cmVlL21haW4vcGFja2FnZXMvJTQwYXdzLWNkay9pbnRlZy10ZXN0cy1hbHBoYScsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGNsZWFuID0gcnVuT3B0aW9ucy5jbGVhbiA/PyB0cnVlO1xuICAgIHRyeSB7XG4gICAgICBmb3IgKGNvbnN0IFt0ZXN0Q2FzZU5hbWUsIGFjdHVhbFRlc3RDYXNlXSBvZiBPYmplY3QuZW50cmllcyhhY3R1YWxUZXN0U3VpdGUudGVzdFN1aXRlKSkge1xuICAgICAgICBjb25zdCB1cGRhdGVXb3JrZmxvd0VuYWJsZWQgPSAocnVuT3B0aW9ucy51cGRhdGVXb3JrZmxvdyA/PyBmYWxzZSlcbiAgICAgICAgICAmJiAoYWN0dWFsVGVzdENhc2Uuc3RhY2tVcGRhdGVXb3JrZmxvdyA/PyBmYWxzZSk7XG4gICAgICAgIGNvbnN0IGFsbG93RGVsZXRlRmFpbHVyZXMgPSBhY3R1YWxUZXN0Q2FzZS5hbGxvd0RlbGV0ZUZhaWx1cmVzID8/IHJ1bk9wdGlvbnMuYWxsb3dEZWxldGVGYWlsdXJlcyA/PyBmYWxzZTtcblxuICAgICAgICBjb25zdCB2ZXJib3NpdHkgPSBhbmFseXplVmVyYm9zaXR5KHJ1bk9wdGlvbnMudmVyYm9zaXR5KTtcblxuICAgICAgICBpZiAoIXJ1bk9wdGlvbnMuZHJ5UnVuICYmIChhY3R1YWxUZXN0Q2FzZS5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5lbmFibGVkID8/IHRydWUpKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGFzc2VydGlvblJlc3VsdHMgPSBhd2FpdCB0aGlzLmRlcGxveVRlc3RBbmRBc3NlcnRpb25zKFxuICAgICAgICAgICAgICBhY3R1YWwsXG4gICAgICAgICAgICAgIHByZXZpb3VzVmVyc2lvbixcbiAgICAgICAgICAgICAgYWN0dWFsVGVzdENhc2UsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByb2xlQXJuOiBydW5PcHRpb25zLnJvbGVBcm4gPz8gYWN0dWFsVGVzdENhc2UuY2RrQ29tbWFuZE9wdGlvbnM/LmRlcGxveT8uYXJncz8ucm9sZUFybixcbiAgICAgICAgICAgICAgICB2ZXJib3NlOiB2ZXJib3NpdHkudmVyYm9zZSxcbiAgICAgICAgICAgICAgICBkZWJ1ZzogdmVyYm9zaXR5LmRlYnVnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB1cGRhdGVXb3JrZmxvd0VuYWJsZWQsXG4gICAgICAgICAgICAgIHRlc3RDYXNlTmFtZSxcbiAgICAgICAgICAgICAgYWxsb3dEZWxldGVGYWlsdXJlcyxcbiAgICAgICAgICAgICAgcnVuT3B0aW9ucy51cGRhdGVGcm9tVGFncyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGlmICghcnVuT3B0aW9ucy5kcnlSdW4gJiYgY2xlYW4gJiYgKGFjdHVhbFRlc3RDYXNlLmNka0NvbW1hbmRPcHRpb25zPy5kZXN0cm95Py5lbmFibGVkID8/IHRydWUpKSB7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZGVzdHJveVRlc3RBbmRBc3NlcnRpb25zKGFjdHVhbCwgYWN0dWFsVGVzdENhc2UsIHtcbiAgICAgICAgICAgICAgICAuLi5hY3R1YWxUZXN0Q2FzZS5jZGtDb21tYW5kT3B0aW9ucz8uZGVzdHJveT8uYXJncyxcbiAgICAgICAgICAgICAgICByb2xlQXJuOiBydW5PcHRpb25zLnJvbGVBcm4gPz8gYWN0dWFsVGVzdENhc2UuY2RrQ29tbWFuZE9wdGlvbnM/LmRlc3Ryb3k/LmFyZ3M/LnJvbGVBcm4sXG4gICAgICAgICAgICAgICAgdmVyYm9zZTogdmVyYm9zaXR5LnZlcmJvc2UsXG4gICAgICAgICAgICAgICAgZGVidWc6IHZlcmJvc2l0eS5kZWJ1ZyxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIG9ubHkgY3JlYXRlIHRoZSBzbmFwc2hvdCBpZiB0aGVyZSBhcmUgbm8gZmFpbGVkIGFzc2VydGlvbiByZXN1bHRzXG4gICAgICAvLyAoaS5lLiBubyBmYWlsdXJlcylcbiAgICAgIGlmICghT2JqZWN0LnZhbHVlcyhhc3NlcnRpb25SZXN1bHRzID8/IHt9KS5zb21lKHJlc3VsdCA9PiByZXN1bHQuc3RhdHVzID09PSAnZmFpbCcpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuY3JlYXRlU25hcHNob3QoYWN0dWFsVGVzdFN1aXRlLmVuYWJsZUxvb2t1cHMpO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhY3R1YWwuY2xlYW51cCgpO1xuICAgIH1cblxuICAgIHJldHVybiBhc3NlcnRpb25SZXN1bHRzO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjcmVhdGVTbmFwc2hvdChlbmFibGVMb29rdXBzOiBMZWdhY3lFbmFibGVMb29rdXBzKSB7XG4gICAgY29uc3QgZXhwZWN0ZWQgPSBhd2FpdCBDZGtUZXN0QXBwLmZvckdvbGRlblNuYXBzaG90KHRoaXMuYXBwT3B0aW9ucyk7XG4gICAgYXdhaXQgZXhwZWN0ZWQuc3ludGhGb3JHb2xkZW5TbmFwc2hvdCh0aGlzLmRlc3RydWN0aXZlQ2hhbmdlcyA/PyBbXSwgZW5hYmxlTG9va3Vwcyk7XG4gIH1cblxuICAvKipcbiAgICogUnVucyBjZGsgZGVwbG95IC0td2F0Y2ggZm9yIGFuIGludGVncmF0aW9uIHRlc3RcbiAgICpcbiAgICogVGhpcyBpcyBtZWFudCB0byBiZSBydW4gb24gYSBzaW5nbGUgdGVzdCBhbmQgd2lsbCBub3QgY3JlYXRlIGEgc25hcHNob3RcbiAgICovXG4gIHB1YmxpYyBhc3luYyB3YXRjaEludGVnVGVzdChvcHRpb25zOiBXYXRjaE9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBTZXQgdXAgYWN0dWFsXG4gICAgY29uc3QgYWN0dWFsID0gYXdhaXQgQ2RrVGVzdEFwcC5mb3JEZXBsb3ltZW50KHRoaXMuYXBwT3B0aW9ucyk7XG4gICAgYXdhaXQgYWN0dWFsLnN5bnRoRm9yRGVwbG95bWVudCgpO1xuXG4gICAgLy8gSnVzdCB0YWtlIHRoZSBmaXJzdCB0ZXN0IGNhc2UsIHRoYXQncyB0aGUgb25lIHdlIHdhdGNoLlxuICAgIC8vIE5vdCBldmVuIHN1cmUgaG93IGJldHRlciBiZWhhdmlvciBoZXJlIGlzIHBvc3NpYmxlLCBidXQgd2F0Y2ggaXNuJ3QgdXNlZCB0aGF0IG9mdGVuLlxuICAgIGNvbnN0IGZpcnN0VGVzdENhc2VOYW1lID0gT2JqZWN0LmtleXMoYWN0dWFsLnRlc3RDYXNlcygpKVswXTtcblxuICAgIGNvbnN0IHZlcmJvc2l0eSA9IGFuYWx5emVWZXJib3NpdHkob3B0aW9ucy52ZXJib3NpdHkpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndhdGNoKFxuICAgICAgICBhY3R1YWwsXG4gICAgICAgIGZpcnN0VGVzdENhc2VOYW1lLFxuICAgICAgICB7XG4gICAgICAgICAgLi4uREVGQVVMVF9BUkdTLFxuICAgICAgICAgIGRlcGxveW1lbnRNZXRob2Q6IHtcbiAgICAgICAgICAgIG1ldGhvZDogJ2hvdHN3YXAnLFxuICAgICAgICAgICAgZmFsbGJhY2s6IHtcbiAgICAgICAgICAgICAgbWV0aG9kOiAnY2hhbmdlLXNldCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJvZmlsZTogdGhpcy5hcHBPcHRpb25zLnByb2ZpbGUsXG4gICAgICAgICAgcmVxdWlyZUFwcHJvdmFsOiBSZXF1aXJlQXBwcm92YWwuTkVWRVIsXG4gICAgICAgICAgdHJhY2VMb2dzOiB2ZXJib3NpdHkudHJhY2VMb2dzID8/IGZhbHNlLFxuICAgICAgICAgIHZlcmJvc2U6IHZlcmJvc2l0eS52ZXJib3NlLFxuICAgICAgICAgIGRlYnVnOiB2ZXJib3NpdHkuZGVidWcsXG4gICAgICAgICAgcm9sZUFybjogb3B0aW9ucy5yb2xlQXJuLFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25zLnZlcmJvc2l0eSA/PyAwLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja291dCB0aGUgc25hcHNob3QgZGlyZWN0b3J5IGF0IGEgc3BlY2lmaWMgZ2l0IHJlZiAodGFnLCBjb21taXQsIGJyYW5jaCkuXG4gICAqIEZhaWxzIGZhc3QgaWYgdGhlIHNuYXBzaG90IGRvZXMgbm90IGV4aXN0IGF0IHRoZSBnaXZlbiByZWYuXG4gICAqL1xuICBwcml2YXRlIGNoZWNrb3V0U25hcHNob3RBdFJlZihzbmFwc2hvdEFwcDogQ2RrVGVzdEFwcCwgcmVmOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBnaXRDd2QgPSBwYXRoLmRpcm5hbWUoc25hcHNob3RBcHAub3V0cHV0RGlyZWN0b3J5KTtcbiAgICBjb25zdCBnaXQgPSBbJ2dpdCcsICctQycsIGdpdEN3ZF07XG4gICAgY29uc3QgcmVsYXRpdmVTbmFwc2hvdERpciA9IHBhdGgucmVsYXRpdmUoZ2l0Q3dkLCBzbmFwc2hvdEFwcC5vdXRwdXREaXJlY3RvcnkpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGV4ZWMoWy4uLmdpdCwgJ2NoZWNrb3V0JywgcmVmLCAnLS0nLCByZWxhdGl2ZVNuYXBzaG90RGlyXSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgU25hcHNob3QgZG9lcyBub3QgZXhpc3QgYXQgdGFnICcke3JlZn0nLiBgICtcbiAgICAgICAgYFBhdGg6ICR7cmVsYXRpdmVTbmFwc2hvdERpcn1cXG5gICtcbiAgICAgICAgYFVuZGVybHlpbmcgZXJyb3I6ICR7Zm9ybWF0RXJyb3IoZSl9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlcGxveSB0aGUgc25hcHNob3QgZnJvbSBlYWNoIGdpdCB0YWcgaW4gc2VxdWVuY2UsIHRoZW4gbGV0IHRoZSBjYWxsZXJcbiAgICogZGVwbG95IHRoZSBjdXJyZW50IGNvZGUgYXMgdGhlIGZpbmFsIHVwZGF0ZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZGVwbG95RnJvbVRhZ3MoXG4gICAgYWN0dWFsQXBwOiBDZGtUZXN0QXBwLFxuICAgIGRlcGxveUFyZ3M6IGNkay5EZXBsb3lPcHRpb25zLFxuICAgIHRlc3RDYXNlTmFtZTogc3RyaW5nLFxuICAgIHRhZ3M6IHN0cmluZ1tdLFxuICAgIGFsbG93RGVsZXRlRmFpbHVyZXM6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRvdGFsVGFncyA9IHRhZ3MubGVuZ3RoO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b3RhbFRhZ3M7IGkrKykge1xuICAgICAgY29uc3QgdGFnID0gdGFnc1tpXTtcbiAgICAgIGxvZ2dlci5oaWdobGlnaHQoYCR7dGhpcy50ZXN0LnRlc3ROYW1lfS8ke3Rlc3RDYXNlTmFtZX06IGRlcGxveWluZyB0YWcgJHt0YWd9ICgke2kgKyAxfS8ke3RvdGFsVGFnc30pYCk7XG5cbiAgICAgIHRoaXMuY2hlY2tvdXRTbmFwc2hvdEF0UmVmKGFjdHVhbEFwcCwgdGFnKTtcblxuICAgICAgY29uc3QgZXhwZWN0ZWRUZXN0U3VpdGUgPSBhY3R1YWxBcHAudGVzdFN1aXRlO1xuICAgICAgaWYgKCFleHBlY3RlZFRlc3RTdWl0ZSB8fCAhKHRlc3RDYXNlTmFtZSBpbiBleHBlY3RlZFRlc3RTdWl0ZS50ZXN0U3VpdGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgVGVzdCBjYXNlICcke3Rlc3RDYXNlTmFtZX0nIGRvZXMgbm90IGV4aXN0IGluIHNuYXBzaG90IGF0IHRhZyAnJHt0YWd9J2AsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4cGVjdGVkVGVzdENhc2UgPSBleHBlY3RlZFRlc3RTdWl0ZS50ZXN0U3VpdGVbdGVzdENhc2VOYW1lXTtcbiAgICAgIGNvbnN0IGRlcGxveVJlc3VsdCA9IGF3YWl0IGFjdHVhbEFwcC5kZXBsb3koe1xuICAgICAgICAuLi5kZXBsb3lBcmdzLFxuICAgICAgICBzdGFja3M6IGV4cGVjdGVkVGVzdENhc2Uuc3RhY2tzLFxuICAgICAgICAuLi5leHBlY3RlZFRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzLFxuICAgICAgICBjb250ZXh0OiBleHBlY3RlZFRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzPy5jb250ZXh0LFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChkZXBsb3lSZXN1bHQuZGVsZXRlRmFpbHVyZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBkZXRhaWxzID0gZGVwbG95UmVzdWx0LmRlbGV0ZUZhaWx1cmVzXG4gICAgICAgICAgLm1hcChmID0+IGAgIC0gJHtmLmxvZ2ljYWxSZXNvdXJjZUlkfSAoJHtmLnJlc291cmNlVHlwZX0pOiAke2YucmVhc29ufWApXG4gICAgICAgICAgLmpvaW4oJ1xcbicpO1xuICAgICAgICBjb25zdCBtZXNzYWdlID1cbiAgICAgICAgICBgVXBkYXRlIGZyb20gdGFnICcke3RhZ30nOiAke2RlcGxveVJlc3VsdC5kZWxldGVGYWlsdXJlcy5sZW5ndGh9IHJlc291cmNlKHMpIGZhaWxlZCB0byBkZWxldGU6XFxuJHtkZXRhaWxzfWA7XG4gICAgICAgIGlmIChhbGxvd0RlbGV0ZUZhaWx1cmVzKSB7XG4gICAgICAgICAgbG9nZ2VyLndhcm5pbmcobWVzc2FnZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgbG9nZ2VyLmhpZ2hsaWdodChgJHthY3R1YWxBcHAudGVzdC50ZXN0TmFtZX0vJHt0ZXN0Q2FzZU5hbWV9OiBkZXBsb3lpbmcgY3VycmVudCBicmFuY2ggKGZpbmFsKWApO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZW4gcnVubmluZyBpbnRlZ3JhdGlvbiB0ZXN0cyB3aXRoIHRoZSB1cGRhdGUgcGF0aCB3b3JrZmxvd1xuICAgKiBpdCBpcyBpbXBvcnRhbnQgdGhhdCB0aGUgc25hcHNob3QgdGhhdCBpcyBkZXBsb3llZCBpcyB0aGUgY3VycmVudCBzbmFwc2hvdFxuICAgKiBmcm9tIHRoZSB1cHN0cmVhbSBicmFuY2guIEluIG9yZGVyIHRvIGd1YXJhbnRlZSB0aGF0LCBmaXJzdCBjaGVja291dCB0aGUgbGF0ZXN0XG4gICAqICh0byB0aGUgdXNlcikgc25hcHNob3QgZnJvbSB1cHN0cmVhbVxuICAgKlxuICAgKiBJdCBpcyBub3Qgc3RyYWlnaHRmb3J3YXJkIHRvIGZpZ3VyZSBvdXQgd2hhdCBicmFuY2ggdGhlIGN1cnJlbnRcbiAgICogd29ya2luZyBicmFuY2ggd2FzIGNyZWF0ZWQgZnJvbS4gVGhpcyBpcyBhIGJlc3QgZWZmb3J0IGF0dGVtcHQgdG8gZG8gc28uXG4gICAqIFRoaXMgYXNzdW1lcyB0aGF0IHRoZXJlIGlzIGFuICdvcmlnaW4nLiBgZ2l0IHJlbW90ZSBzaG93IG9yaWdpbmAgcmV0dXJucyBhIGxpc3Qgb2ZcbiAgICogYWxsIGJyYW5jaGVzIGFuZCB3ZSB0aGVuIHNlYXJjaCBmb3Igb25lIHRoYXQgc3RhcnRzIHdpdGggYEhFQUQgYnJhbmNoOiBgXG4gICAqL1xuICBwcml2YXRlIGNoZWNrb3V0U25hcHNob3QoYWN0dWFsQXBwOiBDZGtUZXN0QXBwKTogdm9pZCB7XG4gICAgLy8gV2UgdXNlIHRoZSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyB0aGUgc25hcHNob3QgdG8gcnVuIGdpdCBjb21tYW5kcyBpblxuICAgIC8vIFdlIGRvbid0IGNoYW5nZSB0aGUgY3dkIGZvciBleGVjdXRpbmcgZ2l0LCBidXQgaW5zdGVhZCB1c2UgdGhlIC1DIGZsYWdcbiAgICAvLyBAc2VlIGh0dHBzOi8vZ2l0LXNjbS5jb20vZG9jcy9naXQjRG9jdW1lbnRhdGlvbi9naXQudHh0LS1DbHRwYXRoZ3RcbiAgICAvLyBUaGlzIHdheSB3ZSBhcmUgZ3VhcmFudGVlZCB0byBvcGVyYXRlIHVuZGVyIHRoZSBjb3JyZWN0IGdpdCByZXBvLCBldmVuXG4gICAgLy8gd2hlbiBleGVjdXRpbmcgaW50ZWctcnVubmVyIGZyb20gb3V0c2lkZSB0aGUgcmVwbyB1bmRlciB0ZXN0LlxuICAgIGNvbnN0IGdpdEN3ZCA9IHBhdGguZGlybmFtZShhY3R1YWxBcHAub3V0cHV0RGlyZWN0b3J5KTtcbiAgICBjb25zdCBnaXQgPSBbJ2dpdCcsICctQycsIGdpdEN3ZF07XG5cbiAgICAvLyBodHRwczovL2dpdC1zY20uY29tL2RvY3MvZ2l0LW1lcmdlLWJhc2VcbiAgICBsZXQgYmFzZUJyYW5jaDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8vIHRyeSB0byBmaW5kIHRoZSBiYXNlIGJyYW5jaCB0aGF0IHRoZSB3b3JraW5nIGJyYW5jaCB3YXMgY3JlYXRlZCBmcm9tXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG9yaWdpbjogc3RyaW5nID0gZXhlYyhbLi4uZ2l0LCAncmVtb3RlJywgJ3Nob3cnLCAnb3JpZ2luJ10pO1xuICAgICAgY29uc3Qgb3JpZ2luTGluZXMgPSBvcmlnaW4uc3BsaXQoJ1xcbicpO1xuICAgICAgZm9yIChjb25zdCBsaW5lIG9mIG9yaWdpbkxpbmVzKSB7XG4gICAgICAgIGlmIChsaW5lLnRyaW0oKS5zdGFydHNXaXRoKCdIRUFEIGJyYW5jaDogJykpIHtcbiAgICAgICAgICBiYXNlQnJhbmNoID0gbGluZS50cmltKCkuc3BsaXQoJ0hFQUQgYnJhbmNoOiAnKVsxXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZ2dlci53YXJuaW5nKCclc1xcbiVzJyxcbiAgICAgICAgJ0NvdWxkIG5vdCBkZXRlcm1pbmUgZ2l0IG9yaWdpbiBicmFuY2guJyxcbiAgICAgICAgYFlvdSBuZWVkIHRvIG1hbnVhbGx5IGNoZWNrb3V0IHRoZSBzbmFwc2hvdCBkaXJlY3RvcnkgJHthY3R1YWxBcHAub3V0cHV0RGlyZWN0b3J5fWAgK1xuICAgICAgICAnZnJvbSB0aGUgbWVyZ2UtYmFzZSAoaHR0cHM6Ly9naXQtc2NtLmNvbS9kb2NzL2dpdC1tZXJnZS1iYXNlKScsXG4gICAgICApO1xuICAgICAgbG9nZ2VyLndhcm5pbmcoJ2Vycm9yOiAlcycsIGZvcm1hdEVycm9yKGUpKTtcbiAgICB9XG5cbiAgICAvLyBpZiB3ZSBmb3VuZCB0aGUgYmFzZSBicmFuY2ggdGhlbiBnZXQgdGhlIG1lcmdlLWJhc2UgKG1vc3QgcmVjZW50IGNvbW1vbiBjb21taXQpXG4gICAgLy8gYW5kIGNoZWNrb3V0IHRoZSBzbmFwc2hvdCB1c2luZyB0aGF0IGNvbW1pdFxuICAgIGlmIChiYXNlQnJhbmNoKSB7XG4gICAgICBjb25zdCByZWxhdGl2ZVNuYXBzaG90RGlyID0gcGF0aC5yZWxhdGl2ZShnaXRDd2QsIGFjdHVhbEFwcC5vdXRwdXREaXJlY3RvcnkpO1xuXG4gICAgICBjb25zdCBjaGVja291dENvbW1hbmQgPSBbLi4uZ2l0LCAnY2hlY2tvdXQnLCBbLi4uZ2l0LCAnbWVyZ2UtYmFzZScsICdIRUFEJywgYmFzZUJyYW5jaF0sICctLScsIHJlbGF0aXZlU25hcHNob3REaXJdO1xuICAgICAgdHJ5IHtcbiAgICAgICAgZXhlY1dpdGhTdWJTaGVsbChjaGVja291dENvbW1hbmQpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIud2FybmluZygnJXNcXG4lcycsXG4gICAgICAgICAgYENvdWxkIG5vdCBjaGVja291dCBzbmFwc2hvdCBkaXJlY3RvcnkgJyR7YWN0dWFsQXBwLm91dHB1dERpcmVjdG9yeX0nLiBQbGVhc2UgdmVyaWZ5IHRoZSBmb2xsb3dpbmcgY29tbWFuZCBjb21wbGV0ZXMgY29ycmVjdGx5OmAsXG4gICAgICAgICAgcmVuZGVyQ29tbWFuZChjaGVja291dENvbW1hbmQpLFxuICAgICAgICAgICcnLFxuICAgICAgICApO1xuICAgICAgICBsb2dnZXIud2FybmluZygnZXJyb3I6ICVzJywgZm9ybWF0RXJyb3IoZSkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIGEgaW50ZWcgdGVzdCBjYXNlIHN0YWNrIGRlc3RydWN0aW9uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRlc3Ryb3lUZXN0QW5kQXNzZXJ0aW9ucyhhY3R1YWxBcHA6IENka1Rlc3RBcHAsIGFjdHVhbFRlc3RDYXNlOiBUZXN0Q2FzZSwgZGVzdHJveUFyZ3M6IFBhcnRpYWw8RGVzdHJveU9wdGlvbnM+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChhY3R1YWxUZXN0Q2FzZS5ob29rcz8ucHJlRGVzdHJveSkge1xuICAgICAgICBhY3R1YWxUZXN0Q2FzZS5ob29rcy5wcmVEZXN0cm95LmZvckVhY2goY21kID0+IHtcbiAgICAgICAgICBleGVjKGNodW5rcyhjbWQpLCB7XG4gICAgICAgICAgICBjd2Q6IHBhdGguZGlybmFtZShhY3R1YWxBcHAub3V0cHV0RGlyZWN0b3J5KSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGFjdHVhbEFwcC5kZXN0cm95KHtcbiAgICAgICAgc3RhY2tzOiBbXG4gICAgICAgICAgLi4uYWN0dWFsVGVzdENhc2Uuc3RhY2tzLFxuICAgICAgICAgIC4uLihhY3R1YWxUZXN0Q2FzZS5hc3NlcnRpb25TdGFjayA/IFthY3R1YWxUZXN0Q2FzZS5hc3NlcnRpb25TdGFja10gOiBbXSksXG4gICAgICAgIF0sXG4gICAgICAgIC4uLmRlc3Ryb3lBcmdzLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChhY3R1YWxUZXN0Q2FzZS5ob29rcz8ucG9zdERlc3Ryb3kpIHtcbiAgICAgICAgYWN0dWFsVGVzdENhc2UuaG9va3MucG9zdERlc3Ryb3kuZm9yRWFjaChjbWQgPT4ge1xuICAgICAgICAgIGV4ZWMoY2h1bmtzKGNtZCksIHtcbiAgICAgICAgICAgIGN3ZDogcGF0aC5kaXJuYW1lKGFjdHVhbEFwcC5vdXRwdXREaXJlY3RvcnkpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLnBhcnNlRXJyb3IoZSxcbiAgICAgICAgYWN0dWFsVGVzdENhc2UuY2RrQ29tbWFuZE9wdGlvbnM/LmRlc3Ryb3k/LmV4cGVjdEVycm9yID8/IGZhbHNlLFxuICAgICAgICBhY3R1YWxUZXN0Q2FzZS5jZGtDb21tYW5kT3B0aW9ucz8uZGVzdHJveT8uZXhwZWN0ZWRNZXNzYWdlLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHdhdGNoKGFjdHVhbEFwcDogQ2RrVGVzdEFwcCwgdGVzdENhc2VOYW1lOiBzdHJpbmcsIG9wdGlvbnM6IGNkay5XYXRjaE9wdGlvbnMsIHZlcmJvc2l0eTogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYWN0dWFsVGVzdFN1aXRlID0gYWN0dWFsQXBwLnRlc3RTdWl0ZTtcblxuICAgIGNvbnN0IGFjdHVhbFRlc3RDYXNlID0gYWN0dWFsQXBwLnRlc3RDYXNlcygpW3Rlc3RDYXNlTmFtZV07XG5cbiAgICBpZiAoYWN0dWFsVGVzdENhc2UuaG9va3M/LnByZURlcGxveSkge1xuICAgICAgYWN0dWFsVGVzdENhc2UuaG9va3MucHJlRGVwbG95LmZvckVhY2goY21kID0+IHtcbiAgICAgICAgZXhlYyhjaHVua3MoY21kKSwge1xuICAgICAgICAgIGN3ZDogcGF0aC5kaXJuYW1lKGFjdHVhbEFwcC5vdXRwdXREaXJlY3RvcnkpLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zdCB3YXRjaEFyZ3MgPSB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgbG9va3VwczogYWN0dWFsVGVzdFN1aXRlLmVuYWJsZUxvb2t1cHMsXG4gICAgICBzdGFja3M6IFtcbiAgICAgICAgLi4uYWN0dWFsVGVzdENhc2Uuc3RhY2tzLFxuICAgICAgICAuLi5hY3R1YWxUZXN0Q2FzZS5hc3NlcnRpb25TdGFjayA/IFthY3R1YWxUZXN0Q2FzZS5hc3NlcnRpb25TdGFja10gOiBbXSxcbiAgICAgIF0sXG4gICAgICBvdXRwdXQ6IGFjdHVhbEFwcC5vdXRwdXREaXJlY3RvcnksXG4gICAgICBvdXRwdXRzRmlsZTogcGF0aC5qb2luKGFjdHVhbEFwcC5vdXRwdXREaXJlY3RvcnksICdhc3NlcnRpb24tcmVzdWx0cy5qc29uJyksXG4gICAgICAuLi5hY3R1YWxUZXN0Q2FzZT8uY2RrQ29tbWFuZE9wdGlvbnM/LmRlcGxveT8uYXJncyxcbiAgICAgIGNvbnRleHQ6IGFjdHVhbFRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzPy5jb250ZXh0LFxuICAgIH07XG4gICAgY29uc3QgZGVzdHJveU1lc3NhZ2UgPSB7XG4gICAgICBhZGRpdGlvbmFsTWVzc2FnZXM6IFtcbiAgICAgICAgJ0FmdGVyIHlvdSBhcmUgZG9uZSB5b3UgbXVzdCBtYW51YWxseSBkZXN0cm95IHRoZSBkZXBsb3llZCBzdGFja3MnLFxuICAgICAgICBgICAke1tcbiAgICAgICAgICAuLi5wcm9jZXNzLmVudi5BV1NfUkVHSU9OID8gW2BBV1NfUkVHSU9OPSR7cHJvY2Vzcy5lbnYuQVdTX1JFR0lPTn1gXSA6IFtdLFxuICAgICAgICAgICdjZGsgZGVzdHJveScsXG4gICAgICAgICAgYC1hICcke2FjdHVhbEFwcC5hcHBDb21tYW5kfSdgLFxuICAgICAgICAgIHdhdGNoQXJncy5zdGFja3Muam9pbignICcpLFxuICAgICAgICAgIGAtLXByb2ZpbGUgJHt3YXRjaEFyZ3MucHJvZmlsZX1gLFxuICAgICAgICBdLmpvaW4oJyAnKX1gLFxuICAgICAgXSxcbiAgICB9O1xuICAgIHdvcmtlcnBvb2wud29ya2VyRW1pdChkZXN0cm95TWVzc2FnZSk7XG4gICAgaWYgKHdhdGNoQXJncy52ZXJib3NlKSB7XG4gICAgICAvLyBpZiBgLXZ2dmAgKG9yIGFib3ZlKSBpcyB1c2VkIHRoZW4gcHJpbnQgb3V0IHRoZSBjb21tYW5kIHRoYXQgd2FzIHVzZWRcbiAgICAgIC8vIHRoaXMgYWxsb3dzIHVzZXJzIHRvIG1hbnVhbGx5IHJ1biB0aGUgY29tbWFuZFxuICAgICAgd29ya2VycG9vbC53b3JrZXJFbWl0KHtcbiAgICAgICAgYWRkaXRpb25hbE1lc3NhZ2VzOiBbXG4gICAgICAgICAgJ1JlcHJvOicsXG4gICAgICAgICAgYCAgJHthY3R1YWxBcHAuc3ludGhSZXByb0NvbW1hbmR9YCxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGFzc2VydGlvblJlc3VsdHMgPSBwYXRoLmpvaW4oYWN0dWFsQXBwLm91dHB1dERpcmVjdG9yeSwgJ2Fzc2VydGlvbi1yZXN1bHRzLmpzb24nKTtcbiAgICBjb25zdCB3YXRjaGVyID0gY2hva2lkYXIud2F0Y2goW2FjdHVhbEFwcC5vdXRwdXREaXJlY3RvcnldLCB7XG4gICAgICBjd2Q6IGFjdHVhbEFwcC5vdXRwdXREaXJlY3RvcnksXG4gICAgfSk7XG4gICAgd2F0Y2hlci5vbignYWxsJywgKGV2ZW50OiBFdmVudE5hbWUsIGZpbGU6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKCFpc0ZpbGVFdmVudChldmVudCkpIHtcbiAgICAgICAgcmV0dXJuOyAvLyBJZ25vcmUgbm9uLWZpbGUgZXZlbnRzIGxpa2UgJ2Vycm9yJywgJ3JhdycsICdyZWFkeScsICdhbGwnXG4gICAgICB9XG4gICAgICAvLyB3ZSBvbmx5IGNhcmUgYWJvdXQgY2hhbmdlcyB0byB0aGUgYGFzc2VydGlvbi1yZXN1bHRzLmpzb25gIGZpbGUuIElmIHRoZXJlXG4gICAgICAvLyBhcmUgYXNzZXJ0aW9ucyB0aGVuIHRoaXMgd2lsbCBjaGFuZ2Ugb24gZXZlcnkgZGVwbG95bWVudFxuICAgICAgaWYgKGFzc2VydGlvblJlc3VsdHMuZW5kc1dpdGgoZmlsZSkgJiYgKGV2ZW50ID09PSAnYWRkJyB8fCBldmVudCA9PT0gJ2NoYW5nZScpKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgaWYgKGFjdHVhbFRlc3RDYXNlLmhvb2tzPy5wb3N0RGVwbG95KSB7XG4gICAgICAgICAgYWN0dWFsVGVzdENhc2UuaG9va3MucG9zdERlcGxveS5mb3JFYWNoKGNtZCA9PiB7XG4gICAgICAgICAgICBleGVjKGNodW5rcyhjbWQpLCB7XG4gICAgICAgICAgICAgIGN3ZDogcGF0aC5kaXJuYW1lKGFjdHVhbEFwcC5vdXRwdXREaXJlY3RvcnkpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYWN0dWFsVGVzdENhc2UuYXNzZXJ0aW9uU3RhY2sgJiYgYWN0dWFsVGVzdENhc2UuYXNzZXJ0aW9uU3RhY2tOYW1lKSB7XG4gICAgICAgICAgY29uc3QgcmVzID0gdGhpcy5wcm9jZXNzQXNzZXJ0aW9uUmVzdWx0cyhcbiAgICAgICAgICAgIGFzc2VydGlvblJlc3VsdHMsXG4gICAgICAgICAgICBhY3R1YWxUZXN0Q2FzZS5hc3NlcnRpb25TdGFja05hbWUsXG4gICAgICAgICAgICBhY3R1YWxUZXN0Q2FzZS5hc3NlcnRpb25TdGFjayxcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChyZXMgJiYgT2JqZWN0LnZhbHVlcyhyZXMpLnNvbWUociA9PiByLnN0YXR1cyA9PT0gJ2ZhaWwnKSkge1xuICAgICAgICAgICAgd29ya2VycG9vbC53b3JrZXJFbWl0KHtcbiAgICAgICAgICAgICAgcmVhc29uOiBEaWFnbm9zdGljUmVhc29uLkFTU0VSVElPTl9GQUlMRUQsXG4gICAgICAgICAgICAgIHRlc3ROYW1lOiBgJHt0ZXN0Q2FzZU5hbWV9ICgke3dhdGNoQXJncy5wcm9maWxlfWAsXG4gICAgICAgICAgICAgIG1lc3NhZ2U6IGZvcm1hdEFzc2VydGlvblJlc3VsdHMocmVzKSxcbiAgICAgICAgICAgICAgZHVyYXRpb246IChEYXRlLm5vdygpIC0gc3RhcnQpIC8gMTAwMCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3b3JrZXJwb29sLndvcmtlckVtaXQoe1xuICAgICAgICAgICAgICByZWFzb246IERpYWdub3N0aWNSZWFzb24uVEVTVF9TVUNDRVNTLFxuICAgICAgICAgICAgICB0ZXN0TmFtZTogYCR7dGVzdENhc2VOYW1lfWAsXG4gICAgICAgICAgICAgIG1lc3NhZ2U6IHJlcyA/IGZvcm1hdEFzc2VydGlvblJlc3VsdHMocmVzKSA6ICdOTyBBU1NFUlRJT05TJyxcbiAgICAgICAgICAgICAgZHVyYXRpb246IChEYXRlLm5vdygpIC0gc3RhcnQpIC8gMTAwMCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBlbWl0IHRoZSBkZXN0cm95IG1lc3NhZ2UgYWZ0ZXIgZXZlcnkgcnVuXG4gICAgICAgICAgLy8gc28gdGhhdCBpdCdzIHZpc2libGUgdG8gdGhlIHVzZXJcbiAgICAgICAgICB3b3JrZXJwb29sLndvcmtlckVtaXQoZGVzdHJveU1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICB3YXRjaGVyLm9uKCdyZWFkeScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmVzb2x2ZSh7fSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHsgcHJvbWlzZTogd2FpdGVyLCByZXNvbHZlIH0gPSBwcm9taXNlV2l0aFJlc29sdmVyczxudW1iZXIgfCBudWxsPigpO1xuXG4gICAgYXdhaXQgYWN0dWFsQXBwLndhdGNoKHdhdGNoQXJncywge1xuICAgICAgLy8gaWYgYC12YCAob3IgYWJvdmUpIGlzIHBhc3NlZCB0aGVuIHN0cmVhbSB0aGUgbG9nc1xuICAgICAgb25TdGRvdXQ6IChtZXNzYWdlKSA9PiB7XG4gICAgICAgIGlmICh2ZXJib3NpdHkgPiAwKSB7XG4gICAgICAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICAvLyBpZiBgLXZgIChvciBhYm92ZSkgaXMgcGFzc2VkIHRoZW4gc3RyZWFtIHRoZSBsb2dzXG4gICAgICBvblN0ZGVycjogKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgaWYgKHZlcmJvc2l0eSA+IDApIHtcbiAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIG9uQ2xvc2U6IGFzeW5jIChjb2RlKSA9PiB7XG4gICAgICAgIGlmIChjb2RlICE9PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXYXRjaCBleGl0ZWQgd2l0aCBlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHdhdGNoZXIuY2xvc2UoKTtcbiAgICAgICAgcmVzb2x2ZShjb2RlKTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBhd2FpdCB3YWl0ZXI7XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSBhIGludGVnIHRlc3QgY2FzZSBkZXBsb3ltZW50LCBpbmNsdWRpbmdcbiAgICogcGVyZm9ybWluZyB0aGUgdXBkYXRlIHdvcmtmbG93XG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRlcGxveVRlc3RBbmRBc3NlcnRpb25zKFxuICAgIGFwcDogQ2RrVGVzdEFwcCxcbiAgICBwcmV2aW91c1ZlcnNpb246IENka1Rlc3RBcHAsXG4gICAgdGVzdENhc2U6IFRlc3RDYXNlLFxuICAgIGRlcGxveUFyZ3M6IGNkay5EZXBsb3lPcHRpb25zLFxuICAgIHVwZGF0ZVdvcmtmbG93RW5hYmxlZDogYm9vbGVhbixcbiAgICB0ZXN0Q2FzZU5hbWU6IHN0cmluZyxcbiAgICBhbGxvd0RlbGV0ZUZhaWx1cmVzOiBib29sZWFuLFxuICAgIHVwZGF0ZUZyb21UYWdzPzogc3RyaW5nW10sXG4gICk6IFByb21pc2U8QXNzZXJ0aW9uUmVzdWx0cyB8IHVuZGVmaW5lZD4ge1xuICAgIHRyeSB7XG4gICAgICBpZiAodGVzdENhc2UuaG9va3M/LnByZURlcGxveSkge1xuICAgICAgICB0ZXN0Q2FzZS5ob29rcy5wcmVEZXBsb3kuZm9yRWFjaChjbWQgPT4ge1xuICAgICAgICAgIGV4ZWMoY2h1bmtzKGNtZCksIHtcbiAgICAgICAgICAgIGN3ZDogcGF0aC5kaXJuYW1lKGFwcC5vdXRwdXREaXJlY3RvcnkpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmICh1cGRhdGVGcm9tVGFncyAmJiB1cGRhdGVGcm9tVGFncy5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIFRhZy1zZXF1ZW5jZSB1cGRhdGUgd29ya2Zsb3c6IGRlcGxveSBlYWNoIHRhZydzIHNuYXBzaG90IGluIG9yZGVyXG4gICAgICAgIGF3YWl0IHRoaXMuZGVwbG95RnJvbVRhZ3MoYXBwLCBkZXBsb3lBcmdzLCB0ZXN0Q2FzZU5hbWUsIHVwZGF0ZUZyb21UYWdzLCBhbGxvd0RlbGV0ZUZhaWx1cmVzKTtcbiAgICAgIH0gZWxzZSBpZiAodXBkYXRlV29ya2Zsb3dFbmFibGVkICYmIGF3YWl0IHByZXZpb3VzVmVyc2lvbi5oYXNPdXRwdXQoKSkge1xuICAgICAgICAvLyBOb3JtYWwgbWVyZ2UtYmFzZSB1cGRhdGUgd29ya2Zsb3dcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRUZXN0U3VpdGUgPSBhd2FpdCBwcmV2aW91c1ZlcnNpb24ubG9hZEV4aXN0aW5nU3VpdGUoKTtcbiAgICAgICAgaWYgKGV4cGVjdGVkVGVzdFN1aXRlICYmIHRlc3RDYXNlTmFtZSBpbiBleHBlY3RlZFRlc3RTdWl0ZT8udGVzdFN1aXRlKSB7XG4gICAgICAgICAgdGhpcy5jaGVja291dFNuYXBzaG90KHByZXZpb3VzVmVyc2lvbik7XG4gICAgICAgICAgY29uc3QgZXhwZWN0ZWRUZXN0Q2FzZSA9IGV4cGVjdGVkVGVzdFN1aXRlLnRlc3RTdWl0ZVt0ZXN0Q2FzZU5hbWVdO1xuXG4gICAgICAgICAgYXdhaXQgcHJldmlvdXNWZXJzaW9uLmRlcGxveSh7XG4gICAgICAgICAgICAuLi5kZXBsb3lBcmdzLFxuICAgICAgICAgICAgc3RhY2tzOiBleHBlY3RlZFRlc3RDYXNlLnN0YWNrcyxcbiAgICAgICAgICAgIC4uLmV4cGVjdGVkVGVzdENhc2U/LmNka0NvbW1hbmRPcHRpb25zPy5kZXBsb3k/LmFyZ3MsXG4gICAgICAgICAgICBjb250ZXh0OiBleHBlY3RlZFRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzPy5jb250ZXh0LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIG5vdyBkZXBsb3kgdGhlIFwiYWN0dWFsXCIgdGVzdC5cbiAgICAgIC8vIFRoaXMgaXMgdGhlIHN0YWNrIHVwZGF0ZSBpZiB0aGUgdXBkYXRlIHdvcmtmbG93IHJhbiBhYm92ZS5cbiAgICAgIGNvbnN0IGFjdHVhbERlcGxveVJlc3VsdCA9IGF3YWl0IGFwcC5kZXBsb3koe1xuICAgICAgICAuLi5kZXBsb3lBcmdzLFxuICAgICAgICBzdGFja3M6IHRlc3RDYXNlLnN0YWNrcyxcbiAgICAgICAgLi4udGVzdENhc2U/LmNka0NvbW1hbmRPcHRpb25zPy5kZXBsb3k/LmFyZ3MsXG4gICAgICAgIGNvbnRleHQ6IHRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzPy5jb250ZXh0LFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChhY3R1YWxEZXBsb3lSZXN1bHQuZGVsZXRlRmFpbHVyZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBkZXRhaWxzID0gYWN0dWFsRGVwbG95UmVzdWx0LmRlbGV0ZUZhaWx1cmVzXG4gICAgICAgICAgLm1hcChmID0+IGAgIC0gJHtmLmxvZ2ljYWxSZXNvdXJjZUlkfSAoJHtmLnJlc291cmNlVHlwZX0pOiAke2YucmVhc29ufWApXG4gICAgICAgICAgLmpvaW4oJ1xcbicpO1xuICAgICAgICBjb25zdCBtZXNzYWdlID1cbiAgICAgICAgICBgJHthY3R1YWxEZXBsb3lSZXN1bHQuZGVsZXRlRmFpbHVyZXMubGVuZ3RofSByZXNvdXJjZShzKSBmYWlsZWQgdG8gZGVsZXRlIGR1cmluZyBzdGFjayB1cGRhdGU6XFxuJHtkZXRhaWxzfVxcbmAgK1xuICAgICAgICAgICdUaGVzZSByZXNvdXJjZXMgYXJlIG5vIGxvbmdlciBtYW5hZ2VkIGJ5IENsb3VkRm9ybWF0aW9uIGJ1dCBzdGlsbCBleGlzdCBhbmQgbWF5IGluY3VyIGNoYXJnZXMuJztcbiAgICAgICAgaWYgKGFsbG93RGVsZXRlRmFpbHVyZXMpIHtcbiAgICAgICAgICBsb2dnZXIud2FybmluZyhtZXNzYWdlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhlcmUgYXJlIGFueSBhc3NlcnRpb25zXG4gICAgICAvLyBkZXBsb3kgdGhlIGFzc2VydGlvbiBzdGFjayBhcyB3ZWxsXG4gICAgICAvLyBUaGlzIGlzIHNlcGFyYXRlIGZyb20gdGhlIGFib3ZlIGRlcGxveW1lbnQgYmVjYXVzZSB3ZSB3YW50IHRvXG4gICAgICAvLyBzZXQgYHJvbGxiYWNrOiBmYWxzZWAuIFRoaXMgYWxsb3dzIHRoZSBhc3NlcnRpb24gc3RhY2sgdG8gZGVwbG95IGFsbCB0aGVcbiAgICAgIC8vIGFzc2VydGlvbnMgaW5zdGVhZCBvZiBmYWlsaW5nIGF0IHRoZSBmaXJzdCBmYWlsZWQgYXNzZXJ0aW9uXG4gICAgICAvLyBjb21iaW5pbmcgaXQgd2l0aCB0aGUgYWJvdmUgZGVwbG95bWVudCB3b3VsZCBwcmV2ZW50IGFueSByZXBsYWNlbWVudCB1cGRhdGVzXG4gICAgICBpZiAodGVzdENhc2UuYXNzZXJ0aW9uU3RhY2spIHtcbiAgICAgICAgYXdhaXQgYXBwLmRlcGxveSh7XG4gICAgICAgICAgLi4uZGVwbG95QXJncyxcbiAgICAgICAgICBzdGFja3M6IFtcbiAgICAgICAgICAgIHRlc3RDYXNlLmFzc2VydGlvblN0YWNrLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgcm9sbGJhY2s6IGZhbHNlLFxuICAgICAgICAgIC4uLnRlc3RDYXNlPy5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5hcmdzLFxuICAgICAgICAgIG91dHB1dHNGaWxlOiBwYXRoLmpvaW4oYXBwLm91dHB1dERpcmVjdG9yeSwgJ2Fzc2VydGlvbi1yZXN1bHRzLmpzb24nKSxcbiAgICAgICAgICBjb250ZXh0OiB0ZXN0Q2FzZT8uY2RrQ29tbWFuZE9wdGlvbnM/LmRlcGxveT8uYXJncz8uY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0ZXN0Q2FzZS5ob29rcz8ucG9zdERlcGxveSkge1xuICAgICAgICB0ZXN0Q2FzZS5ob29rcy5wb3N0RGVwbG95LmZvckVhY2goY21kID0+IHtcbiAgICAgICAgICBleGVjKGNodW5rcyhjbWQpLCB7XG4gICAgICAgICAgICBjd2Q6IHBhdGguZGlybmFtZShhcHAub3V0cHV0RGlyZWN0b3J5KSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0ZXN0Q2FzZS5hc3NlcnRpb25TdGFjayAmJiB0ZXN0Q2FzZS5hc3NlcnRpb25TdGFja05hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0Fzc2VydGlvblJlc3VsdHMoXG4gICAgICAgICAgcGF0aC5qb2luKGFwcC5vdXRwdXREaXJlY3RvcnksICdhc3NlcnRpb24tcmVzdWx0cy5qc29uJyksXG4gICAgICAgICAgdGVzdENhc2UuYXNzZXJ0aW9uU3RhY2tOYW1lLFxuICAgICAgICAgIHRlc3RDYXNlLmFzc2VydGlvblN0YWNrLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMucGFyc2VFcnJvcihlLFxuICAgICAgICB0ZXN0Q2FzZS5jZGtDb21tYW5kT3B0aW9ucz8uZGVwbG95Py5leHBlY3RFcnJvciA/PyBmYWxzZSxcbiAgICAgICAgdGVzdENhc2UuY2RrQ29tbWFuZE9wdGlvbnM/LmRlcGxveT8uZXhwZWN0ZWRNZXNzYWdlLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2Nlc3MgdGhlIG91dHB1dHNGaWxlIHdoaWNoIGNvbnRhaW5zIHRoZSBhc3NlcnRpb25zIHJlc3VsdHMgYXMgc3RhY2tcbiAgICogb3V0cHV0c1xuICAgKi9cbiAgcHJpdmF0ZSBwcm9jZXNzQXNzZXJ0aW9uUmVzdWx0cyhmaWxlOiBzdHJpbmcsIGFzc2VydGlvblN0YWNrTmFtZTogc3RyaW5nLCBhc3NlcnRpb25TdGFja0lkOiBzdHJpbmcpOiBBc3NlcnRpb25SZXN1bHRzIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCByZXN1bHRzOiBBc3NlcnRpb25SZXN1bHRzID0ge307XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoZmlsZSkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG91dHB1dHM6IHsgW2tleTogc3RyaW5nXTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB9ID0gZnMucmVhZEpTT05TeW5jKGZpbGUpO1xuXG4gICAgICAgIGlmIChhc3NlcnRpb25TdGFja05hbWUgaW4gb3V0cHV0cykge1xuICAgICAgICAgIGZvciAoY29uc3QgW2Fzc2VydGlvbklkLCByZXN1bHRdIG9mIE9iamVjdC5lbnRyaWVzKG91dHB1dHNbYXNzZXJ0aW9uU3RhY2tOYW1lXSkpIHtcbiAgICAgICAgICAgIGlmIChhc3NlcnRpb25JZC5zdGFydHNXaXRoKCdBc3NlcnRpb25SZXN1bHRzJykpIHtcbiAgICAgICAgICAgICAgY29uc3QgYXNzZXJ0aW9uUmVzdWx0OiBBc3NlcnRpb25SZXN1bHQgPSBKU09OLnBhcnNlKHJlc3VsdC5yZXBsYWNlKC9cXG4vZywgJ1xcXFxuJykpO1xuICAgICAgICAgICAgICBpZiAoYXNzZXJ0aW9uUmVzdWx0LnN0YXR1cyA9PT0gJ2ZhaWwnIHx8IGFzc2VydGlvblJlc3VsdC5zdGF0dXMgPT09ICdzdWNjZXNzJykge1xuICAgICAgICAgICAgICAgIHJlc3VsdHNbYXNzZXJ0aW9uSWRdID0gYXNzZXJ0aW9uUmVzdWx0O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGlmIHRoZXJlIGFyZSBvdXRwdXRzLCBidXQgdGhleSBjYW5ub3QgYmUgcHJvY2Vzc2VkLCB0aGVuIHRocm93IGFuIGVycm9yXG4gICAgICAgIC8vIHNvIHRoYXQgdGhlIHRlc3QgZmFpbHNcbiAgICAgICAgcmVzdWx0c1thc3NlcnRpb25TdGFja0lkXSA9IHtcbiAgICAgICAgICBzdGF0dXM6ICdmYWlsJyxcbiAgICAgICAgICBtZXNzYWdlOiBgZXJyb3IgcHJvY2Vzc2luZyBhc3NlcnRpb24gcmVzdWx0czogJHtlfWAsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICAvLyByZW1vdmUgdGhlIG91dHB1dHMgZmlsZSBzbyBpdCBpcyBub3QgcGFydCBvZiB0aGUgc25hcHNob3RcbiAgICAgICAgLy8gaXQgd2lsbCBjb250YWluIGVudiBzcGVjaWZpYyBpbmZvcm1hdGlvbiBmcm9tIHZhbHVlc1xuICAgICAgICAvLyByZXNvbHZlZCBhdCBkZXBsb3kgdGltZVxuICAgICAgICBmcy51bmxpbmtTeW5jKGZpbGUpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmtleXMocmVzdWx0cykubGVuZ3RoID4gMCA/IHJlc3VsdHMgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIGFuIGVycm9yIG1lc3NhZ2UgcmV0dXJuZWQgZnJvbSBhIENESyBjb21tYW5kXG4gICAqL1xuICBwcml2YXRlIHBhcnNlRXJyb3IoZTogdW5rbm93biwgZXhwZWN0RXJyb3I6IGJvb2xlYW4sIGV4cGVjdGVkTWVzc2FnZT86IHN0cmluZykge1xuICAgIGlmIChleHBlY3RFcnJvcikge1xuICAgICAgaWYgKGV4cGVjdGVkTWVzc2FnZSkge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gKGUgYXMgRXJyb3IpLm1lc3NhZ2U7XG4gICAgICAgIGlmICghbWVzc2FnZS5tYXRjaChleHBlY3RlZE1lc3NhZ2UpKSB7XG4gICAgICAgICAgdGhyb3cgKGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFuYWx5emVWZXJib3NpdHkodmVyYm9zaXR5OiBudW1iZXIgPSAwKTogeyB2ZXJib3NlPzogYm9vbGVhbjsgZGVidWc/OiBib29sZWFuOyB0cmFjZUxvZ3M/OiBib29sZWFuIH0ge1xuICByZXR1cm4ge1xuICAgIHZlcmJvc2U6IHZlcmJvc2l0eSA+PSAzID8gdHJ1ZSA6IHVuZGVmaW5lZCxcbiAgICBkZWJ1ZzogdmVyYm9zaXR5ID49IDQgPyB0cnVlIDogdW5kZWZpbmVkLFxuICAgIHRyYWNlTG9nczogdmVyYm9zaXR5ID49IDIgPyB0cnVlIDogZmFsc2UsXG4gIH07XG59XG4iXX0=