UNPKG

projen

Version:

CDK for software projects

360 lines • 55.1 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.JsiiProject = exports.Stability = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const consts_1 = require("./consts"); const jsii_docgen_1 = require("./jsii-docgen"); const consts_2 = require("../build/private/consts"); const workflow_steps_1 = require("../github/workflow-steps"); const workflows_model_1 = require("../github/workflows-model"); const javascript_1 = require("../javascript"); const runner_options_1 = require("../runner-options"); const typescript_1 = require("../typescript"); const util_1 = require("../util"); const EMAIL_REGEX = /^[^\s@]+@[^\s@]+$/; const URL_REGEX = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/; const REPO_TEMP_DIRECTORY = ".repo"; const BUILD_ARTIFACT_OLD_DIR = "dist.old"; var Stability; (function (Stability) { Stability["EXPERIMENTAL"] = "experimental"; Stability["STABLE"] = "stable"; Stability["DEPRECATED"] = "deprecated"; })(Stability || (exports.Stability = Stability = {})); /** * Multi-language jsii library project * * @pjid jsii */ class JsiiProject extends typescript_1.TypeScriptProject { constructor(options) { const { authorEmail, authorUrl } = parseAuthorAddress(options); const jsiiVersion = options.jsiiVersion ?? "~5.9.0"; const defaultOptions = { repository: options.repositoryUrl, authorName: options.author, authorEmail, authorUrl, }; const forcedOptions = { releaseToNpm: false, // we have a jsii release workflow disableTsconfig: true, // jsii generates its own tsconfig.json docgen: false, // we use jsii-docgen here so disable typescript docgen }; const mergedOptions = (0, util_1.deepMerge)([ defaultOptions, options, forcedOptions, ]); super(mergedOptions); const srcdir = this.srcdir; const libdir = this.libdir; this.addFields({ types: `${libdir}/index.d.ts` }); const compressAssembly = options.compressAssembly ?? false; // this is an unhelpful warning const jsiiFlags = ["--silence-warnings=reserved-word"]; if (compressAssembly) { jsiiFlags.push("--compress-assembly"); } const compatIgnore = options.compatIgnore ?? ".compatignore"; this.addFields({ stability: options.stability ?? Stability.STABLE }); if (options.stability === Stability.DEPRECATED) { this.addFields({ deprecated: true }); } const compatTask = this.addTask("compat", { description: "Perform API compatibility check against latest version", exec: `jsii-diff npm:$(node -p "require(\'./package.json\').name") -k --ignore-file ${compatIgnore} || (echo "\nUNEXPECTED BREAKING CHANGES: add keys such as \'removed:constructs.Node.of\' to ${compatIgnore} to skip.\n" && exit 1)`, }); const compat = options.compat ?? false; if (compat) { this.compileTask.spawn(compatTask); } this.compileTask.reset(["jsii", ...jsiiFlags].join(" ")); this.watchTask.reset(["jsii", "-w", ...jsiiFlags].join(" ")); // Create a new package:all task, it will be filled with language targets later this.packageAllTask = this.addTask("package-all", { description: "Packages artifacts for all target languages", }); // in jsii we consider the entire repo (post build) as the build artifact // which is then used to create the language bindings in separate jobs. // we achieve this by doing a checkout and overwrite with the files from the js package. this.packageJsTask = this.addPackagingTask("js"); // When running inside CI we initially only package js. Other targets are packaged in separate jobs. // Outside of CI (i.e locally) we simply package all targets. this.packageTask.reset(); this.packageTask.spawn(this.packageJsTask, { // Only run in CI condition: `node -e "if (!process.env.CI) process.exit(1)"`, }); this.packageTask.spawn(this.packageAllTask, { // Don't run in CI condition: `node -e "if (process.env.CI) process.exit(1)"`, }); const targets = {}; const jsii = { outdir: this.artifactsDirectory, targets, tsc: { outDir: libdir, rootDir: srcdir, }, }; if (options.excludeTypescript) { jsii.excludeTypescript = options.excludeTypescript; } this.addFields({ jsii }); const extraJobOptions = { ...this.getJobRunsOnConfig(options), ...(options.workflowContainerImage ? { container: { image: options.workflowContainerImage } } : {}), }; if (options.releaseToNpm != false) { const npmjs = { registry: this.package.npmRegistry, npmTokenSecret: this.package.npmTokenSecret, npmProvenance: this.package.npmProvenance, codeArtifactOptions: options.codeArtifactOptions, trustedPublishing: options.npmTrustedPublishing ?? false, }; this.addTargetToBuild("js", this.packageJsTask, extraJobOptions); this.addTargetToRelease("js", this.packageJsTask, npmjs); } // we cannot call an option `java` because the java code generated by jsii // does not compile due to a conflict between this option name and the `java` // package (e.g. when `java.util.Objects` is referenced). if ("java" in options) { throw new Error('the "java" option is now called "publishToMaven"'); } const maven = options.publishToMaven; if (maven) { targets.java = { package: maven.javaPackage, maven: { groupId: maven.mavenGroupId, artifactId: maven.mavenArtifactId, }, }; const task = this.addPackagingTask("java"); this.addTargetToBuild("java", task, extraJobOptions); this.addTargetToRelease("java", task, maven); } const pypi = options.publishToPypi ?? options.python; if (pypi) { targets.python = { distName: pypi.distName, module: pypi.module, }; const task = this.addPackagingTask("python"); this.addTargetToBuild("python", task, extraJobOptions); this.addTargetToRelease("python", task, pypi); } const nuget = options.publishToNuget ?? options.dotnet; if (nuget) { targets.dotnet = { namespace: nuget.dotNetNamespace, packageId: nuget.packageId, iconUrl: nuget.iconUrl, }; const task = this.addPackagingTask("dotnet"); this.addTargetToBuild("dotnet", task, extraJobOptions); this.addTargetToRelease("dotnet", task, nuget); } const golang = options.publishToGo; if (golang) { targets.go = { moduleName: golang.moduleName, packageName: golang.packageName, versionSuffix: golang.versionSuffix, }; const task = this.addPackagingTask("go"); this.addTargetToBuild("go", task, extraJobOptions); this.addTargetToRelease("go", task, golang); } // If jsiiVersion is "*", don't specify anything so the user can manage. // Otherwise, use `jsiiVersion` const jsiiSuffix = jsiiVersion === "*" ? "" : `@${jsiiVersion}`; this.addDevDeps(`jsii${jsiiSuffix}`, `jsii-rosetta${jsiiSuffix}`, "jsii-diff", "jsii-pacmak"); this.gitignore.exclude(".jsii", "tsconfig.json"); this.npmignore?.include(".jsii"); if (options.docgen ?? true) { // If jsiiVersion is "*", don't specify anything so the user can manage. // Otherwise use a version that is compatible with all supported jsii releases. const docgenVersion = options.jsiiVersion === "*" ? "*" : "^10.5.0"; new jsii_docgen_1.JsiiDocgen(this, { version: docgenVersion, filePath: options.docgenFilePath, }); } // jsii updates .npmignore, so we make it writable if (this.npmignore) { this.npmignore.readonly = false; } } /** * Adds a target language to the release workflow. * @param language * @returns */ addTargetToRelease(language, packTask, target) { if (!this.release) { return; } const pacmak = this.pacmakForLanguage(language, packTask); const prePublishSteps = [ ...pacmak.bootstrapSteps, workflow_steps_1.WorkflowSteps.checkout({ with: { path: REPO_TEMP_DIRECTORY, ...(this.github?.downloadLfs ? { lfs: true } : {}), }, }), ...pacmak.packagingSteps, ]; const commonPublishOptions = { publishTools: pacmak.publishTools, prePublishSteps, }; const handler = publishTo[language]; this.release?.publisher[handler]({ ...commonPublishOptions, ...target, }); } /** * Adds a target language to the build workflow * @param language * @returns */ addTargetToBuild(language, packTask, extraJobOptions) { if (!this.buildWorkflow) { return; } const pacmak = this.pacmakForLanguage(language, packTask); this.buildWorkflow.addPostBuildJob(`package-${language}`, { ...(0, runner_options_1.filteredRunsOnOptions)(extraJobOptions.runsOn, extraJobOptions.runsOnGroup), permissions: { contents: workflows_model_1.JobPermission.READ, }, tools: { node: { version: this.nodeVersion ?? "lts/*" }, ...pacmak.publishTools, }, steps: [ ...pacmak.bootstrapSteps, workflow_steps_1.WorkflowSteps.checkout({ with: { path: REPO_TEMP_DIRECTORY, ref: consts_2.PULL_REQUEST_REF, repository: consts_2.PULL_REQUEST_REPOSITORY, ...(this.github?.downloadLfs ? { lfs: true } : {}), }, }), ...pacmak.packagingSteps, ], ...extraJobOptions, }); } addPackagingTask(language) { const packageTargetTask = this.tasks.addTask(`package:${language}`, { description: `Create ${language} language bindings`, }); const commandParts = ["jsii-pacmak", "-v"]; if (this.package.packageManager === javascript_1.NodePackageManager.PNPM) { commandParts.push('--pack-command "pnpm pack"'); } commandParts.push(`--target ${language}`); packageTargetTask.exec(commandParts.join(" ")); this.packageAllTask.spawn(packageTargetTask); return packageTargetTask; } pacmakForLanguage(target, packTask) { const bootstrapSteps = []; const packagingSteps = []; // Generic bootstrapping for all target languages bootstrapSteps.push(...this.workflowBootstrapSteps); if (this.package.packageManager === javascript_1.NodePackageManager.PNPM) { bootstrapSteps.push({ name: "Setup pnpm", uses: "pnpm/action-setup@v4", with: { version: this.package.pnpmVersion }, }); } else if (this.package.packageManager === javascript_1.NodePackageManager.BUN) { bootstrapSteps.push({ name: "Setup bun", uses: "oven-sh/setup-bun@v2", with: { "bun-version": this.package.bunVersion }, }); } // Installation steps before packaging, but after checkout packagingSteps.push({ name: "Install Dependencies", run: `cd ${REPO_TEMP_DIRECTORY} && ${this.package.installCommand}`, }, { name: "Extract build artifact", run: `tar --strip-components=1 -xzvf ${this.artifactsDirectory}/js/*.tgz -C ${REPO_TEMP_DIRECTORY}`, }, { name: `Move build artifact out of the way`, run: `mv ${this.artifactsDirectory} ${BUILD_ARTIFACT_OLD_DIR}`, }, { name: `Create ${target} artifact`, run: `cd ${REPO_TEMP_DIRECTORY} && ${this.runTaskCommand(packTask)}`, }, { name: `Collect ${target} artifact`, run: `mv ${REPO_TEMP_DIRECTORY}/${this.artifactsDirectory} ${this.artifactsDirectory}`, }); return { publishTools: consts_1.JSII_TOOLCHAIN[target], bootstrapSteps, packagingSteps, }; } /** * Generates the runs-on config for Jobs. * Throws error if 'runsOn' and 'runsOnGroup' are both set. * * @param options - 'runsOn' or 'runsOnGroup'. */ getJobRunsOnConfig(options) { return options.workflowRunsOnGroup ? { runsOnGroup: options.workflowRunsOnGroup } : options.workflowRunsOn ? { runsOn: options.workflowRunsOn } : {}; } } exports.JsiiProject = JsiiProject; _a = JSII_RTTI_SYMBOL_1; JsiiProject[_a] = { fqn: "projen.cdk.JsiiProject", version: "0.99.17" }; const publishTo = { js: "publishToNpm", java: "publishToMaven", python: "publishToPyPi", dotnet: "publishToNuget", go: "publishToGo", }; function parseAuthorAddress(options) { let authorEmail = options.authorEmail; let authorUrl = options.authorUrl; if (options.authorAddress) { if (options.authorEmail && options.authorEmail !== options.authorAddress) { throw new Error("authorEmail is deprecated and cannot be used in conjunction with authorAddress"); } if (options.authorUrl && options.authorUrl !== options.authorAddress) { throw new Error("authorUrl is deprecated and cannot be used in conjunction with authorAddress."); } if (EMAIL_REGEX.test(options.authorAddress)) { authorEmail = options.authorAddress; } else if (URL_REGEX.test(options.authorAddress)) { authorUrl = options.authorAddress; } else { throw new Error(`authorAddress must be either an email address or a URL: ${options.authorAddress}`); } } return { authorEmail, authorUrl }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNpaS1wcm9qZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Nkay9qc2lpLXByb2plY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFDQSxxQ0FBNEQ7QUFDNUQsK0NBQTJDO0FBQzNDLG9EQUdpQztBQUNqQyw2REFBeUQ7QUFDekQsK0RBQTRFO0FBQzVFLDhDQUFtRDtBQVVuRCxzREFBMEQ7QUFDMUQsOENBQTRFO0FBQzVFLGtDQUFvQztBQUVwQyxNQUFNLFdBQVcsR0FBRyxtQkFBbUIsQ0FBQztBQUN4QyxNQUFNLFNBQVMsR0FDYixzTEFBc0wsQ0FBQztBQUV6TCxNQUFNLG1CQUFtQixHQUFHLE9BQU8sQ0FBQztBQUNwQyxNQUFNLHNCQUFzQixHQUFHLFVBQVUsQ0FBQztBQWtIMUMsSUFBWSxTQUlYO0FBSkQsV0FBWSxTQUFTO0lBQ25CLDBDQUE2QixDQUFBO0lBQzdCLDhCQUFpQixDQUFBO0lBQ2pCLHNDQUF5QixDQUFBO0FBQzNCLENBQUMsRUFKVyxTQUFTLHlCQUFULFNBQVMsUUFJcEI7QUFtREQ7Ozs7R0FJRztBQUNILE1BQWEsV0FBWSxTQUFRLDhCQUFpQjtJQUloRCxZQUFZLE9BQTJCO1FBQ3JDLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLEdBQUcsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFL0QsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsSUFBSSxRQUFRLENBQUM7UUFFcEQsTUFBTSxjQUFjLEdBQXNDO1lBQ3hELFVBQVUsRUFBRSxPQUFPLENBQUMsYUFBYTtZQUNqQyxVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU07WUFDMUIsV0FBVztZQUNYLFNBQVM7U0FDVixDQUFDO1FBRUYsTUFBTSxhQUFhLEdBQUc7WUFDcEIsWUFBWSxFQUFFLEtBQUssRUFBRSxrQ0FBa0M7WUFDdkQsZUFBZSxFQUFFLElBQUksRUFBRSx1Q0FBdUM7WUFDOUQsTUFBTSxFQUFFLEtBQUssRUFBRSx1REFBdUQ7U0FDdkUsQ0FBQztRQUVGLE1BQU0sYUFBYSxHQUFHLElBQUEsZ0JBQVMsRUFBQztZQUM5QixjQUFjO1lBQ2QsT0FBTztZQUNQLGFBQWE7U0FDZCxDQUE2QixDQUFDO1FBRS9CLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUVyQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzNCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFFM0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sYUFBYSxFQUFFLENBQUMsQ0FBQztRQUVsRCxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxLQUFLLENBQUM7UUFFM0QsK0JBQStCO1FBQy9CLE1BQU0sU0FBUyxHQUFHLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUN2RCxJQUFJLGdCQUFnQixFQUFFLENBQUM7WUFDckIsU0FBUyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ3hDLENBQUM7UUFFRCxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxJQUFJLGVBQWUsQ0FBQztRQUU3RCxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLElBQUksU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFFckUsSUFBSSxPQUFPLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdkMsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFO1lBQ3hDLFdBQVcsRUFBRSx3REFBd0Q7WUFDckUsSUFBSSxFQUFFLGdGQUFnRixZQUFZLGdHQUFnRyxZQUFZLHlCQUF5QjtTQUN4TyxDQUFDLENBQUM7UUFFSCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQztRQUN2QyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUVELElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFN0QsK0VBQStFO1FBQy9FLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUU7WUFDaEQsV0FBVyxFQUFFLDZDQUE2QztTQUMzRCxDQUFDLENBQUM7UUFFSCx5RUFBeUU7UUFDekUsdUVBQXVFO1FBQ3ZFLHdGQUF3RjtRQUN4RixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVqRCxvR0FBb0c7UUFDcEcsNkRBQTZEO1FBQzdELElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN6QyxpQkFBaUI7WUFDakIsU0FBUyxFQUFFLGdEQUFnRDtTQUM1RCxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFO1lBQzFDLGtCQUFrQjtZQUNsQixTQUFTLEVBQUUsK0NBQStDO1NBQzNELENBQUMsQ0FBQztRQUVILE1BQU0sT0FBTyxHQUF3QixFQUFFLENBQUM7UUFFeEMsTUFBTSxJQUFJLEdBQVE7WUFDaEIsTUFBTSxFQUFFLElBQUksQ0FBQyxrQkFBa0I7WUFDL0IsT0FBTztZQUNQLEdBQUcsRUFBRTtnQkFDSCxNQUFNLEVBQUUsTUFBTTtnQkFDZCxPQUFPLEVBQUUsTUFBTTthQUNoQjtTQUNGLENBQUM7UUFFRixJQUFJLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7UUFDckQsQ0FBQztRQUVELElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXpCLE1BQU0sZUFBZSxHQUFpQjtZQUNwQyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUM7WUFDbkMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxzQkFBc0I7Z0JBQ2hDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsc0JBQXNCLEVBQUUsRUFBRTtnQkFDMUQsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUNSLENBQUM7UUFFRixJQUFJLE9BQU8sQ0FBQyxZQUFZLElBQUksS0FBSyxFQUFFLENBQUM7WUFDbEMsTUFBTSxLQUFLLEdBQXNCO2dCQUMvQixRQUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXO2dCQUNsQyxjQUFjLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjO2dCQUMzQyxhQUFhLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhO2dCQUN6QyxtQkFBbUIsRUFBRSxPQUFPLENBQUMsbUJBQW1CO2dCQUNoRCxpQkFBaUIsRUFBRSxPQUFPLENBQUMsb0JBQW9CLElBQUksS0FBSzthQUN6RCxDQUFDO1lBQ0YsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBQ2pFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMzRCxDQUFDO1FBRUQsMEVBQTBFO1FBQzFFLDZFQUE2RTtRQUM3RSx5REFBeUQ7UUFDekQsSUFBSSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7WUFDdEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDO1FBQ3JDLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixPQUFPLENBQUMsSUFBSSxHQUFHO2dCQUNiLE9BQU8sRUFBRSxLQUFLLENBQUMsV0FBVztnQkFDMUIsS0FBSyxFQUFFO29CQUNMLE9BQU8sRUFBRSxLQUFLLENBQUMsWUFBWTtvQkFDM0IsVUFBVSxFQUFFLEtBQUssQ0FBQyxlQUFlO2lCQUNsQzthQUNGLENBQUM7WUFFRixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0MsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUM7WUFDckQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDL0MsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxhQUFhLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUNyRCxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsT0FBTyxDQUFDLE1BQU0sR0FBRztnQkFDZixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7Z0JBQ3ZCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTthQUNwQixDQUFDO1lBRUYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzdDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hELENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsY0FBYyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDdkQsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLE9BQU8sQ0FBQyxNQUFNLEdBQUc7Z0JBQ2YsU0FBUyxFQUFFLEtBQUssQ0FBQyxlQUFlO2dCQUNoQyxTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7Z0JBQzFCLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTzthQUN2QixDQUFDO1lBRUYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzdDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO1FBQ25DLElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsRUFBRSxHQUFHO2dCQUNYLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtnQkFDN0IsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXO2dCQUMvQixhQUFhLEVBQUUsTUFBTSxDQUFDLGFBQWE7YUFDcEMsQ0FBQztZQUVGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQztZQUNuRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBRUQsd0VBQXdFO1FBQ3hFLCtCQUErQjtRQUMvQixNQUFNLFVBQVUsR0FBRyxXQUFXLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksV0FBVyxFQUFFLENBQUM7UUFDaEUsSUFBSSxDQUFDLFVBQVUsQ0FDYixPQUFPLFVBQVUsRUFBRSxFQUNuQixlQUFlLFVBQVUsRUFBRSxFQUMzQixXQUFXLEVBQ1gsYUFBYSxDQUNkLENBQUM7UUFFRixJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFakMsSUFBSSxPQUFPLENBQUMsTUFBTSxJQUFJLElBQUksRUFBRSxDQUFDO1lBQzNCLHdFQUF3RTtZQUN4RSwrRUFBK0U7WUFDL0UsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLFdBQVcsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ3BFLElBQUksd0JBQVUsQ0FBQyxJQUFJLEVBQUU7Z0JBQ25CLE9BQU8sRUFBRSxhQUFhO2dCQUN0QixRQUFRLEVBQUUsT0FBTyxDQUFDLGNBQWM7YUFDakMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELGtEQUFrRDtRQUNsRCxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDbEMsQ0FBQztJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssa0JBQWtCLENBQ3hCLFFBQTBCLEVBQzFCLFFBQWMsRUFDZCxNQUtxQjtRQUVyQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2xCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMxRCxNQUFNLGVBQWUsR0FBRztZQUN0QixHQUFHLE1BQU0sQ0FBQyxjQUFjO1lBQ3hCLDhCQUFhLENBQUMsUUFBUSxDQUFDO2dCQUNyQixJQUFJLEVBQUU7b0JBQ0osSUFBSSxFQUFFLG1CQUFtQjtvQkFDekIsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2lCQUNuRDthQUNGLENBQUM7WUFDRixHQUFHLE1BQU0sQ0FBQyxjQUFjO1NBQ3pCLENBQUM7UUFDRixNQUFNLG9CQUFvQixHQUF5QjtZQUNqRCxZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVk7WUFDakMsZUFBZTtTQUNoQixDQUFDO1FBRUYsTUFBTSxPQUFPLEdBQWMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQy9CLEdBQUcsb0JBQW9CO1lBQ3ZCLEdBQUcsTUFBTTtTQUNWLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssZ0JBQWdCLENBQ3RCLFFBQTBCLEVBQzFCLFFBQWMsRUFDZCxlQUE2QjtRQUU3QixJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3hCLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUUxRCxJQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsQ0FBQyxXQUFXLFFBQVEsRUFBRSxFQUFFO1lBQ3hELEdBQUcsSUFBQSxzQ0FBcUIsRUFDdEIsZUFBZSxDQUFDLE1BQU0sRUFDdEIsZUFBZSxDQUFDLFdBQVcsQ0FDNUI7WUFDRCxXQUFXLEVBQUU7Z0JBQ1gsUUFBUSxFQUFFLCtCQUFhLENBQUMsSUFBSTthQUM3QjtZQUNELEtBQUssRUFBRTtnQkFDTCxJQUFJLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVcsSUFBSSxPQUFPLEVBQUU7Z0JBQzlDLEdBQUcsTUFBTSxDQUFDLFlBQVk7YUFDdkI7WUFDRCxLQUFLLEVBQUU7Z0JBQ0wsR0FBRyxNQUFNLENBQUMsY0FBYztnQkFDeEIsOEJBQWEsQ0FBQyxRQUFRLENBQUM7b0JBQ3JCLElBQUksRUFBRTt3QkFDSixJQUFJLEVBQUUsbUJBQW1CO3dCQUN6QixHQUFHLEVBQUUseUJBQWdCO3dCQUNyQixVQUFVLEVBQUUsZ0NBQXVCO3dCQUNuQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7cUJBQ25EO2lCQUNGLENBQUM7Z0JBQ0YsR0FBRyxNQUFNLENBQUMsY0FBYzthQUN6QjtZQUNELEdBQUcsZUFBZTtTQUNuQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sZ0JBQWdCLENBQUMsUUFBMEI7UUFDakQsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLFFBQVEsRUFBRSxFQUFFO1lBQ2xFLFdBQVcsRUFBRSxVQUFVLFFBQVEsb0JBQW9CO1NBQ3BELENBQUMsQ0FBQztRQUNILE1BQU0sWUFBWSxHQUFHLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTNDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEtBQUssK0JBQWtCLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDNUQsWUFBWSxDQUFDLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1FBQ2xELENBQUM7UUFFRCxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQVksUUFBUSxFQUFFLENBQUMsQ0FBQztRQUUxQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRS9DLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDN0MsT0FBTyxpQkFBaUIsQ0FBQztJQUMzQixDQUFDO0lBRU8saUJBQWlCLENBQ3ZCLE1BQXdCLEVBQ3hCLFFBQWM7UUFNZCxNQUFNLGNBQWMsR0FBZ0IsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sY0FBYyxHQUFnQixFQUFFLENBQUM7UUFFdkMsaURBQWlEO1FBQ2pELGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUNwRCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxLQUFLLCtCQUFrQixDQUFDLElBQUksRUFBRSxDQUFDO1lBQzVELGNBQWMsQ0FBQyxJQUFJLENBQUM7Z0JBQ2xCLElBQUksRUFBRSxZQUFZO2dCQUNsQixJQUFJLEVBQUUsc0JBQXNCO2dCQUM1QixJQUFJLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUU7YUFDNUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEtBQUssK0JBQWtCLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDbEUsY0FBYyxDQUFDLElBQUksQ0FBQztnQkFDbEIsSUFBSSxFQUFFLFdBQVc7Z0JBQ2pCLElBQUksRUFBRSxzQkFBc0I7Z0JBQzVCLElBQUksRUFBRSxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRTthQUNqRCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsMERBQTBEO1FBQzFELGNBQWMsQ0FBQyxJQUFJLENBQ2pCO1lBQ0UsSUFBSSxFQUFFLHNCQUFzQjtZQUM1QixHQUFHLEVBQUUsTUFBTSxtQkFBbUIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRTtTQUNuRSxFQUNEO1lBQ0UsSUFBSSxFQUFFLHdCQUF3QjtZQUM5QixHQUFHLEVBQUUsa0NBQWtDLElBQUksQ0FBQyxrQkFBa0IsZ0JBQWdCLG1CQUFtQixFQUFFO1NBQ3BHLEVBQ0Q7WUFDRSxJQUFJLEVBQUUsb0NBQW9DO1lBQzFDLEdBQUcsRUFBRSxNQUFNLElBQUksQ0FBQyxrQkFBa0IsSUFBSSxzQkFBc0IsRUFBRTtTQUMvRCxFQUNEO1lBQ0UsSUFBSSxFQUFFLFVBQVUsTUFBTSxXQUFXO1lBQ2pDLEdBQUcsRUFBRSxNQUFNLG1CQUFtQixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEVBQUU7U0FDckUsRUFDRDtZQUNFLElBQUksRUFBRSxXQUFXLE1BQU0sV0FBVztZQUNsQyxHQUFHLEVBQUUsTUFBTSxtQkFBbUIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO1NBQ3ZGLENBQ0YsQ0FBQztRQUVGLE9BQU87WUFDTCxZQUFZLEVBQUUsdUJBQWMsQ0FBQyxNQUFNLENBQUM7WUFDcEMsY0FBYztZQUNkLGNBQWM7U0FDZixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssa0JBQWtCLENBQUMsT0FBMkI7UUFDcEQsT0FBTyxPQUFPLENBQUMsbUJBQW1CO1lBQ2hDLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsbUJBQW1CLEVBQUU7WUFDOUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxjQUFjO2dCQUN0QixDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLGNBQWMsRUFBRTtnQkFDcEMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNYLENBQUM7O0FBaFlILGtDQWlZQzs7O0FBWUQsTUFBTSxTQUFTLEdBQW9CO0lBQ2pDLEVBQUUsRUFBRSxjQUFjO0lBQ2xCLElBQUksRUFBRSxnQkFBZ0I7SUFDdEIsTUFBTSxFQUFFLGVBQWU7SUFDdkIsTUFBTSxFQUFFLGdCQUFnQjtJQUN4QixFQUFFLEVBQUUsYUFBYTtDQUNsQixDQUFDO0FBRUYsU0FBUyxrQkFBa0IsQ0FBQyxPQUEyQjtJQUNyRCxJQUFJLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO0lBQ3RDLElBQUksU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7SUFDbEMsSUFBSSxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDMUIsSUFBSSxPQUFPLENBQUMsV0FBVyxJQUFJLE9BQU8sQ0FBQyxXQUFXLEtBQUssT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3pFLE1BQU0sSUFBSSxLQUFLLENBQ2IsZ0ZBQWdGLENBQ2pGLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxPQUFPLENBQUMsU0FBUyxJQUFJLE9BQU8sQ0FBQyxTQUFTLEtBQUssT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3JFLE1BQU0sSUFBSSxLQUFLLENBQ2IsK0VBQStFLENBQ2hGLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO1lBQzVDLFdBQVcsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDO1FBQ3RDLENBQUM7YUFBTSxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7WUFDakQsU0FBUyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7UUFDcEMsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLElBQUksS0FBSyxDQUNiLDJEQUEyRCxPQUFPLENBQUMsYUFBYSxFQUFFLENBQ25GLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLENBQUM7QUFDcEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRhc2sgfSBmcm9tIFwiLi5cIjtcbmltcG9ydCB7IEpzaWlQYWNtYWtUYXJnZXQsIEpTSUlfVE9PTENIQUlOIH0gZnJvbSBcIi4vY29uc3RzXCI7XG5pbXBvcnQgeyBKc2lpRG9jZ2VuIH0gZnJvbSBcIi4vanNpaS1kb2NnZW5cIjtcbmltcG9ydCB7XG4gIFBVTExfUkVRVUVTVF9SRUYsXG4gIFBVTExfUkVRVUVTVF9SRVBPU0lUT1JZLFxufSBmcm9tIFwiLi4vYnVpbGQvcHJpdmF0ZS9jb25zdHNcIjtcbmltcG9ydCB7IFdvcmtmbG93U3RlcHMgfSBmcm9tIFwiLi4vZ2l0aHViL3dvcmtmbG93LXN0ZXBzXCI7XG5pbXBvcnQgeyBKb2IsIEpvYlBlcm1pc3Npb24sIFN0ZXAsIFRvb2xzIH0gZnJvbSBcIi4uL2dpdGh1Yi93b3JrZmxvd3MtbW9kZWxcIjtcbmltcG9ydCB7IE5vZGVQYWNrYWdlTWFuYWdlciB9IGZyb20gXCIuLi9qYXZhc2NyaXB0XCI7XG5pbXBvcnQge1xuICBDb21tb25QdWJsaXNoT3B0aW9ucyxcbiAgR29QdWJsaXNoT3B0aW9ucyxcbiAgTWF2ZW5QdWJsaXNoT3B0aW9ucyxcbiAgTnBtUHVibGlzaE9wdGlvbnMsXG4gIE51Z2V0UHVibGlzaE9wdGlvbnMsXG4gIFB1Ymxpc2hlcixcbiAgUHlQaVB1Ymxpc2hPcHRpb25zLFxufSBmcm9tIFwiLi4vcmVsZWFzZVwiO1xuaW1wb3J0IHsgZmlsdGVyZWRSdW5zT25PcHRpb25zIH0gZnJvbSBcIi4uL3J1bm5lci1vcHRpb25zXCI7XG5pbXBvcnQgeyBUeXBlU2NyaXB0UHJvamVjdCwgVHlwZVNjcmlwdFByb2plY3RPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzY3JpcHRcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSB9IGZyb20gXCIuLi91dGlsXCI7XG5cbmNvbnN0IEVNQUlMX1JFR0VYID0gL15bXlxcc0BdK0BbXlxcc0BdKyQvO1xuY29uc3QgVVJMX1JFR0VYID1cbiAgLygoKFtBLVphLXpdezMsOX06KD86XFwvXFwvKT8pKD86W1xcLTs6Jj1cXCtcXCQsXFx3XStAKT9bQS1aYS16MC05XFwuXFwtXSt8KD86d3d3XFwufFtcXC07OiY9XFwrXFwkLFxcd10rQClbQS1aYS16MC05XFwuXFwtXSspKCg/OlxcL1tcXCt+JVxcL1xcLlxcd1xcLV9dKik/XFw/Pyg/OltcXC1cXCs9JjslQFxcLlxcd19dKikjPyg/OltcXC5cXCFcXC9cXFxcXFx3XSopKT8pLztcblxuY29uc3QgUkVQT19URU1QX0RJUkVDVE9SWSA9IFwiLnJlcG9cIjtcbmNvbnN0IEJVSUxEX0FSVElGQUNUX09MRF9ESVIgPSBcImRpc3Qub2xkXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSnNpaVByb2plY3RPcHRpb25zIGV4dGVuZHMgVHlwZVNjcmlwdFByb2plY3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIEBkZWZhdWx0IFwiLlwiXG4gICAqL1xuICByZWFkb25seSByb290ZGlyPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBHaXQgcmVwb3NpdG9yeSBVUkwuXG4gICAqIEBkZWZhdWx0ICRHSVRfUkVNT1RFXG4gICAqL1xuICByZWFkb25seSByZXBvc2l0b3J5VXJsOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBsaWJyYXJ5IGF1dGhvci5cbiAgICogQGRlZmF1bHQgJEdJVF9VU0VSX05BTUVcbiAgICovXG4gIHJlYWRvbmx5IGF1dGhvcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFbWFpbCBvciBVUkwgb2YgdGhlIGxpYnJhcnkgYXV0aG9yLlxuICAgKiBAZGVmYXVsdCAkR0lUX1VTRVJfRU1BSUxcbiAgICovXG4gIHJlYWRvbmx5IGF1dGhvckFkZHJlc3M6IHN0cmluZztcblxuICAvKipcbiAgICogUHVibGlzaCB0byBtYXZlblxuICAgKiBAZGVmYXVsdCAtIG5vIHB1Ymxpc2hpbmdcbiAgICovXG4gIHJlYWRvbmx5IHB1Ymxpc2hUb01hdmVuPzogSnNpaUphdmFUYXJnZXQ7XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2ggdG8gcHlwaVxuICAgKiBAZGVmYXVsdCAtIG5vIHB1Ymxpc2hpbmdcbiAgICovXG4gIHJlYWRvbmx5IHB1Ymxpc2hUb1B5cGk/OiBKc2lpUHl0aG9uVGFyZ2V0O1xuXG4gIC8qKlxuICAgKiBQdWJsaXNoIEdvIGJpbmRpbmdzIHRvIGEgZ2l0IHJlcG9zaXRvcnkuXG4gICAqIEBkZWZhdWx0IC0gbm8gcHVibGlzaGluZ1xuICAgKi9cbiAgcmVhZG9ubHkgcHVibGlzaFRvR28/OiBKc2lpR29UYXJnZXQ7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBgcHVibGlzaFRvUHlQaWBcbiAgICovXG4gIHJlYWRvbmx5IHB5dGhvbj86IEpzaWlQeXRob25UYXJnZXQ7XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2ggdG8gTnVHZXRcbiAgICogQGRlZmF1bHQgLSBubyBwdWJsaXNoaW5nXG4gICAqL1xuICByZWFkb25seSBwdWJsaXNoVG9OdWdldD86IEpzaWlEb3ROZXRUYXJnZXQ7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBgcHVibGlzaFRvTnVnZXRgXG4gICAqL1xuICByZWFkb25seSBkb3RuZXQ/OiBKc2lpRG90TmV0VGFyZ2V0O1xuXG4gIC8qKlxuICAgKiBBdXRvbWF0aWNhbGx5IHJ1biBBUEkgY29tcGF0aWJpbGl0eSB0ZXN0IGFnYWluc3QgdGhlIGxhdGVzdCB2ZXJzaW9uIHB1Ymxpc2hlZCB0byBucG0gYWZ0ZXIgY29tcGlsYXRpb24uXG4gICAqXG4gICAqIC0gWW91IGNhbiBtYW51YWxseSBydW4gY29tcGF0aWJpbGl0eSB0ZXN0cyB1c2luZyBgeWFybiBjb21wYXRgIGlmIHRoaXMgZmVhdHVyZSBpcyBkaXNhYmxlZC5cbiAgICogLSBZb3UgY2FuIGlnbm9yZSBjb21wYXRpYmlsaXR5IGZhaWx1cmVzIGJ5IGFkZGluZyBsaW5lcyB0byBhIFwiLmNvbXBhdGlnbm9yZVwiIGZpbGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBjb21wYXQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBpZ25vcmUgZmlsZSBmb3IgQVBJIGNvbXBhdGliaWxpdHkgdGVzdHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwiLmNvbXBhdGlnbm9yZVwiXG4gICAqL1xuICByZWFkb25seSBjb21wYXRJZ25vcmU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFjY2VwdHMgYSBsaXN0IG9mIGdsb2IgcGF0dGVybnMuIEZpbGVzIG1hdGNoaW5nIGFueSBvZiB0aG9zZSBwYXR0ZXJucyB3aWxsIGJlIGV4Y2x1ZGVkIGZyb20gdGhlIFR5cGVTY3JpcHQgY29tcGlsZXIgaW5wdXQuXG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIGpzaWkgd2lsbCBpbmNsdWRlIGFsbCAqLnRzIGZpbGVzIChleGNlcHQgLmQudHMgZmlsZXMpIGluIHRoZSBUeXBlU2NyaXB0IGNvbXBpbGVyIGlucHV0LlxuICAgKiBUaGlzIGNhbiBiZSBwcm9ibGVtYXRpYyBmb3IgZXhhbXBsZSB3aGVuIHRoZSBwYWNrYWdlJ3MgYnVpbGQgb3IgdGVzdCBwcm9jZWR1cmUgZ2VuZXJhdGVzIC50cyBmaWxlc1xuICAgKiB0aGF0IGNhbm5vdCBiZSBjb21waWxlZCB3aXRoIGpzaWkncyBjb21waWxlciBzZXR0aW5ncy5cbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGVUeXBlc2NyaXB0Pzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEZpbGUgcGF0aCBmb3IgZ2VuZXJhdGVkIGRvY3MuXG4gICAqIEBkZWZhdWx0IFwiQVBJLm1kXCJcbiAgICovXG4gIHJlYWRvbmx5IGRvY2dlbkZpbGVQYXRoPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFbWl0IGEgY29tcHJlc3NlZCB2ZXJzaW9uIG9mIHRoZSBhc3NlbWJseVxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgY29tcHJlc3NBc3NlbWJseT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFZlcnNpb24gb2YgdGhlIGpzaWkgY29tcGlsZXIgdG8gdXNlLlxuICAgKlxuICAgKiBTZXQgdG8gXCIqXCIgaWYgeW91IHdhbnQgdG8gbWFudWFsbHkgbWFuYWdlIHRoZSB2ZXJzaW9uIG9mIGpzaWkgaW4geW91clxuICAgKiBwcm9qZWN0IGJ5IG1hbmFnaW5nIHVwZGF0ZXMgdG8gYHBhY2thZ2UuanNvbmAgb24geW91ciBvd24uXG4gICAqXG4gICAqIE5PVEU6IFRoZSBqc2lpIGNvbXBpbGVyIHJlbGVhc2VzIHNpbmNlIDUuMC4wIGFyZSBub3Qgc2VtYW50aWNhbGx5IHZlcnNpb25lZFxuICAgKiBhbmQgc2hvdWxkIHJlbWFpbiBvbiB0aGUgc2FtZSBtaW5vciwgc28gd2UgcmVjb21tZW5kIHVzaW5nIGEgYH5gIGRlcGVuZGVuY3lcbiAgICogKGUuZy4gYH41LjAuMGApLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIn41LjkuMFwiXG4gICAqIEBwam5ldyBcIn41LjkuMFwiXG4gICAqL1xuICByZWFkb25seSBqc2lpVmVyc2lvbj86IHN0cmluZztcbn1cblxuZXhwb3J0IGVudW0gU3RhYmlsaXR5IHtcbiAgRVhQRVJJTUVOVEFMID0gXCJleHBlcmltZW50YWxcIixcbiAgU1RBQkxFID0gXCJzdGFibGVcIixcbiAgREVQUkVDQVRFRCA9IFwiZGVwcmVjYXRlZFwiLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEpzaWlKYXZhVGFyZ2V0IGV4dGVuZHMgTWF2ZW5QdWJsaXNoT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGphdmFQYWNrYWdlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1hdmVuR3JvdXBJZDogc3RyaW5nO1xuICByZWFkb25seSBtYXZlbkFydGlmYWN0SWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBKc2lpUHl0aG9uVGFyZ2V0IGV4dGVuZHMgUHlQaVB1Ymxpc2hPcHRpb25zIHtcbiAgcmVhZG9ubHkgZGlzdE5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgbW9kdWxlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSnNpaURvdE5ldFRhcmdldCBleHRlbmRzIE51Z2V0UHVibGlzaE9wdGlvbnMge1xuICByZWFkb25seSBkb3ROZXROYW1lc3BhY2U6IHN0cmluZztcbiAgcmVhZG9ubHkgcGFja2FnZUlkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGljb25Vcmw/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogR28gdGFyZ2V0IGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBKc2lpR29UYXJnZXQgZXh0ZW5kcyBHb1B1Ymxpc2hPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgcmVwb3NpdG9yeSBpbiB3aGljaCB0aGlzIG1vZHVsZSB3aWxsIGJlIHB1Ymxpc2hlZCAoZS5nLiBnaXRodWIuY29tL293bmVyL3JlcG8pLlxuICAgKlxuICAgKiBUaGUgbW9kdWxlIGl0c2VsZiB3aWxsIGFsd2F5cyBiZSBwdWJsaXNoZWQgdW5kZXIgYSBzdWJkaXJlY3RvcnkgbmFtZWQgYWNjb3JkaW5nXG4gICAqIHRvIHRoZSBgcGFja2FnZU5hbWVgIG9mIHRoZSBtb2R1bGUgKGUuZy4gZ2l0aHViLmNvbS9mb28vYmFyL3BrZykuXG4gICAqXG4gICAqIEBleGFtcGxlIGdpdGh1Yi5jb20vb3duZXIvcmVwb1xuICAgKi9cbiAgcmVhZG9ubHkgbW9kdWxlTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgR28gcGFja2FnZSBuYW1lLlxuICAgKlxuICAgKiBJZiBub3Qgc3BlY2lmaWVkLCBwYWNrYWdlIG5hbWUgd2lsbCBiZSBkZXJpdmVkIGZyb20gdGhlIEphdmFTY3JpcHQgbW9kdWxlIG5hbWVcbiAgICogYnkgcmVtb3Zpbmcgbm9uLWFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIChlLmcuIEBwcm9qZW4vZm9vLWJhciB3aWxsIGJlIHByb2plbmZvb2JhcikuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZGVyaXZlZCBmcm9tIHRoZSBKYXZhU2NyaXB0IG1vZHVsZSBuYW1lXG4gICAqL1xuICByZWFkb25seSBwYWNrYWdlTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogQSBzdWZmaXggYXBwZW5kZWQgYXQgdGhlIGVuZCBvZiB0aGUgbW9kdWxlIHZlcnNpb24gKGUuZyBgXCItZGV2cHJlZml4XCJgKS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uU3VmZml4Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE11bHRpLWxhbmd1YWdlIGpzaWkgbGlicmFyeSBwcm9qZWN0XG4gKlxuICogQHBqaWQganNpaVxuICovXG5leHBvcnQgY2xhc3MgSnNpaVByb2plY3QgZXh0ZW5kcyBUeXBlU2NyaXB0UHJvamVjdCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGFja2FnZUFsbFRhc2s6IFRhc2s7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGFja2FnZUpzVGFzazogVGFzaztcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBKc2lpUHJvamVjdE9wdGlvbnMpIHtcbiAgICBjb25zdCB7IGF1dGhvckVtYWlsLCBhdXRob3JVcmwgfSA9IHBhcnNlQXV0aG9yQWRkcmVzcyhvcHRpb25zKTtcblxuICAgIGNvbnN0IGpzaWlWZXJzaW9uID0gb3B0aW9ucy5qc2lpVmVyc2lvbiA/PyBcIn41LjkuMFwiO1xuXG4gICAgY29uc3QgZGVmYXVsdE9wdGlvbnM6IFBhcnRpYWw8VHlwZVNjcmlwdFByb2plY3RPcHRpb25zPiA9IHtcbiAgICAgIHJlcG9zaXRvcnk6IG9wdGlvbnMucmVwb3NpdG9yeVVybCxcbiAgICAgIGF1dGhvck5hbWU6IG9wdGlvbnMuYXV0aG9yLFxuICAgICAgYXV0aG9yRW1haWwsXG4gICAgICBhdXRob3JVcmwsXG4gICAgfTtcblxuICAgIGNvbnN0IGZvcmNlZE9wdGlvbnMgPSB7XG4gICAgICByZWxlYXNlVG9OcG06IGZhbHNlLCAvLyB3ZSBoYXZlIGEganNpaSByZWxlYXNlIHdvcmtmbG93XG4gICAgICBkaXNhYmxlVHNjb25maWc6IHRydWUsIC8vIGpzaWkgZ2VuZXJhdGVzIGl0cyBvd24gdHNjb25maWcuanNvblxuICAgICAgZG9jZ2VuOiBmYWxzZSwgLy8gd2UgdXNlIGpzaWktZG9jZ2VuIGhlcmUgc28gZGlzYWJsZSB0eXBlc2NyaXB0IGRvY2dlblxuICAgIH07XG5cbiAgICBjb25zdCBtZXJnZWRPcHRpb25zID0gZGVlcE1lcmdlKFtcbiAgICAgIGRlZmF1bHRPcHRpb25zLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIGZvcmNlZE9wdGlvbnMsXG4gICAgXSkgYXMgVHlwZVNjcmlwdFByb2plY3RPcHRpb25zO1xuXG4gICAgc3VwZXIobWVyZ2VkT3B0aW9ucyk7XG5cbiAgICBjb25zdCBzcmNkaXIgPSB0aGlzLnNyY2RpcjtcbiAgICBjb25zdCBsaWJkaXIgPSB0aGlzLmxpYmRpcjtcblxuICAgIHRoaXMuYWRkRmllbGRzKHsgdHlwZXM6IGAke2xpYmRpcn0vaW5kZXguZC50c2AgfSk7XG5cbiAgICBjb25zdCBjb21wcmVzc0Fzc2VtYmx5ID0gb3B0aW9ucy5jb21wcmVzc0Fzc2VtYmx5ID8/IGZhbHNlO1xuXG4gICAgLy8gdGhpcyBpcyBhbiB1bmhlbHBmdWwgd2FybmluZ1xuICAgIGNvbnN0IGpzaWlGbGFncyA9IFtcIi0tc2lsZW5jZS13YXJuaW5ncz1yZXNlcnZlZC13b3JkXCJdO1xuICAgIGlmIChjb21wcmVzc0Fzc2VtYmx5KSB7XG4gICAgICBqc2lpRmxhZ3MucHVzaChcIi0tY29tcHJlc3MtYXNzZW1ibHlcIik7XG4gICAgfVxuXG4gICAgY29uc3QgY29tcGF0SWdub3JlID0gb3B0aW9ucy5jb21wYXRJZ25vcmUgPz8gXCIuY29tcGF0aWdub3JlXCI7XG5cbiAgICB0aGlzLmFkZEZpZWxkcyh7IHN0YWJpbGl0eTogb3B0aW9ucy5zdGFiaWxpdHkgPz8gU3RhYmlsaXR5LlNUQUJMRSB9KTtcblxuICAgIGlmIChvcHRpb25zLnN0YWJpbGl0eSA9PT0gU3RhYmlsaXR5LkRFUFJFQ0FURUQpIHtcbiAgICAgIHRoaXMuYWRkRmllbGRzKHsgZGVwcmVjYXRlZDogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBjb21wYXRUYXNrID0gdGhpcy5hZGRUYXNrKFwiY29tcGF0XCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlBlcmZvcm0gQVBJIGNvbXBhdGliaWxpdHkgY2hlY2sgYWdhaW5zdCBsYXRlc3QgdmVyc2lvblwiLFxuICAgICAgZXhlYzogYGpzaWktZGlmZiBucG06JChub2RlIC1wIFwicmVxdWlyZShcXCcuL3BhY2thZ2UuanNvblxcJykubmFtZVwiKSAtayAtLWlnbm9yZS1maWxlICR7Y29tcGF0SWdub3JlfSB8fCAoZWNobyBcIlxcblVORVhQRUNURUQgQlJFQUtJTkcgQ0hBTkdFUzogYWRkIGtleXMgc3VjaCBhcyBcXCdyZW1vdmVkOmNvbnN0cnVjdHMuTm9kZS5vZlxcJyB0byAke2NvbXBhdElnbm9yZX0gdG8gc2tpcC5cXG5cIiAmJiBleGl0IDEpYCxcbiAgICB9KTtcblxuICAgIGNvbnN0IGNvbXBhdCA9IG9wdGlvbnMuY29tcGF0ID8/IGZhbHNlO1xuICAgIGlmIChjb21wYXQpIHtcbiAgICAgIHRoaXMuY29tcGlsZVRhc2suc3Bhd24oY29tcGF0VGFzayk7XG4gICAgfVxuXG4gICAgdGhpcy5jb21waWxlVGFzay5yZXNldChbXCJqc2lpXCIsIC4uLmpzaWlGbGFnc10uam9pbihcIiBcIikpO1xuICAgIHRoaXMud2F0Y2hUYXNrLnJlc2V0KFtcImpzaWlcIiwgXCItd1wiLCAuLi5qc2lpRmxhZ3NdLmpvaW4oXCIgXCIpKTtcblxuICAgIC8vIENyZWF0ZSBhIG5ldyBwYWNrYWdlOmFsbCB0YXNrLCBpdCB3aWxsIGJlIGZpbGxlZCB3aXRoIGxhbmd1YWdlIHRhcmdldHMgbGF0ZXJcbiAgICB0aGlzLnBhY2thZ2VBbGxUYXNrID0gdGhpcy5hZGRUYXNrKFwicGFja2FnZS1hbGxcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiUGFja2FnZXMgYXJ0aWZhY3RzIGZvciBhbGwgdGFyZ2V0IGxhbmd1YWdlc1wiLFxuICAgIH0pO1xuXG4gICAgLy8gaW4ganNpaSB3ZSBjb25zaWRlciB0aGUgZW50aXJlIHJlcG8gKHBvc3QgYnVpbGQpIGFzIHRoZSBidWlsZCBhcnRpZmFjdFxuICAgIC8vIHdoaWNoIGlzIHRoZW4gdXNlZCB0byBjcmVhdGUgdGhlIGxhbmd1YWdlIGJpbmRpbmdzIGluIHNlcGFyYXRlIGpvYnMuXG4gICAgLy8gd2UgYWNoaWV2ZSB0aGlzIGJ5IGRvaW5nIGEgY2hlY2tvdXQgYW5kIG92ZXJ3cml0ZSB3aXRoIHRoZSBmaWxlcyBmcm9tIHRoZSBqcyBwYWNrYWdlLlxuICAgIHRoaXMucGFja2FnZUpzVGFzayA9IHRoaXMuYWRkUGFja2FnaW5nVGFzayhcImpzXCIpO1xuXG4gICAgLy8gV2hlbiBydW5uaW5nIGluc2lkZSBDSSB3ZSBpbml0aWFsbHkgb25seSBwYWNrYWdlIGpzLiBPdGhlciB0YXJnZXRzIGFyZSBwYWNrYWdlZCBpbiBzZXBhcmF0ZSBqb2JzLlxuICAgIC8vIE91dHNpZGUgb2YgQ0kgKGkuZSBsb2NhbGx5KSB3ZSBzaW1wbHkgcGFja2FnZSBhbGwgdGFyZ2V0cy5cbiAgICB0aGlzLnBhY2thZ2VUYXNrLnJlc2V0KCk7XG4gICAgdGhpcy5wYWNrYWdlVGFzay5zcGF3bih0aGlzLnBhY2thZ2VKc1Rhc2ssIHtcbiAgICAgIC8vIE9ubHkgcnVuIGluIENJXG4gICAgICBjb25kaXRpb246IGBub2RlIC1lIFwiaWYgKCFwcm9jZXNzLmVudi5DSSkgcHJvY2Vzcy5leGl0KDEpXCJgLFxuICAgIH0pO1xuICAgIHRoaXMucGFja2FnZVRhc2suc3Bhd24odGhpcy5wYWNrYWdlQWxsVGFzaywge1xuICAgICAgLy8gRG9uJ3QgcnVuIGluIENJXG4gICAgICBjb25kaXRpb246IGBub2RlIC1lIFwiaWYgKHByb2Nlc3MuZW52LkNJKSBwcm9jZXNzLmV4aXQoMSlcImAsXG4gICAgfSk7XG5cbiAgICBjb25zdCB0YXJnZXRzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG5cbiAgICBjb25zdCBqc2lpOiBhbnkgPSB7XG4gICAgICBvdXRkaXI6IHRoaXMuYXJ0aWZhY3RzRGlyZWN0b3J5LFxuICAgICAgdGFyZ2V0cyxcbiAgICAgIHRzYzoge1xuICAgICAgICBvdXREaXI6IGxpYmRpcixcbiAgICAgICAgcm9vdERpcjogc3JjZGlyLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgaWYgKG9wdGlvbnMuZXhjbHVkZVR5cGVzY3JpcHQpIHtcbiAgICAgIGpzaWkuZXhjbHVkZVR5cGVzY3JpcHQgPSBvcHRpb25zLmV4Y2x1ZGVUeXBlc2NyaXB0O1xuICAgIH1cblxuICAgIHRoaXMuYWRkRmllbGRzKHsganNpaSB9KTtcblxuICAgIGNvbnN0IGV4dHJhSm9iT3B0aW9uczogUGFydGlhbDxKb2I+ID0ge1xuICAgICAgLi4udGhpcy5nZXRKb2JSdW5zT25Db25maWcob3B0aW9ucyksXG4gICAgICAuLi4ob3B0aW9ucy53b3JrZmxvd0NvbnRhaW5lckltYWdlXG4gICAgICAgID8geyBjb250YWluZXI6IHsgaW1hZ2U6IG9wdGlvbnMud29ya2Zsb3dDb250YWluZXJJbWFnZSB9IH1cbiAgICAgICAgOiB7fSksXG4gICAgfTtcblxuICAgIGlmIChvcHRpb25zLnJlbGVhc2VUb05wbSAhPSBmYWxzZSkge1xuICAgICAgY29uc3QgbnBtanM6IE5wbVB1Ymxpc2hPcHRpb25zID0ge1xuICAgICAgICByZWdpc3RyeTogdGhpcy5wYWNrYWdlLm5wbVJlZ2lzdHJ5LFxuICAgICAgICBucG1Ub2tlblNlY3JldDogdGhpcy5wYWNrYWdlLm5wbVRva2VuU2VjcmV0LFxuICAgICAgICBucG1Qcm92ZW5hbmNlOiB0aGlzLnBhY2thZ2UubnBtUHJvdmVuYW5jZSxcbiAgICAgICAgY29kZUFydGlmYWN0T3B0aW9uczogb3B0aW9ucy5jb2RlQXJ0aWZhY3RPcHRpb25zLFxuICAgICAgICB0cnVzdGVkUHVibGlzaGluZzogb3B0aW9ucy5ucG1UcnVzdGVkUHVibGlzaGluZyA/PyBmYWxzZSxcbiAgICAgIH07XG4gICAgICB0aGlzLmFkZFRhcmdldFRvQnVpbGQoXCJqc1wiLCB0aGlzLnBhY2thZ2VKc1Rhc2ssIGV4dHJhSm9iT3B0aW9ucyk7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvUmVsZWFzZShcImpzXCIsIHRoaXMucGFja2FnZUpzVGFzaywgbnBtanMpO1xuICAgIH1cblxuICAgIC8vIHdlIGNhbm5vdCBjYWxsIGFuIG9wdGlvbiBgamF2YWAgYmVjYXVzZSB0aGUgamF2YSBjb2RlIGdlbmVyYXRlZCBieSBqc2lpXG4gICAgLy8gZG9lcyBub3QgY29tcGlsZSBkdWUgdG8gYSBjb25mbGljdCBiZXR3ZWVuIHRoaXMgb3B0aW9uIG5hbWUgYW5kIHRoZSBgamF2YWBcbiAgICAvLyBwYWNrYWdlIChlLmcuIHdoZW4gYGphdmEudXRpbC5PYmplY3RzYCBpcyByZWZlcmVuY2VkKS5cbiAgICBpZiAoXCJqYXZhXCIgaW4gb3B0aW9ucykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgXCJqYXZhXCIgb3B0aW9uIGlzIG5vdyBjYWxsZWQgXCJwdWJsaXNoVG9NYXZlblwiJyk7XG4gICAgfVxuXG4gICAgY29uc3QgbWF2ZW4gPSBvcHRpb25zLnB1Ymxpc2hUb01hdmVuO1xuICAgIGlmIChtYXZlbikge1xuICAgICAgdGFyZ2V0cy5qYXZhID0ge1xuICAgICAgICBwYWNrYWdlOiBtYXZlbi5qYXZhUGFja2FnZSxcbiAgICAgICAgbWF2ZW46IHtcbiAgICAgICAgICBncm91cElkOiBtYXZlbi5tYXZlbkdyb3VwSWQsXG4gICAgICAgICAgYXJ0aWZhY3RJZDogbWF2ZW4ubWF2ZW5BcnRpZmFjdElkLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdGFzayA9IHRoaXMuYWRkUGFja2FnaW5nVGFzayhcImphdmFcIik7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvQnVpbGQoXCJqYXZhXCIsIHRhc2ssIGV4dHJhSm9iT3B0aW9ucyk7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvUmVsZWFzZShcImphdmFcIiwgdGFzaywgbWF2ZW4pO1xuICAgIH1cblxuICAgIGNvbnN0IHB5cGkgPSBvcHRpb25zLnB1Ymxpc2hUb1B5cGkgPz8gb3B0aW9ucy5weXRob247XG4gICAgaWYgKHB5cGkpIHtcbiAgICAgIHRhcmdldHMucHl0aG9uID0ge1xuICAgICAgICBkaXN0TmFtZTogcHlwaS5kaXN0TmFtZSxcbiAgICAgICAgbW9kdWxlOiBweXBpLm1vZHVsZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHRhc2sgPSB0aGlzLmFkZFBhY2thZ2luZ1Rhc2soXCJweXRob25cIik7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvQnVpbGQoXCJweXRob25cIiwgdGFzaywgZXh0cmFKb2JPcHRpb25zKTtcbiAgICAgIHRoaXMuYWRkVGFyZ2V0VG9SZWxlYXNlKFwicHl0aG9uXCIsIHRhc2ssIHB5cGkpO1xuICAgIH1cblxuICAgIGNvbnN0IG51Z2V0ID0gb3B0aW9ucy5wdWJsaXNoVG9OdWdldCA/PyBvcHRpb25zLmRvdG5ldDtcbiAgICBpZiAobnVnZXQpIHtcbiAgICAgIHRhcmdldHMuZG90bmV0ID0ge1xuICAgICAgICBuYW1lc3BhY2U6IG51Z2V0LmRvdE5ldE5hbWVzcGFjZSxcbiAgICAgICAgcGFja2FnZUlkOiBudWdldC5wYWNrYWdlSWQsXG4gICAgICAgIGljb25Vcmw6IG51Z2V0Lmljb25VcmwsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0YXNrID0gdGhpcy5hZGRQYWNrYWdpbmdUYXNrKFwiZG90bmV0XCIpO1xuICAgICAgdGhpcy5hZGRUYXJnZXRUb0J1aWxkKFwiZG90bmV0XCIsIHRhc2ssIGV4dHJhSm9iT3B0aW9ucyk7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvUmVsZWFzZShcImRvdG5ldFwiLCB0YXNrLCBudWdldCk7XG4gICAgfVxuXG4gICAgY29uc3QgZ29sYW5nID0gb3B0aW9ucy5wdWJsaXNoVG9HbztcbiAgICBpZiAoZ29sYW5nKSB7XG4gICAgICB0YXJnZXRzLmdvID0ge1xuICAgICAgICBtb2R1bGVOYW1lOiBnb2xhbmcubW9kdWxlTmFtZSxcbiAgICAgICAgcGFja2FnZU5hbWU6IGdvbGFuZy5wYWNrYWdlTmFtZSxcbiAgICAgICAgdmVyc2lvblN1ZmZpeDogZ29sYW5nLnZlcnNpb25TdWZmaXgsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0YXNrID0gdGhpcy5hZGRQYWNrYWdpbmdUYXNrKFwiZ29cIik7XG4gICAgICB0aGlzLmFkZFRhcmdldFRvQnVpbGQoXCJnb1wiLCB0YXNrLCBleHRyYUpvYk9wdGlvbnMpO1xuICAgICAgdGhpcy5hZGRUYXJnZXRUb1JlbGVhc2UoXCJnb1wiLCB0YXNrLCBnb2xhbmcpO1xuICAgIH1cblxuICAgIC8vIElmIGpzaWlWZXJzaW9uIGlzIFwiKlwiLCBkb24ndCBzcGVjaWZ5IGFueXRoaW5nIHNvIHRoZSB1c2VyIGNhbiBtYW5hZ2UuXG4gICAgLy8gT3RoZXJ3aXNlLCB1c2UgYGpzaWlWZXJzaW9uYFxuICAgIGNvbnN0IGpzaWlTdWZmaXggPSBqc2lpVmVyc2lvbiA9PT0gXCIqXCIgPyBcIlwiIDogYEAke2pzaWlWZXJzaW9ufWA7XG4gICAgdGhpcy5hZGREZXZEZXBzKFxuICAgICAgYGpzaWkke2pzaWlTdWZmaXh9YCxcbiAgICAgIGBqc2lpLXJvc2V0dGEke2pzaWlTdWZmaXh9YCxcbiAgICAgIFwianNpaS1kaWZmXCIsXG4gICAgICBcImpzaWktcGFjbWFrXCIsXG4gICAgKTtcblxuICAgIHRoaXMuZ2l0aWdub3JlLmV4Y2x1ZGUoXCIuanNpaVwiLCBcInRzY29uZmlnLmpzb25cIik7XG4gICAgdGhpcy5ucG1pZ25vcmU/LmluY2x1ZGUoXCIuanNpaVwiKTtcblxuICAgIGlmIChvcHRpb25zLmRvY2dlbiA/PyB0cnVlKSB7XG4gICAgICAvLyBJZiBqc2lpVmVyc2lvbiBpcyBcIipcIiwgZG9uJ3Qgc3BlY2lmeSBhbnl0aGluZyBzbyB0aGUgdXNlciBjYW4gbWFuYWdlLlxuICAgICAgLy8gT3RoZXJ3aXNlIHVzZSBhIHZlcnNpb24gdGhhdCBpcyBjb21wYXRpYmxlIHdpdGggYWxsIHN1cHBvcnRlZCBqc2lpIHJlbGVhc2VzLlxuICAgICAgY29uc3QgZG9jZ2VuVmVyc2lvbiA9IG9wdGlvbnMuanNpaVZlcnNpb24gPT09IFwiKlwiID8gXCIqXCIgOiBcIl4xMC41LjBcIjtcbiAgICAgIG5ldyBKc2lpRG9jZ2VuKHRoaXMsIHtcbiAgICAgICAgdmVyc2lvbjogZG9jZ2VuVmVyc2lvbixcbiAgICAgICAgZmlsZVBhdGg6IG9wdGlvbnMuZG9jZ2VuRmlsZVBhdGgsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBqc2lpIHVwZGF0ZXMgLm5wbWlnbm9yZSwgc28gd2UgbWFrZSBpdCB3cml0YWJsZVxuICAgIGlmICh0aGlzLm5wbWlnbm9yZSkge1xuICAgICAgdGhpcy5ucG1pZ25vcmUucmVhZG9ubHkgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHRhcmdldCBsYW5ndWFnZSB0byB0aGUgcmVsZWFzZSB3b3JrZmxvdy5cbiAgICogQHBhcmFtIGxhbmd1YWdlXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBwcml2YXRlIGFkZFRhcmdldFRvUmVsZWFzZShcbiAgICBsYW5ndWFnZTogSnNpaVBhY21ha1RhcmdldCxcbiAgICBwYWNrVGFzazogVGFzayxcbiAgICB0YXJnZXQ6XG4gICAgICB8IEpzaWlQeXRob25UYXJnZXRcbiAgICAgIHwgSnNpaURvdE5ldFRhcmdldFxuICAgICAgfCBKc2lpR29UYXJnZXRcbiAgICAgIHwgSnNpaUphdmFUYXJnZXRcbiAgICAgIHwgTnBtUHVibGlzaE9wdGlvbnMsXG4gICkge1xuICAgIGlmICghdGhpcy5yZWxlYXNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcGFjbWFrID0gdGhpcy5wYWNtYWtGb3JMYW5ndWFnZShsYW5ndWFnZSwgcGFja1Rhc2spO1xuICAgIGNvbnN0IHByZVB1Ymxpc2hTdGVwcyA9IFtcbiAgICAgIC4uLnBhY21hay5ib290c3RyYXBTdGVwcyxcbiAgICAgIFdvcmtmbG93U3RlcHMuY2hlY2tvdXQoe1xuICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgcGF0aDogUkVQT19URU1QX0RJUkVDVE9SWSxcbiAgICAgICAgICAuLi4odGhpcy5naXRodWI/LmRvd25sb2FkTGZzID8geyBsZnM6IHRydWUgfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgLi4ucGFjbWFrLnBhY2thZ2luZ1N0ZXBzLFxuICAgIF07XG4gICAgY29uc3QgY29tbW9uUHVibGlzaE9wdGlvbnM6IENvbW1vblB1Ymxpc2hPcHRpb25zID0ge1xuICAgICAgcHVibGlzaFRvb2xzOiBwYWNtYWsucHVibGlzaFRvb2xzLFxuICAgICAgcHJlUHVibGlzaFN0ZXBzLFxuICAgIH07XG5cbiAgICBjb25zdCBoYW5kbGVyOiBQdWJsaXNoVG8gPSBwdWJsaXNoVG9bbGFuZ3VhZ2VdO1xuICAgIHRoaXMucmVsZWFzZT8ucHVibGlzaGVyW2hhbmRsZXJdKHtcbiAgICAgIC4uLmNvbW1vblB1Ymxpc2hPcHRpb25zLFxuICAgICAgLi4udGFyZ2V0LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSB0YXJnZXQgbGFuZ3VhZ2UgdG8gdGhlIGJ1aWxkIHdvcmtmbG93XG4gICAqIEBwYXJhbSBsYW5ndWFnZVxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgcHJpdmF0ZSBhZGRUYXJnZXRUb0J1aWxkKFxuICAgIGxhbmd1YWdlOiBKc2lpUGFjbWFrVGFyZ2V0LFxuICAgIHBhY2tUYXNrOiBUYXNrLFxuICAgIGV4dHJhSm9iT3B0aW9uczogUGFydGlhbDxKb2I+LFxuICApIHtcbiAgICBpZiAoIXRoaXMuYnVpbGRXb3JrZmxvdykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwYWNtYWsgPSB0aGlzLnBhY21ha0Zvckxhbmd1YWdlKGxhbmd1YWdlLCBwYWNrVGFzayk7XG5cbiAgICB0aGlzLmJ1aWxkV29ya2Zsb3cuYWRkUG9zdEJ1aWxkSm9iKGBwYWNrYWdlLSR7bGFuZ3VhZ2V9YCwge1xuICAgICAgLi4uZmlsdGVyZWRSdW5zT25PcHRpb25zKFxuICAgICAgICBleHRyYUpvYk9wdGlvbnMucnVuc09uLFxuICAgICAgICBleHRyYUpvYk9wdGlvbnMucnVuc09uR3JvdXAsXG4gICAgICApLFxuICAgICAgcGVybWlzc2lvbnM6IHtcbiAgICAgICAgY29udGVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCxcbiAgICAgIH0sXG4gICAgICB0b29sczoge1xuICAgICAgICBub2RlOiB7IHZlcnNpb246IHRoaXMubm9kZVZlcnNpb24gPz8gXCJsdHMvKlwiIH0sXG4gICAgICAgIC4uLnBhY21hay5wdWJsaXNoVG9vbHMsXG4gICAgICB9LFxuICAgICAgc3RlcHM6IFtcbiAgICAgICAgLi4ucGFjbWFrLmJvb3RzdHJhcFN0ZXBzLFxuICAgICAgICBXb3JrZmxvd1N0ZXBzLmNoZWNrb3V0KHtcbiAgICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgICBwYXRoOiBSRVBPX1RFTVBfRElSRUNUT1JZLFxuICAgICAgICAgICAgcmVmOiBQVUxMX1JFUVVFU1RfUkVGLFxuICAgICAgICAgICAgcmVwb3NpdG9yeTogUFVMTF9SRVFVRVNUX1JFUE9TSVRPUlksXG4gICAgICAgICAgICAuLi4odGhpcy5naXRodWI/LmRvd25sb2FkTGZzID8geyBsZnM6IHRydWUgfSA6IHt9KSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgLi4ucGFjbWFrLnBhY2thZ2luZ1N0ZXBzLFxuICAgICAgXSxcbiAgICAgIC4uLmV4dHJhSm9iT3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkUGFja2FnaW5nVGFzayhsYW5ndWFnZTogSnNpaVBhY21ha1RhcmdldCk6IFRhc2sge1xuICAgIGNvbnN0IHBhY2thZ2VUYXJnZXRUYXNrID0gdGhpcy50YXNrcy5hZGRUYXNrKGBwYWNrYWdlOiR7bGFuZ3VhZ2V9YCwge1xuICAgICAgZGVzY3JpcHRpb246IGBDcmVhdGUgJHtsYW5ndWFnZX0gbGFuZ3VhZ2UgYmluZGluZ3NgLFxuICAgIH0pO1xuICAgIGNvbnN0IGNvbW1hbmRQYXJ0cyA9IFtcImpzaWktcGFjbWFrXCIsIFwiLXZcIl07XG5cbiAgICBpZiAodGhpcy5wYWNrYWdlLnBhY2thZ2VNYW5hZ2VyID09PSBOb2RlUGFja2FnZU1hbmFnZXIuUE5QTSkge1xuICAgICAgY29tbWFuZFBhcnRzLnB1c2goJy0tcGFjay1jb21tYW5kIFwicG5wbSBwYWNrXCInKTtcbiAgICB9XG5cbiAgICBjb21tYW5kUGFydHMucHVzaChgLS10YXJnZXQgJHtsYW5ndWFnZX1gKTtcblxuICAgIHBhY2thZ2VUYXJnZXRUYXNrLmV4ZWMoY2