"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.onAfterBuild = exports.onBeforeBuild = exports.throwError = void 0; /** * 构建进程(独立 worker)加载的钩子脚本;custom-builder 的 configs.*.hooks 指向本文件。 * custom-builder.ts 会 re-export 本文件的钩子,供编辑器校验通过。 */ const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const lz4js_1 = __importDefault(require("lz4js")); const terser_1 = require("terser"); exports.throwError = true; function readJson(filePath) { const raw = fs_1.default.readFileSync(filePath, 'utf8'); return JSON.parse(raw); } /** 解析 game.json;若尾部被旧内容污染则截取首个完整 JSON 对象 */ function readGameJsonSafe(filePath) { const raw = fs_1.default.readFileSync(filePath, 'utf8').trim(); try { return JSON.parse(raw); } catch (err) { const start = raw.indexOf('{'); if (start < 0) throw err; let depth = 0; let end = -1; for (let i = start; i < raw.length; i++) { const ch = raw[i]; if (ch === '{') depth++; else if (ch === '}') { depth--; if (depth === 0) { end = i; break; } } } if (end > start) { const recovered = raw.slice(start, end + 1); console.warn(`[tools] game.json 含脏数据,已自动截取有效 JSON: ${filePath}`); return JSON.parse(recovered); } throw err; } } function writeJsonFile(filePath, data) { const content = `${JSON.stringify(data, null, 2)}\n`; const tmp = `${filePath}.tmp`; fs_1.default.writeFileSync(tmp, content, 'utf8'); fs_1.default.renameSync(tmp, filePath); } function resolveConfigNameVersion(projectPath) { var _a, _b, _c, _d, _e, _f; const sdkConfigPath = path_1.default.join(projectPath, 'assets', 'script', 'sdk', 'sdkConfig.ts'); const sdkConfigContent = fs_1.default.readFileSync(sdkConfigPath, 'utf8'); const importRegex = /import\s+\{\s*(\w+)\s*\}\s+from\s+["']\.\/config\/([^"']+)["'];?/g; const importMap = new Map(); let m = null; while ((m = importRegex.exec(sdkConfigContent))) { importMap.set(m[1], m[2]); } const configAssign = sdkConfigContent.match(/static\s+readonly\s+config\s*:\s*IConfigData\s*=\s*(\w+)\s*;/); const symbol = (_a = configAssign === null || configAssign === void 0 ? void 0 : configAssign[1]) !== null && _a !== void 0 ? _a : 'DefaultConfig'; const relConfig = (_b = importMap.get(symbol)) !== null && _b !== void 0 ? _b : 'DefaultConfig'; const configPath = path_1.default.join(projectPath, 'assets', 'script', 'sdk', 'config', `${relConfig}.ts`); const configContent = fs_1.default.readFileSync(configPath, 'utf8'); const name = (_d = (_c = configContent.match(/name\s*:\s*["']([^"']+)["']/)) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : 'config'; const vsion = (_f = (_e = configContent.match(/vsion\s*:\s*["']([^"']+)["']/)) === null || _e === void 0 ? void 0 : _e[1]) !== null && _f !== void 0 ? _f : '0.0.0'; return { name, vsion }; } function encodeForRuntime(jsonObj) { const jsonString = JSON.stringify(jsonObj); const uint8 = new TextEncoder().encode(jsonString); const compressed = Uint8Array.from(lz4js_1.default.compress(uint8)); const binary = Buffer.from(compressed).toString('latin1'); const base64 = Buffer.from(binary, 'latin1').toString('base64'); return Buffer.from(base64, 'latin1'); } const HOT_UPDATE_TABLE_FILES = [ { tableKey: 'Chapter', fileName: 'Chapter.json' }, { tableKey: 'BattleCube', fileName: 'BattleCube.json' }, { tableKey: 'Skill_pool', fileName: 'Skill_pool.json' }, { tableKey: 'skill_pool_use', fileName: 'skill_pool_use.json' }, { tableKey: 'Const_weight', fileName: 'Const_weight.json' }, { tableKey: 'TetriWaveWeight', fileName: 'TetriWaveWeight.json' }, { tableKey: 'Weapon2', fileName: 'Weapon2.json' }, { tableKey: 'Monster', fileName: 'Monster.json' }, { tableKey: 'Monster2', fileName: 'Monster2.json' }, ]; function generateConfigBin() { const projectPath = Editor.Project.path; const configDir = path_1.default.join(projectPath, 'assets', 'bundles', 'first', 'config'); const mergeJson = {}; for (const { tableKey, fileName } of HOT_UPDATE_TABLE_FILES) { const fp = path_1.default.join(configDir, fileName); if (!fs_1.default.existsSync(fp)) { console.warn(`[tools] skip bin generate: missing ${fileName}`); return; } mergeJson[tableKey] = readJson(fp); } const { name, vsion } = resolveConfigNameVersion(projectPath); const safeName = `${name}${vsion}`.replace(/[<>:"/\\|?*]+/g, '_'); const outDir = path_1.default.join(projectPath, 'bin'); const outFile = path_1.default.join(outDir, `${safeName}.bin`); fs_1.default.mkdirSync(outDir, { recursive: true }); fs_1.default.writeFileSync(outFile, encodeForRuntime(mergeJson)); console.log(`[tools] generated config bin: ${outFile}`); } function collectJsFiles(dir, acc) { if (!fs_1.default.existsSync(dir)) return; const st = fs_1.default.statSync(dir); if (!st.isDirectory()) return; const entries = fs_1.default.readdirSync(dir, { withFileTypes: true }); for (const e of entries) { const full = path_1.default.join(dir, e.name); if (e.isDirectory()) { collectJsFiles(full, acc); } else if (e.isFile() && e.name.endsWith('.js')) { acc.push(full); } } } function collectStripRoots(options, result) { var _a, _b, _c, _d; const roots = new Set(); const add = (p) => { if (p == null || p === '') return; const s = path_1.default.normalize(String(p).replace(/\//g, path_1.default.sep)); try { if (fs_1.default.existsSync(s)) { const st = fs_1.default.statSync(s); if (st.isDirectory()) roots.add(s); } } catch (_a) { /* ignore */ } }; add(result === null || result === void 0 ? void 0 : result.dest); add((_a = result === null || result === void 0 ? void 0 : result.paths) === null || _a === void 0 ? void 0 : _a.dir); add((_b = result === null || result === void 0 ? void 0 : result.paths) === null || _b === void 0 ? void 0 : _b.assets); add((_c = result === null || result === void 0 ? void 0 : result.paths) === null || _c === void 0 ? void 0 : _c.bundleScripts); add((_d = result === null || result === void 0 ? void 0 : result.paths) === null || _d === void 0 ? void 0 : _d.subpackages); const projectPath = Editor.Project.path; if (projectPath && (options === null || options === void 0 ? void 0 : options.buildPath) && (options === null || options === void 0 ? void 0 : options.outputName)) { let bp = String(options.buildPath); if (bp.includes('project:')) { bp = path_1.default.join(projectPath, bp.replace(/^project:\/\//, '').replace(/^project:/, '')); } add(path_1.default.join(bp, options.outputName)); } return [...roots]; } function collectAllJsFiles(roots) { const files = new Set(); for (const root of roots) { const acc = []; collectJsFiles(root, acc); for (const f of acc) files.add(path_1.default.normalize(f)); } return [...files]; } async function minifyStripConsole(src) { const base = { compress: { drop_console: true, drop_debugger: true, passes: 2, }, mangle: false, format: { comments: 'some' }, ecma: 2020, }; let out = await (0, terser_1.minify)(src, base); if (out.code != null) return out.code; out = await (0, terser_1.minify)(src, Object.assign(Object.assign({}, base), { module: true })); if (out.code != null) return out.code; throw new Error('terser returned empty'); } async function stripConsoleFromBuildOutput(roots) { const files = collectAllJsFiles(roots); if (files.length === 0) { console.warn('[tools] stripConsole: no .js under roots', roots); return; } let ok = 0; let fail = 0; for (const file of files) { try { const src = fs_1.default.readFileSync(file, 'utf8'); const code = await minifyStripConsole(src); fs_1.default.writeFileSync(file, code, 'utf8'); ok++; } catch (err) { fail++; console.warn(`[tools] stripConsole skip (terser error): ${file}`, err); } } console.log(`[tools] stripConsole done: ok=${ok}, fail=${fail}, roots=${roots.join('; ')}`); } const PARALLEL_PRELOAD_SUBPACKAGES = [ { name: 'main' }, { name: 'first' }, { name: 'comm' }, ]; /** 远程资源包:体积大,不计入微信 30M 包体,不得写入 subpackages */ const REMOTE_BUNDLE_NAMES = new Set(['audio', 'tetriMap']); function resolveBuildDest(options, result) { const candidates = []; if (result === null || result === void 0 ? void 0 : result.dest) candidates.push(String(result.dest)); const projectPath = Editor.Project.path; if (projectPath && (options === null || options === void 0 ? void 0 : options.buildPath) && (options === null || options === void 0 ? void 0 : options.outputName)) { let bp = String(options.buildPath); if (bp.includes('project:')) { bp = path_1.default.join(projectPath, bp.replace(/^project:\/\//, '').replace(/^project:/, '')); } candidates.push(path_1.default.join(bp, options.outputName)); } for (const c of candidates) { const normalized = path_1.default.normalize(c); const gameJson = path_1.default.join(normalized, 'game.json'); if (fs_1.default.existsSync(gameJson)) return normalized; } return null; } function isWeChatGameJson(gameJson) { var _a, _b; const provider = (_b = (_a = gameJson === null || gameJson === void 0 ? void 0 : gameJson.plugins) === null || _a === void 0 ? void 0 : _a.cocos) === null || _b === void 0 ? void 0 : _b.provider; return typeof provider === 'string' && provider.startsWith('wx'); } /** 构建后校正 game.json:仅保留启动三分包并行预下载 */ function patchWeChatGameJson(buildDest) { const gameJsonPath = path_1.default.join(buildDest, 'game.json'); if (!fs_1.default.existsSync(gameJsonPath)) return; const gameJson = readGameJsonSafe(gameJsonPath); gameJson.parallelPreloadSubpackages = PARALLEL_PRELOAD_SUBPACKAGES; if (Array.isArray(gameJson.subpackages)) { const before = gameJson.subpackages.length; gameJson.subpackages = gameJson.subpackages.filter((sp) => { var _a; return !REMOTE_BUNDLE_NAMES.has((_a = sp === null || sp === void 0 ? void 0 : sp.name) !== null && _a !== void 0 ? _a : ''); }); if (gameJson.subpackages.length < before) { console.log('[tools] removed remote bundles from subpackages:', [...REMOTE_BUNDLE_NAMES]); } } // 未使用开放数据域时不要写 openDataContext;空字符串会导致微信开发者工具编译失败 const openDataContext = gameJson.openDataContext; if (openDataContext == null || (typeof openDataContext === 'string' && !openDataContext.trim())) { delete gameJson.openDataContext; } writeJsonFile(gameJsonPath, gameJson); readGameJsonSafe(gameJsonPath); console.log('[tools] patched game.json → parallelPreloadSubpackages main/first/comm, removed empty openDataContext'); } function shouldStripConsole(options) { var _a, _b; const v = (_b = (_a = options === null || options === void 0 ? void 0 : options.packages) === null || _a === void 0 ? void 0 : _a.tools) === null || _b === void 0 ? void 0 : _b.stripConsole; if (v === true) return true; if (v === 'true' || v === 1) return true; return false; } function onBeforeBuild(_options, _result) { try { console.log('[tools] onBeforeBuild: generate config bin'); generateConfigBin(); } catch (err) { console.error('[tools] onBeforeBuild generate config bin failed:', err); } return true; } exports.onBeforeBuild = onBeforeBuild; async function onAfterBuild(options, result) { try { const buildDest = resolveBuildDest(options, result); if (buildDest) { const gameJsonPath = path_1.default.join(buildDest, 'game.json'); if (fs_1.default.existsSync(gameJsonPath)) { if ((options === null || options === void 0 ? void 0 : options.platform) === 'wechatgame' || isWeChatGameJson(readGameJsonSafe(gameJsonPath))) { patchWeChatGameJson(buildDest); } } } else if ((options === null || options === void 0 ? void 0 : options.platform) === 'wechatgame') { console.warn('[tools] wechatgame build finished but build output dir was not resolved'); } } catch (err) { console.error('[tools] onAfterBuild patch game.json failed:', err); } try { if (shouldStripConsole(options)) { const roots = collectStripRoots(options, result); if (roots.length === 0) { console.warn('[tools] stripConsole 已勾选但未能解析构建输出目录(检查 result.dest / paths / buildPath+outputName)'); } else { console.log('[tools] onAfterBuild stripConsole →', roots.join(' | ')); await stripConsoleFromBuildOutput(roots); } } } catch (err) { console.error('[tools] onAfterBuild stripConsole failed:', err); } try { console.log('[tools] onAfterBuild: generate config bin'); generateConfigBin(); } catch (err) { console.error('[tools] onAfterBuild generate config bin failed:', err); } return true; } exports.onAfterBuild = onAfterBuild; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtaG9va3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zb3VyY2UvYnVpbGQtaG9va3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7OztHQUdHO0FBQ0gsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUN4QixrREFBd0I7QUFDeEIsbUNBQWdDO0FBRW5CLFFBQUEsVUFBVSxHQUFHLElBQUksQ0FBQztBQUUvQixTQUFTLFFBQVEsQ0FBQyxRQUFnQjtJQUM5QixNQUFNLEdBQUcsR0FBRyxZQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM5QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0IsQ0FBQztBQUVELDRDQUE0QztBQUM1QyxTQUFTLGdCQUFnQixDQUFDLFFBQWdCO0lBQ3RDLE1BQU0sR0FBRyxHQUFHLFlBQUUsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3JELElBQUk7UUFDQSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDMUI7SUFBQyxPQUFPLEdBQUcsRUFBRTtRQUNWLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsSUFBSSxLQUFLLEdBQUcsQ0FBQztZQUFFLE1BQU0sR0FBRyxDQUFDO1FBQ3pCLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNkLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2IsS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDckMsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xCLElBQUksRUFBRSxLQUFLLEdBQUc7Z0JBQUUsS0FBSyxFQUFFLENBQUM7aUJBQ25CLElBQUksRUFBRSxLQUFLLEdBQUcsRUFBRTtnQkFDakIsS0FBSyxFQUFFLENBQUM7Z0JBQ1IsSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFO29CQUNiLEdBQUcsR0FBRyxDQUFDLENBQUM7b0JBQ1IsTUFBTTtpQkFDVDthQUNKO1NBQ0o7UUFDRCxJQUFJLEdBQUcsR0FBRyxLQUFLLEVBQUU7WUFDYixNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDNUMsT0FBTyxDQUFDLElBQUksQ0FBQyx3Q0FBd0MsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUNqRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDaEM7UUFDRCxNQUFNLEdBQUcsQ0FBQztLQUNiO0FBQ0wsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLFFBQWdCLEVBQUUsSUFBYTtJQUNsRCxNQUFNLE9BQU8sR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3JELE1BQU0sR0FBRyxHQUFHLEdBQUcsUUFBUSxNQUFNLENBQUM7SUFDOUIsWUFBRSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZDLFlBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ2pDLENBQUM7QUFFRCxTQUFTLHdCQUF3QixDQUFDLFdBQW1COztJQUNqRCxNQUFNLGFBQWEsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxjQUFjLENBQUMsQ0FBQztJQUN4RixNQUFNLGdCQUFnQixHQUFHLFlBQUUsQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBRWhFLE1BQU0sV0FBVyxHQUFHLG1FQUFtRSxDQUFDO0lBQ3hGLE1BQU0sU0FBUyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBQzVDLElBQUksQ0FBQyxHQUEyQixJQUFJLENBQUM7SUFDckMsT0FBTyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsRUFBRTtRQUM3QyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUM3QjtJQUVELE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyw4REFBOEQsQ0FBQyxDQUFDO0lBQzVHLE1BQU0sTUFBTSxHQUFHLE1BQUEsWUFBWSxhQUFaLFlBQVksdUJBQVosWUFBWSxDQUFHLENBQUMsQ0FBQyxtQ0FBSSxlQUFlLENBQUM7SUFDcEQsTUFBTSxTQUFTLEdBQUcsTUFBQSxTQUFTLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxtQ0FBSSxlQUFlLENBQUM7SUFDM0QsTUFBTSxVQUFVLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEdBQUcsU0FBUyxLQUFLLENBQUMsQ0FBQztJQUNsRyxNQUFNLGFBQWEsR0FBRyxZQUFFLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUUxRCxNQUFNLElBQUksR0FBRyxNQUFBLE1BQUEsYUFBYSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQywwQ0FBRyxDQUFDLENBQUMsbUNBQUksUUFBUSxDQUFDO0lBQ2pGLE1BQU0sS0FBSyxHQUFHLE1BQUEsTUFBQSxhQUFhLENBQUMsS0FBSyxDQUFDLDhCQUE4QixDQUFDLDBDQUFHLENBQUMsQ0FBQyxtQ0FBSSxPQUFPLENBQUM7SUFDbEYsT0FBTyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUMzQixDQUFDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxPQUFZO0lBQ2xDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDM0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbkQsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxlQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFFeEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDMUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2hFLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDekMsQ0FBQztBQUVELE1BQU0sc0JBQXNCLEdBQTZDO0lBQ3JFLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFO0lBQ2pELEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUU7SUFDdkQsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxpQkFBaUIsRUFBRTtJQUN2RCxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxRQUFRLEVBQUUscUJBQXFCLEVBQUU7SUFDL0QsRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxtQkFBbUIsRUFBRTtJQUMzRCxFQUFFLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsc0JBQXNCLEVBQUU7SUFDakUsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUU7SUFDakQsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUU7SUFDakQsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUU7Q0FDdEQsQ0FBQztBQUVGLFNBQVMsaUJBQWlCO0lBQ3RCLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0lBQ3hDLE1BQU0sU0FBUyxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBRWpGLE1BQU0sU0FBUyxHQUE0QixFQUFFLENBQUM7SUFDOUMsS0FBSyxNQUFNLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxJQUFJLHNCQUFzQixFQUFFO1FBQ3pELE1BQU0sRUFBRSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxZQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ3BCLE9BQU8sQ0FBQyxJQUFJLENBQUMsc0NBQXNDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDL0QsT0FBTztTQUNWO1FBQ0QsU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztLQUN0QztJQUVELE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsd0JBQXdCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDOUQsTUFBTSxRQUFRLEdBQUcsR0FBRyxJQUFJLEdBQUcsS0FBSyxFQUFFLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2xFLE1BQU0sTUFBTSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzdDLE1BQU0sT0FBTyxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsUUFBUSxNQUFNLENBQUMsQ0FBQztJQUNyRCxZQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzFDLFlBQUUsQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDdkQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsT0FBTyxFQUFFLENBQUMsQ0FBQztBQUM1RCxDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsR0FBVyxFQUFFLEdBQWE7SUFDOUMsSUFBSSxDQUFDLFlBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDO1FBQUUsT0FBTztJQUNoQyxNQUFNLEVBQUUsR0FBRyxZQUFFLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVCLElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFO1FBQUUsT0FBTztJQUM5QixNQUFNLE9BQU8sR0FBRyxZQUFFLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzdELEtBQUssTUFBTSxDQUFDLElBQUksT0FBTyxFQUFFO1FBQ3JCLE1BQU0sSUFBSSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUNqQixjQUFjLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQzdCO2FBQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDN0MsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNsQjtLQUNKO0FBQ0wsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsT0FBWSxFQUFFLE1BQVc7O0lBQ2hELE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDaEMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFVLEVBQUUsRUFBRTtRQUN2QixJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFBRSxPQUFPO1FBQ2xDLE1BQU0sQ0FBQyxHQUFHLGNBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsY0FBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDN0QsSUFBSTtZQUNBLElBQUksWUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDbEIsTUFBTSxFQUFFLEdBQUcsWUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDMUIsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO29CQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDdEM7U0FDSjtRQUFDLFdBQU07WUFDSixZQUFZO1NBQ2Y7SUFDTCxDQUFDLENBQUM7SUFFRixHQUFHLENBQUMsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2xCLEdBQUcsQ0FBQyxNQUFBLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxLQUFLLDBDQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3hCLEdBQUcsQ0FBQyxNQUFBLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxLQUFLLDBDQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzNCLEdBQUcsQ0FBQyxNQUFBLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxLQUFLLDBDQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ2xDLEdBQUcsQ0FBQyxNQUFBLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxLQUFLLDBDQUFFLFdBQVcsQ0FBQyxDQUFDO0lBRWhDLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0lBQ3hDLElBQUksV0FBVyxLQUFJLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxTQUFTLENBQUEsS0FBSSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsVUFBVSxDQUFBLEVBQUU7UUFDMUQsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDekIsRUFBRSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUN6RjtRQUNELEdBQUcsQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztLQUMxQztJQUVELE9BQU8sQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ3RCLENBQUM7QUFFRCxTQUFTLGlCQUFpQixDQUFDLEtBQWU7SUFDdEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUNoQyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRTtRQUN0QixNQUFNLEdBQUcsR0FBYSxFQUFFLENBQUM7UUFDekIsY0FBYyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMxQixLQUFLLE1BQU0sQ0FBQyxJQUFJLEdBQUc7WUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLGNBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUNyRDtJQUNELE9BQU8sQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ3RCLENBQUM7QUFFRCxLQUFLLFVBQVUsa0JBQWtCLENBQUMsR0FBVztJQUN6QyxNQUFNLElBQUksR0FBRztRQUNULFFBQVEsRUFBRTtZQUNOLFlBQVksRUFBRSxJQUFJO1lBQ2xCLGFBQWEsRUFBRSxJQUFJO1lBQ25CLE1BQU0sRUFBRSxDQUFDO1NBQ1o7UUFDRCxNQUFNLEVBQUUsS0FBSztRQUNiLE1BQU0sRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFlLEVBQUU7UUFDckMsSUFBSSxFQUFFLElBQWE7S0FDdEIsQ0FBQztJQUNGLElBQUksR0FBRyxHQUFHLE1BQU0sSUFBQSxlQUFNLEVBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2xDLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxJQUFJO1FBQUUsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDO0lBQ3RDLEdBQUcsR0FBRyxNQUFNLElBQUEsZUFBTSxFQUFDLEdBQUcsa0NBQU8sSUFBSSxLQUFFLE1BQU0sRUFBRSxJQUFJLElBQUcsQ0FBQztJQUNuRCxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksSUFBSTtRQUFFLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQztJQUN0QyxNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7QUFDN0MsQ0FBQztBQUVELEtBQUssVUFBVSwyQkFBMkIsQ0FBQyxLQUFlO0lBQ3RELE1BQU0sS0FBSyxHQUFHLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7UUFDcEIsT0FBTyxDQUFDLElBQUksQ0FBQywwQ0FBMEMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNoRSxPQUFPO0tBQ1Y7SUFDRCxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDWCxJQUFJLElBQUksR0FBRyxDQUFDLENBQUM7SUFDYixLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRTtRQUN0QixJQUFJO1lBQ0EsTUFBTSxHQUFHLEdBQUcsWUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDMUMsTUFBTSxJQUFJLEdBQUcsTUFBTSxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzQyxZQUFFLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDckMsRUFBRSxFQUFFLENBQUM7U0FDUjtRQUFDLE9BQU8sR0FBRyxFQUFFO1lBQ1YsSUFBSSxFQUFFLENBQUM7WUFDUCxPQUFPLENBQUMsSUFBSSxDQUFDLDZDQUE2QyxJQUFJLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztTQUMxRTtLQUNKO0lBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsRUFBRSxVQUFVLElBQUksV0FBVyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNoRyxDQUFDO0FBRUQsTUFBTSw0QkFBNEIsR0FBRztJQUNqQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUU7SUFDaEIsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO0lBQ2pCLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRTtDQUNuQixDQUFDO0FBRUYsOENBQThDO0FBQzlDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztBQUUzRCxTQUFTLGdCQUFnQixDQUFDLE9BQVksRUFBRSxNQUFXO0lBQy9DLE1BQU0sVUFBVSxHQUFhLEVBQUUsQ0FBQztJQUNoQyxJQUFJLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxJQUFJO1FBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDdkQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7SUFDeEMsSUFBSSxXQUFXLEtBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFNBQVMsQ0FBQSxLQUFJLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxVQUFVLENBQUEsRUFBRTtRQUMxRCxJQUFJLEVBQUUsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ25DLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUN6QixFQUFFLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQ3pGO1FBQ0QsVUFBVSxDQUFDLElBQUksQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztLQUN0RDtJQUNELEtBQUssTUFBTSxDQUFDLElBQUksVUFBVSxFQUFFO1FBQ3hCLE1BQU0sVUFBVSxHQUFHLGNBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsTUFBTSxRQUFRLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDcEQsSUFBSSxZQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQztZQUFFLE9BQU8sVUFBVSxDQUFDO0tBQ2xEO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDaEIsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsUUFBYTs7SUFDbkMsTUFBTSxRQUFRLEdBQUcsTUFBQSxNQUFBLFFBQVEsYUFBUixRQUFRLHVCQUFSLFFBQVEsQ0FBRSxPQUFPLDBDQUFFLEtBQUssMENBQUUsUUFBUSxDQUFDO0lBQ3BELE9BQU8sT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDckUsQ0FBQztBQUVELG9DQUFvQztBQUNwQyxTQUFTLG1CQUFtQixDQUFDLFNBQWlCO0lBQzFDLE1BQU0sWUFBWSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZELElBQUksQ0FBQyxZQUFFLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQztRQUFFLE9BQU87SUFFekMsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDaEQsUUFBUSxDQUFDLDBCQUEwQixHQUFHLDRCQUE0QixDQUFDO0lBQ25FLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUU7UUFDckMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUM7UUFDM0MsUUFBUSxDQUFDLFdBQVcsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FDOUMsQ0FBQyxFQUFxQixFQUFFLEVBQUUsV0FBQyxPQUFBLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLE1BQUEsRUFBRSxhQUFGLEVBQUUsdUJBQUYsRUFBRSxDQUFFLElBQUksbUNBQUksRUFBRSxDQUFDLENBQUEsRUFBQSxDQUN0RSxDQUFDO1FBQ0YsSUFBSSxRQUFRLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxNQUFNLEVBQUU7WUFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrREFBa0QsRUFBRSxDQUFDLEdBQUcsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO1NBQzdGO0tBQ0o7SUFDRCxrREFBa0Q7SUFDbEQsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQztJQUNqRCxJQUNJLGVBQWUsSUFBSSxJQUFJO1dBQ3BCLENBQUMsT0FBTyxlQUFlLEtBQUssUUFBUSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQ3JFO1FBQ0UsT0FBTyxRQUFRLENBQUMsZUFBZSxDQUFDO0tBQ25DO0lBQ0QsYUFBYSxDQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN0QyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMvQixPQUFPLENBQUMsR0FBRyxDQUFDLHVHQUF1RyxDQUFDLENBQUM7QUFDekgsQ0FBQztBQUVELFNBQVMsa0JBQWtCLENBQUMsT0FBWTs7SUFDcEMsTUFBTSxDQUFDLEdBQUcsTUFBQSxNQUFBLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxRQUFRLDBDQUFFLEtBQUssMENBQUUsWUFBWSxDQUFDO0lBQ2pELElBQUksQ0FBQyxLQUFLLElBQUk7UUFBRSxPQUFPLElBQUksQ0FBQztJQUM1QixJQUFJLENBQUMsS0FBSyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN6QyxPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFDO0FBRUQsU0FBZ0IsYUFBYSxDQUFDLFFBQWEsRUFBRSxPQUFZO0lBQ3JELElBQUk7UUFDQSxPQUFPLENBQUMsR0FBRyxDQUFDLDRDQUE0QyxDQUFDLENBQUM7UUFDMUQsaUJBQWlCLEVBQUUsQ0FBQztLQUN2QjtJQUFDLE9BQU8sR0FBRyxFQUFFO1FBQ1YsT0FBTyxDQUFDLEtBQUssQ0FBQyxtREFBbUQsRUFBRSxHQUFHLENBQUMsQ0FBQztLQUMzRTtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2hCLENBQUM7QUFSRCxzQ0FRQztBQUVNLEtBQUssVUFBVSxZQUFZLENBQUMsT0FBWSxFQUFFLE1BQVc7SUFDeEQsSUFBSTtRQUNBLE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNwRCxJQUFJLFNBQVMsRUFBRTtZQUNYLE1BQU0sWUFBWSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQ3ZELElBQUksWUFBRSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRTtnQkFDN0IsSUFBSSxDQUFBLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxRQUFRLE1BQUssWUFBWSxJQUFJLGdCQUFnQixDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDLEVBQUU7b0JBQ3hGLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxDQUFDO2lCQUNsQzthQUNKO1NBQ0o7YUFBTSxJQUFJLENBQUEsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFFBQVEsTUFBSyxZQUFZLEVBQUU7WUFDM0MsT0FBTyxDQUFDLElBQUksQ0FBQyx5RUFBeUUsQ0FBQyxDQUFDO1NBQzNGO0tBQ0o7SUFBQyxPQUFPLEdBQUcsRUFBRTtRQUNWLE9BQU8sQ0FBQyxLQUFLLENBQUMsOENBQThDLEVBQUUsR0FBRyxDQUFDLENBQUM7S0FDdEU7SUFDRCxJQUFJO1FBQ0EsSUFBSSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUM3QixNQUFNLEtBQUssR0FBRyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDakQsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDcEIsT0FBTyxDQUFDLElBQUksQ0FDUixvRkFBb0YsQ0FDdkYsQ0FBQzthQUNMO2lCQUFNO2dCQUNILE9BQU8sQ0FBQyxHQUFHLENBQUMscUNBQXFDLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUN0RSxNQUFNLDJCQUEyQixDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzVDO1NBQ0o7S0FDSjtJQUFDLE9BQU8sR0FBRyxFQUFFO1FBQ1YsT0FBTyxDQUFDLEtBQUssQ0FBQywyQ0FBMkMsRUFBRSxHQUFHLENBQUMsQ0FBQztLQUNuRTtJQUNELElBQUk7UUFDQSxPQUFPLENBQUMsR0FBRyxDQUFDLDJDQUEyQyxDQUFDLENBQUM7UUFDekQsaUJBQWlCLEVBQUUsQ0FBQztLQUN2QjtJQUFDLE9BQU8sR0FBRyxFQUFFO1FBQ1YsT0FBTyxDQUFDLEtBQUssQ0FBQyxrREFBa0QsRUFBRSxHQUFHLENBQUMsQ0FBQztLQUMxRTtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2hCLENBQUM7QUF0Q0Qsb0NBc0NDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIOaehOW7uui/m+eoi++8iOeLrOeriyB3b3JrZXLvvInliqDovb3nmoTpkqnlrZDohJrmnKzvvJtjdXN0b20tYnVpbGRlciDnmoQgY29uZmlncy4qLmhvb2tzIOaMh+WQkeacrOaWh+S7tuOAglxyXG4gKiBjdXN0b20tYnVpbGRlci50cyDkvJogcmUtZXhwb3J0IOacrOaWh+S7tueahOmSqeWtkO+8jOS+m+e8lui+keWZqOagoemqjOmAmui/h+OAglxyXG4gKi9cclxuaW1wb3J0IGZzIGZyb20gJ2ZzJztcclxuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XHJcbmltcG9ydCBsejQgZnJvbSAnbHo0anMnO1xyXG5pbXBvcnQgeyBtaW5pZnkgfSBmcm9tICd0ZXJzZXInO1xyXG5cclxuZXhwb3J0IGNvbnN0IHRocm93RXJyb3IgPSB0cnVlO1xyXG5cclxuZnVuY3Rpb24gcmVhZEpzb24oZmlsZVBhdGg6IHN0cmluZykge1xyXG4gICAgY29uc3QgcmF3ID0gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCAndXRmOCcpO1xyXG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmF3KTtcclxufVxyXG5cclxuLyoqIOino+aekCBnYW1lLmpzb27vvJvoi6XlsL7pg6jooqvml6flhoXlrrnmsaHmn5PliJnmiKrlj5bpppbkuKrlrozmlbQgSlNPTiDlr7nosaEgKi9cclxuZnVuY3Rpb24gcmVhZEdhbWVKc29uU2FmZShmaWxlUGF0aDogc3RyaW5nKTogYW55IHtcclxuICAgIGNvbnN0IHJhdyA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgJ3V0ZjgnKS50cmltKCk7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKHJhdyk7XHJcbiAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICBjb25zdCBzdGFydCA9IHJhdy5pbmRleE9mKCd7Jyk7XHJcbiAgICAgICAgaWYgKHN0YXJ0IDwgMCkgdGhyb3cgZXJyO1xyXG4gICAgICAgIGxldCBkZXB0aCA9IDA7XHJcbiAgICAgICAgbGV0IGVuZCA9IC0xO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IHJhdy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCBjaCA9IHJhd1tpXTtcclxuICAgICAgICAgICAgaWYgKGNoID09PSAneycpIGRlcHRoKys7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGNoID09PSAnfScpIHtcclxuICAgICAgICAgICAgICAgIGRlcHRoLS07XHJcbiAgICAgICAgICAgICAgICBpZiAoZGVwdGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBlbmQgPSBpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChlbmQgPiBzdGFydCkge1xyXG4gICAgICAgICAgICBjb25zdCByZWNvdmVyZWQgPSByYXcuc2xpY2Uoc3RhcnQsIGVuZCArIDEpO1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYFt0b29sc10gZ2FtZS5qc29uIOWQq+iEj+aVsOaNru+8jOW3suiHquWKqOaIquWPluacieaViCBKU09OOiAke2ZpbGVQYXRofWApO1xyXG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShyZWNvdmVyZWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHdyaXRlSnNvbkZpbGUoZmlsZVBhdGg6IHN0cmluZywgZGF0YTogdW5rbm93bik6IHZvaWQge1xyXG4gICAgY29uc3QgY29udGVudCA9IGAke0pTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpfVxcbmA7XHJcbiAgICBjb25zdCB0bXAgPSBgJHtmaWxlUGF0aH0udG1wYDtcclxuICAgIGZzLndyaXRlRmlsZVN5bmModG1wLCBjb250ZW50LCAndXRmOCcpO1xyXG4gICAgZnMucmVuYW1lU3luYyh0bXAsIGZpbGVQYXRoKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVzb2x2ZUNvbmZpZ05hbWVWZXJzaW9uKHByb2plY3RQYXRoOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IHNka0NvbmZpZ1BhdGggPSBwYXRoLmpvaW4ocHJvamVjdFBhdGgsICdhc3NldHMnLCAnc2NyaXB0JywgJ3NkaycsICdzZGtDb25maWcudHMnKTtcclxuICAgIGNvbnN0IHNka0NvbmZpZ0NvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoc2RrQ29uZmlnUGF0aCwgJ3V0ZjgnKTtcclxuXHJcbiAgICBjb25zdCBpbXBvcnRSZWdleCA9IC9pbXBvcnRcXHMrXFx7XFxzKihcXHcrKVxccypcXH1cXHMrZnJvbVxccytbXCInXVxcLlxcL2NvbmZpZ1xcLyhbXlwiJ10rKVtcIiddOz8vZztcclxuICAgIGNvbnN0IGltcG9ydE1hcCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XHJcbiAgICBsZXQgbTogUmVnRXhwRXhlY0FycmF5IHwgbnVsbCA9IG51bGw7XHJcbiAgICB3aGlsZSAoKG0gPSBpbXBvcnRSZWdleC5leGVjKHNka0NvbmZpZ0NvbnRlbnQpKSkge1xyXG4gICAgICAgIGltcG9ydE1hcC5zZXQobVsxXSwgbVsyXSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY29uZmlnQXNzaWduID0gc2RrQ29uZmlnQ29udGVudC5tYXRjaCgvc3RhdGljXFxzK3JlYWRvbmx5XFxzK2NvbmZpZ1xccyo6XFxzKklDb25maWdEYXRhXFxzKj1cXHMqKFxcdyspXFxzKjsvKTtcclxuICAgIGNvbnN0IHN5bWJvbCA9IGNvbmZpZ0Fzc2lnbj8uWzFdID8/ICdEZWZhdWx0Q29uZmlnJztcclxuICAgIGNvbnN0IHJlbENvbmZpZyA9IGltcG9ydE1hcC5nZXQoc3ltYm9sKSA/PyAnRGVmYXVsdENvbmZpZyc7XHJcbiAgICBjb25zdCBjb25maWdQYXRoID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnYXNzZXRzJywgJ3NjcmlwdCcsICdzZGsnLCAnY29uZmlnJywgYCR7cmVsQ29uZmlnfS50c2ApO1xyXG4gICAgY29uc3QgY29uZmlnQ29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhjb25maWdQYXRoLCAndXRmOCcpO1xyXG5cclxuICAgIGNvbnN0IG5hbWUgPSBjb25maWdDb250ZW50Lm1hdGNoKC9uYW1lXFxzKjpcXHMqW1wiJ10oW15cIiddKylbXCInXS8pPy5bMV0gPz8gJ2NvbmZpZyc7XHJcbiAgICBjb25zdCB2c2lvbiA9IGNvbmZpZ0NvbnRlbnQubWF0Y2goL3ZzaW9uXFxzKjpcXHMqW1wiJ10oW15cIiddKylbXCInXS8pPy5bMV0gPz8gJzAuMC4wJztcclxuICAgIHJldHVybiB7IG5hbWUsIHZzaW9uIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGVuY29kZUZvclJ1bnRpbWUoanNvbk9iajogYW55KSB7XHJcbiAgICBjb25zdCBqc29uU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoanNvbk9iaik7XHJcbiAgICBjb25zdCB1aW50OCA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShqc29uU3RyaW5nKTtcclxuICAgIGNvbnN0IGNvbXByZXNzZWQgPSBVaW50OEFycmF5LmZyb20obHo0LmNvbXByZXNzKHVpbnQ4KSk7XHJcblxyXG4gICAgY29uc3QgYmluYXJ5ID0gQnVmZmVyLmZyb20oY29tcHJlc3NlZCkudG9TdHJpbmcoJ2xhdGluMScpO1xyXG4gICAgY29uc3QgYmFzZTY0ID0gQnVmZmVyLmZyb20oYmluYXJ5LCAnbGF0aW4xJykudG9TdHJpbmcoJ2Jhc2U2NCcpO1xyXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJhc2U2NCwgJ2xhdGluMScpO1xyXG59XHJcblxyXG5jb25zdCBIT1RfVVBEQVRFX1RBQkxFX0ZJTEVTOiB7IHRhYmxlS2V5OiBzdHJpbmc7IGZpbGVOYW1lOiBzdHJpbmcgfVtdID0gW1xyXG4gICAgeyB0YWJsZUtleTogJ0NoYXB0ZXInLCBmaWxlTmFtZTogJ0NoYXB0ZXIuanNvbicgfSxcclxuICAgIHsgdGFibGVLZXk6ICdCYXR0bGVDdWJlJywgZmlsZU5hbWU6ICdCYXR0bGVDdWJlLmpzb24nIH0sXHJcbiAgICB7IHRhYmxlS2V5OiAnU2tpbGxfcG9vbCcsIGZpbGVOYW1lOiAnU2tpbGxfcG9vbC5qc29uJyB9LFxyXG4gICAgeyB0YWJsZUtleTogJ3NraWxsX3Bvb2xfdXNlJywgZmlsZU5hbWU6ICdza2lsbF9wb29sX3VzZS5qc29uJyB9LFxyXG4gICAgeyB0YWJsZUtleTogJ0NvbnN0X3dlaWdodCcsIGZpbGVOYW1lOiAnQ29uc3Rfd2VpZ2h0Lmpzb24nIH0sIFxyXG4gICAgeyB0YWJsZUtleTogJ1RldHJpV2F2ZVdlaWdodCcsIGZpbGVOYW1lOiAnVGV0cmlXYXZlV2VpZ2h0Lmpzb24nIH0sXHJcbiAgICB7IHRhYmxlS2V5OiAnV2VhcG9uMicsIGZpbGVOYW1lOiAnV2VhcG9uMi5qc29uJyB9LFxyXG4gICAgeyB0YWJsZUtleTogJ01vbnN0ZXInLCBmaWxlTmFtZTogJ01vbnN0ZXIuanNvbicgfSxcclxuICAgIHsgdGFibGVLZXk6ICdNb25zdGVyMicsIGZpbGVOYW1lOiAnTW9uc3RlcjIuanNvbicgfSxcclxuXTtcclxuXHJcbmZ1bmN0aW9uIGdlbmVyYXRlQ29uZmlnQmluKCkge1xyXG4gICAgY29uc3QgcHJvamVjdFBhdGggPSBFZGl0b3IuUHJvamVjdC5wYXRoO1xyXG4gICAgY29uc3QgY29uZmlnRGlyID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnYXNzZXRzJywgJ2J1bmRsZXMnLCAnZmlyc3QnLCAnY29uZmlnJyk7XHJcblxyXG4gICAgY29uc3QgbWVyZ2VKc29uOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xyXG4gICAgZm9yIChjb25zdCB7IHRhYmxlS2V5LCBmaWxlTmFtZSB9IG9mIEhPVF9VUERBVEVfVEFCTEVfRklMRVMpIHtcclxuICAgICAgICBjb25zdCBmcCA9IHBhdGguam9pbihjb25maWdEaXIsIGZpbGVOYW1lKTtcclxuICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZnApKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgW3Rvb2xzXSBza2lwIGJpbiBnZW5lcmF0ZTogbWlzc2luZyAke2ZpbGVOYW1lfWApO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG1lcmdlSnNvblt0YWJsZUtleV0gPSByZWFkSnNvbihmcCk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgeyBuYW1lLCB2c2lvbiB9ID0gcmVzb2x2ZUNvbmZpZ05hbWVWZXJzaW9uKHByb2plY3RQYXRoKTtcclxuICAgIGNvbnN0IHNhZmVOYW1lID0gYCR7bmFtZX0ke3ZzaW9ufWAucmVwbGFjZSgvWzw+OlwiL1xcXFx8PypdKy9nLCAnXycpO1xyXG4gICAgY29uc3Qgb3V0RGlyID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnYmluJyk7XHJcbiAgICBjb25zdCBvdXRGaWxlID0gcGF0aC5qb2luKG91dERpciwgYCR7c2FmZU5hbWV9LmJpbmApO1xyXG4gICAgZnMubWtkaXJTeW5jKG91dERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XHJcbiAgICBmcy53cml0ZUZpbGVTeW5jKG91dEZpbGUsIGVuY29kZUZvclJ1bnRpbWUobWVyZ2VKc29uKSk7XHJcbiAgICBjb25zb2xlLmxvZyhgW3Rvb2xzXSBnZW5lcmF0ZWQgY29uZmlnIGJpbjogJHtvdXRGaWxlfWApO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb2xsZWN0SnNGaWxlcyhkaXI6IHN0cmluZywgYWNjOiBzdHJpbmdbXSkge1xyXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGRpcikpIHJldHVybjtcclxuICAgIGNvbnN0IHN0ID0gZnMuc3RhdFN5bmMoZGlyKTtcclxuICAgIGlmICghc3QuaXNEaXJlY3RvcnkoKSkgcmV0dXJuO1xyXG4gICAgY29uc3QgZW50cmllcyA9IGZzLnJlYWRkaXJTeW5jKGRpciwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xyXG4gICAgZm9yIChjb25zdCBlIG9mIGVudHJpZXMpIHtcclxuICAgICAgICBjb25zdCBmdWxsID0gcGF0aC5qb2luKGRpciwgZS5uYW1lKTtcclxuICAgICAgICBpZiAoZS5pc0RpcmVjdG9yeSgpKSB7XHJcbiAgICAgICAgICAgIGNvbGxlY3RKc0ZpbGVzKGZ1bGwsIGFjYyk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChlLmlzRmlsZSgpICYmIGUubmFtZS5lbmRzV2l0aCgnLmpzJykpIHtcclxuICAgICAgICAgICAgYWNjLnB1c2goZnVsbCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjb2xsZWN0U3RyaXBSb290cyhvcHRpb25zOiBhbnksIHJlc3VsdDogYW55KTogc3RyaW5nW10ge1xyXG4gICAgY29uc3Qgcm9vdHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcclxuICAgIGNvbnN0IGFkZCA9IChwOiB1bmtub3duKSA9PiB7XHJcbiAgICAgICAgaWYgKHAgPT0gbnVsbCB8fCBwID09PSAnJykgcmV0dXJuO1xyXG4gICAgICAgIGNvbnN0IHMgPSBwYXRoLm5vcm1hbGl6ZShTdHJpbmcocCkucmVwbGFjZSgvXFwvL2csIHBhdGguc2VwKSk7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMocykpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHN0ID0gZnMuc3RhdFN5bmMocyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3QuaXNEaXJlY3RvcnkoKSkgcm9vdHMuYWRkKHMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgICAgIC8qIGlnbm9yZSAqL1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgYWRkKHJlc3VsdD8uZGVzdCk7XHJcbiAgICBhZGQocmVzdWx0Py5wYXRocz8uZGlyKTtcclxuICAgIGFkZChyZXN1bHQ/LnBhdGhzPy5hc3NldHMpO1xyXG4gICAgYWRkKHJlc3VsdD8ucGF0aHM/LmJ1bmRsZVNjcmlwdHMpO1xyXG4gICAgYWRkKHJlc3VsdD8ucGF0aHM/LnN1YnBhY2thZ2VzKTtcclxuXHJcbiAgICBjb25zdCBwcm9qZWN0UGF0aCA9IEVkaXRvci5Qcm9qZWN0LnBhdGg7XHJcbiAgICBpZiAocHJvamVjdFBhdGggJiYgb3B0aW9ucz8uYnVpbGRQYXRoICYmIG9wdGlvbnM/Lm91dHB1dE5hbWUpIHtcclxuICAgICAgICBsZXQgYnAgPSBTdHJpbmcob3B0aW9ucy5idWlsZFBhdGgpO1xyXG4gICAgICAgIGlmIChicC5pbmNsdWRlcygncHJvamVjdDonKSkge1xyXG4gICAgICAgICAgICBicCA9IHBhdGguam9pbihwcm9qZWN0UGF0aCwgYnAucmVwbGFjZSgvXnByb2plY3Q6XFwvXFwvLywgJycpLnJlcGxhY2UoL15wcm9qZWN0Oi8sICcnKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGFkZChwYXRoLmpvaW4oYnAsIG9wdGlvbnMub3V0cHV0TmFtZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBbLi4ucm9vdHNdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb2xsZWN0QWxsSnNGaWxlcyhyb290czogc3RyaW5nW10pOiBzdHJpbmdbXSB7XHJcbiAgICBjb25zdCBmaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xyXG4gICAgZm9yIChjb25zdCByb290IG9mIHJvb3RzKSB7XHJcbiAgICAgICAgY29uc3QgYWNjOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgICAgIGNvbGxlY3RKc0ZpbGVzKHJvb3QsIGFjYyk7XHJcbiAgICAgICAgZm9yIChjb25zdCBmIG9mIGFjYykgZmlsZXMuYWRkKHBhdGgubm9ybWFsaXplKGYpKTtcclxuICAgIH1cclxuICAgIHJldHVybiBbLi4uZmlsZXNdO1xyXG59XHJcblxyXG5hc3luYyBmdW5jdGlvbiBtaW5pZnlTdHJpcENvbnNvbGUoc3JjOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgY29uc3QgYmFzZSA9IHtcclxuICAgICAgICBjb21wcmVzczoge1xyXG4gICAgICAgICAgICBkcm9wX2NvbnNvbGU6IHRydWUsXHJcbiAgICAgICAgICAgIGRyb3BfZGVidWdnZXI6IHRydWUsXHJcbiAgICAgICAgICAgIHBhc3NlczogMixcclxuICAgICAgICB9LFxyXG4gICAgICAgIG1hbmdsZTogZmFsc2UsXHJcbiAgICAgICAgZm9ybWF0OiB7IGNvbW1lbnRzOiAnc29tZScgYXMgY29uc3QgfSxcclxuICAgICAgICBlY21hOiAyMDIwIGFzIGNvbnN0LFxyXG4gICAgfTtcclxuICAgIGxldCBvdXQgPSBhd2FpdCBtaW5pZnkoc3JjLCBiYXNlKTtcclxuICAgIGlmIChvdXQuY29kZSAhPSBudWxsKSByZXR1cm4gb3V0LmNvZGU7XHJcbiAgICBvdXQgPSBhd2FpdCBtaW5pZnkoc3JjLCB7IC4uLmJhc2UsIG1vZHVsZTogdHJ1ZSB9KTtcclxuICAgIGlmIChvdXQuY29kZSAhPSBudWxsKSByZXR1cm4gb3V0LmNvZGU7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RlcnNlciByZXR1cm5lZCBlbXB0eScpO1xyXG59XHJcblxyXG5hc3luYyBmdW5jdGlvbiBzdHJpcENvbnNvbGVGcm9tQnVpbGRPdXRwdXQocm9vdHM6IHN0cmluZ1tdKSB7XHJcbiAgICBjb25zdCBmaWxlcyA9IGNvbGxlY3RBbGxKc0ZpbGVzKHJvb3RzKTtcclxuICAgIGlmIChmaWxlcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICBjb25zb2xlLndhcm4oJ1t0b29sc10gc3RyaXBDb25zb2xlOiBubyAuanMgdW5kZXIgcm9vdHMnLCByb290cyk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgbGV0IG9rID0gMDtcclxuICAgIGxldCBmYWlsID0gMDtcclxuICAgIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNyYyA9IGZzLnJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpO1xyXG4gICAgICAgICAgICBjb25zdCBjb2RlID0gYXdhaXQgbWluaWZ5U3RyaXBDb25zb2xlKHNyYyk7XHJcbiAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZSwgY29kZSwgJ3V0ZjgnKTtcclxuICAgICAgICAgICAgb2srKztcclxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgZmFpbCsrO1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYFt0b29sc10gc3RyaXBDb25zb2xlIHNraXAgKHRlcnNlciBlcnJvcik6ICR7ZmlsZX1gLCBlcnIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGNvbnNvbGUubG9nKGBbdG9vbHNdIHN0cmlwQ29uc29sZSBkb25lOiBvaz0ke29rfSwgZmFpbD0ke2ZhaWx9LCByb290cz0ke3Jvb3RzLmpvaW4oJzsgJyl9YCk7XHJcbn1cclxuXHJcbmNvbnN0IFBBUkFMTEVMX1BSRUxPQURfU1VCUEFDS0FHRVMgPSBbXHJcbiAgICB7IG5hbWU6ICdtYWluJyB9LFxyXG4gICAgeyBuYW1lOiAnZmlyc3QnIH0sXHJcbiAgICB7IG5hbWU6ICdjb21tJyB9LFxyXG5dO1xyXG5cclxuLyoqIOi/nOeoi+i1hOa6kOWMhe+8muS9k+enr+Wkp++8jOS4jeiuoeWFpeW+ruS/oSAzME0g5YyF5L2T77yM5LiN5b6X5YaZ5YWlIHN1YnBhY2thZ2VzICovXHJcbmNvbnN0IFJFTU9URV9CVU5ETEVfTkFNRVMgPSBuZXcgU2V0KFsnYXVkaW8nLCAndGV0cmlNYXAnXSk7XHJcblxyXG5mdW5jdGlvbiByZXNvbHZlQnVpbGREZXN0KG9wdGlvbnM6IGFueSwgcmVzdWx0OiBhbnkpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IGNhbmRpZGF0ZXM6IHN0cmluZ1tdID0gW107XHJcbiAgICBpZiAocmVzdWx0Py5kZXN0KSBjYW5kaWRhdGVzLnB1c2goU3RyaW5nKHJlc3VsdC5kZXN0KSk7XHJcbiAgICBjb25zdCBwcm9qZWN0UGF0aCA9IEVkaXRvci5Qcm9qZWN0LnBhdGg7XHJcbiAgICBpZiAocHJvamVjdFBhdGggJiYgb3B0aW9ucz8uYnVpbGRQYXRoICYmIG9wdGlvbnM/Lm91dHB1dE5hbWUpIHtcclxuICAgICAgICBsZXQgYnAgPSBTdHJpbmcob3B0aW9ucy5idWlsZFBhdGgpO1xyXG4gICAgICAgIGlmIChicC5pbmNsdWRlcygncHJvamVjdDonKSkge1xyXG4gICAgICAgICAgICBicCA9IHBhdGguam9pbihwcm9qZWN0UGF0aCwgYnAucmVwbGFjZSgvXnByb2plY3Q6XFwvXFwvLywgJycpLnJlcGxhY2UoL15wcm9qZWN0Oi8sICcnKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhbmRpZGF0ZXMucHVzaChwYXRoLmpvaW4oYnAsIG9wdGlvbnMub3V0cHV0TmFtZSkpO1xyXG4gICAgfVxyXG4gICAgZm9yIChjb25zdCBjIG9mIGNhbmRpZGF0ZXMpIHtcclxuICAgICAgICBjb25zdCBub3JtYWxpemVkID0gcGF0aC5ub3JtYWxpemUoYyk7XHJcbiAgICAgICAgY29uc3QgZ2FtZUpzb24gPSBwYXRoLmpvaW4obm9ybWFsaXplZCwgJ2dhbWUuanNvbicpO1xyXG4gICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGdhbWVKc29uKSkgcmV0dXJuIG5vcm1hbGl6ZWQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNXZUNoYXRHYW1lSnNvbihnYW1lSnNvbjogYW55KTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBwcm92aWRlciA9IGdhbWVKc29uPy5wbHVnaW5zPy5jb2Nvcz8ucHJvdmlkZXI7XHJcbiAgICByZXR1cm4gdHlwZW9mIHByb3ZpZGVyID09PSAnc3RyaW5nJyAmJiBwcm92aWRlci5zdGFydHNXaXRoKCd3eCcpO1xyXG59XHJcblxyXG4vKiog5p6E5bu65ZCO5qCh5q2jIGdhbWUuanNvbu+8muS7heS/neeVmeWQr+WKqOS4ieWIhuWMheW5tuihjOmihOS4i+i9vSAqL1xyXG5mdW5jdGlvbiBwYXRjaFdlQ2hhdEdhbWVKc29uKGJ1aWxkRGVzdDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBjb25zdCBnYW1lSnNvblBhdGggPSBwYXRoLmpvaW4oYnVpbGREZXN0LCAnZ2FtZS5qc29uJyk7XHJcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZ2FtZUpzb25QYXRoKSkgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IGdhbWVKc29uID0gcmVhZEdhbWVKc29uU2FmZShnYW1lSnNvblBhdGgpO1xyXG4gICAgZ2FtZUpzb24ucGFyYWxsZWxQcmVsb2FkU3VicGFja2FnZXMgPSBQQVJBTExFTF9QUkVMT0FEX1NVQlBBQ0tBR0VTO1xyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZ2FtZUpzb24uc3VicGFja2FnZXMpKSB7XHJcbiAgICAgICAgY29uc3QgYmVmb3JlID0gZ2FtZUpzb24uc3VicGFja2FnZXMubGVuZ3RoO1xyXG4gICAgICAgIGdhbWVKc29uLnN1YnBhY2thZ2VzID0gZ2FtZUpzb24uc3VicGFja2FnZXMuZmlsdGVyKFxyXG4gICAgICAgICAgICAoc3A6IHsgbmFtZT86IHN0cmluZyB9KSA9PiAhUkVNT1RFX0JVTkRMRV9OQU1FUy5oYXMoc3A/Lm5hbWUgPz8gJycpLFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgaWYgKGdhbWVKc29uLnN1YnBhY2thZ2VzLmxlbmd0aCA8IGJlZm9yZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnW3Rvb2xzXSByZW1vdmVkIHJlbW90ZSBidW5kbGVzIGZyb20gc3VicGFja2FnZXM6JywgWy4uLlJFTU9URV9CVU5ETEVfTkFNRVNdKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyDmnKrkvb/nlKjlvIDmlL7mlbDmja7ln5/ml7bkuI3opoHlhpkgb3BlbkRhdGFDb250ZXh077yb56m65a2X56ym5Liy5Lya5a+86Ie05b6u5L+h5byA5Y+R6ICF5bel5YW357yW6K+R5aSx6LSlXHJcbiAgICBjb25zdCBvcGVuRGF0YUNvbnRleHQgPSBnYW1lSnNvbi5vcGVuRGF0YUNvbnRleHQ7XHJcbiAgICBpZiAoXHJcbiAgICAgICAgb3BlbkRhdGFDb250ZXh0ID09IG51bGxcclxuICAgICAgICB8fCAodHlwZW9mIG9wZW5EYXRhQ29udGV4dCA9PT0gJ3N0cmluZycgJiYgIW9wZW5EYXRhQ29udGV4dC50cmltKCkpXHJcbiAgICApIHtcclxuICAgICAgICBkZWxldGUgZ2FtZUpzb24ub3BlbkRhdGFDb250ZXh0O1xyXG4gICAgfVxyXG4gICAgd3JpdGVKc29uRmlsZShnYW1lSnNvblBhdGgsIGdhbWVKc29uKTtcclxuICAgIHJlYWRHYW1lSnNvblNhZmUoZ2FtZUpzb25QYXRoKTtcclxuICAgIGNvbnNvbGUubG9nKCdbdG9vbHNdIHBhdGNoZWQgZ2FtZS5qc29uIOKGkiBwYXJhbGxlbFByZWxvYWRTdWJwYWNrYWdlcyBtYWluL2ZpcnN0L2NvbW0sIHJlbW92ZWQgZW1wdHkgb3BlbkRhdGFDb250ZXh0Jyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNob3VsZFN0cmlwQ29uc29sZShvcHRpb25zOiBhbnkpOiBib29sZWFuIHtcclxuICAgIGNvbnN0IHYgPSBvcHRpb25zPy5wYWNrYWdlcz8udG9vbHM/LnN0cmlwQ29uc29sZTtcclxuICAgIGlmICh2ID09PSB0cnVlKSByZXR1cm4gdHJ1ZTtcclxuICAgIGlmICh2ID09PSAndHJ1ZScgfHwgdiA9PT0gMSkgcmV0dXJuIHRydWU7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBvbkJlZm9yZUJ1aWxkKF9vcHRpb25zOiBhbnksIF9yZXN1bHQ6IGFueSkge1xyXG4gICAgdHJ5IHtcclxuICAgICAgICBjb25zb2xlLmxvZygnW3Rvb2xzXSBvbkJlZm9yZUJ1aWxkOiBnZW5lcmF0ZSBjb25maWcgYmluJyk7XHJcbiAgICAgICAgZ2VuZXJhdGVDb25maWdCaW4oKTtcclxuICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1t0b29sc10gb25CZWZvcmVCdWlsZCBnZW5lcmF0ZSBjb25maWcgYmluIGZhaWxlZDonLCBlcnIpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbkFmdGVyQnVpbGQob3B0aW9uczogYW55LCByZXN1bHQ6IGFueSkge1xyXG4gICAgdHJ5IHtcclxuICAgICAgICBjb25zdCBidWlsZERlc3QgPSByZXNvbHZlQnVpbGREZXN0KG9wdGlvbnMsIHJlc3VsdCk7XHJcbiAgICAgICAgaWYgKGJ1aWxkRGVzdCkge1xyXG4gICAgICAgICAgICBjb25zdCBnYW1lSnNvblBhdGggPSBwYXRoLmpvaW4oYnVpbGREZXN0LCAnZ2FtZS5qc29uJyk7XHJcbiAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGdhbWVKc29uUGF0aCkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zPy5wbGF0Zm9ybSA9PT0gJ3dlY2hhdGdhbWUnIHx8IGlzV2VDaGF0R2FtZUpzb24ocmVhZEdhbWVKc29uU2FmZShnYW1lSnNvblBhdGgpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhdGNoV2VDaGF0R2FtZUpzb24oYnVpbGREZXN0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAob3B0aW9ucz8ucGxhdGZvcm0gPT09ICd3ZWNoYXRnYW1lJykge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1t0b29sc10gd2VjaGF0Z2FtZSBidWlsZCBmaW5pc2hlZCBidXQgYnVpbGQgb3V0cHV0IGRpciB3YXMgbm90IHJlc29sdmVkJyk7XHJcbiAgICAgICAgfVxyXG4gICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignW3Rvb2xzXSBvbkFmdGVyQnVpbGQgcGF0Y2ggZ2FtZS5qc29uIGZhaWxlZDonLCBlcnIpO1xyXG4gICAgfVxyXG4gICAgdHJ5IHtcclxuICAgICAgICBpZiAoc2hvdWxkU3RyaXBDb25zb2xlKG9wdGlvbnMpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJvb3RzID0gY29sbGVjdFN0cmlwUm9vdHMob3B0aW9ucywgcmVzdWx0KTtcclxuICAgICAgICAgICAgaWYgKHJvb3RzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICAgICAgICAgICAgICdbdG9vbHNdIHN0cmlwQ29uc29sZSDlt7Lli77pgInkvYbmnKrog73op6PmnpDmnoTlu7rovpPlh7rnm67lvZXvvIjmo4Dmn6UgcmVzdWx0LmRlc3QgLyBwYXRocyAvIGJ1aWxkUGF0aCtvdXRwdXROYW1l77yJJyxcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnW3Rvb2xzXSBvbkFmdGVyQnVpbGQgc3RyaXBDb25zb2xlIOKGkicsIHJvb3RzLmpvaW4oJyB8ICcpKTtcclxuICAgICAgICAgICAgICAgIGF3YWl0IHN0cmlwQ29uc29sZUZyb21CdWlsZE91dHB1dChyb290cyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdbdG9vbHNdIG9uQWZ0ZXJCdWlsZCBzdHJpcENvbnNvbGUgZmFpbGVkOicsIGVycik7XHJcbiAgICB9XHJcbiAgICB0cnkge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCdbdG9vbHNdIG9uQWZ0ZXJCdWlsZDogZ2VuZXJhdGUgY29uZmlnIGJpbicpO1xyXG4gICAgICAgIGdlbmVyYXRlQ29uZmlnQmluKCk7XHJcbiAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdbdG9vbHNdIG9uQWZ0ZXJCdWlsZCBnZW5lcmF0ZSBjb25maWcgYmluIGZhaWxlZDonLCBlcnIpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbn1cclxuIl19