@cdklabs/cdk-appmod-catalog-blueprints 1.4.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +2579 -194
- package/lib/document-processing/adapter/adapter.d.ts +4 -2
- package/lib/document-processing/adapter/adapter.js +1 -1
- package/lib/document-processing/adapter/queued-s3-adapter.d.ts +9 -2
- package/lib/document-processing/adapter/queued-s3-adapter.js +29 -15
- package/lib/document-processing/agentic-document-processing.d.ts +4 -0
- package/lib/document-processing/agentic-document-processing.js +20 -10
- package/lib/document-processing/base-document-processing.d.ts +54 -2
- package/lib/document-processing/base-document-processing.js +136 -82
- package/lib/document-processing/bedrock-document-processing.d.ts +202 -2
- package/lib/document-processing/bedrock-document-processing.js +717 -77
- package/lib/document-processing/chunking-config.d.ts +614 -0
- package/lib/document-processing/chunking-config.js +5 -0
- package/lib/document-processing/default-document-processing-config.js +1 -1
- package/lib/document-processing/index.d.ts +1 -0
- package/lib/document-processing/index.js +2 -1
- package/lib/document-processing/resources/aggregation/handler.py +567 -0
- package/lib/document-processing/resources/aggregation/requirements.txt +7 -0
- package/lib/document-processing/resources/aggregation/test_handler.py +362 -0
- package/lib/document-processing/resources/cleanup/handler.py +276 -0
- package/lib/document-processing/resources/cleanup/requirements.txt +5 -0
- package/lib/document-processing/resources/cleanup/test_handler.py +436 -0
- package/lib/document-processing/resources/default-bedrock-invoke/index.py +85 -3
- package/lib/document-processing/resources/default-bedrock-invoke/test_index.py +622 -0
- package/lib/document-processing/resources/pdf-chunking/README.md +313 -0
- package/lib/document-processing/resources/pdf-chunking/chunking_strategies.py +460 -0
- package/lib/document-processing/resources/pdf-chunking/error_handling.py +491 -0
- package/lib/document-processing/resources/pdf-chunking/handler.py +958 -0
- package/lib/document-processing/resources/pdf-chunking/metrics.py +435 -0
- package/lib/document-processing/resources/pdf-chunking/requirements.txt +3 -0
- package/lib/document-processing/resources/pdf-chunking/strategy_selection.py +420 -0
- package/lib/document-processing/resources/pdf-chunking/structured_logging.py +457 -0
- package/lib/document-processing/resources/pdf-chunking/test_chunking_strategies.py +353 -0
- package/lib/document-processing/resources/pdf-chunking/test_error_handling.py +487 -0
- package/lib/document-processing/resources/pdf-chunking/test_handler.py +609 -0
- package/lib/document-processing/resources/pdf-chunking/test_integration.py +694 -0
- package/lib/document-processing/resources/pdf-chunking/test_metrics.py +532 -0
- package/lib/document-processing/resources/pdf-chunking/test_strategy_selection.py +471 -0
- package/lib/document-processing/resources/pdf-chunking/test_structured_logging.py +449 -0
- package/lib/document-processing/resources/pdf-chunking/test_token_estimation.py +374 -0
- package/lib/document-processing/resources/pdf-chunking/token_estimation.py +189 -0
- package/lib/document-processing/tests/agentic-document-processing-nag.test.js +4 -3
- package/lib/document-processing/tests/agentic-document-processing.test.js +488 -4
- package/lib/document-processing/tests/base-document-processing-nag.test.js +9 -2
- package/lib/document-processing/tests/base-document-processing-schema.test.d.ts +1 -0
- package/lib/document-processing/tests/base-document-processing-schema.test.js +337 -0
- package/lib/document-processing/tests/base-document-processing.test.js +114 -8
- package/lib/document-processing/tests/bedrock-document-processing-chunking-nag.test.d.ts +1 -0
- package/lib/document-processing/tests/bedrock-document-processing-chunking-nag.test.js +382 -0
- package/lib/document-processing/tests/bedrock-document-processing-nag.test.js +4 -3
- package/lib/document-processing/tests/bedrock-document-processing-security.test.d.ts +1 -0
- package/lib/document-processing/tests/bedrock-document-processing-security.test.js +389 -0
- package/lib/document-processing/tests/bedrock-document-processing.test.js +808 -8
- package/lib/document-processing/tests/chunking-config.test.d.ts +1 -0
- package/lib/document-processing/tests/chunking-config.test.js +238 -0
- package/lib/document-processing/tests/queued-s3-adapter-nag.test.js +9 -2
- package/lib/document-processing/tests/queued-s3-adapter.test.js +17 -6
- package/lib/framework/agents/base-agent.js +1 -1
- package/lib/framework/agents/batch-agent.js +1 -1
- package/lib/framework/agents/default-agent-config.js +1 -1
- package/lib/framework/bedrock/bedrock.js +1 -1
- package/lib/framework/custom-resource/default-runtimes.js +1 -1
- package/lib/framework/foundation/access-log.js +1 -1
- package/lib/framework/foundation/eventbridge-broker.js +1 -1
- package/lib/framework/foundation/network.d.ts +4 -2
- package/lib/framework/foundation/network.js +52 -41
- package/lib/framework/tests/access-log.test.js +5 -2
- package/lib/framework/tests/batch-agent.test.js +5 -2
- package/lib/framework/tests/bedrock.test.js +5 -2
- package/lib/framework/tests/eventbridge-broker.test.js +5 -2
- package/lib/framework/tests/framework-nag.test.js +26 -7
- package/lib/framework/tests/network.test.js +30 -2
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/utilities/data-loader.js +1 -1
- package/lib/utilities/lambda-iam-utils.js +1 -1
- package/lib/utilities/observability/cloudfront-distribution-observability-property-injector.js +1 -1
- package/lib/utilities/observability/default-observability-config.js +1 -1
- package/lib/utilities/observability/lambda-observability-property-injector.js +1 -1
- package/lib/utilities/observability/log-group-data-protection-utils.js +1 -1
- package/lib/utilities/observability/powertools-config.d.ts +10 -1
- package/lib/utilities/observability/powertools-config.js +19 -3
- package/lib/utilities/observability/state-machine-observability-property-injector.js +1 -1
- package/lib/utilities/test-utils.d.ts +43 -0
- package/lib/utilities/test-utils.js +56 -0
- package/lib/utilities/tests/data-loader-nag.test.js +3 -2
- package/lib/utilities/tests/data-loader.test.js +3 -2
- package/lib/webapp/frontend-construct.js +1 -1
- package/lib/webapp/tests/frontend-construct-nag.test.js +3 -2
- package/lib/webapp/tests/frontend-construct.test.js +3 -2
- package/package.json +6 -5
- package/lib/document-processing/resources/default-error-handler/index.js +0 -46
- package/lib/document-processing/resources/default-pdf-processor/index.js +0 -46
- package/lib/document-processing/resources/default-pdf-validator/index.js +0 -36
|
@@ -5,8 +5,10 @@ const assertions_1 = require("aws-cdk-lib/assertions");
|
|
|
5
5
|
const aws_bedrock_1 = require("aws-cdk-lib/aws-bedrock");
|
|
6
6
|
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
7
7
|
const framework_1 = require("../../framework");
|
|
8
|
+
const test_utils_1 = require("../../utilities/test-utils");
|
|
8
9
|
const bedrock_document_processing_1 = require("../bedrock-document-processing");
|
|
9
10
|
describe('BedrockDocumentProcessing', () => {
|
|
11
|
+
let app;
|
|
10
12
|
let defaultStack;
|
|
11
13
|
let customStack;
|
|
12
14
|
let crossRegionStack;
|
|
@@ -14,6 +16,7 @@ describe('BedrockDocumentProcessing', () => {
|
|
|
14
16
|
let postProcessingStack;
|
|
15
17
|
let customPromptsStack;
|
|
16
18
|
let customTimeoutStack;
|
|
19
|
+
let chunkingStack;
|
|
17
20
|
let defaultTemplate;
|
|
18
21
|
let customTemplate;
|
|
19
22
|
let crossRegionTemplate;
|
|
@@ -21,10 +24,13 @@ describe('BedrockDocumentProcessing', () => {
|
|
|
21
24
|
let postProcessingTemplate;
|
|
22
25
|
let customPromptsTemplate;
|
|
23
26
|
let customTimeoutTemplate;
|
|
27
|
+
let chunkingTemplate;
|
|
24
28
|
beforeAll(() => {
|
|
25
|
-
|
|
29
|
+
// Use createTestApp() to skip bundling and speed up tests
|
|
30
|
+
app = (0, test_utils_1.createTestApp)();
|
|
31
|
+
defaultStack = new aws_cdk_lib_1.Stack(app, 'DefaultStack');
|
|
26
32
|
new bedrock_document_processing_1.BedrockDocumentProcessing(defaultStack, 'DefaultTest', {});
|
|
27
|
-
customStack = new aws_cdk_lib_1.Stack();
|
|
33
|
+
customStack = new aws_cdk_lib_1.Stack(app, 'CustomStack');
|
|
28
34
|
new bedrock_document_processing_1.BedrockDocumentProcessing(customStack, 'CustomTest', {
|
|
29
35
|
classificationBedrockModel: {
|
|
30
36
|
fmModelId: aws_bedrock_1.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_HAIKU_20240307_V1_0,
|
|
@@ -35,14 +41,14 @@ describe('BedrockDocumentProcessing', () => {
|
|
|
35
41
|
useCrossRegionInference: false,
|
|
36
42
|
},
|
|
37
43
|
});
|
|
38
|
-
crossRegionStack = new aws_cdk_lib_1.Stack();
|
|
44
|
+
crossRegionStack = new aws_cdk_lib_1.Stack(app, 'CrossRegionStack');
|
|
39
45
|
new bedrock_document_processing_1.BedrockDocumentProcessing(crossRegionStack, 'CrossRegionTest', {
|
|
40
46
|
classificationBedrockModel: {
|
|
41
47
|
useCrossRegionInference: true,
|
|
42
48
|
crossRegionInferencePrefix: framework_1.BedrockCrossRegionInferencePrefix.EU,
|
|
43
49
|
},
|
|
44
50
|
});
|
|
45
|
-
enrichmentStack = new aws_cdk_lib_1.Stack();
|
|
51
|
+
enrichmentStack = new aws_cdk_lib_1.Stack(app, 'EnrichmentStack');
|
|
46
52
|
const enrichmentFn = new aws_lambda_1.Function(enrichmentStack, 'EnrichmentFn', {
|
|
47
53
|
runtime: aws_lambda_1.Runtime.NODEJS_20_X,
|
|
48
54
|
handler: 'index.handler',
|
|
@@ -51,7 +57,7 @@ describe('BedrockDocumentProcessing', () => {
|
|
|
51
57
|
new bedrock_document_processing_1.BedrockDocumentProcessing(enrichmentStack, 'EnrichmentTest', {
|
|
52
58
|
enrichmentLambdaFunction: enrichmentFn,
|
|
53
59
|
});
|
|
54
|
-
postProcessingStack = new aws_cdk_lib_1.Stack();
|
|
60
|
+
postProcessingStack = new aws_cdk_lib_1.Stack(app, 'PostProcessingStack');
|
|
55
61
|
const postProcessingFn = new aws_lambda_1.Function(postProcessingStack, 'PostProcessingFn', {
|
|
56
62
|
runtime: aws_lambda_1.Runtime.NODEJS_20_X,
|
|
57
63
|
handler: 'index.handler',
|
|
@@ -60,15 +66,28 @@ describe('BedrockDocumentProcessing', () => {
|
|
|
60
66
|
new bedrock_document_processing_1.BedrockDocumentProcessing(postProcessingStack, 'PostProcessingTest', {
|
|
61
67
|
postProcessingLambdaFunction: postProcessingFn,
|
|
62
68
|
});
|
|
63
|
-
customPromptsStack = new aws_cdk_lib_1.Stack();
|
|
69
|
+
customPromptsStack = new aws_cdk_lib_1.Stack(app, 'CustomPromptsStack');
|
|
64
70
|
new bedrock_document_processing_1.BedrockDocumentProcessing(customPromptsStack, 'CustomPromptsTest', {
|
|
65
71
|
classificationPrompt: 'Custom classification prompt',
|
|
66
72
|
processingPrompt: 'Custom processing prompt',
|
|
67
73
|
});
|
|
68
|
-
customTimeoutStack = new aws_cdk_lib_1.Stack();
|
|
74
|
+
customTimeoutStack = new aws_cdk_lib_1.Stack(app, 'CustomTimeoutStack');
|
|
69
75
|
new bedrock_document_processing_1.BedrockDocumentProcessing(customTimeoutStack, 'CustomTimeoutTest', {
|
|
70
76
|
stepTimeouts: aws_cdk_lib_1.Duration.minutes(10),
|
|
71
77
|
});
|
|
78
|
+
chunkingStack = new aws_cdk_lib_1.Stack(app, 'ChunkingStack');
|
|
79
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(chunkingStack, 'ChunkingTest', {
|
|
80
|
+
enableChunking: true,
|
|
81
|
+
chunkingConfig: {
|
|
82
|
+
strategy: 'hybrid',
|
|
83
|
+
maxPagesPerChunk: 100,
|
|
84
|
+
targetTokensPerChunk: 80000,
|
|
85
|
+
pageThreshold: 100,
|
|
86
|
+
tokenThreshold: 150000,
|
|
87
|
+
processingMode: 'parallel',
|
|
88
|
+
maxConcurrency: 10,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
72
91
|
defaultTemplate = assertions_1.Template.fromStack(defaultStack);
|
|
73
92
|
customTemplate = assertions_1.Template.fromStack(customStack);
|
|
74
93
|
crossRegionTemplate = assertions_1.Template.fromStack(crossRegionStack);
|
|
@@ -76,6 +95,7 @@ describe('BedrockDocumentProcessing', () => {
|
|
|
76
95
|
postProcessingTemplate = assertions_1.Template.fromStack(postProcessingStack);
|
|
77
96
|
customPromptsTemplate = assertions_1.Template.fromStack(customPromptsStack);
|
|
78
97
|
customTimeoutTemplate = assertions_1.Template.fromStack(customTimeoutStack);
|
|
98
|
+
chunkingTemplate = assertions_1.Template.fromStack(chunkingStack);
|
|
79
99
|
});
|
|
80
100
|
describe('Basic infrastructure', () => {
|
|
81
101
|
test('creates basic infrastructure', () => {
|
|
@@ -256,5 +276,785 @@ describe('BedrockDocumentProcessing', () => {
|
|
|
256
276
|
});
|
|
257
277
|
});
|
|
258
278
|
});
|
|
279
|
+
describe('Chunking configuration', () => {
|
|
280
|
+
test('accepts enableChunking prop', () => {
|
|
281
|
+
// This test verifies that the BedrockDocumentProcessingProps interface
|
|
282
|
+
// correctly accepts the enableChunking boolean flag
|
|
283
|
+
expect(chunkingStack).toBeDefined();
|
|
284
|
+
});
|
|
285
|
+
test('accepts chunkingConfig prop with all strategy options', () => {
|
|
286
|
+
// This test verifies that the BedrockDocumentProcessingProps interface
|
|
287
|
+
// correctly accepts the chunkingConfig with all configuration options
|
|
288
|
+
chunkingTemplate.hasResourceProperties('AWS::S3::Bucket', {});
|
|
289
|
+
chunkingTemplate.hasResourceProperties('AWS::SQS::Queue', {});
|
|
290
|
+
chunkingTemplate.hasResourceProperties('AWS::DynamoDB::Table', { BillingMode: 'PAY_PER_REQUEST' });
|
|
291
|
+
});
|
|
292
|
+
test('accepts fixed-pages strategy configuration', () => {
|
|
293
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
294
|
+
const fixedPagesStack = new aws_cdk_lib_1.Stack(testApp, 'FixedPagesStack');
|
|
295
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(fixedPagesStack, 'FixedPagesTest', {
|
|
296
|
+
enableChunking: true,
|
|
297
|
+
chunkingConfig: {
|
|
298
|
+
strategy: 'fixed-pages',
|
|
299
|
+
pageThreshold: 100,
|
|
300
|
+
chunkSize: 50,
|
|
301
|
+
overlapPages: 5,
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
// Verify stack is created successfully
|
|
305
|
+
expect(fixedPagesStack).toBeDefined();
|
|
306
|
+
});
|
|
307
|
+
test('accepts token-based strategy configuration', () => {
|
|
308
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
309
|
+
const tokenBasedStack = new aws_cdk_lib_1.Stack(testApp, 'TokenBasedStack');
|
|
310
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(tokenBasedStack, 'TokenBasedTest', {
|
|
311
|
+
enableChunking: true,
|
|
312
|
+
chunkingConfig: {
|
|
313
|
+
strategy: 'token-based',
|
|
314
|
+
tokenThreshold: 150000,
|
|
315
|
+
maxTokensPerChunk: 100000,
|
|
316
|
+
overlapTokens: 5000,
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
// Verify stack is created successfully
|
|
320
|
+
expect(tokenBasedStack).toBeDefined();
|
|
321
|
+
});
|
|
322
|
+
test('accepts hybrid strategy configuration', () => {
|
|
323
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
324
|
+
const hybridStack = new aws_cdk_lib_1.Stack(testApp, 'HybridStack');
|
|
325
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(hybridStack, 'HybridTest', {
|
|
326
|
+
enableChunking: true,
|
|
327
|
+
chunkingConfig: {
|
|
328
|
+
strategy: 'hybrid',
|
|
329
|
+
maxPagesPerChunk: 100,
|
|
330
|
+
targetTokensPerChunk: 80000,
|
|
331
|
+
pageThreshold: 100,
|
|
332
|
+
tokenThreshold: 150000,
|
|
333
|
+
overlapTokens: 5000,
|
|
334
|
+
},
|
|
335
|
+
});
|
|
336
|
+
// Verify stack is created successfully
|
|
337
|
+
expect(hybridStack).toBeDefined();
|
|
338
|
+
});
|
|
339
|
+
test('accepts default chunking configuration', () => {
|
|
340
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
341
|
+
const defaultChunkingStack = new aws_cdk_lib_1.Stack(testApp, 'DefaultChunkingStack');
|
|
342
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(defaultChunkingStack, 'DefaultChunkingTest', {
|
|
343
|
+
enableChunking: true,
|
|
344
|
+
});
|
|
345
|
+
// Verify stack is created successfully with default config
|
|
346
|
+
expect(defaultChunkingStack).toBeDefined();
|
|
347
|
+
});
|
|
348
|
+
test('does not enable chunking when enableChunking is false', () => {
|
|
349
|
+
// Verify that the default stack (without chunking) works as expected
|
|
350
|
+
expect(defaultStack).toBeDefined();
|
|
351
|
+
defaultTemplate.hasResourceProperties('AWS::S3::Bucket', {});
|
|
352
|
+
defaultTemplate.hasResourceProperties('AWS::SQS::Queue', {});
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
describe('Workflow branching for chunking', () => {
|
|
356
|
+
test('creates state machine with chunking workflow', () => {
|
|
357
|
+
// Verify that a state machine is created when chunking is enabled
|
|
358
|
+
chunkingTemplate.resourceCountIs('AWS::StepFunctions::StateMachine', 1);
|
|
359
|
+
// Verify the state machine has the expected configuration
|
|
360
|
+
chunkingTemplate.hasResourceProperties('AWS::StepFunctions::StateMachine', {
|
|
361
|
+
EncryptionConfiguration: assertions_1.Match.objectLike({
|
|
362
|
+
Type: 'CUSTOMER_MANAGED_KMS_KEY',
|
|
363
|
+
}),
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
test('standard workflow is used when chunking is disabled', () => {
|
|
367
|
+
// Verify that when enableChunking is false, the standard workflow is used
|
|
368
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
369
|
+
const noChunkingStack = new aws_cdk_lib_1.Stack(testApp, 'NoChunkingStack');
|
|
370
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(noChunkingStack, 'NoChunkingTest', {
|
|
371
|
+
enableChunking: false,
|
|
372
|
+
});
|
|
373
|
+
const noChunkingTemplate = assertions_1.Template.fromStack(noChunkingStack);
|
|
374
|
+
// Should have state machine
|
|
375
|
+
noChunkingTemplate.resourceCountIs('AWS::StepFunctions::StateMachine', 1);
|
|
376
|
+
// Should NOT have PDF chunking Lambda (Python 3.13 with 2048 MB)
|
|
377
|
+
const lambdas = noChunkingTemplate.findResources('AWS::Lambda::Function');
|
|
378
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
379
|
+
lambda.Properties.MemorySize === 2048);
|
|
380
|
+
expect(chunkingLambda).toBeUndefined();
|
|
381
|
+
});
|
|
382
|
+
test('creates PDF chunking Lambda when chunking is enabled', () => {
|
|
383
|
+
// Verify that the PDF chunking Lambda is created
|
|
384
|
+
const lambdas = chunkingTemplate.findResources('AWS::Lambda::Function');
|
|
385
|
+
// Find the chunking Lambda by its characteristics (Python 3.13, 2048 MB memory)
|
|
386
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
387
|
+
lambda.Properties.MemorySize === 2048 &&
|
|
388
|
+
lambda.Properties.Timeout === 600);
|
|
389
|
+
expect(chunkingLambda).toBeDefined();
|
|
390
|
+
expect(chunkingLambda).toHaveProperty('Properties.Handler', 'handler.handler');
|
|
391
|
+
});
|
|
392
|
+
test('PDF chunking Lambda has correct environment variables for hybrid strategy', () => {
|
|
393
|
+
// Verify chunking configuration is passed via environment variables
|
|
394
|
+
// Find the chunking Lambda specifically
|
|
395
|
+
const lambdas = chunkingTemplate.findResources('AWS::Lambda::Function');
|
|
396
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
397
|
+
lambda.Properties.MemorySize === 2048);
|
|
398
|
+
expect(chunkingLambda).toBeDefined();
|
|
399
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNKING_STRATEGY', 'hybrid');
|
|
400
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.MAX_PAGES_PER_CHUNK', '100');
|
|
401
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.TARGET_TOKENS_PER_CHUNK', '80000');
|
|
402
|
+
});
|
|
403
|
+
test('PDF chunking Lambda has S3 access permissions', () => {
|
|
404
|
+
// Verify that the chunking Lambda has S3 permissions
|
|
405
|
+
chunkingTemplate.hasResourceProperties('AWS::IAM::Role', {
|
|
406
|
+
Policies: assertions_1.Match.arrayWith([
|
|
407
|
+
assertions_1.Match.objectLike({
|
|
408
|
+
PolicyDocument: assertions_1.Match.objectLike({
|
|
409
|
+
Statement: assertions_1.Match.arrayWith([
|
|
410
|
+
assertions_1.Match.objectLike({
|
|
411
|
+
Action: assertions_1.Match.arrayWith([
|
|
412
|
+
's3:GetObject',
|
|
413
|
+
's3:PutObject',
|
|
414
|
+
]),
|
|
415
|
+
}),
|
|
416
|
+
]),
|
|
417
|
+
}),
|
|
418
|
+
}),
|
|
419
|
+
]),
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
test('state machine can invoke PDF chunking Lambda', () => {
|
|
423
|
+
// Verify that the state machine role has permission to invoke the chunking Lambda
|
|
424
|
+
chunkingTemplate.hasResourceProperties('AWS::IAM::Policy', {
|
|
425
|
+
PolicyDocument: assertions_1.Match.objectLike({
|
|
426
|
+
Statement: assertions_1.Match.arrayWith([
|
|
427
|
+
assertions_1.Match.objectLike({
|
|
428
|
+
Action: 'lambda:InvokeFunction',
|
|
429
|
+
Effect: 'Allow',
|
|
430
|
+
}),
|
|
431
|
+
]),
|
|
432
|
+
}),
|
|
433
|
+
});
|
|
434
|
+
});
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
describe('Chunk-aware classification integration', () => {
|
|
438
|
+
describe('Classification Lambda chunk context', () => {
|
|
439
|
+
test('classification Lambda receives chunk metadata in Map State', () => {
|
|
440
|
+
// Verify that the Map State passes chunk metadata to the classification Lambda
|
|
441
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
442
|
+
const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'ChunkContextStack');
|
|
443
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(chunkingStack, 'ChunkContextTest', {
|
|
444
|
+
enableChunking: true,
|
|
445
|
+
chunkingConfig: {
|
|
446
|
+
strategy: 'hybrid',
|
|
447
|
+
maxPagesPerChunk: 100,
|
|
448
|
+
targetTokensPerChunk: 80000,
|
|
449
|
+
},
|
|
450
|
+
});
|
|
451
|
+
const template = assertions_1.Template.fromStack(chunkingStack);
|
|
452
|
+
// Verify state machine is created with Map State
|
|
453
|
+
template.hasResourceProperties('AWS::StepFunctions::StateMachine', {
|
|
454
|
+
DefinitionString: assertions_1.Match.objectLike({
|
|
455
|
+
'Fn::Join': assertions_1.Match.arrayWith(['']),
|
|
456
|
+
}),
|
|
457
|
+
});
|
|
458
|
+
// Verify the state machine definition includes Map state with chunk parameters
|
|
459
|
+
const stateMachines = template.findResources('AWS::StepFunctions::StateMachine');
|
|
460
|
+
const stateMachineDefinition = Object.values(stateMachines)[0];
|
|
461
|
+
expect(stateMachineDefinition).toBeDefined();
|
|
462
|
+
});
|
|
463
|
+
test('non-chunked workflow does not include chunk context', () => {
|
|
464
|
+
// Verify that when chunking is disabled, no chunk context is added
|
|
465
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
466
|
+
const noChunkingStack = new aws_cdk_lib_1.Stack(testApp, 'NoChunkContextStack');
|
|
467
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(noChunkingStack, 'NoChunkContextTest', {
|
|
468
|
+
enableChunking: false,
|
|
469
|
+
});
|
|
470
|
+
const template = assertions_1.Template.fromStack(noChunkingStack);
|
|
471
|
+
// Should have state machine
|
|
472
|
+
template.resourceCountIs('AWS::StepFunctions::StateMachine', 1);
|
|
473
|
+
// Should NOT have PDF chunking Lambda
|
|
474
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
475
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
476
|
+
lambda.Properties.MemorySize === 2048);
|
|
477
|
+
expect(chunkingLambda).toBeUndefined();
|
|
478
|
+
});
|
|
479
|
+
test('chunked workflow includes Map State for parallel chunk processing', () => {
|
|
480
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
481
|
+
const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'MapStateStack');
|
|
482
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(chunkingStack, 'MapStateTest', {
|
|
483
|
+
enableChunking: true,
|
|
484
|
+
chunkingConfig: {
|
|
485
|
+
strategy: 'hybrid',
|
|
486
|
+
processingMode: 'parallel',
|
|
487
|
+
maxConcurrency: 5,
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
const template = assertions_1.Template.fromStack(chunkingStack);
|
|
491
|
+
// Verify state machine is created
|
|
492
|
+
template.resourceCountIs('AWS::StepFunctions::StateMachine', 1);
|
|
493
|
+
// Verify classification Lambda exists
|
|
494
|
+
template.hasResourceProperties('AWS::Lambda::Function', {
|
|
495
|
+
Environment: {
|
|
496
|
+
Variables: {
|
|
497
|
+
INVOKE_TYPE: 'classification',
|
|
498
|
+
},
|
|
499
|
+
},
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
test('classification Lambda is reused for both chunked and non-chunked paths', () => {
|
|
503
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
504
|
+
const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'ReuseStack');
|
|
505
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(chunkingStack, 'ReuseTest', {
|
|
506
|
+
enableChunking: true,
|
|
507
|
+
});
|
|
508
|
+
const template = assertions_1.Template.fromStack(chunkingStack);
|
|
509
|
+
// Count classification Lambdas (should be 1, reused for both paths)
|
|
510
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
511
|
+
const classificationLambdas = Object.values(lambdas).filter((lambda) => lambda.Properties.Environment?.Variables?.INVOKE_TYPE === 'classification');
|
|
512
|
+
// Should have exactly 1 classification Lambda (reused)
|
|
513
|
+
expect(classificationLambdas.length).toBe(1);
|
|
514
|
+
});
|
|
515
|
+
test('workflow maintains backward compatibility for small documents', () => {
|
|
516
|
+
// When chunking is enabled but document is small, it should use standard workflow
|
|
517
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
518
|
+
const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'BackwardCompatStack');
|
|
519
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(chunkingStack, 'BackwardCompatTest', {
|
|
520
|
+
enableChunking: true,
|
|
521
|
+
chunkingConfig: {
|
|
522
|
+
strategy: 'hybrid',
|
|
523
|
+
pageThreshold: 100,
|
|
524
|
+
tokenThreshold: 150000,
|
|
525
|
+
},
|
|
526
|
+
});
|
|
527
|
+
const template = assertions_1.Template.fromStack(chunkingStack);
|
|
528
|
+
// Verify both classification and processing Lambdas exist
|
|
529
|
+
template.hasResourceProperties('AWS::Lambda::Function', {
|
|
530
|
+
Environment: {
|
|
531
|
+
Variables: {
|
|
532
|
+
INVOKE_TYPE: 'classification',
|
|
533
|
+
},
|
|
534
|
+
},
|
|
535
|
+
});
|
|
536
|
+
template.hasResourceProperties('AWS::Lambda::Function', {
|
|
537
|
+
Environment: {
|
|
538
|
+
Variables: {
|
|
539
|
+
INVOKE_TYPE: 'processing',
|
|
540
|
+
},
|
|
541
|
+
},
|
|
542
|
+
});
|
|
543
|
+
// Verify state machine has Choice state for branching
|
|
544
|
+
template.resourceCountIs('AWS::StepFunctions::StateMachine', 1);
|
|
545
|
+
});
|
|
546
|
+
});
|
|
547
|
+
describe('Accuracy comparison between chunked and non-chunked', () => {
|
|
548
|
+
test('both workflows use same classification Lambda function', () => {
|
|
549
|
+
// This ensures accuracy is maintained because the same model and prompt are used
|
|
550
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
551
|
+
const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'AccuracyStack');
|
|
552
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(chunkingStack, 'AccuracyTest', {
|
|
553
|
+
enableChunking: true,
|
|
554
|
+
classificationBedrockModel: {
|
|
555
|
+
fmModelId: aws_bedrock_1.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_HAIKU_20240307_V1_0,
|
|
556
|
+
useCrossRegionInference: false,
|
|
557
|
+
},
|
|
558
|
+
});
|
|
559
|
+
const template = assertions_1.Template.fromStack(chunkingStack);
|
|
560
|
+
// Verify the classification Lambda uses the specified model
|
|
561
|
+
template.hasResourceProperties('AWS::Lambda::Function', {
|
|
562
|
+
Environment: {
|
|
563
|
+
Variables: {
|
|
564
|
+
MODEL_ID: 'anthropic.claude-3-haiku-20240307-v1:0',
|
|
565
|
+
INVOKE_TYPE: 'classification',
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
});
|
|
570
|
+
test('custom classification prompt is used for both chunked and non-chunked', () => {
|
|
571
|
+
const customPrompt = 'Custom classification prompt for testing';
|
|
572
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
573
|
+
const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'CustomPromptStack');
|
|
574
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(chunkingStack, 'CustomPromptTest', {
|
|
575
|
+
enableChunking: true,
|
|
576
|
+
classificationPrompt: customPrompt,
|
|
577
|
+
});
|
|
578
|
+
const template = assertions_1.Template.fromStack(chunkingStack);
|
|
579
|
+
// Verify the custom prompt is set
|
|
580
|
+
template.hasResourceProperties('AWS::Lambda::Function', {
|
|
581
|
+
Environment: {
|
|
582
|
+
Variables: {
|
|
583
|
+
PROMPT: customPrompt,
|
|
584
|
+
INVOKE_TYPE: 'classification',
|
|
585
|
+
},
|
|
586
|
+
},
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
describe('Configuration validation', () => {
|
|
592
|
+
describe('Invalid configuration rejection', () => {
|
|
593
|
+
test('throws error for chunkSize <= 0', () => {
|
|
594
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
595
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'InvalidChunkSizeStack');
|
|
596
|
+
expect(() => {
|
|
597
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'InvalidChunkSizeTest', {
|
|
598
|
+
enableChunking: true,
|
|
599
|
+
chunkingConfig: {
|
|
600
|
+
strategy: 'fixed-pages',
|
|
601
|
+
chunkSize: 0,
|
|
602
|
+
},
|
|
603
|
+
});
|
|
604
|
+
}).toThrow('ChunkingConfig validation error: chunkSize must be greater than 0');
|
|
605
|
+
});
|
|
606
|
+
test('throws error for negative chunkSize', () => {
|
|
607
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
608
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'NegativeChunkSizeStack');
|
|
609
|
+
expect(() => {
|
|
610
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'NegativeChunkSizeTest', {
|
|
611
|
+
enableChunking: true,
|
|
612
|
+
chunkingConfig: {
|
|
613
|
+
strategy: 'fixed-pages',
|
|
614
|
+
chunkSize: -10,
|
|
615
|
+
},
|
|
616
|
+
});
|
|
617
|
+
}).toThrow('ChunkingConfig validation error: chunkSize must be greater than 0');
|
|
618
|
+
});
|
|
619
|
+
test('throws error for negative overlapPages', () => {
|
|
620
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
621
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'NegativeOverlapStack');
|
|
622
|
+
expect(() => {
|
|
623
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'NegativeOverlapTest', {
|
|
624
|
+
enableChunking: true,
|
|
625
|
+
chunkingConfig: {
|
|
626
|
+
strategy: 'fixed-pages',
|
|
627
|
+
chunkSize: 50,
|
|
628
|
+
overlapPages: -5,
|
|
629
|
+
},
|
|
630
|
+
});
|
|
631
|
+
}).toThrow('ChunkingConfig validation error: overlapPages must be non-negative');
|
|
632
|
+
});
|
|
633
|
+
test('throws error for overlapPages >= chunkSize', () => {
|
|
634
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
635
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'OverlapTooLargeStack');
|
|
636
|
+
expect(() => {
|
|
637
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'OverlapTooLargeTest', {
|
|
638
|
+
enableChunking: true,
|
|
639
|
+
chunkingConfig: {
|
|
640
|
+
strategy: 'fixed-pages',
|
|
641
|
+
chunkSize: 50,
|
|
642
|
+
overlapPages: 50,
|
|
643
|
+
},
|
|
644
|
+
});
|
|
645
|
+
}).toThrow('ChunkingConfig validation error: overlapPages must be less than chunkSize');
|
|
646
|
+
});
|
|
647
|
+
test('throws error for pageThreshold <= 0', () => {
|
|
648
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
649
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'InvalidPageThresholdStack');
|
|
650
|
+
expect(() => {
|
|
651
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'InvalidPageThresholdTest', {
|
|
652
|
+
enableChunking: true,
|
|
653
|
+
chunkingConfig: {
|
|
654
|
+
strategy: 'fixed-pages',
|
|
655
|
+
pageThreshold: 0,
|
|
656
|
+
},
|
|
657
|
+
});
|
|
658
|
+
}).toThrow('ChunkingConfig validation error: pageThreshold must be greater than 0');
|
|
659
|
+
});
|
|
660
|
+
test('throws error for tokenThreshold <= 0', () => {
|
|
661
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
662
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'InvalidTokenThresholdStack');
|
|
663
|
+
expect(() => {
|
|
664
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'InvalidTokenThresholdTest', {
|
|
665
|
+
enableChunking: true,
|
|
666
|
+
chunkingConfig: {
|
|
667
|
+
strategy: 'token-based',
|
|
668
|
+
tokenThreshold: -100,
|
|
669
|
+
},
|
|
670
|
+
});
|
|
671
|
+
}).toThrow('ChunkingConfig validation error: tokenThreshold must be greater than 0');
|
|
672
|
+
});
|
|
673
|
+
test('throws error for maxTokensPerChunk <= 0', () => {
|
|
674
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
675
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'InvalidMaxTokensStack');
|
|
676
|
+
expect(() => {
|
|
677
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'InvalidMaxTokensTest', {
|
|
678
|
+
enableChunking: true,
|
|
679
|
+
chunkingConfig: {
|
|
680
|
+
strategy: 'token-based',
|
|
681
|
+
maxTokensPerChunk: 0,
|
|
682
|
+
},
|
|
683
|
+
});
|
|
684
|
+
}).toThrow('ChunkingConfig validation error: maxTokensPerChunk must be greater than 0');
|
|
685
|
+
});
|
|
686
|
+
test('throws error for negative overlapTokens', () => {
|
|
687
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
688
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'NegativeOverlapTokensStack');
|
|
689
|
+
expect(() => {
|
|
690
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'NegativeOverlapTokensTest', {
|
|
691
|
+
enableChunking: true,
|
|
692
|
+
chunkingConfig: {
|
|
693
|
+
strategy: 'token-based',
|
|
694
|
+
overlapTokens: -1000,
|
|
695
|
+
},
|
|
696
|
+
});
|
|
697
|
+
}).toThrow('ChunkingConfig validation error: overlapTokens must be non-negative');
|
|
698
|
+
});
|
|
699
|
+
test('throws error for overlapTokens >= maxTokensPerChunk', () => {
|
|
700
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
701
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'OverlapTokensTooLargeStack');
|
|
702
|
+
expect(() => {
|
|
703
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'OverlapTokensTooLargeTest', {
|
|
704
|
+
enableChunking: true,
|
|
705
|
+
chunkingConfig: {
|
|
706
|
+
strategy: 'token-based',
|
|
707
|
+
maxTokensPerChunk: 50000,
|
|
708
|
+
overlapTokens: 50000,
|
|
709
|
+
},
|
|
710
|
+
});
|
|
711
|
+
}).toThrow('ChunkingConfig validation error: overlapTokens must be less than maxTokensPerChunk');
|
|
712
|
+
});
|
|
713
|
+
test('throws error for maxPagesPerChunk <= 0', () => {
|
|
714
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
715
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'InvalidMaxPagesStack');
|
|
716
|
+
expect(() => {
|
|
717
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'InvalidMaxPagesTest', {
|
|
718
|
+
enableChunking: true,
|
|
719
|
+
chunkingConfig: {
|
|
720
|
+
strategy: 'hybrid',
|
|
721
|
+
maxPagesPerChunk: 0,
|
|
722
|
+
},
|
|
723
|
+
});
|
|
724
|
+
}).toThrow('ChunkingConfig validation error: maxPagesPerChunk must be greater than 0');
|
|
725
|
+
});
|
|
726
|
+
test('throws error for targetTokensPerChunk <= 0', () => {
|
|
727
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
728
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'InvalidTargetTokensStack');
|
|
729
|
+
expect(() => {
|
|
730
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'InvalidTargetTokensTest', {
|
|
731
|
+
enableChunking: true,
|
|
732
|
+
chunkingConfig: {
|
|
733
|
+
strategy: 'hybrid',
|
|
734
|
+
targetTokensPerChunk: -1,
|
|
735
|
+
},
|
|
736
|
+
});
|
|
737
|
+
}).toThrow('ChunkingConfig validation error: targetTokensPerChunk must be greater than 0');
|
|
738
|
+
});
|
|
739
|
+
test('throws error for maxConcurrency <= 0', () => {
|
|
740
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
741
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'InvalidMaxConcurrencyStack');
|
|
742
|
+
expect(() => {
|
|
743
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'InvalidMaxConcurrencyTest', {
|
|
744
|
+
enableChunking: true,
|
|
745
|
+
chunkingConfig: {
|
|
746
|
+
maxConcurrency: 0,
|
|
747
|
+
},
|
|
748
|
+
});
|
|
749
|
+
}).toThrow('ChunkingConfig validation error: maxConcurrency must be greater than 0');
|
|
750
|
+
});
|
|
751
|
+
test('throws error for minSuccessThreshold < 0', () => {
|
|
752
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
753
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'InvalidMinThresholdLowStack');
|
|
754
|
+
expect(() => {
|
|
755
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'InvalidMinThresholdLowTest', {
|
|
756
|
+
enableChunking: true,
|
|
757
|
+
chunkingConfig: {
|
|
758
|
+
minSuccessThreshold: -0.1,
|
|
759
|
+
},
|
|
760
|
+
});
|
|
761
|
+
}).toThrow('ChunkingConfig validation error: minSuccessThreshold must be between 0 and 1');
|
|
762
|
+
});
|
|
763
|
+
test('throws error for minSuccessThreshold > 1', () => {
|
|
764
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
765
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'InvalidMinThresholdHighStack');
|
|
766
|
+
expect(() => {
|
|
767
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'InvalidMinThresholdHighTest', {
|
|
768
|
+
enableChunking: true,
|
|
769
|
+
chunkingConfig: {
|
|
770
|
+
minSuccessThreshold: 1.5,
|
|
771
|
+
},
|
|
772
|
+
});
|
|
773
|
+
}).toThrow('ChunkingConfig validation error: minSuccessThreshold must be between 0 and 1');
|
|
774
|
+
});
|
|
775
|
+
});
|
|
776
|
+
describe('Valid configuration acceptance', () => {
|
|
777
|
+
test('accepts valid boundary values', () => {
|
|
778
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
779
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'ValidBoundaryStack');
|
|
780
|
+
// Should not throw
|
|
781
|
+
expect(() => {
|
|
782
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'ValidBoundaryTest', {
|
|
783
|
+
enableChunking: true,
|
|
784
|
+
chunkingConfig: {
|
|
785
|
+
strategy: 'fixed-pages',
|
|
786
|
+
chunkSize: 1, // minimum valid
|
|
787
|
+
overlapPages: 0, // minimum valid
|
|
788
|
+
pageThreshold: 1, // minimum valid
|
|
789
|
+
},
|
|
790
|
+
});
|
|
791
|
+
}).not.toThrow();
|
|
792
|
+
});
|
|
793
|
+
test('accepts minSuccessThreshold at boundaries', () => {
|
|
794
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
795
|
+
const stack1 = new aws_cdk_lib_1.Stack(testApp, 'MinThreshold0Stack');
|
|
796
|
+
const stack2 = new aws_cdk_lib_1.Stack(testApp, 'MinThreshold1Stack');
|
|
797
|
+
// Should not throw for 0
|
|
798
|
+
expect(() => {
|
|
799
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack1, 'MinThreshold0Test', {
|
|
800
|
+
enableChunking: true,
|
|
801
|
+
chunkingConfig: {
|
|
802
|
+
minSuccessThreshold: 0,
|
|
803
|
+
},
|
|
804
|
+
});
|
|
805
|
+
}).not.toThrow();
|
|
806
|
+
// Should not throw for 1
|
|
807
|
+
expect(() => {
|
|
808
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack2, 'MinThreshold1Test', {
|
|
809
|
+
enableChunking: true,
|
|
810
|
+
chunkingConfig: {
|
|
811
|
+
minSuccessThreshold: 1,
|
|
812
|
+
},
|
|
813
|
+
});
|
|
814
|
+
}).not.toThrow();
|
|
815
|
+
});
|
|
816
|
+
});
|
|
817
|
+
describe('Validation skipped when chunking disabled', () => {
|
|
818
|
+
test('does not validate config when enableChunking is false', () => {
|
|
819
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
820
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'ChunkingDisabledStack');
|
|
821
|
+
// Should not throw even with invalid config because chunking is disabled
|
|
822
|
+
expect(() => {
|
|
823
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'ChunkingDisabledTest', {
|
|
824
|
+
enableChunking: false,
|
|
825
|
+
chunkingConfig: {
|
|
826
|
+
chunkSize: -10, // Invalid but should be ignored
|
|
827
|
+
},
|
|
828
|
+
});
|
|
829
|
+
}).not.toThrow();
|
|
830
|
+
});
|
|
831
|
+
test('does not validate config when enableChunking is undefined', () => {
|
|
832
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
833
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'ChunkingUndefinedStack');
|
|
834
|
+
// Should not throw even with invalid config because chunking is not enabled
|
|
835
|
+
expect(() => {
|
|
836
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'ChunkingUndefinedTest', {
|
|
837
|
+
chunkingConfig: {
|
|
838
|
+
chunkSize: 0, // Invalid but should be ignored
|
|
839
|
+
},
|
|
840
|
+
});
|
|
841
|
+
}).not.toThrow();
|
|
842
|
+
});
|
|
843
|
+
});
|
|
844
|
+
});
|
|
845
|
+
describe('Configuration precedence', () => {
|
|
846
|
+
describe('Default values applied', () => {
|
|
847
|
+
test('uses default strategy when not specified', () => {
|
|
848
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
849
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'DefaultStrategyStack');
|
|
850
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'DefaultStrategyTest', {
|
|
851
|
+
enableChunking: true,
|
|
852
|
+
chunkingConfig: {}, // Empty config, should use defaults
|
|
853
|
+
});
|
|
854
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
855
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
856
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
857
|
+
lambda.Properties.MemorySize === 2048);
|
|
858
|
+
expect(chunkingLambda).toBeDefined();
|
|
859
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNKING_STRATEGY', 'hybrid');
|
|
860
|
+
});
|
|
861
|
+
test('uses default pageThreshold when not specified', () => {
|
|
862
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
863
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'DefaultPageThresholdStack');
|
|
864
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'DefaultPageThresholdTest', {
|
|
865
|
+
enableChunking: true,
|
|
866
|
+
chunkingConfig: {
|
|
867
|
+
strategy: 'fixed-pages',
|
|
868
|
+
},
|
|
869
|
+
});
|
|
870
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
871
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
872
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
873
|
+
lambda.Properties.MemorySize === 2048);
|
|
874
|
+
expect(chunkingLambda).toBeDefined();
|
|
875
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.PAGE_THRESHOLD', '100');
|
|
876
|
+
});
|
|
877
|
+
test('uses default tokenThreshold when not specified', () => {
|
|
878
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
879
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'DefaultTokenThresholdStack');
|
|
880
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'DefaultTokenThresholdTest', {
|
|
881
|
+
enableChunking: true,
|
|
882
|
+
chunkingConfig: {
|
|
883
|
+
strategy: 'token-based',
|
|
884
|
+
},
|
|
885
|
+
});
|
|
886
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
887
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
888
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
889
|
+
lambda.Properties.MemorySize === 2048);
|
|
890
|
+
expect(chunkingLambda).toBeDefined();
|
|
891
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.TOKEN_THRESHOLD', '150000');
|
|
892
|
+
});
|
|
893
|
+
test('uses default maxConcurrency when not specified', () => {
|
|
894
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
895
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'DefaultConcurrencyStack');
|
|
896
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'DefaultConcurrencyTest', {
|
|
897
|
+
enableChunking: true,
|
|
898
|
+
chunkingConfig: {
|
|
899
|
+
processingMode: 'parallel',
|
|
900
|
+
},
|
|
901
|
+
});
|
|
902
|
+
// Verify stack is created successfully with default maxConcurrency of 10
|
|
903
|
+
expect(stack).toBeDefined();
|
|
904
|
+
});
|
|
905
|
+
});
|
|
906
|
+
describe('Custom configuration overrides defaults', () => {
|
|
907
|
+
test('custom strategy overrides default', () => {
|
|
908
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
909
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'CustomStrategyStack');
|
|
910
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'CustomStrategyTest', {
|
|
911
|
+
enableChunking: true,
|
|
912
|
+
chunkingConfig: {
|
|
913
|
+
strategy: 'token-based',
|
|
914
|
+
},
|
|
915
|
+
});
|
|
916
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
917
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
918
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
919
|
+
lambda.Properties.MemorySize === 2048);
|
|
920
|
+
expect(chunkingLambda).toBeDefined();
|
|
921
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNKING_STRATEGY', 'token-based');
|
|
922
|
+
});
|
|
923
|
+
test('custom pageThreshold overrides default', () => {
|
|
924
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
925
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'CustomPageThresholdStack');
|
|
926
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'CustomPageThresholdTest', {
|
|
927
|
+
enableChunking: true,
|
|
928
|
+
chunkingConfig: {
|
|
929
|
+
pageThreshold: 50,
|
|
930
|
+
},
|
|
931
|
+
});
|
|
932
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
933
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
934
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
935
|
+
lambda.Properties.MemorySize === 2048);
|
|
936
|
+
expect(chunkingLambda).toBeDefined();
|
|
937
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.PAGE_THRESHOLD', '50');
|
|
938
|
+
});
|
|
939
|
+
test('custom tokenThreshold overrides default', () => {
|
|
940
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
941
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'CustomTokenThresholdStack');
|
|
942
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'CustomTokenThresholdTest', {
|
|
943
|
+
enableChunking: true,
|
|
944
|
+
chunkingConfig: {
|
|
945
|
+
tokenThreshold: 200000,
|
|
946
|
+
},
|
|
947
|
+
});
|
|
948
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
949
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
950
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
951
|
+
lambda.Properties.MemorySize === 2048);
|
|
952
|
+
expect(chunkingLambda).toBeDefined();
|
|
953
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.TOKEN_THRESHOLD', '200000');
|
|
954
|
+
});
|
|
955
|
+
test('custom chunkSize overrides default', () => {
|
|
956
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
957
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'CustomChunkSizeStack');
|
|
958
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'CustomChunkSizeTest', {
|
|
959
|
+
enableChunking: true,
|
|
960
|
+
chunkingConfig: {
|
|
961
|
+
strategy: 'fixed-pages',
|
|
962
|
+
chunkSize: 25,
|
|
963
|
+
},
|
|
964
|
+
});
|
|
965
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
966
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
967
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
968
|
+
lambda.Properties.MemorySize === 2048);
|
|
969
|
+
expect(chunkingLambda).toBeDefined();
|
|
970
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNK_SIZE', '25');
|
|
971
|
+
});
|
|
972
|
+
test('custom maxPagesPerChunk overrides default', () => {
|
|
973
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
974
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'CustomMaxPagesStack');
|
|
975
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'CustomMaxPagesTest', {
|
|
976
|
+
enableChunking: true,
|
|
977
|
+
chunkingConfig: {
|
|
978
|
+
strategy: 'hybrid',
|
|
979
|
+
maxPagesPerChunk: 75,
|
|
980
|
+
},
|
|
981
|
+
});
|
|
982
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
983
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
984
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
985
|
+
lambda.Properties.MemorySize === 2048);
|
|
986
|
+
expect(chunkingLambda).toBeDefined();
|
|
987
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.MAX_PAGES_PER_CHUNK', '75');
|
|
988
|
+
});
|
|
989
|
+
test('default maxPagesPerChunk is 99 to stay under Bedrock 100-page limit', () => {
|
|
990
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
991
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'DefaultMaxPagesStack');
|
|
992
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'DefaultMaxPagesTest', {
|
|
993
|
+
enableChunking: true,
|
|
994
|
+
chunkingConfig: {
|
|
995
|
+
strategy: 'hybrid',
|
|
996
|
+
// maxPagesPerChunk not specified - should default to 99
|
|
997
|
+
},
|
|
998
|
+
});
|
|
999
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
1000
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
1001
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
1002
|
+
lambda.Properties.MemorySize === 2048);
|
|
1003
|
+
expect(chunkingLambda).toBeDefined();
|
|
1004
|
+
// Default should be 99, not 100, because Bedrock has a hard limit of 100 pages per PDF
|
|
1005
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.MAX_PAGES_PER_CHUNK', '99');
|
|
1006
|
+
});
|
|
1007
|
+
test('custom targetTokensPerChunk overrides default', () => {
|
|
1008
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
1009
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'CustomTargetTokensStack');
|
|
1010
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'CustomTargetTokensTest', {
|
|
1011
|
+
enableChunking: true,
|
|
1012
|
+
chunkingConfig: {
|
|
1013
|
+
strategy: 'hybrid',
|
|
1014
|
+
targetTokensPerChunk: 60000,
|
|
1015
|
+
},
|
|
1016
|
+
});
|
|
1017
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
1018
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
1019
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
1020
|
+
lambda.Properties.MemorySize === 2048);
|
|
1021
|
+
expect(chunkingLambda).toBeDefined();
|
|
1022
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.TARGET_TOKENS_PER_CHUNK', '60000');
|
|
1023
|
+
});
|
|
1024
|
+
test('all custom values override all defaults', () => {
|
|
1025
|
+
const testApp = (0, test_utils_1.createTestApp)();
|
|
1026
|
+
const stack = new aws_cdk_lib_1.Stack(testApp, 'AllCustomStack');
|
|
1027
|
+
new bedrock_document_processing_1.BedrockDocumentProcessing(stack, 'AllCustomTest', {
|
|
1028
|
+
enableChunking: true,
|
|
1029
|
+
chunkingConfig: {
|
|
1030
|
+
strategy: 'fixed-pages',
|
|
1031
|
+
pageThreshold: 200,
|
|
1032
|
+
tokenThreshold: 300000,
|
|
1033
|
+
chunkSize: 75,
|
|
1034
|
+
overlapPages: 10,
|
|
1035
|
+
maxTokensPerChunk: 150000,
|
|
1036
|
+
overlapTokens: 10000,
|
|
1037
|
+
targetTokensPerChunk: 120000,
|
|
1038
|
+
maxPagesPerChunk: 150,
|
|
1039
|
+
processingMode: 'sequential',
|
|
1040
|
+
maxConcurrency: 5,
|
|
1041
|
+
},
|
|
1042
|
+
});
|
|
1043
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
1044
|
+
const lambdas = template.findResources('AWS::Lambda::Function');
|
|
1045
|
+
const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
|
|
1046
|
+
lambda.Properties.MemorySize === 2048);
|
|
1047
|
+
expect(chunkingLambda).toBeDefined();
|
|
1048
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNKING_STRATEGY', 'fixed-pages');
|
|
1049
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.PAGE_THRESHOLD', '200');
|
|
1050
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.TOKEN_THRESHOLD', '300000');
|
|
1051
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNK_SIZE', '75');
|
|
1052
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.OVERLAP_PAGES', '10');
|
|
1053
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.MAX_TOKENS_PER_CHUNK', '150000');
|
|
1054
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.OVERLAP_TOKENS', '10000');
|
|
1055
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.TARGET_TOKENS_PER_CHUNK', '120000');
|
|
1056
|
+
expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.MAX_PAGES_PER_CHUNK', '150');
|
|
1057
|
+
});
|
|
1058
|
+
});
|
|
259
1059
|
});
|
|
260
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVkcm9jay1kb2N1bWVudC1wcm9jZXNzaW5nLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi91c2UtY2FzZXMvZG9jdW1lbnQtcHJvY2Vzc2luZy90ZXN0cy9iZWRyb2NrLWRvY3VtZW50LXByb2Nlc3NpbmcudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZDQUE4QztBQUM5Qyx1REFBeUQ7QUFDekQseURBQW9FO0FBQ3BFLHVEQUFpRTtBQUNqRSwrQ0FBb0U7QUFDcEUsZ0ZBQTJFO0FBRTNFLFFBQVEsQ0FBQywyQkFBMkIsRUFBRSxHQUFHLEVBQUU7SUFDekMsSUFBSSxZQUFtQixDQUFDO0lBQ3hCLElBQUksV0FBa0IsQ0FBQztJQUN2QixJQUFJLGdCQUF1QixDQUFDO0lBQzVCLElBQUksZUFBc0IsQ0FBQztJQUMzQixJQUFJLG1CQUEwQixDQUFDO0lBQy9CLElBQUksa0JBQXlCLENBQUM7SUFDOUIsSUFBSSxrQkFBeUIsQ0FBQztJQUM5QixJQUFJLGVBQXlCLENBQUM7SUFDOUIsSUFBSSxjQUF3QixDQUFDO0lBQzdCLElBQUksbUJBQTZCLENBQUM7SUFDbEMsSUFBSSxrQkFBNEIsQ0FBQztJQUNqQyxJQUFJLHNCQUFnQyxDQUFDO0lBQ3JDLElBQUkscUJBQStCLENBQUM7SUFDcEMsSUFBSSxxQkFBK0IsQ0FBQztJQUVwQyxTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsWUFBWSxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO1FBQzNCLElBQUksdURBQXlCLENBQUMsWUFBWSxFQUFFLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUUvRCxXQUFXLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7UUFDMUIsSUFBSSx1REFBeUIsQ0FBQyxXQUFXLEVBQUUsWUFBWSxFQUFFO1lBQ3ZELDBCQUEwQixFQUFFO2dCQUMxQixTQUFTLEVBQUUsdUNBQXlCLENBQUMsc0NBQXNDO2dCQUMzRSx1QkFBdUIsRUFBRSxL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O0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsc0JBQXNCLEVBQUUsR0FBRyxFQUFFO1FBQ3BDLElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUU7WUFDaEQsZUFBZSxDQUFDLHFCQUFxQixDQUFDLHVCQUF1QixFQUFFO2dCQUM3RCxVQUFVLEVBQUUsR0FBRztnQkFDZixPQUFPLEVBQUUsR0FBRzthQUNiLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLDZDQUE2QyxFQUFFLEdBQUcsRUFBRTtZQUN2RCxlQUFlLENBQUMscUJBQXFCLENBQUMsdUJBQXVCLEVBQUU7Z0JBQzdELFdBQVcsRUFBRTtvQkFDWCxTQUFTLEVBQUU7d0JBQ1QsV0FBVyxFQUFFLGdCQUFnQjtxQkFDOUI7aUJBQ0Y7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7WUFDbkQsZUFBZSxDQUFDLHFCQUFxQixDQUFDLHVCQUF1QixFQUFFO2dCQUM3RCxXQUFXLEVBQUU7b0JBQ1gsU0FBUyxFQUFFO3dCQUNULFdBQVcsRUFBRSxZQUFZO3FCQUMxQjtpQkFDRjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IER1cmF0aW9uLCBTdGFjayB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IE1hdGNoLCBUZW1wbGF0ZSB9IGZyb20gJ2F3cy1jZGstbGliL2Fzc2VydGlvbnMnO1xuaW1wb3J0IHsgRm91bmRhdGlvbk1vZGVsSWRlbnRpZmllciB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1iZWRyb2NrJztcbmltcG9ydCB7IENvZGUsIEZ1bmN0aW9uLCBSdW50aW1lIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBCZWRyb2NrQ3Jvc3NSZWdpb25JbmZlcmVuY2VQcmVmaXggfSBmcm9tICcuLi8uLi9mcmFtZXdvcmsnO1xuaW1wb3J0IHsgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyB9IGZyb20gJy4uL2JlZHJvY2stZG9jdW1lbnQtcHJvY2Vzc2luZyc7XG5cbmRlc2NyaWJlKCdCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nJywgKCkgPT4ge1xuICBsZXQgZGVmYXVsdFN0YWNrOiBTdGFjaztcbiAgbGV0IGN1c3RvbVN0YWNrOiBTdGFjaztcbiAgbGV0IGNyb3NzUmVnaW9uU3RhY2s6IFN0YWNrO1xuICBsZXQgZW5yaWNobWVudFN0YWNrOiBTdGFjaztcbiAgbGV0IHBvc3RQcm9jZXNzaW5nU3RhY2s6IFN0YWNrO1xuICBsZXQgY3VzdG9tUHJvbXB0c1N0YWNrOiBTdGFjaztcbiAgbGV0IGN1c3RvbVRpbWVvdXRTdGFjazogU3RhY2s7XG4gIGxldCBkZWZhdWx0VGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgY3VzdG9tVGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgY3Jvc3NSZWdpb25UZW1wbGF0ZTogVGVtcGxhdGU7XG4gIGxldCBlbnJpY2htZW50VGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgcG9zdFByb2Nlc3NpbmdUZW1wbGF0ZTogVGVtcGxhdGU7XG4gIGxldCBjdXN0b21Qcm9tcHRzVGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgY3VzdG9tVGltZW91dFRlbXBsYXRlOiBUZW1wbGF0ZTtcblxuICBiZWZvcmVBbGwoKCkgPT4ge1xuICAgIGRlZmF1bHRTdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGRlZmF1bHRTdGFjaywgJ0RlZmF1bHRUZXN0Jywge30pO1xuXG4gICAgY3VzdG9tU3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhjdXN0b21TdGFjaywgJ0N1c3RvbVRlc3QnLCB7XG4gICAgICBjbGFzc2lmaWNhdGlvbkJlZHJvY2tNb2RlbDoge1xuICAgICAgICBmbU1vZGVsSWQ6IEZvdW5kYXRpb25Nb2RlbElkZW50aWZpZXIuQU5USFJPUElDX0NMQVVERV8zX0hBSUtVXzIwMjQwMzA3X1YxXzAsXG4gICAgICAgIHVzZUNyb3NzUmVnaW9uSW5mZXJlbmNlOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBwcm9jZXNzaW5nQmVkcm9ja01vZGVsOiB7XG4gICAgICAgIGZtTW9kZWxJZDogRm91bmRhdGlvbk1vZGVsSWRlbnRpZmllci5BTlRIUk9QSUNfQ0xBVURFXzNfSEFJS1VfMjAyNDAzMDdfVjFfMCxcbiAgICAgICAgdXNlQ3Jvc3NSZWdpb25JbmZlcmVuY2U6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNyb3NzUmVnaW9uU3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhjcm9zc1JlZ2lvblN0YWNrLCAnQ3Jvc3NSZWdpb25UZXN0Jywge1xuICAgICAgY2xhc3NpZmljYXRpb25CZWRyb2NrTW9kZWw6IHtcbiAgICAgICAgdXNlQ3Jvc3NSZWdpb25JbmZlcmVuY2U6IHRydWUsXG4gICAgICAgIGNyb3NzUmVnaW9uSW5mZXJlbmNlUHJlZml4OiBCZWRyb2NrQ3Jvc3NSZWdpb25JbmZlcmVuY2VQcmVmaXguRVUsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgZW5yaWNobWVudFN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgY29uc3QgZW5yaWNobWVudEZuID0gbmV3IEZ1bmN0aW9uKGVucmljaG1lbnRTdGFjaywgJ0VucmljaG1lbnRGbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIwX1gsXG4gICAgICBoYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoJ2V4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+ICh7IGVucmljaGVkOiB0cnVlIH0pOycpLFxuICAgIH0pO1xuICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGVucmljaG1lbnRTdGFjaywgJ0VucmljaG1lbnRUZXN0Jywge1xuICAgICAgZW5yaWNobWVudExhbWJkYUZ1bmN0aW9uOiBlbnJpY2htZW50Rm4sXG4gICAgfSk7XG5cbiAgICBwb3N0UHJvY2Vzc2luZ1N0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgY29uc3QgcG9zdFByb2Nlc3NpbmdGbiA9IG5ldyBGdW5jdGlvbihwb3N0UHJvY2Vzc2luZ1N0YWNrLCAnUG9zdFByb2Nlc3NpbmdGbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIwX1gsXG4gICAgICBoYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoJ2V4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+ICh7IHByb2Nlc3NlZDogdHJ1ZSB9KTsnKSxcbiAgICB9KTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhwb3N0UHJvY2Vzc2luZ1N0YWNrLCAnUG9zdFByb2Nlc3NpbmdUZXN0Jywge1xuICAgICAgcG9zdFByb2Nlc3NpbmdMYW1iZGFGdW5jdGlvbjogcG9zdFByb2Nlc3NpbmdGbixcbiAgICB9KTtcblxuICAgIGN1c3RvbVByb21wdHNTdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGN1c3RvbVByb21wdHNTdGFjaywgJ0N1c3RvbVByb21wdHNUZXN0Jywge1xuICAgICAgY2xhc3NpZmljYXRpb25Qcm9tcHQ6ICdDdXN0b20gY2xhc3NpZmljYXRpb24gcHJvbXB0JyxcbiAgICAgIHByb2Nlc3NpbmdQcm9tcHQ6ICdDdXN0b20gcHJvY2Vzc2luZyBwcm9tcHQnLFxuICAgIH0pO1xuXG4gICAgY3VzdG9tVGltZW91dFN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoY3VzdG9tVGltZW91dFN0YWNrLCAnQ3VzdG9tVGltZW91dFRlc3QnLCB7XG4gICAgICBzdGVwVGltZW91dHM6IER1cmF0aW9uLm1pbnV0ZXMoMTApLFxuICAgIH0pO1xuXG4gICAgZGVmYXVsdFRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGRlZmF1bHRTdGFjayk7XG4gICAgY3VzdG9tVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3VzdG9tU3RhY2spO1xuICAgIGNyb3NzUmVnaW9uVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3Jvc3NSZWdpb25TdGFjayk7XG4gICAgZW5yaWNobWVudFRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGVucmljaG1lbnRTdGFjayk7XG4gICAgcG9zdFByb2Nlc3NpbmdUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhwb3N0UHJvY2Vzc2luZ1N0YWNrKTtcbiAgICBjdXN0b21Qcm9tcHRzVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3VzdG9tUHJvbXB0c1N0YWNrKTtcbiAgICBjdXN0b21UaW1lb3V0VGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3VzdG9tVGltZW91dFN0YWNrKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0Jhc2ljIGluZnJhc3RydWN0dXJlJywgKCkgPT4ge1xuICAgIHRlc3QoJ2NyZWF0ZXMgYmFzaWMgaW5mcmFzdHJ1Y3R1cmUnLCAoKSA9PiB7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlMzOjpCdWNrZXQnLCB7fSk7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlNRUzo6UXVldWUnLCB7fSk7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkR5bmFtb0RCOjpUYWJsZScsIHsgQmlsbGluZ01vZGU6ICdQQVlfUEVSX1JFUVVFU1QnIH0pO1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpTdGVwRnVuY3Rpb25zOjpTdGF0ZU1hY2hpbmUnLCB7fSk7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCA1KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2NyZWF0ZXMgY2xhc3NpZmljYXRpb24gYW5kIHByb2Nlc3NpbmcgTGFtYmRhIGZ1bmN0aW9ucycsICgpID0+IHtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIDUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnTW9kZWwgY29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgICB0ZXN0KCd1c2VzIGRlZmF1bHQgbW9kZWwgd2l0aCBjcm9zcy1yZWdpb24gcHJlZml4IGRpc2FibGVkJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgTU9ERUxfSUQ6ICdhbnRocm9waWMuY2xhdWRlLXNvbm5ldC00LTIwMjUwNTE0LXYxOjAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3VzZXMgY3VzdG9tIG1vZGVsIHdpdGhvdXQgY3Jvc3MtcmVnaW9uIHByZWZpeCcsICgpID0+IHtcbiAgICAgIGN1c3RvbVRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgTU9ERUxfSUQ6ICdhbnRocm9waWMuY2xhdWRlLTMtaGFpa3UtMjAyNDAzMDctdjE6MCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnY29uZmlndXJlcyBjdXN0b20gY3Jvc3MtcmVnaW9uIHByZWZpeCcsICgpID0+IHtcbiAgICAgIGNyb3NzUmVnaW9uVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBNT0RFTF9JRDogJ2V1LmFudGhyb3BpYy5jbGF1ZGUtc29ubmV0LTQtMjAyNTA1MTQtdjE6MCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnY29uZmlndXJlcyBkaWZmZXJlbnQgbW9kZWxzIGZvciBjbGFzc2lmaWNhdGlvbiBhbmQgcHJvY2Vzc2luZycsICgpID0+IHtcbiAgICAgIGN1c3RvbVRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgTU9ERUxfSUQ6ICdhbnRocm9waWMuY2xhdWRlLTMtaGFpa3UtMjAyNDAzMDctdjE6MCcsXG4gICAgICAgICAgICBJTlZPS0VfVFlQRTogJ2NsYXNzaWZpY2F0aW9uJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBjdXN0b21UZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgIE1PREVMX0lEOiAnYW50aHJvcGljLmNsYXVkZS0zLWhhaWt1LTIwMjQwMzA3LXYxOjAnLFxuICAgICAgICAgICAgSU5WT0tFX1RZUEU6ICdwcm9jZXNzaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdJQU0gcGVybWlzc2lvbnMnLCAoKSA9PiB7XG4gICAgdGVzdCgnY3JlYXRlcyBiZWRyb2NrIHBlcm1pc3Npb25zJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpJQU06OlJvbGUnLCB7XG4gICAgICAgIEFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudDoge1xuICAgICAgICAgIFN0YXRlbWVudDogW3tcbiAgICAgICAgICAgIEFjdGlvbjogJ3N0czpBc3N1bWVSb2xlJyxcbiAgICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgICAgIFByaW5jaXBhbDogeyBTZXJ2aWNlOiAnbGFtYmRhLmFtYXpvbmF3cy5jb20nIH0sXG4gICAgICAgICAgfV0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2dyYW50cyBCZWRyb2NrIGludm9rZSBwZXJtaXNzaW9ucycsICgpID0+IHtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6SUFNOjpSb2xlJywge1xuICAgICAgICBQb2xpY2llczogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgIFBvbGljeURvY3VtZW50OiB7XG4gICAgICAgICAgICAgIFN0YXRlbWVudDogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgICAgICAgIEFjdGlvbjogWydiZWRyb2NrOkludm9rZU1vZGVsJywgJ2JlZHJvY2s6SW52b2tlTW9kZWxXaXRoUmVzcG9uc2VTdHJlYW0nXSxcbiAgICAgICAgICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICBdKSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnZ3JhbnRzIFMzIGFjY2VzcyBwZXJtaXNzaW9ucycsICgpID0+IHtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6SUFNOjpSb2xlJywge1xuICAgICAgICBQb2xpY2llczogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgIFBvbGljeURvY3VtZW50OiB7XG4gICAgICAgICAgICAgIFN0YXRlbWVudDogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgICAgICAgIEFjdGlvbjogTWF0Y2guYXJyYXlXaXRoKFsnczM6R2V0T2JqZWN0J10pLFxuICAgICAgICAgICAgICAgICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0pLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdPcHRpb25hbCB3b3JrZmxvdyBzdGVwcycsICgpID0+IHtcbiAgICB0ZXN0KCdpbmNsdWRlcyBlbnJpY2htZW50IExhbWJkYSB3aGVuIHByb3ZpZGVkJywgKCkgPT4ge1xuICAgICAgZW5yaWNobWVudFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBIYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICB9KTtcbiAgICAgIGVucmljaG1lbnRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywge1xuICAgICAgICBEZWZpbml0aW9uU3RyaW5nOiBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAnRm46OkpvaW4nOiBNYXRjaC5hcnJheVdpdGgoWycnXSksXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdpbmNsdWRlcyBwb3N0LXByb2Nlc3NpbmcgTGFtYmRhIHdoZW4gcHJvdmlkZWQnLCAoKSA9PiB7XG4gICAgICBwb3N0UHJvY2Vzc2luZ1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBIYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICB9KTtcbiAgICAgIHBvc3RQcm9jZXNzaW5nVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIHtcbiAgICAgICAgRGVmaW5pdGlvblN0cmluZzogTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgJ0ZuOjpKb2luJzogTWF0Y2guYXJyYXlXaXRoKFsnJ10pLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQ3VzdG9tIGNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gICAgdGVzdCgndXNlcyBjdXN0b20gY2xhc3NpZmljYXRpb24gcHJvbXB0JywgKCkgPT4ge1xuICAgICAgY3VzdG9tUHJvbXB0c1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgUFJPTVBUOiAnQ3VzdG9tIGNsYXNzaWZpY2F0aW9uIHByb21wdCcsXG4gICAgICAgICAgICBJTlZPS0VfVFlQRTogJ2NsYXNzaWZpY2F0aW9uJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd1c2VzIGN1c3RvbSBwcm9jZXNzaW5nIHByb21wdCcsICgpID0+IHtcbiAgICAgIGN1c3RvbVByb21wdHNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgIFBST01QVDogJ0N1c3RvbSBwcm9jZXNzaW5nIHByb21wdCcsXG4gICAgICAgICAgICBJTlZPS0VfVFlQRTogJ3Byb2Nlc3NpbmcnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2NvbmZpZ3VyZXMgY3VzdG9tIHN0ZXAgdGltZW91dCcsICgpID0+IHtcbiAgICAgIGN1c3RvbVRpbWVvdXRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgVGltZW91dDogNjAwLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdMYW1iZGEgY29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgICB0ZXN0KCdjb25maWd1cmVzIExhbWJkYSBtZW1vcnkgYW5kIHRpbWVvdXQnLCAoKSA9PiB7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIE1lbW9yeVNpemU6IDUxMixcbiAgICAgICAgVGltZW91dDogMzAwLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzZXRzIGNvcnJlY3QgaW52b2tlIHR5cGUgZm9yIGNsYXNzaWZpY2F0aW9uJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgSU5WT0tFX1RZUEU6ICdjbGFzc2lmaWNhdGlvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2V0cyBjb3JyZWN0IGludm9rZSB0eXBlIGZvciBwcm9jZXNzaW5nJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgSU5WT0tFX1RZUEU6ICdwcm9jZXNzaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
|
|
1060
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVkcm9jay1kb2N1bWVudC1wcm9jZXNzaW5nLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi91c2UtY2FzZXMvZG9jdW1lbnQtcHJvY2Vzc2luZy90ZXN0cy9iZWRyb2NrLWRvY3VtZW50LXByb2Nlc3NpbmcudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZDQUFtRDtBQUNuRCx1REFBeUQ7QUFDekQseURBQW9FO0FBQ3BFLHVEQUFpRTtBQUNqRSwrQ0FBb0U7QUFDcEUsMkRBQTJEO0FBQzNELGdGQUEyRTtBQUUzRSxRQUFRLENBQUMsMkJBQTJCLEVBQUUsR0FBRyxFQUFFO0lBQ3pDLElBQUksR0FBUSxDQUFDO0lBQ2IsSUFBSSxZQUFtQixDQUFDO0lBQ3hCLElBQUksV0FBa0IsQ0FBQztJQUN2QixJQUFJLGdCQUF1QixDQUFDO0lBQzVCLElBQUksZUFBc0IsQ0FBQztJQUMzQixJQUFJLG1CQUEwQixDQUFDO0lBQy9CLElBQUksa0JBQXlCLENBQUM7SUFDOUIsSUFBSSxrQkFBeUIsQ0FBQztJQUM5QixJQUFJLGFBQW9CLENBQUM7SUFDekIsSUFBSSxlQUF5QixDQUFDO0lBQzlCLElBQUksY0FBd0IsQ0FBQztJQUM3QixJQUFJLG1CQUE2QixDQUFDO0lBQ2xDLElBQUksa0JBQTRCLENBQUM7SUFDakMsSUFBSSxzQkFBZ0MsQ0FBQztJQUNyQyxJQUFJLHFCQUErQixDQUFDO0lBQ3BDLElBQUkscUJBQStCLENBQUM7SUFDcEMsSUFBSSxnQkFBMEIsQ0FBQztJQUUvQixTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsMERBQTBEO1FBQzFELEdBQUcsR0FBRyxJQUFBLDBCQUFhLEdBQUUsQ0FBQztRQUV0QixZQUFZLEdBQUcsSUFBSSxtQkFBSyxDQUFDLEdBQUcsRUFBRSxjQUFjLENBQUMsQ0FBQztRQUM5QyxJQUFJLHVEQUF5QixDQUFDLFlBQVksRUFBRSxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFL0Qs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QUFhLENBQUMsQ0FBQztZQUMzRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsY0FBYyxDQUFDLGlEQUFpRCxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2hHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxjQUFjLENBQUMsa0RBQWtELEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDcEcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyw2Q0FBNkMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMzRixNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsY0FBYyxDQUFDLGdEQUFnRCxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzlGLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxjQUFjLENBQUMsdURBQXVELEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDekcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxpREFBaUQsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNsRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsY0FBYyxDQUFDLDBEQUEwRCxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzVHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxjQUFjLENBQUMsc0RBQXNELEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkcsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXBwLCBEdXJhdGlvbiwgU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBNYXRjaCwgVGVtcGxhdGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hc3NlcnRpb25zJztcbmltcG9ydCB7IEZvdW5kYXRpb25Nb2RlbElkZW50aWZpZXIgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtYmVkcm9jayc7XG5pbXBvcnQgeyBDb2RlLCBGdW5jdGlvbiwgUnVudGltZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgQmVkcm9ja0Nyb3NzUmVnaW9uSW5mZXJlbmNlUHJlZml4IH0gZnJvbSAnLi4vLi4vZnJhbWV3b3JrJztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBcHAgfSBmcm9tICcuLi8uLi91dGlsaXRpZXMvdGVzdC11dGlscyc7XG5pbXBvcnQgeyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nIH0gZnJvbSAnLi4vYmVkcm9jay1kb2N1bWVudC1wcm9jZXNzaW5nJztcblxuZGVzY3JpYmUoJ0JlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcnLCAoKSA9PiB7XG4gIGxldCBhcHA6IEFwcDtcbiAgbGV0IGRlZmF1bHRTdGFjazogU3RhY2s7XG4gIGxldCBjdXN0b21TdGFjazogU3RhY2s7XG4gIGxldCBjcm9zc1JlZ2lvblN0YWNrOiBTdGFjaztcbiAgbGV0IGVucmljaG1lbnRTdGFjazogU3RhY2s7XG4gIGxldCBwb3N0UHJvY2Vzc2luZ1N0YWNrOiBTdGFjaztcbiAgbGV0IGN1c3RvbVByb21wdHNTdGFjazogU3RhY2s7XG4gIGxldCBjdXN0b21UaW1lb3V0U3RhY2s6IFN0YWNrO1xuICBsZXQgY2h1bmtpbmdTdGFjazogU3RhY2s7XG4gIGxldCBkZWZhdWx0VGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgY3VzdG9tVGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgY3Jvc3NSZWdpb25UZW1wbGF0ZTogVGVtcGxhdGU7XG4gIGxldCBlbnJpY2htZW50VGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgcG9zdFByb2Nlc3NpbmdUZW1wbGF0ZTogVGVtcGxhdGU7XG4gIGxldCBjdXN0b21Qcm9tcHRzVGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgY3VzdG9tVGltZW91dFRlbXBsYXRlOiBUZW1wbGF0ZTtcbiAgbGV0IGNodW5raW5nVGVtcGxhdGU6IFRlbXBsYXRlO1xuXG4gIGJlZm9yZUFsbCgoKSA9PiB7XG4gICAgLy8gVXNlIGNyZWF0ZVRlc3RBcHAoKSB0byBza2lwIGJ1bmRsaW5nIGFuZCBzcGVlZCB1cCB0ZXN0c1xuICAgIGFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcblxuICAgIGRlZmF1bHRTdGFjayA9IG5ldyBTdGFjayhhcHAsICdEZWZhdWx0U3RhY2snKTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhkZWZhdWx0U3RhY2ssICdEZWZhdWx0VGVzdCcsIHt9KTtcblxuICAgIGN1c3RvbVN0YWNrID0gbmV3IFN0YWNrKGFwcCwgJ0N1c3RvbVN0YWNrJyk7XG4gICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoY3VzdG9tU3RhY2ssICdDdXN0b21UZXN0Jywge1xuICAgICAgY2xhc3NpZmljYXRpb25CZWRyb2NrTW9kZWw6IHtcbiAgICAgICAgZm1Nb2RlbElkOiBGb3VuZGF0aW9uTW9kZWxJZGVudGlmaWVyLkFOVEhST1BJQ19DTEFVREVfM19IQUlLVV8yMDI0MDMwN19WMV8wLFxuICAgICAgICB1c2VDcm9zc1JlZ2lvbkluZmVyZW5jZTogZmFsc2UsXG4gICAgICB9LFxuICAgICAgcHJvY2Vzc2luZ0JlZHJvY2tNb2RlbDoge1xuICAgICAgICBmbU1vZGVsSWQ6IEZvdW5kYXRpb25Nb2RlbElkZW50aWZpZXIuQU5USFJPUElDX0NMQVVERV8zX0hBSUtVXzIwMjQwMzA3X1YxXzAsXG4gICAgICAgIHVzZUNyb3NzUmVnaW9uSW5mZXJlbmNlOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjcm9zc1JlZ2lvblN0YWNrID0gbmV3IFN0YWNrKGFwcCwgJ0Nyb3NzUmVnaW9uU3RhY2snKTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhjcm9zc1JlZ2lvblN0YWNrLCAnQ3Jvc3NSZWdpb25UZXN0Jywge1xuICAgICAgY2xhc3NpZmljYXRpb25CZWRyb2NrTW9kZWw6IHtcbiAgICAgICAgdXNlQ3Jvc3NSZWdpb25JbmZlcmVuY2U6IHRydWUsXG4gICAgICAgIGNyb3NzUmVnaW9uSW5mZXJlbmNlUHJlZml4OiBCZWRyb2NrQ3Jvc3NSZWdpb25JbmZlcmVuY2VQcmVmaXguRVUsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgZW5yaWNobWVudFN0YWNrID0gbmV3IFN0YWNrKGFwcCwgJ0VucmljaG1lbnRTdGFjaycpO1xuICAgIGNvbnN0IGVucmljaG1lbnRGbiA9IG5ldyBGdW5jdGlvbihlbnJpY2htZW50U3RhY2ssICdFbnJpY2htZW50Rm4nLCB7XG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMF9YLFxuICAgICAgaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFxuICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKCdleHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoKSA9PiAoeyBlbnJpY2hlZDogdHJ1ZSB9KTsnKSxcbiAgICB9KTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhlbnJpY2htZW50U3RhY2ssICdFbnJpY2htZW50VGVzdCcsIHtcbiAgICAgIGVucmljaG1lbnRMYW1iZGFGdW5jdGlvbjogZW5yaWNobWVudEZuLFxuICAgIH0pO1xuXG4gICAgcG9zdFByb2Nlc3NpbmdTdGFjayA9IG5ldyBTdGFjayhhcHAsICdQb3N0UHJvY2Vzc2luZ1N0YWNrJyk7XG4gICAgY29uc3QgcG9zdFByb2Nlc3NpbmdGbiA9IG5ldyBGdW5jdGlvbihwb3N0UHJvY2Vzc2luZ1N0YWNrLCAnUG9zdFByb2Nlc3NpbmdGbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIwX1gsXG4gICAgICBoYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoJ2V4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+ICh7IHByb2Nlc3NlZDogdHJ1ZSB9KTsnKSxcbiAgICB9KTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhwb3N0UHJvY2Vzc2luZ1N0YWNrLCAnUG9zdFByb2Nlc3NpbmdUZXN0Jywge1xuICAgICAgcG9zdFByb2Nlc3NpbmdMYW1iZGFGdW5jdGlvbjogcG9zdFByb2Nlc3NpbmdGbixcbiAgICB9KTtcblxuICAgIGN1c3RvbVByb21wdHNTdGFjayA9IG5ldyBTdGFjayhhcHAsICdDdXN0b21Qcm9tcHRzU3RhY2snKTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhjdXN0b21Qcm9tcHRzU3RhY2ssICdDdXN0b21Qcm9tcHRzVGVzdCcsIHtcbiAgICAgIGNsYXNzaWZpY2F0aW9uUHJvbXB0OiAnQ3VzdG9tIGNsYXNzaWZpY2F0aW9uIHByb21wdCcsXG4gICAgICBwcm9jZXNzaW5nUHJvbXB0OiAnQ3VzdG9tIHByb2Nlc3NpbmcgcHJvbXB0JyxcbiAgICB9KTtcblxuICAgIGN1c3RvbVRpbWVvdXRTdGFjayA9IG5ldyBTdGFjayhhcHAsICdDdXN0b21UaW1lb3V0U3RhY2snKTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhjdXN0b21UaW1lb3V0U3RhY2ssICdDdXN0b21UaW1lb3V0VGVzdCcsIHtcbiAgICAgIHN0ZXBUaW1lb3V0czogRHVyYXRpb24ubWludXRlcygxMCksXG4gICAgfSk7XG5cbiAgICBjaHVua2luZ1N0YWNrID0gbmV3IFN0YWNrKGFwcCwgJ0NodW5raW5nU3RhY2snKTtcbiAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhjaHVua2luZ1N0YWNrLCAnQ2h1bmtpbmdUZXN0Jywge1xuICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICBzdHJhdGVneTogJ2h5YnJpZCcsXG4gICAgICAgIG1heFBhZ2VzUGVyQ2h1bms6IDEwMCxcbiAgICAgICAgdGFyZ2V0VG9rZW5zUGVyQ2h1bms6IDgwMDAwLFxuICAgICAgICBwYWdlVGhyZXNob2xkOiAxMDAsXG4gICAgICAgIHRva2VuVGhyZXNob2xkOiAxNTAwMDAsXG4gICAgICAgIHByb2Nlc3NpbmdNb2RlOiAncGFyYWxsZWwnLFxuICAgICAgICBtYXhDb25jdXJyZW5jeTogMTAsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgZGVmYXVsdFRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGRlZmF1bHRTdGFjayk7XG4gICAgY3VzdG9tVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3VzdG9tU3RhY2spO1xuICAgIGNyb3NzUmVnaW9uVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3Jvc3NSZWdpb25TdGFjayk7XG4gICAgZW5yaWNobWVudFRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGVucmljaG1lbnRTdGFjayk7XG4gICAgcG9zdFByb2Nlc3NpbmdUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhwb3N0UHJvY2Vzc2luZ1N0YWNrKTtcbiAgICBjdXN0b21Qcm9tcHRzVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3VzdG9tUHJvbXB0c1N0YWNrKTtcbiAgICBjdXN0b21UaW1lb3V0VGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY3VzdG9tVGltZW91dFN0YWNrKTtcbiAgICBjaHVua2luZ1RlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGNodW5raW5nU3RhY2spO1xuICB9KTtcblxuICBkZXNjcmliZSgnQmFzaWMgaW5mcmFzdHJ1Y3R1cmUnLCAoKSA9PiB7XG4gICAgdGVzdCgnY3JlYXRlcyBiYXNpYyBpbmZyYXN0cnVjdHVyZScsICgpID0+IHtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6UzM6OkJ1Y2tldCcsIHt9KTtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6U1FTOjpRdWV1ZScsIHt9KTtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6RHluYW1vREI6OlRhYmxlJywgeyBCaWxsaW5nTW9kZTogJ1BBWV9QRVJfUkVRVUVTVCcgfSk7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIHt9KTtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIDUpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnY3JlYXRlcyBjbGFzc2lmaWNhdGlvbiBhbmQgcHJvY2Vzc2luZyBMYW1iZGEgZnVuY3Rpb25zJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLnJlc291cmNlQ291bnRJcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywgNSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdNb2RlbCBjb25maWd1cmF0aW9uJywgKCkgPT4ge1xuICAgIHRlc3QoJ3VzZXMgZGVmYXVsdCBtb2RlbCB3aXRoIGNyb3NzLXJlZ2lvbiBwcmVmaXggZGlzYWJsZWQnLCAoKSA9PiB7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBNT0RFTF9JRDogJ2FudGhyb3BpYy5jbGF1ZGUtc29ubmV0LTQtMjAyNTA1MTQtdjE6MCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgndXNlcyBjdXN0b20gbW9kZWwgd2l0aG91dCBjcm9zcy1yZWdpb24gcHJlZml4JywgKCkgPT4ge1xuICAgICAgY3VzdG9tVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBNT0RFTF9JRDogJ2FudGhyb3BpYy5jbGF1ZGUtMy1oYWlrdS0yMDI0MDMwNy12MTowJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdjb25maWd1cmVzIGN1c3RvbSBjcm9zcy1yZWdpb24gcHJlZml4JywgKCkgPT4ge1xuICAgICAgY3Jvc3NSZWdpb25UZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgIE1PREVMX0lEOiAnZXUuYW50aHJvcGljLmNsYXVkZS1zb25uZXQtNC0yMDI1MDUxNC12MTowJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdjb25maWd1cmVzIGRpZmZlcmVudCBtb2RlbHMgZm9yIGNsYXNzaWZpY2F0aW9uIGFuZCBwcm9jZXNzaW5nJywgKCkgPT4ge1xuICAgICAgY3VzdG9tVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBNT0RFTF9JRDogJ2FudGhyb3BpYy5jbGF1ZGUtMy1oYWlrdS0yMDI0MDMwNy12MTowJyxcbiAgICAgICAgICAgIElOVk9LRV9UWVBFOiAnY2xhc3NpZmljYXRpb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGN1c3RvbVRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgTU9ERUxfSUQ6ICdhbnRocm9waWMuY2xhdWRlLTMtaGFpa3UtMjAyNDAzMDctdjE6MCcsXG4gICAgICAgICAgICBJTlZPS0VfVFlQRTogJ3Byb2Nlc3NpbmcnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0lBTSBwZXJtaXNzaW9ucycsICgpID0+IHtcbiAgICB0ZXN0KCdjcmVhdGVzIGJlZHJvY2sgcGVybWlzc2lvbnMnLCAoKSA9PiB7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OklBTTo6Um9sZScsIHtcbiAgICAgICAgQXNzdW1lUm9sZVBvbGljeURvY3VtZW50OiB7XG4gICAgICAgICAgU3RhdGVtZW50OiBbe1xuICAgICAgICAgICAgQWN0aW9uOiAnc3RzOkFzc3VtZVJvbGUnLFxuICAgICAgICAgICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgICAgICAgICAgUHJpbmNpcGFsOiB7IFNlcnZpY2U6ICdsYW1iZGEuYW1hem9uYXdzLmNvbScgfSxcbiAgICAgICAgICB9XSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnZ3JhbnRzIEJlZHJvY2sgaW52b2tlIHBlcm1pc3Npb25zJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpJQU06OlJvbGUnLCB7XG4gICAgICAgIFBvbGljaWVzOiBNYXRjaC5hcnJheVdpdGgoW1xuICAgICAgICAgIE1hdGNoLm9iamVjdExpa2Uoe1xuICAgICAgICAgICAgUG9saWN5RG9jdW1lbnQ6IHtcbiAgICAgICAgICAgICAgU3RhdGVtZW50OiBNYXRjaC5hcnJheVdpdGgoW1xuICAgICAgICAgICAgICAgIE1hdGNoLm9iamVjdExpa2Uoe1xuICAgICAgICAgICAgICAgICAgQWN0aW9uOiBbJ2JlZHJvY2s6SW52b2tlTW9kZWwnLCAnYmVkcm9jazpJbnZva2VNb2RlbFdpdGhSZXNwb25zZVN0cmVhbSddLFxuICAgICAgICAgICAgICAgICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0pLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdncmFudHMgUzMgYWNjZXNzIHBlcm1pc3Npb25zJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpJQU06OlJvbGUnLCB7XG4gICAgICAgIFBvbGljaWVzOiBNYXRjaC5hcnJheVdpdGgoW1xuICAgICAgICAgIE1hdGNoLm9iamVjdExpa2Uoe1xuICAgICAgICAgICAgUG9saWN5RG9jdW1lbnQ6IHtcbiAgICAgICAgICAgICAgU3RhdGVtZW50OiBNYXRjaC5hcnJheVdpdGgoW1xuICAgICAgICAgICAgICAgIE1hdGNoLm9iamVjdExpa2Uoe1xuICAgICAgICAgICAgICAgICAgQWN0aW9uOiBNYXRjaC5hcnJheVdpdGgoWydzMzpHZXRPYmplY3QnXSksXG4gICAgICAgICAgICAgICAgICBFZmZlY3Q6ICdBbGxvdycsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSksXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ09wdGlvbmFsIHdvcmtmbG93IHN0ZXBzJywgKCkgPT4ge1xuICAgIHRlc3QoJ2luY2x1ZGVzIGVucmljaG1lbnQgTGFtYmRhIHdoZW4gcHJvdmlkZWQnLCAoKSA9PiB7XG4gICAgICBlbnJpY2htZW50VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIH0pO1xuICAgICAgZW5yaWNobWVudFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpTdGVwRnVuY3Rpb25zOjpTdGF0ZU1hY2hpbmUnLCB7XG4gICAgICAgIERlZmluaXRpb25TdHJpbmc6IE1hdGNoLm9iamVjdExpa2Uoe1xuICAgICAgICAgICdGbjo6Sm9pbic6IE1hdGNoLmFycmF5V2l0aChbJyddKSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2luY2x1ZGVzIHBvc3QtcHJvY2Vzc2luZyBMYW1iZGEgd2hlbiBwcm92aWRlZCcsICgpID0+IHtcbiAgICAgIHBvc3RQcm9jZXNzaW5nVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIH0pO1xuICAgICAgcG9zdFByb2Nlc3NpbmdUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywge1xuICAgICAgICBEZWZpbml0aW9uU3RyaW5nOiBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAnRm46OkpvaW4nOiBNYXRjaC5hcnJheVdpdGgoWycnXSksXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdDdXN0b20gY29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgICB0ZXN0KCd1c2VzIGN1c3RvbSBjbGFzc2lmaWNhdGlvbiBwcm9tcHQnLCAoKSA9PiB7XG4gICAgICBjdXN0b21Qcm9tcHRzVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBQUk9NUFQ6ICdDdXN0b20gY2xhc3NpZmljYXRpb24gcHJvbXB0JyxcbiAgICAgICAgICAgIElOVk9LRV9UWVBFOiAnY2xhc3NpZmljYXRpb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3VzZXMgY3VzdG9tIHByb2Nlc3NpbmcgcHJvbXB0JywgKCkgPT4ge1xuICAgICAgY3VzdG9tUHJvbXB0c1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgUFJPTVBUOiAnQ3VzdG9tIHByb2Nlc3NpbmcgcHJvbXB0JyxcbiAgICAgICAgICAgIElOVk9LRV9UWVBFOiAncHJvY2Vzc2luZycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnY29uZmlndXJlcyBjdXN0b20gc3RlcCB0aW1lb3V0JywgKCkgPT4ge1xuICAgICAgY3VzdG9tVGltZW91dFRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBUaW1lb3V0OiA2MDAsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0xhbWJkYSBjb25maWd1cmF0aW9uJywgKCkgPT4ge1xuICAgIHRlc3QoJ2NvbmZpZ3VyZXMgTGFtYmRhIG1lbW9yeSBhbmQgdGltZW91dCcsICgpID0+IHtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgTWVtb3J5U2l6ZTogNTEyLFxuICAgICAgICBUaW1lb3V0OiAzMDAsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3NldHMgY29ycmVjdCBpbnZva2UgdHlwZSBmb3IgY2xhc3NpZmljYXRpb24nLCAoKSA9PiB7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBJTlZPS0VfVFlQRTogJ2NsYXNzaWZpY2F0aW9uJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzZXRzIGNvcnJlY3QgaW52b2tlIHR5cGUgZm9yIHByb2Nlc3NpbmcnLCAoKSA9PiB7XG4gICAgICBkZWZhdWx0VGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBJTlZPS0VfVFlQRTogJ3Byb2Nlc3NpbmcnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0NodW5raW5nIGNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gICAgdGVzdCgnYWNjZXB0cyBlbmFibGVDaHVua2luZyBwcm9wJywgKCkgPT4ge1xuICAgICAgLy8gVGhpcyB0ZXN0IHZlcmlmaWVzIHRoYXQgdGhlIEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmdQcm9wcyBpbnRlcmZhY2VcbiAgICAgIC8vIGNvcnJlY3RseSBhY2NlcHRzIHRoZSBlbmFibGVDaHVua2luZyBib29sZWFuIGZsYWdcbiAgICAgIGV4cGVjdChjaHVua2luZ1N0YWNrKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnYWNjZXB0cyBjaHVua2luZ0NvbmZpZyBwcm9wIHdpdGggYWxsIHN0cmF0ZWd5IG9wdGlvbnMnLCAoKSA9PiB7XG4gICAgICAvLyBUaGlzIHRlc3QgdmVyaWZpZXMgdGhhdCB0aGUgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZ1Byb3BzIGludGVyZmFjZVxuICAgICAgLy8gY29ycmVjdGx5IGFjY2VwdHMgdGhlIGNodW5raW5nQ29uZmlnIHdpdGggYWxsIGNvbmZpZ3VyYXRpb24gb3B0aW9uc1xuICAgICAgY2h1bmtpbmdUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6UzM6OkJ1Y2tldCcsIHt9KTtcbiAgICAgIGNodW5raW5nVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlNRUzo6UXVldWUnLCB7fSk7XG4gICAgICBjaHVua2luZ1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpEeW5hbW9EQjo6VGFibGUnLCB7IEJpbGxpbmdNb2RlOiAnUEFZX1BFUl9SRVFVRVNUJyB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2FjY2VwdHMgZml4ZWQtcGFnZXMgc3RyYXRlZ3kgY29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBmaXhlZFBhZ2VzU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0ZpeGVkUGFnZXNTdGFjaycpO1xuICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoZml4ZWRQYWdlc1N0YWNrLCAnRml4ZWRQYWdlc1Rlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgIHN0cmF0ZWd5OiAnZml4ZWQtcGFnZXMnLFxuICAgICAgICAgIHBhZ2VUaHJlc2hvbGQ6IDEwMCxcbiAgICAgICAgICBjaHVua1NpemU6IDUwLFxuICAgICAgICAgIG92ZXJsYXBQYWdlczogNSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBWZXJpZnkgc3RhY2sgaXMgY3JlYXRlZCBzdWNjZXNzZnVsbHlcbiAgICAgIGV4cGVjdChmaXhlZFBhZ2VzU3RhY2spLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdhY2NlcHRzIHRva2VuLWJhc2VkIHN0cmF0ZWd5IGNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3QgdG9rZW5CYXNlZFN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdUb2tlbkJhc2VkU3RhY2snKTtcbiAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKHRva2VuQmFzZWRTdGFjaywgJ1Rva2VuQmFzZWRUZXN0Jywge1xuICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICBzdHJhdGVneTogJ3Rva2VuLWJhc2VkJyxcbiAgICAgICAgICB0b2tlblRocmVzaG9sZDogMTUwMDAwLFxuICAgICAgICAgIG1heFRva2Vuc1BlckNodW5rOiAxMDAwMDAsXG4gICAgICAgICAgb3ZlcmxhcFRva2VuczogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBWZXJpZnkgc3RhY2sgaXMgY3JlYXRlZCBzdWNjZXNzZnVsbHlcbiAgICAgIGV4cGVjdCh0b2tlbkJhc2VkU3RhY2spLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdhY2NlcHRzIGh5YnJpZCBzdHJhdGVneSBjb25maWd1cmF0aW9uJywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IGh5YnJpZFN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdIeWJyaWRTdGFjaycpO1xuICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoaHlicmlkU3RhY2ssICdIeWJyaWRUZXN0Jywge1xuICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICBzdHJhdGVneTogJ2h5YnJpZCcsXG4gICAgICAgICAgbWF4UGFnZXNQZXJDaHVuazogMTAwLFxuICAgICAgICAgIHRhcmdldFRva2Vuc1BlckNodW5rOiA4MDAwMCxcbiAgICAgICAgICBwYWdlVGhyZXNob2xkOiAxMDAsXG4gICAgICAgICAgdG9rZW5UaHJlc2hvbGQ6IDE1MDAwMCxcbiAgICAgICAgICBvdmVybGFwVG9rZW5zOiA1MDAwLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFZlcmlmeSBzdGFjayBpcyBjcmVhdGVkIHN1Y2Nlc3NmdWxseVxuICAgICAgZXhwZWN0KGh5YnJpZFN0YWNrKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnYWNjZXB0cyBkZWZhdWx0IGNodW5raW5nIGNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3QgZGVmYXVsdENodW5raW5nU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0RlZmF1bHRDaHVua2luZ1N0YWNrJyk7XG4gICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhkZWZhdWx0Q2h1bmtpbmdTdGFjaywgJ0RlZmF1bHRDaHVua2luZ1Rlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFZlcmlmeSBzdGFjayBpcyBjcmVhdGVkIHN1Y2Nlc3NmdWxseSB3aXRoIGRlZmF1bHQgY29uZmlnXG4gICAgICBleHBlY3QoZGVmYXVsdENodW5raW5nU3RhY2spLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdkb2VzIG5vdCBlbmFibGUgY2h1bmtpbmcgd2hlbiBlbmFibGVDaHVua2luZyBpcyBmYWxzZScsICgpID0+IHtcbiAgICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBkZWZhdWx0IHN0YWNrICh3aXRob3V0IGNodW5raW5nKSB3b3JrcyBhcyBleHBlY3RlZFxuICAgICAgZXhwZWN0KGRlZmF1bHRTdGFjaykudG9CZURlZmluZWQoKTtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6UzM6OkJ1Y2tldCcsIHt9KTtcbiAgICAgIGRlZmF1bHRUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6U1FTOjpRdWV1ZScsIHt9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1dvcmtmbG93IGJyYW5jaGluZyBmb3IgY2h1bmtpbmcnLCAoKSA9PiB7XG4gICAgdGVzdCgnY3JlYXRlcyBzdGF0ZSBtYWNoaW5lIHdpdGggY2h1bmtpbmcgd29ya2Zsb3cnLCAoKSA9PiB7XG4gICAgICAvLyBWZXJpZnkgdGhhdCBhIHN0YXRlIG1hY2hpbmUgaXMgY3JlYXRlZCB3aGVuIGNodW5raW5nIGlzIGVuYWJsZWRcbiAgICAgIGNodW5raW5nVGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIDEpO1xuXG4gICAgICAvLyBWZXJpZnkgdGhlIHN0YXRlIG1hY2hpbmUgaGFzIHRoZSBleHBlY3RlZCBjb25maWd1cmF0aW9uXG4gICAgICBjaHVua2luZ1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpTdGVwRnVuY3Rpb25zOjpTdGF0ZU1hY2hpbmUnLCB7XG4gICAgICAgIEVuY3J5cHRpb25Db25maWd1cmF0aW9uOiBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICBUeXBlOiAnQ1VTVE9NRVJfTUFOQUdFRF9LTVNfS0VZJyxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3N0YW5kYXJkIHdvcmtmbG93IGlzIHVzZWQgd2hlbiBjaHVua2luZyBpcyBkaXNhYmxlZCcsICgpID0+IHtcbiAgICAgIC8vIFZlcmlmeSB0aGF0IHdoZW4gZW5hYmxlQ2h1bmtpbmcgaXMgZmFsc2UsIHRoZSBzdGFuZGFyZCB3b3JrZmxvdyBpcyB1c2VkXG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgbm9DaHVua2luZ1N0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdOb0NodW5raW5nU3RhY2snKTtcbiAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKG5vQ2h1bmtpbmdTdGFjaywgJ05vQ2h1bmtpbmdUZXN0Jywge1xuICAgICAgICBlbmFibGVDaHVua2luZzogZmFsc2UsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgbm9DaHVua2luZ1RlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKG5vQ2h1bmtpbmdTdGFjayk7XG5cbiAgICAgIC8vIFNob3VsZCBoYXZlIHN0YXRlIG1hY2hpbmVcbiAgICAgIG5vQ2h1bmtpbmdUZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywgMSk7XG5cbiAgICAgIC8vIFNob3VsZCBOT1QgaGF2ZSBQREYgY2h1bmtpbmcgTGFtYmRhIChQeXRob24gMy4xMyB3aXRoIDIwNDggTUIpXG4gICAgICBjb25zdCBsYW1iZGFzID0gbm9DaHVua2luZ1RlbXBsYXRlLmZpbmRSZXNvdXJjZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicpO1xuICAgICAgY29uc3QgY2h1bmtpbmdMYW1iZGEgPSBPYmplY3QudmFsdWVzKGxhbWJkYXMpLmZpbmQoKGxhbWJkYTogYW55KSA9PlxuICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5SdW50aW1lID09PSAncHl0aG9uMy4xMycgJiZcbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMjA0OCxcbiAgICAgICk7XG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvQmVVbmRlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2NyZWF0ZXMgUERGIGNodW5raW5nIExhbWJkYSB3aGVuIGNodW5raW5nIGlzIGVuYWJsZWQnLCAoKSA9PiB7XG4gICAgICAvLyBWZXJpZnkgdGhhdCB0aGUgUERGIGNodW5raW5nIExhbWJkYSBpcyBjcmVhdGVkXG4gICAgICBjb25zdCBsYW1iZGFzID0gY2h1bmtpbmdUZW1wbGF0ZS5maW5kUmVzb3VyY2VzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKTtcblxuICAgICAgLy8gRmluZCB0aGUgY2h1bmtpbmcgTGFtYmRhIGJ5IGl0cyBjaGFyYWN0ZXJpc3RpY3MgKFB5dGhvbiAzLjEzLCAyMDQ4IE1CIG1lbW9yeSlcbiAgICAgIGNvbnN0IGNodW5raW5nTGFtYmRhID0gT2JqZWN0LnZhbHVlcyhsYW1iZGFzKS5maW5kKChsYW1iZGE6IGFueSkgPT5cbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuUnVudGltZSA9PT0gJ3B5dGhvbjMuMTMnICYmXG4gICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDIwNDggJiZcbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuVGltZW91dCA9PT0gNjAwLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNodW5raW5nTGFtYmRhKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KGNodW5raW5nTGFtYmRhKS50b0hhdmVQcm9wZXJ0eSgnUHJvcGVydGllcy5IYW5kbGVyJywgJ2hhbmRsZXIuaGFuZGxlcicpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnUERGIGNodW5raW5nIExhbWJkYSBoYXMgY29ycmVjdCBlbnZpcm9ubWVudCB2YXJpYWJsZXMgZm9yIGh5YnJpZCBzdHJhdGVneScsICgpID0+IHtcbiAgICAgIC8vIFZlcmlmeSBjaHVua2luZyBjb25maWd1cmF0aW9uIGlzIHBhc3NlZCB2aWEgZW52aXJvbm1lbnQgdmFyaWFibGVzXG4gICAgICAvLyBGaW5kIHRoZSBjaHVua2luZyBMYW1iZGEgc3BlY2lmaWNhbGx5XG4gICAgICBjb25zdCBsYW1iZGFzID0gY2h1bmtpbmdUZW1wbGF0ZS5maW5kUmVzb3VyY2VzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKTtcbiAgICAgIGNvbnN0IGNodW5raW5nTGFtYmRhID0gT2JqZWN0LnZhbHVlcyhsYW1iZGFzKS5maW5kKChsYW1iZGE6IGFueSkgPT5cbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuUnVudGltZSA9PT0gJ3B5dGhvbjMuMTMnICYmXG4gICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDIwNDgsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlcy5DSFVOS0lOR19TVFJBVEVHWScsICdoeWJyaWQnKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLk1BWF9QQUdFU19QRVJfQ0hVTksnLCAnMTAwJyk7XG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlcy5UQVJHRVRfVE9LRU5TX1BFUl9DSFVOSycsICc4MDAwMCcpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnUERGIGNodW5raW5nIExhbWJkYSBoYXMgUzMgYWNjZXNzIHBlcm1pc3Npb25zJywgKCkgPT4ge1xuICAgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGNodW5raW5nIExhbWJkYSBoYXMgUzMgcGVybWlzc2lvbnNcbiAgICAgIGNodW5raW5nVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OklBTTo6Um9sZScsIHtcbiAgICAgICAgUG9saWNpZXM6IE1hdGNoLmFycmF5V2l0aChbXG4gICAgICAgICAgTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgICBQb2xpY3lEb2N1bWVudDogTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgICAgIFN0YXRlbWVudDogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgICAgICAgIEFjdGlvbjogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICAgICAgICAgICAgJ3MzOkdldE9iamVjdCcsXG4gICAgICAgICAgICAgICAgICAgICdzMzpQdXRPYmplY3QnLFxuICAgICAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSksXG4gICAgICAgIF0pLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzdGF0ZSBtYWNoaW5lIGNhbiBpbnZva2UgUERGIGNodW5raW5nIExhbWJkYScsICgpID0+IHtcbiAgICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBzdGF0ZSBtYWNoaW5lIHJvbGUgaGFzIHBlcm1pc3Npb24gdG8gaW52b2tlIHRoZSBjaHVua2luZyBMYW1iZGFcbiAgICAgIGNodW5raW5nVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OklBTTo6UG9saWN5Jywge1xuICAgICAgICBQb2xpY3lEb2N1bWVudDogTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgU3RhdGVtZW50OiBNYXRjaC5hcnJheVdpdGgoW1xuICAgICAgICAgICAgTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgICAgIEFjdGlvbjogJ2xhbWJkYTpJbnZva2VGdW5jdGlvbicsXG4gICAgICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIF0pLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5cbmRlc2NyaWJlKCdDaHVuay1hd2FyZSBjbGFzc2lmaWNhdGlvbiBpbnRlZ3JhdGlvbicsICgpID0+IHtcbiAgZGVzY3JpYmUoJ0NsYXNzaWZpY2F0aW9uIExhbWJkYSBjaHVuayBjb250ZXh0JywgKCkgPT4ge1xuICAgIHRlc3QoJ2NsYXNzaWZpY2F0aW9uIExhbWJkYSByZWNlaXZlcyBjaHVuayBtZXRhZGF0YSBpbiBNYXAgU3RhdGUnLCAoKSA9PiB7XG4gICAgICAvLyBWZXJpZnkgdGhhdCB0aGUgTWFwIFN0YXRlIHBhc3NlcyBjaHVuayBtZXRhZGF0YSB0byB0aGUgY2xhc3NpZmljYXRpb24gTGFtYmRhXG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3QgY2h1bmtpbmdTdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnQ2h1bmtDb250ZXh0U3RhY2snKTtcbiAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGNodW5raW5nU3RhY2ssICdDaHVua0NvbnRleHRUZXN0Jywge1xuICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICBzdHJhdGVneTogJ2h5YnJpZCcsXG4gICAgICAgICAgbWF4UGFnZXNQZXJDaHVuazogMTAwLFxuICAgICAgICAgIHRhcmdldFRva2Vuc1BlckNodW5rOiA4MDAwMCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhjaHVua2luZ1N0YWNrKTtcblxuICAgICAgLy8gVmVyaWZ5IHN0YXRlIG1hY2hpbmUgaXMgY3JlYXRlZCB3aXRoIE1hcCBTdGF0ZVxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIHtcbiAgICAgICAgRGVmaW5pdGlvblN0cmluZzogTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgJ0ZuOjpKb2luJzogTWF0Y2guYXJyYXlXaXRoKFsnJ10pLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBWZXJpZnkgdGhlIHN0YXRlIG1hY2hpbmUgZGVmaW5pdGlvbiBpbmNsdWRlcyBNYXAgc3RhdGUgd2l0aCBjaHVuayBwYXJhbWV0ZXJzXG4gICAgICBjb25zdCBzdGF0ZU1hY2hpbmVzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcygnQVdTOjpTdGVwRnVuY3Rpb25zOjpTdGF0ZU1hY2hpbmUnKTtcbiAgICAgIGNvbnN0IHN0YXRlTWFjaGluZURlZmluaXRpb24gPSBPYmplY3QudmFsdWVzKHN0YXRlTWFjaGluZXMpWzBdO1xuICAgICAgZXhwZWN0KHN0YXRlTWFjaGluZURlZmluaXRpb24pLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdub24tY2h1bmtlZCB3b3JrZmxvdyBkb2VzIG5vdCBpbmNsdWRlIGNodW5rIGNvbnRleHQnLCAoKSA9PiB7XG4gICAgICAvLyBWZXJpZnkgdGhhdCB3aGVuIGNodW5raW5nIGlzIGRpc2FibGVkLCBubyBjaHVuayBjb250ZXh0IGlzIGFkZGVkXG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgbm9DaHVua2luZ1N0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdOb0NodW5rQ29udGV4dFN0YWNrJyk7XG4gICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhub0NodW5raW5nU3RhY2ssICdOb0NodW5rQ29udGV4dFRlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiBmYWxzZSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhub0NodW5raW5nU3RhY2spO1xuXG4gICAgICAvLyBTaG91bGQgaGF2ZSBzdGF0ZSBtYWNoaW5lXG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywgMSk7XG5cbiAgICAgIC8vIFNob3VsZCBOT1QgaGF2ZSBQREYgY2h1bmtpbmcgTGFtYmRhXG4gICAgICBjb25zdCBsYW1iZGFzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyk7XG4gICAgICBjb25zdCBjaHVua2luZ0xhbWJkYSA9IE9iamVjdC52YWx1ZXMobGFtYmRhcykuZmluZCgobGFtYmRhOiBhbnkpID0+XG4gICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLlJ1bnRpbWUgPT09ICdweXRob24zLjEzJyAmJlxuICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5NZW1vcnlTaXplID09PSAyMDQ4LFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnY2h1bmtlZCB3b3JrZmxvdyBpbmNsdWRlcyBNYXAgU3RhdGUgZm9yIHBhcmFsbGVsIGNodW5rIHByb2Nlc3NpbmcnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3QgY2h1bmtpbmdTdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnTWFwU3RhdGVTdGFjaycpO1xuICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoY2h1bmtpbmdTdGFjaywgJ01hcFN0YXRlVGVzdCcsIHtcbiAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgc3RyYXRlZ3k6ICdoeWJyaWQnLFxuICAgICAgICAgIHByb2Nlc3NpbmdNb2RlOiAncGFyYWxsZWwnLFxuICAgICAgICAgIG1heENvbmN1cnJlbmN5OiA1LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGNodW5raW5nU3RhY2spO1xuXG4gICAgICAvLyBWZXJpZnkgc3RhdGUgbWFjaGluZSBpcyBjcmVhdGVkXG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywgMSk7XG5cbiAgICAgIC8vIFZlcmlmeSBjbGFzc2lmaWNhdGlvbiBMYW1iZGEgZXhpc3RzXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgIElOVk9LRV9UWVBFOiAnY2xhc3NpZmljYXRpb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2NsYXNzaWZpY2F0aW9uIExhbWJkYSBpcyByZXVzZWQgZm9yIGJvdGggY2h1bmtlZCBhbmQgbm9uLWNodW5rZWQgcGF0aHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3QgY2h1bmtpbmdTdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnUmV1c2VTdGFjaycpO1xuICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoY2h1bmtpbmdTdGFjaywgJ1JldXNlVGVzdCcsIHtcbiAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY2h1bmtpbmdTdGFjayk7XG5cbiAgICAgIC8vIENvdW50IGNsYXNzaWZpY2F0aW9uIExhbWJkYXMgKHNob3VsZCBiZSAxLCByZXVzZWQgZm9yIGJvdGggcGF0aHMpXG4gICAgICBjb25zdCBsYW1iZGFzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyk7XG4gICAgICBjb25zdCBjbGFzc2lmaWNhdGlvbkxhbWJkYXMgPSBPYmplY3QudmFsdWVzKGxhbWJkYXMpLmZpbHRlcigobGFtYmRhOiBhbnkpID0+XG4gICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLkVudmlyb25tZW50Py5WYXJpYWJsZXM/LklOVk9LRV9UWVBFID09PSAnY2xhc3NpZmljYXRpb24nLFxuICAgICAgKTtcblxuICAgICAgLy8gU2hvdWxkIGhhdmUgZXhhY3RseSAxIGNsYXNzaWZpY2F0aW9uIExhbWJkYSAocmV1c2VkKVxuICAgICAgZXhwZWN0KGNsYXNzaWZpY2F0aW9uTGFtYmRhcy5sZW5ndGgpLnRvQmUoMSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd3b3JrZmxvdyBtYWludGFpbnMgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBmb3Igc21hbGwgZG9jdW1lbnRzJywgKCkgPT4ge1xuICAgICAgLy8gV2hlbiBjaHVua2luZyBpcyBlbmFibGVkIGJ1dCBkb2N1bWVudCBpcyBzbWFsbCwgaXQgc2hvdWxkIHVzZSBzdGFuZGFyZCB3b3JrZmxvd1xuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IGNodW5raW5nU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0JhY2t3YXJkQ29tcGF0U3RhY2snKTtcbiAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGNodW5raW5nU3RhY2ssICdCYWNrd2FyZENvbXBhdFRlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgIHN0cmF0ZWd5OiAnaHlicmlkJyxcbiAgICAgICAgICBwYWdlVGhyZXNob2xkOiAxMDAsXG4gICAgICAgICAgdG9rZW5UaHJlc2hvbGQ6IDE1MDAwMCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhjaHVua2luZ1N0YWNrKTtcblxuICAgICAgLy8gVmVyaWZ5IGJvdGggY2xhc3NpZmljYXRpb24gYW5kIHByb2Nlc3NpbmcgTGFtYmRhcyBleGlzdFxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBJTlZPS0VfVFlQRTogJ2NsYXNzaWZpY2F0aW9uJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgSU5WT0tFX1RZUEU6ICdwcm9jZXNzaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFZlcmlmeSBzdGF0ZSBtYWNoaW5lIGhhcyBDaG9pY2Ugc3RhdGUgZm9yIGJyYW5jaGluZ1xuICAgICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIDEpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWNjdXJhY3kgY29tcGFyaXNvbiBiZXR3ZWVuIGNodW5rZWQgYW5kIG5vbi1jaHVua2VkJywgKCkgPT4ge1xuICAgIHRlc3QoJ2JvdGggd29ya2Zsb3dzIHVzZSBzYW1lIGNsYXNzaWZpY2F0aW9uIExhbWJkYSBmdW5jdGlvbicsICgpID0+IHtcbiAgICAgIC8vIFRoaXMgZW5zdXJlcyBhY2N1cmFjeSBpcyBtYWludGFpbmVkIGJlY2F1c2UgdGhlIHNhbWUgbW9kZWwgYW5kIHByb21wdCBhcmUgdXNlZFxuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IGNodW5raW5nU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0FjY3VyYWN5U3RhY2snKTtcbiAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGNodW5raW5nU3RhY2ssICdBY2N1cmFjeVRlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjbGFzc2lmaWNhdGlvbkJlZHJvY2tNb2RlbDoge1xuICAgICAgICAgIGZtTW9kZWxJZDogRm91bmRhdGlvbk1vZGVsSWRlbnRpZmllci5BTlRIUk9QSUNfQ0xBVURFXzNfSEFJS1VfMjAyNDAzMDdfVjFfMCxcbiAgICAgICAgICB1c2VDcm9zc1JlZ2lvbkluZmVyZW5jZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soY2h1bmtpbmdTdGFjayk7XG5cbiAgICAgIC8vIFZlcmlmeSB0aGUgY2xhc3NpZmljYXRpb24gTGFtYmRhIHVzZXMgdGhlIHNwZWNpZmllZCBtb2RlbFxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBNT0RFTF9JRDogJ2FudGhyb3BpYy5jbGF1ZGUtMy1oYWlrdS0yMDI0MDMwNy12MTowJyxcbiAgICAgICAgICAgIElOVk9LRV9UWVBFOiAnY2xhc3NpZmljYXRpb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2N1c3RvbSBjbGFzc2lmaWNhdGlvbiBwcm9tcHQgaXMgdXNlZCBmb3IgYm90aCBjaHVua2VkIGFuZCBub24tY2h1bmtlZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGN1c3RvbVByb21wdCA9ICdDdXN0b20gY2xhc3NpZmljYXRpb24gcHJvbXB0IGZvciB0ZXN0aW5nJztcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBjaHVua2luZ1N0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdDdXN0b21Qcm9tcHRTdGFjaycpO1xuICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoY2h1bmtpbmdTdGFjaywgJ0N1c3RvbVByb21wdFRlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjbGFzc2lmaWNhdGlvblByb21wdDogY3VzdG9tUHJvbXB0LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGNodW5raW5nU3RhY2spO1xuXG4gICAgICAvLyBWZXJpZnkgdGhlIGN1c3RvbSBwcm9tcHQgaXMgc2V0XG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgIFBST01QVDogY3VzdG9tUHJvbXB0LFxuICAgICAgICAgICAgSU5WT0tFX1RZUEU6ICdjbGFzc2lmaWNhdGlvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5cbmRlc2NyaWJlKCdDb25maWd1cmF0aW9uIHZhbGlkYXRpb24nLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCdJbnZhbGlkIGNvbmZpZ3VyYXRpb24gcmVqZWN0aW9uJywgKCkgPT4ge1xuICAgIHRlc3QoJ3Rocm93cyBlcnJvciBmb3IgY2h1bmtTaXplIDw9IDAnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0ludmFsaWRDaHVua1NpemVTdGFjaycpO1xuXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0ludmFsaWRDaHVua1NpemVUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICBzdHJhdGVneTogJ2ZpeGVkLXBhZ2VzJyxcbiAgICAgICAgICAgIGNodW5rU2l6ZTogMCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pLnRvVGhyb3coJ0NodW5raW5nQ29uZmlnIHZhbGlkYXRpb24gZXJyb3I6IGNodW5rU2l6ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd0aHJvd3MgZXJyb3IgZm9yIG5lZ2F0aXZlIGNodW5rU2l6ZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnTmVnYXRpdmVDaHVua1NpemVTdGFjaycpO1xuXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ05lZ2F0aXZlQ2h1bmtTaXplVGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgICAgc3RyYXRlZ3k6ICdmaXhlZC1wYWdlcycsXG4gICAgICAgICAgICBjaHVua1NpemU6IC0xMCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pLnRvVGhyb3coJ0NodW5raW5nQ29uZmlnIHZhbGlkYXRpb24gZXJyb3I6IGNodW5rU2l6ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd0aHJvd3MgZXJyb3IgZm9yIG5lZ2F0aXZlIG92ZXJsYXBQYWdlcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnTmVnYXRpdmVPdmVybGFwU3RhY2snKTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdOZWdhdGl2ZU92ZXJsYXBUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICBzdHJhdGVneTogJ2ZpeGVkLXBhZ2VzJyxcbiAgICAgICAgICAgIGNodW5rU2l6ZTogNTAsXG4gICAgICAgICAgICBvdmVybGFwUGFnZXM6IC01LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSkudG9UaHJvdygnQ2h1bmtpbmdDb25maWcgdmFsaWRhdGlvbiBlcnJvcjogb3ZlcmxhcFBhZ2VzIG11c3QgYmUgbm9uLW5lZ2F0aXZlJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd0aHJvd3MgZXJyb3IgZm9yIG92ZXJsYXBQYWdlcyA+PSBjaHVua1NpemUnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ092ZXJsYXBUb29MYXJnZVN0YWNrJyk7XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKHN0YWNrLCAnT3ZlcmxhcFRvb0xhcmdlVGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgICAgc3RyYXRlZ3k6ICdmaXhlZC1wYWdlcycsXG4gICAgICAgICAgICBjaHVua1NpemU6IDUwLFxuICAgICAgICAgICAgb3ZlcmxhcFBhZ2VzOiA1MCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pLnRvVGhyb3coJ0NodW5raW5nQ29uZmlnIHZhbGlkYXRpb24gZXJyb3I6IG92ZXJsYXBQYWdlcyBtdXN0IGJlIGxlc3MgdGhhbiBjaHVua1NpemUnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Rocm93cyBlcnJvciBmb3IgcGFnZVRocmVzaG9sZCA8PSAwJywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdJbnZhbGlkUGFnZVRocmVzaG9sZFN0YWNrJyk7XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKHN0YWNrLCAnSW52YWxpZFBhZ2VUaHJlc2hvbGRUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICBzdHJhdGVneTogJ2ZpeGVkLXBhZ2VzJyxcbiAgICAgICAgICAgIHBhZ2VUaHJlc2hvbGQ6IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KS50b1Rocm93KCdDaHVua2luZ0NvbmZpZyB2YWxpZGF0aW9uIGVycm9yOiBwYWdlVGhyZXNob2xkIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Rocm93cyBlcnJvciBmb3IgdG9rZW5UaHJlc2hvbGQgPD0gMCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnSW52YWxpZFRva2VuVGhyZXNob2xkU3RhY2snKTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdJbnZhbGlkVG9rZW5UaHJlc2hvbGRUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICBzdHJhdGVneTogJ3Rva2VuLWJhc2VkJyxcbiAgICAgICAgICAgIHRva2VuVGhyZXNob2xkOiAtMTAwLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSkudG9UaHJvdygnQ2h1bmtpbmdDb25maWcgdmFsaWRhdGlvbiBlcnJvcjogdG9rZW5UaHJlc2hvbGQgbXVzdCBiZSBncmVhdGVyIHRoYW4gMCcpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgndGhyb3dzIGVycm9yIGZvciBtYXhUb2tlbnNQZXJDaHVuayA8PSAwJywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdJbnZhbGlkTWF4VG9rZW5zU3RhY2snKTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdJbnZhbGlkTWF4VG9rZW5zVGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgICAgc3RyYXRlZ3k6ICd0b2tlbi1iYXNlZCcsXG4gICAgICAgICAgICBtYXhUb2tlbnNQZXJDaHVuazogMCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pLnRvVGhyb3coJ0NodW5raW5nQ29uZmlnIHZhbGlkYXRpb24gZXJyb3I6IG1heFRva2Vuc1BlckNodW5rIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Rocm93cyBlcnJvciBmb3IgbmVnYXRpdmUgb3ZlcmxhcFRva2VucycsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnTmVnYXRpdmVPdmVybGFwVG9rZW5zU3RhY2snKTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdOZWdhdGl2ZU92ZXJsYXBUb2tlbnNUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICBzdHJhdGVneTogJ3Rva2VuLWJhc2VkJyxcbiAgICAgICAgICAgIG92ZXJsYXBUb2tlbnM6IC0xMDAwLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSkudG9UaHJvdygnQ2h1bmtpbmdDb25maWcgdmFsaWRhdGlvbiBlcnJvcjogb3ZlcmxhcFRva2VucyBtdXN0IGJlIG5vbi1uZWdhdGl2ZScpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgndGhyb3dzIGVycm9yIGZvciBvdmVybGFwVG9rZW5zID49IG1heFRva2Vuc1BlckNodW5rJywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdPdmVybGFwVG9rZW5zVG9vTGFyZ2VTdGFjaycpO1xuXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ092ZXJsYXBUb2tlbnNUb29MYXJnZVRlc3QnLCB7XG4gICAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICAgIHN0cmF0ZWd5OiAndG9rZW4tYmFzZWQnLFxuICAgICAgICAgICAgbWF4VG9rZW5zUGVyQ2h1bms6IDUwMDAwLFxuICAgICAgICAgICAgb3ZlcmxhcFRva2VuczogNTAwMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KS50b1Rocm93KCdDaHVua2luZ0NvbmZpZyB2YWxpZGF0aW9uIGVycm9yOiBvdmVybGFwVG9rZW5zIG11c3QgYmUgbGVzcyB0aGFuIG1heFRva2Vuc1BlckNodW5rJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd0aHJvd3MgZXJyb3IgZm9yIG1heFBhZ2VzUGVyQ2h1bmsgPD0gMCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnSW52YWxpZE1heFBhZ2VzU3RhY2snKTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdJbnZhbGlkTWF4UGFnZXNUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICBzdHJhdGVneTogJ2h5YnJpZCcsXG4gICAgICAgICAgICBtYXhQYWdlc1BlckNodW5rOiAwLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSkudG9UaHJvdygnQ2h1bmtpbmdDb25maWcgdmFsaWRhdGlvbiBlcnJvcjogbWF4UGFnZXNQZXJDaHVuayBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd0aHJvd3MgZXJyb3IgZm9yIHRhcmdldFRva2Vuc1BlckNodW5rIDw9IDAnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0ludmFsaWRUYXJnZXRUb2tlbnNTdGFjaycpO1xuXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0ludmFsaWRUYXJnZXRUb2tlbnNUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICBzdHJhdGVneTogJ2h5YnJpZCcsXG4gICAgICAgICAgICB0YXJnZXRUb2tlbnNQZXJDaHVuazogLTEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KS50b1Rocm93KCdDaHVua2luZ0NvbmZpZyB2YWxpZGF0aW9uIGVycm9yOiB0YXJnZXRUb2tlbnNQZXJDaHVuayBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd0aHJvd3MgZXJyb3IgZm9yIG1heENvbmN1cnJlbmN5IDw9IDAnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0ludmFsaWRNYXhDb25jdXJyZW5jeVN0YWNrJyk7XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKHN0YWNrLCAnSW52YWxpZE1heENvbmN1cnJlbmN5VGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgICAgbWF4Q29uY3VycmVuY3k6IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KS50b1Rocm93KCdDaHVua2luZ0NvbmZpZyB2YWxpZGF0aW9uIGVycm9yOiBtYXhDb25jdXJyZW5jeSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd0aHJvd3MgZXJyb3IgZm9yIG1pblN1Y2Nlc3NUaHJlc2hvbGQgPCAwJywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdJbnZhbGlkTWluVGhyZXNob2xkTG93U3RhY2snKTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdJbnZhbGlkTWluVGhyZXNob2xkTG93VGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgICAgbWluU3VjY2Vzc1RocmVzaG9sZDogLTAuMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pLnRvVGhyb3coJ0NodW5raW5nQ29uZmlnIHZhbGlkYXRpb24gZXJyb3I6IG1pblN1Y2Nlc3NUaHJlc2hvbGQgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Rocm93cyBlcnJvciBmb3IgbWluU3VjY2Vzc1RocmVzaG9sZCA+IDEnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0ludmFsaWRNaW5UaHJlc2hvbGRIaWdoU3RhY2snKTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdJbnZhbGlkTWluVGhyZXNob2xkSGlnaFRlc3QnLCB7XG4gICAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICAgIG1pblN1Y2Nlc3NUaHJlc2hvbGQ6IDEuNSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pLnRvVGhyb3coJ0NodW5raW5nQ29uZmlnIHZhbGlkYXRpb24gZXJyb3I6IG1pblN1Y2Nlc3NUaHJlc2hvbGQgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1ZhbGlkIGNvbmZpZ3VyYXRpb24gYWNjZXB0YW5jZScsICgpID0+IHtcbiAgICB0ZXN0KCdhY2NlcHRzIHZhbGlkIGJvdW5kYXJ5IHZhbHVlcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnVmFsaWRCb3VuZGFyeVN0YWNrJyk7XG5cbiAgICAgIC8vIFNob3VsZCBub3QgdGhyb3dcbiAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKHN0YWNrLCAnVmFsaWRCb3VuZGFyeVRlc3QnLCB7XG4gICAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICAgIHN0cmF0ZWd5OiAnZml4ZWQtcGFnZXMnLFxuICAgICAgICAgICAgY2h1bmtTaXplOiAxLCAvLyBtaW5pbXVtIHZhbGlkXG4gICAgICAgICAgICBvdmVybGFwUGFnZXM6IDAsIC8vIG1pbmltdW0gdmFsaWRcbiAgICAgICAgICAgIHBhZ2VUaHJlc2hvbGQ6IDEsIC8vIG1pbmltdW0gdmFsaWRcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pLm5vdC50b1Rocm93KCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdhY2NlcHRzIG1pblN1Y2Nlc3NUaHJlc2hvbGQgYXQgYm91bmRhcmllcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjazEgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ01pblRocmVzaG9sZDBTdGFjaycpO1xuICAgICAgY29uc3Qgc3RhY2syID0gbmV3IFN0YWNrKHRlc3RBcHAsICdNaW5UaHJlc2hvbGQxU3RhY2snKTtcblxuICAgICAgLy8gU2hvdWxkIG5vdCB0aHJvdyBmb3IgMFxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2sxLCAnTWluVGhyZXNob2xkMFRlc3QnLCB7XG4gICAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICAgIG1pblN1Y2Nlc3NUaHJlc2hvbGQ6IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KS5ub3QudG9UaHJvdygpO1xuXG4gICAgICAvLyBTaG91bGQgbm90IHRocm93IGZvciAxXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjazIsICdNaW5UaHJlc2hvbGQxVGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgICAgbWluU3VjY2Vzc1RocmVzaG9sZDogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pLm5vdC50b1Rocm93KCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdWYWxpZGF0aW9uIHNraXBwZWQgd2hlbiBjaHVua2luZyBkaXNhYmxlZCcsICgpID0+IHtcbiAgICB0ZXN0KCdkb2VzIG5vdCB2YWxpZGF0ZSBjb25maWcgd2hlbiBlbmFibGVDaHVua2luZyBpcyBmYWxzZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnQ2h1bmtpbmdEaXNhYmxlZFN0YWNrJyk7XG5cbiAgICAgIC8vIFNob3VsZCBub3QgdGhyb3cgZXZlbiB3aXRoIGludmFsaWQgY29uZmlnIGJlY2F1c2UgY2h1bmtpbmcgaXMgZGlzYWJsZWRcbiAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKHN0YWNrLCAnQ2h1bmtpbmdEaXNhYmxlZFRlc3QnLCB7XG4gICAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IGZhbHNlLFxuICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICBjaHVua1NpemU6IC0xMCwgLy8gSW52YWxpZCBidXQgc2hvdWxkIGJlIGlnbm9yZWRcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pLm5vdC50b1Rocm93KCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdkb2VzIG5vdCB2YWxpZGF0ZSBjb25maWcgd2hlbiBlbmFibGVDaHVua2luZyBpcyB1bmRlZmluZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0NodW5raW5nVW5kZWZpbmVkU3RhY2snKTtcblxuICAgICAgLy8gU2hvdWxkIG5vdCB0aHJvdyBldmVuIHdpdGggaW52YWxpZCBjb25maWcgYmVjYXVzZSBjaHVua2luZyBpcyBub3QgZW5hYmxlZFxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdDaHVua2luZ1VuZGVmaW5lZFRlc3QnLCB7XG4gICAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICAgIGNodW5rU2l6ZTogMCwgLy8gSW52YWxpZCBidXQgc2hvdWxkIGJlIGlnbm9yZWRcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pLm5vdC50b1Rocm93KCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdDb25maWd1cmF0aW9uIHByZWNlZGVuY2UnLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCdEZWZhdWx0IHZhbHVlcyBhcHBsaWVkJywgKCkgPT4ge1xuICAgIHRlc3QoJ3VzZXMgZGVmYXVsdCBzdHJhdGVneSB3aGVuIG5vdCBzcGVjaWZpZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0RlZmF1bHRTdHJhdGVneVN0YWNrJyk7XG4gICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0RlZmF1bHRTdHJhdGVneVRlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjaHVua2luZ0NvbmZpZzoge30sIC8vIEVtcHR5IGNvbmZpZywgc2hvdWxkIHVzZSBkZWZhdWx0c1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICAgIGNvbnN0IGxhbWJkYXMgPSB0ZW1wbGF0ZS5maW5kUmVzb3VyY2VzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKTtcbiAgICAgIGNvbnN0IGNodW5raW5nTGFtYmRhID0gT2JqZWN0LnZhbHVlcyhsYW1iZGFzKS5maW5kKChsYW1iZGE6IGFueSkgPT5cbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuUnVudGltZSA9PT0gJ3B5dGhvbjMuMTMnICYmXG4gICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDIwNDgsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlcy5DSFVOS0lOR19TVFJBVEVHWScsICdoeWJyaWQnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3VzZXMgZGVmYXVsdCBwYWdlVGhyZXNob2xkIHdoZW4gbm90IHNwZWNpZmllZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnRGVmYXVsdFBhZ2VUaHJlc2hvbGRTdGFjaycpO1xuICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdEZWZhdWx0UGFnZVRocmVzaG9sZFRlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgIHN0cmF0ZWd5OiAnZml4ZWQtcGFnZXMnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICAgIGNvbnN0IGxhbWJkYXMgPSB0ZW1wbGF0ZS5maW5kUmVzb3VyY2VzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKTtcbiAgICAgIGNvbnN0IGNodW5raW5nTGFtYmRhID0gT2JqZWN0LnZhbHVlcyhsYW1iZGFzKS5maW5kKChsYW1iZGE6IGFueSkgPT5cbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuUnVudGltZSA9PT0gJ3B5dGhvbjMuMTMnICYmXG4gICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDIwNDgsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlcy5QQUdFX1RIUkVTSE9MRCcsICcxMDAnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3VzZXMgZGVmYXVsdCB0b2tlblRocmVzaG9sZCB3aGVuIG5vdCBzcGVjaWZpZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0RlZmF1bHRUb2tlblRocmVzaG9sZFN0YWNrJyk7XG4gICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0RlZmF1bHRUb2tlblRocmVzaG9sZFRlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgIHN0cmF0ZWd5OiAndG9rZW4tYmFzZWQnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICAgIGNvbnN0IGxhbWJkYXMgPSB0ZW1wbGF0ZS5maW5kUmVzb3VyY2VzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKTtcbiAgICAgIGNvbnN0IGNodW5raW5nTGFtYmRhID0gT2JqZWN0LnZhbHVlcyhsYW1iZGFzKS5maW5kKChsYW1iZGE6IGFueSkgPT5cbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuUnVudGltZSA9PT0gJ3B5dGhvbjMuMTMnICYmXG4gICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDIwNDgsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlcy5UT0tFTl9USFJFU0hPTEQnLCAnMTUwMDAwJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd1c2VzIGRlZmF1bHQgbWF4Q29uY3VycmVuY3kgd2hlbiBub3Qgc3BlY2lmaWVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdEZWZhdWx0Q29uY3VycmVuY3lTdGFjaycpO1xuICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdEZWZhdWx0Q29uY3VycmVuY3lUZXN0Jywge1xuICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICBwcm9jZXNzaW5nTW9kZTogJ3BhcmFsbGVsJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBWZXJpZnkgc3RhY2sgaXMgY3JlYXRlZCBzdWNjZXNzZnVsbHkgd2l0aCBkZWZhdWx0IG1heENvbmN1cnJlbmN5IG9mIDEwXG4gICAgICBleHBlY3Qoc3RhY2spLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdDdXN0b20gY29uZmlndXJhdGlvbiBvdmVycmlkZXMgZGVmYXVsdHMnLCAoKSA9PiB7XG4gICAgdGVzdCgnY3VzdG9tIHN0cmF0ZWd5IG92ZXJyaWRlcyBkZWZhdWx0JywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdDdXN0b21TdHJhdGVneVN0YWNrJyk7XG4gICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0N1c3RvbVN0cmF0ZWd5VGVzdCcsIHtcbiAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgc3RyYXRlZ3k6ICd0b2tlbi1iYXNlZCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgICAgY29uc3QgbGFtYmRhcyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicpO1xuICAgICAgY29uc3QgY2h1bmtpbmdMYW1iZGEgPSBPYmplY3QudmFsdWVzKGxhbWJkYXMpLmZpbmQoKGxhbWJkYTogYW55KSA9PlxuICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5SdW50aW1lID09PSAncHl0aG9uMy4xMycgJiZcbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMjA0OCxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLkNIVU5LSU5HX1NUUkFURUdZJywgJ3Rva2VuLWJhc2VkJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdjdXN0b20gcGFnZVRocmVzaG9sZCBvdmVycmlkZXMgZGVmYXVsdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnQ3VzdG9tUGFnZVRocmVzaG9sZFN0YWNrJyk7XG4gICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0N1c3RvbVBhZ2VUaHJlc2hvbGRUZXN0Jywge1xuICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICBwYWdlVGhyZXNob2xkOiA1MCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgICBjb25zdCBsYW1iZGFzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyk7XG4gICAgICBjb25zdCBjaHVua2luZ0xhbWJkYSA9IE9iamVjdC52YWx1ZXMobGFtYmRhcykuZmluZCgobGFtYmRhOiBhbnkpID0+XG4gICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLlJ1bnRpbWUgPT09ICdweXRob24zLjEzJyAmJlxuICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5NZW1vcnlTaXplID09PSAyMDQ4LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNodW5raW5nTGFtYmRhKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KGNodW5raW5nTGFtYmRhKS50b0hhdmVQcm9wZXJ0eSgnUHJvcGVydGllcy5FbnZpcm9ubWVudC5WYXJpYWJsZXMuUEFHRV9USFJFU0hPTEQnLCAnNTAnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2N1c3RvbSB0b2tlblRocmVzaG9sZCBvdmVycmlkZXMgZGVmYXVsdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnQ3VzdG9tVG9rZW5UaHJlc2hvbGRTdGFjaycpO1xuICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdDdXN0b21Ub2tlblRocmVzaG9sZFRlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgIHRva2VuVGhyZXNob2xkOiAyMDAwMDAsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgICAgY29uc3QgbGFtYmRhcyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicpO1xuICAgICAgY29uc3QgY2h1bmtpbmdMYW1iZGEgPSBPYmplY3QudmFsdWVzKGxhbWJkYXMpLmZpbmQoKGxhbWJkYTogYW55KSA9PlxuICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5SdW50aW1lID09PSAncHl0aG9uMy4xMycgJiZcbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMjA0OCxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLlRPS0VOX1RIUkVTSE9MRCcsICcyMDAwMDAnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2N1c3RvbSBjaHVua1NpemUgb3ZlcnJpZGVzIGRlZmF1bHQnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0N1c3RvbUNodW5rU2l6ZVN0YWNrJyk7XG4gICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0N1c3RvbUNodW5rU2l6ZVRlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgIHN0cmF0ZWd5OiAnZml4ZWQtcGFnZXMnLFxuICAgICAgICAgIGNodW5rU2l6ZTogMjUsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgICAgY29uc3QgbGFtYmRhcyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicpO1xuICAgICAgY29uc3QgY2h1bmtpbmdMYW1iZGEgPSBPYmplY3QudmFsdWVzKGxhbWJkYXMpLmZpbmQoKGxhbWJkYTogYW55KSA9PlxuICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5SdW50aW1lID09PSAncHl0aG9uMy4xMycgJiZcbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMjA0OCxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLkNIVU5LX1NJWkUnLCAnMjUnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2N1c3RvbSBtYXhQYWdlc1BlckNodW5rIG92ZXJyaWRlcyBkZWZhdWx0JywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdDdXN0b21NYXhQYWdlc1N0YWNrJyk7XG4gICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0N1c3RvbU1heFBhZ2VzVGVzdCcsIHtcbiAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgc3RyYXRlZ3k6ICdoeWJyaWQnLFxuICAgICAgICAgIG1heFBhZ2VzUGVyQ2h1bms6IDc1LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICAgIGNvbnN0IGxhbWJkYXMgPSB0ZW1wbGF0ZS5maW5kUmVzb3VyY2VzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKTtcbiAgICAgIGNvbnN0IGNodW5raW5nTGFtYmRhID0gT2JqZWN0LnZhbHVlcyhsYW1iZGFzKS5maW5kKChsYW1iZGE6IGFueSkgPT5cbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuUnVudGltZSA9PT0gJ3B5dGhvbjMuMTMnICYmXG4gICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDIwNDgsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlcy5NQVhfUEFHRVNfUEVSX0NIVU5LJywgJzc1Jyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdkZWZhdWx0IG1heFBhZ2VzUGVyQ2h1bmsgaXMgOTkgdG8gc3RheSB1bmRlciBCZWRyb2NrIDEwMC1wYWdlIGxpbWl0JywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdEZWZhdWx0TWF4UGFnZXNTdGFjaycpO1xuICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdEZWZhdWx0TWF4UGFnZXNUZXN0Jywge1xuICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICBzdHJhdGVneTogJ2h5YnJpZCcsXG4gICAgICAgICAgLy8gbWF4UGFnZXNQZXJDaHVuayBub3Qgc3BlY2lmaWVkIC0gc2hvdWxkIGRlZmF1bHQgdG8gOTlcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgICBjb25zdCBsYW1iZGFzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyk7XG4gICAgICBjb25zdCBjaHVua2luZ0xhbWJkYSA9IE9iamVjdC52YWx1ZXMobGFtYmRhcykuZmluZCgobGFtYmRhOiBhbnkpID0+XG4gICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLlJ1bnRpbWUgPT09ICdweXRob24zLjEzJyAmJlxuICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5NZW1vcnlTaXplID09PSAyMDQ4LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNodW5raW5nTGFtYmRhKS50b0JlRGVmaW5lZCgpO1xuICAgICAgLy8gRGVmYXVsdCBzaG91bGQgYmUgOTksIG5vdCAxMDAsIGJlY2F1c2UgQmVkcm9jayBoYXMgYSBoYXJkIGxpbWl0IG9mIDEwMCBwYWdlcyBwZXIgUERGXG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlcy5NQVhfUEFHRVNfUEVSX0NIVU5LJywgJzk5Jyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdjdXN0b20gdGFyZ2V0VG9rZW5zUGVyQ2h1bmsgb3ZlcnJpZGVzIGRlZmF1bHQnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0N1c3RvbVRhcmdldFRva2Vuc1N0YWNrJyk7XG4gICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0N1c3RvbVRhcmdldFRva2Vuc1Rlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgIHN0cmF0ZWd5OiAnaHlicmlkJyxcbiAgICAgICAgICB0YXJnZXRUb2tlbnNQZXJDaHVuazogNjAwMDAsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgICAgY29uc3QgbGFtYmRhcyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicpO1xuICAgICAgY29uc3QgY2h1bmtpbmdMYW1iZGEgPSBPYmplY3QudmFsdWVzKGxhbWJkYXMpLmZpbmQoKGxhbWJkYTogYW55KSA9PlxuICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5SdW50aW1lID09PSAncHl0aG9uMy4xMycgJiZcbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMjA0OCxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLlRBUkdFVF9UT0tFTlNfUEVSX0NIVU5LJywgJzYwMDAwJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdhbGwgY3VzdG9tIHZhbHVlcyBvdmVycmlkZSBhbGwgZGVmYXVsdHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0FsbEN1c3RvbVN0YWNrJyk7XG4gICAgICBuZXcgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0FsbEN1c3RvbVRlc3QnLCB7XG4gICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgIHN0cmF0ZWd5OiAnZml4ZWQtcGFnZXMnLFxuICAgICAgICAgIHBhZ2VUaHJlc2hvbGQ6IDIwMCxcbiAgICAgICAgICB0b2tlblRocmVzaG9sZDogMzAwMDAwLFxuICAgICAgICAgIGNodW5rU2l6ZTogNzUsXG4gICAgICAgICAgb3ZlcmxhcFBhZ2VzOiAxMCxcbiAgICAgICAgICBtYXhUb2tlbnNQZXJDaHVuazogMTUwMDAwLFxuICAgICAgICAgIG92ZXJsYXBUb2tlbnM6IDEwMDAwLFxuICAgICAgICAgIHRhcmdldFRva2Vuc1BlckNodW5rOiAxMjAwMDAsXG4gICAgICAgICAgbWF4UGFnZXNQZXJDaHVuazogMTUwLFxuICAgICAgICAgIHByb2Nlc3NpbmdNb2RlOiAnc2VxdWVudGlhbCcsXG4gICAgICAgICAgbWF4Q29uY3VycmVuY3k6IDUsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgICAgY29uc3QgbGFtYmRhcyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicpO1xuICAgICAgY29uc3QgY2h1bmtpbmdMYW1iZGEgPSBPYmplY3QudmFsdWVzKGxhbWJkYXMpLmZpbmQoKGxhbWJkYTogYW55KSA9PlxuICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5SdW50aW1lID09PSAncHl0aG9uMy4xMycgJiZcbiAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMjA0OCxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLkNIVU5LSU5HX1NUUkFURUdZJywgJ2ZpeGVkLXBhZ2VzJyk7XG4gICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlcy5QQUdFX1RIUkVTSE9MRCcsICcyMDAnKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLlRPS0VOX1RIUkVTSE9MRCcsICczMDAwMDAnKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLkNIVU5LX1NJWkUnLCAnNzUnKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLk9WRVJMQVBfUEFHRVMnLCAnMTAnKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLk1BWF9UT0tFTlNfUEVSX0NIVU5LJywgJzE1MDAwMCcpO1xuICAgICAgZXhwZWN0KGNodW5raW5nTGFtYmRhKS50b0hhdmVQcm9wZXJ0eSgnUHJvcGVydGllcy5FbnZpcm9ubWVudC5WYXJpYWJsZXMuT1ZFUkxBUF9UT0tFTlMnLCAnMTAwMDAnKTtcbiAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLlRBUkdFVF9UT0tFTlNfUEVSX0NIVU5LJywgJzEyMDAwMCcpO1xuICAgICAgZXhwZWN0KGNodW5raW5nTGFtYmRhKS50b0hhdmVQcm9wZXJ0eSgnUHJvcGVydGllcy5FbnZpcm9ubWVudC5WYXJpYWJsZXMuTUFYX1BBR0VTX1BFUl9DSFVOSycsICcxNTAnKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|