UNPKG

@aws/pdk

Version:

All documentation is located at: https://aws.github.io/aws-pdk

239 lines 36.9 kB
"use strict"; /*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.FeatureBranches = void 0; const path = require("path"); const pdk_nag_1 = require("../pdk-nag"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const aws_codebuild_1 = require("aws-cdk-lib/aws-codebuild"); const aws_events_targets_1 = require("aws-cdk-lib/aws-events-targets"); const aws_iam_1 = require("aws-cdk-lib/aws-iam"); const aws_lambda_1 = require("aws-cdk-lib/aws-lambda"); const cdk_nag_1 = require("cdk-nag"); const constructs_1 = require("constructs"); class FeatureBranches extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); const buildCommands = props.synthShellStepPartialProps?.commands && props.synthShellStepPartialProps.commands.length > 0 ? props.synthShellStepPartialProps.commands : ["npx nx run-many --target=build --all"]; const installCommands = props.synthShellStepPartialProps?.installCommands && props.synthShellStepPartialProps.installCommands.length > 0 ? props.synthShellStepPartialProps.installCommands : [ "npm install -g aws-cdk", "yarn install --frozen-lockfile || npx projen && yarn install --frozen-lockfile", ]; const cdkCommand = props.cdkCommand ?? "npx cdk"; const createFeatureBranchProject = new aws_codebuild_1.Project(this, "CreateFeatureBranchProject", { ...props.codeBuildDefaults, description: "Build project to deploy feature branch pipelines", source: aws_codebuild_1.Source.codeCommit({ repository: props.codeRepository }), environment: { buildImage: aws_codebuild_1.LinuxBuildImage.STANDARD_7_0, computeType: aws_codebuild_1.ComputeType.SMALL, ...props.codeBuildDefaults?.buildEnvironment, privileged: props.dockerEnabledForSynth, }, buildSpec: aws_codebuild_1.BuildSpec.fromObjectToYaml({ version: "0.2", phases: { install: { commands: installCommands, }, build: { commands: [ ...buildCommands, `cd ${props.cdkSrcDir}`, `${cdkCommand} synth`, `${cdkCommand} deploy --require-approval=never`, ], }, }, artifacts: { files: ["**/*"], }, }), }); if (props.codeBuildDefaults?.rolePolicy) { props.codeBuildDefaults.rolePolicy.forEach((policy) => { createFeatureBranchProject.addToRolePolicy(policy); }); } createFeatureBranchProject.addToRolePolicy(new aws_iam_1.PolicyStatement({ effect: aws_iam_1.Effect.ALLOW, actions: ["sts:AssumeRole"], resources: [`arn:*:iam::${aws_cdk_lib_1.Stack.of(this).account}:role/*`], conditions: { "ForAnyValue:StringEquals": { "iam:ResourceTag/aws-cdk:bootstrap-role": [ "image-publishing", "file-publishing", "deploy", ], }, }, })); const createFeatureBranchFunction = new aws_lambda_1.Function(this, "LambdaTriggerCreateBranch", { runtime: aws_lambda_1.Runtime.PYTHON_3_12, code: aws_lambda_1.Code.fromAsset(path.join(__dirname, "lambda/create_branch")), handler: "create_branch.handler", environment: { CODEBUILD_PROJECT: createFeatureBranchProject.projectName, MAIN_BRANCH: props.defaultBranchName, }, }); createFeatureBranchFunction.addToRolePolicy(new aws_iam_1.PolicyStatement({ effect: aws_iam_1.Effect.ALLOW, actions: ["codebuild:StartBuild"], resources: [createFeatureBranchProject.projectArn], })); const destroyFeatureBranchFunction = new aws_lambda_1.Function(this, "LambdaTriggerDestroyBranch", { runtime: aws_lambda_1.Runtime.PYTHON_3_12, code: aws_lambda_1.Code.fromAsset(path.join(__dirname, "lambda/destroy_branch")), handler: "destroy_branch.handler", environment: { MAIN_BRANCH: props.defaultBranchName, REPO_NAME: props.codeRepository.repositoryName, }, }); destroyFeatureBranchFunction.addToRolePolicy(new aws_iam_1.PolicyStatement({ effect: aws_iam_1.Effect.ALLOW, actions: ["cloudformation:DeleteStack"], resources: [ aws_cdk_lib_1.Stack.of(this).formatArn({ service: "cloudformation", resource: "stack", resourceName: "*/*", }), ], conditions: { "ForAllValues:StringEquals": { "aws:TagKeys": ["FeatureBranch", "RepoName"], }, }, })); destroyFeatureBranchFunction.addToRolePolicy(new aws_iam_1.PolicyStatement({ effect: aws_iam_1.Effect.ALLOW, actions: ["tag:GetResources"], resources: ["*"], })); props.codeRepository.onReferenceCreated("BranchCreateTrigger", { target: new aws_events_targets_1.LambdaFunction(createFeatureBranchFunction), description: "AWS CodeCommit reference created event.", eventPattern: { detail: { referenceType: ["branch"], referenceName: props.branchNamePrefixes.map((prefix) => ({ prefix })), }, }, }); props.codeRepository.onReferenceDeleted("BranchDestroyTrigger", { target: new aws_events_targets_1.LambdaFunction(destroyFeatureBranchFunction), description: "AWS CodeCommit reference deleted event.", eventPattern: { detail: { referenceType: ["branch"], referenceName: props.branchNamePrefixes.map((prefix) => { return { prefix }; }), }, }, }); const stack = aws_cdk_lib_1.Stack.of(this); ["AwsSolutions-IAM5", "AwsPrototyping-IAMNoWildcardPermissions"].forEach((RuleId) => { cdk_nag_1.NagSuppressions.addResourceSuppressions(createFeatureBranchProject.role, [ { id: RuleId, reason: "CodeBuild requires get, list, and pull access to the CodeCommit repository.", appliesTo: [ "Action::codecommit:Get*", "Action::codecommit:List*", ], }, { id: RuleId, reason: "CodeBuild requires access to create report groups that are dynamically determined.", appliesTo: [ { regex: `/^Resource::arn:${pdk_nag_1.PDKNag.getStackPartitionRegex(stack)}:codebuild:${pdk_nag_1.PDKNag.getStackRegionRegex(stack)}:${pdk_nag_1.PDKNag.getStackAccountRegex(stack)}:report-group/<[a-zA-Z0-9]*CreateFeatureBranchProject.*>-\\*$/g`, }, ], }, { id: RuleId, reason: "CodeBuild requires access to manage logs and streams whose names are dynamically determined.", appliesTo: [ { regex: `/^Resource::arn:${pdk_nag_1.PDKNag.getStackPartitionRegex(stack)}:logs:${pdk_nag_1.PDKNag.getStackRegionRegex(stack)}:${pdk_nag_1.PDKNag.getStackAccountRegex(stack)}:log-group:/aws/codebuild/<[a-zA-Z0-9]*CreateFeatureBranchProject.*>:\\*$/g`, }, ], }, { id: RuleId, reason: "CodeBuild requires access to assume a role from within the current account limited by a condition in order to deploy.", appliesTo: [ { regex: `/^Resource::arn:\\*:iam::${pdk_nag_1.PDKNag.getStackAccountRegex(stack)}:role/\\*$/g`, }, ], }, ], true); cdk_nag_1.NagSuppressions.addResourceSuppressions(destroyFeatureBranchFunction.role, [ { id: RuleId, reason: "The DestroyBranch Lambda requires access to delete any stacks with specific tags.", appliesTo: [ { regex: `/^Resource::arn:${pdk_nag_1.PDKNag.getStackPartitionRegex(stack)}:cloudformation:${pdk_nag_1.PDKNag.getStackRegionRegex(stack)}:${pdk_nag_1.PDKNag.getStackAccountRegex(stack)}:stack/\\*/\\*$/g`, }, ], }, { id: RuleId, reason: "The DestroyBranch Lambda requires access to look up CloudFormation stacks by tag. The Resource Group Tagging API must use 'Resource': '*'.", appliesTo: ["Resource::*"], }, ], true); }); ["AwsSolutions-IAM4", "AwsPrototyping-IAMNoManagedPolicies"].forEach((RuleId) => { cdk_nag_1.NagSuppressions.addResourceSuppressions(createFeatureBranchFunction, [ { id: RuleId, reason: "Lambda functions use the default AWS LambdaBasicExecutionRole managed role.", appliesTo: [ { regex: `/^Policy::arn:${pdk_nag_1.PDKNag.getStackPartitionRegex(stack)}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g`, }, ], }, ], true); cdk_nag_1.NagSuppressions.addResourceSuppressions(destroyFeatureBranchFunction, [ { id: RuleId, reason: "Lambda functions use the default AWS LambdaBasicExecutionRole managed role.", appliesTo: [ { regex: `/^Policy::arn:${pdk_nag_1.PDKNag.getStackPartitionRegex(stack)}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole$/g`, }, ], }, ], true); }); [ "AwsSolutions-CB4", "AwsPrototyping-CodeBuildProjectKMSEncryptedArtifacts", ].forEach((RuleId) => { cdk_nag_1.NagSuppressions.addResourceSuppressions(createFeatureBranchProject, [ { id: RuleId, reason: "Encryption of Codebuild is not required.", }, ]); }); } } exports.FeatureBranches = FeatureBranches; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVhdHVyZS1icmFuY2hlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImZlYXR1cmUtYnJhbmNoZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO3NDQUNzQzs7O0FBRXRDLDZCQUE2QjtBQUM3QiwwQ0FBc0M7QUFDdEMsNkNBQW9DO0FBQ3BDLDZEQU1tQztBQUVuQyx1RUFBZ0U7QUFDaEUsaURBQThEO0FBQzlELHVEQUFpRTtBQUVqRSxxQ0FBMEM7QUFDMUMsMkNBQXVDO0FBK0R2QyxNQUFhLGVBQWdCLFNBQVEsc0JBQVM7SUFDNUMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUEyQjtRQUNuRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLE1BQU0sYUFBYSxHQUNqQixLQUFLLENBQUMsMEJBQTBCLEVBQUUsUUFBUTtZQUMxQyxLQUFLLENBQUMsMEJBQTBCLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQ2xELENBQUMsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLENBQUMsUUFBUTtZQUMzQyxDQUFDLENBQUMsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBRS9DLE1BQU0sZUFBZSxHQUNuQixLQUFLLENBQUMsMEJBQTBCLEVBQUUsZUFBZTtZQUNqRCxLQUFLLENBQUMsMEJBQTBCLENBQUMsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQ3pELENBQUMsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLENBQUMsZUFBZTtZQUNsRCxDQUFDLENBQUM7Z0JBQ0Usd0JBQXdCO2dCQUN4QixnRkFBZ0Y7YUFDakYsQ0FBQztRQUVSLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxVQUFVLElBQUksU0FBUyxDQUFDO1FBRWpELE1BQU0sMEJBQTBCLEdBQUcsSUFBSSx1QkFBTyxDQUM1QyxJQUFJLEVBQ0osNEJBQTRCLEVBQzVCO1lBQ0UsR0FBRyxLQUFLLENBQUMsaUJBQWlCO1lBQzFCLFdBQVcsRUFBRSxrREFBa0Q7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MkIsRUFDM0I7Z0JBQ0U7b0JBQ0UsRUFBRSxFQUFFLE1BQU07b0JBQ1YsTUFBTSxFQUNKLDZFQUE2RTtvQkFDL0UsU0FBUyxFQUFFO3dCQUNUOzRCQUNFLEtBQUssRUFBRSxpQkFBaUIsZ0JBQU0sQ0FBQyxzQkFBc0IsQ0FDbkQsS0FBSyxDQUNOLDhEQUE4RDt5QkFDaEU7cUJBQ0Y7aUJBQ0Y7YUFDRixFQUNELElBQUksQ0FDTCxDQUFDO1lBQ0YseUJBQWUsQ0FBQyx1QkFBdUIsQ0FDckMsNEJBQTRCLEVBQzVCO2dCQUNFO29CQUNFLEVBQUUsRUFBRSxNQUFNO29CQUNWLE1BQU0sRUFDSiw2RUFBNkU7b0JBQy9FLFNBQVMsRUFBRTt3QkFDVDs0QkFDRSxLQUFLLEVBQUUsaUJBQWlCLGdCQUFNLENBQUMsc0JBQXNCLENBQ25ELEtBQUssQ0FDTiw4REFBOEQ7eUJBQ2hFO3FCQUNGO2lCQUNGO2FBQ0YsRUFDRCxJQUFJLENBQ0wsQ0FBQztRQUNKLENBQUMsQ0FDRixDQUFDO1FBRUY7WUFDRSxrQkFBa0I7WUFDbEIsc0RBQXNEO1NBQ3ZELENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDbkIseUJBQWUsQ0FBQyx1QkFBdUIsQ0FBQywwQkFBMEIsRUFBRTtnQkFDbEU7b0JBQ0UsRUFBRSxFQUFFLE1BQU07b0JBQ1YsTUFBTSxFQUFFLDBDQUEwQztpQkFDbkQ7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQXRURCwwQ0FzVEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiEgQ29weXJpZ2h0IFtBbWF6b24uY29tXShodHRwOi8vYW1hem9uLmNvbS8pLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjAgKi9cblxuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgUERLTmFnIH0gZnJvbSBcIkBhd3MvcGRrLW5hZ1wiO1xuaW1wb3J0IHsgU3RhY2sgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7XG4gIEJ1aWxkU3BlYyxcbiAgQ29tcHV0ZVR5cGUsXG4gIExpbnV4QnVpbGRJbWFnZSxcbiAgUHJvamVjdCxcbiAgU291cmNlLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNvZGVidWlsZFwiO1xuaW1wb3J0IHsgSVJlcG9zaXRvcnkgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNvZGVjb21taXRcIjtcbmltcG9ydCB7IExhbWJkYUZ1bmN0aW9uIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1ldmVudHMtdGFyZ2V0c1wiO1xuaW1wb3J0IHsgRWZmZWN0LCBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiO1xuaW1wb3J0IHsgQ29kZSwgRnVuY3Rpb24sIFJ1bnRpbWUgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiO1xuaW1wb3J0IHsgQ29kZVBpcGVsaW5lUHJvcHMsIFNoZWxsU3RlcFByb3BzIH0gZnJvbSBcImF3cy1jZGstbGliL3BpcGVsaW5lc1wiO1xuaW1wb3J0IHsgTmFnU3VwcHJlc3Npb25zIH0gZnJvbSBcImNkay1uYWdcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmVhdHVyZUJyYW5jaGVzUHJvcHNcbiAgZXh0ZW5kcyBQaWNrPFxuICAgIENvZGVQaXBlbGluZVByb3BzLFxuICAgIFwiY29kZUJ1aWxkRGVmYXVsdHNcIiB8IFwiZG9ja2VyRW5hYmxlZEZvclN5bnRoXCJcbiAgPiB7XG4gIC8qKlxuICAgKiBCcmFuY2ggbmFtZSBwcmVmaXhlc1xuICAgKiBBbnkgYnJhbmNoZXMgY3JlYXRlZCBtYXRjaGluZyB0aGlzIGxpc3Qgb2YgcHJlZml4ZXMgd2lsbCBjcmVhdGUgYSBuZXcgcGlwZWxpbmUgYW5kIHN0YWNrLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBDcmVhdGVzIGEgbmV3IHBpcGVsaW5lIGFuZCBzdGFjayBmb3IgYW55IGJyYW5jaFxuICAgKiBuZXcgUERLUGlwZWxpbmUodGhpcywgJ1BES1BpcGVsaW5lJywge1xuICAgKiAgIHJlcG9zaXRvcnlOYW1lOiAnbXktcmVwbycsXG4gICAqICAgYnJhbmNoTmFtZVByZWZpeGVzOiBbJyddLFxuICAgKiB9XG4gICAqIEBleGFtcGxlXG4gICAqIC8vIENyZWF0ZXMgYSBuZXcgcGlwZWxpbmUgYW5kIHN0YWNrIGZvciBhbnkgYnJhbmNoIHN0YXJ0aW5nIHdpdGggJ2ZlYXR1cmUvJyBvciAnZml4LydcbiAgICogbmV3IFBES1BpcGVsaW5lKHRoaXMsICdQREtQaXBlbGluZScsIHtcbiAgICogICByZXBvc2l0b3J5TmFtZTogJ215LXJlcG8nLFxuICAgKiAgIGJyYW5jaE5hbWVQcmVmaXhlczogWydmZWF0dXJlLycsICdmaXgvJ10sXG4gICAqIH1cbiAgICogQGV4YW1wbGVcbiAgICogLy8gRGlzYWJsZXMgZmVhdHVyZSBicmFuY2hlcyAoZGVmYXVsdClcbiAgICogbmV3IFBES1BpcGVsaW5lKHRoaXMsICdQREtQaXBlbGluZScsIHtcbiAgICogICByZXBvc2l0b3J5TmFtZTogJ215LXJlcG8nLFxuICAgKiAgIGJyYW5jaE5hbWVQcmVmaXhlczogW10sIC8vIG9yIHNpbXBseSBleGNsdWRlIHRoaXMgbGluZVxuICAgKiB9XG4gICAqL1xuICByZWFkb25seSBicmFuY2hOYW1lUHJlZml4ZXM6IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgZGlyZWN0b3J5IHdpdGggYGNkay5qc29uYCB0byBydW4gY2RrIHN5bnRoIGZyb20uXG4gICAqL1xuICByZWFkb25seSBjZGtTcmNEaXI6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIENvZGVDb21taXQgcmVwb3NpdG9yeS5cbiAgICovXG4gIHJlYWRvbmx5IGNvZGVSZXBvc2l0b3J5OiBJUmVwb3NpdG9yeTtcblxuICAvKipcbiAgICogRGVmYXVsdCBicmFuY2guXG4gICAqL1xuICByZWFkb25seSBkZWZhdWx0QnJhbmNoTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQREtQaXBlbGluZSBieSBkZWZhdWx0IGFzc3VtZXMgYSBOWCBNb25vcmVwbyBzdHJ1Y3R1cmUgZm9yIGl0J3MgY29kZWJhc2UgYW5kXG4gICAqIHVzZXMgc2FuZSBkZWZhdWx0cyBmb3IgdGhlIGluc3RhbGwgYW5kIHJ1biBjb21tYW5kcy4gVG8gb3ZlcnJpZGUgdGhlc2UgZGVmYXVsdHNcbiAgICogYW5kL29yIHByb3ZpZGUgYWRkaXRpb25hbCBpbnB1dHMsIHNwZWNpZnkgZW52IHNldHRpbmdzLCBldGMgeW91IGNhbiBwcm92aWRlXG4gICAqIGEgcGFydGlhbCBTaGVsbFN0ZXBQcm9wcy5cbiAgICovXG4gIHJlYWRvbmx5IHN5bnRoU2hlbGxTdGVwUGFydGlhbFByb3BzPzogU2hlbGxTdGVwUHJvcHM7XG5cbiAgLyoqXG4gICAqIENESyBjb21tYW5kLiBPdmVycmlkZSB0aGUgY29tbWFuZCB1c2VkIHRvIGNhbGwgY2RrIGZvciBzeW50aCBhbmQgZGVwbG95LlxuICAgKlxuICAgKiBAZGVmYXVsdCAnbnB4IGNkaydcbiAgICovXG4gIHJlYWRvbmx5IGNka0NvbW1hbmQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBGZWF0dXJlQnJhbmNoZXMgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogRmVhdHVyZUJyYW5jaGVzUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgYnVpbGRDb21tYW5kczogc3RyaW5nW10gPVxuICAgICAgcHJvcHMuc3ludGhTaGVsbFN0ZXBQYXJ0aWFsUHJvcHM/LmNvbW1hbmRzICYmXG4gICAgICBwcm9wcy5zeW50aFNoZWxsU3RlcFBhcnRpYWxQcm9wcy5jb21tYW5kcy5sZW5ndGggPiAwXG4gICAgICAgID8gcHJvcHMuc3ludGhTaGVsbFN0ZXBQYXJ0aWFsUHJvcHMuY29tbWFuZHNcbiAgICAgICAgOiBbXCJucHggbnggcnVuLW1hbnkgLS10YXJnZXQ9YnVpbGQgLS1hbGxcIl07XG5cbiAgICBjb25zdCBpbnN0YWxsQ29tbWFuZHM6IHN0cmluZ1tdID1cbiAgICAgIHByb3BzLnN5bnRoU2hlbGxTdGVwUGFydGlhbFByb3BzPy5pbnN0YWxsQ29tbWFuZHMgJiZcbiAgICAgIHByb3BzLnN5bnRoU2hlbGxTdGVwUGFydGlhbFByb3BzLmluc3RhbGxDb21tYW5kcy5sZW5ndGggPiAwXG4gICAgICAgID8gcHJvcHMuc3ludGhTaGVsbFN0ZXBQYXJ0aWFsUHJvcHMuaW5zdGFsbENvbW1hbmRzXG4gICAgICAgIDogW1xuICAgICAgICAgICAgXCJucG0gaW5zdGFsbCAtZyBhd3MtY2RrXCIsXG4gICAgICAgICAgICBcInlhcm4gaW5zdGFsbCAtLWZyb3plbi1sb2NrZmlsZSB8fCBucHggcHJvamVuICYmIHlhcm4gaW5zdGFsbCAtLWZyb3plbi1sb2NrZmlsZVwiLFxuICAgICAgICAgIF07XG5cbiAgICBjb25zdCBjZGtDb21tYW5kID0gcHJvcHMuY2RrQ29tbWFuZCA/PyBcIm5weCBjZGtcIjtcblxuICAgIGNvbnN0IGNyZWF0ZUZlYXR1cmVCcmFuY2hQcm9qZWN0ID0gbmV3IFByb2plY3QoXG4gICAgICB0aGlzLFxuICAgICAgXCJDcmVhdGVGZWF0dXJlQnJhbmNoUHJvamVjdFwiLFxuICAgICAge1xuICAgICAgICAuLi5wcm9wcy5jb2RlQnVpbGREZWZhdWx0cyxcbiAgICAgICAgZGVzY3JpcHRpb246IFwiQnVpbGQgcHJvamVjdCB0byBkZXBsb3kgZmVhdHVyZSBicmFuY2ggcGlwZWxpbmVzXCIsXG4gICAgICAgIHNvdXJjZTogU291cmNlLmNvZGVDb21taXQoeyByZXBvc2l0b3J5OiBwcm9wcy5jb2RlUmVwb3NpdG9yeSB9KSxcbiAgICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBidWlsZEltYWdlOiBMaW51eEJ1aWxkSW1hZ2UuU1RBTkRBUkRfN18wLFxuICAgICAgICAgIGNvbXB1dGVUeXBlOiBDb21wdXRlVHlwZS5TTUFMTCxcbiAgICAgICAgICAuLi5wcm9wcy5jb2RlQnVpbGREZWZhdWx0cz8uYnVpbGRFbnZpcm9ubWVudCxcbiAgICAgICAgICBwcml2aWxlZ2VkOiBwcm9wcy5kb2NrZXJFbmFibGVkRm9yU3ludGgsXG4gICAgICAgIH0sXG4gICAgICAgIGJ1aWxkU3BlYzogQnVpbGRTcGVjLmZyb21PYmplY3RUb1lhbWwoe1xuICAgICAgICAgIHZlcnNpb246IFwiMC4yXCIsXG4gICAgICAgICAgcGhhc2VzOiB7XG4gICAgICAgICAgICBpbnN0YWxsOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmRzOiBpbnN0YWxsQ29tbWFuZHMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYnVpbGQ6IHtcbiAgICAgICAgICAgICAgY29tbWFuZHM6IFtcbiAgICAgICAgICAgICAgICAuLi5idWlsZENvbW1hbmRzLFxuICAgICAgICAgICAgICAgIGBjZCAke3Byb3BzLmNka1NyY0Rpcn1gLFxuICAgICAgICAgICAgICAgIGAke2Nka0NvbW1hbmR9IHN5bnRoYCxcbiAgICAgICAgICAgICAgICBgJHtjZGtDb21tYW5kfSBkZXBsb3kgLS1yZXF1aXJlLWFwcHJvdmFsPW5ldmVyYCxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBhcnRpZmFjdHM6IHtcbiAgICAgICAgICAgIGZpbGVzOiBbXCIqKi8qXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfVxuICAgICk7XG5cbiAgICBpZiAocHJvcHMuY29kZUJ1aWxkRGVmYXVsdHM/LnJvbGVQb2xpY3kpIHtcbiAgICAgIHByb3BzLmNvZGVCdWlsZERlZmF1bHRzLnJvbGVQb2xpY3kuZm9yRWFjaCgocG9saWN5KSA9PiB7XG4gICAgICAgIGNyZWF0ZUZlYXR1cmVCcmFuY2hQcm9qZWN0LmFkZFRvUm9sZVBvbGljeShwb2xpY3kpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY3JlYXRlRmVhdHVyZUJyYW5jaFByb2plY3QuYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XLFxuICAgICAgICBhY3Rpb25zOiBbXCJzdHM6QXNzdW1lUm9sZVwiXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbYGFybjoqOmlhbTo6JHtTdGFjay5vZih0aGlzKS5hY2NvdW50fTpyb2xlLypgXSxcbiAgICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICAgIFwiRm9yQW55VmFsdWU6U3RyaW5nRXF1YWxzXCI6IHtcbiAgICAgICAgICAgIFwiaWFtOlJlc291cmNlVGFnL2F3cy1jZGs6Ym9vdHN0cmFwLXJvbGVcIjogW1xuICAgICAgICAgICAgICBcImltYWdlLXB1Ymxpc2hpbmdcIixcbiAgICAgICAgICAgICAgXCJmaWxlLXB1Ymxpc2hpbmdcIixcbiAgICAgICAgICAgICAgXCJkZXBsb3lcIixcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGNvbnN0IGNyZWF0ZUZlYXR1cmVCcmFuY2hGdW5jdGlvbiA9IG5ldyBGdW5jdGlvbihcbiAgICAgIHRoaXMsXG4gICAgICBcIkxhbWJkYVRyaWdnZXJDcmVhdGVCcmFuY2hcIixcbiAgICAgIHtcbiAgICAgICAgcnVudGltZTogUnVudGltZS5QWVRIT05fM18xMixcbiAgICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKF9fZGlybmFtZSwgXCJsYW1iZGEvY3JlYXRlX2JyYW5jaFwiKSksXG4gICAgICAgIGhhbmRsZXI6IFwiY3JlYXRlX2JyYW5jaC5oYW5kbGVyXCIsXG4gICAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgICAgQ09ERUJVSUxEX1BST0pFQ1Q6IGNyZWF0ZUZlYXR1cmVCcmFuY2hQcm9qZWN0LnByb2plY3ROYW1lLFxuICAgICAgICAgIE1BSU5fQlJBTkNIOiBwcm9wcy5kZWZhdWx0QnJhbmNoTmFtZSxcbiAgICAgICAgfSxcbiAgICAgIH1cbiAgICApO1xuXG4gICAgY3JlYXRlRmVhdHVyZUJyYW5jaEZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgYWN0aW9uczogW1wiY29kZWJ1aWxkOlN0YXJ0QnVpbGRcIl0sXG4gICAgICAgIHJlc291cmNlczogW2NyZWF0ZUZlYXR1cmVCcmFuY2hQcm9qZWN0LnByb2plY3RBcm5dLFxuICAgICAgfSlcbiAgICApO1xuXG4gICAgY29uc3QgZGVzdHJveUZlYXR1cmVCcmFuY2hGdW5jdGlvbiA9IG5ldyBGdW5jdGlvbihcbiAgICAgIHRoaXMsXG4gICAgICBcIkxhbWJkYVRyaWdnZXJEZXN0cm95QnJhbmNoXCIsXG4gICAgICB7XG4gICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuUFlUSE9OXzNfMTIsXG4gICAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KHBhdGguam9pbihfX2Rpcm5hbWUsIFwibGFtYmRhL2Rlc3Ryb3lfYnJhbmNoXCIpKSxcbiAgICAgICAgaGFuZGxlcjogXCJkZXN0cm95X2JyYW5jaC5oYW5kbGVyXCIsXG4gICAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgICAgTUFJTl9CUkFOQ0g6IHByb3BzLmRlZmF1bHRCcmFuY2hOYW1lLFxuICAgICAgICAgIFJFUE9fTkFNRTogcHJvcHMuY29kZVJlcG9zaXRvcnkucmVwb3NpdG9yeU5hbWUsXG4gICAgICAgIH0sXG4gICAgICB9XG4gICAgKTtcbiAgICBkZXN0cm95RmVhdHVyZUJyYW5jaEZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgYWN0aW9uczogW1wiY2xvdWRmb3JtYXRpb246RGVsZXRlU3RhY2tcIl0sXG4gICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgIFN0YWNrLm9mKHRoaXMpLmZvcm1hdEFybih7XG4gICAgICAgICAgICBzZXJ2aWNlOiBcImNsb3VkZm9ybWF0aW9uXCIsXG4gICAgICAgICAgICByZXNvdXJjZTogXCJzdGFja1wiLFxuICAgICAgICAgICAgcmVzb3VyY2VOYW1lOiBcIiovKlwiLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgICAgXCJGb3JBbGxWYWx1ZXM6U3RyaW5nRXF1YWxzXCI6IHtcbiAgICAgICAgICAgIFwiYXdzOlRhZ0tleXNcIjogW1wiRmVhdHVyZUJyYW5jaFwiLCBcIlJlcG9OYW1lXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICk7XG4gICAgZGVzdHJveUZlYXR1cmVCcmFuY2hGdW5jdGlvbi5hZGRUb1JvbGVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICAgIGFjdGlvbnM6IFtcInRhZzpHZXRSZXNvdXJjZXNcIl0sXG4gICAgICAgIHJlc291cmNlczogW1wiKlwiXSxcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIHByb3BzLmNvZGVSZXBvc2l0b3J5Lm9uUmVmZXJlbmNlQ3JlYXRlZChcIkJyYW5jaENyZWF0ZVRyaWdnZXJcIiwge1xuICAgICAgdGFyZ2V0OiBuZXcgTGFtYmRhRnVuY3Rpb24oY3JlYXRlRmVhdHVyZUJyYW5jaEZ1bmN0aW9uKSxcbiAgICAgIGRlc2NyaXB0aW9uOiBcIkFXUyBDb2RlQ29tbWl0IHJlZmVyZW5jZSBjcmVhdGVkIGV2ZW50LlwiLFxuICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgIGRldGFpbDoge1xuICAgICAgICAgIHJlZmVyZW5jZVR5cGU6IFtcImJyYW5jaFwiXSxcbiAgICAgICAgICByZWZlcmVuY2VOYW1lOiBwcm9wcy5icmFuY2hOYW1lUHJlZml4ZXMubWFwKChwcmVmaXgpID0+ICh7IHByZWZpeCB9KSksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgcHJvcHMuY29kZVJlcG9zaXRvcnkub25SZWZlcmVuY2VEZWxldGVkKFwiQnJhbmNoRGVzdHJveVRyaWdnZXJcIiwge1xuICAgICAgdGFyZ2V0OiBuZXcgTGFtYmRhRnVuY3Rpb24oZGVzdHJveUZlYXR1cmVCcmFuY2hGdW5jdGlvbiksXG4gICAgICBkZXNjcmlwdGlvbjogXCJBV1MgQ29kZUNvbW1pdCByZWZlcmVuY2UgZGVsZXRlZCBldmVudC5cIixcbiAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICByZWZlcmVuY2VUeXBlOiBbXCJicmFuY2hcIl0sXG4gICAgICAgICAgcmVmZXJlbmNlTmFtZTogcHJvcHMuYnJhbmNoTmFtZVByZWZpeGVzLm1hcCgocHJlZml4KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4geyBwcmVmaXggfTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpO1xuXG4gICAgW1wiQXdzU29sdXRpb25zLUlBTTVcIiwgXCJBd3NQcm90b3R5cGluZy1JQU1Ob1dpbGRjYXJkUGVybWlzc2lvbnNcIl0uZm9yRWFjaChcbiAgICAgIChSdWxlSWQpID0+IHtcbiAgICAgICAgTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICAgICAgICAgIGNyZWF0ZUZlYXR1cmVCcmFuY2hQcm9qZWN0LnJvbGUhLFxuICAgICAgICAgIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6IFJ1bGVJZCxcbiAgICAgICAgICAgICAgcmVhc29uOlxuICAgICAgICAgICAgICAgIFwiQ29kZUJ1aWxkIHJlcXVpcmVzIGdldCwgbGlzdCwgYW5kIHB1bGwgYWNjZXNzIHRvIHRoZSBDb2RlQ29tbWl0IHJlcG9zaXRvcnkuXCIsXG4gICAgICAgICAgICAgIGFwcGxpZXNUbzogW1xuICAgICAgICAgICAgICAgIFwiQWN0aW9uOjpjb2RlY29tbWl0OkdldCpcIixcbiAgICAgICAgICAgICAgICBcIkFjdGlvbjo6Y29kZWNvbW1pdDpMaXN0KlwiLFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6IFJ1bGVJZCxcbiAgICAgICAgICAgICAgcmVhc29uOlxuICAgICAgICAgICAgICAgIFwiQ29kZUJ1aWxkIHJlcXVpcmVzIGFjY2VzcyB0byBjcmVhdGUgcmVwb3J0IGdyb3VwcyB0aGF0IGFyZSBkeW5hbWljYWxseSBkZXRlcm1pbmVkLlwiLFxuICAgICAgICAgICAgICBhcHBsaWVzVG86IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByZWdleDogYC9eUmVzb3VyY2U6OmFybjoke1BES05hZy5nZXRTdGFja1BhcnRpdGlvblJlZ2V4KFxuICAgICAgICAgICAgICAgICAgICBzdGFja1xuICAgICAgICAgICAgICAgICAgKX06Y29kZWJ1aWxkOiR7UERLTmFnLmdldFN0YWNrUmVnaW9uUmVnZXgoXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrXG4gICAgICAgICAgICAgICAgICApfToke1BES05hZy5nZXRTdGFja0FjY291bnRSZWdleChcbiAgICAgICAgICAgICAgICAgICAgc3RhY2tcbiAgICAgICAgICAgICAgICAgICl9OnJlcG9ydC1ncm91cC88W2EtekEtWjAtOV0qQ3JlYXRlRmVhdHVyZUJyYW5jaFByb2plY3QuKj4tXFxcXCokL2dgLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogUnVsZUlkLFxuICAgICAgICAgICAgICByZWFzb246XG4gICAgICAgICAgICAgICAgXCJDb2RlQnVpbGQgcmVxdWlyZXMgYWNjZXNzIHRvIG1hbmFnZSBsb2dzIGFuZCBzdHJlYW1zIHdob3NlIG5hbWVzIGFyZSBkeW5hbWljYWxseSBkZXRlcm1pbmVkLlwiLFxuICAgICAgICAgICAgICBhcHBsaWVzVG86IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByZWdleDogYC9eUmVzb3VyY2U6OmFybjoke1BES05hZy5nZXRTdGFja1BhcnRpdGlvblJlZ2V4KFxuICAgICAgICAgICAgICAgICAgICBzdGFja1xuICAgICAgICAgICAgICAgICAgKX06bG9nczoke1BES05hZy5nZXRTdGFja1JlZ2lvblJlZ2V4KFxuICAgICAgICAgICAgICAgICAgICBzdGFja1xuICAgICAgICAgICAgICAgICAgKX06JHtQREtOYWcuZ2V0U3RhY2tBY2NvdW50UmVnZXgoXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrXG4gICAgICAgICAgICAgICAgICApfTpsb2ctZ3JvdXA6L2F3cy9jb2RlYnVpbGQvPFthLXpBLVowLTldKkNyZWF0ZUZlYXR1cmVCcmFuY2hQcm9qZWN0Lio+OlxcXFwqJC9nYCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6IFJ1bGVJZCxcbiAgICAgICAgICAgICAgcmVhc29uOlxuICAgICAgICAgICAgICAgIFwiQ29kZUJ1aWxkIHJlcXVpcmVzIGFjY2VzcyB0byBhc3N1bWUgYSByb2xlIGZyb20gd2l0aGluIHRoZSBjdXJyZW50IGFjY291bnQgbGltaXRlZCBieSBhIGNvbmRpdGlvbiBpbiBvcmRlciB0byBkZXBsb3kuXCIsXG4gICAgICAgICAgICAgIGFwcGxpZXNUbzogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHJlZ2V4OiBgL15SZXNvdXJjZTo6YXJuOlxcXFwqOmlhbTo6JHtQREtOYWcuZ2V0U3RhY2tBY2NvdW50UmVnZXgoXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrXG4gICAgICAgICAgICAgICAgICApfTpyb2xlL1xcXFwqJC9nYCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcblxuICAgICAgICBOYWdTdXBwcmVzc2lvbnMuYWRkUmVzb3VyY2VTdXBwcmVzc2lvbnMoXG4gICAgICAgICAgZGVzdHJveUZlYXR1cmVCcmFuY2hGdW5jdGlvbi5yb2xlISxcbiAgICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiBSdWxlSWQsXG4gICAgICAgICAgICAgIHJlYXNvbjpcbiAgICAgICAgICAgICAgICBcIlRoZSBEZXN0cm95QnJhbmNoIExhbWJkYSByZXF1aXJlcyBhY2Nlc3MgdG8gZGVsZXRlIGFueSBzdGFja3Mgd2l0aCBzcGVjaWZpYyB0YWdzLlwiLFxuICAgICAgICAgICAgICBhcHBsaWVzVG86IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByZWdleDogYC9eUmVzb3VyY2U6OmFybjoke1BES05hZy5nZXRTdGFja1BhcnRpdGlvblJlZ2V4KFxuICAgICAgICAgICAgICAgICAgICBzdGFja1xuICAgICAgICAgICAgICAgICAgKX06Y2xvdWRmb3JtYXRpb246JHtQREtOYWcuZ2V0U3RhY2tSZWdpb25SZWdleChcbiAgICAgICAgICAgICAgICAgICAgc3RhY2tcbiAgICAgICAgICAgICAgICAgICl9OiR7UERLTmFnLmdldFN0YWNrQWNjb3VudFJlZ2V4KHN0YWNrKX06c3RhY2svXFxcXCovXFxcXCokL2dgLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogUnVsZUlkLFxuICAgICAgICAgICAgICByZWFzb246XG4gICAgICAgICAgICAgICAgXCJUaGUgRGVzdHJveUJyYW5jaCBMYW1iZGEgcmVxdWlyZXMgYWNjZXNzIHRvIGxvb2sgdXAgQ2xvdWRGb3JtYXRpb24gc3RhY2tzIGJ5IHRhZy4gVGhlIFJlc291cmNlIEdyb3VwIFRhZ2dpbmcgQVBJIG11c3QgdXNlICdSZXNvdXJjZSc6ICcqJy5cIixcbiAgICAgICAgICAgICAgYXBwbGllc1RvOiBbXCJSZXNvdXJjZTo6KlwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0cnVlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIFtcIkF3c1NvbHV0aW9ucy1JQU00XCIsIFwiQXdzUHJvdG90eXBpbmctSUFNTm9NYW5hZ2VkUG9saWNpZXNcIl0uZm9yRWFjaChcbiAgICAgIChSdWxlSWQpID0+IHtcbiAgICAgICAgTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICAgICAgICAgIGNyZWF0ZUZlYXR1cmVCcmFuY2hGdW5jdGlvbixcbiAgICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiBSdWxlSWQsXG4gICAgICAgICAgICAgIHJlYXNvbjpcbiAgICAgICAgICAgICAgICBcIkxhbWJkYSBmdW5jdGlvbnMgdXNlIHRoZSBkZWZhdWx0IEFXUyBMYW1iZGFCYXNpY0V4ZWN1dGlvblJvbGUgbWFuYWdlZCByb2xlLlwiLFxuICAgICAgICAgICAgICBhcHBsaWVzVG86IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByZWdleDogYC9eUG9saWN5Ojphcm46JHtQREtOYWcuZ2V0U3RhY2tQYXJ0aXRpb25SZWdleChcbiAgICAgICAgICAgICAgICAgICAgc3RhY2tcbiAgICAgICAgICAgICAgICAgICl9OmlhbTo6YXdzOnBvbGljeS9zZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlJC9nYCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgICAgTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICAgICAgICAgIGRlc3Ryb3lGZWF0dXJlQnJhbmNoRnVuY3Rpb24sXG4gICAgICAgICAgW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogUnVsZUlkLFxuICAgICAgICAgICAgICByZWFzb246XG4gICAgICAgICAgICAgICAgXCJMYW1iZGEgZnVuY3Rpb25zIHVzZSB0aGUgZGVmYXVsdCBBV1MgTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlIG1hbmFnZWQgcm9sZS5cIixcbiAgICAgICAgICAgICAgYXBwbGllc1RvOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgcmVnZXg6IGAvXlBvbGljeTo6YXJuOiR7UERLTmFnLmdldFN0YWNrUGFydGl0aW9uUmVnZXgoXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrXG4gICAgICAgICAgICAgICAgICApfTppYW06OmF3czpwb2xpY3kvc2VydmljZS1yb2xlL0FXU0xhbWJkYUJhc2ljRXhlY3V0aW9uUm9sZSQvZ2AsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0cnVlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIFtcbiAgICAgIFwiQXdzU29sdXRpb25zLUNCNFwiLFxuICAgICAgXCJBd3NQcm90b3R5cGluZy1Db2RlQnVpbGRQcm9qZWN0S01TRW5jcnlwdGVkQXJ0aWZhY3RzXCIsXG4gICAgXS5mb3JFYWNoKChSdWxlSWQpID0+IHtcbiAgICAgIE5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9ucyhjcmVhdGVGZWF0dXJlQnJhbmNoUHJvamVjdCwgW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6IFJ1bGVJZCxcbiAgICAgICAgICByZWFzb246IFwiRW5jcnlwdGlvbiBvZiBDb2RlYnVpbGQgaXMgbm90IHJlcXVpcmVkLlwiLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==