UNPKG

gitlab-ci-local

Version:

Tired of pushing to test your .gitlab-ci.yml?

279 lines 38 kB
import assert from "assert"; import fs from "fs-extra"; import * as dotenv from "dotenv"; import * as path from "path"; import camelCase from "camelcase"; import { Utils } from "./utils.js"; import chalk from "chalk"; async function isInGitRepository() { try { await Utils.spawn(["git", "rev-parse", "--is-inside-work-tree"]); return true; } catch (err) { return false; } } async function gitRootPath() { const { stdout } = await Utils.spawn(["git", "rev-parse", "--show-toplevel"]); return stdout; } export class Argv { static default = { "variablesFile": ".gitlab-ci-local-variables.yml", "evaluateRuleChanges": true, "ignoreSchemaPaths": [], }; map = new Map(); writeStreams; async fallbackCwd(args) { if (args.cwd !== undefined || args.file !== undefined) return; if (fs.existsSync(`${process.cwd()}/.gitlab-ci.yml`)) return; if (!(await isInGitRepository())) return; this.writeStreams?.stderr(chalk `{yellow .gitlab-ci.yml not found in cwd, falling back to git root directory}\n`); this.map.set("cwd", path.relative(process.cwd(), await gitRootPath())); } static async build(args, writeStreams) { const argv = new Argv(args, writeStreams); await argv.fallbackCwd(args); argv.injectDotenv(`${argv.home}/.gitlab-ci-local/.env`, args); argv.injectDotenv(`${argv.cwd}/.gitlab-ci-local-env`, args); if (!argv.shellExecutorNoImage && argv.shellIsolation) { writeStreams?.stderr(chalk `{black.bgYellowBright WARN } --shell-isolation does not work with --no-shell-executor-no-image\n`); } if (argv.defaultImageExplicitlySet && argv.shellIsolation) { writeStreams?.stderr(chalk `{black.bgYellowBright WARN } --default-image does not work with --shell-isolation=true\n`); } if (argv.defaultImageExplicitlySet && argv.shellExecutorNoImage) { writeStreams?.stderr(chalk `{black.bgYellowBright WARN } --default-image does not work with --shell-executor-no-image=true\n`); } if (argv.defaultImageExplicitlySet && argv.forceShellExecutor) { writeStreams?.stderr(chalk `{black.bgYellowBright WARN } --default-image does not work with --force-shell-executor=true\n`); } return argv; } constructor(argv, writeStreams) { if (argv.noColor) { chalk.level = 0; } this.writeStreams = writeStreams; for (const [key, value] of Object.entries(argv)) { this.map.set(key, value); } } injectDotenv(potentialDotenvFilepath, argv) { if (fs.existsSync(potentialDotenvFilepath)) { const config = dotenv.parse(fs.readFileSync(potentialDotenvFilepath)); for (const [key, value] of Object.entries(config)) { const argKey = camelCase(key); // Special handle KEY=VALUE variable keys if (argKey === "variable") { let currentVal = argv[argKey]; if (currentVal == null) { currentVal = []; this.map.set(argKey, currentVal); } if (!Array.isArray(currentVal)) { continue; } for (const pair of value.split(" ")) { currentVal.unshift(pair); } } else if (argv[argKey] == null) { // Work around `dotenv.parse` limitation https://github.com/motdotla/dotenv/issues/51#issuecomment-552559070 if (value === "true") this.map.set(argKey, true); else if (value === "false") this.map.set(argKey, false); else if (value === "null") this.map.set(argKey, null); else if (!isNaN(Number(value))) this.map.set(argKey, Number(value)); else this.map.set(argKey, value); } } } } get cwd() { let cwd = this.map.get("cwd") ?? "."; assert(typeof cwd != "object", "--cwd option cannot be an array"); assert(!path.isAbsolute(cwd), "Please use relative path for the --cwd option"); cwd = path.normalize(`${process.cwd()}/${cwd}`); cwd = cwd.replace(/\/$/, ""); assert(fs.pathExistsSync(cwd), `${cwd} is not a directory`); return cwd; } get variablesFile() { return this.map.get("variablesFile") ?? Argv.default.variablesFile; } get evaluateRuleChanges() { return this.map.get("evaluateRuleChanges") ?? Argv.default.evaluateRuleChanges; } get file() { return this.map.get("file") ?? ".gitlab-ci.yml"; } get stateDir() { return (this.map.get("stateDir") ?? ".gitlab-ci-local").replace(/\/$/, ""); } get home() { return (this.map.get("home") ?? process.env.HOME ?? "").replace(/\/$/, ""); } get volume() { const val = this.map.get("volume") ?? []; return typeof val == "string" ? val.split(" ") : val; } get network() { const val = this.map.get("network") ?? []; return typeof val == "string" ? val.split(" ") : val; } get extraHost() { const val = this.map.get("extraHost") ?? []; return typeof val == "string" ? val.split(" ") : val; } get ignoreSchemaPaths() { return this.map.get("ignoreSchemaPaths") ?? Argv.default.ignoreSchemaPaths; } get pullPolicy() { return this.map.get("pullPolicy") ?? "if-not-present"; } get remoteVariables() { return this.map.get("remoteVariables"); } get variable() { const val = this.map.get("variable"); const variables = {}; const pairs = typeof val == "string" ? val.split(" ") : val; (pairs ?? []).forEach((variablePair) => { const exec = /(?<key>\w*?)(=)(?<value>(.|\n|\r)*)/.exec(variablePair); if (exec?.groups?.key) { variables[exec.groups.key] = exec?.groups?.value; } }); return variables; } get unsetVariables() { return this.map.get("unsetVariable") ?? []; } get manual() { const val = this.map.get("manual") ?? []; return typeof val == "string" ? val.split(" ") : val; } get job() { return this.map.get("job") ?? []; } get autoCompleting() { return this.map.get("autoCompleting") ?? false; } get cleanup() { return this.map.get("cleanup") ?? true; } get quiet() { return this.map.get("quiet") ?? false; } get umask() { // TODO: default to false in 5.x.x return this.map.get("umask") ?? true; } get privileged() { return this.map.get("privileged") ?? false; } get ulimit() { const ulimit = this.map.get("ulimit"); if (!ulimit) return null; return ulimit; } get needs() { return this.map.get("needs") ?? false; } get onlyNeeds() { return this.map.get("onlyNeeds") ?? false; } get stage() { return this.map.get("stage") ?? null; } get completion() { return this.map.get("completion") ?? false; } get list() { return this.map.get("list") ?? false; } get listAll() { return this.map.get("listAll") ?? false; } get listJson() { return this.map.get("listJson") ?? false; } get listCsv() { return this.map.get("listCsv") ?? false; } get listCsvAll() { return this.map.get("listCsvAll") ?? false; } get preview() { return this.map.get("preview") ?? false; } get shellIsolation() { // TODO: default to true in 5.x.x return this.map.get("shellIsolation") ?? false; } get fetchIncludes() { return this.map.get("fetchIncludes") ?? false; } get mountCache() { return this.map.get("mountCache") ?? false; } get artifactsToSource() { // TODO: default to false in 5.x.x return this.map.get("artifactsToSource") ?? true; } get showTimestamps() { return this.map.get("timestamps") ?? false; } get maxJobNamePadding() { return this.map.get("maxJobNamePadding") ?? null; } get containerMacAddress() { return this.map.get("containerMacAddress") ?? null; } get containerEmulate() { return this.map.get("containerEmulate") ?? null; } get concurrency() { const concurrency = this.map.get("concurrency"); if (!concurrency) return null; return Number(concurrency); } get containerExecutable() { return this.map.get("containerExecutable") ?? "docker"; } get jsonSchemaValidation() { return this.map.get("jsonSchemaValidation") ?? true; } get shellExecutorNoImage() { // TODO: default to false in 5.x.x return this.map.get("shellExecutorNoImage") ?? true; } get forceShellExecutor() { return this.map.get("forceShellExecutor") ?? false; } get defaultImage() { return this.map.get("defaultImage") ?? "docker.io/ruby:3.1"; } get defaultImageExplicitlySet() { return this.map.get("defaultImage") ?? false; } get maximumIncludes() { return this.map.get("maximumIncludes") ?? 150; // https://docs.gitlab.com/ee/administration/settings/continuous_integration.html#maximum-includes } get childPipelineDepth() { return this.map.get("childPipelineDepth"); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJndi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImFyZ3YudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMxQixPQUFPLEtBQUssTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUNqQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLFNBQVMsTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFDLEtBQUssRUFBQyxNQUFNLFlBQVksQ0FBQztBQUVqQyxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFFMUIsS0FBSyxVQUFVLGlCQUFpQjtJQUM1QixJQUFJLENBQUM7UUFDRCxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLHVCQUF1QixDQUFDLENBQUMsQ0FBQztRQUNqRSxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztRQUNoQixPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0FBQ0wsQ0FBQztBQUVELEtBQUssVUFBVSxXQUFXO0lBQ3RCLE1BQU0sRUFBQyxNQUFNLEVBQUMsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixDQUFDLENBQUMsQ0FBQztJQUM1RSxPQUFPLE1BQU0sQ0FBQztBQUNsQixDQUFDO0FBRUQsTUFBTSxPQUFPLElBQUk7SUFDYixNQUFNLENBQVUsT0FBTyxHQUFHO1FBQ3RCLGVBQWUsRUFBRSxnQ0FBZ0M7UUFDakQscUJBQXFCLEVBQUUsSUFBSTtRQUMzQixtQkFBbUIsRUFBRSxFQUFFO0tBQzFCLENBQUM7SUFFRixHQUFHLEdBQXFCLElBQUksR0FBRyxFQUFlLENBQUM7SUFDOUIsWUFBWSxDQUEyQjtJQUVoRCxLQUFLLENBQUMsV0FBVyxDQUFF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RyxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDOUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmcy1leHRyYVwiO1xuaW1wb3J0ICogYXMgZG90ZW52IGZyb20gXCJkb3RlbnZcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCBjYW1lbENhc2UgZnJvbSBcImNhbWVsY2FzZVwiO1xuaW1wb3J0IHtVdGlsc30gZnJvbSBcIi4vdXRpbHMuanNcIjtcbmltcG9ydCB7V3JpdGVTdHJlYW1zfSBmcm9tIFwiLi93cml0ZS1zdHJlYW1zLmpzXCI7XG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5cbmFzeW5jIGZ1bmN0aW9uIGlzSW5HaXRSZXBvc2l0b3J5ICgpIHtcbiAgICB0cnkge1xuICAgICAgICBhd2FpdCBVdGlscy5zcGF3bihbXCJnaXRcIiwgXCJyZXYtcGFyc2VcIiwgXCItLWlzLWluc2lkZS13b3JrLXRyZWVcIl0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBnaXRSb290UGF0aCAoKSB7XG4gICAgY29uc3Qge3N0ZG91dH0gPSBhd2FpdCBVdGlscy5zcGF3bihbXCJnaXRcIiwgXCJyZXYtcGFyc2VcIiwgXCItLXNob3ctdG9wbGV2ZWxcIl0pO1xuICAgIHJldHVybiBzdGRvdXQ7XG59XG5cbmV4cG9ydCBjbGFzcyBBcmd2IHtcbiAgICBzdGF0aWMgcmVhZG9ubHkgZGVmYXVsdCA9IHtcbiAgICAgICAgXCJ2YXJpYWJsZXNGaWxlXCI6IFwiLmdpdGxhYi1jaS1sb2NhbC12YXJpYWJsZXMueW1sXCIsXG4gICAgICAgIFwiZXZhbHVhdGVSdWxlQ2hhbmdlc1wiOiB0cnVlLFxuICAgICAgICBcImlnbm9yZVNjaGVtYVBhdGhzXCI6IFtdLFxuICAgIH07XG5cbiAgICBtYXA6IE1hcDxzdHJpbmcsIGFueT4gPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgd3JpdGVTdHJlYW1zOiBXcml0ZVN0cmVhbXMgfCB1bmRlZmluZWQ7XG5cbiAgICBwcml2YXRlIGFzeW5jIGZhbGxiYWNrQ3dkIChhcmdzOiBhbnkpIHtcbiAgICAgICAgaWYgKGFyZ3MuY3dkICE9PSB1bmRlZmluZWQgfHwgYXJncy5maWxlICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoYCR7cHJvY2Vzcy5jd2QoKX0vLmdpdGxhYi1jaS55bWxgKSkgcmV0dXJuO1xuICAgICAgICBpZiAoIShhd2FpdCBpc0luR2l0UmVwb3NpdG9yeSgpKSkgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMud3JpdGVTdHJlYW1zPy5zdGRlcnIoY2hhbGtge3llbGxvdyAuZ2l0bGFiLWNpLnltbCBub3QgZm91bmQgaW4gY3dkLCBmYWxsaW5nIGJhY2sgdG8gZ2l0IHJvb3QgZGlyZWN0b3J5fVxcbmApO1xuICAgICAgICB0aGlzLm1hcC5zZXQoXCJjd2RcIiwgcGF0aC5yZWxhdGl2ZShwcm9jZXNzLmN3ZCgpLCBhd2FpdCBnaXRSb290UGF0aCgpKSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGFzeW5jIGJ1aWxkIChhcmdzOiBhbnksIHdyaXRlU3RyZWFtcz86IFdyaXRlU3RyZWFtcykge1xuICAgICAgICBjb25zdCBhcmd2ID0gbmV3IEFyZ3YoYXJncywgd3JpdGVTdHJlYW1zKTtcbiAgICAgICAgYXdhaXQgYXJndi5mYWxsYmFja0N3ZChhcmdzKTtcblxuICAgICAgICBhcmd2LmluamVjdERvdGVudihgJHthcmd2LmhvbWV9Ly5naXRsYWItY2ktbG9jYWwvLmVudmAsIGFyZ3MpO1xuICAgICAgICBhcmd2LmluamVjdERvdGVudihgJHthcmd2LmN3ZH0vLmdpdGxhYi1jaS1sb2NhbC1lbnZgLCBhcmdzKTtcblxuICAgICAgICBpZiAoIWFyZ3Yuc2hlbGxFeGVjdXRvck5vSW1hZ2UgJiYgYXJndi5zaGVsbElzb2xhdGlvbikge1xuICAgICAgICAgICAgd3JpdGVTdHJlYW1zPy5zdGRlcnIoY2hhbGtge2JsYWNrLmJnWWVsbG93QnJpZ2h0ICBXQVJOIH0gLS1zaGVsbC1pc29sYXRpb24gZG9lcyBub3Qgd29yayB3aXRoIC0tbm8tc2hlbGwtZXhlY3V0b3Itbm8taW1hZ2VcXG5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhcmd2LmRlZmF1bHRJbWFnZUV4cGxpY2l0bHlTZXQgJiYgYXJndi5zaGVsbElzb2xhdGlvbikge1xuICAgICAgICAgICAgd3JpdGVTdHJlYW1zPy5zdGRlcnIoY2hhbGtge2JsYWNrLmJnWWVsbG93QnJpZ2h0ICBXQVJOIH0gLS1kZWZhdWx0LWltYWdlIGRvZXMgbm90IHdvcmsgd2l0aCAtLXNoZWxsLWlzb2xhdGlvbj10cnVlXFxuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYXJndi5kZWZhdWx0SW1hZ2VFeHBsaWNpdGx5U2V0ICYmIGFyZ3Yuc2hlbGxFeGVjdXRvck5vSW1hZ2UpIHtcbiAgICAgICAgICAgIHdyaXRlU3RyZWFtcz8uc3RkZXJyKGNoYWxrYHtibGFjay5iZ1llbGxvd0JyaWdodCAgV0FSTiB9IC0tZGVmYXVsdC1pbWFnZSBkb2VzIG5vdCB3b3JrIHdpdGggLS1zaGVsbC1leGVjdXRvci1uby1pbWFnZT10cnVlXFxuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYXJndi5kZWZhdWx0SW1hZ2VFeHBsaWNpdGx5U2V0ICYmIGFyZ3YuZm9yY2VTaGVsbEV4ZWN1dG9yKSB7XG4gICAgICAgICAgICB3cml0ZVN0cmVhbXM/LnN0ZGVycihjaGFsa2B7YmxhY2suYmdZZWxsb3dCcmlnaHQgIFdBUk4gfSAtLWRlZmF1bHQtaW1hZ2UgZG9lcyBub3Qgd29yayB3aXRoIC0tZm9yY2Utc2hlbGwtZXhlY3V0b3I9dHJ1ZVxcbmApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyZ3Y7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvciAoYXJndjogYW55LCB3cml0ZVN0cmVhbXM/OiBXcml0ZVN0cmVhbXMpIHtcbiAgICAgICAgaWYgKGFyZ3Yubm9Db2xvcikge1xuICAgICAgICAgICAgY2hhbGsubGV2ZWwgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud3JpdGVTdHJlYW1zID0gd3JpdGVTdHJlYW1zO1xuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhhcmd2KSkge1xuICAgICAgICAgICAgdGhpcy5tYXAuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbmplY3REb3RlbnYgKHBvdGVudGlhbERvdGVudkZpbGVwYXRoOiBzdHJpbmcsIGFyZ3Y6IGFueSkge1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhwb3RlbnRpYWxEb3RlbnZGaWxlcGF0aCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IGRvdGVudi5wYXJzZShmcy5yZWFkRmlsZVN5bmMocG90ZW50aWFsRG90ZW52RmlsZXBhdGgpKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGNvbmZpZykpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhcmdLZXkgPSBjYW1lbENhc2Uoa2V5KTtcblxuICAgICAgICAgICAgICAgIC8vIFNwZWNpYWwgaGFuZGxlIEtFWT1WQUxVRSB2YXJpYWJsZSBrZXlzXG4gICAgICAgICAgICAgICAgaWYgKGFyZ0tleSA9PT0gXCJ2YXJpYWJsZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBjdXJyZW50VmFsID0gYXJndlthcmdLZXldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFZhbCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50VmFsID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcC5zZXQoYXJnS2V5LCBjdXJyZW50VmFsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoY3VycmVudFZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcGFpciBvZiB2YWx1ZS5zcGxpdChcIiBcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRWYWwudW5zaGlmdChwYWlyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJndlthcmdLZXldID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gV29yayBhcm91bmQgYGRvdGVudi5wYXJzZWAgbGltaXRhdGlvbiBodHRwczovL2dpdGh1Yi5jb20vbW90ZG90bGEvZG90ZW52L2lzc3Vlcy81MSNpc3N1ZWNvbW1lbnQtNTUyNTU5MDcwXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gXCJ0cnVlXCIpIHRoaXMubWFwLnNldChhcmdLZXksIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PT0gXCJmYWxzZVwiKSB0aGlzLm1hcC5zZXQoYXJnS2V5LCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09PSBcIm51bGxcIikgdGhpcy5tYXAuc2V0KGFyZ0tleSwgbnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFpc05hTihOdW1iZXIodmFsdWUpKSkgdGhpcy5tYXAuc2V0KGFyZ0tleSwgTnVtYmVyKHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgdGhpcy5tYXAuc2V0KGFyZ0tleSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBjd2QgKCk6IHN0cmluZyB7XG4gICAgICAgIGxldCBjd2QgPSB0aGlzLm1hcC5nZXQoXCJjd2RcIikgPz8gXCIuXCI7XG4gICAgICAgIGFzc2VydCh0eXBlb2YgY3dkICE9IFwib2JqZWN0XCIsIFwiLS1jd2Qgb3B0aW9uIGNhbm5vdCBiZSBhbiBhcnJheVwiKTtcbiAgICAgICAgYXNzZXJ0KCFwYXRoLmlzQWJzb2x1dGUoY3dkKSwgXCJQbGVhc2UgdXNlIHJlbGF0aXZlIHBhdGggZm9yIHRoZSAtLWN3ZCBvcHRpb25cIik7XG4gICAgICAgIGN3ZCA9IHBhdGgubm9ybWFsaXplKGAke3Byb2Nlc3MuY3dkKCl9LyR7Y3dkfWApO1xuICAgICAgICBjd2QgPSBjd2QucmVwbGFjZSgvXFwvJC8sIFwiXCIpO1xuICAgICAgICBhc3NlcnQoZnMucGF0aEV4aXN0c1N5bmMoY3dkKSwgYCR7Y3dkfSBpcyBub3QgYSBkaXJlY3RvcnlgKTtcbiAgICAgICAgcmV0dXJuIGN3ZDtcbiAgICB9XG5cbiAgICBnZXQgdmFyaWFibGVzRmlsZSAoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcInZhcmlhYmxlc0ZpbGVcIikgPz8gQXJndi5kZWZhdWx0LnZhcmlhYmxlc0ZpbGU7XG4gICAgfVxuXG4gICAgZ2V0IGV2YWx1YXRlUnVsZUNoYW5nZXMgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiZXZhbHVhdGVSdWxlQ2hhbmdlc1wiKSA/PyBBcmd2LmRlZmF1bHQuZXZhbHVhdGVSdWxlQ2hhbmdlcztcbiAgICB9XG5cbiAgICBnZXQgZmlsZSAoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImZpbGVcIikgPz8gXCIuZ2l0bGFiLWNpLnltbFwiO1xuICAgIH1cblxuICAgIGdldCBzdGF0ZURpciAoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLm1hcC5nZXQoXCJzdGF0ZURpclwiKSA/PyBcIi5naXRsYWItY2ktbG9jYWxcIikucmVwbGFjZSgvXFwvJC8sIFwiXCIpO1xuICAgIH1cblxuICAgIGdldCBob21lICgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gKHRoaXMubWFwLmdldChcImhvbWVcIikgPz8gcHJvY2Vzcy5lbnYuSE9NRSA/PyBcIlwiKS5yZXBsYWNlKC9cXC8kLywgXCJcIik7XG4gICAgfVxuXG4gICAgZ2V0IHZvbHVtZSAoKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCB2YWwgPSB0aGlzLm1hcC5nZXQoXCJ2b2x1bWVcIikgPz8gW107XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsID09IFwic3RyaW5nXCIgPyB2YWwuc3BsaXQoXCIgXCIpIDogdmFsO1xuICAgIH1cblxuICAgIGdldCBuZXR3b3JrICgpOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMubWFwLmdldChcIm5ldHdvcmtcIikgPz8gW107XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsID09IFwic3RyaW5nXCIgPyB2YWwuc3BsaXQoXCIgXCIpIDogdmFsO1xuICAgIH1cblxuICAgIGdldCBleHRyYUhvc3QgKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgdmFsID0gdGhpcy5tYXAuZ2V0KFwiZXh0cmFIb3N0XCIpID8/IFtdO1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbCA9PSBcInN0cmluZ1wiID8gdmFsLnNwbGl0KFwiIFwiKSA6IHZhbDtcbiAgICB9XG5cbiAgICBnZXQgaWdub3JlU2NoZW1hUGF0aHMgKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImlnbm9yZVNjaGVtYVBhdGhzXCIpID8/IEFyZ3YuZGVmYXVsdC5pZ25vcmVTY2hlbWFQYXRocztcbiAgICB9XG5cbiAgICBnZXQgcHVsbFBvbGljeSAoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcInB1bGxQb2xpY3lcIikgPz8gXCJpZi1ub3QtcHJlc2VudFwiO1xuICAgIH1cblxuICAgIGdldCByZW1vdGVWYXJpYWJsZXMgKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJyZW1vdGVWYXJpYWJsZXNcIik7XG4gICAgfVxuXG4gICAgZ2V0IHZhcmlhYmxlICgpOiB7W2tleTogc3RyaW5nXTogc3RyaW5nfSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMubWFwLmdldChcInZhcmlhYmxlXCIpO1xuICAgICAgICBjb25zdCB2YXJpYWJsZXM6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9ID0ge307XG4gICAgICAgIGNvbnN0IHBhaXJzID0gdHlwZW9mIHZhbCA9PSBcInN0cmluZ1wiID8gdmFsLnNwbGl0KFwiIFwiKSA6IHZhbDtcbiAgICAgICAgKHBhaXJzID8/IFtdKS5mb3JFYWNoKCh2YXJpYWJsZVBhaXI6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXhlYyA9IC8oPzxrZXk+XFx3Kj8pKD0pKD88dmFsdWU+KC58XFxufFxccikqKS8uZXhlYyh2YXJpYWJsZVBhaXIpO1xuICAgICAgICAgICAgaWYgKGV4ZWM/Lmdyb3Vwcz8ua2V5KSB7XG4gICAgICAgICAgICAgICAgdmFyaWFibGVzW2V4ZWMuZ3JvdXBzLmtleV0gPSBleGVjPy5ncm91cHM/LnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHZhcmlhYmxlcztcbiAgICB9XG5cbiAgICBnZXQgdW5zZXRWYXJpYWJsZXMgKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcInVuc2V0VmFyaWFibGVcIikgPz8gW107XG4gICAgfVxuXG4gICAgZ2V0IG1hbnVhbCAoKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCB2YWwgPSB0aGlzLm1hcC5nZXQoXCJtYW51YWxcIikgPz8gW107XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsID09IFwic3RyaW5nXCIgPyB2YWwuc3BsaXQoXCIgXCIpIDogdmFsO1xuICAgIH1cblxuICAgIGdldCBqb2IgKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImpvYlwiKSA/PyBbXTtcbiAgICB9XG5cbiAgICBnZXQgYXV0b0NvbXBsZXRpbmcgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiYXV0b0NvbXBsZXRpbmdcIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IGNsZWFudXAgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiY2xlYW51cFwiKSA/PyB0cnVlO1xuICAgIH1cblxuICAgIGdldCBxdWlldCAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJxdWlldFwiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgdW1hc2sgKCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBUT0RPOiBkZWZhdWx0IHRvIGZhbHNlIGluIDUueC54XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJ1bWFza1wiKSA/PyB0cnVlO1xuICAgIH1cblxuICAgIGdldCBwcml2aWxlZ2VkICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcInByaXZpbGVnZWRcIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IHVsaW1pdCAoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICAgIGNvbnN0IHVsaW1pdCA9IHRoaXMubWFwLmdldChcInVsaW1pdFwiKTtcbiAgICAgICAgaWYgKCF1bGltaXQpIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gdWxpbWl0O1xuICAgIH1cblxuICAgIGdldCBuZWVkcyAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJuZWVkc1wiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgb25seU5lZWRzICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcIm9ubHlOZWVkc1wiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgc3RhZ2UgKCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwic3RhZ2VcIikgPz8gbnVsbDtcbiAgICB9XG5cbiAgICBnZXQgY29tcGxldGlvbiAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJjb21wbGV0aW9uXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBsaXN0ICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImxpc3RcIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IGxpc3RBbGwgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwibGlzdEFsbFwiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgbGlzdEpzb24gKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwibGlzdEpzb25cIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IGxpc3RDc3YgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwibGlzdENzdlwiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgbGlzdENzdkFsbCAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJsaXN0Q3N2QWxsXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBwcmV2aWV3ICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcInByZXZpZXdcIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IHNoZWxsSXNvbGF0aW9uICgpOiBib29sZWFuIHtcbiAgICAgICAgLy8gVE9ETzogZGVmYXVsdCB0byB0cnVlIGluIDUueC54XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJzaGVsbElzb2xhdGlvblwiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgZmV0Y2hJbmNsdWRlcyAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJmZXRjaEluY2x1ZGVzXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBtb3VudENhY2hlICgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcIm1vdW50Q2FjaGVcIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IGFydGlmYWN0c1RvU291cmNlICgpOiBib29sZWFuIHtcbiAgICAgICAgLy8gVE9ETzogZGVmYXVsdCB0byBmYWxzZSBpbiA1LngueFxuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiYXJ0aWZhY3RzVG9Tb3VyY2VcIikgPz8gdHJ1ZTtcbiAgICB9XG5cbiAgICBnZXQgc2hvd1RpbWVzdGFtcHMgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwidGltZXN0YW1wc1wiKSA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgbWF4Sm9iTmFtZVBhZGRpbmcgKCk6IG51bWJlciB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwibWF4Sm9iTmFtZVBhZGRpbmdcIikgPz8gbnVsbDtcbiAgICB9XG5cbiAgICBnZXQgY29udGFpbmVyTWFjQWRkcmVzcyAoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJjb250YWluZXJNYWNBZGRyZXNzXCIpID8/IG51bGw7XG4gICAgfVxuXG4gICAgZ2V0IGNvbnRhaW5lckVtdWxhdGUgKCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiY29udGFpbmVyRW11bGF0ZVwiKSA/PyBudWxsO1xuICAgIH1cblxuICAgIGdldCBjb25jdXJyZW5jeSAoKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgICAgIGNvbnN0IGNvbmN1cnJlbmN5ID0gdGhpcy5tYXAuZ2V0KFwiY29uY3VycmVuY3lcIik7XG4gICAgICAgIGlmICghY29uY3VycmVuY3kpIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gTnVtYmVyKGNvbmN1cnJlbmN5KTtcbiAgICB9XG5cbiAgICBnZXQgY29udGFpbmVyRXhlY3V0YWJsZSAoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImNvbnRhaW5lckV4ZWN1dGFibGVcIikgPz8gXCJkb2NrZXJcIjtcbiAgICB9XG5cbiAgICBnZXQganNvblNjaGVtYVZhbGlkYXRpb24gKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwianNvblNjaGVtYVZhbGlkYXRpb25cIikgPz8gdHJ1ZTtcbiAgICB9XG5cbiAgICBnZXQgc2hlbGxFeGVjdXRvck5vSW1hZ2UgKCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBUT0RPOiBkZWZhdWx0IHRvIGZhbHNlIGluIDUueC54XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJzaGVsbEV4ZWN1dG9yTm9JbWFnZVwiKSA/PyB0cnVlO1xuICAgIH1cblxuICAgIGdldCBmb3JjZVNoZWxsRXhlY3V0b3IgKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KFwiZm9yY2VTaGVsbEV4ZWN1dG9yXCIpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBkZWZhdWx0SW1hZ2UgKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJkZWZhdWx0SW1hZ2VcIikgPz8gXCJkb2NrZXIuaW8vcnVieTozLjFcIjtcbiAgICB9XG5cbiAgICBnZXQgZGVmYXVsdEltYWdlRXhwbGljaXRseVNldCAoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoXCJkZWZhdWx0SW1hZ2VcIikgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2V0IG1heGltdW1JbmNsdWRlcyAoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcIm1heGltdW1JbmNsdWRlc1wiKSA/PyAxNTA7IC8vIGh0dHBzOi8vZG9jcy5naXRsYWIuY29tL2VlL2FkbWluaXN0cmF0aW9uL3NldHRpbmdzL2NvbnRpbnVvdXNfaW50ZWdyYXRpb24uaHRtbCNtYXhpbXVtLWluY2x1ZGVzXG4gICAgfVxuXG4gICAgZ2V0IGNoaWxkUGlwZWxpbmVEZXB0aCAoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChcImNoaWxkUGlwZWxpbmVEZXB0aFwiKTtcbiAgICB9XG59XG4iXX0=