UNPKG

projen

Version:

CDK for software projects

280 lines • 36.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.PoetryPyproject = exports.Poetry = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const TOML = __importStar(require("@iarna/toml")); const component_1 = require("../component"); const dependencies_1 = require("../dependencies"); const toml_1 = require("../toml"); const util_1 = require("../util"); const pyproject_toml_file_1 = require("./pyproject-toml-file"); const exec_1 = require("../util/exec"); /** * Manage project dependencies, virtual environments, and packaging through the * poetry CLI tool. */ class Poetry extends component_1.Component { static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.python.Poetry", version: "0.103.12" }; /** * Task for updating the lockfile and installing project dependencies. */ installTask; /** * Task for installing dependencies according to the existing lockfile. */ installCiTask; /** * Task for publishing the package to a package repository. */ publishTask; /** * Task for publishing the package to the Test PyPI repository for testing purposes. */ publishTestTask; /** * Path to the Python executable to use. */ pythonExec; /** * Represents the configuration of the `pyproject.toml` file for a Poetry project. * This includes package metadata, dependencies, and Poetry-specific settings. */ pyProject; constructor(project, options) { super(project); this.pythonExec = options.pythonExec ?? "python"; this.installTask = project.addTask("install", { description: "Install dependencies and update lockfile", execArgs: ["poetry", "update"], }); this.installCiTask = project.addTask("install:ci", { description: "Install dependencies with frozen lockfile", steps: [ { execArgs: ["poetry", "check", "--lock"] }, { execArgs: ["poetry", "install"] }, ], }); this.project.tasks.addEnvironment("VIRTUAL_ENV", // Create .venv on the first run if it doesn't already exist "$(poetry env info -p || poetry run poetry env info -p)"); this.project.tasks.addEnvironment("PATH", "$(echo $(poetry env info -p)/bin:$PATH)"); project.packageTask.execArgs(["poetry", "build"]); this.publishTestTask = project.addTask("publish:test", { description: "Uploads the package against a test PyPI endpoint.", execArgs: ["poetry", "publish", "-r", "testpypi"], }); this.publishTask = project.addTask("publish", { description: "Uploads the package to PyPI.", execArgs: ["poetry", "publish"], }); this.pyProject = new PoetryPyproject(project, { name: project.name, version: options.version, description: options.description ?? "", license: options.license, authors: [`${options.authorName} <${options.authorEmail}>`], homepage: options.homepage, classifiers: options.classifiers, ...options.poetryOptions, dependencies: () => this.synthDependencies(), devDependencies: () => this.synthDevDependencies(), }); new toml_1.TomlFile(project, "poetry.toml", { committed: false, obj: { repositories: { testpypi: { url: "https://test.pypi.org/legacy/", }, }, }, }); } synthDependencies() { const dependencies = {}; let pythonDefined = false; for (const pkg of this.project.deps.all) { if (pkg.name === "python") { pythonDefined = true; } if (pkg.type === dependencies_1.DependencyType.RUNTIME) { dependencies[pkg.name] = pkg.version ?? "*"; } } if (!pythonDefined) { // Python version must be defined for poetry projects. Default to ^3.8. dependencies.python = "^3.8"; } return this.permitDepsWithTomlInlineTables(dependencies); } synthDevDependencies() { const dependencies = {}; for (const pkg of this.project.deps.all) { if ([dependencies_1.DependencyType.DEVENV, dependencies_1.DependencyType.TEST].includes(pkg.type)) { dependencies[pkg.name] = pkg.version ?? "*"; } } return this.permitDepsWithTomlInlineTables(dependencies); } /** * Parses dependency values that may include TOML inline tables, converting them into JavaScript objects. * If a dependency value cannot be parsed as a TOML inline table (indicating it is a plain SemVer string), * it is left unchanged. This allows to support the full range of Poetry's dependency specification. * @see https://python-poetry.org/docs/dependency-specification/ * @see https://toml.io/en/v1.0.0#inline-table * * @example * // Given a `dependencies` object like this: * const dependencies = { * "mypackage": "{ version = '1.2.3', extras = ['extra1', 'extra2'] }", * "anotherpackage": "^2.3.4" * }; * // After parsing, the resulting object would be: * { * "mypackage": { * version: "1.2.3", * extras: ["extra1", "extra2"] * }, * "anotherpackage": "^2.3.4" * } * // Note: The value of `anotherpackage` remains unchanged as it is a plain SemVer string. * * @param dependencies An object where each key is a dependency name and each value is a string that might be * either a SemVer string or a TOML inline table string. * @returns A new object where each key is a dependency name and each value is either the original SemVer string * or the parsed JavaScript object representation of the TOML inline table. */ permitDepsWithTomlInlineTables(dependencies) { const parseTomlInlineTable = (dependencyValue) => { try { // Attempt parsing the `dependencyValue` as a TOML inline table return TOML.parse(`dependencyKey = ${dependencyValue}`).dependencyKey; } catch { // If parsing fails, treat the `dependencyValue` as a plain SemVer string return dependencyValue; } }; return Object.fromEntries(Object.entries(dependencies).map(([dependencyKey, dependencyValue]) => { return [dependencyKey, parseTomlInlineTable(dependencyValue)]; })); } /** * Adds a runtime dependency. * * @param spec Format `<module>@<semver>` */ addDependency(spec) { this.project.deps.addDependency(spec, dependencies_1.DependencyType.RUNTIME); } /** * Adds a dev dependency. * * @param spec Format `<module>@<semver>` */ addDevDependency(spec) { this.project.deps.addDependency(spec, dependencies_1.DependencyType.DEVENV); } /** * Initializes the virtual environment if it doesn't exist (called during post-synthesis). */ setupEnvironment() { const result = exec_1.poetry.tryCapture(["--version"], { cwd: this.project.outdir, }); if (!result) { this.project.logger.info("Unable to setup an environment since poetry is not installed. Please install poetry (https://python-poetry.org/docs/) or use a different component for managing environments such as 'venv'."); } let envPath = exec_1.poetry.tryCapture(["env", "info", "-p"], { cwd: this.project.outdir, }); if (!envPath) { this.project.logger.info("Setting up a virtual environment..."); exec_1.poetry.run(["env", "use", this.pythonExec], { cwd: this.project.outdir, }); envPath = exec_1.poetry.tryCapture(["env", "info", "-p"], { cwd: this.project.outdir, }); this.project.logger.info(`Environment successfully created (located in ${envPath}}).`); } } /** * Installs dependencies (called during post-synthesis). */ installDependencies() { this.project.logger.info("Installing dependencies..."); // If the pyproject.toml file has changed, update the lockfile prior to installation if (this.pyProject.file.changed) { this.project.tasks.runTask(this.installTask.name); } else { this.project.tasks.runTask(this.installCiTask.name); } } } exports.Poetry = Poetry; /** * Represents configuration of a pyproject.toml file for a Poetry project. * * @see https://python-poetry.org/docs/pyproject/ */ class PoetryPyproject extends component_1.Component { static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.python.PoetryPyproject", version: "0.103.12" }; file; constructor(scope, options) { super(scope); const { devDependencies, ...poetryConfig } = options; this.file = new pyproject_toml_file_1.PyprojectTomlFile(scope, { tool: { poetry: { ...(0, util_1.decamelizeKeysRecursively)(poetryConfig, { separator: "-" }), group: { dev: { dependencies: devDependencies, }, }, }, }, buildSystem: { requires: ["poetry-core"], buildBackend: "poetry.core.masonry.api", }, }); } } exports.PoetryPyproject = PoetryPyproject; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ldHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3B5dGhvbi9wb2V0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLGtEQUFvQztBQVNwQyw0Q0FBeUM7QUFDekMsa0RBQWlEO0FBR2pELGtDQUFtQztBQUNuQyxrQ0FBb0Q7QUFDcEQsK0RBQTBEO0FBQzFELHVDQUFzQztBQUt0Qzs7O0dBR0c7QUFDSCxNQUFhLE1BQ1gsU0FBUSxxQkFBUzs7SUFHakI7O09BRUc7SUFDYSxXQUFXLENBQU87SUFFbEM7O09BRUc7SUFDYSxhQUFhLENBQU87SUFFcEM7O09BRUc7SUFDYSxXQUFXLENBQU87SUFFbEM7O09BRUc7SUFDYSxlQUFlLENBQU87SUFFdEM7O09BRUc7SUFDYyxVQUFVLENBQVM7SUFFcEM7OztPQUdHO0lBQ2MsU0FBUyxDQUFrQjtJQUU1QyxZQUFZLE9BQWdCLEVBQUUsT0FBc0I7UUFDbEQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxJQUFJLFFBQVEsQ0FBQztRQUVqRCxJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFO1lBQzVDLFdBQVcsRUFBRSwwQ0FBMEM7WUFDdkQsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQztTQUMvQixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFO1lBQ2pELFdBQVcsRUFBRSwyQ0FBMkM7WUFDeEQsS0FBSyxFQUFFO2dCQUNMLEVBQUUsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsRUFBRTtnQkFDM0MsRUFBRSxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLEVBQUU7YUFDcEM7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQy9CLGFBQWE7UUFDYiw0REFBNEQ7UUFDNUQsd0RBQXdELENBQ3pELENBQUM7UUFDRixJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQy9CLE1BQU0sRUFDTix5Q0FBeUMsQ0FDMUMsQ0FBQztRQUVGLE9BQU8sQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFFbEQsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRTtZQUNyRCxXQUFXLEVBQUUsbURBQW1EO1lBQ2hFLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQztTQUNsRCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFO1lBQzVDLFdBQVcsRUFBRSw4QkFBOEI7WUFDM0MsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQztTQUNoQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksZUFBZSxDQUFDLE9BQU8sRUFBRTtZQUM1QyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDbEIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1lBQ3hCLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxJQUFJLEVBQUU7WUFDdEMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1lBQ3hCLE9BQU8sRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLFVBQVUsS0FBSyxPQUFPLENBQUMsV0FBVyxHQUFHLENBQUM7WUFDM0QsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1lBQzFCLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVztZQUNoQyxHQUFHLE9BQU8sQ0FBQyxhQUFhO1lBQ3hCLFlBQVksRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDNUMsZUFBZSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtTQUNuRCxDQUFDLENBQUM7UUFFSCxJQUFJLGVBQVEsQ0FBQyxPQUFPLEVBQUUsYUFBYSxFQUFFO1lBQ25DLFNBQVMsRUFBRSxLQUFLO1lBQ2hCLEdBQUcsRUFBRTtnQkFDSCxZQUFZLEVBQUU7b0JBQ1osUUFBUSxFQUFFO3dCQUNSLEdBQUcsRUFBRSwrQkFBK0I7cUJBQ3JDO2lCQUNGO2FBQ0Y7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLE1BQU0sWUFBWSxHQUEyQixFQUFFLENBQUM7UUFDaEQsSUFBSSxhQUFhLEdBQVksS0FBSyxDQUFDO1FBQ25DLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDeEMsSUFBSSxHQUFHLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUMxQixhQUFhLEdBQUcsSUFBSSxDQUFDO1lBQ3ZCLENBQUM7WUFDRCxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssNkJBQWMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDeEMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsT0FBTyxJQUFJLEdBQUcsQ0FBQztZQUM5QyxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNuQix1RUFBdUU7WUFDdkUsWUFBWSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDL0IsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLDhCQUE4QixDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFTyxvQkFBb0I7UUFDMUIsTUFBTSxZQUFZLEdBQTJCLEVBQUUsQ0FBQztRQUNoRCxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ3hDLElBQUksQ0FBQyw2QkFBYyxDQUFDLE1BQU0sRUFBRSw2QkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDcEUsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsT0FBTyxJQUFJLEdBQUcsQ0FBQztZQUM5QyxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLDhCQUE4QixDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BMkJHO0lBQ0ssOEJBQThCLENBQUMsWUFFdEM7UUFDQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsZUFBdUIsRUFBRSxFQUFFO1lBQ3ZELElBQUksQ0FBQztnQkFDSCwrREFBK0Q7Z0JBQy9ELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsZUFBZSxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUM7WUFDeEUsQ0FBQztZQUFDLE1BQU0sQ0FBQztnQkFDUCx5RUFBeUU7Z0JBQ3pFLE9BQU8sZUFBZSxDQUFDO1lBQ3pCLENBQUM7UUFDSCxDQUFDLENBQUM7UUFFRixPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQ3ZCLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxhQUFhLEVBQUUsZUFBZSxDQUFDLEVBQUUsRUFBRTtZQUNwRSxPQUFPLENBQUMsYUFBYSxFQUFFLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksYUFBYSxDQUFDLElBQVk7UUFDL0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSw2QkFBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksZ0JBQWdCLENBQUMsSUFBWTtRQUNsQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLDZCQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVEOztPQUVHO0lBQ0ksZ0JBQWdCO1FBQ3JCLE1BQU0sTUFBTSxHQUFHLGFBQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUM5QyxHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNO1NBQ3pCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDdEIsOExBQThMLENBQy9MLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxPQUFPLEdBQUcsYUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDckQsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTTtTQUN6QixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMscUNBQXFDLENBQUMsQ0FBQztZQUNoRSxhQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUU7Z0JBQzFDLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU07YUFDekIsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxHQUFHLGFBQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFO2dCQUNqRCxHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNO2FBQ3pCLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDdEIsZ0RBQWdELE9BQU8sS0FBSyxDQUM3RCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLG1CQUFtQjtRQUN4QixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUN2RCxvRkFBb0Y7UUFDcEYsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRCxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RELENBQUM7SUFDSCxDQUFDOztBQTFPSCx3QkEyT0M7QUFtSkQ7Ozs7R0FJRztBQUNILE1BQWEsZUFBZ0IsU0FBUSxxQkFBUzs7SUFDNUIsSUFBSSxDQUFvQjtJQUV4QyxZQUFZLEtBQWlCLEVBQUUsT0FBK0I7UUFDNUQsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWIsTUFBTSxFQUFFLGVBQWUsRUFBRSxHQUFHLFlBQVksRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUVyRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksdUNBQWlCLENBQUMsS0FBSyxFQUFFO1lBQ3ZDLElBQUksRUFBRTtnQkFDSixNQUFNLEVBQUU7b0JBQ04sR0FBRyxJQUFBLGdDQUF5QixFQUFDLFlBQVksRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQztvQkFDOUQsS0FBSyxFQUFFO3dCQUNMLEdBQUcsRUFBRTs0QkFDSCxZQUFZLEVBQUUsZUFBZTt5QkFDOUI7cUJBQ0Y7aUJBQ0Y7YUFDRjtZQUNELFdBQVcsRUFBRTtnQkFDWCxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUM7Z0JBQ3pCLFlBQVksRUFBRSx5QkFBeUI7YUFDeEM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDOztBQXhCSCwwQ0F5QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBUT01MIGZyb20gXCJAaWFybmEvdG9tbFwiO1xuaW1wb3J0IHR5cGUgeyBJQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB0eXBlIHsgSVB5dGhvbkRlcHMgfSBmcm9tIFwiLi9weXRob24tZGVwc1wiO1xuaW1wb3J0IHR5cGUgeyBJUHl0aG9uRW52IH0gZnJvbSBcIi4vcHl0aG9uLWVudlwiO1xuaW1wb3J0IHR5cGUge1xuICBJUHl0aG9uUGFja2FnaW5nLFxuICBQeXRob25QYWNrYWdpbmdPcHRpb25zLFxufSBmcm9tIFwiLi9weXRob24tcGFja2FnaW5nXCI7XG5pbXBvcnQgdHlwZSB7IFB5dGhvbkV4ZWN1dGFibGVPcHRpb25zIH0gZnJvbSBcIi4vcHl0aG9uLXByb2plY3RcIjtcbmltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gXCIuLi9jb21wb25lbnRcIjtcbmltcG9ydCB7IERlcGVuZGVuY3lUeXBlIH0gZnJvbSBcIi4uL2RlcGVuZGVuY2llc1wiO1xuaW1wb3J0IHR5cGUgeyBQcm9qZWN0IH0gZnJvbSBcIi4uL3Byb2plY3RcIjtcbmltcG9ydCB0eXBlIHsgVGFzayB9IGZyb20gXCIuLi90YXNrXCI7XG5pbXBvcnQgeyBUb21sRmlsZSB9IGZyb20gXCIuLi90b21sXCI7XG5pbXBvcnQgeyBkZWNhbWVsaXplS2V5c1JlY3Vyc2l2ZWx5IH0gZnJvbSBcIi4uL3V0aWxcIjtcbmltcG9ydCB7IFB5cHJvamVjdFRvbWxGaWxlIH0gZnJvbSBcIi4vcHlwcm9qZWN0LXRvbWwtZmlsZVwiO1xuaW1wb3J0IHsgcG9ldHJ5IH0gZnJvbSBcIi4uL3V0aWwvZXhlY1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBvZXRyeU9wdGlvbnNcbiAgZXh0ZW5kcyBQeXRob25QYWNrYWdpbmdPcHRpb25zLCBQeXRob25FeGVjdXRhYmxlT3B0aW9ucyB7fVxuXG4vKipcbiAqIE1hbmFnZSBwcm9qZWN0IGRlcGVuZGVuY2llcywgdmlydHVhbCBlbnZpcm9ubWVudHMsIGFuZCBwYWNrYWdpbmcgdGhyb3VnaCB0aGVcbiAqIHBvZXRyeSBDTEkgdG9vbC5cbiAqL1xuZXhwb3J0IGNsYXNzIFBvZXRyeVxuICBleHRlbmRzIENvbXBvbmVudFxuICBpbXBsZW1lbnRzIElQeXRob25EZXBzLCBJUHl0aG9uRW52LCBJUHl0aG9uUGFja2FnaW5nXG57XG4gIC8qKlxuICAgKiBUYXNrIGZvciB1cGRhdGluZyB0aGUgbG9ja2ZpbGUgYW5kIGluc3RhbGxpbmcgcHJvamVjdCBkZXBlbmRlbmNpZXMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaW5zdGFsbFRhc2s6IFRhc2s7XG5cbiAgLyoqXG4gICAqIFRhc2sgZm9yIGluc3RhbGxpbmcgZGVwZW5kZW5jaWVzIGFjY29yZGluZyB0byB0aGUgZXhpc3RpbmcgbG9ja2ZpbGUuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaW5zdGFsbENpVGFzazogVGFzaztcblxuICAvKipcbiAgICogVGFzayBmb3IgcHVibGlzaGluZyB0aGUgcGFja2FnZSB0byBhIHBhY2thZ2UgcmVwb3NpdG9yeS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwdWJsaXNoVGFzazogVGFzaztcblxuICAvKipcbiAgICogVGFzayBmb3IgcHVibGlzaGluZyB0aGUgcGFja2FnZSB0byB0aGUgVGVzdCBQeVBJIHJlcG9zaXRvcnkgZm9yIHRlc3RpbmcgcHVycG9zZXMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcHVibGlzaFRlc3RUYXNrOiBUYXNrO1xuXG4gIC8qKlxuICAgKiBQYXRoIHRvIHRoZSBQeXRob24gZXhlY3V0YWJsZSB0byB1c2UuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHB5dGhvbkV4ZWM6IHN0cmluZztcblxuICAvKipcbiAgICogUmVwcmVzZW50cyB0aGUgY29uZmlndXJhdGlvbiBvZiB0aGUgYHB5cHJvamVjdC50b21sYCBmaWxlIGZvciBhIFBvZXRyeSBwcm9qZWN0LlxuICAgKiBUaGlzIGluY2x1ZGVzIHBhY2thZ2UgbWV0YWRhdGEsIGRlcGVuZGVuY2llcywgYW5kIFBvZXRyeS1zcGVjaWZpYyBzZXR0aW5ncy5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcHlQcm9qZWN0OiBQb2V0cnlQeXByb2plY3Q7XG5cbiAgY29uc3RydWN0b3IocHJvamVjdDogUHJvamVjdCwgb3B0aW9uczogUG9ldHJ5T3B0aW9ucykge1xuICAgIHN1cGVyKHByb2plY3QpO1xuICAgIHRoaXMucHl0aG9uRXhlYyA9IG9wdGlvbnMucHl0aG9uRXhlYyA/PyBcInB5dGhvblwiO1xuXG4gICAgdGhpcy5pbnN0YWxsVGFzayA9IHByb2plY3QuYWRkVGFzayhcImluc3RhbGxcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiSW5zdGFsbCBkZXBlbmRlbmNpZXMgYW5kIHVwZGF0ZSBsb2NrZmlsZVwiLFxuICAgICAgZXhlY0FyZ3M6IFtcInBvZXRyeVwiLCBcInVwZGF0ZVwiXSxcbiAgICB9KTtcblxuICAgIHRoaXMuaW5zdGFsbENpVGFzayA9IHByb2plY3QuYWRkVGFzayhcImluc3RhbGw6Y2lcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiSW5zdGFsbCBkZXBlbmRlbmNpZXMgd2l0aCBmcm96ZW4gbG9ja2ZpbGVcIixcbiAgICAgIHN0ZXBzOiBbXG4gICAgICAgIHsgZXhlY0FyZ3M6IFtcInBvZXRyeVwiLCBcImNoZWNrXCIsIFwiLS1sb2NrXCJdIH0sXG4gICAgICAgIHsgZXhlY0FyZ3M6IFtcInBvZXRyeVwiLCBcImluc3RhbGxcIl0gfSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICB0aGlzLnByb2plY3QudGFza3MuYWRkRW52aXJvbm1lbnQoXG4gICAgICBcIlZJUlRVQUxfRU5WXCIsXG4gICAgICAvLyBDcmVhdGUgLnZlbnYgb24gdGhlIGZpcnN0IHJ1biBpZiBpdCBkb2Vzbid0IGFscmVhZHkgZXhpc3RcbiAgICAgIFwiJChwb2V0cnkgZW52IGluZm8gLXAgfHwgcG9ldHJ5IHJ1biBwb2V0cnkgZW52IGluZm8gLXApXCIsXG4gICAgKTtcbiAgICB0aGlzLnByb2plY3QudGFza3MuYWRkRW52aXJvbm1lbnQoXG4gICAgICBcIlBBVEhcIixcbiAgICAgIFwiJChlY2hvICQocG9ldHJ5IGVudiBpbmZvIC1wKS9iaW46JFBBVEgpXCIsXG4gICAgKTtcblxuICAgIHByb2plY3QucGFja2FnZVRhc2suZXhlY0FyZ3MoW1wicG9ldHJ5XCIsIFwiYnVpbGRcIl0pO1xuXG4gICAgdGhpcy5wdWJsaXNoVGVzdFRhc2sgPSBwcm9qZWN0LmFkZFRhc2soXCJwdWJsaXNoOnRlc3RcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiVXBsb2FkcyB0aGUgcGFja2FnZSBhZ2FpbnN0IGEgdGVzdCBQeVBJIGVuZHBvaW50LlwiLFxuICAgICAgZXhlY0FyZ3M6IFtcInBvZXRyeVwiLCBcInB1Ymxpc2hcIiwgXCItclwiLCBcInRlc3RweXBpXCJdLFxuICAgIH0pO1xuXG4gICAgdGhpcy5wdWJsaXNoVGFzayA9IHByb2plY3QuYWRkVGFzayhcInB1Ymxpc2hcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiVXBsb2FkcyB0aGUgcGFja2FnZSB0byBQeVBJLlwiLFxuICAgICAgZXhlY0FyZ3M6IFtcInBvZXRyeVwiLCBcInB1Ymxpc2hcIl0sXG4gICAgfSk7XG5cbiAgICB0aGlzLnB5UHJvamVjdCA9IG5ldyBQb2V0cnlQeXByb2plY3QocHJvamVjdCwge1xuICAgICAgbmFtZTogcHJvamVjdC5uYW1lLFxuICAgICAgdmVyc2lvbjogb3B0aW9ucy52ZXJzaW9uLFxuICAgICAgZGVzY3JpcHRpb246IG9wdGlvbnMuZGVzY3JpcHRpb24gPz8gXCJcIixcbiAgICAgIGxpY2Vuc2U6IG9wdGlvbnMubGljZW5zZSxcbiAgICAgIGF1dGhvcnM6IFtgJHtvcHRpb25zLmF1dGhvck5hbWV9IDwke29wdGlvbnMuYXV0aG9yRW1haWx9PmBdLFxuICAgICAgaG9tZXBhZ2U6IG9wdGlvbnMuaG9tZXBhZ2UsXG4gICAgICBjbGFzc2lmaWVyczogb3B0aW9ucy5jbGFzc2lmaWVycyxcbiAgICAgIC4uLm9wdGlvbnMucG9ldHJ5T3B0aW9ucyxcbiAgICAgIGRlcGVuZGVuY2llczogKCkgPT4gdGhpcy5zeW50aERlcGVuZGVuY2llcygpLFxuICAgICAgZGV2RGVwZW5kZW5jaWVzOiAoKSA9PiB0aGlzLnN5bnRoRGV2RGVwZW5kZW5jaWVzKCksXG4gICAgfSk7XG5cbiAgICBuZXcgVG9tbEZpbGUocHJvamVjdCwgXCJwb2V0cnkudG9tbFwiLCB7XG4gICAgICBjb21taXR0ZWQ6IGZhbHNlLFxuICAgICAgb2JqOiB7XG4gICAgICAgIHJlcG9zaXRvcmllczoge1xuICAgICAgICAgIHRlc3RweXBpOiB7XG4gICAgICAgICAgICB1cmw6IFwiaHR0cHM6Ly90ZXN0LnB5cGkub3JnL2xlZ2FjeS9cIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3ludGhEZXBlbmRlbmNpZXMoKSB7XG4gICAgY29uc3QgZGVwZW5kZW5jaWVzOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XG4gICAgbGV0IHB5dGhvbkRlZmluZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IHBrZyBvZiB0aGlzLnByb2plY3QuZGVwcy5hbGwpIHtcbiAgICAgIGlmIChwa2cubmFtZSA9PT0gXCJweXRob25cIikge1xuICAgICAgICBweXRob25EZWZpbmVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChwa2cudHlwZSA9PT0gRGVwZW5kZW5jeVR5cGUuUlVOVElNRSkge1xuICAgICAgICBkZXBlbmRlbmNpZXNbcGtnLm5hbWVdID0gcGtnLnZlcnNpb24gPz8gXCIqXCI7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghcHl0aG9uRGVmaW5lZCkge1xuICAgICAgLy8gUHl0aG9uIHZlcnNpb24gbXVzdCBiZSBkZWZpbmVkIGZvciBwb2V0cnkgcHJvamVjdHMuIERlZmF1bHQgdG8gXjMuOC5cbiAgICAgIGRlcGVuZGVuY2llcy5weXRob24gPSBcIl4zLjhcIjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucGVybWl0RGVwc1dpdGhUb21sSW5saW5lVGFibGVzKGRlcGVuZGVuY2llcyk7XG4gIH1cblxuICBwcml2YXRlIHN5bnRoRGV2RGVwZW5kZW5jaWVzKCkge1xuICAgIGNvbnN0IGRlcGVuZGVuY2llczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9O1xuICAgIGZvciAoY29uc3QgcGtnIG9mIHRoaXMucHJvamVjdC5kZXBzLmFsbCkge1xuICAgICAgaWYgKFtEZXBlbmRlbmN5VHlwZS5ERVZFTlYsIERlcGVuZGVuY3lUeXBlLlRFU1RdLmluY2x1ZGVzKHBrZy50eXBlKSkge1xuICAgICAgICBkZXBlbmRlbmNpZXNbcGtnLm5hbWVdID0gcGtnLnZlcnNpb24gPz8gXCIqXCI7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnBlcm1pdERlcHNXaXRoVG9tbElubGluZVRhYmxlcyhkZXBlbmRlbmNpZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlcyBkZXBlbmRlbmN5IHZhbHVlcyB0aGF0IG1heSBpbmNsdWRlIFRPTUwgaW5saW5lIHRhYmxlcywgY29udmVydGluZyB0aGVtIGludG8gSmF2YVNjcmlwdCBvYmplY3RzLlxuICAgKiBJZiBhIGRlcGVuZGVuY3kgdmFsdWUgY2Fubm90IGJlIHBhcnNlZCBhcyBhIFRPTUwgaW5saW5lIHRhYmxlIChpbmRpY2F0aW5nIGl0IGlzIGEgcGxhaW4gU2VtVmVyIHN0cmluZyksXG4gICAqIGl0IGlzIGxlZnQgdW5jaGFuZ2VkLiBUaGlzIGFsbG93cyB0byBzdXBwb3J0IHRoZSBmdWxsIHJhbmdlIG9mIFBvZXRyeSdzIGRlcGVuZGVuY3kgc3BlY2lmaWNhdGlvbi5cbiAgICogQHNlZSBodHRwczovL3B5dGhvbi1wb2V0cnkub3JnL2RvY3MvZGVwZW5kZW5jeS1zcGVjaWZpY2F0aW9uL1xuICAgKiBAc2VlIGh0dHBzOi8vdG9tbC5pby9lbi92MS4wLjAjaW5saW5lLXRhYmxlXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIEdpdmVuIGEgYGRlcGVuZGVuY2llc2Agb2JqZWN0IGxpa2UgdGhpczpcbiAgICogY29uc3QgZGVwZW5kZW5jaWVzID0ge1xuICAgKiAgIFwibXlwYWNrYWdlXCI6IFwieyB2ZXJzaW9uID0gJzEuMi4zJywgZXh0cmFzID0gWydleHRyYTEnLCAnZXh0cmEyJ10gfVwiLFxuICAgKiAgIFwiYW5vdGhlcnBhY2thZ2VcIjogXCJeMi4zLjRcIlxuICAgKiB9O1xuICAgKiAvLyBBZnRlciBwYXJzaW5nLCB0aGUgcmVzdWx0aW5nIG9iamVjdCB3b3VsZCBiZTpcbiAgICoge1xuICAgKiAgIFwibXlwYWNrYWdlXCI6IHtcbiAgICogICAgIHZlcnNpb246IFwiMS4yLjNcIixcbiAgICogICAgIGV4dHJhczogW1wiZXh0cmExXCIsIFwiZXh0cmEyXCJdXG4gICAqICAgfSxcbiAgICogICBcImFub3RoZXJwYWNrYWdlXCI6IFwiXjIuMy40XCJcbiAgICogfVxuICAgKiAvLyBOb3RlOiBUaGUgdmFsdWUgb2YgYGFub3RoZXJwYWNrYWdlYCByZW1haW5zIHVuY2hhbmdlZCBhcyBpdCBpcyBhIHBsYWluIFNlbVZlciBzdHJpbmcuXG4gICAqXG4gICAqIEBwYXJhbSBkZXBlbmRlbmNpZXMgQW4gb2JqZWN0IHdoZXJlIGVhY2gga2V5IGlzIGEgZGVwZW5kZW5jeSBuYW1lIGFuZCBlYWNoIHZhbHVlIGlzIGEgc3RyaW5nIHRoYXQgbWlnaHQgYmVcbiAgICogZWl0aGVyIGEgU2VtVmVyIHN0cmluZyBvciBhIFRPTUwgaW5saW5lIHRhYmxlIHN0cmluZy5cbiAgICogQHJldHVybnMgQSBuZXcgb2JqZWN0IHdoZXJlIGVhY2gga2V5IGlzIGEgZGVwZW5kZW5jeSBuYW1lIGFuZCBlYWNoIHZhbHVlIGlzIGVpdGhlciB0aGUgb3JpZ2luYWwgU2VtVmVyIHN0cmluZ1xuICAgKiBvciB0aGUgcGFyc2VkIEphdmFTY3JpcHQgb2JqZWN0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBUT01MIGlubGluZSB0YWJsZS5cbiAgICovXG4gIHByaXZhdGUgcGVybWl0RGVwc1dpdGhUb21sSW5saW5lVGFibGVzKGRlcGVuZGVuY2llczoge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZztcbiAgfSkge1xuICAgIGNvbnN0IHBhcnNlVG9tbElubGluZVRhYmxlID0gKGRlcGVuZGVuY3lWYWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBBdHRlbXB0IHBhcnNpbmcgdGhlIGBkZXBlbmRlbmN5VmFsdWVgIGFzIGEgVE9NTCBpbmxpbmUgdGFibGVcbiAgICAgICAgcmV0dXJuIFRPTUwucGFyc2UoYGRlcGVuZGVuY3lLZXkgPSAke2RlcGVuZGVuY3lWYWx1ZX1gKS5kZXBlbmRlbmN5S2V5O1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIElmIHBhcnNpbmcgZmFpbHMsIHRyZWF0IHRoZSBgZGVwZW5kZW5jeVZhbHVlYCBhcyBhIHBsYWluIFNlbVZlciBzdHJpbmdcbiAgICAgICAgcmV0dXJuIGRlcGVuZGVuY3lWYWx1ZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC5lbnRyaWVzKGRlcGVuZGVuY2llcykubWFwKChbZGVwZW5kZW5jeUtleSwgZGVwZW5kZW5jeVZhbHVlXSkgPT4ge1xuICAgICAgICByZXR1cm4gW2RlcGVuZGVuY3lLZXksIHBhcnNlVG9tbElubGluZVRhYmxlKGRlcGVuZGVuY3lWYWx1ZSldO1xuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcnVudGltZSBkZXBlbmRlbmN5LlxuICAgKlxuICAgKiBAcGFyYW0gc3BlYyBGb3JtYXQgYDxtb2R1bGU+QDxzZW12ZXI+YFxuICAgKi9cbiAgcHVibGljIGFkZERlcGVuZGVuY3koc3BlYzogc3RyaW5nKSB7XG4gICAgdGhpcy5wcm9qZWN0LmRlcHMuYWRkRGVwZW5kZW5jeShzcGVjLCBEZXBlbmRlbmN5VHlwZS5SVU5USU1FKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgZGV2IGRlcGVuZGVuY3kuXG4gICAqXG4gICAqIEBwYXJhbSBzcGVjIEZvcm1hdCBgPG1vZHVsZT5APHNlbXZlcj5gXG4gICAqL1xuICBwdWJsaWMgYWRkRGV2RGVwZW5kZW5jeShzcGVjOiBzdHJpbmcpIHtcbiAgICB0aGlzLnByb2plY3QuZGVwcy5hZGREZXBlbmRlbmN5KHNwZWMsIERlcGVuZGVuY3lUeXBlLkRFVkVOVik7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgdGhlIHZpcnR1YWwgZW52aXJvbm1lbnQgaWYgaXQgZG9lc24ndCBleGlzdCAoY2FsbGVkIGR1cmluZyBwb3N0LXN5bnRoZXNpcykuXG4gICAqL1xuICBwdWJsaWMgc2V0dXBFbnZpcm9ubWVudCgpIHtcbiAgICBjb25zdCByZXN1bHQgPSBwb2V0cnkudHJ5Q2FwdHVyZShbXCItLXZlcnNpb25cIl0sIHtcbiAgICAgIGN3ZDogdGhpcy5wcm9qZWN0Lm91dGRpcixcbiAgICB9KTtcbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgdGhpcy5wcm9qZWN0LmxvZ2dlci5pbmZvKFxuICAgICAgICBcIlVuYWJsZSB0byBzZXR1cCBhbiBlbnZpcm9ubWVudCBzaW5jZSBwb2V0cnkgaXMgbm90IGluc3RhbGxlZC4gUGxlYXNlIGluc3RhbGwgcG9ldHJ5IChodHRwczovL3B5dGhvbi1wb2V0cnkub3JnL2RvY3MvKSBvciB1c2UgYSBkaWZmZXJlbnQgY29tcG9uZW50IGZvciBtYW5hZ2luZyBlbnZpcm9ubWVudHMgc3VjaCBhcyAndmVudicuXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGxldCBlbnZQYXRoID0gcG9ldHJ5LnRyeUNhcHR1cmUoW1wiZW52XCIsIFwiaW5mb1wiLCBcIi1wXCJdLCB7XG4gICAgICBjd2Q6IHRoaXMucHJvamVjdC5vdXRkaXIsXG4gICAgfSk7XG4gICAgaWYgKCFlbnZQYXRoKSB7XG4gICAgICB0aGlzLnByb2plY3QubG9nZ2VyLmluZm8oXCJTZXR0aW5nIHVwIGEgdmlydHVhbCBlbnZpcm9ubWVudC4uLlwiKTtcbiAgICAgIHBvZXRyeS5ydW4oW1wiZW52XCIsIFwidXNlXCIsIHRoaXMucHl0aG9uRXhlY10sIHtcbiAgICAgICAgY3dkOiB0aGlzLnByb2plY3Qub3V0ZGlyLFxuICAgICAgfSk7XG4gICAgICBlbnZQYXRoID0gcG9ldHJ5LnRyeUNhcHR1cmUoW1wiZW52XCIsIFwiaW5mb1wiLCBcIi1wXCJdLCB7XG4gICAgICAgIGN3ZDogdGhpcy5wcm9qZWN0Lm91dGRpcixcbiAgICAgIH0pO1xuICAgICAgdGhpcy5wcm9qZWN0LmxvZ2dlci5pbmZvKFxuICAgICAgICBgRW52aXJvbm1lbnQgc3VjY2Vzc2Z1bGx5IGNyZWF0ZWQgKGxvY2F0ZWQgaW4gJHtlbnZQYXRofX0pLmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbnN0YWxscyBkZXBlbmRlbmNpZXMgKGNhbGxlZCBkdXJpbmcgcG9zdC1zeW50aGVzaXMpLlxuICAgKi9cbiAgcHVibGljIGluc3RhbGxEZXBlbmRlbmNpZXMoKSB7XG4gICAgdGhpcy5wcm9qZWN0LmxvZ2dlci5pbmZvKFwiSW5zdGFsbGluZyBkZXBlbmRlbmNpZXMuLi5cIik7XG4gICAgLy8gSWYgdGhlIHB5cHJvamVjdC50b21sIGZpbGUgaGFzIGNoYW5nZWQsIHVwZGF0ZSB0aGUgbG9ja2ZpbGUgcHJpb3IgdG8gaW5zdGFsbGF0aW9uXG4gICAgaWYgKHRoaXMucHlQcm9qZWN0LmZpbGUuY2hhbmdlZCkge1xuICAgICAgdGhpcy5wcm9qZWN0LnRhc2tzLnJ1blRhc2sodGhpcy5pbnN0YWxsVGFzay5uYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wcm9qZWN0LnRhc2tzLnJ1blRhc2sodGhpcy5pbnN0YWxsQ2lUYXNrLm5hbWUpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFBvZXRyeS1zcGVjaWZpYyBvcHRpb25zLlxuICogQHNlZSBodHRwczovL3B5dGhvbi1wb2V0cnkub3JnL2RvY3MvcHlwcm9qZWN0L1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvZXRyeVB5cHJvamVjdE9wdGlvbnNXaXRob3V0RGVwcyB7XG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBwYWNrYWdlIChyZXF1aXJlZCkuXG4gICAqL1xuICByZWFkb25seSBuYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBWZXJzaW9uIG9mIHRoZSBwYWNrYWdlIChyZXF1aXJlZCkuXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIHNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSBwYWNrYWdlIChyZXF1aXJlZCkuXG4gICAqL1xuICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcblxuICAvKipcbiAgICogTGljZW5zZSBvZiB0aGlzIHBhY2thZ2UgYXMgYW4gU1BEWCBpZGVudGlmaWVyLlxuICAgKlxuICAgKiBJZiB0aGUgcHJvamVjdCBpcyBwcm9wcmlldGFyeSBhbmQgZG9lcyBub3QgdXNlIGEgc3BlY2lmaWMgbGljZW5zZSwgeW91XG4gICAqIGNhbiBzZXQgdGhpcyB2YWx1ZSBhcyBcIlByb3ByaWV0YXJ5XCIuXG4gICAqL1xuICByZWFkb25seSBsaWNlbnNlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYXV0aG9ycyBvZiB0aGUgcGFja2FnZS4gTXVzdCBiZSBpbiB0aGUgZm9ybSBcIm5hbWUgPGVtYWlsPlwiXG4gICAqL1xuICByZWFkb25seSBhdXRob3JzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIHRoZSBtYWludGFpbmVycyBvZiB0aGUgcGFja2FnZS4gTXVzdCBiZSBpbiB0aGUgZm9ybSBcIm5hbWUgPGVtYWlsPlwiXG4gICAqL1xuICByZWFkb25seSBtYWludGFpbmVycz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgcmVhZG1lIGZpbGUgb2YgdGhlIHBhY2thZ2UuXG4gICAqL1xuICByZWFkb25seSByZWFkbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgVVJMIHRvIHRoZSB3ZWJzaXRlIG9mIHRoZSBwcm9qZWN0LlxuICAgKi9cbiAgcmVhZG9ubHkgaG9tZXBhZ2U/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgVVJMIHRvIHRoZSByZXBvc2l0b3J5IG9mIHRoZSBwcm9qZWN0LlxuICAgKi9cbiAgcmVhZG9ubHkgcmVwb3NpdG9yeT86IHN0cmluZztcblxuICAvKipcbiAgICogQSBVUkwgdG8gdGhlIGRvY3VtZW50YXRpb24gb2YgdGhlIHByb2plY3QuXG4gICAqL1xuICByZWFkb25seSBkb2N1bWVudGF0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2Yga2V5d29yZHMgKG1heDogNSkgdGhhdCB0aGUgcGFja2FnZSBpcyByZWxhdGVkIHRvLlxuICAgKi9cbiAgcmVhZG9ubHkga2V5d29yZHM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIFB5UEkgdHJvdmUgY2xhc3NpZmllcnMgdGhhdCBkZXNjcmliZSB0aGUgcHJvamVjdC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL3B5cGkub3JnL2NsYXNzaWZpZXJzL1xuICAgKi9cbiAgcmVhZG9ubHkgY2xhc3NpZmllcnM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIHBhY2thZ2VzIGFuZCBtb2R1bGVzIHRvIGluY2x1ZGUgaW4gdGhlIGZpbmFsIGRpc3RyaWJ1dGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IHBhY2thZ2VzPzogYW55W107XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBwYXR0ZXJucyB0aGF0IHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIGZpbmFsIHBhY2thZ2UuXG4gICAqL1xuICByZWFkb25seSBpbmNsdWRlPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBwYXR0ZXJucyB0aGF0IHdpbGwgYmUgZXhjbHVkZWQgaW4gdGhlIGZpbmFsIHBhY2thZ2UuXG4gICAqXG4gICAqIElmIGEgVkNTIGlzIGJlaW5nIHVzZWQgZm9yIGEgcGFja2FnZSwgdGhlIGV4Y2x1ZGUgZmllbGQgd2lsbCBiZSBzZWVkZWQgd2l0aFxuICAgKiB0aGUgVkNT4oCZIGlnbm9yZSBzZXR0aW5ncyAoLmdpdGlnbm9yZSBmb3IgZ2l0IGZvciBleGFtcGxlKS5cbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGU/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIHNjcmlwdHMgb3IgZXhlY3V0YWJsZXMgdGhhdCB3aWxsIGJlIGluc3RhbGxlZCB3aGVuIGluc3RhbGxpbmcgdGhlIHBhY2thZ2UuXG4gICAqL1xuICByZWFkb25seSBzY3JpcHRzPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfTtcblxuICAvKipcbiAgICogU291cmNlIHJlZ2lzdHJpZXMgZnJvbSB3aGljaCBwYWNrYWdlcyBhcmUgcmV0cmlldmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlPzogYW55W107XG5cbiAgLyoqXG4gICAqIFBhY2thZ2UgZXh0cmFzXG4gICAqL1xuICByZWFkb25seSBleHRyYXM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZ1tdIH07XG5cbiAgLyoqXG4gICAqIFBsdWdpbnMuIE11c3QgYmUgc3BlY2lmaWVkIGFzIGEgdGFibGUuXG4gICAqIEBzZWUgaHR0cHM6Ly90b21sLmlvL2VuL3YxLjAuMCN0YWJsZVxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2lucz86IGFueTtcblxuICAvKipcbiAgICogUHJvamVjdCBjdXN0b20gVVJMcywgaW4gYWRkaXRpb24gdG8gaG9tZXBhZ2UsIHJlcG9zaXRvcnkgYW5kIGRvY3VtZW50YXRpb24uXG4gICAqIEUuZy4gXCJCdWcgVHJhY2tlclwiXG4gICAqL1xuICByZWFkb25seSB1cmxzPzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcbiAgLyoqXG4gICAqIFBhY2thZ2UgbW9kZSAob3B0aW9uYWwpLlxuICAgKiBAc2VlIGh0dHBzOi8vcHl0aG9uLXBvZXRyeS5vcmcvZG9jcy9weXByb2plY3QvI3BhY2thZ2UtbW9kZVxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqIEBleGFtcGxlIGZhbHNlXG4gICAqL1xuICByZWFkb25seSBwYWNrYWdlTW9kZT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUG9ldHJ5LXNwZWNpZmljIG9wdGlvbnMuXG4gKiBAc2VlIGh0dHBzOi8vcHl0aG9uLXBvZXRyeS5vcmcvZG9jcy9weXByb2plY3QvXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUG9ldHJ5UHlwcm9qZWN0T3B0aW9ucyBleHRlbmRzIFBvZXRyeVB5cHJvamVjdE9wdGlvbnNXaXRob3V0RGVwcyB7XG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgZGVwZW5kZW5jaWVzIGZvciB0aGUgcHJvamVjdC5cbiAgICpcbiAgICogVGhlIHB5dGhvbiB2ZXJzaW9uIGZvciB3aGljaCB5b3VyIHBhY2thZ2UgaXMgY29tcGF0aWJsZSBpcyBhbHNvIHJlcXVpcmVkLlxuICAgKlxuICAgKiBAZXhhbXBsZSB7IHJlcXVlc3RzOiBcIl4yLjEzLjBcIiB9XG4gICAqL1xuICByZWFkb25seSBkZXBlbmRlbmNpZXM/OiB7IFtrZXk6IHN0cmluZ106IGFueSB9O1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgZGV2ZWxvcG1lbnQgZGVwZW5kZW5jaWVzIGZvciB0aGUgcHJvamVjdC5cbiAgICpcbiAgICogQGV4YW1wbGUgeyByZXF1ZXN0czogXCJeMi4xMy4wXCIgfVxuICAgKi9cbiAgcmVhZG9ubHkgZGV2RGVwZW5kZW5jaWVzPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGNvbmZpZ3VyYXRpb24gb2YgYSBweXByb2plY3QudG9tbCBmaWxlIGZvciBhIFBvZXRyeSBwcm9qZWN0LlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9weXRob24tcG9ldHJ5Lm9yZy9kb2NzL3B5cHJvamVjdC9cbiAqL1xuZXhwb3J0IGNsYXNzIFBvZXRyeVB5cHJvamVjdCBleHRlbmRzIENvbXBvbmVudCB7XG4gIHB1YmxpYyByZWFkb25seSBmaWxlOiBQeXByb2plY3RUb21sRmlsZTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogSUNvbnN0cnVjdCwgb3B0aW9uczogUG9ldHJ5UHlwcm9qZWN0T3B0aW9ucykge1xuICAgIHN1cGVyKHNjb3BlKTtcblxuICAgIGNvbnN0IHsgZGV2RGVwZW5kZW5jaWVzLCAuLi5wb2V0cnlDb25maWcgfSA9IG9wdGlvbnM7XG5cbiAgICB0aGlzLmZpbGUgPSBuZXcgUHlwcm9qZWN0VG9tbEZpbGUoc2NvcGUsIHtcbiAgICAgIHRvb2w6IHtcbiAgICAgICAgcG9ldHJ5OiB7XG4gICAgICAgICAgLi4uZGVjYW1lbGl6ZUtleXNSZWN1cnNpdmVseShwb2V0cnlDb25maWcsIHsgc2VwYXJhdG9yOiBcIi1cIiB9KSxcbiAgICAgICAgICBncm91cDoge1xuICAgICAgICAgICAgZGV2OiB7XG4gICAgICAgICAgICAgIGRlcGVuZGVuY2llczogZGV2RGVwZW5kZW5jaWVzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGJ1aWxkU3lzdGVtOiB7XG4gICAgICAgIHJlcXVpcmVzOiBbXCJwb2V0cnktY29yZVwiXSxcbiAgICAgICAgYnVpbGRCYWNrZW5kOiBcInBvZXRyeS5jb3JlLm1hc29ucnkuYXBpXCIsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG4iXX0=