UNPKG

jsii-release

Version:

Release jsii modules to multiple package managers

231 lines 34.4 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 (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GoReleaser = void 0; const path = __importStar(require("path")); const fs = __importStar(require("fs-extra")); const git = __importStar(require("../help/git")); const os = __importStar(require("../help/os")); const shell = __importStar(require("../help/shell")); /** * Release a set of Golang modules. */ class GoReleaser { constructor(props) { var _a, _b, _c, _d, _e; if (!shell.which('git')) { throw new Error('git must be available to in order to be able to push Go code to GitHub'); } this.version = props.version; this.gitCommitMessage = props.message; this.dir = path.resolve((_a = props.dir) !== null && _a !== void 0 ? _a : path.join(process.cwd(), 'dist', 'go')); this.gitBranch = (_b = props.branch) !== null && _b !== void 0 ? _b : 'main'; this.dryRun = (_c = props.dryRun) !== null && _c !== void 0 ? _c : false; const gitUsername = (_d = props.username) !== null && _d !== void 0 ? _d : git.username(); const gitUseremail = (_e = props.email) !== null && _e !== void 0 ? _e : git.email(); if (!gitUsername) { throw new Error('Unable to detect username. either configure a git user.name or pass GIT_USER_NAME env variable'); } if (!gitUseremail) { throw new Error('Unable to detect user email. either configure a git user.email or pass GIT_USER_EMAIL env variable'); } this.gitUseremail = gitUseremail; this.gitUsername = gitUsername; } /** * Run the release process. * * @returns metadata about the release. */ release() { const modules = this.collectModules(this.dir); if (modules.length === 0) { console.log('No modules detected. Skipping'); return {}; } console.log('Detected modules:'); modules.forEach(m => console.log(` - ${m.modFile}`)); const repoURL = this.extractRepoURL(modules); const repoDir = path.join(os.mkdtempSync(), 'repo'); git.clone(repoURL, repoDir); const cwd = process.cwd(); try { process.chdir(repoDir); return this.doRelease(modules, repoDir); } finally { process.chdir(cwd); } } doRelease(modules, repoDir) { var _a; git.identify(this.gitUsername, this.gitUseremail); git.checkout(this.gitBranch, { createIfMissing: true }); this.syncRepo(repoDir); git.add('.'); if (!git.diffIndex()) { console.log('No changes. Skipping release'); return {}; } const commitMessage = (_a = this.gitCommitMessage) !== null && _a !== void 0 ? _a : this.buildReleaseMessage(modules); git.commit(commitMessage); const tags = []; for (const module of modules) { const name = this.buildTagName(module); const created = git.tag(name); if (created) { tags.push(name); } } if (tags.length === 0) { console.log('All tags already exist. Skipping release'); return {}; } const refs = [...tags, this.gitBranch]; if (this.dryRun) { console.log('==========================================='); console.log(' 🏜️ DRY-RUN MODE 🏜️'); console.log('==========================================='); refs.forEach(t => console.log(`Remote ref will be updated: ${t}`)); } else { refs.forEach(t => git.push(t)); } return { tags, commitMessage, repoDir }; } collectModules(dir) { const modules = []; for (const p of [...fs.readdirSync(dir), '.']) { const modFile = path.join(dir, p, 'go.mod'); if (fs.existsSync(modFile)) { modules.push(this.parseModule(modFile)); } } return modules; } parseModule(modFile) { const version = this.extractVersion(path.dirname(modFile)); const majorVersion = Number(version.split('.')[0]); // extract the module decleration (e.g 'module github.com/aws/constructs-go/constructs/v3') const match = fs.readFileSync(modFile).toString().match(/module (.*)/); if (!match || !match[1]) { throw new Error(`Unable to detected module declaration in ${modFile}`); } // e.g 'github.com/aws/constructs-go/constructs/v3' const cannonicalName = match[1]; // e.g ['github.com', 'aws', 'constructs-go', 'constructs', 'v3'] const cannonicalNameParts = cannonicalName.split('/'); // e.g 'github.com/aws/constructs-go' const repoURL = cannonicalNameParts.slice(0, 3).join('/'); // e.g 'v3' const majorVersionSuffix = majorVersion > 1 ? `/v${majorVersion}` : ''; if (!cannonicalName.endsWith(majorVersionSuffix)) { throw new Error(`Module declaration in '${modFile}' expected to end with '${majorVersionSuffix}' since its major version is larger than 1`); } if (!repoURL.startsWith('github.com')) { if (!(git.detectSSH() || git.detectGHE())) { throw new Error(`Repository must be hosted on github.com. Found: '${repoURL}' in ${modFile}`); } } let repoPath = cannonicalNameParts .slice(3) // e.g ['constructs', 'v3'] .join('/'); // e.g 'constructs/v3' // we could have something like // constructs/v3 // or something like // constructsv3/v3 // we only want to strip the last 'v3' const split = repoPath.split('/'); if (split[split.length - 1] === `v${majorVersion}`) { split.pop(); repoPath = split.join('/'); } // strip '/' if exists (wont exist for top level modules) repoPath = repoPath.endsWith('/') ? repoPath.substr(0, repoPath.length - 1) : repoPath; return { modFile, version, cannonicalName, repoPath, repoURL }; } buildTagName(m) { return m.repoPath === '' ? `v${m.version}` : `${m.repoPath}/v${m.version}`; } buildReleaseMessage(modules) { const semantic = 'chore(release)'; const versions = new Set(modules.map(m => m.version)); if (versions.size === 1) { // single version (e.g chore(release): v1.2.3) return `${semantic}: v${versions.values().next().value}`; } else { // multiple versions (e.g chore(release): chore(release): module1@v1.2.3 module2@v1.2.3) return `${semantic}: ${modules.map(m => `${m.repoPath ? `${m.repoPath}@` : ''}v${m.version}`).join(' ')}`; } } syncRepo(repoDir) { const topLevel = path.join(repoDir, 'go.mod'); if (fs.existsSync(topLevel)) { // with top level modules we sync the entire repository // so we just empty it out fs.readdirSync(repoDir) .filter(f => f !== '.git') .forEach(f => fs.removeSync(path.join(repoDir, f))); } else { // otherwise, we selectively remove the submodules only. for (const p of fs.readdirSync(repoDir)) { const submodule = path.join(repoDir, p, 'go.mod'); if (fs.existsSync(submodule)) { fs.removeSync(path.join(repoDir, p)); } } } fs.copySync(this.dir, repoDir, { recursive: true }); } extractRepoURL(modules) { const repos = new Set(modules.map(m => m.repoURL)); if (repos.size === 0) { throw new Error('Unable to detect repository from module files.'); } if (repos.size > 1) { throw new Error('Multiple repositories found in module files'); } return repos.values().next().value; } extractVersion(moduleDirectory) { const versionFile = path.join(moduleDirectory, 'version'); const repoVersion = this.version; const moduleVersion = fs.existsSync(versionFile) ? fs.readFileSync(versionFile).toString() : undefined; if (repoVersion && moduleVersion && repoVersion !== moduleVersion) { throw new Error(`Repo version (${repoVersion}) conflicts with module version (${moduleVersion}) for module in ${moduleDirectory}`); } // just take the one thats defined, they have to the same if both are. const version = moduleVersion ? moduleVersion : repoVersion; if (!version) { throw new Error(`Unable to determine version of module ${moduleDirectory}. ` + "Either include a 'version' file, or specify a global version using the VERSION environment variable."); } return version; } } exports.GoReleaser = GoReleaser; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ28uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGFyZ2V0cy9nby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJDQUE2QjtBQUM3Qiw2Q0FBK0I7QUFDL0IsaURBQW1DO0FBQ25DLCtDQUFpQztBQUNqQyxxREFBdUM7QUE0R3ZDOztHQUVHO0FBQ0gsTUFBYSxVQUFVO0lBV3JCLFlBQVksS0FBc0I7O1FBRWhDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0VBQXdFLENBQUMsQ0FBQztTQUMzRjtRQUVELElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUM3QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUN0QyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBQSxLQUFLLENBQUMsR0FBRyxtQ0FBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUM3RSxJQUFJLENBQUMsU0FBUyxHQUFHLE1BQUEsS0FBSyxDQUFDLE1BQU0sbUNBQUksTUFBTSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBQSxLQUFLLENBQUMsTUFBTSxtQ0FBSSxLQUFLLENBQUM7UUFFcEMsTUFBTSxXQUFXLEdBQUcsTUFBQSxLQUFLLENBQUMsUUFBUSxtQ0FBSSxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDckQsTUFBTSxZQUFZLEdBQUcsTUFBQSxLQUFLLENBQUMsS0FBSyxtQ0FBSSxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFaEQsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLGdHQUFnRyxDQUFDLENBQUM7U0FDbkg7UUFFRCxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0dBQW9HLENBQUMsQ0FBQztTQUN2SDtRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksT0FBTztRQUNaLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzlDLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDeEIsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1lBQzdDLE9BQU8sRUFBRSxDQUFDO1NBQ1g7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDakMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXJELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDcEQsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFNUIsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQzFCLElBQUk7WUFDRixPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3ZCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7U0FDekM7Z0JBQVM7WUFDUixPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ3BCO0lBRUgsQ0FBQztJQUVPLFNBQVMsQ0FBQyxPQUFtQixFQUFFLE9BQWU7O1FBRXBELEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDbEQsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUV2QixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsRUFBRTtZQUNwQixPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixDQUFDLENBQUM7WUFDNUMsT0FBTyxFQUFFLENBQUM7U0FDWDtRQUVELE1BQU0sYUFBYSxHQUFHLE1BQUEsSUFBSSxDQUFDLGdCQUFnQixtQ0FBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakYsR0FBRyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUUxQixNQUFNLElBQUksR0FBRyxFQUFFLENBQUM7UUFDaEIsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUU7WUFDNUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN2QyxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzlCLElBQUksT0FBTyxFQUFFO2dCQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7YUFBRTtTQUNsQztRQUVELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDckIsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO1lBQ3hELE9BQU8sRUFBRSxDQUFDO1NBQ1g7UUFFRCxNQUFNLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUV2QyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDZixPQUFPLENBQUMsR0FBRyxDQUFDLDZDQUE2QyxDQUFDLENBQUM7WUFDM0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1lBQ2hELE9BQU8sQ0FBQyxHQUFHLENBQUMsNkNBQTZDLENBQUMsQ0FBQztZQUMzRCxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQ3BFO2FBQU07WUFDTCxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2hDO1FBQ0QsT0FBTyxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVPLGNBQWMsQ0FBQyxHQUFXO1FBQ2hDLE1BQU0sT0FBTyxHQUFlLEVBQUUsQ0FBQztRQUMvQixLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFO1lBQzdDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUM1QyxJQUFJLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQzFCLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2FBQ3pDO1NBQ0Y7UUFDRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRU8sV0FBVyxDQUFDLE9BQWU7UUFFakMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDM0QsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVuRCwyRkFBMkY7UUFDM0YsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLDRDQUE0QyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1NBQ3hFO1FBRUQsbURBQW1EO1FBQ25ELE1BQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVoQyxpRUFBaUU7UUFDakUsTUFBTSxtQkFBbUIsR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXRELHFDQUFxQztRQUNyQyxNQUFNLE9BQU8sR0FBRyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUUxRCxXQUFXO1FBQ1gsTUFBTSxrQkFBa0IsR0FBRyxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFFdkUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQUMsRUFBRTtZQUNoRCxNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixPQUFPLDJCQUEyQixrQkFBa0IsNENBQTRDLENBQUMsQ0FBQztTQUM3STtRQUVELElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxFQUFFO1lBQ3JDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsSUFBSSxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRTtnQkFDekMsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsT0FBTyxRQUFRLE9BQU8sRUFBRSxDQUFDLENBQUM7YUFDL0Y7U0FDRjtRQUNELElBQUksUUFBUSxHQUFHLG1CQUFtQjthQUMvQixLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsMkJBQTJCO2FBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLHNCQUFzQjtRQUVwQywrQkFBK0I7UUFDL0IsZ0JBQWdCO1FBQ2hCLG9CQUFvQjtRQUNwQixrQkFBa0I7UUFDbEIsc0NBQXNDO1FBQ3RDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbEMsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxJQUFJLFlBQVksRUFBRSxFQUFFO1lBQ2xELEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNaLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQzVCO1FBRUQseURBQXlEO1FBQ3pELFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7UUFFdkYsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQztJQUVqRSxDQUFDO0lBRU8sWUFBWSxDQUFDLENBQVc7UUFDOUIsT0FBTyxDQUFDLENBQUMsUUFBUSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDN0UsQ0FBQztJQUVPLG1CQUFtQixDQUFDLE9BQW1CO1FBQzdDLE1BQU0sUUFBUSxHQUFHLGdCQUFnQixDQUFDO1FBQ2xDLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUN0RCxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFFO1lBQ3ZCLDhDQUE4QztZQUM5QyxPQUFPLEdBQUcsUUFBUSxNQUFNLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztTQUMxRDthQUFNO1lBQ0wseUZBQXlGO1lBQ3pGLE9BQU8sR0FBRyxRQUFRLEtBQUssT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztTQUMzRztJQUNILENBQUM7SUFFTyxRQUFRLENBQUMsT0FBZTtRQUM5QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM5QyxJQUFJLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUU7WUFDM0IsdURBQXVEO1lBQ3ZELDBCQUEwQjtZQUMxQixFQUFFLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQztpQkFDcEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLE1BQU0sQ0FBQztpQkFDekIsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDdkQ7YUFBTTtZQUNMLHdEQUF3RDtZQUN4RCxLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ3ZDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDbEQsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFO29CQUM1QixFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ3RDO2FBQ0Y7U0FDRjtRQUNELEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRU8sY0FBYyxDQUFDLE9BQW1CO1FBQ3hDLE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxDQUFTLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUMzRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFFO1lBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztTQUNuRTtRQUNELElBQUksS0FBSyxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUU7WUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1NBQ2hFO1FBQ0QsT0FBTyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDO0lBQ3JDLENBQUM7SUFFTyxjQUFjLENBQUMsZUFBdUI7UUFFNUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFMUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUNqQyxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFFdkcsSUFBSSxXQUFXLElBQUksYUFBYSxJQUFJLFdBQVcsS0FBSyxhQUFhLEVBQUU7WUFDakUsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsV0FBVyxvQ0FBb0MsYUFBYSxtQkFBbUIsZUFBZSxFQUFFLENBQUMsQ0FBQztTQUNwSTtRQUVELHNFQUFzRTtRQUN0RSxNQUFNLE9BQU8sR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO1FBRTVELElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDWixNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxlQUFlLElBQUk7a0JBQ3hFLHNHQUFzRyxDQUFDLENBQUM7U0FDN0c7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUVqQixDQUFDO0NBRUY7QUFsUEQsZ0NBa1BDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCAqIGFzIGdpdCBmcm9tICcuLi9oZWxwL2dpdCc7XG5pbXBvcnQgKiBhcyBvcyBmcm9tICcuLi9oZWxwL29zJztcbmltcG9ydCAqIGFzIHNoZWxsIGZyb20gJy4uL2hlbHAvc2hlbGwnO1xuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBzb21lIGluZm9ybWF0aW9uIGFib3V0IHRoZSByZWxlYXNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdvUmVsZWFzZSB7XG5cbiAgLyoqXG4gICAqIFRoZSB0YWdzIHRoZSByZWxlYXNlIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkb25seSB0YWdzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFRoZSBjb21taXQgbWVzc2FnZSBvZiB0aGUgcmVsZWFzZS5cbiAgICovXG4gIHJlYWRvbmx5IGNvbW1pdE1lc3NhZ2U/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBkaXJlY3Rvcnkgd2hlcmUgdGhlIHJlcG9zaXRvcnkgd2FzIHJlbGVhc2VkIGZyb20uXG4gICAqL1xuICByZWFkb25seSByZXBvRGlyPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGBHb1JlbGVhc2VyYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHb1JlbGVhc2VyUHJvcHMge1xuXG4gIC8qKlxuICAgKiBUaGUgc291cmNlIGNvZGUgZGlyZWN0b3J5LlxuICAgKlxuICAgKiBAZGVmYXVsdCAnZGlzdC9nbydcbiAgICovXG4gIHJlYWRvbmx5IGRpcj86IHN0cmluZztcblxuICAvKipcbiAgICogRXhlY3V0ZSBhIGRyeSBydW4gb25seS5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGRyeVJ1bj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBicmFuY2ggdG8gcHVzaCB0by5cbiAgICpcbiAgICogQGRlZmF1bHQgJ21haW4nXG4gICAqL1xuICByZWFkb25seSBicmFuY2g/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB1c2VybmFtZSB0byB1c2UgZm9yIHRoZSBjb21taXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGFrZW4gZnJvbSBnaXQgY29uZmlnLiB0aHJvd3MgaWYgbm90IGNvbmZpZ3VyZWQuXG4gICAqL1xuICByZWFkb25seSB1c2VybmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGVtYWlsIHRvIHVzZSBmb3IgdGhlIGNvbW1pdC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0YWtlbiBmcm9tIGdpdCBjb25maWcuIHRocm93cyBpZiBub3QgY29uZmlndXJlZC5cbiAgICovXG4gIHJlYWRvbmx5IGVtYWlsPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgdmVyc2lvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0YWtlbiBmcm9tIHRoZSAndmVyc2lvbicuIHRocm93cyBpZiBkb2Vzbid0IGV4aXN0LlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG1lc3NhZ2UgdG8gdXNlIGZvciB0aGUgY29tbWl0IG1hcmtpbmcgdGhlIHJlbGVhc2UuXG4gICAqL1xuICByZWFkb25seSBtZXNzYWdlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEluZm9ybWF0aW9uIGFib3V0IGEgc3BlY2lmaWMgbW9kdWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdvTW9kdWxlIHtcblxuICAvKipcbiAgICogUGF0aCB0byB0aGUgbW9kIGZpbGUuXG4gICAqL1xuICByZWFkb25seSBtb2RGaWxlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB2ZXJzaW9uIG9mIHRoZSBtb2R1bGUuXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBjYW5ub25pY2FsIG5hbWUgb2YgdGhlIG1vZHVsZS4gKGUuZyAnZ2l0aHViLmNvbS9hd3MvY29uc3RydWN0cy1nby9jb25zdHJ1Y3RzL3YzYClcbiAgICovXG4gIHJlYWRvbmx5IGNhbm5vbmljYWxOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwYXRoIGluc2lkZSB0aGUgcmVwb3NpdG9yeSB0aGUgbW9kdWxlIGlzIGxvY2F0ZWQgaW4uIChlLmcgJ2NvbnN0cnVjdHMnKVxuICAgKi9cbiAgcmVhZG9ubHkgcmVwb1BhdGg6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlcG9zaXRvcnkgVVJMLiAoZS5nICdnaXRodWIuY29tL2F3cy9jb25zdHJ1Y3RzJylcbiAgICovXG4gIHJlYWRvbmx5IHJlcG9VUkw6IHN0cmluZztcblxufVxuXG4vKipcbiAqIFJlbGVhc2UgYSBzZXQgb2YgR29sYW5nIG1vZHVsZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBHb1JlbGVhc2VyIHtcblxuICBwcml2YXRlIHJlYWRvbmx5IHZlcnNpb24/OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ2l0Q29tbWl0TWVzc2FnZT86IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IGRpcjogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGRyeVJ1bjogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSBnaXRCcmFuY2g6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBnaXRVc2VybmFtZTogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGdpdFVzZXJlbWFpbDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBHb1JlbGVhc2VyUHJvcHMpIHtcblxuICAgIGlmICghc2hlbGwud2hpY2goJ2dpdCcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dpdCBtdXN0IGJlIGF2YWlsYWJsZSB0byBpbiBvcmRlciB0byBiZSBhYmxlIHRvIHB1c2ggR28gY29kZSB0byBHaXRIdWInKTtcbiAgICB9XG5cbiAgICB0aGlzLnZlcnNpb24gPSBwcm9wcy52ZXJzaW9uO1xuICAgIHRoaXMuZ2l0Q29tbWl0TWVzc2FnZSA9IHByb3BzLm1lc3NhZ2U7XG4gICAgdGhpcy5kaXIgPSBwYXRoLnJlc29sdmUocHJvcHMuZGlyID8/IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnZGlzdCcsICdnbycpKTtcbiAgICB0aGlzLmdpdEJyYW5jaCA9IHByb3BzLmJyYW5jaCA/PyAnbWFpbic7XG4gICAgdGhpcy5kcnlSdW4gPSBwcm9wcy5kcnlSdW4gPz8gZmFsc2U7XG5cbiAgICBjb25zdCBnaXRVc2VybmFtZSA9IHByb3BzLnVzZXJuYW1lID8/IGdpdC51c2VybmFtZSgpO1xuICAgIGNvbnN0IGdpdFVzZXJlbWFpbCA9IHByb3BzLmVtYWlsID8/IGdpdC5lbWFpbCgpO1xuXG4gICAgaWYgKCFnaXRVc2VybmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZGV0ZWN0IHVzZXJuYW1lLiBlaXRoZXIgY29uZmlndXJlIGEgZ2l0IHVzZXIubmFtZSBvciBwYXNzIEdJVF9VU0VSX05BTUUgZW52IHZhcmlhYmxlJyk7XG4gICAgfVxuXG4gICAgaWYgKCFnaXRVc2VyZW1haWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRldGVjdCB1c2VyIGVtYWlsLiBlaXRoZXIgY29uZmlndXJlIGEgZ2l0IHVzZXIuZW1haWwgb3IgcGFzcyBHSVRfVVNFUl9FTUFJTCBlbnYgdmFyaWFibGUnKTtcbiAgICB9XG5cbiAgICB0aGlzLmdpdFVzZXJlbWFpbCA9IGdpdFVzZXJlbWFpbDtcbiAgICB0aGlzLmdpdFVzZXJuYW1lID0gZ2l0VXNlcm5hbWU7XG4gIH1cblxuICAvKipcbiAgICogUnVuIHRoZSByZWxlYXNlIHByb2Nlc3MuXG4gICAqXG4gICAqIEByZXR1cm5zIG1ldGFkYXRhIGFib3V0IHRoZSByZWxlYXNlLlxuICAgKi9cbiAgcHVibGljIHJlbGVhc2UoKTogR29SZWxlYXNlIHtcbiAgICBjb25zdCBtb2R1bGVzID0gdGhpcy5jb2xsZWN0TW9kdWxlcyh0aGlzLmRpcik7XG4gICAgaWYgKG1vZHVsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zb2xlLmxvZygnTm8gbW9kdWxlcyBkZXRlY3RlZC4gU2tpcHBpbmcnKTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZygnRGV0ZWN0ZWQgbW9kdWxlczonKTtcbiAgICBtb2R1bGVzLmZvckVhY2gobSA9PiBjb25zb2xlLmxvZyhgIC0gJHttLm1vZEZpbGV9YCkpO1xuXG4gICAgY29uc3QgcmVwb1VSTCA9IHRoaXMuZXh0cmFjdFJlcG9VUkwobW9kdWxlcyk7XG4gICAgY29uc3QgcmVwb0RpciA9IHBhdGguam9pbihvcy5ta2R0ZW1wU3luYygpLCAncmVwbycpO1xuICAgIGdpdC5jbG9uZShyZXBvVVJMLCByZXBvRGlyKTtcblxuICAgIGNvbnN0IGN3ZCA9IHByb2Nlc3MuY3dkKCk7XG4gICAgdHJ5IHtcbiAgICAgIHByb2Nlc3MuY2hkaXIocmVwb0Rpcik7XG4gICAgICByZXR1cm4gdGhpcy5kb1JlbGVhc2UobW9kdWxlcywgcmVwb0Rpcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHByb2Nlc3MuY2hkaXIoY3dkKTtcbiAgICB9XG5cbiAgfVxuXG4gIHByaXZhdGUgZG9SZWxlYXNlKG1vZHVsZXM6IEdvTW9kdWxlW10sIHJlcG9EaXI6IHN0cmluZyk6IEdvUmVsZWFzZSB7XG5cbiAgICBnaXQuaWRlbnRpZnkodGhpcy5naXRVc2VybmFtZSwgdGhpcy5naXRVc2VyZW1haWwpO1xuICAgIGdpdC5jaGVja291dCh0aGlzLmdpdEJyYW5jaCwgeyBjcmVhdGVJZk1pc3Npbmc6IHRydWUgfSk7XG4gICAgdGhpcy5zeW5jUmVwbyhyZXBvRGlyKTtcblxuICAgIGdpdC5hZGQoJy4nKTtcbiAgICBpZiAoIWdpdC5kaWZmSW5kZXgoKSkge1xuICAgICAgY29uc29sZS5sb2coJ05vIGNoYW5nZXMuIFNraXBwaW5nIHJlbGVhc2UnKTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBjb25zdCBjb21taXRNZXNzYWdlID0gdGhpcy5naXRDb21taXRNZXNzYWdlID8/IHRoaXMuYnVpbGRSZWxlYXNlTWVzc2FnZShtb2R1bGVzKTtcbiAgICBnaXQuY29tbWl0KGNvbW1pdE1lc3NhZ2UpO1xuXG4gICAgY29uc3QgdGFncyA9IFtdO1xuICAgIGZvciAoY29uc3QgbW9kdWxlIG9mIG1vZHVsZXMpIHtcbiAgICAgIGNvbnN0IG5hbWUgPSB0aGlzLmJ1aWxkVGFnTmFtZShtb2R1bGUpO1xuICAgICAgY29uc3QgY3JlYXRlZCA9IGdpdC50YWcobmFtZSk7XG4gICAgICBpZiAoY3JlYXRlZCkgeyB0YWdzLnB1c2gobmFtZSk7IH1cbiAgICB9XG5cbiAgICBpZiAodGFncy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUubG9nKCdBbGwgdGFncyBhbHJlYWR5IGV4aXN0LiBTa2lwcGluZyByZWxlYXNlJyk7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgY29uc3QgcmVmcyA9IFsuLi50YWdzLCB0aGlzLmdpdEJyYW5jaF07XG5cbiAgICBpZiAodGhpcy5kcnlSdW4pIHtcbiAgICAgIGNvbnNvbGUubG9nKCc9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Jyk7XG4gICAgICBjb25zb2xlLmxvZygnICAgICAgICAgICAg8J+PnO+4jyBEUlktUlVOIE1PREUg8J+PnO+4jycpO1xuICAgICAgY29uc29sZS5sb2coJz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0nKTtcbiAgICAgIHJlZnMuZm9yRWFjaCh0ID0+IGNvbnNvbGUubG9nKGBSZW1vdGUgcmVmIHdpbGwgYmUgdXBkYXRlZDogJHt0fWApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVmcy5mb3JFYWNoKHQgPT4gZ2l0LnB1c2godCkpO1xuICAgIH1cbiAgICByZXR1cm4geyB0YWdzLCBjb21taXRNZXNzYWdlLCByZXBvRGlyIH07XG4gIH1cblxuICBwcml2YXRlIGNvbGxlY3RNb2R1bGVzKGRpcjogc3RyaW5nKTogR29Nb2R1bGVbXSB7XG4gICAgY29uc3QgbW9kdWxlczogR29Nb2R1bGVbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgcCBvZiBbLi4uZnMucmVhZGRpclN5bmMoZGlyKSwgJy4nXSkge1xuICAgICAgY29uc3QgbW9kRmlsZSA9IHBhdGguam9pbihkaXIsIHAsICdnby5tb2QnKTtcbiAgICAgIGlmIChmcy5leGlzdHNTeW5jKG1vZEZpbGUpKSB7XG4gICAgICAgIG1vZHVsZXMucHVzaCh0aGlzLnBhcnNlTW9kdWxlKG1vZEZpbGUpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1vZHVsZXM7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTW9kdWxlKG1vZEZpbGU6IHN0cmluZyk6IEdvTW9kdWxlIHtcblxuICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLmV4dHJhY3RWZXJzaW9uKHBhdGguZGlybmFtZShtb2RGaWxlKSk7XG4gICAgY29uc3QgbWFqb3JWZXJzaW9uID0gTnVtYmVyKHZlcnNpb24uc3BsaXQoJy4nKVswXSk7XG5cbiAgICAvLyBleHRyYWN0IHRoZSBtb2R1bGUgZGVjbGVyYXRpb24gKGUuZyAnbW9kdWxlIGdpdGh1Yi5jb20vYXdzL2NvbnN0cnVjdHMtZ28vY29uc3RydWN0cy92MycpXG4gICAgY29uc3QgbWF0Y2ggPSBmcy5yZWFkRmlsZVN5bmMobW9kRmlsZSkudG9TdHJpbmcoKS5tYXRjaCgvbW9kdWxlICguKikvKTtcbiAgICBpZiAoIW1hdGNoIHx8ICFtYXRjaFsxXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gZGV0ZWN0ZWQgbW9kdWxlIGRlY2xhcmF0aW9uIGluICR7bW9kRmlsZX1gKTtcbiAgICB9XG5cbiAgICAvLyBlLmcgJ2dpdGh1Yi5jb20vYXdzL2NvbnN0cnVjdHMtZ28vY29uc3RydWN0cy92MydcbiAgICBjb25zdCBjYW5ub25pY2FsTmFtZSA9IG1hdGNoWzFdO1xuXG4gICAgLy8gZS5nIFsnZ2l0aHViLmNvbScsICdhd3MnLCAnY29uc3RydWN0cy1nbycsICdjb25zdHJ1Y3RzJywgJ3YzJ11cbiAgICBjb25zdCBjYW5ub25pY2FsTmFtZVBhcnRzID0gY2Fubm9uaWNhbE5hbWUuc3BsaXQoJy8nKTtcblxuICAgIC8vIGUuZyAnZ2l0aHViLmNvbS9hd3MvY29uc3RydWN0cy1nbydcbiAgICBjb25zdCByZXBvVVJMID0gY2Fubm9uaWNhbE5hbWVQYXJ0cy5zbGljZSgwLCAzKS5qb2luKCcvJyk7XG5cbiAgICAvLyBlLmcgJ3YzJ1xuICAgIGNvbnN0IG1ham9yVmVyc2lvblN1ZmZpeCA9IG1ham9yVmVyc2lvbiA+IDEgPyBgL3Yke21ham9yVmVyc2lvbn1gIDogJyc7XG5cbiAgICBpZiAoIWNhbm5vbmljYWxOYW1lLmVuZHNXaXRoKG1ham9yVmVyc2lvblN1ZmZpeCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kdWxlIGRlY2xhcmF0aW9uIGluICcke21vZEZpbGV9JyBleHBlY3RlZCB0byBlbmQgd2l0aCAnJHttYWpvclZlcnNpb25TdWZmaXh9JyBzaW5jZSBpdHMgbWFqb3IgdmVyc2lvbiBpcyBsYXJnZXIgdGhhbiAxYCk7XG4gICAgfVxuXG4gICAgaWYgKCFyZXBvVVJMLnN0YXJ0c1dpdGgoJ2dpdGh1Yi5jb20nKSkge1xuICAgICAgaWYgKCEoZ2l0LmRldGVjdFNTSCgpIHx8IGdpdC5kZXRlY3RHSEUoKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXBvc2l0b3J5IG11c3QgYmUgaG9zdGVkIG9uIGdpdGh1Yi5jb20uIEZvdW5kOiAnJHtyZXBvVVJMfScgaW4gJHttb2RGaWxlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBsZXQgcmVwb1BhdGggPSBjYW5ub25pY2FsTmFtZVBhcnRzXG4gICAgICAuc2xpY2UoMykgLy8gZS5nIFsnY29uc3RydWN0cycsICd2MyddXG4gICAgICAuam9pbignLycpOyAvLyBlLmcgJ2NvbnN0cnVjdHMvdjMnXG5cbiAgICAvLyB3ZSBjb3VsZCBoYXZlIHNvbWV0aGluZyBsaWtlXG4gICAgLy8gY29uc3RydWN0cy92M1xuICAgIC8vIG9yIHNvbWV0aGluZyBsaWtlXG4gICAgLy8gY29uc3RydWN0c3YzL3YzXG4gICAgLy8gd2Ugb25seSB3YW50IHRvIHN0cmlwIHRoZSBsYXN0ICd2MydcbiAgICBjb25zdCBzcGxpdCA9IHJlcG9QYXRoLnNwbGl0KCcvJyk7XG4gICAgaWYgKHNwbGl0W3NwbGl0Lmxlbmd0aCAtIDFdID09PSBgdiR7bWFqb3JWZXJzaW9ufWApIHtcbiAgICAgIHNwbGl0LnBvcCgpO1xuICAgICAgcmVwb1BhdGggPSBzcGxpdC5qb2luKCcvJyk7XG4gICAgfVxuXG4gICAgLy8gc3RyaXAgJy8nIGlmIGV4aXN0cyAod29udCBleGlzdCBmb3IgdG9wIGxldmVsIG1vZHVsZXMpXG4gICAgcmVwb1BhdGggPSByZXBvUGF0aC5lbmRzV2l0aCgnLycpID8gcmVwb1BhdGguc3Vic3RyKDAsIHJlcG9QYXRoLmxlbmd0aCAtIDEpIDogcmVwb1BhdGg7XG5cbiAgICByZXR1cm4geyBtb2RGaWxlLCB2ZXJzaW9uLCBjYW5ub25pY2FsTmFtZSwgcmVwb1BhdGgsIHJlcG9VUkwgfTtcblxuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFRhZ05hbWUobTogR29Nb2R1bGUpIHtcbiAgICByZXR1cm4gbS5yZXBvUGF0aCA9PT0gJycgPyBgdiR7bS52ZXJzaW9ufWAgOiBgJHttLnJlcG9QYXRofS92JHttLnZlcnNpb259YDtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRSZWxlYXNlTWVzc2FnZShtb2R1bGVzOiBHb01vZHVsZVtdKSB7XG4gICAgY29uc3Qgc2VtYW50aWMgPSAnY2hvcmUocmVsZWFzZSknO1xuICAgIGNvbnN0IHZlcnNpb25zID0gbmV3IFNldChtb2R1bGVzLm1hcChtID0+IG0udmVyc2lvbikpO1xuICAgIGlmICh2ZXJzaW9ucy5zaXplID09PSAxKSB7XG4gICAgICAvLyBzaW5nbGUgdmVyc2lvbiAoZS5nIGNob3JlKHJlbGVhc2UpOiB2MS4yLjMpXG4gICAgICByZXR1cm4gYCR7c2VtYW50aWN9OiB2JHt2ZXJzaW9ucy52YWx1ZXMoKS5uZXh0KCkudmFsdWV9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbXVsdGlwbGUgdmVyc2lvbnMgKGUuZyBjaG9yZShyZWxlYXNlKTogY2hvcmUocmVsZWFzZSk6IG1vZHVsZTFAdjEuMi4zICBtb2R1bGUyQHYxLjIuMylcbiAgICAgIHJldHVybiBgJHtzZW1hbnRpY306ICR7bW9kdWxlcy5tYXAobSA9PiBgJHttLnJlcG9QYXRoID8gYCR7bS5yZXBvUGF0aH1AYCA6ICcnfXYke20udmVyc2lvbn1gKS5qb2luKCcgJyl9YDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN5bmNSZXBvKHJlcG9EaXI6IHN0cmluZykge1xuICAgIGNvbnN0IHRvcExldmVsID0gcGF0aC5qb2luKHJlcG9EaXIsICdnby5tb2QnKTtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyh0b3BMZXZlbCkpIHtcbiAgICAgIC8vIHdpdGggdG9wIGxldmVsIG1vZHVsZXMgd2Ugc3luYyB0aGUgZW50aXJlIHJlcG9zaXRvcnlcbiAgICAgIC8vIHNvIHdlIGp1c3QgZW1wdHkgaXQgb3V0XG4gICAgICBmcy5yZWFkZGlyU3luYyhyZXBvRGlyKVxuICAgICAgICAuZmlsdGVyKGYgPT4gZiAhPT0gJy5naXQnKVxuICAgICAgICAuZm9yRWFjaChmID0+IGZzLnJlbW92ZVN5bmMocGF0aC5qb2luKHJlcG9EaXIsIGYpKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG90aGVyd2lzZSwgd2Ugc2VsZWN0aXZlbHkgcmVtb3ZlIHRoZSBzdWJtb2R1bGVzIG9ubHkuXG4gICAgICBmb3IgKGNvbnN0IHAgb2YgZnMucmVhZGRpclN5bmMocmVwb0RpcikpIHtcbiAgICAgICAgY29uc3Qgc3VibW9kdWxlID0gcGF0aC5qb2luKHJlcG9EaXIsIHAsICdnby5tb2QnKTtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoc3VibW9kdWxlKSkge1xuICAgICAgICAgIGZzLnJlbW92ZVN5bmMocGF0aC5qb2luKHJlcG9EaXIsIHApKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBmcy5jb3B5U3luYyh0aGlzLmRpciwgcmVwb0RpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RSZXBvVVJMKG1vZHVsZXM6IEdvTW9kdWxlW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHJlcG9zID0gbmV3IFNldDxzdHJpbmc+KG1vZHVsZXMubWFwKG0gPT4gbS5yZXBvVVJMKSk7XG4gICAgaWYgKHJlcG9zLnNpemUgPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRldGVjdCByZXBvc2l0b3J5IGZyb20gbW9kdWxlIGZpbGVzLicpO1xuICAgIH1cbiAgICBpZiAocmVwb3Muc2l6ZSA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTXVsdGlwbGUgcmVwb3NpdG9yaWVzIGZvdW5kIGluIG1vZHVsZSBmaWxlcycpO1xuICAgIH1cbiAgICByZXR1cm4gcmVwb3MudmFsdWVzKCkubmV4dCgpLnZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0VmVyc2lvbihtb2R1bGVEaXJlY3Rvcnk6IHN0cmluZyk6IHN0cmluZyB7XG5cbiAgICBjb25zdCB2ZXJzaW9uRmlsZSA9IHBhdGguam9pbihtb2R1bGVEaXJlY3RvcnksICd2ZXJzaW9uJyk7XG5cbiAgICBjb25zdCByZXBvVmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICBjb25zdCBtb2R1bGVWZXJzaW9uID0gZnMuZXhpc3RzU3luYyh2ZXJzaW9uRmlsZSkgPyBmcy5yZWFkRmlsZVN5bmModmVyc2lvbkZpbGUpLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAocmVwb1ZlcnNpb24gJiYgbW9kdWxlVmVyc2lvbiAmJiByZXBvVmVyc2lvbiAhPT0gbW9kdWxlVmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXBvIHZlcnNpb24gKCR7cmVwb1ZlcnNpb259KSBjb25mbGljdHMgd2l0aCBtb2R1bGUgdmVyc2lvbiAoJHttb2R1bGVWZXJzaW9ufSkgZm9yIG1vZHVsZSBpbiAke21vZHVsZURpcmVjdG9yeX1gKTtcbiAgICB9XG5cbiAgICAvLyBqdXN0IHRha2UgdGhlIG9uZSB0aGF0cyBkZWZpbmVkLCB0aGV5IGhhdmUgdG8gdGhlIHNhbWUgaWYgYm90aCBhcmUuXG4gICAgY29uc3QgdmVyc2lvbiA9IG1vZHVsZVZlcnNpb24gPyBtb2R1bGVWZXJzaW9uIDogcmVwb1ZlcnNpb247XG5cbiAgICBpZiAoIXZlcnNpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGRldGVybWluZSB2ZXJzaW9uIG9mIG1vZHVsZSAke21vZHVsZURpcmVjdG9yeX0uIGBcbiAgICAgICAgKyBcIkVpdGhlciBpbmNsdWRlIGEgJ3ZlcnNpb24nIGZpbGUsIG9yIHNwZWNpZnkgYSBnbG9iYWwgdmVyc2lvbiB1c2luZyB0aGUgVkVSU0lPTiBlbnZpcm9ubWVudCB2YXJpYWJsZS5cIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZlcnNpb247XG5cbiAgfVxuXG59XG4iXX0=