@solar-angular/platform-browser 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/esm2022/file-manager.mjs +45 -0
- package/esm2022/fullscreen.service.mjs +35 -0
- package/esm2022/image-compressor.mjs +169 -0
- package/esm2022/index.mjs +7 -0
- package/esm2022/resource-loader.mjs +44 -0
- package/esm2022/solar-angular-platform-browser.mjs +5 -0
- package/esm2022/spreadsheet.service.mjs +282 -0
- package/esm2022/storage/index.mjs +3 -0
- package/esm2022/storage/local-storage.mjs +40 -0
- package/esm2022/storage/session-storage.mjs +41 -0
- package/fesm2022/solar-angular-platform-browser.mjs +643 -0
- package/fesm2022/solar-angular-platform-browser.mjs.map +1 -0
- package/file-manager.d.ts +17 -0
- package/fullscreen.service.d.ts +17 -0
- package/image-compressor.d.ts +62 -0
- package/index.d.ts +6 -0
- package/package.json +28 -0
- package/resource-loader.d.ts +8 -0
- package/spreadsheet.service.d.ts +55 -0
- package/storage/index.d.ts +2 -0
- package/storage/local-storage.d.ts +22 -0
- package/storage/session-storage.d.ts +23 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { DatePipe, DOCUMENT } from '@angular/common';
|
|
2
|
+
import { inject, Injectable } from '@angular/core';
|
|
3
|
+
import { defer, firstValueFrom, map, shareReplay } from 'rxjs';
|
|
4
|
+
import { ResourceLoader } from './resource-loader';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
const EXCEL_COL_ALIAS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
7
|
+
const NUMBER_PATTERN = /[0-9]/g;
|
|
8
|
+
const CHAR_PATTERN = /[a-zA-Z]/g;
|
|
9
|
+
export class SpreadsheetService {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.document = inject(DOCUMENT);
|
|
12
|
+
this.resourceLoader = inject(ResourceLoader);
|
|
13
|
+
this.datePipe = new DatePipe('zh-CN');
|
|
14
|
+
// ExcelJS 对象,用时异步自动加载
|
|
15
|
+
this.excel = defer(() => Promise.all([
|
|
16
|
+
this.resourceLoader.loadScript('https://img.omofresh.com/js/aieyes-exceljs-o_1_8_10.min.js'), // 修改过的 https://www.npmjs.com/package/aieyes-exceljs-o
|
|
17
|
+
this.resourceLoader.loadStylesheet('https://img.omofresh.com/css/exceljs.min.css'), // aieyes-exceljs-o 中定义的
|
|
18
|
+
])).pipe(map(() => ExcelJS), shareReplay(1));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 根据当前的单元格找到下一列的地址
|
|
22
|
+
* 采用倒序进位法,这样就不需要递归了
|
|
23
|
+
*/
|
|
24
|
+
nextColOfCell(cell) {
|
|
25
|
+
// 先把字母和数字分开,字母是列,数字是行,倒序排列
|
|
26
|
+
const args = cell.match(CHAR_PATTERN).reverse();
|
|
27
|
+
let needAppend = false;
|
|
28
|
+
for (let i = 0; i < args.length; i++) {
|
|
29
|
+
const arg = args[i];
|
|
30
|
+
if (arg !== 'Z') {
|
|
31
|
+
const idx = EXCEL_COL_ALIAS.indexOf(arg);
|
|
32
|
+
args[i] = EXCEL_COL_ALIAS[idx + 1];
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
args[i] = 'A';
|
|
37
|
+
if (i === args.length - 1) { // 说明是最后一个了,需要补A
|
|
38
|
+
needAppend = true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (needAppend) {
|
|
43
|
+
args.push('A');
|
|
44
|
+
}
|
|
45
|
+
return args.reverse().join(''); // 最终的结果,反转再合并
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 获取单元格的行
|
|
49
|
+
*/
|
|
50
|
+
rowOfCell(cell) {
|
|
51
|
+
return cell.match(NUMBER_PATTERN).join('');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 获取单元格的列
|
|
55
|
+
*/
|
|
56
|
+
colOfCell(cell) {
|
|
57
|
+
return cell.match(CHAR_PATTERN).join('');
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 单元格的列号
|
|
61
|
+
* 当作26进制计算列的编号
|
|
62
|
+
*/
|
|
63
|
+
colNumberOfCell(cell) {
|
|
64
|
+
let col = 0;
|
|
65
|
+
cell.match(CHAR_PATTERN).reverse().forEach((c, i) => {
|
|
66
|
+
if (i == 0) {
|
|
67
|
+
// 个位
|
|
68
|
+
col += EXCEL_COL_ALIAS.indexOf(c) + 1;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// 十位以上
|
|
72
|
+
col += (EXCEL_COL_ALIAS.indexOf(c) + 1) * i * 26;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return col;
|
|
76
|
+
}
|
|
77
|
+
async parseDomTable(table, _opts) {
|
|
78
|
+
const excel = await firstValueFrom(this.excel);
|
|
79
|
+
return excel.TableParser.utils.parseDomTable(table, _opts);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 只导出一个table, 内容放在第一个sheet上
|
|
83
|
+
*/
|
|
84
|
+
async exportDomTableById(tableId, fileName, _opts) {
|
|
85
|
+
const table = this.document.getElementById(tableId);
|
|
86
|
+
const excel = await firstValueFrom(this.excel);
|
|
87
|
+
const wb = new excel.Workbook();
|
|
88
|
+
const ws = wb.addWorksheet(fileName);
|
|
89
|
+
const re = await this.exportDomTable(wb, ws, table, null, null, _opts);
|
|
90
|
+
await this.saveAsFile(re.wb, fileName);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 导出多个table, 内容放在多个sheet上
|
|
94
|
+
*/
|
|
95
|
+
async exportDomTableSheets(tableIds, sheetNames, fileName, _opts) {
|
|
96
|
+
const excel = await firstValueFrom(this.excel);
|
|
97
|
+
let wb = new excel.Workbook();
|
|
98
|
+
for (let index = 0; index < tableIds.length; index++) {
|
|
99
|
+
const table = this.document.getElementById(tableIds[index]);
|
|
100
|
+
const sheetName = sheetNames[index];
|
|
101
|
+
const ws = wb.addWorksheet(sheetName);
|
|
102
|
+
const re = await this.exportDomTable(wb, ws, table, null, null, _opts);
|
|
103
|
+
wb = re.wb;
|
|
104
|
+
}
|
|
105
|
+
await this.saveAsFile(wb, fileName);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 在一页中导出多个table, 每个table默认间隔1列
|
|
109
|
+
*/
|
|
110
|
+
async exportDomTableParallel(tableIds, fileName, gap = 1, _opts) {
|
|
111
|
+
const excel = await firstValueFrom(this.excel);
|
|
112
|
+
let wb = new excel.Workbook();
|
|
113
|
+
const ws = wb.addWorksheet(fileName);
|
|
114
|
+
let cursor = 'A'; // 从第一列开始导出,并列几个table
|
|
115
|
+
for (const tableId of tableIds) {
|
|
116
|
+
const table = this.document.getElementById(tableId);
|
|
117
|
+
const re = await this.exportDomTable(wb, ws, table, cursor, null, _opts);
|
|
118
|
+
const lastCol = re.cols[re.cols.length - 1];
|
|
119
|
+
cursor = this.nextColOfCell(lastCol);
|
|
120
|
+
for (let k = 0; k < gap; k++) {
|
|
121
|
+
cursor = this.nextColOfCell(cursor);
|
|
122
|
+
}
|
|
123
|
+
wb = re.wb;
|
|
124
|
+
}
|
|
125
|
+
await this.saveAsFile(wb, fileName);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 在一页中垂直导出多个table
|
|
129
|
+
*/
|
|
130
|
+
async exportDomTableVertical(tableIds, fileName, gap = 0, _opts) {
|
|
131
|
+
let rowOffset = 0;
|
|
132
|
+
const excel = await firstValueFrom(this.excel);
|
|
133
|
+
let wb = new excel.Workbook();
|
|
134
|
+
const ws = wb.addWorksheet(fileName);
|
|
135
|
+
for (const tableId of tableIds) {
|
|
136
|
+
const table = this.document.getElementById(tableId);
|
|
137
|
+
const re = await this.exportDomTable(wb, ws, table, null, rowOffset, _opts);
|
|
138
|
+
rowOffset += re.rows.length + gap;
|
|
139
|
+
wb = re.wb;
|
|
140
|
+
}
|
|
141
|
+
await this.saveAsFile(wb, fileName);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* 导出dom table
|
|
145
|
+
* colCursor: 标记起始列
|
|
146
|
+
* rowOffset: 偏移的行数
|
|
147
|
+
* @return 返回最后一列的列名
|
|
148
|
+
*/
|
|
149
|
+
async exportDomTable(wb, ws, table, colCursor, rowOffset, _opts) {
|
|
150
|
+
if (!_opts) {
|
|
151
|
+
_opts = { cellDates: true, dateNF: 'yyyy/M/d' }; // 默认的日期格式
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
_opts.cellDates = true;
|
|
155
|
+
}
|
|
156
|
+
const ref = await this.parseDomTable(table, _opts);
|
|
157
|
+
let colOffset = 0; // colCursor偏移量,默认为0
|
|
158
|
+
if (colCursor) {
|
|
159
|
+
const c = ws.getColumn(colCursor);
|
|
160
|
+
colOffset = c.number - 1;
|
|
161
|
+
}
|
|
162
|
+
rowOffset = rowOffset || 0; // rowOffset默认为0
|
|
163
|
+
const cellMap = {};
|
|
164
|
+
Object.keys(ref).sort().forEach(cellAlias => {
|
|
165
|
+
if (!cellAlias.startsWith('!')) {
|
|
166
|
+
let rowNum = this.rowOfCell(cellAlias);
|
|
167
|
+
rowNum = String(parseInt(rowNum, 10) + rowOffset);
|
|
168
|
+
const colNum = this.colNumberOfCell(cellAlias);
|
|
169
|
+
const col = ws.getColumn(colOffset + colNum); // 根据偏移量找出所在的列
|
|
170
|
+
const finalCell = col.letter + rowNum;
|
|
171
|
+
cellMap[finalCell] = ref[cellAlias];
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
const colSet = new Set();
|
|
175
|
+
Object.keys(cellMap).forEach(k => {
|
|
176
|
+
colSet.add(this.colOfCell(k));
|
|
177
|
+
});
|
|
178
|
+
let cols = Array.from(colSet);
|
|
179
|
+
// 因为excel的列都是连续的,如果导出table存在跨列的话这里面可能却少某一列,所以需要补充缺少的列名保证这一段是连续的
|
|
180
|
+
let cursor = cols[0];
|
|
181
|
+
for (let i = 0; i < ref['!cols'].length - 1; i++) {
|
|
182
|
+
const next = this.nextColOfCell(cursor);
|
|
183
|
+
colSet.add(next);
|
|
184
|
+
cursor = next;
|
|
185
|
+
}
|
|
186
|
+
cols = Array.from(colSet).sort((a, b) => {
|
|
187
|
+
if (a.length === b.length) {
|
|
188
|
+
return a.localeCompare(b);
|
|
189
|
+
}
|
|
190
|
+
else if (a.length > b.length) {
|
|
191
|
+
return 1;
|
|
192
|
+
}
|
|
193
|
+
else if (b.length > a.length) {
|
|
194
|
+
return -1;
|
|
195
|
+
}
|
|
196
|
+
return -1;
|
|
197
|
+
});
|
|
198
|
+
// 赋值
|
|
199
|
+
Object.keys(cellMap).forEach(alias => {
|
|
200
|
+
const cell = ws.getCell(alias);
|
|
201
|
+
const cellConfig = cellMap[alias];
|
|
202
|
+
if (cellConfig.t === 'd') { // 日期格式需格式化后显示,换言之转为了字符串
|
|
203
|
+
cell.value = this.datePipe.transform(cellConfig.v, cellConfig.z);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
cell.value = cellConfig.v;
|
|
207
|
+
}
|
|
208
|
+
// 默认就有边框的
|
|
209
|
+
if (cellConfig.style.bordered) { // 表示需要加边框
|
|
210
|
+
cell.style.border = {
|
|
211
|
+
top: { style: 'thin' },
|
|
212
|
+
left: { style: 'thin' },
|
|
213
|
+
bottom: { style: 'thin' },
|
|
214
|
+
right: { style: 'thin' }
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
// 默认内容垂直居中,左右居中不一定
|
|
218
|
+
cell.style.alignment = {
|
|
219
|
+
horizontal: cellConfig.style.align,
|
|
220
|
+
vertical: 'middle',
|
|
221
|
+
wrapText: true
|
|
222
|
+
};
|
|
223
|
+
// 字体默认为宋体
|
|
224
|
+
cell.style.font = {
|
|
225
|
+
bold: cellConfig.style.bold,
|
|
226
|
+
name: '宋体',
|
|
227
|
+
size: cellConfig.style.pound // 字号
|
|
228
|
+
};
|
|
229
|
+
// 背景色/前景色
|
|
230
|
+
if (cellConfig.style.background) {
|
|
231
|
+
cell.fill = {
|
|
232
|
+
type: 'pattern',
|
|
233
|
+
pattern: 'solid',
|
|
234
|
+
fgColor: { argb: cellConfig.style.background }, // 实际上fgColor是理解上的背景色,而不是前景色,不知道excel怎么定义的
|
|
235
|
+
// bgColor: {argb: 'ffd8e6de'}
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
// 设置每行的高度
|
|
240
|
+
ref['!rows'].forEach((rowConfig, rowIndex) => {
|
|
241
|
+
const row = ws.getRow(rowIndex + rowOffset + 1);
|
|
242
|
+
row.height = rowConfig.height;
|
|
243
|
+
});
|
|
244
|
+
// 设置列宽
|
|
245
|
+
ref['!cols'].forEach((colConfig, colIndex) => {
|
|
246
|
+
const colAlias = cols[colIndex];
|
|
247
|
+
const col = ws.getColumn(colAlias);
|
|
248
|
+
if (colConfig.width) {
|
|
249
|
+
col.width = colConfig.width;
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
// 合并单元格, 由于不一定有,所以要判断一下
|
|
253
|
+
ref['!merges']?.forEach(mergeParam => {
|
|
254
|
+
const s = mergeParam['s'];
|
|
255
|
+
const e = mergeParam['e'];
|
|
256
|
+
const startCell = ws.getCell(rowOffset + s.r + 1, colOffset + s.c + 1);
|
|
257
|
+
const endCell = ws.getCell(rowOffset + e.r + 1, colOffset + e.c + 1);
|
|
258
|
+
ws.mergeCells([startCell.address, endCell.address]);
|
|
259
|
+
});
|
|
260
|
+
return { wb, cols, rows: ref['!rows'] };
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* 保存Workbook到磁盘上
|
|
264
|
+
*/
|
|
265
|
+
async saveAsFile(wb, fileName) {
|
|
266
|
+
const excelData = await wb.xlsx.writeBuffer();
|
|
267
|
+
const blob = new Blob([excelData], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /* MediaType.Xlsx */ });
|
|
268
|
+
const anchor = document.createElement('a');
|
|
269
|
+
anchor.href = URL.createObjectURL(blob);
|
|
270
|
+
anchor.download = fileName + '.xlsx';
|
|
271
|
+
anchor.click();
|
|
272
|
+
}
|
|
273
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SpreadsheetService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
274
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SpreadsheetService, providedIn: 'root' }); }
|
|
275
|
+
}
|
|
276
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SpreadsheetService, decorators: [{
|
|
277
|
+
type: Injectable,
|
|
278
|
+
args: [{
|
|
279
|
+
providedIn: 'root'
|
|
280
|
+
}]
|
|
281
|
+
}] });
|
|
282
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ByZWFkc2hlZXQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3BhY2thZ2VzL3BsYXRmb3JtLWJyb3dzZXIvc3JjL3NwcmVhZHNoZWV0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRCxPQUFPLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9ELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7QUFLbkQsTUFBTSxlQUFlLEdBQUcsNEJBQTRCLENBQUM7QUFDckQsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDO0FBQ2hDLE1BQU0sWUFBWSxHQUFHLFdBQVcsQ0FBQztBQUtqQyxNQUFNLE9BQU8sa0JBQWtCO0lBSC9CO1FBSW1CLGFBQVEsR0FBYSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEMsbUJBQWMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDeEMsYUFBUSxHQUFHLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWxELHNCQUFzQjtRQUNMLFVBQUssR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQztZQUMvQyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyw0REFBNEQsQ0FBQyxFQUFFLHNEQUFzRDtZQUNwSixJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyw4Q0FBOEMsQ0FBQyxFQUFFLHdCQUF3QjtTQUM3RyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ04sR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUNsQixXQUFX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QUUsUUFBZ0I7UUFDaEQsTUFBTSxTQUFTLEdBQUcsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzlDLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxJQUFJLDBGQUFnQixFQUFFLENBQUMsQ0FBQztRQUM3RCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzNDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QyxNQUFNLENBQUMsUUFBUSxHQUFHLFFBQVEsR0FBRyxPQUFPLENBQUM7UUFDckMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2pCLENBQUM7K0dBdFJVLGtCQUFrQjttSEFBbEIsa0JBQWtCLGNBRmpCLE1BQU07OzRGQUVQLGtCQUFrQjtrQkFIOUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEYXRlUGlwZSwgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgaW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNZWRpYVR5cGUgfSBmcm9tICdAc29sYXIta2l0L2NvcmUnO1xuaW1wb3J0IHsgZGVmZXIsIGZpcnN0VmFsdWVGcm9tLCBtYXAsIHNoYXJlUmVwbGF5IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBSZXNvdXJjZUxvYWRlciB9IGZyb20gJy4vcmVzb3VyY2UtbG9hZGVyJztcbi8vIOS4jem7mOiupOmbhuaIkGV4Y2VsanPkuobvvIzpnIDopoHnmoTml7blgJnms6jlhaVYbHN4U2VydmljZeWKqOaAgeWKoOi9ve+8jOWboOS4uuS4jeaYr+avj+S4quWcsOaWuemDvemcgOimgeWvvOWHumV4Y2VsXG4vLyBpbXBvcnQge1RhYmxlUGFyc2VyLCBXb3JrYm9va30gZnJvbSAnYWlleWVzLWV4Y2VsanMtbyc7XG5kZWNsYXJlIGxldCBFeGNlbEpTOiBhbnk7ICAgLy8gZnJvbSBleGNlbGpzXG5cbmNvbnN0IEVYQ0VMX0NPTF9BTElBUyA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWic7XG5jb25zdCBOVU1CRVJfUEFUVEVSTiA9IC9bMC05XS9nO1xuY29uc3QgQ0hBUl9QQVRURVJOID0gL1thLXpBLVpdL2c7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIFNwcmVhZHNoZWV0U2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZG9jdW1lbnQ6IERvY3VtZW50ID0gaW5qZWN0KERPQ1VNRU5UKTtcbiAgcHJpdmF0ZSByZWFkb25seSByZXNvdXJjZUxvYWRlciA9IGluamVjdChSZXNvdXJjZUxvYWRlcik7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGF0ZVBpcGUgPSBuZXcgRGF0ZVBpcGUoJ3poLUNOJyk7XG5cbiAgLy8gRXhjZWxKUyDlr7nosaHvvIznlKjml7blvILmraXoh6rliqjliqDovb1cbiAgcHJpdmF0ZSByZWFkb25seSBleGNlbCA9IGRlZmVyKCgpID0+IFByb21pc2UuYWxsKFtcbiAgICB0aGlzLnJlc291cmNlTG9hZGVyLmxvYWRTY3JpcHQoJ2h0dHBzOi8vaW1nLm9tb2ZyZXNoLmNvbS9qcy9haWV5ZXMtZXhjZWxqcy1vXzFfOF8xMC5taW4uanMnKSwgLy8g5L+u5pS56L+H55qEIGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2FpZXllcy1leGNlbGpzLW9cbiAgICB0aGlzLnJlc291cmNlTG9hZGVyLmxvYWRTdHlsZXNoZWV0KCdodHRwczovL2ltZy5vbW9mcmVzaC5jb20vY3NzL2V4Y2VsanMubWluLmNzcycpLCAvLyBhaWV5ZXMtZXhjZWxqcy1vIOS4reWumuS5ieeahFxuICBdKSkucGlwZShcbiAgICBtYXAoKCkgPT4gRXhjZWxKUyksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICAvKipcbiAgICog5qC55o2u5b2T5YmN55qE5Y2V5YWD5qC85om+5Yiw5LiL5LiA5YiX55qE5Zyw5Z2AXG4gICAqIOmHh+eUqOWAkuW6j+i/m+S9jeazle+8jOi/meagt+WwseS4jemcgOimgemAkuW9kuS6hlxuICAgKi9cbiAgcHJpdmF0ZSBuZXh0Q29sT2ZDZWxsKGNlbGw6IHN0cmluZykge1xuICAgIC8vIOWFiOaKiuWtl+avjeWSjOaVsOWtl+WIhuW8gO+8jOWtl+avjeaYr+WIl++8jOaVsOWtl+aYr+ihjO+8jOWAkuW6j+aOkuWIl1xuICAgIGNvbnN0IGFyZ3MgPSBjZWxsLm1hdGNoKENIQVJfUEFUVEVSTikhLnJldmVyc2UoKTtcbiAgICBsZXQgbmVlZEFwcGVuZCA9IGZhbHNlO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgYXJnID0gYXJnc1tpXTtcbiAgICAgIGlmIChhcmcgIT09ICdaJykge1xuICAgICAgICBjb25zdCBpZHggPSBFWENFTF9DT0xfQUxJQVMuaW5kZXhPZihhcmcpO1xuICAgICAgICBhcmdzW2ldID0gRVhDRUxfQ09MX0FMSUFTW2lkeCArIDFdO1xuICAgICAgICBicmVhaztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFyZ3NbaV0gPSAnQSc7XG4gICAgICAgIGlmIChpID09PSBhcmdzLmxlbmd0aCAtIDEpIHsgICAgLy8g6K+05piO5piv5pyA5ZCO5LiA5Liq5LqG77yM6ZyA6KaB6KGlQVxuICAgICAgICAgIG5lZWRBcHBlbmQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChuZWVkQXBwZW5kKSB7XG4gICAgICBhcmdzLnB1c2goJ0EnKTtcbiAgICB9XG4gICAgcmV0dXJuIGFyZ3MucmV2ZXJzZSgpLmpvaW4oJycpOyAgICAvLyDmnIDnu4jnmoTnu5PmnpzvvIzlj43ovazlho3lkIjlubZcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bljZXlhYPmoLznmoTooYxcbiAgICovXG4gIHByaXZhdGUgcm93T2ZDZWxsKGNlbGw6IHN0cmluZykge1xuICAgIHJldHVybiBjZWxsLm1hdGNoKE5VTUJFUl9QQVRURVJOKSEuam9pbignJyk7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5Y2V5YWD5qC855qE5YiXXG4gICAqL1xuICBwcml2YXRlIGNvbE9mQ2VsbChjZWxsOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gY2VsbC5tYXRjaChDSEFSX1BBVFRFUk4pIS5qb2luKCcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDljZXlhYPmoLznmoTliJflj7dcbiAgICog5b2T5L2cMjbov5vliLborqHnrpfliJfnmoTnvJblj7dcbiAgICovXG4gIHByaXZhdGUgY29sTnVtYmVyT2ZDZWxsKGNlbGw6IHN0cmluZykge1xuICAgIGxldCBjb2wgPSAwO1xuICAgIGNlbGwubWF0Y2goQ0hBUl9QQVRURVJOKSEucmV2ZXJzZSgpLmZvckVhY2goKGMsIGkpID0+IHtcbiAgICAgIGlmIChpID09IDApIHtcbiAgICAgICAgLy8g5Liq5L2NXG4gICAgICAgIGNvbCArPSBFWENFTF9DT0xfQUxJQVMuaW5kZXhPZihjKSArIDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyDljYHkvY3ku6XkuIpcbiAgICAgICAgY29sICs9IChFWENFTF9DT0xfQUxJQVMuaW5kZXhPZihjKSArIDEpICogaSAqIDI2O1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBjb2w7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBhcnNlRG9tVGFibGUodGFibGU6IEhUTUxFbGVtZW50LCBfb3B0cz86IGFueSkge1xuICAgIGNvbnN0IGV4Y2VsID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5leGNlbCk7XG4gICAgcmV0dXJuIGV4Y2VsLlRhYmxlUGFyc2VyLnV0aWxzLnBhcnNlRG9tVGFibGUodGFibGUsIF9vcHRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlj6rlr7zlh7rkuIDkuKp0YWJsZSwg5YaF5a655pS+5Zyo56ys5LiA5Liqc2hlZXTkuIpcbiAgICovXG4gIGFzeW5jIGV4cG9ydERvbVRhYmxlQnlJZCh0YWJsZUlkOiBzdHJpbmcsIGZpbGVOYW1lOiBzdHJpbmcsIF9vcHRzPzogYW55KSB7XG4gICAgY29uc3QgdGFibGUgPSB0aGlzLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhYmxlSWQpITtcbiAgICBjb25zdCBleGNlbCA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuZXhjZWwpO1xuICAgIGNvbnN0IHdiID0gbmV3IGV4Y2VsLldvcmtib29rKCk7XG4gICAgY29uc3Qgd3MgPSB3Yi5hZGRXb3Jrc2hlZXQoZmlsZU5hbWUpO1xuICAgIGNvbnN0IHJlID0gYXdhaXQgdGhpcy5leHBvcnREb21UYWJsZSh3Yiwgd3MsIHRhYmxlLCBudWxsLCBudWxsLCBfb3B0cyk7XG4gICAgYXdhaXQgdGhpcy5zYXZlQXNGaWxlKHJlLndiLCBmaWxlTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICog5a+85Ye65aSa5LiqdGFibGUsIOWGheWuueaUvuWcqOWkmuS4qnNoZWV05LiKXG4gICAqL1xuICBhc3luYyBleHBvcnREb21UYWJsZVNoZWV0cyh0YWJsZUlkczogc3RyaW5nW10sIHNoZWV0TmFtZXM6IHN0cmluZ1tdLCBmaWxlTmFtZTogc3RyaW5nLCBfb3B0cz86IGFueSkge1xuICAgIGNvbnN0IGV4Y2VsID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5leGNlbCk7XG4gICAgbGV0IHdiID0gbmV3IGV4Y2VsLldvcmtib29rKCk7XG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGFibGVJZHMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCB0YWJsZSA9IHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFibGVJZHNbaW5kZXhdKSE7XG4gICAgICBjb25zdCBzaGVldE5hbWUgPSBzaGVldE5hbWVzW2luZGV4XTtcbiAgICAgIGNvbnN0IHdzID0gd2IuYWRkV29ya3NoZWV0KHNoZWV0TmFtZSk7XG4gICAgICBjb25zdCByZSA9IGF3YWl0IHRoaXMuZXhwb3J0RG9tVGFibGUod2IsIHdzLCB0YWJsZSwgbnVsbCwgbnVsbCwgX29wdHMpO1xuICAgICAgd2IgPSByZS53YjtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnNhdmVBc0ZpbGUod2IsIGZpbGVOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlnKjkuIDpobXkuK3lr7zlh7rlpJrkuKp0YWJsZSwg5q+P5LiqdGFibGXpu5jorqTpl7TpmpQx5YiXXG4gICAqL1xuICBhc3luYyBleHBvcnREb21UYWJsZVBhcmFsbGVsKHRhYmxlSWRzOiBzdHJpbmdbXSwgZmlsZU5hbWU6IHN0cmluZywgZ2FwID0gMSwgX29wdHM/OiBhbnkpIHtcbiAgICBjb25zdCBleGNlbCA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuZXhjZWwpO1xuXG4gICAgbGV0IHdiID0gbmV3IGV4Y2VsLldvcmtib29rKCk7XG4gICAgY29uc3Qgd3MgPSB3Yi5hZGRXb3Jrc2hlZXQoZmlsZU5hbWUpO1xuICAgIGxldCBjdXJzb3IgPSAnQSc7ICAgIC8vIOS7juesrOS4gOWIl+W8gOWni+WvvOWHuu+8jOW5tuWIl+WHoOS4qnRhYmxlXG5cbiAgICBmb3IgKGNvbnN0IHRhYmxlSWQgb2YgdGFibGVJZHMpIHtcbiAgICAgIGNvbnN0IHRhYmxlID0gdGhpcy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YWJsZUlkKSE7XG4gICAgICBjb25zdCByZSA9IGF3YWl0IHRoaXMuZXhwb3J0RG9tVGFibGUod2IsIHdzLCB0YWJsZSwgY3Vyc29yLCBudWxsLCBfb3B0cyk7XG4gICAgICBjb25zdCBsYXN0Q29sID0gcmUuY29sc1tyZS5jb2xzLmxlbmd0aCAtIDFdO1xuICAgICAgY3Vyc29yID0gdGhpcy5uZXh0Q29sT2ZDZWxsKGxhc3RDb2wpO1xuICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBnYXA7IGsrKykge1xuICAgICAgICBjdXJzb3IgPSB0aGlzLm5leHRDb2xPZkNlbGwoY3Vyc29yKTtcbiAgICAgIH1cbiAgICAgIHdiID0gcmUud2I7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5zYXZlQXNGaWxlKHdiLCBmaWxlTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICog5Zyo5LiA6aG15Lit5Z6C55u05a+85Ye65aSa5LiqdGFibGVcbiAgICovXG4gIGFzeW5jIGV4cG9ydERvbVRhYmxlVmVydGljYWwodGFibGVJZHM6IHN0cmluZ1tdLCBmaWxlTmFtZTogc3RyaW5nLCBnYXAgPSAwLCBfb3B0cz86IGFueSkge1xuICAgIGxldCByb3dPZmZzZXQgPSAwO1xuICAgIGNvbnN0IGV4Y2VsID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5leGNlbCk7XG4gICAgbGV0IHdiID0gbmV3IGV4Y2VsLldvcmtib29rKCk7XG4gICAgY29uc3Qgd3MgPSB3Yi5hZGRXb3Jrc2hlZXQoZmlsZU5hbWUpO1xuXG4gICAgZm9yIChjb25zdCB0YWJsZUlkIG9mIHRhYmxlSWRzKSB7XG4gICAgICBjb25zdCB0YWJsZSA9IHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFibGVJZCkhO1xuICAgICAgY29uc3QgcmUgPSBhd2FpdCB0aGlzLmV4cG9ydERvbVRhYmxlKHdiLCB3cywgdGFibGUsIG51bGwsIHJvd09mZnNldCwgX29wdHMpO1xuICAgICAgcm93T2Zmc2V0ICs9IHJlLnJvd3MubGVuZ3RoICsgZ2FwO1xuICAgICAgd2IgPSByZS53YjtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnNhdmVBc0ZpbGUod2IsIGZpbGVOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlr7zlh7pkb20gdGFibGVcbiAgICogY29sQ3Vyc29yOiDmoIforrDotbflp4vliJdcbiAgICogcm93T2Zmc2V0OiDlgY/np7vnmoTooYzmlbBcbiAgICogQHJldHVybiDov5Tlm57mnIDlkI7kuIDliJfnmoTliJflkI1cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZXhwb3J0RG9tVGFibGUod2I6IGFueSwgd3M6IGFueSwgdGFibGU6IEhUTUxFbGVtZW50LCBjb2xDdXJzb3I/OiBzdHJpbmcgfCBudWxsLCByb3dPZmZzZXQ/OiBudW1iZXIgfCBudWxsLCBfb3B0cz86IGFueSkge1xuICAgIGlmICghX29wdHMpIHtcbiAgICAgIF9vcHRzID0geyBjZWxsRGF0ZXM6IHRydWUsIGRhdGVORjogJ3l5eXkvTS9kJyB9OyAgICAvLyDpu5jorqTnmoTml6XmnJ/moLzlvI9cbiAgICB9IGVsc2Uge1xuICAgICAgX29wdHMuY2VsbERhdGVzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCByZWYgPSBhd2FpdCB0aGlzLnBhcnNlRG9tVGFibGUodGFibGUsIF9vcHRzKTtcbiAgICBsZXQgY29sT2Zmc2V0ID0gMDsgICAgLy8gY29sQ3Vyc29y5YGP56e76YeP77yM6buY6K6k5Li6MFxuICAgIGlmIChjb2xDdXJzb3IpIHtcbiAgICAgIGNvbnN0IGMgPSB3cy5nZXRDb2x1bW4oY29sQ3Vyc29yKTtcbiAgICAgIGNvbE9mZnNldCA9IGMubnVtYmVyIC0gMTtcbiAgICB9XG4gICAgcm93T2Zmc2V0ID0gcm93T2Zmc2V0IHx8IDA7ICAgLy8gcm93T2Zmc2V06buY6K6k5Li6MFxuICAgIGNvbnN0IGNlbGxNYXA6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICBPYmplY3Qua2V5cyhyZWYpLnNvcnQoKS5mb3JFYWNoKGNlbGxBbGlhcyA9PiB7XG4gICAgICBpZiAoIWNlbGxBbGlhcy5zdGFydHNXaXRoKCchJykpIHtcbiAgICAgICAgbGV0IHJvd051bSA9IHRoaXMucm93T2ZDZWxsKGNlbGxBbGlhcyk7XG4gICAgICAgIHJvd051bSA9IFN0cmluZyhwYXJzZUludChyb3dOdW0sIDEwKSArIHJvd09mZnNldCk7XG4gICAgICAgIGNvbnN0IGNvbE51bSA9IHRoaXMuY29sTnVtYmVyT2ZDZWxsKGNlbGxBbGlhcyk7XG4gICAgICAgIGNvbnN0IGNvbCA9IHdzLmdldENvbHVtbihjb2xPZmZzZXQgKyBjb2xOdW0pOyAvLyDmoLnmja7lgY/np7vph4/mib7lh7rmiYDlnKjnmoTliJdcbiAgICAgICAgY29uc3QgZmluYWxDZWxsID0gY29sLmxldHRlciArIHJvd051bTtcbiAgICAgICAgY2VsbE1hcFtmaW5hbENlbGxdID0gcmVmW2NlbGxBbGlhc107XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgY29sU2V0ID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgT2JqZWN0LmtleXMoY2VsbE1hcCkuZm9yRWFjaChrID0+IHtcbiAgICAgIGNvbFNldC5hZGQodGhpcy5jb2xPZkNlbGwoaykpO1xuICAgIH0pO1xuICAgIGxldCBjb2xzID0gQXJyYXkuZnJvbShjb2xTZXQpO1xuICAgIC8vIOWboOS4umV4Y2Vs55qE5YiX6YO95piv6L+e57ut55qE77yM5aaC5p6c5a+85Ye6dGFibGXlrZjlnKjot6jliJfnmoTor53ov5nph4zpnaLlj6/og73ljbTlsJHmn5DkuIDliJfvvIzmiYDku6XpnIDopoHooaXlhYXnvLrlsJHnmoTliJflkI3kv53or4Hov5nkuIDmrrXmmK/ov57nu63nmoRcbiAgICBsZXQgY3Vyc29yID0gY29sc1swXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlZlsnIWNvbHMnXS5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgIGNvbnN0IG5leHQgPSB0aGlzLm5leHRDb2xPZkNlbGwoY3Vyc29yKTtcbiAgICAgIGNvbFNldC5hZGQobmV4dCk7XG4gICAgICBjdXJzb3IgPSBuZXh0O1xuICAgIH1cbiAgICBjb2xzID0gQXJyYXkuZnJvbShjb2xTZXQpLnNvcnQoKGE6IHN0cmluZywgYjogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAoYS5sZW5ndGggPT09IGIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBhLmxvY2FsZUNvbXBhcmUoYik7XG4gICAgICB9IGVsc2UgaWYgKGEubGVuZ3RoID4gYi5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9IGVsc2UgaWYgKGIubGVuZ3RoID4gYS5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH0pO1xuICAgIC8vIOi1i+WAvFxuICAgIE9iamVjdC5rZXlzKGNlbGxNYXApLmZvckVhY2goYWxpYXMgPT4ge1xuICAgICAgY29uc3QgY2VsbCA9IHdzLmdldENlbGwoYWxpYXMpO1xuICAgICAgY29uc3QgY2VsbENvbmZpZyA9IGNlbGxNYXBbYWxpYXNdO1xuICAgICAgaWYgKGNlbGxDb25maWcudCA9PT0gJ2QnKSB7ICAgLy8g5pel5pyf5qC85byP6ZyA5qC85byP5YyW5ZCO5pi+56S677yM5o2i6KiA5LmL6L2s5Li65LqG5a2X56ym5LiyXG4gICAgICAgIGNlbGwudmFsdWUgPSB0aGlzLmRhdGVQaXBlLnRyYW5zZm9ybShjZWxsQ29uZmlnLnYsIGNlbGxDb25maWcueik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjZWxsLnZhbHVlID0gY2VsbENvbmZpZy52O1xuICAgICAgfVxuICAgICAgLy8g6buY6K6k5bCx5pyJ6L655qGG55qEXG4gICAgICBpZiAoY2VsbENvbmZpZy5zdHlsZS5ib3JkZXJlZCkgeyAgICAvLyDooajnpLrpnIDopoHliqDovrnmoYZcbiAgICAgICAgY2VsbC5zdHlsZS5ib3JkZXIgPSB7XG4gICAgICAgICAgdG9wOiB7IHN0eWxlOiAndGhpbicgfSxcbiAgICAgICAgICBsZWZ0OiB7IHN0eWxlOiAndGhpbicgfSxcbiAgICAgICAgICBib3R0b206IHsgc3R5bGU6ICd0aGluJyB9LFxuICAgICAgICAgIHJpZ2h0OiB7IHN0eWxlOiAndGhpbicgfVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgLy8g6buY6K6k5YaF5a655Z6C55u05bGF5Lit77yM5bem5Y+z5bGF5Lit5LiN5LiA5a6aXG4gICAgICBjZWxsLnN0eWxlLmFsaWdubWVudCA9IHtcbiAgICAgICAgaG9yaXpvbnRhbDogY2VsbENvbmZpZy5zdHlsZS5hbGlnbixcbiAgICAgICAgdmVydGljYWw6ICdtaWRkbGUnLFxuICAgICAgICB3cmFwVGV4dDogdHJ1ZVxuICAgICAgfTtcbiAgICAgIC8vIOWtl+S9k+m7mOiupOS4uuWui+S9k1xuICAgICAgY2VsbC5zdHlsZS5mb250ID0ge1xuICAgICAgICBib2xkOiBjZWxsQ29uZmlnLnN0eWxlLmJvbGQsXG4gICAgICAgIG5hbWU6ICflrovkvZMnLFxuICAgICAgICBzaXplOiBjZWxsQ29uZmlnLnN0eWxlLnBvdW5kIC8vIOWtl+WPt1xuICAgICAgfTtcbiAgICAgIC8vIOiDjOaZr+iJsi/liY3mma/oibJcbiAgICAgIGlmIChjZWxsQ29uZmlnLnN0eWxlLmJhY2tncm91bmQpIHtcbiAgICAgICAgY2VsbC5maWxsID0ge1xuICAgICAgICAgIHR5cGU6ICdwYXR0ZXJuJyxcbiAgICAgICAgICBwYXR0ZXJuOiAnc29saWQnLFxuICAgICAgICAgIGZnQ29sb3I6IHsgYXJnYjogY2VsbENvbmZpZy5zdHlsZS5iYWNrZ3JvdW5kIH0sICAgIC8vIOWunumZheS4imZnQ29sb3LmmK/nkIbop6PkuIrnmoTog4zmma/oibLvvIzogIzkuI3mmK/liY3mma/oibLvvIzkuI3nn6XpgZNleGNlbOaAjuS5iOWumuS5ieeahFxuICAgICAgICAgIC8vIGJnQ29sb3I6IHthcmdiOiAnZmZkOGU2ZGUnfVxuICAgICAgICB9IGFzIGFueTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICAvLyDorr7nva7mr4/ooYznmoTpq5jluqZcbiAgICAocmVmWychcm93cyddIGFzIGFueVtdKS5mb3JFYWNoKChyb3dDb25maWcsIHJvd0luZGV4KSA9PiB7XG4gICAgICBjb25zdCByb3cgPSB3cy5nZXRSb3cocm93SW5kZXggKyByb3dPZmZzZXQgKyAxKTtcbiAgICAgIHJvdy5oZWlnaHQgPSByb3dDb25maWcuaGVpZ2h0O1xuICAgIH0pO1xuICAgIC8vIOiuvue9ruWIl+WuvVxuICAgIChyZWZbJyFjb2xzJ10gYXMgYW55W10pLmZvckVhY2goKGNvbENvbmZpZywgY29sSW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGNvbEFsaWFzID0gY29sc1tjb2xJbmRleF07XG4gICAgICBjb25zdCBjb2wgPSB3cy5nZXRDb2x1bW4oY29sQWxpYXMpO1xuICAgICAgaWYgKGNvbENvbmZpZy53aWR0aCkge1xuICAgICAgICBjb2wud2lkdGggPSBjb2xDb25maWcud2lkdGg7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8g5ZCI5bm25Y2V5YWD5qC8LCDnlLHkuo7kuI3kuIDlrprmnInvvIzmiYDku6XopoHliKTmlq3kuIDkuItcbiAgICAocmVmWychbWVyZ2VzJ10gYXMgYW55W10gfCBudWxsKT8uZm9yRWFjaChtZXJnZVBhcmFtID0+IHtcbiAgICAgIGNvbnN0IHMgPSBtZXJnZVBhcmFtWydzJ107XG4gICAgICBjb25zdCBlID0gbWVyZ2VQYXJhbVsnZSddO1xuICAgICAgY29uc3Qgc3RhcnRDZWxsID0gd3MuZ2V0Q2VsbChyb3dPZmZzZXQgKyBzLnIgKyAxLCBjb2xPZmZzZXQgKyBzLmMgKyAxKTtcbiAgICAgIGNvbnN0IGVuZENlbGwgPSB3cy5nZXRDZWxsKHJvd09mZnNldCArIGUuciArIDEsIGNvbE9mZnNldCArIGUuYyArIDEpO1xuICAgICAgd3MubWVyZ2VDZWxscyhbc3RhcnRDZWxsLmFkZHJlc3MsIGVuZENlbGwuYWRkcmVzc10pO1xuICAgIH0pO1xuICAgIHJldHVybiB7IHdiLCBjb2xzLCByb3dzOiByZWZbJyFyb3dzJ10gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDkv53lrZhXb3JrYm9va+WIsOejgeebmOS4ilxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzYXZlQXNGaWxlKHdiOiBhbnksIGZpbGVOYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBleGNlbERhdGEgPSBhd2FpdCB3Yi54bHN4LndyaXRlQnVmZmVyKCk7XG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtleGNlbERhdGFdLCB7IHR5cGU6IE1lZGlhVHlwZS5YbHN4IH0pO1xuICAgIGNvbnN0IGFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBhbmNob3IuaHJlZiA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgYW5jaG9yLmRvd25sb2FkID0gZmlsZU5hbWUgKyAnLnhsc3gnO1xuICAgIGFuY2hvci5jbGljaygpO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export * from './local-storage';
|
|
2
|
+
export * from './session-storage';
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9wbGF0Zm9ybS1icm93c2VyL3NyYy9zdG9yYWdlL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsaUJBQWlCLENBQUE7QUFDL0IsY0FBYyxtQkFBbUIsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vbG9jYWwtc3RvcmFnZSdcbmV4cG9ydCAqIGZyb20gJy4vc2Vzc2lvbi1zdG9yYWdlJ1xuIl19
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DOCUMENT } from '@angular/common';
|
|
2
|
+
import { inject, Injectable } from '@angular/core';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class LocalStorage {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.storage = inject(DOCUMENT).defaultView.localStorage;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 保存数据
|
|
10
|
+
* @param key 键名
|
|
11
|
+
* @param value 数据
|
|
12
|
+
*/
|
|
13
|
+
set(key, value) {
|
|
14
|
+
this.storage.setItem(key, JSON.stringify(value));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 获取数据
|
|
18
|
+
* @param key 键名
|
|
19
|
+
*/
|
|
20
|
+
get(key) {
|
|
21
|
+
const data = this.storage.getItem(key);
|
|
22
|
+
return data ? JSON.parse(data) : null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 移除数据
|
|
26
|
+
* @param key 键名
|
|
27
|
+
*/
|
|
28
|
+
remove(key) {
|
|
29
|
+
this.storage.removeItem(key);
|
|
30
|
+
}
|
|
31
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LocalStorage, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
32
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LocalStorage, providedIn: 'root' }); }
|
|
33
|
+
}
|
|
34
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LocalStorage, decorators: [{
|
|
35
|
+
type: Injectable,
|
|
36
|
+
args: [{
|
|
37
|
+
providedIn: 'root'
|
|
38
|
+
}]
|
|
39
|
+
}] });
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtc3RvcmFnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL3BsYXRmb3JtLWJyb3dzZXIvc3JjL3N0b3JhZ2UvbG9jYWwtc3RvcmFnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBS25ELE1BQU0sT0FBTyxZQUFZO0lBSHpCO1FBSW1CLFlBQU8sR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsV0FBWSxDQUFDLFlBQVksQ0FBQztLQTRCdkU7SUExQkM7Ozs7T0FJRztJQUNILEdBQUcsQ0FBVSxHQUFXLEVBQUUsS0FBUTtRQUNoQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRDs7O09BR0c7SUFDSCxHQUFHLENBQUksR0FBVztRQUNoQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2QyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3hDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxNQUFNLENBQUMsR0FBVztRQUNoQixJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMvQixDQUFDOytHQTNCVSxZQUFZO21IQUFaLFlBQVksY0FGWCxNQUFNOzs0RkFFUCxZQUFZO2tCQUh4QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBMb2NhbFN0b3JhZ2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IHN0b3JhZ2UgPSBpbmplY3QoRE9DVU1FTlQpLmRlZmF1bHRWaWV3IS5sb2NhbFN0b3JhZ2U7XG5cbiAgLyoqXG4gICAqIOS/neWtmOaVsOaNrlxuICAgKiBAcGFyYW0ga2V5IOmUruWQjVxuICAgKiBAcGFyYW0gdmFsdWUg5pWw5o2uXG4gICAqL1xuICBzZXQ8VCA9IGFueT4oa2V5OiBzdHJpbmcsIHZhbHVlOiBUKTogdm9pZCB7XG4gICAgdGhpcy5zdG9yYWdlLnNldEl0ZW0oa2V5LCBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluaVsOaNrlxuICAgKiBAcGFyYW0ga2V5IOmUruWQjVxuICAgKi9cbiAgZ2V0PFQ+KGtleTogc3RyaW5nKTogVCB8IG51bGwge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLnN0b3JhZ2UuZ2V0SXRlbShrZXkpO1xuICAgIHJldHVybiBkYXRhID8gSlNPTi5wYXJzZShkYXRhKSA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICog56e76Zmk5pWw5o2uXG4gICAqIEBwYXJhbSBrZXkg6ZSu5ZCNXG4gICAqL1xuICByZW1vdmUoa2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnN0b3JhZ2UucmVtb3ZlSXRlbShrZXkpO1xuICB9XG5cbn1cbiJdfQ==
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { DOCUMENT } from '@angular/common';
|
|
2
|
+
import { inject, Injectable } from '@angular/core';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class SessionStorage {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.storage = inject(DOCUMENT).defaultView.sessionStorage;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 保存数据
|
|
10
|
+
* @param key 键名
|
|
11
|
+
* @param value 数据
|
|
12
|
+
*/
|
|
13
|
+
set(key, value) {
|
|
14
|
+
this.storage.setItem(key, JSON.stringify(value));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 获取数据
|
|
18
|
+
* @param key 键名
|
|
19
|
+
* @param defaults 默认值
|
|
20
|
+
*/
|
|
21
|
+
get(key) {
|
|
22
|
+
const data = this.storage.getItem(key);
|
|
23
|
+
return data ? JSON.parse(data) : null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 移除数据
|
|
27
|
+
* @param key 键名
|
|
28
|
+
*/
|
|
29
|
+
remove(key) {
|
|
30
|
+
this.storage.removeItem(key);
|
|
31
|
+
}
|
|
32
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SessionStorage, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
33
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SessionStorage, providedIn: 'root' }); }
|
|
34
|
+
}
|
|
35
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SessionStorage, decorators: [{
|
|
36
|
+
type: Injectable,
|
|
37
|
+
args: [{
|
|
38
|
+
providedIn: 'root'
|
|
39
|
+
}]
|
|
40
|
+
}] });
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi1zdG9yYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGFja2FnZXMvcGxhdGZvcm0tYnJvd3Nlci9zcmMvc3RvcmFnZS9zZXNzaW9uLXN0b3JhZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQUtuRCxNQUFNLE9BQU8sY0FBYztJQUgzQjtRQUltQixZQUFPLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFdBQVksQ0FBQyxjQUFjLENBQUM7S0E2QnpFO0lBM0JDOzs7O09BSUc7SUFDSCxHQUFHLENBQVUsR0FBVyxFQUFFLEtBQVE7UUFDaEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEdBQUcsQ0FBVSxHQUFXO1FBQ3RCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU0sQ0FBQyxHQUFXO1FBQ2hCLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQy9CLENBQUM7K0dBNUJVLGNBQWM7bUhBQWQsY0FBYyxjQUZiLE1BQU07OzRGQUVQLGNBQWM7a0JBSDFCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgaW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIFNlc3Npb25TdG9yYWdlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBzdG9yYWdlID0gaW5qZWN0KERPQ1VNRU5UKS5kZWZhdWx0VmlldyEuc2Vzc2lvblN0b3JhZ2U7XG5cbiAgLyoqXG4gICAqIOS/neWtmOaVsOaNrlxuICAgKiBAcGFyYW0ga2V5IOmUruWQjVxuICAgKiBAcGFyYW0gdmFsdWUg5pWw5o2uXG4gICAqL1xuICBzZXQ8VCA9IGFueT4oa2V5OiBzdHJpbmcsIHZhbHVlOiBUKTogdm9pZCB7XG4gICAgdGhpcy5zdG9yYWdlLnNldEl0ZW0oa2V5LCBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluaVsOaNrlxuICAgKiBAcGFyYW0ga2V5IOmUruWQjVxuICAgKiBAcGFyYW0gZGVmYXVsdHMg6buY6K6k5YC8XG4gICAqL1xuICBnZXQ8VCA9IGFueT4oa2V5OiBzdHJpbmcpOiBUIHwgbnVsbCB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuc3RvcmFnZS5nZXRJdGVtKGtleSk7XG4gICAgcmV0dXJuIGRhdGEgPyBKU09OLnBhcnNlKGRhdGEpIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiDnp7vpmaTmlbDmja5cbiAgICogQHBhcmFtIGtleSDplK7lkI1cbiAgICovXG4gIHJlbW92ZShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc3RvcmFnZS5yZW1vdmVJdGVtKGtleSk7XG4gIH1cblxufVxuIl19
|