You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
281 lines
47 KiB
281 lines
47 KiB
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.unload = exports.load = exports.methods = void 0;
|
|
const path_1 = __importDefault(require("path"));
|
|
const Fs = require('fs');
|
|
// ── 属性映射:标记 → MapGrid 组件全部 8 个属性的完整值 ──
|
|
const MARKER_PROPS = {
|
|
'': { _isCanWalk: true, _isCanPutGrid: true, _isBestPlace: false, _isCanBeDig: false, _isCanPutText: false, _isCanRemove: false, _isCanBeThunder: false, _isFreePlace: false },
|
|
'CanWalk': { _isCanWalk: true, _isCanPutGrid: true, _isBestPlace: true, _isCanBeDig: false, _isCanPutText: false, _isCanRemove: false, _isCanBeThunder: false, _isFreePlace: false },
|
|
'CanBeDig': { _isCanWalk: false, _isCanPutGrid: false, _isBestPlace: false, _isCanBeDig: true, _isCanPutText: false, _isCanRemove: false, _isCanBeThunder: false, _isFreePlace: false },
|
|
'CanPut': { _isCanWalk: false, _isCanPutGrid: false, _isBestPlace: false, _isCanBeDig: false, _isCanPutText: true, _isCanRemove: false, _isCanBeThunder: false, _isFreePlace: false },
|
|
'spawnPoint_1': { _isCanWalk: true, _isCanPutGrid: false, _isBestPlace: false, _isCanBeDig: false, _isCanPutText: false, _isCanRemove: false, _isCanBeThunder: false, _isFreePlace: false },
|
|
'spawnPoint_2': { _isCanWalk: true, _isCanPutGrid: false, _isBestPlace: false, _isCanBeDig: false, _isCanPutText: false, _isCanRemove: false, _isCanBeThunder: false, _isFreePlace: false },
|
|
'spawnPoint_3': { _isCanWalk: true, _isCanPutGrid: false, _isBestPlace: false, _isCanBeDig: false, _isCanPutText: false, _isCanRemove: false, _isCanBeThunder: false, _isFreePlace: false },
|
|
'wallTarget1': { _isCanWalk: true, _isCanPutGrid: false, _isBestPlace: false, _isCanBeDig: false, _isCanPutText: false, _isCanRemove: false, _isCanBeThunder: false, _isFreePlace: false },
|
|
'wallTarget2': { _isCanWalk: true, _isCanPutGrid: false, _isBestPlace: false, _isCanBeDig: false, _isCanPutText: false, _isCanRemove: false, _isCanBeThunder: false, _isFreePlace: false },
|
|
'isFreePlace': { _isCanWalk: true, _isCanPutGrid: true, _isBestPlace: false, _isCanBeDig: false, _isCanPutText: false, _isCanRemove: false, _isCanBeThunder: false, _isFreePlace: true },
|
|
};
|
|
const SPAWN_MARKERS = ['spawnPoint_1', 'spawnPoint_2', 'spawnPoint_3'];
|
|
const MAPGRID_FILE_ID = 'a5Czjqnj1DIa/1qXv6uwzF';
|
|
const CELL_SIZE = 93;
|
|
const ORIGIN_X = -325.5;
|
|
const ORIGIN_Y = 418.5;
|
|
const COLS = 8;
|
|
const ROWS = 10;
|
|
function cellToWorld(index) {
|
|
const col = index % COLS;
|
|
const row = Math.floor(index / COLS);
|
|
return { x: ORIGIN_X + col * CELL_SIZE, y: ORIGIN_Y - row * CELL_SIZE };
|
|
}
|
|
/** 在 JSON 数组中按 _name 查找节点,返回索引 */
|
|
function findNodeIndex(data, name) {
|
|
for (let i = 0; i < data.length; i++) {
|
|
if (data[i] && data[i]._name === name)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
/** 获取格子的 PrefabInstance 对象 */
|
|
function getGridInstance(data, geziIdx, gridIndex) {
|
|
const gezi = data[geziIdx];
|
|
if (!gezi || !gezi._children || gridIndex >= gezi._children.length)
|
|
return null;
|
|
const gridRef = gezi._children[gridIndex];
|
|
const gridNode = data[gridRef.__id__];
|
|
if (!gridNode || !gridNode._prefab)
|
|
return null;
|
|
const prefabInfo = data[gridNode._prefab.__id__];
|
|
if (!prefabInfo || !prefabInfo.instance)
|
|
return null;
|
|
return data[prefabInfo.instance.__id__];
|
|
}
|
|
/** 清除指定格子中所有 MapGrid 组件的属性覆盖 */
|
|
function clearGridOverrides(data, geziIdx, gridIndex) {
|
|
const instance = getGridInstance(data, geziIdx, gridIndex);
|
|
if (!instance || !instance.propertyOverrides)
|
|
return;
|
|
instance.propertyOverrides = instance.propertyOverrides.filter((ref) => {
|
|
const po = data[ref.__id__];
|
|
if (!po || !po.targetInfo)
|
|
return true; // 保留非 targetInfo 的条目
|
|
const ti = data[po.targetInfo.__id__];
|
|
if (!ti || !ti.localID)
|
|
return true;
|
|
// 删除 targetInfo.localID 匹配 MapGrid 组件的覆盖
|
|
return ti.localID[0] !== MAPGRID_FILE_ID;
|
|
});
|
|
}
|
|
/** 向指定格子的 PrefabInstance 追加一条 MapGrid 属性覆盖 */
|
|
function addGridOverride(data, geziIdx, gridIndex, propName, value) {
|
|
const instance = getGridInstance(data, geziIdx, gridIndex);
|
|
if (!instance || !instance.propertyOverrides)
|
|
return;
|
|
const targetInfoId = data.length;
|
|
data.push({ __type__: 'cc.TargetInfo', localID: [MAPGRID_FILE_ID] });
|
|
const overrideId = data.length;
|
|
data.push({
|
|
__type__: 'CCPropertyOverrideInfo',
|
|
targetInfo: { __id__: targetInfoId },
|
|
propertyPath: [propName],
|
|
value: value,
|
|
});
|
|
instance.propertyOverrides.push({ __id__: overrideId });
|
|
}
|
|
/** 移动/设置指定父节点下某个子节点的坐标 */
|
|
function setChildPos(data, parentName, childName, x, y) {
|
|
const parentIdx = findNodeIndex(data, parentName);
|
|
if (parentIdx < 0)
|
|
return false;
|
|
const parent = data[parentIdx];
|
|
if (!parent._children)
|
|
return false;
|
|
for (const ref of parent._children) {
|
|
const child = data[ref.__id__];
|
|
if (child && child._name === childName) {
|
|
child._lpos = { __type__: 'cc.Vec3', x, y, z: 0 };
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
/** 从父节点中删除指定名称的子节点 */
|
|
function removeChildByName(data, parentName, childName) {
|
|
const parentIdx = findNodeIndex(data, parentName);
|
|
if (parentIdx < 0)
|
|
return;
|
|
const parent = data[parentIdx];
|
|
if (!parent._children)
|
|
return;
|
|
parent._children = parent._children.filter((ref) => {
|
|
const child = data[ref.__id__];
|
|
return !(child && child._name === childName);
|
|
});
|
|
}
|
|
/** 向父节点添加一个浅拷贝自模板的子节点(用于补充缺失的 spawnPoint) */
|
|
function copyChildFromTemplate(data, template, parentName, childName) {
|
|
const parentIdx = findNodeIndex(data, parentName);
|
|
if (parentIdx < 0)
|
|
return;
|
|
// 从模板中找到同名子节点引用
|
|
const tplParentIdx = findNodeIndex(template, parentName);
|
|
if (tplParentIdx < 0)
|
|
return;
|
|
const tplParent = template[tplParentIdx];
|
|
for (const ref of tplParent._children || []) {
|
|
const child = template[ref.__id__];
|
|
if (child && child._name === childName) {
|
|
// 将子节点及其组件深克隆追加到 data 末尾,并在父节点 _children 中引用
|
|
const cloneStartIdx = data.length;
|
|
const cloned = JSON.parse(JSON.stringify(child));
|
|
data.push(cloned);
|
|
data[parentIdx]._children.push({ __id__: cloneStartIdx });
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* 应用格子数据到预制体 JSON(新增和更新共用)
|
|
*/
|
|
function applyGridData(data, template, grids) {
|
|
const geziIdx = findNodeIndex(data, '格子');
|
|
if (geziIdx < 0)
|
|
return;
|
|
// 1. 收集 spawn 位置映射 + 遍历格子清除旧覆盖 / 添加新覆盖
|
|
const spawnPositions = new Map();
|
|
for (let i = 0; i < 80; i++) {
|
|
clearGridOverrides(data, geziIdx, i);
|
|
const marker = grids[i] || '';
|
|
const props = MARKER_PROPS[marker];
|
|
if (props) {
|
|
for (const [prop, value] of Object.entries(props)) {
|
|
addGridOverride(data, geziIdx, i, prop, value);
|
|
}
|
|
}
|
|
if (SPAWN_MARKERS.includes(marker)) {
|
|
spawnPositions.set(marker, cellToWorld(i));
|
|
}
|
|
}
|
|
// 2. wallTarget1/wallTarget2 配对
|
|
const t1 = grids.indexOf('wallTarget1');
|
|
const t2 = grids.indexOf('wallTarget2');
|
|
if (t1 >= 0 && t2 >= 0) {
|
|
const p1 = cellToWorld(t1), p2 = cellToWorld(t2);
|
|
const r1 = Math.floor(t1 / COLS), c1 = t1 % COLS;
|
|
const r2 = Math.floor(t2 / COLS), c2 = t2 % COLS;
|
|
let mx, my;
|
|
if (r1 === r2) {
|
|
mx = (p1.x + p2.x) / 2;
|
|
my = p1.y;
|
|
} // 横连
|
|
else if (c1 === c2) {
|
|
mx = p1.x;
|
|
my = (p1.y + p2.y) / 2;
|
|
} // 竖连
|
|
else {
|
|
mx = (p1.x + p2.x) / 2;
|
|
my = (p1.y + p2.y) / 2;
|
|
} // 斜角
|
|
setChildPos(data, '目标点', 'wallTarget1', mx, my);
|
|
}
|
|
else if (t1 >= 0) {
|
|
const pos = cellToWorld(t1);
|
|
setChildPos(data, '目标点', 'wallTarget1', pos.x, pos.y);
|
|
}
|
|
// 3. 同步 spawn 节点:删除多余 → 补回缺失 → 设置坐标
|
|
const allSpawns = ['spawnPoint_1', 'spawnPoint_2', 'spawnPoint_3', 'spawnPoint_4', 'spawnPoint_5', 'spawnPoint_6', 'spawnPoint_7'];
|
|
for (const spName of allSpawns) {
|
|
if (spawnPositions.has(spName))
|
|
continue;
|
|
removeChildByName(data, '出怪口', spName);
|
|
}
|
|
for (const [spName, pos] of spawnPositions) {
|
|
const parentIdx = findNodeIndex(data, '出怪口');
|
|
const exists = parentIdx >= 0 && (data[parentIdx]._children || []).some((ref) => {
|
|
const child = data[ref.__id__];
|
|
return child && child._name === spName;
|
|
});
|
|
if (!exists) {
|
|
copyChildFromTemplate(data, template, '出怪口', spName);
|
|
}
|
|
setChildPos(data, '出怪口', spName, pos.x, pos.y);
|
|
}
|
|
}
|
|
// ── 扩展入口 ──
|
|
exports.methods = {
|
|
async generateMapLayers() {
|
|
try {
|
|
const projectPath = Editor.Project.path;
|
|
// 1. 读取 Excel
|
|
const excelPath = path_1.default.join(projectPath, 'assets/res/地图/地图.xls');
|
|
if (!Fs.existsSync(excelPath)) {
|
|
console.error('[地图生成] Excel 文件不存在:', excelPath);
|
|
return;
|
|
}
|
|
const xlsxPath = path_1.default.join(__dirname, '../../excel-to-json-ts/lib/xlsx.js');
|
|
const XLSX = require(xlsxPath);
|
|
const buffer = Fs.readFileSync(excelPath);
|
|
const workbook = XLSX.read(buffer, { type: 'buffer' });
|
|
// 2. 读取模板
|
|
const templatePath = path_1.default.join(projectPath, 'assets/bundles/battleMap/prefab/地图/mapLayerTemplate.prefab');
|
|
if (!Fs.existsSync(templatePath)) {
|
|
console.error('[地图生成] 模板预制体不存在:', templatePath);
|
|
return;
|
|
}
|
|
const templateJson = Fs.readFileSync(templatePath, 'utf-8');
|
|
const templateData = JSON.parse(templateJson);
|
|
const prefabDir = path_1.default.join(projectPath, 'assets/bundles/battleMap/prefab/地图');
|
|
console.log(`[地图生成] 开始处理 ${workbook.SheetNames.length} 个工作表...`);
|
|
// 3. 遍历每个工作表
|
|
for (const sheetName of workbook.SheetNames) {
|
|
const worksheet = workbook.Sheets[sheetName];
|
|
const rows = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
|
|
const grids = [];
|
|
for (let r = 0; r < ROWS; r++) {
|
|
for (let c = 0; c < COLS; c++) {
|
|
const raw = (rows[r] || [])[c];
|
|
grids.push((raw !== undefined && raw !== null && raw !== '') ? String(raw).trim() : '');
|
|
}
|
|
}
|
|
const prefabPath = path_1.default.join(prefabDir, `${sheetName}.prefab`);
|
|
const exists = Fs.existsSync(prefabPath);
|
|
let prefabData;
|
|
if (exists) {
|
|
// 已有预制体 → 读取后原地修改
|
|
const existingJson = Fs.readFileSync(prefabPath, 'utf-8');
|
|
prefabData = JSON.parse(existingJson);
|
|
applyGridData(prefabData, templateData, grids);
|
|
}
|
|
else {
|
|
// 新预制体 → 从模板克隆生成
|
|
prefabData = JSON.parse(JSON.stringify(templateData));
|
|
prefabData[0]._name = sheetName;
|
|
prefabData[1]._name = sheetName;
|
|
applyGridData(prefabData, templateData, grids);
|
|
}
|
|
const jsonStr = JSON.stringify(prefabData, null, 2);
|
|
const url = `db://assets/bundles/battleMap/prefab/地图/${sheetName}.prefab`;
|
|
await Editor.Message.request('asset-db', 'create-asset', url, jsonStr, { overwrite: true });
|
|
const stats = {};
|
|
for (const m of grids) {
|
|
const k = m || '(空白)';
|
|
stats[k] = (stats[k] || 0) + 1;
|
|
}
|
|
const statStr = Object.entries(stats).sort((a, b) => b[1] - a[1]).map(([k, v]) => `${k}:${v}`).join(', ');
|
|
console.log(`[地图生成] ${exists ? '~' : '+'} ${sheetName}.prefab (${statStr})`);
|
|
}
|
|
console.log('[地图生成] 全部完成!');
|
|
}
|
|
catch (err) {
|
|
console.error('[地图生成] 错误:', err);
|
|
}
|
|
},
|
|
};
|
|
function load() { }
|
|
exports.load = load;
|
|
function unload() { }
|
|
exports.unload = unload;
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NvdXJjZS9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLGdEQUF3QjtBQUV4QixNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFFekIseUNBQXlDO0FBQ3pDLE1BQU0sWUFBWSxHQUE0QztJQUMxRCxFQUFFLEVBQWUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFHLGFBQWEsRUFBRSxJQUFJLEVBQUcsWUFBWSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUU7SUFDN0wsU0FBUyxFQUFRLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRyxhQUFhLEVBQUUsSUFBSSxFQUFHLFlBQVksRUFBRSxJQUFJLEVBQUcsV0FBVyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFO0lBQzdMLFVBQVUsRUFBTyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUcsYUFBYSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRTtJQUM3TCxRQUFRLEVBQVMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUcsWUFBWSxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUU7SUFDN0wsY0FBYyxFQUFHLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRyxhQUFhLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFO0lBQzdMLGNBQWMsRUFBRyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUcsYUFBYSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRTtJQUM3TCxjQUFjLEVBQUcsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFHLGFBQWEsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUU7SUFDN0wsYUFBYSxFQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRyxhQUFhLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFO0lBQzdMLGFBQWEsRUFBSSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUcsYUFBYSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxL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OlsiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5cbmNvbnN0IEZzID0gcmVxdWlyZSgnZnMnKTtcblxuLy8g4pSA4pSAIOWxnuaAp+aYoOWwhO+8muagh+iusCDihpIgTWFwR3JpZCDnu4Tku7blhajpg6ggOCDkuKrlsZ7mgKfnmoTlrozmlbTlgLwg4pSA4pSAXG5jb25zdCBNQVJLRVJfUFJPUFM6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+PiA9IHtcbiAgICAnJzogICAgICAgICAgICAgIHsgX2lzQ2FuV2FsazogdHJ1ZSwgIF9pc0NhblB1dEdyaWQ6IHRydWUsICBfaXNCZXN0UGxhY2U6IGZhbHNlLCBfaXNDYW5CZURpZzogZmFsc2UsIF9pc0NhblB1dFRleHQ6IGZhbHNlLCBfaXNDYW5SZW1vdmU6IGZhbHNlLCBfaXNDYW5CZVRodW5kZXI6IGZhbHNlLCBfaXNGcmVlUGxhY2U6IGZhbHNlIH0sXG4gICAgJ0NhbldhbGsnOiAgICAgICB7IF9pc0NhbldhbGs6IHRydWUsICBfaXNDYW5QdXRHcmlkOiB0cnVlLCAgX2lzQmVzdFBsYWNlOiB0cnVlLCAgX2lzQ2FuQmVEaWc6IGZhbHNlLCBfaXNDYW5QdXRUZXh0OiBmYWxzZSwgX2lzQ2FuUmVtb3ZlOiBmYWxzZSwgX2lzQ2FuQmVUaHVuZGVyOiBmYWxzZSwgX2lzRnJlZVBsYWNlOiBmYWxzZSB9LFxuICAgICdDYW5CZURpZyc6ICAgICAgeyBfaXNDYW5XYWxrOiBmYWxzZSwgX2lzQ2FuUHV0R3JpZDogZmFsc2UsIF9pc0Jlc3RQbGFjZTogZmFsc2UsIF9pc0NhbkJlRGlnOiB0cnVlLCAgX2lzQ2FuUHV0VGV4dDogZmFsc2UsIF9pc0NhblJlbW92ZTogZmFsc2UsIF9pc0NhbkJlVGh1bmRlcjogZmFsc2UsIF9pc0ZyZWVQbGFjZTogZmFsc2UgfSxcbiAgICAnQ2FuUHV0JzogICAgICAgIHsgX2lzQ2FuV2FsazogZmFsc2UsIF9pc0NhblB1dEdyaWQ6IGZhbHNlLCBfaXNCZXN0UGxhY2U6IGZhbHNlLCBfaXNDYW5CZURpZzogZmFsc2UsIF9pc0NhblB1dFRleHQ6IHRydWUsICBfaXNDYW5SZW1vdmU6IGZhbHNlLCBfaXNDYW5CZVRodW5kZXI6IGZhbHNlLCBfaXNGcmVlUGxhY2U6IGZhbHNlIH0sXG4gICAgJ3NwYXduUG9pbnRfMSc6ICB7IF9pc0NhbldhbGs6IHRydWUsICBfaXNDYW5QdXRHcmlkOiBmYWxzZSwgX2lzQmVzdFBsYWNlOiBmYWxzZSwgX2lzQ2FuQmVEaWc6IGZhbHNlLCBfaXNDYW5QdXRUZXh0OiBmYWxzZSwgX2lzQ2FuUmVtb3ZlOiBmYWxzZSwgX2lzQ2FuQmVUaHVuZGVyOiBmYWxzZSwgX2lzRnJlZVBsYWNlOiBmYWxzZSB9LFxuICAgICdzcGF3blBvaW50XzInOiAgeyBfaXNDYW5XYWxrOiB0cnVlLCAgX2lzQ2FuUHV0R3JpZDogZmFsc2UsIF9pc0Jlc3RQbGFjZTogZmFsc2UsIF9pc0NhbkJlRGlnOiBmYWxzZSwgX2lzQ2FuUHV0VGV4dDogZmFsc2UsIF9pc0NhblJlbW92ZTogZmFsc2UsIF9pc0NhbkJlVGh1bmRlcjogZmFsc2UsIF9pc0ZyZWVQbGFjZTogZmFsc2UgfSxcbiAgICAnc3Bhd25Qb2ludF8zJzogIHsgX2lzQ2FuV2FsazogdHJ1ZSwgIF9pc0NhblB1dEdyaWQ6IGZhbHNlLCBfaXNCZXN0UGxhY2U6IGZhbHNlLCBfaXNDYW5CZURpZzogZmFsc2UsIF9pc0NhblB1dFRleHQ6IGZhbHNlLCBfaXNDYW5SZW1vdmU6IGZhbHNlLCBfaXNDYW5CZVRodW5kZXI6IGZhbHNlLCBfaXNGcmVlUGxhY2U6IGZhbHNlIH0sXG4gICAgJ3dhbGxUYXJnZXQxJzogICB7IF9pc0NhbldhbGs6IHRydWUsICBfaXNDYW5QdXRHcmlkOiBmYWxzZSwgX2lzQmVzdFBsYWNlOiBmYWxzZSwgX2lzQ2FuQmVEaWc6IGZhbHNlLCBfaXNDYW5QdXRUZXh0OiBmYWxzZSwgX2lzQ2FuUmVtb3ZlOiBmYWxzZSwgX2lzQ2FuQmVUaHVuZGVyOiBmYWxzZSwgX2lzRnJlZVBsYWNlOiBmYWxzZSB9LFxuICAgICd3YWxsVGFyZ2V0Mic6ICAgeyBfaXNDYW5XYWxrOiB0cnVlLCAgX2lzQ2FuUHV0R3JpZDogZmFsc2UsIF9pc0Jlc3RQbGFjZTogZmFsc2UsIF9pc0NhbkJlRGlnOiBmYWxzZSwgX2lzQ2FuUHV0VGV4dDogZmFsc2UsIF9pc0NhblJlbW92ZTogZmFsc2UsIF9pc0NhbkJlVGh1bmRlcjogZmFsc2UsIF9pc0ZyZWVQbGFjZTogZmFsc2UgfSxcbiAgICAnaXNGcmVlUGxhY2UnOiAgIHsgX2lzQ2FuV2FsazogdHJ1ZSwgIF9pc0NhblB1dEdyaWQ6IHRydWUsICBfaXNCZXN0UGxhY2U6IGZhbHNlLCBfaXNDYW5CZURpZzogZmFsc2UsIF9pc0NhblB1dFRleHQ6IGZhbHNlLCBfaXNDYW5SZW1vdmU6IGZhbHNlLCBfaXNDYW5CZVRodW5kZXI6IGZhbHNlLCBfaXNGcmVlUGxhY2U6IHRydWUgIH0sXG59O1xuXG5jb25zdCBTUEFXTl9NQVJLRVJTID0gWydzcGF3blBvaW50XzEnLCAnc3Bhd25Qb2ludF8yJywgJ3NwYXduUG9pbnRfMyddO1xuY29uc3QgTUFQR1JJRF9GSUxFX0lEID0gJ2E1Q3pqcW5qMURJYS8xcVh2NnV3ekYnO1xuXG5jb25zdCBDRUxMX1NJWkUgPSA5MztcbmNvbnN0IE9SSUdJTl9YID0gLTMyNS41O1xuY29uc3QgT1JJR0lOX1kgPSA0MTguNTtcbmNvbnN0IENPTFMgPSA4O1xuY29uc3QgUk9XUyA9IDEwO1xuXG5mdW5jdGlvbiBjZWxsVG9Xb3JsZChpbmRleDogbnVtYmVyKTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHtcbiAgICBjb25zdCBjb2wgPSBpbmRleCAlIENPTFM7XG4gICAgY29uc3Qgcm93ID0gTWF0aC5mbG9vcihpbmRleCAvIENPTFMpO1xuICAgIHJldHVybiB7IHg6IE9SSUdJTl9YICsgY29sICogQ0VMTF9TSVpFLCB5OiBPUklHSU5fWSAtIHJvdyAqIENFTExfU0laRSB9O1xufVxuXG4vKiog5ZyoIEpTT04g5pWw57uE5Lit5oyJIF9uYW1lIOafpeaJvuiKgueCue+8jOi/lOWbnue0ouW8lSAqL1xuZnVuY3Rpb24gZmluZE5vZGVJbmRleChkYXRhOiBhbnlbXSwgbmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGRhdGFbaV0gJiYgZGF0YVtpXS5fbmFtZSA9PT0gbmFtZSkgcmV0dXJuIGk7XG4gICAgfVxuICAgIHJldHVybiAtMTtcbn1cblxuLyoqIOiOt+WPluagvOWtkOeahCBQcmVmYWJJbnN0YW5jZSDlr7nosaEgKi9cbmZ1bmN0aW9uIGdldEdyaWRJbnN0YW5jZShkYXRhOiBhbnlbXSwgZ2V6aUlkeDogbnVtYmVyLCBncmlkSW5kZXg6IG51bWJlcik6IGFueSB8IG51bGwge1xuICAgIGNvbnN0IGdlemkgPSBkYXRhW2dlemlJZHhdO1xuICAgIGlmICghZ2V6aSB8fCAhZ2V6aS5fY2hpbGRyZW4gfHwgZ3JpZEluZGV4ID49IGdlemkuX2NoaWxkcmVuLmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgZ3JpZFJlZiA9IGdlemkuX2NoaWxkcmVuW2dyaWRJbmRleF07XG4gICAgY29uc3QgZ3JpZE5vZGUgPSBkYXRhW2dyaWRSZWYuX19pZF9fXTtcbiAgICBpZiAoIWdyaWROb2RlIHx8ICFncmlkTm9kZS5fcHJlZmFiKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBwcmVmYWJJbmZvID0gZGF0YVtncmlkTm9kZS5fcHJlZmFiLl9faWRfX107XG4gICAgaWYgKCFwcmVmYWJJbmZvIHx8ICFwcmVmYWJJbmZvLmluc3RhbmNlKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gZGF0YVtwcmVmYWJJbmZvLmluc3RhbmNlLl9faWRfX107XG59XG5cbi8qKiDmuIXpmaTmjIflrprmoLzlrZDkuK3miYDmnIkgTWFwR3JpZCDnu4Tku7bnmoTlsZ7mgKfopobnm5YgKi9cbmZ1bmN0aW9uIGNsZWFyR3JpZE92ZXJyaWRlcyhkYXRhOiBhbnlbXSwgZ2V6aUlkeDogbnVtYmVyLCBncmlkSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGluc3RhbmNlID0gZ2V0R3JpZEluc3RhbmNlKGRhdGEsIGdlemlJZHgsIGdyaWRJbmRleCk7XG4gICAgaWYgKCFpbnN0YW5jZSB8fCAhaW5zdGFuY2UucHJvcGVydHlPdmVycmlkZXMpIHJldHVybjtcbiAgICBpbnN0YW5jZS5wcm9wZXJ0eU92ZXJyaWRlcyA9IGluc3RhbmNlLnByb3BlcnR5T3ZlcnJpZGVzLmZpbHRlcigocmVmOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgcG8gPSBkYXRhW3JlZi5fX2lkX19dO1xuICAgICAgICBpZiAoIXBvIHx8ICFwby50YXJnZXRJbmZvKSByZXR1cm4gdHJ1ZTsgLy8g5L+d55WZ6Z2eIHRhcmdldEluZm8g55qE5p2h55uuXG4gICAgICAgIGNvbnN0IHRpID0gZGF0YVtwby50YXJnZXRJbmZvLl9faWRfX107XG4gICAgICAgIGlmICghdGkgfHwgIXRpLmxvY2FsSUQpIHJldHVybiB0cnVlO1xuICAgICAgICAvLyDliKDpmaQgdGFyZ2V0SW5mby5sb2NhbElEIOWMuemFjSBNYXBHcmlkIOe7hOS7tueahOimhuebllxuICAgICAgICByZXR1cm4gdGkubG9jYWxJRFswXSAhPT0gTUFQR1JJRF9GSUxFX0lEO1xuICAgIH0pO1xufVxuXG4vKiog5ZCR5oyH5a6a5qC85a2Q55qEIFByZWZhYkluc3RhbmNlIOi/veWKoOS4gOadoSBNYXBHcmlkIOWxnuaAp+imhuebliAqL1xuZnVuY3Rpb24gYWRkR3JpZE92ZXJyaWRlKGRhdGE6IGFueVtdLCBnZXppSWR4OiBudW1iZXIsIGdyaWRJbmRleDogbnVtYmVyLCBwcm9wTmFtZTogc3RyaW5nLCB2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgY29uc3QgaW5zdGFuY2UgPSBnZXRHcmlkSW5zdGFuY2UoZGF0YSwgZ2V6aUlkeCwgZ3JpZEluZGV4KTtcbiAgICBpZiAoIWluc3RhbmNlIHx8ICFpbnN0YW5jZS5wcm9wZXJ0eU92ZXJyaWRlcykgcmV0dXJuO1xuXG4gICAgY29uc3QgdGFyZ2V0SW5mb0lkID0gZGF0YS5sZW5ndGg7XG4gICAgZGF0YS5wdXNoKHsgX190eXBlX186ICdjYy5UYXJnZXRJbmZvJywgbG9jYWxJRDogW01BUEdSSURfRklMRV9JRF0gfSk7XG5cbiAgICBjb25zdCBvdmVycmlkZUlkID0gZGF0YS5sZW5ndGg7XG4gICAgZGF0YS5wdXNoKHtcbiAgICAgICAgX190eXBlX186ICdDQ1Byb3BlcnR5T3ZlcnJpZGVJbmZvJyxcbiAgICAgICAgdGFyZ2V0SW5mbzogeyBfX2lkX186IHRhcmdldEluZm9JZCB9LFxuICAgICAgICBwcm9wZXJ0eVBhdGg6IFtwcm9wTmFtZV0sXG4gICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICB9KTtcbiAgICBpbnN0YW5jZS5wcm9wZXJ0eU92ZXJyaWRlcy5wdXNoKHsgX19pZF9fOiBvdmVycmlkZUlkIH0pO1xufVxuXG4vKiog56e75YqoL+iuvue9ruaMh+WumueItuiKgueCueS4i+afkOS4quWtkOiKgueCueeahOWdkOaghyAqL1xuZnVuY3Rpb24gc2V0Q2hpbGRQb3MoZGF0YTogYW55W10sIHBhcmVudE5hbWU6IHN0cmluZywgY2hpbGROYW1lOiBzdHJpbmcsIHg6IG51bWJlciwgeTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgcGFyZW50SWR4ID0gZmluZE5vZGVJbmRleChkYXRhLCBwYXJlbnROYW1lKTtcbiAgICBpZiAocGFyZW50SWR4IDwgMCkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHBhcmVudCA9IGRhdGFbcGFyZW50SWR4XTtcbiAgICBpZiAoIXBhcmVudC5fY2hpbGRyZW4pIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IHJlZiBvZiBwYXJlbnQuX2NoaWxkcmVuKSB7XG4gICAgICAgIGNvbnN0IGNoaWxkID0gZGF0YVtyZWYuX19pZF9fXTtcbiAgICAgICAgaWYgKGNoaWxkICYmIGNoaWxkLl9uYW1lID09PSBjaGlsZE5hbWUpIHtcbiAgICAgICAgICAgIGNoaWxkLl9scG9zID0geyBfX3R5cGVfXzogJ2NjLlZlYzMnLCB4LCB5LCB6OiAwIH07XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKiDku47niLboioLngrnkuK3liKDpmaTmjIflrprlkI3np7DnmoTlrZDoioLngrkgKi9cbmZ1bmN0aW9uIHJlbW92ZUNoaWxkQnlOYW1lKGRhdGE6IGFueVtdLCBwYXJlbnROYW1lOiBzdHJpbmcsIGNoaWxkTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgcGFyZW50SWR4ID0gZmluZE5vZGVJbmRleChkYXRhLCBwYXJlbnROYW1lKTtcbiAgICBpZiAocGFyZW50SWR4IDwgMCkgcmV0dXJuO1xuICAgIGNvbnN0IHBhcmVudCA9IGRhdGFbcGFyZW50SWR4XTtcbiAgICBpZiAoIXBhcmVudC5fY2hpbGRyZW4pIHJldHVybjtcbiAgICBwYXJlbnQuX2NoaWxkcmVuID0gcGFyZW50Ll9jaGlsZHJlbi5maWx0ZXIoKHJlZjogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IGNoaWxkID0gZGF0YVtyZWYuX19pZF9fXTtcbiAgICAgICAgcmV0dXJuICEoY2hpbGQgJiYgY2hpbGQuX25hbWUgPT09IGNoaWxkTmFtZSk7XG4gICAgfSk7XG59XG5cbi8qKiDlkJHniLboioLngrnmt7vliqDkuIDkuKrmtYXmi7fotJ3oh6rmqKHmnb/nmoTlrZDoioLngrnvvIjnlKjkuo7ooaXlhYXnvLrlpLHnmoQgc3Bhd25Qb2ludO+8iSAqL1xuZnVuY3Rpb24gY29weUNoaWxkRnJvbVRlbXBsYXRlKGRhdGE6IGFueVtdLCB0ZW1wbGF0ZTogYW55W10sIHBhcmVudE5hbWU6IHN0cmluZywgY2hpbGROYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBwYXJlbnRJZHggPSBmaW5kTm9kZUluZGV4KGRhdGEsIHBhcmVudE5hbWUpO1xuICAgIGlmIChwYXJlbnRJZHggPCAwKSByZXR1cm47XG4gICAgLy8g5LuO5qih5p2/5Lit5om+5Yiw5ZCM5ZCN5a2Q6IqC54K55byV55SoXG4gICAgY29uc3QgdHBsUGFyZW50SWR4ID0gZmluZE5vZGVJbmRleCh0ZW1wbGF0ZSwgcGFyZW50TmFtZSk7XG4gICAgaWYgKHRwbFBhcmVudElkeCA8IDApIHJldHVybjtcbiAgICBjb25zdCB0cGxQYXJlbnQgPSB0ZW1wbGF0ZVt0cGxQYXJlbnRJZHhdO1xuICAgIGZvciAoY29uc3QgcmVmIG9mIHRwbFBhcmVudC5fY2hpbGRyZW4gfHwgW10pIHtcbiAgICAgICAgY29uc3QgY2hpbGQgPSB0ZW1wbGF0ZVtyZWYuX19pZF9fXTtcbiAgICAgICAgaWYgKGNoaWxkICYmIGNoaWxkLl9uYW1lID09PSBjaGlsZE5hbWUpIHtcbiAgICAgICAgICAgIC8vIOWwhuWtkOiKgueCueWPiuWFtue7hOS7tua3seWFi+mahui/veWKoOWIsCBkYXRhIOacq+Wwvu+8jOW5tuWcqOeItuiKgueCuSBfY2hpbGRyZW4g5Lit5byV55SoXG4gICAgICAgICAgICBjb25zdCBjbG9uZVN0YXJ0SWR4ID0gZGF0YS5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBjbG9uZWQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGNoaWxkKSk7XG4gICAgICAgICAgICBkYXRhLnB1c2goY2xvbmVkKTtcbiAgICAgICAgICAgIGRhdGFbcGFyZW50SWR4XS5fY2hpbGRyZW4ucHVzaCh7IF9faWRfXzogY2xvbmVTdGFydElkeCB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiDlupTnlKjmoLzlrZDmlbDmja7liLDpooTliLbkvZMgSlNPTu+8iOaWsOWinuWSjOabtOaWsOWFseeUqO+8iVxuICovXG5mdW5jdGlvbiBhcHBseUdyaWREYXRhKGRhdGE6IGFueVtdLCB0ZW1wbGF0ZTogYW55W10sIGdyaWRzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IGdlemlJZHggPSBmaW5kTm9kZUluZGV4KGRhdGEsICfmoLzlrZAnKTtcbiAgICBpZiAoZ2V6aUlkeCA8IDApIHJldHVybjtcblxuICAgIC8vIDEuIOaUtumbhiBzcGF3biDkvY3nva7mmKDlsIQgKyDpgY3ljobmoLzlrZDmuIXpmaTml6fopobnm5YgLyDmt7vliqDmlrDopobnm5ZcbiAgICBjb25zdCBzcGF3blBvc2l0aW9ucyA9IG5ldyBNYXA8c3RyaW5nLCB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0+KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCA4MDsgaSsrKSB7XG4gICAgICAgIGNsZWFyR3JpZE92ZXJyaWRlcyhkYXRhLCBnZXppSWR4LCBpKTtcblxuICAgICAgICBjb25zdCBtYXJrZXIgPSBncmlkc1tpXSB8fCAnJztcbiAgICAgICAgY29uc3QgcHJvcHMgPSBNQVJLRVJfUFJPUFNbbWFya2VyXTtcbiAgICAgICAgaWYgKHByb3BzKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IFtwcm9wLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHMpKSB7XG4gICAgICAgICAgICAgICAgYWRkR3JpZE92ZXJyaWRlKGRhdGEsIGdlemlJZHgsIGksIHByb3AsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChTUEFXTl9NQVJLRVJTLmluY2x1ZGVzKG1hcmtlcikpIHtcbiAgICAgICAgICAgIHNwYXduUG9zaXRpb25zLnNldChtYXJrZXIsIGNlbGxUb1dvcmxkKGkpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIDIuIHdhbGxUYXJnZXQxL3dhbGxUYXJnZXQyIOmFjeWvuVxuICAgIGNvbnN0IHQxID0gZ3JpZHMuaW5kZXhPZignd2FsbFRhcmdldDEnKTtcbiAgICBjb25zdCB0MiA9IGdyaWRzLmluZGV4T2YoJ3dhbGxUYXJnZXQyJyk7XG4gICAgaWYgKHQxID49IDAgJiYgdDIgPj0gMCkge1xuICAgICAgICBjb25zdCBwMSA9IGNlbGxUb1dvcmxkKHQxKSwgcDIgPSBjZWxsVG9Xb3JsZCh0Mik7XG4gICAgICAgIGNvbnN0IHIxID0gTWF0aC5mbG9vcih0MSAvIENPTFMpLCBjMSA9IHQxICUgQ09MUztcbiAgICAgICAgY29uc3QgcjIgPSBNYXRoLmZsb29yKHQyIC8gQ09MUyksIGMyID0gdDIgJSBDT0xTO1xuICAgICAgICBsZXQgbXg6IG51bWJlciwgbXk6IG51bWJlcjtcbiAgICAgICAgaWYgKHIxID09PSByMikgICAgICB7IG14ID0gKHAxLnggKyBwMi54KSAvIDI7IG15ID0gcDEueTsgfSAgICAgICAgICAvLyDmqKrov55cbiAgICAgICAgZWxzZSBpZiAoYzEgPT09IGMyKSB7IG14ID0gcDEueDsgICAgICAgICAgICAgICAgbXkgPSAocDEueSArIHAyLnkpIC8gMjsgfSAvLyDnq5bov55cbiAgICAgICAgZWxzZSAgICAgICAgICAgICAgICB7IG14ID0gKHAxLnggKyBwMi54KSAvIDI7ICAgbXkgPSAocDEueSArIHAyLnkpIC8gMjsgfSAvLyDmlpzop5JcbiAgICAgICAgc2V0Q2hpbGRQb3MoZGF0YSwgJ+ebruagh+eCuScsICd3YWxsVGFyZ2V0MScsIG14LCBteSk7XG4gICAgfSBlbHNlIGlmICh0MSA+PSAwKSB7XG4gICAgICAgIGNvbnN0IHBvcyA9IGNlbGxUb1dvcmxkKHQxKTtcbiAgICAgICAgc2V0Q2hpbGRQb3MoZGF0YSwgJ+ebruagh+eCuScsICd3YWxsVGFyZ2V0MScsIHBvcy54LCBwb3MueSk7XG4gICAgfVxuXG4gICAgLy8gMy4g5ZCM5q2lIHNwYXduIOiKgueCue+8muWIoOmZpOWkmuS9mSDihpIg6KGl5Zue57y65aSxIOKGkiDorr7nva7lnZDmoIdcbiAgICBjb25zdCBhbGxTcGF3bnMgPSBbJ3NwYXduUG9pbnRfMScsICdzcGF3blBvaW50XzInLCAnc3Bhd25Qb2ludF8zJywgJ3NwYXduUG9pbnRfNCcsICdzcGF3blBvaW50XzUnLCAnc3Bhd25Qb2ludF82JywgJ3NwYXduUG9pbnRfNyddO1xuICAgIGZvciAoY29uc3Qgc3BOYW1lIG9mIGFsbFNwYXducykge1xuICAgICAgICBpZiAoc3Bhd25Qb3NpdGlvbnMuaGFzKHNwTmFtZSkpIGNvbnRpbnVlO1xuICAgICAgICByZW1vdmVDaGlsZEJ5TmFtZShkYXRhLCAn5Ye65oCq5Y+jJywgc3BOYW1lKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBbc3BOYW1lLCBwb3NdIG9mIHNwYXduUG9zaXRpb25zKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudElkeCA9IGZpbmROb2RlSW5kZXgoZGF0YSwgJ+WHuuaAquWPoycpO1xuICAgICAgICBjb25zdCBleGlzdHMgPSBwYXJlbnRJZHggPj0gMCAmJiAoZGF0YVtwYXJlbnRJZHhdLl9jaGlsZHJlbiB8fCBbXSkuc29tZSgocmVmOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkID0gZGF0YVtyZWYuX19pZF9fXTtcbiAgICAgICAgICAgIHJldHVybiBjaGlsZCAmJiBjaGlsZC5fbmFtZSA9PT0gc3BOYW1lO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFleGlzdHMpIHtcbiAgICAgICAgICAgIGNvcHlDaGlsZEZyb21UZW1wbGF0ZShkYXRhLCB0ZW1wbGF0ZSwgJ+WHuuaAquWPoycsIHNwTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgc2V0Q2hpbGRQb3MoZGF0YSwgJ+WHuuaAquWPoycsIHNwTmFtZSwgcG9zLngsIHBvcy55KTtcbiAgICB9XG59XG5cbi8vIOKUgOKUgCDmianlsZXlhaXlj6Mg4pSA4pSAXG5leHBvcnQgY29uc3QgbWV0aG9kczogeyBba2V5OiBzdHJpbmddOiAoLi4uYXJnczogYW55W10pID0+IGFueSB9ID0ge1xuICAgIGFzeW5jIGdlbmVyYXRlTWFwTGF5ZXJzKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcHJvamVjdFBhdGggPSBFZGl0b3IuUHJvamVjdC5wYXRoO1xuXG4gICAgICAgICAgICAvLyAxLiDor7vlj5YgRXhjZWxcbiAgICAgICAgICAgIGNvbnN0IGV4Y2VsUGF0aCA9IHBhdGguam9pbihwcm9qZWN0UGF0aCwgJ2Fzc2V0cy9yZXMv5Zyw5Zu+L+WcsOWbvi54bHMnKTtcbiAgICAgICAgICAgIGlmICghRnMuZXhpc3RzU3luYyhleGNlbFBhdGgpKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignW+WcsOWbvueUn+aIkF0gRXhjZWwg5paH5Lu25LiN5a2Y5ZyoOicsIGV4Y2VsUGF0aCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeGxzeFBhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vLi4vZXhjZWwtdG8tanNvbi10cy9saWIveGxzeC5qcycpO1xuICAgICAgICAgICAgY29uc3QgWExTWCA9IHJlcXVpcmUoeGxzeFBhdGgpO1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gRnMucmVhZEZpbGVTeW5jKGV4Y2VsUGF0aCk7XG4gICAgICAgICAgICBjb25zdCB3b3JrYm9vayA9IFhMU1gucmVhZChidWZmZXIsIHsgdHlwZTogJ2J1ZmZlcicgfSk7XG5cbiAgICAgICAgICAgIC8vIDIuIOivu+WPluaooeadv1xuICAgICAgICAgICAgY29uc3QgdGVtcGxhdGVQYXRoID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnYXNzZXRzL2J1bmRsZXMvYmF0dGxlTWFwL3ByZWZhYi/lnLDlm74vbWFwTGF5ZXJUZW1wbGF0ZS5wcmVmYWInKTtcbiAgICAgICAgICAgIGlmICghRnMuZXhpc3RzU3luYyh0ZW1wbGF0ZVBhdGgpKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignW+WcsOWbvueUn+aIkF0g5qih5p2/6aKE5Yi25L2T5LiN5a2Y5ZyoOicsIHRlbXBsYXRlUGF0aCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdGVtcGxhdGVKc29uID0gRnMucmVhZEZpbGVTeW5jKHRlbXBsYXRlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICAgICAgICBjb25zdCB0ZW1wbGF0ZURhdGEgPSBKU09OLnBhcnNlKHRlbXBsYXRlSnNvbik7XG5cbiAgICAgICAgICAgIGNvbnN0IHByZWZhYkRpciA9IHBhdGguam9pbihwcm9qZWN0UGF0aCwgJ2Fzc2V0cy9idW5kbGVzL2JhdHRsZU1hcC9wcmVmYWIv5Zyw5Zu+Jyk7XG5cbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBb5Zyw5Zu+55Sf5oiQXSDlvIDlp4vlpITnkIYgJHt3b3JrYm9vay5TaGVldE5hbWVzLmxlbmd0aH0g5Liq5bel5L2c6KGoLi4uYCk7XG5cbiAgICAgICAgICAgIC8vIDMuIOmBjeWOhuavj+S4quW3peS9nOihqFxuICAgICAgICAgICAgZm9yIChjb25zdCBzaGVldE5hbWUgb2Ygd29ya2Jvb2suU2hlZXROYW1lcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdvcmtzaGVldCA9IHdvcmtib29rLlNoZWV0c1tzaGVldE5hbWVdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJvd3M6IGFueVtdW10gPSBYTFNYLnV0aWxzLnNoZWV0X3RvX2pzb24od29ya3NoZWV0LCB7IGhlYWRlcjogMSB9KTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGdyaWRzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHIgPSAwOyByIDwgUk9XUzsgcisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgQ09MUzsgYysrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByYXcgPSAocm93c1tyXSB8fCBbXSlbY107XG4gICAgICAgICAgICAgICAgICAgICAgICBncmlkcy5wdXNoKChyYXcgIT09IHVuZGVmaW5lZCAmJiByYXcgIT09IG51bGwgJiYgcmF3ICE9PSAnJykgPyBTdHJpbmcocmF3KS50cmltKCkgOiAnJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmVmYWJQYXRoID0gcGF0aC5qb2luKHByZWZhYkRpciwgYCR7c2hlZXROYW1lfS5wcmVmYWJgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBleGlzdHMgPSBGcy5leGlzdHNTeW5jKHByZWZhYlBhdGgpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHByZWZhYkRhdGE6IGFueVtdO1xuICAgICAgICAgICAgICAgIGlmIChleGlzdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5bey5pyJ6aKE5Yi25L2TIOKGkiDor7vlj5blkI7ljp/lnLDkv67mlLlcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdKc29uID0gRnMucmVhZEZpbGVTeW5jKHByZWZhYlBhdGgsICd1dGYtOCcpO1xuICAgICAgICAgICAgICAgICAgICBwcmVmYWJEYXRhID0gSlNPTi5wYXJzZShleGlzdGluZ0pzb24pO1xuICAgICAgICAgICAgICAgICAgICBhcHBseUdyaWREYXRhKHByZWZhYkRhdGEsIHRlbXBsYXRlRGF0YSwgZ3JpZHMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIOaWsOmihOWItuS9kyDihpIg5LuO5qih5p2/5YWL6ZqG55Sf5oiQXG4gICAgICAgICAgICAgICAgICAgIHByZWZhYkRhdGEgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRlbXBsYXRlRGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICBwcmVmYWJEYXRhWzBdLl9uYW1lID0gc2hlZXROYW1lO1xuICAgICAgICAgICAgICAgICAgICBwcmVmYWJEYXRhWzFdLl9uYW1lID0gc2hlZXROYW1lO1xuICAgICAgICAgICAgICAgICAgICBhcHBseUdyaWREYXRhKHByZWZhYkRhdGEsIHRlbXBsYXRlRGF0YSwgZ3JpZHMpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGpzb25TdHIgPSBKU09OLnN0cmluZ2lmeShwcmVmYWJEYXRhLCBudWxsLCAyKTtcbiAgICAgICAgICAgICAgICBjb25zdCB1cmwgPSBgZGI6Ly9hc3NldHMvYnVuZGxlcy9iYXR0bGVNYXAvcHJlZmFiL+WcsOWbvi8ke3NoZWV0TmFtZX0ucHJlZmFiYDtcbiAgICAgICAgICAgICAgICBhd2FpdCBFZGl0b3IuTWVzc2FnZS5yZXF1ZXN0KCdhc3NldC1kYicsICdjcmVhdGUtYXNzZXQnLCB1cmwsIGpzb25TdHIsIHsgb3ZlcndyaXRlOiB0cnVlIH0pO1xuXG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhdHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7fTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG0gb2YgZ3JpZHMpIHsgY29uc3QgayA9IG0gfHwgJyjnqbrnmb0pJzsgc3RhdHNba10gPSAoc3RhdHNba10gfHwgMCkgKyAxOyB9XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhdFN0ciA9IE9iamVjdC5lbnRyaWVzKHN0YXRzKS5zb3J0KChhLCBiKSA9PiBiWzFdIC0gYVsxXSkubWFwKChbaywgdl0pID0+IGAke2t9OiR7dn1gKS5qb2luKCcsICcpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBb5Zyw5Zu+55Sf5oiQXSAke2V4aXN0cyA/ICd+JyA6ICcrJ30gJHtzaGVldE5hbWV9LnByZWZhYiAgKCR7c3RhdFN0cn0pYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdb5Zyw5Zu+55Sf5oiQXSDlhajpg6jlrozmiJDvvIEnKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdb5Zyw5Zu+55Sf5oiQXSDplJnor686JywgZXJyKTtcbiAgICAgICAgfVxuICAgIH0sXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gbG9hZCgpIHsgfVxuZXhwb3J0IGZ1bmN0aW9uIHVubG9hZCgpIHsgfVxuIl19
|