UNPKG

projen

Version:

CDK for software projects

138 lines • 20.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.Uv = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const component_1 = require("../component"); const uv_config_1 = require("./uv-config"); const dependencies_1 = require("../dependencies"); const task_runtime_1 = require("../task-runtime"); const util_1 = require("../util"); const pyproject_toml_file_1 = require("./pyproject-toml-file"); /** * Manage project dependencies, virtual environments, and packaging through uv. */ class Uv extends component_1.Component { constructor(scope, options) { super(scope); const requiresPython = options.project?.requiresPython ?? ">=3.12,<4.0"; this.venvPython = options.pythonExec ?? requiresPython; this.installTask = this.project.addTask("install", { description: "Install dependencies and update lockfile", exec: "uv sync && uv lock", }); this.installCiTask = this.project.addTask("install:ci", { description: "Install dependencies with frozen lockfile", exec: "uv sync", }); this.project.tasks.addEnvironment("VIRTUAL_ENV", ".venv"); this.project.tasks.addEnvironment("PATH", "$(echo .venv/bin:$PATH)"); this.project.packageTask.exec("uv build"); this.publishTestTask = this.project.addTask("publish:test", { description: "Uploads the package against a test PyPI endpoint.", exec: "uv publish --index testpypi", }); this.publishTask = this.project.addTask("publish", { description: "Uploads the package to PyPI.", exec: "uv publish", }); this.file = new pyproject_toml_file_1.PyprojectTomlFile(this.project, { project: { name: options.project?.name ?? this.project.name, requiresPython, ...options.project, dependencies: (() => [ ...(options?.project?.dependencies ?? []), ...this.synthDependencies(), ]), }, dependencyGroups: (() => this.synthDependencyGroups()), buildSystem: options.buildSystem, tool: { uv: (0, uv_config_1.toJson_UvConfiguration)(options.uv), }, }); } /** Formats dependencies in UV style. */ formatDependency(dep) { const name = dep.name; const version = dep.version; if (!version || version === "*") { return name; } // Translate caret (^) to Python compatible constraints if (version.startsWith("^")) { const cleanVersion = version.slice(1); const [major] = cleanVersion.split("."); const nextMajor = Number(major) + 1; return `${name}>=${cleanVersion},<${nextMajor}.0.0`; } // Translate tilde (~) to compatible release clause per PEP 440 if (version.startsWith("~")) { const cleanVersion = version.slice(1); // Only keep major.minor for tilde if possible const [major, minor = "0", patch = "0"] = cleanVersion.split("."); const nextMinor = Number(minor) + 1; return `${name}>=${major}.${minor}.${patch},<${major}.${nextMinor}.0`; } // Otherwise treat as an exact version return `${name}==${version}`; } getDependencies(dependencyTypes) { return (this.project.deps.all .filter((pkg) => dependencyTypes.includes(pkg.type) && pkg.name !== "python") // remove duplicate versions of the same dependency .filter((dep, index, self) => index === self.findIndex((d) => d.name === dep.name)) .map((pkg) => this.formatDependency(pkg))); } synthDependencies() { return this.getDependencies([dependencies_1.DependencyType.RUNTIME]); } synthDependencyGroups() { const devDeps = this.getDependencies([ dependencies_1.DependencyType.DEVENV, dependencies_1.DependencyType.TEST, ]); if (devDeps) { return { dev: devDeps }; } else { return undefined; } } addDependency(spec) { this.project.deps.addDependency(spec, dependencies_1.DependencyType.RUNTIME); } addDevDependency(spec) { this.project.deps.addDependency(spec, dependencies_1.DependencyType.DEVENV); } setupEnvironment() { const result = (0, util_1.execOrUndefined)("which uv", { cwd: this.project.outdir, }); if (!result) { this.project.logger.info("Unable to setup an environment since uv is not installed. Please install uv (https://github.com/astral-sh/uv) or use a different component for managing environments."); return; } // Create venv with the specific Python version // this will install the requested python version if needed (0, util_1.exec)(`uv venv --python ${this.venvPython} .venv`, { cwd: this.project.outdir, }); this.project.logger.info(`Environment successfully created in .venv directory with Python ${this.venvPython}.`); } installDependencies() { this.project.logger.info("Installing dependencies..."); const runtime = new task_runtime_1.TaskRuntime(this.project.outdir); if (this.file.changed) { runtime.runTask(this.installTask.name); } else { runtime.runTask(this.installCiTask.name); } } } exports.Uv = Uv; _a = JSII_RTTI_SYMBOL_1; Uv[_a] = { fqn: "projen.python.Uv", version: "0.98.32" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHl0aG9uL3V2LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBSUEsNENBQXlDO0FBQ3pDLDJDQUFzRTtBQUN0RSxrREFBNkQ7QUFFN0Qsa0RBQThDO0FBQzlDLGtDQUFnRDtBQUVoRCwrREFBMEQ7QUF5QjFEOztHQUVHO0FBQ0gsTUFBYSxFQUNYLFNBQVEscUJBQVM7SUFjakIsWUFBWSxLQUFpQixFQUFFLE9BQWtCO1FBQy9DLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUViLE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsY0FBYyxJQUFJLGFBQWEsQ0FBQztRQUN4RSxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLElBQUksY0FBYyxDQUFDO1FBRXZELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFO1lBQ2pELFdBQVcsRUFBRSwwQ0FBMEM7WUFDdkQsSUFBSSxFQUFFLG9CQUFvQjtTQUMzQixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRTtZQUN0RCxXQUFXLEVBQUUsMkNBQTJDO1lBQ3hELElBQUksRUFBRSxTQUFTO1NBQ2hCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO1FBRXJFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUUxQyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxPQUFPLENB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XG5pbXBvcnQgeyBJUHl0aG9uRGVwcyB9IGZyb20gXCIuL3B5dGhvbi1kZXBzXCI7XG5pbXBvcnQgeyBJUHl0aG9uRW52IH0gZnJvbSBcIi4vcHl0aG9uLWVudlwiO1xuaW1wb3J0IHsgSVB5dGhvblBhY2thZ2luZyB9IGZyb20gXCIuL3B5dGhvbi1wYWNrYWdpbmdcIjtcbmltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gXCIuLi9jb21wb25lbnRcIjtcbmltcG9ydCB7IHRvSnNvbl9VdkNvbmZpZ3VyYXRpb24sIFV2Q29uZmlndXJhdGlvbiB9IGZyb20gXCIuL3V2LWNvbmZpZ1wiO1xuaW1wb3J0IHsgRGVwZW5kZW5jeSwgRGVwZW5kZW5jeVR5cGUgfSBmcm9tIFwiLi4vZGVwZW5kZW5jaWVzXCI7XG5pbXBvcnQgeyBUYXNrIH0gZnJvbSBcIi4uL3Rhc2tcIjtcbmltcG9ydCB7IFRhc2tSdW50aW1lIH0gZnJvbSBcIi4uL3Rhc2stcnVudGltZVwiO1xuaW1wb3J0IHsgZXhlYywgZXhlY09yVW5kZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWxcIjtcbmltcG9ydCB7IEJ1aWxkU3lzdGVtLCBQeXByb2plY3RUb21sUHJvamVjdCB9IGZyb20gXCIuL3B5cHJvamVjdC10b21sXCI7XG5pbXBvcnQgeyBQeXByb2plY3RUb21sRmlsZSB9IGZyb20gXCIuL3B5cHJvamVjdC10b21sLWZpbGVcIjtcbmltcG9ydCB7IFB5dGhvbkV4ZWN1dGFibGVPcHRpb25zIH0gZnJvbSBcIi4vcHl0aG9uLXByb2plY3RcIjtcblxuLyoqXG4gKiBPcHRpb25zIGZvciBVViBwcm9qZWN0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVXZPcHRpb25zIGV4dGVuZHMgUHl0aG9uRXhlY3V0YWJsZU9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIHByb2plY3QncyBiYXNpYyBtZXRhZGF0YSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvamVjdD86IFB5cHJvamVjdFRvbWxQcm9qZWN0O1xuXG4gIC8qKlxuICAgKiBEZWNsYXJlcyBhbnkgUHl0aG9uIGxldmVsIGRlcGVuZGVuY2llcyB0aGF0IG11c3QgYmUgaW5zdGFsbGVkIGluIG9yZGVyIHRvIHJ1biB0aGUgcHJvamVjdOKAmXMgYnVpbGQgc3lzdGVtIHN1Y2Nlc3NmdWxseS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBidWlsZCBzeXN0ZW1cbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkU3lzdGVtPzogQnVpbGRTeXN0ZW07XG5cbiAgLyoqXG4gICAqIFRoZSBjb25maWd1cmF0aW9uIGFuZCBtZXRhZGF0YSBmb3IgdXYuXG4gICAqL1xuICByZWFkb25seSB1dj86IFV2Q29uZmlndXJhdGlvbjtcbn1cblxuLyoqXG4gKiBNYW5hZ2UgcHJvamVjdCBkZXBlbmRlbmNpZXMsIHZpcnR1YWwgZW52aXJvbm1lbnRzLCBhbmQgcGFja2FnaW5nIHRocm91Z2ggdXYuXG4gKi9cbmV4cG9ydCBjbGFzcyBVdlxuICBleHRlbmRzIENvbXBvbmVudFxuICBpbXBsZW1lbnRzIElQeXRob25EZXBzLCBJUHl0aG9uRW52LCBJUHl0aG9uUGFja2FnaW5nXG57XG4gIC8qKlxuICAgKiBUaGUgYHB5cHJvamVjdC50b21sYCBmaWxlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZmlsZTogUHlwcm9qZWN0VG9tbEZpbGU7XG4gIHB1YmxpYyByZWFkb25seSBpbnN0YWxsVGFzazogVGFzaztcbiAgcHVibGljIHJlYWRvbmx5IGluc3RhbGxDaVRhc2s6IFRhc2s7XG4gIHB1YmxpYyByZWFkb25seSBwdWJsaXNoVGFzazogVGFzaztcbiAgcHVibGljIHJlYWRvbmx5IHB1Ymxpc2hUZXN0VGFzazogVGFzaztcblxuICBwcml2YXRlIHJlYWRvbmx5IHZlbnZQeXRob246IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogSUNvbnN0cnVjdCwgb3B0aW9uczogVXZPcHRpb25zKSB7XG4gICAgc3VwZXIoc2NvcGUpO1xuXG4gICAgY29uc3QgcmVxdWlyZXNQeXRob24gPSBvcHRpb25zLnByb2plY3Q/LnJlcXVpcmVzUHl0aG9uID8/IFwiPj0zLjEyLDw0LjBcIjtcbiAgICB0aGlzLnZlbnZQeXRob24gPSBvcHRpb25zLnB5dGhvbkV4ZWMgPz8gcmVxdWlyZXNQeXRob247XG5cbiAgICB0aGlzLmluc3RhbGxUYXNrID0gdGhpcy5wcm9qZWN0LmFkZFRhc2soXCJpbnN0YWxsXCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIkluc3RhbGwgZGVwZW5kZW5jaWVzIGFuZCB1cGRhdGUgbG9ja2ZpbGVcIixcbiAgICAgIGV4ZWM6IFwidXYgc3luYyAmJiB1diBsb2NrXCIsXG4gICAgfSk7XG5cbiAgICB0aGlzLmluc3RhbGxDaVRhc2sgPSB0aGlzLnByb2plY3QuYWRkVGFzayhcImluc3RhbGw6Y2lcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiSW5zdGFsbCBkZXBlbmRlbmNpZXMgd2l0aCBmcm96ZW4gbG9ja2ZpbGVcIixcbiAgICAgIGV4ZWM6IFwidXYgc3luY1wiLFxuICAgIH0pO1xuXG4gICAgdGhpcy5wcm9qZWN0LnRhc2tzLmFkZEVudmlyb25tZW50KFwiVklSVFVBTF9FTlZcIiwgXCIudmVudlwiKTtcbiAgICB0aGlzLnByb2plY3QudGFza3MuYWRkRW52aXJvbm1lbnQoXCJQQVRIXCIsIFwiJChlY2hvIC52ZW52L2JpbjokUEFUSClcIik7XG5cbiAgICB0aGlzLnByb2plY3QucGFja2FnZVRhc2suZXhlYyhcInV2IGJ1aWxkXCIpO1xuXG4gICAgdGhpcy5wdWJsaXNoVGVzdFRhc2sgPSB0aGlzLnByb2plY3QuYWRkVGFzayhcInB1Ymxpc2g6dGVzdFwiLCB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJVcGxvYWRzIHRoZSBwYWNrYWdlIGFnYWluc3QgYSB0ZXN0IFB5UEkgZW5kcG9pbnQuXCIsXG4gICAgICBleGVjOiBcInV2IHB1Ymxpc2ggLS1pbmRleCB0ZXN0cHlwaVwiLFxuICAgIH0pO1xuXG4gICAgdGhpcy5wdWJsaXNoVGFzayA9IHRoaXMucHJvamVjdC5hZGRUYXNrKFwicHVibGlzaFwiLCB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJVcGxvYWRzIHRoZSBwYWNrYWdlIHRvIFB5UEkuXCIsXG4gICAgICBleGVjOiBcInV2IHB1Ymxpc2hcIixcbiAgICB9KTtcblxuICAgIHRoaXMuZmlsZSA9IG5ldyBQeXByb2plY3RUb21sRmlsZSh0aGlzLnByb2plY3QsIHtcbiAgICAgIHByb2plY3Q6IHtcbiAgICAgICAgbmFtZTogb3B0aW9ucy5wcm9qZWN0Py5uYW1lID8/IHRoaXMucHJvamVjdC5uYW1lLFxuICAgICAgICByZXF1aXJlc1B5dGhvbixcbiAgICAgICAgLi4ub3B0aW9ucy5wcm9qZWN0LFxuICAgICAgICBkZXBlbmRlbmNpZXM6ICgoKSA9PiBbXG4gICAgICAgICAgLi4uKG9wdGlvbnM/LnByb2plY3Q/LmRlcGVuZGVuY2llcyA/PyBbXSksXG4gICAgICAgICAgLi4udGhpcy5zeW50aERlcGVuZGVuY2llcygpLFxuICAgICAgICBdKSBhcyBhbnksXG4gICAgICB9LFxuICAgICAgZGVwZW5kZW5jeUdyb3VwczogKCgpID0+IHRoaXMuc3ludGhEZXBlbmRlbmN5R3JvdXBzKCkpIGFzIGFueSxcbiAgICAgIGJ1aWxkU3lzdGVtOiBvcHRpb25zLmJ1aWxkU3lzdGVtLFxuICAgICAgdG9vbDoge1xuICAgICAgICB1djogdG9Kc29uX1V2Q29uZmlndXJhdGlvbihvcHRpb25zLnV2KSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKiogRm9ybWF0cyBkZXBlbmRlbmNpZXMgaW4gVVYgc3R5bGUuICovXG4gIHByaXZhdGUgZm9ybWF0RGVwZW5kZW5jeShkZXA6IERlcGVuZGVuY3kpOiBzdHJpbmcge1xuICAgIGNvbnN0IG5hbWUgPSBkZXAubmFtZTtcbiAgICBjb25zdCB2ZXJzaW9uID0gZGVwLnZlcnNpb247XG5cbiAgICBpZiAoIXZlcnNpb24gfHwgdmVyc2lvbiA9PT0gXCIqXCIpIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cblxuICAgIC8vIFRyYW5zbGF0ZSBjYXJldCAoXikgdG8gUHl0aG9uIGNvbXBhdGlibGUgY29uc3RyYWludHNcbiAgICBpZiAodmVyc2lvbi5zdGFydHNXaXRoKFwiXlwiKSkge1xuICAgICAgY29uc3QgY2xlYW5WZXJzaW9uID0gdmVyc2lvbi5zbGljZSgxKTtcbiAgICAgIGNvbnN0IFttYWpvcl0gPSBjbGVhblZlcnNpb24uc3BsaXQoXCIuXCIpO1xuICAgICAgY29uc3QgbmV4dE1ham9yID0gTnVtYmVyKG1ham9yKSArIDE7XG4gICAgICByZXR1cm4gYCR7bmFtZX0+PSR7Y2xlYW5WZXJzaW9ufSw8JHtuZXh0TWFqb3J9LjAuMGA7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNsYXRlIHRpbGRlICh+KSB0byBjb21wYXRpYmxlIHJlbGVhc2UgY2xhdXNlIHBlciBQRVAgNDQwXG4gICAgaWYgKHZlcnNpb24uc3RhcnRzV2l0aChcIn5cIikpIHtcbiAgICAgIGNvbnN0IGNsZWFuVmVyc2lvbiA9IHZlcnNpb24uc2xpY2UoMSk7XG5cbiAgICAgIC8vIE9ubHkga2VlcCBtYWpvci5taW5vciBmb3IgdGlsZGUgaWYgcG9zc2libGVcbiAgICAgIGNvbnN0IFttYWpvciwgbWlub3IgPSBcIjBcIiwgcGF0Y2ggPSBcIjBcIl0gPSBjbGVhblZlcnNpb24uc3BsaXQoXCIuXCIpO1xuICAgICAgY29uc3QgbmV4dE1pbm9yID0gTnVtYmVyKG1pbm9yKSArIDE7XG4gICAgICByZXR1cm4gYCR7bmFtZX0+PSR7bWFqb3J9LiR7bWlub3J9LiR7cGF0Y2h9LDwke21ham9yfS4ke25leHRNaW5vcn0uMGA7XG4gICAgfVxuXG4gICAgLy8gT3RoZXJ3aXNlIHRyZWF0IGFzIGFuIGV4YWN0IHZlcnNpb25cbiAgICByZXR1cm4gYCR7bmFtZX09PSR7dmVyc2lvbn1gO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREZXBlbmRlbmNpZXMoZGVwZW5kZW5jeVR5cGVzOiBEZXBlbmRlbmN5VHlwZVtdKTogc3RyaW5nW10ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLnByb2plY3QuZGVwcy5hbGxcbiAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAocGtnKSA9PiBkZXBlbmRlbmN5VHlwZXMuaW5jbHVkZXMocGtnLnR5cGUpICYmIHBrZy5uYW1lICE9PSBcInB5dGhvblwiXG4gICAgICAgIClcbiAgICAgICAgLy8gcmVtb3ZlIGR1cGxpY2F0ZSB2ZXJzaW9ucyBvZiB0aGUgc2FtZSBkZXBlbmRlbmN5XG4gICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgKGRlcCwgaW5kZXgsIHNlbGYpID0+XG4gICAgICAgICAgICBpbmRleCA9PT0gc2VsZi5maW5kSW5kZXgoKGQpID0+IGQubmFtZSA9PT0gZGVwLm5hbWUpXG4gICAgICAgIClcbiAgICAgICAgLm1hcCgocGtnKSA9PiB0aGlzLmZvcm1hdERlcGVuZGVuY3kocGtnKSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW50aERlcGVuZGVuY2llcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0RGVwZW5kZW5jaWVzKFtEZXBlbmRlbmN5VHlwZS5SVU5USU1FXSk7XG4gIH1cblxuICBwcml2YXRlIHN5bnRoRGVwZW5kZW5jeUdyb3VwcygpOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZ1tdIH0gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGRldkRlcHMgPSB0aGlzLmdldERlcGVuZGVuY2llcyhbXG4gICAgICBEZXBlbmRlbmN5VHlwZS5ERVZFTlYsXG4gICAgICBEZXBlbmRlbmN5VHlwZS5URVNULFxuICAgIF0pO1xuXG4gICAgaWYgKGRldkRlcHMpIHtcbiAgICAgIHJldHVybiB7IGRldjogZGV2RGVwcyB9O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhZGREZXBlbmRlbmN5KHNwZWM6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMucHJvamVjdC5kZXBzLmFkZERlcGVuZGVuY3koc3BlYywgRGVwZW5kZW5jeVR5cGUuUlVOVElNRSk7XG4gIH1cblxuICBwdWJsaWMgYWRkRGV2RGVwZW5kZW5jeShzcGVjOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnByb2plY3QuZGVwcy5hZGREZXBlbmRlbmN5KHNwZWMsIERlcGVuZGVuY3lUeXBlLkRFVkVOVik7XG4gIH1cblxuICBwdWJsaWMgc2V0dXBFbnZpcm9ubWVudCgpOiB2b2lkIHtcbiAgICBjb25zdCByZXN1bHQgPSBleGVjT3JVbmRlZmluZWQoXCJ3aGljaCB1dlwiLCB7XG4gICAgICBjd2Q6IHRoaXMucHJvamVjdC5vdXRkaXIsXG4gICAgfSk7XG4gICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgIHRoaXMucHJvamVjdC5sb2dnZXIuaW5mbyhcbiAgICAgICAgXCJVbmFibGUgdG8gc2V0dXAgYW4gZW52aXJvbm1lbnQgc2luY2UgdXYgaXMgbm90IGluc3RhbGxlZC4gUGxlYXNlIGluc3RhbGwgdXYgKGh0dHBzOi8vZ2l0aHViLmNvbS9hc3RyYWwtc2gvdXYpIG9yIHVzZSBhIGRpZmZlcmVudCBjb21wb25lbnQgZm9yIG1hbmFnaW5nIGVudmlyb25tZW50cy5cIlxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgdmVudiB3aXRoIHRoZSBzcGVjaWZpYyBQeXRob24gdmVyc2lvblxuICAgIC8vIHRoaXMgd2lsbCBpbnN0YWxsIHRoZSByZXF1ZXN0ZWQgcHl0aG9uIHZlcnNpb24gaWYgbmVlZGVkXG4gICAgZXhlYyhgdXYgdmVudiAtLXB5dGhvbiAke3RoaXMudmVudlB5dGhvbn0gLnZlbnZgLCB7XG4gICAgICBjd2Q6IHRoaXMucHJvamVjdC5vdXRkaXIsXG4gICAgfSk7XG4gICAgdGhpcy5wcm9qZWN0LmxvZ2dlci5pbmZvKFxuICAgICAgYEVudmlyb25tZW50IHN1Y2Nlc3NmdWxseSBjcmVhdGVkIGluIC52ZW52IGRpcmVjdG9yeSB3aXRoIFB5dGhvbiAke3RoaXMudmVudlB5dGhvbn0uYFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgaW5zdGFsbERlcGVuZGVuY2llcygpOiB2b2lkIHtcbiAgICB0aGlzLnByb2plY3QubG9nZ2VyLmluZm8oXCJJbnN0YWxsaW5nIGRlcGVuZGVuY2llcy4uLlwiKTtcbiAgICBjb25zdCBydW50aW1lID0gbmV3IFRhc2tSdW50aW1lKHRoaXMucHJvamVjdC5vdXRkaXIpO1xuICAgIGlmICh0aGlzLmZpbGUuY2hhbmdlZCkge1xuICAgICAgcnVudGltZS5ydW5UYXNrKHRoaXMuaW5zdGFsbFRhc2submFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJ1bnRpbWUucnVuVGFzayh0aGlzLmluc3RhbGxDaVRhc2submFtZSk7XG4gICAgfVxuICB9XG59XG4iXX0=