pptx-react-viewer 2.19.7 → 2.20.1

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 (108) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +1 -1
  3. package/dist/{AiChatPanel-WVO66CKC.mjs → AiChatPanel-NRWACXJ7.mjs} +4 -4
  4. package/dist/AiChatPanel-NRWACXJ7.mjs.br +0 -0
  5. package/dist/AiChatPanel-NRWACXJ7.mjs.gz +0 -0
  6. package/dist/{AiChatPanel-MAC2Z5SK.js → AiChatPanel-ZSVNVRM5.js} +24 -24
  7. package/dist/AiChatPanel-ZSVNVRM5.js.br +0 -0
  8. package/dist/AiChatPanel-ZSVNVRM5.js.gz +0 -0
  9. package/dist/{Model3DScene-CU4WGIMH.js → Model3DScene-3HGARMTA.js} +2 -2
  10. package/dist/Model3DScene-3HGARMTA.js.br +0 -0
  11. package/dist/Model3DScene-3HGARMTA.js.gz +0 -0
  12. package/dist/{Model3DScene-PTCZUGIT.mjs → Model3DScene-IFYFOD6F.mjs} +1 -1
  13. package/dist/{Model3DScene-PTCZUGIT.mjs.br → Model3DScene-IFYFOD6F.mjs.br} +0 -0
  14. package/dist/Model3DScene-IFYFOD6F.mjs.gz +0 -0
  15. package/dist/{chunk-ZPNLWBED.mjs → chunk-2MENHAYJ.mjs} +814 -449
  16. package/dist/chunk-2MENHAYJ.mjs.br +0 -0
  17. package/dist/chunk-2MENHAYJ.mjs.gz +0 -0
  18. package/dist/{chunk-GUGHIQ4P.js → chunk-4Z4HEIP5.js} +847 -456
  19. package/dist/chunk-4Z4HEIP5.js.br +0 -0
  20. package/dist/chunk-4Z4HEIP5.js.gz +0 -0
  21. package/dist/{chunk-MVKRI3CZ.js → chunk-6CPUGAK7.js} +2 -0
  22. package/dist/chunk-6CPUGAK7.js.br +0 -0
  23. package/dist/{chunk-MVKRI3CZ.js.gz → chunk-6CPUGAK7.js.gz} +0 -0
  24. package/dist/{chunk-XDF76VFA.js → chunk-GKOJO67G.js} +480 -507
  25. package/dist/chunk-GKOJO67G.js.br +0 -0
  26. package/dist/chunk-GKOJO67G.js.gz +0 -0
  27. package/dist/{chunk-5BG5BANR.mjs → chunk-HZ2PAL7P.mjs} +153 -338
  28. package/dist/chunk-HZ2PAL7P.mjs.br +0 -0
  29. package/dist/chunk-HZ2PAL7P.mjs.gz +0 -0
  30. package/dist/{chunk-V5PW4QCE.js → chunk-LLZ25OVR.js} +178 -172
  31. package/dist/chunk-LLZ25OVR.js.br +0 -0
  32. package/dist/chunk-LLZ25OVR.js.gz +0 -0
  33. package/dist/{chunk-SQJBFMEX.mjs → chunk-MZOZNBRO.mjs} +2 -0
  34. package/dist/chunk-MZOZNBRO.mjs.br +0 -0
  35. package/dist/{chunk-SQJBFMEX.mjs.gz → chunk-MZOZNBRO.mjs.gz} +0 -0
  36. package/dist/{chunk-QZV7XDQG.mjs → chunk-O5BR276S.mjs} +25 -19
  37. package/dist/chunk-O5BR276S.mjs.br +0 -0
  38. package/dist/chunk-O5BR276S.mjs.gz +0 -0
  39. package/dist/{chunk-EVM5OFAD.js → chunk-QJJX2E6I.js} +3 -3
  40. package/dist/chunk-QJJX2E6I.js.br +0 -0
  41. package/dist/chunk-QJJX2E6I.js.gz +0 -0
  42. package/dist/{chunk-DZHCLAH3.mjs → chunk-RJ26DQIM.mjs} +1 -1
  43. package/dist/chunk-RJ26DQIM.mjs.br +0 -0
  44. package/dist/chunk-RJ26DQIM.mjs.gz +0 -0
  45. package/dist/{chunk-LP3Y4NXE.mjs → chunk-SZJLZWEX.mjs} +104 -131
  46. package/dist/chunk-SZJLZWEX.mjs.br +0 -0
  47. package/dist/chunk-SZJLZWEX.mjs.gz +0 -0
  48. package/dist/{chunk-JENKEQZP.js → chunk-WCJ3HF4C.js} +1174 -1359
  49. package/dist/chunk-WCJ3HF4C.js.br +0 -0
  50. package/dist/chunk-WCJ3HF4C.js.gz +0 -0
  51. package/dist/i18n.js +4 -4
  52. package/dist/i18n.js.br +0 -0
  53. package/dist/i18n.js.gz +0 -0
  54. package/dist/i18n.mjs +1 -1
  55. package/dist/i18n.mjs.br +0 -0
  56. package/dist/i18n.mjs.gz +0 -0
  57. package/dist/index.js +47 -47
  58. package/dist/index.js.br +0 -0
  59. package/dist/index.js.gz +0 -0
  60. package/dist/index.mjs +6 -6
  61. package/dist/index.mjs.br +0 -0
  62. package/dist/index.mjs.gz +0 -0
  63. package/dist/internals.d.ts.map +1 -1
  64. package/dist/internals.js +79 -79
  65. package/dist/internals.js.br +0 -0
  66. package/dist/internals.js.gz +0 -0
  67. package/dist/internals.mjs +4 -4
  68. package/dist/internals.mjs.br +0 -0
  69. package/dist/internals.mjs.gz +0 -0
  70. package/dist/pptx-viewer.css +1 -1
  71. package/dist/pptx-viewer.css.br +0 -0
  72. package/dist/pptx-viewer.css.gz +0 -0
  73. package/dist/viewer/index.js +27 -27
  74. package/dist/viewer/index.js.br +0 -0
  75. package/dist/viewer/index.js.gz +0 -0
  76. package/dist/viewer/index.mjs +6 -6
  77. package/dist/viewer/index.mjs.br +0 -0
  78. package/dist/viewer/index.mjs.gz +0 -0
  79. package/package.json +1 -1
  80. package/dist/AiChatPanel-MAC2Z5SK.js.br +0 -0
  81. package/dist/AiChatPanel-MAC2Z5SK.js.gz +0 -0
  82. package/dist/AiChatPanel-WVO66CKC.mjs.br +0 -0
  83. package/dist/AiChatPanel-WVO66CKC.mjs.gz +0 -0
  84. package/dist/Model3DScene-CU4WGIMH.js.br +0 -0
  85. package/dist/Model3DScene-CU4WGIMH.js.gz +0 -0
  86. package/dist/Model3DScene-PTCZUGIT.mjs.gz +0 -0
  87. package/dist/chunk-5BG5BANR.mjs.br +0 -0
  88. package/dist/chunk-5BG5BANR.mjs.gz +0 -0
  89. package/dist/chunk-DZHCLAH3.mjs.br +0 -0
  90. package/dist/chunk-DZHCLAH3.mjs.gz +0 -0
  91. package/dist/chunk-EVM5OFAD.js.br +0 -0
  92. package/dist/chunk-EVM5OFAD.js.gz +0 -0
  93. package/dist/chunk-GUGHIQ4P.js.br +0 -0
  94. package/dist/chunk-GUGHIQ4P.js.gz +0 -0
  95. package/dist/chunk-JENKEQZP.js.br +0 -0
  96. package/dist/chunk-JENKEQZP.js.gz +0 -0
  97. package/dist/chunk-LP3Y4NXE.mjs.br +0 -0
  98. package/dist/chunk-LP3Y4NXE.mjs.gz +0 -0
  99. package/dist/chunk-MVKRI3CZ.js.br +0 -0
  100. package/dist/chunk-QZV7XDQG.mjs.br +0 -0
  101. package/dist/chunk-QZV7XDQG.mjs.gz +0 -0
  102. package/dist/chunk-SQJBFMEX.mjs.br +0 -0
  103. package/dist/chunk-V5PW4QCE.js.br +0 -0
  104. package/dist/chunk-V5PW4QCE.js.gz +0 -0
  105. package/dist/chunk-XDF76VFA.js.br +0 -0
  106. package/dist/chunk-XDF76VFA.js.gz +0 -0
  107. package/dist/chunk-ZPNLWBED.mjs.br +0 -0
  108. package/dist/chunk-ZPNLWBED.mjs.gz +0 -0
Binary file
Binary file
@@ -2119,6 +2119,8 @@ var translationsEn = {
2119
2119
  "pptx.ribbon.customColour": "Custom colour...",
2120
2120
  "pptx.ribbon.textHighlightColour": "Text highlight colour",
2121
2121
  "pptx.ribbon.highlightColourValue": "Highlight colour {{color}}",
2122
+ "pptx.ribbon.fillColourValue": "Fill colour {{color}}",
2123
+ "pptx.ribbon.outlineColourValue": "Outline colour {{color}}",
2122
2124
  "pptx.ribbon.bulletList": "Bullet list",
2123
2125
  "pptx.ribbon.justify": "Justify",
2124
2126
  "pptx.toolbar.findAndReplace": "Find and replace",
Binary file
@@ -1,5 +1,5 @@
1
- import { translationsEn } from './chunk-SQJBFMEX.mjs';
2
- import { SHAPE_PRESET_DEFS, VIEWER_SHORTCUT_REFERENCE, getAnimationInitialStyle, cloneHistorySnapshot, hasShapeProperties, getImageFitStyle, isImageLikeElement, getImageTilingStyle, runMediaCommand, findMediaElementByElementId, mediaPlaybackAttributes, buildTextBlockStyle, hasTextProperties, toCssWritingMode, toCssTextOrientation, toCssVerticalDirection, buildTextBodyLayoutStyle, buildTextBody3DSceneStyle, buildParagraphs, colorWithOpacity, normalizeHexColor, build3DExtrusionData, getComputedFillStyle, getComputedEffectStyle, getComputedStrokeStyle, isStrokeOnlyPresetElement, resolveShapeGeometry, normalizeStrokeDashType, getSvgStrokeDasharray, buildSvgGradientDef, isCalloutShape, getCalloutLeaderLineGeometry, buildCalloutLeaderLineSvgPath, getCalloutViewBoxBounds, svgLineCap, getCompoundLineOffsets, getCompoundLineWidths, computeSelectionRect, DEFAULT_FONT_FAMILY, cellStyleToCss, rectToCells, isCellInRect, tableContainerCss, buildChartViewModel, resolveChartKind, chartPreserveAspectRatio, buildNotesPdfBytes, buildSlidesPdfBytes, buildPreviewAnimation, buildMotionPathPreview, getRoundRectRadiusPx2, getResolvedShapeClipPath, mediaFallbackVisual, registerPersistentAudio, resolveAutoFitFontScale, getSubstituteFontFamily, parsePanoseString, hasDistinctScriptFonts, nestedTextDecorationStyle, pieceLetterSpacing, resolveMetricTrackingPx, hollowTextFillStyle, TEXT_BUILD_ID_SEP, buildTextBuildSpec, textBuildSpanStyle, apply3dEffects, clampUnitInterval, customGeometryPathsToSvgSubpaths, svgGradientFillRef, computeColumnBoundaries, getTableCellBandStyle, parseDrawingColor, parseDrawingColorOpacity, getCellDiagonalBorders, cellRunStyle, getChartStylePalette, mediaFallbackIcon, mediaFallbackLabelKey, MEDIA_CHROME_ATTRIBUTE, convertOmmlToMathMl, sanitizeMathMl, tableCellCss, computeResizedColumnWidths, computeResizedRowHeight, DEFAULT_ROW_HEIGHT, ooxmlGradientAngleToCssDegrees, chartPartToAttrs, splitRunForMetrics, hexToRgbChannels, segmentByScript, resolveFontForScript } from './chunk-ZPNLWBED.mjs';
1
+ import { translationsEn } from './chunk-MZOZNBRO.mjs';
2
+ import { SHAPE_PRESET_DEFS, VIEWER_SHORTCUT_REFERENCE, getAnimationInitialStyle, cloneHistorySnapshot, hasShapeProperties, getImageFitStyle, isImageLikeElement, getImageTilingStyle, runMediaCommand, findMediaElementByElementId, mediaPlaybackAttributes, buildTextBlockStyle, hasTextProperties, toCssWritingMode, toCssTextOrientation, toCssVerticalDirection, buildTextBodyLayoutStyle, buildTextBody3DSceneStyle, buildParagraphs, colorWithOpacity, normalizeHexColor, build3DExtrusionData, getComputedFillStyle, getComputedEffectStyle, getComputedStrokeStyle, isStrokeOnlyPresetElement, resolveShapeGeometry, normalizeStrokeDashType, getSvgStrokeDasharray, buildSvgGradientDef, isCalloutShape, getCalloutLeaderLineGeometry, buildCalloutLeaderLineSvgPath, getCalloutViewBoxBounds, svgLineCap, getCompoundLineOffsets, getCompoundLineWidths, computeSelectionRect, DEFAULT_FONT_FAMILY, cellStyleToCss, rectToCells, isCellInRect, tableContainerCss, buildChartViewModel, resolveChartKind, chartPreserveAspectRatio, buildNotesPdfBytes, buildSlidesPdfBytes, buildPreviewAnimation, buildMotionPathPreview, getRoundRectRadiusPx2, getResolvedShapeClipPath, mediaFallbackVisual, registerPersistentAudio, resolveAutoFitFontScale, getSubstituteFontFamily, parsePanoseString, hasDistinctScriptFonts, nestedTextDecorationStyle, pieceLetterSpacing, resolveMetricTrackingPx, hollowTextFillStyle, TEXT_BUILD_ID_SEP, buildTextBuildSpec, textBuildSpanStyle, apply3dEffects, clampUnitInterval, customGeometryPathsToSvgSubpaths, svgGradientFillRef, computeColumnBoundaries, getTableCellBandStyle, parseDrawingColor, parseDrawingColorOpacity, getCellDiagonalBorders, cellRunStyle, getChartStylePalette, computeChartLegendLayout, mediaFallbackIcon, mediaFallbackLabelKey, MEDIA_CHROME_ATTRIBUTE, convertOmmlToMathMl, sanitizeMathMl, tableCellCss, computeResizedColumnWidths, computeResizedRowHeight, DEFAULT_ROW_HEIGHT, ooxmlGradientAngleToCssDegrees, chartPartToAttrs, splitRunForMetrics, hexToRgbChannels, segmentByScript, resolveFontForScript } from './chunk-2MENHAYJ.mjs';
3
3
  import { clsx } from 'clsx';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import React6, { useRef, useState, useEffect, useCallback, useMemo, useLayoutEffect } from 'react';
@@ -3612,7 +3612,6 @@ function renderTableElement(element, textStyle, options) {
3612
3612
  }
3613
3613
  );
3614
3614
  }
3615
- var LEGEND_ITEM_WIDTH = 80;
3616
3615
  function partAttrs(part) {
3617
3616
  return part ? chartPartToAttrs(part) : void 0;
3618
3617
  }
@@ -3626,8 +3625,7 @@ function buildReactChartViewModel(element) {
3626
3625
  if (element.type !== "chart" || !element.chartData) {
3627
3626
  return buildChartViewModel(element);
3628
3627
  }
3629
- const palette = resolveReactPalette(element.chartData);
3630
- const themedElement = {
3628
+ const palette = resolveReactPalette(element.chartData), themedElement = {
3631
3629
  ...element,
3632
3630
  chartData: { ...element.chartData, colorPalette: palette }
3633
3631
  };
@@ -3647,7 +3645,8 @@ function renderPrimitive(prim, key) {
3647
3645
  fill: r.fill,
3648
3646
  rx: r.rx ?? 0,
3649
3647
  opacity: r.opacity ?? 1,
3650
- ...partAttrs(r.part)
3648
+ ...partAttrs(r.part),
3649
+ children: r.title !== void 0 ? /* @__PURE__ */ jsx("title", { children: r.title }) : null
3651
3650
  },
3652
3651
  key
3653
3652
  );
@@ -3678,7 +3677,8 @@ function renderPrimitive(prim, key) {
3678
3677
  strokeWidth: p.strokeWidth,
3679
3678
  fill: p.fill,
3680
3679
  opacity: p.opacity ?? 1,
3681
- ...partAttrs(p.part)
3680
+ ...partAttrs(p.part),
3681
+ children: p.title !== void 0 ? /* @__PURE__ */ jsx("title", { children: p.title }) : null
3682
3682
  },
3683
3683
  key
3684
3684
  );
@@ -3693,7 +3693,8 @@ function renderPrimitive(prim, key) {
3693
3693
  r: c.r,
3694
3694
  fill: c.fill,
3695
3695
  opacity: c.opacity ?? 1,
3696
- ...partAttrs(c.part)
3696
+ ...partAttrs(c.part),
3697
+ children: c.title !== void 0 ? /* @__PURE__ */ jsx("title", { children: c.title }) : null
3697
3698
  },
3698
3699
  key
3699
3700
  );
@@ -3710,7 +3711,8 @@ function renderPrimitive(prim, key) {
3710
3711
  stroke: l.stroke,
3711
3712
  strokeWidth: l.strokeWidth,
3712
3713
  strokeDasharray: l.dashArray,
3713
- opacity: l.opacity ?? 1
3714
+ opacity: l.opacity ?? 1,
3715
+ children: l.title !== void 0 ? /* @__PURE__ */ jsx("title", { children: l.title }) : null
3714
3716
  },
3715
3717
  key
3716
3718
  );
@@ -3726,7 +3728,8 @@ function renderPrimitive(prim, key) {
3726
3728
  strokeWidth: p.strokeWidth,
3727
3729
  opacity: p.opacity ?? 1,
3728
3730
  strokeDasharray: p.dashArray,
3729
- ...partAttrs(p.part)
3731
+ ...partAttrs(p.part),
3732
+ children: p.title !== void 0 ? /* @__PURE__ */ jsx("title", { children: p.title }) : null
3730
3733
  },
3731
3734
  key
3732
3735
  );
@@ -3773,7 +3776,7 @@ function renderText(t, key) {
3773
3776
  );
3774
3777
  }
3775
3778
  function renderChartViewModel(elementId, vm, preserveAspectRatio = "none") {
3776
- const isVerticalLegend = vm.legendAnchor === "start";
3779
+ const legendItems = computeChartLegendLayout(vm);
3777
3780
  return /* @__PURE__ */ jsxs(
3778
3781
  "svg",
3779
3782
  {
@@ -3837,14 +3840,17 @@ function renderChartViewModel(elementId, vm, preserveAspectRatio = "none") {
3837
3840
  vm.categoryLabels.map((lbl, i) => renderText(lbl, `${elementId}-cl-${i}`)),
3838
3841
  vm.primitives.map((prim, i) => renderPrimitive(prim, `${elementId}-p-${i}`)),
3839
3842
  vm.dataLabels.map((dl, i) => renderText(dl, `${elementId}-dl-${i}`)),
3840
- vm.legend.map((entry, i) => {
3841
- const x = isVerticalLegend ? vm.legendX : vm.legendX - vm.legend.length * LEGEND_ITEM_WIDTH / 2 + i * LEGEND_ITEM_WIDTH;
3842
- const y = isVerticalLegend ? vm.legendY + i * 14 : vm.legendY;
3843
- return /* @__PURE__ */ jsxs("g", { transform: `translate(${x.toFixed(1)},${y.toFixed(1)})`, children: [
3844
- /* @__PURE__ */ jsx("rect", { x: 0, y: -7, width: 10, height: 10, rx: 2, fill: entry.color }),
3845
- /* @__PURE__ */ jsx("text", { x: 13, y: 3, fontSize: 9, fill: "#475569", children: entry.label })
3846
- ] }, `${elementId}-lg-${i}`);
3847
- })
3843
+ legendItems.map((item, i) => /* @__PURE__ */ jsxs(
3844
+ "g",
3845
+ {
3846
+ transform: `translate(${item.x.toFixed(1)},${item.y.toFixed(1)})`,
3847
+ children: [
3848
+ /* @__PURE__ */ jsx("rect", { x: 0, y: -7, width: 10, height: 10, rx: 2, fill: item.color }),
3849
+ /* @__PURE__ */ jsx("text", { x: 13, y: 3, fontSize: 9, fill: "#475569", children: item.label })
3850
+ ]
3851
+ },
3852
+ `${elementId}-lg-${i}`
3853
+ ))
3848
3854
  ]
3849
3855
  }
3850
3856
  );
Binary file
Binary file
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkGUGHIQ4P_js = require('./chunk-GUGHIQ4P.js');
3
+ var chunk4Z4HEIP5_js = require('./chunk-4Z4HEIP5.js');
4
4
  var chunk4VNS5WPM_js = require('./chunk-4VNS5WPM.js');
5
5
  var mcp = require('pptx-viewer-mcp');
6
6
  var mcpSchemas = require('pptx-viewer-mcp/schemas');
@@ -14879,7 +14879,7 @@ async function buildSlideMarkdown(slides, slideIndex2, meta3, options = {}) {
14879
14879
  };
14880
14880
  let markdown;
14881
14881
  try {
14882
- const converter = new chunkGUGHIQ4P_js.PptxMarkdownConverter(
14882
+ const converter = new chunk4Z4HEIP5_js.PptxMarkdownConverter(
14883
14883
  "",
14884
14884
  {
14885
14885
  sourceName: meta3.title ?? "deck.pptx",
@@ -15471,7 +15471,7 @@ var getTheme = (ctx) => {
15471
15471
  name: theme?.name,
15472
15472
  colorScheme: theme?.colorScheme,
15473
15473
  fontScheme: theme?.fontScheme,
15474
- availablePresets: Object.keys(chunkGUGHIQ4P_js.ThemePresets)
15474
+ availablePresets: Object.keys(chunk4Z4HEIP5_js.ThemePresets)
15475
15475
  };
15476
15476
  };
15477
15477
  var readExecutors = {
Binary file
Binary file
@@ -1,4 +1,4 @@
1
- import { ThemePresets, PptxMarkdownConverter } from './chunk-ZPNLWBED.mjs';
1
+ import { ThemePresets, PptxMarkdownConverter } from './chunk-2MENHAYJ.mjs';
2
2
  import { __export } from './chunk-XGB3TDIC.mjs';
3
3
  import * as mcp from 'pptx-viewer-mcp';
4
4
  import * as mcpSchemas from 'pptx-viewer-mcp/schemas';
Binary file
Binary file
@@ -1,6 +1,6 @@
1
- import { cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, executeMediaCommand, buildPdfFromImageData, buildNotesPdf, EMU_PER_PX, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-QZV7XDQG.mjs';
2
- import { translationsEn } from './chunk-SQJBFMEX.mjs';
3
- import { TOOLBAR_TABS, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createPresenceProjector, BROADCAST_THROTTLE_MS, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, PresentationAnimationController, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, hasShowSlideAfter, nextShowSlideIndex, previousShowSlideIndex, createPresenterShowGuard, attachPresentationVisibilityPause, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, collectImagePaths, partitionTemplateElements, resolveAuthoredCustomShowId, buildInitialGuides, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, downloadBlob, sanitizeDownloadFilename, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, detectTouchDevice, detectOrientation, isMobileViewport, MOBILE_BREAKPOINT, TABLET_BREAKPOINT, describeFontEmbedding, mayLeaveSlideShow, stopAllPersistentAudio, remapTextToSegments, guidePxToEmu, buildSaveSlides, embeddedFontSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, openPptxFile, readBackstageRecentFile, isActionHidden, canInteractWithElement, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, generatePackageReadme, presentationBaseName, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, firstShowSlideIndex, mapPresentationWheel, buildPrintDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, runPresentationAction, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, canvasToJpegData, downloadDataUrl, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, encodeGif, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, buildPrintHtmlDocument, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, setCellText, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, isPpactionUrl, parsePpactionUrl, safeOpenUrl, ACTION_BUTTON_PRESETS, elementActionToPptxAction, buildSmartArtPresetData, computeSnapToShape, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, applyResize, snapBoxToGrid, applyMotionPathPreset } from './chunk-ZPNLWBED.mjs';
1
+ import { cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, executeMediaCommand, buildPdfFromImageData, buildNotesPdf, EMU_PER_PX, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-O5BR276S.mjs';
2
+ import { translationsEn } from './chunk-MZOZNBRO.mjs';
3
+ import { TOOLBAR_TABS, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createPresenceProjector, BROADCAST_THROTTLE_MS, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, PresentationAnimationController, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, hasShowSlideAfter, nextShowSlideIndex, previousShowSlideIndex, createPresenterShowGuard, attachPresentationVisibilityPause, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, collectImagePaths, partitionTemplateElements, resolveAuthoredCustomShowId, buildInitialGuides, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, downloadBlob, sanitizeDownloadFilename, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, detectTouchDevice, detectOrientation, isMobileViewport, MOBILE_BREAKPOINT, TABLET_BREAKPOINT, describeFontEmbedding, mayLeaveSlideShow, stopAllPersistentAudio, remapTextToSegments, guidePxToEmu, buildSaveSlides, embeddedFontSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, openPptxFile, readBackstageRecentFile, isActionHidden, canInteractWithElement, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, generatePackageReadme, presentationBaseName, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, firstShowSlideIndex, mapPresentationWheel, computeColorFilter, computeSlideIndices, buildPrintDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, runPresentationAction, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, replyToCommentInList, canvasToJpegData, downloadDataUrl, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, encodeGif, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, buildPrintHtmlDocument, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, setCellText, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, isPpactionUrl, parsePpactionUrl, safeOpenUrl, ACTION_BUTTON_PRESETS, elementActionToPptxAction, isUrlSafe, buildSmartArtPresetData, computeSnapToShape, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, applyResize, snapBoxToGrid, applyMotionPathPreset } from './chunk-2MENHAYJ.mjs';
4
4
  import { useRef, useState, useEffect, useCallback, useMemo, useLayoutEffect, useSyncExternalStore, useImperativeHandle } from 'react';
5
5
  import JSZip from 'jszip';
6
6
  import { useTranslation } from 'react-i18next';
@@ -3002,65 +3002,72 @@ function useModalDismissDrag(onClose, threshold = 120) {
3002
3002
  }
3003
3003
 
3004
3004
  // src/viewer/hooks/useComments-helpers.ts
3005
- function generateCommentId() {
3006
- return `comment-${crypto.randomUUID()}`;
3007
- }
3008
- function addCommentToSlide(slides, slideIndex, comment) {
3005
+ function replaceCommentsOnSlide(slides, slideIndex, next) {
3009
3006
  return slides.map(
3010
- (entry, index) => index === slideIndex ? { ...entry, comments: [...entry.comments || [], comment] } : entry
3007
+ (entry, index) => index === slideIndex ? { ...entry, comments: next } : entry
3011
3008
  );
3012
3009
  }
3010
+ function addCommentToSlide(slides, slideIndex, text, authorName, elementId) {
3011
+ const slide = slides[slideIndex];
3012
+ if (!slide) {
3013
+ return { slides, didAdd: false };
3014
+ }
3015
+ const next = addCommentToList(
3016
+ slide.comments || [],
3017
+ text,
3018
+ authorName,
3019
+ void 0,
3020
+ void 0,
3021
+ elementId
3022
+ );
3023
+ if (!next) {
3024
+ return { slides, didAdd: false };
3025
+ }
3026
+ return { slides: replaceCommentsOnSlide(slides, slideIndex, next), didAdd: true };
3027
+ }
3013
3028
  function removeCommentFromSlide(slides, slideIndex, commentId) {
3014
- let didDelete = false;
3015
- const updated = slides.map((entry, index) => {
3016
- if (index !== slideIndex) {
3017
- return entry;
3018
- }
3019
- const existing = entry.comments || [];
3020
- const next = existing.filter((c) => {
3021
- const keep = c.id !== commentId;
3022
- if (!keep) {
3023
- didDelete = true;
3024
- }
3025
- return keep;
3026
- });
3027
- return next.length === existing.length ? entry : { ...entry, comments: next };
3028
- });
3029
- return { slides: updated, didDelete };
3029
+ const slide = slides[slideIndex];
3030
+ if (!slide) {
3031
+ return { slides, didDelete: false };
3032
+ }
3033
+ const next = removeCommentFromList(slide.comments || [], commentId);
3034
+ if (!next) {
3035
+ return { slides, didDelete: false };
3036
+ }
3037
+ return { slides: replaceCommentsOnSlide(slides, slideIndex, next), didDelete: true };
3030
3038
  }
3031
3039
  function editCommentInSlide(slides, slideIndex, commentId, newText) {
3032
- let didUpdate = false;
3033
- const updated = slides.map((entry, index) => {
3034
- if (index !== slideIndex) {
3035
- return entry;
3036
- }
3037
- const next = (entry.comments || []).map((c) => {
3038
- if (c.id !== commentId) {
3039
- return c;
3040
- }
3041
- didUpdate = true;
3042
- return { ...c, text: newText };
3043
- });
3044
- return didUpdate ? { ...entry, comments: next } : entry;
3045
- });
3046
- return { slides: updated, didUpdate };
3040
+ const slide = slides[slideIndex];
3041
+ if (!slide) {
3042
+ return { slides, didUpdate: false };
3043
+ }
3044
+ const next = editCommentInList(slide.comments || [], commentId, newText);
3045
+ if (!next) {
3046
+ return { slides, didUpdate: false };
3047
+ }
3048
+ return { slides: replaceCommentsOnSlide(slides, slideIndex, next), didUpdate: true };
3047
3049
  }
3048
3050
  function toggleResolvedInSlide(slides, slideIndex, commentId) {
3049
- let didUpdate = false;
3050
- const updated = slides.map((entry, index) => {
3051
- if (index !== slideIndex) {
3052
- return entry;
3053
- }
3054
- const next = (entry.comments || []).map((c) => {
3055
- if (c.id !== commentId) {
3056
- return c;
3057
- }
3058
- didUpdate = true;
3059
- return { ...c, resolved: !c.resolved };
3060
- });
3061
- return didUpdate ? { ...entry, comments: next } : entry;
3062
- });
3063
- return { slides: updated, didUpdate };
3051
+ const slide = slides[slideIndex];
3052
+ if (!slide) {
3053
+ return { slides, didUpdate: false };
3054
+ }
3055
+ const next = toggleCommentResolvedInList(slide.comments || [], commentId);
3056
+ if (!next) {
3057
+ return { slides, didUpdate: false };
3058
+ }
3059
+ return { slides: replaceCommentsOnSlide(slides, slideIndex, next), didUpdate: true };
3060
+ }
3061
+ function addReplyToSlide(slides, slideIndex, parentId, text, authorName) {
3062
+ const slide = slides[slideIndex];
3063
+ if (!slide) {
3064
+ return { slides, didAdd: false };
3065
+ }
3066
+ const next = replyToCommentInList(slide.comments || [], parentId, text, authorName);
3067
+ if (!next) {
3068
+ return { slides, didAdd: false };
3069
+ }
3070
+ return { slides: replaceCommentsOnSlide(slides, slideIndex, next), didAdd: true };
3064
3071
  }
3065
3072
  function pruneSlideDrafts(drafts, slideIds) {
3066
3073
  const next = {};
@@ -3111,14 +3118,21 @@ function useComments({
3111
3118
  if (draft.length === 0) {
3112
3119
  return;
3113
3120
  }
3114
- const newComment = {
3115
- id: generateCommentId(),
3116
- text: draft,
3117
- author: userName,
3118
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3119
- elementId: selectedElementId ?? void 0
3120
- };
3121
- onUpdateSlides((prev) => addCommentToSlide(prev, slideIndex, newComment));
3121
+ let didAdd = false;
3122
+ onUpdateSlides((prev) => {
3123
+ const result = addCommentToSlide(
3124
+ prev,
3125
+ slideIndex,
3126
+ draft,
3127
+ userName,
3128
+ selectedElementId ?? void 0
3129
+ );
3130
+ didAdd = result.didAdd;
3131
+ return result.slides;
3132
+ });
3133
+ if (!didAdd) {
3134
+ return;
3135
+ }
3122
3136
  setCommentDraftBySlideId((prev) => ({
3123
3137
  ...prev,
3124
3138
  [slide.id]: ""
@@ -3258,39 +3272,19 @@ function useComments({
3258
3272
  if (!slide) {
3259
3273
  return;
3260
3274
  }
3261
- const parentComment = (slide.comments || []).find((c) => c.id === commentId);
3262
- if (!parentComment) {
3263
- return;
3264
- }
3265
3275
  const replyText = String(replyDraftByCommentId[commentId] || "").trim();
3266
3276
  if (replyText.length === 0) {
3267
3277
  return;
3268
3278
  }
3269
- const replyComment = {
3270
- id: generateCommentId(),
3271
- text: replyText,
3272
- author: userName,
3273
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3274
- threadId: commentId,
3275
- elementId: parentComment.elementId
3276
- };
3277
- onUpdateSlides(
3278
- (prev) => prev.map((entry, index) => {
3279
- if (index !== slideIndex) {
3280
- return entry;
3281
- }
3282
- const updatedComments = (entry.comments || []).map((c) => {
3283
- if (c.id !== commentId) {
3284
- return c;
3285
- }
3286
- return {
3287
- ...c,
3288
- replies: [...c.replies || [], replyComment]
3289
- };
3290
- });
3291
- return { ...entry, comments: updatedComments };
3292
- })
3293
- );
3279
+ let didAdd = false;
3280
+ onUpdateSlides((prev) => {
3281
+ const result = addReplyToSlide(prev, slideIndex, commentId, replyText, userName);
3282
+ didAdd = result.didAdd;
3283
+ return result.slides;
3284
+ });
3285
+ if (!didAdd) {
3286
+ return;
3287
+ }
3294
3288
  setReplyingToCommentId(null);
3295
3289
  setReplyDraftByCommentId((prev) => {
3296
3290
  const next = { ...prev };
@@ -5412,6 +5406,9 @@ function createStructuredElementHandlers(deps) {
5412
5406
  return;
5413
5407
  }
5414
5408
  const resolved = resolveHyperlinkEditResult(data);
5409
+ if (resolved.url && !isUrlSafe(resolved.url)) {
5410
+ return;
5411
+ }
5415
5412
  const actionClick = {
5416
5413
  url: resolved.url || void 0,
5417
5414
  action: resolved.action,
@@ -7518,26 +7515,14 @@ function usePrintHandlers(input) {
7518
7515
  if (!pptxData || settings.printWhat !== "slides") {
7519
7516
  return handlePrintWithSettings(settings);
7520
7517
  }
7521
- const colorFilter = (() => {
7522
- if (settings.colorMode === "grayscale") {
7523
- return "filter: grayscale(1);";
7524
- }
7525
- if (settings.colorMode === "blackAndWhite") {
7526
- return "filter: grayscale(1) contrast(2);";
7527
- }
7528
- return "";
7529
- })();
7530
- const slideIndices = (() => {
7531
- if (settings.slideRange === "current") {
7532
- return [activeSlideIndex];
7533
- }
7534
- if (settings.slideRange === "custom") {
7535
- const from = Math.max(0, settings.customRangeFrom - 1);
7536
- const to = Math.min(slides.length - 1, settings.customRangeTo - 1);
7537
- return Array.from({ length: to - from + 1 }, (_, i) => from + i);
7538
- }
7539
- return Array.from({ length: slides.length }, (_, i) => i);
7540
- })();
7518
+ const colorFilter = computeColorFilter(settings.colorMode);
7519
+ const slideIndices = computeSlideIndices(
7520
+ settings.slideRange,
7521
+ activeSlideIndex,
7522
+ slides.length,
7523
+ settings.customRangeFrom,
7524
+ settings.customRangeTo
7525
+ );
7541
7526
  try {
7542
7527
  const svgs = exportAllSlidesToSvg(pptxData, {
7543
7528
  slideIndices
@@ -7558,26 +7543,14 @@ function usePrintHandlers(input) {
7558
7543
  };
7559
7544
  const handlePrintWithSettings = async (settings) => {
7560
7545
  setIsPrintDialogOpen(false);
7561
- const colorFilter = (() => {
7562
- if (settings.colorMode === "grayscale") {
7563
- return "filter: grayscale(1);";
7564
- }
7565
- if (settings.colorMode === "blackAndWhite") {
7566
- return "filter: grayscale(1) contrast(2);";
7567
- }
7568
- return "";
7569
- })();
7570
- const slideIndices = (() => {
7571
- if (settings.slideRange === "current") {
7572
- return [activeSlideIndex];
7573
- }
7574
- if (settings.slideRange === "custom") {
7575
- const from = Math.max(0, settings.customRangeFrom - 1);
7576
- const to = Math.min(slides.length - 1, settings.customRangeTo - 1);
7577
- return Array.from({ length: to - from + 1 }, (_, i) => from + i);
7578
- }
7579
- return Array.from({ length: slides.length }, (_, i) => i);
7580
- })();
7546
+ const colorFilter = computeColorFilter(settings.colorMode);
7547
+ const slideIndices = computeSlideIndices(
7548
+ settings.slideRange,
7549
+ activeSlideIndex,
7550
+ slides.length,
7551
+ settings.customRangeFrom,
7552
+ settings.customRangeTo
7553
+ );
7581
7554
  if (settings.printWhat === "outline") {
7582
7555
  openPrintWindow(
7583
7556
  "Outline",
Binary file
Binary file