@ryuzaki13/react-foundation-lib 1.1.8 → 1.1.9
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/dist/excel/excel.d.ts
CHANGED
|
@@ -21,6 +21,18 @@ export type DownloadExcelFileArgs = {
|
|
|
21
21
|
columnIndex: number;
|
|
22
22
|
}) => ExcelCellStyle | undefined;
|
|
23
23
|
};
|
|
24
|
+
/** Описание одного табличного листа внутри Excel-книги. */
|
|
25
|
+
export type ExcelWorkbookSheet = Omit<DownloadExcelFileArgs, "fileName"> & {
|
|
26
|
+
/** Желаемое имя листа; writer нормализует ограничения формата и конфликты имён. */
|
|
27
|
+
name: string;
|
|
28
|
+
};
|
|
29
|
+
/** Аргументы формирования Excel-книги с одним или несколькими табличными листами. */
|
|
30
|
+
export type DownloadExcelWorkbookArgs = {
|
|
31
|
+
/** Имя скачиваемого `.xlsx` файла. */
|
|
32
|
+
fileName: string;
|
|
33
|
+
/** Листы книги в порядке отображения в Excel. */
|
|
34
|
+
sheets: ExcelWorkbookSheet[];
|
|
35
|
+
};
|
|
24
36
|
/**
|
|
25
37
|
* Приводит общий value-state проекта к базовому Excel-стилю.
|
|
26
38
|
*
|
|
@@ -35,6 +47,14 @@ export declare function resolveExcelCellStyleFromState(state: State | undefined)
|
|
|
35
47
|
* невалидный `<autoFilter>` без реального диапазона.
|
|
36
48
|
*/
|
|
37
49
|
export declare function buildExcelAutoFilterRef(columnCount: number, rowCount: number): string | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Нормализует имена листов по ограничениям Excel и делает их уникальными.
|
|
52
|
+
*
|
|
53
|
+
* Runtime-заголовки могут содержать запрещённые символы, превышать 31 знак или
|
|
54
|
+
* совпадать между несколькими представлениями одной конфигурации. Нормализация
|
|
55
|
+
* выполняется централизованно, чтобы все consumers получали открываемую книгу.
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveExcelSheetNames(names: readonly string[]): string[];
|
|
38
58
|
/**
|
|
39
59
|
* Собирает SheetData для `write-excel-file`.
|
|
40
60
|
*
|
|
@@ -42,6 +62,13 @@ export declare function buildExcelAutoFilterRef(columnCount: number, rowCount: n
|
|
|
42
62
|
* колонки/строки и необязательный callback стилей конкретных ячеек.
|
|
43
63
|
*/
|
|
44
64
|
export declare function buildExcelSheetData(args: Omit<DownloadExcelFileArgs, "fileName" | "autoFilter">): SheetData;
|
|
65
|
+
/**
|
|
66
|
+
* Формирует и скачивает Excel-книгу с независимыми табличными листами.
|
|
67
|
+
*
|
|
68
|
+
* Каждый лист получает собственные ширины колонок, стили ячеек и диапазон
|
|
69
|
+
* автофильтра. Доменная подготовка колонок и строк остаётся у вызывающей стороны.
|
|
70
|
+
*/
|
|
71
|
+
export declare function downloadExcelWorkbook(args: DownloadExcelWorkbookArgs): Promise<void>;
|
|
45
72
|
/**
|
|
46
73
|
* Формирует и скачивает `.xlsx` в браузере.
|
|
47
74
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"excel.d.ts","sourceRoot":"","sources":["../../src/excel/excel.ts"],"names":[],"mappings":"AAAA,OAAsB,EAAa,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"excel.d.ts","sourceRoot":"","sources":["../../src/excel/excel.ts"],"names":[],"mappings":"AAAA,OAAsB,EAAa,KAAK,UAAU,EAA4B,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAG/H,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,MAAM,WAAW,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,eAAe,GAAG,kBAAkB,CAAC;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC;AAE3E,MAAM,MAAM,qBAAqB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,WAAW,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,KAAK,cAAc,GAAG,SAAS,CAAC;CACnI,CAAC;AAEF,2DAA2D;AAC3D,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,GAAG;IAC1E,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,qFAAqF;AACrF,MAAM,MAAM,yBAAyB,GAAG;IACvC,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC7B,CAAC;AAsBF;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAGnG;AAoBD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIjG;AAyBD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CA2BzE;AAuBD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,GAAG,YAAY,CAAC,GAAG,SAAS,CA8B3G;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB1F;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAalF"}
|
package/dist/excel/index.js
CHANGED
|
@@ -12,12 +12,12 @@ var u = {
|
|
|
12
12
|
fontWeight: "bold",
|
|
13
13
|
bottomBorderStyle: "thin",
|
|
14
14
|
bottomBorderColor: "#D9D9D9"
|
|
15
|
-
};
|
|
16
|
-
function
|
|
15
|
+
}, f = 31, p = /[\u0000-\u001f[\]/\\:*?]+/g, m = /^'+|'+$/g, h = /\s+/g;
|
|
16
|
+
function g(e) {
|
|
17
17
|
let t = e ? u[e] : void 0;
|
|
18
18
|
return t ? { textColor: t } : void 0;
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function _(e) {
|
|
21
21
|
let t = e + 1, n = "";
|
|
22
22
|
for (; t > 0;) {
|
|
23
23
|
let e = (t - 1) % 26;
|
|
@@ -25,13 +25,28 @@ function p(e) {
|
|
|
25
25
|
}
|
|
26
26
|
return n;
|
|
27
27
|
}
|
|
28
|
-
function
|
|
29
|
-
if (!(e <= 0 || t <= 0)) return `A1:${
|
|
30
|
-
}
|
|
31
|
-
function
|
|
32
|
-
if (e) return { files: { transform: { "xl/worksheets/sheet{id}.xml": { transform: (t
|
|
28
|
+
function v(e, t) {
|
|
29
|
+
if (!(e <= 0 || t <= 0)) return `A1:${_(e - 1)}${t}`;
|
|
30
|
+
}
|
|
31
|
+
function y(e) {
|
|
32
|
+
if (e.some(Boolean)) return { files: { transform: { "xl/worksheets/sheet{id}.xml": { transform: (t, n, r) => {
|
|
33
|
+
let i = e[r.sheetIndex];
|
|
34
|
+
return i ? t.replace("</sheetData>", `</sheetData><autoFilter ref="${i}"/>`) : t;
|
|
35
|
+
} } } } };
|
|
36
|
+
}
|
|
37
|
+
function b(e) {
|
|
38
|
+
let t = /* @__PURE__ */ new Set(), n = [];
|
|
39
|
+
for (let r = 0; r < e.length; r += 1) {
|
|
40
|
+
let i = `Лист ${r + 1}`, a = e[r]?.replace(p, " ").replace(h, " ").trim().replace(m, "").trim() || i, o = a.slice(0, f), s = 2;
|
|
41
|
+
for (; t.has(o.toLocaleLowerCase());) {
|
|
42
|
+
let e = ` (${s})`;
|
|
43
|
+
o = `${a.slice(0, f - e.length)}${e}`, s += 1;
|
|
44
|
+
}
|
|
45
|
+
t.add(o.toLocaleLowerCase()), n.push(o);
|
|
46
|
+
}
|
|
47
|
+
return n;
|
|
33
48
|
}
|
|
34
|
-
function
|
|
49
|
+
function x(e, t) {
|
|
35
50
|
if (!(e == null || e === "")) {
|
|
36
51
|
if (t === Number) {
|
|
37
52
|
let t = typeof e == "number" ? e : Number(e);
|
|
@@ -40,7 +55,7 @@ function g(e, t) {
|
|
|
40
55
|
return t === String ? String(e) : t === Boolean ? !!e : t === Date ? e instanceof Date ? e : i(e) ?? void 0 : e;
|
|
41
56
|
}
|
|
42
57
|
}
|
|
43
|
-
function
|
|
58
|
+
function S(e) {
|
|
44
59
|
let t = [e.columns.map((e) => ({
|
|
45
60
|
type: String,
|
|
46
61
|
value: e.header,
|
|
@@ -49,7 +64,7 @@ function _(e) {
|
|
|
49
64
|
for (let n = 0; n < e.rows.length; n++) {
|
|
50
65
|
let r = e.rows[n], i = [];
|
|
51
66
|
for (let t = 0; t < e.columns.length; t++) {
|
|
52
|
-
let a = e.columns[t], o =
|
|
67
|
+
let a = e.columns[t], o = x(r[a.id], a.type), s = e.getCellStyle?.({
|
|
53
68
|
row: r,
|
|
54
69
|
column: a,
|
|
55
70
|
rowIndex: n,
|
|
@@ -66,66 +81,86 @@ function _(e) {
|
|
|
66
81
|
}
|
|
67
82
|
return t;
|
|
68
83
|
}
|
|
69
|
-
async function
|
|
70
|
-
|
|
71
|
-
|
|
84
|
+
async function C(e) {
|
|
85
|
+
if (e.sheets.length === 0) throw Error("Для формирования Excel-книги нужен минимум один лист");
|
|
86
|
+
let t = b(e.sheets.map((e) => e.name)), n = [], r = e.sheets.map((e, r) => {
|
|
87
|
+
let i = S(e);
|
|
88
|
+
return n.push(e.autoFilter ? v(e.columns.length, i.length) : void 0), {
|
|
89
|
+
data: i,
|
|
90
|
+
sheet: t[r],
|
|
91
|
+
columns: e.columns.map((e) => ({ width: e.width }))
|
|
92
|
+
};
|
|
93
|
+
}), i = y(n);
|
|
94
|
+
await l(r, { features: i ? [i] : void 0 }).toFile(e.fileName);
|
|
95
|
+
}
|
|
96
|
+
async function w(e) {
|
|
97
|
+
await C({
|
|
98
|
+
fileName: e.fileName,
|
|
99
|
+
sheets: [{
|
|
100
|
+
name: "Sheet1",
|
|
101
|
+
columns: e.columns,
|
|
102
|
+
rows: e.rows,
|
|
103
|
+
autoFilter: e.autoFilter,
|
|
104
|
+
getCellStyle: e.getCellStyle
|
|
105
|
+
}]
|
|
106
|
+
});
|
|
72
107
|
}
|
|
73
108
|
//#endregion
|
|
74
109
|
//#region src/excel/tableExport.ts
|
|
75
|
-
var
|
|
76
|
-
function
|
|
110
|
+
var T = "#,##0", E = "#,##0.0", D = "dd.mm.yyyy", O = "d mmm", k = "d mmmm", A = "hh:mm", j = "hh:mm:ss", M = `${D} ${A}`, N = `${D} ${j}`;
|
|
111
|
+
function P(e) {
|
|
77
112
|
let t = s(e).plan?.steps.find((e) => e.type === "typedValueFormat");
|
|
78
113
|
return t?.type === "typedValueFormat" ? t.config : void 0;
|
|
79
114
|
}
|
|
80
|
-
function
|
|
115
|
+
function F(t) {
|
|
81
116
|
return t.clientOnly ? Number : e(t.odataType) ? Date : n(t.odataType) ? Boolean : r(t.odataType) || t.role === "measure" ? Number : String;
|
|
82
117
|
}
|
|
83
|
-
function
|
|
84
|
-
let n =
|
|
118
|
+
function I(e) {
|
|
119
|
+
let n = P(e.formattersPipeline)?.numberPresetName?.trim();
|
|
85
120
|
return n && c(n) ? n : t(e.odataType) ? "integer" : "decimal";
|
|
86
121
|
}
|
|
87
|
-
function
|
|
88
|
-
let t = c(
|
|
89
|
-
return t ? t.decimals > 0 ? `#,##0.${"0".repeat(t.decimals)}` :
|
|
122
|
+
function L(e) {
|
|
123
|
+
let t = c(I(e));
|
|
124
|
+
return t ? t.decimals > 0 ? `#,##0.${"0".repeat(t.decimals)}` : T : E;
|
|
90
125
|
}
|
|
91
|
-
function
|
|
92
|
-
return
|
|
126
|
+
function R(e) {
|
|
127
|
+
return P(e.formattersPipeline)?.datePresetName?.trim() || (e.odataType === "time" ? a.time : e.odataType === "datetime" || e.odataType === "datetimeOffset" ? a.datetime : a.date);
|
|
93
128
|
}
|
|
94
|
-
function
|
|
129
|
+
function z(e) {
|
|
95
130
|
return e.replace(/H/g, "h").replace(/M/g, "m");
|
|
96
131
|
}
|
|
97
|
-
function
|
|
98
|
-
if (e === a.odataDatetime || e === a.abapDatetime) return
|
|
99
|
-
if (e === a.odataDate || e === a.abapDate) return
|
|
100
|
-
if (e === a.monthShort) return
|
|
101
|
-
if (e === a.monthLong) return
|
|
102
|
-
if (e.startsWith("datetime")) return e === a.datetime || e === a.datetimeShort ?
|
|
103
|
-
if (e.startsWith("time")) return e === a.time || e === a.timeShort ?
|
|
104
|
-
if (e.startsWith("date")) return
|
|
132
|
+
function B(e) {
|
|
133
|
+
if (e === a.odataDatetime || e === a.abapDatetime) return N;
|
|
134
|
+
if (e === a.odataDate || e === a.abapDate) return D;
|
|
135
|
+
if (e === a.monthShort) return O;
|
|
136
|
+
if (e === a.monthLong) return k;
|
|
137
|
+
if (e.startsWith("datetime")) return e === a.datetime || e === a.datetimeShort ? M : N;
|
|
138
|
+
if (e.startsWith("time")) return e === a.time || e === a.timeShort ? A : j;
|
|
139
|
+
if (e.startsWith("date")) return D;
|
|
105
140
|
}
|
|
106
|
-
function
|
|
107
|
-
return
|
|
141
|
+
function V(e, t) {
|
|
142
|
+
return B(e) || (t?.pattern ? z(t.pattern) : z(e));
|
|
108
143
|
}
|
|
109
|
-
function
|
|
110
|
-
let t =
|
|
111
|
-
return
|
|
144
|
+
function H(e) {
|
|
145
|
+
let t = R(e);
|
|
146
|
+
return V(t, o(t));
|
|
112
147
|
}
|
|
113
|
-
function
|
|
114
|
-
if (t === Number) return
|
|
115
|
-
if (t === Date) return
|
|
148
|
+
function U(e, t) {
|
|
149
|
+
if (t === Number) return L(e);
|
|
150
|
+
if (t === Date) return H(e);
|
|
116
151
|
}
|
|
117
|
-
function
|
|
118
|
-
let t =
|
|
152
|
+
function W(e) {
|
|
153
|
+
let t = F(e);
|
|
119
154
|
return {
|
|
120
155
|
id: e.id,
|
|
121
156
|
header: e.header,
|
|
122
157
|
width: e.width,
|
|
123
158
|
type: t,
|
|
124
|
-
format:
|
|
159
|
+
format: U(e, t)
|
|
125
160
|
};
|
|
126
161
|
}
|
|
127
|
-
async function
|
|
128
|
-
await
|
|
162
|
+
async function G({ fileName: e, table: t, autoFilter: n = !0 }) {
|
|
163
|
+
await w({
|
|
129
164
|
fileName: e,
|
|
130
165
|
columns: t.columns,
|
|
131
166
|
rows: t.rows,
|
|
@@ -133,7 +168,19 @@ async function z({ fileName: e, table: t, autoFilter: n = !0 }) {
|
|
|
133
168
|
getCellStyle: ({ rowIndex: e, column: n }) => t.cellStyles?.[e]?.[n.id]
|
|
134
169
|
});
|
|
135
170
|
}
|
|
171
|
+
async function K({ fileName: e, sheets: t }) {
|
|
172
|
+
await C({
|
|
173
|
+
fileName: e,
|
|
174
|
+
sheets: t.map(({ name: e, table: t, autoFilter: n = !0 }) => ({
|
|
175
|
+
name: e,
|
|
176
|
+
columns: t.columns,
|
|
177
|
+
rows: t.rows,
|
|
178
|
+
autoFilter: n,
|
|
179
|
+
getCellStyle: ({ rowIndex: e, column: n }) => t.cellStyles?.[e]?.[n.id]
|
|
180
|
+
}))
|
|
181
|
+
});
|
|
182
|
+
}
|
|
136
183
|
//#endregion
|
|
137
|
-
export {
|
|
184
|
+
export { v as buildExcelAutoFilterRef, S as buildExcelSheetData, W as createTableExcelColumn, w as downloadExcelFile, C as downloadExcelWorkbook, G as downloadResolvedExcelTable, K as downloadResolvedExcelWorkbook, g as resolveExcelCellStyleFromState, b as resolveExcelSheetNames, F as resolveTableExcelColumnType };
|
|
138
185
|
|
|
139
186
|
//# sourceMappingURL=index.js.map
|
package/dist/excel/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/excel/excel.ts","../../src/excel/tableExport.ts"],"sourcesContent":["import writeXlsxFile, { type Cell, type CellObject, type Feature, type SheetData } from \"write-excel-file/browser\";\n\nimport { parseDate } from \"../formatters/date\";\nimport { type State } from \"../types\";\n\nexport type ExcelColumn = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\ttype?: StringConstructor | NumberConstructor | DateConstructor | BooleanConstructor;\n\tformat?: string;\n};\n\nexport type ExcelRow = Record<string, unknown>;\n\nexport type ExcelCellStyle = Omit<CellObject, \"value\" | \"type\" | \"format\">;\n\nexport type DownloadExcelFileArgs = {\n\tfileName: string;\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tautoFilter?: boolean;\n\tgetCellStyle?: (args: { row: ExcelRow; column: ExcelColumn; rowIndex: number; columnIndex: number }) => ExcelCellStyle | undefined;\n};\n\ntype BrowserExcelFileContent = File | Blob | ArrayBuffer;\n\nconst VALUE_STATE_TEXT_COLORS: Partial<Record<State, string>> = {\n\tinformation: \"#2563EB\",\n\tsuccess: \"#107C10\",\n\twarning: \"#B7791F\",\n\terror: \"#C50F1F\"\n};\n\nconst HEADER_CELL_STYLE = {\n\tfontWeight: \"bold\",\n\tbottomBorderStyle: \"thin\",\n\tbottomBorderColor: \"#D9D9D9\"\n} satisfies ExcelCellStyle;\n\n/**\n * Приводит общий value-state проекта к базовому Excel-стилю.\n *\n * Helper живет в shared Excel-слое, чтобы analytical/detail экспорт не\n * дублировали палитру статусов и одинаково подсвечивали warning/error/success.\n */\nexport function resolveExcelCellStyleFromState(state: State | undefined): ExcelCellStyle | undefined {\n\tconst textColor = state ? VALUE_STATE_TEXT_COLORS[state] : undefined;\n\treturn textColor ? { textColor } : undefined;\n}\n\n/**\n * Переводит zero-based индекс колонки в Excel-адрес (`0 -> A`, `27 -> AB`).\n * Нужен для XML-диапазонов, потому что `write-excel-file` не предоставляет\n * отдельного API для построения ссылок вида `A1:C10`.\n */\nfunction numberToColumnName(index: number): string {\n\tlet value = index + 1;\n\tlet out = \"\";\n\n\twhile (value > 0) {\n\t\tconst remainder = (value - 1) % 26;\n\t\tout = String.fromCharCode(65 + remainder) + out;\n\t\tvalue = Math.floor((value - 1) / 26);\n\t}\n\n\treturn out;\n}\n\n/**\n * Строит диапазон автофильтра для всей выгруженной таблицы.\n *\n * Возвращает `undefined` для пустой сетки, чтобы не вставлять в xlsx\n * невалидный `<autoFilter>` без реального диапазона.\n */\nexport function buildExcelAutoFilterRef(columnCount: number, rowCount: number): string | undefined {\n\tif (columnCount <= 0 || rowCount <= 0) return undefined;\n\n\treturn `A1:${numberToColumnName(columnCount - 1)}${rowCount}`;\n}\n\n/**\n * Добавляет autoFilter через feature-transform `write-excel-file`.\n *\n * Библиотека умеет трансформировать XML листа, но не имеет высокоуровневого\n * параметра `autoFilter`, поэтому здесь изолирован низкоуровневый OpenXML-хук.\n */\nfunction createAutoFilterFeature<FileContent>(ref: string | undefined): Feature<FileContent> | undefined {\n\tif (!ref) return undefined;\n\n\treturn {\n\t\tfiles: {\n\t\t\ttransform: {\n\t\t\t\t\"xl/worksheets/sheet{id}.xml\": {\n\t\t\t\t\ttransform: (content) => content.replace(\"</sheetData>\", `</sheetData><autoFilter ref=\"${ref}\"/>`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Приводит входное значение к типу Excel-ячейки.\n *\n * Важный смысл: если колонка числовая, в файл должен попасть настоящий Number,\n * а не уже отформатированная строка. Тогда Excel сможет применять `format`.\n */\nfunction normalizeCellValue(value: unknown, type: ExcelColumn[\"type\"]) {\n\tif (value == null || value === \"\") return undefined;\n\n\tif (type === Number) {\n\t\tconst numberValue = typeof value === \"number\" ? value : Number(value);\n\t\treturn Number.isFinite(numberValue) ? numberValue : undefined;\n\t}\n\n\tif (type === String) return String(value);\n\tif (type === Boolean) return Boolean(value);\n\tif (type === Date) return value instanceof Date ? value : (parseDate(value) ?? undefined);\n\n\treturn value as CellObject[\"value\"];\n}\n\n/**\n * Собирает SheetData для `write-excel-file`.\n *\n * Функция намеренно не знает о бизнес-сущностях: ей передают уже готовые\n * колонки/строки и необязательный callback стилей конкретных ячеек.\n */\nexport function buildExcelSheetData(args: Omit<DownloadExcelFileArgs, \"fileName\" | \"autoFilter\">): SheetData {\n\tconst headerRow: Cell[] = args.columns.map((column) => ({\n\t\ttype: String,\n\t\tvalue: column.header,\n\t\t...HEADER_CELL_STYLE\n\t}));\n\n\tconst sheetRows: SheetData = [headerRow];\n\n\tfor (let rowIndex = 0; rowIndex < args.rows.length; rowIndex++) {\n\t\tconst row = args.rows[rowIndex];\n\t\tconst sheetRow: Cell[] = [];\n\n\t\tfor (let columnIndex = 0; columnIndex < args.columns.length; columnIndex++) {\n\t\t\tconst column = args.columns[columnIndex];\n\t\t\tconst value = normalizeCellValue(row[column.id], column.type);\n\t\t\tconst style = args.getCellStyle?.({ row, column, rowIndex, columnIndex });\n\n\t\t\tsheetRow.push({\n\t\t\t\tvalue,\n\t\t\t\ttype: column.type,\n\t\t\t\tformat: column.format,\n\t\t\t\t...style\n\t\t\t});\n\t\t}\n\n\t\tsheetRows.push(sheetRow);\n\t}\n\n\treturn sheetRows;\n}\n\n/**\n * Формирует и скачивает `.xlsx` в браузере.\n *\n * Это публичная generic-точка shared-слоя: она отвечает только за Excel-файл,\n * а подготовка доменных данных остаётся на вызывающей стороне.\n */\nexport async function downloadExcelFile(args: DownloadExcelFileArgs): Promise<void> {\n\tconst sheetData = buildExcelSheetData(args);\n\tconst autoFilterRef = args.autoFilter ? buildExcelAutoFilterRef(args.columns.length, sheetData.length) : undefined;\n\tconst autoFilterFeature = createAutoFilterFeature<BrowserExcelFileContent>(autoFilterRef);\n\n\tawait writeXlsxFile(\n\t\tsheetData,\n\t\t{\n\t\t\tcolumns: args.columns.map((column) => ({\n\t\t\t\twidth: column.width\n\t\t\t}))\n\t\t},\n\t\t{\n\t\t\tfeatures: autoFilterFeature ? [autoFilterFeature] : undefined\n\t\t}\n\t).toFile(args.fileName);\n}\n","import { DEFAULT_DATE_PRESET_NAMES, getDatePreset, type DateFormatPreset } from \"../formatters/date\";\nimport { getNumberPreset } from \"../formatters/number\";\nimport {\n\tvalidateFormattersPipelineConfig,\n\ttype FormattersPipelineConfig,\n\ttype FormattersPipelineTypedValueFormatConfig\n} from \"../formatters/pipeline\";\nimport {\n\tisODataBooleanType,\n\tisODataDateType,\n\tisODataIntegerType,\n\tisODataNumericType,\n\ttype ColumnRole,\n\ttype ODataMetaType\n} from \"../odata-service\";\n\nimport { downloadExcelFile, type ExcelCellStyle, type ExcelColumn, type ExcelRow } from \"./excel\";\n\nexport type TableExcelColumnDescriptor = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\trole?: ColumnRole;\n\todataType?: ODataMetaType;\n\tclientOnly?: boolean;\n\tformattersPipeline?: FormattersPipelineConfig;\n};\n\nexport type ResolvedExcelTable = {\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tcellStyles?: ReadonlyArray<Readonly<Record<string, ExcelCellStyle | undefined>>>;\n};\n\nexport type DownloadResolvedExcelTableArgs = {\n\tfileName: string;\n\ttable: ResolvedExcelTable;\n\tautoFilter?: boolean;\n};\n\nconst INTEGER_EXCEL_FORMAT = \"#,##0\";\nconst DEFAULT_DECIMAL_EXCEL_FORMAT = \"#,##0.0\";\nconst EXCEL_DATE_FORMAT = \"dd.mm.yyyy\";\nconst EXCEL_DAY_MONTH_SHORT_FORMAT = \"d mmm\";\nconst EXCEL_DAY_MONTH_LONG_FORMAT = \"d mmmm\";\nconst EXCEL_TIME_FORMAT = \"hh:mm\";\nconst EXCEL_TIME_SECONDS_FORMAT = \"hh:mm:ss\";\nconst EXCEL_DATETIME_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_FORMAT}`;\nconst EXCEL_DATETIME_SECONDS_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_SECONDS_FORMAT}`;\n\nfunction resolveTypedValueFormatConfig(\n\tformattersPipeline: FormattersPipelineConfig | undefined\n): FormattersPipelineTypedValueFormatConfig | undefined {\n\tconst validation = validateFormattersPipelineConfig(formattersPipeline);\n\tconst typedValueFormatStep = validation.plan?.steps.find((step) => step.type === \"typedValueFormat\");\n\n\treturn typedValueFormatStep?.type === \"typedValueFormat\" ? typedValueFormatStep.config : undefined;\n}\n\nexport function resolveTableExcelColumnType(descriptor: TableExcelColumnDescriptor): ExcelColumn[\"type\"] {\n\tif (descriptor.clientOnly) return Number;\n\tif (isODataDateType(descriptor.odataType)) return Date;\n\tif (isODataBooleanType(descriptor.odataType)) return Boolean;\n\tif (isODataNumericType(descriptor.odataType)) return Number;\n\tif (descriptor.role === \"measure\") return Number;\n\treturn String;\n}\n\nfunction resolveNumberPresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.numberPresetName?.trim();\n\tif (configuredPresetName && getNumberPreset(configuredPresetName)) return configuredPresetName;\n\tif (isODataIntegerType(descriptor.odataType)) return \"integer\";\n\treturn \"decimal\";\n}\n\nfunction resolveExcelNumberFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst preset = getNumberPreset(resolveNumberPresetName(descriptor));\n\tif (!preset) return DEFAULT_DECIMAL_EXCEL_FORMAT;\n\treturn preset.decimals > 0 ? `#,##0.${\"0\".repeat(preset.decimals)}` : INTEGER_EXCEL_FORMAT;\n}\n\nfunction resolveDatePresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.datePresetName?.trim();\n\tif (configuredPresetName) return configuredPresetName;\n\tif (descriptor.odataType === \"time\") return DEFAULT_DATE_PRESET_NAMES.time;\n\tif (descriptor.odataType === \"datetime\" || descriptor.odataType === \"datetimeOffset\") return DEFAULT_DATE_PRESET_NAMES.datetime;\n\treturn DEFAULT_DATE_PRESET_NAMES.date;\n}\n\nfunction normalizeDatePatternForExcel(pattern: string): string {\n\treturn pattern.replace(/H/g, \"h\").replace(/M/g, \"m\");\n}\n\nfunction resolveBuiltinDatePresetExcelFormat(presetName: string): string | undefined {\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDatetime || presetName === DEFAULT_DATE_PRESET_NAMES.abapDatetime) {\n\t\treturn EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDate || presetName === DEFAULT_DATE_PRESET_NAMES.abapDate) {\n\t\treturn EXCEL_DATE_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthShort) {\n\t\treturn EXCEL_DAY_MONTH_SHORT_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthLong) {\n\t\treturn EXCEL_DAY_MONTH_LONG_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"datetime\")) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.datetime || presetName === DEFAULT_DATE_PRESET_NAMES.datetimeShort\n\t\t\t? EXCEL_DATETIME_FORMAT\n\t\t\t: EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"time\")) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.time || presetName === DEFAULT_DATE_PRESET_NAMES.timeShort\n\t\t\t? EXCEL_TIME_FORMAT\n\t\t\t: EXCEL_TIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"date\")) return EXCEL_DATE_FORMAT;\n\n\treturn undefined;\n}\n\nfunction resolveExcelDateFormatFromPreset(presetName: string, preset: DateFormatPreset | undefined): string {\n\tconst builtinFormat = resolveBuiltinDatePresetExcelFormat(presetName);\n\tif (builtinFormat) return builtinFormat;\n\tif (preset?.pattern) return normalizeDatePatternForExcel(preset.pattern);\n\n\t// Настройка datePresetName исторически хранит и ручной шаблон. Если имени\n\t// нет в реестре, передаём шаблон в Excel как есть после нормализации токенов.\n\treturn normalizeDatePatternForExcel(presetName);\n}\n\nfunction resolveExcelDateFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst presetName = resolveDatePresetName(descriptor);\n\treturn resolveExcelDateFormatFromPreset(presetName, getDatePreset(presetName));\n}\n\nfunction resolveTableExcelColumnFormat(descriptor: TableExcelColumnDescriptor, type: ExcelColumn[\"type\"]): string | undefined {\n\tif (type === Number) return resolveExcelNumberFormat(descriptor);\n\tif (type === Date) return resolveExcelDateFormat(descriptor);\n\treturn undefined;\n}\n\nexport function createTableExcelColumn(descriptor: TableExcelColumnDescriptor): ExcelColumn {\n\tconst type = resolveTableExcelColumnType(descriptor);\n\treturn {\n\t\tid: descriptor.id,\n\t\theader: descriptor.header,\n\t\twidth: descriptor.width,\n\t\ttype,\n\t\tformat: resolveTableExcelColumnFormat(descriptor, type)\n\t};\n}\n\nexport async function downloadResolvedExcelTable({ fileName, table, autoFilter = true }: DownloadResolvedExcelTableArgs): Promise<void> {\n\tawait downloadExcelFile({\n\t\tfileName,\n\t\tcolumns: table.columns,\n\t\trows: table.rows,\n\t\tautoFilter,\n\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t});\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/excel/excel.ts","../../src/excel/tableExport.ts"],"sourcesContent":["import writeXlsxFile, { type Cell, type CellObject, type Feature, type Sheet, type SheetData } from \"write-excel-file/browser\";\n\nimport { parseDate } from \"../formatters/date\";\nimport { type State } from \"../types\";\n\nexport type ExcelColumn = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\ttype?: StringConstructor | NumberConstructor | DateConstructor | BooleanConstructor;\n\tformat?: string;\n};\n\nexport type ExcelRow = Record<string, unknown>;\n\nexport type ExcelCellStyle = Omit<CellObject, \"value\" | \"type\" | \"format\">;\n\nexport type DownloadExcelFileArgs = {\n\tfileName: string;\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tautoFilter?: boolean;\n\tgetCellStyle?: (args: { row: ExcelRow; column: ExcelColumn; rowIndex: number; columnIndex: number }) => ExcelCellStyle | undefined;\n};\n\n/** Описание одного табличного листа внутри Excel-книги. */\nexport type ExcelWorkbookSheet = Omit<DownloadExcelFileArgs, \"fileName\"> & {\n\t/** Желаемое имя листа; writer нормализует ограничения формата и конфликты имён. */\n\tname: string;\n};\n\n/** Аргументы формирования Excel-книги с одним или несколькими табличными листами. */\nexport type DownloadExcelWorkbookArgs = {\n\t/** Имя скачиваемого `.xlsx` файла. */\n\tfileName: string;\n\t/** Листы книги в порядке отображения в Excel. */\n\tsheets: ExcelWorkbookSheet[];\n};\n\ntype BrowserExcelFileContent = File | Blob | ArrayBuffer;\n\nconst VALUE_STATE_TEXT_COLORS: Partial<Record<State, string>> = {\n\tinformation: \"#2563EB\",\n\tsuccess: \"#107C10\",\n\twarning: \"#B7791F\",\n\terror: \"#C50F1F\"\n};\n\nconst HEADER_CELL_STYLE = {\n\tfontWeight: \"bold\",\n\tbottomBorderStyle: \"thin\",\n\tbottomBorderColor: \"#D9D9D9\"\n} satisfies ExcelCellStyle;\n\nconst EXCEL_SHEET_NAME_MAX_LENGTH = 31;\nconst EXCEL_SHEET_NAME_INVALID_CHARACTERS = /[\\u0000-\\u001f[\\]/\\\\:*?]+/g;\nconst EXCEL_SHEET_NAME_EDGE_APOSTROPHES = /^'+|'+$/g;\nconst EXCEL_SHEET_NAME_WHITESPACE = /\\s+/g;\n\n/**\n * Приводит общий value-state проекта к базовому Excel-стилю.\n *\n * Helper живет в shared Excel-слое, чтобы analytical/detail экспорт не\n * дублировали палитру статусов и одинаково подсвечивали warning/error/success.\n */\nexport function resolveExcelCellStyleFromState(state: State | undefined): ExcelCellStyle | undefined {\n\tconst textColor = state ? VALUE_STATE_TEXT_COLORS[state] : undefined;\n\treturn textColor ? { textColor } : undefined;\n}\n\n/**\n * Переводит zero-based индекс колонки в Excel-адрес (`0 -> A`, `27 -> AB`).\n * Нужен для XML-диапазонов, потому что `write-excel-file` не предоставляет\n * отдельного API для построения ссылок вида `A1:C10`.\n */\nfunction numberToColumnName(index: number): string {\n\tlet value = index + 1;\n\tlet out = \"\";\n\n\twhile (value > 0) {\n\t\tconst remainder = (value - 1) % 26;\n\t\tout = String.fromCharCode(65 + remainder) + out;\n\t\tvalue = Math.floor((value - 1) / 26);\n\t}\n\n\treturn out;\n}\n\n/**\n * Строит диапазон автофильтра для всей выгруженной таблицы.\n *\n * Возвращает `undefined` для пустой сетки, чтобы не вставлять в xlsx\n * невалидный `<autoFilter>` без реального диапазона.\n */\nexport function buildExcelAutoFilterRef(columnCount: number, rowCount: number): string | undefined {\n\tif (columnCount <= 0 || rowCount <= 0) return undefined;\n\n\treturn `A1:${numberToColumnName(columnCount - 1)}${rowCount}`;\n}\n\n/**\n * Добавляет autoFilter через feature-transform `write-excel-file`.\n *\n * Библиотека умеет трансформировать XML листа, но не имеет высокоуровневого\n * параметра `autoFilter`, поэтому здесь изолирован низкоуровневый OpenXML-хук.\n */\nfunction createAutoFilterFeature<FileContent>(refs: readonly (string | undefined)[]): Feature<FileContent> | undefined {\n\tif (!refs.some(Boolean)) return undefined;\n\n\treturn {\n\t\tfiles: {\n\t\t\ttransform: {\n\t\t\t\t\"xl/worksheets/sheet{id}.xml\": {\n\t\t\t\t\ttransform: (content, _options, properties) => {\n\t\t\t\t\t\tconst ref = refs[properties.sheetIndex];\n\t\t\t\t\t\treturn ref ? content.replace(\"</sheetData>\", `</sheetData><autoFilter ref=\"${ref}\"/>`) : content;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Нормализует имена листов по ограничениям Excel и делает их уникальными.\n *\n * Runtime-заголовки могут содержать запрещённые символы, превышать 31 знак или\n * совпадать между несколькими представлениями одной конфигурации. Нормализация\n * выполняется централизованно, чтобы все consumers получали открываемую книгу.\n */\nexport function resolveExcelSheetNames(names: readonly string[]): string[] {\n\tconst usedNames = new Set<string>();\n\tconst resolvedNames: string[] = [];\n\n\tfor (let index = 0; index < names.length; index += 1) {\n\t\tconst fallbackName = `Лист ${index + 1}`;\n\t\tconst normalizedName = names[index]\n\t\t\t?.replace(EXCEL_SHEET_NAME_INVALID_CHARACTERS, \" \")\n\t\t\t.replace(EXCEL_SHEET_NAME_WHITESPACE, \" \")\n\t\t\t.trim()\n\t\t\t.replace(EXCEL_SHEET_NAME_EDGE_APOSTROPHES, \"\")\n\t\t\t.trim();\n\t\tconst baseName = normalizedName || fallbackName;\n\t\tlet resolvedName = baseName.slice(0, EXCEL_SHEET_NAME_MAX_LENGTH);\n\t\tlet duplicateIndex = 2;\n\n\t\twhile (usedNames.has(resolvedName.toLocaleLowerCase())) {\n\t\t\tconst suffix = ` (${duplicateIndex})`;\n\t\t\tresolvedName = `${baseName.slice(0, EXCEL_SHEET_NAME_MAX_LENGTH - suffix.length)}${suffix}`;\n\t\t\tduplicateIndex += 1;\n\t\t}\n\n\t\tusedNames.add(resolvedName.toLocaleLowerCase());\n\t\tresolvedNames.push(resolvedName);\n\t}\n\n\treturn resolvedNames;\n}\n\n/**\n * Приводит входное значение к типу Excel-ячейки.\n *\n * Важный смысл: если колонка числовая, в файл должен попасть настоящий Number,\n * а не уже отформатированная строка. Тогда Excel сможет применять `format`.\n */\nfunction normalizeCellValue(value: unknown, type: ExcelColumn[\"type\"]) {\n\tif (value == null || value === \"\") return undefined;\n\n\tif (type === Number) {\n\t\tconst numberValue = typeof value === \"number\" ? value : Number(value);\n\t\treturn Number.isFinite(numberValue) ? numberValue : undefined;\n\t}\n\n\tif (type === String) return String(value);\n\tif (type === Boolean) return Boolean(value);\n\tif (type === Date) return value instanceof Date ? value : (parseDate(value) ?? undefined);\n\n\treturn value as CellObject[\"value\"];\n}\n\n/**\n * Собирает SheetData для `write-excel-file`.\n *\n * Функция намеренно не знает о бизнес-сущностях: ей передают уже готовые\n * колонки/строки и необязательный callback стилей конкретных ячеек.\n */\nexport function buildExcelSheetData(args: Omit<DownloadExcelFileArgs, \"fileName\" | \"autoFilter\">): SheetData {\n\tconst headerRow: Cell[] = args.columns.map((column) => ({\n\t\ttype: String,\n\t\tvalue: column.header,\n\t\t...HEADER_CELL_STYLE\n\t}));\n\n\tconst sheetRows: SheetData = [headerRow];\n\n\tfor (let rowIndex = 0; rowIndex < args.rows.length; rowIndex++) {\n\t\tconst row = args.rows[rowIndex];\n\t\tconst sheetRow: Cell[] = [];\n\n\t\tfor (let columnIndex = 0; columnIndex < args.columns.length; columnIndex++) {\n\t\t\tconst column = args.columns[columnIndex];\n\t\t\tconst value = normalizeCellValue(row[column.id], column.type);\n\t\t\tconst style = args.getCellStyle?.({ row, column, rowIndex, columnIndex });\n\n\t\t\tsheetRow.push({\n\t\t\t\tvalue,\n\t\t\t\ttype: column.type,\n\t\t\t\tformat: column.format,\n\t\t\t\t...style\n\t\t\t});\n\t\t}\n\n\t\tsheetRows.push(sheetRow);\n\t}\n\n\treturn sheetRows;\n}\n\n/**\n * Формирует и скачивает Excel-книгу с независимыми табличными листами.\n *\n * Каждый лист получает собственные ширины колонок, стили ячеек и диапазон\n * автофильтра. Доменная подготовка колонок и строк остаётся у вызывающей стороны.\n */\nexport async function downloadExcelWorkbook(args: DownloadExcelWorkbookArgs): Promise<void> {\n\tif (args.sheets.length === 0) {\n\t\tthrow new Error(\"Для формирования Excel-книги нужен минимум один лист\");\n\t}\n\n\tconst sheetNames = resolveExcelSheetNames(args.sheets.map((sheet) => sheet.name));\n\tconst autoFilterRefs: Array<string | undefined> = [];\n\tconst sheets: Sheet<BrowserExcelFileContent>[] = args.sheets.map((sheet, index) => {\n\t\tconst data = buildExcelSheetData(sheet);\n\t\tautoFilterRefs.push(sheet.autoFilter ? buildExcelAutoFilterRef(sheet.columns.length, data.length) : undefined);\n\n\t\treturn {\n\t\t\tdata,\n\t\t\tsheet: sheetNames[index],\n\t\t\tcolumns: sheet.columns.map((column) => ({\n\t\t\t\twidth: column.width\n\t\t\t}))\n\t\t};\n\t});\n\tconst autoFilterFeature = createAutoFilterFeature<BrowserExcelFileContent>(autoFilterRefs);\n\n\tawait writeXlsxFile(sheets, {\n\t\tfeatures: autoFilterFeature ? [autoFilterFeature] : undefined\n\t}).toFile(args.fileName);\n}\n\n/**\n * Формирует и скачивает `.xlsx` в браузере.\n *\n * Это публичная generic-точка shared-слоя: она отвечает только за Excel-файл,\n * а подготовка доменных данных остаётся на вызывающей стороне.\n */\nexport async function downloadExcelFile(args: DownloadExcelFileArgs): Promise<void> {\n\tawait downloadExcelWorkbook({\n\t\tfileName: args.fileName,\n\t\tsheets: [\n\t\t\t{\n\t\t\t\tname: \"Sheet1\",\n\t\t\t\tcolumns: args.columns,\n\t\t\t\trows: args.rows,\n\t\t\t\tautoFilter: args.autoFilter,\n\t\t\t\tgetCellStyle: args.getCellStyle\n\t\t\t}\n\t\t]\n\t});\n}\n","import { DEFAULT_DATE_PRESET_NAMES, getDatePreset, type DateFormatPreset } from \"../formatters/date\";\nimport { getNumberPreset } from \"../formatters/number\";\nimport {\n\tvalidateFormattersPipelineConfig,\n\ttype FormattersPipelineConfig,\n\ttype FormattersPipelineTypedValueFormatConfig\n} from \"../formatters/pipeline\";\nimport {\n\tisODataBooleanType,\n\tisODataDateType,\n\tisODataIntegerType,\n\tisODataNumericType,\n\ttype ColumnRole,\n\ttype ODataMetaType\n} from \"../odata-service\";\n\nimport { downloadExcelFile, downloadExcelWorkbook, type ExcelCellStyle, type ExcelColumn, type ExcelRow } from \"./excel\";\n\nexport type TableExcelColumnDescriptor = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\trole?: ColumnRole;\n\todataType?: ODataMetaType;\n\tclientOnly?: boolean;\n\tformattersPipeline?: FormattersPipelineConfig;\n};\n\nexport type ResolvedExcelTable = {\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tcellStyles?: ReadonlyArray<Readonly<Record<string, ExcelCellStyle | undefined>>>;\n};\n\nexport type DownloadResolvedExcelTableArgs = {\n\tfileName: string;\n\ttable: ResolvedExcelTable;\n\tautoFilter?: boolean;\n};\n\n/** Один подготовленный табличный лист generic Excel-книги. */\nexport type ResolvedExcelWorkbookSheet = {\n\t/** Желаемое имя листа. */\n\tname: string;\n\t/** Подготовленные колонки, строки и optional стили ячеек. */\n\ttable: ResolvedExcelTable;\n\t/** Включить автофильтр для этого листа. По умолчанию включён. */\n\tautoFilter?: boolean;\n};\n\n/** Аргументы скачивания книги из нескольких подготовленных таблиц. */\nexport type DownloadResolvedExcelWorkbookArgs = {\n\t/** Имя скачиваемого `.xlsx` файла. */\n\tfileName: string;\n\t/** Табличные листы в порядке отображения в книге. */\n\tsheets: ResolvedExcelWorkbookSheet[];\n};\n\nconst INTEGER_EXCEL_FORMAT = \"#,##0\";\nconst DEFAULT_DECIMAL_EXCEL_FORMAT = \"#,##0.0\";\nconst EXCEL_DATE_FORMAT = \"dd.mm.yyyy\";\nconst EXCEL_DAY_MONTH_SHORT_FORMAT = \"d mmm\";\nconst EXCEL_DAY_MONTH_LONG_FORMAT = \"d mmmm\";\nconst EXCEL_TIME_FORMAT = \"hh:mm\";\nconst EXCEL_TIME_SECONDS_FORMAT = \"hh:mm:ss\";\nconst EXCEL_DATETIME_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_FORMAT}`;\nconst EXCEL_DATETIME_SECONDS_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_SECONDS_FORMAT}`;\n\nfunction resolveTypedValueFormatConfig(\n\tformattersPipeline: FormattersPipelineConfig | undefined\n): FormattersPipelineTypedValueFormatConfig | undefined {\n\tconst validation = validateFormattersPipelineConfig(formattersPipeline);\n\tconst typedValueFormatStep = validation.plan?.steps.find((step) => step.type === \"typedValueFormat\");\n\n\treturn typedValueFormatStep?.type === \"typedValueFormat\" ? typedValueFormatStep.config : undefined;\n}\n\nexport function resolveTableExcelColumnType(descriptor: TableExcelColumnDescriptor): ExcelColumn[\"type\"] {\n\tif (descriptor.clientOnly) return Number;\n\tif (isODataDateType(descriptor.odataType)) return Date;\n\tif (isODataBooleanType(descriptor.odataType)) return Boolean;\n\tif (isODataNumericType(descriptor.odataType)) return Number;\n\tif (descriptor.role === \"measure\") return Number;\n\treturn String;\n}\n\nfunction resolveNumberPresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.numberPresetName?.trim();\n\tif (configuredPresetName && getNumberPreset(configuredPresetName)) return configuredPresetName;\n\tif (isODataIntegerType(descriptor.odataType)) return \"integer\";\n\treturn \"decimal\";\n}\n\nfunction resolveExcelNumberFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst preset = getNumberPreset(resolveNumberPresetName(descriptor));\n\tif (!preset) return DEFAULT_DECIMAL_EXCEL_FORMAT;\n\treturn preset.decimals > 0 ? `#,##0.${\"0\".repeat(preset.decimals)}` : INTEGER_EXCEL_FORMAT;\n}\n\nfunction resolveDatePresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.datePresetName?.trim();\n\tif (configuredPresetName) return configuredPresetName;\n\tif (descriptor.odataType === \"time\") return DEFAULT_DATE_PRESET_NAMES.time;\n\tif (descriptor.odataType === \"datetime\" || descriptor.odataType === \"datetimeOffset\") return DEFAULT_DATE_PRESET_NAMES.datetime;\n\treturn DEFAULT_DATE_PRESET_NAMES.date;\n}\n\nfunction normalizeDatePatternForExcel(pattern: string): string {\n\treturn pattern.replace(/H/g, \"h\").replace(/M/g, \"m\");\n}\n\nfunction resolveBuiltinDatePresetExcelFormat(presetName: string): string | undefined {\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDatetime || presetName === DEFAULT_DATE_PRESET_NAMES.abapDatetime) {\n\t\treturn EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDate || presetName === DEFAULT_DATE_PRESET_NAMES.abapDate) {\n\t\treturn EXCEL_DATE_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthShort) {\n\t\treturn EXCEL_DAY_MONTH_SHORT_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthLong) {\n\t\treturn EXCEL_DAY_MONTH_LONG_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"datetime\")) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.datetime || presetName === DEFAULT_DATE_PRESET_NAMES.datetimeShort\n\t\t\t? EXCEL_DATETIME_FORMAT\n\t\t\t: EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"time\")) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.time || presetName === DEFAULT_DATE_PRESET_NAMES.timeShort\n\t\t\t? EXCEL_TIME_FORMAT\n\t\t\t: EXCEL_TIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"date\")) return EXCEL_DATE_FORMAT;\n\n\treturn undefined;\n}\n\nfunction resolveExcelDateFormatFromPreset(presetName: string, preset: DateFormatPreset | undefined): string {\n\tconst builtinFormat = resolveBuiltinDatePresetExcelFormat(presetName);\n\tif (builtinFormat) return builtinFormat;\n\tif (preset?.pattern) return normalizeDatePatternForExcel(preset.pattern);\n\n\t// Настройка datePresetName исторически хранит и ручной шаблон. Если имени\n\t// нет в реестре, передаём шаблон в Excel как есть после нормализации токенов.\n\treturn normalizeDatePatternForExcel(presetName);\n}\n\nfunction resolveExcelDateFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst presetName = resolveDatePresetName(descriptor);\n\treturn resolveExcelDateFormatFromPreset(presetName, getDatePreset(presetName));\n}\n\nfunction resolveTableExcelColumnFormat(descriptor: TableExcelColumnDescriptor, type: ExcelColumn[\"type\"]): string | undefined {\n\tif (type === Number) return resolveExcelNumberFormat(descriptor);\n\tif (type === Date) return resolveExcelDateFormat(descriptor);\n\treturn undefined;\n}\n\nexport function createTableExcelColumn(descriptor: TableExcelColumnDescriptor): ExcelColumn {\n\tconst type = resolveTableExcelColumnType(descriptor);\n\treturn {\n\t\tid: descriptor.id,\n\t\theader: descriptor.header,\n\t\twidth: descriptor.width,\n\t\ttype,\n\t\tformat: resolveTableExcelColumnFormat(descriptor, type)\n\t};\n}\n\nexport async function downloadResolvedExcelTable({ fileName, table, autoFilter = true }: DownloadResolvedExcelTableArgs): Promise<void> {\n\tawait downloadExcelFile({\n\t\tfileName,\n\t\tcolumns: table.columns,\n\t\trows: table.rows,\n\t\tautoFilter,\n\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t});\n}\n\n/** Скачивает многолистовую книгу из таблиц, уже подготовленных доменными consumers. */\nexport async function downloadResolvedExcelWorkbook({ fileName, sheets }: DownloadResolvedExcelWorkbookArgs): Promise<void> {\n\tawait downloadExcelWorkbook({\n\t\tfileName,\n\t\tsheets: sheets.map(({ name, table, autoFilter = true }) => ({\n\t\t\tname,\n\t\t\tcolumns: table.columns,\n\t\t\trows: table.rows,\n\t\t\tautoFilter,\n\t\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t\t}))\n\t});\n}\n"],"mappings":";;;;;AAyCA,IAAM,IAA0D;CAC/D,aAAa;CACb,SAAS;CACT,SAAS;CACT,OAAO;AACR,GAEM,IAAoB;CACzB,YAAY;CACZ,mBAAmB;CACnB,mBAAmB;AACpB,GAEM,IAA8B,IAC9B,IAAsC,8BACtC,IAAoC,YACpC,IAA8B;AAQpC,SAAgB,EAA+B,GAAsD;CACpG,IAAM,IAAY,IAAQ,EAAwB,KAAS,KAAA;CAC3D,OAAO,IAAY,EAAE,aAAU,IAAI,KAAA;AACpC;AAOA,SAAS,EAAmB,GAAuB;CAClD,IAAI,IAAQ,IAAQ,GAChB,IAAM;CAEV,OAAO,IAAQ,IAAG;EACjB,IAAM,KAAa,IAAQ,KAAK;EAEhC,AADA,IAAM,OAAO,aAAa,KAAK,CAAS,IAAI,GAC5C,IAAQ,KAAK,OAAO,IAAQ,KAAK,EAAE;CACpC;CAEA,OAAO;AACR;AAQA,SAAgB,EAAwB,GAAqB,GAAsC;CAC9F,WAAe,KAAK,KAAY,IAEpC,OAAO,MAAM,EAAmB,IAAc,CAAC,IAAI;AACpD;AAQA,SAAS,EAAqC,GAAyE;CACjH,MAAK,KAAK,OAAO,GAEtB,OAAO,EACN,OAAO,EACN,WAAW,EACV,+BAA+B,EAC9B,YAAY,GAAS,GAAU,MAAe;EAC7C,IAAM,IAAM,EAAK,EAAW;EAC5B,OAAO,IAAM,EAAQ,QAAQ,gBAAgB,gCAAgC,EAAI,IAAI,IAAI;CAC1F,EACD,EACD,EACD,EACD;AACD;AASA,SAAgB,EAAuB,GAAoC;CAC1E,IAAM,oBAAY,IAAI,IAAY,GAC5B,IAA0B,CAAC;CAEjC,KAAK,IAAI,IAAQ,GAAG,IAAQ,EAAM,QAAQ,KAAS,GAAG;EACrD,IAAM,IAAe,QAAQ,IAAQ,KAO/B,IANiB,EAAM,EAAM,EAChC,QAAQ,GAAqC,GAAG,CAAC,CAClD,QAAQ,GAA6B,GAAG,CAAC,CACzC,KAAK,CAAC,CACN,QAAQ,GAAmC,EAAE,CAAC,CAC9C,KAAK,KAC4B,GAC/B,IAAe,EAAS,MAAM,GAAG,CAA2B,GAC5D,IAAiB;EAErB,OAAO,EAAU,IAAI,EAAa,kBAAkB,CAAC,IAAG;GACvD,IAAM,IAAS,KAAK,EAAe;GAEnC,AADA,IAAe,GAAG,EAAS,MAAM,GAAG,IAA8B,EAAO,MAAM,IAAI,KACnF,KAAkB;EACnB;EAGA,AADA,EAAU,IAAI,EAAa,kBAAkB,CAAC,GAC9C,EAAc,KAAK,CAAY;CAChC;CAEA,OAAO;AACR;AAQA,SAAS,EAAmB,GAAgB,GAA2B;CAClE,WAAS,QAAQ,MAAU,KAE/B;MAAI,MAAS,QAAQ;GACpB,IAAM,IAAc,OAAO,KAAU,WAAW,IAAQ,OAAO,CAAK;GACpE,OAAO,OAAO,SAAS,CAAW,IAAI,IAAc,KAAA;EACrD;EAMA,OAJI,MAAS,SAAe,OAAO,CAAK,IACpC,MAAS,UAAgB,EAAQ,IACjC,MAAS,OAAa,aAAiB,OAAO,IAAS,EAAU,CAAK,KAAK,KAAA,IAExE;CANP;AAOD;AAQA,SAAgB,EAAoB,GAAyE;CAO5G,IAAM,IAAuB,CANH,EAAK,QAAQ,KAAK,OAAY;EACvD,MAAM;EACN,OAAO,EAAO;EACd,GAAG;CACJ,EAE8B,CAAS;CAEvC,KAAK,IAAI,IAAW,GAAG,IAAW,EAAK,KAAK,QAAQ,KAAY;EAC/D,IAAM,IAAM,EAAK,KAAK,IAChB,IAAmB,CAAC;EAE1B,KAAK,IAAI,IAAc,GAAG,IAAc,EAAK,QAAQ,QAAQ,KAAe;GAC3E,IAAM,IAAS,EAAK,QAAQ,IACtB,IAAQ,EAAmB,EAAI,EAAO,KAAK,EAAO,IAAI,GACtD,IAAQ,EAAK,eAAe;IAAE;IAAK;IAAQ;IAAU;GAAY,CAAC;GAExE,EAAS,KAAK;IACb;IACA,MAAM,EAAO;IACb,QAAQ,EAAO;IACf,GAAG;GACJ,CAAC;EACF;EAEA,EAAU,KAAK,CAAQ;CACxB;CAEA,OAAO;AACR;AAQA,eAAsB,EAAsB,GAAgD;CAC3F,IAAI,EAAK,OAAO,WAAW,GAC1B,MAAU,MAAM,sDAAsD;CAGvE,IAAM,IAAa,EAAuB,EAAK,OAAO,KAAK,MAAU,EAAM,IAAI,CAAC,GAC1E,IAA4C,CAAC,GAC7C,IAA2C,EAAK,OAAO,KAAK,GAAO,MAAU;EAClF,IAAM,IAAO,EAAoB,CAAK;EAGtC,OAFA,EAAe,KAAK,EAAM,aAAa,EAAwB,EAAM,QAAQ,QAAQ,EAAK,MAAM,IAAI,KAAA,CAAS,GAEtG;GACN;GACA,OAAO,EAAW;GAClB,SAAS,EAAM,QAAQ,KAAK,OAAY,EACvC,OAAO,EAAO,MACf,EAAE;EACH;CACD,CAAC,GACK,IAAoB,EAAiD,CAAc;CAEzF,MAAM,EAAc,GAAQ,EAC3B,UAAU,IAAoB,CAAC,CAAiB,IAAI,KAAA,EACrD,CAAC,CAAC,CAAC,OAAO,EAAK,QAAQ;AACxB;AAQA,eAAsB,EAAkB,GAA4C;CACnF,MAAM,EAAsB;EAC3B,UAAU,EAAK;EACf,QAAQ,CACP;GACC,MAAM;GACN,SAAS,EAAK;GACd,MAAM,EAAK;GACX,YAAY,EAAK;GACjB,cAAc,EAAK;EACpB,CACD;CACD,CAAC;AACF;;;ACnNA,IAAM,IAAuB,SACvB,IAA+B,WAC/B,IAAoB,cACpB,IAA+B,SAC/B,IAA8B,UAC9B,IAAoB,SACpB,IAA4B,YAC5B,IAAwB,GAAG,EAAkB,GAAG,KAChD,IAAgC,GAAG,EAAkB,GAAG;AAE9D,SAAS,EACR,GACuD;CAEvD,IAAM,IADa,EAAiC,CACvB,CAAA,CAAW,MAAM,MAAM,MAAM,MAAS,EAAK,SAAS,kBAAkB;CAEnG,OAAO,GAAsB,SAAS,qBAAqB,EAAqB,SAAS,KAAA;AAC1F;AAEA,SAAgB,EAA4B,GAA6D;CAMxG,OALI,EAAW,aAAmB,SAC9B,EAAgB,EAAW,SAAS,IAAU,OAC9C,EAAmB,EAAW,SAAS,IAAU,UACjD,EAAmB,EAAW,SAAS,KACvC,EAAW,SAAS,YAAkB,SACnC;AACR;AAEA,SAAS,EAAwB,GAAgD;CAChF,IAAM,IAAuB,EAA8B,EAAW,kBAAkB,CAAC,EAAE,kBAAkB,KAAK;CAGlH,OAFI,KAAwB,EAAgB,CAAoB,IAAU,IACtE,EAAmB,EAAW,SAAS,IAAU,YAC9C;AACR;AAEA,SAAS,EAAyB,GAAgD;CACjF,IAAM,IAAS,EAAgB,EAAwB,CAAU,CAAC;CAElE,OADK,IACE,EAAO,WAAW,IAAI,SAAS,IAAI,OAAO,EAAO,QAAQ,MAAM,IADlD;AAErB;AAEA,SAAS,EAAsB,GAAgD;CAK9E,OAJ6B,EAA8B,EAAW,kBAAkB,CAAC,EAAE,gBAAgB,KAAK,MAE5G,EAAW,cAAc,SAAe,EAA0B,OAClE,EAAW,cAAc,cAAc,EAAW,cAAc,mBAAyB,EAA0B,WAChH,EAA0B;AAClC;AAEA,SAAS,EAA6B,GAAyB;CAC9D,OAAO,EAAQ,QAAQ,MAAM,GAAG,CAAC,CAAC,QAAQ,MAAM,GAAG;AACpD;AAEA,SAAS,EAAoC,GAAwC;CACpF,IAAI,MAAe,EAA0B,iBAAiB,MAAe,EAA0B,cACtG,OAAO;CAGR,IAAI,MAAe,EAA0B,aAAa,MAAe,EAA0B,UAClG,OAAO;CAGR,IAAI,MAAe,EAA0B,YAC5C,OAAO;CAGR,IAAI,MAAe,EAA0B,WAC5C,OAAO;CAGR,IAAI,EAAW,WAAW,UAAU,GACnC,OAAO,MAAe,EAA0B,YAAY,MAAe,EAA0B,gBAClG,IACA;CAGJ,IAAI,EAAW,WAAW,MAAM,GAC/B,OAAO,MAAe,EAA0B,QAAQ,MAAe,EAA0B,YAC9F,IACA;CAGJ,IAAI,EAAW,WAAW,MAAM,GAAG,OAAO;AAG3C;AAEA,SAAS,EAAiC,GAAoB,GAA8C;CAO3G,OANsB,EAAoC,CACtD,MACA,GAAQ,UAAgB,EAA6B,EAAO,OAAO,IAIhE,EAA6B,CAAU;AAC/C;AAEA,SAAS,EAAuB,GAAgD;CAC/E,IAAM,IAAa,EAAsB,CAAU;CACnD,OAAO,EAAiC,GAAY,EAAc,CAAU,CAAC;AAC9E;AAEA,SAAS,EAA8B,GAAwC,GAA+C;CAC7H,IAAI,MAAS,QAAQ,OAAO,EAAyB,CAAU;CAC/D,IAAI,MAAS,MAAM,OAAO,EAAuB,CAAU;AAE5D;AAEA,SAAgB,EAAuB,GAAqD;CAC3F,IAAM,IAAO,EAA4B,CAAU;CACnD,OAAO;EACN,IAAI,EAAW;EACf,QAAQ,EAAW;EACnB,OAAO,EAAW;EAClB;EACA,QAAQ,EAA8B,GAAY,CAAI;CACvD;AACD;AAEA,eAAsB,EAA2B,EAAE,aAAU,UAAO,gBAAa,MAAuD;CACvI,MAAM,EAAkB;EACvB;EACA,SAAS,EAAM;EACf,MAAM,EAAM;EACZ;EACA,eAAe,EAAE,aAAU,gBAAa,EAAM,aAAa,EAAS,GAAG,EAAO;CAC/E,CAAC;AACF;AAGA,eAAsB,EAA8B,EAAE,aAAU,aAA4D;CAC3H,MAAM,EAAsB;EAC3B;EACA,QAAQ,EAAO,KAAK,EAAE,SAAM,UAAO,gBAAa,UAAY;GAC3D;GACA,SAAS,EAAM;GACf,MAAM,EAAM;GACZ;GACA,eAAe,EAAE,aAAU,gBAAa,EAAM,aAAa,EAAS,GAAG,EAAO;EAC/E,EAAE;CACH,CAAC;AACF"}
|
|
@@ -20,7 +20,25 @@ export type DownloadResolvedExcelTableArgs = {
|
|
|
20
20
|
table: ResolvedExcelTable;
|
|
21
21
|
autoFilter?: boolean;
|
|
22
22
|
};
|
|
23
|
+
/** Один подготовленный табличный лист generic Excel-книги. */
|
|
24
|
+
export type ResolvedExcelWorkbookSheet = {
|
|
25
|
+
/** Желаемое имя листа. */
|
|
26
|
+
name: string;
|
|
27
|
+
/** Подготовленные колонки, строки и optional стили ячеек. */
|
|
28
|
+
table: ResolvedExcelTable;
|
|
29
|
+
/** Включить автофильтр для этого листа. По умолчанию включён. */
|
|
30
|
+
autoFilter?: boolean;
|
|
31
|
+
};
|
|
32
|
+
/** Аргументы скачивания книги из нескольких подготовленных таблиц. */
|
|
33
|
+
export type DownloadResolvedExcelWorkbookArgs = {
|
|
34
|
+
/** Имя скачиваемого `.xlsx` файла. */
|
|
35
|
+
fileName: string;
|
|
36
|
+
/** Табличные листы в порядке отображения в книге. */
|
|
37
|
+
sheets: ResolvedExcelWorkbookSheet[];
|
|
38
|
+
};
|
|
23
39
|
export declare function resolveTableExcelColumnType(descriptor: TableExcelColumnDescriptor): ExcelColumn["type"];
|
|
24
40
|
export declare function createTableExcelColumn(descriptor: TableExcelColumnDescriptor): ExcelColumn;
|
|
25
41
|
export declare function downloadResolvedExcelTable({ fileName, table, autoFilter }: DownloadResolvedExcelTableArgs): Promise<void>;
|
|
42
|
+
/** Скачивает многолистовую книгу из таблиц, уже подготовленных доменными consumers. */
|
|
43
|
+
export declare function downloadResolvedExcelWorkbook({ fileName, sheets }: DownloadResolvedExcelWorkbookArgs): Promise<void>;
|
|
26
44
|
//# sourceMappingURL=tableExport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tableExport.d.ts","sourceRoot":"","sources":["../../src/excel/tableExport.ts"],"names":[],"mappings":"AAEA,OAAO,EAEN,KAAK,wBAAwB,EAE7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAKN,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,
|
|
1
|
+
{"version":3,"file":"tableExport.d.ts","sourceRoot":"","sources":["../../src/excel/tableExport.ts"],"names":[],"mappings":"AAEA,OAAO,EAEN,KAAK,wBAAwB,EAE7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAKN,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAA4C,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEzH,MAAM,MAAM,0BAA0B,GAAG;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAChC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,UAAU,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;CACjF,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,MAAM,0BAA0B,GAAG;IACxC,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,KAAK,EAAE,kBAAkB,CAAC;IAC1B,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,iCAAiC,GAAG;IAC/C,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,MAAM,EAAE,0BAA0B,EAAE,CAAC;CACrC,CAAC;AAqBF,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,0BAA0B,GAAG,WAAW,CAAC,MAAM,CAAC,CAOvG;AAkFD,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,0BAA0B,GAAG,WAAW,CAS1F;AAED,wBAAsB,0BAA0B,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAiB,EAAE,EAAE,8BAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtI;AAED,uFAAuF;AACvF,wBAAsB,6BAA6B,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,iCAAiC,GAAG,OAAO,CAAC,IAAI,CAAC,CAW1H"}
|