UNPKG

projen

Version:

CDK for software projects

279 lines • 43.3 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({ name: "Download build artifacts", uses: "actions/download-artifact@v8", with: { name: constants_1.BUILD_ARTIFACT_NAME, 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); } /** * 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({ 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.64" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtd29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYnVpbGQvYnVpbGQtd29ya2Zsb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBNkM7QUFFN0MsNENBQXlDO0FBRXpDLHNDQUttQjtBQUNuQixtREFJNkI7QUFDN0IsaURBR2dDO0FBQ2hDLGlFQUE2RDtBQVE3RCwrREFBMEQ7QUFDMUQsOENBQTRDO0FBRzVDLHNEQUEwRDtBQUMxRCw2Q0FTMEI7QUFDMUIsdUNBQXNEO0FBbUh0RCxNQUFhLGFBQWMsU0FBUSxxQkFBUztJQW9CMUMsWUFBWSxPQUFnQixFQUFFLE9BQTZCO1FBQ3pELEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUhBLG1CQUFjLEdBQWEsRUFBRSxDQUFDO1FBSzdDLE1BQU0sTUFBTSxHQUFHLGVBQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDWixNQUFNLElBQUksS0FBSyxDQUNiLCtEQUErRCxDQUNoRSxDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUM7UUFDakQsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxJQUFJLEVBQUUsQ0FBQztRQUNuRCxJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksdUNBQTJCLENBQUM7UUFDdEUsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDO1FBQ25DLElBQUksQ0FBQyxrQkFBa0I7WUFDckIsT0FBTyxDQUFDLGtCQUFrQixJQUFJLG9DQUEyQixDQUFDO1FBQzVELElBQUEsMEJBQW1CLEVBQUMsSUFBSSxDQUFDLGtCQUFr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QUFNLElBQUksQ0FBQztnQkFDakMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ0osQ0FBQyxDQUFDO29CQUNFO3dCQUNFLElBQUksRUFBRSw2QkFBNkI7d0JBQ25DLGVBQWUsRUFBRSxJQUFJO3dCQUNyQixHQUFHLEVBQUUsTUFBTSxJQUFJLENBQUMsa0JBQWtCLHNCQUFzQixrQ0FBc0IsRUFBRTtxQkFDakY7b0JBQ0Qsc0JBQWEsQ0FBQyxjQUFjLENBQUM7d0JBQzNCLElBQUksRUFBRTs0QkFDSixJQUFJLEVBQUUsK0JBQW1COzRCQUN6QixJQUFJLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNO2dDQUN2QixDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FDWix5QkFBeUIsRUFDekIsSUFBSSxDQUFDLGtCQUFrQixDQUN4QjtnQ0FDSCxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQjt5QkFDNUI7cUJBQ0YsQ0FBQztpQkFDSCxDQUFDO1NBQ1AsQ0FBQztJQUNKLENBQUM7O0FBOVVILHNDQStVQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBvc2l4UGF0aCBmcm9tIFwibm9kZTpwYXRoL3Bvc2l4XCI7XG5pbXBvcnQgdHlwZSB7IFRhc2sgfSBmcm9tIFwiLi5cIjtcbmltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gXCIuLi9jb21wb25lbnRcIjtcbmltcG9ydCB0eXBlIHsgR2l0SWRlbnRpdHksIHdvcmtmbG93cyB9IGZyb20gXCIuLi9naXRodWJcIjtcbmltcG9ydCB7XG4gIENoZWNrb3V0U3VibW9kdWxlcyxcbiAgR2l0SHViLFxuICBHaXRodWJXb3JrZmxvdyxcbiAgV29ya2Zsb3dTdGVwcyxcbn0gZnJvbSBcIi4uL2dpdGh1YlwiO1xuaW1wb3J0IHtcbiAgQlVJTERfQVJUSUZBQ1RfTkFNRSxcbiAgREVGQVVMVF9HSVRIVUJfQUNUSU9OU19VU0VSLFxuICBQRVJNSVNTSU9OX0JBQ0tVUF9GSUxFLFxufSBmcm9tIFwiLi4vZ2l0aHViL2NvbnN0YW50c1wiO1xuaW1wb3J0IHtcbiAgZW5zdXJlTm90SGlkZGVuUGF0aCxcbiAgcHJvamVjdFBhdGhSZWxhdGl2ZVRvUmVwb1Jvb3QsXG59IGZyb20gXCIuLi9naXRodWIvcHJpdmF0ZS91dGlsXCI7XG5pbXBvcnQgeyBXb3JrZmxvd0FjdGlvbnMgfSBmcm9tIFwiLi4vZ2l0aHViL3dvcmtmbG93LWFjdGlvbnNcIjtcbmltcG9ydCB0eXBlIHtcbiAgSm9iLFxuICBKb2JQZXJtaXNzaW9ucyxcbiAgSm9iU3RlcCxcbiAgVG9vbHMsXG4gIFRyaWdnZXJzLFxufSBmcm9tIFwiLi4vZ2l0aHViL3dvcmtmbG93cy1tb2RlbFwiO1xuaW1wb3J0IHsgSm9iUGVybWlzc2lvbiB9IGZyb20gXCIuLi9naXRodWIvd29ya2Zsb3dzLW1vZGVsXCI7XG5pbXBvcnQgeyBOb2RlUHJvamVjdCB9IGZyb20gXCIuLi9qYXZhc2NyaXB0XCI7XG5pbXBvcnQgdHlwZSB7IFByb2plY3QgfSBmcm9tIFwiLi4vcHJvamVjdFwiO1xuaW1wb3J0IHR5cGUgeyBHcm91cFJ1bm5lck9wdGlvbnMgfSBmcm9tIFwiLi4vcnVubmVyLW9wdGlvbnNcIjtcbmltcG9ydCB7IGZpbHRlcmVkUnVuc09uT3B0aW9ucyB9IGZyb20gXCIuLi9ydW5uZXItb3B0aW9uc1wiO1xuaW1wb3J0IHtcbiAgQlVJTERfSk9CSUQsXG4gIERFRkFVTFRfQVJUSUZBQ1RTX0RJUkVDVE9SWSxcbiAgTk9UX0ZPUkssXG4gIFBVTExfUkVRVUVTVF9SRUYsXG4gIFBVTExfUkVRVUVTVF9SRVBPU0lUT1JZLFxuICBTRUxGX01VVEFUSU9OX0NPTkRJVElPTixcbiAgU0VMRl9NVVRBVElPTl9IQVBQRU5FRF9PVVRQVVQsXG4gIFNFTEZfTVVUQVRJT05fU1RFUCxcbn0gZnJvbSBcIi4vcHJpdmF0ZS9jb25zdHNcIjtcbmltcG9ydCB7IHdvcmtmbG93TmFtZUZvclByb2plY3QgfSBmcm9tIFwiLi4vdXRpbC9uYW1lXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbGRXb3JrZmxvd0NvbW1vbk9wdGlvbnMge1xuICAvKipcbiAgICogTmFtZSBvZiB0aGUgYnVpbGRmaWxlIChlLmcuIFwiYnVpbGRcIiBiZWNvbWVzIFwiYnVpbGQueW1sXCIpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcImJ1aWxkXCJcbiAgICovXG4gIHJlYWRvbmx5IG5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFN0ZXBzIHRvIGV4ZWN1dGUgYmVmb3JlIHRoZSBidWlsZC5cbiAgICogQGRlZmF1bHQgW11cbiAgICovXG4gIHJlYWRvbmx5IHByZUJ1aWxkU3RlcHM/OiBKb2JTdGVwW107XG5cbiAgLyoqXG4gICAqIEJ1aWxkIHdvcmtmbG93IHRyaWdnZXJzXG4gICAqIEBkZWZhdWx0IFwieyBwdWxsUmVxdWVzdDoge30sIHdvcmtmbG93RGlzcGF0Y2g6IHt9IH1cIlxuICAgKi9cbiAgcmVhZG9ubHkgd29ya2Zsb3dUcmlnZ2Vycz86IFRyaWdnZXJzO1xuXG4gIC8qKlxuICAgKiBQZXJtaXNzaW9ucyBncmFudGVkIHRvIHRoZSBidWlsZCBqb2JcbiAgICogVG8gbGltaXQgam9iIHBlcm1pc3Npb25zIGZvciBgY29udGVudHNgLCB0aGUgZGVzaXJlZCBwZXJtaXNzaW9ucyBoYXZlIHRvIGJlIGV4cGxpY2l0bHkgc2V0LCBlLmcuOiBgeyBjb250ZW50czogSm9iUGVybWlzc2lvbi5OT05FIH1gXG4gICAqIEBkZWZhdWx0IGB7IGNvbnRlbnRzOiBKb2JQZXJtaXNzaW9uLldSSVRFIH1gXG4gICAqL1xuICByZWFkb25seSBwZXJtaXNzaW9ucz86IEpvYlBlcm1pc3Npb25zO1xuXG4gIC8qKlxuICAgKiBCdWlsZCBlbnZpcm9ubWVudCB2YXJpYWJsZXMuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqL1xuICByZWFkb25seSBlbnY/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkV29ya2Zsb3dPcHRpb25zIGV4dGVuZHMgQnVpbGRXb3JrZmxvd0NvbW1vbk9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIHRhc2sgdG8gZXhlY3V0ZSBpbiBvcmRlciB0byBidWlsZCB0aGUgcHJvamVjdC5cbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkVGFzazogVGFzaztcblxuICAvKipcbiAgICogQSBuYW1lIG9mIGEgZGlyZWN0b3J5IHRoYXQgaW5jbHVkZXMgYnVpbGQgYXJ0aWZhY3RzLlxuICAgKiBAZGVmYXVsdCBcImRpc3RcIlxuICAgKi9cbiAgcmVhZG9ubHkgYXJ0aWZhY3RzRGlyZWN0b3J5Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgY29udGFpbmVyIGltYWdlIHRvIHVzZSBmb3IgYnVpbGRzLlxuICAgKiBAZGVmYXVsdCAtIHRoZSBkZWZhdWx0IHdvcmtmbG93IGNvbnRhaW5lclxuICAgKi9cbiAgcmVhZG9ubHkgY29udGFpbmVySW1hZ2U/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEF1dG9tYXRpY2FsbHkgdXBkYXRlIGZpbGVzIG1vZGlmaWVkIGR1cmluZyBidWlsZHMgdG8gcHVsbC1yZXF1ZXN0IGJyYW5jaGVzLlxuICAgKiBUaGlzIG1lYW5zIHRoYXQgYW55IGZpbGVzIHN5bnRoZXNpemVkIGJ5IHByb2plbiBvciBlLmcuIHRlc3Qgc25hcHNob3RzIHdpbGxcbiAgICogYWx3YXlzIGJlIHVwLXRvLWRhdGUgYmVmb3JlIGEgUFIgaXMgbWVyZ2VkLlxuICAgKlxuICAgKiBJbXBsaWVzIHRoYXQgUFIgYnVpbGRzIGRvIG5vdCBoYXZlIGFudGktdGFtcGVyIGNoZWNrcy5cbiAgICpcbiAgICogVGhpcyBpcyBlbmFibGVkIGJ5IGRlZmF1bHQgb25seSBpZiBgZ2l0aHViVG9rZW5TZWNyZXRgIGlzIHNldC4gT3RoZXJ3aXNlIGl0XG4gICAqIGlzIGRpc2FibGVkLCB3aGljaCBpbXBsaWVzIHRoYXQgZmlsZSBjaGFuZ2VzIHRoYXQgaGFwcGVuIGR1cmluZyBidWlsZCB3aWxsXG4gICAqIG5vdCBiZSBwdXNoZWQgYmFjayB0byB0aGUgYnJhbmNoLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBtdXRhYmxlQnVpbGQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBQZXJmb3JtIGEgbXV0YWJsZSAobm9uLWZyb3plbikgaW5zdGFsbCBkdXJpbmcgYnVpbGRzLiBUaGlzIHdpbGwgdXBkYXRlIHRoZVxuICAgKiBwYWNrYWdlIGxvY2tmaWxlIGR1cmluZyBpbnN0YWxscywgd2hpY2ggaXMgdXNlZnVsIHdoZW4gYnVpbGQgc3RlcHMgbW9kaWZ5XG4gICAqIGRlcGVuZGVuY2llcy4gU2V0IHRvIGBmYWxzZWAgdG8gdXNlIGZyb3plbiBsb2NrZmlsZSBpbnN0YWxscyBldmVuIHdoZW5cbiAgICogYG11dGFibGVCdWlsZGAgaXMgZW5hYmxlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB2YWx1ZSBvZiBgbXV0YWJsZUJ1aWxkYFxuICAgKi9cbiAgcmVhZG9ubHkgbXV0YWJsZUluc3RhbGw/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBTdGVwcyB0byBleGVjdXRlIGFmdGVyIGJ1aWxkLlxuICAgKiBAZGVmYXVsdCBbXVxuICAgKi9cbiAgcmVhZG9ubHkgcG9zdEJ1aWxkU3RlcHM/OiBKb2JTdGVwW107XG5cbiAgLyoqXG4gICAqIEdpdCBpZGVudGl0eSB0byB1c2UgZm9yIHRoZSB3b3JrZmxvdy5cbiAgICogQGRlZmF1bHQgLSBkZWZhdWx0IEdpdEh1YiBBY3Rpb25zIHVzZXJcbiAgICovXG4gIHJlYWRvbmx5IGdpdElkZW50aXR5PzogR2l0SWRlbnRpdHk7XG5cbiAgLyoqXG4gICAqIEdpdGh1YiBSdW5uZXIgc2VsZWN0aW9uIGxhYmVsc1xuICAgKiBAZGVmYXVsdCBbXCJ1YnVudHUtbGF0ZXN0XCJdXG4gICAqIEBkZXNjcmlwdGlvbiBEZWZpbmVzIGEgdGFyZ2V0IFJ1bm5lciBieSBsYWJlbHNcbiAgICogQHRocm93cyB7RXJyb3J9IGlmIGJvdGggYHJ1bnNPbmAgYW5kIGBydW5zT25Hcm91cGAgYXJlIHNwZWNpZmllZFxuICAgKi9cbiAgcmVhZG9ubHkgcnVuc09uPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEdpdGh1YiBSdW5uZXIgc2VsZWN0aW9uIGxhYmVsc1xuICAgKiBAZGVmYXVsdCAtIHJ1bnNPblxuICAgKiBAZGVzY3JpcHRpb24gRGVmaW5lcyBhIHRhcmdldCBSdW5uZXIgYnkgbGFiZWxzIGZvciBqdXN0IHRoZSBidWlsZCBqb2JcbiAgICogQHRocm93cyB7RXJyb3J9IGlmIGJvdGggYHJ1bnNPbmAgYW5kIGBydW5zT25Hcm91cGAgYXJlIHNwZWNpZmllZFxuICAgKi9cbiAgcmVhZG9ubHkgYnVpbGRSdW5zT24/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogR2l0aHViIFJ1bm5lciBHcm91cCBzZWxlY3Rpb24gb3B0aW9uc1xuICAgKiBAZGVzY3JpcHRpb24gRGVmaW5lcyBhIHRhcmdldCBSdW5uZXIgR3JvdXAgYnkgbmFtZSBhbmQvb3IgbGFiZWxzXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBpZiBib3RoIGBydW5zT25gIGFuZCBgcnVuc09uR3JvdXBgIGFyZSBzcGVjaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IHJ1bnNPbkdyb3VwPzogR3JvdXBSdW5uZXJPcHRpb25zO1xufVxuXG5leHBvcnQgY2xhc3MgQnVpbGRXb3JrZmxvdyBleHRlbmRzIENvbXBvbmVudCB7XG4gIC8qKlxuICAgKiBOYW1lIG9mIGdlbmVyYXRlZCBnaXRodWIgd29ya2Zsb3dcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB1bmRlcmx5aW5nIEdpdEh1YiBBY3Rpb25zIHdvcmtmbG93XG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgd29ya2Zsb3c6IEdpdGh1YldvcmtmbG93O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgcG9zdEJ1aWxkU3RlcHM6IEpvYlN0ZXBbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBwcmVCdWlsZFN0ZXBzOiBKb2JTdGVwW107XG4gIHByaXZhdGUgcmVhZG9ubHkgZ2l0SWRlbnRpdHk6IEdpdElkZW50aXR5O1xuICBwcml2YXRlIHJlYWRvbmx5IGJ1aWxkVGFzazogVGFzaztcbiAgcHJpdmF0ZSByZWFkb25seSBnaXRodWI6IEdpdEh1YjtcbiAgcHJpdmF0ZSByZWFkb25seSBhcnRpZmFjdHNEaXJlY3Rvcnk6IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IF9wb3N0QnVpbGRKb2JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKHByb2plY3Q6IFByb2plY3QsIG9wdGlvbnM6IEJ1aWxkV29ya2Zsb3dPcHRpb25zKSB7XG4gICAgc3VwZXIocHJvamVjdCk7XG5cbiAgICBjb25zdCBnaXRodWIgPSBHaXRIdWIub2YodGhpcy5wcm9qZWN0LnJvb3QpO1xuICAgIGlmICghZ2l0aHViKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiQnVpbGRXb3JrZmxvdyBpcyBjdXJyZW50bHkgb25seSBzdXBwb3J0ZWQgZm9yIEdpdEh1YiBwcm9qZWN0c1wiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmdpdGh1YiA9IGdpdGh1YjtcbiAgICB0aGlzLnByZUJ1aWxkU3RlcHMgPSBvcHRpb25zLnByZUJ1aWxkU3RlcHMgPz8gW107XG4gICAgdGhpcy5wb3N0QnVpbGRTdGVwcyA9IG9wdGlvbnMucG9zdEJ1aWxkU3RlcHMgPz8gW107XG4gICAgdGhpcy5naXRJZGVudGl0eSA9IG9wdGlvbnMuZ2l0SWRlbnRpdHkgPz8gREVGQVVMVF9HSVRIVUJfQUNUSU9OU19VU0VSO1xuICAgIHRoaXMuYnVpbGRUYXNrID0gb3B0aW9ucy5idWlsZFRhc2s7XG4gICAgdGhpcy5hcnRpZmFjdHNEaXJlY3RvcnkgPVxuICAgICAgb3B0aW9ucy5hcnRpZmFjdHNEaXJlY3RvcnkgPz8gREVGQVVMVF9BUlRJRkFDVFNfRElSRUNUT1JZO1xuICAgIGVuc3VyZU5vdEhpZGRlblBhdGgodGhpcy5hcnRpZmFjdHNEaXJlY3RvcnksIFwiYXJ0aWZhY3RzRGlyZWN0b3J5XCIpO1xuICAgIHRoaXMubmFtZSA9IG9wdGlvbnMubmFtZSA/PyB3b3JrZmxvd05hbWVGb3JQcm9qZWN0KFwiYnVpbGRcIiwgdGhpcy5wcm9qZWN0KTtcbiAgICBjb25zdCBtdXRhYmxlQnVpbGRzID0gb3B0aW9ucy5tdXRhYmxlQnVpbGQgPz8gdHJ1ZTtcblxuICAgIHRoaXMud29ya2Zsb3cgPSBuZXcgR2l0aHViV29ya2Zsb3coZ2l0aHViLCB0aGlzLm5hbWUpO1xuICAgIHRoaXMud29ya2Zsb3cub24oXG4gICAgICBvcHRpb25zLndvcmtmbG93VHJpZ2dlcnMgPz8ge1xuICAgICAgICBwdWxsUmVxdWVzdDoge30sXG4gICAgICAgIHdvcmtmbG93RGlzcGF0Y2g6IHt9LCAvLyBhbGxvdyBtYW51YWwgdHJpZ2dlcmluZ1xuICAgICAgfSxcbiAgICApO1xuXG4gICAgdGhpcy5hZGRCdWlsZEpvYihvcHRpb25zKTtcblxuICAgIGlmIChtdXRhYmxlQnVpbGRzKSB7XG4gICAgICB0aGlzLmFkZFNlbGZNdXRhdGlvbkpvYihvcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAocHJvamVjdCBpbnN0YW5jZW9mIE5vZGVQcm9qZWN0KSB7XG4gICAgICBwcm9qZWN0LmFkZFBhY2thZ2VJZ25vcmUoUEVSTUlTU0lPTl9CQUNLVVBfRklMRSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRCdWlsZEpvYihvcHRpb25zOiBCdWlsZFdvcmtmbG93T3B0aW9ucykge1xuICAgIGNvbnN0IHByb2plY3RQYXRoUmVsYXRpdmVUb1Jvb3QgPSBwcm9qZWN0UGF0aFJlbGF0aXZlVG9SZXBvUm9vdChcbiAgICAgIHRoaXMucHJvamVjdCxcbiAgICApO1xuICAgIGNvbnN0IGpvYkNvbmZpZzogd29ya2Zsb3dzLkpvYiA9IHtcbiAgICAgIC4uLmZpbHRlcmVkUnVuc09uT3B0aW9ucyhcbiAgICAgICAgb3B0aW9ucy5idWlsZFJ1bnNPbiA/PyBvcHRpb25zLnJ1bnNPbixcbiAgICAgICAgb3B0aW9ucy5ydW5zT25Hcm91cCxcbiAgICAgICksXG4gICAgICBjb250YWluZXI6IG9wdGlvbnMuY29udGFpbmVySW1hZ2VcbiAgICAgICAgPyB7IGltYWdlOiBvcHRpb25zLmNvbnRhaW5lckltYWdlIH1cbiAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICBlbnY6IHtcbiAgICAgICAgQ0k6IFwidHJ1ZVwiLFxuICAgICAgICAuLi5vcHRpb25zLmVudixcbiAgICAgIH0sXG4gICAgICBwZXJtaXNzaW9uczoge1xuICAgICAgICBjb250ZW50czogSm9iUGVybWlzc2lvbi5XUklURSxcbiAgICAgICAgLi4ub3B0aW9ucy5wZXJtaXNzaW9ucyxcbiAgICAgIH0sXG4gICAgICBkZWZhdWx0czogdGhpcy5wcm9qZWN0LnBhcmVudCAvLyBpcyBzdWJwcm9qZWN0LFxuICAgICAgICA/IHtcbiAgICAgICAgICAgIHJ1bjoge1xuICAgICAgICAgICAgICB3b3JraW5nRGlyZWN0b3J5OiBwcm9qZWN0UGF0aFJlbGF0aXZlVG9Sb290LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9XG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgc3RlcHM6ICgoKSA9PiB0aGlzLnJlbmRlckJ1aWxkU3RlcHMocHJvamVjdFBhdGhSZWxhdGl2ZVRvUm9vdCkpIGFzIGFueSxcbiAgICAgIG91dHB1dHM6IHtcbiAgICAgICAgW1NFTEZfTVVUQVRJT05fSEFQUEVORURfT1VUUFVUXToge1xuICAgICAgICAgIHN0ZXBJZDogU0VMRl9NVVRBVElPTl9TVEVQLFxuICAgICAgICAgIG91dHB1dE5hbWU6IFNFTEZfTVVUQVRJT05fSEFQUEVORURfT1VUUFVULFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgdGhpcy53b3JrZmxvdy5hZGRKb2IoQlVJTERfSk9CSUQsIGpvYkNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGxpc3Qgb2Ygam9iIElEcyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBidWlsZC5cbiAgICovXG4gIHB1YmxpYyBnZXQgYnVpbGRKb2JJZHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbQlVJTERfSk9CSUQsIC4uLnRoaXMuX3Bvc3RCdWlsZEpvYnNdO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgc3RlcHMgdGhhdCBhcmUgZXhlY3V0ZWQgYWZ0ZXIgdGhlIGJ1aWxkLlxuICAgKiBAcGFyYW0gc3RlcHMgVGhlIGpvYiBzdGVwc1xuICAgKi9cbiAgcHVibGljIGFkZFBvc3RCdWlsZFN0ZXBzKC4uLnN0ZXBzOiBKb2JTdGVwW10pOiB2b2lkIHtcbiAgICB0aGlzLnBvc3RCdWlsZFN0ZXBzLnB1c2goLi4uc3RlcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYW5vdGhlciBqb2IgdG8gdGhlIGJ1aWxkIHdvcmtmbG93IHdoaWNoIGlzIGV4ZWN1dGVkIGFmdGVyIHRoZSBidWlsZFxuICAgKiBqb2Igc3VjY2VlZGVkLlxuICAgKlxuICAgKiBKb2JzIGFyZSBleGVjdXRlZCBfb25seV8gaWYgdGhlIGJ1aWxkIGRpZCBOT1Qgc2VsZiBtdXRhdGUuIElmIHRoZSBidWlsZFxuICAgKiBzZWxmLW11dGF0ZSwgdGhlIGJyYW5jaCB3aWxsIGVpdGhlciBiZSB1cGRhdGVkIG9yIHRoZSBidWlsZCB3aWxsIGZhaWwgKGluXG4gICAqIGZvcmtzKSwgc28gdGhlcmUgaXMgbm8gcG9pbnQgaW4gZXhlY3V0aW5nIHRoZSBwb3N0LWJ1aWxkIGpvYi5cbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBpZCBvZiB0aGUgbmV3IGpvYlxuICAgKiBAcGFyYW0gam9iIFRoZSBqb2Igc3BlY2lmaWNhdGlvblxuICAgKi9cbiAgcHVibGljIGFkZFBvc3RCdWlsZEpvYihpZDogc3RyaW5nLCBqb2I6IEpvYikge1xuICAgIGNvbnN0IHN0ZXBzID0gW107XG5cbiAgICBzdGVwcy5wdXNoKFxuICAgICAge1xuICAgICAgICBuYW1lOiBcIkRvd25sb2FkIGJ1aWxkIGFydGlmYWN0c1wiLFxuICAgICAgICB1c2VzOiBcImFjdGlvbnMvZG93bmxvYWQtYXJ0aWZhY3RAdjhcIixcbiAgICAgICAgd2l0aDoge1xuICAgICAgICAgIG5hbWU6IEJVSUxEX0FSVElGQUNUX05BTUUsXG4gICAgICAgICAgcGF0aDogdGhpcy5hcnRpZmFjdHNEaXJlY3RvcnksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBcIlJlc3RvcmUgYnVpbGQgYXJ0aWZhY3QgcGVybWlzc2lvbnNcIixcbiAgICAgICAgY29udGludWVPbkVycm9yOiB0cnVlLFxuICAgICAgICBydW46IFtcbiAgICAgICAgICBgY2QgJHt0aGlzLmFydGlmYWN0c0RpcmVjdG9yeX0gJiYgc2V0ZmFjbCAtLXJlc3RvcmU9JHtQRVJNSVNTSU9OX0JBQ0tVUF9GSUxFfWAsXG4gICAgICAgIF0uam9pbihcIlxcblwiKSxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIHN0ZXBzLnB1c2goLi4uKGpvYi5zdGVwcyA/PyBbXSkpO1xuXG4gICAgdGhpcy53b3JrZmxvdy5hZGRKb2IoaWQsIHtcbiAgICAgIG5lZWRzOiBbQlVJTERfSk9CSURdLFxuICAgICAgLy8gb25seSBydW4gaWYgYnVpbGQgZGlkIG5vdCBzZWxmLW11dGF0ZVxuICAgICAgaWY6IGBcXCR7eyAhJHtTRUxGX01VVEFUSU9OX0NPTkRJVElPTn0gfX1gLFxuICAgICAgLi4uam9iLFxuICAgICAgc3RlcHM6IHN0ZXBzLFxuICAgIH0pO1xuXG4gICAgLy8gYWRkIHRvIHRoZSBsaXN0IG9mIGJ1aWxkIGpvYiBJRHNcbiAgICB0aGlzLl9wb3N0QnVpbGRKb2JzLnB1c2goaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1biBhIHRhc2sgYXMgYSBqb2Igd2l0aGluIHRoZSBidWlsZCB3b3JrZmxvdyB3aGljaCBpcyBleGVjdXRlZCBhZnRlciB0aGVcbiAgICogYnVpbGQgam9iIHN1Y2NlZWRlZC5cbiAgICpcbiAgICogVGhlIGpvYiB3aWxsIGhhdmUgYWNjZXNzIHRvIGJ1aWxkIGFydGlmYWN0cyBhbmQgd2lsbCBpbnN0YWxsIHByb2plY3RcbiAgICogZGVwZW5kZW5jaWVzIGluIG9yZGVyIHRvIGJlIGFibGUgdG8gcnVuIGFueSBjb21tYW5kcyB1c2VkIGluIHRoZSB0YXNrcy5cbiAgICpcbiAgICogSm9icyBhcmUgZXhlY3V0ZWQgX29ubHlfIGlmIHRoZSBidWlsZCBkaWQgTk9UIHNlbGYgbXV0YXRlLiBJZiB0aGUgYnVpbGRcbiAgICogc2VsZi1tdXRhdGUsIHRoZSBicmFuY2ggd2lsbCBlaXRoZXIgYmUgdXBkYXRlZCBvciB0aGUgYnVpbGQgd2lsbCBmYWlsIChpblxuICAgKiBmb3JrcyksIHNvIHRoZXJlIGlzIG5vIHBvaW50IGluIGV4ZWN1dGluZyB0aGUgcG9zdC1idWlsZCBqb2IuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIFNwZWNpZnkgdG9vbHMgYW5kIG90aGVyIG9wdGlvbnNcbiAgICovXG4gIHB1YmxpYyBhZGRQb3N0QnVpbGRKb2JUYXNrKFxuICAgIHRhc2s6IFRhc2ssXG4gICAgb3B0aW9uczogQWRkUG9zdEJ1aWxkSm9iVGFza09wdGlvbnMgPSB7fSxcbiAgKSB7XG4gICAgdGhpcy5hZGRQb3N0QnVpbGRKb2JDb21tYW5kcyhcbiAgICAgIGBwb3N0LWJ1aWxkLSR7dGFzay5uYW1lfWAsXG4gICAgICBbYCR7dGhpcy5wcm9qZWN0LnByb2plbkNvbW1hbmR9ICR7dGFzay5uYW1lfWBdLFxuICAgICAge1xuICAgICAgICBjaGVja291dFJlcG86IHRydWUsXG4gICAgICAgIGluc3RhbGxEZXBzOiB0cnVlLFxuICAgICAgICB0b29sczogb3B0aW9ucy50b29scyxcbiAgICAgICAgLi4uZmlsdGVyZWRSdW5zT25PcHRpb25zKG9wdGlvbnMucnVuc09uLCBvcHRpb25zLnJ1bnNPbkdyb3VwKSxcbiAgICAgIH0sXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYSBzZXF1ZW5jZSBvZiBjb21tYW5kcyBhcyBhIGpvYiB3aXRoaW4gdGhlIGJ1aWxkIHdvcmtmbG93IHdoaWNoIGlzXG4gICAqIGV4ZWN1dGVkIGFmdGVyIHRoZSBidWlsZCBqb2Igc3VjY2VlZGVkLlxuICAgKlxuICAgKiBKb2JzIGFyZSBleGVjdXRlZCBfb25seV8gaWYgdGhlIGJ1aWxkIGRpZCBOT1Qgc2VsZiBtdXRhdGUuIElmIHRoZSBidWlsZFxuICAgKiBzZWxmLW11dGF0ZSwgdGhlIGJyYW5jaCB3aWxsIGVpdGhlciBiZSB1cGRhdGVkIG9yIHRoZSBidWlsZCB3aWxsIGZhaWwgKGluXG4gICAqIGZvcmtzKSwgc28gdGhlcmUgaXMgbm8gcG9pbnQgaW4gZXhlY3V0aW5nIHRoZSBwb3N0LWJ1aWxkIGpvYi5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgU3BlY2lmeSB0b29scyBhbmQgb3RoZXIgb3B0aW9uc1xuICAgKi9cbiAgcHVibGljIGFkZFBvc3RCdWlsZEpvYkNvbW1hbmRzKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgY29tbWFuZHM6IHN0cmluZ1tdLFxuICAgIG9wdGlvbnM/OiBBZGRQb3N0QnVpbGRKb2JDb21tYW5kc09wdGlvbnMsXG4gICkge1xuICAgIGNvbnN0IHN0ZXBzID0gW107XG5cbiAgICBpZiAob3B0aW9ucz8uY2hlY2tvdXRSZXBvKSB7XG4gICAgICBzdGVwcy5wdXNoKFxuICAgICAgICBXb3JrZmxvd1N0ZXBzLmNoZWNrb3V0KHtcbiAgICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgICByZWY6IFBVTExfUkVRVUVTVF9SRUYsXG4gICAgICAgICAgICByZXBvc2l0b3J5OiBQVUxMX1JFUVVFU1RfUkVQT1NJVE9SWSxcbiAgICAgICAgICAgIC4uLih0aGlzLmdpdGh1Yi5kb3dubG9hZExmcyA/IHsgbGZzOiB0cnVlIH0gOiB7fSksXG4gICAgICAgICAgICAuLi4odGhpcy5naXRodWIuY2hlY2tvdXRTdWJtb2R1bGVzICE9PSBDaGVja291dFN1Ym1vZHVsZXMuRElTQUJMRURcbiAgICAgICAgICAgICAgPyB7IHN1Ym1vZHVsZXM6IHRoaXMuZ2l0aHViLmNoZWNrb3V0U3VibW9kdWxlcyB9XG4gICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBvcHRpb25zPy5jaGVja291dFJlcG8gJiZcbiAgICAgIG9wdGlvbnM/Lmluc3RhbGxEZXBzICYmXG4gICAgICB0aGlzLnByb2plY3QgaW5zdGFuY2VvZiBOb2RlUHJvamVjdFxuICAgICkge1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIG5hbWU6IFwiSW5zdGFsbCBkZXBlbmRlbmNpZXNcIixcbiAgICAgICAgcnVuOiBgJHt0aGlzLnByb2plY3QucGFja2FnZS5pbnN0YWxsQ29tbWFuZH1gLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RlcHMucHVzaCh7IHJ1bjogY29tbWFuZHMuam9pbihcIlxcblwiKSB9KTtcblxuICAgIHRoaXMuYWRkUG9zdEJ1aWxkSm9iKGlkLCB7XG4gICAgICBwZXJtaXNzaW9uczoge1xuICAgICAgICBjb250ZW50czogSm9iUGVybWlzc2lvbi5SRUFELFxuICAgICAgfSxcbiAgICAgIHRvb2xzOiBvcHRpb25zPy50b29scyxcbiAgICAgIC4uLmZpbHRlcmVkUnVuc09uT3B0aW9ucyhvcHRpb25zPy5ydW5zT24sIG9wdGlvbnM/LnJ1bnNPbkdyb3VwKSxcbiAgICAgIHN0ZXBzLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRTZWxmTXV0YXRpb25Kb2Iob3B0aW9uczogQnVpbGRXb3JrZmxvd09wdGlvbnMpIHtcbiAgICBjb25zdCBjcmVkZW50aWFscyA9IHRoaXMud29ya2Zsb3cucHJvamVuQ3JlZGVudGlhbHM7XG4gICAgdGhpcy53b3JrZmxvdy5hZGRKb2IoXCJzZWxmLW11dGF0aW9uXCIsIHtcbiAgICAgIC4uLmZpbHRlcmVkUnVuc09uT3B0aW9ucyhvcHRpb25zLnJ1bnNPbiwgb3B0aW9ucy5ydW5zT25Hcm91cCksXG4gICAgICBwZXJtaXNzaW9uczoge1xuICAgICAgICBjb250ZW50czogSm9iUGVybWlzc2lvbi5XUklURSxcbiAgICAgIH0sXG4gICAgICBuZWVkczogW0JVSUxEX0pPQklEXSxcbiAgICAgIGlmOiBgYWx3YXlzKCkgJiYgJHtTRUxGX01VVEFUSU9OX0NPTkRJVElPTn0gJiYgJHtOT1RfRk9SS31gLFxuICAgICAgZW52aXJvbm1lbnQ6IGNyZWRlbnRpYWxzLmVudmlyb25tZW50LFxuICAgICAgc3RlcHM6IFtcbiAgICAgICAgLi4uY3JlZGVudGlhbHMuc2V0dXBTdGVwcyxcbiAgICAgICAgLi4uV29ya2Zsb3dBY3Rpb25zLmNoZWNrb3V0V2l0aFBhdGNoKHtcbiAgICAgICAgICAvLyB3ZSBuZWVkIHRvIHVzZSBhIFBBVCBzbyB0aGF0IG91ciBwdXNoIHdpbGwgdHJpZ2dlciB0aGUgYnVpbGQgd29ya2Zsb3dcbiAgICAgICAgICB0b2tlbjogY3JlZGVudGlhbHMudG9rZW5SZWYsXG4gICAgICAgICAgcmVmOiBQVUxMX1JFUVVFU1RfUkVGLFxuICAgICAgICAgIHJlcG9zaXRvcnk6IFBVTExfUkVRVUVTVF9SRVBPU0lUT1JZLFxuICAgICAgICAgIGxmczogdGhpcy5naXRodWIuZG93bmxvYWRMZnMsXG4gICAgICAgIH0pLFxuICAgICAgICBXb3JrZmxvd1N0ZXBzLnNldHVwR2l0SWRlbnRpdHkoeyBnaXRJZGVudGl0eTogdGhpcy5naXRJZGVudGl0eSB9KSxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiUHVzaCBjaGFuZ2VzXCIsXG4gICAgICAgICAgZW52OiB7XG4gICAgICAgICAgICBQVUxMX1JFUVVFU1RfUkVGLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcnVuOiBbXG4gICAgICAgICAgICBcImdpdCBhZGQgLlwiLFxuICAgICAgICAgICAgJ2dpdCBjb21taXQgLXMgLW0gXCJjaG9yZTogc2VsZiBtdXRhdGlvblwiJyxcbiAgICAgICAgICAgIGBnaXQgcHVzaCBvcmlnaW4gXCJIRUFEOiRQVUxMX1JFUVVFU1RfUkVGXCJgLFxuICAgICAgICAgIF0uam9pbihcIlxcblwiKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIChsYXppbHkpIGR1cmluZyBzeW50aCB0byByZW5kZXIgdGhlIGJ1aWxkIGpvYiBzdGVwcy5cbiAgICovXG4gIHByaXZhdGUgcmVuZGVyQnVpbGRTdGVwcyhwcm9qZWN0UGF0aFJlbGF0aXZlVG9Sb290OiBzdHJpbmcpOiBKb2JTdGVwW10ge1xuICAgIHJldHVybiBbXG4gICAgICBXb3JrZmxvd1N0ZXBzLmNoZWNrb3V0KHtcbiAgICAgICAgd2l0aDoge1xuICAgICAgICAgIHJlZjogUFVMTF9SRVFVRVNUX1JFRixcbiAgICAgICAgICByZXBvc2l0b3J5OiBQVUxMX1JFUVVFU1RfUkVQT1NJVE9SWSxcbiAgICAgICAgICAuLi4odGhpcy5naXRodWIuZG93bmxvYWRMZnMgPyB7IGxmczogdHJ1ZSB9IDoge30pLFxuICAgICAgICAgIC4uLih0aGlzLmdpdGh1Yi5jaGVja291dFN1Ym1vZHVsZXNcbiAgICAgICAgICAgID8geyBzdWJtb2R1bGVzOiB0aGlzLmdpdGh1Yi5jaGVja291dFN1Ym1vZHVsZXMgfVxuICAgICAgICAgICAgOiB7fSksXG4gICAgICAgIH0sXG4gICAgICB9KSxcblxuICAgICAgLi4udGhpcy5wcmVCdWlsZFN0ZXBzLFxuXG4gICAgICB7XG4gICAgICAgIG5hbWU6IHRoaXMuYnVpbGRUYXNrLm5hbWUsXG4gICAgICAgIHJ1bjogdGhpcy5naXRodWIucHJvamVjdC5ydW5UYXNrQ29tbWFuZCh0aGlzLmJ1aWxkVGFzayksXG4gICAgICB9LFxuXG4gICAgICAuLi50aGlzLnBvc3RCdWlsZFN0ZXBzLFxuXG4gICAgICAvLyBjaGVjayBmb3IgbXV0YXRpb25zIGFuZCB1cGxvYWQgYSBnaXQgcGF0Y2ggZmlsZSBhcyBhbiBhcnRpZmFjdFxuICAgICAgLi4uV29ya2Zsb3dBY3Rpb25zLnVwbG9hZEdpdFBhdGNoKHtcbiAgICAgICAgc3RlcElkOiBTRUxGX01VVEFUSU9OX1NURVAsXG4gICAgICAgIG91dHB1dE5hbWU6IFNFTEZfTVVUQVRJT05fSEFQUEVORURfT1VUUFVULFxuICAgICAgICBtdXRhdGlvbkVycm9yOlxuICAgICAgICAgIFwiRmlsZXMgd2VyZSBjaGFuZ2VkIGR1cmluZyBidWlsZCAoc2VlIGJ1aWxkIGxvZykuIElmIHRoaXMgd2FzIHRyaWdnZXJlZCBmcm9tIGEgZm9yaywgeW91IHdpbGwgbmVlZCB0byB1cGRhdGUgeW91ciBicmFuY2guXCIsXG4gICAgICB9KSxcblxuICAgICAgLy8gdXBsb2FkIHRoZSBidWlsZCBhcnRpZmFjdCBvbmx5IGlmIHdlIGhhdmUgcG9zdC1idWlsZCBqb2JzIChvdGhlcndpc2UsIHRoZXJlJ3Mgbm8gcG9pbnQpXG4gICAgICAuLi4odGhpcy5fcG9zdEJ1aWxkSm9icy5sZW5ndGggPT0gMFxuICAgICAgICA/IFtdXG4gICAgICAgIDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBuYW1lOiBcIkJhY2t1cCBhcnRpZmFjdCBwZXJtaXNzaW9uc1wiLFxuICAgICAgICAgICAgICBjb250aW51ZU9uRXJyb3I6IHRydWUsXG4gICAgICAgICAgICAgIHJ1bjogYGNkICR7dGhpcy5hcnRpZmFjdHNEaXJlY3Rvcnl9ICYmIGdldGZhY2wgLVIgLiA+ICR7UEVSTUlTU0lPTl9CQUNLVVBfRklMRX1gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFdvcmtmbG93U3RlcHMudXBsb2FkQXJ0aWZhY3Qoe1xuICAgICAgICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgICAgICAgbmFtZTogQlVJTERfQVJUSUZBQ1RfTkFNRSxcbiAgICAgICAgICAgICAgICBwYXRoOiB0aGlzLnByb2plY3QucGFyZW50XG4gICAgICAgICAgICAgICAgICA/IHBvc2l4UGF0aC5qb2luKFxuICAgICAgICAgICAgICAgICAgICAgIHByb2plY3RQYXRoUmVsYXRpdmVUb1Jvb3QsXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcnRpZmFjdHNEaXJlY3RvcnksXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIDogdGhpcy5hcnRpZmFjdHNEaXJlY3RvcnksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdKSxcbiAgICBdO1xuICB9XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYEJ1aWxkV29ya2Zsb3cuYWRkUG9zdEJ1aWxkSm9iVGFza2BcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBZGRQb3N0QnVpbGRKb2JUYXNrT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUb29scyB0aGF0IHNob3VsZCBiZSBpbnN0YWxsZWQgYmVmb3JlIHRoZSB0YXNrIGlzIHJ1bi5cbiAgICovXG4gIHJlYWRvbmx5IHRvb2xzPzogVG9vbHM7XG5cbiAgLyoqXG4gICAqIEdpdGh1YiBSdW5uZXIgc2VsZWN0aW9uIGxhYmVsc1xuICAgKiBAZGVmYXVsdCBbXCJ1YnVudHUtbGF0ZXN0XCJdXG4gICAqIEBkZXNjcmlwdGlvbiBEZWZpbmVzIGEgdGFyZ2V0IFJ1bm5lciBieSBsYWJlbHNcbiAgICogQHRocm93cyB7RXJyb3J9IGlmIGJvdGggYHJ1bnNPbmAgYW5kIGBydW5zT25Hcm91cGAgYXJlIHNwZWNpZmllZFxuICAgKi9cbiAgcmVhZG9ubHkgcnVuc09uPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEdpdGh1YiBSdW5uZXIgR3JvdXAgc2VsZWN0aW9uIG9wdGlvbnNcbiAgICogQGRlc2NyaXB0aW9uIERlZmluZXMgYSB0YXJnZXQgUnVubmVyIEdyb3VwIGJ5IG5hbWUgYW5kL29yIGxhYmVsc1xuICAgKiBAdGhyb3dzIHtFcnJvcn0gaWYgYm90aCBgcnVuc09uYCBhbmQgYHJ1bnNPbkdyb3VwYCBhcmUgc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSBydW5zT25Hcm91cD86IEdyb3VwUnVubmVyT3B0aW9ucztcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBgQnVpbGRXb3JrZmxvdy5hZGRQb3N0QnVpbGRKb2JDb21tYW5kc2BcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBZGRQb3N0QnVpbGRKb2JDb21tYW5kc09wdGlvbnMge1xuICAvKipcbiAgICogVG9vbHMgdGhhdCBzaG91bGQgYmUgaW5zdGFsbGVkIGJlZm9yZSB0aGUgY29tbWFuZHMgYXJlIHJ1bi5cbiAgICovXG4gIHJlYWRvbmx5IHRvb2xzPzogVG9vbHM7XG5cbiAgLyoqXG4gICAqIENoZWNrIG91dCB0aGUgcmVwb3NpdG9yeSBhdCB0aGUgcHVsbCByZXF1ZXN0IGJyYW5jaCBiZWZvcmUgY29tbWFuZHMgYXJlXG4gICAqIHJ1bi5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGNoZWNrb3V0UmVwbz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEluc3RhbGwgcHJvamVjdCBkZXBlbmRlbmNpZXMgYmVmb3JlIHJ1bm5pbmcgY29tbWFuZHMuIGBjaGVja291dFJlcG9gIG11c3RcbiAgICogYWxzbyBiZSBzZXQgdG8gdHJ1ZS5cbiAgICpcbiAgICogQ3VycmVudGx5IG9ubHkgc3VwcG9ydGVkIGZvciBgTm9kZVByb2plY3RgLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgaW5zdGFsbERlcHM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBHaXRodWIgUnVubmVyIHNlbGVjdGlvbiBsYWJlbHNcbiAgICogQGRlZmF1bHQgW1widWJ1bnR1LWxhdGVzdFwiXVxuICAgKiBAZGVzY3JpcHRpb24gRGVmaW5lcyBhIHRhcmdldCBSdW5uZXIgYnkgbGFiZWxzXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBpZiBib3RoIGBydW5zT25gIGFuZCBgcnVuc09uR3JvdXBgIGFyZSBzcGVjaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IHJ1bnNPbj86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBHaXRodWIgUnVubmVyIEdyb3VwIHNlbGVjdGlvbiBvcHRpb25zXG4gICAqIEBkZXNjcmlwdGlvbiBEZWZpbmVzIGEgdGFyZ2V0IFJ1bm5lciBHcm91cCBieSBuYW1lIGFuZC9vciBsYWJlbHNcbiAgICogQHRocm93cyB7RXJyb3J9IGlmIGJvdGggYHJ1bnNPbmAgYW5kIGBydW5zT25Hcm91cGAgYXJlIHNwZWNpZmllZFxuICAgKi9cbiAgcmVhZG9ubHkgcnVuc09uR3JvdXA/OiBHcm91cFJ1bm5lck9wdGlvbnM7XG59XG4iXX0=