UNPKG

ng-cw-v12

Version:

Angular UI component library

262 lines 41.4 kB
import { Injectable } from '@angular/core'; import * as XLSX from 'xlsx-js-style'; import * as i0 from "@angular/core"; export class NcExcelService { /** * 导出Excel,表头支持多级和合并 * @param headers 表头配置数组,支持多级和合并单元格 * @param data 要导出的数据数组,每个元素为一个对象,对象的属性需要与表头的key对应 * @param filename 导出的文件名(不需要包含.xlsx后缀) * @param maxWordCount 单元格最大字数,超过此数量将自动换行显示,默认值:10 * @returns 直接触发文件下载,不返回值 */ exportExcel(headers, data, filename, maxWordCount = 10) { // 创建工作簿和工作表 const wb = XLSX.utils.book_new(); const ws = XLSX.utils.json_to_sheet([]); // 处理表头 const headerRows = this.processHeaders(headers); XLSX.utils.sheet_add_aoa(ws, headerRows, { origin: 'A1' }); // 获取所有有效的键 const validKeys = this.getValidKeys(headers); // 过滤并转换数据 const filteredData = data.map(item => this.filterData(item, validKeys)); // 添加过滤后的数据 XLSX.utils.sheet_add_json(ws, filteredData, { origin: { r: headerRows.length, c: 0 }, skipHeader: true }); // 设置合并单元格 ws['!merges'] = this.getMerges(headers); // 设置单元格样式(居中对齐) this.setCellStyles(ws, headerRows.length, maxWordCount); // 将工作表添加到工作簿 XLSX.utils.book_append_sheet(wb, ws, 'Sheet1'); // 导出Excel文件 XLSX.writeFile(wb, `${filename}.xlsx`); } processHeaders(headers) { const result = []; let maxDepth = this.getMaxDepth(headers); for (let i = 0; i < maxDepth; i++) { result.push([]); } const fillHeaders = (headers, depth = 0, colIndex = 0) => { headers.forEach((header) => { const colspan = header.colspan || 1; const rowspan = header.rowspan || 1; // 填充当前单元格 result[depth][colIndex] = header.label; // 如果有子项,递归处理 if (header.children) { fillHeaders(header.children, depth + 1, colIndex); } else { // 如果没有子项,填充空白单元格 for (let i = depth + 1; i < maxDepth; i++) { result[i][colIndex] = ''; } } // 处理跨列 for (let i = 1; i < colspan; i++) { result[depth][colIndex + i] = ''; } // 处理跨行 for (let i = 1; i < rowspan; i++) { if (!result[depth + i]) { result[depth + i] = []; } result[depth + i][colIndex] = ''; } colIndex += colspan; }); }; fillHeaders(headers); return result; } getMaxDepth(headers, depth = 1) { let maxDepth = depth; headers.forEach((header) => { if (header.children) { const childDepth = this.getMaxDepth(header.children, depth + 1); maxDepth = Math.max(maxDepth, childDepth); } }); return maxDepth; } getValidKeys(headers) { const keys = []; const extractKeys = (headers) => { headers.forEach((header) => { if (header.children) { extractKeys(header.children); } else { if (header.key) { keys.push(header.key); } } }); }; extractKeys(headers); return keys; } filterData(item, validKeys) { const filteredItem = {}; validKeys.forEach(key => { var _a; filteredItem[key] = (_a = item[key]) !== null && _a !== void 0 ? _a : ''; }); return filteredItem; } getMerges(headers) { const merges = []; let colIndex = 0; const processMerges = (headers, rowIndex = 0) => { headers.forEach((header) => { const colspan = header.colspan || 1; const rowspan = header.rowspan || 1; if (colspan > 1 || rowspan > 1) { merges.push({ s: { r: rowIndex, c: colIndex }, e: { r: rowIndex + rowspan - 1, c: colIndex + colspan - 1 } }); } if (header.children) { processMerges(header.children, rowIndex + 1); } else { colIndex += colspan; } }); }; processMerges(headers); return merges; } setCellStyles(ws, headerRows, maxWordCount) { if (!ws['!cols']) ws['!cols'] = []; if (!ws['!rows']) ws['!rows'] = []; const range = XLSX.utils.decode_range(ws['!ref'] || 'A1:Z1000'); // 列宽 const maxLengths = this.getMaxLengths(ws, range); //每列的最大字数,例:[10,3,4,5,6,15] for (let i = 0; i <= range.e.c; i++) { ws['!cols'][i] = { wch: Math.max(8, Math.min(this.mathMultiply(maxWordCount, 2.829), this.mathMultiply(maxLengths[i], 2.829))) }; //字体大小为13px时,字数为11,会在28.43宽度时换行,测试时excel会在设置的宽度上加0.14,所以设置单个字宽度为2.829 } //单元格样式和行高 for (let R = range.s.r; R <= range.e.r; R++) { let maxLines = 1; //当前行内单元格最大文字行数 const isHeader = R < headerRows; const isEvenRow = R % 2 === 0; for (let C = range.s.c; C <= range.e.c; C++) { const cellAddress = XLSX.utils.encode_cell({ r: R, c: C }); if (!ws[cellAddress]) continue; if (!ws[cellAddress].s) ws[cellAddress].s = {}; // 计算单元格内容的行数 const cellValue = String(ws[cellAddress].v || ''); const cellWidth = ws['!cols'][C].wch || 8; const totalWidth = this.mathMultiply(this.getAdjustedLength(cellValue), 2.829); const lines = Math.ceil(this.mathDivide(totalWidth, cellWidth)); maxLines = Math.max(maxLines, lines); ws[cellAddress].s = { alignment: { vertical: 'center', horizontal: 'center', wrapText: true }, font: { name: '仿宋', sz: 13, bold: isHeader, color: { rgb: isHeader ? 'FFFFFF' : '000000' } }, fill: { fgColor: { rgb: isHeader ? "538dd5" : (isEvenRow ? "F2F2F2" : "FFFFFF") } }, border: { top: { style: 'thin', color: { rgb: isHeader ? 'e0e0e0' : 'a9a9a9' } }, bottom: { style: 'thin', color: { rgb: isHeader ? 'e0e0e0' : 'a9a9a9' } }, left: { style: 'thin', color: { rgb: isHeader ? 'e0e0e0' : 'a9a9a9' } }, right: { style: 'thin', color: { rgb: isHeader ? 'e0e0e0' : 'a9a9a9' } } } }; } // 设置行高 const baseHeight = isHeader ? 30 : 25; const lineHeight = isHeader ? 20 : 18; ws['!rows'][R] = { hpt: Math.max(baseHeight, lineHeight * maxLines) }; } } getMaxLengths(ws, range) { const maxLengths = []; for (let C = range.s.c; C <= range.e.c; C++) { let maxLength = 0; for (let R = range.s.r; R <= range.e.r; R++) { const cellAddress = XLSX.utils.encode_cell({ r: R, c: C }); if (ws[cellAddress] && ws[cellAddress].v) { const cellValue = String(ws[cellAddress].v); const adjustedLength = this.getAdjustedLength(cellValue); maxLength = Math.max(maxLength, adjustedLength); } } maxLengths[C] = maxLength; } return maxLengths; } getAdjustedLength(value) { let length = 0; for (let i = 0; i < value.length; i++) { if (/[\u4e00-\u9fa5]/.test(value[i])) { length += 1; // 中文字符 } else if (/[a-zA-Z0-9]/.test(value[i])) { length += 0.5; // 英文字母和数字 } else { length += 1; // 其他字符 } } return length; } mathMultiply(value1, value2) { // 将浮点数转换为字符串 let aStr = value1.toString(); let bStr = value2.toString(); // 找到小数点后的位置 let aDecimals = (aStr.split('.')[1] || '').length; let bDecimals = (bStr.split('.')[1] || '').length; // 将浮点数转换为整数 let aInt = parseInt(aStr.replace('.', '')); let bInt = parseInt(bStr.replace('.', '')); // 进行整数乘法 let resultInt = aInt * bInt; // 计算最终的小数位数 let totalDecimals = aDecimals + bDecimals; // 将结果转换回浮点数 return resultInt / Math.pow(10, totalDecimals); } mathDivide(value1, value2) { // 将浮点数转换为字符串 let aStr = value1.toString(); let bStr = value2.toString(); // 找到小数点后的位置 let aDecimals = (aStr.split('.')[1] || '').length; let bDecimals = (bStr.split('.')[1] || '').length; // 找到最大的小数位数 let maxDecimals = Math.max(aDecimals, bDecimals); // 将浮点数转换为整数 let aInt = Math.round(value1 * Math.pow(10, maxDecimals)); let bInt = Math.round(value2 * Math.pow(10, maxDecimals)); // 进行整数除法并直接返回结果 return aInt / bInt; } } NcExcelService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcExcelService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); NcExcelService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcExcelService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcExcelService, decorators: [{ type: Injectable }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhjZWwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvZXhjZWwtc2VydmljZS9leGNlbC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxLQUFLLElBQUksTUFBTSxlQUFlLENBQUM7O0FBV3RDLE1BQU0sT0FBTyxjQUFjO0lBQ3ZCOzs7Ozs7O09BT0c7SUFDSCxXQUFXLENBQUMsT0FBd0IsRUFBRSxJQUFXLEVBQUUsUUFBZ0IsRUFBRSxlQUF1QixFQUFFO1FBRTFGLFlBQVk7UUFDWixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2pDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRXhDLE9BQU87UUFDUCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEVBQUUsRUFBRSxVQUFVLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUUzRCxXQUFXO1FBQ1gsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUU3QyxVQUFVO1FBQ1YsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFFeEUsV0FBVztRQUNYLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLEVBQUUsRUFBRSxZQUFZLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUUs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QUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDMUQsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUUxRCxnQkFBZ0I7UUFDaEIsT0FBTyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ3ZCLENBQUM7OzJHQTlSUSxjQUFjOytHQUFkLGNBQWM7MkZBQWQsY0FBYztrQkFEMUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0ICogYXMgWExTWCBmcm9tICd4bHN4LWpzLXN0eWxlJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmNFeGNlbEhlYWRlciB7XHJcbiAgICBsYWJlbDogc3RyaW5nOy8vIOihqOWktOaYvuekuueahOaWh+acrFxyXG4gICAga2V5Pzogc3RyaW5nOy8vIOWvueW6lOaVsOaNruWvueixoeeahOWxnuaAp+WQje+8jOeUqOS6juaVsOaNruaYoOWwhFxyXG4gICAgcm93c3Bhbj86IG51bWJlcjsvLyDljZXlhYPmoLznurXlkJHlkIjlubbnmoTooYzmlbBcclxuICAgIGNvbHNwYW4/OiBudW1iZXI7Ly8g5Y2V5YWD5qC85qiq5ZCR5ZCI5bm255qE5YiX5pWwXHJcbiAgICBjaGlsZHJlbj86IE5jRXhjZWxIZWFkZXJbXTsvLyDlrZDooajlpLTphY3nva7vvIznlKjkuo7lpJrnuqfooajlpLRcclxufVxyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgTmNFeGNlbFNlcnZpY2Uge1xyXG4gICAgLyoqXHJcbiAgICAgKiDlr7zlh7pFeGNlbO+8jOihqOWktOaUr+aMgeWkmue6p+WSjOWQiOW5tlxyXG4gICAgICogQHBhcmFtIGhlYWRlcnMg6KGo5aS06YWN572u5pWw57uE77yM5pSv5oyB5aSa57qn5ZKM5ZCI5bm25Y2V5YWD5qC8XHJcbiAgICAgKiBAcGFyYW0gZGF0YSDopoHlr7zlh7rnmoTmlbDmja7mlbDnu4TvvIzmr4/kuKrlhYPntKDkuLrkuIDkuKrlr7nosaHvvIzlr7nosaHnmoTlsZ7mgKfpnIDopoHkuI7ooajlpLTnmoRrZXnlr7nlupRcclxuICAgICAqIEBwYXJhbSBmaWxlbmFtZSDlr7zlh7rnmoTmlofku7blkI3vvIjkuI3pnIDopoHljIXlkKsueGxzeOWQjue8gO+8iVxyXG4gICAgICogQHBhcmFtIG1heFdvcmRDb3VudCDljZXlhYPmoLzmnIDlpKflrZfmlbDvvIzotoXov4fmraTmlbDph4/lsIboh6rliqjmjaLooYzmmL7npLrvvIzpu5jorqTlgLzvvJoxMFxyXG4gICAgICogQHJldHVybnMg55u05o6l6Kem5Y+R5paH5Lu25LiL6L2977yM5LiN6L+U5Zue5YC8XHJcbiAgICAgKi9cclxuICAgIGV4cG9ydEV4Y2VsKGhlYWRlcnM6IE5jRXhjZWxIZWFkZXJbXSwgZGF0YTogYW55W10sIGZpbGVuYW1lOiBzdHJpbmcsIG1heFdvcmRDb3VudDogbnVtYmVyID0gMTApOiB2b2lkIHtcclxuXHJcbiAgICAgICAgLy8g5Yib5bu65bel5L2c57C/5ZKM5bel5L2c6KGoXHJcbiAgICAgICAgY29uc3Qgd2IgPSBYTFNYLnV0aWxzLmJvb2tfbmV3KCk7XHJcbiAgICAgICAgY29uc3Qgd3MgPSBYTFNYLnV0aWxzLmpzb25fdG9fc2hlZXQoW10pO1xyXG5cclxuICAgICAgICAvLyDlpITnkIbooajlpLRcclxuICAgICAgICBjb25zdCBoZWFkZXJSb3dzID0gdGhpcy5wcm9jZXNzSGVhZGVycyhoZWFkZXJzKTtcclxuICAgICAgICBYTFNYLnV0aWxzLnNoZWV0X2FkZF9hb2Eod3MsIGhlYWRlclJvd3MsIHsgb3JpZ2luOiAnQTEnIH0pO1xyXG5cclxuICAgICAgICAvLyDojrflj5bmiYDmnInmnInmlYjnmoTplK5cclxuICAgICAgICBjb25zdCB2YWxpZEtleXMgPSB0aGlzLmdldFZhbGlkS2V5cyhoZWFkZXJzKTtcclxuXHJcbiAgICAgICAgLy8g6L+H5ruk5bm26L2s5o2i5pWw5o2uXHJcbiAgICAgICAgY29uc3QgZmlsdGVyZWREYXRhID0gZGF0YS5tYXAoaXRlbSA9PiB0aGlzLmZpbHRlckRhdGEoaXRlbSwgdmFsaWRLZXlzKSk7XHJcblxyXG4gICAgICAgIC8vIOa3u+WKoOi/h+a7pOWQjueahOaVsOaNrlxyXG4gICAgICAgIFhMU1gudXRpbHMuc2hlZXRfYWRkX2pzb24od3MsIGZpbHRlcmVkRGF0YSwgeyBvcmlnaW46IHsgcjogaGVhZGVyUm93cy5sZW5ndGgsIGM6IDAgfSwgc2tpcEhlYWRlcjogdHJ1ZSB9KTtcclxuXHJcbiAgICAgICAgLy8g6K6+572u5ZCI5bm25Y2V5YWD5qC8XHJcbiAgICAgICAgd3NbJyFtZXJnZXMnXSA9IHRoaXMuZ2V0TWVyZ2VzKGhlYWRlcnMpO1xyXG5cclxuICAgICAgICAvLyDorr7nva7ljZXlhYPmoLzmoLflvI/vvIjlsYXkuK3lr7npvZDvvIlcclxuICAgICAgICB0aGlzLnNldENlbGxTdHlsZXMod3MsIGhlYWRlclJvd3MubGVuZ3RoLCBtYXhXb3JkQ291bnQpO1xyXG5cclxuICAgICAgICAvLyDlsIblt6XkvZzooajmt7vliqDliLDlt6XkvZznsL9cclxuICAgICAgICBYTFNYLnV0aWxzLmJvb2tfYXBwZW5kX3NoZWV0KHdiLCB3cywgJ1NoZWV0MScpO1xyXG5cclxuICAgICAgICAvLyDlr7zlh7pFeGNlbOaWh+S7tlxyXG4gICAgICAgIFhMU1gud3JpdGVGaWxlKHdiLCBgJHtmaWxlbmFtZX0ueGxzeGApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgcHJvY2Vzc0hlYWRlcnMoaGVhZGVyczogTmNFeGNlbEhlYWRlcltdKTogc3RyaW5nW11bXSB7XHJcbiAgICAgICAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXVtdID0gW107XHJcbiAgICAgICAgbGV0IG1heERlcHRoID0gdGhpcy5nZXRNYXhEZXB0aChoZWFkZXJzKTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXhEZXB0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKFtdKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGZpbGxIZWFkZXJzID0gKGhlYWRlcnM6IE5jRXhjZWxIZWFkZXJbXSwgZGVwdGg6IG51bWJlciA9IDAsIGNvbEluZGV4OiBudW1iZXIgPSAwKSA9PiB7XHJcbiAgICAgICAgICAgIGhlYWRlcnMuZm9yRWFjaCgoaGVhZGVyOiBOY0V4Y2VsSGVhZGVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xzcGFuID0gaGVhZGVyLmNvbHNwYW4gfHwgMTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJvd3NwYW4gPSBoZWFkZXIucm93c3BhbiB8fCAxO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIOWhq+WFheW9k+WJjeWNleWFg+agvFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0W2RlcHRoXVtjb2xJbmRleF0gPSBoZWFkZXIubGFiZWw7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c5pyJ5a2Q6aG577yM6YCS5b2S5aSE55CGXHJcbiAgICAgICAgICAgICAgICBpZiAoaGVhZGVyLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmlsbEhlYWRlcnMoaGVhZGVyLmNoaWxkcmVuLCBkZXB0aCArIDEsIGNvbEluZGV4KTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8g5aaC5p6c5rKh5pyJ5a2Q6aG577yM5aGr5YWF56m655m95Y2V5YWD5qC8XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGRlcHRoICsgMTsgaSA8IG1heERlcHRoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldW2NvbEluZGV4XSA9ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyDlpITnkIbot6jliJdcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgY29sc3BhbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2RlcHRoXVtjb2xJbmRleCArIGldID0gJyc7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy8g5aSE55CG6Leo6KGMXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJvd3NwYW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghcmVzdWx0W2RlcHRoICsgaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2RlcHRoICsgaV0gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2RlcHRoICsgaV1bY29sSW5kZXhdID0gJyc7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY29sSW5kZXggKz0gY29sc3BhbjtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBmaWxsSGVhZGVycyhoZWFkZXJzKTtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0TWF4RGVwdGgoaGVhZGVyczogTmNFeGNlbEhlYWRlcltdLCBkZXB0aDogbnVtYmVyID0gMSk6IG51bWJlciB7XHJcbiAgICAgICAgbGV0IG1heERlcHRoID0gZGVwdGg7XHJcbiAgICAgICAgaGVhZGVycy5mb3JFYWNoKChoZWFkZXI6IE5jRXhjZWxIZWFkZXIpID0+IHtcclxuICAgICAgICAgICAgaWYgKGhlYWRlci5jaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2hpbGREZXB0aCA9IHRoaXMuZ2V0TWF4RGVwdGgoaGVhZGVyLmNoaWxkcmVuLCBkZXB0aCArIDEpO1xyXG4gICAgICAgICAgICAgICAgbWF4RGVwdGggPSBNYXRoLm1heChtYXhEZXB0aCwgY2hpbGREZXB0aCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gbWF4RGVwdGg7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRWYWxpZEtleXMoaGVhZGVyczogTmNFeGNlbEhlYWRlcltdKTogc3RyaW5nW10ge1xyXG4gICAgICAgIGNvbnN0IGtleXM6IHN0cmluZ1tdID0gW107XHJcbiAgICAgICAgY29uc3QgZXh0cmFjdEtleXMgPSAoaGVhZGVyczogTmNFeGNlbEhlYWRlcltdKSA9PiB7XHJcbiAgICAgICAgICAgIGhlYWRlcnMuZm9yRWFjaCgoaGVhZGVyOiBOY0V4Y2VsSGVhZGVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGVhZGVyLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0cmFjdEtleXMoaGVhZGVyLmNoaWxkcmVuKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhlYWRlci5rZXkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAga2V5cy5wdXNoKGhlYWRlci5rZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBleHRyYWN0S2V5cyhoZWFkZXJzKTtcclxuICAgICAgICByZXR1cm4ga2V5cztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGZpbHRlckRhdGEoaXRlbTogYW55LCB2YWxpZEtleXM6IHN0cmluZ1tdKTogYW55IHtcclxuICAgICAgICBjb25zdCBmaWx0ZXJlZEl0ZW06IGFueSA9IHt9O1xyXG4gICAgICAgIHZhbGlkS2V5cy5mb3JFYWNoKGtleSA9PiB7XHJcbiAgICAgICAgICAgIGZpbHRlcmVkSXRlbVtrZXldID0gaXRlbVtrZXldID8/ICcnO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBmaWx0ZXJlZEl0ZW07XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRNZXJnZXMoaGVhZGVyczogTmNFeGNlbEhlYWRlcltdKTogWExTWC5SYW5nZVtdIHtcclxuICAgICAgICBjb25zdCBtZXJnZXM6IFhMU1guUmFuZ2VbXSA9IFtdO1xyXG4gICAgICAgIGxldCBjb2xJbmRleCA9IDA7XHJcblxyXG4gICAgICAgIGNvbnN0IHByb2Nlc3NNZXJnZXMgPSAoaGVhZGVyczogTmNFeGNlbEhlYWRlcltdLCByb3dJbmRleDogbnVtYmVyID0gMCkgPT4ge1xyXG4gICAgICAgICAgICBoZWFkZXJzLmZvckVhY2goKGhlYWRlcjogTmNFeGNlbEhlYWRlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY29sc3BhbiA9IGhlYWRlci5jb2xzcGFuIHx8IDE7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByb3dzcGFuID0gaGVhZGVyLnJvd3NwYW4gfHwgMTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoY29sc3BhbiA+IDEgfHwgcm93c3BhbiA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICBtZXJnZXMucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHM6IHsgcjogcm93SW5kZXgsIGM6IGNvbEluZGV4IH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGU6IHsgcjogcm93SW5kZXggKyByb3dzcGFuIC0gMSwgYzogY29sSW5kZXggKyBjb2xzcGFuIC0gMSB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGhlYWRlci5jaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3NNZXJnZXMoaGVhZGVyLmNoaWxkcmVuLCByb3dJbmRleCArIDEpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjb2xJbmRleCArPSBjb2xzcGFuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBwcm9jZXNzTWVyZ2VzKGhlYWRlcnMpO1xyXG4gICAgICAgIHJldHVybiBtZXJnZXM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzZXRDZWxsU3R5bGVzKHdzOiBYTFNYLldvcmtTaGVldCwgaGVhZGVyUm93czogbnVtYmVyLCBtYXhXb3JkQ291bnQ6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGlmICghd3NbJyFjb2xzJ10pIHdzWychY29scyddID0gW107XHJcbiAgICAgICAgaWYgKCF3c1snIXJvd3MnXSkgd3NbJyFyb3dzJ10gPSBbXTtcclxuICAgICAgICBjb25zdCByYW5nZSA9IFhMU1gudXRpbHMuZGVjb2RlX3JhbmdlKHdzWychcmVmJ10gfHwgJ0ExOloxMDAwJyk7XHJcblxyXG4gICAgICAgIC8vIOWIl+WuvVxyXG4gICAgICAgIGNvbnN0IG1heExlbmd0aHMgPSB0aGlzLmdldE1heExlbmd0aHMod3MsIHJhbmdlKTsvL+avj+WIl+eahOacgOWkp+Wtl+aVsO+8jOS+i++8mlsxMCwzLDQsNSw2LDE1XVxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHJhbmdlLmUuYzsgaSsrKSB7XHJcbiAgICAgICAgICAgIHdzWychY29scyddW2ldID0geyB3Y2g6IE1hdGgubWF4KDgsIE1hdGgubWluKHRoaXMubWF0aE11bHRpcGx5KG1heFdvcmRDb3VudCwgMi44MjkpLCB0aGlzLm1hdGhNdWx0aXBseShtYXhMZW5ndGhzW2ldLCAyLjgyOSkpKSB9O1xyXG4gICAgICAgICAgICAvL+Wtl+S9k+Wkp+Wwj+S4ujEzcHjml7bvvIzlrZfmlbDkuLoxMe+8jOS8muWcqDI4LjQz5a695bqm5pe25o2i6KGM77yM5rWL6K+V5pe2ZXhjZWzkvJrlnKjorr7nva7nmoTlrr3luqbkuIrliqAwLjE077yM5omA5Lul6K6+572u5Y2V5Liq5a2X5a695bqm5Li6Mi44MjlcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8v5Y2V5YWD5qC85qC35byP5ZKM6KGM6auYXHJcbiAgICAgICAgZm9yIChsZXQgUiA9IHJhbmdlLnMucjsgUiA8PSByYW5nZS5lLnI7IFIrKykge1xyXG4gICAgICAgICAgICBsZXQgbWF4TGluZXMgPSAxOy8v5b2T5YmN6KGM5YaF5Y2V5YWD5qC85pyA5aSn5paH5a2X6KGM5pWwXHJcbiAgICAgICAgICAgIGNvbnN0IGlzSGVhZGVyID0gUiA8IGhlYWRlclJvd3M7XHJcbiAgICAgICAgICAgIGNvbnN0IGlzRXZlblJvdyA9IFIgJSAyID09PSAwO1xyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgQyA9IHJhbmdlLnMuYzsgQyA8PSByYW5nZS5lLmM7IEMrKykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2VsbEFkZHJlc3MgPSBYTFNYLnV0aWxzLmVuY29kZV9jZWxsKHsgcjogUiwgYzogQyB9KTtcclxuICAgICAgICAgICAgICAgIGlmICghd3NbY2VsbEFkZHJlc3NdKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGlmICghd3NbY2VsbEFkZHJlc3NdLnMpIHdzW2NlbGxBZGRyZXNzXS5zID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgLy8g6K6h566X5Y2V5YWD5qC85YaF5a6555qE6KGM5pWwXHJcbiAgICAgICAgICAgICAgICBjb25zdCBjZWxsVmFsdWUgPSBTdHJpbmcod3NbY2VsbEFkZHJlc3NdLnYgfHwgJycpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2VsbFdpZHRoID0gd3NbJyFjb2xzJ11bQ10ud2NoIHx8IDg7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0b3RhbFdpZHRoID0gdGhpcy5tYXRoTXVsdGlwbHkodGhpcy5nZXRBZGp1c3RlZExlbmd0aChjZWxsVmFsdWUpLCAyLjgyOSk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBsaW5lcyA9IE1hdGguY2VpbCh0aGlzLm1hdGhEaXZpZGUodG90YWxXaWR0aCwgY2VsbFdpZHRoKSk7XHJcbiAgICAgICAgICAgICAgICBtYXhMaW5lcyA9IE1hdGgubWF4KG1heExpbmVzLCBsaW5lcyk7XHJcblxyXG4gICAgICAgICAgICAgICAgd3NbY2VsbEFkZHJlc3NdLnMgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWxpZ25tZW50OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRpY2FsOiAnY2VudGVyJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9yaXpvbnRhbDogJ2NlbnRlcicsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdyYXBUZXh0OiB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICBmb250OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICfku7/lrosnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzejogMTMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvbGQ6IGlzSGVhZGVyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvcjogeyByZ2I6IGlzSGVhZGVyID8gJ0ZGRkZGRicgOiAnMDAwMDAwJyB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICBmaWxsOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZnQ29sb3I6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJnYjogaXNIZWFkZXIgPyBcIjUzOGRkNVwiIDogKGlzRXZlblJvdyA/IFwiRjJGMkYyXCIgOiBcIkZGRkZGRlwiKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICBib3JkZXI6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiB7IHN0eWxlOiAndGhpbicsIGNvbG9yOiB7IHJnYjogaXNIZWFkZXIgPyAnZTBlMGUwJyA6ICdhOWE5YTknIH0gfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm90dG9tOiB7IHN0eWxlOiAndGhpbicsIGNvbG9yOiB7IHJnYjogaXNIZWFkZXIgPyAnZTBlMGUwJyA6ICdhOWE5YTknIH0gfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdDogeyBzdHlsZTogJ3RoaW4nLCBjb2xvcjogeyByZ2I6IGlzSGVhZGVyID8gJ2UwZTBlMCcgOiAnYTlhOWE5JyB9IH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0OiB7IHN0eWxlOiAndGhpbicsIGNvbG9yOiB7IHJnYjogaXNIZWFkZXIgPyAnZTBlMGUwJyA6ICdhOWE5YTknIH0gfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8g6K6+572u6KGM6auYXHJcbiAgICAgICAgICAgIGNvbnN0IGJhc2VIZWlnaHQgPSBpc0hlYWRlciA/IDMwIDogMjU7XHJcbiAgICAgICAgICAgIGNvbnN0IGxpbmVIZWlnaHQgPSBpc0hlYWRlciA/IDIwIDogMTg7XHJcbiAgICAgICAgICAgIHdzWychcm93cyddW1JdID0geyBocHQ6IE1hdGgubWF4KGJhc2VIZWlnaHQsIGxpbmVIZWlnaHQgKiBtYXhMaW5lcykgfTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRNYXhMZW5ndGhzKHdzOiBYTFNYLldvcmtTaGVldCwgcmFuZ2U6IFhMU1guUmFuZ2UpOiBudW1iZXJbXSB7XHJcbiAgICAgICAgY29uc3QgbWF4TGVuZ3RoczogbnVtYmVyW10gPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBDID0gcmFuZ2Uucy5jOyBDIDw9IHJhbmdlLmUuYzsgQysrKSB7XHJcbiAgICAgICAgICAgIGxldCBtYXhMZW5ndGggPSAwO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBSID0gcmFuZ2Uucy5yOyBSIDw9IHJhbmdlLmUucjsgUisrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjZWxsQWRkcmVzcyA9IFhMU1gudXRpbHMuZW5jb2RlX2NlbGwoeyByOiBSLCBjOiBDIH0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHdzW2NlbGxBZGRyZXNzXSAmJiB3c1tjZWxsQWRkcmVzc10udikge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNlbGxWYWx1ZSA9IFN0cmluZyh3c1tjZWxsQWRkcmVzc10udik7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqdXN0ZWRMZW5ndGggPSB0aGlzLmdldEFkanVzdGVkTGVuZ3RoKGNlbGxWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgbWF4TGVuZ3RoID0gTWF0aC5tYXgobWF4TGVuZ3RoLCBhZGp1c3RlZExlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbWF4TGVuZ3Roc1tDXSA9IG1heExlbmd0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG1heExlbmd0aHM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRBZGp1c3RlZExlbmd0aCh2YWx1ZTogc3RyaW5nKTogbnVtYmVyIHtcclxuICAgICAgICBsZXQgbGVuZ3RoID0gMDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmICgvW1xcdTRlMDAtXFx1OWZhNV0vLnRlc3QodmFsdWVbaV0pKSB7XHJcbiAgICAgICAgICAgICAgICBsZW5ndGggKz0gMTsgLy8g5Lit5paH5a2X56ymXHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoL1thLXpBLVowLTldLy50ZXN0KHZhbHVlW2ldKSkge1xyXG4gICAgICAgICAgICAgICAgbGVuZ3RoICs9IDAuNTsgLy8g6Iux5paH5a2X5q+N5ZKM5pWw5a2XXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsZW5ndGggKz0gMTsgLy8g5YW25LuW5a2X56ymXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG1hdGhNdWx0aXBseSh2YWx1ZTE6IG51bWJlciwgdmFsdWUyOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIC8vIOWwhua1rueCueaVsOi9rOaNouS4uuWtl+espuS4slxyXG4gICAgICAgIGxldCBhU3RyID0gdmFsdWUxLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgbGV0IGJTdHIgPSB2YWx1ZTIudG9TdHJpbmcoKTtcclxuXHJcbiAgICAgICAgLy8g5om+5Yiw5bCP5pWw54K55ZCO55qE5L2N572uXHJcbiAgICAgICAgbGV0IGFEZWNpbWFscyA9IChhU3RyLnNwbGl0KCcuJylbMV0gfHwgJycpLmxlbmd0aDtcclxuICAgICAgICBsZXQgYkRlY2ltYWxzID0gKGJTdHIuc3BsaXQoJy4nKVsxXSB8fCAnJykubGVuZ3RoO1xyXG5cclxuICAgICAgICAvLyDlsIbmta7ngrnmlbDovazmjaLkuLrmlbTmlbBcclxuICAgICAgICBsZXQgYUludCA9IHBhcnNlSW50KGFTdHIucmVwbGFjZSgnLicsICcnKSk7XHJcbiAgICAgICAgbGV0IGJJbnQgPSBwYXJzZUludChiU3RyLnJlcGxhY2UoJy4nLCAnJykpO1xyXG5cclxuICAgICAgICAvLyDov5vooYzmlbTmlbDkuZjms5VcclxuICAgICAgICBsZXQgcmVzdWx0SW50ID0gYUludCAqIGJJbnQ7XHJcblxyXG4gICAgICAgIC8vIOiuoeeul+acgOe7iOeahOWwj+aVsOS9jeaVsFxyXG4gICAgICAgIGxldCB0b3RhbERlY2ltYWxzID0gYURlY2ltYWxzICsgYkRlY2ltYWxzO1xyXG5cclxuICAgICAgICAvLyDlsIbnu5PmnpzovazmjaLlm57mta7ngrnmlbBcclxuICAgICAgICByZXR1cm4gcmVzdWx0SW50IC8gTWF0aC5wb3coMTAsIHRvdGFsRGVjaW1hbHMpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgbWF0aERpdmlkZSh2YWx1ZTE6IG51bWJlciwgdmFsdWUyOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIC8vIOWwhua1rueCueaVsOi9rOaNouS4uuWtl+espuS4slxyXG4gICAgICAgIGxldCBhU3RyID0gdmFsdWUxLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgbGV0IGJTdHIgPSB2YWx1ZTIudG9TdHJpbmcoKTtcclxuXHJcbiAgICAgICAgLy8g5om+5Yiw5bCP5pWw54K55ZCO55qE5L2N572uXHJcbiAgICAgICAgbGV0IGFEZWNpbWFscyA9IChhU3RyLnNwbGl0KCcuJylbMV0gfHwgJycpLmxlbmd0aDtcclxuICAgICAgICBsZXQgYkRlY2ltYWxzID0gKGJTdHIuc3BsaXQoJy4nKVsxXSB8fCAnJykubGVuZ3RoO1xyXG5cclxuICAgICAgICAvLyDmib7liLDmnIDlpKfnmoTlsI/mlbDkvY3mlbBcclxuICAgICAgICBsZXQgbWF4RGVjaW1hbHMgPSBNYXRoLm1heChhRGVjaW1hbHMsIGJEZWNpbWFscyk7XHJcblxyXG4gICAgICAgIC8vIOWwhua1rueCueaVsOi9rOaNouS4uuaVtOaVsFxyXG4gICAgICAgIGxldCBhSW50ID0gTWF0aC5yb3VuZCh2YWx1ZTEgKiBNYXRoLnBvdygxMCwgbWF4RGVjaW1hbHMpKTtcclxuICAgICAgICBsZXQgYkludCA9IE1hdGgucm91bmQodmFsdWUyICogTWF0aC5wb3coMTAsIG1heERlY2ltYWxzKSk7XHJcblxyXG4gICAgICAgIC8vIOi/m+ihjOaVtOaVsOmZpOazleW5tuebtOaOpei/lOWbnue7k+aenFxyXG4gICAgICAgIHJldHVybiBhSW50IC8gYkludDtcclxuICAgIH1cclxufSJdfQ==