@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.
- package/lib/cli.d.ts.map +1 -1
- package/lib/cli.js +3 -2
- package/lib/engines/toolkit-lib.d.ts +1 -1
- package/lib/engines/toolkit-lib.d.ts.map +1 -1
- package/lib/engines/toolkit-lib.js +11 -11
- package/lib/files.d.ts +9 -0
- package/lib/files.d.ts.map +1 -0
- package/lib/files.js +51 -0
- package/lib/index.js +218 -182
- package/lib/runner/{cdk-integ-helper.d.ts → cdk-test-app.d.ts} +90 -114
- package/lib/runner/cdk-test-app.d.ts.map +1 -0
- package/lib/runner/cdk-test-app.js +584 -0
- package/lib/runner/engine.d.ts +2 -2
- package/lib/runner/engine.d.ts.map +1 -1
- package/lib/runner/engine.js +2 -2
- package/lib/runner/index.d.ts +1 -1
- package/lib/runner/index.d.ts.map +1 -1
- package/lib/runner/index.js +2 -2
- package/lib/runner/integ-test-runner.d.ts +36 -36
- package/lib/runner/integ-test-runner.d.ts.map +1 -1
- package/lib/runner/integ-test-runner.js +172 -235
- package/lib/runner/integ-test-suite.d.ts +6 -11
- package/lib/runner/integ-test-suite.d.ts.map +1 -1
- package/lib/runner/integ-test-suite.js +14 -20
- package/lib/runner/integration-tests.d.ts +12 -3
- package/lib/runner/integration-tests.d.ts.map +1 -1
- package/lib/runner/integration-tests.js +32 -8
- package/lib/runner/snapshot-test-runner.d.ts +19 -22
- package/lib/runner/snapshot-test-runner.d.ts.map +1 -1
- package/lib/runner/snapshot-test-runner.js +47 -75
- package/lib/workers/extract/extract_worker.d.ts.map +1 -1
- package/lib/workers/extract/extract_worker.js +65 -78
- package/lib/workers/extract/index.js +226955 -226979
- package/lib/workers/integ-test-worker.d.ts.map +1 -1
- package/lib/workers/integ-test-worker.js +3 -2
- package/package.json +3 -3
- package/lib/runner/cdk-integ-helper.d.ts.map +0 -1
- 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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
*
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
*
|
|
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
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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(
|
|
177
|
+
checkoutSnapshotAtRef(snapshotApp, ref) {
|
|
178
|
+
const gitCwd = path.dirname(snapshotApp.outputDirectory);
|
|
115
179
|
const git = ['git', '-C', gitCwd];
|
|
116
|
-
const relativeSnapshotDir = path.relative(gitCwd,
|
|
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.
|
|
135
|
-
this.checkoutSnapshotAtRef(tag);
|
|
136
|
-
const 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
|
|
205
|
+
const deployResult = await actualApp.deploy({
|
|
142
206
|
...deployArgs,
|
|
143
207
|
stacks: expectedTestCase.stacks,
|
|
144
208
|
...expectedTestCase?.cdkCommandOptions?.deploy?.args,
|
|
145
|
-
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(`${
|
|
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(
|
|
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 ${
|
|
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,
|
|
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 '${
|
|
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
|
|
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(
|
|
284
|
+
cwd: path.dirname(actualApp.outputDirectory),
|
|
336
285
|
});
|
|
337
286
|
});
|
|
338
287
|
}
|
|
339
|
-
await
|
|
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(
|
|
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(
|
|
355
|
-
const actualTestSuite =
|
|
356
|
-
const actualTestCase =
|
|
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(
|
|
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:
|
|
372
|
-
outputsFile: path.
|
|
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 '${
|
|
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(
|
|
412
|
-
const watcher = chokidar.watch([
|
|
413
|
-
cwd:
|
|
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(
|
|
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
|
|
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
|
|
488
|
-
const actualTestCase = (await this.actualTestSuite()).testSuite[testCaseName];
|
|
428
|
+
async deployTestAndAssertions(app, previousVersion, testCase, deployArgs, updateWorkflowEnabled, testCaseName, allowDeleteFailures, updateFromTags) {
|
|
489
429
|
try {
|
|
490
|
-
if (
|
|
491
|
-
|
|
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(
|
|
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 &&
|
|
441
|
+
else if (updateWorkflowEnabled && await previousVersion.hasOutput()) {
|
|
502
442
|
// Normal merge-base update workflow
|
|
503
|
-
const expectedTestSuite = await
|
|
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
|
|
447
|
+
await previousVersion.deploy({
|
|
508
448
|
...deployArgs,
|
|
509
449
|
stacks: expectedTestCase.stacks,
|
|
510
450
|
...expectedTestCase?.cdkCommandOptions?.deploy?.args,
|
|
511
|
-
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
|
|
457
|
+
const actualDeployResult = await app.deploy({
|
|
520
458
|
...deployArgs,
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
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 (
|
|
550
|
-
await
|
|
482
|
+
if (testCase.assertionStack) {
|
|
483
|
+
await app.deploy({
|
|
551
484
|
...deployArgs,
|
|
552
|
-
lookups: (await this.actualTestSuite()).enableLookups,
|
|
553
485
|
stacks: [
|
|
554
|
-
|
|
486
|
+
testCase.assertionStack,
|
|
555
487
|
],
|
|
556
488
|
rollback: false,
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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 (
|
|
565
|
-
|
|
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(
|
|
497
|
+
cwd: path.dirname(app.outputDirectory),
|
|
568
498
|
});
|
|
569
499
|
});
|
|
570
500
|
}
|
|
571
|
-
if (
|
|
572
|
-
return this.processAssertionResults(path.join(
|
|
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,
|
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZWctdGVzdC1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbnRlZy10ZXN0LXJ1bm5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFFN0IsMEVBQWlFO0FBQ2pFLG1EQUFxQztBQUNyQyxvREFBNkQ7QUFDN0QsNkNBQStCO0FBQy9CLHVEQUF5QztBQUV6QyxrREFBb0M7QUFDcEMsb0NBQStGO0FBRS9GLGlEQUEwRDtBQUcxRCw4Q0FBMEY7QUFFMUY7Ozs7R0FJRztBQUNILE1BQU0sV0FBVyxHQUFHLENBQUMsbUJBQU0sQ0FBQyxHQUFHLEVBQUUsbUJBQU0sQ0FBQyxNQUFNLENBQVUsQ0FBQztBQUd6RDs7R0FFRztBQUNILFNBQVMsV0FBVyxDQUFDLEtBQWdCO0lBQ25DLE9BQVEsV0FBaUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDNUQsQ0FBQztBQWlHRDs7O0dBR0c7QUFDSCxNQUFhLGVBQWU7SUFHRztJQUE0QztJQUZ4RCxJQUFJLENBQVk7SUFFakMsWUFBNkIsVUFBeUIsRUFBbUIsa0JBQXdDO1FBQXBGLGVBQVUsR0FBVixVQUFVLENBQWU7UUFBbUIsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFzQjtRQUMvRyxJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUM7SUFDOUIsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsVUFBc0I7UUFDbEQsSUFBSSxnQkFBOEMsQ0FBQztRQUVuRCxnQkFBZ0I7UUFDaEIsSUFBSSxNQUFNLEdBQUcsTUFBTSx5QkFBVSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDN0QsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLG9DQUFvQyxFQUFFLENBQUM7WUFDekQsTUFBTSxHQUFHLE1BQU0seUJBQVUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFFRCxNQUFNLGVBQWUsR0FBRyxNQUFNLHlCQUFVLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRTVFLE1BQU0sZUFBZSxHQUFHLE1BQU0sTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFFMUQsSUFBSSxlQUFlLENBQUMsSUFBSSxLQUFLLG1CQUFtQixJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUM7WUFDakYsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxxREFBcUQ7Z0JBQ3hGLHlCQUF5QjtnQkFDekIsZ0ZBQWdGLENBQ2pGLENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUM7UUFDdkMsSUFBSSxDQUFDO1lBQ0gsS0FBSyxNQUFNLENBQUMsWUFBWSxFQUFFLGNBQWMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZGLE1BQU0scUJBQXFCLEdBQUcsQ0FBQyxVQUFVLENBQUMsY0FBYyxJQUFJLEtBQUssQ0FBQzt1QkFDN0QsQ0FBQyxjQUFjLENBQUMsbUJBQW1CLElBQUksS0FBSyxDQUFDLENBQUM7Z0JBQ25ELE1BQU0sbUJBQW1CLEdBQUcsY0FBYyxDQUFDLG1CQUFtQixJQUFJLFVBQVUsQ0FBQyxtQkFBbUIsSUFBSSxLQUFLLENBQUM7Z0JBRTFHLE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFekQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLE9BQU8sSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUN0RixJQUFJLENBQUM7d0JBQ0gsZ0JBQWdCLEdBQUcsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQ25ELE1BQU0sRUFDTixlQUFlLEVBQ2YsY0FBYyxFQUNkOzRCQUNFLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTyxJQUFJLGNBQWMsQ0FBQyxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU87NEJBQ3RGLE9BQU8sRUFBRSxTQUFTLENBQUMsT0FBTzs0QkFDMUIsS0FBSyxFQUFFLFNBQVMsQ0FBQyxLQUFLO3lCQUN2QixFQUNELHFCQUFxQixFQUNyQixZQUFZLEVBQ1osbUJBQW1CLEVBQ25CLFVBQVUsQ0FBQyxjQUFjLENBQzFCLENBQUM7b0JBQ0osQ0FBQzs0QkFBUyxDQUFDO3dCQUNULElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxJQUFJLEtBQUssSUFBSSxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsRUFBRSxPQUFPLEVBQUUsT0FBTyxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUM7NEJBQ2hHLE1BQU0sSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUU7Z0NBQzFELEdBQUcsY0FBYyxDQUFDLGlCQUFpQixFQUFFLE9BQU8sRUFBRSxJQUFJO2dDQUNsRCxPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU8sSUFBSSxjQUFjLENBQUMsaUJBQWlCLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPO2dDQUN2RixPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU87Z0NBQzFCLEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSzs2QkFDdkIsQ0FBQyxDQUFDO3dCQUNMLENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELG9FQUFvRTtZQUNwRSxxQkFBcUI7WUFDckIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsRUFBRSxDQUFDO2dCQUNwRixNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQzNELENBQUM7UUFDSCxDQUFDO2dCQUFTLENBQUM7WUFDVCxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbkIsQ0FBQztRQUVELE9BQU8sZ0JBQWdCLENBQUM7SUFDMUIsQ0FBQztJQUVPLEtBQUssQ0FBQyxjQUFjLENBQUMsYUFBa0M7UUFDN0QsTUFBTSxRQUFRLEdBQUcsTUFBTSx5QkFBVSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNyRSxNQUFNLFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLElBQUksRUFBRSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ3RGLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUFxQjtRQUMvQyxnQkFBZ0I7UUFDaEIsTUFBTSxNQUFNLEdBQUcsTUFBTSx5QkFBVSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDL0QsTUFBTSxNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUVsQywwREFBMEQ7UUFDMUQsdUZBQXVGO1FBQ3ZGLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3RCxNQUFNLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUNkLE1BQU0sRUFDTixpQkFBaUIsRUFDakI7Z0JBQ0UsR0FBRywyQkFBWTtnQkFDZixnQkFBZ0IsRUFBRTtvQkFDaEIsTUFBTSxFQUFFLFNBQVM7b0JBQ2pCLFFBQVEsRUFBRTt3QkFDUixNQUFNLEVBQUUsWUFBWTtxQkFDckI7aUJBQ0Y7Z0JBQ0QsT0FBTyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTztnQkFDaEMsZUFBZSxFQUFFLHVDQUFlLENBQUMsS0FBSztnQkFDdEMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxTQUFTLElBQUksS0FBSztnQkFDdkMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxPQUFPO2dCQUMxQixLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUs7Z0JBQ3RCLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTzthQUN6QixFQUNELE9BQU8sQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUN2QixDQUFDO1FBQ0osQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxNQUFNLENBQUMsQ0FBQztRQUNWLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0sscUJBQXFCLENBQUMsV0FBdUIsRUFBRSxHQUFXO1FBQ2hFLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3pELE1BQU0sR0FBRyxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNsQyxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUUvRSxJQUFJLENBQUM7WUFDSCxJQUFBLFlBQUksRUFBQyxDQUFDLEdBQUcsR0FBRyxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixDQUFDLENBQUMsQ0FBQztRQUM3RCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxLQUFLLENBQ2IsbUNBQW1DLEdBQUcsS0FBSztnQkFDM0MsU0FBUyxtQkFBbUIsSUFBSTtnQkFDaEMscUJBQXFCLElBQUEsb0JBQVcsRUFBQyxDQUFDLENBQUMsRUFBRSxDQUN0QyxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSyxLQUFLLENBQUMsY0FBYyxDQUMxQixTQUFxQixFQUNyQixVQUE2QixFQUM3QixZQUFvQixFQUNwQixJQUFjLEVBQ2QsbUJBQTRCO1FBRTVCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFFOUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ25DLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwQixNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksWUFBWSxtQkFBbUIsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztZQUV4RyxJQUFJLENBQUMscUJBQXFCLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRTNDLE1BQU0saUJBQWlCLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQztZQUM5QyxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxDQUFDLFlBQVksSUFBSSxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUN6RSxNQUFNLElBQUksS0FBSyxDQUNiLGNBQWMsWUFBWSx3Q0FBd0MsR0FBRyxHQUFHLENBQ3pFLENBQUM7WUFDSixDQUFDO1lBRUQsTUFBTSxnQkFBZ0IsR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDbkUsTUFBTSxZQUFZLEdBQUcsTUFBTSxTQUFTLENBQUMsTUFBTSxDQUFDO2dCQUMxQyxHQUFHLFVBQVU7Z0JBQ2IsTUFBTSxFQUFFLGdCQUFnQixDQUFDLE1BQU07Z0JBQy9CLEdBQUcsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLElBQUk7Z0JBQ3BELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU87YUFDcEUsQ0FBQyxDQUFDO1lBRUgsSUFBSSxZQUFZLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDM0MsTUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLGNBQWM7cUJBQ3hDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLGlCQUFpQixLQUFLLENBQUMsQ0FBQyxZQUFZLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO3FCQUN2RSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2QsTUFBTSxPQUFPLEdBQ1gsb0JBQW9CLEdBQUcsTUFBTSxZQUFZLENBQUMsY0FBYyxDQUFDLE1BQU0sbUNBQW1DLE9BQU8sRUFBRSxDQUFDO2dCQUM5RyxJQUFJLG1CQUFtQixFQUFFLENBQUM7b0JBQ3hCLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzFCLENBQUM7cUJBQU0sQ0FBQztvQkFDTixNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUMzQixDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksWUFBWSxvQ0FBb0MsQ0FBQyxDQUFDO0lBQ25HLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ssZ0JBQWdCLENBQUMsU0FBcUI7UUFDNUMseUVBQXlFO1FBQ3pFLHlFQUF5RTtRQUN6RSxxRUFBcUU7UUFDckUseUVBQXlFO1FBQ3pFLGdFQUFnRTtRQUNoRSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN2RCxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFbEMsMENBQTBDO1FBQzFDLElBQUksVUFBVSxHQUF1QixTQUFTLENBQUM7UUFDL0MsdUVBQXVFO1FBQ3ZFLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFXLElBQUEsWUFBSSxFQUFDLENBQUMsR0FBRyxHQUFHLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ2xFLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsS0FBSyxNQUFNLElBQUksSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7b0JBQzVDLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNyRCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQ3JCLHdDQUF3QyxFQUN4Qyx3REFBd0QsU0FBUyxDQUFDLGVBQWUsRUFBRTtnQkFDbkYsK0RBQStELENBQ2hFLENBQUM7WUFDRixNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxJQUFBLG9CQUFXLEVBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBRUQsa0ZBQWtGO1FBQ2xGLDhDQUE4QztRQUM5QyxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2YsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsZUFBZSxDQUFDLENBQUM7WUFFN0UsTUFBTSxlQUFlLEdBQUcsQ0FBQyxHQUFHLEdBQUcsRUFBRSxVQUFVLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLFVBQVUsQ0FBQyxFQUFFLElBQUksRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBQ3BILElBQUksQ0FBQztnQkFDSCxJQUFBLHdCQUFnQixFQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3BDLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNYLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUNyQiwwQ0FBMEMsU0FBUyxDQUFDLGVBQWUsNkRBQTZELEVBQ2hJLElBQUEscUJBQWEsRUFBQyxlQUFlLENBQUMsRUFDOUIsRUFBRSxDQUNILENBQUM7Z0JBQ0YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsSUFBQSxvQkFBVyxFQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxLQUFLLENBQUMsd0JBQXdCLENBQUMsU0FBcUIsRUFBRSxjQUF3QixFQUFFLFdBQW9DO1FBQzFILElBQUksQ0FBQztZQUNILElBQUksY0FBYyxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQztnQkFDckMsY0FBYyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO29CQUM1QyxJQUFBLFlBQUksRUFBQyxJQUFBLGNBQU0sRUFBQyxHQUFHLENBQUMsRUFBRTt3QkFDaEIsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQztxQkFDN0MsQ0FBQyxDQUFDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELE1BQU0sU0FBUyxDQUFDLE9BQU8sQ0FBQztnQkFDdEIsTUFBTSxFQUFFO29CQUNOLEdBQUcsY0FBYyxDQUFDLE1BQU07b0JBQ3hCLEdBQUcsQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2lCQUMxRTtnQkFDRCxHQUFHLFdBQVc7YUFDZixDQUFDLENBQUM7WUFFSCxJQUFJLGNBQWMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLENBQUM7Z0JBQ3RDLGNBQWMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtvQkFDN0MsSUFBQSxZQUFJLEVBQUMsSUFBQSxjQUFNLEVBQUMsR0FBRyxDQUFDLEVBQUU7d0JBQ2hCLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUM7cUJBQzdDLENBQUMsQ0FBQztnQkFDTCxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUNmLGNBQWMsQ0FBQyxpQkFBaUIsRUFBRSxPQUFPLEVBQUUsV0FBVyxJQUFJLEtBQUssRUFDL0QsY0FBYyxDQUFDLGlCQUFpQixFQUFFLE9BQU8sRUFBRSxlQUFlLENBQzNELENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBcUIsRUFBRSxZQUFvQixFQUFFLE9BQXlCLEVBQUUsU0FBaUI7UUFDM0csTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQztRQUU1QyxNQUFNLGNBQWMsR0FBRyxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFM0QsSUFBSSxjQUFjLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxDQUFDO1lBQ3BDLGNBQWMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDM0MsSUFBQSxZQUFJLEVBQUMsSUFBQSxjQUFNLEVBQUMsR0FBRyxDQUFDLEVBQUU7b0JBQ2hCLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUM7aUJBQzdDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHO1lBQ2hCLEdBQUcsT0FBTztZQUNWLE9BQU8sRUFBRSxlQUFlLENBQUMsYUFBYTtZQUN0QyxNQUFNLEVBQUU7Z0JBQ04sR0FBRyxjQUFjLENBQUMsTUFBTTtnQkFDeEIsR0FBRyxjQUFjLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTthQUN4RTtZQUNELE1BQU0sRUFBRSxTQUFTLENBQUMsZUFBZTtZQUNqQyxXQUFXLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLHdCQUF3QixDQUFDO1lBQzNFLEdBQUcsY0FBYyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxJQUFJO1lBQ2xELE9BQU8sRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPO1NBQ2xFLENBQUM7UUFDRixNQUFNLGNBQWMsR0FBRztZQUNyQixrQkFBa0IsRUFBRTtnQkFDbEIsa0VBQWtFO2dCQUNsRSxLQUFLO29CQUNILEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ3pFLGFBQWE7b0JBQ2IsT0FBTyxTQUFTLENBQUMsVUFBVSxHQUFHO29CQUM5QixTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7b0JBQzFCLGFBQWEsU0FBUyxDQUFDLE9BQU8sRUFBRTtpQkFDakMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7YUFDZDtTQUNGLENBQUM7UUFDRixVQUFVLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3RDLElBQUksU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RCLHdFQUF3RTtZQUN4RSxnREFBZ0Q7WUFDaEQsVUFBVSxDQUFDLFVBQVUsQ0FBQztnQkFDcEIsa0JBQWtCLEVBQUU7b0JBQ2xCLFFBQVE7b0JBQ1IsS0FBSyxTQUFTLENBQUMsaUJBQWlCLEVBQUU7aUJBQ25DO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLHdCQUF3QixDQUFDLENBQUM7UUFDeEYsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsRUFBRTtZQUMxRCxHQUFHLEVBQUUsU0FBUyxDQUFDLGVBQWU7U0FDL0IsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxLQUFnQixFQUFFLElBQVksRUFBRSxFQUFFO1lBQ25ELElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDeEIsT0FBTyxDQUFDLDZEQUE2RDtZQUN2RSxDQUFDO1lBQ0QsNEVBQTRFO1lBQzVFLDJEQUEyRDtZQUMzRCxJQUFJLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxLQUFLLElBQUksS0FBSyxLQUFLLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQy9FLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDekIsSUFBSSxjQUFjLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxDQUFDO29CQUNyQyxjQUFjLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7d0JBQzVDLElBQUEsWUFBSSxFQUFDLElBQUEsY0FBTSxFQUFDLEdBQUcsQ0FBQyxFQUFFOzRCQUNoQixHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDO3lCQUM3QyxDQUFDLENBQUM7b0JBQ0wsQ0FBQyxDQUFDLENBQUM7Z0JBQ0wsQ0FBQztnQkFFRCxJQUFJLGNBQWMsQ0FBQyxjQUFjLElBQUksY0FBYyxDQUFDLGtCQUFrQixFQUFFLENBQUM7b0JBQ3ZFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FDdEMsZ0JBQWdCLEVBQ2hCLGNBQWMsQ0FBQyxrQkFBa0IsRUFDakMsY0FBYyxDQUFDLGNBQWMsQ0FDOUIsQ0FBQztvQkFDRixJQUFJLEdBQUcsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLEVBQUUsQ0FBQzt3QkFDN0QsVUFBVSxDQUFDLFVBQVUsQ0FBQzs0QkFDcEIsTUFBTSxFQUFFLHlCQUFnQixDQUFDLGdCQUFnQjs0QkFDekMsUUFBUSxFQUFFLEdBQUcsWUFBWSxLQUFLLFNBQVMsQ0FBQyxPQUFPLEVBQUU7NEJBQ2pELE9BQU8sRUFBRSxJQUFBLCtCQUFzQixFQUFDLEdBQUcsQ0FBQzs0QkFDcEMsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxHQUFHLElBQUk7eUJBQ3RDLENBQUMsQ0FBQztvQkFDTCxDQUFDO3lCQUFNLENBQUM7d0JBQ04sVUFBVSxDQUFDLFVBQVUsQ0FBQzs0QkFDcEIsTUFBTSxFQUFFLHlCQUFnQixDQUFDLFlBQVk7NEJBQ3JDLFFBQVEsRUFBRSxHQUFHLFlBQVksRUFBRTs0QkFDM0IsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBQSwrQkFBc0IsRUFBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZTs0QkFDNUQsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxHQUFHLElBQUk7eUJBQ3RDLENBQUMsQ0FBQztvQkFDTCxDQUFDO29CQUNELDJDQUEyQztvQkFDM0MsbUNBQW1DO29CQUNuQyxVQUFVLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUN4QyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUMxQixPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDN0IsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2QsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLElBQUEsNEJBQW9CLEdBQWlCLENBQUM7UUFFM0UsTUFBTSxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRTtZQUMvQixvREFBb0Q7WUFDcEQsUUFBUSxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ3BCLElBQUksU0FBUyxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUNsQixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDaEMsQ0FBQztZQUNILENBQUM7WUFDRCxvREFBb0Q7WUFDcEQsUUFBUSxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ3BCLElBQUksU0FBUyxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUNsQixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDaEMsQ0FBQztZQUNILENBQUM7WUFDRCxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFO2dCQUN0QixJQUFJLElBQUksS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDZixNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7Z0JBQzdDLENBQUM7Z0JBQ0QsTUFBTSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3RCLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNoQixDQUFDO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsTUFBTSxNQUFNLENBQUM7SUFDZixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssS0FBSyxDQUFDLHVCQUF1QixDQUNuQyxHQUFlLEVBQ2YsZUFBMkIsRUFDM0IsUUFBa0IsRUFDbEIsVUFBNkIsRUFDN0IscUJBQThCLEVBQzlCLFlBQW9CLEVBQ3BCLG1CQUE0QixFQUM1QixjQUF5QjtRQUV6QixJQUFJLENBQUM7WUFDSCxJQUFJLFFBQVEsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLENBQUM7Z0JBQzlCLFFBQVEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtvQkFDckMsSUFBQSxZQUFJLEVBQUMsSUFBQSxjQUFNLEVBQUMsR0FBRyxDQUFDLEVBQUU7d0JBQ2hCLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUM7cUJBQ3ZDLENBQUMsQ0FBQztnQkFDTCxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7WUFDRCxJQUFJLGNBQWMsSUFBSSxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNoRCxvRUFBb0U7Z0JBQ3BFLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztZQUNoRyxDQUFDO2lCQUFNLElBQUkscUJBQXFCLElBQUksTUFBTSxlQUFlLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQztnQkFDdEUsb0NBQW9DO2dCQUNwQyxNQUFNLGlCQUFpQixHQUFHLE1BQU0sZUFBZSxDQUFDLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3BFLElBQUksaUJBQWlCLElBQUksWUFBWSxJQUFJLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxDQUFDO29CQUN0RSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZUFBZSxDQUFDLENBQUM7b0JBQ3ZDLE1BQU0sZ0JBQWdCLEdBQUcsaUJBQWlCLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUVuRSxNQUFNLGVBQWUsQ0FBQyxNQUFNLENBQUM7d0JBQzNCLEdBQUcsVUFBVTt3QkFDYixNQUFNLEVBQUUsZ0JBQWdCLENBQUMsTUFBTTt3QkFDL0IsR0FBRyxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsSUFBSTt3QkFDcEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTztxQkFDcEUsQ0FBQyxDQUFDO2dCQUNMLENBQUM7WUFDSCxDQUFDO1lBRUQsZ0NBQWdDO1lBQ2hDLDZEQUE2RDtZQUM3RCxNQUFNLGtCQUFrQixHQUFHLE1BQU0sR0FBRyxDQUFDLE1BQU0sQ0FBQztnQkFDMUMsR0FBRyxVQUFVO2dCQUNiLE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTTtnQkFDdkIsR0FBRyxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLElBQUk7Z0JBQzVDLE9BQU8sRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPO2FBQzVELENBQUMsQ0FBQztZQUVILElBQUksa0JBQWtCLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDakQsTUFBTSxPQUFPLEdBQUcsa0JBQWtCLENBQUMsY0FBYztxQkFDOUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsaUJBQWlCLEtBQUssQ0FBQyxDQUFDLFlBQVksTUFBTSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7cUJBQ3ZFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDZCxNQUFNLE9BQU8sR0FDWCxHQUFHLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxNQUFNLHVEQUF1RCxPQUFPLElBQUk7b0JBQzdHLGdHQUFnRyxDQUFDO2dCQUNuRyxJQUFJLG1CQUFtQixFQUFFLENBQUM7b0JBQ3hCLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzFCLENBQUM7cUJBQU0sQ0FBQztvQkFDTixNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUMzQixDQUFDO1lBQ0gsQ0FBQztZQUVELDhCQUE4QjtZQUM5QixxQ0FBcUM7WUFDckMsZ0VBQWdFO1lBQ2hFLDJFQUEyRTtZQUMzRSw4REFBOEQ7WUFDOUQsK0VBQStFO1lBQy9FLElBQUksUUFBUSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUM1QixNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUM7b0JBQ2YsR0FBRyxVQUFVO29CQUNiLE1BQU0sRUFBRTt3QkFDTixRQUFRLENBQUMsY0FBYztxQkFDeEI7b0JBQ0QsUUFBUSxFQUFFLEtBQUs7b0JBQ2YsR0FBRyxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLElBQUk7b0JBQzVDLFdBQVcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLEVBQUUsd0JBQXdCLENBQUM7b0JBQ3JFLE9BQU8sRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPO2lCQUM1RCxDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQsSUFBSSxRQUFRLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxDQUFDO2dCQUMvQixRQUFRLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7b0JBQ3RDLElBQUEsWUFBSSxFQUFDLElBQUEsY0FBTSxFQUFDLEdBQUcsQ0FBQyxFQUFFO3dCQUNoQixHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDO3FCQUN2QyxDQUFDLENBQUM7Z0JBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQsSUFBSSxRQUFRLENBQUMsY0FBYyxJQUFJLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUMzRCxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FDakMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLHdCQUF3QixDQUFDLEVBQ3hELFFBQVEsQ0FBQyxrQkFBa0IsRUFDM0IsUUFBUSxDQUFDLGNBQWMsQ0FDeEIsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUNmLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsV0FBVyxJQUFJLEtBQUssRUFDeEQsUUFBUSxDQUFDLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxlQUFlLENBQ3BELENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTztJQUNULENBQUM7SUFFRDs7O09BR0c7SUFDSyx1QkFBdUIsQ0FBQyxJQUFZLEVBQUUsa0JBQTBCLEVBQUUsZ0JBQXdCO1FBQ2hHLE1BQU0sT0FBTyxHQUFxQixFQUFFLENBQUM7UUFDckMsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDO2dCQUNILE1BQU0sT0FBTyxHQUFpRCxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVwRixJQUFJLGtCQUFrQixJQUFJLE9BQU8sRUFBRSxDQUFDO29CQUNsQyxLQUFLLE1BQU0sQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxFQUFFLENBQUM7d0JBQ2hGLElBQUksV0FBVyxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7NEJBQy9DLE1BQU0sZUFBZSxHQUFvQixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7NEJBQ2xGLElBQUksZUFBZSxDQUFDLE1BQU0sS0FBSyxNQUFNLElBQUksZUFBZSxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQ0FDOUUsT0FBTyxDQUFDLFdBQVcsQ0FBQyxHQUFHLGVBQWUsQ0FBQzs0QkFDekMsQ0FBQzt3QkFDSCxDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNYLDBFQUEwRTtnQkFDMUUseUJBQXlCO2dCQUN6QixPQUFPLENBQUMsZ0JBQWdCLENBQUMsR0FBRztvQkFDMUIsTUFBTSxFQUFFLE1BQU07b0JBQ2QsT0FBTyxFQUFFLHVDQUF1QyxDQUFDLEVBQUU7aUJBQ3BELENBQUM7WUFDSixDQUFDO29CQUFTLENBQUM7Z0JBQ1QsNERBQTREO2dCQUM1RCx1REFBdUQ7Z0JBQ3ZELDBCQUEwQjtnQkFDMUIsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QixDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUMvRCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxVQUFVLENBQUMsQ0FBVSxFQUFFLFdBQW9CLEVBQUUsZUFBd0I7UUFDM0UsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUNwQixNQUFNLE9BQU8sR0FBSSxDQUFXLENBQUMsT0FBTyxDQUFDO2dCQUNyQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO29CQUNwQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ1osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sQ0FBQyxDQUFDO1FBQ1YsQ0FBQztJQUNILENBQUM7Q0FDRjtBQTNrQkQsMENBMmtCQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsWUFBb0IsQ0FBQztJQUM3QyxPQUFPO1FBQ0wsT0FBTyxFQUFFLFNBQVMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUztRQUMxQyxLQUFLLEVBQUUsU0FBUyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTO1FBQ3hDLFNBQVMsRUFBRSxTQUFTLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUs7S0FDekMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHR5cGUgeyBEZXN0cm95T3B0aW9ucywgVGVzdENhc2UgfSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnO1xuaW1wb3J0IHsgUmVxdWlyZUFwcHJvdmFsIH0gZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCAqIGFzIGNob2tpZGFyIGZyb20gJ2Nob2tpZGFyJztcbmltcG9ydCB7IHR5cGUgRXZlbnROYW1lLCBFVkVOVFMgfSBmcm9tICdjaG9raWRhci9oYW5kbGVyLmpzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCAqIGFzIHdvcmtlcnBvb2wgZnJvbSAnd29ya2VycG9vbCc7XG5pbXBvcnQgdHlwZSAqIGFzIGNkayBmcm9tICcuLi9lbmdpbmVzL2Nkay1pbnRlcmZhY2UnO1xuaW1wb3J0ICogYXMgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBjaHVua3MsIGV4ZWMsIGV4ZWNXaXRoU3ViU2hlbGwsIHByb21pc2VXaXRoUmVzb2x2ZXJzLCByZW5kZXJDb21tYW5kIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHR5cGUgeyBDZGtUZXN0QXBwT3B0aW9ucywgTGVnYWN5RW5hYmxlTG9va3VwcyB9IGZyb20gJy4vY2RrLXRlc3QtYXBwJztcbmltcG9ydCB7IENka1Rlc3RBcHAsIERFRkFVTFRfQVJHUyB9IGZyb20gJy4vY2RrLXRlc3QtYXBwJztcbmltcG9ydCB0eXBlIHsgSW50ZWdUZXN0IH0gZnJvbSAnLi9pbnRlZ3JhdGlvbi10ZXN0cyc7XG5pbXBvcnQgdHlwZSB7IERlc3RydWN0aXZlQ2hhbmdlLCBBc3NlcnRpb25SZXN1bHRzLCBBc3NlcnRpb25SZXN1bHQgfSBmcm9tICcuLi93b3JrZXJzL2NvbW1vbic7XG5pbXBvcnQgeyBEaWFnbm9zdGljUmVhc29uLCBmb3JtYXRBc3NlcnRpb25SZXN1bHRzLCBmb3JtYXRFcnJvciB9IGZyb20gJy4uL3dvcmtlcnMvY29tbW9uJztcblxuLyoqXG4gKiBGaWxlIGV2ZW50cyB0aGF0IHdlIGNhcmUgYWJvdXQgZnJvbSBjaG9raWRhci5cbiAqIEluIGNob2tpZGFyIHY0LCBFdmVudE5hbWUgaW5jbHVkZXMgYWRkaXRpb25hbCBldmVudHMgbGlrZSAnZXJyb3InLCAncmF3JywgJ3JlYWR5JywgJ2FsbCdcbiAqIHRoYXQgd2UgbmVlZCB0byBmaWx0ZXIgb3V0IGluIHRoZSAnYWxsJyBoYW5kbGVyLlxuICovXG5jb25zdCBGSUxFX0VWRU5UUyA9IFtFVkVOVFMuQURELCBFVkVOVFMuQ0hBTkdFXSBhcyBjb25zdDtcbnR5cGUgRmlsZUV2ZW50ID0gdHlwZW9mIEZJTEVfRVZFTlRTW251bWJlcl07XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhbiBldmVudCBpcyBhIGZpbGUgZXZlbnQgd2Ugc2hvdWxkIHByb2Nlc3MuXG4gKi9cbmZ1bmN0aW9uIGlzRmlsZUV2ZW50KGV2ZW50OiBFdmVudE5hbWUpOiBldmVudCBpcyBGaWxlRXZlbnQge1xuICByZXR1cm4gKEZJTEVfRVZFTlRTIGFzIHJlYWRvbmx5IHN0cmluZ1tdKS5pbmNsdWRlcyhldmVudCk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tbW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgbGV2ZWwgb2YgdmVyYm9zaXR5IGZvciBsb2dnaW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdCAwXG4gICAqL1xuICByZWFkb25seSB2ZXJib3NpdHk/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=
|