@extable/core 0.3.3 → 0.3.5

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.
@@ -0,0 +1,988 @@
1
+ function R() {
2
+ return typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID() : `row_${Math.random().toString(16).slice(2)}`;
3
+ }
4
+ function q(s) {
5
+ if (s !== void 0)
6
+ return Array.isArray(s) ? s : [s];
7
+ }
8
+ function L(s) {
9
+ if (s)
10
+ try {
11
+ s.remove();
12
+ } catch {
13
+ }
14
+ }
15
+ const w = (s, t = 2) => s.toString().padStart(t, "0"), v = {
16
+ yyyy: (s) => w(s.getFullYear(), 4),
17
+ MM: (s) => w(s.getMonth() + 1),
18
+ dd: (s) => w(s.getDate()),
19
+ HH: (s) => w(s.getHours()),
20
+ hh: (s) => {
21
+ const t = s.getHours() % 12 || 12;
22
+ return w(t);
23
+ },
24
+ mm: (s) => w(s.getMinutes()),
25
+ ss: (s) => w(s.getSeconds()),
26
+ a: (s) => s.getHours() >= 12 ? "PM" : "AM"
27
+ }, M = Object.keys(v).sort((s, t) => t.length - s.length), T = /* @__PURE__ */ new Set(["yyyy", "MM", "dd"]), F = /* @__PURE__ */ new Set(["HH", "hh", "mm", "ss", "a"]), A = /* @__PURE__ */ new Set([...T, ...F]), S = {
28
+ iso: "yyyy-MM-dd",
29
+ us: "MM/dd/yyyy",
30
+ eu: "dd.MM.yyyy"
31
+ }, C = {
32
+ iso: "HH:mm:ss",
33
+ "24h": "HH:mm",
34
+ "12h": "hh:mm a"
35
+ }, b = {
36
+ iso: "yyyy-MM-dd'T'HH:mm:ss'Z'",
37
+ "iso-24h": "yyyy-MM-dd'T'HH:mm:ss'Z'",
38
+ "iso-12h": "yyyy-MM-dd hh:mm a",
39
+ us: "MM/dd/yyyy HH:mm",
40
+ "us-24h": "MM/dd/yyyy HH:mm",
41
+ "us-12h": "MM/dd/yyyy hh:mm a",
42
+ eu: "dd.MM.yyyy HH:mm",
43
+ "eu-24h": "dd.MM.yyyy HH:mm",
44
+ "eu-12h": "dd.MM.yyyy hh:mm a"
45
+ };
46
+ function N(s) {
47
+ const t = new Date(s);
48
+ return Number.isNaN(t.getTime()) ? null : t;
49
+ }
50
+ function U(s, t) {
51
+ let e = "", n = 0, i = !1;
52
+ for (; n < t.length; ) {
53
+ const r = t[n];
54
+ if (r === "'") {
55
+ i = !i, n += 1;
56
+ continue;
57
+ }
58
+ if (i) {
59
+ e += r, n += 1;
60
+ continue;
61
+ }
62
+ let o = !1;
63
+ for (const l of M)
64
+ if (t.startsWith(l, n)) {
65
+ e += v[l](s), n += l.length, o = !0;
66
+ break;
67
+ }
68
+ o || (e += r, n += 1);
69
+ }
70
+ return e;
71
+ }
72
+ function B(s, t) {
73
+ return t === "date" ? T.has(s) : t === "time" ? F.has(s) : A.has(s);
74
+ }
75
+ function H(s, t) {
76
+ let e = 0, n = !1;
77
+ for (; e < s.length; ) {
78
+ if (s[e] === "'") {
79
+ n = !n, e += 1;
80
+ continue;
81
+ }
82
+ if (n) {
83
+ e += 1;
84
+ continue;
85
+ }
86
+ let r = !1;
87
+ for (const o of M)
88
+ if (s.startsWith(o, e)) {
89
+ if (!B(o, t)) return !1;
90
+ e += o.length, r = !0;
91
+ break;
92
+ }
93
+ r || (e += 1);
94
+ }
95
+ return !0;
96
+ }
97
+ function k(s, t) {
98
+ if (!s)
99
+ return t === "date" ? S.iso : t === "time" ? C.iso : b.iso;
100
+ if (t === "date" && S[s]) return S[s];
101
+ if (t === "time" && C[s]) return C[s];
102
+ if (t === "datetime" && b[s]) return b[s];
103
+ const e = t === "date" ? S.iso : t === "time" ? C.iso : b.iso;
104
+ return H(s, t) ? s : e;
105
+ }
106
+ const V = (s) => !Number.isNaN(s.getTime()), j = (s) => {
107
+ if (typeof s == "string") return s;
108
+ if (s && typeof s == "object") {
109
+ const t = s;
110
+ if (t.kind === "enum")
111
+ return typeof t.value == "string" ? t.value : null;
112
+ }
113
+ return null;
114
+ }, O = (s) => {
115
+ if (Array.isArray(s) && s.every((t) => typeof t == "string")) return s;
116
+ if (s && typeof s == "object") {
117
+ const t = s;
118
+ if (t.kind === "tags") {
119
+ const e = t.values;
120
+ return Array.isArray(e) && e.every((n) => typeof n == "string") ? e : null;
121
+ }
122
+ }
123
+ return null;
124
+ };
125
+ function I(s, t) {
126
+ if (s == null) return null;
127
+ switch (t.type) {
128
+ case "string": {
129
+ if (typeof s != "string") return "Expected a string";
130
+ const e = t.format;
131
+ if (e?.maxLength !== void 0 && s.length > e.maxLength)
132
+ return `Too long (max ${e.maxLength})`;
133
+ if (e?.regex)
134
+ try {
135
+ if (!new RegExp(e.regex).test(s)) return "Does not match pattern";
136
+ } catch {
137
+ }
138
+ return null;
139
+ }
140
+ case "number":
141
+ return typeof s != "number" || !Number.isFinite(s) ? "Expected a number" : t.format?.signed === !1 && s < 0 ? "Expected a non-negative number" : null;
142
+ case "int":
143
+ return typeof s != "number" || !Number.isSafeInteger(s) ? "Expected an integer" : null;
144
+ case "uint":
145
+ return typeof s != "number" || !Number.isSafeInteger(s) || s < 0 ? "Expected a non-negative integer" : null;
146
+ case "boolean":
147
+ return typeof s != "boolean" ? "Expected a boolean" : null;
148
+ case "enum": {
149
+ const e = j(s);
150
+ if (!e) return "Expected an enum value";
151
+ const n = t.enum?.allowCustom ?? !1, i = t.enum?.options ?? [];
152
+ return !n && i.length && !i.includes(e) ? "Not in allowed options" : null;
153
+ }
154
+ case "tags": {
155
+ const e = O(s);
156
+ if (!e) return "Expected a list of tags";
157
+ const n = t.tags?.allowCustom ?? !1, i = t.tags?.options ?? [];
158
+ if (!n && i.length) {
159
+ for (const r of e)
160
+ if (!i.includes(r)) return "Contains an unknown tag";
161
+ }
162
+ return null;
163
+ }
164
+ case "date":
165
+ case "time":
166
+ case "datetime": {
167
+ const e = t.format;
168
+ if (t.type === "date" ? k(e, "date") : t.type === "time" ? k(e, "time") : k(e, "datetime"), s instanceof Date) return V(s) ? null : "Invalid date";
169
+ if (typeof s == "string") {
170
+ const n = N(s);
171
+ return n && V(n) ? null : "Invalid date/time";
172
+ }
173
+ return "Expected a date/time string";
174
+ }
175
+ default:
176
+ return null;
177
+ }
178
+ }
179
+ class W {
180
+ constructor(t, e, n) {
181
+ this.rows = [], this.baseIndexById = /* @__PURE__ */ new Map(), this.dataVersion = 0, this.visibleRowsCache = null, this.distinctValueCache = /* @__PURE__ */ new Map(), this.pending = /* @__PURE__ */ new Map(), this.rowVersion = /* @__PURE__ */ new Map(), this.listeners = /* @__PURE__ */ new Set(), this.cellStyles = /* @__PURE__ */ new Map(), this.cellConditionalStyles = /* @__PURE__ */ new Map(), this.computedCache = /* @__PURE__ */ new Map(), this.conditionalCache = /* @__PURE__ */ new Map(), this.rowConditionalCache = /* @__PURE__ */ new Map(), this.formulaDiagnostics = /* @__PURE__ */ new Map(), this.conditionalDiagnostics = /* @__PURE__ */ new Map(), this.baseValidationErrors = /* @__PURE__ */ new Map(), this.uniqueValidationErrors = /* @__PURE__ */ new Map(), this.notifySuspended = !1, this.notifyDirty = !1, this.schema = e, this.view = n, this.setData(t ?? []);
182
+ }
183
+ subscribe(t) {
184
+ return this.listeners.add(t), () => this.listeners.delete(t);
185
+ }
186
+ notify() {
187
+ if (this.visibleRowsCache = null, this.distinctValueCache.clear(), this.notifySuspended) {
188
+ this.notifyDirty = !0;
189
+ return;
190
+ }
191
+ for (const t of this.listeners) t();
192
+ }
193
+ batchUpdate(t) {
194
+ this.notifySuspended = !0;
195
+ try {
196
+ t();
197
+ } finally {
198
+ this.notifySuspended = !1, this.notifyDirty && (this.notifyDirty = !1, this.notify());
199
+ }
200
+ }
201
+ setData(t) {
202
+ this.dataVersion += 1, this.pending.clear(), this.cellStyles.clear(), this.cellConditionalStyles.clear(), this.computedCache.clear(), this.conditionalCache.clear(), this.rowConditionalCache.clear(), this.formulaDiagnostics.clear(), this.conditionalDiagnostics.clear(), this.baseValidationErrors.clear(), this.uniqueValidationErrors.clear(), this.rows = (t ?? []).map((e, n) => {
203
+ const i = R();
204
+ return this.rowVersion.set(i, 0), {
205
+ id: i,
206
+ raw: e,
207
+ displayIndex: n + 1
208
+ };
209
+ }), this.rebuildBaseIndex(), this.recomputeValidationErrors(), this.notify();
210
+ }
211
+ setSchema(t) {
212
+ this.dataVersion += 1, this.schema = t, this.computedCache.clear(), this.conditionalCache.clear(), this.rowConditionalCache.clear(), this.formulaDiagnostics.clear(), this.conditionalDiagnostics.clear(), this.recomputeValidationErrors(), this.notify();
213
+ }
214
+ setView(t) {
215
+ this.dataVersion += 1, Array.isArray(t.sorts) && t.sorts.length > 1 ? this.view = { ...t, sorts: t.sorts.slice(0, 1) } : this.view = t, this.notify();
216
+ }
217
+ getSchema() {
218
+ return { ...this.schema, columns: this.getColumns() };
219
+ }
220
+ getColumns() {
221
+ return this.schema.columns;
222
+ }
223
+ getRowConditionalStyleFn() {
224
+ return this.schema.row?.conditionalStyle ?? null;
225
+ }
226
+ getView() {
227
+ return this.view;
228
+ }
229
+ getDataVersion() {
230
+ return this.dataVersion;
231
+ }
232
+ getFullSchema() {
233
+ return this.schema;
234
+ }
235
+ listRows() {
236
+ return this.computeVisibleRows().rows;
237
+ }
238
+ listAllRows() {
239
+ return this.rows;
240
+ }
241
+ getAllRowCount() {
242
+ return this.rows.length;
243
+ }
244
+ findRow(t) {
245
+ const e = this.baseIndexById.get(t);
246
+ if (e === void 0) return null;
247
+ const n = this.rows[e];
248
+ if (n && n.id === t) return { row: n, index: e };
249
+ const i = this.rows.findIndex((o) => o.id === t);
250
+ if (i < 0) return null;
251
+ const r = this.rows[i];
252
+ return r ? (this.rebuildBaseIndex(), { row: r, index: i }) : null;
253
+ }
254
+ getRowHeight(t) {
255
+ return this.view.rowHeights?.[t];
256
+ }
257
+ setRowHeight(t, e) {
258
+ this.view.rowHeights || (this.view.rowHeights = {}), this.view.rowHeights[t] !== e && (this.view.rowHeights[t] = e, this.notify());
259
+ }
260
+ setRowHeightsBulk(t) {
261
+ const e = Object.entries(t);
262
+ if (e.length === 0) return;
263
+ this.view.rowHeights || (this.view.rowHeights = {});
264
+ let n = !1;
265
+ for (const [i, r] of e)
266
+ this.view.rowHeights[i] !== r && (this.view.rowHeights[i] = r, n = !0);
267
+ n && this.notify();
268
+ }
269
+ getCell(t, e) {
270
+ const n = this.findRow(t);
271
+ if (!n) return;
272
+ const i = n.row, r = this.pending.get(t);
273
+ return r && e in r ? r[e] : i.raw[e];
274
+ }
275
+ getRawCell(t, e) {
276
+ const n = this.findRow(t);
277
+ return n ? n.row.raw[e] : void 0;
278
+ }
279
+ isRowReadonly(t) {
280
+ const e = this.findRow(t);
281
+ return e ? !!e.row.raw._readonly : !1;
282
+ }
283
+ isActionType(t) {
284
+ return t === "button" || t === "link";
285
+ }
286
+ supportsConditionalReadonly(t) {
287
+ return t === "boolean" || t === "number" || t === "date" || t === "time" || t === "datetime" || t === "string" || t === "enum" || t === "tags";
288
+ }
289
+ isColumnReadonly(t) {
290
+ const e = this.schema.columns.find((n) => n.key === t);
291
+ return this.isActionType(e?.type) ? !0 : !!(e?.readonly || e?.formula);
292
+ }
293
+ getCellInteraction(t, e) {
294
+ const n = this.schema.columns.find((u) => String(u.key) === String(e));
295
+ if (!n) return { readonly: !1, disabled: !1, muted: !1 };
296
+ const i = this.isRowReadonly(t) || this.isColumnReadonly(e), r = this.resolveConditionalStyle(t, n).delta, o = this.getCellStyle(t, e), a = this.supportsConditionalReadonly(n.type) && !!(n.style?.readonly || r?.readonly || o?.readonly), c = this.isActionType(n.type), f = c && !!(n.style?.disabled || r?.disabled || o?.disabled), d = i || a || f, g = !!n.formula;
297
+ return { readonly: d, disabled: f, muted: f || d && !c && !g };
298
+ }
299
+ isReadonly(t, e) {
300
+ return this.getCellInteraction(t, e).readonly;
301
+ }
302
+ setCell(t, e, n, i) {
303
+ this.dataVersion += 1;
304
+ const r = this.findRow(t);
305
+ if (!r) return;
306
+ const o = r.row, l = () => {
307
+ const c = this.rowVersion.get(t) ?? 0;
308
+ this.rowVersion.set(t, c + 1);
309
+ };
310
+ if (i)
311
+ o.raw[e] = n, this.pending.delete(t), l();
312
+ else {
313
+ const c = this.getRawCell(t, e), f = this.pending.get(t) ?? {};
314
+ this.isEqual(c, n) ? delete f[e] : f[e] = n, Object.keys(f).length > 0 ? this.pending.set(t, f) : this.pending.delete(t), l();
315
+ }
316
+ this.updateValidationForCell(t, e, this.getCell(t, e)), this.schema.columns.find((c) => c.key === e)?.unique && this.recomputeUniqueValidationForColumn(e), this.clearDiagnosticsForCell(t, e), this.notify();
317
+ }
318
+ applyPending(t) {
319
+ this.dataVersion += 1;
320
+ const e = this.pending.get(t);
321
+ if (!e) return;
322
+ const n = this.findRow(t);
323
+ if (!n) return;
324
+ const i = n.row, r = /* @__PURE__ */ new Set();
325
+ for (const [o, l] of Object.entries(e)) {
326
+ i.raw[o] = l, this.updateValidationForCell(t, o, l);
327
+ const a = this.schema.columns.find((c) => String(c.key) === String(o));
328
+ a?.unique && r.add(a.key), this.clearDiagnosticsForCell(t, o);
329
+ }
330
+ this.pending.delete(t);
331
+ for (const o of r) this.recomputeUniqueValidationForColumn(o);
332
+ this.notify();
333
+ }
334
+ clearPending(t) {
335
+ this.dataVersion += 1, this.pending.delete(t), this.notify();
336
+ }
337
+ getPending() {
338
+ return this.pending;
339
+ }
340
+ hasPending(t, e) {
341
+ const n = this.pending.get(t);
342
+ return n ? e in n : !1;
343
+ }
344
+ insertRow(t) {
345
+ return this.insertRowAt(t, this.rows.length);
346
+ }
347
+ insertRowAt(t, e, n) {
348
+ this.dataVersion += 1;
349
+ const i = n ?? R(), r = Math.max(0, Math.min(e, this.rows.length));
350
+ return this.rows.splice(r, 0, { id: i, raw: t, displayIndex: 0 }), this.reindexRows(), this.rowVersion.set(i, 0), this.rebuildBaseIndex(), this.recomputeValidationErrors(), this.notify(), i;
351
+ }
352
+ removeRow(t) {
353
+ this.dataVersion += 1;
354
+ const e = this.findRow(t);
355
+ if (!e) return null;
356
+ const n = this.rows.splice(e.index, 1)[0];
357
+ return n ? (this.pending.delete(t), this.rowVersion.delete(t), this.reindexRows(), this.rebuildBaseIndex(), this.recomputeValidationErrors(), this.notify(), { row: n, index: e.index }) : null;
358
+ }
359
+ getDisplayIndex(t) {
360
+ return this.findRow(t)?.row.displayIndex ?? null;
361
+ }
362
+ getRowIndex(t) {
363
+ return this.computeVisibleRows().indexById.get(t) ?? -1;
364
+ }
365
+ getBaseRowIndex(t) {
366
+ return this.baseIndexById.get(t) ?? -1;
367
+ }
368
+ getColumnIndex(t) {
369
+ return this.getColumns().findIndex((e) => e.key === t);
370
+ }
371
+ getColumnByIndex(t) {
372
+ return this.getColumns()[t] ?? null;
373
+ }
374
+ getRowByIndex(t) {
375
+ return this.listRows()[t] ?? null;
376
+ }
377
+ rebuildBaseIndex() {
378
+ this.baseIndexById.clear();
379
+ for (let t = 0; t < this.rows.length; t += 1) {
380
+ const e = this.rows[t];
381
+ e && this.baseIndexById.set(e.id, t);
382
+ }
383
+ }
384
+ getFilterSortKey(t) {
385
+ const e = t?.excludeColumnKey, n = t?.includeSort ?? !0, i = this.view, r = (i.filters ?? []).filter((a) => {
386
+ if (e === void 0) return !0;
387
+ const c = a?.key;
388
+ return String(c) !== String(e);
389
+ }).map((a) => {
390
+ if (a?.kind === "values") {
391
+ const d = a;
392
+ return {
393
+ kind: "values",
394
+ key: String(d.key),
395
+ includeBlanks: !!d.includeBlanks,
396
+ values: (d.values ?? []).map((g) => this.stableValueKey(g))
397
+ };
398
+ }
399
+ const f = a;
400
+ return {
401
+ kind: "op",
402
+ key: String(f.key),
403
+ op: String(f.op ?? ""),
404
+ value: this.stableValueKey(f.value)
405
+ };
406
+ }).sort((a, c) => a.key === c.key ? a.kind < c.kind ? -1 : 1 : a.key < c.key ? -1 : 1), o = Object.entries(i.columnDiagnostics ?? {}).filter(([a]) => e !== void 0 ? String(a) !== String(e) : !0).map(([a, c]) => ({
407
+ key: String(a),
408
+ errors: !!c?.errors,
409
+ warnings: !!c?.warnings
410
+ })).filter((a) => a.errors || a.warnings).sort((a, c) => a.key < c.key ? -1 : a.key > c.key ? 1 : 0), l = n ? (i.sorts ?? []).slice(0, 1).map((a) => ({ key: String(a.key), dir: a.dir })) : [];
411
+ return JSON.stringify({ filters: r, columnDiagnosticsEntries: o, sorts: l });
412
+ }
413
+ stableValueKey(t) {
414
+ if (t === null) return "null";
415
+ if (t === void 0) return "undefined";
416
+ if (t instanceof Date) return `date:${t.getTime()}`;
417
+ if (typeof t == "string") return `s:${t}`;
418
+ if (typeof t == "number") return `n:${Number.isNaN(t) ? "NaN" : String(t)}`;
419
+ if (typeof t == "boolean") return `b:${t ? "1" : "0"}`;
420
+ if (typeof t == "object") {
421
+ const e = t, n = e.kind;
422
+ if (n === "enum" && typeof e.value == "string") return `enum:${e.value}`;
423
+ if (n === "tags" && Array.isArray(e.values))
424
+ return `tags:${e.values.filter((i) => typeof i == "string").join("|")}`;
425
+ }
426
+ try {
427
+ return `json:${JSON.stringify(t)}`;
428
+ } catch {
429
+ return `str:${String(t)}`;
430
+ }
431
+ }
432
+ isBlankValue(t) {
433
+ return t == null || t === "";
434
+ }
435
+ resolveFilterColumnKey(t) {
436
+ return this.getColumns().find((i) => String(i.key) === String(t))?.key ?? t;
437
+ }
438
+ getFilterCellValue(t, e) {
439
+ const n = this.getColumns().find((i) => String(i.key) === String(e));
440
+ return n ? this.resolveCellValue(t, n).value : this.getCell(t, e);
441
+ }
442
+ valuesFilterMatches(t, e) {
443
+ const n = this.resolveFilterColumnKey(e.key), i = this.getFilterCellValue(t, n);
444
+ if (this.isBlankValue(i)) return !!e.includeBlanks;
445
+ if (!e.values || e.values.length === 0) return !1;
446
+ const r = this.stableValueKey(i);
447
+ for (const o of e.values)
448
+ if (this.stableValueKey(o) === r) return !0;
449
+ return !1;
450
+ }
451
+ rowPassesColumnDiagnostics(t, e, n) {
452
+ const i = !!n.errors, r = !!n.warnings;
453
+ if (!i && !r) return !0;
454
+ const o = this.resolveFilterColumnKey(e), l = this.getColumns().find((c) => String(c.key) === String(o));
455
+ l && (this.resolveCellValue(t, l), this.resolveConditionalStyle(t, l));
456
+ const a = this.getCellMarker(t, o);
457
+ return a ? a.level === "error" ? i : r : !1;
458
+ }
459
+ computeRowsAfterFilter(t) {
460
+ const e = t?.excludeColumnKey, n = t?.includeSort ?? !0, i = this.view, r = this.getSchema(), o = (i.filters ?? []).filter((u) => {
461
+ if (e === void 0) return !0;
462
+ const h = u?.key;
463
+ return String(h) !== String(e);
464
+ }), l = Object.entries(i.columnDiagnostics ?? {}).filter(
465
+ ([u]) => e !== void 0 ? String(u) !== String(e) : !0
466
+ ), a = [];
467
+ for (const u of this.rows) {
468
+ let h = !0;
469
+ for (const m of o)
470
+ if (m?.kind === "values" && !this.valuesFilterMatches(u.id, m)) {
471
+ h = !1;
472
+ break;
473
+ }
474
+ if (h) {
475
+ for (const [m, p] of l)
476
+ if (!this.rowPassesColumnDiagnostics(u.id, m, p)) {
477
+ h = !1;
478
+ break;
479
+ }
480
+ h && a.push(u);
481
+ }
482
+ }
483
+ if (!n) return a;
484
+ const c = (i.sorts ?? []).slice(0, 1)[0];
485
+ if (!c) return a;
486
+ const f = r.columns.find((u) => String(u.key) === String(c.key));
487
+ if (!f) return a;
488
+ const d = c.dir === "desc" ? -1 : 1, g = a.map((u) => {
489
+ const h = this.getFilterCellValue(u.id, f.key), m = this.isBlankValue(h), p = this.baseIndexById.get(u.id) ?? 0;
490
+ return { row: u, v: h, blank: m, baseIndex: p };
491
+ }), y = (u, h) => {
492
+ if (u === h) return 0;
493
+ if (u instanceof Date && h instanceof Date) return u.getTime() - h.getTime();
494
+ if (typeof u == "number" && typeof h == "number") return u - h;
495
+ if (typeof u == "boolean" && typeof h == "boolean") return u === h ? 0 : u ? 1 : -1;
496
+ const m = u instanceof Date ? u.toISOString() : typeof u == "string" ? u : String(u), p = h instanceof Date ? h.toISOString() : typeof h == "string" ? h : String(h);
497
+ return m === p ? 0 : m < p ? -1 : 1;
498
+ };
499
+ return g.sort((u, h) => {
500
+ if (u.blank && h.blank) return u.baseIndex - h.baseIndex;
501
+ if (u.blank) return 1;
502
+ if (h.blank) return -1;
503
+ const m = y(u.v, h.v);
504
+ return m !== 0 ? m * d : u.baseIndex - h.baseIndex;
505
+ }), g.map((u) => u.row);
506
+ }
507
+ computeVisibleRows() {
508
+ const t = this.getFilterSortKey(), e = this.visibleRowsCache;
509
+ if (e && e.version === this.dataVersion && e.key === t) return e;
510
+ const i = this.computeRowsAfterFilter({ includeSort: !0 }), r = /* @__PURE__ */ new Map();
511
+ for (let l = 0; l < i.length; l += 1) {
512
+ const a = i[l];
513
+ a && r.set(a.id, l);
514
+ }
515
+ const o = { version: this.dataVersion, key: t, rows: i, indexById: r };
516
+ return this.visibleRowsCache = o, o;
517
+ }
518
+ getDistinctValuesForColumn(t) {
519
+ const e = `${String(t)}|${this.getFilterSortKey({ excludeColumnKey: t, includeSort: !1 })}`, n = this.distinctValueCache.get(e);
520
+ if (n && n.version === this.dataVersion) return n;
521
+ const i = this.computeRowsAfterFilter({ excludeColumnKey: t, includeSort: !1 }), r = this.getSchema().columns.find((f) => String(f.key) === String(t));
522
+ if (!r) {
523
+ const f = { version: this.dataVersion, values: [], hasBlanks: !1, total: 0 };
524
+ return this.distinctValueCache.set(e, f), f;
525
+ }
526
+ const o = /* @__PURE__ */ new Map();
527
+ let l = !1;
528
+ for (const f of i) {
529
+ const d = this.getFilterCellValue(f.id, r.key);
530
+ if (this.isBlankValue(d)) {
531
+ l = !0;
532
+ continue;
533
+ }
534
+ const g = this.stableValueKey(d);
535
+ if (o.has(g)) continue;
536
+ const y = (() => {
537
+ if (d instanceof Date) return d.toISOString();
538
+ if (typeof d == "string") return d;
539
+ if (typeof d == "number" || typeof d == "boolean") return String(d);
540
+ if (typeof d == "object" && d) {
541
+ const u = d, h = u.kind;
542
+ if (h === "enum" && typeof u.value == "string") return u.value;
543
+ if (h === "tags" && Array.isArray(u.values))
544
+ return u.values.filter((m) => typeof m == "string").join(", ");
545
+ }
546
+ return String(d);
547
+ })();
548
+ o.set(g, { value: d, label: y });
549
+ }
550
+ const a = [...o.values()].sort(
551
+ (f, d) => f.label < d.label ? -1 : f.label > d.label ? 1 : 0
552
+ ), c = {
553
+ version: this.dataVersion,
554
+ values: a,
555
+ hasBlanks: l,
556
+ total: a.length + (l ? 1 : 0)
557
+ };
558
+ return this.distinctValueCache.set(e, c), c;
559
+ }
560
+ cellStyleKey(t, e) {
561
+ return `${t}::${String(e)}`;
562
+ }
563
+ clearDiagnosticsForCell(t, e) {
564
+ const n = this.cellStyleKey(t, e);
565
+ this.formulaDiagnostics.delete(n), this.conditionalDiagnostics.delete(n);
566
+ }
567
+ getCellDiagnostic(t, e) {
568
+ const n = this.cellStyleKey(t, e), i = this.formulaDiagnostics.get(n) ?? null, r = this.conditionalDiagnostics.get(n) ?? null;
569
+ return i ? !r || i.level === "error" ? i : r.level === "error" ? r : i : r;
570
+ }
571
+ getDiagnostics() {
572
+ const t = /* @__PURE__ */ new Set();
573
+ for (const e of this.formulaDiagnostics.keys()) t.add(e);
574
+ for (const e of this.conditionalDiagnostics.keys()) t.add(e);
575
+ return [...t].map((e) => {
576
+ const n = e.indexOf("::"), i = n >= 0 ? e.slice(0, n) : e, r = n >= 0 ? e.slice(n + 2) : "";
577
+ return { rowId: i, colKey: r, diag: this.getCellDiagnostic(i, r) };
578
+ });
579
+ }
580
+ getRowObjectEffective(t) {
581
+ const e = this.findRow(t);
582
+ if (!e) return null;
583
+ const n = e.row, i = this.pending.get(t);
584
+ if (!i || Object.keys(i).length === 0)
585
+ return n.raw;
586
+ const r = { ...n.raw };
587
+ for (const [o, l] of Object.entries(i))
588
+ r[o] = l;
589
+ return r;
590
+ }
591
+ resolveCellValue(t, e) {
592
+ if (!e.formula)
593
+ return { value: this.getCell(t, e.key), diagnostic: null };
594
+ const n = this.getRowVersion(t), i = this.cellStyleKey(t, e.key), r = this.computedCache.get(i);
595
+ if (r && r.version === n && r.formulaRef === e.formula)
596
+ return r.diagnostic && this.formulaDiagnostics.set(i, r.diagnostic), {
597
+ value: r.value,
598
+ textOverride: r.textOverride,
599
+ diagnostic: r.diagnostic
600
+ };
601
+ const o = this.getRowObjectEffective(t);
602
+ if (!o) {
603
+ const l = this.getCell(t, e.key), a = {
604
+ version: n,
605
+ formulaRef: e.formula,
606
+ value: l,
607
+ diagnostic: null
608
+ };
609
+ return this.computedCache.set(i, a), { value: l, diagnostic: null };
610
+ }
611
+ try {
612
+ const l = e.formula(o);
613
+ if (Array.isArray(l) && l.length >= 2 && l[1] instanceof Error) {
614
+ const c = {
615
+ level: "warning",
616
+ message: l[1].message,
617
+ source: "formula"
618
+ }, f = l[0];
619
+ return this.computedCache.set(i, { version: n, formulaRef: e.formula, value: f, diagnostic: c }), this.formulaDiagnostics.set(i, c), { value: f, diagnostic: c };
620
+ }
621
+ const a = l;
622
+ return this.computedCache.set(i, { version: n, formulaRef: e.formula, value: a, diagnostic: null }), this.formulaDiagnostics.delete(i), { value: a, diagnostic: null };
623
+ } catch (l) {
624
+ const c = { level: "error", message: l instanceof Error ? l.message : String(l), source: "formula" };
625
+ return this.computedCache.set(i, {
626
+ version: n,
627
+ formulaRef: e.formula,
628
+ value: null,
629
+ textOverride: "#ERROR",
630
+ diagnostic: c
631
+ }), this.formulaDiagnostics.set(i, c), { value: null, textOverride: "#ERROR", diagnostic: c };
632
+ }
633
+ }
634
+ setCellConditionalStyle(t, e, n) {
635
+ const i = this.cellStyleKey(t, e);
636
+ n ? this.cellConditionalStyles.set(i, n) : this.cellConditionalStyles.delete(i), this.conditionalCache.delete(i), this.clearDiagnosticsForCell(t, e), this.notify();
637
+ }
638
+ evalConditionalStyleFn(t, e) {
639
+ try {
640
+ const n = t(e);
641
+ return n instanceof Error ? {
642
+ delta: null,
643
+ diagnostic: { level: "warning", message: n.message, source: "conditionalStyle" },
644
+ forceErrorText: !1
645
+ } : { delta: n ?? null, diagnostic: null, forceErrorText: !1 };
646
+ } catch (n) {
647
+ return {
648
+ delta: null,
649
+ diagnostic: { level: "error", message: n instanceof Error ? n.message : String(n), source: "conditionalStyle" },
650
+ forceErrorText: !0
651
+ };
652
+ }
653
+ }
654
+ resolveRowConditionalStyle(t) {
655
+ const e = this.getRowConditionalStyleFn();
656
+ if (!e) return { delta: null, diagnostic: null, forceErrorText: !1 };
657
+ const n = this.getRowVersion(t), i = this.rowConditionalCache.get(t);
658
+ if (i && i.version === n && i.fnRef === e)
659
+ return {
660
+ delta: i.delta,
661
+ diagnostic: i.diagnostic,
662
+ forceErrorText: i.forceErrorText
663
+ };
664
+ const r = this.getRowObjectEffective(t);
665
+ if (!r) {
666
+ const l = { version: n, fnRef: e, delta: null, diagnostic: null, forceErrorText: !1 };
667
+ return this.rowConditionalCache.set(t, l), { delta: null, diagnostic: null, forceErrorText: !1 };
668
+ }
669
+ const o = this.evalConditionalStyleFn(e, r);
670
+ return this.rowConditionalCache.set(t, { version: n, fnRef: e, ...o }), o;
671
+ }
672
+ resolveConditionalStyle(t, e) {
673
+ const n = this.getRowVersion(t), i = this.cellStyleKey(t, e.key), r = this.getRowObjectEffective(t), o = this.resolveRowConditionalStyle(t), l = (g, y) => y ? g ? { ...g, ...y } : { ...y } : g;
674
+ let a = null, c = null, f = !1;
675
+ if (a = l(a, o.delta), o.diagnostic && (c = o.diagnostic), f = f || o.forceErrorText, e.conditionalStyle && r) {
676
+ const g = `${t}::${String(e.key)}::col`, y = this.conditionalCache.get(g);
677
+ if (y && y.version === n && y.fnRef === e.conditionalStyle)
678
+ a = l(a, y.delta), y.diagnostic && (c === null || c.level !== "error") && (c = y.diagnostic), f = f || y.forceErrorText;
679
+ else {
680
+ const u = this.evalConditionalStyleFn(e.conditionalStyle, r);
681
+ this.conditionalCache.set(g, { version: n, fnRef: e.conditionalStyle, ...u }), a = l(a, u.delta), u.diagnostic && (c === null || c.level !== "error") && (c = u.diagnostic), f = f || u.forceErrorText;
682
+ }
683
+ }
684
+ const d = this.cellConditionalStyles.get(i);
685
+ if (d && r) {
686
+ const g = this.conditionalCache.get(i);
687
+ if (g && g.version === n && g.fnRef === d)
688
+ a = l(a, g.delta), g.diagnostic && (c === null || c.level !== "error") && (c = g.diagnostic), f = f || g.forceErrorText;
689
+ else {
690
+ const y = this.evalConditionalStyleFn(d, r);
691
+ this.conditionalCache.set(i, { version: n, fnRef: d, ...y }), a = l(a, y.delta), y.diagnostic && (c === null || c.level !== "error") && (c = y.diagnostic), f = f || y.forceErrorText;
692
+ }
693
+ }
694
+ return c ? this.conditionalDiagnostics.set(i, c) : this.conditionalDiagnostics.delete(i), { delta: a, diagnostic: c, forceErrorText: f };
695
+ }
696
+ getValidationErrors() {
697
+ const t = /* @__PURE__ */ new Map();
698
+ for (const [n, i] of this.baseValidationErrors.entries()) t.set(n, { ...i });
699
+ for (const [n, i] of this.uniqueValidationErrors.entries()) {
700
+ const r = t.get(n);
701
+ r ? t.set(n, { ...r, message: `${r.message}
702
+ ${i.message}` }) : t.set(n, { ...i });
703
+ }
704
+ const e = [...t.values()];
705
+ return e.sort((n, i) => {
706
+ const r = this.getRowIndex(n.rowId), o = this.getRowIndex(i.rowId);
707
+ if (r !== o) return r - o;
708
+ const l = this.getColumnIndex(n.colKey), a = this.getColumnIndex(i.colKey);
709
+ return l - a;
710
+ }), e;
711
+ }
712
+ getCellValidationMessage(t, e) {
713
+ const n = this.cellStyleKey(t, e), i = this.baseValidationErrors.get(n)?.message ?? null, r = this.uniqueValidationErrors.get(n)?.message ?? null;
714
+ return i ? r ? `${i}
715
+ ${r}` : i : r;
716
+ }
717
+ getCellMarker(t, e) {
718
+ const n = this.getCellDiagnostic(t, e), i = this.getCellValidationMessage(t, e);
719
+ if (!n && !i) return null;
720
+ const r = i ? "error" : n?.level ?? "warning", o = [n?.message ?? null, i].filter(Boolean).join(`
721
+ `);
722
+ return { level: r, message: o };
723
+ }
724
+ updateValidationForCell(t, e, n) {
725
+ const i = this.schema.columns.find((l) => String(l.key) === String(e));
726
+ if (!i) return;
727
+ const r = I(n, i), o = this.cellStyleKey(t, e);
728
+ r ? this.baseValidationErrors.set(o, { rowId: t, colKey: e, message: r }) : this.baseValidationErrors.delete(o);
729
+ }
730
+ recomputeValidationErrors() {
731
+ this.baseValidationErrors.clear(), this.uniqueValidationErrors.clear();
732
+ for (const t of this.rows)
733
+ for (const e of this.schema.columns) {
734
+ const n = this.getCell(t.id, e.key);
735
+ this.updateValidationForCell(t.id, e.key, n);
736
+ }
737
+ for (const t of this.getColumns())
738
+ t.unique && this.recomputeUniqueValidationForColumn(t.key);
739
+ }
740
+ normalizeUniqueValue(t) {
741
+ if (t == null) return null;
742
+ if (typeof t == "string") return t === "" ? null : t;
743
+ if (typeof t == "number" || typeof t == "boolean") return String(t);
744
+ if (t instanceof Date) return String(t.getTime());
745
+ if (typeof t == "object") {
746
+ const e = t, n = e.kind;
747
+ if (n === "enum" && typeof e.value == "string")
748
+ return e.value === "" ? null : e.value;
749
+ if (n === "tags" && Array.isArray(e.values)) {
750
+ const i = e.values.filter((r) => typeof r == "string").join(",");
751
+ return i === "" ? null : i;
752
+ }
753
+ }
754
+ return String(t);
755
+ }
756
+ recomputeUniqueValidationForColumn(t) {
757
+ const e = String(t);
758
+ for (const i of Array.from(this.uniqueValidationErrors.keys())) {
759
+ const r = i.indexOf("::");
760
+ (r >= 0 ? i.slice(r + 2) : "") === e && this.uniqueValidationErrors.delete(i);
761
+ }
762
+ const n = /* @__PURE__ */ new Map();
763
+ for (const i of this.rows) {
764
+ const r = this.getCell(i.id, t), o = this.normalizeUniqueValue(r);
765
+ if (!o) continue;
766
+ const l = n.get(o) ?? [];
767
+ l.push(i.id), n.set(o, l);
768
+ }
769
+ for (const i of n.values()) {
770
+ if (i.length < 2) continue;
771
+ const r = i.map((l) => this.getDisplayIndex(l)).filter((l) => typeof l == "number" && Number.isFinite(l)).sort((l, a) => l - a), o = r.length ? r.join(", ") : i.join(", ");
772
+ for (const l of i) {
773
+ const a = this.cellStyleKey(l, t);
774
+ this.uniqueValidationErrors.set(a, {
775
+ rowId: l,
776
+ colKey: t,
777
+ message: `Duplicate value
778
+ Rows: ${o}`
779
+ });
780
+ }
781
+ }
782
+ }
783
+ getCellStyle(t, e) {
784
+ return this.cellStyles.get(this.cellStyleKey(t, e)) ?? null;
785
+ }
786
+ setCellStyle(t, e, n) {
787
+ const i = this.cellStyleKey(t, e);
788
+ !n || Object.keys(n).length === 0 ? this.cellStyles.delete(i) : this.cellStyles.set(i, n), this.notify();
789
+ }
790
+ updateColumnStyle(t, e) {
791
+ const n = this.schema.columns.find((r) => String(r.key) === String(t));
792
+ if (!n) return;
793
+ const i = typeof e == "function" ? e(n.style) : e;
794
+ n.style = i, this.notify();
795
+ }
796
+ isEqual(t, e) {
797
+ return t instanceof Date && e instanceof Date ? t.getTime() === e.getTime() : Object.is(t, e);
798
+ }
799
+ getRowVersion(t) {
800
+ return this.rowVersion.get(t) ?? 0;
801
+ }
802
+ reindexRows() {
803
+ let t = 1;
804
+ for (const e of this.rows)
805
+ e.displayIndex = t, t += 1;
806
+ }
807
+ }
808
+ const x = 864e5;
809
+ function E(s) {
810
+ const t = N(s);
811
+ return t ? Number.isNaN(t.getTime()) ? null : t : null;
812
+ }
813
+ function $(s) {
814
+ const t = /* @__PURE__ */ new Date(`1970-01-01T${s}`);
815
+ return Number.isNaN(t.getTime()) ? null : t;
816
+ }
817
+ function X(s, t, e) {
818
+ if (t == null) return null;
819
+ if (typeof t == "object") {
820
+ const n = t;
821
+ if (n.kind === "lookup" && typeof n.value == "string")
822
+ return n.value;
823
+ if (typeof n.label == "string" && "value" in n && e.type === "labeled") {
824
+ const i = n.value;
825
+ return i == null ? null : typeof i == "string" ? i : typeof i == "number" || typeof i == "boolean" ? String(i) : i instanceof Date ? i.toISOString() : String(i);
826
+ }
827
+ }
828
+ if (e.type === "string" || e.type === "labeled") return null;
829
+ if (e.type === "boolean") return String(!!t);
830
+ if ((e.type === "number" || e.type === "int" || e.type === "uint") && typeof t == "number")
831
+ return String(t);
832
+ if (e.type === "datetime") {
833
+ const n = t instanceof Date ? t : E(String(t));
834
+ return n ? String(n.getTime()) : null;
835
+ }
836
+ if (e.type === "date") {
837
+ const n = t instanceof Date ? t : E(String(t));
838
+ if (!n) return null;
839
+ const i = Math.floor(n.getTime() / x) * x;
840
+ return String(i);
841
+ }
842
+ if (e.type === "time") {
843
+ const n = t instanceof Date ? t : $(String(t));
844
+ return n ? String(n.getTime() % x) : null;
845
+ }
846
+ return null;
847
+ }
848
+ const G = 35, z = 48, J = 35, Y = 8, Z = 4, Q = 4;
849
+ function tt(s, t, e = 100) {
850
+ const n = {
851
+ // Reserve extra space for browser UI affordances (e.g. date picker icon) and formatting.
852
+ date: 8
853
+ };
854
+ return s.columns.map((i) => {
855
+ const r = t.columnWidths?.[String(i.key)] ?? i.width ?? e, o = n[i.type] ?? 0;
856
+ return r + o;
857
+ });
858
+ }
859
+ function K(s) {
860
+ const t = s.style, e = t?.decorations;
861
+ return {
862
+ backgroundColor: t?.backgroundColor,
863
+ textColor: t?.textColor,
864
+ bold: e?.bold,
865
+ italic: e?.italic,
866
+ underline: e?.underline,
867
+ strike: e?.strike,
868
+ readonly: t?.readonly,
869
+ disabled: t?.disabled
870
+ };
871
+ }
872
+ function D(s, t) {
873
+ return t ? {
874
+ backgroundColor: t.backgroundColor ?? s.backgroundColor,
875
+ textColor: t.textColor ?? s.textColor,
876
+ bold: t.bold ?? s.bold,
877
+ italic: t.italic ?? s.italic,
878
+ underline: t.underline ?? s.underline,
879
+ strike: t.strike ?? s.strike,
880
+ readonly: t.readonly ?? s.readonly,
881
+ disabled: t.disabled ?? s.disabled
882
+ } : s;
883
+ }
884
+ function et(s, t, e) {
885
+ const n = K(e), i = s.resolveConditionalStyle(t, e).delta ?? {}, r = s.getCellStyle(t, e.key) ?? {}, o = D(D(n, i), r);
886
+ return { columnStyle: n, cellStyle: r, resolved: o };
887
+ }
888
+ function nt(s) {
889
+ let t = "";
890
+ s.backgroundColor && (t += `background-color:${s.backgroundColor};`), s.textColor && (t += `color:${s.textColor};`), s.bold && (t += "font-weight:600;"), s.italic && (t += "font-style:italic;");
891
+ const e = [];
892
+ return s.underline && e.push("underline"), s.strike && e.push("line-through"), e.length && (t += `text-decoration-line:${e.join(" ")};`), t;
893
+ }
894
+ function it(s) {
895
+ if (typeof s == "string") return { label: s };
896
+ if (!s || typeof s != "object") return null;
897
+ const t = s, e = t.label, n = t.command, i = t.commandfor;
898
+ return typeof e != "string" ? null : typeof n == "string" && typeof i == "string" ? { label: e, command: n, commandfor: i } : null;
899
+ }
900
+ function st(s) {
901
+ if (typeof s == "string") return s;
902
+ if (!s || typeof s != "object") return "";
903
+ const t = s.label;
904
+ return typeof t == "string" ? t : "";
905
+ }
906
+ function rt(s) {
907
+ if (typeof s == "string") return { label: s, href: s };
908
+ if (!s || typeof s != "object") return null;
909
+ const t = s, e = t.label, n = t.href, i = t.target;
910
+ return typeof e != "string" || typeof n != "string" ? null : typeof i == "string" ? { label: e, href: n, target: i } : i === void 0 ? { label: e, href: n } : null;
911
+ }
912
+ function ot(s) {
913
+ if (typeof s == "string") return s;
914
+ if (!s || typeof s != "object") return "";
915
+ const t = s, e = t.label, n = t.href;
916
+ return typeof e == "string" ? e : typeof n == "string" ? n : "";
917
+ }
918
+ function P(s) {
919
+ return s.normalize("NFKC").trim();
920
+ }
921
+ const _ = (s) => {
922
+ const t = s.trim(), e = /^([+-]?)(0[bBoOxX])([0-9a-fA-F]+)$/.exec(t);
923
+ if (!e) return null;
924
+ const n = e[1] === "-" ? -1 : 1, i = e[2].toLowerCase(), r = e[3] ?? "";
925
+ let o = 10, l = /^[0-9]+$/;
926
+ if (i === "0b" ? (o = 2, l = /^[01]+$/) : i === "0o" ? (o = 8, l = /^[0-7]+$/) : i === "0x" && (o = 16, l = /^[0-9a-fA-F]+$/), !r || !l.test(r)) return NaN;
927
+ const a = Number.parseInt(r, o);
928
+ return n * a;
929
+ };
930
+ function lt(s) {
931
+ const t = P(s);
932
+ if (t === "") return { ok: !1, reason: "empty" };
933
+ const e = _(t);
934
+ if (e !== null)
935
+ return Number.isFinite(e) ? { ok: !0, value: e } : { ok: !1, reason: "invalid" };
936
+ const n = Number(t);
937
+ return Number.isFinite(n) ? { ok: !0, value: n } : { ok: !1, reason: Number.isNaN(n) ? "invalid" : "non-finite" };
938
+ }
939
+ function at(s, t) {
940
+ return Number.isFinite(s) ? t === "number" ? { ok: !0, value: s } : Number.isSafeInteger(s) ? t === "uint" && s < 0 ? { ok: !1, reason: "out-of-range" } : { ok: !0, value: s } : { ok: !1, reason: "not-integer" } : { ok: !1, reason: "non-finite" };
941
+ }
942
+ function ct(s, t) {
943
+ const e = s < 0 ? "-" : "", n = Math.abs(s), i = t === "binary" ? n.toString(2) : t === "octal" ? n.toString(8) : n.toString(16);
944
+ return `${e}${t === "binary" ? "0b" : t === "octal" ? "0o" : "0x"}${i}`;
945
+ }
946
+ function ut(s, t) {
947
+ if (!Number.isFinite(s)) return "";
948
+ if ((t?.format ?? "decimal") === "scientific") {
949
+ const i = t?.precision;
950
+ return i !== void 0 && Number.isFinite(i) && i > 0 ? s.toExponential(Math.max(0, Math.floor(i) - 1)) : s.toExponential();
951
+ }
952
+ const n = t?.scale;
953
+ if (n !== void 0 && Number.isFinite(n)) {
954
+ const i = Math.max(0, Math.floor(n));
955
+ return s.toFixed(i);
956
+ }
957
+ return String(s);
958
+ }
959
+ export {
960
+ Z as C,
961
+ J as D,
962
+ G as H,
963
+ z as R,
964
+ it as a,
965
+ rt as b,
966
+ K as c,
967
+ st as d,
968
+ ot as e,
969
+ Q as f,
970
+ tt as g,
971
+ ut as h,
972
+ ct as i,
973
+ k as j,
974
+ U as k,
975
+ Y as l,
976
+ D as m,
977
+ lt as n,
978
+ at as o,
979
+ N as p,
980
+ P as q,
981
+ L as r,
982
+ nt as s,
983
+ X as t,
984
+ W as u,
985
+ q as v,
986
+ et as w
987
+ };
988
+ //# sourceMappingURL=numberIO-BhW20Lm1.js.map