@iyulab/flex-table 0.14.0 → 0.16.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.
@@ -174,6 +174,14 @@ var s = t`
174
174
 
175
175
  .ft-body { position: relative; }
176
176
 
177
+ .ft-frozen-rows {
178
+ display: block;
179
+ position: sticky;
180
+ z-index: 3;
181
+ border-bottom: 2px solid var(--ft-active-color);
182
+ background: var(--ft-bg);
183
+ }
184
+
177
185
  .ft-row {
178
186
  display: block;
179
187
  position: absolute;
@@ -280,6 +288,39 @@ var s = t`
280
288
  color: var(--ft-empty-color);
281
289
  }
282
290
 
291
+ .ft-has-comment {
292
+ position: relative;
293
+ }
294
+
295
+ .ft-comment-indicator {
296
+ position: absolute;
297
+ top: 0;
298
+ right: 0;
299
+ width: 0;
300
+ height: 0;
301
+ border-style: solid;
302
+ border-width: 0 7px 7px 0;
303
+ border-color: transparent #f59e0b transparent transparent;
304
+ pointer-events: none;
305
+ z-index: 1;
306
+ }
307
+
308
+ .ft-import-overlay {
309
+ position: absolute;
310
+ inset: 0;
311
+ z-index: 100;
312
+ background: rgba(59, 130, 246, 0.15);
313
+ border: 2px dashed rgba(59, 130, 246, 0.8);
314
+ display: flex;
315
+ align-items: center;
316
+ justify-content: center;
317
+ font-size: 14px;
318
+ font-weight: 500;
319
+ color: rgb(37, 99, 235);
320
+ pointer-events: none;
321
+ border-radius: 4px;
322
+ }
323
+
283
324
  .ft-row-num-header,
284
325
  .ft-row-num {
285
326
  position: absolute;
@@ -353,7 +394,7 @@ var s = t`
353
394
  position: absolute;
354
395
  top: 100%;
355
396
  left: 0;
356
- min-width: 160px;
397
+ min-width: 200px;
357
398
  background: var(--ft-bg);
358
399
  border: 1px solid var(--ft-border-color);
359
400
  border-radius: 4px;
@@ -407,6 +448,51 @@ var s = t`
407
448
  color: var(--ft-text-color);
408
449
  }
409
450
 
451
+ .ft-filter-mode-row {
452
+ display: flex;
453
+ gap: 4px;
454
+ margin-bottom: 4px;
455
+ }
456
+
457
+ .ft-filter-mode-select {
458
+ flex: 1;
459
+ padding: 3px 6px;
460
+ font: inherit;
461
+ font-size: 12px;
462
+ border: 1px solid var(--ft-border-color);
463
+ border-radius: 3px;
464
+ color: var(--ft-text-color);
465
+ background: var(--ft-editor-bg);
466
+ cursor: pointer;
467
+ }
468
+
469
+ .ft-num-cond-row {
470
+ display: flex;
471
+ gap: 4px;
472
+ margin-bottom: 4px;
473
+ }
474
+
475
+ .ft-num-op-select {
476
+ flex: 0 0 44px;
477
+ }
478
+
479
+ .ft-num-cond-input {
480
+ flex: 1;
481
+ }
482
+
483
+ .ft-filter-empty-row {
484
+ margin-top: 6px;
485
+ padding-top: 6px;
486
+ border-top: 1px solid var(--ft-border-color);
487
+ }
488
+
489
+ .ft-filter-empty-row label {
490
+ display: block;
491
+ font-size: 11px;
492
+ color: var(--ft-sort-indicator-color);
493
+ margin-bottom: 3px;
494
+ }
495
+
410
496
  /* --- Row Selection (Checkbox) --- */
411
497
 
412
498
  .ft-checkbox-header,
@@ -902,13 +988,13 @@ function S(e, t, n) {
902
988
  if (c && l) continue;
903
989
  if (c) return 1;
904
990
  if (l) return -1;
905
- let u = ee(t, s, i.get(a) ?? "text");
991
+ let u = C(t, s, i.get(a) ?? "text");
906
992
  if (u !== 0) return o === "asc" ? u : -u;
907
993
  }
908
994
  return n - r;
909
995
  }), r;
910
996
  }
911
- function ee(e, t, n) {
997
+ function C(e, t, n) {
912
998
  switch (n) {
913
999
  case "number": {
914
1000
  let n = Number(e), r = Number(t);
@@ -923,7 +1009,7 @@ function ee(e, t, n) {
923
1009
  default: return String(e).localeCompare(String(t));
924
1010
  }
925
1011
  }
926
- function C(e, t, n) {
1012
+ function w(e, t, n) {
927
1013
  let r = e.find((e) => e.key === t);
928
1014
  return n ? r ? r.direction === "asc" ? e.map((e) => e.key === t ? {
929
1015
  ...e,
@@ -941,7 +1027,7 @@ function C(e, t, n) {
941
1027
  }
942
1028
  //#endregion
943
1029
  //#region src/core/filtering.ts
944
- function w(e, t, n) {
1030
+ function T(e, t, n) {
945
1031
  if (t.length === 0) return Array.from({ length: e.length }, (e, t) => t);
946
1032
  let r = [];
947
1033
  for (let i = 0; i < e.length; i++) {
@@ -960,9 +1046,9 @@ function w(e, t, n) {
960
1046
  }
961
1047
  //#endregion
962
1048
  //#region src/core/undo.ts
963
- var T = 100, E = class {
1049
+ var E = 100, D = class {
964
1050
  constructor() {
965
- this._undoStack = [], this._redoStack = [], this._maxSize = T;
1051
+ this._undoStack = [], this._redoStack = [], this._maxSize = E;
966
1052
  }
967
1053
  get maxSize() {
968
1054
  return this._maxSize;
@@ -999,7 +1085,7 @@ var T = 100, E = class {
999
1085
  };
1000
1086
  //#endregion
1001
1087
  //#region src/clipboard/clipboard.ts
1002
- function te(e, t, n) {
1088
+ function ee(e, t, n) {
1003
1089
  let r = [];
1004
1090
  for (let i = n.startRow; i <= n.endRow; i++) {
1005
1091
  let a = e[i], o = [];
@@ -1011,7 +1097,7 @@ function te(e, t, n) {
1011
1097
  }
1012
1098
  return r.join("\n");
1013
1099
  }
1014
- function ne(e) {
1100
+ function O(e) {
1015
1101
  let t = e.replace(/\r\n/g, "\n").replace(/\r/g, "\n"), n = [], r = [], i = 0, a = t.length;
1016
1102
  for (; i <= a;) {
1017
1103
  if (i === a) {
@@ -1040,7 +1126,7 @@ function ne(e) {
1040
1126
  }
1041
1127
  return n;
1042
1128
  }
1043
- function D(e, t) {
1129
+ function k(e, t) {
1044
1130
  if (e === "") return null;
1045
1131
  switch (t.type) {
1046
1132
  case "number": {
@@ -1053,7 +1139,7 @@ function D(e, t) {
1053
1139
  }
1054
1140
  //#endregion
1055
1141
  //#region src/export/xlsx-writer.ts
1056
- var re = (() => {
1142
+ var te = (() => {
1057
1143
  let e = new Uint32Array(256);
1058
1144
  for (let t = 0; t < 256; t++) {
1059
1145
  let n = t;
@@ -1062,56 +1148,56 @@ var re = (() => {
1062
1148
  }
1063
1149
  return e;
1064
1150
  })();
1065
- function O(e) {
1151
+ function A(e) {
1066
1152
  let t = 4294967295;
1067
- for (let n = 0; n < e.length; n++) t = re[(t ^ e[n]) & 255] ^ t >>> 8;
1153
+ for (let n = 0; n < e.length; n++) t = te[(t ^ e[n]) & 255] ^ t >>> 8;
1068
1154
  return (t ^ 4294967295) >>> 0;
1069
1155
  }
1070
- var k = new TextEncoder();
1071
- function A(e) {
1156
+ var j = new TextEncoder();
1157
+ function ne(e) {
1072
1158
  let t = [], n = [], r = 0;
1073
1159
  for (let i of e) {
1074
- let e = k.encode(i.name), a = O(i.data), o = i.data.length, s = new ArrayBuffer(30 + e.length), c = new DataView(s);
1160
+ let e = j.encode(i.name), a = A(i.data), o = i.data.length, s = new ArrayBuffer(30 + e.length), c = new DataView(s);
1075
1161
  c.setUint32(0, 67324752, !0), c.setUint16(4, 20, !0), c.setUint16(6, 0, !0), c.setUint16(8, 0, !0), c.setUint16(10, 0, !0), c.setUint16(12, 33, !0), c.setUint32(14, a, !0), c.setUint32(18, o, !0), c.setUint32(22, o, !0), c.setUint16(26, e.length, !0), c.setUint16(28, 0, !0), new Uint8Array(s, 30).set(e), t.push(new Uint8Array(s)), t.push(i.data);
1076
1162
  let l = new ArrayBuffer(46 + e.length), u = new DataView(l);
1077
1163
  u.setUint32(0, 33639248, !0), u.setUint16(4, 20, !0), u.setUint16(6, 20, !0), u.setUint16(8, 0, !0), u.setUint16(10, 0, !0), u.setUint16(12, 0, !0), u.setUint16(14, 33, !0), u.setUint32(16, a, !0), u.setUint32(20, o, !0), u.setUint32(24, o, !0), u.setUint16(28, e.length, !0), u.setUint16(30, 0, !0), u.setUint16(32, 0, !0), u.setUint16(34, 0, !0), u.setUint16(36, 0, !0), u.setUint32(38, 0, !0), u.setUint32(42, r, !0), new Uint8Array(l, 46).set(e), n.push(new Uint8Array(l)), r += 30 + e.length + o;
1078
1164
  }
1079
- let i = j(n), a = /* @__PURE__ */ new ArrayBuffer(22), o = new DataView(a);
1080
- return o.setUint32(0, 101010256, !0), o.setUint16(4, 0, !0), o.setUint16(6, 0, !0), o.setUint16(8, e.length, !0), o.setUint16(10, e.length, !0), o.setUint32(12, i.length, !0), o.setUint32(16, r, !0), o.setUint16(20, 0, !0), j([
1165
+ let i = M(n), a = /* @__PURE__ */ new ArrayBuffer(22), o = new DataView(a);
1166
+ return o.setUint32(0, 101010256, !0), o.setUint16(4, 0, !0), o.setUint16(6, 0, !0), o.setUint16(8, e.length, !0), o.setUint16(10, e.length, !0), o.setUint32(12, i.length, !0), o.setUint32(16, r, !0), o.setUint16(20, 0, !0), M([
1081
1167
  ...t,
1082
1168
  i,
1083
1169
  new Uint8Array(a)
1084
1170
  ]);
1085
1171
  }
1086
- function j(e) {
1172
+ function M(e) {
1087
1173
  let t = e.reduce((e, t) => e + t.length, 0), n = new Uint8Array(t), r = 0;
1088
1174
  for (let t of e) n.set(t, r), r += t.length;
1089
1175
  return n;
1090
1176
  }
1091
- function M(e) {
1177
+ function N(e) {
1092
1178
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1093
1179
  }
1094
- function N(e) {
1180
+ function P(e) {
1095
1181
  let t = "";
1096
1182
  for (e++; e > 0;) t = String.fromCharCode(64 + (e % 26 || 26)) + t, e = Math.floor((e - 1) / 26);
1097
1183
  return t;
1098
1184
  }
1099
- function P(e, t) {
1100
- return N(t) + (e + 1);
1185
+ function F(e, t) {
1186
+ return P(t) + (e + 1);
1101
1187
  }
1102
- function F(e) {
1188
+ function I(e) {
1103
1189
  let t = Date.UTC(1899, 11, 30);
1104
1190
  return (e.getTime() - t) / 864e5;
1105
1191
  }
1106
- var I = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>\n <Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>\n <Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>\n <Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>\n</Types>", L = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>\n</Relationships>", R = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <sheets><sheet name=\"Sheet1\" sheetId=\"1\" r:id=\"rId1\"/></sheets>\n</workbook>", z = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n</Relationships>", B = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">\n <numFmts count=\"1\"><numFmt numFmtId=\"164\" formatCode=\"yyyy-mm-dd\"/></numFmts>\n <fonts count=\"2\">\n <font><sz val=\"11\"/><name val=\"Calibri\"/></font>\n <font><sz val=\"11\"/><b/><name val=\"Calibri\"/></font>\n </fonts>\n <fills count=\"2\">\n <fill><patternFill patternType=\"none\"/></fill>\n <fill><patternFill patternType=\"gray125\"/></fill>\n </fills>\n <borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>\n <cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>\n <cellXfs count=\"3\">\n <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>\n <xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>\n <xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>\n </cellXfs>\n</styleSheet>";
1107
- function V(e, t) {
1108
- let n = [], r = t.map((e, t) => `<c r="${P(0, t)}" t="str" s="2"><v>${M(e.header)}</v></c>`);
1192
+ var L = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>\n <Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>\n <Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>\n <Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>\n</Types>", R = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>\n</Relationships>", re = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <sheets><sheet name=\"Sheet1\" sheetId=\"1\" r:id=\"rId1\"/></sheets>\n</workbook>", ie = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n</Relationships>", ae = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">\n <numFmts count=\"1\"><numFmt numFmtId=\"164\" formatCode=\"yyyy-mm-dd\"/></numFmts>\n <fonts count=\"2\">\n <font><sz val=\"11\"/><name val=\"Calibri\"/></font>\n <font><sz val=\"11\"/><b/><name val=\"Calibri\"/></font>\n </fonts>\n <fills count=\"2\">\n <fill><patternFill patternType=\"none\"/></fill>\n <fill><patternFill patternType=\"gray125\"/></fill>\n </fills>\n <borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>\n <cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>\n <cellXfs count=\"3\">\n <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>\n <xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>\n <xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>\n </cellXfs>\n</styleSheet>";
1193
+ function oe(e, t) {
1194
+ let n = [], r = t.map((e, t) => `<c r="${F(0, t)}" t="str" s="2"><v>${N(e.header)}</v></c>`);
1109
1195
  return n.push(`<row r="1">${r.join("")}</row>`), e.forEach((e, r) => {
1110
1196
  let i = t.map((t, n) => {
1111
- let i = P(r + 1, n), a = e[t.key];
1197
+ let i = F(r + 1, n), a = e[t.key];
1112
1198
  if (a == null) return `<c r="${i}" t="str"><v></v></c>`;
1113
1199
  let o = t.type ?? "text";
1114
- return o === "number" && typeof a == "number" ? `<c r="${i}"><v>${a}</v></c>` : (o === "date" || o === "datetime") && a instanceof Date ? `<c r="${i}" s="1"><v>${F(a).toFixed(6)}</v></c>` : o === "boolean" ? `<c r="${i}" t="b"><v>${+!!a}</v></c>` : `<c r="${i}" t="str"><v>${M(String(a))}</v></c>`;
1200
+ return o === "number" && typeof a == "number" ? `<c r="${i}"><v>${a}</v></c>` : (o === "date" || o === "datetime") && a instanceof Date ? `<c r="${i}" s="1"><v>${I(a).toFixed(6)}</v></c>` : o === "boolean" ? `<c r="${i}" t="b"><v>${+!!a}</v></c>` : `<c r="${i}" t="str"><v>${N(String(a))}</v></c>`;
1115
1201
  });
1116
1202
  n.push(`<row r="${r + 2}">${i.join("")}</row>`);
1117
1203
  }), `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
@@ -1119,55 +1205,55 @@ function V(e, t) {
1119
1205
  <sheetData>${n.join("")}</sheetData>
1120
1206
  </worksheet>`;
1121
1207
  }
1122
- function H(e, t) {
1123
- let n = V(e, t);
1124
- return A([
1208
+ function z(e, t) {
1209
+ let n = oe(e, t);
1210
+ return ne([
1125
1211
  {
1126
1212
  name: "[Content_Types].xml",
1127
- data: k.encode(I)
1213
+ data: j.encode(L)
1128
1214
  },
1129
1215
  {
1130
1216
  name: "_rels/.rels",
1131
- data: k.encode(L)
1217
+ data: j.encode(R)
1132
1218
  },
1133
1219
  {
1134
1220
  name: "xl/workbook.xml",
1135
- data: k.encode(R)
1221
+ data: j.encode(re)
1136
1222
  },
1137
1223
  {
1138
1224
  name: "xl/_rels/workbook.xml.rels",
1139
- data: k.encode(z)
1225
+ data: j.encode(ie)
1140
1226
  },
1141
1227
  {
1142
1228
  name: "xl/worksheets/sheet1.xml",
1143
- data: k.encode(n)
1229
+ data: j.encode(n)
1144
1230
  },
1145
1231
  {
1146
1232
  name: "xl/styles.xml",
1147
- data: k.encode(B)
1233
+ data: j.encode(ae)
1148
1234
  }
1149
1235
  ]);
1150
1236
  }
1151
1237
  //#endregion
1152
1238
  //#region src/export/export.ts
1153
- function U(e, t, n) {
1239
+ function B(e, t, n) {
1154
1240
  switch (n) {
1155
- case "csv": return G(e, t, ",");
1156
- case "tsv": return G(e, t, " ");
1157
- case "json": return q(e, t);
1158
- case "xlsx": return H(e, t);
1241
+ case "csv": return H(e, t, ",");
1242
+ case "tsv": return H(e, t, " ");
1243
+ case "json": return W(e, t);
1244
+ case "xlsx": return z(e, t);
1159
1245
  }
1160
1246
  }
1161
- function W(e, t) {
1247
+ function V(e, t) {
1162
1248
  return e == null ? "" : (t.type === "date" || t.type === "datetime") && e instanceof Date ? e.toISOString() : String(e);
1163
1249
  }
1164
- function G(e, t, n) {
1165
- return [t.map((e) => K(e.header, n)).join(n), ...e.map((e) => t.map((t) => K(W(e[t.key], t), n)).join(n))].join("\n");
1250
+ function H(e, t, n) {
1251
+ return [t.map((e) => U(e.header, n)).join(n), ...e.map((e) => t.map((t) => U(V(e[t.key], t), n)).join(n))].join("\n");
1166
1252
  }
1167
- function K(e, t) {
1253
+ function U(e, t) {
1168
1254
  return e.includes(t) || e.includes("\"") || e.includes("\n") || e.includes("\r") ? "\"" + e.replace(/"/g, "\"\"") + "\"" : e;
1169
1255
  }
1170
- function q(e, t) {
1256
+ function W(e, t) {
1171
1257
  let n = e.map((e) => {
1172
1258
  let n = {};
1173
1259
  for (let r of t) {
@@ -1178,30 +1264,142 @@ function q(e, t) {
1178
1264
  });
1179
1265
  return JSON.stringify(n, null, 2);
1180
1266
  }
1181
- function J(e, t, n) {
1267
+ function G(e, t, n) {
1182
1268
  let r = new Blob([e], { type: n }), i = URL.createObjectURL(r), a = document.createElement("a");
1183
1269
  a.href = i, a.download = t, a.style.display = "none", document.body.appendChild(a), a.click(), document.body.removeChild(a), setTimeout(() => URL.revokeObjectURL(i), 100);
1184
1270
  }
1185
- var ie = {
1271
+ var K = {
1186
1272
  csv: "text/csv;charset=utf-8",
1187
1273
  tsv: "text/tab-separated-values;charset=utf-8",
1188
1274
  json: "application/json;charset=utf-8",
1189
1275
  xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
1190
- }, ae = {
1276
+ }, se = {
1191
1277
  csv: ".csv",
1192
1278
  tsv: ".tsv",
1193
1279
  json: ".json",
1194
1280
  xlsx: ".xlsx"
1195
1281
  };
1196
- function oe(e) {
1197
- return ie[e];
1282
+ function ce(e) {
1283
+ return K[e];
1198
1284
  }
1199
- function se(e) {
1200
- return ae[e];
1285
+ function le(e) {
1286
+ return se[e];
1287
+ }
1288
+ //#endregion
1289
+ //#region src/export/xlsx-reader.ts
1290
+ function ue(e) {
1291
+ for (let t = e.byteLength - 22; t >= 0; t--) if (e.getUint32(t, !0) === 101010256) return t;
1292
+ throw Error("XLSX: End of central directory not found — not a valid ZIP file");
1293
+ }
1294
+ function de(e) {
1295
+ let t = ue(e), n = e.getUint32(t + 16, !0), r = e.getUint32(t + 12, !0), i = new TextDecoder("utf-8"), a = [], o = n, s = n + r;
1296
+ for (; o < s && e.getUint32(o, !0) === 33639248;) {
1297
+ let t = e.getUint16(o + 10, !0), n = e.getUint32(o + 20, !0), r = e.getUint32(o + 24, !0), s = e.getUint16(o + 28, !0), c = e.getUint16(o + 30, !0), l = e.getUint16(o + 32, !0), u = e.getUint32(o + 42, !0), d = i.decode(new Uint8Array(e.buffer, o + 46, s));
1298
+ a.push({
1299
+ name: d,
1300
+ compressionMethod: t,
1301
+ compressedSize: n,
1302
+ uncompressedSize: r,
1303
+ localHeaderOffset: u
1304
+ }), o += 46 + s + c + l;
1305
+ }
1306
+ return a;
1307
+ }
1308
+ async function fe(e) {
1309
+ let t = new DecompressionStream("deflate-raw"), n = t.writable.getWriter(), r = t.readable.getReader();
1310
+ n.write(e), n.close();
1311
+ let i = [];
1312
+ for (;;) {
1313
+ let { done: e, value: t } = await r.read();
1314
+ if (e) break;
1315
+ i.push(t);
1316
+ }
1317
+ let a = i.reduce((e, t) => e + t.length, 0), o = new Uint8Array(a), s = 0;
1318
+ for (let e of i) o.set(e, s), s += e.length;
1319
+ return o;
1320
+ }
1321
+ async function pe(e, t) {
1322
+ let n = t.localHeaderOffset, r = e.getUint16(n + 26, !0), i = e.getUint16(n + 28, !0), a = n + 30 + r + i, o = new Uint8Array(e.buffer, a, t.compressedSize);
1323
+ if (t.compressionMethod === 0) return o.slice();
1324
+ if (t.compressionMethod === 8) return fe(o);
1325
+ throw Error(`XLSX: Unsupported compression method ${t.compressionMethod}`);
1326
+ }
1327
+ async function me(e) {
1328
+ let t = new DataView(e), n = de(t), r = /* @__PURE__ */ new Map();
1329
+ for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await pe(t, e));
1330
+ return r;
1331
+ }
1332
+ var he = new TextDecoder("utf-8");
1333
+ function q(e) {
1334
+ let t = he.decode(e);
1335
+ return new DOMParser().parseFromString(t, "application/xml");
1336
+ }
1337
+ function ge(e) {
1338
+ if (!e) return [];
1339
+ let t = q(e);
1340
+ return Array.from(t.querySelectorAll("si")).map((e) => Array.from(e.querySelectorAll("t")).map((e) => e.textContent ?? "").join(""));
1341
+ }
1342
+ function _e(e) {
1343
+ let t = (e - 1) * 864e5 + Date.UTC(1899, 11, 30);
1344
+ return new Date(t).toISOString().slice(0, 10);
1345
+ }
1346
+ function ve(e, t) {
1347
+ let n = q(e).querySelectorAll("row");
1348
+ if (n.length === 0) return [];
1349
+ let r = 0, i = /* @__PURE__ */ new Map();
1350
+ for (let e of n) {
1351
+ let n = parseInt(e.getAttribute("r") ?? "1", 10) - 1, a = /* @__PURE__ */ new Map();
1352
+ i.set(n, a);
1353
+ for (let n of e.querySelectorAll("c")) {
1354
+ let e = ye(n.getAttribute("r") ?? "");
1355
+ e > r && (r = e);
1356
+ let i = n.getAttribute("t") ?? "", o = n.getAttribute("s") ?? "", s = n.querySelector("v")?.textContent ?? "", c = n.querySelector("is > t")?.textContent ?? null, l;
1357
+ if (i === "s") l = t[parseInt(s, 10)] ?? "";
1358
+ else if (i === "str" || i === "inlineStr") l = c ?? s;
1359
+ else if (i === "b") l = s === "1" ? "true" : "false";
1360
+ else if (s === "") l = "";
1361
+ else {
1362
+ let e = parseFloat(s);
1363
+ l = !isNaN(e) && o !== "" && parseInt(o, 10) > 0 && e >= 1 && e <= 73050 ? _e(e) : s;
1364
+ }
1365
+ a.set(e, l);
1366
+ }
1367
+ }
1368
+ if (i.size === 0) return [];
1369
+ let a = Math.max(...i.keys()), o = [];
1370
+ for (let e = 0; e <= a; e++) {
1371
+ let t = i.get(e) ?? /* @__PURE__ */ new Map(), n = [];
1372
+ for (let e = 0; e <= r; e++) n.push(t.get(e) ?? "");
1373
+ o.push(n);
1374
+ }
1375
+ return o;
1376
+ }
1377
+ function ye(e) {
1378
+ let t = 0, n = 0;
1379
+ for (; n < e.length && e[n] >= "A" && e[n] <= "Z";) t = t * 26 + (e.charCodeAt(n) - 64), n++;
1380
+ return t - 1;
1381
+ }
1382
+ async function be(e) {
1383
+ let t = await me(e), n = ge(t.get("xl/sharedStrings.xml")), r = t.get("xl/worksheets/sheet1.xml");
1384
+ if (!r) {
1385
+ for (let [e, n] of t) if (e.toLowerCase().includes("worksheets/sheet")) {
1386
+ r = n;
1387
+ break;
1388
+ }
1389
+ }
1390
+ if (!r) throw Error("XLSX: No worksheet found");
1391
+ let i = ve(r, n);
1392
+ return i.length === 0 ? {
1393
+ headers: [],
1394
+ rows: []
1395
+ } : {
1396
+ headers: i[0],
1397
+ rows: i.slice(1)
1398
+ };
1201
1399
  }
1202
1400
  //#endregion
1203
1401
  //#region \0@oxc-project+runtime@0.130.0/helpers/decorate.js
1204
- function Y(e, t, n, r) {
1402
+ function J(e, t, n, r) {
1205
1403
  var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
1206
1404
  if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
1207
1405
  else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
@@ -1209,9 +1407,16 @@ function Y(e, t, n, r) {
1209
1407
  }
1210
1408
  //#endregion
1211
1409
  //#region src/flex-table.ts
1212
- var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
1410
+ var Y = {
1411
+ eq: "=",
1412
+ neq: "≠",
1413
+ gt: ">",
1414
+ lt: "<",
1415
+ gte: "≥",
1416
+ lte: "≤"
1417
+ }, X = 120, Z = 40, xe = 32, Q = 5, $ = class extends e {
1213
1418
  constructor(...e) {
1214
- super(...e), this.columns = [], this.data = [], this.rowHeight = ce, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._activeCell = null, this._editingCell = null, this._sortCriteria = [], this._selection = new y(), this._editing = new b(), this._rowSelection = new x(), this._undo = new E(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._autocompleteState = null, this._headerMenu = null, this._bodyContextMenu = null, this._viewDirty = !0, this._isDragging = !1, this._wasDrag = !1, this._resizing = null, this._resizeCleanup = null, this._colDrag = null, this._colDragIndicatorLeft = null, this._fillDrag = null, this._rowDrag = null, this._rowDragIndicatorY = null, this._findState = null, this._columnWidths = /* @__PURE__ */ new Map(), this._hostResizeObserver = null, this._invalidCells = /* @__PURE__ */ new Map(), this._textFilterState = /* @__PURE__ */ new Map(), this._numberFilterState = /* @__PURE__ */ new Map(), this._dateFilterState = /* @__PURE__ */ new Map();
1419
+ super(...e), this.columns = [], this.data = [], this.rowHeight = xe, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.importEnabled = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._activeCell = null, this._editingCell = null, this._sortCriteria = [], this._selection = new y(), this._editing = new b(), this._rowSelection = new x(), this._undo = new D(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._autocompleteState = null, this._headerMenu = null, this._bodyContextMenu = null, this._viewDirty = !0, this._isDragging = !1, this._wasDrag = !1, this._resizing = null, this._resizeCleanup = null, this._colDrag = null, this._colDragIndicatorLeft = null, this._fillDrag = null, this._rowDrag = null, this._rowDragIndicatorY = null, this._findState = null, this._columnWidths = /* @__PURE__ */ new Map(), this._hostResizeObserver = null, this._comments = /* @__PURE__ */ new Map(), this._isDragOver = !1, this._invalidCells = /* @__PURE__ */ new Map(), this._textFilterState = /* @__PURE__ */ new Map(), this._numberFilterState = /* @__PURE__ */ new Map(), this._dateFilterState = /* @__PURE__ */ new Map(), this._emptyFilterState = /* @__PURE__ */ new Map();
1215
1420
  }
1216
1421
  static {
1217
1422
  this.styles = s;
@@ -1520,12 +1725,111 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
1520
1725
  if (!t) return "";
1521
1726
  let n = this.visibleColumns.slice(t.startCol, t.endCol + 1), r = [];
1522
1727
  for (let e = t.startRow; e <= t.endRow; e++) r.push(this.data[this._toDataIndex(e)]);
1523
- return U(r, n, e);
1728
+ return B(r, n, e);
1524
1729
  }
1525
- return U(this._sortedIndices.map((e) => this.data[e]), this.visibleColumns, e);
1730
+ return B(this._sortedIndices.map((e) => this.data[e]), this.visibleColumns, e);
1526
1731
  }
1527
1732
  exportToFile(e, t) {
1528
- J(this.exportToString(e), t ?? `export${se(e)}`, oe(e));
1733
+ G(this.exportToString(e), t ?? `export${le(e)}`, ce(e));
1734
+ }
1735
+ setComment(e, t, n) {
1736
+ if (n) this._comments.has(e) || this._comments.set(e, /* @__PURE__ */ new Map()), this._comments.get(e).set(t, n);
1737
+ else {
1738
+ let n = this._comments.get(e);
1739
+ n && (n.delete(t), n.size === 0 && this._comments.delete(e));
1740
+ }
1741
+ this.dispatchEvent(new CustomEvent("comment-change", {
1742
+ detail: {
1743
+ dataIndex: e,
1744
+ colKey: t,
1745
+ text: n ?? null
1746
+ },
1747
+ bubbles: !0,
1748
+ composed: !0
1749
+ })), this.requestUpdate();
1750
+ }
1751
+ getComment(e, t) {
1752
+ return this._comments.get(e)?.get(t) ?? null;
1753
+ }
1754
+ getAllComments() {
1755
+ let e = [];
1756
+ for (let [t, n] of this._comments) for (let [r, i] of n) e.push({
1757
+ dataIndex: t,
1758
+ colKey: r,
1759
+ text: i
1760
+ });
1761
+ return e;
1762
+ }
1763
+ clearComments() {
1764
+ this._comments.clear(), this.requestUpdate();
1765
+ }
1766
+ async importFromFile(e) {
1767
+ let t = e.name.toLowerCase();
1768
+ if (t.endsWith(".xlsx")) {
1769
+ let t = await be(await e.arrayBuffer());
1770
+ this._applyImportedSheet(t);
1771
+ } else if (t.endsWith(".csv") || t.endsWith(".tsv")) {
1772
+ let t = O(await e.text());
1773
+ this._applyImportedRows(t);
1774
+ } else console.warn(`flex-table importFromFile: unsupported file type "${e.name}"`);
1775
+ }
1776
+ _applyImportedSheet(e) {
1777
+ let t = this._buildHeaderColumnMap(e.headers), n = e.rows.map((n) => {
1778
+ let r = {};
1779
+ return e.headers.forEach((e, i) => {
1780
+ let a = t.get(e);
1781
+ if (!a) return;
1782
+ let o = this.columns.find((e) => e.key === a);
1783
+ r[a] = o ? k(n[i] ?? "", o) : n[i] ?? null;
1784
+ }), r;
1785
+ });
1786
+ this.data = n, this.dispatchEvent(new CustomEvent("data-import", {
1787
+ detail: { count: n.length },
1788
+ bubbles: !0,
1789
+ composed: !0
1790
+ }));
1791
+ }
1792
+ _applyImportedRows(e) {
1793
+ if (e.length === 0) return;
1794
+ let t = e[0], n = this._buildHeaderColumnMap(t), r = e.slice(1).map((e) => {
1795
+ let r = {};
1796
+ return t.forEach((t, i) => {
1797
+ let a = n.get(t);
1798
+ if (!a) return;
1799
+ let o = this.columns.find((e) => e.key === a);
1800
+ r[a] = o ? k(e[i] ?? "", o) : e[i] ?? null;
1801
+ }), r;
1802
+ });
1803
+ this.data = r, this.dispatchEvent(new CustomEvent("data-import", {
1804
+ detail: { count: r.length },
1805
+ bubbles: !0,
1806
+ composed: !0
1807
+ }));
1808
+ }
1809
+ _buildHeaderColumnMap(e) {
1810
+ let t = /* @__PURE__ */ new Map();
1811
+ for (let n of e) {
1812
+ let e = this.columns.find((e) => e.header === n);
1813
+ if (e) {
1814
+ t.set(n, e.key);
1815
+ continue;
1816
+ }
1817
+ let r = this.columns.find((e) => e.header.toLowerCase() === n.toLowerCase());
1818
+ r && t.set(n, r.key);
1819
+ }
1820
+ return t;
1821
+ }
1822
+ _onDragover(e) {
1823
+ this.importEnabled && (e.dataTransfer?.types.includes("Files") ?? !1) && (e.preventDefault(), e.dataTransfer.dropEffect = "copy", this._isDragOver = !0);
1824
+ }
1825
+ _onDragleave() {
1826
+ this._isDragOver = !1;
1827
+ }
1828
+ async _onDrop(e) {
1829
+ if (this._isDragOver = !1, !this.importEnabled) return;
1830
+ e.preventDefault();
1831
+ let t = e.dataTransfer?.files[0];
1832
+ t && await this.importFromFile(t);
1529
1833
  }
1530
1834
  _getSelectedDataRows() {
1531
1835
  let e = this._selection.getEffectiveRange();
@@ -1547,21 +1851,27 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
1547
1851
  get _visibleRowCount() {
1548
1852
  return this._sortedIndices.length;
1549
1853
  }
1854
+ get _frozenRowCount() {
1855
+ return Math.min(this.frozenRows, this._visibleRowCount);
1856
+ }
1857
+ get frozenRowsHeight() {
1858
+ return this._frozenRowCount * this.rowHeight;
1859
+ }
1550
1860
  get totalBodyHeight() {
1551
- return this._visibleRowCount * this.rowHeight;
1861
+ return Math.max(0, this._visibleRowCount - this._frozenRowCount) * this.rowHeight;
1552
1862
  }
1553
1863
  get visibleRange() {
1554
- let e = Math.max(0, this._scrollTop - this.headerHeight), t = Math.max(0, Math.floor(e / this.rowHeight) - Q), n = Math.ceil(this._viewportHeight / this.rowHeight);
1864
+ let e = this._frozenRowCount, t = Math.max(0, this._scrollTop - this.headerHeight - this.frozenRowsHeight), n = e + Math.floor(t / this.rowHeight), r = Math.max(e, n - Q), i = Math.ceil(this._viewportHeight / this.rowHeight);
1555
1865
  return {
1556
- start: t,
1557
- end: Math.min(this._visibleRowCount, Math.floor(e / this.rowHeight) + n + Q)
1866
+ start: r,
1867
+ end: Math.min(this._visibleRowCount, n + i + Q)
1558
1868
  };
1559
1869
  }
1560
1870
  connectedCallback() {
1561
- super.connectedCallback(), this._onScroll = this._onScroll.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onDocumentClick = this._onDocumentClick.bind(this), this._onContextMenu = this._onContextMenu.bind(this), this.addEventListener("scroll", this._onScroll, { passive: !0 }), this.addEventListener("keydown", this._onKeyDown), this.addEventListener("contextmenu", this._onContextMenu), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "0"), this.setAttribute("role", "grid"), typeof ResizeObserver < "u" && (this._hostResizeObserver = new ResizeObserver(() => this._measureViewport()), this._hostResizeObserver.observe(this));
1871
+ super.connectedCallback(), this._onScroll = this._onScroll.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onDocumentClick = this._onDocumentClick.bind(this), this._onContextMenu = this._onContextMenu.bind(this), this._onDragover = this._onDragover.bind(this), this._onDragleave = this._onDragleave.bind(this), this._onDrop = this._onDrop.bind(this), this.addEventListener("scroll", this._onScroll, { passive: !0 }), this.addEventListener("keydown", this._onKeyDown), this.addEventListener("contextmenu", this._onContextMenu), this.addEventListener("dragover", this._onDragover), this.addEventListener("dragleave", this._onDragleave), this.addEventListener("drop", this._onDrop), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "0"), this.setAttribute("role", "grid"), typeof ResizeObserver < "u" && (this._hostResizeObserver = new ResizeObserver(() => this._measureViewport()), this._hostResizeObserver.observe(this));
1562
1872
  }
1563
1873
  disconnectedCallback() {
1564
- super.disconnectedCallback(), this.removeEventListener("scroll", this._onScroll), this.removeEventListener("keydown", this._onKeyDown), this.removeEventListener("contextmenu", this._onContextMenu), document.removeEventListener("click", this._onDocumentClick), this._isDragging = !1, this._wasDrag = !1, this._resizeCleanup &&= (this._resizeCleanup(), null), this._hostResizeObserver &&= (this._hostResizeObserver.disconnect(), null);
1874
+ super.disconnectedCallback(), this.removeEventListener("scroll", this._onScroll), this.removeEventListener("keydown", this._onKeyDown), this.removeEventListener("contextmenu", this._onContextMenu), this.removeEventListener("dragover", this._onDragover), this.removeEventListener("dragleave", this._onDragleave), this.removeEventListener("drop", this._onDrop), document.removeEventListener("click", this._onDocumentClick), this._isDragging = !1, this._wasDrag = !1, this._resizeCleanup &&= (this._resizeCleanup(), null), this._hostResizeObserver &&= (this._hostResizeObserver.disconnect(), null);
1565
1875
  }
1566
1876
  firstUpdated() {
1567
1877
  this._measureViewport();
@@ -1609,7 +1919,7 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
1609
1919
  this._filteredIndices = Array.from({ length: this.data.length }, (e, t) => t), this._sortedIndices = this._filteredIndices;
1610
1920
  return;
1611
1921
  }
1612
- if (this._filteredIndices = w(this.data, this._filters, (e, t, n) => {
1922
+ if (this._filteredIndices = T(this.data, this._filters, (e, t, n) => {
1613
1923
  this.dispatchEvent(new CustomEvent("filter-error", {
1614
1924
  detail: {
1615
1925
  error: e,
@@ -1748,7 +2058,7 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
1748
2058
  }
1749
2059
  let t = this.shadowRoot?.querySelector(".ft-editor");
1750
2060
  if (t) {
1751
- let n = D(t.value, e);
2061
+ let n = k(t.value, e);
1752
2062
  this._applyEdit(n);
1753
2063
  } else this._cancelEdit();
1754
2064
  }
@@ -1970,7 +2280,7 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
1970
2280
  async _handleCopy(e) {
1971
2281
  let t = this._selection.getEffectiveRange();
1972
2282
  if (!t) return;
1973
- let n = this.visibleColumns, r = te(this._sortedIndices.map((e) => this.data[e]), n, t);
2283
+ let n = this.visibleColumns, r = ee(this._sortedIndices.map((e) => this.data[e]), n, t);
1974
2284
  try {
1975
2285
  await navigator.clipboard.writeText(r);
1976
2286
  } catch (e) {
@@ -1996,7 +2306,7 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
1996
2306
  if (!this._activeCell) return;
1997
2307
  let e = await this._readClipboardText();
1998
2308
  if (e == null) return;
1999
- let t = ne(e);
2309
+ let t = O(e);
2000
2310
  if (t.length === 0) return;
2001
2311
  let n = this._expandRowsForPaste(this._activeCell.row, t.length), r = this._applyPasteData(this._activeCell, t);
2002
2312
  if (r.length > 0 || n.length > 0) {
@@ -2054,7 +2364,7 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
2054
2364
  for (let a = 0; a < t[i].length; a++) {
2055
2365
  let s = e.col + a;
2056
2366
  if (s >= n.length) break;
2057
- let c = n[s], l = this.data[o][c.key], u = D(t[i][a], c);
2367
+ let c = n[s], l = this.data[o][c.key], u = k(t[i][a], c);
2058
2368
  this.data[o][c.key] = u, r.push({
2059
2369
  row: o,
2060
2370
  col: s,
@@ -2119,7 +2429,7 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
2119
2429
  for (let r = e.startCol + 1; r <= e.endCol; r++) {
2120
2430
  let e = t[r];
2121
2431
  if (!e || !this._isCellEditable(e)) continue;
2122
- let a = D(o == null ? "" : String(o), e);
2432
+ let a = k(o == null ? "" : String(o), e);
2123
2433
  n.push({
2124
2434
  row: i,
2125
2435
  key: e.key,
@@ -2193,7 +2503,7 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
2193
2503
  _scrollToActiveCell() {
2194
2504
  if (!this._activeCell) return;
2195
2505
  let e = this._activeCell.row * this.rowHeight + this.headerHeight, t = e + this.rowHeight;
2196
- e < this.scrollTop + this.headerHeight ? this.scrollTop = e - this.headerHeight : t > this.scrollTop + this.clientHeight && (this.scrollTop = t - this.clientHeight);
2506
+ this._activeCell.row < this._frozenRowCount || (e < this.scrollTop + this.headerHeight + this.frozenRowsHeight ? this.scrollTop = e - this.headerHeight - this.frozenRowsHeight : t > this.scrollTop + this.clientHeight && (this.scrollTop = t - this.clientHeight));
2197
2507
  let n = this.visibleColumns, r = this._activeCell.col, i = this._colLeftOffsets[r] ?? 0, a = i + this._getColWidth(n[r]);
2198
2508
  i < this.scrollLeft ? this.scrollLeft = i : a > this.scrollLeft + this.clientWidth && (this.scrollLeft = a - this.clientWidth);
2199
2509
  }
@@ -2210,7 +2520,7 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
2210
2520
  this._selectColumn(n);
2211
2521
  return;
2212
2522
  }
2213
- t.sortable !== !1 && (this._sortCriteria = C(this._sortCriteria, t.key, e.shiftKey), this.dataMode !== "server" && this._recomputeView(), this.requestUpdate(), this.dispatchEvent(new CustomEvent("sort-change", {
2523
+ t.sortable !== !1 && (this._sortCriteria = w(this._sortCriteria, t.key, e.shiftKey), this.dataMode !== "server" && this._recomputeView(), this.requestUpdate(), this.dispatchEvent(new CustomEvent("sort-change", {
2214
2524
  detail: { criteria: [...this._sortCriteria] },
2215
2525
  bubbles: !0,
2216
2526
  composed: !0
@@ -2451,36 +2761,215 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
2451
2761
  </div>
2452
2762
  `;
2453
2763
  }
2764
+ _buildTextPredicate(e, t) {
2765
+ let n = e.toLowerCase();
2766
+ switch (t) {
2767
+ case "starts": return (e) => String(e ?? "").toLowerCase().startsWith(n);
2768
+ case "ends": return (e) => String(e ?? "").toLowerCase().endsWith(n);
2769
+ case "wildcard": {
2770
+ let e = n.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, "."), t = RegExp("^" + e + "$", "i");
2771
+ return (e) => t.test(String(e ?? ""));
2772
+ }
2773
+ default: return (e) => String(e ?? "").toLowerCase().includes(n);
2774
+ }
2775
+ }
2776
+ _applyTextFilter(e) {
2777
+ let t = this._emptyFilterState.get(e);
2778
+ if (t) {
2779
+ this.setFilter(e, this._buildEmptyPredicate(t));
2780
+ return;
2781
+ }
2782
+ let n = this._textFilterState.get(e);
2783
+ n?.value ? this.setFilter(e, this._buildTextPredicate(n.value, n.mode)) : this.removeFilter(e);
2784
+ }
2785
+ _buildEmptyPredicate(e) {
2786
+ return e === "empty" ? (e) => e == null || e === "" : (e) => e != null && e !== "";
2787
+ }
2788
+ _renderEmptyFilterRow(e, t) {
2789
+ return n`
2790
+ <div class="ft-filter-empty-row">
2791
+ <label>Blank cells</label>
2792
+ <select class="ft-filter-mode-select"
2793
+ .value=${this._emptyFilterState.get(e) ?? ""}
2794
+ @change=${(n) => {
2795
+ let r = n.target.value;
2796
+ (r === "" || r === "empty" || r === "non-empty") && (r ? this._emptyFilterState.set(e, r) : this._emptyFilterState.delete(e), t?.(), this._applyFilterForKey(e));
2797
+ }}
2798
+ @keydown=${(e) => {
2799
+ e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
2800
+ }}>
2801
+ <option value="">— All —</option>
2802
+ <option value="empty">Empty only</option>
2803
+ <option value="non-empty">Non-empty only</option>
2804
+ </select>
2805
+ </div>
2806
+ `;
2807
+ }
2808
+ _evalNumCond(e, t) {
2809
+ let n = t.value;
2810
+ switch (t.op) {
2811
+ case "eq": return e === n;
2812
+ case "neq": return e !== n;
2813
+ case "gt": return e > n;
2814
+ case "lt": return e < n;
2815
+ case "gte": return e >= n;
2816
+ case "lte": return e <= n;
2817
+ }
2818
+ }
2819
+ _buildNumberPredicate(e) {
2820
+ let t = e.cond1.value != null, n = e.cond2.value != null;
2821
+ return !t && !n ? null : (r) => {
2822
+ let i = Number(r);
2823
+ if (isNaN(i)) return !1;
2824
+ if (t && !n) return this._evalNumCond(i, e.cond1);
2825
+ if (!t && n) return this._evalNumCond(i, e.cond2);
2826
+ let a = this._evalNumCond(i, e.cond1), o = this._evalNumCond(i, e.cond2);
2827
+ return e.join === "or" ? a || o : a && o;
2828
+ };
2829
+ }
2830
+ _buildDatePredicate(e) {
2831
+ return e.from == null && e.to == null ? null : (t) => {
2832
+ if (t == null || t === "") return !1;
2833
+ let n = t instanceof Date ? t : new Date(String(t));
2834
+ if (isNaN(n.getTime()) || e.from && n < new Date(e.from)) return !1;
2835
+ if (e.to) {
2836
+ let t = new Date(e.to);
2837
+ if (e.to.length === 10 && t.setHours(23, 59, 59, 999), n > t) return !1;
2838
+ }
2839
+ return !0;
2840
+ };
2841
+ }
2842
+ _applyFilterForKey(e) {
2843
+ let t = this._emptyFilterState.get(e);
2844
+ if (t) {
2845
+ this.setFilter(e, this._buildEmptyPredicate(t));
2846
+ return;
2847
+ }
2848
+ if (this._textFilterState.has(e)) this._applyTextFilter(e);
2849
+ else if (this._numberFilterState.has(e)) {
2850
+ let t = this._buildNumberPredicate(this._numberFilterState.get(e));
2851
+ t ? this.setFilter(e, t) : this.removeFilter(e);
2852
+ } else if (this._dateFilterState.has(e)) {
2853
+ let t = this._buildDatePredicate(this._dateFilterState.get(e));
2854
+ t ? this.setFilter(e, t) : this.removeFilter(e);
2855
+ } else this.removeFilter(e);
2856
+ }
2454
2857
  _renderTextFilter(e) {
2858
+ let t = this._textFilterState.get(e.key) ?? {
2859
+ value: "",
2860
+ mode: "contains"
2861
+ };
2455
2862
  return n`
2863
+ <div class="ft-filter-mode-row">
2864
+ <select class="ft-filter-mode-select"
2865
+ .value=${t.mode}
2866
+ @change=${(t) => {
2867
+ let n = t.target.value, r = this._textFilterState.get(e.key) ?? {
2868
+ value: "",
2869
+ mode: "contains"
2870
+ };
2871
+ this._textFilterState.set(e.key, {
2872
+ ...r,
2873
+ mode: n
2874
+ }), this._applyTextFilter(e.key);
2875
+ }}
2876
+ @keydown=${(e) => {
2877
+ e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
2878
+ }}>
2879
+ <option value="contains">Contains</option>
2880
+ <option value="starts">Starts with</option>
2881
+ <option value="ends">Ends with</option>
2882
+ <option value="wildcard">Wildcard</option>
2883
+ </select>
2884
+ </div>
2456
2885
  <input class="ft-filter-input" type="text" placeholder="Search..."
2457
- .value=${this._textFilterState.get(e.key) ?? ""}
2886
+ .value=${t.value}
2458
2887
  @input=${(t) => {
2459
- let n = t.target.value;
2460
- this._textFilterState.set(e.key, n), n ? this.setFilter(e.key, (e) => String(e ?? "").toLowerCase().includes(n.toLowerCase())) : this.removeFilter(e.key);
2888
+ let n = t.target.value, r = this._textFilterState.get(e.key) ?? {
2889
+ value: "",
2890
+ mode: "contains"
2891
+ };
2892
+ this._textFilterState.set(e.key, {
2893
+ ...r,
2894
+ value: n
2895
+ }), this._emptyFilterState.delete(e.key), this._applyTextFilter(e.key);
2461
2896
  }}
2462
2897
  @keydown=${(e) => {
2463
2898
  e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
2464
2899
  }}>
2900
+ ${this._renderEmptyFilterRow(e.key, () => {
2901
+ this._textFilterState.delete(e.key);
2902
+ })}
2465
2903
  `;
2466
2904
  }
2467
- _renderNumberFilter(e) {
2468
- let t = this._numberFilterState.get(e.key) ?? {};
2905
+ _defaultNumState() {
2906
+ return {
2907
+ cond1: {
2908
+ op: "gte",
2909
+ value: null
2910
+ },
2911
+ join: "and",
2912
+ cond2: {
2913
+ op: "lte",
2914
+ value: null
2915
+ }
2916
+ };
2917
+ }
2918
+ _renderNumCondRow(e, t) {
2919
+ let r = (this._numberFilterState.get(e) ?? this._defaultNumState())[t];
2469
2920
  return n`
2470
- <div class="ft-filter-range">
2471
- <input class="ft-filter-input" type="number" placeholder="Min"
2472
- .value=${t.min == null ? "" : String(t.min)}
2473
- @input=${(t) => this._applyNumberFilter(e.key, t, "min")}
2921
+ <div class="ft-num-cond-row">
2922
+ <select class="ft-filter-mode-select ft-num-op-select"
2923
+ .value=${r.op}
2924
+ @change=${(n) => {
2925
+ let r = n.target.value, i = this._numberFilterState.get(e) ?? this._defaultNumState();
2926
+ i[t] = {
2927
+ ...i[t],
2928
+ op: r
2929
+ }, this._numberFilterState.set(e, i), this._emptyFilterState.delete(e), this._applyFilterForKey(e);
2930
+ }}
2931
+ @keydown=${(e) => {
2932
+ e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
2933
+ }}>
2934
+ ${Object.keys(Y).map((e) => n`<option value=${e}>${Y[e]}</option>`)}
2935
+ </select>
2936
+ <input class="ft-filter-input ft-num-cond-input" type="number" placeholder="Value"
2937
+ .value=${r.value == null ? "" : String(r.value)}
2938
+ @input=${(n) => {
2939
+ let r = n.target.value, i = this._numberFilterState.get(e) ?? this._defaultNumState();
2940
+ i[t] = {
2941
+ ...i[t],
2942
+ value: r === "" ? null : Number(r)
2943
+ }, this._numberFilterState.set(e, i), this._emptyFilterState.delete(e), this._applyFilterForKey(e);
2944
+ }}
2474
2945
  @keydown=${(e) => {
2475
2946
  e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
2476
2947
  }}>
2477
- <input class="ft-filter-input" type="number" placeholder="Max"
2478
- .value=${t.max == null ? "" : String(t.max)}
2479
- @input=${(t) => this._applyNumberFilter(e.key, t, "max")}
2948
+ </div>
2949
+ `;
2950
+ }
2951
+ _renderNumberFilter(e) {
2952
+ let t = this._numberFilterState.get(e.key) ?? this._defaultNumState();
2953
+ return n`
2954
+ ${this._renderNumCondRow(e.key, "cond1")}
2955
+ <div class="ft-filter-mode-row">
2956
+ <select class="ft-filter-mode-select"
2957
+ .value=${t.join}
2958
+ @change=${(t) => {
2959
+ let n = t.target.value, r = this._numberFilterState.get(e.key) ?? this._defaultNumState();
2960
+ r.join = n, this._numberFilterState.set(e.key, r), this._emptyFilterState.delete(e.key), this._applyFilterForKey(e.key);
2961
+ }}
2480
2962
  @keydown=${(e) => {
2481
2963
  e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
2482
2964
  }}>
2965
+ <option value="and">AND</option>
2966
+ <option value="or">OR</option>
2967
+ </select>
2483
2968
  </div>
2969
+ ${this._renderNumCondRow(e.key, "cond2")}
2970
+ ${this._renderEmptyFilterRow(e.key, () => {
2971
+ this._numberFilterState.delete(e.key);
2972
+ })}
2484
2973
  `;
2485
2974
  }
2486
2975
  _cellKey(e, t) {
@@ -2501,13 +2990,6 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
2501
2990
  let n = this._invalidCells.get(this._cellKey(e, t));
2502
2991
  return n ? n.error : null;
2503
2992
  }
2504
- _applyNumberFilter(e, t, n) {
2505
- let r = t.target.value, i = this._numberFilterState.get(e) ?? {};
2506
- r === "" ? delete i[n] : i[n] = Number(r), this._numberFilterState.set(e, i), i.min == null && i.max == null ? this.removeFilter(e) : this.setFilter(e, (e) => {
2507
- let t = Number(e);
2508
- return !(isNaN(t) || i.min != null && t < i.min || i.max != null && t > i.max);
2509
- });
2510
- }
2511
2993
  _renderDateFilter(e) {
2512
2994
  let t = e.type === "datetime" ? "datetime-local" : "date", r = this._dateFilterState.get(e.key) ?? {};
2513
2995
  return n`
@@ -2525,20 +3007,14 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
2525
3007
  e.key === "Escape" && (this._openFilterKey = null), e.stopPropagation();
2526
3008
  }}>
2527
3009
  </div>
3010
+ ${this._renderEmptyFilterRow(e.key, () => {
3011
+ this._dateFilterState.delete(e.key);
3012
+ })}
2528
3013
  `;
2529
3014
  }
2530
3015
  _applyDateFilter(e, t, n) {
2531
3016
  let r = t.target.value, i = this._dateFilterState.get(e) ?? {};
2532
- r === "" ? delete i[n] : i[n] = r, this._dateFilterState.set(e, i), i.from == null && i.to == null ? this.removeFilter(e) : this.setFilter(e, (e) => {
2533
- if (e == null || e === "") return !1;
2534
- let t = e instanceof Date ? e : new Date(String(e));
2535
- if (isNaN(t.getTime()) || i.from && t < new Date(i.from)) return !1;
2536
- if (i.to) {
2537
- let e = new Date(i.to);
2538
- if (i.to.length === 10 && e.setHours(23, 59, 59, 999), t > e) return !1;
2539
- }
2540
- return !0;
2541
- });
3017
+ r === "" ? delete i[n] : i[n] = r, this._dateFilterState.set(e, i), this._emptyFilterState.delete(e), this._applyFilterForKey(e);
2542
3018
  }
2543
3019
  _renderBooleanFilter(e) {
2544
3020
  return n`
@@ -2554,10 +3030,11 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
2554
3030
  <option value="true">\u2714 True</option>
2555
3031
  <option value="false">\u2718 False</option>
2556
3032
  </select>
3033
+ ${this._renderEmptyFilterRow(e.key)}
2557
3034
  `;
2558
3035
  }
2559
3036
  _clearColumnFilter(e) {
2560
- this.removeFilter(e), this._textFilterState.delete(e), this._numberFilterState.delete(e), this._dateFilterState.delete(e), this._openFilterKey = null;
3037
+ this.removeFilter(e), this._textFilterState.delete(e), this._numberFilterState.delete(e), this._dateFilterState.delete(e), this._emptyFilterState.delete(e), this._openFilterKey = null;
2561
3038
  }
2562
3039
  _onResizeAutoFit(e, t) {
2563
3040
  e.preventDefault(), e.stopPropagation();
@@ -2999,12 +3476,12 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
2999
3476
  `;
3000
3477
  }
3001
3478
  render() {
3002
- let e = this.visibleColumns;
3003
- if (e.length === 0) return n`<div class="ft-empty">No columns defined</div>`;
3004
- let t = this.headerHeight, r = this._totalRowWidth, { start: i, end: a } = this.visibleColRange, o = [];
3005
- for (let t = 0; t < e.length; t++) (e[t].pinned === "left" || e[t].pinned === "right") && (t < i || t >= a) && o.push(t);
3006
- let s = 0, c = this._scrollLeft, l = this.selectable ? n`<div class="ft-checkbox-header"
3007
- style="position: absolute; top: 0; left: ${c + s}px; width: 36px; height: ${t}px; z-index: 4;">
3479
+ let e = this.visibleColumns, t = this.importEnabled && this._isDragOver ? n`<div class="ft-import-overlay">Drop file to import (.xlsx / .csv)</div>` : r;
3480
+ if (e.length === 0) return n`${t}<div class="ft-empty">No columns defined</div>`;
3481
+ let i = this.headerHeight, a = this._totalRowWidth, { start: o, end: s } = this.visibleColRange, c = [];
3482
+ for (let t = 0; t < e.length; t++) (e[t].pinned === "left" || e[t].pinned === "right") && (t < o || t >= s) && c.push(t);
3483
+ let l = 0, u = this._scrollLeft, d = this.selectable ? n`<div class="ft-checkbox-header"
3484
+ style="position: absolute; top: 0; left: ${u + l}px; width: 36px; height: ${i}px; z-index: 4;">
3008
3485
  ${this._rowSelection.mode === "multi" ? n`
3009
3486
  <input type="checkbox"
3010
3487
  .checked=${this._rowSelection.isAllSelected}
@@ -3012,36 +3489,38 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
3012
3489
  @change=${this._onSelectAllChange}>
3013
3490
  ` : ""}
3014
3491
  </div>` : "";
3015
- this.selectable && (s += 36);
3016
- let u = this.showRowNumbers ? n`<div class="ft-row-num-header"
3017
- style="position: absolute; top: 0; left: ${c + s}px; width: 48px; height: ${t}px; z-index: 4;">#</div>` : "", d = [];
3018
- for (let t of o) d.push(this._renderHeaderCell(e[t], t));
3019
- for (let t = i; t < a; t++) d.push(this._renderHeaderCell(e[t], t));
3020
- let f = this._colDragIndicatorLeft == null ? "" : n`<div class="ft-drop-indicator" style="left:${this._colDragIndicatorLeft}px"></div>`;
3492
+ this.selectable && (l += 36);
3493
+ let f = this.showRowNumbers ? n`<div class="ft-row-num-header"
3494
+ style="position: absolute; top: 0; left: ${u + l}px; width: 48px; height: ${i}px; z-index: 4;">#</div>` : "", p = [];
3495
+ for (let t of c) p.push(this._renderHeaderCell(e[t], t));
3496
+ for (let t = o; t < s; t++) p.push(this._renderHeaderCell(e[t], t));
3497
+ let m = this._colDragIndicatorLeft == null ? "" : n`<div class="ft-drop-indicator" style="left:${this._colDragIndicatorLeft}px"></div>`;
3021
3498
  if (this.data.length === 0 || this._visibleRowCount === 0) return n`
3022
- <div class="ft-header" role="row" style="width: ${r}px; height: ${t}px;">
3023
- ${l}${u}
3024
- ${d}
3025
- ${f}
3499
+ <div class="ft-header" role="row" style="width: ${a}px; height: ${i}px;">
3500
+ ${d}${f}
3501
+ ${p}
3502
+ ${m}
3026
3503
  </div>
3027
3504
  <div class="ft-empty">${this.data.length === 0 ? "No data" : "No matching data"}</div>
3028
3505
  `;
3029
- let { start: p, end: m } = this.visibleRange, h = [];
3030
- for (let e = p; e < m; e++) h.push(this._renderRow(e, i, a, o));
3031
- let g = this._renderFillHandle(), _ = this._rowDragIndicatorY == null ? "" : n`<div class="ft-row-drop-indicator" style="top:${this._rowDragIndicatorY}px;width:${r + this._prefixWidth}px;"></div>`;
3506
+ let { start: h, end: g } = this.visibleRange, _ = this._frozenRowCount, v = [];
3507
+ for (let e = h; e < g; e++) v.push(this._renderRow(e, o, s, c, (e - _) * this.rowHeight));
3508
+ let y = this._renderFillHandle(), b = this._rowDragIndicatorY == null ? "" : n`<div class="ft-row-drop-indicator" style="top:${this._rowDragIndicatorY}px;width:${a + this._prefixWidth}px;"></div>`;
3032
3509
  return n`
3510
+ ${t}
3033
3511
  ${this._renderFindPanel()}
3034
- <div class="ft-header" role="row" style="width: ${r}px; height: ${t}px;">
3035
- ${l}${u}
3036
- ${d}
3037
- ${f}
3512
+ <div class="ft-header" role="row" style="width: ${a}px; height: ${i}px;">
3513
+ ${d}${f}
3514
+ ${p}
3515
+ ${m}
3038
3516
  </div>
3039
- <div class="ft-body" style="height: ${this.totalBodyHeight}px; width: ${r}px;">
3040
- ${h}
3517
+ ${this._renderFrozenRows(o, s, c)}
3518
+ <div class="ft-body" style="height: ${this.totalBodyHeight}px; width: ${a}px;">
3519
+ ${v}
3041
3520
  </div>
3042
- ${this.footerData ? this._renderFooter(i, a, o) : ""}
3043
- ${_}
3044
- ${g}
3521
+ ${this.footerData ? this._renderFooter(o, s, c) : ""}
3522
+ ${b}
3523
+ ${y}
3045
3524
  ${this._renderHeaderContextMenu()}
3046
3525
  ${this._renderBodyContextMenu()}
3047
3526
  `;
@@ -3052,6 +3531,17 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
3052
3531
  _onRowCheckboxChange(e, t) {
3053
3532
  e.stopPropagation(), this._rowSelection.toggle(t), this._rowSelectionVersion++, this._dispatchRowSelectionEvent();
3054
3533
  }
3534
+ _renderFrozenRows(e, t, i) {
3535
+ let a = this._frozenRowCount;
3536
+ if (a === 0) return r;
3537
+ let o = this._totalRowWidth, s = [];
3538
+ for (let n = 0; n < a; n++) s.push(this._renderRow(n, e, t, i, n * this.rowHeight));
3539
+ return n`
3540
+ <div class="ft-frozen-rows" style="top: ${this.headerHeight}px; height: ${this.frozenRowsHeight}px; width: ${o}px;">
3541
+ ${s}
3542
+ </div>
3543
+ `;
3544
+ }
3055
3545
  _renderFooter(e, t, r) {
3056
3546
  if (!this.footerData) return "";
3057
3547
  let i = this.visibleColumns, a = this.rowHeight, o = this._totalRowWidth, s = this._scrollLeft, c = 0, l = this.selectable ? n`<div class="ft-footer-cell ft-checkbox-cell"
@@ -3080,29 +3570,29 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
3080
3570
  </div>
3081
3571
  `;
3082
3572
  }
3083
- _renderRow(e, t, r, i) {
3084
- let a = this.visibleColumns, o = this._toDataIndex(e), s = this.data[o], c = e * this.rowHeight, l = this.rowHeight, u = this._totalRowWidth, d = e % 2 == 0 ? "ft-row-even" : "ft-row-odd", f = this.selectable && this._rowSelection.isSelected(e), p = this._scrollLeft, m = 0, h = this.selectable ? n`
3573
+ _renderRow(e, t, r, i, a) {
3574
+ let o = this.visibleColumns, s = this._toDataIndex(e), c = this.data[s], l = a ?? e * this.rowHeight, u = this.rowHeight, d = this._totalRowWidth, f = e % 2 == 0 ? "ft-row-even" : "ft-row-odd", p = this.selectable && this._rowSelection.isSelected(e), m = this._scrollLeft, h = 0, g = this.selectable ? n`
3085
3575
  <div class="ft-checkbox-cell"
3086
- style="position: absolute; top: 0; left: ${p + m}px; width: 36px; height: ${l}px; z-index: 2;">
3576
+ style="position: absolute; top: 0; left: ${m + h}px; width: 36px; height: ${u}px; z-index: 2;">
3087
3577
  <input type="checkbox"
3088
- .checked=${f}
3578
+ .checked=${p}
3089
3579
  @change=${(t) => this._onRowCheckboxChange(t, e)}>
3090
3580
  </div>
3091
3581
  ` : "";
3092
- this.selectable && (m += 36);
3093
- let g = this._rowDrag?.active && this._rowDrag.rowIndex === e, _ = this.showRowNumbers ? n`
3094
- <div class="ft-row-num ${g ? "ft-col-dragging" : ""}"
3095
- style="position: absolute; top: 0; left: ${p + m}px; width: 48px; height: ${l}px; z-index: 2; cursor: grab;"
3582
+ this.selectable && (h += 36);
3583
+ let _ = this._rowDrag?.active && this._rowDrag.rowIndex === e, v = this.showRowNumbers ? n`
3584
+ <div class="ft-row-num ${_ ? "ft-col-dragging" : ""}"
3585
+ style="position: absolute; top: 0; left: ${m + h}px; width: 48px; height: ${u}px; z-index: 2; cursor: grab;"
3096
3586
  @mousedown=${(t) => this._onRowNumMouseDown(t, e)}
3097
- @click=${() => this._onRowNumberClick(e)}>${o + 1}</div>
3098
- ` : "", v = [];
3099
- for (let t of i) v.push(this._renderCell(s, a[t], e, t));
3100
- for (let n = t; n < r; n++) v.push(this._renderCell(s, a[n], e, n));
3587
+ @click=${() => this._onRowNumberClick(e)}>${s + 1}</div>
3588
+ ` : "", y = [];
3589
+ for (let t of i) y.push(this._renderCell(c, o[t], e, t));
3590
+ for (let n = t; n < r; n++) y.push(this._renderCell(c, o[n], e, n));
3101
3591
  return n`
3102
- <div class="ft-row ${d} ${f ? "ft-row-selected" : ""}" role="row"
3103
- style="top: ${c}px; height: ${l}px; width: ${u}px;">
3104
- ${h}${_}
3105
- ${v}
3592
+ <div class="ft-row ${f} ${p ? "ft-row-selected" : ""}" role="row"
3593
+ style="top: ${l}px; height: ${u}px; width: ${d}px;">
3594
+ ${g}${v}
3595
+ ${y}
3106
3596
  </div>
3107
3597
  `;
3108
3598
  }
@@ -3125,9 +3615,7 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
3125
3615
  ${this._renderEditor(e, t)}
3126
3616
  </div>
3127
3617
  `;
3128
- let v = o || c, y = this._isCellInvalid(i, a), b = (this._findState?.results ?? []).findIndex((e) => e.row === i && e.col === a), x = b >= 0, S = x && b === this._findState.currentIndex;
3129
- return n`
3130
- <div class=${[
3618
+ let v = o || c, y = this._isCellInvalid(i, a), b = (this._findState?.results ?? []).findIndex((e) => e.row === i && e.col === a), x = b >= 0, S = x && b === this._findState.currentIndex, C = [
3131
3619
  "ft-cell",
3132
3620
  `ft-type-${t.type ?? "text"}`,
3133
3621
  o ? "ft-active" : "",
@@ -3135,7 +3623,9 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
3135
3623
  d ? "ft-pinned" : "",
3136
3624
  y ? "ft-invalid" : "",
3137
3625
  S ? "ft-find-current" : x ? "ft-find-match" : ""
3138
- ].filter(Boolean).join(" ")}
3626
+ ].filter(Boolean).join(" "), w = this._toDataIndex(i), T = this._comments.get(w)?.get(t.key) ?? null, E = T !== null, D = E ? n`<div class="ft-comment-indicator" title=${T}></div>` : r;
3627
+ return n`
3628
+ <div class=${E ? C + " ft-has-comment" : C}
3139
3629
  role="gridcell"
3140
3630
  data-col-index=${a}
3141
3631
  aria-selected=${v ? "true" : "false"}
@@ -3147,6 +3637,7 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
3147
3637
  @mouseenter=${() => this._onCellMouseEnter(i, a)}
3148
3638
  @click=${(e) => this._onCellClickEvent(e, i, a)}
3149
3639
  @dblclick=${() => this._onCellDblClick(i, a)}>
3640
+ ${D}
3150
3641
  ${f(e[t.key], e, t)}
3151
3642
  </div>
3152
3643
  `;
@@ -3223,39 +3714,45 @@ var X = 120, Z = 40, ce = 32, Q = 5, $ = class extends e {
3223
3714
  return isNaN(t.getTime()) ? "" : `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, "0")}-${String(t.getDate()).padStart(2, "0")}T${String(t.getHours()).padStart(2, "0")}:${String(t.getMinutes()).padStart(2, "0")}`;
3224
3715
  }
3225
3716
  };
3226
- Y([a({ type: Array })], $.prototype, "columns", void 0), Y([a({
3717
+ J([a({ type: Array })], $.prototype, "columns", void 0), J([a({
3227
3718
  type: Array,
3228
3719
  hasChanged: () => !0
3229
- })], $.prototype, "data", void 0), Y([a({
3720
+ })], $.prototype, "data", void 0), J([a({
3230
3721
  type: Number,
3231
3722
  attribute: "row-height"
3232
- })], $.prototype, "rowHeight", void 0), Y([a({
3723
+ })], $.prototype, "rowHeight", void 0), J([a({
3233
3724
  type: Boolean,
3234
3725
  attribute: "show-row-numbers"
3235
- })], $.prototype, "showRowNumbers", void 0), Y([a({
3726
+ })], $.prototype, "showRowNumbers", void 0), J([a({
3236
3727
  type: String,
3237
3728
  reflect: !0
3238
- })], $.prototype, "theme", void 0), Y([a({
3729
+ })], $.prototype, "theme", void 0), J([a({
3239
3730
  type: Number,
3240
3731
  attribute: "max-rows"
3241
- })], $.prototype, "maxRows", void 0), Y([a({ type: Boolean })], $.prototype, "editable", void 0), Y([a({
3732
+ })], $.prototype, "maxRows", void 0), J([a({ type: Boolean })], $.prototype, "editable", void 0), J([a({
3242
3733
  type: Boolean,
3243
3734
  attribute: "show-filters"
3244
- })], $.prototype, "showFilters", void 0), Y([a({
3735
+ })], $.prototype, "showFilters", void 0), J([a({
3245
3736
  type: Boolean,
3246
3737
  attribute: "show-context-menu"
3247
- })], $.prototype, "showContextMenu", void 0), Y([a({ type: Boolean })], $.prototype, "selectable", void 0), Y([a({
3738
+ })], $.prototype, "showContextMenu", void 0), J([a({
3739
+ type: Number,
3740
+ attribute: "frozen-rows"
3741
+ })], $.prototype, "frozenRows", void 0), J([a({
3742
+ type: Boolean,
3743
+ attribute: "import-enabled"
3744
+ })], $.prototype, "importEnabled", void 0), J([a({ type: Boolean })], $.prototype, "selectable", void 0), J([a({
3248
3745
  type: String,
3249
3746
  attribute: "selection-mode"
3250
- })], $.prototype, "selectionMode", null), Y([a({
3747
+ })], $.prototype, "selectionMode", null), J([a({
3251
3748
  type: String,
3252
3749
  attribute: "data-mode"
3253
- })], $.prototype, "dataMode", void 0), Y([a({
3750
+ })], $.prototype, "dataMode", void 0), J([a({
3254
3751
  type: Object,
3255
3752
  attribute: "footer-data"
3256
- })], $.prototype, "footerData", void 0), Y([a({
3753
+ })], $.prototype, "footerData", void 0), J([a({
3257
3754
  type: Number,
3258
3755
  attribute: "max-undo-size"
3259
- })], $.prototype, "maxUndoSize", null), Y([o()], $.prototype, "_scrollTop", void 0), Y([o()], $.prototype, "_scrollLeft", void 0), Y([o()], $.prototype, "_viewportHeight", void 0), Y([o()], $.prototype, "_viewportWidth", void 0), Y([o()], $.prototype, "_activeCell", void 0), Y([o()], $.prototype, "_editingCell", void 0), Y([o()], $.prototype, "_sortCriteria", void 0), Y([o()], $.prototype, "_openFilterKey", void 0), Y([o()], $.prototype, "_rowSelectionVersion", void 0), Y([o()], $.prototype, "_autocompleteState", void 0), Y([o()], $.prototype, "_headerMenu", void 0), Y([o()], $.prototype, "_bodyContextMenu", void 0), $ = Y([i("flex-table")], $);
3756
+ })], $.prototype, "maxUndoSize", null), J([o()], $.prototype, "_scrollTop", void 0), J([o()], $.prototype, "_scrollLeft", void 0), J([o()], $.prototype, "_viewportHeight", void 0), J([o()], $.prototype, "_viewportWidth", void 0), J([o()], $.prototype, "_activeCell", void 0), J([o()], $.prototype, "_editingCell", void 0), J([o()], $.prototype, "_sortCriteria", void 0), J([o()], $.prototype, "_openFilterKey", void 0), J([o()], $.prototype, "_rowSelectionVersion", void 0), J([o()], $.prototype, "_autocompleteState", void 0), J([o()], $.prototype, "_headerMenu", void 0), J([o()], $.prototype, "_bodyContextMenu", void 0), J([o()], $.prototype, "_isDragOver", void 0), $ = J([i("flex-table")], $);
3260
3757
  //#endregion
3261
- export { f as a, x as i, U as n, E as r, $ as t };
3758
+ export { f as a, x as i, B as n, D as r, $ as t };