pptx-react-viewer 3.21.0 → 4.1.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 (188) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/{AiChatPanel-UD756KAU.mjs → AiChatPanel-C3ACRWOY.mjs} +4 -4
  3. package/dist/AiChatPanel-C3ACRWOY.mjs.br +0 -0
  4. package/dist/AiChatPanel-C3ACRWOY.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-B3QM7MIC.js → AiChatPanel-GQNSKMP6.js} +25 -25
  6. package/dist/AiChatPanel-GQNSKMP6.js.br +0 -0
  7. package/dist/AiChatPanel-GQNSKMP6.js.gz +0 -0
  8. package/dist/{Area3DChartScene-435BFPLY.js → Area3DChartScene-3I6KB2DN.js} +2 -2
  9. package/dist/{Area3DChartScene-435BFPLY.js.br → Area3DChartScene-3I6KB2DN.js.br} +0 -0
  10. package/dist/Area3DChartScene-3I6KB2DN.js.gz +0 -0
  11. package/dist/{Area3DChartScene-MQKUWVMS.mjs → Area3DChartScene-4TPNRYXS.mjs} +1 -1
  12. package/dist/Area3DChartScene-4TPNRYXS.mjs.br +0 -0
  13. package/dist/Area3DChartScene-4TPNRYXS.mjs.gz +0 -0
  14. package/dist/{Bar3DChartScene-D4GMQGPN.mjs → Bar3DChartScene-V45IUIT7.mjs} +1 -1
  15. package/dist/Bar3DChartScene-V45IUIT7.mjs.br +0 -0
  16. package/dist/Bar3DChartScene-V45IUIT7.mjs.gz +0 -0
  17. package/dist/{Bar3DChartScene-KEYLVYJA.js → Bar3DChartScene-ZSCATOYF.js} +2 -2
  18. package/dist/Bar3DChartScene-ZSCATOYF.js.br +0 -0
  19. package/dist/Bar3DChartScene-ZSCATOYF.js.gz +0 -0
  20. package/dist/{Line3DChartScene-B3AWFXE4.mjs → Line3DChartScene-DCQJEZK6.mjs} +1 -1
  21. package/dist/Line3DChartScene-DCQJEZK6.mjs.br +0 -0
  22. package/dist/Line3DChartScene-DCQJEZK6.mjs.gz +0 -0
  23. package/dist/{Line3DChartScene-JYGXLE56.js → Line3DChartScene-DK55LQ2D.js} +2 -2
  24. package/dist/{Line3DChartScene-JYGXLE56.js.br → Line3DChartScene-DK55LQ2D.js.br} +0 -0
  25. package/dist/Line3DChartScene-DK55LQ2D.js.gz +0 -0
  26. package/dist/{Model3DScene-JF5J6N6W.js → Model3DScene-2WNP4XBP.js} +2 -2
  27. package/dist/Model3DScene-2WNP4XBP.js.br +0 -0
  28. package/dist/Model3DScene-2WNP4XBP.js.gz +0 -0
  29. package/dist/{Model3DScene-4TG4YRVM.mjs → Model3DScene-SA5XMR2D.mjs} +1 -1
  30. package/dist/Model3DScene-SA5XMR2D.mjs.br +0 -0
  31. package/dist/Model3DScene-SA5XMR2D.mjs.gz +0 -0
  32. package/dist/{PieChart3DScene-4BQ6PR7P.mjs → PieChart3DScene-HC2ZWL42.mjs} +1 -1
  33. package/dist/PieChart3DScene-HC2ZWL42.mjs.br +0 -0
  34. package/dist/PieChart3DScene-HC2ZWL42.mjs.gz +0 -0
  35. package/dist/{PieChart3DScene-CCQWSH3W.js → PieChart3DScene-Q75D66HS.js} +2 -2
  36. package/dist/{PieChart3DScene-CCQWSH3W.js.br → PieChart3DScene-Q75D66HS.js.br} +0 -0
  37. package/dist/PieChart3DScene-Q75D66HS.js.gz +0 -0
  38. package/dist/{SmartArt3DScene-QZGIABOK.mjs → SmartArt3DScene-D4VNNPHS.mjs} +124 -19
  39. package/dist/SmartArt3DScene-D4VNNPHS.mjs.br +0 -0
  40. package/dist/SmartArt3DScene-D4VNNPHS.mjs.gz +0 -0
  41. package/dist/{SmartArt3DScene-T236GYUT.js → SmartArt3DScene-NHD7CZJ5.js} +123 -18
  42. package/dist/SmartArt3DScene-NHD7CZJ5.js.br +0 -0
  43. package/dist/SmartArt3DScene-NHD7CZJ5.js.gz +0 -0
  44. package/dist/{SurfaceChart3DScene-FRQC5HBG.mjs → SurfaceChart3DScene-JRMX4PN5.mjs} +1 -1
  45. package/dist/SurfaceChart3DScene-JRMX4PN5.mjs.br +0 -0
  46. package/dist/SurfaceChart3DScene-JRMX4PN5.mjs.gz +0 -0
  47. package/dist/{SurfaceChart3DScene-UVZPT6OD.js → SurfaceChart3DScene-ODS5E6ZG.js} +2 -2
  48. package/dist/{SurfaceChart3DScene-UVZPT6OD.js.br → SurfaceChart3DScene-ODS5E6ZG.js.br} +0 -0
  49. package/dist/SurfaceChart3DScene-ODS5E6ZG.js.gz +0 -0
  50. package/dist/{chunk-EJMDD4VV.mjs → chunk-25CABWCR.mjs} +131 -329
  51. package/dist/chunk-25CABWCR.mjs.br +0 -0
  52. package/dist/chunk-25CABWCR.mjs.gz +0 -0
  53. package/dist/{chunk-BXMPXKV5.mjs → chunk-3B6YIH4K.mjs} +626 -133
  54. package/dist/chunk-3B6YIH4K.mjs.br +0 -0
  55. package/dist/chunk-3B6YIH4K.mjs.gz +0 -0
  56. package/dist/{chunk-BFPIMU6Q.js → chunk-A6JKOHSV.js} +2143 -1644
  57. package/dist/chunk-A6JKOHSV.js.br +0 -0
  58. package/dist/chunk-A6JKOHSV.js.gz +0 -0
  59. package/dist/{chunk-TOOKJUPG.mjs → chunk-GRAARMUW.mjs} +1 -1
  60. package/dist/chunk-GRAARMUW.mjs.br +0 -0
  61. package/dist/chunk-GRAARMUW.mjs.gz +0 -0
  62. package/dist/{chunk-H7QPQ4OR.js → chunk-MQHMMB6V.js} +5 -5
  63. package/dist/chunk-MQHMMB6V.js.br +0 -0
  64. package/dist/chunk-MQHMMB6V.js.gz +0 -0
  65. package/dist/{chunk-M6QJKPU2.js → chunk-NR4MQJM5.js} +1961 -2161
  66. package/dist/chunk-NR4MQJM5.js.br +0 -0
  67. package/dist/chunk-NR4MQJM5.js.gz +0 -0
  68. package/dist/{chunk-M24DEOP6.js → chunk-NXGUR2DO.js} +2 -0
  69. package/dist/chunk-NXGUR2DO.js.br +0 -0
  70. package/dist/chunk-NXGUR2DO.js.gz +0 -0
  71. package/dist/{chunk-R664EPDC.mjs → chunk-PC7H3C5W.mjs} +2 -0
  72. package/dist/chunk-PC7H3C5W.mjs.br +0 -0
  73. package/dist/chunk-PC7H3C5W.mjs.gz +0 -0
  74. package/dist/{chunk-SUZIFHXI.js → chunk-PUALTXTU.js} +182 -182
  75. package/dist/chunk-PUALTXTU.js.br +0 -0
  76. package/dist/chunk-PUALTXTU.js.gz +0 -0
  77. package/dist/{chunk-TMTQJAGK.mjs → chunk-Q6QJOD56.mjs} +2307 -552
  78. package/dist/chunk-Q6QJOD56.mjs.br +0 -0
  79. package/dist/chunk-Q6QJOD56.mjs.gz +0 -0
  80. package/dist/{chunk-T6V342NP.js → chunk-SK2CZQ6P.js} +2313 -551
  81. package/dist/chunk-SK2CZQ6P.js.br +0 -0
  82. package/dist/chunk-SK2CZQ6P.js.gz +0 -0
  83. package/dist/{chunk-HZEOZUUH.mjs → chunk-WLWAYLL6.mjs} +2 -2
  84. package/dist/chunk-WLWAYLL6.mjs.br +0 -0
  85. package/dist/chunk-WLWAYLL6.mjs.gz +0 -0
  86. package/dist/i18n/de.cjs +2 -0
  87. package/dist/i18n/de.cjs.br +0 -0
  88. package/dist/i18n/de.cjs.gz +0 -0
  89. package/dist/i18n/de.mjs +2 -0
  90. package/dist/i18n/de.mjs.br +0 -0
  91. package/dist/i18n/de.mjs.gz +0 -0
  92. package/dist/i18n/es.cjs +2 -0
  93. package/dist/i18n/es.cjs.br +0 -0
  94. package/dist/i18n/es.cjs.gz +0 -0
  95. package/dist/i18n/es.mjs +2 -0
  96. package/dist/i18n/es.mjs.br +0 -0
  97. package/dist/i18n/es.mjs.gz +0 -0
  98. package/dist/i18n/fr.cjs +2 -0
  99. package/dist/i18n/fr.cjs.br +0 -0
  100. package/dist/i18n/fr.cjs.gz +0 -0
  101. package/dist/i18n/fr.mjs +2 -0
  102. package/dist/i18n/fr.mjs.br +0 -0
  103. package/dist/i18n/fr.mjs.gz +0 -0
  104. package/dist/i18n/zh-CN.cjs +2 -0
  105. package/dist/i18n/zh-CN.cjs.br +0 -0
  106. package/dist/i18n/zh-CN.cjs.gz +0 -0
  107. package/dist/i18n/zh-CN.mjs +2 -0
  108. package/dist/i18n/zh-CN.mjs.br +0 -0
  109. package/dist/i18n/zh-CN.mjs.gz +0 -0
  110. package/dist/i18n.js +4 -4
  111. package/dist/i18n.js.br +0 -0
  112. package/dist/i18n.js.gz +0 -0
  113. package/dist/i18n.mjs +1 -1
  114. package/dist/i18n.mjs.br +0 -0
  115. package/dist/i18n.mjs.gz +0 -0
  116. package/dist/index.d.ts +586 -7
  117. package/dist/index.js +52 -48
  118. package/dist/index.js.br +0 -0
  119. package/dist/index.js.gz +0 -0
  120. package/dist/index.mjs +6 -6
  121. package/dist/index.mjs.br +0 -0
  122. package/dist/index.mjs.gz +0 -0
  123. package/dist/internals.d.ts +447 -13
  124. package/dist/internals.js +105 -105
  125. package/dist/internals.js.br +0 -0
  126. package/dist/internals.js.gz +0 -0
  127. package/dist/internals.mjs +4 -4
  128. package/dist/internals.mjs.br +0 -0
  129. package/dist/internals.mjs.gz +0 -0
  130. package/dist/viewer/index.js +32 -32
  131. package/dist/viewer/index.js.br +0 -0
  132. package/dist/viewer/index.js.gz +0 -0
  133. package/dist/viewer/index.mjs +6 -6
  134. package/dist/viewer/index.mjs.br +0 -0
  135. package/dist/viewer/index.mjs.gz +0 -0
  136. package/package.json +2 -2
  137. package/dist/AiChatPanel-B3QM7MIC.js.br +0 -0
  138. package/dist/AiChatPanel-B3QM7MIC.js.gz +0 -0
  139. package/dist/AiChatPanel-UD756KAU.mjs.br +0 -0
  140. package/dist/AiChatPanel-UD756KAU.mjs.gz +0 -0
  141. package/dist/Area3DChartScene-435BFPLY.js.gz +0 -0
  142. package/dist/Area3DChartScene-MQKUWVMS.mjs.br +0 -0
  143. package/dist/Area3DChartScene-MQKUWVMS.mjs.gz +0 -0
  144. package/dist/Bar3DChartScene-D4GMQGPN.mjs.br +0 -0
  145. package/dist/Bar3DChartScene-D4GMQGPN.mjs.gz +0 -0
  146. package/dist/Bar3DChartScene-KEYLVYJA.js.br +0 -0
  147. package/dist/Bar3DChartScene-KEYLVYJA.js.gz +0 -0
  148. package/dist/Line3DChartScene-B3AWFXE4.mjs.br +0 -0
  149. package/dist/Line3DChartScene-B3AWFXE4.mjs.gz +0 -0
  150. package/dist/Line3DChartScene-JYGXLE56.js.gz +0 -0
  151. package/dist/Model3DScene-4TG4YRVM.mjs.br +0 -0
  152. package/dist/Model3DScene-4TG4YRVM.mjs.gz +0 -0
  153. package/dist/Model3DScene-JF5J6N6W.js.br +0 -0
  154. package/dist/Model3DScene-JF5J6N6W.js.gz +0 -0
  155. package/dist/PieChart3DScene-4BQ6PR7P.mjs.br +0 -0
  156. package/dist/PieChart3DScene-4BQ6PR7P.mjs.gz +0 -0
  157. package/dist/PieChart3DScene-CCQWSH3W.js.gz +0 -0
  158. package/dist/SmartArt3DScene-QZGIABOK.mjs.br +0 -0
  159. package/dist/SmartArt3DScene-QZGIABOK.mjs.gz +0 -0
  160. package/dist/SmartArt3DScene-T236GYUT.js.br +0 -0
  161. package/dist/SmartArt3DScene-T236GYUT.js.gz +0 -0
  162. package/dist/SurfaceChart3DScene-FRQC5HBG.mjs.br +0 -0
  163. package/dist/SurfaceChart3DScene-FRQC5HBG.mjs.gz +0 -0
  164. package/dist/SurfaceChart3DScene-UVZPT6OD.js.gz +0 -0
  165. package/dist/chunk-BFPIMU6Q.js.br +0 -0
  166. package/dist/chunk-BFPIMU6Q.js.gz +0 -0
  167. package/dist/chunk-BXMPXKV5.mjs.br +0 -0
  168. package/dist/chunk-BXMPXKV5.mjs.gz +0 -0
  169. package/dist/chunk-EJMDD4VV.mjs.br +0 -0
  170. package/dist/chunk-EJMDD4VV.mjs.gz +0 -0
  171. package/dist/chunk-H7QPQ4OR.js.br +0 -0
  172. package/dist/chunk-H7QPQ4OR.js.gz +0 -0
  173. package/dist/chunk-HZEOZUUH.mjs.br +0 -0
  174. package/dist/chunk-HZEOZUUH.mjs.gz +0 -0
  175. package/dist/chunk-M24DEOP6.js.br +0 -0
  176. package/dist/chunk-M24DEOP6.js.gz +0 -0
  177. package/dist/chunk-M6QJKPU2.js.br +0 -0
  178. package/dist/chunk-M6QJKPU2.js.gz +0 -0
  179. package/dist/chunk-R664EPDC.mjs.br +0 -0
  180. package/dist/chunk-R664EPDC.mjs.gz +0 -0
  181. package/dist/chunk-SUZIFHXI.js.br +0 -0
  182. package/dist/chunk-SUZIFHXI.js.gz +0 -0
  183. package/dist/chunk-T6V342NP.js.br +0 -0
  184. package/dist/chunk-T6V342NP.js.gz +0 -0
  185. package/dist/chunk-TMTQJAGK.mjs.br +0 -0
  186. package/dist/chunk-TMTQJAGK.mjs.gz +0 -0
  187. package/dist/chunk-TOOKJUPG.mjs.br +0 -0
  188. package/dist/chunk-TOOKJUPG.mjs.gz +0 -0
@@ -1,10 +1,10 @@
1
- import { DEFAULT_STROKE_COLOR, getConnectorPathGeometry, buildLineShadowCss, buildLineGlowFilter, renderConnectorMarker, getShapeVisualStyle, getTextStyleForElement, DEFAULT_TEXT_COLOR, renderVectorShape, isConnectorOrLineElement, build3DExtrusionData, getImageRenderStyle, cn, getImageSurfaceStyle, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, DEFAULT_FILL_COLOR, getCropShapeClipPath, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, getImageSurfaceMaskStyle, getImageTilingStyle, getDuotoneColors, getTextWarpStyle, renderTextSegments, buildReactChartViewModel, renderChartElement, MIN_ELEMENT_SIZE, buildTextBody3DSceneStyle, DEFAULT_TEXT_FONT_SIZE, DEFAULT_FONT_FAMILY, HYPERLINK_COLOR, cloneHistorySnapshot, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, buildPdfFromTiledImageData, buildNotesPdf, GRID_SIZE } from './chunk-HZEOZUUH.mjs';
2
- import { GlyphOutlineFontCache, createGlyphOutlineLookup, DEFAULT_VIEWER_OPTIONS, TOOLBAR_TABS, getSelectionControlArtworkStyle, hasShapeProperties, normalizeHexColor, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, svgLineCap, hasTextProperties, getSelectionOutlineColor, connectorWrapperTransform, getAriaRoleDescription, getAriaLabel, getAriaRole, resolveElementInteractivity, isEditableTextElement, buildTextStyleOverrideCss, isElementRendered, resolveElementAriaAttributes, shouldRenderHitTarget, elementHitTargetStyle, getImageEffectsOpacity, getImageEffectsFilter, inlineElementPointerEvents, isHollowShapeElement, LINK_TOOLTIP_HOST_CLASS, ACTION_BUTTON_PRESETS, mediaTransportVisible, isInkElement, getGroupChildParentFill, getElementLabel, getResizeHandleHitAreaStyle, paintedStrokeWidth, buildCssGradientFromShapeStyle, ensureActionAffordanceStyles, resolveElementActionAffordance, actionAffordanceLabels, paintedElementSize, getElementTransform, resolveElementHighlightClick, applyHighlightClickStyle, getComputedEffectStyle, getSoftEdgeSvgFilter, getEffectStyleSource, getBevelLightingSvgFilter, buildStrokeOutline, buildHollowHitOutline, buildSubpathFillOverlay, isImageLikeElement, strokeOutlineViewBox, resolveRevealedSmartArtNodes, resolveRevealedDrawingShapes, buildSmartArtA11y, canDrillDown, computeSmartArtElementLayout, flattenNodes, buildSummaryZoomView, isImageTiled, getImageColorWashStyle, readEditableText, placeCaretAtEnd, getPendingSelectionRestore, restoreSegmentSelection, getTextCompensationTransform, resolveChartKind, subscribeBarFacePicturePixelSamples, getBarFacePicturePixelSampleVersion, ensureChartInteractionStyles, applyChartPartHighlight, resolveRevealedChartData, formatAxisValue, buildInkGroupStrokes, getInkReplayStyles, INK_REPLAY_KEYFRAMES, buildContentPartStrokes, getContentPartReplayStyles, resolveOleType, getOleAriaLabel, getOleTypeColor, getOleTypeLabel, filterRenderedElements, resolveGroupChildFill, isLinkedTextBox, getOverflowSegments, shouldUseSvgWarp, getTextBodyRotationTransform, placeholderPromptDescriptor, attachRotateHandlePlacement, elementIdSelector, createRotationDrag, ACTION_INDICATOR_CLASS, ACTION_INDICATOR_ICON_PATH, LINK_TOOLTIP_CLASS, LINK_TOOLTIP_PANEL_CLASS, LINK_TOOLTIP_LABEL_CLASS, LINK_TOOLTIP_HINT_CLASS, DEFAULT_PALETTE2, resolvePalette, computeDrawingViewBox, projectDrawingShapes, resolveRevealedDrawingShapeNodeIds, styleShadowFilter, buildChromeStyle, measureSvgViewportRect, modelDataToBlobUrl, getImageSvgFilters, buildDuotoneCacheKey, getDuotoneCachedResult, applyDuotone, setDuotoneCachedResult, buildCacheKey, DEFAULT_COLOR_CHANGE_TOLERANCE, getCachedResult, applyColorChange, setCachedResult, inlineListBodyText, createInlineListSeed, readListActivationSelection, createInlineListModelObserver, bindInlineListParagraph, bindInlineListRun, attachInlineListController, restoreInlineListBodySelection, getInlineEditorSelectionResult, isBulletMarkerSegment, findChartPartTarget, buildSurfaceChart3DDataForElement, buildBarChart3DDataForElement, buildLineChart3DDataForElement, buildAreaChart3DDataForElement, buildPieChart3DDataForElement, withChartTitle, buildSmartArt3DModel, collectCoherent3DOffNodeIds, isBrowserOpenableMime, formatBytes, getOleDisplayName, getOleBadgeLabel, openUrlInNewTab, getSubstituteFontFamily, hasGlyphEnvelope, buildGlyphEnvelope, getWarpPath, isWedgeCalloutPresetShape, isElementActionable, centeredSvgTextLines, findSmartArtNodeText, setSmartArtNodeStyle, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, updateSmartArtNodeText, advanceChartMarkDrag, advanceChartValueDrag, buildChartMarkDragGeometry, beginChartMarkDrag, beginChartValueDrag, groupIntoParagraphs, substituteFieldText, computeInlineEditorRect, withChartPointValue, MIN_TOUCH_TARGET_PX, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, createPresenceProjector, BROADCAST_THROTTLE_MS, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, createActiveAnimationGroup, cancelBuildReveal, clearPlaybackTimers, PresentationAnimationController, resolveMediaTimeNodeElementIds, advanceMainSequence, playGroup, 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, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, visibleTemplateElements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, createPresentationLoadResources, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, partitionTemplateElements, seedRecentColors, resolveAuthoredCustomShowId, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, updateElement, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, canInteractWithElement, prepareExportClone, normalizeColorsForCapture, preprocessCssForCapture, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, resolveImageResolutionScale, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, resolveAuthoredSlideRange, mayLeaveSlideShow, stopAllPersistentAudio, guidePxToEmu, buildSaveSlides, buildDeckSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, collectReferencedFontFamilies, resolveGoogleWebfontHref, syncGoogleWebfontStylesheet, selectGoogleWebfontFamilies, fetchGoogleWebfontOutlineBytes, mapSlideShowStartKey, mapEditorKey, isEditorTextInputTarget, prepareElementForInsertion, createViewerOptionsStore, observeYDocSlides, LOCAL_SYNC_ORIGIN, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, checkModifyPassword, viewerPreferencesFromViewProperties, DEFAULT_VIEWER_PREFERENCES, viewPropertiesPatchFromPreferences, openPptxFile, readBackstageRecentFile, MORPH_CROSSFADE_GROUP_STYLE, MORPH_CROSSFADE_HALF_STYLE, getSlideTransitionAnimations, getFragmentedTransitionDescriptor, SLIDE_TRANSITION_KEYFRAMES, isActionHidden, buildInlineTextCommitPatch, resolveInlineEditAutoFitHeight, resolveInlineEditNormAutofitShrink, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, downloadBlob, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, mapPresentationWheel, openPendingPrintWindow, computeColorFilter, filterHiddenSlideIndices, computeSlideIndices, buildPrintDocument, finishPrintWindow, buildPrintHtmlDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, reResolveElementColors, resolveViewportFitOptions, calculateViewportFit, scheduleAutoAdvanceChain, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, resolveTransitionSoundAction, runPresentationAction, safeOpenUrl, buildRunProgramNotice, toggleStageElementMedia, resolveOleVerbTarget, downloadDataUrl, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, remapTextToSegments, buildInlineListStylePatch, applyActiveInlineListFormatting, applyListStyleUpdate, setPendingSelectionRestore, applyTextStyleUpdate, toggleSelectionBullets, transformInlineListCase, applyCaseTransformToSegments, transformTextCase, resolveExportCaptureDecision, recordProgressPercent, computeGridSpacingPx, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, overlayMasterViewInlineSnapshot, overlayInlineTextSnapshot, cloneElementUpdates, assertElementUpdateTarget, prepareElementUpdateBatch, createWriteBackScheduler, observeExternalCollaborationReadiness, resolveHistoryDepth, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, replyToCommentInList, removeTableElementColumn, insertTableElementColumn, removeTableElementRow, insertTableElementRow, updateCellTextStyleInRawXml, setCellText, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, stopCaptureStream, GIF_POST_CAPTURE_MAX_SIDE, encodeGif, rasterResultToPngBlob, rasterizeElementTiles, placeTileOnPage, PDF_SLIDES_PAGE_WIDTH_PT, PDF_SLIDES_PAGE_HEIGHT_PT, canvasToJpegData, rasterizeElementTiledToCanvas, isPpactionUrl, parsePpactionUrl, resolvePresentationAction, elementActionToPptxAction, isUrlSafe, buildSmartArtPresetData, classifyMediaType, computeSnapToShape, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, borrowExternalCollaborationAwareness, observeExternalCollaborationSession, clampGifDimensions, rasterizeElement, shouldConfirmExternalHyperlink, applyResize, lockResizeAspect, snapBoxToGrid, applyMotionPathPreset, bringForward, sendBackward, bringToFront, sendToBack } from './chunk-TMTQJAGK.mjs';
3
- import { translationsEn } from './chunk-R664EPDC.mjs';
4
- import React18, { createContext, useMemo, useState, useCallback, useEffect, Suspense, useRef, useLayoutEffect, useContext, useSyncExternalStore, useImperativeHandle } from 'react';
1
+ import { DEFAULT_STROKE_COLOR, getConnectorPathGeometry, buildLineShadowCss, buildLineGlowFilter, renderConnectorMarker, getShapeVisualStyle, getTextStyleForElement, DEFAULT_TEXT_COLOR, renderVectorShape, isConnectorOrLineElement, build3DExtrusionData, getImageRenderStyle, cn, getImageSurfaceStyle, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, DEFAULT_FILL_COLOR, getCropShapeClipPath, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, getImageSurfaceMaskStyle, getImageTilingStyle, getDuotoneColors, getTextWarpStyle, renderTextSegments, buildReactChartViewModel, renderChartElement, MIN_ELEMENT_SIZE, buildTextBody3DSceneStyle, DEFAULT_TEXT_FONT_SIZE, DEFAULT_FONT_FAMILY, HYPERLINK_COLOR, cloneHistorySnapshot, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, buildPdfFromTiledImageData, GRID_SIZE, buildNotesPdf } from './chunk-WLWAYLL6.mjs';
2
+ import { GlyphOutlineFontCache, createGlyphOutlineLookup, DEFAULT_VIEWER_OPTIONS, TOOLBAR_TABS, getSelectionControlArtworkStyle, hasShapeProperties, normalizeHexColor, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, svgLineCap, hasTextProperties, getSelectionOutlineColor, connectorWrapperTransform, getAriaRoleDescription, getAriaLabel, getAriaRole, resolveElementInteractivity, isEditableTextElement, buildTextStyleOverrideCss, isElementRendered, resolveElementAriaAttributes, shouldRenderHitTarget, elementHitTargetStyle, getImageEffectsOpacity, getImageEffectsFilter, inlineElementPointerEvents, isHollowShapeElement, LINK_TOOLTIP_HOST_CLASS, ACTION_BUTTON_PRESETS, mediaTransportVisible, isInkElement, getGroupChildParentFill, getElementLabel, getResizeHandleHitAreaStyle, paintedStrokeWidth, buildCssGradientFromShapeStyle, ensureActionAffordanceStyles, resolveElementActionAffordance, actionAffordanceLabels, paintedElementSize, getElementTransform, resolveElementHighlightClick, applyHighlightClickStyle, getComputedEffectStyle, getSoftEdgeSvgFilter, getEffectStyleSource, getBevelLightingSvgFilter, buildStrokeOutline, buildHollowHitOutline, buildSubpathFillOverlay, isImageLikeElement, strokeOutlineViewBox, resolveRevealedSmartArtNodes, resolveRevealedDrawingShapes, buildSmartArtA11y, canDrillDown, computeSmartArtElementLayout, flattenNodes, buildSummaryZoomView, isImageTiled, getImageColorWashStyle, readEditableText, placeCaretAtEnd, getPendingSelectionRestore, restoreSegmentSelection, getTextCompensationTransform, resolveChartKind, subscribeBarFacePicturePixelSamples, getBarFacePicturePixelSampleVersion, ensureChartInteractionStyles, applyChartPartHighlight, resolveRevealedChartData, formatAxisValue, buildInkGroupStrokes, getInkReplayStyles, INK_REPLAY_KEYFRAMES, buildContentPartStrokes, getContentPartReplayStyles, resolveOleType, getOleAriaLabel, getOleTypeColor, getOleTypeLabel, filterRenderedElements, resolveGroupChildFill, isLinkedTextBox, getOverflowSegments, shouldUseSvgWarp, getTextBodyRotationTransform, placeholderPromptDescriptor, attachRotateHandlePlacement, elementIdSelector, createRotationDrag, ACTION_INDICATOR_CLASS, ACTION_INDICATOR_ICON_PATH, LINK_TOOLTIP_CLASS, LINK_TOOLTIP_PANEL_CLASS, LINK_TOOLTIP_LABEL_CLASS, LINK_TOOLTIP_HINT_CLASS, DEFAULT_PALETTE2, resolvePalette, computeDrawingViewBox, projectDrawingShapes, resolveRevealedDrawingShapeNodeIds, styleShadowFilter, buildChromeStyle, measureSvgViewportRect, modelDataToBlobUrl, getImageSvgFilters, buildDuotoneCacheKey, getDuotoneCachedResult, applyDuotone, setDuotoneCachedResult, buildCacheKey, DEFAULT_COLOR_CHANGE_TOLERANCE, getCachedResult, applyColorChange, setCachedResult, inlineListBodyText, createInlineListSeed, readListActivationSelection, createInlineListModelObserver, attachCollaborationInlineEditor, bindInlineListParagraph, bindInlineListRun, attachInlineListController, restoreInlineListBodySelection, getInlineEditorSelectionResult, isBulletMarkerSegment, findChartPartTarget, buildSurfaceChart3DDataForElement, buildBarChart3DDataForElement, buildLineChart3DDataForElement, buildAreaChart3DDataForElement, buildPieChart3DDataForElement, withChartTitle, resolveSmartArt3DLayout, buildSmartArt3DModel, collectCoherent3DOffNodeIds, isBrowserOpenableMime, formatBytes, getOleDisplayName, getOleBadgeLabel, openUrlInNewTab, getSubstituteFontFamily, hasGlyphEnvelope, buildGlyphEnvelope, getWarpPath, isWedgeCalloutPresetShape, isElementActionable, centeredSvgTextLines, findSmartArtNodeText, setSmartArtNodeStyle, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, updateSmartArtNodeText, advanceChartMarkDrag, advanceChartValueDrag, buildChartMarkDragGeometry, beginChartMarkDrag, beginChartValueDrag, groupIntoParagraphs, substituteFieldText, computeInlineEditorRect, withChartPointValue, MIN_TOUCH_TARGET_PX, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, createPresenceProjector, BROADCAST_THROTTLE_MS, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, createActiveAnimationGroup, cancelBuildReveal, clearPlaybackTimers, PresentationAnimationController, resolveMediaTimeNodeElementIds, advanceMainSequence, playGroup, 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, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, visibleTemplateElements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, createPresentationLoadResources, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, partitionTemplateElements, seedRecentColors, resolveAuthoredCustomShowId, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, updateElement, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, canInteractWithElement, prepareExportClone, normalizeColorsForCapture, preprocessCssForCapture, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, resolveImageResolutionScale, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, resolveAuthoredSlideRange, mayLeaveSlideShow, stopAllPersistentAudio, guidePxToEmu, buildSaveSlides, buildDeckSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, collectReferencedFontFamilies, resolveGoogleWebfontHref, syncGoogleWebfontStylesheet, selectGoogleWebfontFamilies, fetchGoogleWebfontOutlineBytes, mapSlideShowStartKey, mapEditorKey, isEditorTextInputTarget, prepareElementForInsertion, createViewerOptionsStore, observeYDocSlides, LOCAL_SYNC_ORIGIN, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, checkModifyPassword, viewerPreferencesFromViewProperties, DEFAULT_VIEWER_PREFERENCES, viewPropertiesPatchFromPreferences, openPptxFile, readBackstageRecentFile, resolveCollaborationShellEditability, resolveCollaborationShellState, MORPH_CROSSFADE_GROUP_STYLE, MORPH_CROSSFADE_HALF_STYLE, getSlideTransitionAnimations, getFragmentedTransitionDescriptor, SLIDE_TRANSITION_KEYFRAMES, isActionHidden, buildInlineTextCommitPatch, resolveInlineEditAutoFitHeight, resolveInlineEditNormAutofitShrink, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, downloadBlob, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, mapPresentationWheel, openPendingPrintWindow, computeColorFilter, filterHiddenSlideIndices, computeSlideIndices, buildPrintDocument, finishPrintWindow, buildPrintHtmlDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, reResolveElementColors, resolveViewportFitOptions, calculateViewportFit, scheduleAutoAdvanceChain, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, resolveTransitionSoundAction, runPresentationAction, safeOpenUrl, buildRunProgramNotice, toggleStageElementMedia, resolveOleVerbTarget, downloadDataUrl, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, remapTextToSegments, buildInlineListStylePatch, applyActiveInlineListFormatting, applyListStyleUpdate, setPendingSelectionRestore, applyTextStyleUpdate, toggleSelectionBullets, transformInlineListCase, applyCaseTransformToSegments, transformTextCase, resolveExportCaptureDecision, recordProgressPercent, computeGridSpacingPx, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, overlayMasterViewInlineSnapshot, overlayInlineTextSnapshot, cloneElementUpdates, assertElementUpdateTarget, prepareElementUpdateBatch, createWriteBackScheduler, observeExternalCollaborationReadiness, resolveHistoryDepth, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, replyToCommentInList, removeTableElementColumn, insertTableElementColumn, removeTableElementRow, insertTableElementRow, updateCellTextStyleInRawXml, setCellText, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, stopCaptureStream, GIF_POST_CAPTURE_MAX_SIDE, encodeGif, rasterResultToPngBlob, rasterizeElementTiles, placeTileOnPage, PDF_SLIDES_PAGE_WIDTH_PT, PDF_SLIDES_PAGE_HEIGHT_PT, canvasToJpegData, createSnapshotTextPositions, isPpactionUrl, parsePpactionUrl, resolvePresentationAction, elementActionToPptxAction, isUrlSafe, buildSmartArtPresetData, classifyMediaType, computeSnapToShape, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, rasterizeElementTiledToCanvas, borrowExternalCollaborationAwareness, observeExternalCollaborationSession, clampGifDimensions, rasterizeElement, shouldConfirmExternalHyperlink, applyResize, lockResizeAspect, snapBoxToGrid, applyMotionPathPreset, bringForward, sendBackward, bringToFront, sendToBack } from './chunk-Q6QJOD56.mjs';
3
+ import { translationsEn } from './chunk-PC7H3C5W.mjs';
4
+ import React20, { createContext, useMemo, useState, useCallback, useEffect, Suspense, useRef, useLayoutEffect, useContext, useSyncExternalStore, useImperativeHandle } from 'react';
5
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
6
  import { useTranslation } from 'react-i18next';
6
7
  import { flushSync } from 'react-dom';
7
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
8
  import { LuRotateCw } from 'react-icons/lu';
9
9
 
10
10
  function useVirtualizedSlides({
@@ -507,19 +507,104 @@ function useCollaborativeState({
507
507
  canvasHeight
508
508
  });
509
509
  const connectedCount = status === "connected" ? remoteUsers.length + 1 : remoteUsers.length;
510
- if (!config) {
510
+ return useMemo(
511
+ () => config ? { status, remoteUsers, broadcastPresence, connectedCount, config, doc, synced, retry } : null,
512
+ [status, remoteUsers, broadcastPresence, connectedCount, config, doc, synced, retry]
513
+ );
514
+ }
515
+ var CollaborationContext = createContext(null);
516
+ function useCollaboration() {
517
+ return useContext(CollaborationContext);
518
+ }
519
+ function CollaborationProvider({
520
+ config,
521
+ canvasWidth,
522
+ canvasHeight,
523
+ children
524
+ }) {
525
+ const value = useCollaborativeState({
526
+ config,
527
+ canvasWidth,
528
+ canvasHeight
529
+ });
530
+ return /* @__PURE__ */ jsx(CollaborationContext.Provider, { value, children });
531
+ }
532
+ function RemoteUserCursors({
533
+ remoteUsers,
534
+ activeSlideIndex,
535
+ canvasWidth,
536
+ canvasHeight
537
+ }) {
538
+ const visibleUsers = remoteUsers.filter((u) => u.activeSlideIndex === activeSlideIndex);
539
+ if (visibleUsers.length === 0) {
511
540
  return null;
512
541
  }
513
- return {
514
- status,
515
- remoteUsers,
516
- broadcastPresence,
517
- connectedCount,
518
- config,
519
- doc,
520
- synced,
521
- retry
522
- };
542
+ return /* @__PURE__ */ jsx(
543
+ "svg",
544
+ {
545
+ "data-testid": "remote-user-cursors",
546
+ "data-export-ignore": "true",
547
+ className: "absolute inset-0 pointer-events-none",
548
+ style: { zIndex: 9999 },
549
+ width: canvasWidth,
550
+ height: canvasHeight,
551
+ viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
552
+ "aria-hidden": "true",
553
+ children: visibleUsers.map((user) => /* @__PURE__ */ jsxs(
554
+ "g",
555
+ {
556
+ style: {
557
+ transform: `translate(${user.cursorX}px, ${user.cursorY}px)`,
558
+ transition: "transform 90ms linear",
559
+ willChange: "transform"
560
+ },
561
+ "data-testid": `remote-cursor-${user.clientId}`,
562
+ "data-pptx-remote-cursor": user.clientId,
563
+ children: [
564
+ /* @__PURE__ */ jsx(
565
+ "path",
566
+ {
567
+ d: "M0 0 L0 16 L4.5 12.5 L8 20 L10.5 19 L7 11.5 L12 11 Z",
568
+ fill: user.userColor,
569
+ stroke: "#fff",
570
+ strokeWidth: 1,
571
+ opacity: 0.9
572
+ }
573
+ ),
574
+ /* @__PURE__ */ jsxs("g", { transform: "translate(14, 18)", children: [
575
+ /* @__PURE__ */ jsx(
576
+ "rect",
577
+ {
578
+ rx: 3,
579
+ ry: 3,
580
+ x: -2,
581
+ y: -10,
582
+ width: Math.min(user.userName.length * 7 + 8, 150),
583
+ height: 16,
584
+ fill: user.userColor,
585
+ opacity: 0.85
586
+ }
587
+ ),
588
+ /* @__PURE__ */ jsx(
589
+ "text",
590
+ {
591
+ fill: "#fff",
592
+ fontSize: 10,
593
+ fontFamily: "system-ui, sans-serif",
594
+ fontWeight: 500,
595
+ dominantBaseline: "central",
596
+ y: -2,
597
+ x: 2,
598
+ children: user.userName.length > 20 ? `${user.userName.slice(0, 18)}...` : user.userName
599
+ }
600
+ )
601
+ ] })
602
+ ]
603
+ },
604
+ user.clientId
605
+ ))
606
+ }
607
+ );
523
608
  }
524
609
  function useSheetDismissDrag(onClose, threshold = 120) {
525
610
  const [dragY, setDragY] = useState(0);
@@ -806,19 +891,19 @@ function useEditorHistory(input) {
806
891
  }
807
892
  const previousSnapshot = lastHistorySnapshotRef.current;
808
893
  if (!previousSnapshot) {
809
- lastHistorySnapshotRef.current = cloneHistorySnapshot(snapshot);
894
+ lastHistorySnapshotRef.current = snapshot;
810
895
  lastHistorySerializedRef.current = serialized;
811
896
  lastCheapHashRef.current = cheapHash;
812
897
  updateHistoryAvailability();
813
898
  return;
814
899
  }
815
900
  onDirtyRef.current?.();
816
- historyPastRef.current.push(cloneHistorySnapshot(previousSnapshot));
901
+ historyPastRef.current.push(previousSnapshot);
817
902
  while (historyPastRef.current.length > Math.max(1, maxHistoryEntries)) {
818
903
  historyPastRef.current.shift();
819
904
  }
820
905
  historyFutureRef.current = [];
821
- lastHistorySnapshotRef.current = cloneHistorySnapshot(snapshot);
906
+ lastHistorySnapshotRef.current = snapshot;
822
907
  lastHistorySerializedRef.current = serialized;
823
908
  lastCheapHashRef.current = cheapHash;
824
909
  updateHistoryAvailability();
@@ -3837,6 +3922,17 @@ function useInlineEditingState(onTextChange) {
3837
3922
  const inlineEditingElementIdRef = useRef(null);
3838
3923
  const inlineEditingTextRef = useRef("");
3839
3924
  const inlineEditingSnapshotRef = useRef(void 0);
3925
+ const inlineEditingReaderRef = useRef(void 0);
3926
+ const registerInlineEditReader = useCallback(
3927
+ (elementId, read) => {
3928
+ const entry = { elementId, read };
3929
+ inlineEditingReaderRef.current = entry;
3930
+ return () => {
3931
+ if (inlineEditingReaderRef.current === entry) inlineEditingReaderRef.current = void 0;
3932
+ };
3933
+ },
3934
+ []
3935
+ );
3840
3936
  const [inlineEditingElementId, setElementId] = useState(null);
3841
3937
  const [inlineEditingText, setText] = useState("");
3842
3938
  const setInlineEditingElementId = useCallback(
@@ -3867,7 +3963,9 @@ function useInlineEditingState(onTextChange) {
3867
3963
  setInlineEditingText,
3868
3964
  inlineEditingElementIdRef,
3869
3965
  inlineEditingTextRef,
3870
- inlineEditingSnapshotRef
3966
+ inlineEditingSnapshotRef,
3967
+ inlineEditingReaderRef,
3968
+ registerInlineEditReader
3871
3969
  };
3872
3970
  }
3873
3971
  function useSlideState() {
@@ -5530,6 +5628,7 @@ function useCanvasInteractions(input) {
5530
5628
  inlineEditingText,
5531
5629
  inlineEditingTextRef,
5532
5630
  inlineEditingSnapshotRef,
5631
+ inlineEditingReaderRef,
5533
5632
  ops,
5534
5633
  history,
5535
5634
  presentationHandleAction,
@@ -5546,12 +5645,15 @@ function useCanvasInteractions(input) {
5546
5645
  }
5547
5646
  const el = elementLookup.get(editId);
5548
5647
  if (el && hasTextProperties(el)) {
5549
- const liveText = inlineEditingTextRef?.current ?? inlineEditingText;
5648
+ const reader = inlineEditingReaderRef?.current;
5649
+ const read = reader?.elementId === editId ? reader.read() : void 0;
5650
+ if (read?.kind === "unsupported") return;
5651
+ const liveText = read?.snapshot.text ?? inlineEditingTextRef?.current ?? inlineEditingText;
5550
5652
  const committedText = transformCommittedText ? transformCommittedText(liveText) : liveText;
5551
5653
  const textPatch = buildInlineTextCommitPatch(
5552
5654
  el,
5553
5655
  committedText,
5554
- inlineEditingSnapshotRef?.current
5656
+ read?.snapshot ?? inlineEditingSnapshotRef?.current
5555
5657
  );
5556
5658
  if (!textPatch) {
5557
5659
  setInlineEditingElementId(null);
@@ -7870,6 +7972,7 @@ function useExportMediaHandlers(input) {
7870
7972
  setExportProgress,
7871
7973
  setExportStatusMessage
7872
7974
  } = input;
7975
+ const slideCount = slides.length;
7873
7976
  const handleExportVideo = useCallback(async () => {
7874
7977
  if (!canvasStageRef.current) {
7875
7978
  return;
@@ -7884,7 +7987,7 @@ function useExportMediaHandlers(input) {
7884
7987
  const { scale } = resolveExportCaptureDecision(imageResolutionScale, "video");
7885
7988
  const blob = await exportAllSlidesAsVideo(
7886
7989
  canvasStageRef,
7887
- slides.length,
7990
+ slideCount,
7888
7991
  setActiveSlideIndex,
7889
7992
  activeSlideIndex,
7890
7993
  {
@@ -7915,7 +8018,7 @@ function useExportMediaHandlers(input) {
7915
8018
  }
7916
8019
  }, [
7917
8020
  canvasStageRef,
7918
- slides.length,
8021
+ slideCount,
7919
8022
  setActiveSlideIndex,
7920
8023
  activeSlideIndex,
7921
8024
  imageResolutionScale,
@@ -7942,7 +8045,7 @@ function useExportMediaHandlers(input) {
7942
8045
  );
7943
8046
  const blob = await exportAllSlidesAsGif(
7944
8047
  canvasStageRef,
7945
- slides.length,
8048
+ slideCount,
7946
8049
  setActiveSlideIndex,
7947
8050
  activeSlideIndex,
7948
8051
  {
@@ -7970,7 +8073,7 @@ function useExportMediaHandlers(input) {
7970
8073
  }
7971
8074
  }, [
7972
8075
  canvasStageRef,
7973
- slides.length,
8076
+ slideCount,
7974
8077
  setActiveSlideIndex,
7975
8078
  activeSlideIndex,
7976
8079
  imageResolutionScale,
@@ -7982,6 +8085,75 @@ function useExportMediaHandlers(input) {
7982
8085
  ]);
7983
8086
  return { handleExportVideo, handleExportGif };
7984
8087
  }
8088
+ function useExportNotesPdf(input) {
8089
+ const {
8090
+ slides,
8091
+ activeSlideIndex,
8092
+ canvasStageRef,
8093
+ setActiveSlideIndex,
8094
+ imageExportScale,
8095
+ exportAbortRef,
8096
+ setExportModalOpen,
8097
+ setExportModalTitle,
8098
+ setExportProgress,
8099
+ setExportStatusMessage
8100
+ } = input;
8101
+ return useCallback(async () => {
8102
+ if (!canvasStageRef.current) {
8103
+ return;
8104
+ }
8105
+ const abortCtrl = new AbortController();
8106
+ exportAbortRef.current = abortCtrl;
8107
+ setExportModalTitle("Export as PDF (Notes)");
8108
+ setExportStatusMessage("Capturing slides...");
8109
+ setExportProgress(0);
8110
+ setExportModalOpen(true);
8111
+ try {
8112
+ const slideNotes = slides.map((s) => s.notes);
8113
+ await exportAllSlidesAsNotesPdf(
8114
+ canvasStageRef,
8115
+ slides.length,
8116
+ setActiveSlideIndex,
8117
+ activeSlideIndex,
8118
+ slideNotes,
8119
+ "presentation-notes.pdf",
8120
+ {
8121
+ scale: imageExportScale,
8122
+ onProgress: (current, total) => {
8123
+ setExportProgress(slideProgressPercent(current, total));
8124
+ setExportStatusMessage(slideStatusLabel("Rendering", current, total));
8125
+ },
8126
+ signal: abortCtrl.signal
8127
+ }
8128
+ );
8129
+ setExportProgress(EXPORT_ASSEMBLING_PERCENT);
8130
+ setExportStatusMessage("Building PDF...");
8131
+ await new Promise((r) => {
8132
+ setTimeout(r, 100);
8133
+ });
8134
+ setExportProgress(EXPORT_DONE_PERCENT);
8135
+ setExportStatusMessage("Done!");
8136
+ } catch (err) {
8137
+ if (!isExportAbortError(err)) {
8138
+ console.error("[PowerPointViewer] Notes PDF export failed:", err);
8139
+ }
8140
+ } finally {
8141
+ exportAbortRef.current = null;
8142
+ setExportModalOpen(false);
8143
+ }
8144
+ }, [
8145
+ canvasStageRef,
8146
+ slides,
8147
+ setActiveSlideIndex,
8148
+ activeSlideIndex,
8149
+ imageExportScale,
8150
+ exportAbortRef,
8151
+ setExportModalOpen,
8152
+ setExportModalTitle,
8153
+ setExportProgress,
8154
+ setExportStatusMessage
8155
+ ]);
8156
+ }
7985
8157
 
7986
8158
  // src/viewer/hooks/useExportHandlers.ts
7987
8159
  function useExportHandlers(input) {
@@ -8010,11 +8182,25 @@ function useExportHandlers(input) {
8010
8182
  imageExportScale,
8011
8183
  imageResolutionScale
8012
8184
  } = input;
8185
+ const slideCount = slides.length;
8186
+ const backgroundColor = activeSlide?.backgroundColor;
8013
8187
  const [exportModalOpen, setExportModalOpen] = useState(false);
8014
8188
  const [exportModalTitle, setExportModalTitle] = useState("");
8015
8189
  const [exportProgress, setExportProgress] = useState(0);
8016
8190
  const [exportStatusMessage, setExportStatusMessage] = useState("");
8017
8191
  const exportAbortRef = useRef(null);
8192
+ const handleExportNotesPdf = useExportNotesPdf({
8193
+ slides,
8194
+ activeSlideIndex,
8195
+ canvasStageRef,
8196
+ setActiveSlideIndex,
8197
+ imageExportScale,
8198
+ exportAbortRef,
8199
+ setExportModalOpen,
8200
+ setExportModalTitle,
8201
+ setExportProgress,
8202
+ setExportStatusMessage
8203
+ });
8018
8204
  const { handleExportVideo, handleExportGif } = useExportMediaHandlers({
8019
8205
  slides,
8020
8206
  activeSlideIndex,
@@ -8060,13 +8246,13 @@ function useExportHandlers(input) {
8060
8246
  }
8061
8247
  try {
8062
8248
  await exportSlideAsPng(stageEl, activeSlideIndex, {
8063
- backgroundColor: activeSlide?.backgroundColor,
8249
+ backgroundColor,
8064
8250
  scale: imageExportScale
8065
8251
  });
8066
8252
  } catch (err) {
8067
8253
  console.error("[PowerPointViewer] PNG export failed:", err);
8068
8254
  }
8069
- }, [canvasStageRef, activeSlideIndex, activeSlide?.backgroundColor, imageExportScale]);
8255
+ }, [canvasStageRef, activeSlideIndex, backgroundColor, imageExportScale]);
8070
8256
  const handleExportPdf = useCallback(async () => {
8071
8257
  if (!canvasStageRef.current) {
8072
8258
  return;
@@ -8080,7 +8266,7 @@ function useExportHandlers(input) {
8080
8266
  try {
8081
8267
  await exportAllSlidesAsPdf(
8082
8268
  canvasStageRef,
8083
- slides.length,
8269
+ slideCount,
8084
8270
  setActiveSlideIndex,
8085
8271
  activeSlideIndex,
8086
8272
  "presentation.pdf",
@@ -8108,51 +8294,7 @@ function useExportHandlers(input) {
8108
8294
  exportAbortRef.current = null;
8109
8295
  setExportModalOpen(false);
8110
8296
  }
8111
- }, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex, imageExportScale]);
8112
- const handleExportNotesPdf = useCallback(async () => {
8113
- if (!canvasStageRef.current) {
8114
- return;
8115
- }
8116
- const abortCtrl = new AbortController();
8117
- exportAbortRef.current = abortCtrl;
8118
- setExportModalTitle("Export as PDF (Notes)");
8119
- setExportStatusMessage("Capturing slides...");
8120
- setExportProgress(0);
8121
- setExportModalOpen(true);
8122
- try {
8123
- const slideNotes = slides.map((s) => s.notes);
8124
- await exportAllSlidesAsNotesPdf(
8125
- canvasStageRef,
8126
- slides.length,
8127
- setActiveSlideIndex,
8128
- activeSlideIndex,
8129
- slideNotes,
8130
- "presentation-notes.pdf",
8131
- {
8132
- scale: imageExportScale,
8133
- onProgress: (current, total) => {
8134
- setExportProgress(slideProgressPercent(current, total));
8135
- setExportStatusMessage(slideStatusLabel("Rendering", current, total));
8136
- },
8137
- signal: abortCtrl.signal
8138
- }
8139
- );
8140
- setExportProgress(EXPORT_ASSEMBLING_PERCENT);
8141
- setExportStatusMessage("Building PDF...");
8142
- await new Promise((r) => {
8143
- setTimeout(r, 100);
8144
- });
8145
- setExportProgress(EXPORT_DONE_PERCENT);
8146
- setExportStatusMessage("Done!");
8147
- } catch (err) {
8148
- if (!isExportAbortError(err)) {
8149
- console.error("[PowerPointViewer] Notes PDF export failed:", err);
8150
- }
8151
- } finally {
8152
- exportAbortRef.current = null;
8153
- setExportModalOpen(false);
8154
- }
8155
- }, [canvasStageRef, slides, setActiveSlideIndex, activeSlideIndex, imageExportScale]);
8297
+ }, [canvasStageRef, slideCount, setActiveSlideIndex, activeSlideIndex, imageExportScale]);
8156
8298
  const handleCopySlideAsImage = useCallback(async () => {
8157
8299
  const stageEl = canvasStageRef.current;
8158
8300
  if (!stageEl) {
@@ -8160,13 +8302,13 @@ function useExportHandlers(input) {
8160
8302
  }
8161
8303
  try {
8162
8304
  await copySlideToClipboard(stageEl, {
8163
- backgroundColor: activeSlide?.backgroundColor,
8305
+ backgroundColor,
8164
8306
  scale: imageExportScale
8165
8307
  });
8166
8308
  } catch (err) {
8167
8309
  console.error("[PowerPointViewer] Copy slide as image failed:", err);
8168
8310
  }
8169
- }, [canvasStageRef, activeSlide?.backgroundColor, imageExportScale]);
8311
+ }, [canvasStageRef, backgroundColor, imageExportScale]);
8170
8312
  const handleCancelExport = useCallback(() => {
8171
8313
  exportAbortRef.current?.abort();
8172
8314
  exportAbortRef.current = null;
@@ -9289,6 +9431,7 @@ function useSerialize(input) {
9289
9431
  inlineEditingElementIdRef,
9290
9432
  inlineEditingTextRef,
9291
9433
  inlineEditingSnapshotRef,
9434
+ inlineEditingReaderRef,
9292
9435
  transformCommittedText,
9293
9436
  password,
9294
9437
  embedFonts = true,
@@ -9301,8 +9444,11 @@ function useSerialize(input) {
9301
9444
  return null;
9302
9445
  }
9303
9446
  const pendingEditId = inlineEditingElementIdRef.current;
9304
- const pendingEditText = inlineEditingTextRef.current;
9305
- const pendingSnapshot = inlineEditingSnapshotRef?.current;
9447
+ const reader = inlineEditingReaderRef?.current;
9448
+ const read = reader?.elementId === pendingEditId ? reader.read() : void 0;
9449
+ if (read?.kind === "unsupported") return null;
9450
+ const pendingEditText = read?.snapshot.text ?? inlineEditingTextRef.current;
9451
+ const pendingSnapshot = read?.snapshot ?? inlineEditingSnapshotRef?.current;
9306
9452
  const pending = overlayPendingInlineEdit(
9307
9453
  {
9308
9454
  slides,
@@ -9387,6 +9533,7 @@ function useSerialize(input) {
9387
9533
  inlineEditingElementIdRef,
9388
9534
  inlineEditingTextRef,
9389
9535
  inlineEditingSnapshotRef,
9536
+ inlineEditingReaderRef,
9390
9537
  transformCommittedText,
9391
9538
  password,
9392
9539
  embedFonts,
@@ -9730,6 +9877,7 @@ function useEditorOperations(input) {
9730
9877
  inlineEditingSnapshotRef: state.inlineEditingSnapshotRef,
9731
9878
  ops,
9732
9879
  inlineEditingTextRef: state.inlineEditingTextRef,
9880
+ inlineEditingReaderRef: state.inlineEditingReaderRef,
9733
9881
  history,
9734
9882
  presentationHandleAction: presentation.handlePresentationAction,
9735
9883
  setEditingEquationOmml: dialogs.setEditingEquationOmml,
@@ -10223,6 +10371,7 @@ function useContentLifecycle(input) {
10223
10371
  inlineEditingElementIdRef: state.inlineEditingElementIdRef,
10224
10372
  inlineEditingTextRef: state.inlineEditingTextRef,
10225
10373
  inlineEditingSnapshotRef: state.inlineEditingSnapshotRef,
10374
+ inlineEditingReaderRef: state.inlineEditingReaderRef,
10226
10375
  transformCommittedText: input.transformCommittedText,
10227
10376
  password,
10228
10377
  embedFonts
@@ -11034,7 +11183,15 @@ function useExternalDocumentSync(input, scheduleWriteBack) {
11034
11183
  const factories = {
11035
11184
  createMap: () => new Y.Map(),
11036
11185
  createArray: () => new Y.Array(),
11037
- createText: () => new Y.Text()
11186
+ createText: () => new Y.Text(),
11187
+ createTextPositions: (text) => createSnapshotTextPositions(text, {
11188
+ read: () => Y.snapshot(doc),
11189
+ equal: Y.equalSnapshots,
11190
+ subscribeBeforeObservers: (listener) => {
11191
+ doc.on("beforeObserverCalls", listener);
11192
+ return () => doc.off("beforeObserverCalls", listener);
11193
+ }
11194
+ })
11038
11195
  };
11039
11196
  publish.current = (nextSlides) => {
11040
11197
  const slides = nextSlides ?? latest.current.slides;
@@ -11285,8 +11442,12 @@ function useCollaborationLivePatch({
11285
11442
  doc,
11286
11443
  isConnected,
11287
11444
  isSynced = true,
11288
- externalSession
11445
+ externalSession,
11446
+ onBeforeDetach
11289
11447
  }) {
11448
+ const latestDetach = useRef(onBeforeDetach);
11449
+ latestDetach.current = onBeforeDetach;
11450
+ const [initialized, setInitialized] = useState(null);
11290
11451
  useEffect(() => {
11291
11452
  if (externalSession) {
11292
11453
  return;
@@ -11309,15 +11470,28 @@ function useCollaborationLivePatch({
11309
11470
  factories = {
11310
11471
  createMap: () => new Y.Map(),
11311
11472
  createArray: () => new Y.Array(),
11312
- createText: () => new Y.Text()
11473
+ createText: () => new Y.Text(),
11474
+ createTextPositions: (text) => createSnapshotTextPositions(text, {
11475
+ read: () => Y.snapshot(doc),
11476
+ equal: Y.equalSnapshots,
11477
+ subscribeBeforeObservers: (listener) => {
11478
+ doc.on("beforeObserverCalls", listener);
11479
+ return () => doc.off("beforeObserverCalls", listener);
11480
+ }
11481
+ })
11313
11482
  };
11314
11483
  configure();
11484
+ setInitialized({ doc, patcher });
11315
11485
  })();
11316
11486
  return () => {
11317
11487
  cancelled = true;
11488
+ if (factories) {
11489
+ latestDetach.current?.(doc);
11490
+ }
11318
11491
  patcher.configure(null, null);
11319
11492
  };
11320
11493
  }, [patcher, doc, isConnected, isSynced, externalSession]);
11494
+ return initialized?.doc === doc && initialized?.patcher === patcher;
11321
11495
  }
11322
11496
  function useLayoutSwitching(input) {
11323
11497
  const { handler, slides, activeSlideIndex, ops, history, onTemplateElementsChanged } = input;
@@ -11653,6 +11827,8 @@ function buildCanvasProps(input) {
11653
11827
  openExternalUrl(url, target);
11654
11828
  };
11655
11829
  return {
11830
+ livePatcher: s.livePatcher,
11831
+ registerInlineEditReader: s.registerInlineEditReader,
11656
11832
  imagePaste: insertHandlers.imagePaste,
11657
11833
  activeSlide: effectiveSlide,
11658
11834
  templateElements: effectiveTemplateElements,
@@ -12062,6 +12238,218 @@ function buildToolbarProps(input) {
12062
12238
  hiddenActions
12063
12239
  };
12064
12240
  }
12241
+ function CollaborationCursorOverlay({
12242
+ collaboration,
12243
+ activeSlideIndex,
12244
+ canvasWidth,
12245
+ canvasHeight,
12246
+ selectedElementId
12247
+ }) {
12248
+ const context = useCollaboration();
12249
+ const collab = collaboration === void 0 ? context : collaboration;
12250
+ const broadcastPresence = collab?.broadcastPresence;
12251
+ const containerRef = useRef(null);
12252
+ useEffect(() => {
12253
+ broadcastPresence?.({
12254
+ selectedElementId: selectedElementId ?? void 0,
12255
+ activeSlideIndex
12256
+ });
12257
+ }, [broadcastPresence, selectedElementId, activeSlideIndex]);
12258
+ useEffect(() => {
12259
+ if (!broadcastPresence) {
12260
+ return;
12261
+ }
12262
+ const parent = containerRef.current?.parentElement;
12263
+ if (!parent) {
12264
+ return;
12265
+ }
12266
+ const handler = (e) => {
12267
+ const rect = parent.getBoundingClientRect();
12268
+ const x = (e.clientX - rect.left) / rect.width * canvasWidth;
12269
+ const y = (e.clientY - rect.top) / rect.height * canvasHeight;
12270
+ broadcastPresence({
12271
+ cursorX: x,
12272
+ cursorY: y,
12273
+ activeSlideIndex
12274
+ });
12275
+ };
12276
+ parent.addEventListener("pointermove", handler);
12277
+ return () => parent.removeEventListener("pointermove", handler);
12278
+ }, [broadcastPresence, canvasWidth, canvasHeight, activeSlideIndex]);
12279
+ if (!collab) {
12280
+ return null;
12281
+ }
12282
+ return /* @__PURE__ */ jsx(
12283
+ "div",
12284
+ {
12285
+ ref: containerRef,
12286
+ "data-testid": "collab-pointer-tracker",
12287
+ "data-export-ignore": "true",
12288
+ style: { display: "contents" },
12289
+ children: /* @__PURE__ */ jsx(
12290
+ RemoteUserCursors,
12291
+ {
12292
+ remoteUsers: collab.remoteUsers,
12293
+ activeSlideIndex,
12294
+ canvasWidth,
12295
+ canvasHeight
12296
+ }
12297
+ )
12298
+ }
12299
+ );
12300
+ }
12301
+ function RemoteSelectionOverlay({
12302
+ collaboration,
12303
+ elements,
12304
+ activeSlideIndex
12305
+ }) {
12306
+ const context = useCollaboration();
12307
+ const collab = collaboration === void 0 ? context : collaboration;
12308
+ if (!collab) {
12309
+ return null;
12310
+ }
12311
+ const elementMap = /* @__PURE__ */ new Map();
12312
+ for (const el of elements) {
12313
+ elementMap.set(el.id, el);
12314
+ }
12315
+ const selections = [];
12316
+ for (const user of collab.remoteUsers) {
12317
+ if (user.activeSlideIndex === activeSlideIndex && user.selectedElementId) {
12318
+ const el = elementMap.get(user.selectedElementId);
12319
+ if (el) {
12320
+ selections.push({
12321
+ userName: user.userName,
12322
+ userColor: user.userColor,
12323
+ element: el
12324
+ });
12325
+ }
12326
+ }
12327
+ }
12328
+ if (selections.length === 0) {
12329
+ return null;
12330
+ }
12331
+ return /* @__PURE__ */ jsx(Fragment, { children: selections.map((sel) => /* @__PURE__ */ jsx(
12332
+ "div",
12333
+ {
12334
+ "data-testid": `remote-selection-${sel.element.id}`,
12335
+ "data-pptx-remote-selection": sel.element.id,
12336
+ "data-export-ignore": "true",
12337
+ className: "absolute pointer-events-none",
12338
+ style: {
12339
+ left: sel.element.x,
12340
+ top: sel.element.y,
12341
+ width: sel.element.width,
12342
+ height: sel.element.height,
12343
+ zIndex: 9997,
12344
+ border: `2px solid ${sel.userColor}`,
12345
+ borderRadius: 2
12346
+ },
12347
+ children: /* @__PURE__ */ jsx(
12348
+ "span",
12349
+ {
12350
+ className: "absolute -top-5 left-0 px-1 py-0.5 text-[9px] font-medium text-white rounded-sm whitespace-nowrap leading-none",
12351
+ style: { backgroundColor: sel.userColor },
12352
+ children: sel.userName
12353
+ }
12354
+ )
12355
+ },
12356
+ `remote-sel-${sel.element.id}`
12357
+ )) });
12358
+ }
12359
+ function useCollaborationDocumentSync(input) {
12360
+ const { collaboration, ...state } = input;
12361
+ const latest = useRef(input);
12362
+ latest.current = input;
12363
+ const getSourceBytes = useCallback(() => {
12364
+ const bytes = latest.current.content;
12365
+ return bytes instanceof Uint8Array ? bytes : bytes ? new Uint8Array(bytes) : null;
12366
+ }, []);
12367
+ const getSaveOptions = useCallback(() => buildDeckSaveOptions(latest.current.deckSaveState), []);
12368
+ const config = collaboration?.config;
12369
+ const doc = collaboration?.doc;
12370
+ const status = collaboration?.status;
12371
+ const preserveAcceptedEdits = useCallback((detachingDoc) => {
12372
+ const current = latest.current;
12373
+ const session = current.collaboration;
12374
+ if (session?.doc === detachingDoc && !session.config.externalSession && (session.status !== "connected" || !session.synced || session.config.role === "viewer")) {
12375
+ current.setSlides(readSlidesFromYDoc(detachingDoc));
12376
+ }
12377
+ }, []);
12378
+ const isConnected = config?.externalSession ? Boolean(collaboration?.doc) : collaboration?.status === "connected";
12379
+ useYjsDocumentSync({
12380
+ ...state,
12381
+ doc: collaboration?.doc ?? null,
12382
+ isConnected,
12383
+ isSynced: collaboration?.synced ?? false,
12384
+ config,
12385
+ livePatcher: state.livePatcher,
12386
+ getSourceBytes,
12387
+ getSaveOptions
12388
+ });
12389
+ const initialized = useCollaborationLivePatch({
12390
+ patcher: state.livePatcher,
12391
+ externalSession: config?.externalSession,
12392
+ doc: collaboration?.doc ?? null,
12393
+ isConnected: isConnected && config?.role !== "viewer",
12394
+ isSynced: collaboration?.synced ?? false,
12395
+ onBeforeDetach: preserveAcceptedEdits
12396
+ });
12397
+ useEffect(() => {
12398
+ if (!config?.externalSession || !doc) {
12399
+ latest.current.onReadOnlyChange?.(
12400
+ config?.externalSession ? status !== "error" : Boolean(config) && status !== "error" && (!initialized || Boolean(doc) && config?.role === "viewer")
12401
+ );
12402
+ }
12403
+ }, [doc, config, status, initialized]);
12404
+ }
12405
+ function useViewerBuildingBlocksCollaboration(input) {
12406
+ const { state, activeSlideIndex } = input.core;
12407
+ const collaboration = useCollaborativeState({
12408
+ config: input.config,
12409
+ canvasWidth: state.canvasSize.width,
12410
+ canvasHeight: state.canvasSize.height
12411
+ });
12412
+ useCollaborationDocumentSync({
12413
+ collaboration,
12414
+ content: input.content,
12415
+ slides: state.slides,
12416
+ setSlides: state.setSlides,
12417
+ templateElementsBySlideId: state.templateElementsBySlideId,
12418
+ loadVersion: input.loadVersion,
12419
+ loadOrigin: input.loadOrigin,
12420
+ livePatcher: state.livePatcher,
12421
+ onReadOnlyChange: input.onReadOnlyChange,
12422
+ deckSaveState: {
12423
+ ...state,
12424
+ embedFonts: input.embedFonts,
12425
+ slideSize: resolveSlideSizeSelection({
12426
+ current: state.slideSizeEmu,
12427
+ canvas: state.canvasSize
12428
+ }).size
12429
+ }
12430
+ });
12431
+ const overlay = collaboration ? /* @__PURE__ */ jsxs(Fragment, { children: [
12432
+ /* @__PURE__ */ jsx(
12433
+ RemoteSelectionOverlay,
12434
+ {
12435
+ collaboration,
12436
+ elements: state.slides[activeSlideIndex]?.elements ?? [],
12437
+ activeSlideIndex
12438
+ }
12439
+ ),
12440
+ /* @__PURE__ */ jsx(
12441
+ CollaborationCursorOverlay,
12442
+ {
12443
+ collaboration,
12444
+ activeSlideIndex,
12445
+ selectedElementId: state.selectedElementId,
12446
+ canvasWidth: state.canvasSize.width,
12447
+ canvasHeight: state.canvasSize.height
12448
+ }
12449
+ )
12450
+ ] }) : void 0;
12451
+ return { collaboration, overlay };
12452
+ }
12065
12453
  function useViewerBuildingBlocksCore(input) {
12066
12454
  const { content} = input;
12067
12455
  const state = useViewerState();
@@ -12488,6 +12876,7 @@ function useViewerBuildingBlocksState(input) {
12488
12876
  setShowGuides: state.setShowGuides
12489
12877
  });
12490
12878
  return {
12879
+ loadVersion,
12491
12880
  dialogs,
12492
12881
  editorOps,
12493
12882
  exportHandlers,
@@ -12505,7 +12894,7 @@ function useViewerBuildingBlocksState(input) {
12505
12894
  function useViewerBuildingBlocks(input) {
12506
12895
  const {
12507
12896
  content: incomingContent,
12508
- canEdit = false,
12897
+ canEdit: requestedCanEdit = false,
12509
12898
  filePath,
12510
12899
  fileName,
12511
12900
  autosaveEnabled = true,
@@ -12523,15 +12912,19 @@ function useViewerBuildingBlocks(input) {
12523
12912
  onOpenHeaderFooter,
12524
12913
  onOpenShareDialog
12525
12914
  } = input;
12915
+ const [collaborationReadOnly, setCollaborationReadOnly] = useState(Boolean(input.collaboration));
12526
12916
  const { t } = useTranslation();
12527
12917
  const [content, setContent] = useState(incomingContent ?? null);
12918
+ const [loadOrigin, setLoadOrigin] = useState("bootstrap");
12528
12919
  useEffect(() => {
12529
12920
  setContent(incomingContent ?? null);
12921
+ setLoadOrigin("bootstrap");
12530
12922
  }, [incomingContent]);
12531
12923
  const onOpenFile = useCallback(() => {
12532
12924
  void (async () => {
12533
12925
  const picked = await openPptxFile();
12534
12926
  if (picked) {
12927
+ setLoadOrigin("user");
12535
12928
  setContent(picked.buffer);
12536
12929
  }
12537
12930
  })();
@@ -12540,6 +12933,7 @@ function useViewerBuildingBlocks(input) {
12540
12933
  void (async () => {
12541
12934
  const bytes = await readBackstageRecentFile(key);
12542
12935
  if (bytes) {
12936
+ setLoadOrigin("user");
12543
12937
  setContent(bytes);
12544
12938
  }
12545
12939
  })();
@@ -12565,8 +12959,16 @@ function useViewerBuildingBlocks(input) {
12565
12959
  gridSpacingPx,
12566
12960
  viewerOptions
12567
12961
  } = core;
12962
+ const canEdit = resolveCollaborationShellEditability({
12963
+ authorizedCanEdit: requestedCanEdit,
12964
+ configured: Boolean(input.collaboration),
12965
+ readOnly: collaborationReadOnly,
12966
+ sourcePending: Boolean(content) && loading,
12967
+ sourceError: Boolean(error)
12968
+ });
12568
12969
  const {
12569
12970
  dialogs,
12971
+ loadVersion,
12570
12972
  editorOps,
12571
12973
  exportHandlers,
12572
12974
  printHandlers,
@@ -12593,6 +12995,15 @@ function useViewerBuildingBlocks(input) {
12593
12995
  onSelectionChange,
12594
12996
  onSlideCountChange
12595
12997
  });
12998
+ const { collaboration, overlay } = useViewerBuildingBlocksCollaboration({
12999
+ core,
13000
+ config: input.collaboration,
13001
+ content,
13002
+ loadOrigin,
13003
+ loadVersion,
13004
+ embedFonts: dialogs.embedFontsEnabled,
13005
+ onReadOnlyChange: setCollaborationReadOnly
13006
+ });
12596
13007
  const toolbarProps = buildToolbarProps({
12597
13008
  mode,
12598
13009
  canEdit,
@@ -12647,7 +13058,38 @@ function useViewerBuildingBlocks(input) {
12647
13058
 
12648
13059
  ${url}`
12649
13060
  });
12650
- return { toolbarProps, canvasProps, mode, loading, error, autosaveStatus };
13061
+ canvasProps.collaborationOverlay = overlay;
13062
+ const shellState = useMemo(
13063
+ () => resolveCollaborationShellState({
13064
+ authorizedCanEdit: requestedCanEdit,
13065
+ configured: Boolean(input.collaboration),
13066
+ readOnly: collaborationReadOnly,
13067
+ sourcePending: Boolean(content) && loading,
13068
+ sourceError: Boolean(error),
13069
+ status: collaboration?.status ?? "disconnected",
13070
+ remoteUsers: collaboration?.remoteUsers ?? []
13071
+ }),
13072
+ [
13073
+ requestedCanEdit,
13074
+ input.collaboration,
13075
+ collaborationReadOnly,
13076
+ content,
13077
+ loading,
13078
+ error,
13079
+ collaboration?.status,
13080
+ collaboration?.remoteUsers
13081
+ ]
13082
+ );
13083
+ return {
13084
+ toolbarProps,
13085
+ canvasProps,
13086
+ mode,
13087
+ loading,
13088
+ error,
13089
+ autosaveStatus,
13090
+ collaboration,
13091
+ shellState
13092
+ };
12651
13093
  }
12652
13094
  function ColorChangedImage({
12653
13095
  src,
@@ -12965,16 +13407,16 @@ function LoadingState({ className }) {
12965
13407
  function FailedToLoad() {
12966
13408
  return null;
12967
13409
  }
12968
- var LazyArea3DChartScene = React18.lazy(
13410
+ var LazyArea3DChartScene = React20.lazy(
12969
13411
  async () => {
12970
13412
  try {
12971
- return await import('./Area3DChartScene-MQKUWVMS.mjs');
13413
+ return await import('./Area3DChartScene-4TPNRYXS.mjs');
12972
13414
  } catch {
12973
13415
  return { default: FailedToLoad };
12974
13416
  }
12975
13417
  }
12976
13418
  );
12977
- var SceneErrorBoundary = class extends React18.Component {
13419
+ var SceneErrorBoundary = class extends React20.Component {
12978
13420
  constructor(props) {
12979
13421
  super(props);
12980
13422
  this.state = { hasError: false };
@@ -13034,16 +13476,16 @@ var BarChart3DContext = createContext(false);
13034
13476
  function FailedToLoad2() {
13035
13477
  return null;
13036
13478
  }
13037
- var LazyBar3DChartScene = React18.lazy(
13479
+ var LazyBar3DChartScene = React20.lazy(
13038
13480
  async () => {
13039
13481
  try {
13040
- return await import('./Bar3DChartScene-D4GMQGPN.mjs');
13482
+ return await import('./Bar3DChartScene-V45IUIT7.mjs');
13041
13483
  } catch {
13042
13484
  return { default: FailedToLoad2 };
13043
13485
  }
13044
13486
  }
13045
13487
  );
13046
- var SceneErrorBoundary2 = class extends React18.Component {
13488
+ var SceneErrorBoundary2 = class extends React20.Component {
13047
13489
  constructor(props) {
13048
13490
  super(props);
13049
13491
  this.state = { hasError: false };
@@ -13137,16 +13579,16 @@ var LineChart3DContext = createContext(false);
13137
13579
  function FailedToLoad3() {
13138
13580
  return null;
13139
13581
  }
13140
- var LazyLine3DChartScene = React18.lazy(
13582
+ var LazyLine3DChartScene = React20.lazy(
13141
13583
  async () => {
13142
13584
  try {
13143
- return await import('./Line3DChartScene-B3AWFXE4.mjs');
13585
+ return await import('./Line3DChartScene-DCQJEZK6.mjs');
13144
13586
  } catch {
13145
13587
  return { default: FailedToLoad3 };
13146
13588
  }
13147
13589
  }
13148
13590
  );
13149
- var SceneErrorBoundary3 = class extends React18.Component {
13591
+ var SceneErrorBoundary3 = class extends React20.Component {
13150
13592
  constructor(props) {
13151
13593
  super(props);
13152
13594
  this.state = { hasError: false };
@@ -13206,16 +13648,16 @@ var PieChart3DContext = createContext(false);
13206
13648
  function FailedToLoad4() {
13207
13649
  return null;
13208
13650
  }
13209
- var LazyPieChart3DScene = React18.lazy(
13651
+ var LazyPieChart3DScene = React20.lazy(
13210
13652
  async () => {
13211
13653
  try {
13212
- return await import('./PieChart3DScene-4BQ6PR7P.mjs');
13654
+ return await import('./PieChart3DScene-HC2ZWL42.mjs');
13213
13655
  } catch {
13214
13656
  return { default: FailedToLoad4 };
13215
13657
  }
13216
13658
  }
13217
13659
  );
13218
- var SceneErrorBoundary4 = class extends React18.Component {
13660
+ var SceneErrorBoundary4 = class extends React20.Component {
13219
13661
  constructor(props) {
13220
13662
  super(props);
13221
13663
  this.state = { hasError: false };
@@ -13273,16 +13715,16 @@ var SurfaceChart3DContext = createContext(false);
13273
13715
  function FailedToLoad5() {
13274
13716
  return null;
13275
13717
  }
13276
- var LazySurfaceChart3DScene = React18.lazy(
13718
+ var LazySurfaceChart3DScene = React20.lazy(
13277
13719
  async () => {
13278
13720
  try {
13279
- return await import('./SurfaceChart3DScene-FRQC5HBG.mjs');
13721
+ return await import('./SurfaceChart3DScene-JRMX4PN5.mjs');
13280
13722
  } catch {
13281
13723
  return { default: FailedToLoad5 };
13282
13724
  }
13283
13725
  }
13284
13726
  );
13285
- var SceneErrorBoundary5 = class extends React18.Component {
13727
+ var SceneErrorBoundary5 = class extends React20.Component {
13286
13728
  constructor(props) {
13287
13729
  super(props);
13288
13730
  this.state = { hasError: false };
@@ -14051,7 +14493,7 @@ function ResizeHandles({
14051
14493
  ))
14052
14494
  ] });
14053
14495
  }
14054
- var ConnectorElementRenderer = React18.memo(
14496
+ var ConnectorElementRenderer = React20.memo(
14055
14497
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the memo component its displayName
14056
14498
  function ConnectorElementRendererInner({
14057
14499
  el,
@@ -14438,7 +14880,7 @@ function shapeParams(element) {
14438
14880
  const hasFill = style?.fillColor !== void 0 && style.fillColor !== "transparent" || Boolean(buildCssGradientFromShapeStyle(style) || style?.fillGradient) || style?.fillMode === "pattern" && Boolean(style.fillPatternPreset);
14439
14881
  return { hf: hasFill, fc: fillColor, sw: strokeWidth, sc: strokeColor };
14440
14882
  }
14441
- var Extrusion3DOverlay = React18.memo(
14883
+ var Extrusion3DOverlay = React20.memo(
14442
14884
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the memo component its displayName
14443
14885
  function Extrusion3DOverlayInner({ data }) {
14444
14886
  if (!data.hasExtrusion || data.panels.length === 0) {
@@ -14672,7 +15114,7 @@ function ShapeEffectOverlay({
14672
15114
  ) : null
14673
15115
  ] });
14674
15116
  }
14675
- var ElementRenderer = React18.memo(
15117
+ var ElementRenderer = React20.memo(
14676
15118
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the memo component its displayName
14677
15119
  function ElementRendererInner({
14678
15120
  element: el,
@@ -15363,7 +15805,11 @@ function renderOleBadge(oleType) {
15363
15805
  )
15364
15806
  ] });
15365
15807
  }
15808
+ var InlineCollaborationContext = createContext(void 0);
15809
+
15810
+ // src/viewer/components/elements/useInlineListEditor.tsx
15366
15811
  function useInlineListEditor(element, rootRef, onChange, onModelReplacement) {
15812
+ const collaboration = useContext(InlineCollaborationContext);
15367
15813
  const initial = useRef(null);
15368
15814
  let activationMismatch = false;
15369
15815
  if (!initial.current?.seed) {
@@ -15371,7 +15817,8 @@ function useInlineListEditor(element, rootRef, onChange, onModelReplacement) {
15371
15817
  const modelBody = inlineListBodyText(
15372
15818
  "textSegments" in element ? element.textSegments : void 0
15373
15819
  );
15374
- const candidate = createInlineListSeed(element);
15820
+ const connected = collaboration?.elementIds.has(element.id) && collaboration.patcher.isActive() && collaboration.patcher.beginTextEdit ? collaboration : void 0;
15821
+ const candidate = createInlineListSeed(element, { includePlain: Boolean(connected) });
15375
15822
  activationMismatch = Boolean(candidate && liveRoot && readEditableText(liveRoot) !== modelBody);
15376
15823
  const seed = activationMismatch ? void 0 : candidate;
15377
15824
  const activationSelection = initial.current && seed && rootRef.current ? readListActivationSelection(
@@ -15380,10 +15827,12 @@ function useInlineListEditor(element, rootRef, onChange, onModelReplacement) {
15380
15827
  ) : void 0;
15381
15828
  if (!initial.current || seed) {
15382
15829
  initial.current = {
15830
+ element,
15383
15831
  seed,
15832
+ collaboration: connected,
15384
15833
  model: createInlineListModelObserver(element),
15385
15834
  activationSelection,
15386
- children: seed ? renderTextSegments(
15835
+ children: seed && !connected ? renderTextSegments(
15387
15836
  element,
15388
15837
  DEFAULT_TEXT_COLOR,
15389
15838
  void 0,
@@ -15420,6 +15869,38 @@ function useInlineListEditor(element, rootRef, onChange, onModelReplacement) {
15420
15869
  return;
15421
15870
  }
15422
15871
  retiredRef.current = false;
15872
+ if (session.collaboration) {
15873
+ const context = session.collaboration;
15874
+ const controller2 = attachCollaborationInlineEditor(root, session.element, {
15875
+ patcher: context.patcher,
15876
+ slideId: context.slideId,
15877
+ onSnapshot: (snapshot) => onChangeRef.current(snapshot.text, snapshot),
15878
+ onCancel: () => {
15879
+ retiredRef.current = true;
15880
+ onModelReplacementRef.current();
15881
+ }
15882
+ });
15883
+ if (!controller2) {
15884
+ retiredRef.current = true;
15885
+ onModelReplacementRef.current();
15886
+ return;
15887
+ }
15888
+ controllerRef.current = controller2;
15889
+ const releaseReader = context.registerReader?.(session.element.id, controller2.read);
15890
+ return () => {
15891
+ retiredRef.current = true;
15892
+ const current = context.readReadOnlyElement?.(session.element.id);
15893
+ const accepted = current && controller2.checkModel(current) && controller2.readAccepted();
15894
+ if (accepted) {
15895
+ onChangeRef.current(accepted.text, accepted);
15896
+ }
15897
+ releaseReader?.();
15898
+ controller2.dispose();
15899
+ if (controllerRef.current === controller2) {
15900
+ controllerRef.current = null;
15901
+ }
15902
+ };
15903
+ }
15423
15904
  for (const paragraph of seed.paragraphs) {
15424
15905
  const block = root.querySelector(`[data-pptx-list-paragraph="${paragraph.token}"]`);
15425
15906
  if (block) {
@@ -15462,6 +15943,12 @@ function useInlineListEditor(element, rootRef, onChange, onModelReplacement) {
15462
15943
  if (!controller) {
15463
15944
  return;
15464
15945
  }
15946
+ if (controller.checkModel) {
15947
+ const owner = session.collaboration;
15948
+ const sameOwner = owner?.patcher === collaboration?.patcher && owner?.slideId === collaboration?.slideId;
15949
+ controller.checkModel(sameOwner ? element : void 0);
15950
+ return;
15951
+ }
15465
15952
  const change = session.model.check(element, controller.read());
15466
15953
  if (change.kind === "current") {
15467
15954
  return;
@@ -15473,10 +15960,12 @@ function useInlineListEditor(element, rootRef, onChange, onModelReplacement) {
15473
15960
  controller.dispose();
15474
15961
  controllerRef.current = null;
15475
15962
  onModelReplacementRef.current();
15476
- }, [element, session]);
15963
+ }, [element, session, collaboration?.patcher, collaboration?.slideId]);
15477
15964
  return {
15478
15965
  ...session,
15479
- canCommit: () => !retiredRef.current,
15966
+ connected: Boolean(session.collaboration),
15967
+ mutate: (range, apply) => controllerRef.current?.mutate?.(range, apply) ?? false,
15968
+ canCommit: () => !retiredRef.current && (!session.collaboration || controllerRef.current?.read().kind === "supported"),
15480
15969
  retire: () => {
15481
15970
  retiredRef.current = true;
15482
15971
  controllerRef.current?.dispose();
@@ -15549,8 +16038,12 @@ function InlineTextEditor({
15549
16038
  const trimRange = document.createRange();
15550
16039
  trimRange.setStart(startContainer, startOffset - 1);
15551
16040
  trimRange.setEnd(startContainer, startOffset);
15552
- trimRange.deleteContents();
15553
- }, []);
16041
+ if (list.connected) {
16042
+ list.mutate(trimRange, () => trimRange.deleteContents());
16043
+ } else {
16044
+ trimRange.deleteContents();
16045
+ }
16046
+ }, [list]);
15554
16047
  useEffect(() => {
15555
16048
  const el = editorRef.current;
15556
16049
  if (!el) {
@@ -15676,10 +16169,10 @@ function InlineTextEditor({
15676
16169
  function FailedToLoad6() {
15677
16170
  return null;
15678
16171
  }
15679
- var LazyModel3DScene = React18.lazy(
16172
+ var LazyModel3DScene = React20.lazy(
15680
16173
  async () => {
15681
16174
  try {
15682
- return await import('./Model3DScene-4TG4YRVM.mjs');
16175
+ return await import('./Model3DScene-SA5XMR2D.mjs');
15683
16176
  } catch {
15684
16177
  return { default: FailedToLoad6 };
15685
16178
  }
@@ -15741,7 +16234,7 @@ function PosterFallback({
15741
16234
  }
15742
16235
  );
15743
16236
  }
15744
- var Model3DErrorBoundary = class extends React18.Component {
16237
+ var Model3DErrorBoundary = class extends React20.Component {
15745
16238
  constructor(props) {
15746
16239
  super(props);
15747
16240
  this.state = { hasError: false };
@@ -15950,10 +16443,10 @@ function SmartArtInlineNodeEditor({
15950
16443
  onCancel
15951
16444
  }) {
15952
16445
  const { t } = useTranslation();
15953
- const ref = React18.useRef(null);
15954
- const [value, setValue] = React18.useState(initialText);
15955
- const settled = React18.useRef(false);
15956
- React18.useEffect(() => {
16446
+ const ref = React20.useRef(null);
16447
+ const [value, setValue] = React20.useState(initialText);
16448
+ const settled = React20.useRef(false);
16449
+ React20.useEffect(() => {
15957
16450
  const el = ref.current;
15958
16451
  if (el) {
15959
16452
  el.focus();
@@ -16046,16 +16539,16 @@ function findNodeIdFromEvent(target) {
16046
16539
  return null;
16047
16540
  }
16048
16541
  function useSmartArtHoverState(containerRef, measureNodeRect = measureScreenNodeRect) {
16049
- const [hoveredNodeId, setHoveredNodeId] = React18.useState(null);
16050
- const [hoveredNodeRect, setHoveredNodeRect] = React18.useState(null);
16051
- const hideTimeoutRef = React18.useRef(null);
16052
- const cancelPendingHide = React18.useCallback(() => {
16542
+ const [hoveredNodeId, setHoveredNodeId] = React20.useState(null);
16543
+ const [hoveredNodeRect, setHoveredNodeRect] = React20.useState(null);
16544
+ const hideTimeoutRef = React20.useRef(null);
16545
+ const cancelPendingHide = React20.useCallback(() => {
16053
16546
  if (hideTimeoutRef.current !== null) {
16054
16547
  window.clearTimeout(hideTimeoutRef.current);
16055
16548
  hideTimeoutRef.current = null;
16056
16549
  }
16057
16550
  }, []);
16058
- const handleMouseMove = React18.useCallback(
16551
+ const handleMouseMove = React20.useCallback(
16059
16552
  (e, ignoreRef) => {
16060
16553
  const nodeEl = findNodeIdFromEvent(e.target);
16061
16554
  const container = containerRef.current;
@@ -16078,12 +16571,12 @@ function useSmartArtHoverState(containerRef, measureNodeRect = measureScreenNode
16078
16571
  },
16079
16572
  [containerRef, cancelPendingHide, measureNodeRect]
16080
16573
  );
16081
- const clearHover = React18.useCallback(() => {
16574
+ const clearHover = React20.useCallback(() => {
16082
16575
  cancelPendingHide();
16083
16576
  setHoveredNodeId(null);
16084
16577
  setHoveredNodeRect(null);
16085
16578
  }, [cancelPendingHide]);
16086
- React18.useEffect(() => cancelPendingHide, [cancelPendingHide]);
16579
+ React20.useEffect(() => cancelPendingHide, [cancelPendingHide]);
16087
16580
  return { hoveredNodeId, hoveredNodeRect, handleMouseMove, clearHover };
16088
16581
  }
16089
16582
  var EDITOR_PADDING = 4;
@@ -16099,14 +16592,14 @@ function SmartArtEditableLayer({
16099
16592
  measureNodeRect = measureScreenNodeRect,
16100
16593
  children
16101
16594
  }) {
16102
- const containerRef = React18.useRef(null);
16103
- const styleBarRef = React18.useRef(null);
16104
- const [edit, setEdit] = React18.useState(null);
16595
+ const containerRef = React20.useRef(null);
16596
+ const styleBarRef = React20.useRef(null);
16597
+ const [edit, setEdit] = React20.useState(null);
16105
16598
  const { hoveredNodeId, hoveredNodeRect, handleMouseMove, clearHover } = useSmartArtHoverState(
16106
16599
  containerRef,
16107
16600
  measureNodeRect
16108
16601
  );
16109
- const openEditor = React18.useCallback(
16602
+ const openEditor = React20.useCallback(
16110
16603
  (target) => {
16111
16604
  const nodeEl = findNodeIdFromEvent(target);
16112
16605
  const container = containerRef.current;
@@ -16721,20 +17214,20 @@ function sameDiagramReveal(prev, next) {
16721
17214
  }
16722
17215
  return true;
16723
17216
  }
16724
- var SmartArtRenderer = React18.memo(SmartArtRendererImpl, arePropsEqual);
17217
+ var SmartArtRenderer = React20.memo(SmartArtRendererImpl, arePropsEqual);
16725
17218
  function FailedToLoad7() {
16726
17219
  return null;
16727
17220
  }
16728
- var LazySmartArt3DScene = React18.lazy(
17221
+ var LazySmartArt3DScene = React20.lazy(
16729
17222
  async () => {
16730
17223
  try {
16731
- return await import('./SmartArt3DScene-QZGIABOK.mjs');
17224
+ return await import('./SmartArt3DScene-D4VNNPHS.mjs');
16732
17225
  } catch {
16733
17226
  return { default: FailedToLoad7 };
16734
17227
  }
16735
17228
  }
16736
17229
  );
16737
- var SceneErrorBoundary6 = class extends React18.Component {
17230
+ var SceneErrorBoundary6 = class extends React20.Component {
16738
17231
  constructor(props) {
16739
17232
  super(props);
16740
17233
  this.state = { hasError: false };
@@ -16781,7 +17274,7 @@ function SmartArt3DRenderer({
16781
17274
  }
16782
17275
  const palette = resolvePalette2(element);
16783
17276
  const style = resolveStyle(element);
16784
- const layoutResult = computeSmartArtElementLayout(
17277
+ const layoutResult = resolveSmartArt3DLayout(
16785
17278
  element.smartArtData,
16786
17279
  nodes,
16787
17280
  { width: element.width, height: element.height },
@@ -16937,7 +17430,7 @@ function EnvelopeGlyph({
16937
17430
  }
16938
17431
  return /* @__PURE__ */ jsx("g", { "data-glyph-slices": glyph.slices.length, children: glyph.slices.map((slice, si) => {
16939
17432
  const clipId = `${glyphKey}-s${si}`;
16940
- return /* @__PURE__ */ jsxs(React18.Fragment, { children: [
17433
+ return /* @__PURE__ */ jsxs(React20.Fragment, { children: [
16941
17434
  /* @__PURE__ */ jsx("clipPath", { id: clipId, clipPathUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
16942
17435
  "rect",
16943
17436
  {
@@ -17865,7 +18358,7 @@ function StaticElementRendererImpl({
17865
18358
  }
17866
18359
  );
17867
18360
  }
17868
- var StaticElementRenderer = React18.memo(StaticElementRendererImpl);
18361
+ var StaticElementRenderer = React20.memo(StaticElementRendererImpl);
17869
18362
  StaticElementRenderer.displayName = "StaticElementRenderer";
17870
18363
  function SlideLayer({
17871
18364
  slide,
@@ -18338,4 +18831,4 @@ function useResizablePanels() {
18338
18831
  };
18339
18832
  }
18340
18833
 
18341
- export { ACTION_VERB_MAP, AreaChart3DContext, BarChart3DContext, ChartPartSelectionProvider, ElementRenderer, FragmentedTransitionLayer, LineChart3DContext, LoadingState, MIN_TOUCH_TARGET, MorphTransitionOverlay, PieChart3DContext, PresentationTransitionOverlay, ResizeHandles, SlideBackgroundImageLayer, SlideLayer, SmartArt3DContext, SmartArtRenderer, StaticElementRenderer, SurfaceChart3DContext, ViewerOptionsContext, computeToolbarVisibility, detectTargetType, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, playAnimationSound, renderStrokeView, renderToCanvas, resolveSmartArtDataPalette, safePrompt, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useChartPartSelection, useClipboardHandlers, useCollaborationLivePatch, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, useContentLifecycle, useDerivedElementState, useDerivedSlideState, useDialogCustomShows, useEditorHistory, useEditorOperations, useElementManipulation, useElementOperations, useExportHandlers, useExportSaveAs, useFindReplace, useFollowMode, useFontInjection, useGroupAlignLayerHandlers, useIOHandlers, useInsertElements, useIsMobile, useKeyboardInsets, useKeyboardShortcutWiring, useKeyboardShortcuts, useLayoutSwitching, useLoadContent, useMergeShapesHandler, useModalDismissDrag, usePointerHandlers, usePresenceTracking, usePresentationAnnotations, usePresentationKeyboard, usePresentationMode, usePresentationSetup, usePresenterWindow, usePrintHandlers, usePropertyHandlers, useReadOnlyRecommendationState, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewPreferencesSync, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerOptionsContext, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport };
18834
+ export { ACTION_VERB_MAP, AreaChart3DContext, BarChart3DContext, ChartPartSelectionProvider, CollaborationCursorOverlay, CollaborationProvider, ElementRenderer, FragmentedTransitionLayer, InlineCollaborationContext, LineChart3DContext, LoadingState, MIN_TOUCH_TARGET, MorphTransitionOverlay, PieChart3DContext, PresentationTransitionOverlay, RemoteSelectionOverlay, RemoteUserCursors, ResizeHandles, SlideBackgroundImageLayer, SlideLayer, SmartArt3DContext, SmartArtRenderer, StaticElementRenderer, SurfaceChart3DContext, ViewerOptionsContext, computeToolbarVisibility, detectTargetType, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, playAnimationSound, renderStrokeView, renderToCanvas, resolveSmartArtDataPalette, safePrompt, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useChartPartSelection, useClipboardHandlers, useCollaboration, useCollaborationDocumentSync, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, useContentLifecycle, useDerivedElementState, useDerivedSlideState, useDialogCustomShows, useEditorHistory, useEditorOperations, useElementManipulation, useElementOperations, useExportHandlers, useExportSaveAs, useFindReplace, useFollowMode, useFontInjection, useGroupAlignLayerHandlers, useIOHandlers, useInsertElements, useIsMobile, useKeyboardInsets, useKeyboardShortcutWiring, useKeyboardShortcuts, useLayoutSwitching, useLoadContent, useMergeShapesHandler, useModalDismissDrag, usePointerHandlers, usePresenceTracking, usePresentationAnnotations, usePresentationKeyboard, usePresentationMode, usePresentationSetup, usePresenterWindow, usePrintHandlers, usePropertyHandlers, useReadOnlyRecommendationState, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewPreferencesSync, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerOptionsContext, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport };