@pixerate/editor 0.51.0 → 0.53.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.
Files changed (69) hide show
  1. package/dist/agent/index.cjs +23 -23
  2. package/dist/agent/index.js +4 -4
  3. package/dist/chart/index.cjs +475 -124
  4. package/dist/chart/index.cjs.map +1 -1
  5. package/dist/chart/index.d.cts +174 -25
  6. package/dist/chart/index.d.ts +174 -25
  7. package/dist/chart/index.js +375 -24
  8. package/dist/chart/index.js.map +1 -1
  9. package/dist/{chunk-GJBIVWB2.js → chunk-3S72F46R.js} +387 -9
  10. package/dist/chunk-3S72F46R.js.map +1 -0
  11. package/dist/{chunk-5TWIN7ZJ.js → chunk-47WWV3LI.js} +34 -4
  12. package/dist/chunk-47WWV3LI.js.map +1 -0
  13. package/dist/{chunk-OV7UAKIY.js → chunk-633QC34G.js} +172 -1
  14. package/dist/chunk-633QC34G.js.map +1 -0
  15. package/dist/{chunk-MR2764X2.js → chunk-AGGUNWT6.js} +2 -322
  16. package/dist/chunk-AGGUNWT6.js.map +1 -0
  17. package/dist/{chunk-T6XU4B54.js → chunk-BQQZ6MOI.js} +7 -7
  18. package/dist/{chunk-LNKZPIQD.cjs → chunk-C3JHII3M.cjs} +67 -67
  19. package/dist/{chunk-LNKZPIQD.cjs.map → chunk-C3JHII3M.cjs.map} +1 -1
  20. package/dist/{chunk-JOX6MJW4.cjs → chunk-CKRNELPO.cjs} +176 -5
  21. package/dist/chunk-CKRNELPO.cjs.map +1 -0
  22. package/dist/{chunk-TGBCBQFV.cjs → chunk-DK6QBGCS.cjs} +45 -15
  23. package/dist/chunk-DK6QBGCS.cjs.map +1 -0
  24. package/dist/{chunk-GTZXF4BI.cjs → chunk-NK3WL5TJ.cjs} +298 -133
  25. package/dist/chunk-NK3WL5TJ.cjs.map +1 -0
  26. package/dist/{chunk-3JNRQVTS.cjs → chunk-NN3JGUSX.cjs} +402 -24
  27. package/dist/chunk-NN3JGUSX.cjs.map +1 -0
  28. package/dist/{chunk-3CC7OPUQ.cjs → chunk-O6FO6VI3.cjs} +3 -323
  29. package/dist/chunk-O6FO6VI3.cjs.map +1 -0
  30. package/dist/{chunk-DQPBQXKG.js → chunk-OIKYP7XC.js} +8 -8
  31. package/dist/{chunk-FEMIVHN3.cjs → chunk-P43HUQRX.cjs} +16 -16
  32. package/dist/{chunk-FEMIVHN3.cjs.map → chunk-P43HUQRX.cjs.map} +1 -1
  33. package/dist/{chunk-QFTVLEVN.js → chunk-RIXTW3C4.js} +3 -3
  34. package/dist/{chunk-WBOAXDKD.js → chunk-VODBAO32.js} +222 -57
  35. package/dist/chunk-VODBAO32.js.map +1 -0
  36. package/dist/{chunk-2Q46FKZK.cjs → chunk-YZZMX6V7.cjs} +25 -25
  37. package/dist/{chunk-2Q46FKZK.cjs.map → chunk-YZZMX6V7.cjs.map} +1 -1
  38. package/dist/{controller-DS3drIvy.d.cts → controller-CX0QfSv0.d.cts} +53 -2
  39. package/dist/{controller-BdKzaxs2.d.ts → controller-DscWQbjO.d.ts} +53 -2
  40. package/dist/export/index.cjs +5 -5
  41. package/dist/export/index.js +4 -4
  42. package/dist/extensions/index.cjs +7 -7
  43. package/dist/extensions/index.d.cts +2 -2
  44. package/dist/extensions/index.d.ts +2 -2
  45. package/dist/extensions/index.js +6 -6
  46. package/dist/{index-Dt9lzydb.d.ts → index-CALDD35B.d.ts} +1 -1
  47. package/dist/{index-DOy9HzfC.d.cts → index-DIWB6xMf.d.cts} +1 -1
  48. package/dist/index.cjs +15 -14
  49. package/dist/index.cjs.map +1 -1
  50. package/dist/index.d.cts +6 -113
  51. package/dist/index.d.ts +6 -113
  52. package/dist/index.js +13 -12
  53. package/dist/index.js.map +1 -1
  54. package/dist/zip-4nG0YAH7.d.cts +110 -0
  55. package/dist/zip-4nG0YAH7.d.ts +110 -0
  56. package/package.json +1 -1
  57. package/dist/chunk-3CC7OPUQ.cjs.map +0 -1
  58. package/dist/chunk-3JNRQVTS.cjs.map +0 -1
  59. package/dist/chunk-5TWIN7ZJ.js.map +0 -1
  60. package/dist/chunk-GJBIVWB2.js.map +0 -1
  61. package/dist/chunk-GTZXF4BI.cjs.map +0 -1
  62. package/dist/chunk-JOX6MJW4.cjs.map +0 -1
  63. package/dist/chunk-MR2764X2.js.map +0 -1
  64. package/dist/chunk-OV7UAKIY.js.map +0 -1
  65. package/dist/chunk-TGBCBQFV.cjs.map +0 -1
  66. package/dist/chunk-WBOAXDKD.js.map +0 -1
  67. /package/dist/{chunk-T6XU4B54.js.map → chunk-BQQZ6MOI.js.map} +0 -0
  68. /package/dist/{chunk-DQPBQXKG.js.map → chunk-OIKYP7XC.js.map} +0 -0
  69. /package/dist/{chunk-QFTVLEVN.js.map → chunk-RIXTW3C4.js.map} +0 -0
@@ -6,7 +6,7 @@ import {
6
6
  isCartesianChart,
7
7
  normalizeChartSpec,
8
8
  parseChartColor
9
- } from "./chunk-OV7UAKIY.js";
9
+ } from "./chunk-633QC34G.js";
10
10
 
11
11
  // src/chart/ooxml.ts
12
12
  var CHART_OOXML_NS = "http://schemas.openxmlformats.org/drawingml/2006/chart";
@@ -81,6 +81,27 @@ var MARKERS = { circle: "circle", dot: "circle", square: "square", diamond: "dia
81
81
  var TREND_IN = { linear: "linear", exp: "exponential", log: "logarithmic", poly: "polynomial", power: "power", movingAvg: "moving-average" };
82
82
  var TREND_OUT = { linear: "linear", exponential: "exp", logarithmic: "log", polynomial: "poly", power: "power", "moving-average": "movingAvg" };
83
83
  var LEGEND_IN = { b: "bottom", t: "top", l: "left", r: "right", tr: "right" };
84
+ var ERR_IN = { fixedVal: "fixed", percentage: "percent", stdDev: "stddev", stdErr: "stderr", cust: "custom" };
85
+ var ERR_OUT = { fixed: "fixedVal", percent: "percentage", stddev: "stdDev", stderr: "stdErr", custom: "cust" };
86
+ function readErrorBars(e) {
87
+ const type = ERR_IN[val(e, "errValType") ?? "fixedVal"];
88
+ if (!type) return null;
89
+ const bars = { type };
90
+ const value = numberOf(val(e, "val"));
91
+ if (value !== null && type !== "custom" && type !== "stderr") bars.value = Math.abs(value);
92
+ if (type === "custom") {
93
+ const plus = kid(e, "plus");
94
+ const minus = kid(e, "minus");
95
+ const p = plus ? numbers(plus).map((v) => v === null ? null : Math.abs(v)) : [];
96
+ const m = minus ? numbers(minus).map((v) => v === null ? null : Math.abs(v)) : [];
97
+ if (p.some((v) => v !== null)) bars.plus = p;
98
+ if (m.some((v) => v !== null) && JSON.stringify(m) !== JSON.stringify(p)) bars.minus = m;
99
+ }
100
+ const direction = val(e, "errBarType");
101
+ if (direction === "plus" || direction === "minus") bars.direction = direction;
102
+ if (bool(val(e, "noEndCap"))) bars.cap = false;
103
+ return bars;
104
+ }
84
105
  function chartFromOoxml(xml, options = {}) {
85
106
  const issues = [];
86
107
  const unsupported = [];
@@ -240,7 +261,18 @@ function chartFromOoxml(xml, options = {}) {
240
261
  trends.push(line);
241
262
  }
242
263
  if (trends.length) out.trendlines = trends;
243
- if (kids(s, "errBars").length) unsupported.push("error bars");
264
+ for (const e of kids(s, "errBars")) {
265
+ const bars = readErrorBars(e);
266
+ if (!bars) {
267
+ unsupported.push(`error bars of type "${val(e, "errValType")}"`);
268
+ continue;
269
+ }
270
+ if (val(e, "errDir") === "x") {
271
+ if (type === "scatter" || type === "bubble") out.xErrorBars = bars;
272
+ else unsupported.push("x error bars on a category chart");
273
+ } else if (type === "pie" || type === "donut" || type === "radar") unsupported.push(`error bars on a ${type} chart`);
274
+ else out.errorBars = bars;
275
+ }
244
276
  series.push(out);
245
277
  }
246
278
  }
@@ -273,8 +305,15 @@ function chartFromOoxml(xml, options = {}) {
273
305
  const scaling = kid(a, "scaling");
274
306
  axis.min = numberOf(val(scaling, "min"));
275
307
  axis.max = numberOf(val(scaling, "max"));
276
- if (val(scaling, "orientation") === "maxMin") unsupported.push("a reversed axis");
277
- if (kid(scaling, "logBase")) unsupported.push("a logarithmic axis");
308
+ if (val(scaling, "orientation") === "maxMin") axis.reverse = true;
309
+ if (kid(scaling, "logBase")) {
310
+ if (a.localName !== "valAx") unsupported.push("a logarithmic category axis");
311
+ else {
312
+ axis.scale = "log";
313
+ const base = numberOf(val(scaling, "logBase")) ?? 10;
314
+ if (base !== 10) axis.logBase = base;
315
+ }
316
+ }
278
317
  axis.step = numberOf(val(a, "majorUnit"));
279
318
  const fmt = kid(a, "numFmt");
280
319
  const code = fmt?.getAttribute("formatCode");
@@ -384,6 +423,14 @@ function chartFormatToCode(format) {
384
423
  return d !== void 0 || format.prefix || format.suffix ? wrap(`#,##0${frac(d, 0)}`) : "General";
385
424
  }
386
425
  }
426
+ function errBarsXml(bars, dir) {
427
+ let x = `<c:errBars>${dir ? `<c:errDir val="${dir}"/>` : ""}<c:errBarType val="${bars.direction ?? "both"}"/><c:errValType val="${ERR_OUT[bars.type]}"/><c:noEndCap val="${bars.cap === false ? 1 : 0}"/>`;
428
+ if (bars.type === "custom") {
429
+ const plus = bars.plus ?? (bars.minus ?? []).map(() => null);
430
+ x += `<c:plus>${numLit(plus)}</c:plus><c:minus>${numLit(bars.minus ?? plus)}</c:minus>`;
431
+ } else if (bars.type !== "stderr") x += `<c:val val="${bars.value ?? (bars.type === "percent" ? 5 : 1)}"/>`;
432
+ return `${x}</c:errBars>`;
433
+ }
387
434
  var MARKER_OUT = { circle: "circle", square: "square", diamond: "diamond", triangle: "triangle", cross: "x", none: "none" };
388
435
  function chartToOoxml(spec) {
389
436
  const issues = [];
@@ -442,6 +489,14 @@ function chartToOoxml(spec) {
442
489
  x += `<c:dispRSqr val="${t.showR2 ? 1 : 0}"/><c:dispEq val="${t.showEquation ? 1 : 0}"/></c:trendline>`;
443
490
  parts.push(x);
444
491
  }
492
+ if (!pieLike && kind !== "radar") {
493
+ const xyKind = kind === "scatter" || kind === "bubble";
494
+ if (s.errorBars) parts.push(errBarsXml(s.errorBars, xyKind ? "y" : null));
495
+ if (s.xErrorBars) {
496
+ if (xyKind) parts.push(errBarsXml(s.xErrorBars, "x"));
497
+ else issues.push(`"${s.name}" has x error bars, which only scatter and bubble charts can hold; they are left out.`);
498
+ }
499
+ } else if (s.errorBars || s.xErrorBars) issues.push(`Error bars on "${s.name}" are left out: ${kind} charts cannot show them.`);
445
500
  const valCode = chartFormatToCode(s.format ?? (s.axis === "secondary" ? spec.yAxis2.format : spec.yAxis.format));
446
501
  if (kind === "scatter" || kind === "bubble") {
447
502
  const xs = s.x ?? spec.categories.map((_, i) => i + 1);
@@ -484,7 +539,7 @@ function chartToOoxml(spec) {
484
539
  return `<c:pieChart><c:varyColors val="1"/>${sers}${dLbls}<c:firstSliceAng val="0"/></c:pieChart>`;
485
540
  }
486
541
  });
487
- const scaling = (a) => `<c:scaling><c:orientation val="minMax"/>${a.max !== null ? `<c:max val="${a.max}"/>` : ""}${a.min !== null ? `<c:min val="${a.min}"/>` : ""}</c:scaling>`;
542
+ const scaling = (a) => `<c:scaling>${a.scale === "log" ? `<c:logBase val="${a.logBase ?? 10}"/>` : ""}<c:orientation val="${a.reverse ? "maxMin" : "minMax"}"/>${a.max !== null ? `<c:max val="${a.max}"/>` : ""}${a.min !== null ? `<c:min val="${a.min}"/>` : ""}</c:scaling>`;
488
543
  const title = (a) => a.title ? `<c:title>${rich(a.title)}</c:title>` : "";
489
544
  const fmt = (a) => {
490
545
  const code = chartFormatToCode(a.format);
@@ -494,11 +549,14 @@ function chartToOoxml(spec) {
494
549
  const catPos = horizontal ? "l" : "b";
495
550
  const valPos = horizontal ? "b" : "l";
496
551
  const valAx = (id, cross, a, pos, crosses, catKind = false) => `<c:valAx><c:axId val="${id}"/>${scaling(a)}<c:delete val="${a.show ? 0 : 1}"/><c:axPos val="${pos}"/>${a.gridlines ? "<c:majorGridlines/>" : ""}${title(a)}${fmt(a)}<c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="${crosses}"/><c:crossBetween val="${catKind ? "midCat" : "between"}"/>${a.step ? `<c:majorUnit val="${a.step}"/>` : ""}</c:valAx>`;
497
- const catAx = (id, cross, a, pos, hidden = false) => `<c:${a.kind === "date" ? "dateAx" : "catAx"}><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="${a.show && !hidden ? 0 : 1}"/><c:axPos val="${pos}"/>${a.gridlines ? "<c:majorGridlines/>" : ""}${title(a)}<c:numFmt formatCode="General" sourceLinked="1"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="autoZero"/><c:auto val="1"/>${a.kind === "date" ? '<c:lblOffset val="100"/><c:baseTimeUnit val="days"/>' : '<c:lblAlgn val="ctr"/><c:lblOffset val="100"/><c:noMultiLvlLbl val="0"/>'}</c:${a.kind === "date" ? "dateAx" : "catAx"}>`;
552
+ const catAx = (id, cross, a, pos, hidden = false) => `<c:${a.kind === "date" ? "dateAx" : "catAx"}><c:axId val="${id}"/><c:scaling><c:orientation val="${a.reverse ? "maxMin" : "minMax"}"/></c:scaling><c:delete val="${a.show && !hidden ? 0 : 1}"/><c:axPos val="${pos}"/>${a.gridlines ? "<c:majorGridlines/>" : ""}${title(a)}<c:numFmt formatCode="General" sourceLinked="1"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="autoZero"/><c:auto val="1"/>${a.kind === "date" ? '<c:lblOffset val="100"/><c:baseTimeUnit val="days"/>' : '<c:lblAlgn val="ctr"/><c:lblOffset val="100"/><c:noMultiLvlLbl val="0"/>'}</c:${a.kind === "date" ? "dateAx" : "catAx"}>`;
498
553
  let axes = "";
499
554
  if (!pieLike) {
500
555
  if (xy) axes = valAx(ids.cat, ids.val, spec.xAxis, "b", "autoZero", true) + valAx(ids.val, ids.cat, spec.yAxis, "l", "autoZero", true);
501
- else axes = catAx(ids.cat, ids.val, spec.xAxis, catPos) + valAx(ids.val, ids.cat, spec.yAxis, valPos, "autoZero");
556
+ else {
557
+ if (spec.xAxis.scale === "log") issues.push("The category axis cannot be logarithmic; its log scale is left out.");
558
+ axes = catAx(ids.cat, ids.val, spec.xAxis, catPos) + valAx(ids.val, ids.cat, spec.yAxis, valPos, "autoZero");
559
+ }
502
560
  if (groups.some((g) => g.secondary)) axes += catAx(ids.cat2, ids.val2, spec.xAxis, catPos, true) + valAx(ids.val2, ids.cat2, spec.yAxis2, horizontal ? "t" : "r", "max");
503
561
  }
504
562
  const legendPos = { bottom: "b", top: "t", left: "l", right: "r" }[spec.legend.position];
@@ -510,12 +568,332 @@ function chartToOoxml(spec) {
510
568
  return { xml, issues: [...new Set(issues)] };
511
569
  }
512
570
 
571
+ // src/import/zip.ts
572
+ var ZipError = class extends Error {
573
+ code;
574
+ entryName;
575
+ constructor(code, message, details = {}) {
576
+ super(message, details.cause !== void 0 ? { cause: details.cause } : void 0);
577
+ this.name = "ZipError";
578
+ this.code = code;
579
+ this.entryName = details.entryName;
580
+ }
581
+ };
582
+ var DEFAULT_ZIP_MAX_ENTRIES = 1e4;
583
+ var DEFAULT_ZIP_MAX_TOTAL_SIZE = 256 * 1024 * 1024;
584
+ var SIG_EOCD = 101010256;
585
+ var SIG_ZIP64_EOCD = 101075792;
586
+ var SIG_ZIP64_LOCATOR = 117853008;
587
+ var SIG_CENTRAL = 33639248;
588
+ var SIG_LOCAL = 67324752;
589
+ var EOCD_SIZE = 22;
590
+ var MAX_COMMENT = 65535;
591
+ var crcTable = null;
592
+ function zipCrc32(data) {
593
+ if (!crcTable) {
594
+ crcTable = new Uint32Array(256);
595
+ for (let n = 0; n < 256; n++) {
596
+ let c = n;
597
+ for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
598
+ crcTable[n] = c >>> 0;
599
+ }
600
+ }
601
+ let crc = 4294967295;
602
+ for (let i = 0; i < data.length; i++) crc = crcTable[(crc ^ data[i]) & 255] ^ crc >>> 8;
603
+ return (crc ^ 4294967295) >>> 0;
604
+ }
605
+ function toBytes(data) {
606
+ if (ArrayBuffer.isView(data)) return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
607
+ return new Uint8Array(data);
608
+ }
609
+ function isUnsafeZipPath(name) {
610
+ if (!name || name.includes("\0")) return true;
611
+ const normalized = name.replace(/\\/g, "/");
612
+ if (normalized.startsWith("/") || /^[a-zA-Z]:/.test(normalized)) return true;
613
+ return normalized.split("/").some((segment) => segment === "..");
614
+ }
615
+ var utf8 = new TextDecoder("utf-8");
616
+ var CP437_HIGH = "\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xA2\xA3\xA5\u20A7\u0192\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\u2310\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0";
617
+ function decodeName(bytes, isUtf8) {
618
+ if (isUtf8 || bytes.every((b) => b < 128)) return utf8.decode(bytes);
619
+ let out = "";
620
+ for (const b of bytes) out += b < 128 ? String.fromCharCode(b) : CP437_HIGH[b - 128];
621
+ return out;
622
+ }
623
+ var ZipArchive = class {
624
+ constructor(bytes, entries, maxTotalSize) {
625
+ this.bytes = bytes;
626
+ this.maxTotalSize = maxTotalSize;
627
+ this.entries = entries;
628
+ entries.forEach((entry) => {
629
+ if (!this.byName.has(entry.name)) this.byName.set(entry.name, entry);
630
+ });
631
+ }
632
+ bytes;
633
+ maxTotalSize;
634
+ /** Entries in central-directory order. */
635
+ entries;
636
+ byName = /* @__PURE__ */ new Map();
637
+ extracted = 0;
638
+ /** Looks up an entry by exact name (a leading `/` is ignored). */
639
+ get(name) {
640
+ return this.byName.get(name.replace(/^\/+/, ""));
641
+ }
642
+ has(name) {
643
+ return !!this.get(name);
644
+ }
645
+ /** Uncompressed bytes extracted so far (counted against `maxTotalSize`). */
646
+ get extractedSize() {
647
+ return this.extracted;
648
+ }
649
+ /** Extracts an entry's data, verifying its size and CRC-32. */
650
+ async read(entryOrName) {
651
+ const entry = typeof entryOrName === "string" ? this.get(entryOrName) : entryOrName;
652
+ if (!entry) {
653
+ throw new ZipError("entry_not_found", `ZIP entry "${String(entryOrName)}" not found.`, {
654
+ entryName: String(entryOrName)
655
+ });
656
+ }
657
+ const name = entry.name;
658
+ if (entry.encrypted) {
659
+ throw new ZipError("encrypted", `ZIP entry "${name}" is encrypted; encrypted archives are not supported.`, {
660
+ entryName: name
661
+ });
662
+ }
663
+ if (entry.isDirectory) return new Uint8Array(0);
664
+ const remaining = this.maxTotalSize - this.extracted;
665
+ if (entry.size > remaining) {
666
+ throw new ZipError(
667
+ "too_large",
668
+ `Extracting "${name}" (${entry.size} bytes) would exceed the ${this.maxTotalSize}-byte limit.`,
669
+ { entryName: name }
670
+ );
671
+ }
672
+ const { bytes } = this;
673
+ const offset = entry.localHeaderOffset;
674
+ if (offset + 30 > bytes.length || readU32(bytes, offset) !== SIG_LOCAL) {
675
+ throw new ZipError("corrupt_entry", `ZIP entry "${name}" has no valid local header.`, { entryName: name });
676
+ }
677
+ const dataStart = offset + 30 + readU16(bytes, offset + 26) + readU16(bytes, offset + 28);
678
+ const dataEnd = dataStart + entry.compressedSize;
679
+ if (dataEnd > bytes.length) {
680
+ throw new ZipError("corrupt_entry", `ZIP entry "${name}" is truncated.`, { entryName: name });
681
+ }
682
+ const raw = bytes.subarray(dataStart, dataEnd);
683
+ let data;
684
+ if (entry.method === 0) {
685
+ if (entry.compressedSize !== entry.size) {
686
+ throw new ZipError("corrupt_entry", `Stored ZIP entry "${name}" has inconsistent sizes.`, { entryName: name });
687
+ }
688
+ data = raw.slice();
689
+ } else if (entry.method === 8) {
690
+ data = await inflateRaw(raw, entry.size, name);
691
+ } else {
692
+ throw new ZipError(
693
+ "unsupported_feature",
694
+ `ZIP entry "${name}" uses unsupported compression method ${entry.method}; only stored and deflate are supported.`,
695
+ { entryName: name }
696
+ );
697
+ }
698
+ if (data.length !== entry.size) {
699
+ throw new ZipError("corrupt_entry", `ZIP entry "${name}" size does not match the directory.`, { entryName: name });
700
+ }
701
+ this.extracted += data.length;
702
+ if (zipCrc32(data) !== entry.crc32) {
703
+ throw new ZipError("corrupt_entry", `ZIP entry "${name}" failed its CRC-32 check.`, { entryName: name });
704
+ }
705
+ return data;
706
+ }
707
+ /** Extracts an entry and decodes it as UTF-8 (a leading BOM is removed). */
708
+ async readText(entryOrName) {
709
+ const text = utf8.decode(await this.read(entryOrName));
710
+ return text.charCodeAt(0) === 65279 ? text.slice(1) : text;
711
+ }
712
+ };
713
+ function readU16(bytes, offset) {
714
+ return bytes[offset] | bytes[offset + 1] << 8;
715
+ }
716
+ function readU32(bytes, offset) {
717
+ return (bytes[offset] | bytes[offset + 1] << 8 | bytes[offset + 2] << 16 | bytes[offset + 3] << 24) >>> 0;
718
+ }
719
+ function readU64(bytes, offset) {
720
+ const value = readU32(bytes, offset) + readU32(bytes, offset + 4) * 4294967296;
721
+ if (!Number.isSafeInteger(value)) {
722
+ throw new ZipError("unsupported_feature", "ZIP64 value exceeds the supported range.");
723
+ }
724
+ return value;
725
+ }
726
+ async function inflateRaw(raw, limit, entryName) {
727
+ const Stream = globalThis.DecompressionStream;
728
+ if (typeof Stream !== "function") {
729
+ throw new ZipError(
730
+ "unsupported_environment",
731
+ "Inflating ZIP entries needs DecompressionStream (modern browsers, Node 18+).",
732
+ { entryName }
733
+ );
734
+ }
735
+ const stream = new Stream("deflate-raw");
736
+ const writer = stream.writable.getWriter();
737
+ const reader = stream.readable.getReader();
738
+ const CHUNK = 64 * 1024;
739
+ const feeding = (async () => {
740
+ for (let i = 0; i < raw.length; i += CHUNK) await writer.write(raw.subarray(i, i + CHUNK));
741
+ await writer.close();
742
+ })();
743
+ feeding.catch(() => {
744
+ });
745
+ const chunks = [];
746
+ let total = 0;
747
+ try {
748
+ for (; ; ) {
749
+ const { done, value } = await reader.read();
750
+ if (done) break;
751
+ total += value.length;
752
+ if (total > limit) {
753
+ throw new ZipError(
754
+ "corrupt_entry",
755
+ `ZIP entry "${entryName}" inflates beyond its declared size of ${limit} bytes.`,
756
+ { entryName }
757
+ );
758
+ }
759
+ chunks.push(value);
760
+ }
761
+ } catch (error) {
762
+ reader.cancel().catch(() => {
763
+ });
764
+ writer.abort().catch(() => {
765
+ });
766
+ if (error instanceof ZipError) throw error;
767
+ throw new ZipError("corrupt_entry", `ZIP entry "${entryName}" has an invalid deflate stream.`, {
768
+ entryName,
769
+ cause: error
770
+ });
771
+ }
772
+ await feeding.catch(() => {
773
+ });
774
+ const out = new Uint8Array(total);
775
+ let pos = 0;
776
+ for (const chunk of chunks) {
777
+ out.set(chunk, pos);
778
+ pos += chunk.length;
779
+ }
780
+ return out;
781
+ }
782
+ function findEndOfCentralDirectory(bytes) {
783
+ const min = Math.max(0, bytes.length - EOCD_SIZE - MAX_COMMENT);
784
+ for (let i = bytes.length - EOCD_SIZE; i >= min; i--) {
785
+ if (readU32(bytes, i) === SIG_EOCD && i + EOCD_SIZE + readU16(bytes, i + 20) <= bytes.length) return i;
786
+ }
787
+ return -1;
788
+ }
789
+ async function readZip(data, options = {}) {
790
+ const bytes = toBytes(data);
791
+ const maxEntries = options.maxEntries ?? DEFAULT_ZIP_MAX_ENTRIES;
792
+ const maxTotalSize = options.maxTotalSize ?? DEFAULT_ZIP_MAX_TOTAL_SIZE;
793
+ const eocd = findEndOfCentralDirectory(bytes);
794
+ if (eocd < 0) throw new ZipError("invalid_archive", "Not a ZIP archive (no end of central directory record).");
795
+ let diskNumber = readU16(bytes, eocd + 4);
796
+ let cdDisk = readU16(bytes, eocd + 6);
797
+ let count = readU16(bytes, eocd + 10);
798
+ let cdSize = readU32(bytes, eocd + 12);
799
+ let cdOffset = readU32(bytes, eocd + 16);
800
+ if (count === 65535 || cdSize === 4294967295 || cdOffset === 4294967295) {
801
+ const locator = eocd - 20;
802
+ if (locator < 0 || readU32(bytes, locator) !== SIG_ZIP64_LOCATOR) {
803
+ throw new ZipError("invalid_archive", "ZIP64 archive is missing its end of central directory locator.");
804
+ }
805
+ const record = readU64(bytes, locator + 8);
806
+ if (record + 56 > bytes.length || readU32(bytes, record) !== SIG_ZIP64_EOCD) {
807
+ throw new ZipError("invalid_archive", "ZIP64 end of central directory record not found.");
808
+ }
809
+ diskNumber = readU32(bytes, record + 16);
810
+ cdDisk = readU32(bytes, record + 20);
811
+ count = readU64(bytes, record + 32);
812
+ cdSize = readU64(bytes, record + 40);
813
+ cdOffset = readU64(bytes, record + 48);
814
+ }
815
+ if (diskNumber !== 0 || cdDisk !== 0) {
816
+ throw new ZipError("unsupported_feature", "Multi-disk (spanned) ZIP archives are not supported.");
817
+ }
818
+ if (count > maxEntries) {
819
+ throw new ZipError("too_many_entries", `ZIP archive has ${count} entries; the limit is ${maxEntries}.`);
820
+ }
821
+ if (cdOffset + cdSize > bytes.length) {
822
+ throw new ZipError("invalid_archive", "ZIP central directory lies outside the file.");
823
+ }
824
+ const entries = [];
825
+ let p = cdOffset;
826
+ for (let i = 0; i < count; i++) {
827
+ if (p + 46 > bytes.length || readU32(bytes, p) !== SIG_CENTRAL) {
828
+ throw new ZipError("invalid_archive", "ZIP central directory is corrupt.");
829
+ }
830
+ const flags = readU16(bytes, p + 8);
831
+ const method = readU16(bytes, p + 10);
832
+ const crc32 = readU32(bytes, p + 16);
833
+ let compressedSize = readU32(bytes, p + 20);
834
+ let size = readU32(bytes, p + 24);
835
+ const nameLength = readU16(bytes, p + 28);
836
+ const extraLength = readU16(bytes, p + 30);
837
+ const commentLength = readU16(bytes, p + 32);
838
+ let localHeaderOffset = readU32(bytes, p + 42);
839
+ const nameStart = p + 46;
840
+ const extraStart = nameStart + nameLength;
841
+ const next = extraStart + extraLength + commentLength;
842
+ if (next > bytes.length) throw new ZipError("invalid_archive", "ZIP central directory is truncated.");
843
+ for (let e = extraStart; e + 4 <= extraStart + extraLength; ) {
844
+ const id = readU16(bytes, e);
845
+ const len = readU16(bytes, e + 2);
846
+ if (id === 1) {
847
+ let f = e + 4;
848
+ const end = f + len;
849
+ if (size === 4294967295 && f + 8 <= end) {
850
+ size = readU64(bytes, f);
851
+ f += 8;
852
+ }
853
+ if (compressedSize === 4294967295 && f + 8 <= end) {
854
+ compressedSize = readU64(bytes, f);
855
+ f += 8;
856
+ }
857
+ if (localHeaderOffset === 4294967295 && f + 8 <= end) localHeaderOffset = readU64(bytes, f);
858
+ }
859
+ e += 4 + len;
860
+ }
861
+ const rawName = decodeName(bytes.subarray(nameStart, extraStart), (flags & 2048) !== 0);
862
+ const name = rawName.replace(/\\/g, "/");
863
+ p = next;
864
+ if (isUnsafeZipPath(rawName)) {
865
+ if (options.unsafePaths === "skip") continue;
866
+ throw new ZipError("unsafe_path", `ZIP entry name "${rawName}" is absolute or escapes the archive root.`, {
867
+ entryName: rawName
868
+ });
869
+ }
870
+ entries.push({
871
+ name,
872
+ isDirectory: name.endsWith("/"),
873
+ encrypted: (flags & 1) !== 0,
874
+ method,
875
+ compressedSize,
876
+ size,
877
+ crc32,
878
+ localHeaderOffset
879
+ });
880
+ }
881
+ return new ZipArchive(bytes, entries, maxTotalSize);
882
+ }
883
+
513
884
  export {
514
885
  CHART_OOXML_NS,
515
886
  CHART_OOXML_CONTENT_TYPE,
516
887
  CHART_OOXML_RELATIONSHIP,
517
888
  chartFromOoxml,
518
889
  chartFormatToCode,
519
- chartToOoxml
890
+ chartToOoxml,
891
+ ZipError,
892
+ DEFAULT_ZIP_MAX_ENTRIES,
893
+ DEFAULT_ZIP_MAX_TOTAL_SIZE,
894
+ zipCrc32,
895
+ isUnsafeZipPath,
896
+ ZipArchive,
897
+ readZip
520
898
  };
521
- //# sourceMappingURL=chunk-GJBIVWB2.js.map
899
+ //# sourceMappingURL=chunk-3S72F46R.js.map