@files-preview-app/preview-file 1.2.9 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -14,6 +14,7 @@ var OBJLoader_js = require('three/examples/jsm/loaders/OBJLoader.js');
14
14
  var OrbitControls_js = require('three/examples/jsm/controls/OrbitControls.js');
15
15
  var RTFJS = require('rtf.js/dist/RTFJS.bundle.js');
16
16
 
17
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
17
18
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
18
19
 
19
20
  function _interopNamespace(e) {
@@ -366,16 +367,21 @@ async function sourceToArrayBuffer(source, signal) {
366
367
  metadata.mimeType = source.type || void 0;
367
368
  metadata.extension = extractExtension(source.name);
368
369
  buffer = await source.arrayBuffer();
369
- } else if (source instanceof Blob) {
370
+ } else if (source instanceof Blob || source && typeof source.arrayBuffer === "function" && typeof source.size === "number") {
370
371
  metadata.size = source.size;
371
372
  metadata.mimeType = source.type || void 0;
373
+ if (source.name) {
374
+ metadata.name = source.name;
375
+ metadata.extension = extractExtension(source.name);
376
+ }
372
377
  buffer = await source.arrayBuffer();
373
- } else if (source instanceof ArrayBuffer) {
378
+ } else if (source instanceof ArrayBuffer || Object.prototype.toString.call(source) === "[object ArrayBuffer]" || source && typeof source.byteLength === "number" && typeof source.slice === "function") {
374
379
  buffer = source;
375
- } else if (source instanceof Uint8Array) {
376
- buffer = source.buffer.slice(
377
- source.byteOffset,
378
- source.byteOffset + source.byteLength
380
+ } else if (source instanceof Uint8Array || ArrayBuffer.isView(source)) {
381
+ const view = source;
382
+ buffer = view.buffer.slice(
383
+ view.byteOffset,
384
+ view.byteOffset + view.byteLength
379
385
  );
380
386
  } else {
381
387
  throw new Error("Unsupported file source type");
@@ -504,6 +510,86 @@ function createElement(tag, attrs, ...children) {
504
510
  }
505
511
  return el;
506
512
  }
513
+ var DB_NAME = "PreviewFileTransferDB";
514
+ var DB_STORE = "transfers";
515
+ function openDB() {
516
+ return new Promise((resolve, reject) => {
517
+ if (typeof indexedDB === "undefined") {
518
+ return reject(new Error("IndexedDB is not available"));
519
+ }
520
+ const req = indexedDB.open(DB_NAME, 1);
521
+ req.onupgradeneeded = () => {
522
+ const db = req.result;
523
+ if (!db.objectStoreNames.contains(DB_STORE)) {
524
+ db.createObjectStore(DB_STORE, { keyPath: "id" });
525
+ }
526
+ };
527
+ req.onsuccess = () => resolve(req.result);
528
+ req.onerror = () => reject(req.error);
529
+ });
530
+ }
531
+ async function saveTransferPayload(id, payload) {
532
+ if (typeof window !== "undefined") {
533
+ try {
534
+ window[id] = payload;
535
+ window.__lastTransfer = payload;
536
+ } catch {
537
+ }
538
+ }
539
+ try {
540
+ const db = await openDB();
541
+ return new Promise((resolve, reject) => {
542
+ const tx = db.transaction(DB_STORE, "readwrite");
543
+ const store = tx.objectStore(DB_STORE);
544
+ store.put({ id, ...payload, timestamp: Date.now() });
545
+ tx.oncomplete = () => resolve();
546
+ tx.onerror = () => reject(tx.error);
547
+ });
548
+ } catch (e) {
549
+ console.warn("[saveTransferPayload] IndexedDB store warning:", e);
550
+ }
551
+ }
552
+ async function getTransferPayload(id) {
553
+ if (typeof window !== "undefined") {
554
+ try {
555
+ if (window.opener && window.opener[id]) {
556
+ return window.opener[id];
557
+ }
558
+ if (window[id]) {
559
+ return window[id];
560
+ }
561
+ if (window.opener && window.opener.__lastTransfer) {
562
+ return window.opener.__lastTransfer;
563
+ }
564
+ if (window.__lastTransfer) {
565
+ return window.__lastTransfer;
566
+ }
567
+ } catch {
568
+ }
569
+ }
570
+ try {
571
+ const db = await openDB();
572
+ return new Promise((resolve) => {
573
+ const tx = db.transaction(DB_STORE, "readonly");
574
+ const store = tx.objectStore(DB_STORE);
575
+ const req = store.get(id);
576
+ req.onsuccess = () => {
577
+ if (req.result && req.result.buffer) {
578
+ resolve({
579
+ buffer: req.result.buffer,
580
+ metadata: req.result.metadata,
581
+ options: req.result.options
582
+ });
583
+ } else {
584
+ resolve(null);
585
+ }
586
+ };
587
+ req.onerror = () => resolve(null);
588
+ });
589
+ } catch {
590
+ return null;
591
+ }
592
+ }
507
593
  var ICON_ZOOM_IN = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>`;
508
594
  var ICON_ZOOM_OUT = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>`;
509
595
  var ICON_FIT_PAGE = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"></rect><line x1="8" y1="12" x2="16" y2="12"></line><polyline points="11 9 8 12 11 15"></polyline><polyline points="13 9 16 12 13 15"></polyline></svg>`;
@@ -523,6 +609,7 @@ var ICON_COPY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" str
523
609
  var ICON_FAST_FORWARD = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 19 22 12 13 5 13 19"></polygon><polygon points="2 19 11 12 2 5 2 19"></polygon></svg>`;
524
610
  var ICON_REWIND = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="11 19 2 12 11 5 11 19"></polygon><polygon points="22 19 13 12 22 5 22 19"></polygon></svg>`;
525
611
  var ICON_SPEED = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>`;
612
+ var ICON_EXTERNAL_WINDOW = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>`;
526
613
  var ICON_MAP = {
527
614
  "zoom-in": ICON_ZOOM_IN,
528
615
  "zoom-out": ICON_ZOOM_OUT,
@@ -549,7 +636,9 @@ var ICON_MAP = {
549
636
  "forward-10": ICON_FAST_FORWARD,
550
637
  "rewind": ICON_REWIND,
551
638
  "replay-10": ICON_REWIND,
552
- "speed": ICON_SPEED
639
+ "speed": ICON_SPEED,
640
+ "open-window": ICON_EXTERNAL_WINDOW,
641
+ "external-window": ICON_EXTERNAL_WINDOW
553
642
  };
554
643
  var ToolbarController = class {
555
644
  el;
@@ -766,7 +855,7 @@ var ThumbnailPanel = class {
766
855
  }
767
856
  }
768
857
  };
769
- var FilePreviewViewer = class {
858
+ var FilePreviewViewer = class _FilePreviewViewer {
770
859
  plugins = [];
771
860
  activeInstance = null;
772
861
  abortController = null;
@@ -803,6 +892,7 @@ var FilePreviewViewer = class {
803
892
  * Preview a file in the given container element.
804
893
  */
805
894
  async preview(container, source, options = {}) {
895
+ this.currentOptions = options;
806
896
  this.abort();
807
897
  this.abortController = new AbortController();
808
898
  const { signal } = this.abortController;
@@ -812,7 +902,10 @@ var FilePreviewViewer = class {
812
902
  this.showLoading();
813
903
  try {
814
904
  const { buffer, metadata } = await sourceToArrayBuffer(source, signal);
815
- this.currentBuffer = buffer;
905
+ if (options.metadata) {
906
+ Object.assign(metadata, options.metadata);
907
+ }
908
+ this.currentBuffer = buffer.slice(0);
816
909
  this.currentMetadata = metadata;
817
910
  if (signal.aborted) throw new DOMException("Aborted", "AbortError");
818
911
  const fileInfo = { metadata, buffer };
@@ -842,6 +935,7 @@ var FilePreviewViewer = class {
842
935
  }
843
936
  });
844
937
  this.activeInstance = instance;
938
+ instance.openInSeparateWindow = () => this.openInSeparateWindow();
845
939
  this.hideLoading();
846
940
  this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
847
941
  if (options.showToolbar !== false && this.toolbar) {
@@ -851,26 +945,16 @@ var FilePreviewViewer = class {
851
945
  actions.push({
852
946
  id: "fullscreen",
853
947
  icon: "fullscreen",
854
- label: "Toggle Fullscreen",
948
+ label: "Fullscreen",
855
949
  type: "button",
856
950
  group: "view",
857
- execute: async () => {
951
+ execute: () => {
858
952
  try {
859
- const isNativeFs = !!document.fullscreenElement;
860
- const isCssFs = this.wrapperEl?.classList.contains("fp-fullscreen-active");
861
- if (!isNativeFs && !isCssFs) {
862
- if (this.wrapperEl?.requestFullscreen) {
863
- await this.wrapperEl.requestFullscreen().catch(() => {
864
- this.wrapperEl?.classList.add("fp-fullscreen-active");
865
- });
866
- } else {
867
- this.wrapperEl?.classList.add("fp-fullscreen-active");
868
- }
953
+ if (!document.fullscreenElement) {
954
+ this.wrapperEl?.requestFullscreen?.();
955
+ this.wrapperEl?.classList.add("fp-fullscreen-active");
869
956
  } else {
870
- if (document.fullscreenElement) {
871
- await document.exitFullscreen().catch(() => {
872
- });
873
- }
957
+ document.exitFullscreen?.();
874
958
  this.wrapperEl?.classList.remove("fp-fullscreen-active");
875
959
  }
876
960
  } catch {
@@ -882,6 +966,28 @@ var FilePreviewViewer = class {
882
966
  }
883
967
  });
884
968
  }
969
+ const openWinAction = actions.find((a) => a.id === "open-window");
970
+ if (openWinAction) {
971
+ if (options?._isSeparateWindow) {
972
+ const idx = actions.indexOf(openWinAction);
973
+ if (idx !== -1) actions.splice(idx, 1);
974
+ } else {
975
+ openWinAction.execute = () => {
976
+ this.openInSeparateWindow();
977
+ };
978
+ }
979
+ } else if (!options?._isSeparateWindow) {
980
+ actions.push({
981
+ id: "open-window",
982
+ icon: "open-window",
983
+ label: "Open in Separate Full Window",
984
+ type: "button",
985
+ group: "actions",
986
+ execute: () => {
987
+ this.openInSeparateWindow();
988
+ }
989
+ });
990
+ }
885
991
  this.toolbar.update(actions);
886
992
  this.toolbar.show();
887
993
  }
@@ -914,6 +1020,104 @@ var FilePreviewViewer = class {
914
1020
  throw error;
915
1021
  }
916
1022
  }
1023
+ /**
1024
+ * Opens the current file preview in a separate full browser window.
1025
+ */
1026
+ openInSeparateWindow() {
1027
+ if (!this.currentBuffer) {
1028
+ console.warn("[FilePreviewViewer] No active file buffer to open in separate window");
1029
+ return null;
1030
+ }
1031
+ if (this.currentOptions.onOpenSeparateWindow) {
1032
+ return this.currentOptions.onOpenSeparateWindow({
1033
+ buffer: this.currentBuffer,
1034
+ metadata: this.currentMetadata || { name: "Document" },
1035
+ options: this.currentOptions
1036
+ });
1037
+ }
1038
+ const transferId = "fp_win_" + Date.now() + "_" + Math.random().toString(36).slice(2, 8);
1039
+ let clonedBuffer;
1040
+ try {
1041
+ clonedBuffer = this.currentBuffer.slice(0);
1042
+ } catch {
1043
+ clonedBuffer = this.currentBuffer;
1044
+ }
1045
+ const payload = {
1046
+ buffer: clonedBuffer,
1047
+ metadata: this.currentMetadata ? { ...this.currentMetadata } : void 0,
1048
+ options: { ...this.currentOptions, _isSeparateWindow: true }
1049
+ };
1050
+ if (typeof window !== "undefined") {
1051
+ try {
1052
+ window[transferId] = payload;
1053
+ window.__lastTransfer = payload;
1054
+ } catch {
1055
+ }
1056
+ }
1057
+ saveTransferPayload(transferId, payload).catch((err) => {
1058
+ console.warn("[FilePreviewViewer] Transfer payload save warning:", err);
1059
+ });
1060
+ let targetUrl = null;
1061
+ if (this.currentOptions.standaloneViewerUrl) {
1062
+ const u = new URL(this.currentOptions.standaloneViewerUrl, window.location.href);
1063
+ u.searchParams.set("mode", "fullscreen");
1064
+ u.searchParams.set("transferId", transferId);
1065
+ targetUrl = u.toString();
1066
+ } else if (typeof window !== "undefined" && window.location?.href && !window.location.href.startsWith("about:")) {
1067
+ const u = new URL(window.location.href);
1068
+ u.searchParams.set("mode", "fullscreen");
1069
+ u.searchParams.set("transferId", transferId);
1070
+ targetUrl = u.toString();
1071
+ }
1072
+ if (targetUrl) {
1073
+ const newWin2 = window.open(targetUrl, "_blank");
1074
+ if (!newWin2) {
1075
+ alert("Popup blocker prevented opening the preview in a separate window. Please allow popups for this site.");
1076
+ return null;
1077
+ }
1078
+ return newWin2;
1079
+ }
1080
+ const title = (this.currentMetadata?.name || "Document Preview") + " - Full Preview";
1081
+ const newWin = window.open("", "_blank");
1082
+ if (!newWin) {
1083
+ alert("Popup blocker prevented opening the preview in a separate window. Please allow popups for this site.");
1084
+ return null;
1085
+ }
1086
+ newWin.document.title = title;
1087
+ newWin.document.body.style.margin = "0";
1088
+ newWin.document.body.style.padding = "0";
1089
+ newWin.document.body.style.width = "100vw";
1090
+ newWin.document.body.style.height = "100vh";
1091
+ newWin.document.body.style.overflow = "hidden";
1092
+ newWin.document.body.style.backgroundColor = "#f8fafc";
1093
+ const headNodes = document.querySelectorAll('link[rel="stylesheet"], style');
1094
+ headNodes.forEach((node) => {
1095
+ newWin.document.head.appendChild(node.cloneNode(true));
1096
+ });
1097
+ const root = newWin.document.createElement("div");
1098
+ root.id = "full-window-preview-root";
1099
+ root.style.width = "100%";
1100
+ root.style.height = "100%";
1101
+ root.style.overflow = "hidden";
1102
+ newWin.document.body.appendChild(root);
1103
+ const separateViewer = new _FilePreviewViewer();
1104
+ for (const plugin of this.plugins) {
1105
+ separateViewer.registerPlugin(plugin);
1106
+ }
1107
+ separateViewer.preview(root, this.currentBuffer.slice(0), {
1108
+ ...this.currentOptions,
1109
+ showToolbar: true,
1110
+ toolbarPosition: "top",
1111
+ metadata: this.currentMetadata || void 0,
1112
+ _isSeparateWindow: true
1113
+ }).catch((err) => {
1114
+ console.error("[FilePreviewViewer] Error rendering in separate window:", err);
1115
+ });
1116
+ newWin.addEventListener("beforeunload", () => {
1117
+ separateViewer.destroy();
1118
+ });
1119
+ return newWin;
1120
+ }
917
1121
  /**
918
1122
  * Subscribe to viewer events.
919
1123
  */
@@ -1319,8 +1523,20 @@ var CfbfReader = class {
1319
1523
  }
1320
1524
  };
1321
1525
  if (typeof window !== "undefined" && pdfjsLib__namespace.GlobalWorkerOptions) {
1322
- if (!pdfjsLib__namespace.GlobalWorkerOptions.workerSrc) {
1323
- pdfjsLib__namespace.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjsLib__namespace.version || "4.10.38"}/build/pdf.worker.min.mjs`;
1526
+ if (!pdfjsLib__namespace.GlobalWorkerOptions.workerPort && !pdfjsLib__namespace.GlobalWorkerOptions.workerSrc) {
1527
+ const customWorker = window.__PDF_WORKER_SRC__;
1528
+ if (customWorker) {
1529
+ pdfjsLib__namespace.GlobalWorkerOptions.workerSrc = customWorker;
1530
+ } else {
1531
+ try {
1532
+ pdfjsLib__namespace.GlobalWorkerOptions.workerPort = new Worker(
1533
+ new URL("pdfjs-dist/build/pdf.worker.min.mjs", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))),
1534
+ { type: "module" }
1535
+ );
1536
+ } catch {
1537
+ pdfjsLib__namespace.GlobalWorkerOptions.workerSrc = "./pdf.worker.min.mjs";
1538
+ }
1539
+ }
1324
1540
  }
1325
1541
  }
1326
1542
  var PdfPlugin = class {
@@ -1414,6 +1630,14 @@ var PdfPlugin = class {
1414
1630
  type: "button",
1415
1631
  group: "actions",
1416
1632
  execute: () => instance.print?.()
1633
+ },
1634
+ {
1635
+ id: "open-window",
1636
+ icon: "open-window",
1637
+ label: "Open in Separate Full Window",
1638
+ type: "button",
1639
+ group: "actions",
1640
+ execute: () => instance.openInSeparateWindow?.()
1417
1641
  }
1418
1642
  ];
1419
1643
  }
@@ -1463,18 +1687,21 @@ var PdfPlugin = class {
1463
1687
  indicator.style.pointerEvents = "none";
1464
1688
  container.appendChild(indicator);
1465
1689
  ctx.container.appendChild(container);
1690
+ const standardFontsUrl = typeof window !== "undefined" && window.__PDF_STANDARD_FONTS_URL__ || "./standard_fonts/";
1691
+ const cmapsUrl = typeof window !== "undefined" && window.__PDF_CMAPS_URL__ || "./cmaps/";
1466
1692
  const loadingTask = pdfjsLib__namespace.getDocument({
1467
- data: new Uint8Array(ctx.buffer),
1468
- cMapUrl: `https://unpkg.com/pdfjs-dist@${pdfjsLib__namespace.version || "4.10.38"}/cmaps/`,
1693
+ data: new Uint8Array(ctx.buffer.slice(0)),
1694
+ cMapUrl: cmapsUrl,
1469
1695
  cMapPacked: true,
1470
- standardFontDataUrl: `https://unpkg.com/pdfjs-dist@${pdfjsLib__namespace.version || "4.10.38"}/standard_fonts/`
1696
+ standardFontDataUrl: standardFontsUrl,
1697
+ verbosity: 0
1471
1698
  });
1472
1699
  const pdfDoc = await loadingTask.promise;
1473
1700
  const totalPages = Math.max(1, pdfDoc.numPages);
1474
1701
  let currentPage = 1;
1475
1702
  let zoomScale = 1;
1476
1703
  let rotation = 0;
1477
- let fitMode = "width";
1704
+ let fitMode = "page";
1478
1705
  let currentRenderTask = null;
1479
1706
  const renderPage = async (pageNum) => {
1480
1707
  if (currentRenderTask) {
@@ -1494,15 +1721,15 @@ var PdfPlugin = class {
1494
1721
  const containerWidth = container.clientWidth || 900;
1495
1722
  const containerHeight = container.clientHeight || 700;
1496
1723
  const unscaledVp = page.getViewport({ scale: 1, rotation });
1497
- const availWidth = Math.max(280, containerWidth - 48);
1498
- const availHeight = Math.max(280, containerHeight - 88);
1724
+ const availWidth = Math.max(320, containerWidth - 48);
1725
+ const availHeight = Math.max(550, containerHeight - 88);
1499
1726
  const scaleW = availWidth / unscaledVp.width;
1500
1727
  const scaleH = availHeight / unscaledVp.height;
1501
1728
  let fitScale;
1502
1729
  if (fitMode === "page") {
1503
- fitScale = Math.max(0.5, Math.min(scaleW, scaleH));
1730
+ fitScale = Math.max(0.4, Math.min(scaleW, scaleH));
1504
1731
  } else {
1505
- fitScale = Math.max(0.65, Math.min(1.15, scaleW));
1732
+ fitScale = Math.max(0.65, Math.min(1.25, scaleW));
1506
1733
  }
1507
1734
  const effectiveScale = (fitScale > 0 ? fitScale : 1) * zoomScale;
1508
1735
  const pixelRatio = window.devicePixelRatio || 1;
@@ -1528,7 +1755,7 @@ var PdfPlugin = class {
1528
1755
  currentRenderTask = null;
1529
1756
  }
1530
1757
  };
1531
- await renderPage(1);
1758
+ renderPage(1);
1532
1759
  let resizeTimer = null;
1533
1760
  const resizeObserver = new ResizeObserver(() => {
1534
1761
  if (resizeTimer) clearTimeout(resizeTimer);
@@ -1572,7 +1799,7 @@ var PdfPlugin = class {
1572
1799
  renderPage(currentPage);
1573
1800
  },
1574
1801
  fitToPage: () => {
1575
- fitMode = fitMode === "width" ? "page" : "width";
1802
+ fitMode = fitMode === "page" ? "width" : "page";
1576
1803
  zoomScale = 1;
1577
1804
  rotation = 0;
1578
1805
  renderPage(currentPage);
@@ -2049,6 +2276,14 @@ var DocxPlugin = class {
2049
2276
  type: "button",
2050
2277
  group: "actions",
2051
2278
  execute: () => instance.print?.()
2279
+ },
2280
+ {
2281
+ id: "open-window",
2282
+ icon: "open-window",
2283
+ label: "Open in Separate Full Window",
2284
+ type: "button",
2285
+ group: "actions",
2286
+ execute: () => instance.openInSeparateWindow?.()
2052
2287
  }
2053
2288
  );
2054
2289
  return actions;
@@ -2108,6 +2343,31 @@ var DocxPlugin = class {
2108
2343
  }
2109
2344
  if (wrapper.children.length > 0 && (wrapper.textContent?.trim().length ?? 0) > 0) {
2110
2345
  renderedSuccessfully = true;
2346
+ try {
2347
+ const unzipped = fflate.unzipSync(new Uint8Array(ctx.buffer));
2348
+ const chartKeys = Object.keys(unzipped).filter((k) => k.replace(/^[./\\]+/, "").toLowerCase().startsWith("word/charts/chart") && k.endsWith(".xml")).sort();
2349
+ if (chartKeys.length > 0) {
2350
+ const allDivs = Array.from(wrapper.querySelectorAll("div"));
2351
+ const emptyContainers = allDivs.filter((div) => {
2352
+ const st = div.getAttribute("style") || "";
2353
+ return st.includes("width:") && st.includes("height:") && div.children.length === 0 && (div.textContent?.trim().length ?? 0) === 0;
2354
+ });
2355
+ chartKeys.forEach((cKey, idx) => {
2356
+ const target = emptyContainers[idx];
2357
+ if (target) {
2358
+ const xmlStr = fflate.strFromU8(unzipped[cKey]);
2359
+ const svg = this.parseAndRenderChartSvg(xmlStr);
2360
+ if (svg) {
2361
+ target.innerHTML = svg;
2362
+ target.style.display = "block";
2363
+ target.style.margin = "12px auto";
2364
+ }
2365
+ }
2366
+ });
2367
+ }
2368
+ } catch (chartErr) {
2369
+ console.warn("[DocxPlugin] Non-critical error rendering DrawingML charts:", chartErr);
2370
+ }
2111
2371
  }
2112
2372
  } catch (err) {
2113
2373
  console.warn("[DocxPlugin] docx-preview failed, triggering native fallback:", err);
@@ -2139,64 +2399,74 @@ var DocxPlugin = class {
2139
2399
  }
2140
2400
  let sections = Array.from(wrapper.querySelectorAll("section.docx"));
2141
2401
  const cards = Array.from(wrapper.querySelectorAll(".fp-docx-page-card"));
2142
- if (sections.length === 1 && cards.length === 0) {
2143
- const singleSec = sections[0];
2144
- const contentContainer = singleSec.querySelector("article") || singleSec;
2145
- const children = Array.from(contentContainer.children);
2146
- const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
2147
- const secH = singleSec.offsetHeight || singleSec.scrollHeight;
2148
- if (secH > pageH * 1.25 && children.length > 1) {
2149
- const childHeights = children.map((c) => {
2150
- const rectH = c.getBoundingClientRect().height;
2151
- const offH = c.offsetHeight;
2152
- const textLen = c.textContent?.trim().length || 0;
2153
- const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
2154
- return Math.max(rectH, offH, estH);
2155
- });
2156
- const parent = singleSec.parentElement || wrapper;
2157
- const newSections = [singleSec];
2158
- const headerEl = singleSec.querySelector("header");
2159
- const footerEl = singleSec.querySelector("footer");
2160
- contentContainer.innerHTML = "";
2161
- singleSec.style.minHeight = `${pageH}px`;
2162
- singleSec.style.boxSizing = "border-box";
2163
- let curContent = contentContainer;
2164
- let curH = 0;
2165
- const maxH = pageH - 140;
2166
- for (let i = 0; i < children.length; i++) {
2167
- const child = children[i];
2168
- const chH = childHeights[i];
2169
- curContent.appendChild(child);
2170
- curH += chH;
2171
- if (curH >= maxH && i < children.length - 1) {
2172
- const nextSec = document.createElement("section");
2173
- nextSec.className = singleSec.className;
2174
- nextSec.style.cssText = singleSec.style.cssText;
2175
- nextSec.style.minHeight = `${pageH}px`;
2176
- nextSec.style.boxSizing = "border-box";
2177
- nextSec.style.backgroundColor = "#ffffff";
2178
- nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2179
- nextSec.style.borderRadius = "4px";
2180
- nextSec.style.marginBottom = "24px";
2181
- if (headerEl) {
2182
- nextSec.appendChild(headerEl.cloneNode(true));
2183
- }
2184
- const nextArticle = document.createElement("article");
2185
- if (contentContainer.tagName.toLowerCase() === "article") {
2186
- nextArticle.style.cssText = contentContainer.style.cssText;
2187
- }
2188
- nextSec.appendChild(nextArticle);
2189
- if (footerEl) {
2190
- nextSec.appendChild(footerEl.cloneNode(true));
2402
+ if (sections.length > 0 && cards.length === 0) {
2403
+ const finalSections = [];
2404
+ for (const singleSec of sections) {
2405
+ const contentContainer = singleSec.querySelector("article") || singleSec;
2406
+ const children = Array.from(contentContainer.children);
2407
+ const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
2408
+ const secH = singleSec.scrollHeight || singleSec.offsetHeight;
2409
+ if (secH > pageH * 1.25 && children.length > 1) {
2410
+ const childHeights = children.map((c) => {
2411
+ const rectH = c.getBoundingClientRect().height;
2412
+ const offH = c.offsetHeight;
2413
+ const textLen = c.textContent?.trim().length || 0;
2414
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
2415
+ return Math.max(rectH, offH, estH);
2416
+ });
2417
+ const parent = singleSec.parentElement || wrapper;
2418
+ const headerEl = singleSec.querySelector("header");
2419
+ const footerEl = singleSec.querySelector("footer");
2420
+ contentContainer.innerHTML = "";
2421
+ singleSec.style.minHeight = `${pageH}px`;
2422
+ singleSec.style.boxSizing = "border-box";
2423
+ let curContent = contentContainer;
2424
+ let curSec = singleSec;
2425
+ let curH = 0;
2426
+ const maxH = pageH - 140;
2427
+ finalSections.push(singleSec);
2428
+ for (let i = 0; i < children.length; i++) {
2429
+ const child = children[i];
2430
+ const chH = childHeights[i];
2431
+ curContent.appendChild(child);
2432
+ curH += chH;
2433
+ if (curH >= maxH && i < children.length - 1) {
2434
+ const nextSec = document.createElement("section");
2435
+ nextSec.className = singleSec.className;
2436
+ nextSec.style.cssText = singleSec.style.cssText;
2437
+ nextSec.style.minHeight = `${pageH}px`;
2438
+ nextSec.style.boxSizing = "border-box";
2439
+ nextSec.style.backgroundColor = "#ffffff";
2440
+ nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2441
+ nextSec.style.borderRadius = "4px";
2442
+ nextSec.style.marginBottom = "24px";
2443
+ if (headerEl) {
2444
+ nextSec.appendChild(headerEl.cloneNode(true));
2445
+ }
2446
+ const nextArticle = document.createElement("article");
2447
+ if (contentContainer.tagName.toLowerCase() === "article") {
2448
+ nextArticle.style.cssText = contentContainer.style.cssText;
2449
+ }
2450
+ nextSec.appendChild(nextArticle);
2451
+ if (footerEl) {
2452
+ nextSec.appendChild(footerEl.cloneNode(true));
2453
+ }
2454
+ if (curSec.nextSibling) {
2455
+ parent.insertBefore(nextSec, curSec.nextSibling);
2456
+ } else {
2457
+ parent.appendChild(nextSec);
2458
+ }
2459
+ finalSections.push(nextSec);
2460
+ curSec = nextSec;
2461
+ curContent = nextArticle;
2462
+ curH = 0;
2191
2463
  }
2192
- parent.appendChild(nextSec);
2193
- newSections.push(nextSec);
2194
- curContent = nextArticle;
2195
- curH = 0;
2196
2464
  }
2465
+ } else {
2466
+ finalSections.push(singleSec);
2197
2467
  }
2198
- sections = newSections;
2199
2468
  }
2469
+ sections = finalSections;
2200
2470
  }
2201
2471
  const pageElements = sections.length > 0 ? sections : cards;
2202
2472
  const totalPages = Math.max(1, pageElements.length);
@@ -2588,6 +2858,88 @@ var DocxPlugin = class {
2588
2858
  }
2589
2859
  return result;
2590
2860
  }
2861
+ parseAndRenderChartSvg(xmlStr, width = 500, height = 260) {
2862
+ const catMatches = [...xmlStr.matchAll(/<c:cat>[\s\S]*?<c:strCache>([\s\S]*?)<\/c:strCache>/g)];
2863
+ let categories = [];
2864
+ if (catMatches.length > 0) {
2865
+ categories = [...catMatches[0][1].matchAll(/<c:v>([^<]+)<\/c:v>/g)].map((m) => m[1]);
2866
+ }
2867
+ if (categories.length === 0) {
2868
+ categories = ["Category 1", "Category 2", "Category 3", "Category 4"];
2869
+ }
2870
+ const defaultColors = ["#004586", "#ff420e", "#ffd320", "#579d1c", "#7e0021", "#83caff"];
2871
+ const sers = [...xmlStr.matchAll(/<c:ser>([\s\S]*?)<\/c:ser>/g)];
2872
+ const series = [];
2873
+ sers.forEach((s, sIdx) => {
2874
+ const titleMatch = s[1].match(/<c:tx>[\s\S]*?<c:v>([^<]+)<\/c:v>/);
2875
+ const title = titleMatch ? titleMatch[1] : `Series ${sIdx + 1}`;
2876
+ const clrMatch = s[1].match(/<a:srgbClr\s+val="([^"]+)"/);
2877
+ const color = clrMatch ? "#" + clrMatch[1] : defaultColors[sIdx % defaultColors.length];
2878
+ const valMatch = s[1].match(/<c:val>[\s\S]*?<c:numCache>([\s\S]*?)<\/c:numCache>/);
2879
+ let values = [];
2880
+ if (valMatch) {
2881
+ values = [...valMatch[1].matchAll(/<c:pt\s+idx="(\d+)">\s*<c:v>([^<]+)<\/c:v>/g)].sort((a, b) => parseInt(a[1], 10) - parseInt(b[1], 10)).map((m) => parseFloat(m[2]) || 0);
2882
+ }
2883
+ series.push({ title, color, values });
2884
+ });
2885
+ if (series.length === 0) return "";
2886
+ let maxVal = 10;
2887
+ series.forEach((s) => s.values.forEach((v) => {
2888
+ if (v > maxVal) maxVal = v;
2889
+ }));
2890
+ maxVal = Math.ceil(maxVal * 1.15);
2891
+ if (maxVal % 2 !== 0) maxVal++;
2892
+ const padLeft = 45;
2893
+ const padBottom = 55;
2894
+ const padTop = 20;
2895
+ const padRight = 20;
2896
+ const plotW = width - padLeft - padRight;
2897
+ const plotH = height - padTop - padBottom;
2898
+ const yTicks = 5;
2899
+ let gridLines = "";
2900
+ for (let i = 0; i <= yTicks; i++) {
2901
+ const val = maxVal / yTicks * i;
2902
+ const y = padTop + plotH - val / maxVal * plotH;
2903
+ gridLines += `<line x1="${padLeft}" y1="${y}" x2="${padLeft + plotW}" y2="${y}" stroke="#e2e8f0" stroke-width="1" />`;
2904
+ gridLines += `<text x="${padLeft - 8}" y="${y + 4}" text-anchor="end" font-size="11" fill="#64748b" font-family="Calibri, sans-serif">${Math.round(val)}</text>`;
2905
+ }
2906
+ const numCats = categories.length;
2907
+ const numSers = series.length;
2908
+ const groupW = plotW / numCats;
2909
+ const barW = Math.max(8, Math.min(28, groupW * 0.7 / numSers));
2910
+ const groupPad = (groupW - barW * numSers) / 2;
2911
+ let bars = "";
2912
+ let catLabels = "";
2913
+ for (let c = 0; c < numCats; c++) {
2914
+ const catX = padLeft + c * groupW;
2915
+ catLabels += `<text x="${catX + groupW / 2}" y="${padTop + plotH + 18}" text-anchor="middle" font-size="11" fill="#334155" font-family="Calibri, sans-serif">${categories[c]}</text>`;
2916
+ for (let s = 0; s < numSers; s++) {
2917
+ const val = series[s].values[c] ?? 0;
2918
+ const bH = Math.max(0, val / maxVal * plotH);
2919
+ const bX = catX + groupPad + s * barW;
2920
+ const bY = padTop + plotH - bH;
2921
+ bars += `<rect x="${bX}" y="${bY}" width="${barW - 2}" height="${bH}" fill="${series[s].color}" rx="1" />`;
2922
+ }
2923
+ }
2924
+ let legend = "";
2925
+ const legY = height - 12;
2926
+ let legX = padLeft + (plotW - numSers * 100) / 2;
2927
+ series.forEach((s) => {
2928
+ legend += `<rect x="${legX}" y="${legY - 9}" width="10" height="10" fill="${s.color}" rx="2" />`;
2929
+ legend += `<text x="${legX + 15}" y="${legY}" font-size="11" fill="#475569" font-family="Calibri, sans-serif">${s.title}</text>`;
2930
+ legX += 95;
2931
+ });
2932
+ return `
2933
+ <svg viewBox="0 0 ${width} ${height}" width="100%" height="100%" style="background:#ffffff; border-radius:4px; overflow:visible;" xmlns="http://www.w3.org/2000/svg">
2934
+ ${gridLines}
2935
+ <line x1="${padLeft}" y1="${padTop + plotH}" x2="${padLeft + plotW}" y2="${padTop + plotH}" stroke="#94a3b8" stroke-width="1.5" />
2936
+ <line x1="${padLeft}" y1="${padTop}" x2="${padLeft}" y2="${padTop + plotH}" stroke="#94a3b8" stroke-width="1.5" />
2937
+ ${bars}
2938
+ ${catLabels}
2939
+ ${legend}
2940
+ </svg>
2941
+ `.trim();
2942
+ }
2591
2943
  };
2592
2944
  function docxPlugin() {
2593
2945
  return new DocxPlugin();
@@ -3154,6 +3506,16 @@ var CodePlugin = class {
3154
3506
  execute: () => {
3155
3507
  instance.print?.();
3156
3508
  }
3509
+ },
3510
+ {
3511
+ id: "open-window",
3512
+ icon: "open-window",
3513
+ label: "Open in Separate Full Window",
3514
+ type: "button",
3515
+ group: "actions",
3516
+ execute: () => {
3517
+ instance.openInSeparateWindow?.();
3518
+ }
3157
3519
  }
3158
3520
  );
3159
3521
  return actions;
@@ -4322,6 +4684,14 @@ var RtfPlugin = class {
4322
4684
  type: "button",
4323
4685
  group: "actions",
4324
4686
  execute: () => instance.print?.()
4687
+ },
4688
+ {
4689
+ id: "open-window",
4690
+ icon: "open-window",
4691
+ label: "Open in Separate Full Window",
4692
+ type: "button",
4693
+ group: "actions",
4694
+ execute: () => instance.openInSeparateWindow?.()
4325
4695
  }
4326
4696
  );
4327
4697
  return actions;
@@ -4374,59 +4744,54 @@ var RtfPlugin = class {
4374
4744
  }
4375
4745
  const doc = new RTFJS__namespace.Document(ctx.buffer, {});
4376
4746
  const htmlElements = await doc.render();
4377
- if (htmlElements.length === 1) {
4378
- const singleEl = htmlElements[0];
4379
- wrapper.appendChild(singleEl);
4380
- const children = Array.from(singleEl.children);
4381
- const secH = singleEl.offsetHeight || singleEl.scrollHeight;
4382
- if (secH > 1300 && children.length > 1) {
4383
- const childHeights = children.map((c) => {
4384
- const rectH = c.getBoundingClientRect().height;
4385
- const offH = c.offsetHeight;
4386
- const textLen = c.textContent?.trim().length || 0;
4387
- const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
4388
- return Math.max(rectH, offH, estH);
4389
- });
4390
- wrapper.innerHTML = "";
4391
- const createRtfCard = () => {
4392
- const card = document.createElement("div");
4393
- card.className = "fp-rtf-page-card";
4394
- card.style.backgroundColor = "#ffffff";
4395
- card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
4396
- card.style.borderRadius = "4px";
4397
- card.style.padding = "72px 56px";
4398
- card.style.width = "816px";
4399
- card.style.minHeight = "1056px";
4400
- card.style.boxSizing = "border-box";
4401
- card.style.marginBottom = "24px";
4402
- return card;
4403
- };
4404
- let curCard = createRtfCard();
4405
- wrapper.appendChild(curCard);
4406
- pageElements = [curCard];
4407
- let curH = 0;
4408
- const maxH = 920;
4409
- for (let i = 0; i < children.length; i++) {
4410
- const child = children[i];
4411
- const chH = childHeights[i];
4412
- curCard.appendChild(child);
4413
- curH += chH;
4414
- if (curH >= maxH && i < children.length - 1) {
4415
- curCard = createRtfCard();
4416
- wrapper.appendChild(curCard);
4417
- pageElements.push(curCard);
4418
- curH = 0;
4419
- }
4420
- }
4747
+ const contentNodes = [];
4748
+ for (const item of htmlElements) {
4749
+ if (item.children && item.children.length > 0 && !item.tagName.toLowerCase().startsWith("table")) {
4750
+ contentNodes.push(...Array.from(item.children));
4421
4751
  } else {
4422
- pageElements = [singleEl];
4752
+ contentNodes.push(item);
4423
4753
  }
4424
- } else {
4425
- pageElements = htmlElements;
4426
- for (let i = 0; i < htmlElements.length; i++) {
4427
- const el = htmlElements[i];
4428
- el.style.display = i === 0 ? "block" : "none";
4429
- wrapper.appendChild(el);
4754
+ }
4755
+ wrapper.innerHTML = "";
4756
+ contentNodes.forEach((node) => wrapper.appendChild(node));
4757
+ const childHeights = contentNodes.map((c) => {
4758
+ const rectH = c.getBoundingClientRect ? c.getBoundingClientRect().height : 0;
4759
+ const offH = c.offsetHeight || 0;
4760
+ const textLen = c.textContent?.trim().length || 0;
4761
+ const estH = Math.max(24, Math.ceil(textLen / 75) * 22 + 14);
4762
+ return Math.max(rectH, offH, estH);
4763
+ });
4764
+ wrapper.innerHTML = "";
4765
+ const createRtfCard = () => {
4766
+ const card = document.createElement("div");
4767
+ card.className = "fp-rtf-page-card";
4768
+ card.style.backgroundColor = "#ffffff";
4769
+ card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
4770
+ card.style.borderRadius = "4px";
4771
+ card.style.padding = "72px 56px";
4772
+ card.style.width = "816px";
4773
+ card.style.minHeight = "1056px";
4774
+ card.style.boxSizing = "border-box";
4775
+ card.style.marginBottom = "24px";
4776
+ card.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
4777
+ card.style.lineHeight = "1.6";
4778
+ return card;
4779
+ };
4780
+ let curCard = createRtfCard();
4781
+ wrapper.appendChild(curCard);
4782
+ pageElements = [curCard];
4783
+ let curH = 0;
4784
+ const maxH = 912;
4785
+ for (let i = 0; i < contentNodes.length; i++) {
4786
+ const child = contentNodes[i];
4787
+ const chH = childHeights[i];
4788
+ curCard.appendChild(child);
4789
+ curH += chH;
4790
+ if (curH >= maxH && i < contentNodes.length - 1) {
4791
+ curCard = createRtfCard();
4792
+ wrapper.appendChild(curCard);
4793
+ pageElements.push(curCard);
4794
+ curH = 0;
4430
4795
  }
4431
4796
  }
4432
4797
  } catch (err) {
@@ -4795,6 +5160,14 @@ var OpenDocumentPlugin = class {
4795
5160
  type: "button",
4796
5161
  group: "actions",
4797
5162
  execute: () => instance.print?.()
5163
+ },
5164
+ {
5165
+ id: "open-window",
5166
+ icon: "open-window",
5167
+ label: "Open in Separate Full Window",
5168
+ type: "button",
5169
+ group: "actions",
5170
+ execute: () => instance.openInSeparateWindow?.()
4798
5171
  }
4799
5172
  );
4800
5173
  return actions;
@@ -5383,6 +5756,14 @@ var DocPlugin = class {
5383
5756
  type: "button",
5384
5757
  group: "actions",
5385
5758
  execute: () => instance.print?.()
5759
+ },
5760
+ {
5761
+ id: "open-window",
5762
+ icon: "open-window",
5763
+ label: "Open in Separate Full Window",
5764
+ type: "button",
5765
+ group: "actions",
5766
+ execute: () => instance.openInSeparateWindow?.()
5386
5767
  }
5387
5768
  );
5388
5769
  return actions;
@@ -5674,9 +6055,25 @@ var DocPlugin = class {
5674
6055
  heuristicTextExtraction(buffer) {
5675
6056
  return this.extractStringsFromBytes(new Uint8Array(buffer));
5676
6057
  }
6058
+ cleanWordDocFields(text) {
6059
+ if (!text) return "";
6060
+ let cleaned = text.replace(
6061
+ /\x13\s*HYPERLINK\s*"?([^"\x14]+)"?\s*\x14([\s\S]*?)\x15/gi,
6062
+ (_match, url, label) => {
6063
+ const cleanUrl = url.trim();
6064
+ const cleanLabel = label.trim() || cleanUrl;
6065
+ return `<a href="${cleanUrl}" target="_blank" rel="noopener noreferrer" style="color: #2563eb; text-decoration: underline;">${cleanLabel}</a>`;
6066
+ }
6067
+ );
6068
+ cleaned = cleaned.replace(/\x13[^\x14\x15]*\x14([^\x15]*)\x15/g, "$1");
6069
+ cleaned = cleaned.replace(/\x13[^\x15]*\x15/g, "");
6070
+ cleaned = cleaned.replace(/[\x13\x14\x15]/g, "");
6071
+ return cleaned;
6072
+ }
5677
6073
  splitIntoPages(text) {
5678
6074
  if (!text) return [""];
5679
- const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
6075
+ const cleanedText = this.cleanWordDocFields(text);
6076
+ const normalized = cleanedText.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
5680
6077
  const explicitParts = normalized.split(/[\x0C\f]|\n\s*[-=_]{3,}\s*(?:PAGE|Page|page break)[\s\d\w-]*[-=_]{3,}\s*\n/i).map((p) => p.trim()).filter((p) => p.length > 0);
5681
6078
  if (explicitParts.length === 0) explicitParts.push(normalized);
5682
6079
  const maxLinesPerPage = 32;
@@ -5687,7 +6084,8 @@ var DocPlugin = class {
5687
6084
  let currentLines = [];
5688
6085
  let count = 0;
5689
6086
  for (const line of lines) {
5690
- const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
6087
+ const plainLine = line.replace(/<[^>]+>/g, "");
6088
+ const vLines = Math.max(1, Math.ceil((plainLine.length || 1) / charsPerLine));
5691
6089
  if (count + vLines > maxLinesPerPage && currentLines.length > 0) {
5692
6090
  finalPages.push(currentLines.join("\n"));
5693
6091
  currentLines = [];
@@ -5763,25 +6161,26 @@ var DocPlugin = class {
5763
6161
  i++;
5764
6162
  continue;
5765
6163
  }
6164
+ const sanitizeOptions = { ADD_TAGS: ["a"], ADD_ATTR: ["href", "target", "rel", "style"] };
5766
6165
  if (line.length < 60 && !line.endsWith(".") && (/^[A-Z0-9\s:_-]+$/.test(line) || line.startsWith("#"))) {
5767
6166
  if (inList) {
5768
6167
  html += "</ul>";
5769
6168
  inList = false;
5770
6169
  }
5771
- html += `<h2 style="font-size: 16px; font-weight: 700; color: #1e3a8a; margin: 16px 0 8px; border-bottom: 1px solid #e2e8f0; padding-bottom: 4px;">${DOMPurify6__default.default.sanitize(line)}</h2>`;
6170
+ html += `<h2 style="font-size: 16px; font-weight: 700; color: #1e3a8a; margin: 16px 0 8px; border-bottom: 1px solid #e2e8f0; padding-bottom: 4px;">${DOMPurify6__default.default.sanitize(line, sanitizeOptions)}</h2>`;
5772
6171
  } else if (line.startsWith("\u2022") || line.startsWith("-") || line.startsWith("*")) {
5773
6172
  if (!inList) {
5774
6173
  html += '<ul style="margin: 8px 0; padding-left: 24px;">';
5775
6174
  inList = true;
5776
6175
  }
5777
6176
  const bulletText = line.replace(/^[•\-\*]\s*/, "");
5778
- html += `<li style="margin: 4px 0; line-height: 1.15; font-size: 12pt;">${DOMPurify6__default.default.sanitize(bulletText)}</li>`;
6177
+ html += `<li style="margin: 4px 0; line-height: 1.15; font-size: 12pt;">${DOMPurify6__default.default.sanitize(bulletText, sanitizeOptions)}</li>`;
5779
6178
  } else {
5780
6179
  if (inList) {
5781
6180
  html += "</ul>";
5782
6181
  inList = false;
5783
6182
  }
5784
- html += `<p style="line-height: 1.15; margin: 0; font-size: 12pt; text-align: justify;">${DOMPurify6__default.default.sanitize(line)}</p>`;
6183
+ html += `<p style="line-height: 1.15; margin: 0; font-size: 12pt; text-align: justify;">${DOMPurify6__default.default.sanitize(line, sanitizeOptions)}</p>`;
5785
6184
  }
5786
6185
  i++;
5787
6186
  }
@@ -6354,6 +6753,7 @@ exports.excelPlugin = excelPlugin;
6354
6753
  exports.extractExtension = extractExtension;
6355
6754
  exports.formatFileSize = formatFileSize;
6356
6755
  exports.getDefaultPlugins = getDefaultPlugins;
6756
+ exports.getTransferPayload = getTransferPayload;
6357
6757
  exports.htmlPreviewPlugin = htmlPreviewPlugin;
6358
6758
  exports.markdownPlugin = markdownPlugin;
6359
6759
  exports.mediaPlugin = mediaPlugin;
@@ -6366,6 +6766,7 @@ exports.printElement = printElement;
6366
6766
  exports.rtfPlugin = rtfPlugin;
6367
6767
  exports.sanitizeHTML = sanitizeHTML;
6368
6768
  exports.sanitizeSVG = sanitizeSVG;
6769
+ exports.saveTransferPayload = saveTransferPayload;
6369
6770
  exports.sourceToArrayBuffer = sourceToArrayBuffer;
6370
6771
  exports.threeDPlugin = threeDPlugin;
6371
6772
  //# sourceMappingURL=index.cjs.map