UNPKG

projen

Version:

CDK for software projects

289 lines • 45 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.BuildWorkflow = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const posixPath = require("node:path/posix"); const component_1 = require("../component"); const github_1 = require("../github"); const constants_1 = require("../github/constants"); const util_1 = require("../github/private/util"); const workflow_actions_1 = require("../github/workflow-actions"); const workflows_model_1 = require("../github/workflows-model"); const javascript_1 = require("../javascript"); const runner_options_1 = require("../runner-options"); const consts_1 = require("./private/consts"); const name_1 = require("../util/name"); class BuildWorkflow extends component_1.Component { constructor(project, options) { super(project); this._postBuildJobs = []; const github = github_1.GitHub.of(this.project.root); if (!github) { throw new Error("BuildWorkflow is currently only supported for GitHub projects"); } this.github = github; this.preBuildSteps = options.preBuildSteps ?? []; this.postBuildSteps = options.postBuildSteps ?? []; this.gitIdentity = options.gitIdentity ?? constants_1.DEFAULT_GITHUB_ACTIONS_USER; this.buildTask = options.buildTask; this.artifactsDirectory = options.artifactsDirectory ?? consts_1.DEFAULT_ARTIFACTS_DIRECTORY; (0, util_1.ensureNotHiddenPath)(this.artifactsDirectory, "artifactsDirectory"); this.name = options.name ?? (0, name_1.workflowNameForProject)("build", this.project); const mutableBuilds = options.mutableBuild ?? true; this.workflow = new github_1.GithubWorkflow(github, this.name); this.workflow.on(options.workflowTriggers ?? { pullRequest: {}, workflowDispatch: {}, // allow manual triggering }); this.addBuildJob(options); if (mutableBuilds) { this.addSelfMutationJob(options); } if (project instanceof javascript_1.NodeProject) { project.addPackageIgnore(constants_1.PERMISSION_BACKUP_FILE); } } addBuildJob(options) { const projectPathRelativeToRoot = (0, util_1.projectPathRelativeToRepoRoot)(this.project); const jobConfig = { ...(0, runner_options_1.filteredRunsOnOptions)(options.buildRunsOn ?? options.runsOn, options.runsOnGroup), container: options.containerImage ? { image: options.containerImage } : undefined, env: { CI: "true", ...options.env, }, permissions: { contents: workflows_model_1.JobPermission.WRITE, ...options.permissions, }, defaults: this.project.parent // is subproject, ? { run: { workingDirectory: projectPathRelativeToRoot, }, } : undefined, steps: (() => this.renderBuildSteps(projectPathRelativeToRoot)), outputs: { [consts_1.SELF_MUTATION_HAPPENED_OUTPUT]: { stepId: consts_1.SELF_MUTATION_STEP, outputName: consts_1.SELF_MUTATION_HAPPENED_OUTPUT, }, }, }; this.workflow.addJob(consts_1.BUILD_JOBID, jobConfig); } /** * Returns a list of job IDs that are part of the build. */ get buildJobIds() { return [consts_1.BUILD_JOBID, ...this._postBuildJobs]; } /** * Adds steps that are executed after the build. * @param steps The job steps */ addPostBuildSteps(...steps) { this.postBuildSteps.push(...steps); } /** * Adds another job to the build workflow which is executed after the build * job succeeded. * * Jobs are executed _only_ if the build did NOT self mutate. If the build * self-mutate, the branch will either be updated or the build will fail (in * forks), so there is no point in executing the post-build job. * * @param id The id of the new job * @param job The job specification */ addPostBuildJob(id, job) { const steps = []; steps.push(github_1.WorkflowSteps.downloadArtifact({ name: "Download build artifacts", with: { artifactIds: [ `\${{ needs.${consts_1.BUILD_JOBID}.outputs.${consts_1.ARTIFACT_ID_OUTPUT} }}`, ], path: this.artifactsDirectory, }, }), { name: "Restore build artifact permissions", continueOnError: true, run: [ `cd ${this.artifactsDirectory} && setfacl --restore=${constants_1.PERMISSION_BACKUP_FILE}`, ].join("\n"), }); steps.push(...(job.steps ?? [])); this.workflow.addJob(id, { needs: [consts_1.BUILD_JOBID], // only run if build did not self-mutate if: `\${{ !${consts_1.SELF_MUTATION_CONDITION} }}`, ...job, steps: steps, }); // add to the list of build job IDs this._postBuildJobs.push(id); // add artifact_id output to the build job (only needed when post-build jobs exist) const buildJob = this.workflow.getJob(consts_1.BUILD_JOBID); if (buildJob.outputs && !buildJob.outputs[consts_1.ARTIFACT_ID_OUTPUT]) { buildJob.outputs[consts_1.ARTIFACT_ID_OUTPUT] = { stepId: consts_1.UPLOAD_ARTIFACT_STEP, outputName: "artifact-id", }; } } /** * Run a task as a job within the build workflow which is executed after the * build job succeeded. * * The job will have access to build artifacts and will install project * dependencies in order to be able to run any commands used in the tasks. * * Jobs are executed _only_ if the build did NOT self mutate. If the build * self-mutate, the branch will either be updated or the build will fail (in * forks), so there is no point in executing the post-build job. * * @param options Specify tools and other options */ addPostBuildJobTask(task, options = {}) { this.addPostBuildJobCommands(`post-build-${task.name}`, [`${this.project.projenCommand} ${task.name}`], { checkoutRepo: true, installDeps: true, tools: options.tools, ...(0, runner_options_1.filteredRunsOnOptions)(options.runsOn, options.runsOnGroup), }); } /** * Run a sequence of commands as a job within the build workflow which is * executed after the build job succeeded. * * Jobs are executed _only_ if the build did NOT self mutate. If the build * self-mutate, the branch will either be updated or the build will fail (in * forks), so there is no point in executing the post-build job. * * @param options Specify tools and other options */ addPostBuildJobCommands(id, commands, options) { const steps = []; if (options?.checkoutRepo) { steps.push(github_1.WorkflowSteps.checkout({ with: { ref: consts_1.PULL_REQUEST_REF, repository: consts_1.PULL_REQUEST_REPOSITORY, ...(this.github.downloadLfs ? { lfs: true } : {}), ...(this.github.checkoutSubmodules !== github_1.CheckoutSubmodules.DISABLED ? { submodules: this.github.checkoutSubmodules } : {}), }, })); } if (options?.checkoutRepo && options?.installDeps && this.project instanceof javascript_1.NodeProject) { steps.push({ name: "Install dependencies", run: `${this.project.package.installCommand}`, }); } steps.push({ run: commands.join("\n") }); this.addPostBuildJob(id, { permissions: { contents: workflows_model_1.JobPermission.READ, }, tools: options?.tools, ...(0, runner_options_1.filteredRunsOnOptions)(options?.runsOn, options?.runsOnGroup), steps, }); } addSelfMutationJob(options) { const credentials = this.workflow.projenCredentials; this.workflow.addJob("self-mutation", { ...(0, runner_options_1.filteredRunsOnOptions)(options.runsOn, options.runsOnGroup), permissions: { contents: workflows_model_1.JobPermission.WRITE, }, needs: [consts_1.BUILD_JOBID], if: `always() && ${consts_1.SELF_MUTATION_CONDITION} && ${consts_1.NOT_FORK}`, environment: credentials.environment, steps: [ ...credentials.setupSteps, ...workflow_actions_1.WorkflowActions.checkoutWithPatch({ // we need to use a PAT so that our push will trigger the build workflow token: credentials.tokenRef, ref: consts_1.PULL_REQUEST_REF, repository: consts_1.PULL_REQUEST_REPOSITORY, lfs: this.github.downloadLfs, }), github_1.WorkflowSteps.setupGitIdentity({ gitIdentity: this.gitIdentity }), { name: "Push changes", env: { PULL_REQUEST_REF: consts_1.PULL_REQUEST_REF, }, run: [ "git add .", 'git commit -s -m "chore: self mutation"', `git push origin "HEAD:$PULL_REQUEST_REF"`, ].join("\n"), }, ], }); } /** * Called (lazily) during synth to render the build job steps. */ renderBuildSteps(projectPathRelativeToRoot) { return [ github_1.WorkflowSteps.checkout({ with: { ref: consts_1.PULL_REQUEST_REF, repository: consts_1.PULL_REQUEST_REPOSITORY, ...(this.github.downloadLfs ? { lfs: true } : {}), ...(this.github.checkoutSubmodules ? { submodules: this.github.checkoutSubmodules } : {}), }, }), ...this.preBuildSteps, { name: this.buildTask.name, run: this.github.project.runTaskCommand(this.buildTask), }, ...this.postBuildSteps, // check for mutations and upload a git patch file as an artifact ...workflow_actions_1.WorkflowActions.uploadGitPatch({ stepId: consts_1.SELF_MUTATION_STEP, outputName: consts_1.SELF_MUTATION_HAPPENED_OUTPUT, mutationError: "Files were changed during build (see build log). If this was triggered from a fork, you will need to update your branch.", }), // upload the build artifact only if we have post-build jobs (otherwise, there's no point) ...(this._postBuildJobs.length == 0 ? [] : [ { name: "Backup artifact permissions", continueOnError: true, run: `cd ${this.artifactsDirectory} && getfacl -R . > ${constants_1.PERMISSION_BACKUP_FILE}`, }, github_1.WorkflowSteps.uploadArtifact({ id: consts_1.UPLOAD_ARTIFACT_STEP, with: { name: constants_1.BUILD_ARTIFACT_NAME, path: this.project.parent ? posixPath.join(projectPathRelativeToRoot, this.artifactsDirectory) : this.artifactsDirectory, }, }), ]), ]; } } exports.BuildWorkflow = BuildWorkflow; _a = JSII_RTTI_SYMBOL_1; BuildWorkflow[_a] = { fqn: "projen.build.BuildWorkflow", version: "0.99.70" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtd29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYnVpbGQvYnVpbGQtd29ya2Zsb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBNkM7QUFFN0MsNENBQXlDO0FBRXpDLHNDQUttQjtBQUNuQixtREFJNkI7QUFDN0IsaURBR2dDO0FBQ2hDLGlFQUE2RDtBQVE3RCwrREFBMEQ7QUFDMUQsOENBQTRDO0FBRzVDLHNEQUEwRDtBQUMxRCw2Q0FXMEI7QUFDMUIsdUNBQXNEO0FBbUh0RCxNQUFhLGFBQWMsU0FBUSxxQkFBUztJQW9CMUMsWUFBWSxPQUFnQixFQUFFLE9BQTZCO1FBQ3pELEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUhBLG1CQUFjLEdBQWEsRUFBRSxDQUFDO1FBSzdDLE1BQU0sTUFBTSxHQUFHLGVBQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDWixNQUFNLElBQUksS0FBSyxDQUNiLCtEQUErRCxDQUNoRSxDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUM7UUFDakQsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxJQUFJLEVBQUUsQ0FBQztRQUNuRCxJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksdUNBQTJCLENBQUM7UUFDdEUsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDO1FBQ25DLElBQUksQ0FBQyxrQkFBa0I7WUFDckIsT0FBTyxDQUFDLGtCQUFrQixJQUFJLG9DQUEyQixDQUFDO1FBQzVELElBQUEsMEJBQW1CLEVBQUMsSUFBSSxDQUFDLGtCQUFr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SSxDQUFDLFNBQVMsQ0FBQyxJQUFJO2dCQUN6QixHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7YUFDeEQ7WUFFRCxHQUFHLElBQUksQ0FBQyxjQUFjO1lBRXRCLGlFQUFpRTtZQUNqRSxHQUFHLGtDQUFlLENBQUMsY0FBYyxDQUFDO2dCQUNoQyxNQUFNLEVBQUUsMkJBQWtCO2dCQUMxQixVQUFVLEVBQUUsc0NBQTZCO2dCQUN6QyxhQUFhLEVBQ1gsMEhBQTBIO2FBQzdILENBQUM7WUFFRiwwRkFBMEY7WUFDMUYsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxJQUFJLENBQUM7Z0JBQ2pDLENBQUMsQ0FBQyxFQUFFO2dCQUNKLENBQUMsQ0FBQztvQkFDRTt3QkFDRSxJQUFJLEVBQUUsNkJBQTZCO3dCQUNuQyxlQUFlLEVBQUUsSUFBSTt3QkFDckIsR0FBRyxFQUFFLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixzQkFBc0Isa0NBQXNCLEVBQUU7cUJBQ2pGO29CQUNELHNCQUFhLENBQUMsY0FBYyxDQUFDO3dCQUMzQixFQUFFLEVBQUUsNkJBQW9CO3dCQUN4QixJQUFJLEVBQUU7NEJBQ0osSUFBSSxFQUFFLCtCQUFtQjs0QkFDekIsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTTtnQ0FDdkIsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQ1oseUJBQXlCLEVBQ3pCLElBQUksQ0FBQyxrQkFBa0IsQ0FDeEI7Z0NBQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0I7eUJBQzVCO3FCQUNGLENBQUM7aUJBQ0gsQ0FBQztTQUNQLENBQUM7SUFDSixDQUFDOztBQXpWSCxzQ0EwVkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwb3NpeFBhdGggZnJvbSBcIm5vZGU6cGF0aC9wb3NpeFwiO1xuaW1wb3J0IHR5cGUgeyBUYXNrIH0gZnJvbSBcIi4uXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi4vY29tcG9uZW50XCI7XG5pbXBvcnQgdHlwZSB7IEdpdElkZW50aXR5LCB3b3JrZmxvd3MgfSBmcm9tIFwiLi4vZ2l0aHViXCI7XG5pbXBvcnQge1xuICBDaGVja291dFN1Ym1vZHVsZXMsXG4gIEdpdEh1YixcbiAgR2l0aHViV29ya2Zsb3csXG4gIFdvcmtmbG93U3RlcHMsXG59IGZyb20gXCIuLi9naXRodWJcIjtcbmltcG9ydCB7XG4gIEJVSUxEX0FSVElGQUNUX05BTUUsXG4gIERFRkFVTFRfR0lUSFVCX0FDVElPTlNfVVNFUixcbiAgUEVSTUlTU0lPTl9CQUNLVVBfRklMRSxcbn0gZnJvbSBcIi4uL2dpdGh1Yi9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIGVuc3VyZU5vdEhpZGRlblBhdGgsXG4gIHByb2plY3RQYXRoUmVsYXRpdmVUb1JlcG9Sb290LFxufSBmcm9tIFwiLi4vZ2l0aHViL3ByaXZhdGUvdXRpbFwiO1xuaW1wb3J0IHsgV29ya2Zsb3dBY3Rpb25zIH0gZnJvbSBcIi4uL2dpdGh1Yi93b3JrZmxvdy1hY3Rpb25zXCI7XG5pbXBvcnQgdHlwZSB7XG4gIEpvYixcbiAgSm9iUGVybWlzc2lvbnMsXG4gIEpvYlN0ZXAsXG4gIFRvb2xzLFxuICBUcmlnZ2Vycyxcbn0gZnJvbSBcIi4uL2dpdGh1Yi93b3JrZmxvd3MtbW9kZWxcIjtcbmltcG9ydCB7IEpvYlBlcm1pc3Npb24gfSBmcm9tIFwiLi4vZ2l0aHViL3dvcmtmbG93cy1tb2RlbFwiO1xuaW1wb3J0IHsgTm9kZVByb2plY3QgfSBmcm9tIFwiLi4vamF2YXNjcmlwdFwiO1xuaW1wb3J0IHR5cGUgeyBQcm9qZWN0IH0gZnJvbSBcIi4uL3Byb2plY3RcIjtcbmltcG9ydCB0eXBlIHsgR3JvdXBSdW5uZXJPcHRpb25zIH0gZnJvbSBcIi4uL3J1bm5lci1vcHRpb25zXCI7XG5pbXBvcnQgeyBmaWx0ZXJlZFJ1bnNPbk9wdGlvbnMgfSBmcm9tIFwiLi4vcnVubmVyLW9wdGlvbnNcIjtcbmltcG9ydCB7XG4gIEFSVElGQUNUX0lEX09VVFBVVCxcbiAgQlVJTERfSk9CSUQsXG4gIERFRkFVTFRfQVJUSUZBQ1RTX0RJUkVDVE9SWSxcbiAgTk9UX0ZPUkssXG4gIFBVTExfUkVRVUVTVF9SRUYsXG4gIFBVTExfUkVRVUVTVF9SRVBPU0lUT1JZLFxuICBTRUxGX01VVEFUSU9OX0NPTkRJVElPTixcbiAgU0VMRl9NVVRBVElPTl9IQVBQRU5FRF9PVVRQVVQsXG4gIFNFTEZfTVVUQVRJT05fU1RFUCxcbiAgVVBMT0FEX0FSVElGQUNUX1NURVAsXG59IGZyb20gXCIuL3ByaXZhdGUvY29uc3RzXCI7XG5pbXBvcnQgeyB3b3JrZmxvd05hbWVGb3JQcm9qZWN0IH0gZnJvbSBcIi4uL3V0aWwvbmFtZVwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkV29ya2Zsb3dDb21tb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIGJ1aWxkZmlsZSAoZS5nLiBcImJ1aWxkXCIgYmVjb21lcyBcImJ1aWxkLnltbFwiKS5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJidWlsZFwiXG4gICAqL1xuICByZWFkb25seSBuYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTdGVwcyB0byBleGVjdXRlIGJlZm9yZSB0aGUgYnVpbGQuXG4gICAqIEBkZWZhdWx0IFtdXG4gICAqL1xuICByZWFkb25seSBwcmVCdWlsZFN0ZXBzPzogSm9iU3RlcFtdO1xuXG4gIC8qKlxuICAgKiBCdWlsZCB3b3JrZmxvdyB0cmlnZ2Vyc1xuICAgKiBAZGVmYXVsdCBcInsgcHVsbFJlcXVlc3Q6IHt9LCB3b3JrZmxvd0Rpc3BhdGNoOiB7fSB9XCJcbiAgICovXG4gIHJlYWRvbmx5IHdvcmtmbG93VHJpZ2dlcnM/OiBUcmlnZ2VycztcblxuICAvKipcbiAgICogUGVybWlzc2lvbnMgZ3JhbnRlZCB0byB0aGUgYnVpbGQgam9iXG4gICAqIFRvIGxpbWl0IGpvYiBwZXJtaXNzaW9ucyBmb3IgYGNvbnRlbnRzYCwgdGhlIGRlc2lyZWQgcGVybWlzc2lvbnMgaGF2ZSB0byBiZSBleHBsaWNpdGx5IHNldCwgZS5nLjogYHsgY29udGVudHM6IEpvYlBlcm1pc3Npb24uTk9ORSB9YFxuICAgKiBAZGVmYXVsdCBgeyBjb250ZW50czogSm9iUGVybWlzc2lvbi5XUklURSB9YFxuICAgKi9cbiAgcmVhZG9ubHkgcGVybWlzc2lvbnM/OiBKb2JQZXJtaXNzaW9ucztcblxuICAvKipcbiAgICogQnVpbGQgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKi9cbiAgcmVhZG9ubHkgZW52PzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCdWlsZFdvcmtmbG93T3B0aW9ucyBleHRlbmRzIEJ1aWxkV29ya2Zsb3dDb21tb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSB0YXNrIHRvIGV4ZWN1dGUgaW4gb3JkZXIgdG8gYnVpbGQgdGhlIHByb2plY3QuXG4gICAqL1xuICByZWFkb25seSBidWlsZFRhc2s6IFRhc2s7XG5cbiAgLyoqXG4gICAqIEEgbmFtZSBvZiBhIGRpcmVjdG9yeSB0aGF0IGluY2x1ZGVzIGJ1aWxkIGFydGlmYWN0cy5cbiAgICogQGRlZmF1bHQgXCJkaXN0XCJcbiAgICovXG4gIHJlYWRvbmx5IGFydGlmYWN0c0RpcmVjdG9yeT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGNvbnRhaW5lciBpbWFnZSB0byB1c2UgZm9yIGJ1aWxkcy5cbiAgICogQGRlZmF1bHQgLSB0aGUgZGVmYXVsdCB3b3JrZmxvdyBjb250YWluZXJcbiAgICovXG4gIHJlYWRvbmx5IGNvbnRhaW5lckltYWdlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBdXRvbWF0aWNhbGx5IHVwZGF0ZSBmaWxlcyBtb2RpZmllZCBkdXJpbmcgYnVpbGRzIHRvIHB1bGwtcmVxdWVzdCBicmFuY2hlcy5cbiAgICogVGhpcyBtZWFucyB0aGF0IGFueSBmaWxlcyBzeW50aGVzaXplZCBieSBwcm9qZW4gb3IgZS5nLiB0ZXN0IHNuYXBzaG90cyB3aWxsXG4gICAqIGFsd2F5cyBiZSB1cC10by1kYXRlIGJlZm9yZSBhIFBSIGlzIG1lcmdlZC5cbiAgICpcbiAgICogSW1wbGllcyB0aGF0IFBSIGJ1aWxkcyBkbyBub3QgaGF2ZSBhbnRpLXRhbXBlciBjaGVja3MuXG4gICAqXG4gICAqIFRoaXMgaXMgZW5hYmxlZCBieSBkZWZhdWx0IG9ubHkgaWYgYGdpdGh1YlRva2VuU2VjcmV0YCBpcyBzZXQuIE90aGVyd2lzZSBpdFxuICAgKiBpcyBkaXNhYmxlZCwgd2hpY2ggaW1wbGllcyB0aGF0IGZpbGUgY2hhbmdlcyB0aGF0IGhhcHBlbiBkdXJpbmcgYnVpbGQgd2lsbFxuICAgKiBub3QgYmUgcHVzaGVkIGJhY2sgdG8gdGhlIGJyYW5jaC5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgbXV0YWJsZUJ1aWxkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogUGVyZm9ybSBhIG11dGFibGUgKG5vbi1mcm96ZW4pIGluc3RhbGwgZHVyaW5nIGJ1aWxkcy4gVGhpcyB3aWxsIHVwZGF0ZSB0aGVcbiAgICogcGFja2FnZSBsb2NrZmlsZSBkdXJpbmcgaW5zdGFsbHMsIHdoaWNoIGlzIHVzZWZ1bCB3aGVuIGJ1aWxkIHN0ZXBzIG1vZGlmeVxuICAgKiBkZXBlbmRlbmNpZXMuIFNldCB0byBgZmFsc2VgIHRvIHVzZSBmcm96ZW4gbG9ja2ZpbGUgaW5zdGFsbHMgZXZlbiB3aGVuXG4gICAqIGBtdXRhYmxlQnVpbGRgIGlzIGVuYWJsZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdmFsdWUgb2YgYG11dGFibGVCdWlsZGBcbiAgICovXG4gIHJlYWRvbmx5IG11dGFibGVJbnN0YWxsPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogU3RlcHMgdG8gZXhlY3V0ZSBhZnRlciBidWlsZC5cbiAgICogQGRlZmF1bHQgW11cbiAgICovXG4gIHJlYWRvbmx5IHBvc3RCdWlsZFN0ZXBzPzogSm9iU3RlcFtdO1xuXG4gIC8qKlxuICAgKiBHaXQgaWRlbnRpdHkgdG8gdXNlIGZvciB0aGUgd29ya2Zsb3cuXG4gICAqIEBkZWZhdWx0IC0gZGVmYXVsdCBHaXRIdWIgQWN0aW9ucyB1c2VyXG4gICAqL1xuICByZWFkb25seSBnaXRJZGVudGl0eT86IEdpdElkZW50aXR5O1xuXG4gIC8qKlxuICAgKiBHaXRodWIgUnVubmVyIHNlbGVjdGlvbiBsYWJlbHNcbiAgICogQGRlZmF1bHQgW1widWJ1bnR1LWxhdGVzdFwiXVxuICAgKiBAZGVzY3JpcHRpb24gRGVmaW5lcyBhIHRhcmdldCBSdW5uZXIgYnkgbGFiZWxzXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBpZiBib3RoIGBydW5zT25gIGFuZCBgcnVuc09uR3JvdXBgIGFyZSBzcGVjaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IHJ1bnNPbj86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBHaXRodWIgUnVubmVyIHNlbGVjdGlvbiBsYWJlbHNcbiAgICogQGRlZmF1bHQgLSBydW5zT25cbiAgICogQGRlc2NyaXB0aW9uIERlZmluZXMgYSB0YXJnZXQgUnVubmVyIGJ5IGxhYmVscyBmb3IganVzdCB0aGUgYnVpbGQgam9iXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBpZiBib3RoIGBydW5zT25gIGFuZCBgcnVuc09uR3JvdXBgIGFyZSBzcGVjaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkUnVuc09uPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEdpdGh1YiBSdW5uZXIgR3JvdXAgc2VsZWN0aW9uIG9wdGlvbnNcbiAgICogQGRlc2NyaXB0aW9uIERlZmluZXMgYSB0YXJnZXQgUnVubmVyIEdyb3VwIGJ5IG5hbWUgYW5kL29yIGxhYmVsc1xuICAgKiBAdGhyb3dzIHtFcnJvcn0gaWYgYm90aCBgcnVuc09uYCBhbmQgYHJ1bnNPbkdyb3VwYCBhcmUgc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSBydW5zT25Hcm91cD86IEdyb3VwUnVubmVyT3B0aW9ucztcbn1cblxuZXhwb3J0IGNsYXNzIEJ1aWxkV29ya2Zsb3cgZXh0ZW5kcyBDb21wb25lbnQge1xuICAvKipcbiAgICogTmFtZSBvZiBnZW5lcmF0ZWQgZ2l0aHViIHdvcmtmbG93XG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgdW5kZXJseWluZyBHaXRIdWIgQWN0aW9ucyB3b3JrZmxvd1xuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHdvcmtmbG93OiBHaXRodWJXb3JrZmxvdztcblxuICBwcml2YXRlIHJlYWRvbmx5IHBvc3RCdWlsZFN0ZXBzOiBKb2JTdGVwW107XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJlQnVpbGRTdGVwczogSm9iU3RlcFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IGdpdElkZW50aXR5OiBHaXRJZGVudGl0eTtcbiAgcHJpdmF0ZSByZWFkb25seSBidWlsZFRhc2s6IFRhc2s7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ2l0aHViOiBHaXRIdWI7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXJ0aWZhY3RzRGlyZWN0b3J5OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfcG9zdEJ1aWxkSm9iczogc3RyaW5nW10gPSBbXTtcblxuICBjb25zdHJ1Y3Rvcihwcm9qZWN0OiBQcm9qZWN0LCBvcHRpb25zOiBCdWlsZFdvcmtmbG93T3B0aW9ucykge1xuICAgIHN1cGVyKHByb2plY3QpO1xuXG4gICAgY29uc3QgZ2l0aHViID0gR2l0SHViLm9mKHRoaXMucHJvamVjdC5yb290KTtcbiAgICBpZiAoIWdpdGh1Yikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIkJ1aWxkV29ya2Zsb3cgaXMgY3VycmVudGx5IG9ubHkgc3VwcG9ydGVkIGZvciBHaXRIdWIgcHJvamVjdHNcIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5naXRodWIgPSBnaXRodWI7XG4gICAgdGhpcy5wcmVCdWlsZFN0ZXBzID0gb3B0aW9ucy5wcmVCdWlsZFN0ZXBzID8/IFtdO1xuICAgIHRoaXMucG9zdEJ1aWxkU3RlcHMgPSBvcHRpb25zLnBvc3RCdWlsZFN0ZXBzID8/IFtdO1xuICAgIHRoaXMuZ2l0SWRlbnRpdHkgPSBvcHRpb25zLmdpdElkZW50aXR5ID8/IERFRkFVTFRfR0lUSFVCX0FDVElPTlNfVVNFUjtcbiAgICB0aGlzLmJ1aWxkVGFzayA9IG9wdGlvbnMuYnVpbGRUYXNrO1xuICAgIHRoaXMuYXJ0aWZhY3RzRGlyZWN0b3J5ID1cbiAgICAgIG9wdGlvbnMuYXJ0aWZhY3RzRGlyZWN0b3J5ID8/IERFRkFVTFRfQVJUSUZBQ1RTX0RJUkVDVE9SWTtcbiAgICBlbnN1cmVOb3RIaWRkZW5QYXRoKHRoaXMuYXJ0aWZhY3RzRGlyZWN0b3J5LCBcImFydGlmYWN0c0RpcmVjdG9yeVwiKTtcbiAgICB0aGlzLm5hbWUgPSBvcHRpb25zLm5hbWUgPz8gd29ya2Zsb3dOYW1lRm9yUHJvamVjdChcImJ1aWxkXCIsIHRoaXMucHJvamVjdCk7XG4gICAgY29uc3QgbXV0YWJsZUJ1aWxkcyA9IG9wdGlvbnMubXV0YWJsZUJ1aWxkID8/IHRydWU7XG5cbiAgICB0aGlzLndvcmtmbG93ID0gbmV3IEdpdGh1YldvcmtmbG93KGdpdGh1YiwgdGhpcy5uYW1lKTtcbiAgICB0aGlzLndvcmtmbG93Lm9uKFxuICAgICAgb3B0aW9ucy53b3JrZmxvd1RyaWdnZXJzID8/IHtcbiAgICAgICAgcHVsbFJlcXVlc3Q6IHt9LFxuICAgICAgICB3b3JrZmxvd0Rpc3BhdGNoOiB7fSwgLy8gYWxsb3cgbWFudWFsIHRyaWdnZXJpbmdcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIHRoaXMuYWRkQnVpbGRKb2Iob3B0aW9ucyk7XG5cbiAgICBpZiAobXV0YWJsZUJ1aWxkcykge1xuICAgICAgdGhpcy5hZGRTZWxmTXV0YXRpb25Kb2Iob3B0aW9ucyk7XG4gICAgfVxuXG4gICAgaWYgKHByb2plY3QgaW5zdGFuY2VvZiBOb2RlUHJvamVjdCkge1xuICAgICAgcHJvamVjdC5hZGRQYWNrYWdlSWdub3JlKFBFUk1JU1NJT05fQkFDS1VQX0ZJTEUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYWRkQnVpbGRKb2Iob3B0aW9uczogQnVpbGRXb3JrZmxvd09wdGlvbnMpIHtcbiAgICBjb25zdCBwcm9qZWN0UGF0aFJlbGF0aXZlVG9Sb290ID0gcHJvamVjdFBhdGhSZWxhdGl2ZVRvUmVwb1Jvb3QoXG4gICAgICB0aGlzLnByb2plY3QsXG4gICAgKTtcbiAgICBjb25zdCBqb2JDb25maWc6IHdvcmtmbG93cy5Kb2IgPSB7XG4gICAgICAuLi5maWx0ZXJlZFJ1bnNPbk9wdGlvbnMoXG4gICAgICAgIG9wdGlvbnMuYnVpbGRSdW5zT24gPz8gb3B0aW9ucy5ydW5zT24sXG4gICAgICAgIG9wdGlvbnMucnVuc09uR3JvdXAsXG4gICAgICApLFxuICAgICAgY29udGFpbmVyOiBvcHRpb25zLmNvbnRhaW5lckltYWdlXG4gICAgICAgID8geyBpbWFnZTogb3B0aW9ucy5jb250YWluZXJJbWFnZSB9XG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgZW52OiB7XG4gICAgICAgIENJOiBcInRydWVcIixcbiAgICAgICAgLi4ub3B0aW9ucy5lbnYsXG4gICAgICB9LFxuICAgICAgcGVybWlzc2lvbnM6IHtcbiAgICAgICAgY29udGVudHM6IEpvYlBlcm1pc3Npb24uV1JJVEUsXG4gICAgICAgIC4uLm9wdGlvbnMucGVybWlzc2lvbnMsXG4gICAgICB9LFxuICAgICAgZGVmYXVsdHM6IHRoaXMucHJvamVjdC5wYXJlbnQgLy8gaXMgc3VicHJvamVjdCxcbiAgICAgICAgPyB7XG4gICAgICAgICAgICBydW46IHtcbiAgICAgICAgICAgICAgd29ya2luZ0RpcmVjdG9yeTogcHJvamVjdFBhdGhSZWxhdGl2ZVRvUm9vdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfVxuICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgIHN0ZXBzOiAoKCkgPT4gdGhpcy5yZW5kZXJCdWlsZFN0ZXBzKHByb2plY3RQYXRoUmVsYXRpdmVUb1Jvb3QpKSBhcyBhbnksXG4gICAgICBvdXRwdXRzOiB7XG4gICAgICAgIFtTRUxGX01VVEFUSU9OX0hBUFBFTkVEX09VVFBVVF06IHtcbiAgICAgICAgICBzdGVwSWQ6IFNFTEZfTVVUQVRJT05fU1RFUCxcbiAgICAgICAgICBvdXRwdXROYW1lOiBTRUxGX01VVEFUSU9OX0hBUFBFTkVEX09VVFBVVCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIHRoaXMud29ya2Zsb3cuYWRkSm9iKEJVSUxEX0pPQklELCBqb2JDb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBsaXN0IG9mIGpvYiBJRHMgdGhhdCBhcmUgcGFydCBvZiB0aGUgYnVpbGQuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGJ1aWxkSm9iSWRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW0JVSUxEX0pPQklELCAuLi50aGlzLl9wb3N0QnVpbGRKb2JzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIHN0ZXBzIHRoYXQgYXJlIGV4ZWN1dGVkIGFmdGVyIHRoZSBidWlsZC5cbiAgICogQHBhcmFtIHN0ZXBzIFRoZSBqb2Igc3RlcHNcbiAgICovXG4gIHB1YmxpYyBhZGRQb3N0QnVpbGRTdGVwcyguLi5zdGVwczogSm9iU3RlcFtdKTogdm9pZCB7XG4gICAgdGhpcy5wb3N0QnVpbGRTdGVwcy5wdXNoKC4uLnN0ZXBzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGFub3RoZXIgam9iIHRvIHRoZSBidWlsZCB3b3JrZmxvdyB3aGljaCBpcyBleGVjdXRlZCBhZnRlciB0aGUgYnVpbGRcbiAgICogam9iIHN1Y2NlZWRlZC5cbiAgICpcbiAgICogSm9icyBhcmUgZXhlY3V0ZWQgX29ubHlfIGlmIHRoZSBidWlsZCBkaWQgTk9UIHNlbGYgbXV0YXRlLiBJZiB0aGUgYnVpbGRcbiAgICogc2VsZi1tdXRhdGUsIHRoZSBicmFuY2ggd2lsbCBlaXRoZXIgYmUgdXBkYXRlZCBvciB0aGUgYnVpbGQgd2lsbCBmYWlsIChpblxuICAgKiBmb3JrcyksIHNvIHRoZXJlIGlzIG5vIHBvaW50IGluIGV4ZWN1dGluZyB0aGUgcG9zdC1idWlsZCBqb2IuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBUaGUgaWQgb2YgdGhlIG5ldyBqb2JcbiAgICogQHBhcmFtIGpvYiBUaGUgam9iIHNwZWNpZmljYXRpb25cbiAgICovXG4gIHB1YmxpYyBhZGRQb3N0QnVpbGRKb2IoaWQ6IHN0cmluZywgam9iOiBKb2IpIHtcbiAgICBjb25zdCBzdGVwcyA9IFtdO1xuXG4gICAgc3RlcHMucHVzaChcbiAgICAgIFdvcmtmbG93U3RlcHMuZG93bmxvYWRBcnRpZmFjdCh7XG4gICAgICAgIG5hbWU6IFwiRG93bmxvYWQgYnVpbGQgYXJ0aWZhY3RzXCIsXG4gICAgICAgIHdpdGg6IHtcbiAgICAgICAgICBhcnRpZmFjdElkczogW1xuICAgICAgICAgICAgYFxcJHt7IG5lZWRzLiR7QlVJTERfSk9CSUR9Lm91dHB1dHMuJHtBUlRJRkFDVF9JRF9PVVRQVVR9IH19YCxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHBhdGg6IHRoaXMuYXJ0aWZhY3RzRGlyZWN0b3J5LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgICB7XG4gICAgICAgIG5hbWU6IFwiUmVzdG9yZSBidWlsZCBhcnRpZmFjdCBwZXJtaXNzaW9uc1wiLFxuICAgICAgICBjb250aW51ZU9uRXJyb3I6IHRydWUsXG4gICAgICAgIHJ1bjogW1xuICAgICAgICAgIGBjZCAke3RoaXMuYXJ0aWZhY3RzRGlyZWN0b3J5fSAmJiBzZXRmYWNsIC0tcmVzdG9yZT0ke1BFUk1JU1NJT05fQkFDS1VQX0ZJTEV9YCxcbiAgICAgICAgXS5qb2luKFwiXFxuXCIpLFxuICAgICAgfSxcbiAgICApO1xuXG4gICAgc3RlcHMucHVzaCguLi4oam9iLnN0ZXBzID8/IFtdKSk7XG5cbiAgICB0aGlzLndvcmtmbG93LmFkZEpvYihpZCwge1xuICAgICAgbmVlZHM6IFtCVUlMRF9KT0JJRF0sXG4gICAgICAvLyBvbmx5IHJ1biBpZiBidWlsZCBkaWQgbm90IHNlbGYtbXV0YXRlXG4gICAgICBpZjogYFxcJHt7ICEke1NFTEZfTVVUQVRJT05fQ09ORElUSU9OfSB9fWAsXG4gICAgICAuLi5qb2IsXG4gICAgICBzdGVwczogc3RlcHMsXG4gICAgfSk7XG5cbiAgICAvLyBhZGQgdG8gdGhlIGxpc3Qgb2YgYnVpbGQgam9iIElEc1xuICAgIHRoaXMuX3Bvc3RCdWlsZEpvYnMucHVzaChpZCk7XG5cbiAgICAvLyBhZGQgYXJ0aWZhY3RfaWQgb3V0cHV0IHRvIHRoZSBidWlsZCBqb2IgKG9ubHkgbmVlZGVkIHdoZW4gcG9zdC1idWlsZCBqb2JzIGV4aXN0KVxuICAgIGNvbnN0IGJ1aWxkSm9iID0gdGhpcy53b3JrZmxvdy5nZXRKb2IoQlVJTERfSk9CSUQpIGFzIEpvYjtcbiAgICBpZiAoYnVpbGRKb2Iub3V0cHV0cyAmJiAhYnVpbGRKb2Iub3V0cHV0c1tBUlRJRkFDVF9JRF9PVVRQVVRdKSB7XG4gICAgICAoYnVpbGRKb2Iub3V0cHV0cyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbQVJUSUZBQ1RfSURfT1VUUFVUXSA9IHtcbiAgICAgICAgc3RlcElkOiBVUExPQURfQVJUSUZBQ1RfU1RFUCxcbiAgICAgICAgb3V0cHV0TmFtZTogXCJhcnRpZmFjdC1pZFwiLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVuIGEgdGFzayBhcyBhIGpvYiB3aXRoaW4gdGhlIGJ1aWxkIHdvcmtmbG93IHdoaWNoIGlzIGV4ZWN1dGVkIGFmdGVyIHRoZVxuICAgKiBidWlsZCBqb2Igc3VjY2VlZGVkLlxuICAgKlxuICAgKiBUaGUgam9iIHdpbGwgaGF2ZSBhY2Nlc3MgdG8gYnVpbGQgYXJ0aWZhY3RzIGFuZCB3aWxsIGluc3RhbGwgcHJvamVjdFxuICAgKiBkZXBlbmRlbmNpZXMgaW4gb3JkZXIgdG8gYmUgYWJsZSB0byBydW4gYW55IGNvbW1hbmRzIHVzZWQgaW4gdGhlIHRhc2tzLlxuICAgKlxuICAgKiBKb2JzIGFyZSBleGVjdXRlZCBfb25seV8gaWYgdGhlIGJ1aWxkIGRpZCBOT1Qgc2VsZiBtdXRhdGUuIElmIHRoZSBidWlsZFxuICAgKiBzZWxmLW11dGF0ZSwgdGhlIGJyYW5jaCB3aWxsIGVpdGhlciBiZSB1cGRhdGVkIG9yIHRoZSBidWlsZCB3aWxsIGZhaWwgKGluXG4gICAqIGZvcmtzKSwgc28gdGhlcmUgaXMgbm8gcG9pbnQgaW4gZXhlY3V0aW5nIHRoZSBwb3N0LWJ1aWxkIGpvYi5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgU3BlY2lmeSB0b29scyBhbmQgb3RoZXIgb3B0aW9uc1xuICAgKi9cbiAgcHVibGljIGFkZFBvc3RCdWlsZEpvYlRhc2soXG4gICAgdGFzazogVGFzayxcbiAgICBvcHRpb25zOiBBZGRQb3N0QnVpbGRKb2JUYXNrT3B0aW9ucyA9IHt9LFxuICApIHtcbiAgICB0aGlzLmFkZFBvc3RCdWlsZEpvYkNvbW1hbmRzKFxuICAgICAgYHBvc3QtYnVpbGQtJHt0YXNrLm5hbWV9YCxcbiAgICAgIFtgJHt0aGlzLnByb2plY3QucHJvamVuQ29tbWFuZH0gJHt0YXNrLm5hbWV9YF0sXG4gICAgICB7XG4gICAgICAgIGNoZWNrb3V0UmVwbzogdHJ1ZSxcbiAgICAgICAgaW5zdGFsbERlcHM6IHRydWUsXG4gICAgICAgIHRvb2xzOiBvcHRpb25zLnRvb2xzLFxuICAgICAgICAuLi5maWx0ZXJlZFJ1bnNPbk9wdGlvbnMob3B0aW9ucy5ydW5zT24sIG9wdGlvbnMucnVuc09uR3JvdXApLFxuICAgICAgfSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1biBhIHNlcXVlbmNlIG9mIGNvbW1hbmRzIGFzIGEgam9iIHdpdGhpbiB0aGUgYnVpbGQgd29ya2Zsb3cgd2hpY2ggaXNcbiAgICogZXhlY3V0ZWQgYWZ0ZXIgdGhlIGJ1aWxkIGpvYiBzdWNjZWVkZWQuXG4gICAqXG4gICAqIEpvYnMgYXJlIGV4ZWN1dGVkIF9vbmx5XyBpZiB0aGUgYnVpbGQgZGlkIE5PVCBzZWxmIG11dGF0ZS4gSWYgdGhlIGJ1aWxkXG4gICAqIHNlbGYtbXV0YXRlLCB0aGUgYnJhbmNoIHdpbGwgZWl0aGVyIGJlIHVwZGF0ZWQgb3IgdGhlIGJ1aWxkIHdpbGwgZmFpbCAoaW5cbiAgICogZm9ya3MpLCBzbyB0aGVyZSBpcyBubyBwb2ludCBpbiBleGVjdXRpbmcgdGhlIHBvc3QtYnVpbGQgam9iLlxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyBTcGVjaWZ5IHRvb2xzIGFuZCBvdGhlciBvcHRpb25zXG4gICAqL1xuICBwdWJsaWMgYWRkUG9zdEJ1aWxkSm9iQ29tbWFuZHMoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBjb21tYW5kczogc3RyaW5nW10sXG4gICAgb3B0aW9ucz86IEFkZFBvc3RCdWlsZEpvYkNvbW1hbmRzT3B0aW9ucyxcbiAgKSB7XG4gICAgY29uc3Qgc3RlcHMgPSBbXTtcblxuICAgIGlmIChvcHRpb25zPy5jaGVja291dFJlcG8pIHtcbiAgICAgIHN0ZXBzLnB1c2goXG4gICAgICAgIFdvcmtmbG93U3RlcHMuY2hlY2tvdXQoe1xuICAgICAgICAgIHdpdGg6IHtcbiAgICAgICAgICAgIHJlZjogUFVMTF9SRVFVRVNUX1JFRixcbiAgICAgICAgICAgIHJlcG9zaXRvcnk6IFBVTExfUkVRVUVTVF9SRVBPU0lUT1JZLFxuICAgICAgICAgICAgLi4uKHRoaXMuZ2l0aHViLmRvd25sb2FkTGZzID8geyBsZnM6IHRydWUgfSA6IHt9KSxcbiAgICAgICAgICAgIC4uLih0aGlzLmdpdGh1Yi5jaGVja291dFN1Ym1vZHVsZXMgIT09IENoZWNrb3V0U3VibW9kdWxlcy5ESVNBQkxFRFxuICAgICAgICAgICAgICA/IHsgc3VibW9kdWxlczogdGhpcy5naXRodWIuY2hlY2tvdXRTdWJtb2R1bGVzIH1cbiAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIG9wdGlvbnM/LmNoZWNrb3V0UmVwbyAmJlxuICAgICAgb3B0aW9ucz8uaW5zdGFsbERlcHMgJiZcbiAgICAgIHRoaXMucHJvamVjdCBpbnN0YW5jZW9mIE5vZGVQcm9qZWN0XG4gICAgKSB7XG4gICAgICBzdGVwcy5wdXNoKHtcbiAgICAgICAgbmFtZTogXCJJbnN0YWxsIGRlcGVuZGVuY2llc1wiLFxuICAgICAgICBydW46IGAke3RoaXMucHJvamVjdC5wYWNrYWdlLmluc3RhbGxDb21tYW5kfWAsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGVwcy5wdXNoKHsgcnVuOiBjb21tYW5kcy5qb2luKFwiXFxuXCIpIH0pO1xuXG4gICAgdGhpcy5hZGRQb3N0QnVpbGRKb2IoaWQsIHtcbiAgICAgIHBlcm1pc3Npb25zOiB7XG4gICAgICAgIGNvbnRlbnRzOiBKb2JQZXJtaXNzaW9uLlJFQUQsXG4gICAgICB9LFxuICAgICAgdG9vbHM6IG9wdGlvbnM/LnRvb2xzLFxuICAgICAgLi4uZmlsdGVyZWRSdW5zT25PcHRpb25zKG9wdGlvbnM/LnJ1bnNPbiwgb3B0aW9ucz8ucnVuc09uR3JvdXApLFxuICAgICAgc3RlcHMsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFkZFNlbGZNdXRhdGlvbkpvYihvcHRpb25zOiBCdWlsZFdvcmtmbG93T3B0aW9ucykge1xuICAgIGNvbnN0IGNyZWRlbnRpYWxzID0gdGhpcy53b3JrZmxvdy5wcm9qZW5DcmVkZW50aWFscztcbiAgICB0aGlzLndvcmtmbG93LmFkZEpvYihcInNlbGYtbXV0YXRpb25cIiwge1xuICAgICAgLi4uZmlsdGVyZWRSdW5zT25PcHRpb25zKG9wdGlvbnMucnVuc09uLCBvcHRpb25zLnJ1bnNPbkdyb3VwKSxcbiAgICAgIHBlcm1pc3Npb25zOiB7XG4gICAgICAgIGNvbnRlbnRzOiBKb2JQZXJtaXNzaW9uLldSSVRFLFxuICAgICAgfSxcbiAgICAgIG5lZWRzOiBbQlVJTERfSk9CSURdLFxuICAgICAgaWY6IGBhbHdheXMoKSAmJiAke1NFTEZfTVVUQVRJT05fQ09ORElUSU9OfSAmJiAke05PVF9GT1JLfWAsXG4gICAgICBlbnZpcm9ubWVudDogY3JlZGVudGlhbHMuZW52aXJvbm1lbnQsXG4gICAgICBzdGVwczogW1xuICAgICAgICAuLi5jcmVkZW50aWFscy5zZXR1cFN0ZXBzLFxuICAgICAgICAuLi5Xb3JrZmxvd0FjdGlvbnMuY2hlY2tvdXRXaXRoUGF0Y2goe1xuICAgICAgICAgIC8vIHdlIG5lZWQgdG8gdXNlIGEgUEFUIHNvIHRoYXQgb3VyIHB1c2ggd2lsbCB0cmlnZ2VyIHRoZSBidWlsZCB3b3JrZmxvd1xuICAgICAgICAgIHRva2VuOiBjcmVkZW50aWFscy50b2tlblJlZixcbiAgICAgICAgICByZWY6IFBVTExfUkVRVUVTVF9SRUYsXG4gICAgICAgICAgcmVwb3NpdG9yeTogUFVMTF9SRVFVRVNUX1JFUE9TSVRPUlksXG4gICAgICAgICAgbGZzOiB0aGlzLmdpdGh1Yi5kb3dubG9hZExmcyxcbiAgICAgICAgfSksXG4gICAgICAgIFdvcmtmbG93U3RlcHMuc2V0dXBHaXRJZGVudGl0eSh7IGdpdElkZW50aXR5OiB0aGlzLmdpdElkZW50aXR5IH0pLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJQdXNoIGNoYW5nZXNcIixcbiAgICAgICAgICBlbnY6IHtcbiAgICAgICAgICAgIFBVTExfUkVRVUVTVF9SRUYsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBydW46IFtcbiAgICAgICAgICAgIFwiZ2l0IGFkZCAuXCIsXG4gICAgICAgICAgICAnZ2l0IGNvbW1pdCAtcyAtbSBcImNob3JlOiBzZWxmIG11dGF0aW9uXCInLFxuICAgICAgICAgICAgYGdpdCBwdXNoIG9yaWdpbiBcIkhFQUQ6JFBVTExfUkVRVUVTVF9SRUZcImAsXG4gICAgICAgICAgXS5qb2luKFwiXFxuXCIpLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgKGxhemlseSkgZHVyaW5nIHN5bnRoIHRvIHJlbmRlciB0aGUgYnVpbGQgam9iIHN0ZXBzLlxuICAgKi9cbiAgcHJpdmF0ZSByZW5kZXJCdWlsZFN0ZXBzKHByb2plY3RQYXRoUmVsYXRpdmVUb1Jvb3Q6IHN0cmluZyk6IEpvYlN0ZXBbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIFdvcmtmbG93U3RlcHMuY2hlY2tvdXQoe1xuICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgcmVmOiBQVUxMX1JFUVVFU1RfUkVGLFxuICAgICAgICAgIHJlcG9zaXRvcnk6IFBVTExfUkVRVUVTVF9SRVBPU0lUT1JZLFxuICAgICAgICAgIC4uLih0aGlzLmdpdGh1Yi5kb3dubG9hZExmcyA/IHsgbGZzOiB0cnVlIH0gOiB7fSksXG4gICAgICAgICAgLi4uKHRoaXMuZ2l0aHViLmNoZWNrb3V0U3VibW9kdWxlc1xuICAgICAgICAgICAgPyB7IHN1Ym1vZHVsZXM6IHRoaXMuZ2l0aHViLmNoZWNrb3V0U3VibW9kdWxlcyB9XG4gICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuXG4gICAgICAuLi50aGlzLnByZUJ1aWxkU3RlcHMsXG5cbiAgICAgIHtcbiAgICAgICAgbmFtZTogdGhpcy5idWlsZFRhc2submFtZSxcbiAgICAgICAgcnVuOiB0aGlzLmdpdGh1Yi5wcm9qZWN0LnJ1blRhc2tDb21tYW5kKHRoaXMuYnVpbGRUYXNrKSxcbiAgICAgIH0sXG5cbiAgICAgIC4uLnRoaXMucG9zdEJ1aWxkU3RlcHMsXG5cbiAgICAgIC8vIGNoZWNrIGZvciBtdXRhdGlvbnMgYW5kIHVwbG9hZCBhIGdpdCBwYXRjaCBmaWxlIGFzIGFuIGFydGlmYWN0XG4gICAgICAuLi5Xb3JrZmxvd0FjdGlvbnMudXBsb2FkR2l0UGF0Y2goe1xuICAgICAgICBzdGVwSWQ6IFNFTEZfTVVUQVRJT05fU1RFUCxcbiAgICAgICAgb3V0cHV0TmFtZTogU0VMRl9NVVRBVElPTl9IQVBQRU5FRF9PVVRQVVQsXG4gICAgICAgIG11dGF0aW9uRXJyb3I6XG4gICAgICAgICAgXCJGaWxlcyB3ZXJlIGNoYW5nZWQgZHVyaW5nIGJ1aWxkIChzZWUgYnVpbGQgbG9nKS4gSWYgdGhpcyB3YXMgdHJpZ2dlcmVkIGZyb20gYSBmb3JrLCB5b3Ugd2lsbCBuZWVkIHRvIHVwZGF0ZSB5b3VyIGJyYW5jaC5cIixcbiAgICAgIH0pLFxuXG4gICAgICAvLyB1cGxvYWQgdGhlIGJ1aWxkIGFydGlmYWN0IG9ubHkgaWYgd2UgaGF2ZSBwb3N0LWJ1aWxkIGpvYnMgKG90aGVyd2lzZSwgdGhlcmUncyBubyBwb2ludClcbiAgICAgIC4uLih0aGlzLl9wb3N0QnVpbGRKb2JzLmxlbmd0aCA9PSAwXG4gICAgICAgID8gW11cbiAgICAgICAgOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG5hbWU6IFwiQmFja3VwIGFydGlmYWN0IHBlcm1pc3Npb25zXCIsXG4gICAgICAgICAgICAgIGNvbnRpbnVlT25FcnJvcjogdHJ1ZSxcbiAgICAgICAgICAgICAgcnVuOiBgY2QgJHt0aGlzLmFydGlmYWN0c0RpcmVjdG9yeX0gJiYgZ2V0ZmFjbCAtUiAuID4gJHtQRVJNSVNTSU9OX0JBQ0tVUF9GSUxFfWAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgV29ya2Zsb3dTdGVwcy51cGxvYWRBcnRpZmFjdCh7XG4gICAgICAgICAgICAgIGlkOiBVUExPQURfQVJUSUZBQ1RfU1RFUCxcbiAgICAgICAgICAgICAgd2l0aDoge1xuICAgICAgICAgICAgICAgIG5hbWU6IEJVSUxEX0FSVElGQUNUX05BTUUsXG4gICAgICAgICAgICAgICAgcGF0aDogdGhpcy5wcm9qZWN0LnBhcmVudFxuICAgICAgICAgICAgICAgICAgPyBwb3NpeFBhdGguam9pbihcbiAgICAgICAgICAgICAgICAgICAgICBwcm9qZWN0UGF0aFJlbGF0aXZlVG9Sb290LFxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJ0aWZhY3RzRGlyZWN0b3J5LFxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICA6IHRoaXMuYXJ0aWZhY3RzRGlyZWN0b3J5LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgXSksXG4gICAgXTtcbiAgfVxufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBCdWlsZFdvcmtmbG93LmFkZFBvc3RCdWlsZEpvYlRhc2tgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWRkUG9zdEJ1aWxkSm9iVGFza09wdGlvbnMge1xuICAvKipcbiAgICogVG9vbHMgdGhhdCBzaG91bGQgYmUgaW5zdGFsbGVkIGJlZm9yZSB0aGUgdGFzayBpcyBydW4uXG4gICAqL1xuICByZWFkb25seSB0b29scz86IFRvb2xzO1xuXG4gIC8qKlxuICAgKiBHaXRodWIgUnVubmVyIHNlbGVjdGlvbiBsYWJlbHNcbiAgICogQGRlZmF1bHQgW1widWJ1bnR1LWxhdGVzdFwiXVxuICAgKiBAZGVzY3JpcHRpb24gRGVmaW5lcyBhIHRhcmdldCBSdW5uZXIgYnkgbGFiZWxzXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBpZiBib3RoIGBydW5zT25gIGFuZCBgcnVuc09uR3JvdXBgIGFyZSBzcGVjaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IHJ1bnNPbj86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBHaXRodWIgUnVubmVyIEdyb3VwIHNlbGVjdGlvbiBvcHRpb25zXG4gICAqIEBkZXNjcmlwdGlvbiBEZWZpbmVzIGEgdGFyZ2V0IFJ1bm5lciBHcm91cCBieSBuYW1lIGFuZC9vciBsYWJlbHNcbiAgICogQHRocm93cyB7RXJyb3J9IGlmIGJvdGggYHJ1bnNPbmAgYW5kIGBydW5zT25Hcm91cGAgYXJlIHNwZWNpZmllZFxuICAgKi9cbiAgcmVhZG9ubHkgcnVuc09uR3JvdXA/OiBHcm91cFJ1bm5lck9wdGlvbnM7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYEJ1aWxkV29ya2Zsb3cuYWRkUG9zdEJ1aWxkSm9iQ29tbWFuZHNgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWRkUG9zdEJ1aWxkSm9iQ29tbWFuZHNPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRvb2xzIHRoYXQgc2hvdWxkIGJlIGluc3RhbGxlZCBiZWZvcmUgdGhlIGNvbW1hbmRzIGFyZSBydW4uXG4gICAqL1xuICByZWFkb25seSB0b29scz86IFRvb2xzO1xuXG4gIC8qKlxuICAgKiBDaGVjayBvdXQgdGhlIHJlcG9zaXRvcnkgYXQgdGhlIHB1bGwgcmVxdWVzdCBicmFuY2ggYmVmb3JlIGNvbW1hbmRzIGFyZVxuICAgKiBydW4uXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBjaGVja291dFJlcG8/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbnN0YWxsIHByb2plY3QgZGVwZW5kZW5jaWVzIGJlZm9yZSBydW5uaW5nIGNvbW1hbmRzLiBgY2hlY2tvdXRSZXBvYCBtdXN0XG4gICAqIGFsc28gYmUgc2V0IHRvIHRydWUuXG4gICAqXG4gICAqIEN1cnJlbnRseSBvbmx5IHN1cHBvcnRlZCBmb3IgYE5vZGVQcm9qZWN0YC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbGxEZXBzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogR2l0aHViIFJ1bm5lciBzZWxlY3Rpb24gbGFiZWxzXG4gICAqIEBkZWZhdWx0IFtcInVidW50dS1sYXRlc3RcIl1cbiAgICogQGRlc2NyaXB0aW9uIERlZmluZXMgYSB0YXJnZXQgUnVubmVyIGJ5IGxhYmVsc1xuICAgKiBAdGhyb3dzIHtFcnJvcn0gaWYgYm90aCBgcnVuc09uYCBhbmQgYHJ1bnNPbkdyb3VwYCBhcmUgc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSBydW5zT24/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogR2l0aHViIFJ1bm5lciBHcm91cCBzZWxlY3Rpb24gb3B0aW9uc1xuICAgKiBAZGVzY3JpcHRpb24gRGVmaW5lcyBhIHRhcmdldCBSdW5uZXIgR3JvdXAgYnkgbmFtZSBhbmQvb3IgbGFiZWxzXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBpZiBib3RoIGBydW5zT25gIGFuZCBgcnVuc09uR3JvdXBgIGFyZSBzcGVjaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IHJ1bnNPbkdyb3VwPzogR3JvdXBSdW5uZXJPcHRpb25zO1xufVxuIl19