cdk-serverless 3.0.0 → 3.1.1
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/.agents/tasks/task-api-gateway-authorizer/2025-01-20-120000-review.md +79 -0
- package/.agents/tasks/task-api-gateway-authorizer/context.json +25 -0
- package/.agents/tasks/task-api-gateway-authorizer/features/FEAT-001.json +22 -0
- package/.agents/tasks/task-api-gateway-authorizer/features/FEAT-002.json +31 -0
- package/.agents/tasks/task-api-gateway-authorizer/features/FEAT-003.json +25 -0
- package/.agents/tasks/task-api-gateway-authorizer/features/FEAT-004.json +24 -0
- package/.agents/tasks/task-api-gateway-authorizer/features/FEAT-005.json +22 -0
- package/.agents/tasks/task-api-gateway-authorizer/task.json +14 -0
- package/docs/constructs/assets/hierarchy.js +1 -1
- package/docs/constructs/assets/search.js +1 -1
- package/docs/constructs/classes/RestApi.html +26 -5
- package/docs/constructs/classes/SingleTableDatastore.html +1 -1
- package/docs/constructs/classes/Workflow.html +1 -1
- package/docs/constructs/hierarchy.html +1 -1
- package/docs/constructs/interfaces/RestApiProps.html +39 -14
- package/lib/constructs/rest-api.d.ts +100 -0
- package/lib/constructs/rest-api.js +213 -3
- package/lib/lambda/rest-api.jwt-authorizer.d.ts +1 -0
- package/lib/lambda/rest-api.jwt-authorizer.js +154 -0
- package/package.json +1 -1
|
@@ -81,6 +81,19 @@ class RestApi extends base_api_1.BaseApi {
|
|
|
81
81
|
* @private
|
|
82
82
|
*/
|
|
83
83
|
this._functions = {};
|
|
84
|
+
this.apiMethods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head'];
|
|
85
|
+
/**
|
|
86
|
+
* Set of operationIds that should have security disabled (security: []).
|
|
87
|
+
* @private
|
|
88
|
+
*/
|
|
89
|
+
this._anonymousOperations = new Set();
|
|
90
|
+
/**
|
|
91
|
+
* Stores the original per-operation security arrays as assigned by patchSecurity,
|
|
92
|
+
* keyed by operationId. Used by setAnonymousOperations to restore security on
|
|
93
|
+
* operations removed from the anonymous set.
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
this._originalOperationSecurity = new Map();
|
|
84
97
|
this.apiSpec = yaml.load(fs.readFileSync(props.definitionFileName).toString());
|
|
85
98
|
let customDomainName;
|
|
86
99
|
if (this.apiFQDN) {
|
|
@@ -208,6 +221,13 @@ class RestApi extends base_api_1.BaseApi {
|
|
|
208
221
|
},
|
|
209
222
|
};
|
|
210
223
|
}
|
|
224
|
+
this.patchSecuritySchemes(this.apiSpec);
|
|
225
|
+
// Initialize anonymous operations from props before patchSecurity distributes security
|
|
226
|
+
if (props.anonymousOperations) {
|
|
227
|
+
for (const opId of props.anonymousOperations) {
|
|
228
|
+
this._anonymousOperations.add(opId);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
211
231
|
this.patchSecurity(this.apiSpec);
|
|
212
232
|
// TODO patch spec for Cognito user pool
|
|
213
233
|
this.api = new aws_cdk_lib_1.aws_apigateway.SpecRestApi(this, 'Resource', {
|
|
@@ -224,6 +244,14 @@ class RestApi extends base_api_1.BaseApi {
|
|
|
224
244
|
sourceArn: this.api.arnForExecuteApi(),
|
|
225
245
|
});
|
|
226
246
|
}
|
|
247
|
+
// Grant API Gateway permission to invoke the JWT authorizer Lambda
|
|
248
|
+
if (this._authorizerFn) {
|
|
249
|
+
this._authorizerFn.addPermission('ApiGatewayAuthorizerInvoke', {
|
|
250
|
+
principal: new aws_cdk_lib_1.aws_iam.ServicePrincipal('apigateway.amazonaws.com'),
|
|
251
|
+
action: 'lambda:InvokeFunction',
|
|
252
|
+
sourceArn: this.api.arnForExecuteApi(),
|
|
253
|
+
});
|
|
254
|
+
}
|
|
227
255
|
if (customDomainName && this.api.domainName) {
|
|
228
256
|
new aws_cdk_lib_1.aws_route53.ARecord(this, 'DnsRecord', {
|
|
229
257
|
zone: this.hostedZone,
|
|
@@ -266,6 +294,79 @@ class RestApi extends base_api_1.BaseApi {
|
|
|
266
294
|
op(this.getFunctionForOperation(operationId));
|
|
267
295
|
}
|
|
268
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Replace the full set of anonymous operations.
|
|
299
|
+
* Anonymous operations will have `security: []` applied in the OpenAPI spec,
|
|
300
|
+
* making them publicly accessible without authentication.
|
|
301
|
+
*
|
|
302
|
+
* Since CDK serializes the OpenAPI spec at synth time (fromInline stores the
|
|
303
|
+
* object reference), mutations after SpecRestApi construction still take effect.
|
|
304
|
+
*
|
|
305
|
+
* @param operationIds - The operation IDs to mark as anonymous. Replaces any previously set anonymous operations.
|
|
306
|
+
*/
|
|
307
|
+
setAnonymousOperations(operationIds) {
|
|
308
|
+
this._anonymousOperations.clear();
|
|
309
|
+
for (const opId of operationIds) {
|
|
310
|
+
this._anonymousOperations.add(opId);
|
|
311
|
+
}
|
|
312
|
+
this.applyAnonymousSecurity();
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Add additional operations to the set of anonymous operations.
|
|
316
|
+
* Newly added operations will have `security: []` applied in the OpenAPI spec.
|
|
317
|
+
*
|
|
318
|
+
* Since CDK serializes the OpenAPI spec at synth time (fromInline stores the
|
|
319
|
+
* object reference), mutations after SpecRestApi construction still take effect.
|
|
320
|
+
*
|
|
321
|
+
* @param operationIds - The operation IDs to add to the anonymous set.
|
|
322
|
+
*/
|
|
323
|
+
addAnonymousOperations(operationIds) {
|
|
324
|
+
for (const opId of operationIds) {
|
|
325
|
+
this._anonymousOperations.add(opId);
|
|
326
|
+
}
|
|
327
|
+
this.applyAnonymousSecurityForOps(operationIds.map(op => op));
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Re-applies security settings to all operations based on the current anonymous set.
|
|
331
|
+
* Operations in the anonymous set get `security: []`; operations removed from the set
|
|
332
|
+
* have their original security restored.
|
|
333
|
+
* @private
|
|
334
|
+
*/
|
|
335
|
+
applyAnonymousSecurity() {
|
|
336
|
+
for (const specPath of Object.values(this.apiSpec.paths || [])) {
|
|
337
|
+
for (const key in specPath) {
|
|
338
|
+
if (!this.apiMethods.includes(key)) {
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
const specMethod = specPath[key];
|
|
342
|
+
if (specMethod.operationId && this._anonymousOperations.has(specMethod.operationId)) {
|
|
343
|
+
specMethod.security = [];
|
|
344
|
+
}
|
|
345
|
+
else if (specMethod.operationId && this._originalOperationSecurity.has(specMethod.operationId)) {
|
|
346
|
+
// Restore original security for operations removed from the anonymous set
|
|
347
|
+
specMethod.security = this._originalOperationSecurity.get(specMethod.operationId);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Applies `security: []` only to the specified operations.
|
|
354
|
+
* @private
|
|
355
|
+
*/
|
|
356
|
+
applyAnonymousSecurityForOps(operationIds) {
|
|
357
|
+
const opsSet = new Set(operationIds);
|
|
358
|
+
for (const specPath of Object.values(this.apiSpec.paths || [])) {
|
|
359
|
+
for (const key in specPath) {
|
|
360
|
+
if (!this.apiMethods.includes(key)) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
const specMethod = specPath[key];
|
|
364
|
+
if (specMethod.operationId && opsSet.has(specMethod.operationId)) {
|
|
365
|
+
specMethod.security = [];
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
269
370
|
addRestResource(path, method) {
|
|
270
371
|
const oaPath = this.apiSpec.paths[path];
|
|
271
372
|
const operation = oaPath[method];
|
|
@@ -349,6 +450,98 @@ class RestApi extends base_api_1.BaseApi {
|
|
|
349
450
|
return false;
|
|
350
451
|
}
|
|
351
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* Injects the authorizer security scheme into the OpenAPI spec based on the
|
|
455
|
+
* authentication type, placing it where API Gateway expects it for the spec
|
|
456
|
+
* version: `components.securitySchemes` for OpenAPI 3.x, or the root
|
|
457
|
+
* `securityDefinitions` for Swagger 2.0. An authorizer written to the wrong
|
|
458
|
+
* location is silently ignored on import, deploying an unauthenticated API.
|
|
459
|
+
*
|
|
460
|
+
* For Cognito: adds a cognito_user_pools authorizer referencing the user pool ARN.
|
|
461
|
+
* For JWT: creates a Lambda authorizer function and adds a token authorizer referencing its ARN.
|
|
462
|
+
*/
|
|
463
|
+
patchSecuritySchemes(spec) {
|
|
464
|
+
if (!this.props.authentication) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
const schemes = this.securitySchemeContainer(spec);
|
|
468
|
+
if (this.props.authentication.hasOwnProperty('userpool')) {
|
|
469
|
+
// Cognito User Pool authorizer
|
|
470
|
+
const cognitoAuth = this.props.authentication;
|
|
471
|
+
const authorizerName = 'CognitoAuthorizer';
|
|
472
|
+
schemes[authorizerName] = {
|
|
473
|
+
'type': 'apiKey',
|
|
474
|
+
'name': 'Authorization',
|
|
475
|
+
'in': 'header',
|
|
476
|
+
'x-amazon-apigateway-authtype': 'cognito_user_pools',
|
|
477
|
+
'x-amazon-apigateway-authorizer': {
|
|
478
|
+
type: 'cognito_user_pools',
|
|
479
|
+
providerARNs: [cognitoAuth.userpool.userPoolArn],
|
|
480
|
+
},
|
|
481
|
+
};
|
|
482
|
+
// Ensure global security references the authorizer so patchSecurity distributes it
|
|
483
|
+
if (!spec.security) {
|
|
484
|
+
spec.security = [{ [authorizerName]: [] }];
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
// JWT (Lambda) authorizer
|
|
489
|
+
const jwtAuth = this.props.authentication;
|
|
490
|
+
const authorizerName = 'JwtAuthorizer';
|
|
491
|
+
const authorizerFn = new func_1.LambdaFunction(this, 'JwtAuthorizerFn', {
|
|
492
|
+
stageName: this.props.stageName,
|
|
493
|
+
entry: 'src/lambda/rest-api.jwt-authorizer.ts',
|
|
494
|
+
description: `[${this.props.stageName}] JWT Authorizer for ${this.props.apiName}`,
|
|
495
|
+
jwt: jwtAuth,
|
|
496
|
+
lambdaOptions: this.props.lambdaOptions,
|
|
497
|
+
lambdaTracing: this.props.lambdaTracing,
|
|
498
|
+
});
|
|
499
|
+
const authorizerUri = cdk.Stack.of(this).formatArn({
|
|
500
|
+
resource: 'path',
|
|
501
|
+
service: 'apigateway',
|
|
502
|
+
account: 'lambda',
|
|
503
|
+
arnFormat: cdk.ArnFormat.SLASH_RESOURCE_NAME,
|
|
504
|
+
resourceName: `2015-03-31/functions/${authorizerFn.functionArn}/invocations`,
|
|
505
|
+
});
|
|
506
|
+
schemes[authorizerName] = {
|
|
507
|
+
'type': 'apiKey',
|
|
508
|
+
'name': 'Authorization',
|
|
509
|
+
'in': 'header',
|
|
510
|
+
'x-amazon-apigateway-authtype': 'custom',
|
|
511
|
+
'x-amazon-apigateway-authorizer': {
|
|
512
|
+
type: this.props.jwtAuthorizerType === 'request' ? 'request' : 'token',
|
|
513
|
+
authorizerUri: authorizerUri,
|
|
514
|
+
authorizerResultTtlInSeconds: this.props.jwtAuthorizerType === 'request' ? 0 : 300,
|
|
515
|
+
...(this.props.jwtAuthorizerType !== 'request' && {
|
|
516
|
+
identitySource: 'method.request.header.Authorization',
|
|
517
|
+
}),
|
|
518
|
+
},
|
|
519
|
+
};
|
|
520
|
+
// Store the authorizer function so we can grant permission after the SpecRestApi is created
|
|
521
|
+
this._authorizerFn = authorizerFn;
|
|
522
|
+
// Ensure global security references the authorizer so patchSecurity distributes it
|
|
523
|
+
if (!spec.security) {
|
|
524
|
+
spec.security = [{ [authorizerName]: [] }];
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Returns the security-scheme container for the spec, creating it if needed.
|
|
530
|
+
* OpenAPI 3.x stores schemes under `components.securitySchemes`; Swagger 2.0
|
|
531
|
+
* uses the root `securityDefinitions`. API Gateway reads only the location that
|
|
532
|
+
* matches the document's declared version, so the authorizer must go there.
|
|
533
|
+
*/
|
|
534
|
+
securitySchemeContainer(spec) {
|
|
535
|
+
const specAny = spec;
|
|
536
|
+
const isOpenApiV3 = typeof specAny.openapi === 'string' && specAny.openapi.startsWith('3');
|
|
537
|
+
if (isOpenApiV3) {
|
|
538
|
+
specAny.components = specAny.components ?? {};
|
|
539
|
+
specAny.components.securitySchemes = specAny.components.securitySchemes ?? {};
|
|
540
|
+
return specAny.components.securitySchemes;
|
|
541
|
+
}
|
|
542
|
+
specAny.securityDefinitions = specAny.securityDefinitions ?? {};
|
|
543
|
+
return specAny.securityDefinitions;
|
|
544
|
+
}
|
|
352
545
|
/**
|
|
353
546
|
* AWS does not properly apply the 'security' option to every single path-method.
|
|
354
547
|
* According to documentation, global security gets applied, if there is no security
|
|
@@ -362,13 +555,30 @@ class RestApi extends base_api_1.BaseApi {
|
|
|
362
555
|
if ('security' in spec) {
|
|
363
556
|
for (const specPath of Object.values(spec.paths || [])) {
|
|
364
557
|
for (const key in specPath) {
|
|
365
|
-
// @ts-expect-error -> There is a wrong definition for method includes! It allows any value to be given!
|
|
366
558
|
if (!this.apiMethods.includes(key)) {
|
|
367
559
|
continue; // Skip if not http method definition
|
|
368
560
|
}
|
|
369
561
|
const specMethod = specPath[key];
|
|
370
562
|
if (!('security' in specMethod)) {
|
|
371
|
-
|
|
563
|
+
const operationId = specMethod.operationId;
|
|
564
|
+
if (operationId && this._anonymousOperations.has(operationId)) {
|
|
565
|
+
// Store what security would have been applied so we can restore later
|
|
566
|
+
this._originalOperationSecurity.set(operationId, spec.security);
|
|
567
|
+
specMethod.security = [];
|
|
568
|
+
}
|
|
569
|
+
else {
|
|
570
|
+
specMethod.security = spec.security;
|
|
571
|
+
if (operationId) {
|
|
572
|
+
this._originalOperationSecurity.set(operationId, spec.security);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
else {
|
|
577
|
+
// Operation already has explicit security defined in the spec
|
|
578
|
+
const operationId = specMethod.operationId;
|
|
579
|
+
if (operationId) {
|
|
580
|
+
this._originalOperationSecurity.set(operationId, specMethod.security);
|
|
581
|
+
}
|
|
372
582
|
}
|
|
373
583
|
}
|
|
374
584
|
}
|
|
@@ -377,4 +587,4 @@ class RestApi extends base_api_1.BaseApi {
|
|
|
377
587
|
}
|
|
378
588
|
}
|
|
379
589
|
exports.RestApi = RestApi;
|
|
380
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdC1hcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uc3RydWN0cy9yZXN0LWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw0Q0FBOEI7QUFDOUIsNkNBTXFCO0FBQ3JCLGlEQUFtQztBQUVuQyw4Q0FBZ0M7QUFHaEMseUNBQW1EO0FBQ25ELGlDQUF1RDtBQUN2RCwrQ0FBd0c7QUE4QnhHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVCRztBQUNILE1BQWEsT0FBb0IsU0FBUSxrQkFBTztJQWtCOUM7Ozs7OztPQU1HO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBVSxLQUF3QjtRQUN4RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUR3QixVQUFLLEdBQUwsS0FBSyxDQUFtQjtRQWIxRTs7O1dBR0c7UUFDSyxlQUFVLEdBQThDLEVBQUUsQ0FBQztRQVlqRSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBYSxDQUFDO1FBRTNGLElBQUksZ0JBQThELENBQUM7UUFDbkUsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsZ0JBQWdCLEdBQUc7Z0JBQ2pCLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTztnQkFDeEIsV0FBVyxFQUFFLElBQUksb0NBQXNCLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUU7b0JBQ2hFLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTztvQkFDeEIsVUFBVSxFQUFFLG9DQUFzQixDQUFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO2lCQUNsRixDQUFDO2FBQ0gsQ0FBQztZQUNGLElBQUks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TztnQkFDVixPQUFPLElBQUksQ0FBQztZQUNkLEtBQUssU0FBUyxDQUFDO1lBQ2YsS0FBSyxLQUFLLENBQUM7WUFDWCxLQUFLLE1BQU0sQ0FBQztZQUNaO2dCQUNFLE9BQU8sS0FBSyxDQUFDO1FBQ2pCLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDTyxhQUFhLENBQUMsSUFBYztRQUNwQyxJQUFJLFVBQVUsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN2QixLQUFLLE1BQU0sUUFBUSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUN2RCxLQUFLLE1BQU0sR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO29CQUMzQix3R0FBd0c7b0JBQ3hHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO3dCQUNuQyxTQUFTLENBQUMscUNBQXFDO29CQUNqRCxDQUFDO29CQUVELE1BQU0sVUFBVSxHQUFJLFFBQTJCLENBQUMsR0FBMkIsQ0FBRSxDQUFDO29CQUM5RSxJQUFJLENBQUMsQ0FBQyxVQUFVLElBQUksVUFBVSxDQUFDLEVBQUUsQ0FBQzt3QkFDaEMsVUFBVSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUN0QyxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3ZCLENBQUM7SUFDSCxDQUFDO0NBRUY7QUFuV0QsMEJBbVdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBhd3NfY2VydGlmaWNhdGVtYW5hZ2VyLFxuICBhd3NfaWFtLFxuICBhd3Nfcm91dGU1MyxcbiAgYXdzX3JvdXRlNTNfdGFyZ2V0cyxcbiAgYXdzX2FwaWdhdGV3YXksXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCAqIGFzIHlhbWwgZnJvbSAnanMteWFtbCc7XG5pbXBvcnQgeyBPcGVuQVBJMywgT3BlcmF0aW9uT2JqZWN0LCBQYXRoSXRlbU9iamVjdCB9IGZyb20gJ29wZW5hcGktdHlwZXNjcmlwdCc7XG5pbXBvcnQgeyBJQ29nbml0b0F1dGhlbnRpY2F0aW9uLCBJSnd0QXV0aGVudGljYXRpb24gfSBmcm9tICcuL2F1dGhlbnRpY2F0aW9uJztcbmltcG9ydCB7IEJhc2VBcGksIEJhc2VBcGlQcm9wcyB9IGZyb20gJy4vYmFzZS1hcGknO1xuaW1wb3J0IHsgTGFtYmRhRnVuY3Rpb24sIExhbWJkYU9wdGlvbnMgfSBmcm9tICcuL2Z1bmMnO1xuaW1wb3J0IHsgQ0ZOX09VVFBVVF9TVUZGSVhfUkVTVEFQSV9ET01BSU5OQU1FLCBDRk5fT1VUUFVUX1NVRkZJWF9SRVNUQVBJX1VSTCB9IGZyb20gJy4uL3NoYXJlZC9vdXRwdXRzJztcblxuZXhwb3J0IGludGVyZmFjZSBSZXN0QXBpUHJvcHM8T1BTPiBleHRlbmRzIEJhc2VBcGlQcm9wcyB7XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHJvdXRlcyBmb3IgYWxsIGVuZHBvaW50cyBjb25maWd1cmVkIGluIHRoZSBvcGVuYXBpLnlhbWwgZmlsZVxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICBhdXRvR2VuZXJhdGVSb3V0ZXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBjdXN0b20gb3B0aW9ucyBmb3IgdGhlIGNyZWF0ZWQgSHR0cEFwaVxuICAgKlxuICAgKiBAZGVmYXVsdCAtXG4gICAqL1xuICByZXN0QXBpUHJvcHM/OiBhd3NfYXBpZ2F0ZXdheS5SZXN0QXBpQmFzZVByb3BzO1xuXG4gIC8qKlxuICAgKiBhZGRpdGlvbmFsIG9wdGlvbnMgZm9yIHRoZSB1bmRlcmx5aW5nIExhbWJkYSBmdW5jdGlvbiBjb25zdHJ1Y3QgcGVyIG9wZXJhdGlvbklkXG4gICAqXG4gICAqIEBkZWZhdWx0IC1cbiAgICovXG4gIGxhbWJkYU9wdGlvbnNCeU9wZXJhdGlvbj86IHsgW29wZXJhdGlvbklkIGluIGtleW9mIE9QU10/OiBMYW1iZGFPcHRpb25zIH07XG5cbiAgZGVmaW5pdGlvbkZpbGVOYW1lOiBzdHJpbmc7XG5cbiAgY29yczogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUaGUgUmVzdEFwaSBjb25zdHJ1Y3Qgc2V0cyB1cCBhbiBBV1MgQVBJIEdhdGV3YXkgUkVTVCBBUEkgdXNpbmcgT3BlbkFQSSBzcGVjaWZpY2F0aW9uLlxuICogVGhpcyBjb25zdHJ1Y3QgZmFjaWxpdGF0ZXMgdGhlIGNyZWF0aW9uIG9mIGEgUkVTVCBBUEkgd2l0aCB2YXJpb3VzIGNvbmZpZ3VyYXRpb25zLCBpbmNsdWRpbmcgY3VzdG9tIGRvbWFpbiwgQ09SUyBzdXBwb3J0LCBhbmQgaW50ZWdyYXRpb24gd2l0aCBMYW1iZGEgZnVuY3Rpb25zLlxuICogSXQgYWxsb3dzIGF1dG8tZ2VuZXJhdGluZyByb3V0ZXMgYmFzZWQgb24gdGhlIHByb3ZpZGVkIE9wZW5BUEkgZGVmaW5pdGlvbiBhbmQgcHJvdmlkZXMgbWV0aG9kcyB0byBkeW5hbWljYWxseSBhZGQgY3VzdG9tIHJvdXRlcyBhbmQgbWFuYWdlIExhbWJkYSBmdW5jdGlvbiBpbnRlZ3JhdGlvbnMuXG4gKlxuICogQHRlbXBsYXRlIFBBVEhTIC0gVGhlIHR5cGUgZGVmaW5pdGlvbiBmb3IgdGhlIEFQSSBwYXRocy5cbiAqIEB0ZW1wbGF0ZSBPUFMgLSBUaGUgdHlwZSBkZWZpbml0aW9uIGZvciB0aGUgQVBJIG9wZXJhdGlvbnMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGFwaSA9IG5ldyBSZXN0QXBpKHRoaXMsICdNeVJlc3RBcGknLCB7XG4gKiAgIGFwaU5hbWU6ICdNeUFQSScsXG4gKiAgIHN0YWdlTmFtZTogJ2RldicsXG4gKiAgIGRlZmluaXRpb25GaWxlTmFtZTogJ29wZW5hcGkueWFtbCcsXG4gKiAgIGF1dGhlbnRpY2F0aW9uOiBteUNvZ25pdG9BdXRoLFxuICogICBzaW5nbGVUYWJsZURhdGFzdG9yZTogbXlEeW5hbW9EQlRhYmxlLFxuICogICBhdXRvR2VuZXJhdGVSb3V0ZXM6IHRydWUsXG4gKiB9KTtcbiAqXG4gKiAvLyBBZGQgYSBjdXN0b20gUkVTVCByZXNvdXJjZVxuICogYXBpLmFkZFJlc3RSZXNvdXJjZSgnL2l0ZW1zJywgJ2dldCcpO1xuICpcbiAqIC8vIEdldCB0aGUgTGFtYmRhIGZ1bmN0aW9uIGZvciBhIHNwZWNpZmljIG9wZXJhdGlvblxuICogY29uc3QgbGFtYmRhRnVuY3Rpb24gPSBhcGkuZ2V0RnVuY3Rpb25Gb3JPcGVyYXRpb24oJ2dldEl0ZW1zJyk7XG4gKi9cbmV4cG9ydCBjbGFzcyBSZXN0QXBpPFBBVEhTLCBPUFM+IGV4dGVuZHMgQmFzZUFwaSB7XG5cbiAgLyoqXG4gICAqIFRoZSBBV1MgQVBJIEdhdGV3YXkgUkVTVCBBUEkgaW5zdGFuY2UuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYXBpOiBhd3NfYXBpZ2F0ZXdheS5TcGVjUmVzdEFwaTtcblxuICAvKipcbiAgICogVGhlIE9wZW5BUEkgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIFJFU1QgQVBJLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFwaVNwZWM6IE9wZW5BUEkzO1xuXG4gIC8qKlxuICAgKiBBIGNvbGxlY3Rpb24gb2YgTGFtYmRhIGZ1bmN0aW9ucyB1c2VkIGFzIGludGVncmF0aW9ucyBmb3IgdGhlIEFQSSBvcGVyYXRpb25zLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfZnVuY3Rpb25zOiB7IFtvcGVyYXRpb25JZDogc3RyaW5nXTogTGFtYmRhRnVuY3Rpb24gfSA9IHt9O1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFJlc3RBcGkuXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSAtIFRoZSBzY29wZSBpbiB3aGljaCB0aGlzIGNvbnN0cnVjdCBpcyBkZWZpbmVkLlxuICAgKiBAcGFyYW0gaWQgLSBUaGUgc2NvcGVkIGNvbnN0cnVjdCBJRC5cbiAgICogQHBhcmFtIHByb3BzIC0gVGhlIHByb3BlcnRpZXMgb2YgdGhlIFJlc3RBcGkgY29uc3RydWN0LlxuICAgKi9cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJpdmF0ZSBwcm9wczogUmVzdEFwaVByb3BzPE9QUz4pIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcblxuICAgIHRoaXMuYXBpU3BlYyA9IHlhbWwubG9hZChmcy5yZWFkRmlsZVN5bmMocHJvcHMuZGVmaW5pdGlvbkZpbGVOYW1lKS50b1N0cmluZygpKSBhcyBPcGVuQVBJMztcblxuICAgIGxldCBjdXN0b21Eb21haW5OYW1lOiBhd3NfYXBpZ2F0ZXdheS5Eb21haW5OYW1lT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICBpZiAodGhpcy5hcGlGUUROKSB7XG4gICAgICBjdXN0b21Eb21haW5OYW1lID0ge1xuICAgICAgICBkb21haW5OYW1lOiB0aGlzLmFwaUZRRE4sXG4gICAgICAgIGNlcnRpZmljYXRlOiBuZXcgYXdzX2NlcnRpZmljYXRlbWFuYWdlci5DZXJ0aWZpY2F0ZSh0aGlzLCAnQ2VydCcsIHtcbiAgICAgICAgICBkb21haW5OYW1lOiB0aGlzLmFwaUZRRE4sXG4gICAgICAgICAgdmFsaWRhdGlvbjogYXdzX2NlcnRpZmljYXRlbWFuYWdlci5DZXJ0aWZpY2F0ZVZhbGlkYXRpb24uZnJvbURucyh0aGlzLmhvc3RlZFpvbmUpLFxuICAgICAgICB9KSxcbiAgICAgIH07XG4gICAgICBuZXcgY2RrLkNmbk91dHB1dCh0aGlzLCAnUmVzdEFwaURvbWFpbk5hbWUnLCB7XG4gICAgICAgIGtleTogYCR7dGhpcy5wcm9wcy5hcGlOYW1lfSR7Q0ZOX09VVFBVVF9TVUZGSVhfUkVTVEFQSV9ET01BSU5OQU1FfWAsXG4gICAgICAgIHZhbHVlOiB0aGlzLmFwaUZRRE4sXG4gICAgICB9KTtcbiAgICAgIG5ldyBjZGsuQ2ZuT3V0cHV0KHRoaXMsICdSZXN0QXBpVXJsT3V0cHV0Jywge1xuICAgICAgICBrZXk6IGAke3RoaXMucHJvcHMuYXBpTmFtZX0ke0NGTl9PVVRQVVRfU1VGRklYX1JFU1RBUElfVVJMfWAsXG4gICAgICAgIHZhbHVlOiAnaHR0cHM6Ly8nICsgdGhpcy5hcGlGUUROLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gaWYgKChwcm9wcy5tb25pdG9yaW5nID8/IHRydWUpICYmIHRoaXMubW9uaXRvcmluZykge1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmFwaUVycm9yc1dpZGdldC5hZGRMZWZ0TWV0cmljKHRoaXMuYXBpLm1ldHJpY1NlcnZlckVycm9yKHtcbiAgICAvLyAgICAgc3RhdGlzdGljOiAnc3VtJyxcbiAgICAvLyAgIH0pKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlFcnJvcnNXaWRnZXQuYWRkTGVmdE1ldHJpYyh0aGlzLmFwaS5tZXRyaWNDbGllbnRFcnJvcih7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ3N1bScsXG4gICAgLy8gICB9KSk7XG5cbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlMYXRlbmN5V2lkZ2V0LmFkZExlZnRNZXRyaWModGhpcy5hcGkubWV0cmljTGF0ZW5jeSh7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ0F2ZXJhZ2UnLFxuICAgIC8vICAgfSkpO1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmFwaUxhdGVuY3lXaWRnZXQuYWRkTGVmdE1ldHJpYyh0aGlzLmFwaS5tZXRyaWNMYXRlbmN5KHtcbiAgICAvLyAgICAgc3RhdGlzdGljOiAncDkwJyxcbiAgICAvLyAgIH0pKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlMYXRlbmN5VGFpbFdpZGdldC5hZGRMZWZ0TWV0cmljKHRoaXMuYXBpLm1ldHJpY0xhdGVuY3koe1xuICAgIC8vICAgICBzdGF0aXN0aWM6ICdwOTUnLFxuICAgIC8vICAgfSkpO1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmFwaUxhdGVuY3lUYWlsV2lkZ2V0LmFkZExlZnRNZXRyaWModGhpcy5hcGkubWV0cmljTGF0ZW5jeSh7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ3A5OScsXG4gICAgLy8gICB9KSk7XG4gICAgLy8gfVxuXG4gICAgaWYgKHByb3BzLmF1dG9HZW5lcmF0ZVJvdXRlcyA/PyB0cnVlKSB7XG4gICAgICBmb3IgKGNvbnN0IHBhdGggaW4gdGhpcy5hcGlTcGVjLnBhdGhzKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hcGlTcGVjLnBhdGhzLCBwYXRoKSkge1xuICAgICAgICAgIGNvbnN0IHBhdGhJdGVtID0gdGhpcy5hcGlTcGVjLnBhdGhzW3BhdGhdO1xuICAgICAgICAgIGZvciAoY29uc3QgbWV0aG9kIGluIHBhdGhJdGVtKSB7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhdGhJdGVtLCBtZXRob2QpICYmXG4gICAgICAgICAgICAgIFsnZ2V0JywgJ3Bvc3QnLCAncHV0JywgJ2RlbGV0ZScsICdwYXRjaCcsICdvcHRpb25zJywgJ2hlYWQnXS5pbmRleE9mKG1ldGhvZCkgPj0gMCkge1xuICAgICAgICAgICAgICAvLyBBZGQgYWxsIG9wZXJhdGlvbnNcbiAgICAgICAgICAgICAgdGhpcy5hZGRSZXN0UmVzb3VyY2UocGF0aCBhcyBhbnksIG1ldGhvZCBhcyBhbnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFkZCBfc3BlYyBFbmRwb2ludFxuICAgIHRoaXMuYXBpU3BlYy5wYXRocyFbJy9vcGVuYXBpLmpzb24nXSA9IHtcbiAgICAgIGdldDoge1xuICAgICAgICAnc3VtbWFyeSc6ICdSZXR1cm5zIHRoZSByYXcgT3BlbkFQSSBzcGVjIG9mIHRoaXMgQVBJJyxcbiAgICAgICAgJ2Rlc2NyaXB0aW9uJzogJ1JldHVybnMgdGhlIHJhdyBPcGVuQVBJIHNwZWMgb2YgdGhpcyBBUEknLFxuICAgICAgICAnb3BlcmF0aW9uSWQnOiAnX3NwZWMnLFxuICAgICAgICAncmVzcG9uc2VzJzoge1xuICAgICAgICAgIDIwMDoge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246ICdPcGVuQVBJIHNwZWMgb2YgdGhpcyBBUEknLFxuICAgICAgICAgICAgY29udGVudDoge1xuICAgICAgICAgICAgICAnYXBwbGljYXRpb24vb3BlbmFwaStqc29uJzoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIC8vIEB0cy1pZ25vcmUgQ3VzdG9tIHByb3BlcnR5IGZvciBBV1NcbiAgICAgICAgJ3gtYW1hem9uLWFwaWdhdGV3YXktaW50ZWdyYXRpb24nOiB7XG4gICAgICAgICAgdHlwZTogJ21vY2snLFxuICAgICAgICAgIGh0dHBNZXRob2Q6ICdHRVQnLFxuICAgICAgICAgIHBheWxvYWRGb3JtYXRWZXJzaW9uOiAnMS4wJyxcbiAgICAgICAgICByZXF1ZXN0VGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAnYXBwbGljYXRpb24vanNvbic6ICd7XFwnc3RhdHVzQ29kZVxcJzogMjAwfScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXNwb25zZXM6IHtcbiAgICAgICAgICAgIDIwMDoge1xuICAgICAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgICAgIHJlc3BvbnNlVGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAgICAgJ2FwcGxpY2F0aW9uL29wZW5hcGkranNvbic6IEpTT04uc3RyaW5naWZ5KHRoaXMuY2xlYW51cFNwZWMoSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSgodGhpcy5hcGlTcGVjKSkpKSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBpZiAocHJvcHMuY29ycykge1xuICAgICAgdGhpcy5hcGlTcGVjLnBhdGhzIVsnL3twcm94eSt9J10gPSB7XG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAnc3VtbWFyeSc6ICdDT1JTIHN1cHBvcnQnLFxuICAgICAgICAgICdkZXNjcmlwdGlvbic6ICdFbmFibGUgQ09SUyBieSByZXR1cm5pbmcgY29ycmVjdCBoZWFkZXJzJyxcbiAgICAgICAgICAndGFncyc6IFsnQ09SUyddLFxuICAgICAgICAgICdyZXNwb25zZXMnOiB7XG4gICAgICAgICAgICAyMDA6IHtcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdEZWZhdWx0IHJlc3BvbnNlIGZvciBDT1JTIG1ldGhvZCcsXG4gICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJzogeyBzY2hlbWE6IHsgdHlwZTogJ3N0cmluZycgfSB9LFxuICAgICAgICAgICAgICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogeyBzY2hlbWE6IHsgdHlwZTogJ3N0cmluZycgfSB9LFxuICAgICAgICAgICAgICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyc6IHsgc2NoZW1hOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICAgICAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyc6IHsgc2NoZW1hOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgY29udGVudDoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgJ3gtYW1hem9uLWFwaWdhdGV3YXktaW50ZWdyYXRpb24nOiB7XG4gICAgICAgICAgICB0eXBlOiAnbW9jaycsXG4gICAgICAgICAgICByZXF1ZXN0VGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAgICdhcHBsaWNhdGlvbi9qc29uJzogJyNzZXQoJGNvbnRleHQucmVxdWVzdE92ZXJyaWRlLmhlYWRlci5vcmlnaW4gPSAkbWV0aG9kLnJlcXVlc3QuaGVhZGVyLm9yaWdpbilcXG57XFxuICBcInN0YXR1c0NvZGVcIiA6IDIwMFxcbn1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlc3BvbnNlczoge1xuICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgc3RhdHVzQ29kZTogJzIwMCcsXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzJzogXCInQ29udGVudC1UeXBlLFgtQW16LURhdGUsQXV0aG9yaXphdGlvbixYLUFwaS1LZXknXCIsXG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyc6IFwiJ3RydWUnXCIsXG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogXCInUFVULEdFVCxQT1NULERFTEVURSxQQVRDSCxIRUFELE9QVElPTlMnXCIsXG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nOiAnY29udGV4dC5yZXF1ZXN0T3ZlcnJpZGUuaGVhZGVyLm9yaWdpbicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZXNwb25zZVRlbXBsYXRlczoge1xuICAgICAgICAgICAgICAgICAgJ2FwcGxpY2F0aW9uL2pzb24nOiAne30nLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMucGF0Y2hTZWN1cml0eSh0aGlzLmFwaVNwZWMpO1xuXG4gICAgLy8gVE9ETyBwYXRjaCBzcGVjIGZvciBDb2duaXRvIHVzZXIgcG9vbFxuXG4gICAgdGhpcy5hcGkgPSBuZXcgYXdzX2FwaWdhdGV3YXkuU3BlY1Jlc3RBcGkodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgcmVzdEFwaU5hbWU6IGAke3Byb3BzLmFwaU5hbWV9IFske3Byb3BzLnN0YWdlTmFtZX1dYCxcbiAgICAgIGRvbWFpbk5hbWU6IGN1c3RvbURvbWFpbk5hbWUsXG4gICAgICBhcGlEZWZpbml0aW9uOiBhd3NfYXBpZ2F0ZXdheS5BcGlEZWZpbml0aW9uLmZyb21JbmxpbmUodGhpcy5hcGlTcGVjKSxcbiAgICAgIC4uLnByb3BzLnJlc3RBcGlQcm9wcyxcbiAgICB9KTtcblxuICAgIC8vIGFkZCBpbnZva2UgcGVybWlzc2lvbnMgdG8gTGFtYmRhIGZ1bmN0aW9uc1xuICAgIGZvciAoY29uc3QgZm4gb2YgT2JqZWN0LnZhbHVlcyh0aGlzLl9mdW5jdGlvbnMpKSB7XG4gICAgICBmbi5hZGRQZXJtaXNzaW9uKCdSZXN0QXBpSW52b2tlJywge1xuICAgICAgICBwcmluY2lwYWw6IG5ldyBhd3NfaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2FwaWdhdGV3YXkuYW1hem9uYXdzLmNvbScpLFxuICAgICAgICBhY3Rpb246ICdsYW1iZGE6SW52b2tlRnVuY3Rpb24nLFxuICAgICAgICBzb3VyY2VBcm46IHRoaXMuYXBpLmFybkZvckV4ZWN1dGVBcGkoKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChjdXN0b21Eb21haW5OYW1lICYmIHRoaXMuYXBpLmRvbWFpbk5hbWUpIHtcbiAgICAgIG5ldyBhd3Nfcm91dGU1My5BUmVjb3JkKHRoaXMsICdEbnNSZWNvcmQnLCB7XG4gICAgICAgIHpvbmU6IHRoaXMuaG9zdGVkWm9uZSEsXG4gICAgICAgIHJlY29yZE5hbWU6IGN1c3RvbURvbWFpbk5hbWUuZG9tYWluTmFtZSxcbiAgICAgICAgdGFyZ2V0OiBhd3Nfcm91dGU1My5SZWNvcmRUYXJnZXQuZnJvbUFsaWFzKFxuICAgICAgICAgIG5ldyBhd3Nfcm91dGU1M190YXJnZXRzLkFwaUdhdGV3YXlEb21haW4odGhpcy5hcGkuZG9tYWluTmFtZSksXG4gICAgICAgICksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgfVxuXG4gIHByb3RlY3RlZCBjbGVhbnVwU3BlYyhzcGVjOiB7IFtrZXk6IHN0cmluZ106IGFueSB9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gICAgT2JqZWN0LmVudHJpZXMoc3BlYykuZm9yRWFjaCgoW3Byb3AsIHZhbHVlXTogW3N0cmluZywgYW55XSkgPT4ge1xuICAgICAgaWYgKHByb3Auc3RhcnRzV2l0aCgneC0nKSkge1xuICAgICAgICBkZWxldGUgc3BlY1twcm9wXTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICB0aGlzLmNsZWFudXBTcGVjKHNwZWNbcHJvcF0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNwZWM7XG4gIH1cblxuICAvKipcbiAgICogcmV0dXJuIHRoZSBnZW5lcmF0ZWQgTGFtYmRhIGZ1bmN0aW9uIGZvciB0aGUgc3BlY2lmaWVkIEFQSSBvcGVyYXRpb25cbiAgICovXG4gIHB1YmxpYyBnZXRGdW5jdGlvbkZvck9wZXJhdGlvbihvcGVyYXRpb25JZDoga2V5b2YgT1BTKTogTGFtYmRhRnVuY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLl9mdW5jdGlvbnNbb3BlcmF0aW9uSWQgYXMgc3RyaW5nXTtcbiAgfVxuXG4gIC8qKlxuICAgKiByZXR1cm4gYSBsaXN0IG9mIGFsbCBnZW5lcmF0ZWQgTGFtYmRhIGZ1bmN0aW9uc1xuICAgKi9cbiAgcHVibGljIGdldEZ1bmN0aW9ucygpOiBMYW1iZGFGdW5jdGlvbltdIHtcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyh0aGlzLl9mdW5jdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZpc2l0b3IgbWV0aG9kIHRvIG1vZGlmeSB0aGUgZ2l2ZW4gZnVuY3Rpb25zXG4gICAqXG4gICAqIEBwYXJhbSBvcGVyYXRpb25JZHMgdGhlIGxpc3Qgb2YgZnVuY3Rpb25zIHRvIHZpc2l0XG4gICAqIEBwYXJhbSBvcCB0aGUgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZXZlcnkgZnVuY3Rpb25cbiAgICovXG4gIHB1YmxpYyBtb2RpZnlPcGVyYXRpb25GdW5jdGlvbnMob3BlcmF0aW9uSWRzOiAoa2V5b2YgT1BTKVtdLCBvcDogKGZuOiBMYW1iZGFGdW5jdGlvbikgPT4gdm9pZCkge1xuICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uSWQgb2Ygb3BlcmF0aW9uSWRzKSB7XG4gICAgICBvcCh0aGlzLmdldEZ1bmN0aW9uRm9yT3BlcmF0aW9uKG9wZXJhdGlvbklkKSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFkZFJlc3RSZXNvdXJjZTxQIGV4dGVuZHMga2V5b2YgUEFUSFM+KHBhdGg6IFAsIG1ldGhvZDoga2V5b2YgUEFUSFNbUF0pIHtcbiAgICBjb25zdCBvYVBhdGggPSB0aGlzLmFwaVNwZWMucGF0aHMhW3BhdGggYXMgc3RyaW5nXSBhcyBQYXRoSXRlbU9iamVjdDtcbiAgICBjb25zdCBvcGVyYXRpb24gPSBvYVBhdGhbbWV0aG9kIGFzIGtleW9mIFBhdGhJdGVtT2JqZWN0XSBhcyBPcGVyYXRpb25PYmplY3Q7XG4gICAgY29uc3Qgb3BlcmF0aW9uSWQgPSBvcGVyYXRpb24ub3BlcmF0aW9uSWQhO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gYCR7bWV0aG9kIGFzIHN0cmluZ30gJHtwYXRoIGFzIHN0cmluZ30gLSAke29wZXJhdGlvbi5zdW1tYXJ5fWA7XG5cbiAgICBjb25zdCBjdXN0b21MYW1iZGFPcHRpb25zID0gdGhpcy5wcm9wcy5sYW1iZGFPcHRpb25zQnlPcGVyYXRpb24gPyB0aGlzLnByb3BzLmxhbWJkYU9wdGlvbnNCeU9wZXJhdGlvbltvcGVyYXRpb25JZCBhcyBrZXlvZiBPUFNdIDogdW5kZWZpbmVkO1xuICAgIHJldHVybiB0aGlzLmFkZEN1c3RvbVJlc3RSZXNvdXJjZShvcGVyYXRpb24sIG1ldGhvZCBhcyBzdHJpbmcsIGRlc2NyaXB0aW9uLCBjdXN0b21MYW1iZGFPcHRpb25zKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRDdXN0b21SZXN0UmVzb3VyY2Uob3BlcmF0aW9uOiBPcGVyYXRpb25PYmplY3QsIG1ldGhvZDogc3RyaW5nLCBkZXNjcmlwdGlvbjogc3RyaW5nLCBhZGRpdGlvbmFsTGFtYmRhT3B0aW9uczogTGFtYmRhT3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCd4LWFtYXpvbi1hcGlnYXRld2F5LWludGVncmF0aW9uJyBpbiBvcGVyYXRpb24pIHtcbiAgICAgIHJldHVybjsgLy8gU2tpcCBpZiBvcGVyYXRpb24gd2FzIGRlY2xhcmVkIGluIHNwZWMgZmlsZSBhbHJlYWR5IVxuICAgIH1cblxuICAgIGNvbnN0IGVudHJ5RmlsZSA9IGAuL3NyYy9sYW1iZGEvcmVzdC4ke3RoaXMucHJvcHMuYXBpTmFtZS50b0xvd2VyQ2FzZSgpfS4ke29wZXJhdGlvbi5vcGVyYXRpb25JZH0udHNgO1xuXG4gICAgY29uc3QgbGFtYmRhT3B0aW9ucyA9IHtcbiAgICAgIC4uLnRoaXMucHJvcHMubGFtYmRhT3B0aW9ucyAmJiB7XG4gICAgICAgIC4uLnRoaXMucHJvcHMubGFtYmRhT3B0aW9ucyxcbiAgICAgIH0sXG4gICAgICAuLi5hZGRpdGlvbmFsTGFtYmRhT3B0aW9ucyxcbiAgICB9O1xuXG4gICAgY29uc3QgYXV0aGVudGljYXRpb24gPSB0aGlzLnByb3BzLmF1dGhlbnRpY2F0aW9uICYmICh0aGlzLnByb3BzLmF1dGhlbnRpY2F0aW9uLmhhc093blByb3BlcnR5KCd1c2VycG9vbCcpXG4gICAgICA/IHsgdXNlclBvb2w6ICh0aGlzLnByb3BzLmF1dGhlbnRpY2F0aW9uIGFzIElDb2duaXRvQXV0aGVudGljYXRpb24pLnVzZXJwb29sIH1cbiAgICAgIDogeyBqd3Q6IHRoaXMucHJvcHMuYXV0aGVudGljYXRpb24gYXMgSUp3dEF1dGhlbnRpY2F0aW9uIH0pO1xuXG4gICAgY29uc3QgZm4gPSBuZXcgTGFtYmRhRnVuY3Rpb24odGhpcywgYEZuJHtvcGVyYXRpb24ub3BlcmF0aW9uSWR9YCwge1xuICAgICAgc3RhZ2VOYW1lOiB0aGlzLnByb3BzLnN0YWdlTmFtZSxcbiAgICAgIGFkZGl0aW9uYWxFbnY6IHtcbiAgICAgICAgLi4udGhpcy5wcm9wcy5kb21haW5OYW1lICYmIHtcbiAgICAgICAgICBET01BSU5fTkFNRTogdGhpcy5wcm9wcy5kb21haW5OYW1lLFxuICAgICAgICB9LFxuICAgICAgICAuLi50aGlzLnByb3BzLmFkZGl0aW9uYWxFbnYsXG4gICAgICB9LFxuICAgICAgZW50cnk6IGVudHJ5RmlsZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBgWyR7dGhpcy5wcm9wcy5zdGFnZU5hbWV9XSAke2Rlc2NyaXB0aW9ufWAsXG4gICAgICAuLi5hdXRoZW50aWNhdGlvbixcbiAgICAgIC4uLnRoaXMucHJvcHMuc2luZ2xlVGFibGVEYXRhc3RvcmUgJiYge1xuICAgICAgICB0YWJsZTogdGhpcy5wcm9wcy5zaW5nbGVUYWJsZURhdGFzdG9yZS50YWJsZSxcbiAgICAgICAgdGFibGVXcml0ZXM6IHRoaXMudGFibGVXcml0ZUFjY2Vzc0Zvck1ldGhvZChtZXRob2QpLFxuICAgICAgfSxcbiAgICAgIC4uLnRoaXMucHJvcHMuYXNzZXRDZG4gJiYge1xuICAgICAgICBhc3NldERvbWFpbk5hbWU6IHRoaXMucHJvcHMuYXNzZXRDZG4uYXNzZXREb21haW5OYW1lLFxuICAgICAgICBhc3NldEJ1Y2tldDogdGhpcy5wcm9wcy5hc3NldENkbi5hc3NldEJ1Y2tldCxcbiAgICAgIH0sXG4gICAgICBsYW1iZGFPcHRpb25zLFxuICAgICAgbGFtYmRhVHJhY2luZzogdGhpcy5wcm9wcy5sYW1iZGFUcmFjaW5nLFxuICAgIH0pO1xuICAgIHRoaXMuX2Z1bmN0aW9uc1tvcGVyYXRpb24ub3BlcmF0aW9uSWQhXSA9IGZuO1xuICAgIGNkay5UYWdzLm9mKGZuKS5hZGQoJ09wZW5BUEknLCBkZXNjcmlwdGlvbi5yZXBsYWNlKC9bXlxcd1xcc1xcZF8uOi89K1xcLUBdL2csICcnKSk7XG5cbiAgICAvLyBpZiAodGhpcy5tb25pdG9yaW5nKSB7XG4gICAgLy8gICB0aGlzLm1vbml0b3JpbmcubGFtYmRhRHVyYXRpb25zV2lkZ2V0LmFkZExlZnRNZXRyaWMoZm4ubWV0cmljRHVyYXRpb24oKSk7XG4gICAgLy8gICB0aGlzLm1vbml0b3JpbmcubGFtYmRhSW52b2tlc1dpZGdldC5hZGRMZWZ0TWV0cmljKGZuLm1ldHJpY0ludm9jYXRpb25zKCkpO1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmxhbWJkYUVycm9yc1dpZGdldC5hZGRMZWZ0TWV0cmljKGZuLm1ldHJpY0Vycm9ycygpKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5sYW1iZGFFcnJvcnNXaWRnZXQuYWRkTGVmdE1ldHJpYyhmbi5tZXRyaWNUaHJvdHRsZXMoKSk7XG4gICAgLy8gfVxuXG4gICAgY29uc3QgaGFzVmVyc2lvbkNvbmZpZyA9IGxhbWJkYU9wdGlvbnMuY3VycmVudFZlcnNpb25PcHRpb25zICE9IHVuZGVmaW5lZDtcblxuICAgIG9wZXJhdGlvblsneC1hbWF6b24tYXBpZ2F0ZXdheS1pbnRlZ3JhdGlvbiddID0ge1xuICAgICAgdHlwZTogJ2F3c19wcm94eScsXG4gICAgICBodHRwTWV0aG9kOiAnUE9TVCcsXG4gICAgICB1cmk6IGNkay5TdGFjay5vZih0aGlzKS5mb3JtYXRBcm4oe1xuICAgICAgICByZXNvdXJjZTogJ3BhdGgnLFxuICAgICAgICBzZXJ2aWNlOiAnYXBpZ2F0ZXdheScsXG4gICAgICAgIGFjY291bnQ6ICdsYW1iZGEnLFxuICAgICAgICBhcm5Gb3JtYXQ6IGNkay5Bcm5Gb3JtYXQuU0xBU0hfUkVTT1VSQ0VfTkFNRSxcbiAgICAgICAgcmVzb3VyY2VOYW1lOiBgMjAxNS0wMy0zMS9mdW5jdGlvbnMvJHsoaGFzVmVyc2lvbkNvbmZpZyA/IGZuLmN1cnJlbnRWZXJzaW9uIDogZm4pLmZ1bmN0aW9uQXJufS9pbnZvY2F0aW9uc2AsXG4gICAgICAgIC8vICAgICAgICAgICAgIF5eXl5eXl5eXl4gLSBUSElTIE5FRURTIFRPIEJFIFRISVMgREFURS4gRVhBQ1RMWSFcbiAgICAgIH0pLFxuICAgICAgcGFzc3Rocm91Z2hCZWhhdmlvcjogJ3doZW5fbm9fdGVtcGxhdGVzJyxcbiAgICAgIHBheWxvYWRGb3JtYXRWZXJzaW9uOiAnMS4wJyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgcHJpdmF0ZSB0YWJsZVdyaXRlQWNjZXNzRm9yTWV0aG9kKG1ldGhvZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgc3dpdGNoIChtZXRob2QudG9Mb3dlckNhc2UoKSkge1xuICAgICAgY2FzZSAnZGVsZXRlJzpcbiAgICAgIGNhc2UgJ3Bvc3QnOlxuICAgICAgY2FzZSAncHV0JzpcbiAgICAgIGNhc2UgJ3BhdGNoJzpcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICBjYXNlICdvcHRpb25zJzpcbiAgICAgIGNhc2UgJ2dldCc6XG4gICAgICBjYXNlICdoZWFkJzpcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQVdTIGRvZXMgbm90IHByb3Blcmx5IGFwcGx5IHRoZSAnc2VjdXJpdHknIG9wdGlvbiB0byBldmVyeSBzaW5nbGUgcGF0aC1tZXRob2QuXG4gICAqIEFjY29yZGluZyB0byBkb2N1bWVudGF0aW9uLCBnbG9iYWwgc2VjdXJpdHkgZ2V0cyBhcHBsaWVkLCBpZiB0aGVyZSBpcyBubyBzZWN1cml0eVxuICAgKiBzZXQgZm9yIHRoZSBwYXJ0aWN1bGFyIHBhdGgtbWV0aG9kLiBJZiB0aGVyZSBpcyBhbnksIGV2ZW4gZW1wdHksIGl0IHdpbGwgZ2V0IHByZWNlZGVuY2UuXG4gICAqIFRISVMgRE9FUyBOT1QgSEFQUEVOIE9OIEFXUy4gSVQgSlVTVCBBTFdBWVMgVVNFUyBUSEUgR0xPQkFMIFNFVFRJTkchXG4gICAqXG4gICAqICdzZWN1cml0eSBhcHBsaWVzIFsuLi5dIHNjaGVtZXMgZ2xvYmFsbHkgdG8gYWxsIEFQSSBvcGVyYXRpb25zLCB1bmxlc3Mgb3ZlcnJpZGRlbiBvbiB0aGUgb3BlcmF0aW9uIGxldmVsJ1xuICAgKiBAc2VlIGh0dHBzOi8vc3dhZ2dlci5pby9kb2NzL3NwZWNpZmljYXRpb24vYXV0aGVudGljYXRpb24vXG4gICAqL1xuICBwcm90ZWN0ZWQgcGF0Y2hTZWN1cml0eShzcGVjOiBPcGVuQVBJMykge1xuICAgIGlmICgnc2VjdXJpdHknIGluIHNwZWMpIHtcbiAgICAgIGZvciAoY29uc3Qgc3BlY1BhdGggb2YgT2JqZWN0LnZhbHVlcyhzcGVjLnBhdGhzIHx8IFtdKSkge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjUGF0aCkge1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLT4gVGhlcmUgaXMgYSB3cm9uZyBkZWZpbml0aW9uIGZvciBtZXRob2QgaW5jbHVkZXMhIEl0IGFsbG93cyBhbnkgdmFsdWUgdG8gYmUgZ2l2ZW4hXG4gICAgICAgICAgaWYgKCF0aGlzLmFwaU1ldGhvZHMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgICAgY29udGludWU7IC8vIFNraXAgaWYgbm90IGh0dHAgbWV0aG9kIGRlZmluaXRpb25cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzcGVjTWV0aG9kID0gKHNwZWNQYXRoIGFzIFBhdGhJdGVtT2JqZWN0KVtrZXkgYXMga2V5b2YgUGF0aEl0ZW1PYmplY3RdITtcbiAgICAgICAgICBpZiAoISgnc2VjdXJpdHknIGluIHNwZWNNZXRob2QpKSB7XG4gICAgICAgICAgICBzcGVjTWV0aG9kLnNlY3VyaXR5ID0gc3BlYy5zZWN1cml0eTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGRlbGV0ZSBzcGVjLnNlY3VyaXR5O1xuICAgIH1cbiAgfVxuXG59XG4iXX0=
|
|
590
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdC1hcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uc3RydWN0cy9yZXN0LWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw0Q0FBOEI7QUFDOUIsNkNBTXFCO0FBQ3JCLGlEQUFtQztBQUVuQyw4Q0FBZ0M7QUFHaEMseUNBQW1EO0FBQ25ELGlDQUF1RDtBQUN2RCwrQ0FBd0c7QUE4RHhHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVCRztBQUNILE1BQWEsT0FBb0IsU0FBUSxrQkFBTztJQXlDOUM7Ozs7OztPQU1HO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBVSxLQUF3QjtRQUN4RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUR3QixVQUFLLEdBQUwsS0FBSyxDQUFtQjtRQXBDMUU7OztXQUdHO1FBQ0ssZUFBVSxHQUE4QyxFQUFFLENBQUM7UUFFbEQsZUFBVSxHQUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFTM0Y7OztXQUdHO1FBQ0sseUJBQW9CLEdBQWdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFFdEQ7Ozs7O1dBS0c7UUFDSywrQkFBMEIsR0FBdUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQVlqRSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBYSxDQUFDO1FBRTNGLElBQUksZ0JBQThELENBQUM7UUFDbkUsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsZ0JBQWdCLEdBQUc7Z0JBQ2pCLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FB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QzlFLElBQUksQ0FBQyxDQUFDLFVBQVUsSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDO3dCQUNoQyxNQUFNLFdBQVcsR0FBSSxVQUE4QixDQUFDLFdBQVcsQ0FBQzt3QkFDaEUsSUFBSSxXQUFXLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDOzRCQUM5RCxzRUFBc0U7NEJBQ3RFLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxRQUFpQixDQUFDLENBQUM7NEJBQ3pFLFVBQVUsQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO3dCQUMzQixDQUFDOzZCQUFNLENBQUM7NEJBQ04sVUFBVSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDOzRCQUNwQyxJQUFJLFdBQVcsRUFBRSxDQUFDO2dDQUNoQixJQUFJLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsUUFBaUIsQ0FBQyxDQUFDOzRCQUMzRSxDQUFDO3dCQUNILENBQUM7b0JBQ0gsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLDhEQUE4RDt3QkFDOUQsTUFBTSxXQUFXLEdBQUksVUFBOEIsQ0FBQyxXQUFXLENBQUM7d0JBQ2hFLElBQUksV0FBVyxFQUFFLENBQUM7NEJBQ2hCLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBQyxRQUFpQixDQUFDLENBQUM7d0JBQ2pGLENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUN2QixDQUFDO0lBQ0gsQ0FBQztDQUVGO0FBN2tCRCwwQkE2a0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBhd3NfY2VydGlmaWNhdGVtYW5hZ2VyLFxuICBhd3NfaWFtLFxuICBhd3Nfcm91dGU1MyxcbiAgYXdzX3JvdXRlNTNfdGFyZ2V0cyxcbiAgYXdzX2FwaWdhdGV3YXksXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCAqIGFzIHlhbWwgZnJvbSAnanMteWFtbCc7XG5pbXBvcnQgeyBPcGVuQVBJMywgT3BlcmF0aW9uT2JqZWN0LCBQYXRoSXRlbU9iamVjdCB9IGZyb20gJ29wZW5hcGktdHlwZXNjcmlwdCc7XG5pbXBvcnQgeyBJQ29nbml0b0F1dGhlbnRpY2F0aW9uLCBJSnd0QXV0aGVudGljYXRpb24gfSBmcm9tICcuL2F1dGhlbnRpY2F0aW9uJztcbmltcG9ydCB7IEJhc2VBcGksIEJhc2VBcGlQcm9wcyB9IGZyb20gJy4vYmFzZS1hcGknO1xuaW1wb3J0IHsgTGFtYmRhRnVuY3Rpb24sIExhbWJkYU9wdGlvbnMgfSBmcm9tICcuL2Z1bmMnO1xuaW1wb3J0IHsgQ0ZOX09VVFBVVF9TVUZGSVhfUkVTVEFQSV9ET01BSU5OQU1FLCBDRk5fT1VUUFVUX1NVRkZJWF9SRVNUQVBJX1VSTCB9IGZyb20gJy4uL3NoYXJlZC9vdXRwdXRzJztcblxuZXhwb3J0IGludGVyZmFjZSBSZXN0QXBpUHJvcHM8T1BTPiBleHRlbmRzIEJhc2VBcGlQcm9wcyB7XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHJvdXRlcyBmb3IgYWxsIGVuZHBvaW50cyBjb25maWd1cmVkIGluIHRoZSBvcGVuYXBpLnlhbWwgZmlsZVxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICBhdXRvR2VuZXJhdGVSb3V0ZXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBjdXN0b20gb3B0aW9ucyBmb3IgdGhlIGNyZWF0ZWQgSHR0cEFwaVxuICAgKlxuICAgKiBAZGVmYXVsdCAtXG4gICAqL1xuICByZXN0QXBpUHJvcHM/OiBhd3NfYXBpZ2F0ZXdheS5SZXN0QXBpQmFzZVByb3BzO1xuXG4gIC8qKlxuICAgKiBhZGRpdGlvbmFsIG9wdGlvbnMgZm9yIHRoZSB1bmRlcmx5aW5nIExhbWJkYSBmdW5jdGlvbiBjb25zdHJ1Y3QgcGVyIG9wZXJhdGlvbklkXG4gICAqXG4gICAqIEBkZWZhdWx0IC1cbiAgICovXG4gIGxhbWJkYU9wdGlvbnNCeU9wZXJhdGlvbj86IHsgW29wZXJhdGlvbklkIGluIGtleW9mIE9QU10/OiBMYW1iZGFPcHRpb25zIH07XG5cbiAgZGVmaW5pdGlvbkZpbGVOYW1lOiBzdHJpbmc7XG5cbiAgY29yczogYm9vbGVhbjtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIG9wZXJhdGlvbiBJRHMgdGhhdCBzaG91bGQgc2tpcCB0aGUgYXV0aG9yaXplciBlbnRpcmVseS5cbiAgICogVGhlc2Ugb3BlcmF0aW9ucyB3aWxsIGhhdmUgYHNlY3VyaXR5OiBbXWAgaW4gdGhlIE9wZW5BUEkgc3BlYywgbWVhbmluZ1xuICAgKiB0aGV5IGFyZSBwdWJsaWNseSBhY2Nlc3NpYmxlIHdpdGhvdXQgYXV0aGVudGljYXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gYW5vbnltb3VzIG9wZXJhdGlvbnNcbiAgICovXG4gIGFub255bW91c09wZXJhdGlvbnM/OiAoa2V5b2YgT1BTKVtdO1xuXG4gIC8qKlxuICAgKiBDb250cm9scyB3aGV0aGVyIHRoZSBKV1QgTGFtYmRhIGF1dGhvcml6ZXIgdXNlcyB0aGUgVE9LRU4gb3IgUkVRVUVTVCB0eXBlLlxuICAgKlxuICAgKiAqKnRva2VuIChkZWZhdWx0KToqKiBUaGUgQVBJIEdhdGV3YXkgdmFsaWRhdGVzIHRoYXQgdGhlIEF1dGhvcml6YXRpb24gaGVhZGVyIGlzIHByZXNlbnRcbiAgICogYmVmb3JlIGludm9raW5nIHRoZSBMYW1iZGEgYXV0aG9yaXplci4gSWYgdGhlIGhlYWRlciBpcyBtaXNzaW5nLCBBUEkgR2F0ZXdheSBpbW1lZGlhdGVseVxuICAgKiByZXR1cm5zIDQwMSB3aXRob3V0IGludm9raW5nIHRoZSBMYW1iZGEuIFRoaXMgaXMgY2hlYXBlciBmb3IgdW5hdXRoZW50aWNhdGVkIHJlcXVlc3RzXG4gICAqIGJlY2F1c2Ugbm8gTGFtYmRhIGludm9jYXRpb24gb2NjdXJzLCBidXQgaXQgZG9lcyBub3Qgc3VwcG9ydCBvcHRpb25hbCBhdXRoZW50aWNhdGlvblxuICAgKiAoZXZlcnkgcmVxdWVzdCBtdXN0IGNhcnJ5IGEgdG9rZW4gb3IgYmUgcmVqZWN0ZWQpLlxuICAgKlxuICAgKiAqKnJlcXVlc3Q6KiogVGhlIEFQSSBHYXRld2F5IGFsd2F5cyBpbnZva2VzIHRoZSBMYW1iZGEgYXV0aG9yaXplciByZWdhcmRsZXNzIG9mIHdoZXRoZXJcbiAgICogdGhlIEF1dGhvcml6YXRpb24gaGVhZGVyIGlzIHByZXNlbnQuIFRoaXMgZW5hYmxlcyBvcHRpb25hbCBhdXRoZW50aWNhdGlvbjogdGhlIExhbWJkYVxuICAgKiBjYW4gaW5zcGVjdCB0aGUgcmVxdWVzdCwgcmV0dXJuIEFsbG93IHdpdGggYW4gYW5vbnltb3VzIHByaW5jaXBhbCB3aGVuIG5vIHRva2VuIGlzXG4gICAqIHByb3ZpZGVkLCBhbmQgcmV0dXJuIEFsbG93IHdpdGggdXNlciBjbGFpbXMgd2hlbiBhIHZhbGlkIHRva2VuIGlzIHByZXNlbnQuIFRoZSB0cmFkZS1vZmZcbiAgICogaXMgdGhhdCB5b3UgcGF5IGZvciBhIExhbWJkYSBpbnZvY2F0aW9uIG9uIGV2ZXJ5IHJlcXVlc3QsIGluY2x1ZGluZyB1bmF1dGhlbnRpY2F0ZWQgb25lcy5cbiAgICpcbiAgICogVXNlICdyZXF1ZXN0JyB3aGVuIHlvdSBuZWVkIGVuZHBvaW50cyB0aGF0IGJlaGF2ZSBkaWZmZXJlbnRseSBmb3IgYXV0aGVudGljYXRlZCB2c1xuICAgKiBhbm9ueW1vdXMgdXNlcnMgKGUuZy4sIHBlcnNvbmFsaXplZCByZXNwb25zZXMgZm9yIGxvZ2dlZC1pbiB1c2VycywgZ2VuZXJpYyByZXNwb25zZXNcbiAgICogZm9yIGd1ZXN0cykgd2l0aG91dCBzcGxpdHRpbmcgdGhlbSBpbnRvIHNlcGFyYXRlIG9wZXJhdGlvbnMuXG4gICAqXG4gICAqIEBkZWZhdWx0ICd0b2tlbidcbiAgICovXG4gIGp3dEF1dGhvcml6ZXJUeXBlPzogJ3Rva2VuJyB8ICdyZXF1ZXN0Jztcbn1cblxuLyoqXG4gKiBUaGUgUmVzdEFwaSBjb25zdHJ1Y3Qgc2V0cyB1cCBhbiBBV1MgQVBJIEdhdGV3YXkgUkVTVCBBUEkgdXNpbmcgT3BlbkFQSSBzcGVjaWZpY2F0aW9uLlxuICogVGhpcyBjb25zdHJ1Y3QgZmFjaWxpdGF0ZXMgdGhlIGNyZWF0aW9uIG9mIGEgUkVTVCBBUEkgd2l0aCB2YXJpb3VzIGNvbmZpZ3VyYXRpb25zLCBpbmNsdWRpbmcgY3VzdG9tIGRvbWFpbiwgQ09SUyBzdXBwb3J0LCBhbmQgaW50ZWdyYXRpb24gd2l0aCBMYW1iZGEgZnVuY3Rpb25zLlxuICogSXQgYWxsb3dzIGF1dG8tZ2VuZXJhdGluZyByb3V0ZXMgYmFzZWQgb24gdGhlIHByb3ZpZGVkIE9wZW5BUEkgZGVmaW5pdGlvbiBhbmQgcHJvdmlkZXMgbWV0aG9kcyB0byBkeW5hbWljYWxseSBhZGQgY3VzdG9tIHJvdXRlcyBhbmQgbWFuYWdlIExhbWJkYSBmdW5jdGlvbiBpbnRlZ3JhdGlvbnMuXG4gKlxuICogQHRlbXBsYXRlIFBBVEhTIC0gVGhlIHR5cGUgZGVmaW5pdGlvbiBmb3IgdGhlIEFQSSBwYXRocy5cbiAqIEB0ZW1wbGF0ZSBPUFMgLSBUaGUgdHlwZSBkZWZpbml0aW9uIGZvciB0aGUgQVBJIG9wZXJhdGlvbnMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGFwaSA9IG5ldyBSZXN0QXBpKHRoaXMsICdNeVJlc3RBcGknLCB7XG4gKiAgIGFwaU5hbWU6ICdNeUFQSScsXG4gKiAgIHN0YWdlTmFtZTogJ2RldicsXG4gKiAgIGRlZmluaXRpb25GaWxlTmFtZTogJ29wZW5hcGkueWFtbCcsXG4gKiAgIGF1dGhlbnRpY2F0aW9uOiBteUNvZ25pdG9BdXRoLFxuICogICBzaW5nbGVUYWJsZURhdGFzdG9yZTogbXlEeW5hbW9EQlRhYmxlLFxuICogICBhdXRvR2VuZXJhdGVSb3V0ZXM6IHRydWUsXG4gKiB9KTtcbiAqXG4gKiAvLyBBZGQgYSBjdXN0b20gUkVTVCByZXNvdXJjZVxuICogYXBpLmFkZFJlc3RSZXNvdXJjZSgnL2l0ZW1zJywgJ2dldCcpO1xuICpcbiAqIC8vIEdldCB0aGUgTGFtYmRhIGZ1bmN0aW9uIGZvciBhIHNwZWNpZmljIG9wZXJhdGlvblxuICogY29uc3QgbGFtYmRhRnVuY3Rpb24gPSBhcGkuZ2V0RnVuY3Rpb25Gb3JPcGVyYXRpb24oJ2dldEl0ZW1zJyk7XG4gKi9cbmV4cG9ydCBjbGFzcyBSZXN0QXBpPFBBVEhTLCBPUFM+IGV4dGVuZHMgQmFzZUFwaSB7XG5cbiAgLyoqXG4gICAqIFRoZSBBV1MgQVBJIEdhdGV3YXkgUkVTVCBBUEkgaW5zdGFuY2UuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYXBpOiBhd3NfYXBpZ2F0ZXdheS5TcGVjUmVzdEFwaTtcblxuICAvKipcbiAgICogVGhlIE9wZW5BUEkgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIFJFU1QgQVBJLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFwaVNwZWM6IE9wZW5BUEkzO1xuXG4gIC8qKlxuICAgKiBBIGNvbGxlY3Rpb24gb2YgTGFtYmRhIGZ1bmN0aW9ucyB1c2VkIGFzIGludGVncmF0aW9ucyBmb3IgdGhlIEFQSSBvcGVyYXRpb25zLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfZnVuY3Rpb25zOiB7IFtvcGVyYXRpb25JZDogc3RyaW5nXTogTGFtYmRhRnVuY3Rpb24gfSA9IHt9O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgYXBpTWV0aG9kcyA9IFsnZ2V0JywgJ3Bvc3QnLCAncHV0JywgJ2RlbGV0ZScsICdwYXRjaCcsICdvcHRpb25zJywgJ2hlYWQnXTtcblxuICAvKipcbiAgICogVGhlIEpXVCBhdXRob3JpemVyIExhbWJkYSBmdW5jdGlvbiwgaWYgSldUIGF1dGhlbnRpY2F0aW9uIGlzIGNvbmZpZ3VyZWQuXG4gICAqIFN0b3JlZCBzbyB0aGUgaW52b2tlIHBlcm1pc3Npb24gY2FuIGJlIGdyYW50ZWQgYWZ0ZXIgdGhlIFNwZWNSZXN0QXBpIGlzIGNyZWF0ZWQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIF9hdXRob3JpemVyRm4/OiBMYW1iZGFGdW5jdGlvbjtcblxuICAvKipcbiAgICogU2V0IG9mIG9wZXJhdGlvbklkcyB0aGF0IHNob3VsZCBoYXZlIHNlY3VyaXR5IGRpc2FibGVkIChzZWN1cml0eTogW10pLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfYW5vbnltb3VzT3BlcmF0aW9uczogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG5cbiAgLyoqXG4gICAqIFN0b3JlcyB0aGUgb3JpZ2luYWwgcGVyLW9wZXJhdGlvbiBzZWN1cml0eSBhcnJheXMgYXMgYXNzaWduZWQgYnkgcGF0Y2hTZWN1cml0eSxcbiAgICoga2V5ZWQgYnkgb3BlcmF0aW9uSWQuIFVzZWQgYnkgc2V0QW5vbnltb3VzT3BlcmF0aW9ucyB0byByZXN0b3JlIHNlY3VyaXR5IG9uXG4gICAqIG9wZXJhdGlvbnMgcmVtb3ZlZCBmcm9tIHRoZSBhbm9ueW1vdXMgc2V0LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfb3JpZ2luYWxPcGVyYXRpb25TZWN1cml0eTogTWFwPHN0cmluZywgYW55W10+ID0gbmV3IE1hcCgpO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFJlc3RBcGkuXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSAtIFRoZSBzY29wZSBpbiB3aGljaCB0aGlzIGNvbnN0cnVjdCBpcyBkZWZpbmVkLlxuICAgKiBAcGFyYW0gaWQgLSBUaGUgc2NvcGVkIGNvbnN0cnVjdCBJRC5cbiAgICogQHBhcmFtIHByb3BzIC0gVGhlIHByb3BlcnRpZXMgb2YgdGhlIFJlc3RBcGkgY29uc3RydWN0LlxuICAgKi9cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJpdmF0ZSBwcm9wczogUmVzdEFwaVByb3BzPE9QUz4pIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcblxuICAgIHRoaXMuYXBpU3BlYyA9IHlhbWwubG9hZChmcy5yZWFkRmlsZVN5bmMocHJvcHMuZGVmaW5pdGlvbkZpbGVOYW1lKS50b1N0cmluZygpKSBhcyBPcGVuQVBJMztcblxuICAgIGxldCBjdXN0b21Eb21haW5OYW1lOiBhd3NfYXBpZ2F0ZXdheS5Eb21haW5OYW1lT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICBpZiAodGhpcy5hcGlGUUROKSB7XG4gICAgICBjdXN0b21Eb21haW5OYW1lID0ge1xuICAgICAgICBkb21haW5OYW1lOiB0aGlzLmFwaUZRRE4sXG4gICAgICAgIGNlcnRpZmljYXRlOiBuZXcgYXdzX2NlcnRpZmljYXRlbWFuYWdlci5DZXJ0aWZpY2F0ZSh0aGlzLCAnQ2VydCcsIHtcbiAgICAgICAgICBkb21haW5OYW1lOiB0aGlzLmFwaUZRRE4sXG4gICAgICAgICAgdmFsaWRhdGlvbjogYXdzX2NlcnRpZmljYXRlbWFuYWdlci5DZXJ0aWZpY2F0ZVZhbGlkYXRpb24uZnJvbURucyh0aGlzLmhvc3RlZFpvbmUpLFxuICAgICAgICB9KSxcbiAgICAgIH07XG4gICAgICBuZXcgY2RrLkNmbk91dHB1dCh0aGlzLCAnUmVzdEFwaURvbWFpbk5hbWUnLCB7XG4gICAgICAgIGtleTogYCR7dGhpcy5wcm9wcy5hcGlOYW1lfSR7Q0ZOX09VVFBVVF9TVUZGSVhfUkVTVEFQSV9ET01BSU5OQU1FfWAsXG4gICAgICAgIHZhbHVlOiB0aGlzLmFwaUZRRE4sXG4gICAgICB9KTtcbiAgICAgIG5ldyBjZGsuQ2ZuT3V0cHV0KHRoaXMsICdSZXN0QXBpVXJsT3V0cHV0Jywge1xuICAgICAgICBrZXk6IGAke3RoaXMucHJvcHMuYXBpTmFtZX0ke0NGTl9PVVRQVVRfU1VGRklYX1JFU1RBUElfVVJMfWAsXG4gICAgICAgIHZhbHVlOiAnaHR0cHM6Ly8nICsgdGhpcy5hcGlGUUROLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gaWYgKChwcm9wcy5tb25pdG9yaW5nID8/IHRydWUpICYmIHRoaXMubW9uaXRvcmluZykge1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmFwaUVycm9yc1dpZGdldC5hZGRMZWZ0TWV0cmljKHRoaXMuYXBpLm1ldHJpY1NlcnZlckVycm9yKHtcbiAgICAvLyAgICAgc3RhdGlzdGljOiAnc3VtJyxcbiAgICAvLyAgIH0pKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlFcnJvcnNXaWRnZXQuYWRkTGVmdE1ldHJpYyh0aGlzLmFwaS5tZXRyaWNDbGllbnRFcnJvcih7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ3N1bScsXG4gICAgLy8gICB9KSk7XG5cbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlMYXRlbmN5V2lkZ2V0LmFkZExlZnRNZXRyaWModGhpcy5hcGkubWV0cmljTGF0ZW5jeSh7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ0F2ZXJhZ2UnLFxuICAgIC8vICAgfSkpO1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmFwaUxhdGVuY3lXaWRnZXQuYWRkTGVmdE1ldHJpYyh0aGlzLmFwaS5tZXRyaWNMYXRlbmN5KHtcbiAgICAvLyAgICAgc3RhdGlzdGljOiAncDkwJyxcbiAgICAvLyAgIH0pKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlMYXRlbmN5VGFpbFdpZGdldC5hZGRMZWZ0TWV0cmljKHRoaXMuYXBpLm1ldHJpY0xhdGVuY3koe1xuICAgIC8vICAgICBzdGF0aXN0aWM6ICdwOTUnLFxuICAgIC8vICAgfSkpO1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmFwaUxhdGVuY3lUYWlsV2lkZ2V0LmFkZExlZnRNZXRyaWModGhpcy5hcGkubWV0cmljTGF0ZW5jeSh7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ3A5OScsXG4gICAgLy8gICB9KSk7XG4gICAgLy8gfVxuXG4gICAgaWYgKHByb3BzLmF1dG9HZW5lcmF0ZVJvdXRlcyA/PyB0cnVlKSB7XG4gICAgICBmb3IgKGNvbnN0IHBhdGggaW4gdGhpcy5hcGlTcGVjLnBhdGhzKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hcGlTcGVjLnBhdGhzLCBwYXRoKSkge1xuICAgICAgICAgIGNvbnN0IHBhdGhJdGVtID0gdGhpcy5hcGlTcGVjLnBhdGhzW3BhdGhdO1xuICAgICAgICAgIGZvciAoY29uc3QgbWV0aG9kIGluIHBhdGhJdGVtKSB7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhdGhJdGVtLCBtZXRob2QpICYmXG4gICAgICAgICAgICAgIFsnZ2V0JywgJ3Bvc3QnLCAncHV0JywgJ2RlbGV0ZScsICdwYXRjaCcsICdvcHRpb25zJywgJ2hlYWQnXS5pbmRleE9mKG1ldGhvZCkgPj0gMCkge1xuICAgICAgICAgICAgICAvLyBBZGQgYWxsIG9wZXJhdGlvbnNcbiAgICAgICAgICAgICAgdGhpcy5hZGRSZXN0UmVzb3VyY2UocGF0aCBhcyBhbnksIG1ldGhvZCBhcyBhbnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFkZCBfc3BlYyBFbmRwb2ludFxuICAgIHRoaXMuYXBpU3BlYy5wYXRocyFbJy9vcGVuYXBpLmpzb24nXSA9IHtcbiAgICAgIGdldDoge1xuICAgICAgICAnc3VtbWFyeSc6ICdSZXR1cm5zIHRoZSByYXcgT3BlbkFQSSBzcGVjIG9mIHRoaXMgQVBJJyxcbiAgICAgICAgJ2Rlc2NyaXB0aW9uJzogJ1JldHVybnMgdGhlIHJhdyBPcGVuQVBJIHNwZWMgb2YgdGhpcyBBUEknLFxuICAgICAgICAnb3BlcmF0aW9uSWQnOiAnX3NwZWMnLFxuICAgICAgICAncmVzcG9uc2VzJzoge1xuICAgICAgICAgIDIwMDoge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246ICdPcGVuQVBJIHNwZWMgb2YgdGhpcyBBUEknLFxuICAgICAgICAgICAgY29udGVudDoge1xuICAgICAgICAgICAgICAnYXBwbGljYXRpb24vb3BlbmFwaStqc29uJzoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIC8vIEB0cy1pZ25vcmUgQ3VzdG9tIHByb3BlcnR5IGZvciBBV1NcbiAgICAgICAgJ3gtYW1hem9uLWFwaWdhdGV3YXktaW50ZWdyYXRpb24nOiB7XG4gICAgICAgICAgdHlwZTogJ21vY2snLFxuICAgICAgICAgIGh0dHBNZXRob2Q6ICdHRVQnLFxuICAgICAgICAgIHBheWxvYWRGb3JtYXRWZXJzaW9uOiAnMS4wJyxcbiAgICAgICAgICByZXF1ZXN0VGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAnYXBwbGljYXRpb24vanNvbic6ICd7XFwnc3RhdHVzQ29kZVxcJzogMjAwfScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXNwb25zZXM6IHtcbiAgICAgICAgICAgIDIwMDoge1xuICAgICAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgICAgIHJlc3BvbnNlVGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAgICAgJ2FwcGxpY2F0aW9uL29wZW5hcGkranNvbic6IEpTT04uc3RyaW5naWZ5KHRoaXMuY2xlYW51cFNwZWMoSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSgodGhpcy5hcGlTcGVjKSkpKSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBpZiAocHJvcHMuY29ycykge1xuICAgICAgdGhpcy5hcGlTcGVjLnBhdGhzIVsnL3twcm94eSt9J10gPSB7XG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAnc3VtbWFyeSc6ICdDT1JTIHN1cHBvcnQnLFxuICAgICAgICAgICdkZXNjcmlwdGlvbic6ICdFbmFibGUgQ09SUyBieSByZXR1cm5pbmcgY29ycmVjdCBoZWFkZXJzJyxcbiAgICAgICAgICAndGFncyc6IFsnQ09SUyddLFxuICAgICAgICAgICdyZXNwb25zZXMnOiB7XG4gICAgICAgICAgICAyMDA6IHtcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdEZWZhdWx0IHJlc3BvbnNlIGZvciBDT1JTIG1ldGhvZCcsXG4gICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJzogeyBzY2hlbWE6IHsgdHlwZTogJ3N0cmluZycgfSB9LFxuICAgICAgICAgICAgICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogeyBzY2hlbWE6IHsgdHlwZTogJ3N0cmluZycgfSB9LFxuICAgICAgICAgICAgICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyc6IHsgc2NoZW1hOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICAgICAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyc6IHsgc2NoZW1hOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgY29udGVudDoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgJ3gtYW1hem9uLWFwaWdhdGV3YXktaW50ZWdyYXRpb24nOiB7XG4gICAgICAgICAgICB0eXBlOiAnbW9jaycsXG4gICAgICAgICAgICByZXF1ZXN0VGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAgICdhcHBsaWNhdGlvbi9qc29uJzogJyNzZXQoJGNvbnRleHQucmVxdWVzdE92ZXJyaWRlLmhlYWRlci5vcmlnaW4gPSAkbWV0aG9kLnJlcXVlc3QuaGVhZGVyLm9yaWdpbilcXG57XFxuICBcInN0YXR1c0NvZGVcIiA6IDIwMFxcbn1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlc3BvbnNlczoge1xuICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgc3RhdHVzQ29kZTogJzIwMCcsXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzJzogXCInQ29udGVudC1UeXBlLFgtQW16LURhdGUsQXV0aG9yaXphdGlvbixYLUFwaS1LZXknXCIsXG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyc6IFwiJ3RydWUnXCIsXG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogXCInUFVULEdFVCxQT1NULERFTEVURSxQQVRDSCxIRUFELE9QVElPTlMnXCIsXG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nOiAnY29udGV4dC5yZXF1ZXN0T3ZlcnJpZGUuaGVhZGVyLm9yaWdpbicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZXNwb25zZVRlbXBsYXRlczoge1xuICAgICAgICAgICAgICAgICAgJ2FwcGxpY2F0aW9uL2pzb24nOiAne30nLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMucGF0Y2hTZWN1cml0eVNjaGVtZXModGhpcy5hcGlTcGVjKTtcblxuICAgIC8vIEluaXRpYWxpemUgYW5vbnltb3VzIG9wZXJhdGlvbnMgZnJvbSBwcm9wcyBiZWZvcmUgcGF0Y2hTZWN1cml0eSBkaXN0cmlidXRlcyBzZWN1cml0eVxuICAgIGlmIChwcm9wcy5hbm9ueW1vdXNPcGVyYXRpb25zKSB7XG4gICAgICBmb3IgKGNvbnN0IG9wSWQgb2YgcHJvcHMuYW5vbnltb3VzT3BlcmF0aW9ucykge1xuICAgICAgICB0aGlzLl9hbm9ueW1vdXNPcGVyYXRpb25zLmFkZChvcElkIGFzIHN0cmluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5wYXRjaFNlY3VyaXR5KHRoaXMuYXBpU3BlYyk7XG5cbiAgICAvLyBUT0RPIHBhdGNoIHNwZWMgZm9yIENvZ25pdG8gdXNlciBwb29sXG5cbiAgICB0aGlzLmFwaSA9IG5ldyBhd3NfYXBpZ2F0ZXdheS5TcGVjUmVzdEFwaSh0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICByZXN0QXBpTmFtZTogYCR7cHJvcHMuYXBpTmFtZX0gWyR7cHJvcHMuc3RhZ2VOYW1lfV1gLFxuICAgICAgZG9tYWluTmFtZTogY3VzdG9tRG9tYWluTmFtZSxcbiAgICAgIGFwaURlZmluaXRpb246IGF3c19hcGlnYXRld2F5LkFwaURlZmluaXRpb24uZnJvbUlubGluZSh0aGlzLmFwaVNwZWMpLFxuICAgICAgLi4ucHJvcHMucmVzdEFwaVByb3BzLFxuICAgIH0pO1xuXG4gICAgLy8gYWRkIGludm9rZSBwZXJtaXNzaW9ucyB0byBMYW1iZGEgZnVuY3Rpb25zXG4gICAgZm9yIChjb25zdCBmbiBvZiBPYmplY3QudmFsdWVzKHRoaXMuX2Z1bmN0aW9ucykpIHtcbiAgICAgIGZuLmFkZFBlcm1pc3Npb24oJ1Jlc3RBcGlJbnZva2UnLCB7XG4gICAgICAgIHByaW5jaXBhbDogbmV3IGF3c19pYW0uU2VydmljZVByaW5jaXBhbCgnYXBpZ2F0ZXdheS5hbWF6b25hd3MuY29tJyksXG4gICAgICAgIGFjdGlvbjogJ2xhbWJkYTpJbnZva2VGdW5jdGlvbicsXG4gICAgICAgIHNvdXJjZUFybjogdGhpcy5hcGkuYXJuRm9yRXhlY3V0ZUFwaSgpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gR3JhbnQgQVBJIEdhdGV3YXkgcGVybWlzc2lvbiB0byBpbnZva2UgdGhlIEpXVCBhdXRob3JpemVyIExhbWJkYVxuICAgIGlmICh0aGlzLl9hdXRob3JpemVyRm4pIHtcbiAgICAgIHRoaXMuX2F1dGhvcml6ZXJGbi5hZGRQZXJtaXNzaW9uKCdBcGlHYXRld2F5QXV0aG9yaXplckludm9rZScsIHtcbiAgICAgICAgcHJpbmNpcGFsOiBuZXcgYXdzX2lhbS5TZXJ2aWNlUHJpbmNpcGFsKCdhcGlnYXRld2F5LmFtYXpvbmF3cy5jb20nKSxcbiAgICAgICAgYWN0aW9uOiAnbGFtYmRhOkludm9rZUZ1bmN0aW9uJyxcbiAgICAgICAgc291cmNlQXJuOiB0aGlzLmFwaS5hcm5Gb3JFeGVjdXRlQXBpKCksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoY3VzdG9tRG9tYWluTmFtZSAmJiB0aGlzLmFwaS5kb21haW5OYW1lKSB7XG4gICAgICBuZXcgYXdzX3JvdXRlNTMuQVJlY29yZCh0aGlzLCAnRG5zUmVjb3JkJywge1xuICAgICAgICB6b25lOiB0aGlzLmhvc3RlZFpvbmUhLFxuICAgICAgICByZWNvcmROYW1lOiBjdXN0b21Eb21haW5OYW1lLmRvbWFpbk5hbWUsXG4gICAgICAgIHRhcmdldDogYXdzX3JvdXRlNTMuUmVjb3JkVGFyZ2V0LmZyb21BbGlhcyhcbiAgICAgICAgICBuZXcgYXdzX3JvdXRlNTNfdGFyZ2V0cy5BcGlHYXRld2F5RG9tYWluKHRoaXMuYXBpLmRvbWFpbk5hbWUpLFxuICAgICAgICApLFxuICAgICAgfSk7XG4gICAgfVxuXG4gIH1cblxuICBwcm90ZWN0ZWQgY2xlYW51cFNwZWMoc3BlYzogeyBba2V5OiBzdHJpbmddOiBhbnkgfSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0ge1xuICAgIE9iamVjdC5lbnRyaWVzKHNwZWMpLmZvckVhY2goKFtwcm9wLCB2YWx1ZV06IFtzdHJpbmcsIGFueV0pID0+IHtcbiAgICAgIGlmIChwcm9wLnN0YXJ0c1dpdGgoJ3gtJykpIHtcbiAgICAgICAgZGVsZXRlIHNwZWNbcHJvcF07XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhpcy5jbGVhbnVwU3BlYyhzcGVjW3Byb3BdKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBzcGVjO1xuICB9XG5cbiAgLyoqXG4gICAqIHJldHVybiB0aGUgZ2VuZXJhdGVkIExhbWJkYSBmdW5jdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBBUEkgb3BlcmF0aW9uXG4gICAqL1xuICBwdWJsaWMgZ2V0RnVuY3Rpb25Gb3JPcGVyYXRpb24ob3BlcmF0aW9uSWQ6IGtleW9mIE9QUyk6IExhbWJkYUZ1bmN0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5fZnVuY3Rpb25zW29wZXJhdGlvbklkIGFzIHN0cmluZ107XG4gIH1cblxuICAvKipcbiAgICogcmV0dXJuIGEgbGlzdCBvZiBhbGwgZ2VuZXJhdGVkIExhbWJkYSBmdW5jdGlvbnNcbiAgICovXG4gIHB1YmxpYyBnZXRGdW5jdGlvbnMoKTogTGFtYmRhRnVuY3Rpb25bXSB7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5fZnVuY3Rpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWaXNpdG9yIG1ldGhvZCB0byBtb2RpZnkgdGhlIGdpdmVuIGZ1bmN0aW9uc1xuICAgKlxuICAgKiBAcGFyYW0gb3BlcmF0aW9uSWRzIHRoZSBsaXN0IG9mIGZ1bmN0aW9ucyB0byB2aXNpdFxuICAgKiBAcGFyYW0gb3AgdGhlIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGV2ZXJ5IGZ1bmN0aW9uXG4gICAqL1xuICBwdWJsaWMgbW9kaWZ5T3BlcmF0aW9uRnVuY3Rpb25zKG9wZXJhdGlvbklkczogKGtleW9mIE9QUylbXSwgb3A6IChmbjogTGFtYmRhRnVuY3Rpb24pID0+IHZvaWQpIHtcbiAgICBmb3IgKGNvbnN0IG9wZXJhdGlvbklkIG9mIG9wZXJhdGlvbklkcykge1xuICAgICAgb3AodGhpcy5nZXRGdW5jdGlvbkZvck9wZXJhdGlvbihvcGVyYXRpb25JZCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlIHRoZSBmdWxsIHNldCBvZiBhbm9ueW1vdXMgb3BlcmF0aW9ucy5cbiAgICogQW5vbnltb3VzIG9wZXJhdGlvbnMgd2lsbCBoYXZlIGBzZWN1cml0eTogW11gIGFwcGxpZWQgaW4gdGhlIE9wZW5BUEkgc3BlYyxcbiAgICogbWFraW5nIHRoZW0gcHVibGljbHkgYWNjZXNzaWJsZSB3aXRob3V0IGF1dGhlbnRpY2F0aW9uLlxuICAgKlxuICAgKiBTaW5jZSBDREsgc2VyaWFsaXplcyB0aGUgT3BlbkFQSSBzcGVjIGF0IHN5bnRoIHRpbWUgKGZyb21JbmxpbmUgc3RvcmVzIHRoZVxuICAgKiBvYmplY3QgcmVmZXJlbmNlKSwgbXV0YXRpb25zIGFmdGVyIFNwZWNSZXN0QXBpIGNvbnN0cnVjdGlvbiBzdGlsbCB0YWtlIGVmZmVjdC5cbiAgICpcbiAgICogQHBhcmFtIG9wZXJhdGlvbklkcyAtIFRoZSBvcGVyYXRpb24gSURzIHRvIG1hcmsgYXMgYW5vbnltb3VzLiBSZXBsYWNlcyBhbnkgcHJldmlvdXNseSBzZXQgYW5vbnltb3VzIG9wZXJhdGlvbnMuXG4gICAqL1xuICBwdWJsaWMgc2V0QW5vbnltb3VzT3BlcmF0aW9ucyhvcGVyYXRpb25JZHM6IChrZXlvZiBPUFMpW10pIHtcbiAgICB0aGlzLl9hbm9ueW1vdXNPcGVyYXRpb25zLmNsZWFyKCk7XG4gICAgZm9yIChjb25zdCBvcElkIG9mIG9wZXJhdGlvbklkcykge1xuICAgICAgdGhpcy5fYW5vbnltb3VzT3BlcmF0aW9ucy5hZGQob3BJZCBhcyBzdHJpbmcpO1xuICAgIH1cbiAgICB0aGlzLmFwcGx5QW5vbnltb3VzU2VjdXJpdHkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYWRkaXRpb25hbCBvcGVyYXRpb25zIHRvIHRoZSBzZXQgb2YgYW5vbnltb3VzIG9wZXJhdGlvbnMuXG4gICAqIE5ld2x5IGFkZGVkIG9wZXJhdGlvbnMgd2lsbCBoYXZlIGBzZWN1cml0eTogW11gIGFwcGxpZWQgaW4gdGhlIE9wZW5BUEkgc3BlYy5cbiAgICpcbiAgICogU2luY2UgQ0RLIHNlcmlhbGl6ZXMgdGhlIE9wZW5BUEkgc3BlYyBhdCBzeW50aCB0aW1lIChmcm9tSW5saW5lIHN0b3JlcyB0aGVcbiAgICogb2JqZWN0IHJlZmVyZW5jZSksIG11dGF0aW9ucyBhZnRlciBTcGVjUmVzdEFwaSBjb25zdHJ1Y3Rpb24gc3RpbGwgdGFrZSBlZmZlY3QuXG4gICAqXG4gICAqIEBwYXJhbSBvcGVyYXRpb25JZHMgLSBUaGUgb3BlcmF0aW9uIElEcyB0byBhZGQgdG8gdGhlIGFub255bW91cyBzZXQuXG4gICAqL1xuICBwdWJsaWMgYWRkQW5vbnltb3VzT3BlcmF0aW9ucyhvcGVyYXRpb25JZHM6IChrZXlvZiBPUFMpW10pIHtcbiAgICBmb3IgKGNvbnN0IG9wSWQgb2Ygb3BlcmF0aW9uSWRzKSB7XG4gICAgICB0aGlzLl9hbm9ueW1vdXNPcGVyYXRpb25zLmFkZChvcElkIGFzIHN0cmluZyk7XG4gICAgfVxuICAgIHRoaXMuYXBwbHlBbm9ueW1vdXNTZWN1cml0eUZvck9wcyhvcGVyYXRpb25JZHMubWFwKG9wID0+IG9wIGFzIHN0cmluZykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlLWFwcGxpZXMgc2VjdXJpdHkgc2V0dGluZ3MgdG8gYWxsIG9wZXJhdGlvbnMgYmFzZWQgb24gdGhlIGN1cnJlbnQgYW5vbnltb3VzIHNldC5cbiAgICogT3BlcmF0aW9ucyBpbiB0aGUgYW5vbnltb3VzIHNldCBnZXQgYHNlY3VyaXR5OiBbXWA7IG9wZXJhdGlvbnMgcmVtb3ZlZCBmcm9tIHRoZSBzZXRcbiAgICogaGF2ZSB0aGVpciBvcmlnaW5hbCBzZWN1cml0eSByZXN0b3JlZC5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgYXBwbHlBbm9ueW1vdXNTZWN1cml0eSgpIHtcbiAgICBmb3IgKGNvbnN0IHNwZWNQYXRoIG9mIE9iamVjdC52YWx1ZXModGhpcy5hcGlTcGVjLnBhdGhzIHx8IFtdKSkge1xuICAgICAgZm9yIChjb25zdCBrZXkgaW4gc3BlY1BhdGgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmFwaU1ldGhvZHMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNwZWNNZXRob2QgPSAoc3BlY1BhdGggYXMgUGF0aEl0ZW1PYmplY3QpW2tleSBhcyBrZXlvZiBQYXRoSXRlbU9iamVjdF0hIGFzIE9wZXJhdGlvbk9iamVjdDtcbiAgICAgICAgaWYgKHNwZWNNZXRob2Qub3BlcmF0aW9uSWQgJiYgdGhpcy5fYW5vbnltb3VzT3BlcmF0aW9ucy5oYXMoc3BlY01ldGhvZC5vcGVyYXRpb25JZCkpIHtcbiAgICAgICAgICBzcGVjTWV0aG9kLnNlY3VyaXR5ID0gW107XG4gICAgICAgIH0gZWxzZSBpZiAoc3BlY01ldGhvZC5vcGVyYXRpb25JZCAmJiB0aGlzLl9vcmlnaW5hbE9wZXJhdGlvblNlY3VyaXR5LmhhcyhzcGVjTWV0aG9kLm9wZXJhdGlvbklkKSkge1xuICAgICAgICAgIC8vIFJlc3RvcmUgb3JpZ2luYWwgc2VjdXJpdHkgZm9yIG9wZXJhdGlvbnMgcmVtb3ZlZCBmcm9tIHRoZSBhbm9ueW1vdXMgc2V0XG4gICAgICAgICAgc3BlY01ldGhvZC5zZWN1cml0eSA9IHRoaXMuX29yaWdpbmFsT3BlcmF0aW9uU2VjdXJpdHkuZ2V0KHNwZWNNZXRob2Qub3BlcmF0aW9uSWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgYHNlY3VyaXR5OiBbXWAgb25seSB0byB0aGUgc3BlY2lmaWVkIG9wZXJhdGlvbnMuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGFwcGx5QW5vbnltb3VzU2VjdXJpdHlGb3JPcHMob3BlcmF0aW9uSWRzOiBzdHJpbmdbXSkge1xuICAgIGNvbnN0IG9wc1NldCA9IG5ldyBTZXQob3BlcmF0aW9uSWRzKTtcbiAgICBmb3IgKGNvbnN0IHNwZWNQYXRoIG9mIE9iamVjdC52YWx1ZXModGhpcy5hcGlTcGVjLnBhdGhzIHx8IFtdKSkge1xuICAgICAgZm9yIChjb25zdCBrZXkgaW4gc3BlY1BhdGgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmFwaU1ldGhvZHMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNwZWNNZXRob2QgPSAoc3BlY1BhdGggYXMgUGF0aEl0ZW1PYmplY3QpW2tleSBhcyBrZXlvZiBQYXRoSXRlbU9iamVjdF0hIGFzIE9wZXJhdGlvbk9iamVjdDtcbiAgICAgICAgaWYgKHNwZWNNZXRob2Qub3BlcmF0aW9uSWQgJiYgb3BzU2V0LmhhcyhzcGVjTWV0aG9kLm9wZXJhdGlvbklkKSkge1xuICAgICAgICAgIHNwZWNNZXRob2Quc2VjdXJpdHkgPSBbXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhZGRSZXN0UmVzb3VyY2U8UCBleHRlbmRzIGtleW9mIFBBVEhTPihwYXRoOiBQLCBtZXRob2Q6IGtleW9mIFBBVEhTW1BdKSB7XG4gICAgY29uc3Qgb2FQYXRoID0gdGhpcy5hcGlTcGVjLnBhdGhzIVtwYXRoIGFzIHN0cmluZ10gYXMgUGF0aEl0ZW1PYmplY3Q7XG4gICAgY29uc3Qgb3BlcmF0aW9uID0gb2FQYXRoW21ldGhvZCBhcyBrZXlvZiBQYXRoSXRlbU9iamVjdF0gYXMgT3BlcmF0aW9uT2JqZWN0O1xuICAgIGNvbnN0IG9wZXJhdGlvbklkID0gb3BlcmF0aW9uLm9wZXJhdGlvbklkITtcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9IGAke21ldGhvZCBhcyBzdHJpbmd9ICR7cGF0aCBhcyBzdHJpbmd9IC0gJHtvcGVyYXRpb24uc3VtbWFyeX1gO1xuXG4gICAgY29uc3QgY3VzdG9tTGFtYmRhT3B0aW9ucyA9IHRoaXMucHJvcHMubGFtYmRhT3B0aW9uc0J5T3BlcmF0aW9uID8gdGhpcy5wcm9wcy5sYW1iZGFPcHRpb25zQnlPcGVyYXRpb25bb3BlcmF0aW9uSWQgYXMga2V5b2YgT1BTXSA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gdGhpcy5hZGRDdXN0b21SZXN0UmVzb3VyY2Uob3BlcmF0aW9uLCBtZXRob2QgYXMgc3RyaW5nLCBkZXNjcmlwdGlvbiwgY3VzdG9tTGFtYmRhT3B0aW9ucyk7XG4gIH1cblxuICBwdWJsaWMgYWRkQ3VzdG9tUmVzdFJlc291cmNlKG9wZXJhdGlvbjogT3BlcmF0aW9uT2JqZWN0LCBtZXRob2Q6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZywgYWRkaXRpb25hbExhbWJkYU9wdGlvbnM6IExhbWJkYU9wdGlvbnMgPSB7fSkge1xuICAgIGlmICgneC1hbWF6b24tYXBpZ2F0ZXdheS1pbnRlZ3JhdGlvbicgaW4gb3BlcmF0aW9uKSB7XG4gICAgICByZXR1cm47IC8vIFNraXAgaWYgb3BlcmF0aW9uIHdhcyBkZWNsYXJlZCBpbiBzcGVjIGZpbGUgYWxyZWFkeSFcbiAgICB9XG5cbiAgICBjb25zdCBlbnRyeUZpbGUgPSBgLi9zcmMvbGFtYmRhL3Jlc3QuJHt0aGlzLnByb3BzLmFwaU5hbWUudG9Mb3dlckNhc2UoKX0uJHtvcGVyYXRpb24ub3BlcmF0aW9uSWR9LnRzYDtcblxuICAgIGNvbnN0IGxhbWJkYU9wdGlvbnMgPSB7XG4gICAgICAuLi50aGlzLnByb3BzLmxhbWJkYU9wdGlvbnMgJiYge1xuICAgICAgICAuLi50aGlzLnByb3BzLmxhbWJkYU9wdGlvbnMsXG4gICAgICB9LFxuICAgICAgLi4uYWRkaXRpb25hbExhbWJkYU9wdGlvbnMsXG4gICAgfTtcblxuICAgIGNvbnN0IGF1dGhlbnRpY2F0aW9uID0gdGhpcy5wcm9wcy5hdXRoZW50aWNhdGlvbiAmJiAodGhpcy5wcm9wcy5hdXRoZW50aWNhdGlvbi5oYXNPd25Qcm9wZXJ0eSgndXNlcnBvb2wnKVxuICAgICAgPyB7IHVzZXJQb29sOiAodGhpcy5wcm9wcy5hdXRoZW50aWNhdGlvbiBhcyBJQ29nbml0b0F1dGhlbnRpY2F0aW9uKS51c2VycG9vbCB9XG4gICAgICA6IHsgand0OiB0aGlzLnByb3BzLmF1dGhlbnRpY2F0aW9uIGFzIElKd3RBdXRoZW50aWNhdGlvbiB9KTtcblxuICAgIGNvbnN0IGZuID0gbmV3IExhbWJkYUZ1bmN0aW9uKHRoaXMsIGBGbiR7b3BlcmF0aW9uLm9wZXJhdGlvbklkfWAsIHtcbiAgICAgIHN0YWdlTmFtZTogdGhpcy5wcm9wcy5zdGFnZU5hbWUsXG4gICAgICBhZGRpdGlvbmFsRW52OiB7XG4gICAgICAgIC4uLnRoaXMucHJvcHMuZG9tYWluTmFtZSAmJiB7XG4gICAgICAgICAgRE9NQUlOX05BTUU6IHRoaXMucHJvcHMuZG9tYWluTmFtZSxcbiAgICAgICAgfSxcbiAgICAgICAgLi4udGhpcy5wcm9wcy5hZGRpdGlvbmFsRW52LFxuICAgICAgfSxcbiAgICAgIGVudHJ5OiBlbnRyeUZpbGUsXG4gICAgICBkZXNjcmlwdGlvbjogYFske3RoaXMucHJvcHMuc3RhZ2VOYW1lfV0gJHtkZXNjcmlwdGlvbn1gLFxuICAgICAgLi4uYXV0aGVudGljYXRpb24sXG4gICAgICAuLi50aGlzLnByb3BzLnNpbmdsZVRhYmxlRGF0YXN0b3JlICYmIHtcbiAgICAgICAgdGFibGU6IHRoaXMucHJvcHMuc2luZ2xlVGFibGVEYXRhc3RvcmUudGFibGUsXG4gICAgICAgIHRhYmxlV3JpdGVzOiB0aGlzLnRhYmxlV3JpdGVBY2Nlc3NGb3JNZXRob2QobWV0aG9kKSxcbiAgICAgIH0sXG4gICAgICAuLi50aGlzLnByb3BzLmFzc2V0Q2RuICYmIHtcbiAgICAgICAgYXNzZXREb21haW5OYW1lOiB0aGlzLnByb3BzLmFzc2V0Q2RuLmFzc2V0RG9tYWluTmFtZSxcbiAgICAgICAgYXNzZXRCdWNrZXQ6IHRoaXMucHJvcHMuYXNzZXRDZG4uYXNzZXRCdWNrZXQsXG4gICAgICB9LFxuICAgICAgbGFtYmRhT3B0aW9ucyxcbiAgICAgIGxhbWJkYVRyYWNpbmc6IHRoaXMucHJvcHMubGFtYmRhVHJhY2luZyxcbiAgICB9KTtcbiAgICB0aGlzLl9mdW5jdGlvbnNbb3BlcmF0aW9uLm9wZXJhdGlvbklkIV0gPSBmbjtcbiAgICBjZGsuVGFncy5vZihmbikuYWRkKCdPcGVuQVBJJywgZGVzY3JpcHRpb24ucmVwbGFjZSgvW15cXHdcXHNcXGRfLjovPStcXC1AXS9nLCAnJykpO1xuXG4gICAgLy8gaWYgKHRoaXMubW9uaXRvcmluZykge1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmxhbWJkYUR1cmF0aW9uc1dpZGdldC5hZGRMZWZ0TWV0cmljKGZuLm1ldHJpY0R1cmF0aW9uKCkpO1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmxhbWJkYUludm9rZXNXaWRnZXQuYWRkTGVmdE1ldHJpYyhmbi5tZXRyaWNJbnZvY2F0aW9ucygpKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5sYW1iZGFFcnJvcnNXaWRnZXQuYWRkTGVmdE1ldHJpYyhmbi5tZXRyaWNFcnJvcnMoKSk7XG4gICAgLy8gICB0aGlzLm1vbml0b3JpbmcubGFtYmRhRXJyb3JzV2lkZ2V0LmFkZExlZnRNZXRyaWMoZm4ubWV0cmljVGhyb3R0bGVzKCkpO1xuICAgIC8vIH1cblxuICAgIGNvbnN0IGhhc1ZlcnNpb25Db25maWcgPSBsYW1iZGFPcHRpb25zLmN1cnJlbnRWZXJzaW9uT3B0aW9ucyAhPSB1bmRlZmluZWQ7XG5cbiAgICBvcGVyYXRpb25bJ3gtYW1hem9uLWFwaWdhdGV3YXktaW50ZWdyYXRpb24nXSA9IHtcbiAgICAgIHR5cGU6ICdhd3NfcHJveHknLFxuICAgICAgaHR0cE1ldGhvZDogJ1BPU1QnLFxuICAgICAgdXJpOiBjZGsuU3RhY2sub2YodGhpcykuZm9ybWF0QXJuKHtcbiAgICAgICAgcmVzb3VyY2U6ICdwYXRoJyxcbiAgICAgICAgc2VydmljZTogJ2FwaWdhdGV3YXknLFxuICAgICAgICBhY2NvdW50OiAnbGFtYmRhJyxcbiAgICAgICAgYXJuRm9ybWF0OiBjZGsuQXJuRm9ybWF0LlNMQVNIX1JFU09VUkNFX05BTUUsXG4gICAgICAgIHJlc291cmNlTmFtZTogYDIwMTUtMDMtMzEvZnVuY3Rpb25zLyR7KGhhc1ZlcnNpb25Db25maWcgPyBmbi5jdXJyZW50VmVyc2lvbiA6IGZuKS5mdW5jdGlvbkFybn0vaW52b2NhdGlvbnNgLFxuICAgICAgICAvLyAgICAgICAgICAgICBeXl5eXl5eXl5eIC0gVEhJUyBORUVEUyBUTyBCRSBUSElTIERBVEUuIEVYQUNUTFkhXG4gICAgICB9KSxcbiAgICAgIHBhc3N0aHJvdWdoQmVoYXZpb3I6ICd3aGVuX25vX3RlbXBsYXRlcycsXG4gICAgICBwYXlsb2FkRm9ybWF0VmVyc2lvbjogJzEuMCcsXG4gICAgfTtcblxuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHByaXZhdGUgdGFibGVXcml0ZUFjY2Vzc0Zvck1ldGhvZChtZXRob2Q6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHN3aXRjaCAobWV0aG9kLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgIGNhc2UgJ2RlbGV0ZSc6XG4gICAgICBjYXNlICdwb3N0JzpcbiAgICAgIGNhc2UgJ3B1dCc6XG4gICAgICBjYXNlICdwYXRjaCc6XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgY2FzZSAnb3B0aW9ucyc6XG4gICAgICBjYXNlICdnZXQnOlxuICAgICAgY2FzZSAnaGVhZCc6XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluamVjdHMgdGhlIGF1dGhvcml6ZXIgc2VjdXJpdHkgc2NoZW1lIGludG8gdGhlIE9wZW5BUEkgc3BlYyBiYXNlZCBvbiB0aGVcbiAgICogYXV0aGVudGljYXRpb24gdHlwZSwgcGxhY2luZyBpdCB3aGVyZSBBUEkgR2F0ZXdheSBleHBlY3RzIGl0IGZvciB0aGUgc3BlY1xuICAgKiB2ZXJzaW9uOiBgY29tcG9uZW50cy5zZWN1cml0eVNjaGVtZXNgIGZvciBPcGVuQVBJIDMueCwgb3IgdGhlIHJvb3RcbiAgICogYHNlY3VyaXR5RGVmaW5pdGlvbnNgIGZvciBTd2FnZ2VyIDIuMC4gQW4gYXV0aG9yaXplciB3cml0dGVuIHRvIHRoZSB3cm9uZ1xuICAgKiBsb2NhdGlvbiBpcyBzaWxlbnRseSBpZ25vcmVkIG9uIGltcG9ydCwgZGVwbG95aW5nIGFuIHVuYXV0aGVudGljYXRlZCBBUEkuXG4gICAqXG4gICAqIEZvciBDb2duaXRvOiBhZGRzIGEgY29nbml0b191c2VyX3Bvb2xzIGF1dGhvcml6ZXIgcmVmZXJlbmNpbmcgdGhlIHVzZXIgcG9vbCBBUk4uXG4gICAqIEZvciBKV1Q6IGNyZWF0ZXMgYSBMYW1iZGEgYXV0aG9yaXplciBmdW5jdGlvbiBhbmQgYWRkcyBhIHRva2VuIGF1dGhvcml6ZXIgcmVmZXJlbmNpbmcgaXRzIEFSTi5cbiAgICovXG4gIHByb3RlY3RlZCBwYXRjaFNlY3VyaXR5U2NoZW1lcyhzcGVjOiBPcGVuQVBJMykge1xuICAgIGlmICghdGhpcy5wcm9wcy5hdXRoZW50aWNhdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHNjaGVtZXMgPSB0aGlzLnNlY3VyaXR5U2NoZW1lQ29udGFpbmVyKHNwZWMpO1xuXG4gICAgaWYgKHRoaXMucHJvcHMuYXV0aGVudGljYXRpb24uaGFzT3duUHJvcGVydHkoJ3VzZXJwb29sJykpIHtcbiAgICAgIC8vIENvZ25pdG8gVXNlciBQb29sIGF1dGhvcml6ZXJcbiAgICAgIGNvbnN0IGNvZ25pdG9BdXRoID0gdGhpcy5wcm9wcy5hdXRoZW50aWNhdGlvbiBhcyBJQ29nbml0b0F1dGhlbnRpY2F0aW9uO1xuICAgICAgY29uc3QgYXV0aG9yaXplck5hbWUgPSAnQ29nbml0b0F1dGhvcml6ZXInO1xuXG4gICAgICBzY2hlbWVzW2F1dGhvcml6ZXJOYW1lXSA9IHtcbiAgICAgICAgJ3R5cGUnOiAnYXBpS2V5JyxcbiAgICAgICAgJ25hbWUnOiAnQXV0aG9yaXphdGlvbicsXG4gICAgICAgICdpbic6ICdoZWFkZXInLFxuICAgICAgICAneC1hbWF6b24tYXBpZ2F0ZXdheS1hdXRodHlwZSc6ICdjb2duaXRvX3VzZXJfcG9vbHMnLFxuICAgICAgICAneC1hbWF6b24tYXBpZ2F0ZXdheS1hdXRob3JpemVyJzoge1xuICAgICAgICAgIHR5cGU6ICdjb2duaXRvX3VzZXJfcG9vbHMnLFxuICAgICAgICAgIHByb3ZpZGVyQVJOczogW2NvZ25pdG9BdXRoLnVzZXJwb29sLnVzZXJQb29sQXJuXSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIC8vIEVuc3VyZSBnbG9iYWwgc2VjdXJpdHkgcmVmZXJlbmNlcyB0aGUgYXV0aG9yaXplciBzbyBwYXRjaFNlY3VyaXR5IGRpc3RyaWJ1dGVzIGl0XG4gICAgICBpZiAoIXNwZWMuc2VjdXJpdHkpIHtcbiAgICAgICAgc3BlYy5zZWN1cml0eSA9IFt7IFthdXRob3JpemVyTmFtZV06IFtdIH1dO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBKV1QgKExhbWJkYSkgYXV0aG9yaXplclxuICAgICAgY29uc3Qgand0QXV0aCA9IHRoaXMucHJvcHMuYXV0aGVudGljYXRpb24gYXMgSUp3dEF1dGhlbnRpY2F0aW9uO1xuICAgICAgY29uc3QgYXV0aG9yaXplck5hbWUgPSAnSnd0QXV0aG9yaXplcic7XG5cbiAgICAgIGNvbnN0IGF1dGhvcml6ZXJGbiA9IG5ldyBMYW1iZGFGdW5jdGlvbih0aGlzLCAnSnd0QXV0aG9yaXplckZuJywge1xuICAgICAgICBzdGFnZU5hbWU6IHRoaXMucHJvcHMuc3RhZ2VOYW1lLFxuICAgICAgICBlbnRyeTogJ3NyYy9sYW1iZGEvcmVzdC1hcGkuand0LWF1dGhvcml6ZXIudHMnLFxuICAgICAgICBkZXNjcmlwdGlvbjogYFske3RoaXMucHJvcHMuc3RhZ2VOYW1lfV0gSldUIEF1dGhvcml6ZXIgZm9yICR7dGhpcy5wcm9wcy5hcGlOYW1lfWAsXG4gICAgICAgIGp3dDogand0QXV0aCxcbiAgICAgICAgbGFtYmRhT3B0aW9uczogdGhpcy5wcm9wcy5sYW1iZGFPcHRpb25zLFxuICAgICAgICBsYW1iZGFUcmFjaW5nOiB0aGlzLnByb3BzLmxhbWJkYVRyYWNpbmcsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgYXV0aG9yaXplclVyaSA9IGNkay5TdGFjay5vZih0aGlzKS5mb3JtYXRBcm4oe1xuICAgICAgICByZXNvdXJjZTogJ3BhdGgnLFxuICAgICAgICBzZXJ2aWNlOiAnYXBpZ2F0ZXdheScsXG4gICAgICAgIGFjY291bnQ6ICdsYW1iZGEnLFxuICAgICAgICBhcm5Gb3JtYXQ6IGNkay5Bcm5Gb3JtYXQuU0xBU0hfUkVTT1VSQ0VfTkFNRSxcbiAgICAgICAgcmVzb3VyY2VOYW1lOiBgMjAxNS0wMy0zMS9mdW5jdGlvbnMvJHthdXRob3JpemVyRm4uZnVuY3Rpb25Bcm59L2ludm9jYXRpb25zYCxcbiAgICAgIH0pO1xuXG4gICAgICBzY2hlbWVzW2F1dGhvcml6ZXJOYW1lXSA9IHtcbiAgICAgICAgJ3R5cGUnOiAnYXBpS2V5JyxcbiAgICAgICAgJ25hbWUnOiAnQXV0aG9yaXphdGlvbicsXG4gICAgICAgICdpbic6ICdoZWFkZXInLFxuICAgICAgICAneC1hbWF6b24tYXBpZ2F0ZXdheS1hdXRodHlwZSc6ICdjdXN0b20nLFxuICAgICAgICAneC1hbWF6b24tYXBpZ2F0ZXdheS1hdXRob3JpemVyJzoge1xuICAgICAgICAgIHR5cGU6IHRoaXMucHJvcHMuand0QXV0aG9yaXplclR5cGUgPT09ICdyZXF1ZXN0JyA/ICdyZXF1ZXN0JyA6ICd0b2tlbicsXG4gICAgICAgICAgYXV0aG9yaXplclVyaTogYXV0aG9yaXplclVyaSxcbiAgICAgICAgICBhdXRob3JpemVyUmVzdWx0VHRsSW5TZWNvbmRzOiB0aGlzLnByb3BzLmp3dEF1dGhvcml6ZXJUeXBlID09PSAncmVxdWVzdCcgPyAwIDogMzAwLFxuICAgICAgICAgIC4uLih0aGlzLnByb3BzLmp3dEF1dGhvcml6ZXJUeXBlICE9PSAncmVxdWVzdCcgJiYge1xuICAgICAgICAgICAgaWRlbnRpdHlTb3VyY2U6ICdtZXRob2QucmVxdWVzdC5oZWFkZXIuQXV0aG9yaXphdGlvbicsXG4gICAgICAgICAgfSksXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICAvLyBTdG9yZSB0aGUgYXV0aG9yaXplciBmdW5jdGlvbiBzbyB3ZSBjYW4gZ3JhbnQgcGVybWlzc2lvbiBhZnRlciB0aGUgU3BlY1Jlc3RBcGkgaXMgY3JlYXRlZFxuICAgICAgdGhpcy5fYXV0aG9yaXplckZuID0gYXV0aG9yaXplckZuO1xuXG4gICAgICAvLyBFbnN1cmUgZ2xvYmFsIHNlY3VyaXR5IHJlZmVyZW5jZXMgdGhlIGF1dGhvcml6ZXIgc28gcGF0Y2hTZWN1cml0eSBkaXN0cmlidXRlcyBpdFxuICAgICAgaWYgKCFzcGVjLnNlY3VyaXR5KSB7XG4gICAgICAgIHNwZWMuc2VjdXJpdHkgPSBbeyBbYXV0aG9yaXplck5hbWVdOiBbXSB9XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc2VjdXJpdHktc2NoZW1lIGNvbnRhaW5lciBmb3IgdGhlIHNwZWMsIGNyZWF0aW5nIGl0IGlmIG5lZWRlZC5cbiAgICogT3BlbkFQSSAzLnggc3RvcmVzIHNjaGVtZXMgdW5kZXIgYGNvbXBvbmVudHMuc2VjdXJpdHlTY2hlbWVzYDsgU3dhZ2dlciAyLjBcbiAgICogdXNlcyB0aGUgcm9vdCBgc2VjdXJpdHlEZWZpbml0aW9uc2AuIEFQSSBHYXRld2F5IHJlYWRzIG9ubHkgdGhlIGxvY2F0aW9uIHRoYXRcbiAgICogbWF0Y2hlcyB0aGUgZG9jdW1lbnQncyBkZWNsYXJlZCB2ZXJzaW9uLCBzbyB0aGUgYXV0aG9yaXplciBtdXN0IGdvIHRoZXJlLlxuICAgKi9cbiAgcHJpdmF0ZSBzZWN1cml0eVNjaGVtZUNvbnRhaW5lcihzcGVjOiBPcGVuQVBJMyk6IHsgW25hbWU6IHN0cmluZ106IGFueSB9IHtcbiAgICBjb25zdCBzcGVjQW55ID0gc3BlYyBhcyBhbnk7XG4gICAgY29uc3QgaXNPcGVuQXBpVjMgPSB0eXBlb2Ygc3BlY0FueS5vcGVuYXBpID09PSAnc3RyaW5nJyAmJiBzcGVjQW55Lm9wZW5hcGkuc3RhcnRzV2l0aCgnMycpO1xuICAgIGlmIChpc09wZW5BcGlWMykge1xuICAgICAgc3BlY0FueS5jb21wb25lbnRzID0gc3BlY0FueS5jb21wb25lbnRzID8/IHt9O1xuICAgICAgc3BlY0FueS5jb21wb25lbnRzLnNlY3VyaXR5U2NoZW1lcyA9IHNwZWNBbnkuY29tcG9uZW50cy5zZWN1cml0eVNjaGVtZXMgPz8ge307XG4gICAgICByZXR1cm4gc3BlY0FueS5jb21wb25lbnRzLnNlY3VyaXR5U2NoZW1lcztcbiAgICB9XG4gICAgc3BlY0FueS5zZWN1cml0eURlZmluaXRpb25zID0gc3BlY0FueS5zZWN1cml0eURlZmluaXRpb25zID8/IHt9O1xuICAgIHJldHVybiBzcGVjQW55LnNlY3VyaXR5RGVmaW5pdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogQVdTIGRvZXMgbm90IHByb3Blcmx5IGFwcGx5IHRoZSAnc2VjdXJpdHknIG9wdGlvbiB0byBldmVyeSBzaW5nbGUgcGF0aC1tZXRob2QuXG4gICAqIEFjY29yZGluZyB0byBkb2N1bWVudGF0aW9uLCBnbG9iYWwgc2VjdXJpdHkgZ2V0cyBhcHBsaWVkLCBpZiB0aGVyZSBpcyBubyBzZWN1cml0eVxuICAgKiBzZXQgZm9yIHRoZSBwYXJ0aWN1bGFyIHBhdGgtbWV0aG9kLiBJZiB0aGVyZSBpcyBhbnksIGV2ZW4gZW1wdHksIGl0IHdpbGwgZ2V0IHByZWNlZGVuY2UuXG4gICAqIFRISVMgRE9FUyBOT1QgSEFQUEVOIE9OIEFXUy4gSVQgSlVTVCBBTFdBWVMgVVNFUyBUSEUgR0xPQkFMIFNFVFRJTkchXG4gICAqXG4gICAqICdzZWN1cml0eSBhcHBsaWVzIFsuLi5dIHNjaGVtZXMgZ2xvYmFsbHkgdG8gYWxsIEFQSSBvcGVyYXRpb25zLCB1bmxlc3Mgb3ZlcnJpZGRlbiBvbiB0aGUgb3BlcmF0aW9uIGxldmVsJ1xuICAgKiBAc2VlIGh0dHBzOi8vc3dhZ2dlci5pby9kb2NzL3NwZWNpZmljYXRpb24vYXV0aGVudGljYXRpb24vXG4gICAqL1xuICBwcm90ZWN0ZWQgcGF0Y2hTZWN1cml0eShzcGVjOiBPcGVuQVBJMykge1xuICAgIGlmICgnc2VjdXJpdHknIGluIHNwZWMpIHtcbiAgICAgIGZvciAoY29uc3Qgc3BlY1BhdGggb2YgT2JqZWN0LnZhbHVlcyhzcGVjLnBhdGhzIHx8IFtdKSkge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjUGF0aCkge1xuICAgICAgICAgIGlmICghdGhpcy5hcGlNZXRob2RzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIGlmIG5vdCBodHRwIG1ldGhvZCBkZWZpbml0aW9uXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgc3BlY01ldGhvZCA9IChzcGVjUGF0aCBhcyBQYXRoSXRlbU9iamVjdClba2V5IGFzIGtleW9mIFBhdGhJdGVtT2JqZWN0XSE7XG4gICAgICAgICAgaWYgKCEoJ3NlY3VyaXR5JyBpbiBzcGVjTWV0aG9kKSkge1xuICAgICAgICAgICAgY29uc3Qgb3BlcmF0aW9uSWQgPSAoc3BlY01ldGhvZCBhcyBPcGVyYXRpb25PYmplY3QpLm9wZXJhdGlvbklkO1xuICAgICAgICAgICAgaWYgKG9wZXJhdGlvbklkICYmIHRoaXMuX2Fub255bW91c09wZXJhdGlvbnMuaGFzKG9wZXJhdGlvbklkKSkge1xuICAgICAgICAgICAgICAvLyBTdG9yZSB3aGF0IHNlY3VyaXR5IHdvdWxkIGhhdmUgYmVlbiBhcHBsaWVkIHNvIHdlIGNhbiByZXN0b3JlIGxhdGVyXG4gICAgICAgICAgICAgIHRoaXMuX29yaWdpbmFsT3BlcmF0aW9uU2VjdXJpdHkuc2V0KG9wZXJhdGlvbklkLCBzcGVjLnNlY3VyaXR5IGFzIGFueVtdKTtcbiAgICAgICAgICAgICAgc3BlY01ldGhvZC5zZWN1cml0eSA9IFtdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc3BlY01ldGhvZC5zZWN1cml0eSA9IHNwZWMuc2VjdXJpdHk7XG4gICAgICAgICAgICAgIGlmIChvcGVyYXRpb25JZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29yaWdpbmFsT3BlcmF0aW9uU2VjdXJpdHkuc2V0KG9wZXJhdGlvbklkLCBzcGVjLnNlY3VyaXR5IGFzIGFueVtdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPcGVyYXRpb24gYWxyZWFkeSBoYXMgZXhwbGljaXQgc2VjdXJpdHkgZGVmaW5lZCBpbiB0aGUgc3BlY1xuICAgICAgICAgICAgY29uc3Qgb3BlcmF0aW9uSWQgPSAoc3BlY01ldGhvZCBhcyBPcGVyYXRpb25PYmplY3QpLm9wZXJhdGlvbklkO1xuICAgICAgICAgICAgaWYgKG9wZXJhdGlvbklkKSB7XG4gICAgICAgICAgICAgIHRoaXMuX29yaWdpbmFsT3BlcmF0aW9uU2VjdXJpdHkuc2V0KG9wZXJhdGlvbklkLCBzcGVjTWV0aG9kLnNlY3VyaXR5IGFzIGFueVtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGRlbGV0ZSBzcGVjLnNlY3VyaXR5O1xuICAgIH1cbiAgfVxuXG59XG4iXX0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handler(event: AWSLambda.APIGatewayTokenAuthorizerEvent | AWSLambda.APIGatewayRequestAuthorizerEvent): Promise<AWSLambda.APIGatewayAuthorizerResult>;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.handler = handler;
|
|
7
|
+
const process_1 = require("process");
|
|
8
|
+
const jsonwebtoken_1 = require("jsonwebtoken");
|
|
9
|
+
const jwk_to_pem_1 = __importDefault(require("jwk-to-pem"));
|
|
10
|
+
const jwtIssuerUrl = process_1.env.JWT_ISSUER_URL ?? '';
|
|
11
|
+
const jwtJwksUrl = process_1.env.JWT_JWKS_URL;
|
|
12
|
+
const jwtAudience = (process_1.env.JWT_AUDIENCE_URL && process_1.env.JWT_AUDIENCE_URL.length > 0) ? process_1.env.JWT_AUDIENCE_URL.split('||') : undefined;
|
|
13
|
+
let cacheKeys;
|
|
14
|
+
const fetchJson = async (url) => {
|
|
15
|
+
const res = await fetch(url, { signal: AbortSignal.timeout(5000) });
|
|
16
|
+
if (!res.ok) {
|
|
17
|
+
throw new Error(`Request to ${url} failed: ${res.status} ${res.statusText}`);
|
|
18
|
+
}
|
|
19
|
+
return (await res.json());
|
|
20
|
+
};
|
|
21
|
+
const getPublicKeys = async (jwksUrl) => {
|
|
22
|
+
if (!cacheKeys) {
|
|
23
|
+
const publicKeys = await fetchJson(jwksUrl);
|
|
24
|
+
cacheKeys = publicKeys.keys.reduce((agg, current) => {
|
|
25
|
+
const pem = (0, jwk_to_pem_1.default)(current);
|
|
26
|
+
agg[current.kid] = { instance: current, pem };
|
|
27
|
+
return agg;
|
|
28
|
+
}, {});
|
|
29
|
+
return cacheKeys;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return cacheKeys;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const getJwksUri = async (discoveryUri, jwksUri) => {
|
|
36
|
+
if (jwksUri) {
|
|
37
|
+
return jwksUri;
|
|
38
|
+
}
|
|
39
|
+
const wellKnownUri = `${discoveryUri}/.well-known/openid-configuration`;
|
|
40
|
+
const issuerMetadata = await fetchJson(wellKnownUri);
|
|
41
|
+
if (!issuerMetadata.jwks_uri) {
|
|
42
|
+
throw new Error('Issuer does not offer JWKS endpoint');
|
|
43
|
+
}
|
|
44
|
+
return issuerMetadata.jwks_uri;
|
|
45
|
+
};
|
|
46
|
+
const promisedVerify = (token, issuerUri, jwksUri) => {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
(0, jsonwebtoken_1.verify)(token, (header, cb) => {
|
|
49
|
+
if (!header.kid) {
|
|
50
|
+
cb(new Error('no key id found'));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
getJwksUri(issuerUri, jwksUri).then(getPublicKeys).then((keys) => {
|
|
54
|
+
const key = keys[header.kid];
|
|
55
|
+
if (!key) {
|
|
56
|
+
cb(new Error('signing key not found for kid'));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
cb(null, key.pem);
|
|
60
|
+
}, cb);
|
|
61
|
+
}, { issuer: issuerUri, audience: jwtAudience }, (err, decoded) => {
|
|
62
|
+
if (err) {
|
|
63
|
+
reject(err);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
resolve(decoded);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
function generatePolicy(principalId, effect, resource, context) {
|
|
72
|
+
const policyDocument = {
|
|
73
|
+
Version: '2012-10-17',
|
|
74
|
+
Statement: [
|
|
75
|
+
{
|
|
76
|
+
Action: 'execute-api:Invoke',
|
|
77
|
+
Effect: effect,
|
|
78
|
+
Resource: resource,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
return {
|
|
83
|
+
principalId,
|
|
84
|
+
policyDocument,
|
|
85
|
+
...(context && { context }),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async function handler(event) {
|
|
89
|
+
// Detect event type: TOKEN has event.type === 'TOKEN', REQUEST has event.type === 'REQUEST'
|
|
90
|
+
if (event.type === 'REQUEST') {
|
|
91
|
+
return handleRequestEvent(event);
|
|
92
|
+
}
|
|
93
|
+
return handleTokenEvent(event);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Verifies a JWT token and generates an Allow policy with claims context.
|
|
97
|
+
* Handles JWKS cache invalidation on signature/key-rotation errors with a single retry.
|
|
98
|
+
*/
|
|
99
|
+
async function verifyTokenAndGeneratePolicy(token, resource) {
|
|
100
|
+
let claims;
|
|
101
|
+
try {
|
|
102
|
+
claims = await promisedVerify(token, jwtIssuerUrl, jwtJwksUrl);
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
// If verification failed due to a signature error (possibly rotated keys),
|
|
106
|
+
// clear the JWKS cache and retry once
|
|
107
|
+
if (err && err.message && (err.message.includes('invalid signature') || err.message.includes('signing key not found'))) {
|
|
108
|
+
cacheKeys = undefined;
|
|
109
|
+
claims = await promisedVerify(token, jwtIssuerUrl, jwtJwksUrl);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const context = {};
|
|
116
|
+
for (const [key, value] of Object.entries(claims)) {
|
|
117
|
+
if (typeof value === 'string') {
|
|
118
|
+
context[key] = value;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
context[key] = JSON.stringify(value);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return generatePolicy(claims.sub || 'user', 'Allow', resource, context);
|
|
125
|
+
}
|
|
126
|
+
async function handleTokenEvent(event) {
|
|
127
|
+
const token = event.authorizationToken;
|
|
128
|
+
if (!token || !token.startsWith('Bearer ')) {
|
|
129
|
+
throw new Error('Unauthorized');
|
|
130
|
+
}
|
|
131
|
+
const jwtToken = token.substring('Bearer '.length);
|
|
132
|
+
try {
|
|
133
|
+
return await verifyTokenAndGeneratePolicy(jwtToken, event.methodArn);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
throw new Error('Unauthorized');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async function handleRequestEvent(event) {
|
|
140
|
+
const authHeader = event.headers?.Authorization || event.headers?.authorization;
|
|
141
|
+
const resource = event.methodArn;
|
|
142
|
+
// No Authorization header: allow as anonymous (optional auth behavior)
|
|
143
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
144
|
+
return generatePolicy('anonymous', 'Allow', resource, {});
|
|
145
|
+
}
|
|
146
|
+
const jwtToken = authHeader.substring('Bearer '.length);
|
|
147
|
+
try {
|
|
148
|
+
return await verifyTokenAndGeneratePolicy(jwtToken, resource);
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
throw new Error('Unauthorized');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdC1hcGkuand0LWF1dGhvcml6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGFtYmRhL3Jlc3QtYXBpLmp3dC1hdXRob3JpemVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBbUhBLDBCQVFDO0FBM0hELHFDQUE4QjtBQUM5QiwrQ0FBcUU7QUFDckUsNERBQWtDO0FBRWxDLE1BQU0sWUFBWSxHQUFHLGFBQUcsQ0FBQyxjQUFjLElBQUksRUFBRSxDQUFDO0FBQzlDLE1BQU0sVUFBVSxHQUFHLGFBQUcsQ0FBQyxZQUFZLENBQUM7QUFDcEMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxhQUFHLENBQUMsZ0JBQWdCLElBQUksYUFBRyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBRyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBNkI3SCxJQUFJLFNBQTBDLENBQUM7QUFFL0MsTUFBTSxTQUFTLEdBQUcsS0FBSyxFQUFLLEdBQVcsRUFBYyxFQUFFO0lBQ3JELE1BQU0sR0FBRyxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLE1BQU0sRUFBRSxXQUFXLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNwRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ1osTUFBTSxJQUFJLEtBQUssQ0FBQyxjQUFjLEdBQUcsWUFBWSxHQUFHLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBQy9FLENBQUM7SUFDRCxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLENBQU0sQ0FBQztBQUNqQyxDQUFDLENBQUM7QUFFRixNQUFNLGFBQWEsR0FBRyxLQUFLLEVBQUUsT0FBZSxFQUFnQyxFQUFFO0lBQzVF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QUFHLEtBQUssQ0FBQyxPQUFPLEVBQUUsYUFBYSxJQUFJLEtBQUssQ0FBQyxPQUFPLEVBQUUsYUFBYSxDQUFDO0lBQ2hGLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7SUFFakMsdUVBQXVFO0lBQ3ZFLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDckQsT0FBTyxjQUFjLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRXhELElBQUksQ0FBQztRQUNILE9BQU8sTUFBTSw0QkFBNEIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYixNQUFNLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZW52IH0gZnJvbSAncHJvY2Vzcyc7XG5pbXBvcnQgeyB2ZXJpZnksIEp3dEhlYWRlciwgU2lnbmluZ0tleUNhbGxiYWNrIH0gZnJvbSAnanNvbndlYnRva2VuJztcbmltcG9ydCBqd2tUb1BlbSBmcm9tICdqd2stdG8tcGVtJztcblxuY29uc3Qgand0SXNzdWVyVXJsID0gZW52LkpXVF9JU1NVRVJfVVJMID8/ICcnO1xuY29uc3Qgand0Sndrc1VybCA9IGVudi5KV1RfSldLU19VUkw7XG5jb25zdCBqd3RBdWRpZW5jZSA9IChlbnYuSldUX0FVRElFTkNFX1VSTCAmJiBlbnYuSldUX0FVRElFTkNFX1VSTC5sZW5ndGggPiAwKSA/IGVudi5KV1RfQVVESUVOQ0VfVVJMLnNwbGl0KCd8fCcpIDogdW5kZWZpbmVkO1xuXG5pbnRlcmZhY2UgUHVibGljS2V5IHtcbiAgYWxnOiBzdHJpbmc7XG4gIGU6IHN0cmluZztcbiAga2lkOiBzdHJpbmc7XG4gIGt0eTogc3RyaW5nO1xuICBuOiBzdHJpbmc7XG4gIHVzZTogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUHVibGljS2V5TWV0YSB7XG4gIGluc3RhbmNlOiBQdWJsaWNLZXk7XG4gIHBlbTogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUHVibGljS2V5cyB7XG4gIGtleXM6IFB1YmxpY0tleVtdO1xufVxuXG5pbnRlcmZhY2UgSXNzdWVyTWV0YWRhdGEge1xuICBqd2tzX3VyaT86IHN0cmluZztcbiAgW2tleTogc3RyaW5nXTogdW5rbm93bjtcbn1cblxuaW50ZXJmYWNlIE1hcE9mS2lkVG9QdWJsaWNLZXkge1xuICBba2V5OiBzdHJpbmddOiBQdWJsaWNLZXlNZXRhO1xufVxuXG5sZXQgY2FjaGVLZXlzOiBNYXBPZktpZFRvUHVibGljS2V5IHwgdW5kZWZpbmVkO1xuXG5jb25zdCBmZXRjaEpzb24gPSBhc3luYyA8VD4odXJsOiBzdHJpbmcpOiBQcm9taXNlPFQ+ID0+IHtcbiAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2godXJsLCB7IHNpZ25hbDogQWJvcnRTaWduYWwudGltZW91dCg1MDAwKSB9KTtcbiAgaWYgKCFyZXMub2spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcXVlc3QgdG8gJHt1cmx9IGZhaWxlZDogJHtyZXMuc3RhdHVzfSAke3Jlcy5zdGF0dXNUZXh0fWApO1xuICB9XG4gIHJldHVybiAoYXdhaXQgcmVzLmpzb24oKSkgYXMgVDtcbn07XG5cbmNvbnN0IGdldFB1YmxpY0tleXMgPSBhc3luYyAoandrc1VybDogc3RyaW5nKTogUHJvbWlzZTxNYXBPZktpZFRvUHVibGljS2V5PiA9PiB7XG4gIGlmICghY2FjaGVLZXlzKSB7XG4gICAgY29uc3QgcHVibGljS2V5cyA9IGF3YWl0IGZldGNoSnNvbjxQdWJsaWNLZXlzPihqd2tzVXJsKTtcbiAgICBjYWNoZUtleXMgPSBwdWJsaWNLZXlzLmtleXMucmVkdWNlKChhZ2csIGN1cnJlbnQpID0+IHtcbiAgICAgIGNvbnN0IHBlbSA9IGp3a1RvUGVtKGN1cnJlbnQgYXMgandrVG9QZW0uSldLKTtcbiAgICAgIGFnZ1tjdXJyZW50LmtpZF0gPSB7IGluc3RhbmNlOiBjdXJyZW50LCBwZW0gfTtcbiAgICAgIHJldHVybiBhZ2c7XG4gICAgfSwge30gYXMgTWFwT2ZLaWRUb1B1YmxpY0tleSk7XG4gICAgcmV0dXJuIGNhY2hlS2V5cztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gY2FjaGVLZXlzO1xuICB9XG59O1xuXG5jb25zdCBnZXRKd2tzVXJpID0gYXN5bmMgKGRpc2NvdmVyeVVyaTogc3RyaW5nLCBqd2tzVXJpPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgaWYgKGp3a3NVcmkpIHtcbiAgICByZXR1cm4gandrc1VyaTtcbiAgfVxuICBjb25zdCB3ZWxsS25vd25VcmkgPSBgJHtkaXNjb3ZlcnlVcml9Ly53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uYDtcbiAgY29uc3QgaXNzdWVyTWV0YWRhdGEgPSBhd2FpdCBmZXRjaEpzb248SXNzdWVyTWV0YWRhdGE+KHdlbGxLbm93blVyaSk7XG4gIGlmICghaXNzdWVyTWV0YWRhdGEuandrc191cmkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lzc3VlciBkb2VzIG5vdCBvZmZlciBKV0tTIGVuZHBvaW50Jyk7XG4gIH1cbiAgcmV0dXJuIGlzc3Vlck1ldGFkYXRhLmp3a3NfdXJpO1xufTtcblxuY29uc3QgcHJvbWlzZWRWZXJpZnkgPSAodG9rZW46IHN0cmluZywgaXNzdWVyVXJpOiBzdHJpbmcsIGp3a3NVcmk/OiBzdHJpbmcpOiBQcm9taXNlPHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9PiA9PiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdmVyaWZ5KHRva2VuLCAoaGVhZGVyOiBKd3RIZWFkZXIsIGNiOiBTaWduaW5nS2V5Q2FsbGJhY2spID0+IHtcbiAgICAgIGlmICghaGVhZGVyLmtpZCkge1xuICAgICAgICBjYihuZXcgRXJyb3IoJ25vIGtleSBpZCBmb3VuZCcpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZ2V0Sndrc1VyaShpc3N1ZXJVcmksIGp3a3NVcmkpLnRoZW4oZ2V0UHVibGljS2V5cykudGhlbigoa2V5cykgPT4ge1xuICAgICAgICBjb25zdCBrZXkgPSBrZXlzW2hlYWRlci5raWQhXTtcbiAgICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAgICBjYihuZXcgRXJyb3IoJ3NpZ25pbmcga2V5IG5vdCBmb3VuZCBmb3Iga2lkJykpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjYihudWxsLCBrZXkucGVtKTtcbiAgICAgIH0sIGNiKTtcbiAgICB9LCB7IGlzc3VlcjogaXNzdWVyVXJpLCBhdWRpZW5jZTogand0QXVkaWVuY2UgYXMgW3N0cmluZywgLi4uc3RyaW5nW11dIH0sIChlcnI6IGFueSwgZGVjb2RlZDogYW55KSA9PiB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShkZWNvZGVkIGFzIHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59O1xuXG5mdW5jdGlvbiBnZW5lcmF0ZVBvbGljeShwcmluY2lwYWxJZDogc3RyaW5nLCBlZmZlY3Q6ICdBbGxvdycgfCAnRGVueScsIHJlc291cmNlOiBzdHJpbmcsIGNvbnRleHQ/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KTogQVdTTGFtYmRhLkFQSUdhdGV3YXlBdXRob3JpemVyUmVzdWx0IHtcbiAgY29uc3QgcG9saWN5RG9jdW1lbnQ6IEFXU0xhbWJkYS5Qb2xpY3lEb2N1bWVudCA9IHtcbiAgICBWZXJzaW9uOiAnMjAxMi0xMC0xNycsXG4gICAgU3RhdGVtZW50OiBbXG4gICAgICB7XG4gICAgICAgIEFjdGlvbjogJ2V4ZWN1dGUtYXBpOkludm9rZScsXG4gICAgICAgIEVmZmVjdDogZWZmZWN0LFxuICAgICAgICBSZXNvdXJjZTogcmVzb3VyY2UsXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBwcmluY2lwYWxJZCxcbiAgICBwb2xpY3lEb2N1bWVudCxcbiAgICAuLi4oY29udGV4dCAmJiB7IGNvbnRleHQgfSksXG4gIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKFxuICBldmVudDogQVdTTGFtYmRhLkFQSUdhdGV3YXlUb2tlbkF1dGhvcml6ZXJFdmVudCB8IEFXU0xhbWJkYS5BUElHYXRld2F5UmVxdWVzdEF1dGhvcml6ZXJFdmVudCxcbik6IFByb21pc2U8QVdTTGFtYmRhLkFQSUdhdGV3YXlBdXRob3JpemVyUmVzdWx0PiB7XG4gIC8vIERldGVjdCBldmVudCB0eXBlOiBUT0tFTiBoYXMgZXZlbnQudHlwZSA9PT0gJ1RPS0VOJywgUkVRVUVTVCBoYXMgZXZlbnQudHlwZSA9PT0gJ1JFUVVFU1QnXG4gIGlmIChldmVudC50eXBlID09PSAnUkVRVUVTVCcpIHtcbiAgICByZXR1cm4gaGFuZGxlUmVxdWVzdEV2ZW50KGV2ZW50IGFzIEFXU0xhbWJkYS5BUElHYXRld2F5UmVxdWVzdEF1dGhvcml6ZXJFdmVudCk7XG4gIH1cbiAgcmV0dXJuIGhhbmRsZVRva2VuRXZlbnQoZXZlbnQgYXMgQVdTTGFtYmRhLkFQSUdhdGV3YXlUb2tlbkF1dGhvcml6ZXJFdmVudCk7XG59XG5cbi8qKlxuICogVmVyaWZpZXMgYSBKV1QgdG9rZW4gYW5kIGdlbmVyYXRlcyBhbiBBbGxvdyBwb2xpY3kgd2l0aCBjbGFpbXMgY29udGV4dC5cbiAqIEhhbmRsZXMgSldLUyBjYWNoZSBpbnZhbGlkYXRpb24gb24gc2lnbmF0dXJlL2tleS1yb3RhdGlvbiBlcnJvcnMgd2l0aCBhIHNpbmdsZSByZXRyeS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gdmVyaWZ5VG9rZW5BbmRHZW5lcmF0ZVBvbGljeSh0b2tlbjogc3RyaW5nLCByZXNvdXJjZTogc3RyaW5nKTogUHJvbWlzZTxBV1NMYW1iZGEuQVBJR2F0ZXdheUF1dGhvcml6ZXJSZXN1bHQ+IHtcbiAgbGV0IGNsYWltczogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH07XG4gIHRyeSB7XG4gICAgY2xhaW1zID0gYXdhaXQgcHJvbWlzZWRWZXJpZnkodG9rZW4sIGp3dElzc3VlclVybCwgand0Sndrc1VybCk7XG4gIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgLy8gSWYgdmVyaWZpY2F0aW9uIGZhaWxlZCBkdWUgdG8gYSBzaWduYXR1cmUgZXJyb3IgKHBvc3NpYmx5IHJvdGF0ZWQga2V5cyksXG4gICAgLy8gY2xlYXIgdGhlIEpXS1MgY2FjaGUgYW5kIHJldHJ5IG9uY2VcbiAgICBpZiAoZXJyICYmIGVyci5tZXNzYWdlICYmIChlcnIubWVzc2FnZS5pbmNsdWRlcygnaW52YWxpZCBzaWduYXR1cmUnKSB8fCBlcnIubWVzc2FnZS5pbmNsdWRlcygnc2lnbmluZyBrZXkgbm90IGZvdW5kJykpKSB7XG4gICAgICBjYWNoZUtleXMgPSB1bmRlZmluZWQ7XG4gICAgICBjbGFpbXMgPSBhd2FpdCBwcm9taXNlZFZlcmlmeSh0b2tlbiwgand0SXNzdWVyVXJsLCBqd3RKd2tzVXJsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGNvbnRleHQ6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoY2xhaW1zKSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb250ZXh0W2tleV0gPSB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dFtrZXldID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBnZW5lcmF0ZVBvbGljeShjbGFpbXMuc3ViIHx8ICd1c2VyJywgJ0FsbG93JywgcmVzb3VyY2UsIGNvbnRleHQpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBoYW5kbGVUb2tlbkV2ZW50KGV2ZW50OiBBV1NMYW1iZGEuQVBJR2F0ZXdheVRva2VuQXV0aG9yaXplckV2ZW50KTogUHJvbWlzZTxBV1NMYW1iZGEuQVBJR2F0ZXdheUF1dGhvcml6ZXJSZXN1bHQ+IHtcbiAgY29uc3QgdG9rZW4gPSBldmVudC5hdXRob3JpemF0aW9uVG9rZW47XG5cbiAgaWYgKCF0b2tlbiB8fCAhdG9rZW4uc3RhcnRzV2l0aCgnQmVhcmVyICcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmF1dGhvcml6ZWQnKTtcbiAgfVxuXG4gIGNvbnN0IGp3dFRva2VuID0gdG9rZW4uc3Vic3RyaW5nKCdCZWFyZXIgJy5sZW5ndGgpO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHZlcmlmeVRva2VuQW5kR2VuZXJhdGVQb2xpY3koand0VG9rZW4sIGV2ZW50Lm1ldGhvZEFybik7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5hdXRob3JpemVkJyk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gaGFuZGxlUmVxdWVzdEV2ZW50KGV2ZW50OiBBV1NMYW1iZGEuQVBJR2F0ZXdheVJlcXVlc3RBdXRob3JpemVyRXZlbnQpOiBQcm9taXNlPEFXU0xhbWJkYS5BUElHYXRld2F5QXV0aG9yaXplclJlc3VsdD4ge1xuICBjb25zdCBhdXRoSGVhZGVyID0gZXZlbnQuaGVhZGVycz8uQXV0aG9yaXphdGlvbiB8fCBldmVudC5oZWFkZXJzPy5hdXRob3JpemF0aW9uO1xuICBjb25zdCByZXNvdXJjZSA9IGV2ZW50Lm1ldGhvZEFybjtcblxuICAvLyBObyBBdXRob3JpemF0aW9uIGhlYWRlcjogYWxsb3cgYXMgYW5vbnltb3VzIChvcHRpb25hbCBhdXRoIGJlaGF2aW9yKVxuICBpZiAoIWF1dGhIZWFkZXIgfHwgIWF1dGhIZWFkZXIuc3RhcnRzV2l0aCgnQmVhcmVyICcpKSB7XG4gICAgcmV0dXJuIGdlbmVyYXRlUG9saWN5KCdhbm9ueW1vdXMnLCAnQWxsb3cnLCByZXNvdXJjZSwge30pO1xuICB9XG5cbiAgY29uc3Qgand0VG9rZW4gPSBhdXRoSGVhZGVyLnN1YnN0cmluZygnQmVhcmVyICcubGVuZ3RoKTtcblxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCB2ZXJpZnlUb2tlbkFuZEdlbmVyYXRlUG9saWN5KGp3dFRva2VuLCByZXNvdXJjZSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5hdXRob3JpemVkJyk7XG4gIH1cbn1cbiJdfQ==
|