function.js
1 "use strict"; 2 var _a; 3 Object.defineProperty(exports, "__esModule", { value: true }); 4 exports.verifyCodeConfig = exports.Function = exports.Tracing = void 0; 5 const jsiiDeprecationWarnings = require("../.warnings.jsii.js"); 6 const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); 7 const cloudwatch = require("@aws-cdk/aws-cloudwatch"); 8 const aws_codeguruprofiler_1 = require("@aws-cdk/aws-codeguruprofiler"); 9 const ec2 = require("@aws-cdk/aws-ec2"); 10 const iam = require("@aws-cdk/aws-iam"); 11 const logs = require("@aws-cdk/aws-logs"); 12 const sqs = require("@aws-cdk/aws-sqs"); 13 const core_1 = require("@aws-cdk/core"); 14 const function_base_1 = require("./function-base"); 15 const function_hash_1 = require("./function-hash"); 16 const handler_1 = require("./handler"); 17 const lambda_version_1 = require("./lambda-version"); 18 const lambda_generated_1 = require("./lambda.generated"); 19 const layers_1 = require("./layers"); 20 const runtime_1 = require("./runtime"); 21 /** 22 * X-Ray Tracing Modes (https://docs.aws.amazon.com/lambda/latest/dg/API_TracingConfig.html). 23 * 24 * @stability stable 25 */ 26 var Tracing; 27 (function (Tracing) { 28 Tracing["ACTIVE"] = "Active"; 29 Tracing["PASS_THROUGH"] = "PassThrough"; 30 Tracing["DISABLED"] = "Disabled"; 31 })(Tracing = exports.Tracing || (exports.Tracing = {})); 32 /** 33 * Deploys a file from inside the construct library as a function. 34 * 35 * The supplied file is subject to the 4096 bytes limit of being embedded in a 36 * CloudFormation template. 37 * 38 * The construct includes an associated role with the lambda. 39 * 40 * This construct does not yet reproduce all features from the underlying resource 41 * library. 42 * 43 * @stability stable 44 */ 45 class Function extends function_base_1.FunctionBase { 46 /** 47 * @stability stable 48 */ 49 constructor(scope, id, props) { 50 var _b, _c, _d, _e, _f, _g, _h, _j; 51 super(scope, id, { 52 physicalName: props.functionName, 53 }); 54 /** 55 * The construct node where permissions are attached. 56 * 57 * @stability stable 58 */ 59 this.permissionsNode = this.node; 60 /** 61 * Whether the addPermission() call adds any permissions. 62 * 63 * True for new Lambdas, false for version $LATEST and imported Lambdas 64 * from different accounts. 65 * 66 * @stability stable 67 */ 68 this.canCreatePermissions = true; 69 this.layers = []; 70 /** 71 * Environment variables for this function 72 */ 73 this.environment = {}; 74 jsiiDeprecationWarnings._aws_cdk_aws_lambda_FunctionProps(props); 75 const managedPolicies = new Array(); 76 // the arn is in the form of - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 77 managedPolicies.push(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole')); 78 if (props.vpc) { 79 // Policy that will have ENI creation permissions 80 managedPolicies.push(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaVPCAccessExecutionRole')); 81 } 82 this.role = props.role || new iam.Role(this, 'ServiceRole', { 83 assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), 84 managedPolicies, 85 }); 86 this.grantPrincipal = this.role; 87 // add additional managed policies when necessary 88 if (props.filesystem) { 89 const config = props.filesystem.config; 90 if (config.policies) { 91 config.policies.forEach(p => { 92 var _b; 93 (_b = this.role) === null || _b === void 0 ? void 0 : _b.addToPrincipalPolicy(p); 94 }); 95 } 96 } 97 for (const statement of (props.initialPolicy || [])) { 98 this.role.addToPrincipalPolicy(statement); 99 } 100 const code = props.code.bind(this); 101 verifyCodeConfig(code, props); 102 let profilingGroupEnvironmentVariables = {}; 103 if (props.profilingGroup && props.profiling !== false) { 104 this.validateProfiling(props); 105 props.profilingGroup.grantPublish(this.role); 106 profilingGroupEnvironmentVariables = { 107 AWS_CODEGURU_PROFILER_GROUP_ARN: core_1.Stack.of(scope).formatArn({ 108 service: 'codeguru-profiler', 109 resource: 'profilingGroup', 110 resourceName: props.profilingGroup.profilingGroupName, 111 }), 112 AWS_CODEGURU_PROFILER_ENABLED: 'TRUE', 113 }; 114 } 115 else if (props.profiling) { 116 this.validateProfiling(props); 117 const profilingGroup = new aws_codeguruprofiler_1.ProfilingGroup(this, 'ProfilingGroup', { 118 computePlatform: aws_codeguruprofiler_1.ComputePlatform.AWS_LAMBDA, 119 }); 120 profilingGroup.grantPublish(this.role); 121 profilingGroupEnvironmentVariables = { 122 AWS_CODEGURU_PROFILER_GROUP_ARN: profilingGroup.profilingGroupArn, 123 AWS_CODEGURU_PROFILER_ENABLED: 'TRUE', 124 }; 125 } 126 const env = { ...profilingGroupEnvironmentVariables, ...props.environment }; 127 for (const [key, value] of Object.entries(env)) { 128 this.addEnvironment(key, value); 129 } 130 this.deadLetterQueue = this.buildDeadLetterQueue(props); 131 let fileSystemConfigs = undefined; 132 if (props.filesystem) { 133 fileSystemConfigs = [{ 134 arn: props.filesystem.config.arn, 135 localMountPath: props.filesystem.config.localMountPath, 136 }]; 137 } 138 if (props.architecture && props.architectures !== undefined) { 139 throw new Error('Either architecture or architectures must be specified but not both.'); 140 } 141 if (props.architectures && props.architectures.length > 1) { 142 throw new Error('Only one architecture must be specified.'); 143 } 144 const architecture = (_b = props.architecture) !== null && _b !== void 0 ? _b : (props.architectures && props.architectures[0]); 145 const resource = new lambda_generated_1.CfnFunction(this, 'Resource', { 146 functionName: this.physicalName, 147 description: props.description, 148 code: { 149 s3Bucket: code.s3Location && code.s3Location.bucketName, 150 s3Key: code.s3Location && code.s3Location.objectKey, 151 s3ObjectVersion: code.s3Location && code.s3Location.objectVersion, 152 zipFile: code.inlineCode, 153 imageUri: (_c = code.image) === null || _c === void 0 ? void 0 : _c.imageUri, 154 }, 155 layers: core_1.Lazy.list({ produce: () => this.layers.map(layer => layer.layerVersionArn) }, { omitEmpty: true }), 156 handler: props.handler === handler_1.Handler.FROM_IMAGE ? undefined : props.handler, 157 timeout: props.timeout && props.timeout.toSeconds(), 158 packageType: props.runtime === runtime_1.Runtime.FROM_IMAGE ? 'Image' : undefined, 159 runtime: props.runtime === runtime_1.Runtime.FROM_IMAGE ? undefined : props.runtime.name, 160 role: this.role.roleArn, 161 // Uncached because calling '_checkEdgeCompatibility', which gets called in the resolve of another 162 // Token, actually *modifies* the 'environment' map. 163 environment: core_1.Lazy.uncachedAny({ produce: () => this.renderEnvironment() }), 164 memorySize: props.memorySize, 165 vpcConfig: this.configureVpc(props), 166 deadLetterConfig: this.buildDeadLetterConfig(this.deadLetterQueue), 167 tracingConfig: this.buildTracingConfig(props), 168 reservedConcurrentExecutions: props.reservedConcurrentExecutions, 169 imageConfig: undefinedIfNoKeys({ 170 command: (_d = code.image) === null || _d === void 0 ? void 0 : _d.cmd, 171 entryPoint: (_e = code.image) === null || _e === void 0 ? void 0 : _e.entrypoint, 172 workingDirectory: (_f = code.image) === null || _f === void 0 ? void 0 : _f.workingDirectory, 173 }), 174 kmsKeyArn: (_g = props.environmentEncryption) === null || _g === void 0 ? void 0 : _g.keyArn, 175 fileSystemConfigs, 176 codeSigningConfigArn: (_h = props.codeSigningConfig) === null || _h === void 0 ? void 0 : _h.codeSigningConfigArn, 177 architectures: architecture ? [architecture.name] : undefined, 178 }); 179 resource.node.addDependency(this.role); 180 this.functionName = this.getResourceNameAttribute(resource.ref); 181 this.functionArn = this.getResourceArnAttribute(resource.attrArn, { 182 service: 'lambda', 183 resource: 'function', 184 resourceName: this.physicalName, 185 arnFormat: core_1.ArnFormat.COLON_RESOURCE_NAME, 186 }); 187 this.runtime = props.runtime; 188 this.architecture = props.architecture; 189 if (props.layers) { 190 if (props.runtime === runtime_1.Runtime.FROM_IMAGE) { 191 throw new Error('Layers are not supported for container image functions'); 192 } 193 this.addLayers(...props.layers); 194 } 195 for (const event of props.events || []) { 196 this.addEventSource(event); 197 } 198 // Log retention 199 if (props.logRetention) { 200 const logRetention = new logs.LogRetention(this, 'LogRetention', { 201 logGroupName: `/aws/lambda/${this.functionName}`, 202 retention: props.logRetention, 203 role: props.logRetentionRole, 204 logRetentionRetryOptions: props.logRetentionRetryOptions, 205 }); 206 this._logGroup = logs.LogGroup.fromLogGroupArn(this, 'LogGroup', logRetention.logGroupArn); 207 } 208 props.code.bindToResource(resource); 209 // Event Invoke Config 210 if (props.onFailure || props.onSuccess || props.maxEventAge || props.retryAttempts !== undefined) { 211 this.configureAsyncInvoke({ 212 onFailure: props.onFailure, 213 onSuccess: props.onSuccess, 214 maxEventAge: props.maxEventAge, 215 retryAttempts: props.retryAttempts, 216 }); 217 } 218 this.currentVersionOptions = props.currentVersionOptions; 219 if (props.filesystem) { 220 if (!props.vpc) { 221 throw new Error('Cannot configure \'filesystem\' without configuring a VPC.'); 222 } 223 const config = props.filesystem.config; 224 if (config.dependency) { 225 this.node.addDependency(...config.dependency); 226 } 227 // There could be a race if the Lambda is used in a CustomResource. It is possible for the Lambda to 228 // fail to attach to a given FileSystem if we do not have a dependency on the SecurityGroup ingress/egress 229 // rules that were created between this Lambda's SG & the Filesystem SG. 230 this.connections.securityGroups.forEach(sg => { 231 sg.node.findAll().forEach(child => { 232 if (child instanceof core_1.CfnResource && child.cfnResourceType === 'AWS::EC2::SecurityGroupEgress') { 233 resource.node.addDependency(child); 234 } 235 }); 236 }); 237 (_j = config.connections) === null || _j === void 0 ? void 0 : _j.securityGroups.forEach(sg => { 238 sg.node.findAll().forEach(child => { 239 if (child instanceof core_1.CfnResource && child.cfnResourceType === 'AWS::EC2::SecurityGroupIngress') { 240 resource.node.addDependency(child); 241 } 242 }); 243 }); 244 } 245 // Configure Lambda insights 246 this.configureLambdaInsights(props); 247 } 248 /** 249 * Returns a `lambda.Version` which represents the current version of this Lambda function. A new version will be created every time the function's configuration changes. 250 * 251 * You can specify options for this version using the `currentVersionOptions` 252 * prop when initializing the `lambda.Function`. 253 * 254 * @stability stable 255 */ 256 get currentVersion() { 257 if (this._currentVersion) { 258 return this._currentVersion; 259 } 260 this._currentVersion = new lambda_version_1.Version(this, 'CurrentVersion', { 261 lambda: this, 262 ...this.currentVersionOptions, 263 }); 264 // override the version's logical ID with a lazy string which includes the 265 // hash of the function itself, so a new version resource is created when 266 // the function configuration changes. 267 const cfn = this._currentVersion.node.defaultChild; 268 const originalLogicalId = this.stack.resolve(cfn.logicalId); 269 cfn.overrideLogicalId(core_1.Lazy.uncachedString({ 270 produce: () => { 271 const hash = function_hash_1.calculateFunctionHash(this); 272 const logicalId = function_hash_1.trimFromStart(originalLogicalId, 255 - 32); 273 return `${logicalId}${hash}`; 274 }, 275 })); 276 return this._currentVersion; 277 } 278 /** 279 * Record whether specific properties in the `AWS::Lambda::Function` resource should also be associated to the Version resource. 280 * 281 * See 'currentVersion' section in the module README for more details. 282 * 283 * @param propertyName The property to classify. 284 * @param locked whether the property should be associated to the version or not. 285 * @stability stable 286 */ 287 static classifyVersionProperty(propertyName, locked) { 288 this._VER_PROPS[propertyName] = locked; 289 } 290 /** 291 * Import a lambda function into the CDK using its ARN. 292 * 293 * @stability stable 294 */ 295 static fromFunctionArn(scope, id, functionArn) { 296 return Function.fromFunctionAttributes(scope, id, { functionArn }); 297 } 298 /** 299 * Creates a Lambda function object which represents a function not defined within this stack. 300 * 301 * @param scope The parent construct. 302 * @param id The name of the lambda construct. 303 * @param attrs the attributes of the function to import. 304 * @stability stable 305 */ 306 static fromFunctionAttributes(scope, id, attrs) { 307 jsiiDeprecationWarnings._aws_cdk_aws_lambda_FunctionAttributes(attrs); 308 const functionArn = attrs.functionArn; 309 const functionName = extractNameFromArn(attrs.functionArn); 310 const role = attrs.role; 311 class Import extends function_base_1.FunctionBase { 312 constructor(s, i) { 313 var _b; 314 super(s, i); 315 this.functionName = functionName; 316 this.functionArn = functionArn; 317 this.role = role; 318 this.permissionsNode = this.node; 319 this.canCreatePermissions = (_b = attrs.sameEnvironment) !== null && _b !== void 0 ? _b : this._isStackAccount(); 320 this.grantPrincipal = role || new iam.UnknownPrincipal({ resource: this }); 321 if (attrs.securityGroup) { 322 this._connections = new ec2.Connections({ 323 securityGroups: [attrs.securityGroup], 324 }); 325 } 326 else if (attrs.securityGroupId) { 327 this._connections = new ec2.Connections({ 328 securityGroups: [ec2.SecurityGroup.fromSecurityGroupId(scope, 'SecurityGroup', attrs.securityGroupId)], 329 }); 330 } 331 } 332 } 333 return new Import(scope, id); 334 } 335 /** 336 * Return the given named metric for this Lambda. 337 * 338 * @stability stable 339 */ 340 static metricAll(metricName, props) { 341 return new cloudwatch.Metric({ 342 namespace: 'AWS/Lambda', 343 metricName, 344 ...props, 345 }); 346 } 347 /** 348 * Metric for the number of Errors executing all Lambdas. 349 * 350 * @default sum over 5 minutes 351 * @stability stable 352 */ 353 static metricAllErrors(props) { 354 return this.metricAll('Errors', { statistic: 'sum', ...props }); 355 } 356 /** 357 * Metric for the Duration executing all Lambdas. 358 * 359 * @default average over 5 minutes 360 * @stability stable 361 */ 362 static metricAllDuration(props) { 363 return this.metricAll('Duration', props); 364 } 365 /** 366 * Metric for the number of invocations of all Lambdas. 367 * 368 * @default sum over 5 minutes 369 * @stability stable 370 */ 371 static metricAllInvocations(props) { 372 return this.metricAll('Invocations', { statistic: 'sum', ...props }); 373 } 374 /** 375 * Metric for the number of throttled invocations of all Lambdas. 376 * 377 * @default sum over 5 minutes 378 * @stability stable 379 */ 380 static metricAllThrottles(props) { 381 return this.metricAll('Throttles', { statistic: 'sum', ...props }); 382 } 383 /** 384 * Metric for the number of concurrent executions across all Lambdas. 385 * 386 * @default max over 5 minutes 387 * @stability stable 388 */ 389 static metricAllConcurrentExecutions(props) { 390 // Mini-FAQ: why max? This metric is a gauge that is emitted every 391 // minute, so either max or avg or a percentile make sense (but sum 392 // doesn't). Max is more sensitive to spiky load changes which is 393 // probably what you're interested in if you're looking at this metric 394 // (Load spikes may lead to concurrent execution errors that would 395 // otherwise not be visible in the avg) 396 return this.metricAll('ConcurrentExecutions', { statistic: 'max', ...props }); 397 } 398 /** 399 * Metric for the number of unreserved concurrent executions across all Lambdas. 400 * 401 * @default max over 5 minutes 402 * @stability stable 403 */ 404 static metricAllUnreservedConcurrentExecutions(props) { 405 return this.metricAll('UnreservedConcurrentExecutions', { statistic: 'max', ...props }); 406 } 407 /** 408 * Adds an environment variable to this Lambda function. 409 * 410 * If this is a ref to a Lambda function, this operation results in a no-op. 411 * 412 * @param key The environment variable key. 413 * @param value The environment variable's value. 414 * @param options Environment variable options. 415 * @stability stable 416 */ 417 addEnvironment(key, value, options) { 418 jsiiDeprecationWarnings._aws_cdk_aws_lambda_EnvironmentOptions(options); 419 this.environment[key] = { value, ...options }; 420 return this; 421 } 422 /** 423 * Adds one or more Lambda Layers to this Lambda function. 424 * 425 * @param layers the layers to be added. 426 * @stability stable 427 * @throws if there are already 5 layers on this function, or the layer is incompatible with this function's runtime. 428 */ 429 addLayers(...layers) { 430 jsiiDeprecationWarnings._aws_cdk_aws_lambda_ILayerVersion(layers); 431 for (const layer of layers) { 432 if (this.layers.length === 5) { 433 throw new Error('Unable to add layer: this lambda function already uses 5 layers.'); 434 } 435 if (layer.compatibleRuntimes && !layer.compatibleRuntimes.find(runtime => runtime.runtimeEquals(this.runtime))) { 436 const runtimes = layer.compatibleRuntimes.map(runtime => runtime.name).join(', '); 437 throw new Error(`This lambda function uses a runtime that is incompatible with this layer (${this.runtime.name} is not in [${runtimes}])`); 438 } 439 // Currently no validations for compatible architectures since Lambda service 440 // allows layers configured with one architecture to be used with a Lambda function 441 // from another architecture. 442 this.layers.push(layer); 443 } 444 } 445 /** 446 * (deprecated) Add a new version for this Lambda. 447 * 448 * If you want to deploy through CloudFormation and use aliases, you need to 449 * add a new version (with a new name) to your Lambda every time you want to 450 * deploy an update. An alias can then refer to the newly created Version. 451 * 452 * All versions should have distinct names, and you should not delete versions 453 * as long as your Alias needs to refer to them. 454 * 455 * @param name A unique name for this version. 456 * @param codeSha256 The SHA-256 hash of the most recently deployed Lambda source code, or omit to skip validation. 457 * @param description A description for this version. 458 * @param provisionedExecutions A provisioned concurrency configuration for a function's version. 459 * @param asyncInvokeConfig configuration for this version when it is invoked asynchronously. 460 * @returns A new Version object. 461 * @deprecated This method will create an AWS::Lambda::Version resource which 462 * snapshots the AWS Lambda function *at the time of its creation* and it 463 * won't get updated when the function changes. Instead, use 464 * `this.currentVersion` to obtain a reference to a version resource that gets 465 * automatically recreated when the function configuration (or code) changes. 466 */ 467 addVersion(name, codeSha256, description, provisionedExecutions, asyncInvokeConfig = {}) { 468 jsiiDeprecationWarnings.print("@aws-cdk/aws-lambda.Function#addVersion", "This method will create an AWS::Lambda::Version resource which\nsnapshots the AWS Lambda function *at the time of its creation* and it\nwon't get updated when the function changes. Instead, use\n`this.currentVersion` to obtain a reference to a version resource that gets\nautomatically recreated when the function configuration (or code) changes."); 469 jsiiDeprecationWarnings._aws_cdk_aws_lambda_EventInvokeConfigOptions(asyncInvokeConfig); 470 return new lambda_version_1.Version(this, 'Version' + name, { 471 lambda: this, 472 codeSha256, 473 description, 474 provisionedConcurrentExecutions: provisionedExecutions, 475 ...asyncInvokeConfig, 476 }); 477 } 478 /** 479 * The LogGroup where the Lambda function's logs are made available. 480 * 481 * If either `logRetention` is set or this property is called, a CloudFormation custom resource is added to the stack that 482 * pre-creates the log group as part of the stack deployment, if it already doesn't exist, and sets the correct log retention 483 * period (never expire, by default). 484 * 485 * Further, if the log group already exists and the `logRetention` is not set, the custom resource will reset the log retention 486 * to never expire even if it was configured with a different value. 487 * 488 * @stability stable 489 */ 490 get logGroup() { 491 if (!this._logGroup) { 492 const logRetention = new logs.LogRetention(this, 'LogRetention', { 493 logGroupName: `/aws/lambda/${this.functionName}`, 494 retention: logs.RetentionDays.INFINITE, 495 }); 496 this._logGroup = logs.LogGroup.fromLogGroupArn(this, `${this.node.id}-LogGroup`, logRetention.logGroupArn); 497 } 498 return this._logGroup; 499 } 500 /** @internal */ 501 _checkEdgeCompatibility() { 502 // Check env vars 503 const envEntries = Object.entries(this.environment); 504 for (const [key, config] of envEntries) { 505 if (config.removeInEdge) { 506 delete this.environment[key]; 507 core_1.Annotations.of(this).addInfo(`Removed ${key} environment variable for Lambda@Edge compatibility`); 508 } 509 } 510 const envKeys = Object.keys(this.environment); 511 if (envKeys.length !== 0) { 512 throw new Error(`The function ${this.node.path} contains environment variables [${envKeys}] and is not compatible with Lambda@Edge. \ 513 Environment variables can be marked for removal when used in Lambda@Edge by setting the \'removeInEdge\' property in the \'addEnvironment()\' API.`); 514 } 515 return; 516 } 517 /** 518 * Configured lambda insights on the function if specified. This is acheived by adding an imported layer which is added to the 519 * list of lambda layers on synthesis. 520 * 521 * https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights-extension-versions.html 522 */ 523 configureLambdaInsights(props) { 524 var _b; 525 if (props.insightsVersion === undefined) { 526 return; 527 } 528 if (props.runtime !== runtime_1.Runtime.FROM_IMAGE) { 529 // Layers cannot be added to Lambda container images. The image should have the insights agent installed. 530 // See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights-Getting-Started-docker.html 531 this.addLayers(layers_1.LayerVersion.fromLayerVersionArn(this, 'LambdaInsightsLayer', props.insightsVersion.layerVersionArn)); 532 } 533 (_b = this.role) === null || _b === void 0 ? void 0 : _b.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLambdaInsightsExecutionRolePolicy')); 534 } 535 renderEnvironment() { 536 if (!this.environment || Object.keys(this.environment).length === 0) { 537 return undefined; 538 } 539 const variables = {}; 540 // Sort environment so the hash of the function used to create 541 // `currentVersion` is not affected by key order (this is how lambda does 542 // it). For backwards compatibility we do not sort environment variables in case 543 // _currentVersion is not defined. Otherwise, this would have invalidated 544 // the template, and for example, may cause unneeded updates for nested 545 // stacks. 546 const keys = this._currentVersion 547 ? Object.keys(this.environment).sort() 548 : Object.keys(this.environment); 549 for (const key of keys) { 550 variables[key] = this.environment[key].value; 551 } 552 return { variables }; 553 } 554 /** 555 * If configured, set up the VPC-related properties 556 * 557 * Returns the VpcConfig that should be added to the 558 * Lambda creation properties. 559 */ 560 configureVpc(props) { 561 var _b; 562 if ((props.securityGroup || props.allowAllOutbound !== undefined) && !props.vpc) { 563 throw new Error('Cannot configure \'securityGroup\' or \'allowAllOutbound\' without configuring a VPC'); 564 } 565 if (!props.vpc) { 566 return undefined; 567 } 568 if (props.securityGroup && props.allowAllOutbound !== undefined) { 569 throw new Error('Configure \'allowAllOutbound\' directly on the supplied SecurityGroup.'); 570 } 571 let securityGroups; 572 if (props.securityGroup && props.securityGroups) { 573 throw new Error('Only one of the function props, securityGroup or securityGroups, is allowed'); 574 } 575 if (props.securityGroups) { 576 securityGroups = props.securityGroups; 577 } 578 else { 579 const securityGroup = props.securityGroup || new ec2.SecurityGroup(this, 'SecurityGroup', { 580 vpc: props.vpc, 581 description: 'Automatic security group for Lambda Function ' + core_1.Names.uniqueId(this), 582 allowAllOutbound: props.allowAllOutbound, 583 }); 584 securityGroups = [securityGroup]; 585 } 586 this._connections = new ec2.Connections({ securityGroups }); 587 if (props.filesystem) { 588 if (props.filesystem.config.connections) { 589 props.filesystem.config.connections.allowDefaultPortFrom(this); 590 } 591 } 592 const allowPublicSubnet = (_b = props.allowPublicSubnet) !== null && _b !== void 0 ? _b : false; 593 const { subnetIds } = props.vpc.selectSubnets(props.vpcSubnets); 594 const publicSubnetIds = new Set(props.vpc.publicSubnets.map(s => s.subnetId)); 595 for (const subnetId of subnetIds) { 596 if (publicSubnetIds.has(subnetId) && !allowPublicSubnet) { 597 throw new Error('Lambda Functions in a public subnet can NOT access the internet. ' + 598 'If you are aware of this limitation and would still like to place the function int a public subnet, set `allowPublicSubnet` to true'); 599 } 600 } 601 // List can't be empty here, if we got this far you intended to put your Lambda 602 // in subnets. We're going to guarantee that we get the nice error message by 603 // making VpcNetwork do the selection again. 604 return { 605 subnetIds, 606 securityGroupIds: securityGroups.map(sg => sg.securityGroupId), 607 }; 608 } 609 buildDeadLetterQueue(props) { 610 if (props.deadLetterQueue && props.deadLetterQueueEnabled === false) { 611 throw Error('deadLetterQueue defined but deadLetterQueueEnabled explicitly set to false'); 612 } 613 if (!props.deadLetterQueue && !props.deadLetterQueueEnabled) { 614 return undefined; 615 } 616 const deadLetterQueue = props.deadLetterQueue || new sqs.Queue(this, 'DeadLetterQueue', { 617 retentionPeriod: core_1.Duration.days(14), 618 }); 619 this.addToRolePolicy(new iam.PolicyStatement({ 620 actions: ['sqs:SendMessage'], 621 resources: [deadLetterQueue.queueArn], 622 })); 623 return deadLetterQueue; 624 } 625 buildDeadLetterConfig(deadLetterQueue) { 626 if (deadLetterQueue) { 627 return { 628 targetArn: deadLetterQueue.queueArn, 629 }; 630 } 631 else { 632 return undefined; 633 } 634 } 635 buildTracingConfig(props) { 636 if (props.tracing === undefined || props.tracing === Tracing.DISABLED) { 637 return undefined; 638 } 639 this.addToRolePolicy(new iam.PolicyStatement({ 640 actions: ['xray:PutTraceSegments', 'xray:PutTelemetryRecords'], 641 resources: ['*'], 642 })); 643 return { 644 mode: props.tracing, 645 }; 646 } 647 validateProfiling(props) { 648 if (!props.runtime.supportsCodeGuruProfiling) { 649 throw new Error(`CodeGuru profiling is not supported by runtime ${props.runtime.name}`); 650 } 651 if (props.environment && (props.environment.AWS_CODEGURU_PROFILER_GROUP_ARN || props.environment.AWS_CODEGURU_PROFILER_ENABLED)) { 652 throw new Error('AWS_CODEGURU_PROFILER_GROUP_ARN and AWS_CODEGURU_PROFILER_ENABLED must not be set when profiling options enabled'); 653 } 654 } 655 } 656 exports.Function = Function; 657 _a = JSII_RTTI_SYMBOL_1; 658 Function[_a] = { fqn: "@aws-cdk/aws-lambda.Function", version: "1.134.0" }; 659 /** @internal */ 660 Function._VER_PROPS = {}; 661 /** 662 * Given an opaque (token) ARN, returns a CloudFormation expression that extracts the function 663 * name from the ARN. 664 * 665 * Function ARNs look like this: 666 * 667 * arn:aws:lambda:region:account-id:function:function-name 668 * 669 * ..which means that in order to extract the `function-name` component from the ARN, we can 670 * split the ARN using ":" and select the component in index 6. 671 * 672 * @returns `FnSelect(6, FnSplit(':', arn))` 673 */ 674 function extractNameFromArn(arn) { 675 return core_1.Fn.select(6, core_1.Fn.split(':', arn)); 676 } 677 function verifyCodeConfig(code, props) { 678 // mutually exclusive 679 const codeType = [code.inlineCode, code.s3Location, code.image]; 680 if (codeType.filter(x => !!x).length !== 1) { 681 throw new Error('lambda.Code must specify exactly one of: "inlineCode", "s3Location", or "image"'); 682 } 683 if (!!code.image === (props.handler !== handler_1.Handler.FROM_IMAGE)) { 684 throw new Error('handler must be `Handler.FROM_IMAGE` when using image asset for Lambda function'); 685 } 686 if (!!code.image === (props.runtime !== runtime_1.Runtime.FROM_IMAGE)) { 687 throw new Error('runtime must be `Runtime.FROM_IMAGE` when using image asset for Lambda function'); 688 } 689 // if this is inline code, check that the runtime supports 690 if (code.inlineCode && !props.runtime.supportsInlineCode) { 691 throw new Error(`Inline source not allowed for ${props.runtime.name}`); 692 } 693 } 694 exports.verifyCodeConfig = verifyCodeConfig; 695 function undefinedIfNoKeys(struct) { 696 const allUndefined = Object.values(struct).every(val => val === undefined); 697 return allUndefined ? undefined : struct; 698 } 699 //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJmdW5jdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxzREFBc0Q7QUFDdEQsd0VBQWlHO0FBQ2pHLHdDQUF3QztBQUN4Qyx3Q0FBd0M7QUFFeEMsMENBQTBDO0FBQzFDLHdDQUF3QztBQUN4Qyx3Q0FBc0c7QUFRdEcsbURBQThFO0FBQzlFLG1EQUF1RTtBQUN2RSx1Q0FBb0M7QUFFcEMscURBQTJEO0FBQzNELHlEQUFpRDtBQUNqRCxxQ0FBdUQ7QUFDdkQsdUNBQW9DOzs7Ozs7QUFPcEMsSUFBWSxPQU9YO0FBUEQsV0FBWSxPQUFPO0lBRWpCLDRCQUFpQixDQUFBO0lBRWpCLHVDQUE0QixDQUFBO0lBRTVCLGdDQUFxQixDQUFBO0FBQ3ZCLENBQUMsRUFQVyxPQUFPLEdBQVAsZUFBTyxLQUFQLGVBQU8sUUFPbEI7Ozs7Ozs7Ozs7Ozs7O0FBOEdELE1BQWEsUUFBUyxTQUFRLDRCQUFZOzs7O0lBK0p4QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQW9COztRQUM1RCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNmLFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWTtTQUNqQyxDQUFDLENBQUM7Ozs7OztRQXBCVyxvQkFBZSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7Ozs7Ozs7OztRQUd6Qix5QkFBb0IsR0FBRyxJQUFJLENBQUM7UUFFOUIsV0FBTSxHQUFvQixFQUFFLENBQUM7UUFJOUM7O1dBRUc7UUFDSyxnQkFBVyxHQUF5QyxFQUFFLENBQUM7O1FBVTdELE1BQU0sZUFBZSxHQUFHLElBQUksS0FBSyxFQUFzQixDQUFDO1FBRXhELCtGQUErRjtRQUMvRixlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsd0JBQXdCLENBQUMsMENBQTBDLENBQUMsQ0FBQyxDQUFDO1FBRTdHLElBQUksS0FBSyxDQUFDLEdBQUcsRUFBRTtZ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QUFJLENBQUMsVUFBVSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRTtRQUN4RCxNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxLQUFLLENBQUMsT0FBUSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7S0FDekU7QUFDSCxDQUFDO0FBcEJELDRDQW9CQztBQUVELFNBQVMsaUJBQWlCLENBQUksTUFBUztJQUNyQyxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxTQUFTLENBQUMsQ0FBQztJQUMzRSxPQUFPLFlBQVksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDM0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSAnQGF3cy1jZGsvYXdzLWNsb3Vkd2F0Y2gnO1xuaW1wb3J0IHsgSVByb2ZpbGluZ0dyb3VwLCBQcm9maWxpbmdHcm91cCwgQ29tcHV0ZVBsYXRmb3JtIH0gZnJvbSAnQGF3cy1jZGsvYXdzLWNvZGVndXJ1cHJvZmlsZXInO1xuaW1wb3J0ICogYXMgZWMyIGZyb20gJ0Bhd3MtY2RrL2F3cy1lYzInO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ0Bhd3MtY2RrL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMga21zIGZyb20gJ0Bhd3MtY2RrL2F3cy1rbXMnO1xuaW1wb3J0ICogYXMgbG9ncyBmcm9tICdAYXdzLWNkay9hd3MtbG9ncyc7XG5pbXBvcnQgKiBhcyBzcXMgZnJvbSAnQGF3cy1jZGsvYXdzLXNxcyc7XG5pbXBvcnQgeyBBbm5vdGF0aW9ucywgQXJuRm9ybWF0LCBDZm5SZXNvdXJjZSwgRHVyYXRpb24sIEZuLCBMYXp5LCBOYW1lcywgU3RhY2sgfSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQXJjaGl0ZWN0dXJlIH0gZnJvbSAnLi9hcmNoaXRlY3R1cmUnO1xuaW1wb3J0IHsgQ29kZSwgQ29kZUNvbmZpZyB9IGZyb20gJy4vY29kZSc7XG5pbXBvcnQgeyBJQ29kZVNpZ25pbmdDb25maWcgfSBmcm9tICcuL2NvZGUtc2lnbmluZy1jb25maWcnO1xuaW1wb3J0IHsgRXZlbnRJbnZva2VDb25maWdPcHRpb25zIH0gZnJvbSAnLi9ldmVudC1pbnZva2UtY29uZmlnJztcbmltcG9ydCB7IElFdmVudFNvdXJjZSB9IGZyb20gJy4vZXZlbnQtc291cmNlJztcbmltcG9ydCB7IEZpbGVTeXN0ZW0gfSBmcm9tICcuL2ZpbGVzeXN0ZW0nO1xuaW1wb3J0IHsgRnVuY3Rpb25BdHRyaWJ1dGVzLCBGdW5jdGlvbkJhc2UsIElGdW5jdGlvbiB9IGZyb20gJy4vZnVuY3Rpb24tYmFzZSc7XG5pbXBvcnQgeyBjYWxjdWxhdGVGdW5jdGlvbkhhc2gsIHRyaW1Gcm9tU3RhcnQgfSBmcm9tICcuL2Z1bmN0aW9uLWhhc2gnO1xuaW1wb3J0IHsgSGFuZGxlciB9IGZyb20gJy4vaGFuZGxlcic7XG5pbXBvcnQgeyBMYW1iZGFJbnNpZ2h0c1ZlcnNpb24gfSBmcm9tICcuL2xhbWJkYS1pbnNpZ2h0cyc7XG5pbXBvcnQgeyBWZXJzaW9uLCBWZXJzaW9uT3B0aW9ucyB9IGZyb20gJy4vbGFtYmRhLXZlcnNpb24nO1xuaW1wb3J0IHsgQ2ZuRnVuY3Rpb24gfSBmcm9tICcuL2xhbWJkYS5nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgTGF5ZXJWZXJzaW9uLCBJTGF5ZXJWZXJzaW9uIH0gZnJvbSAnLi9sYXllcnMnO1xuaW1wb3J0IHsgUnVudGltZSB9IGZyb20gJy4vcnVudGltZSc7XG5cbi8vIGtlZXAgdGhpcyBpbXBvcnQgc2VwYXJhdGUgZnJvbSBvdGhlciBpbXBvcnRzIHRvIHJlZHVjZSBjaGFuY2UgZm9yIG1lcmdlIGNvbmZsaWN0cyB3aXRoIHYyLW1haW5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuaW1wb3J0IHsgTG9nUmV0ZW50aW9uUmV0cnlPcHRpb25zIH0gZnJvbSAnLi9sb2ctcmV0ZW50aW9uJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGVudW0gVHJhY2luZyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBBQ1RJVkUgPSAnQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgUEFTU19USFJPVUdIID0gJ1Bhc3NUaHJvdWdoJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBESVNBQkxFRCA9ICdEaXNhYmxlZCdcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIEZ1bmN0aW9uT3B0aW9ucyBleHRlbmRzIEV2ZW50SW52b2tlQ29uZmlnT3B0aW9ucyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSB0aW1lb3V0PzogRHVyYXRpb247XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGZ1bmN0aW9uTmFtZT86IHN0cmluZztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBtZW1vcnlTaXplPzogbnVtYmVyO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGluaXRpYWxQb2xpY3k/OiBpYW0uUG9saWN5U3RhdGVtZW50W107XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgcm9sZT86IGlhbS5JUm9sZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgdnBjPzogZWMyLklWcGM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgdnBjU3VibmV0cz86IGVjMi5TdWJuZXRTZWxlY3Rpb247XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXA/OiBlYzIuSVNlY3VyaXR5R3JvdXA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgc2VjdXJpdHlHcm91cHM/OiBlYzIuSVNlY3VyaXR5R3JvdXBbXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGFsbG93QWxsT3V0Ym91bmQ/OiBib29sZWFuO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZGVhZExldHRlclF1ZXVlRW5hYmxlZD86IGJvb2xlYW47XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZGVhZExldHRlclF1ZXVlPzogc3FzLklRdWV1ZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgdHJhY2luZz86IFRyYWNpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHByb2ZpbGluZz86IGJvb2xlYW47XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBwcm9maWxpbmdHcm91cD86IElQcm9maWxpbmdHcm91cDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgaW5zaWdodHNWZXJzaW9uPzogTGFtYmRhSW5zaWdodHNWZXJzaW9uO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBsYXllcnM/OiBJTGF5ZXJWZXJzaW9uW107XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgcmVzZXJ2ZWRDb25jdXJyZW50RXhlY3V0aW9ucz86IG51bWJlcjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGV2ZW50cz86IElFdmVudFNvdXJjZVtdO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgbG9nUmV0ZW50aW9uPzogbG9ncy5SZXRlbnRpb25EYXlzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBsb2dSZXRlbnRpb25Sb2xlPzogaWFtLklSb2xlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGxvZ1JldGVudGlvblJldHJ5T3B0aW9ucz86IExvZ1JldGVudGlvblJldHJ5T3B0aW9ucztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgY3VycmVudFZlcnNpb25PcHRpb25zPzogVmVyc2lvbk9wdGlvbnM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBmaWxlc3lzdGVtPzogRmlsZVN5c3RlbTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBhbGxvd1B1YmxpY1N1Ym5ldD86IGJvb2xlYW47XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGVudmlyb25tZW50RW5jcnlwdGlvbj86IGttcy5JS2V5O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgY29kZVNpZ25pbmdDb25maWc/OiBJQ29kZVNpZ25pbmdDb25maWc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBhcmNoaXRlY3R1cmVzPzogQXJjaGl0ZWN0dXJlW107XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGFyY2hpdGVjdHVyZT86IEFyY2hpdGVjdHVyZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGdW5jdGlvblByb3BzIGV4dGVuZHMgRnVuY3Rpb25PcHRpb25zIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgcnVudGltZTogUnVudGltZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBjb2RlOiBDb2RlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgaGFuZGxlcjogc3RyaW5nO1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGNsYXNzIEZ1bmN0aW9uIGV4dGVuZHMgRnVuY3Rpb25CYXNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBnZXQgY3VycmVudFZlcnNpb24oKTogVmVyc2lvbiB7XG4gICAgaWYgKHRoaXMuX2N1cnJlbnRWZXJzaW9uKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY3VycmVudFZlcnNpb247XG4gICAgfVxuXG4gICAgdGhpcy5fY3VycmVudFZlcnNpb24gPSBuZXcgVmVyc2lvbih0aGlzLCAnQ3VycmVudFZlcnNpb24nLCB7XG4gICAgICBsYW1iZGE6IHRoaXMsXG4gICAgICAuLi50aGlzLmN1cnJlbnRWZXJzaW9uT3B0aW9ucyxcbiAgICB9KTtcblxuICAgIC8vIG92ZXJyaWRlIHRoZSB2ZXJzaW9uJ3MgbG9naWNhbCBJRCB3aXRoIGEgbGF6eSBzdHJpbmcgd2hpY2ggaW5jbHVkZXMgdGhlXG4gICAgLy8gaGFzaCBvZiB0aGUgZnVuY3Rpb24gaXRzZWxmLCBzbyBhIG5ldyB2ZXJzaW9uIHJlc291cmNlIGlzIGNyZWF0ZWQgd2hlblxuICAgIC8vIHRoZSBmdW5jdGlvbiBjb25maWd1cmF0aW9uIGNoYW5nZXMuXG4gICAgY29uc3QgY2ZuID0gdGhpcy5fY3VycmVudFZlcnNpb24ubm9kZS5kZWZhdWx0Q2hpbGQgYXMgQ2ZuUmVzb3VyY2U7XG4gICAgY29uc3Qgb3JpZ2luYWxMb2dpY2FsSWQgPSB0aGlzLnN0YWNrLnJlc29sdmUoY2ZuLmxvZ2ljYWxJZCkgYXMgc3RyaW5nO1xuXG4gICAgY2ZuLm92ZXJyaWRlTG9naWNhbElkKExhenkudW5jYWNoZWRTdHJpbmcoe1xuICAgICAgcHJvZHVjZTogKCkgPT4ge1xuICAgICAgICBjb25zdCBoYXNoID0gY2FsY3VsYXRlRnVuY3Rpb25IYXNoKHRoaXMpO1xuICAgICAgICBjb25zdCBsb2dpY2FsSWQgPSB0cmltRnJvbVN0YXJ0KG9yaWdpbmFsTG9naWNhbElkLCAyNTUgLSAzMik7XG4gICAgICAgIHJldHVybiBgJHtsb2dpY2FsSWR9JHtoYXNofWA7XG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIHJldHVybiB0aGlzLl9jdXJyZW50VmVyc2lvbjtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHVibGljIHN0YXRpYyBfVkVSX1BST1BTOiB7IFtrZXk6IHN0cmluZ106IGJvb2xlYW4gfSA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBjbGFzc2lmeVZlcnNpb25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWU6IHN0cmluZywgbG9ja2VkOiBib29sZWFuKSB7XG4gICAgdGhpcy5fVkVSX1BST1BTW3Byb3BlcnR5TmFtZV0gPSBsb2NrZWQ7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBmcm9tRnVuY3Rpb25Bcm4oc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgZnVuY3Rpb25Bcm46IHN0cmluZyk6IElGdW5jdGlvbiB7XG4gICAgcmV0dXJuIEZ1bmN0aW9uLmZyb21GdW5jdGlvbkF0dHJpYnV0ZXMoc2NvcGUsIGlkLCB7IGZ1bmN0aW9uQXJuIH0pO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIGZyb21GdW5jdGlvbkF0dHJpYnV0ZXMoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgYXR0cnM6IEZ1bmN0aW9uQXR0cmlidXRlcyk6IElGdW5jdGlvbiB7XG4gICAgY29uc3QgZnVuY3Rpb25Bcm4gPSBhdHRycy5mdW5jdGlvbkFybjtcbiAgICBjb25zdCBmdW5jdGlvbk5hbWUgPSBleHRyYWN0TmFtZUZyb21Bcm4oYXR0cnMuZnVuY3Rpb25Bcm4pO1xuICAgIGNvbnN0IHJvbGUgPSBhdHRycy5yb2xlO1xuXG4gICAgY2xhc3MgSW1wb3J0IGV4dGVuZHMgRnVuY3Rpb25CYXNlIHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBmdW5jdGlvbk5hbWUgPSBmdW5jdGlvbk5hbWU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZnVuY3Rpb25Bcm4gPSBmdW5jdGlvbkFybjtcbiAgICAgIHB1YmxpYyByZWFkb25seSBncmFudFByaW5jaXBhbDogaWFtLklQcmluY2lwYWw7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcm9sZSA9IHJvbGU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcGVybWlzc2lvbnNOb2RlID0gdGhpcy5ub2RlO1xuXG4gICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2FuQ3JlYXRlUGVybWlzc2lvbnMgPSBhdHRycy5zYW1lRW52aXJvbm1lbnQgPz8gdGhpcy5faXNTdGFja0FjY291bnQoKTtcblxuICAgICAgY29uc3RydWN0b3IoczogQ29uc3RydWN0LCBpOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIocywgaSk7XG5cbiAgICAgICAgdGhpcy5ncmFudFByaW5jaXBhbCA9IHJvbGUgfHwgbmV3IGlhbS5Vbmtub3duUHJpbmNpcGFsKHsgcmVzb3VyY2U6IHRoaXMgfSk7XG5cbiAgICAgICAgaWYgKGF0dHJzLnNlY3VyaXR5R3JvdXApIHtcbiAgICAgICAgICB0aGlzLl9jb25uZWN0aW9ucyA9IG5ldyBlYzIuQ29ubmVjdGlvbnMoe1xuICAgICAgICAgICAgc2VjdXJpdHlHcm91cHM6IFthdHRycy5zZWN1cml0eUdyb3VwXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChhdHRycy5zZWN1cml0eUdyb3VwSWQpIHtcbiAgICAgICAgICB0aGlzLl9jb25uZWN0aW9ucyA9IG5ldyBlYzIuQ29ubmVjdGlvbnMoe1xuICAgICAgICAgICAgc2VjdXJpdHlHcm91cHM6IFtlYzIuU2VjdXJpdHlHcm91cC5mcm9tU2VjdXJpdHlHcm91cElkKHNjb3BlLCAnU2VjdXJpdHlHcm91cCcsIGF0dHJzLnNlY3VyaXR5R3JvdXBJZCldLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIG1ldHJpY0FsbChtZXRyaWNOYW1lOiBzdHJpbmcsIHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiBuZXcgY2xvdWR3YXRjaC5NZXRyaWMoe1xuICAgICAgbmFtZXNwYWNlOiAnQVdTL0xhbWJkYScsXG4gICAgICBtZXRyaWNOYW1lLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIG1ldHJpY0FsbEVycm9ycyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNBbGwoJ0Vycm9ycycsIHsgc3RhdGlzdGljOiAnc3VtJywgLi4ucHJvcHMgfSk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBtZXRyaWNBbGxEdXJhdGlvbihwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNBbGwoJ0R1cmF0aW9uJywgcHJvcHMpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBtZXRyaWNBbGxJbnZvY2F0aW9ucyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNBbGwoJ0ludm9jYXRpb25zJywgeyBzdGF0aXN0aWM6ICdzdW0nLCAuLi5wcm9wcyB9KTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIG1ldHJpY0FsbFRocm90dGxlcyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNBbGwoJ1Rocm90dGxlcycsIHsgc3RhdGlzdGljOiAnc3VtJywgLi4ucHJvcHMgfSk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgbWV0cmljQWxsQ29uY3VycmVudEV4ZWN1dGlvbnMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgLy8gTWluaS1GQVE6IHdoeSBtYXg/IFRoaXMgbWV0cmljIGlzIGEgZ2F1Z2UgdGhhdCBpcyBlbWl0dGVkIGV2ZXJ5XG4gICAgLy8gbWludXRlLCBzbyBlaXRoZXIgbWF4IG9yIGF2ZyBvciBhIHBlcmNlbnRpbGUgbWFrZSBzZW5zZSAoYnV0IHN1bVxuICAgIC8vIGRvZXNuJ3QpLiBNYXggaXMgbW9yZSBzZW5zaXRpdmUgdG8gc3Bpa3kgbG9hZCBjaGFuZ2VzIHdoaWNoIGlzXG4gICAgLy8gcHJvYmFibHkgd2hhdCB5b3UncmUgaW50ZXJlc3RlZCBpbiBpZiB5b3UncmUgbG9va2luZyBhdCB0aGlzIG1ldHJpY1xuICAgIC8vIChMb2FkIHNwaWtlcyBtYXkgbGVhZCB0byBjb25jdXJyZW50IGV4ZWN1dGlvbiBlcnJvcnMgdGhhdCB3b3VsZFxuICAgIC8vIG90aGVyd2lzZSBub3QgYmUgdmlzaWJsZSBpbiB0aGUgYXZnKVxuICAgIHJldHVybiB0aGlzLm1ldHJpY0FsbCgnQ29uY3VycmVudEV4ZWN1dGlvbnMnLCB7IHN0YXRpc3RpYzogJ21heCcsIC4uLnByb3BzIH0pO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgbWV0cmljQWxsVW5yZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY0FsbCgnVW5yZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zJywgeyBzdGF0aXN0aWM6ICdtYXgnLCAuLi5wcm9wcyB9KTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcmVhZG9ubHkgZnVuY3Rpb25OYW1lOiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHJlYWRvbmx5IGZ1bmN0aW9uQXJuOiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHJlYWRvbmx5IHJvbGU/OiBpYW0uSVJvbGU7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZWFkb25seSBydW50aW1lOiBSdW50aW1lO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRQcmluY2lwYWw6IGlhbS5JUHJpbmNpcGFsO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZWFkb25seSBkZWFkTGV0dGVyUXVldWU/OiBzcXMuSVF1ZXVlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcmVhZG9ubHkgYXJjaGl0ZWN0dXJlPzogQXJjaGl0ZWN0dXJlO1xuICBwdWJsaWMgcmVhZG9ubHkgcGVybWlzc2lvbnNOb2RlID0gdGhpcy5ub2RlO1xuXG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNhbkNyZWF0ZVBlcm1pc3Npb25zID0gdHJ1ZTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGxheWVyczogSUxheWVyVmVyc2lvbltdID0gW107XG5cbiAgcHJpdmF0ZSBfbG9nR3JvdXA/OiBsb2dzLklMb2dHcm91cDtcblxuICAvKipcbiAgICogRW52aXJvbm1lbnQgdmFyaWFibGVzIGZvciB0aGlzIGZ1bmN0aW9uXG4gICAqL1xuICBwcml2YXRlIGVudmlyb25tZW50OiB7IFtrZXk6IHN0cmluZ106IEVudmlyb25tZW50Q29uZmlnIH0gPSB7fTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGN1cnJlbnRWZXJzaW9uT3B0aW9ucz86IFZlcnNpb25PcHRpb25zO1xuICBwcml2YXRlIF9jdXJyZW50VmVyc2lvbj86IFZlcnNpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEZ1bmN0aW9uUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHBoeXNpY2FsTmFtZTogcHJvcHMuZnVuY3Rpb25OYW1lLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWFuYWdlZFBvbGljaWVzID0gbmV3IEFycmF5PGlhbS5JTWFuYWdlZFBvbGljeT4oKTtcblxuICAgIC8vIHRoZSBhcm4gaXMgaW4gdGhlIGZvcm0gb2YgLSBhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9zZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlXG4gICAgbWFuYWdlZFBvbGljaWVzLnB1c2goaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdzZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlJykpO1xuXG4gICAgaWYgKHByb3BzLnZwYykge1xuICAgICAgLy8gUG9saWN5IHRoYXQgd2lsbCBoYXZlIEVOSSBjcmVhdGlvbiBwZXJtaXNzaW9uc1xuICAgICAgbWFuYWdlZFBvbGljaWVzLnB1c2goaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdzZXJ2aWNlLXJvbGUvQVdTTGFtYmRhVlBDQWNjZXNzRXhlY3V0aW9uUm9sZScpKTtcbiAgICB9XG5cbiAgICB0aGlzLnJvbGUgPSBwcm9wcy5yb2xlIHx8IG5ldyBpYW0uUm9sZSh0aGlzLCAnU2VydmljZVJvbGUnLCB7XG4gICAgICBhc3N1bWVkQnk6IG5ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnbGFtYmRhLmFtYXpvbmF3cy5jb20nKSxcbiAgICAgIG1hbmFnZWRQb2xpY2llcyxcbiAgICB9KTtcbiAgICB0aGlzLmdyYW50UHJpbmNpcGFsID0gdGhpcy5yb2xlO1xuXG4gICAgLy8gYWRkIGFkZGl0aW9uYWwgbWFuYWdlZCBwb2xpY2llcyB3aGVuIG5lY2Vzc2FyeVxuICAgIGlmIChwcm9wcy5maWxlc3lzdGVtKSB7XG4gICAgICBjb25zdCBjb25maWcgPSBwcm9wcy5maWxlc3lzdGVtLmNvbmZpZztcbiAgICAgIGlmIChjb25maWcucG9saWNpZXMpIHtcbiAgICAgICAgY29uZmlnLnBvbGljaWVzLmZvckVhY2gocCA9PiB7XG4gICAgICAgICAgdGhpcy5yb2xlPy5hZGRUb1ByaW5jaXBhbFBvbGljeShwKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgKHByb3BzLmluaXRpYWxQb2xpY3kgfHwgW10pKSB7XG4gICAgICB0aGlzLnJvbGUuYWRkVG9QcmluY2lwYWxQb2xpY3koc3RhdGVtZW50KTtcbiAgICB9XG5cbiAgICBjb25zdCBjb2RlID0gcHJvcHMuY29kZS5iaW5kKHRoaXMpO1xuICAgIHZlcmlmeUNvZGVDb25maWcoY29kZSwgcHJvcHMpO1xuXG4gICAgbGV0IHByb2ZpbGluZ0dyb3VwRW52aXJvbm1lbnRWYXJpYWJsZXM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBpZiAocHJvcHMucHJvZmlsaW5nR3JvdXAgJiYgcHJvcHMucHJvZmlsaW5nICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy52YWxpZGF0ZVByb2ZpbGluZyhwcm9wcyk7XG4gICAgICBwcm9wcy5wcm9maWxpbmdHcm91cC5ncmFudFB1Ymxpc2godGhpcy5yb2xlKTtcbiAgICAgIHByb2ZpbGluZ0dyb3VwRW52aXJvbm1lbnRWYXJpYWJsZXMgPSB7XG4gICAgICAgIEFXU19DT0RFR1VSVV9QUk9GSUxFUl9HUk9VUF9BUk46IFN0YWNrLm9mKHNjb3BlKS5mb3JtYXRBcm4oe1xuICAgICAgICAgIHNlcnZpY2U6ICdjb2RlZ3VydS1wcm9maWxlcicsXG4gICAgICAgICAgcmVzb3VyY2U6ICdwcm9maWxpbmdHcm91cCcsXG4gICAgICAgICAgcmVzb3VyY2VOYW1lOiBwcm9wcy5wcm9maWxpbmdHcm91cC5wcm9maWxpbmdHcm91cE5hbWUsXG4gICAgICAgIH0pLFxuICAgICAgICBBV1NfQ09ERUdVUlVfUFJPRklMRVJfRU5BQkxFRDogJ1RSVUUnLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHByb3BzLnByb2ZpbGluZykge1xuICAgICAgdGhpcy52YWxpZGF0ZVByb2ZpbGluZyhwcm9wcyk7XG4gICAgICBjb25zdCBwcm9maWxpbmdHcm91cCA9IG5ldyBQcm9maWxpbmdHcm91cCh0aGlzLCAnUHJvZmlsaW5nR3JvdXAnLCB7XG4gICAgICAgIGNvbXB1dGVQbGF0Zm9ybTogQ29tcHV0ZVBsYXRmb3JtLkFXU19MQU1CREEsXG4gICAgICB9KTtcbiAgICAgIHByb2ZpbGluZ0dyb3VwLmdyYW50UHVibGlzaCh0aGlzLnJvbGUpO1xuICAgICAgcHJvZmlsaW5nR3JvdXBFbnZpcm9ubWVudFZhcmlhYmxlcyA9IHtcbiAgICAgICAgQVdTX0NPREVHVVJVX1BST0ZJTEVSX0dST1VQX0FSTjogcHJvZmlsaW5nR3JvdXAucHJvZmlsaW5nR3JvdXBBcm4sXG4gICAgICAgIEFXU19DT0RFR1VSVV9QUk9GSUxFUl9FTkFCTEVEOiAnVFJVRScsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IGVudiA9IHsgLi4ucHJvZmlsaW5nR3JvdXBFbnZpcm9ubWVudFZhcmlhYmxlcywgLi4ucHJvcHMuZW52aXJvbm1lbnQgfTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnYpKSB7XG4gICAgICB0aGlzLmFkZEVudmlyb25tZW50KGtleSwgdmFsdWUpO1xuICAgIH1cblxuICAgIHRoaXMuZGVhZExldHRlclF1ZXVlID0gdGhpcy5idWlsZERlYWRMZXR0ZXJRdWV1ZShwcm9wcyk7XG5cbiAgICBsZXQgZmlsZVN5c3RlbUNvbmZpZ3M6IENmbkZ1bmN0aW9uLkZpbGVTeXN0ZW1Db25maWdQcm9wZXJ0eVtdIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGlmIChwcm9wcy5maWxlc3lzdGVtKSB7XG4gICAgICBmaWxlU3lzdGVtQ29uZmlncyA9IFt7XG4gICAgICAgIGFybjogcHJvcHMuZmlsZXN5c3RlbS5jb25maWcuYXJuLFxuICAgICAgICBsb2NhbE1vdW50UGF0aDogcHJvcHMuZmlsZXN5c3RlbS5jb25maWcubG9jYWxNb3VudFBhdGgsXG4gICAgICB9XTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuYXJjaGl0ZWN0dXJlICYmIHByb3BzLmFyY2hpdGVjdHVyZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgYXJjaGl0ZWN0dXJlIG9yIGFyY2hpdGVjdHVyZXMgbXVzdCBiZSBzcGVjaWZpZWQgYnV0IG5vdCBib3RoLicpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuYXJjaGl0ZWN0dXJlcyAmJiBwcm9wcy5hcmNoaXRlY3R1cmVzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgYXJjaGl0ZWN0dXJlIG11c3QgYmUgc3BlY2lmaWVkLicpO1xuICAgIH1cbiAgICBjb25zdCBhcmNoaXRlY3R1cmUgPSBwcm9wcy5hcmNoaXRlY3R1cmUgPz8gKHByb3BzLmFyY2hpdGVjdHVyZXMgJiYgcHJvcHMuYXJjaGl0ZWN0dXJlc1swXSk7XG5cbiAgICBjb25zdCByZXNvdXJjZTogQ2ZuRnVuY3Rpb24gPSBuZXcgQ2ZuRnVuY3Rpb24odGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgZnVuY3Rpb25OYW1lOiB0aGlzLnBoeXNpY2FsTmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBwcm9wcy5kZXNjcmlwdGlvbixcbiAgICAgIGNvZGU6IHtcbiAgICAgICAgczNCdWNrZXQ6IGNvZGUuczNMb2NhdGlvbiAmJiBjb2RlLnMzTG9jYXRpb24uYnVja2V0TmFtZSxcbiAgICAgICAgczNLZXk6IGNvZGUuczNMb2NhdGlvbiAmJiBjb2RlLnMzTG9jYXRpb24ub2JqZWN0S2V5LFxuICAgICAgICBzM09iamVjdFZlcnNpb246IGNvZGUuczNMb2NhdGlvbiAmJiBjb2RlLnMzTG9jYXRpb24ub2JqZWN0VmVyc2lvbixcbiAgICAgICAgemlwRmlsZTogY29kZS5pbmxpbmVDb2RlLFxuICAgICAgICBpbWFnZVVyaTogY29kZS5pbWFnZT8uaW1hZ2VVcmksXG4gICAgICB9LFxuICAgICAgbGF5ZXJzOiBMYXp5Lmxpc3QoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLmxheWVycy5tYXAobGF5ZXIgPT4gbGF5ZXIubGF5ZXJWZXJzaW9uQXJuKSB9LCB7IG9taXRFbXB0eTogdHJ1ZSB9KSwgLy8gRXZhbHVhdGVkIG9uIHN5bnRoZXNpc1xuICAgICAgaGFuZGxlcjogcHJvcHMuaGFuZGxlciA9PT0gSGFuZGxlci5GUk9NX0lNQUdFID8gdW5kZWZpbmVkIDogcHJvcHMuaGFuZGxlcixcbiAgICAgIHRpbWVvdXQ6IHByb3BzLnRpbWVvdXQgJiYgcHJvcHMudGltZW91dC50b1NlY29uZHMoKSxcbiAgICAgIHBhY2thZ2VUeXBlOiBwcm9wcy5ydW50aW1lID09PSBSdW50aW1lLkZST01fSU1BR0UgPyAnSW1hZ2UnIDogdW5kZWZpbmVkLFxuICAgICAgcnVudGltZTogcHJvcHMucnVudGltZSA9PT0gUnVudGltZS5GUk9NX0lNQUdFID8gdW5kZWZpbmVkIDogcHJvcHMucnVudGltZS5uYW1lLFxuICAgICAgcm9sZTogdGhpcy5yb2xlLnJvbGVBcm4sXG4gICAgICAvLyBVbmNhY2hlZCBiZWNhdXNlIGNhbGxpbmcgJ19jaGVja0VkZ2VDb21wYXRpYmlsaXR5Jywgd2hpY2ggZ2V0cyBjYWxsZWQgaW4gdGhlIHJlc29sdmUgb2YgYW5vdGhlclxuICAgICAgLy8gVG9rZW4sIGFjdHVhbGx5ICptb2RpZmllcyogdGhlICdlbnZpcm9ubWVudCcgbWFwLlxuICAgICAgZW52aXJvbm1lbnQ6IExhenkudW5jYWNoZWRBbnkoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLnJlbmRlckVudmlyb25tZW50KCkgfSksXG4gICAgICBtZW1vcnlTaXplOiBwcm9wcy5tZW1vcnlTaXplLFxuICAgICAgdnBjQ29uZmlnOiB0aGlzLmNvbmZpZ3VyZVZwYyhwcm9wcyksXG4gICAgICBkZWFkTGV0dGVyQ29uZmlnOiB0aGlzLmJ1aWxkRGVhZExldHRlckNvbmZpZyh0aGlzLmRlYWRMZXR0ZXJRdWV1ZSksXG4gICAgICB0cmFjaW5nQ29uZmlnOiB0aGlzLmJ1aWxkVHJhY2luZ0NvbmZpZyhwcm9wcyksXG4gICAgICByZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zOiBwcm9wcy5yZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zLFxuICAgICAgaW1hZ2VDb25maWc6IHVuZGVmaW5lZElmTm9LZXlzKHtcbiAgICAgICAgY29tbWFuZDogY29kZS5pbWFnZT8uY21kLFxuICAgICAgICBlbnRyeVBvaW50OiBjb2RlLmltYWdlPy5lbnRyeXBvaW50LFxuICAgICAgICB3b3JraW5nRGlyZWN0b3J5OiBjb2RlLmltYWdlPy53b3JraW5nRGlyZWN0b3J5LFxuICAgICAgfSksXG4gICAgICBrbXNLZXlBcm46IHByb3BzLmVudmlyb25tZW50RW5jcnlwdGlvbj8ua2V5QXJuLFxuICAgICAgZmlsZVN5c3RlbUNvbmZpZ3MsXG4gICAgICBjb2RlU2lnbmluZ0NvbmZpZ0FybjogcHJvcHMuY29kZVNpZ25pbmdDb25maWc/LmNvZGVTaWduaW5nQ29uZmlnQXJuLFxuICAgICAgYXJjaGl0ZWN0dXJlczogYXJjaGl0ZWN0dXJlID8gW2FyY2hpdGVjdHVyZS5uYW1lXSA6IHVuZGVmaW5lZCxcbiAgICB9KTtcblxuICAgIHJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeSh0aGlzLnJvbGUpO1xuXG4gICAgdGhpcy5mdW5jdGlvbk5hbWUgPSB0aGlzLmdldFJlc291cmNlTmFtZUF0dHJpYnV0ZShyZXNvdXJjZS5yZWYpO1xuICAgIHRoaXMuZnVuY3Rpb25Bcm4gPSB0aGlzLmdldFJlc291cmNlQXJuQXR0cmlidXRlKHJlc291cmNlLmF0dHJBcm4sIHtcbiAgICAgIHNlcnZpY2U6ICdsYW1iZGEnLFxuICAgICAgcmVzb3VyY2U6ICdmdW5jdGlvbicsXG4gICAgICByZXNvdXJjZU5hbWU6IHRoaXMucGh5c2ljYWxOYW1lLFxuICAgICAgYXJuRm9ybWF0OiBBcm5Gb3JtYXQuQ09MT05fUkVTT1VSQ0VfTkFNRSxcbiAgICB9KTtcblxuICAgIHRoaXMucnVudGltZSA9IHByb3BzLnJ1bnRpbWU7XG5cbiAgICB0aGlzLmFyY2hpdGVjdHVyZSA9IHByb3BzLmFyY2hpdGVjdHVyZTtcblxuICAgIGlmIChwcm9wcy5sYXllcnMpIHtcbiAgICAgIGlmIChwcm9wcy5ydW50aW1lID09PSBSdW50aW1lLkZST01fSU1BR0UpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMYXllcnMgYXJlIG5vdCBzdXBwb3J0ZWQgZm9yIGNvbnRhaW5lciBpbWFnZSBmdW5jdGlvbnMnKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hZGRMYXllcnMoLi4ucHJvcHMubGF5ZXJzKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIHByb3BzLmV2ZW50cyB8fCBbXSkge1xuICAgICAgdGhpcy5hZGRFdmVudFNvdXJjZShldmVudCk7XG4gICAgfVxuXG4gICAgLy8gTG9nIHJldGVudGlvblxuICAgIGlmIChwcm9wcy5sb2dSZXRlbnRpb24pIHtcbiAgICAgIGNvbnN0IGxvZ1JldGVudGlvbiA9IG5ldyBsb2dzLkxvZ1JldGVudGlvbih0aGlzLCAnTG9nUmV0ZW50aW9uJywge1xuICAgICAgICBsb2dHcm91cE5hbWU6IGAvYXdzL2xhbWJkYS8ke3RoaXMuZnVuY3Rpb25OYW1lfWAsXG4gICAgICAgIHJldGVudGlvbjogcHJvcHMubG9nUmV0ZW50aW9uLFxuICAgICAgICByb2xlOiBwcm9wcy5sb2dSZXRlbnRpb25Sb2xlLFxuICAgICAgICBsb2dSZXRlbnRpb25SZXRyeU9wdGlvbnM6IHByb3BzLmxvZ1JldGVudGlvblJldHJ5T3B0aW9ucyBhcyBsb2dzLkxvZ1JldGVudGlvblJldHJ5T3B0aW9ucyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5fbG9nR3JvdXAgPSBsb2dzLkxvZ0dyb3VwLmZyb21Mb2dHcm91cEFybih0aGlzLCAnTG9nR3JvdXAnLCBsb2dSZXRlbnRpb24ubG9nR3JvdXBBcm4pO1xuICAgIH1cblxuICAgIHByb3BzLmNvZGUuYmluZFRvUmVzb3VyY2UocmVzb3VyY2UpO1xuXG4gICAgLy8gRXZlbnQgSW52b2tlIENvbmZpZ1xuICAgIGlmIChwcm9wcy5vbkZhaWx1cmUgfHwgcHJvcHMub25TdWNjZXNzIHx8IHByb3BzLm1heEV2ZW50QWdlIHx8IHByb3BzLnJldHJ5QXR0ZW1wdHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5jb25maWd1cmVBc3luY0ludm9rZSh7XG4gICAgICAgIG9uRmFpbHVyZTogcHJvcHMub25GYWlsdXJlLFxuICAgICAgICBvblN1Y2Nlc3M6IHByb3BzLm9uU3VjY2VzcyxcbiAgICAgICAgbWF4RXZlbnRBZ2U6IHByb3BzLm1heEV2ZW50QWdlLFxuICAgICAgICByZXRyeUF0dGVtcHRzOiBwcm9wcy5yZXRyeUF0dGVtcHRzLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50VmVyc2lvbk9wdGlvbnMgPSBwcm9wcy5jdXJyZW50VmVyc2lvbk9wdGlvbnM7XG5cbiAgICBpZiAocHJvcHMuZmlsZXN5c3RlbSkge1xuICAgICAgaWYgKCFwcm9wcy52cGMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgY29uZmlndXJlIFxcJ2ZpbGVzeXN0ZW1cXCcgd2l0aG91dCBjb25maWd1cmluZyBhIFZQQy4nKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbmZpZyA9IHByb3BzLmZpbGVzeXN0ZW0uY29uZmlnO1xuICAgICAgaWYgKGNvbmZpZy5kZXBlbmRlbmN5KSB7XG4gICAgICAgIHRoaXMubm9kZS5hZGREZXBlbmRlbmN5KC4uLmNvbmZpZy5kZXBlbmRlbmN5KTtcbiAgICAgIH1cbiAgICAgIC8vIFRoZXJlIGNvdWxkIGJlIGEgcmFjZSBpZiB0aGUgTGFtYmRhIGlzIHVzZWQgaW4gYSBDdXN0b21SZXNvdXJjZS4gSXQgaXMgcG9zc2libGUgZm9yIHRoZSBMYW1iZGEgdG9cbiAgICAgIC8vIGZhaWwgdG8gYXR0YWNoIHRvIGEgZ2l2ZW4gRmlsZVN5c3RlbSBpZiB3ZSBkbyBub3QgaGF2ZSBhIGRlcGVuZGVuY3kgb24gdGhlIFNlY3VyaXR5R3JvdXAgaW5ncmVzcy9lZ3Jlc3NcbiAgICAgIC8vIHJ1bGVzIHRoYXQgd2VyZSBjcmVhdGVkIGJldHdlZW4gdGhpcyBMYW1iZGEncyBTRyAmIHRoZSBGaWxlc3lzdGVtIFNHLlxuICAgICAgdGhpcy5jb25uZWN0aW9ucy5zZWN1cml0eUdyb3Vwcy5mb3JFYWNoKHNnID0+IHtcbiAgICAgICAgc2cubm9kZS5maW5kQWxsKCkuZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgQ2ZuUmVzb3VyY2UgJiYgY2hpbGQuY2ZuUmVzb3VyY2VUeXBlID09PSAnQVdTOjpFQzI6OlNlY3VyaXR5R3JvdXBFZ3Jlc3MnKSB7XG4gICAgICAgICAgICByZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3koY2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGNvbmZpZy5jb25uZWN0aW9ucz8uc2VjdXJpdHlHcm91cHMuZm9yRWFjaChzZyA9PiB7XG4gICAgICAgIHNnLm5vZGUuZmluZEFsbCgpLmZvckVhY2goY2hpbGQgPT4ge1xuICAgICAgICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIENmblJlc291cmNlICYmIGNoaWxkLmNmblJlc291cmNlVHlwZSA9PT0gJ0FXUzo6RUMyOjpTZWN1cml0eUdyb3VwSW5ncmVzcycpIHtcbiAgICAgICAgICAgIHJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeShjaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENvbmZpZ3VyZSBMYW1iZGEgaW5zaWdodHNcbiAgICB0aGlzLmNvbmZpZ3VyZUxhbWJkYUluc2lnaHRzKHByb3BzKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGFkZEVudmlyb25tZW50KGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBvcHRpb25zPzogRW52aXJvbm1lbnRPcHRpb25zKTogdGhpcyB7XG4gICAgdGhpcy5lbnZpcm9ubWVudFtrZXldID0geyB2YWx1ZSwgLi4ub3B0aW9ucyB9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBhZGRMYXllcnMoLi4ubGF5ZXJzOiBJTGF5ZXJWZXJzaW9uW10pOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGxheWVyIG9mIGxheWVycykge1xuICAgICAgaWYgKHRoaXMubGF5ZXJzLmxlbmd0aCA9PT0gNSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBhZGQgbGF5ZXI6IHRoaXMgbGFtYmRhIGZ1bmN0aW9uIGFscmVhZHkgdXNlcyA1IGxheWVycy4nKTtcbiAgICAgIH1cbiAgICAgIGlmIChsYXllci5jb21wYXRpYmxlUnVudGltZXMgJiYgIWxheWVyLmNvbXBhdGlibGVSdW50aW1lcy5maW5kKHJ1bnRpbWUgPT4gcnVudGltZS5ydW50aW1lRXF1YWxzKHRoaXMucnVudGltZSkpKSB7XG4gICAgICAgIGNvbnN0IHJ1bnRpbWVzID0gbGF5ZXIuY29tcGF0aWJsZVJ1bnRpbWVzLm1hcChydW50aW1lID0+IHJ1bnRpbWUubmFtZSkuam9pbignLCAnKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGlzIGxhbWJkYSBmdW5jdGlvbiB1c2VzIGEgcnVudGltZSB0aGF0IGlzIGluY29tcGF0aWJsZSB3aXRoIHRoaXMgbGF5ZXIgKCR7dGhpcy5ydW50aW1lLm5hbWV9IGlzIG5vdCBpbiBbJHtydW50aW1lc31dKWApO1xuICAgICAgfVxuXG4gICAgICAvLyBDdXJyZW50bHkgbm8gdmFsaWRhdGlvbnMgZm9yIGNvbXBhdGlibGUgYXJjaGl0ZWN0dXJlcyBzaW5jZSBMYW1iZGEgc2VydmljZVxuICAgICAgLy8gYWxsb3dzIGxheWVycyBjb25maWd1cmVkIHdpdGggb25lIGFyY2hpdGVjdHVyZSB0byBiZSB1c2VkIHdpdGggYSBMYW1iZGEgZnVuY3Rpb25cbiAgICAgIC8vIGZyb20gYW5vdGhlciBhcmNoaXRlY3R1cmUuXG5cbiAgICAgIHRoaXMubGF5ZXJzLnB1c2gobGF5ZXIpO1xuICAgIH1cbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBhZGRWZXJzaW9uKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjb2RlU2hhMjU2Pzogc3RyaW5nLFxuICAgIGRlc2NyaXB0aW9uPzogc3RyaW5nLFxuICAgIHByb3Zpc2lvbmVkRXhlY3V0aW9ucz86IG51bWJlcixcbiAgICBhc3luY0ludm9rZUNvbmZpZzogRXZlbnRJbnZva2VDb25maWdPcHRpb25zID0ge30pOiBWZXJzaW9uIHtcblxuICAgIHJldHVybiBuZXcgVmVyc2lvbih0aGlzLCAnVmVyc2lvbicgKyBuYW1lLCB7XG4gICAgICBsYW1iZGE6IHRoaXMsXG4gICAgICBjb2RlU2hhMjU2LFxuICAgICAgZGVzY3JpcHRpb24sXG4gICAgICBwcm92aXNpb25lZENvbmN1cnJlbnRFeGVjdXRpb25zOiBwcm92aXNpb25lZEV4ZWN1dGlvbnMsXG4gICAgICAuLi5hc3luY0ludm9rZUNvbmZpZyxcbiAgICB9KTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBnZXQgbG9nR3JvdXAoKTogbG9ncy5JTG9nR3JvdXAge1xuICAgIGlmICghdGhpcy5fbG9nR3JvdXApIHtcbiAgICAgIGNvbnN0IGxvZ1JldGVudGlvbiA9IG5ldyBsb2dzLkxvZ1JldGVudGlvbih0aGlzLCAnTG9nUmV0ZW50aW9uJywge1xuICAgICAgICBsb2dHcm91cE5hbWU6IGAvYXdzL2xhbWJkYS8ke3RoaXMuZnVuY3Rpb25OYW1lfWAsXG4gICAgICAgIHJldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLklORklOSVRFLFxuICAgICAgfSk7XG4gICAgICB0aGlzLl9sb2dHcm91cCA9IGxvZ3MuTG9nR3JvdXAuZnJvbUxvZ0dyb3VwQXJuKHRoaXMsIGAke3RoaXMubm9kZS5pZH0tTG9nR3JvdXBgLCBsb2dSZXRlbnRpb24ubG9nR3JvdXBBcm4pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbG9nR3JvdXA7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIHB1YmxpYyBfY2hlY2tFZGdlQ29tcGF0aWJpbGl0eSgpOiB2b2lkIHtcbiAgICAvLyBDaGVjayBlbnYgdmFyc1xuICAgIGNvbnN0IGVudkVudHJpZXMgPSBPYmplY3QuZW50cmllcyh0aGlzLmVudmlyb25tZW50KTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIGNvbmZpZ10gb2YgZW52RW50cmllcykge1xuICAgICAgaWYgKGNvbmZpZy5yZW1vdmVJbkVkZ2UpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuZW52aXJvbm1lbnRba2V5XTtcbiAgICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkSW5mbyhgUmVtb3ZlZCAke2tleX0gZW52aXJvbm1lbnQgdmFyaWFibGUgZm9yIExhbWJkYUBFZGdlIGNvbXBhdGliaWxpdHlgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZW52S2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuZW52aXJvbm1lbnQpO1xuICAgIGlmIChlbnZLZXlzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgZnVuY3Rpb24gJHt0aGlzLm5vZGUucGF0aH0gY29udGFpbnMgZW52aXJvbm1lbnQgdmFyaWFibGVzIFske2VudktleXN9XSBhbmQgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBMYW1iZGFARWRnZS4gXFxcbkVudmlyb25tZW50IHZhcmlhYmxlcyBjYW4gYmUgbWFya2VkIGZvciByZW1vdmFsIHdoZW4gdXNlZCBpbiBMYW1iZGFARWRnZSBieSBzZXR0aW5nIHRoZSBcXCdyZW1vdmVJbkVkZ2VcXCcgcHJvcGVydHkgaW4gdGhlIFxcJ2FkZEVudmlyb25tZW50KClcXCcgQVBJLmApO1xuICAgIH1cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmVkIGxhbWJkYSBpbnNpZ2h0cyBvbiB0aGUgZnVuY3Rpb24gaWYgc3BlY2lmaWVkLiBUaGlzIGlzIGFjaGVpdmVkIGJ5IGFkZGluZyBhbiBpbXBvcnRlZCBsYXllciB3aGljaCBpcyBhZGRlZCB0byB0aGVcbiAgICogbGlzdCBvZiBsYW1iZGEgbGF5ZXJzIG9uIHN5bnRoZXNpcy5cbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L21vbml0b3JpbmcvTGFtYmRhLUluc2lnaHRzLWV4dGVuc2lvbi12ZXJzaW9ucy5odG1sXG4gICAqL1xuICBwcml2YXRlIGNvbmZpZ3VyZUxhbWJkYUluc2lnaHRzKHByb3BzOiBGdW5jdGlvblByb3BzKTogdm9pZCB7XG4gICAgaWYgKHByb3BzLmluc2lnaHRzVmVyc2lvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChwcm9wcy5ydW50aW1lICE9PSBSdW50aW1lLkZST01fSU1BR0UpIHtcbiAgICAgIC8vIExheWVycyBjYW5ub3QgYmUgYWRkZWQgdG8gTGFtYmRhIGNvbnRhaW5lciBpbWFnZXMuIFRoZSBpbWFnZSBzaG91bGQgaGF2ZSB0aGUgaW5zaWdodHMgYWdlbnQgaW5zdGFsbGVkLlxuICAgICAgLy8gU2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZFdhdGNoL2xhdGVzdC9tb25pdG9yaW5nL0xhbWJkYS1JbnNpZ2h0cy1HZXR0aW5nLVN0YXJ0ZWQtZG9ja2VyLmh0bWxcbiAgICAgIHRoaXMuYWRkTGF5ZXJzKExheWVyVmVyc2lvbi5mcm9tTGF5ZXJWZXJzaW9uQXJuKHRoaXMsICdMYW1iZGFJbnNpZ2h0c0xheWVyJywgcHJvcHMuaW5zaWdodHNWZXJzaW9uLmxheWVyVmVyc2lvbkFybikpO1xuICAgIH1cbiAgICB0aGlzLnJvbGU/LmFkZE1hbmFnZWRQb2xpY3koaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdDbG91ZFdhdGNoTGFtYmRhSW5zaWdodHNFeGVjdXRpb25Sb2xlUG9saWN5JykpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJFbnZpcm9ubWVudCgpIHtcbiAgICBpZiAoIXRoaXMuZW52aXJvbm1lbnQgfHwgT2JqZWN0LmtleXModGhpcy5lbnZpcm9ubWVudCkubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHZhcmlhYmxlczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIC8vIFNvcnQgZW52aXJvbm1lbnQgc28gdGhlIGhhc2ggb2YgdGhlIGZ1bmN0aW9uIHVzZWQgdG8gY3JlYXRlXG4gICAgLy8gYGN1cnJlbnRWZXJzaW9uYCBpcyBub3QgYWZmZWN0ZWQgYnkga2V5IG9yZGVyICh0aGlzIGlzIGhvdyBsYW1iZGEgZG9lc1xuICAgIC8vIGl0KS4gRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHdlIGRvIG5vdCBzb3J0IGVudmlyb25tZW50IHZhcmlhYmxlcyBpbiBjYXNlXG4gICAgLy8gX2N1cnJlbnRWZXJzaW9uIGlzIG5vdCBkZWZpbmVkLiBPdGhlcndpc2UsIHRoaXMgd291bGQgaGF2ZSBpbnZhbGlkYXRlZFxuICAgIC8vIHRoZSB0ZW1wbGF0ZSwgYW5kIGZvciBleGFtcGxlLCBtYXkgY2F1c2UgdW5uZWVkZWQgdXBkYXRlcyBmb3IgbmVzdGVkXG4gICAgLy8gc3RhY2tzLlxuICAgIGNvbnN0IGtleXMgPSB0aGlzLl9jdXJyZW50VmVyc2lvblxuICAgICAgPyBPYmplY3Qua2V5cyh0aGlzLmVudmlyb25tZW50KS5zb3J0KClcbiAgICAgIDogT2JqZWN0LmtleXModGhpcy5lbnZpcm9ubWVudCk7XG5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICB2YXJpYWJsZXNba2V5XSA9IHRoaXMuZW52aXJvbm1lbnRba2V5XS52YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB2YXJpYWJsZXMgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiBjb25maWd1cmVkLCBzZXQgdXAgdGhlIFZQQy1yZWxhdGVkIHByb3BlcnRpZXNcbiAgICpcbiAgICogUmV0dXJucyB0aGUgVnBjQ29uZmlnIHRoYXQgc2hvdWxkIGJlIGFkZGVkIHRvIHRoZVxuICAgKiBMYW1iZGEgY3JlYXRpb24gcHJvcGVydGllcy5cbiAgICovXG4gIHByaXZhdGUgY29uZmlndXJlVnBjKHByb3BzOiBGdW5jdGlvblByb3BzKTogQ2ZuRnVuY3Rpb24uVnBjQ29uZmlnUHJvcGVydHkgfCB1bmRlZmluZWQge1xuICAgIGlmICgocHJvcHMuc2VjdXJpdHlHcm91cCB8fCBwcm9wcy5hbGxvd0FsbE91dGJvdW5kICE9PSB1bmRlZmluZWQpICYmICFwcm9wcy52cGMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNvbmZpZ3VyZSBcXCdzZWN1cml0eUdyb3VwXFwnIG9yIFxcJ2FsbG93QWxsT3V0Ym91bmRcXCcgd2l0aG91dCBjb25maWd1cmluZyBhIFZQQycpO1xuICAgIH1cblxuICAgIGlmICghcHJvcHMudnBjKSB7IHJldHVybiB1bmRlZmluZWQ7IH1cblxuICAgIGlmIChwcm9wcy5zZWN1cml0eUdyb3VwICYmIHByb3BzLmFsbG93QWxsT3V0Ym91bmQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb25maWd1cmUgXFwnYWxsb3dBbGxPdXRib3VuZFxcJyBkaXJlY3RseSBvbiB0aGUgc3VwcGxpZWQgU2VjdXJpdHlHcm91cC4nKTtcbiAgICB9XG5cbiAgICBsZXQgc2VjdXJpdHlHcm91cHM6IGVjMi5JU2VjdXJpdHlHcm91cFtdO1xuXG4gICAgaWYgKHByb3BzLnNlY3VyaXR5R3JvdXAgJiYgcHJvcHMuc2VjdXJpdHlHcm91cHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2YgdGhlIGZ1bmN0aW9uIHByb3BzLCBzZWN1cml0eUdyb3VwIG9yIHNlY3VyaXR5R3JvdXBzLCBpcyBhbGxvd2VkJyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnNlY3VyaXR5R3JvdXBzKSB7XG4gICAgICBzZWN1cml0eUdyb3VwcyA9IHByb3BzLnNlY3VyaXR5R3JvdXBzO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzZWN1cml0eUdyb3VwID0gcHJvcHMuc2VjdXJpdHlHcm91cCB8fCBuZXcgZWMyLlNlY3VyaXR5R3JvdXAodGhpcywgJ1NlY3VyaXR5R3JvdXAnLCB7XG4gICAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ0F1dG9tYXRpYyBzZWN1cml0eSBncm91cCBmb3IgTGFtYmRhIEZ1bmN0aW9uICcgKyBOYW1lcy51bmlxdWVJZCh0aGlzKSxcbiAgICAgICAgYWxsb3dBbGxPdXRib3VuZDogcHJvcHMuYWxsb3dBbGxPdXRib3VuZCxcbiAgICAgIH0pO1xuICAgICAgc2VjdXJpdHlHcm91cHMgPSBbc2VjdXJpdHlHcm91cF07XG4gICAgfVxuXG4gICAgdGhpcy5fY29ubmVjdGlvbnMgPSBuZXcgZWMyLkNvbm5lY3Rpb25zKHsgc2VjdXJpdHlHcm91cHMgfSk7XG5cbiAgICBpZiAocHJvcHMuZmlsZXN5c3RlbSkge1xuICAgICAgaWYgKHByb3BzLmZpbGVzeXN0ZW0uY29uZmlnLmNvbm5lY3Rpb25zKSB7XG4gICAgICAgIHByb3BzLmZpbGVzeXN0ZW0uY29uZmlnLmNvbm5lY3Rpb25zLmFsbG93RGVmYXVsdFBvcnRGcm9tKHRoaXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGFsbG93UHVibGljU3VibmV0ID0gcHJvcHMuYWxsb3dQdWJsaWNTdWJuZXQgPz8gZmFsc2U7XG4gICAgY29uc3QgeyBzdWJuZXRJZHMgfSA9IHByb3BzLnZwYy5zZWxlY3RTdWJuZXRzKHByb3BzLnZwY1N1Ym5ldHMpO1xuICAgIGNvbnN0IHB1YmxpY1N1Ym5ldElkcyA9IG5ldyBTZXQocHJvcHMudnBjLnB1YmxpY1N1Ym5ldHMubWFwKHMgPT4gcy5zdWJuZXRJZCkpO1xuICAgIGZvciAoY29uc3Qgc3VibmV0SWQgb2Ygc3VibmV0SWRzKSB7XG4gICAgICBpZiAocHVibGljU3VibmV0SWRzLmhhcyhzdWJuZXRJZCkgJiYgIWFsbG93UHVibGljU3VibmV0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTGFtYmRhIEZ1bmN0aW9ucyBpbiBhIHB1YmxpYyBzdWJuZXQgY2FuIE5PVCBhY2Nlc3MgdGhlIGludGVybmV0LiAnICtcbiAgICAgICAgICAnSWYgeW91IGFyZSBhd2FyZSBvZiB0aGlzIGxpbWl0YXRpb24gYW5kIHdvdWxkIHN0aWxsIGxpa2UgdG8gcGxhY2UgdGhlIGZ1bmN0aW9uIGludCBhIHB1YmxpYyBzdWJuZXQsIHNldCBgYWxsb3dQdWJsaWNTdWJuZXRgIHRvIHRydWUnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBMaXN0IGNhbid0IGJlIGVtcHR5IGhlcmUsIGlmIHdlIGdvdCB0aGlzIGZhciB5b3UgaW50ZW5kZWQgdG8gcHV0IHlvdXIgTGFtYmRhXG4gICAgLy8gaW4gc3VibmV0cy4gV2UncmUgZ29pbmcgdG8gZ3VhcmFudGVlIHRoYXQgd2UgZ2V0IHRoZSBuaWNlIGVycm9yIG1lc3NhZ2UgYnlcbiAgICAvLyBtYWtpbmcgVnBjTmV0d29yayBkbyB0aGUgc2VsZWN0aW9uIGFnYWluLlxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHN1Ym5ldElkcyxcbiAgICAgIHNlY3VyaXR5R3JvdXBJZHM6IHNlY3VyaXR5R3JvdXBzLm1hcChzZyA9PiBzZy5zZWN1cml0eUdyb3VwSWQpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRGVhZExldHRlclF1ZXVlKHByb3BzOiBGdW5jdGlvblByb3BzKSB7XG4gICAgaWYgKHByb3BzLmRlYWRMZXR0ZXJRdWV1ZSAmJiBwcm9wcy5kZWFkTGV0dGVyUXVldWVFbmFibGVkID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgRXJyb3IoJ2RlYWRMZXR0ZXJRdWV1ZSBkZWZpbmVkIGJ1dCBkZWFkTGV0dGVyUXVldWVFbmFibGVkIGV4cGxpY2l0bHkgc2V0IHRvIGZhbHNlJyk7XG4gICAgfVxuXG4gICAgaWYgKCFwcm9wcy5kZWFkTGV0dGVyUXVldWUgJiYgIXByb3BzLmRlYWRMZXR0ZXJRdWV1ZUVuYWJsZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgZGVhZExldHRlclF1ZXVlID0gcHJvcHMuZGVhZExldHRlclF1ZXVlIHx8IG5ldyBzcXMuUXVldWUodGhpcywgJ0RlYWRMZXR0ZXJRdWV1ZScsIHtcbiAgICAgIHJldGVudGlvblBlcmlvZDogRHVyYXRpb24uZGF5cygxNCksXG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZFRvUm9sZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBhY3Rpb25zOiBbJ3NxczpTZW5kTWVzc2FnZSddLFxuICAgICAgcmVzb3VyY2VzOiBbZGVhZExldHRlclF1ZXVlLnF1ZXVlQXJuXSxcbiAgICB9KSk7XG5cbiAgICByZXR1cm4gZGVhZExldHRlclF1ZXVlO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZERlYWRMZXR0ZXJDb25maWcoZGVhZExldHRlclF1ZXVlPzogc3FzLklRdWV1ZSkge1xuICAgIGlmIChkZWFkTGV0dGVyUXVldWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRhcmdldEFybjogZGVhZExldHRlclF1ZXVlLnF1ZXVlQXJuLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkVHJhY2luZ0NvbmZpZyhwcm9wczogRnVuY3Rpb25Qcm9wcykge1xuICAgIGlmIChwcm9wcy50cmFjaW5nID09PSB1bmRlZmluZWQgfHwgcHJvcHMudHJhY2luZyA9PT0gVHJhY2luZy5ESVNBQkxFRCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICB0aGlzLmFkZFRvUm9sZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBhY3Rpb25zOiBbJ3hyYXk6UHV0VHJhY2VTZWdtZW50cycsICd4cmF5OlB1dFRlbGVtZXRyeVJlY29yZHMnXSxcbiAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgfSkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZGU6IHByb3BzLnRyYWNpbmcsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVQcm9maWxpbmcocHJvcHM6IEZ1bmN0aW9uUHJvcHMpIHtcbiAgICBpZiAoIXByb3BzLnJ1bnRpbWUuc3VwcG9ydHNDb2RlR3VydVByb2ZpbGluZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb2RlR3VydSBwcm9maWxpbmcgaXMgbm90IHN1cHBvcnRlZCBieSBydW50aW1lICR7cHJvcHMucnVudGltZS5uYW1lfWApO1xuICAgIH1cbiAgICBpZiAocHJvcHMuZW52aXJvbm1lbnQgJiYgKHByb3BzLmVudmlyb25tZW50LkFXU19DT0RFR1VSVV9QUk9GSUxFUl9HUk9VUF9BUk4gfHwgcHJvcHMuZW52aXJvbm1lbnQuQVdTX0NPREVHVVJVX1BST0ZJTEVSX0VOQUJMRUQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FXU19DT0RFR1VSVV9QUk9GSUxFUl9HUk9VUF9BUk4gYW5kIEFXU19DT0RFR1VSVV9QUk9GSUxFUl9FTkFCTEVEIG11c3Qgbm90IGJlIHNldCB3aGVuIHByb2ZpbGluZyBvcHRpb25zIGVuYWJsZWQnKTtcbiAgICB9XG4gIH1cbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGludGVyZmFjZSBFbnZpcm9ubWVudE9wdGlvbnMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHJlbW92ZUluRWRnZT86IGJvb2xlYW5cbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBhbiBlbnZpcm9ubWVudCB2YXJpYWJsZVxuICovXG5pbnRlcmZhY2UgRW52aXJvbm1lbnRDb25maWcgZXh0ZW5kcyBFbnZpcm9ubWVudE9wdGlvbnMge1xuICByZWFkb25seSB2YWx1ZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEdpdmVuIGFuIG9wYXF1ZSAodG9rZW4pIEFSTiwgcmV0dXJucyBhIENsb3VkRm9ybWF0aW9uIGV4cHJlc3Npb24gdGhhdCBleHRyYWN0cyB0aGUgZnVuY3Rpb25cbiAqIG5hbWUgZnJvbSB0aGUgQVJOLlxuICpcbiAqIEZ1bmN0aW9uIEFSTnMgbG9vayBsaWtlIHRoaXM6XG4gKlxuICogICBhcm46YXdzOmxhbWJkYTpyZWdpb246YWNjb3VudC1pZDpmdW5jdGlvbjpmdW5jdGlvbi1uYW1lXG4gKlxuICogLi53aGljaCBtZWFucyB0aGF0IGluIG9yZGVyIHRvIGV4dHJhY3QgdGhlIGBmdW5jdGlvbi1uYW1lYCBjb21wb25lbnQgZnJvbSB0aGUgQVJOLCB3ZSBjYW5cbiAqIHNwbGl0IHRoZSBBUk4gdXNpbmcgXCI6XCIgYW5kIHNlbGVjdCB0aGUgY29tcG9uZW50IGluIGluZGV4IDYuXG4gKlxuICogQHJldHVybnMgYEZuU2VsZWN0KDYsIEZuU3BsaXQoJzonLCBhcm4pKWBcbiAqL1xuZnVuY3Rpb24gZXh0cmFjdE5hbWVGcm9tQXJuKGFybjogc3RyaW5nKSB7XG4gIHJldHVybiBGbi5zZWxlY3QoNiwgRm4uc3BsaXQoJzonLCBhcm4pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZlcmlmeUNvZGVDb25maWcoY29kZTogQ29kZUNvbmZpZywgcHJvcHM6IEZ1bmN0aW9uUHJvcHMpIHtcbiAgLy8gbXV0dWFsbHkgZXhjbHVzaXZlXG4gIGNvbnN0IGNvZGVUeXBlID0gW2NvZGUuaW5saW5lQ29kZSwgY29kZS5zM0xvY2F0aW9uLCBjb2RlLmltYWdlXTtcblxuICBpZiAoY29kZVR5cGUuZmlsdGVyKHggPT4gISF4KS5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2xhbWJkYS5Db2RlIG11c3Qgc3BlY2lmeSBleGFjdGx5IG9uZSBvZjogXCJpbmxpbmVDb2RlXCIsIFwiczNMb2NhdGlvblwiLCBvciBcImltYWdlXCInKTtcbiAgfVxuXG4gIGlmICghIWNvZGUuaW1hZ2UgPT09IChwcm9wcy5oYW5kbGVyICE9PSBIYW5kbGVyLkZST01fSU1BR0UpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdoYW5kbGVyIG11c3QgYmUgYEhhbmRsZXIuRlJPTV9JTUFHRWAgd2hlbiB1c2luZyBpbWFnZSBhc3NldCBmb3IgTGFtYmRhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBpZiAoISFjb2RlLmltYWdlID09PSAocHJvcHMucnVudGltZSAhPT0gUnVudGltZS5GUk9NX0lNQUdFKSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncnVudGltZSBtdXN0IGJlIGBSdW50aW1lLkZST01fSU1BR0VgIHdoZW4gdXNpbmcgaW1hZ2UgYXNzZXQgZm9yIExhbWJkYSBmdW5jdGlvbicpO1xuICB9XG5cbiAgLy8gaWYgdGhpcyBpcyBpbmxpbmUgY29kZSwgY2hlY2sgdGhhdCB0aGUgcnVudGltZSBzdXBwb3J0c1xuICBpZiAoY29kZS5pbmxpbmVDb2RlICYmICFwcm9wcy5ydW50aW1lLnN1cHBvcnRzSW5saW5lQ29kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW5saW5lIHNvdXJjZSBub3QgYWxsb3dlZCBmb3IgJHtwcm9wcy5ydW50aW1lIS5uYW1lfWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuZGVmaW5lZElmTm9LZXlzPEE+KHN0cnVjdDogQSk6IEEgfCB1bmRlZmluZWQge1xuICBjb25zdCBhbGxVbmRlZmluZWQgPSBPYmplY3QudmFsdWVzKHN0cnVjdCkuZXZlcnkodmFsID0+IHZhbCA9PT0gdW5kZWZpbmVkKTtcbiAgcmV0dXJuIGFsbFVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHN0cnVjdDtcbn1cbiJdfQ==