@aurum-grid/enterprise 0.0.0-stage → 0.2.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/dist/import.js ADDED
@@ -0,0 +1,323 @@
1
+ import { readWorkbook } from './excel.js';
2
+ /* ------------------------------------------------------------------ *
3
+ * Turning an uploaded CSV / XLSX file into a typed, editable grid and a
4
+ * backend-ready JSON payload.
5
+ * ------------------------------------------------------------------ */
6
+ export const IMPORT_LIMITS = {
7
+ maxBytes: 10 * 1024 * 1024,
8
+ maxRows: 50_000,
9
+ maxColumns: 200,
10
+ };
11
+ export class ImportError extends Error {
12
+ }
13
+ const RESERVED = new Set(['__proto__', 'prototype', 'constructor', 'hasownproperty', 'tostring', 'valueof', 'isprototypeof', 'propertyisenumerable', 'tolocalestring', '__definegetter__', '__definesetter__', '__lookupgetter__', '__lookupsetter__']);
14
+ // eslint-disable-next-line no-control-regex
15
+ const CONTROL = /[\u0000-\u001f\u007f\u200b-\u200f\u202a-\u202e\u2066-\u2069\uFEFF]/g;
16
+ /**
17
+ * Turn arbitrary header cells into unique, safe field names while keeping readable labels.
18
+ * "Unit price ($)" → unitPrice, "" → column3, "2024" → c2024, "__proto__" → proto_, duplicates → name_2.
19
+ */
20
+ export function sanitizeHeaders(headers) {
21
+ const usedFields = new Set();
22
+ const usedLabels = new Map();
23
+ return headers.map((raw, i) => {
24
+ const source = raw == null ? '' : String(raw);
25
+ let label = source.replace(CONTROL, '').replace(/\s+/g, ' ').trim().slice(0, 120);
26
+ if (!label)
27
+ label = `Column ${i + 1}`;
28
+ const seenLabel = usedLabels.get(label.toLowerCase()) ?? 0;
29
+ usedLabels.set(label.toLowerCase(), seenLabel + 1);
30
+ const headerName = seenLabel ? `${label} (${seenLabel + 1})` : label;
31
+ const words = label.normalize('NFKD').replace(/[\u0300-\u036f]/g, '').split(/[^A-Za-z0-9]+/).filter(Boolean);
32
+ let field = words.map((w, k) => (k ? w[0].toUpperCase() + w.slice(1) : w[0].toLowerCase() + w.slice(1))).join('').slice(0, 64);
33
+ if (!field)
34
+ field = `column${i + 1}`;
35
+ if (/^\d/.test(field))
36
+ field = `c${field}`;
37
+ if (RESERVED.has(field.toLowerCase()) || RESERVED.has(label.toLowerCase()))
38
+ field = `${field.replace(/^_+|_+$/g, '') || 'field'}_`;
39
+ let unique = field;
40
+ let n = 2;
41
+ while (usedFields.has(unique.toLowerCase()))
42
+ unique = `${field}_${n++}`;
43
+ usedFields.add(unique.toLowerCase());
44
+ return { field: unique, headerName, sourceHeader: source };
45
+ });
46
+ }
47
+ const BOOL_TRUE = new Set(['true', 'yes', 'y']);
48
+ const BOOL_FALSE = new Set(['false', 'no', 'n']);
49
+ const NUM_RE = /^[-+]?[$£€¥]?\s*-?(\d{1,3}(,\d{3})+|\d+)(\.\d+)?%?$|^[-+]?\.\d+$/;
50
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}(:\d{2})?)?$/;
51
+ const DMY = /^(\d{1,2})[/.-](\d{1,2})[/.-](\d{4})$/;
52
+ export function parseNumberLike(v) {
53
+ if (typeof v === 'number')
54
+ return Number.isFinite(v) ? v : null;
55
+ if (typeof v !== 'string')
56
+ return null;
57
+ const s = v.trim().replace(/\s/g, '');
58
+ if (!s || !NUM_RE.test(s))
59
+ return null;
60
+ const neg = s.startsWith('-') || /^[$£€¥]-/.test(s);
61
+ const n = Number(s.replace(/[^\d.]/g, ''));
62
+ if (!Number.isFinite(n))
63
+ return null;
64
+ return (neg ? -n : n) / (s.endsWith('%') ? 100 : 1);
65
+ }
66
+ function parseDateLike(v, dayFirst) {
67
+ if (typeof v !== 'string')
68
+ return null;
69
+ const s = v.trim();
70
+ if (ISO_DATE.test(s))
71
+ return s;
72
+ const m = DMY.exec(s);
73
+ if (m) {
74
+ const [a, b] = [Number(m[1]), Number(m[2])];
75
+ const day = dayFirst ? a : b;
76
+ const month = dayFirst ? b : a;
77
+ if (month < 1 || month > 12 || day < 1 || day > 31)
78
+ return null;
79
+ return `${m[3]}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
80
+ }
81
+ return null;
82
+ }
83
+ /** Infer a column type from its values (blank values are ignored). */
84
+ export function inferColumnType(values) {
85
+ const present = values.filter((v) => v != null && String(v).trim() !== '');
86
+ if (!present.length)
87
+ return { type: 'text', dayFirst: true };
88
+ const ratio = (fn) => present.filter(fn).length / present.length;
89
+ if (present.every((v) => typeof v === 'boolean' || BOOL_TRUE.has(String(v).trim().toLowerCase()) || BOOL_FALSE.has(String(v).trim().toLowerCase()))
90
+ && present.some((v) => typeof v === 'boolean' || /^(true|false|yes|no)$/i.test(String(v).trim())))
91
+ return { type: 'boolean', dayFirst: true };
92
+ if (ratio((v) => parseNumberLike(v) != null) >= 0.95)
93
+ return { type: 'number', dayFirst: true };
94
+ // dd/mm vs mm/dd: if any first part > 12 it's day-first; if any second part > 12 it's month-first; default day-first (UK/EU)
95
+ let dayFirst = true;
96
+ for (const v of present) {
97
+ const m = typeof v === 'string' ? DMY.exec(v.trim()) : null;
98
+ if (m && Number(m[2]) > 12)
99
+ dayFirst = false;
100
+ if (m && Number(m[1]) > 12) {
101
+ dayFirst = true;
102
+ break;
103
+ }
104
+ }
105
+ if (ratio((v) => parseDateLike(v, dayFirst) != null) >= 0.95)
106
+ return { type: 'date', dayFirst };
107
+ return { type: 'text', dayFirst };
108
+ }
109
+ function coerce(v, type, dayFirst) {
110
+ if (v == null || (typeof v === 'string' && v.trim() === ''))
111
+ return null;
112
+ switch (type) {
113
+ case 'number':
114
+ return parseNumberLike(v);
115
+ case 'boolean':
116
+ return typeof v === 'boolean' ? v : BOOL_TRUE.has(String(v).trim().toLowerCase());
117
+ case 'date':
118
+ return parseDateLike(String(v), dayFirst) ?? String(v);
119
+ default: {
120
+ const s = typeof v === 'string' ? v : String(v);
121
+ return s.replace(CONTROL, '').slice(0, 10_000);
122
+ }
123
+ }
124
+ }
125
+ /** RFC 4180 CSV/TSV parser with delimiter detection (comma, semicolon, tab, pipe). */
126
+ export function parseDelimited(text, delimiter) {
127
+ const src = text.replace(/^\uFEFF/, '');
128
+ const d = delimiter ?? detectDelimiter(src);
129
+ const rows = [];
130
+ let field = '';
131
+ let row = [];
132
+ let q = false;
133
+ for (let i = 0; i < src.length; i++) {
134
+ const c = src[i];
135
+ if (q) {
136
+ if (c === '"' && src[i + 1] === '"') {
137
+ field += '"';
138
+ i++;
139
+ }
140
+ else if (c === '"')
141
+ q = false;
142
+ else
143
+ field += c;
144
+ }
145
+ else if (c === '"' && field === '')
146
+ q = true;
147
+ else if (c === d) {
148
+ row.push(field);
149
+ field = '';
150
+ }
151
+ else if (c === '\n' || c === '\r') {
152
+ if (c === '\r' && src[i + 1] === '\n')
153
+ i++;
154
+ row.push(field);
155
+ rows.push(row);
156
+ row = [];
157
+ field = '';
158
+ }
159
+ else
160
+ field += c;
161
+ }
162
+ if (field !== '' || row.length) {
163
+ row.push(field);
164
+ rows.push(row);
165
+ }
166
+ return rows.filter((r) => !(r.length === 1 && r[0].trim() === ''));
167
+ }
168
+ function detectDelimiter(text) {
169
+ const sample = text.split(/\r?\n/).slice(0, 10).join('\n');
170
+ let best = ',';
171
+ let bestScore = -1;
172
+ for (const d of [',', ';', '\t', '|']) {
173
+ const counts = sample.split('\n').filter(Boolean).map((l) => l.split(d).length - 1);
174
+ if (!counts.length || counts[0] === 0)
175
+ continue;
176
+ const consistent = counts.filter((c) => c === counts[0]).length / counts.length;
177
+ const score = counts[0] * consistent;
178
+ if (score > bestScore) {
179
+ best = d;
180
+ bestScore = score;
181
+ }
182
+ }
183
+ return best;
184
+ }
185
+ /** Blob → ArrayBuffer/text that also works where Blob#arrayBuffer is missing (older browsers, jsdom). */
186
+ export function blobToArrayBuffer(b) {
187
+ if (typeof b.arrayBuffer === 'function')
188
+ return b.arrayBuffer();
189
+ return new Promise((res, rej) => {
190
+ const r = new FileReader();
191
+ r.onload = () => res(r.result);
192
+ r.onerror = () => rej(r.error ?? new Error('Could not read the file'));
193
+ r.readAsArrayBuffer(b);
194
+ });
195
+ }
196
+ export async function blobToText(b) {
197
+ if (typeof b.text === 'function')
198
+ return b.text();
199
+ return new TextDecoder().decode(await blobToArrayBuffer(b));
200
+ }
201
+ /** Decide the file type from its name and first bytes; rejects anything else. */
202
+ export async function detectFileType(file) {
203
+ const name = (file.name ?? '').toLowerCase();
204
+ const head = new Uint8Array(await blobToArrayBuffer(file.slice(0, 4)));
205
+ const isZip = head[0] === 0x50 && head[1] === 0x4b;
206
+ if (name.endsWith('.xlsx') || name.endsWith('.xlsm')) {
207
+ if (!isZip)
208
+ throw new ImportError('This .xlsx file is not a valid Excel workbook.');
209
+ return 'xlsx';
210
+ }
211
+ if (name.endsWith('.xls'))
212
+ throw new ImportError('Legacy .xls files are not supported. Save the file as .xlsx or .csv and try again.');
213
+ if (name.endsWith('.csv') || name.endsWith('.tsv') || name.endsWith('.txt')) {
214
+ if (isZip)
215
+ throw new ImportError('This file looks like a workbook, not CSV. Rename it to .xlsx.');
216
+ return 'csv';
217
+ }
218
+ throw new ImportError('Choose a .csv or .xlsx file.');
219
+ }
220
+ /** Read a CSV or XLSX upload. CSV is returned as a single sheet named after the file. */
221
+ export async function inspectFile(file, limits = IMPORT_LIMITS) {
222
+ const fileName = (file.name ?? 'upload').replace(CONTROL, '').slice(0, 200);
223
+ if (file.size === 0)
224
+ throw new ImportError('The file is empty.');
225
+ if (file.size > limits.maxBytes)
226
+ throw new ImportError(`The file is ${(file.size / 1048576).toFixed(1)} MB. The limit is ${(limits.maxBytes / 1048576).toFixed(0)} MB.`);
227
+ const fileType = await detectFileType(file);
228
+ if (fileType === 'xlsx') {
229
+ const sheets = await readWorkbook(await blobToArrayBuffer(file), { maxRows: limits.maxRows + 1 });
230
+ if (!sheets.some((s) => s.header.length))
231
+ throw new ImportError('The workbook has no data.');
232
+ return { fileName, fileType, sheets };
233
+ }
234
+ const text = await blobToText(file);
235
+ if (text.includes('\u0000'))
236
+ throw new ImportError('This file contains binary data and is not valid CSV.');
237
+ const table = parseDelimited(text);
238
+ if (!table.length)
239
+ throw new ImportError('The CSV has no rows.');
240
+ const [header, ...rows] = table;
241
+ return { fileName, fileType, sheets: [{ name: fileName.replace(/\.(csv|tsv|txt)$/i, ''), header, rows }] };
242
+ }
243
+ /** Build column definitions, typed rows and the backend payload from a header row + data rows. */
244
+ export function buildImportedGrid(header, rows, o) {
245
+ const limits = o.limits ?? IMPORT_LIMITS;
246
+ const warnings = [];
247
+ if (!header.length || header.every((h) => h == null || String(h).trim() === ''))
248
+ throw new ImportError('The first row must contain column headers.');
249
+ let width = header.length;
250
+ if (width > limits.maxColumns) {
251
+ warnings.push(`Only the first ${limits.maxColumns} of ${width} columns were imported.`);
252
+ width = limits.maxColumns;
253
+ }
254
+ let data = rows.filter((r) => r.some((v) => v != null && String(v).trim() !== ''));
255
+ if (data.length > limits.maxRows) {
256
+ warnings.push(`Only the first ${limits.maxRows.toLocaleString()} of ${data.length.toLocaleString()} rows were imported.`);
257
+ data = data.slice(0, limits.maxRows);
258
+ }
259
+ const ragged = data.filter((r) => r.length > header.length).length;
260
+ if (ragged)
261
+ warnings.push(`${ragged} row${ragged === 1 ? ' has' : 's have'} more cells than there are headers; extra cells were ignored.`);
262
+ const heads = sanitizeHeaders(header.slice(0, width));
263
+ const renamed = heads.filter((h) => h.headerName !== h.sourceHeader.trim()).length;
264
+ if (renamed)
265
+ warnings.push(`${renamed} blank, duplicate or unusual header${renamed === 1 ? ' was' : 's were'} renamed.`);
266
+ const columns = [];
267
+ const types = heads.map((h, i) => {
268
+ const t = inferColumnType(data.map((r) => r[i]));
269
+ columns.push({ ...h, type: t.type });
270
+ return t;
271
+ });
272
+ let unparsed = 0;
273
+ const rowData = data.map((r) => {
274
+ const o2 = Object.create(null);
275
+ heads.forEach((h, i) => {
276
+ const v = coerce(r[i], types[i].type, types[i].dayFirst);
277
+ if (v == null && r[i] != null && String(r[i]).trim() !== '')
278
+ unparsed++;
279
+ o2[h.field] = v;
280
+ });
281
+ return { ...o2 };
282
+ });
283
+ if (unparsed)
284
+ warnings.push(`${unparsed} value${unparsed === 1 ? '' : 's'} didn't match the column type and were left blank.`);
285
+ const columnDefs = columns.map((c) => {
286
+ const distinct = new Set(rowData.map((r) => r[c.field])).size;
287
+ const def = { field: c.field, headerName: c.headerName, editable: true, sortable: true, resizable: true, floatingFilter: true, minWidth: 90 };
288
+ if (c.type === 'number')
289
+ Object.assign(def, { type: 'numericColumn', filter: 'number', cellEditor: 'number' });
290
+ else if (c.type === 'date')
291
+ Object.assign(def, { filter: 'date', cellEditor: 'date', type: 'dateColumn' });
292
+ else if (c.type === 'boolean')
293
+ Object.assign(def, { filter: 'boolean', cellEditor: 'checkbox', valueFormatter: (p) => (p.value == null ? '' : p.value ? 'Yes' : 'No') });
294
+ else
295
+ Object.assign(def, { filter: distinct <= 25 && rowData.length > 25 ? 'set' : 'text' });
296
+ return def;
297
+ });
298
+ const gridName = (o.gridName ?? o.fileName.replace(/\.[^.]+$/, '')).replace(CONTROL, '').trim().slice(0, 120) || 'Imported grid';
299
+ const payload = {
300
+ schemaVersion: 1,
301
+ gridName,
302
+ source: { fileName: o.fileName, fileType: o.fileType, sheet: o.fileType === 'xlsx' ? o.sheet ?? null : null, uploadedAt: (o.now ?? new Date()).toISOString() },
303
+ rowCount: rowData.length,
304
+ columnCount: columns.length,
305
+ columns,
306
+ rows: rowData,
307
+ };
308
+ return { payload, columnDefs, rowData, warnings };
309
+ }
310
+ /** Refresh the payload rows (after edits) without changing schema metadata. */
311
+ export function withRows(payload, rows) {
312
+ const fields = payload.columns.map((c) => c.field);
313
+ const clean = rows.map((r) => {
314
+ const o = {};
315
+ for (const f of fields) {
316
+ const v = r[f];
317
+ o[f] = v == null ? null : typeof v === 'number' || typeof v === 'boolean' ? v : String(v);
318
+ }
319
+ return o;
320
+ });
321
+ return { ...payload, rows: clean, rowCount: clean.length };
322
+ }
323
+ //# sourceMappingURL=import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../src/import.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAqC,MAAM,YAAY,CAAC;AAE7E;;;wEAGwE;AAExE,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,QAAQ,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;IAC1B,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,GAAG;CAChB,CAAC;AA6BF,MAAM,OAAO,WAAY,SAAQ,KAAK;CAAG;AAEzC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAExP,4CAA4C;AAC5C,MAAM,OAAO,GAAG,qEAAqE,CAAC;AAEtF;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAkB;IAChD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAClF,IAAI,CAAC,KAAK;YAAE,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3D,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QACrE,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7G,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/H,IAAI,CAAC,KAAK;YAAE,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC3C,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAAE,KAAK,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,OAAO,GAAG,CAAC;QACnI,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAAE,MAAM,GAAG,GAAG,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;QACxE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QACrC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;AAChD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;AACjD,MAAM,MAAM,GAAG,kEAAkE,CAAC;AAClF,MAAM,QAAQ,GAAG,6CAA6C,CAAC;AAC/D,MAAM,GAAG,GAAG,uCAAuC,CAAC;AAEpD,MAAM,UAAU,eAAe,CAAC,CAAU;IACxC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,GAAG,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,aAAa,CAAC,CAAU,EAAE,QAAiB;IAClD,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACnB,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,EAAE,CAAC;QACN,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QAChE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IACrF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC7D,MAAM,KAAK,GAAG,CAAC,EAA2B,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC1F,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;WAC9I,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS,IAAI,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAChJ,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAChG,6HAA6H;IAC7H,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5D,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE;YAAE,QAAQ,GAAG,KAAK,CAAC;QAC7C,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC;YAC3B,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM;QACR,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAChG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AACpC,CAAC;AAED,SAAS,MAAM,CAAC,CAAU,EAAE,IAAkB,EAAE,QAAiB;IAC/D,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACzE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;QAC5B,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QACpF,KAAK,MAAM;YACT,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,SAAkB;IAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,SAAS,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,GAAG,GAAa,EAAE,CAAC;IACvB,IAAI,CAAC,GAAG,KAAK,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC,EAAE,CAAC;YACN,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACpC,KAAK,IAAI,GAAG,CAAC;gBACb,CAAC,EAAE,CAAC;YACN,CAAC;iBAAM,IAAI,CAAC,KAAK,GAAG;gBAAE,CAAC,GAAG,KAAK,CAAC;;gBAC3B,KAAK,IAAI,CAAC,CAAC;QAClB,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,KAAK,EAAE;YAAE,CAAC,GAAG,IAAI,CAAC;aAC1C,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACjB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChB,KAAK,GAAG,EAAE,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACpC,IAAI,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACf,GAAG,GAAG,EAAE,CAAC;YACT,KAAK,GAAG,EAAE,CAAC;QACb,CAAC;;YAAM,KAAK,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,IAAI,KAAK,KAAK,EAAE,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QAC/B,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,IAAI,IAAI,GAAG,GAAG,CAAC;IACf,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;IACnB,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACpF,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;YAAE,SAAS;QAChD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAChF,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC;QACrC,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;YACtB,IAAI,GAAG,CAAC,CAAC;YACT,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,iBAAiB,CAAC,CAAO;IACvC,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,UAAU;QAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IAChE,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC9B,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,CAAC;QAC3B,CAAC,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAqB,CAAC,CAAC;QAC9C,CAAC,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACvE,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,CAAO;IACtC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAA8B;IACjE,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACnD,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,WAAW,CAAC,gDAAgD,CAAC,CAAC;QACpF,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,oFAAoF,CAAC,CAAC;IACvI,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5E,IAAI,KAAK;YAAE,MAAM,IAAI,WAAW,CAAC,+DAA+D,CAAC,CAAC;QAClG,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,WAAW,CAAC,8BAA8B,CAAC,CAAC;AACxD,CAAC;AAQD,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAA8B,EAAE,MAAM,GAAG,aAAa;IACtF,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5E,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,oBAAoB,CAAC,CAAC;IACjE,IAAI,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,QAAQ;QAAE,MAAM,IAAI,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACzK,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC;QAClG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,WAAW,CAAC,2BAA2B,CAAC,CAAC;QAC7F,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACxC,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,sDAAsD,CAAC,CAAC;IAC3G,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,MAAM,IAAI,WAAW,CAAC,sBAAsB,CAAC,CAAC;IACjE,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;IAChC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC7G,CAAC;AAWD,kGAAkG;AAClG,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,IAA+B,EAAE,CAAe;IACnG,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,aAAa,CAAC;IACzC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,4CAA4C,CAAC,CAAC;IACrJ,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1B,IAAI,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,UAAU,OAAO,KAAK,yBAAyB,CAAC,CAAC;QACxF,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC;IAC5B,CAAC;IACD,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACnF,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QACjC,QAAQ,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,sBAAsB,CAAC,CAAC;QAC1H,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IACnE,IAAI,MAAM;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,+DAA+D,CAAC,CAAC;IAC3I,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IACnF,IAAI,OAAO;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,sCAAsC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,WAAW,CAAC,CAAC;IACzH,MAAM,OAAO,GAAqB,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC/B,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;IACH,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAqD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjF,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACrB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACzD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;gBAAE,QAAQ,EAAE,CAAC;YACxE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IACH,IAAI,QAAQ;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,SAAS,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,oDAAoD,CAAC,CAAC;IAC/H,MAAM,UAAU,GAAa,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC7C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9D,MAAM,GAAG,GAAW,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACtJ,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;aAC1G,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;YAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;aACtG,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAqB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;;YACxL,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5F,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,eAAe,CAAC;IACjI,MAAM,OAAO,GAAgB;QAC3B,aAAa,EAAE,CAAC;QAChB,QAAQ;QACR,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE;QAC9J,QAAQ,EAAE,OAAO,CAAC,MAAM;QACxB,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,OAAO;QACP,IAAI,EAAE,OAAO;KACd,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpD,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,QAAQ,CAAC,OAAoB,EAAE,IAAoC;IACjF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,MAAM,CAAC,GAAqD,EAAE,CAAC;QAC/D,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACf,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5F,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type GridModule } from '@aurum-grid/core';
2
+ export * from './pivot.js';
3
+ export * from './range.js';
4
+ export * from './excel.js';
5
+ export * from './advanced-filter.js';
6
+ export * from './sidebar.js';
7
+ export * from './extras.js';
8
+ export * from './import.js';
9
+ export * from './sync.js';
10
+ export declare const AllEnterpriseModules: GridModule[];
11
+ /**
12
+ * Opt in to every enterprise feature. Call once before creating grids:
13
+ * import { registerEnterprise } from '@aurum-grid/enterprise';
14
+ * import '@aurum-grid/enterprise/styles.css';
15
+ * registerEnterprise();
16
+ */
17
+ export declare function registerEnterprise(modules?: GridModule[]): void;
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
1
+ import { ModuleRegistry } from '@aurum-grid/core';
2
+ import { PivotModule } from './pivot.js';
3
+ import { RangeSelectionModule } from './range.js';
4
+ import { ExcelExportModule } from './excel.js';
5
+ import { AdvancedFilterModule } from './advanced-filter.js';
6
+ import { SideBarModule } from './sidebar.js';
7
+ import { ContextMenuModule, SavedViewsModule } from './extras.js';
8
+ export * from './pivot.js';
9
+ export * from './range.js';
10
+ export * from './excel.js';
11
+ export * from './advanced-filter.js';
12
+ export * from './sidebar.js';
13
+ export * from './extras.js';
14
+ export * from './import.js';
15
+ export * from './sync.js';
16
+ export const AllEnterpriseModules = [
17
+ RangeSelectionModule,
18
+ ExcelExportModule,
19
+ AdvancedFilterModule,
20
+ PivotModule,
21
+ SideBarModule,
22
+ ContextMenuModule,
23
+ SavedViewsModule,
24
+ ];
25
+ /**
26
+ * Opt in to every enterprise feature. Call once before creating grids:
27
+ * import { registerEnterprise } from '@aurum-grid/enterprise';
28
+ * import '@aurum-grid/enterprise/styles.css';
29
+ * registerEnterprise();
30
+ */
31
+ export function registerEnterprise(modules = AllEnterpriseModules) {
32
+ ModuleRegistry.register(...modules);
33
+ }
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAmB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAElE,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAE1B,MAAM,CAAC,MAAM,oBAAoB,GAAiB;IAChD,oBAAoB;IACpB,iBAAiB;IACjB,oBAAoB;IACpB,WAAW;IACX,aAAa;IACb,iBAAiB;IACjB,gBAAgB;CACjB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAwB,oBAAoB;IAC7E,cAAc,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { type AggFuncName, type ColDef, type GridModule } from '@aurum-grid/core';
2
+ export interface PivotValue {
3
+ colId: string;
4
+ aggFunc: AggFuncName;
5
+ headerName?: string;
6
+ }
7
+ export interface PivotConfig {
8
+ /** Row dimensions (fields/colIds) */
9
+ rows: string[];
10
+ /** Column dimension (pivot) fields */
11
+ columns: string[];
12
+ values: PivotValue[];
13
+ /** Add a grand-total column per value */
14
+ totals?: boolean;
15
+ }
16
+ export interface PivotResult {
17
+ columnDefs: ColDef[];
18
+ rowData: Array<Record<string, unknown>>;
19
+ pivotKeys: string[];
20
+ }
21
+ type Getter = (row: any, colId: string) => unknown;
22
+ /** Pure pivot computation (unit-tested). */
23
+ export declare function computePivot(rows: any[], config: PivotConfig, get?: Getter, headerOf?: (colId: string) => string): PivotResult;
24
+ declare module '@aurum-grid/core' {
25
+ interface Grid<T> {
26
+ setPivotMode(on: boolean, config?: PivotConfig): void;
27
+ isPivotMode(): boolean;
28
+ getPivotConfig(): PivotConfig | null;
29
+ setPivotConfig(config: PivotConfig): void;
30
+ }
31
+ }
32
+ export declare const PivotModule: GridModule;
33
+ export {};
package/dist/pivot.js ADDED
@@ -0,0 +1,126 @@
1
+ import { aggregate } from '@aurum-grid/core';
2
+ const SEP = ' | ';
3
+ /** Pure pivot computation (unit-tested). */
4
+ export function computePivot(rows, config, get = (r, k) => r?.[k], headerOf = (c) => c) {
5
+ const pivotKeySet = new Set();
6
+ const buckets = new Map();
7
+ for (const row of rows) {
8
+ const dims = config.rows.map((k) => get(row, k));
9
+ const rk = dims.map((d) => String(d ?? '(Blanks)')).join('\u0001');
10
+ const pk = config.columns.length ? config.columns.map((k) => String(get(row, k) ?? '(Blanks)')).join(SEP) : '';
11
+ pivotKeySet.add(pk);
12
+ let b = buckets.get(rk);
13
+ if (!b)
14
+ buckets.set(rk, (b = { dims, cells: new Map() }));
15
+ let vals = b.cells.get(pk);
16
+ if (!vals)
17
+ b.cells.set(pk, (vals = config.values.map(() => [])));
18
+ config.values.forEach((v, i) => vals[i].push(get(row, v.colId)));
19
+ }
20
+ const pivotKeys = [...pivotKeySet].sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
21
+ const fieldFor = (pk, v) => `pivot_${pk}_${v.colId}_${v.aggFunc}`.replace(/[^A-Za-z0-9_]/g, '_');
22
+ const columnDefs = config.rows.map((k) => ({ field: k, headerName: headerOf(k), pinned: 'left' }));
23
+ const multiValue = config.values.length > 1;
24
+ for (const pk of pivotKeys) {
25
+ for (const v of config.values) {
26
+ const label = v.headerName ?? `${v.aggFunc}(${headerOf(v.colId)})`;
27
+ columnDefs.push({
28
+ colId: fieldFor(pk, v),
29
+ field: fieldFor(pk, v),
30
+ headerName: config.columns.length ? (multiValue ? `${pk} · ${label}` : pk) : label,
31
+ type: 'numericColumn',
32
+ aggFunc: v.aggFunc === 'avg' ? 'avg' : v.aggFunc === 'count' ? 'sum' : v.aggFunc,
33
+ });
34
+ }
35
+ }
36
+ if (config.totals !== false && config.columns.length) {
37
+ for (const v of config.values) {
38
+ columnDefs.push({ colId: `total_${v.colId}_${v.aggFunc}`, field: `total_${v.colId}_${v.aggFunc}`, headerName: `Total ${v.aggFunc}(${headerOf(v.colId)})`, type: 'numericColumn', cellClass: 'agr-pivot-total', aggFunc: v.aggFunc === 'count' ? 'sum' : v.aggFunc === 'avg' ? 'avg' : v.aggFunc });
39
+ }
40
+ }
41
+ const rowData = [...buckets.values()].map((b) => {
42
+ const out = {};
43
+ config.rows.forEach((k, i) => (out[k] = b.dims[i]));
44
+ const totals = config.values.map(() => []);
45
+ for (const pk of pivotKeys) {
46
+ const vals = b.cells.get(pk);
47
+ config.values.forEach((v, i) => {
48
+ out[fieldFor(pk, v)] = vals ? aggregate(v.aggFunc, vals[i]) : null;
49
+ if (vals)
50
+ totals[i].push(...vals[i]);
51
+ });
52
+ }
53
+ if (config.totals !== false && config.columns.length) {
54
+ config.values.forEach((v, i) => (out[`total_${v.colId}_${v.aggFunc}`] = aggregate(v.aggFunc, totals[i])));
55
+ }
56
+ return out;
57
+ });
58
+ return { columnDefs, rowData, pivotKeys };
59
+ }
60
+ export const PivotModule = {
61
+ name: 'PivotModule',
62
+ install(grid) {
63
+ const st = { active: false, config: null, saved: null };
64
+ let meta = { headers: {}, fields: {} };
65
+ const apply = () => {
66
+ if (!st.config || !st.saved)
67
+ return;
68
+ const source = st.saved.rowData;
69
+ const getter = (row, colId) => row?.[meta.fields[colId] ?? colId];
70
+ const res = computePivot(source, st.config, getter, (id) => meta.headers[id] ?? id);
71
+ grid.setColumnDefs(res.columnDefs);
72
+ grid.setRowData(res.rowData);
73
+ grid.eRoot.classList.add('agr-pivot-mode');
74
+ };
75
+ const api = {
76
+ setPivotMode(on, config) {
77
+ if (config)
78
+ st.config = config;
79
+ if (on && !st.active) {
80
+ if (!st.config) {
81
+ const groups = grid.getRowGroupColumns().map((c) => c.colId);
82
+ const values = grid.getColumns().filter((c) => c.aggFunc && typeof c.aggFunc === 'string').map((c) => ({ colId: c.colId, aggFunc: c.aggFunc }));
83
+ const pivots = grid.getColumns().filter((c) => c.pivotActive).map((c) => c.colId);
84
+ st.config = { rows: groups, columns: pivots, values };
85
+ }
86
+ meta = { headers: {}, fields: {} };
87
+ for (const c of grid.getColumns()) {
88
+ meta.headers[c.colId] = c.headerName;
89
+ if (c.colDef.field)
90
+ meta.fields[c.colId] = c.colDef.field;
91
+ }
92
+ st.saved = { columnDefs: grid.getColumnDefs(), rowData: grid.getRowData(), columnState: grid.getColumnState() };
93
+ st.active = true;
94
+ apply();
95
+ }
96
+ else if (on && st.active) {
97
+ apply();
98
+ }
99
+ else if (!on && st.active) {
100
+ st.active = false;
101
+ grid.eRoot.classList.remove('agr-pivot-mode');
102
+ grid.setColumnDefs(st.saved.columnDefs);
103
+ grid.setRowData(st.saved.rowData);
104
+ grid.applyColumnState({ state: st.saved.columnState, applyOrder: true });
105
+ st.saved = null;
106
+ }
107
+ grid.moduleState.set('pivot', { active: st.active, config: st.config });
108
+ grid.dispatch('columnRowGroupChanged', { source: 'pivot' });
109
+ },
110
+ isPivotMode: () => st.active,
111
+ getPivotConfig: () => st.config,
112
+ setPivotConfig(config) {
113
+ st.config = config;
114
+ if (st.active)
115
+ apply();
116
+ grid.moduleState.set('pivot', { active: st.active, config: st.config });
117
+ },
118
+ };
119
+ Object.assign(grid, api);
120
+ return () => {
121
+ for (const k of Object.keys(api))
122
+ delete grid[k];
123
+ };
124
+ },
125
+ };
126
+ //# sourceMappingURL=pivot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pivot.js","sourceRoot":"","sources":["../src/pivot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { GridModule } from '@aurum-grid/core';
2
+ export interface CellRange {
3
+ startRow: number;
4
+ endRow: number;
5
+ /** colIds in displayed order, inclusive */
6
+ columns: string[];
7
+ }
8
+ declare module '@aurum-grid/core' {
9
+ interface Grid<T> {
10
+ getCellRanges(): CellRange[];
11
+ clearRangeSelection(): void;
12
+ addCellRange(params: {
13
+ rowStartIndex: number;
14
+ rowEndIndex: number;
15
+ columnStart: string;
16
+ columnEnd: string;
17
+ }): void;
18
+ getRangeAggregates(): RangeAggregates | null;
19
+ getRangeData(): {
20
+ headers: string[];
21
+ rows: unknown[][];
22
+ formatted: string[][];
23
+ } | null;
24
+ }
25
+ }
26
+ export interface RangeAggregates {
27
+ count: number;
28
+ numericCount: number;
29
+ sum: number;
30
+ avg: number | null;
31
+ min: number | null;
32
+ max: number | null;
33
+ }
34
+ /**
35
+ * Excel-like cell range selection: drag with the mouse, Shift+click to extend,
36
+ * Shift+arrow keys to extend from the focused cell, Ctrl+C copies the range.
37
+ * Status bar shows Sum / Average / Count / Min / Max for numeric cells.
38
+ */
39
+ export declare const RangeSelectionModule: GridModule;