pptx-react-viewer 4.75.0 → 4.77.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 (123) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/{AiChatPanel-6ML3VLIX.mjs → AiChatPanel-7BPX44IR.mjs} +1 -1
  3. package/dist/AiChatPanel-7BPX44IR.mjs.br +0 -0
  4. package/dist/AiChatPanel-7BPX44IR.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-4V7QB5Z3.js → AiChatPanel-YJ5R7PPW.js} +19 -19
  6. package/dist/AiChatPanel-YJ5R7PPW.js.br +0 -0
  7. package/dist/AiChatPanel-YJ5R7PPW.js.gz +0 -0
  8. package/dist/ai.js +2 -2
  9. package/dist/ai.js.br +2 -3
  10. package/dist/ai.js.gz +0 -0
  11. package/dist/ai.mjs +1 -1
  12. package/dist/ai.mjs.br +0 -0
  13. package/dist/ai.mjs.gz +0 -0
  14. package/dist/{chunk-P2IEKYVG.js → chunk-3T5NEBOR.js} +2 -2
  15. package/dist/chunk-3T5NEBOR.js.br +0 -0
  16. package/dist/chunk-3T5NEBOR.js.gz +0 -0
  17. package/dist/{chunk-3AZ6ESJU.js → chunk-5CJHRYFK.js} +1666 -1249
  18. package/dist/chunk-5CJHRYFK.js.br +0 -0
  19. package/dist/chunk-5CJHRYFK.js.gz +0 -0
  20. package/dist/{chunk-6GFSF2ML.js → chunk-AIA7CY5U.js} +4 -29
  21. package/dist/chunk-AIA7CY5U.js.br +0 -0
  22. package/dist/chunk-AIA7CY5U.js.gz +0 -0
  23. package/dist/{chunk-AZLOOFU2.mjs → chunk-I5WQFYAK.mjs} +680 -273
  24. package/dist/chunk-I5WQFYAK.mjs.br +0 -0
  25. package/dist/chunk-I5WQFYAK.mjs.gz +0 -0
  26. package/dist/{chunk-RMEWSJZU.mjs → chunk-J4NOGC3R.mjs} +1 -1
  27. package/dist/chunk-J4NOGC3R.mjs.br +0 -0
  28. package/dist/chunk-J4NOGC3R.mjs.gz +0 -0
  29. package/dist/{chunk-Y53EC3JU.mjs → chunk-JB37G6GW.mjs} +1 -1
  30. package/dist/chunk-JB37G6GW.mjs.br +0 -0
  31. package/dist/chunk-JB37G6GW.mjs.gz +0 -0
  32. package/dist/{chunk-DE4Y5F4T.mjs → chunk-MMBLGDHD.mjs} +556 -375
  33. package/dist/chunk-MMBLGDHD.mjs.br +0 -0
  34. package/dist/chunk-MMBLGDHD.mjs.gz +0 -0
  35. package/dist/{chunk-N3YK2BCA.mjs → chunk-N6BJW23K.mjs} +5 -30
  36. package/dist/chunk-N6BJW23K.mjs.br +0 -0
  37. package/dist/chunk-N6BJW23K.mjs.gz +0 -0
  38. package/dist/{chunk-RJRDE3C2.js → chunk-USEEERPE.js} +1107 -926
  39. package/dist/chunk-USEEERPE.js.br +0 -0
  40. package/dist/chunk-USEEERPE.js.gz +0 -0
  41. package/dist/{chunk-MU3BIZ2U.js → chunk-VCNDY7HS.js} +1 -1
  42. package/dist/chunk-VCNDY7HS.js.br +0 -0
  43. package/dist/chunk-VCNDY7HS.js.gz +0 -0
  44. package/dist/i18n/de.cjs +5 -0
  45. package/dist/i18n/de.cjs.br +0 -0
  46. package/dist/i18n/de.cjs.gz +0 -0
  47. package/dist/i18n/de.mjs +5 -0
  48. package/dist/i18n/de.mjs.br +0 -0
  49. package/dist/i18n/de.mjs.gz +0 -0
  50. package/dist/i18n/es.cjs +5 -0
  51. package/dist/i18n/es.cjs.br +0 -0
  52. package/dist/i18n/es.cjs.gz +0 -0
  53. package/dist/i18n/es.mjs +5 -0
  54. package/dist/i18n/es.mjs.br +0 -0
  55. package/dist/i18n/es.mjs.gz +0 -0
  56. package/dist/i18n/fr.cjs +5 -0
  57. package/dist/i18n/fr.cjs.br +0 -0
  58. package/dist/i18n/fr.cjs.gz +0 -0
  59. package/dist/i18n/fr.mjs +5 -0
  60. package/dist/i18n/fr.mjs.br +0 -0
  61. package/dist/i18n/fr.mjs.gz +0 -0
  62. package/dist/i18n/zh-CN.cjs +5 -0
  63. package/dist/i18n/zh-CN.cjs.br +0 -0
  64. package/dist/i18n/zh-CN.cjs.gz +0 -0
  65. package/dist/i18n/zh-CN.mjs +5 -0
  66. package/dist/i18n/zh-CN.mjs.br +0 -0
  67. package/dist/i18n/zh-CN.mjs.gz +0 -0
  68. package/dist/index.d.ts +59 -8
  69. package/dist/index.js +29 -29
  70. package/dist/index.js.br +0 -0
  71. package/dist/index.js.gz +0 -0
  72. package/dist/index.mjs +5 -5
  73. package/dist/index.mjs.br +0 -0
  74. package/dist/index.mjs.gz +0 -0
  75. package/dist/internals.d.ts +51 -24
  76. package/dist/internals.js +82 -82
  77. package/dist/internals.js.br +0 -0
  78. package/dist/internals.js.gz +0 -0
  79. package/dist/internals.mjs +3 -3
  80. package/dist/internals.mjs.br +0 -0
  81. package/dist/internals.mjs.gz +0 -0
  82. package/dist/no-i18next.d.ts +59 -8
  83. package/dist/no-i18next.js +28 -28
  84. package/dist/no-i18next.js.br +0 -0
  85. package/dist/no-i18next.js.gz +0 -0
  86. package/dist/no-i18next.mjs +4 -4
  87. package/dist/no-i18next.mjs.br +0 -0
  88. package/dist/no-i18next.mjs.gz +0 -0
  89. package/dist/pptx-viewer.css +1 -1
  90. package/dist/pptx-viewer.css.br +0 -0
  91. package/dist/pptx-viewer.css.gz +0 -0
  92. package/dist/viewer/index.d.ts +20 -1
  93. package/dist/viewer/index.js +22 -22
  94. package/dist/viewer/index.js.br +0 -0
  95. package/dist/viewer/index.js.gz +0 -0
  96. package/dist/viewer/index.mjs +5 -5
  97. package/dist/viewer/index.mjs.br +5 -4
  98. package/dist/viewer/index.mjs.gz +0 -0
  99. package/package.json +3 -3
  100. package/dist/AiChatPanel-4V7QB5Z3.js.br +0 -0
  101. package/dist/AiChatPanel-4V7QB5Z3.js.gz +0 -0
  102. package/dist/AiChatPanel-6ML3VLIX.mjs.br +0 -0
  103. package/dist/AiChatPanel-6ML3VLIX.mjs.gz +0 -0
  104. package/dist/chunk-3AZ6ESJU.js.br +0 -0
  105. package/dist/chunk-3AZ6ESJU.js.gz +0 -0
  106. package/dist/chunk-6GFSF2ML.js.br +0 -0
  107. package/dist/chunk-6GFSF2ML.js.gz +0 -0
  108. package/dist/chunk-AZLOOFU2.mjs.br +0 -0
  109. package/dist/chunk-AZLOOFU2.mjs.gz +0 -0
  110. package/dist/chunk-DE4Y5F4T.mjs.br +0 -0
  111. package/dist/chunk-DE4Y5F4T.mjs.gz +0 -0
  112. package/dist/chunk-MU3BIZ2U.js.br +0 -0
  113. package/dist/chunk-MU3BIZ2U.js.gz +0 -0
  114. package/dist/chunk-N3YK2BCA.mjs.br +0 -0
  115. package/dist/chunk-N3YK2BCA.mjs.gz +0 -0
  116. package/dist/chunk-P2IEKYVG.js.br +0 -0
  117. package/dist/chunk-P2IEKYVG.js.gz +0 -0
  118. package/dist/chunk-RJRDE3C2.js.br +0 -0
  119. package/dist/chunk-RJRDE3C2.js.gz +0 -0
  120. package/dist/chunk-RMEWSJZU.mjs.br +0 -0
  121. package/dist/chunk-RMEWSJZU.mjs.gz +0 -0
  122. package/dist/chunk-Y53EC3JU.mjs.br +0 -0
  123. package/dist/chunk-Y53EC3JU.mjs.gz +0 -0
@@ -1,7 +1,7 @@
1
- import { cloneTemplateElementsBySlideId, cloneSlide, cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, useTranslation, partitionTemplateElements, isTemplateElementId, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, comparePresentation, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, stopAllPersistentAudio, buildSaveSlides, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, getImageEffectsOpacity, getImageEffectsFilter, getImageRenderStyle, cn, isEditableTextElement, getShapeVisualStyle, getTextStyleForElement, DEFAULT_TEXT_COLOR, renderVectorShape, isConnectorOrLineElement, build3DExtrusionData, getImageSurfaceStyle, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, getElementLabel, normalizeHexColor, makeCloneId, DEFAULT_TEXT_FONT_SIZE, buildPdfFromTiledImageData, GRID_SIZE, copyFormatFromElement, hasCopyableFormat, isImageTiled, getDuotoneColors, DEFAULT_STROKE_COLOR, DEFAULT_FILL_COLOR, buildCssGradientFromShapeStyle, getCropShapeClipPath, getElementTransform, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, rendersCustomVectorPath, rendersWedgeCalloutVector, getImageSurfaceMaskStyle, getTextWarpStyle, getTextCompensationTransform, getTextCompensationOrigin, renderTextSegments, buildReactChartViewModel, renderChartElement, buildInkGroupStrokes, getInkReplayStyles, INK_REPLAY_KEYFRAMES, buildContentPartStrokes, getContentPartReplayStyles, buildTextBody3DSceneStyle, rerouteConnectorsForMovedElements, applyReroutedConnectors, updateCellTextStyleInRawXml, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, buildNotesPdf, canvasToJpegData, applyFormatToElement, isPpactionUrl, parsePpactionUrl, getImageTilingStyle, buildCacheKey, DEFAULT_COLOR_CHANGE_TOLERANCE, getCachedResult, applyColorChange, setCachedResult, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, getConnectorPathGeometry, buildLineShadowCss, buildLineGlowFilter, renderConnectorMarker, getAriaRoleDescription as getAriaRoleDescription$1, getAriaLabel as getAriaLabel$1, getAriaRole, DEFAULT_FONT_FAMILY, ACTION_BUTTON_PRESETS, isUrlSafe, substituteFieldText } from './chunk-N3YK2BCA.mjs';
2
- import { defineThreeViewElement, MIN_TOUCH_TARGET_PX, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createCollaborationSessionController, registerCollaborationTeardown, createPresenceProjector, BROADCAST_THROTTLE_MS, sanitizeColor, createEditorHistoryController, historyTheme, crossedHistoryTheme, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, createActiveAnimationGroup, cancelBuildReveal, clearPlaybackTimers, PresentationAnimationController, resolveMediaTimeNodeElementIds, resolveMediaBookmarkTimesMs, advanceMainSequence, playGroup, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, resolveShowBackward, resolveShowForward, beginZoomExcursion, buildZoomTransitionOverride, createPresenterShowGuard, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, INITIAL_FIND_REPLACE_SESSION, findReplaceSessionActions, visibleTemplateElements, createCollaborationLivePatcher, reportInlineTextDraft, initialInspectorOpen, resolveGoogleFontsCss2Base, createEmbeddedFontsSheet, collectReferencedFontFamilies, resolveGoogleWebfontHref, syncGoogleWebfontStylesheet, loadDeckWebfontOutlines, GlyphOutlineFontCache, createPresentationLoadResources, prepareDeckWebfonts, prefetchDeckWebfonts, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, resolveTextFillBlipUrls, seedRecentColors, resolveAuthoredCustomShowId, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, resolveInitialSlideIndex, pptxLoadErrorMessage, resolveAutosaveIntervalMs, createAutosaveController, saveAutosaveSnapshot, updateMasterViewElement, updateElement, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, canMergeShapes, canInteractWithElement, prepareHtml2CanvasClone, html2canvasCaptureScope, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, DEFAULT_VIEWER_OPTIONS, resolveImageResolutionScale, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, resolveAuthoredSlideRange, mayLeaveSlideShow, buildDeckSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, createAutosaveRecoveryController, discardAutosaveRecovery, probeAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, rasterResultToPngBlob, downloadBlob, elementPictureFilename, canEditElementPoints, dispatchEditorKey, isFeatureEnabled, parentSelection, textFontSizePtToPx, stepFontSizePt, textFontSizePxToPt, cycleSelectableElement, createCustomizationController, gateViewerEdits, prepareElementForInsertion, slideSpaceElement, resolveReportedViewerMode, autosaveStatusKind, createViewerOptionsStore, observeYDocSlides, LOCAL_SYNC_ORIGIN, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, isKeyboardOpen, scopeLayoutOptionsToSlide, collaborationHistoryReady, bindCollaborationHistory, INITIAL_READ_ONLY_SESSION, readOnlySessionActions, applyReadOnlySessionEvent, readOnlyBannerVisible, readOnlyLocked, viewerPreferencesFromViewProperties, DEFAULT_VIEWER_PREFERENCES, viewPropertiesPatchFromPreferences, resolveCollaborationConfig, openPptxFile, readBackstageRecentFile, resolveCollaborationShellEditability, resolveCollaborationShellState, getResizeHandleHitAreaStyle, resolveElementInteractivity, getBackgroundAnimationState, getShapeEffectLayerPlacement, buildTextStyleOverrideCss, isElementRendered, resolveElementAriaAttributes, isMediaFullscreenActive, shouldRenderHitTarget, elementHitTargetStyle, getShapeEffectAnimationLayerStyle, tableFrameCss, inlineElementPointerEvents, passesClicksThroughBox, LINK_TOOLTIP_HOST_CLASS, resolvePalette as resolvePalette$1, mediaControlBarEnabled, mediaTransportVisible, oleActionsVisible, getGroupChildParentFill, deviceStrokeStageStyle, morphOverlayElementSlots, buildMorphOutlineRules, MORPH_CROSSFADE_GROUP_STYLE, MORPH_CROSSFADE_HALF_STYLE, getSlideTransitionAnimations, getFragmentedTransitionDescriptor, SLIDE_TRANSITION_KEYFRAMES, isActionHidden, buildInlineTextCommitPatch, resolveInlineEditAutoFitHeight, resolveInlineEditNormAutofitShrink, setPendingCaretPoint, resolveGroupDoubleClickTarget, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, promptNameDialog, generateCustomShowId, confirmDeleteDialog, contextMenuInspectorAnchor, savedPresentationFileName, deliverSavedPresentation, exportDeckJson, mapCustomizedEditorKey, isEditorTextInputTarget, groupElements, generateElementId, ungroupElements, alignElements, distributeElements, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, planMergeShapes, applyMergeShapesPlan, mapPresentationKey, lastShowSlideIndex, mapPresentationWheel, createBlankSlide, insertSlidePaste, applySlidePasteTemplates, makeSlideId, insertedLayoutCompletion, buildSlideTemplateSlide, templateSchemeFromTheme, queueThemeWrite, needsOwnedSession, openOwnedCollaboration, resolveViewportFitOptions, editorViewportFitFor, calculateViewportFit, observeViewportClientSize, scheduleAutoAdvanceChain, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, resolveTransitionSoundAction, runPresentationAction, safeOpenUrl, buildRunProgramNotice, toggleStageElementMedia, resolveOleVerbTarget, downloadDataUrl, openUrlInNewTab, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, slideSpaceMembers, remapTextToSegments, getInlineEditorSelectionResult, buildInlineListStylePatch, applyActiveInlineListFormatting, applyListStyleUpdate, setPendingSelectionRestore, applyTextStyleUpdate, toggleSelectionBullets, transformInlineListCase, applyCaseTransformToSegments, transformTextCase, createGestureController, resolveExportCaptureDecision, recordProgressPercent, computeGridSpacingPx as computeGridSpacingPx$1, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, overlayMasterViewInlineSnapshot, overlayInlineTextSnapshot, rasterizeElement, cloneElementForPaste, applyPasteSpecialFormat, buildRasterPictureElement, cloneElementUpdates, assertElementUpdateTarget, prepareElementUpdateBatch, createWriteBackScheduler, writeBackReport, createSyncGate, observeExternalCollaborationReadiness, resolveHistoryDepth, hostFontDownloadLock, lockExternalContentSetting, FONT_DOWNLOAD_SETTING_ID, resolveAllowExternalContent, resolveEffectiveGoogleFonts, createBackstagePresentation, buildFieldSubstitutionContext, buildSlidesPaneFieldContext, buildSlidesPaneTableStyleContext, slidesPaneRehearsalTimings, openSlidesPaneLayoutGallery, getImageColorWashStyle, attachRotateHandlePlacement, getSelectionControlArtworkStyle, getSelectionOutlineColor, paintedStrokeWidth, ensureActionAffordanceStyles, resolveElementActionAffordance, actionAffordanceLabels, paintedElementSize, MEDIA_FULLSCREEN_OVERLAY_STYLE, elementContainerHeightStyle, getAnimationOpacity, abuttingEdgeBleedStyle, resolveElementHighlightClick, applyHighlightClickStyle, getComputedEffectStyle, getShapeEffectFilterDefs, getBevelLightingSvgFilter, buildStrokeOutline, buildHollowHitOutline, getSilhouetteFillLayer, buildSubpathFillOverlay, strokeOutlineViewBox, buildSummaryZoomView, readEditableText, spaceBeforeCaretRange, placeCaretAt, takePendingCaretPoint, getPendingSelectionRestore, restoreSegmentSelection, mapInlineTextFormatKey, mapInlineEditorChord, subscribeBarFacePicturePixelSamples, getBarFacePicturePixelSampleVersion, ensureChartInteractionStyles, applyChartPartHighlight, resolveRevealedChartData, formatAxisValue, chartFormatTargetFromEvent, resolveOleType, getOleAriaLabel, getOleTypeColor, getOleTypeLabel, filterRenderedElements, resolveGroupChildFill, isLinkedTextBox, getOverflowSegments, shouldUseSvgWarp, getTextBodyRotationTransform, getTextCompensationStyle, placeholderPromptDescriptor, getAriaRoleDescription, getAriaLabel, elementIdSelector, TOOLBAR_TABS, resolveGroupPressTarget, scrollInspectorSectionIntoView, computeScrollDelta, buildOutlinePrintJobDocument, printJobRasterFallback, applyThemeByPath, withHistoryTheme, withHistoryMasterThemes, writeThemeParts, loadedThemeName, replyToCommentInList, removeTableElementColumn, insertTableElementColumn, removeTableElementRow, insertTableElementRow, withCellStyle, getCellText, setCellText, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, stopCaptureStream, GIF_POST_CAPTURE_MAX_SIDE, encodeGif, rasterizeElementTiles, placeTileOnPage, PDF_SLIDES_PAGE_WIDTH_PT, PDF_SLIDES_PAGE_HEIGHT_PT, createSnapshotTextPositions, resolvePresentationAction, getImageSvgFilters, getCachedNativeImageSize, probeNativeImageSize, buildDuotoneCacheKey, getDuotoneCachedResult, applyDuotone, setDuotoneCachedResult, svgLineCap, connectorSquareCapPath, connectorSnapTransform, connectorNeedsPath, connectorStrandScreenWidth, connectorWrapperTransform, ACTION_INDICATOR_CLASS, ACTION_INDICATOR_ICON_PATH, LINK_TOOLTIP_CLASS, LINK_TOOLTIP_PANEL_CLASS, LINK_TOOLTIP_LABEL_CLASS, LINK_TOOLTIP_HINT_CLASS, modelDataToBlobUrl, resolveZoomNavigationTarget, inlineListBodyText, createInlineListSeed, readListActivationSelection, createInlineListModelObserver, attachCollaborationInlineEditor, bindInlineListParagraph, bindInlineListRun, attachInlineListController, restoreInlineListBodySelection, isBulletMarkerSegment, resolveChartThreeViewSpec, applyChart3DDrag, applyChart3DSelect, canDrillDown, findChartPartTarget, withChartTitle, resolveSmartArtThreeViewSpec, measureSvgViewportRect, isBrowserOpenableMime, formatBytes, getOleDisplayName, getOleBadgeLabel, isEquationOnlyText, convertOmmlToMathMl, EQUATION_FONT_FAMILY, sanitizeMathMl, buildEquationBlockStyle, buildTextBlockStyle, hasGlyphEnvelope, buildGlyphEnvelopeBlock, warpParagraphLayouts, resolveFontItalic, resolveFontWeight, isWedgeCalloutPresetShape, getAriaRole as getAriaRole$1, isElementActionable, buildSmartArtPresetData, classifyMediaType, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, planPrintJob, openPrintWindow, buildVectorPrintJobDocument, openPendingPrintWindow, borrowExternalCollaborationAwareness, observeExternalCollaborationSession, publishLiveGeometry, rasterizeElementTiledToCanvas, clampGifDimensions, rasterResultToPngDataUrl, openExternalHyperlinkConfirmed, advanceChartMarkDrag, advanceChartValueDrag, resolveChartKind, buildChartMarkDragGeometry, beginChartMarkDrag, beginChartValueDrag, findSmartArtNodeText, commitSmartArtNodeFill, commitSmartArtNodeText, groupIntoParagraphs as groupIntoParagraphs$1, createGlyphOutlineLookup, resolveWarpRunPaint, finishPrintWindow, buildRasterPrintJobDocument, applyMotionPathPreset, resolveRevealedSmartArtNodes, resolveRevealedDrawingShapes, buildSmartArtA11y, computeSmartArtElementLayout, flattenNodes, computeInlineEditorRect, smartArtNodeAtPoint, SMARTART_DEFAULT_PALETTE, computeDrawingViewBox, projectDrawingShapes, resolveRevealedDrawingShapeNodeIds, styleShadowFilter, buildChromeStyle, refreshSmartArtPictureImage, centeredSvgTextLines, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, bringForward, sendBackward, bringToFront, sendToBack } from 'ooxml-ui/pptx';
3
- export { DUOTONE_PRESETS, MOBILE_BREAKPOINT, SLIDE_TRANSITION_KEYFRAMES, TABLET_BREAKPOINT, clearAudienceContent, computeVirtualRange, downloadBlob, getSlideTransitionAnimations, loadAudienceContent, storeAudienceContent } from 'ooxml-ui/pptx';
4
- import React17, { useRef, useState, useCallback, useEffect, useSyncExternalStore, useMemo, useContext, useLayoutEffect, createContext, useImperativeHandle, Suspense } from 'react';
1
+ import { cloneTemplateElementsBySlideId, cloneSlide, cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, useTranslation, partitionTemplateElements, isTemplateElementId, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, comparePresentation, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, stopAllPersistentAudio, buildSaveSlides, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, getImageEffectsOpacity, getImageEffectsFilter, getImageRenderStyle, cn, isEditableTextElement, getShapeVisualStyle, getTextStyleForElement, DEFAULT_TEXT_COLOR, renderVectorShape, isConnectorOrLineElement, build3DExtrusionData, getImageSurfaceStyle, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, getElementLabel, normalizeHexColor, makeCloneId, DEFAULT_TEXT_FONT_SIZE, buildPdfFromTiledImageData, GRID_SIZE, copyFormatFromElement, hasCopyableFormat, isImageTiled, getDuotoneColors, DEFAULT_STROKE_COLOR, DEFAULT_FILL_COLOR, buildCssGradientFromShapeStyle, getCropShapeClipPath, getElementTransform, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, rendersCustomVectorPath, rendersWedgeCalloutVector, getImageSurfaceMaskStyle, getTextWarpStyle, getTextCompensationTransform, getTextCompensationOrigin, renderTextSegments, buildReactChartViewModel, renderChartElement, buildInkGroupStrokes, getInkReplayStyles, INK_REPLAY_KEYFRAMES, buildContentPartStrokes, getContentPartReplayStyles, buildTextBody3DSceneStyle, rerouteConnectorsForMovedElements, applyReroutedConnectors, updateCellTextStyleInRawXml, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, buildNotesPdf, canvasToJpegData, applyFormatToElement, isPpactionUrl, parsePpactionUrl, getImageTilingStyle, buildCacheKey, DEFAULT_COLOR_CHANGE_TOLERANCE, getCachedResult, applyColorChange, setCachedResult, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, getConnectorPathGeometry, buildLineShadowCss, buildLineGlowFilter, renderConnectorMarker, getAriaRoleDescription as getAriaRoleDescription$1, getAriaLabel as getAriaLabel$1, getAriaRole, DEFAULT_FONT_FAMILY, ACTION_BUTTON_PRESETS, isUrlSafe, substituteFieldText } from './chunk-N6BJW23K.mjs';
2
+ import { reportElementRenderError, elementRenderErrorContext, defineThreeViewElement, MIN_TOUCH_TARGET_PX, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createCollaborationSessionController, registerCollaborationTeardown, createPresenceProjector, BROADCAST_THROTTLE_MS, sanitizeColor, createEditorHistoryController, historyTheme, crossedHistoryTheme, createViewerZoomStore, clampZoomScale, resetViewportScroll, createActiveAnimationGroup, cancelBuildReveal, clearPlaybackTimers, PresentationAnimationController, resolveMediaTimeNodeElementIds, resolveMediaBookmarkTimesMs, advanceMainSequence, playGroup, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createWheelStepBuffer, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, resolveShowBackward, resolveShowForward, beginZoomExcursion, buildZoomTransitionOverride, createPresenterShowGuard, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, INITIAL_FIND_REPLACE_SESSION, findReplaceSessionActions, visibleTemplateElements, createCollaborationLivePatcher, reportInlineTextDraft, initialInspectorOpen, resolveGoogleFontsCss2Base, createEmbeddedFontsSheet, collectReferencedFontFamilies, resolveGoogleWebfontHref, syncGoogleWebfontStylesheet, loadDeckWebfontOutlines, GlyphOutlineFontCache, createPresentationLoadResources, prepareDeckWebfonts, prefetchDeckWebfonts, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, resolveTextFillBlipUrls, seedRecentColors, resolveAuthoredCustomShowId, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, resolveInitialSlideIndex, pptxLoadErrorMessage, resolveAutosaveIntervalMs, createAutosaveController, saveAutosaveSnapshot, updateMasterViewElement, updateElement, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, canMergeShapes, canInteractWithElement, prepareHtml2CanvasClone, html2canvasCaptureScope, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, DEFAULT_VIEWER_OPTIONS, resolveImageResolutionScale, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, resolveAuthoredSlideRange, mayLeaveSlideShow, buildDeckSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, createAutosaveRecoveryController, discardAutosaveRecovery, probeAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, rasterResultToPngBlob, downloadBlob, elementPictureFilename, canEditElementPoints, dispatchEditorKey, isFeatureEnabled, parentSelection, textFontSizePtToPx, stepFontSizePt, textFontSizePxToPt, cycleSelectableElement, createCustomizationController, gateViewerEdits, prepareElementForInsertion, slideSpaceElement, resolveReportedViewerMode, autosaveStatusKind, createViewerOptionsStore, observeYDocSlides, LOCAL_SYNC_ORIGIN, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, isKeyboardOpen, scopeLayoutOptionsToSlide, collaborationHistoryReady, bindCollaborationHistory, INITIAL_READ_ONLY_SESSION, readOnlySessionActions, applyReadOnlySessionEvent, readOnlyBannerVisible, readOnlyLocked, viewerPreferencesFromViewProperties, DEFAULT_VIEWER_PREFERENCES, viewPropertiesPatchFromPreferences, resolveCollaborationConfig, openPptxFile, readBackstageRecentFile, resolveCollaborationShellEditability, describeBuildingBlockShell, writeBackReport, resolveBuildingBlockMode, getResizeHandleHitAreaStyle, probeElementRenderFault, resolveElementInteractivity, getBackgroundAnimationState, getShapeEffectLayerPlacement, buildTextStyleOverrideCss, isElementRendered, resolveElementAriaAttributes, isMediaFullscreenActive, shouldRenderHitTarget, elementHitTargetStyle, getShapeEffectAnimationLayerStyle, tableFrameCss, inlineElementPointerEvents, passesClicksThroughBox, LINK_TOOLTIP_HOST_CLASS, resolvePalette as resolvePalette$1, mediaControlBarEnabled, mediaTransportVisible, oleActionsVisible, getGroupChildParentFill, deviceStrokeStageStyle, morphOverlayElementSlots, buildMorphOutlineRules, MORPH_CROSSFADE_GROUP_STYLE, MORPH_CROSSFADE_HALF_STYLE, getSlideTransitionAnimations, getFragmentedTransitionDescriptor, SLIDE_TRANSITION_KEYFRAMES, isActionHidden, buildInlineTextCommitPatch, resolveInlineEditAutoFitHeight, resolveInlineEditNormAutofitShrink, setPendingCaretPoint, resolveGroupDoubleClickTarget, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, promptNameDialog, generateCustomShowId, confirmDeleteDialog, contextMenuInspectorAnchor, savedPresentationFileName, deliverSavedPresentation, exportDeckJson, mapCustomizedEditorKey, isEditorTextInputTarget, groupElements, generateElementId, ungroupElements, alignElements, distributeElements, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, planMergeShapes, applyMergeShapesPlan, mapPresentationKey, lastShowSlideIndex, mapPresentationWheel, createBlankSlide, insertSlidePaste, applySlidePasteTemplates, makeSlideId, insertedLayoutCompletion, buildSlideTemplateSlide, templateSchemeFromTheme, queueThemeWrite, attachViewportNavigation, needsOwnedSession, openOwnedCollaboration, resolveViewportFitOptions, editorViewportFitFor, calculateViewportFit, observeViewportClientSize, scheduleAutoAdvanceChain, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, resolveTransitionSoundAction, runPresentationAction, safeOpenUrl, buildRunProgramNotice, toggleStageElementMedia, resolveOleVerbTarget, downloadDataUrl, openUrlInNewTab, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, slideSpaceMembers, remapTextToSegments, getInlineEditorSelectionResult, buildInlineListStylePatch, applyActiveInlineListFormatting, applyListStyleUpdate, setPendingSelectionRestore, applyTextStyleUpdate, toggleSelectionBullets, transformInlineListCase, applyCaseTransformToSegments, transformTextCase, createGestureController, resolveExportCaptureDecision, recordProgressPercent, computeGridSpacingPx as computeGridSpacingPx$1, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, overlayMasterViewInlineSnapshot, overlayInlineTextSnapshot, rasterizeElement, cloneElementForPaste, applyPasteSpecialFormat, buildRasterPictureElement, cloneElementUpdates, assertElementUpdateTarget, prepareElementUpdateBatch, createSaveRevisionController, createWriteBackScheduler, createSyncGate, observeExternalCollaborationReadiness, resolveHistoryDepth, hostFontDownloadLock, lockExternalContentSetting, FONT_DOWNLOAD_SETTING_ID, resolveAllowExternalContent, resolveEffectiveGoogleFonts, resetSlideLayoutPath, selectionEquation, createPptxBuildingBlockSession, registerBuildingBlockGroups, createBackstagePresentation, buildFieldSubstitutionContext, buildSlidesPaneFieldContext, buildSlidesPaneTableStyleContext, slidesPaneRehearsalTimings, openSlidesPaneLayoutGallery, getImageColorWashStyle, attachRotateHandlePlacement, getSelectionControlArtworkStyle, getSelectionOutlineColor, paintedStrokeWidth, ensureActionAffordanceStyles, resolveElementActionAffordance, actionAffordanceLabels, paintedElementSize, MEDIA_FULLSCREEN_OVERLAY_STYLE, elementContainerHeightStyle, getAnimationOpacity, abuttingEdgeBleedStyle, resolveElementHighlightClick, applyHighlightClickStyle, getComputedEffectStyle, getShapeEffectFilterDefs, getBevelLightingSvgFilter, buildStrokeOutline, buildHollowHitOutline, getSilhouetteFillLayer, buildSubpathFillOverlay, strokeOutlineViewBox, buildSummaryZoomView, readEditableText, spaceBeforeCaretRange, placeCaretAt, takePendingCaretPoint, getPendingSelectionRestore, restoreSegmentSelection, mapInlineTextFormatKey, mapInlineEditorChord, subscribeBarFacePicturePixelSamples, getBarFacePicturePixelSampleVersion, ensureChartInteractionStyles, applyChartPartHighlight, resolveRevealedChartData, formatAxisValue, chartFormatTargetFromEvent, resolveOleType, getOleAriaLabel, getOleTypeColor, getOleTypeLabel, filterRenderedElements, resolveGroupChildFill, isLinkedTextBox, getOverflowSegments, shouldUseSvgWarp, getTextBodyRotationTransform, getTextCompensationStyle, placeholderPromptDescriptor, getAriaRoleDescription, getAriaLabel, elementIdSelector, TOOLBAR_TABS, resolveGroupPressTarget, scrollInspectorSectionIntoView, computeScrollDelta, buildOutlinePrintJobDocument, printJobRasterFallback, applyThemeByPath, withHistoryTheme, withHistoryMasterThemes, writeThemeParts, loadedThemeName, replyToCommentInList, removeTableElementColumn, insertTableElementColumn, removeTableElementRow, insertTableElementRow, withCellStyle, getCellText, setCellText, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, stopCaptureStream, GIF_POST_CAPTURE_MAX_SIDE, encodeGif, rasterizeElementTiles, placeTileOnPage, PDF_SLIDES_PAGE_WIDTH_PT, PDF_SLIDES_PAGE_HEIGHT_PT, createSnapshotTextPositions, resolvePresentationAction, getImageSvgFilters, getCachedNativeImageSize, probeNativeImageSize, buildDuotoneCacheKey, getDuotoneCachedResult, applyDuotone, setDuotoneCachedResult, svgLineCap, connectorSquareCapPath, connectorSnapTransform, connectorNeedsPath, connectorStrandScreenWidth, connectorWrapperTransform, ACTION_INDICATOR_CLASS, ACTION_INDICATOR_ICON_PATH, LINK_TOOLTIP_CLASS, LINK_TOOLTIP_PANEL_CLASS, LINK_TOOLTIP_LABEL_CLASS, LINK_TOOLTIP_HINT_CLASS, modelDataToBlobUrl, resolveZoomNavigationTarget, inlineListBodyText, createInlineListSeed, readListActivationSelection, createInlineListModelObserver, attachCollaborationInlineEditor, bindInlineListParagraph, bindInlineListRun, attachInlineListController, restoreInlineListBodySelection, isBulletMarkerSegment, resolveChartThreeViewSpec, applyChart3DDrag, applyChart3DSelect, canDrillDown, findChartPartTarget, withChartTitle, resolveSmartArtThreeViewSpec, measureSvgViewportRect, isBrowserOpenableMime, formatBytes, getOleDisplayName, getOleBadgeLabel, isEquationOnlyText, convertOmmlToMathMl, EQUATION_FONT_FAMILY, sanitizeMathMl, buildEquationBlockStyle, buildTextBlockStyle, hasGlyphEnvelope, buildGlyphEnvelopeBlock, warpParagraphLayouts, resolveFontItalic, resolveFontWeight, isWedgeCalloutPresetShape, getAriaRole as getAriaRole$1, isElementActionable, buildingBlockFailure, BUILDING_BLOCK_OK, resolveHyperlinkEditResult, buildSmartArtPresetData, classifyMediaType, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, planPrintJob, openPrintWindow, buildVectorPrintJobDocument, openPendingPrintWindow, borrowExternalCollaborationAwareness, observeExternalCollaborationSession, publishLiveGeometry, rasterizeElementTiledToCanvas, clampGifDimensions, rasterResultToPngDataUrl, openExternalHyperlinkConfirmed, advanceChartMarkDrag, advanceChartValueDrag, resolveChartKind, buildChartMarkDragGeometry, beginChartMarkDrag, beginChartValueDrag, findSmartArtNodeText, commitSmartArtNodeFill, commitSmartArtNodeText, groupIntoParagraphs as groupIntoParagraphs$1, createGlyphOutlineLookup, resolveWarpRunPaint, finishPrintWindow, buildRasterPrintJobDocument, applyMotionPathPreset, resolveRevealedSmartArtNodes, resolveRevealedDrawingShapes, buildSmartArtA11y, computeSmartArtElementLayout, flattenNodes, computeInlineEditorRect, smartArtNodeAtPoint, SMARTART_DEFAULT_PALETTE, computeDrawingViewBox, projectDrawingShapes, resolveRevealedDrawingShapeNodeIds, styleShadowFilter, buildChromeStyle, refreshSmartArtPictureImage, centeredSvgTextLines, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, bringForward, sendBackward, bringToFront, sendToBack } from 'ooxml-ui/pptx';
3
+ export { DUOTONE_PRESETS, MOBILE_BREAKPOINT, SLIDE_TRANSITION_KEYFRAMES, TABLET_BREAKPOINT, clearAudienceContent, computeVirtualRange, detectHyperlinkTargetType, downloadBlob, getSlideTransitionAnimations, loadAudienceContent, parseHyperlinkEmailUrl, parseHyperlinkSlideNumber, storeAudienceContent } from 'ooxml-ui/pptx';
4
+ import React18, { createContext, useRef, useState, useCallback, useEffect, useSyncExternalStore, useMemo, useContext, useLayoutEffect, useImperativeHandle, Suspense } from 'react';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
6
  import { PptxHandler, EncryptedFileError, hasShapeProperties, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, guidePxToEmu, hasTextProperties, isInkElement, duplicateSlide, buildThemeColorMap, reResolveSlideColors, reResolveElementColors, reResolveSlideFonts, reResolveElementFonts, isImageLikeElement, getSubstituteFontFamily, elementActionToPptxAction, SvgExporter, setSmartArtNodeStyle, updateSmartArtNodeText } from 'ooxml-core/pptx';
7
7
  import { translationsEn } from 'ooxml-ui/pptx/i18n';
@@ -1020,13 +1020,14 @@ function useZoomViewport({
1020
1020
  canvasSize,
1021
1021
  selectedElements,
1022
1022
  fitPadding,
1023
- maxFitScale
1023
+ maxFitScale,
1024
+ dragPans = false,
1025
+ activeSlideId
1024
1026
  }) {
1025
1027
  const editWrapperRef = useRef(null);
1026
1028
  const canvasStageRef = useRef(null);
1027
1029
  const { viewportRef: canvasViewportRef, viewportNode, setCanvasViewportNode } = useViewportNode();
1028
1030
  const renderScaleRef = useRef(1);
1029
- const wheelBufferRef = useRef(createWheelStepBuffer());
1030
1031
  const storeRef = useRef(null);
1031
1032
  storeRef.current ??= createViewerZoomStore();
1032
1033
  const store = storeRef.current;
@@ -1124,41 +1125,40 @@ function useZoomViewport({
1124
1125
  selectedElements,
1125
1126
  setScale
1126
1127
  ]);
1127
- const handleWheel = useCallback(
1128
- (event) => {
1129
- const mapped = mapEditingWheel(event, wheelBufferRef.current, true);
1130
- if (mapped.intent !== "zoom") {
1131
- return;
1132
- }
1133
- event.preventDefault();
1134
- store.dispatch({
1135
- type: "set-zoom",
1136
- zoom: clampZoomScale(store.getState().zoom + mapped.deltaScale)
1137
- });
1138
- },
1139
- [store]
1140
- );
1128
+ const dragPansRef = useRef(dragPans);
1129
+ useEffect(() => {
1130
+ dragPansRef.current = dragPans;
1131
+ }, [dragPans]);
1141
1132
  useEffect(() => {
1142
1133
  if (viewportNode === null) {
1143
1134
  return;
1144
1135
  }
1145
1136
  let raf = 0;
1146
- let attached = null;
1137
+ let detach = null;
1147
1138
  const attach = () => {
1148
1139
  const viewport = viewportNode ?? canvasViewportRef.current;
1149
1140
  if (!viewport) {
1150
1141
  raf = requestAnimationFrame(attach);
1151
1142
  return;
1152
1143
  }
1153
- attached = viewport;
1154
- viewport.addEventListener("wheel", handleWheel, { passive: false });
1144
+ detach = attachViewportNavigation(viewport, {
1145
+ getZoom: () => store.getState().zoom,
1146
+ setZoom: (zoom) => store.dispatch({ type: "set-zoom", zoom }),
1147
+ dragPans: () => dragPansRef.current
1148
+ });
1155
1149
  };
1156
1150
  attach();
1157
1151
  return () => {
1158
1152
  cancelAnimationFrame(raf);
1159
- attached?.removeEventListener("wheel", handleWheel);
1153
+ detach?.();
1160
1154
  };
1161
- }, [canvasViewportRef, viewportNode, handleWheel]);
1155
+ }, [canvasViewportRef, viewportNode, store]);
1156
+ useEffect(() => {
1157
+ const viewport = viewportNode ?? canvasViewportRef.current;
1158
+ if (viewport) {
1159
+ resetViewportScroll(viewport);
1160
+ }
1161
+ }, [activeSlideId]);
1162
1162
  const getCanvasPointFromClient = useCallback(
1163
1163
  (clientX, clientY) => {
1164
1164
  const canvasStage = canvasStageRef.current;
@@ -1195,7 +1195,6 @@ function useZoomViewport({
1195
1195
  handleResetZoom,
1196
1196
  handleZoomToFit,
1197
1197
  handleZoomToSelection,
1198
- handleWheel,
1199
1198
  centerBoundsInViewport,
1200
1199
  getCanvasPointFromClient
1201
1200
  };
@@ -6116,184 +6115,95 @@ function createFileHandlers(deps) {
6116
6115
  };
6117
6116
  reader.readAsDataURL(file);
6118
6117
  };
6119
- const handleMediaFileChange = (e) => {
6120
- const file = e.target.files?.[0];
6121
- if (!file || !activeSlide) {
6122
- return;
6118
+ const insertMediaFile = (file, shouldInsert) => {
6119
+ if (!activeSlide) {
6120
+ return Promise.resolve(buildingBlockFailure("no-slide"));
6123
6121
  }
6124
- e.target.value = "";
6125
6122
  const mediaType = classifyMediaType(file.type);
6126
6123
  if (!mediaType) {
6127
- return;
6124
+ return Promise.resolve(buildingBlockFailure("unsupported-type"));
6128
6125
  }
6129
6126
  const elFilePath = file.path;
6130
- const insertMediaElement = (mediaSourceUrl, width, height) => {
6131
- addElement({
6132
- id: generateElementId(),
6133
- type: "media",
6134
- mediaType,
6135
- mediaMimeType: file.type || void 0,
6136
- mediaData: mediaSourceUrl,
6137
- x: Math.round((canvasSize.width - width) / 2),
6138
- y: Math.round((canvasSize.height - height) / 2),
6139
- width,
6140
- height
6141
- });
6142
- };
6143
- if (elFilePath) {
6144
- let normalized = elFilePath.replace(/\\/gu, "/");
6145
- if (!normalized.startsWith("/")) {
6146
- normalized = `/${normalized}`;
6147
- }
6148
- const mediaUrl = `pptx-resource://media${encodeURI(normalized)}`;
6149
- if (mediaType === "audio") {
6150
- insertMediaElement(mediaUrl, 420, 64);
6151
- return;
6152
- }
6153
- const probeUrl = URL.createObjectURL(file);
6154
- const probeVideo = document.createElement("video");
6155
- probeVideo.preload = "metadata";
6156
- probeVideo.onloadedmetadata = () => {
6157
- URL.revokeObjectURL(probeUrl);
6158
- const mW = 640, mH = 360;
6159
- let w = probeVideo.videoWidth || mW, h = probeVideo.videoHeight || mH;
6160
- if (w > mW || h > mH) {
6161
- const sc = Math.min(mW / w, mH / h);
6162
- w = Math.round(w * sc);
6163
- h = Math.round(h * sc);
6127
+ return new Promise((resolve) => {
6128
+ const insertMediaElement = (mediaSourceUrl, width, height) => {
6129
+ if (shouldInsert && !shouldInsert()) {
6130
+ resolve(buildingBlockFailure("stale-target"));
6131
+ return;
6164
6132
  }
6165
- insertMediaElement(mediaUrl, w, h);
6133
+ addElement({
6134
+ id: generateElementId(),
6135
+ type: "media",
6136
+ mediaType,
6137
+ mediaMimeType: file.type || void 0,
6138
+ mediaData: mediaSourceUrl,
6139
+ x: Math.round((canvasSize.width - width) / 2),
6140
+ y: Math.round((canvasSize.height - height) / 2),
6141
+ width,
6142
+ height
6143
+ });
6144
+ resolve(BUILDING_BLOCK_OK);
6166
6145
  };
6167
- probeVideo.onerror = () => {
6168
- URL.revokeObjectURL(probeUrl);
6169
- insertMediaElement(mediaUrl, 640, 360);
6146
+ const probeVideoSize = (probeSrc, mediaSourceUrl, release) => {
6147
+ const probeVideo = document.createElement("video");
6148
+ probeVideo.preload = "metadata";
6149
+ probeVideo.onloadedmetadata = () => {
6150
+ release();
6151
+ const mW = 640, mH = 360;
6152
+ let w = probeVideo.videoWidth || mW, h = probeVideo.videoHeight || mH;
6153
+ if (w > mW || h > mH) {
6154
+ const sc = Math.min(mW / w, mH / h);
6155
+ w = Math.round(w * sc);
6156
+ h = Math.round(h * sc);
6157
+ }
6158
+ insertMediaElement(mediaSourceUrl, w, h);
6159
+ };
6160
+ probeVideo.onerror = () => {
6161
+ release();
6162
+ insertMediaElement(mediaSourceUrl, 640, 360);
6163
+ };
6164
+ probeVideo.src = probeSrc;
6170
6165
  };
6171
- probeVideo.src = probeUrl;
6172
- return;
6173
- }
6174
- const reader = new FileReader();
6175
- reader.onload = () => {
6176
- const dataUrl = reader.result;
6177
- if (!dataUrl) {
6178
- return;
6179
- }
6180
- if (mediaType === "audio") {
6181
- insertMediaElement(dataUrl, 420, 64);
6166
+ if (elFilePath) {
6167
+ let normalized = elFilePath.replace(/\\/gu, "/");
6168
+ if (!normalized.startsWith("/")) {
6169
+ normalized = `/${normalized}`;
6170
+ }
6171
+ const mediaUrl = `pptx-resource://media${encodeURI(normalized)}`;
6172
+ if (mediaType === "audio") {
6173
+ insertMediaElement(mediaUrl, 420, 64);
6174
+ return;
6175
+ }
6176
+ const probeUrl = URL.createObjectURL(file);
6177
+ probeVideoSize(probeUrl, mediaUrl, () => URL.revokeObjectURL(probeUrl));
6182
6178
  return;
6183
6179
  }
6184
- const probeVideo = document.createElement("video");
6185
- probeVideo.preload = "metadata";
6186
- probeVideo.onloadedmetadata = () => {
6187
- const mW = 640, mH = 360;
6188
- let w = probeVideo.videoWidth || mW, h = probeVideo.videoHeight || mH;
6189
- if (w > mW || h > mH) {
6190
- const sc = Math.min(mW / w, mH / h);
6191
- w = Math.round(w * sc);
6192
- h = Math.round(h * sc);
6180
+ const reader = new FileReader();
6181
+ reader.onerror = () => resolve(buildingBlockFailure("decode-failed"));
6182
+ reader.onload = () => {
6183
+ const dataUrl = reader.result;
6184
+ if (!dataUrl) {
6185
+ resolve(buildingBlockFailure("decode-failed"));
6186
+ return;
6193
6187
  }
6194
- insertMediaElement(dataUrl, w, h);
6195
- };
6196
- probeVideo.onerror = () => {
6197
- insertMediaElement(dataUrl, 640, 360);
6188
+ if (mediaType === "audio") {
6189
+ insertMediaElement(dataUrl, 420, 64);
6190
+ return;
6191
+ }
6192
+ probeVideoSize(dataUrl, dataUrl, () => {
6193
+ });
6198
6194
  };
6199
- probeVideo.src = dataUrl;
6200
- };
6201
- reader.readAsDataURL(file);
6195
+ reader.readAsDataURL(file);
6196
+ });
6202
6197
  };
6203
- return { handleImageFileChange, handleMediaFileChange };
6204
- }
6205
-
6206
- // src/viewer/components/hyperlink-edit-types.ts
6207
- var ACTION_VERB_MAP = {
6208
- "ppaction://hlinkshowjump?jump=nextslide": "nextSlide",
6209
- "ppaction://hlinkshowjump?jump=previousslide": "prevSlide",
6210
- "ppaction://hlinkshowjump?jump=firstslide": "firstSlide",
6211
- "ppaction://hlinkshowjump?jump=lastslide": "lastSlide",
6212
- "ppaction://hlinkshowjump?jump=endshow": "endShow"
6213
- };
6214
- var ACTION_VERB_TO_PPACTION = {
6215
- nextSlide: "ppaction://hlinkshowjump?jump=nextslide",
6216
- prevSlide: "ppaction://hlinkshowjump?jump=previousslide",
6217
- firstSlide: "ppaction://hlinkshowjump?jump=firstslide",
6218
- lastSlide: "ppaction://hlinkshowjump?jump=lastslide",
6219
- endShow: "ppaction://hlinkshowjump?jump=endshow"
6220
- };
6221
-
6222
- // src/viewer/components/hyperlink-edit-utils.ts
6223
- function detectTargetType(url, action) {
6224
- if (action && action.startsWith("ppaction://")) {
6225
- if (action.includes("hlinksldjump")) {
6226
- return "slide";
6227
- }
6228
- if (ACTION_VERB_MAP[action.toLowerCase()]) {
6229
- return "action";
6230
- }
6231
- return "action";
6232
- }
6233
- if (!url) {
6234
- return "url";
6235
- }
6236
- if (url.startsWith("mailto:")) {
6237
- return "email";
6238
- }
6239
- if (/^[a-zA-Z]:\\|^\.\.?[/\\]|^file:/i.test(url)) {
6240
- return "file";
6241
- }
6242
- return "url";
6243
- }
6244
- function parseEmailUrl(url) {
6245
- if (!url.startsWith("mailto:")) {
6246
- return { address: url, subject: "" };
6247
- }
6248
- const withoutScheme = url.slice(7);
6249
- const qIdx = withoutScheme.indexOf("?");
6250
- if (qIdx < 0) {
6251
- return { address: withoutScheme, subject: "" };
6252
- }
6253
- const address = withoutScheme.slice(0, qIdx);
6254
- const params = new URLSearchParams(withoutScheme.slice(qIdx + 1));
6255
- return { address, subject: params.get("subject") || "" };
6256
- }
6257
- function parseSlideFromUrl(url, action) {
6258
- if (action === "ppaction://hlinksldjump" && url) {
6259
- const match = url.match(/slide(\d+)\.xml$/i);
6260
- if (match) {
6261
- return parseInt(match[1], 10);
6262
- }
6263
- }
6264
- if (url) {
6265
- const hashMatch = url.match(/#\s*Slide\s+(\d+)/i);
6266
- if (hashMatch) {
6267
- return parseInt(hashMatch[1], 10);
6268
- }
6269
- }
6270
- return 1;
6271
- }
6272
- function resolveHyperlinkEditResult(data) {
6273
- const tooltip = data.tooltip.trim() || void 0;
6274
- switch (data.targetType) {
6275
- case "email": {
6276
- const mailto = data.emailSubject ? `mailto:${data.emailAddress}?subject=${encodeURIComponent(data.emailSubject)}` : `mailto:${data.emailAddress}`;
6277
- return { url: mailto, tooltip };
6198
+ const handleMediaFileChange = (e) => {
6199
+ const file = e.target.files?.[0];
6200
+ if (!file || !activeSlide) {
6201
+ return;
6278
6202
  }
6279
- case "slide":
6280
- return {
6281
- url: `slide${data.slideNumber}.xml`,
6282
- action: "ppaction://hlinksldjump",
6283
- tooltip
6284
- };
6285
- case "file":
6286
- return { url: data.filePath, tooltip };
6287
- case "action":
6288
- return {
6289
- url: "",
6290
- action: ACTION_VERB_TO_PPACTION[data.actionVerb],
6291
- tooltip
6292
- };
6293
- case "url":
6294
- default:
6295
- return { url: data.url, tooltip };
6296
- }
6203
+ e.target.value = "";
6204
+ void insertMediaFile(file);
6205
+ };
6206
+ return { handleImageFileChange, handleMediaFileChange, insertMediaFile };
6297
6207
  }
6298
6208
 
6299
6209
  // src/viewer/hooks/insert-structured-elements.ts
@@ -6354,14 +6264,14 @@ function createStructuredElementHandlers(deps) {
6354
6264
  ops.updateElementById(sel.id, { textSegments: updatedSegments });
6355
6265
  history.markDirty();
6356
6266
  };
6357
- const handleHyperlinkConfirm = (data) => {
6267
+ const applyHyperlink = (data) => {
6358
6268
  const sel = selectedElements[0];
6359
6269
  if (!sel) {
6360
- return;
6270
+ return buildingBlockFailure("no-selection");
6361
6271
  }
6362
6272
  const resolved = resolveHyperlinkEditResult(data);
6363
6273
  if (resolved.url && !isUrlSafe(resolved.url)) {
6364
- return;
6274
+ return buildingBlockFailure("unsafe-url");
6365
6275
  }
6366
6276
  const actionClick = {
6367
6277
  url: resolved.url || void 0,
@@ -6370,6 +6280,22 @@ function createStructuredElementHandlers(deps) {
6370
6280
  };
6371
6281
  ops.updateElementById(sel.id, { actionClick });
6372
6282
  history.markDirty();
6283
+ return BUILDING_BLOCK_OK;
6284
+ };
6285
+ const handleHyperlinkConfirm = (data) => {
6286
+ applyHyperlink(data);
6287
+ };
6288
+ const removeHyperlink = () => {
6289
+ const sel = selectedElements[0];
6290
+ if (!sel) {
6291
+ return buildingBlockFailure("no-selection");
6292
+ }
6293
+ if (!sel.actionClick) {
6294
+ return buildingBlockFailure("no-hyperlink");
6295
+ }
6296
+ ops.updateElementById(sel.id, { actionClick: void 0 });
6297
+ history.markDirty();
6298
+ return BUILDING_BLOCK_OK;
6373
6299
  };
6374
6300
  const handleInsertField = (fieldType, value) => {
6375
6301
  if (!activeSlide) {
@@ -6456,6 +6382,8 @@ function createStructuredElementHandlers(deps) {
6456
6382
  handleInsertEquation,
6457
6383
  handleUpdateEquation,
6458
6384
  handleHyperlinkConfirm,
6385
+ applyHyperlink,
6386
+ removeHyperlink,
6459
6387
  handleInsertField,
6460
6388
  handleAddActionButton
6461
6389
  };
@@ -10647,6 +10575,18 @@ function useReportOnChange(value, report, initial = value) {
10647
10575
  callback.current?.(value);
10648
10576
  }, [value]);
10649
10577
  }
10578
+ function useSaveRevision(deps) {
10579
+ const depsRef = useRef(deps);
10580
+ depsRef.current = deps;
10581
+ const controllerRef = useRef(null);
10582
+ controllerRef.current ??= createSaveRevisionController({
10583
+ getSources: () => depsRef.current.getSources(),
10584
+ serialize: () => depsRef.current.serialize(),
10585
+ markClean: () => depsRef.current.markClean(),
10586
+ discardRecovery: () => depsRef.current.discardRecovery()
10587
+ });
10588
+ return controllerRef.current;
10589
+ }
10650
10590
 
10651
10591
  // src/viewer/hooks/useViewerIntegration.ts
10652
10592
  function useViewerIntegration(input) {
@@ -10811,6 +10751,16 @@ function useViewerIntegration(input) {
10811
10751
  const updateElements = useElementUpdateBatch(input);
10812
10752
  const fallbackCustomizationRef = useRef(null);
10813
10753
  const customizationApi = input.customizationApi ?? (fallbackCustomizationRef.current ??= createCustomizationController().api);
10754
+ const saveRevision = useSaveRevision({
10755
+ getSources: getChangeSources,
10756
+ // Not `getContent`: that one announces `onContentChange`; a host save is not an edit feed.
10757
+ serialize: async () => await serializeSlides() ?? new Uint8Array(0),
10758
+ markClean: () => {
10759
+ history.markSaved();
10760
+ state.setIsDirty(false);
10761
+ },
10762
+ discardRecovery: input.discardRecoveryOnHostSave ?? (() => void 0)
10763
+ });
10814
10764
  const latestHandleRef = useRef(null);
10815
10765
  const viewerApiRef = useRef(null);
10816
10766
  viewerApiRef.current ??= new Proxy({}, {
@@ -10887,6 +10837,9 @@ function useViewerIntegration(input) {
10887
10837
  isDirty() {
10888
10838
  return state.isDirty;
10889
10839
  },
10840
+ getSaveRevision: () => saveRevision.getRevision(),
10841
+ getSaveSnapshot: () => saveRevision.snapshot(),
10842
+ acknowledgeSave: (revision) => saveRevision.acknowledge(revision),
10890
10843
  getSelectedElementIds() {
10891
10844
  return state.effectiveSelectedIds;
10892
10845
  },
@@ -12239,8 +12192,8 @@ function buildToolbarProps(input) {
12239
12192
  onAddActionButton: insertHandlers.handleAddActionButton,
12240
12193
  onInsertField: insertHandlers.handleInsertField,
12241
12194
  onOpenHeaderFooter,
12242
- onOpenImagePicker: () => s.imageInputRef.current?.click(),
12243
- onOpenMediaPicker: () => s.mediaInputRef.current?.click(),
12195
+ onOpenImagePicker: input.onOpenImagePicker ?? (() => s.imageInputRef.current?.click()),
12196
+ onOpenMediaPicker: input.onOpenMediaPicker ?? (() => s.mediaInputRef.current?.click()),
12244
12197
  onSetActiveTool: s.setActiveTool,
12245
12198
  onSetDrawingColor: s.setDrawingColor,
12246
12199
  onSetDrawingWidth: s.setDrawingWidth,
@@ -12388,9 +12341,8 @@ function buildToolbarProps(input) {
12388
12341
  activeSlide,
12389
12342
  onTransitionChange: handleTransitionChange,
12390
12343
  onApplyTransitionToAll: handleApplyTransitionToAll,
12391
- // No `onResetSlide` here: this building-blocks surface supplies no
12392
- // `onApplyLayout` either, so there is no layout to reset to. The mounted
12393
- // viewer (`ViewerToolbarSection`) wires both.
12344
+ onApplyLayout: input.onApplyLayout,
12345
+ onResetSlide: input.onResetSlide,
12394
12346
  onSelectAll: () => {
12395
12347
  const allIds = activeSlide?.elements.map((element) => element.id) ?? [];
12396
12348
  if (allIds.length > 0) {
@@ -12405,6 +12357,312 @@ function buildToolbarProps(input) {
12405
12357
  hiddenActions
12406
12358
  };
12407
12359
  }
12360
+ function useDialogFlagRequest(isOpen2, handle) {
12361
+ const handleRef = useRef(handle);
12362
+ handleRef.current = handle;
12363
+ useEffect(() => {
12364
+ if (isOpen2) {
12365
+ handleRef.current();
12366
+ }
12367
+ }, [isOpen2]);
12368
+ }
12369
+ function useFileDialogPorts(input) {
12370
+ const latest = useRef(input);
12371
+ latest.current = input;
12372
+ const { dialogs, request } = input;
12373
+ useDialogFlagRequest(dialogs.isPasswordDialogOpen, () => {
12374
+ dialogs.setIsPasswordDialogOpen(false);
12375
+ request({ kind: "passwordProtection" });
12376
+ });
12377
+ useDialogFlagRequest(dialogs.isDocPropsDialogOpen, () => {
12378
+ dialogs.setIsDocPropsDialogOpen(false);
12379
+ request({ kind: "documentProperties" });
12380
+ });
12381
+ useDialogFlagRequest(dialogs.isFontEmbeddingOpen, () => {
12382
+ dialogs.setIsFontEmbeddingOpen(false);
12383
+ request({ kind: "fontEmbedding" });
12384
+ });
12385
+ useDialogFlagRequest(dialogs.isDigitalSigDialogOpen, () => {
12386
+ dialogs.setIsDigitalSigDialogOpen(false);
12387
+ request({ kind: "digitalSignatures" });
12388
+ });
12389
+ const ports = useRef(null);
12390
+ ports.current ??= /* @__PURE__ */ (() => {
12391
+ const now = () => latest.current;
12392
+ const markDirty = () => now().history.markDirty();
12393
+ return {
12394
+ passwordProtection: {
12395
+ input: () => ({
12396
+ openPasswordSet: now().dialogs.isPasswordProtected,
12397
+ recommendation: now().recommendation,
12398
+ hasModifyVerifier: now().hasModifyVerifier,
12399
+ customProperties: now().state.customProperties
12400
+ }),
12401
+ customProperties: () => now().state.customProperties,
12402
+ applyOpenPassword: (password) => password === null ? now().dialogs.handleRemovePassword() : now().dialogs.handleSetPassword(password),
12403
+ applyCustomProperties: (next) => now().propertyHandlers.handleUpdateCustomProperties(next),
12404
+ markDirty
12405
+ },
12406
+ documentProperties: {
12407
+ current: () => ({
12408
+ core: now().state.coreProperties ?? {},
12409
+ custom: now().state.customProperties,
12410
+ app: now().state.appProperties ?? {}
12411
+ }),
12412
+ applyUpdate: (update) => {
12413
+ const handlers = now().propertyHandlers;
12414
+ if (update.core) {
12415
+ handlers.handleUpdateCoreProperties(update.core);
12416
+ }
12417
+ if (update.custom) {
12418
+ handlers.handleUpdateCustomProperties(update.custom);
12419
+ }
12420
+ if (update.app) {
12421
+ handlers.handleUpdateAppProperties(update.app);
12422
+ }
12423
+ }
12424
+ },
12425
+ fontEmbedding: {
12426
+ input: () => ({
12427
+ embedFonts: now().dialogs.embedFontsEnabled,
12428
+ embeddedFamilies: now().state.embeddedFonts.map((font) => font.name),
12429
+ usedFamilies: now().propertyHandlers.usedFontFamilies,
12430
+ descriptor: now().dialogs.fontEmbedding
12431
+ }),
12432
+ apply: (enabled) => now().dialogs.setEmbedFontsEnabled(enabled),
12433
+ markDirty
12434
+ },
12435
+ digitalSignatures: {
12436
+ signed: () => now().state.hasDigitalSignatures,
12437
+ count: () => now().state.digitalSignatureCount,
12438
+ content: () => now().content,
12439
+ markDirty
12440
+ }
12441
+ };
12442
+ })();
12443
+ return ports.current;
12444
+ }
12445
+
12446
+ // src/viewer/hooks/useViewerBuildingBlocks-find-layout-actions.ts
12447
+ function findReplacePort(findReplace) {
12448
+ return {
12449
+ open: findReplace.findReplaceOpen,
12450
+ setOpen: findReplace.setFindReplaceOpen,
12451
+ query: findReplace.findQuery,
12452
+ replacement: findReplace.replaceQuery,
12453
+ options: {
12454
+ matchCase: findReplace.findMatchCase,
12455
+ includeNotes: findReplace.findIncludeNotes,
12456
+ includeChartTitles: findReplace.findIncludeChartTitles,
12457
+ includeChartData: findReplace.findIncludeChartData
12458
+ },
12459
+ matches: findReplace.findResults,
12460
+ currentIndex: findReplace.findResultIndex,
12461
+ setQuery: findReplace.setFindQuery,
12462
+ setReplacement: findReplace.setReplaceQuery,
12463
+ setOptions: (change) => {
12464
+ if (change.matchCase !== void 0) {
12465
+ findReplace.setFindMatchCase(change.matchCase);
12466
+ }
12467
+ if (change.includeNotes !== void 0) {
12468
+ findReplace.setFindIncludeNotes(change.includeNotes);
12469
+ }
12470
+ if (change.includeChartTitles !== void 0) {
12471
+ findReplace.setFindIncludeChartTitles(change.includeChartTitles);
12472
+ }
12473
+ if (change.includeChartData !== void 0) {
12474
+ findReplace.setFindIncludeChartData(change.includeChartData);
12475
+ }
12476
+ },
12477
+ find: findReplace.performFind,
12478
+ navigate: (delta) => findReplace.navigateFindResult(delta),
12479
+ replaceCurrent: findReplace.handleReplace,
12480
+ replaceAll: findReplace.handleReplaceAll
12481
+ };
12482
+ }
12483
+ function useShowDialogPorts(input) {
12484
+ const { state, dialogs, presentation, session } = input;
12485
+ const { t } = useTranslation();
12486
+ const latest = useRef({ ...input, t });
12487
+ latest.current = { ...input, t };
12488
+ const showsRef = useRef(state.customShows);
12489
+ showsRef.current = state.customShows;
12490
+ const [startRequest, setStartRequest] = useState(0);
12491
+ useDialogFlagRequest(dialogs.isSetUpSlideShowOpen, () => {
12492
+ dialogs.setIsSetUpSlideShowOpen(false);
12493
+ session.request({ kind: "setUpSlideShow" });
12494
+ });
12495
+ useDialogFlagRequest(dialogs.isCustomShowsOpen, () => {
12496
+ dialogs.setIsCustomShowsOpen(false);
12497
+ session.request({ kind: "customShows" });
12498
+ });
12499
+ useDialogFlagRequest(
12500
+ dialogs.isBroadcastDialogOpen,
12501
+ () => dialogs.setIsBroadcastDialogOpen(false)
12502
+ );
12503
+ const shortcutsOpen = state.isShortcutHelpOpen;
12504
+ const firstShortcutsRender = useRef(true);
12505
+ useEffect(() => {
12506
+ if (firstShortcutsRender.current) {
12507
+ firstShortcutsRender.current = false;
12508
+ return;
12509
+ }
12510
+ session.announce({ kind: "shortcuts", open: shortcutsOpen }, shortcutsOpen);
12511
+ }, [shortcutsOpen, session]);
12512
+ useEffect(() => {
12513
+ if (startRequest > 0) {
12514
+ presentation.enterPresentModeFromBeginning();
12515
+ }
12516
+ }, [startRequest]);
12517
+ const ports = useRef(null);
12518
+ ports.current ??= /* @__PURE__ */ (() => {
12519
+ const now = () => latest.current;
12520
+ return {
12521
+ setUpSlideShow: {
12522
+ presentationProperties: () => now().state.presentationProperties,
12523
+ slideCount: () => now().slides.length,
12524
+ customShows: () => now().state.customShows,
12525
+ save: (settings) => now().dialogs.handleSaveSlideShowSettings(settings)
12526
+ },
12527
+ customShows: {
12528
+ customShows: () => showsRef.current,
12529
+ slides: () => now().slides,
12530
+ activeId: () => now().state.activeCustomShowId,
12531
+ commit: (shows, slides) => {
12532
+ showsRef.current = shows;
12533
+ now().dialogs.handleCommitCustomShows(shows, slides);
12534
+ },
12535
+ start: (id) => {
12536
+ now().state.setActiveCustomShowId(id);
12537
+ setStartRequest((count) => count + 1);
12538
+ }
12539
+ },
12540
+ shortcuts: {
12541
+ open: () => now().state.isShortcutHelpOpen,
12542
+ setOpen: (open) => now().state.setIsShortcutHelpOpen(open),
12543
+ toggle: () => now().state.setIsShortcutHelpOpen((open) => !open),
12544
+ translate: (key) => now().t(key)
12545
+ }
12546
+ };
12547
+ })();
12548
+ return ports.current;
12549
+ }
12550
+
12551
+ // src/viewer/hooks/useViewerBuildingBlocksActions.ts
12552
+ function useViewerBuildingBlocksActions(input) {
12553
+ const { state, dialogs, activeSlide, handlerRef } = input;
12554
+ const selectedElement = state.selectedElements[0] ?? null;
12555
+ const scopedLayouts = useMemo(
12556
+ () => scopeLayoutOptionsToActiveSlide(state.layoutOptions, activeSlide),
12557
+ [state.layoutOptions, activeSlide]
12558
+ );
12559
+ const layoutSwitching = useLayoutSwitching({
12560
+ handler: handlerRef.current,
12561
+ slides: input.slides,
12562
+ activeSlideIndex: input.activeSlideIndex,
12563
+ ops: input.editorOps.ops,
12564
+ history: input.history,
12565
+ onTemplateElementsChanged: (slideId, elements) => state.setTemplateElementsBySlideId((prev) => ({ ...prev, [slideId]: elements }))
12566
+ });
12567
+ const availabilityInput = {
12568
+ ready: !state.loading && !state.error,
12569
+ hasActiveSlide: Boolean(activeSlide),
12570
+ canEdit: input.canEdit,
12571
+ editing: input.mode === "edit",
12572
+ canInsert: input.canInsert,
12573
+ hasSelection: selectedElement !== null,
12574
+ selectionHasHyperlink: Boolean(selectedElement?.actionClick),
12575
+ selectionHasEquation: selectionEquation(selectedElement) !== null,
12576
+ layoutCount: scopedLayouts.length,
12577
+ hasCurrentLayout: resetSlideLayoutPath(activeSlide) !== void 0,
12578
+ hasHandler: handlerRef.current !== null
12579
+ };
12580
+ const next = { ...input, availabilityInput, scopedLayouts, layoutSwitching, selectedElement };
12581
+ const latest = useRef(next);
12582
+ latest.current = next;
12583
+ const sessionRef = useRef(null);
12584
+ sessionRef.current ??= createPptxBuildingBlockSession(createReactPort(latest));
12585
+ const session = sessionRef.current;
12586
+ useController(session.requests);
12587
+ const fileDialogPorts = useFileDialogPorts({
12588
+ state,
12589
+ dialogs,
12590
+ propertyHandlers: input.propertyHandlers,
12591
+ history: input.history,
12592
+ content: input.content,
12593
+ recommendation: input.readOnlyRecommendation,
12594
+ hasModifyVerifier: input.hasModifyVerifier,
12595
+ request: (request) => void session.request(request)
12596
+ });
12597
+ const showDialogPorts = useShowDialogPorts({
12598
+ state,
12599
+ dialogs,
12600
+ presentation: input.presentation,
12601
+ slides: input.slides,
12602
+ session
12603
+ });
12604
+ const registered = useRef(false);
12605
+ if (!registered.current) {
12606
+ registered.current = true;
12607
+ registerBuildingBlockGroups(session, { ...fileDialogPorts, ...showDialogPorts });
12608
+ }
12609
+ useDialogFlagRequest(dialogs.isHyperlinkDialogOpen, () => {
12610
+ dialogs.setIsHyperlinkDialogOpen(false);
12611
+ session.request({ kind: "hyperlink" });
12612
+ });
12613
+ useDialogFlagRequest(dialogs.isSmartArtDialogOpen, () => {
12614
+ dialogs.setIsSmartArtDialogOpen(false);
12615
+ session.request({ kind: "smartArt" });
12616
+ });
12617
+ useDialogFlagRequest(dialogs.isEquationDialogOpen, () => {
12618
+ const existingOmml = dialogs.editingEquationOmml;
12619
+ dialogs.setIsEquationDialogOpen(false);
12620
+ dialogs.setEditingEquationOmml(null);
12621
+ session.request({ kind: "equation", existingOmml });
12622
+ });
12623
+ useDialogFlagRequest(dialogs.isChartDialogOpen, () => {
12624
+ dialogs.setIsChartDialogOpen(false);
12625
+ session.request({ kind: "chart" });
12626
+ });
12627
+ return {
12628
+ actions: session.actions(),
12629
+ session,
12630
+ requestImagePicker: () => void session.request({ kind: "image" }),
12631
+ requestMediaPicker: () => void session.request({ kind: "media" }),
12632
+ applyLayout: (path) => void session.applyLayout(path),
12633
+ resetSlide: () => void session.resetSlide(),
12634
+ loadLayoutPreviews: layoutSwitching.loadLayoutPreviews
12635
+ };
12636
+ }
12637
+ function createReactPort(latest) {
12638
+ const insert = () => latest.current.editorOps.insertHandlers;
12639
+ return {
12640
+ availabilityInput: () => latest.current.availabilityInput,
12641
+ fileLimits: () => latest.current.fileLimits,
12642
+ onRequest: (request) => latest.current.onRequest?.(request),
12643
+ onCancel: () => latest.current.state.setIsShortcutHelpOpen(false),
12644
+ target: () => ({
12645
+ deck: latest.current.handlerRef.current,
12646
+ slideId: latest.current.activeSlide?.id,
12647
+ slideIndex: latest.current.activeSlideIndex
12648
+ }),
12649
+ canvasSize: () => latest.current.state.canvasSize,
12650
+ selectedElement: () => latest.current.selectedElement,
12651
+ slideCount: () => latest.current.slides.length,
12652
+ activeSlide: () => latest.current.activeSlide,
12653
+ scopedLayouts: () => latest.current.scopedLayouts,
12654
+ addElement: (element) => insert().addElement(element),
12655
+ insertMediaFile: (file, sameTarget) => insert().insertMediaFile(file, sameTarget),
12656
+ applyHyperlink: (data) => insert().applyHyperlink(data),
12657
+ removeHyperlink: () => insert().removeHyperlink(),
12658
+ insertSmartArt: (layout, items) => insert().handleInsertSmartArt(layout, items),
12659
+ insertChart: (kind, options) => insert().handleAddChart(kind, options),
12660
+ insertEquation: (omml) => insert().handleInsertEquation(omml),
12661
+ updateEquation: (omml) => insert().handleUpdateEquation(omml),
12662
+ findReplace: () => findReplacePort(latest.current.editorOps.findReplace),
12663
+ applyLayout: (path) => latest.current.layoutSwitching.applyLayout(path)
12664
+ };
12665
+ }
12408
12666
  function CollaborationCursorOverlay({
12409
12667
  collaboration,
12410
12668
  activeSlideIndex,
@@ -12669,7 +12927,10 @@ function useViewerBuildingBlocksCore(input) {
12669
12927
  canvasSize,
12670
12928
  selectedElements: state.selectedElements,
12671
12929
  fitPadding: input.fitPadding,
12672
- maxFitScale: input.maxFitScale
12930
+ maxFitScale: input.maxFitScale,
12931
+ // Nothing to select in a read-only view, so a plain drag pans instead.
12932
+ dragPans: mode === "preview",
12933
+ activeSlideId: activeSlide?.id
12673
12934
  });
12674
12935
  const { options: viewerOptions, optionsStore } = useViewerOptions();
12675
12936
  const { setIsDirty } = state;
@@ -12807,6 +13068,8 @@ function useReadOnlyRecommendationState(content) {
12807
13068
  recommendation,
12808
13069
  setRecommendation,
12809
13070
  setModifyVerifier,
13071
+ /** The deck's raw `p:modifyVerifier`, for reporting protection state. */
13072
+ modifyVerifier,
12810
13073
  /** Whether the viewer's `canEdit` should be forced off. */
12811
13074
  locked: readOnlyLocked(recommendation, session),
12812
13075
  bannerVisible: readOnlyBannerVisible(recommendation, session),
@@ -12987,6 +13250,7 @@ function useViewerBuildingBlocksState(input) {
12987
13250
  handlerRef: actionSoundHandlerRef,
12988
13251
  listConversionScope
12989
13252
  });
13253
+ const canInsertElement = !readOnlyRec.locked && !viewerOptions.trust.openInProtectedView;
12990
13254
  const {
12991
13255
  exportHandlers,
12992
13256
  printHandlers,
@@ -12995,7 +13259,8 @@ function useViewerBuildingBlocksState(input) {
12995
13259
  handleEnterPresenterView,
12996
13260
  handleEnterRehearsalMode,
12997
13261
  autosaveStatus,
12998
- loadVersion
13262
+ loadVersion,
13263
+ handlerRef: integrationHandlerRef
12999
13264
  } = useViewerIntegration({
13000
13265
  state,
13001
13266
  zoom,
@@ -13019,7 +13284,7 @@ function useViewerBuildingBlocksState(input) {
13019
13284
  allowExternalImages: resolveAllowExternalContent(allowExternalContent, viewerOptions),
13020
13285
  setReadOnlyRecommendation: readOnlyRec.setRecommendation,
13021
13286
  setModifyVerifier: readOnlyRec.setModifyVerifier,
13022
- canInsertElement: !readOnlyRec.locked && !viewerOptions.trust.openInProtectedView,
13287
+ canInsertElement,
13023
13288
  setCompatToasts: compatToastsState.setToasts,
13024
13289
  canEdit,
13025
13290
  promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
@@ -13056,6 +13321,10 @@ function useViewerBuildingBlocksState(input) {
13056
13321
  });
13057
13322
  return {
13058
13323
  loadVersion,
13324
+ canInsertElement,
13325
+ readOnlyRecommendation: readOnlyRec.recommendation,
13326
+ hasModifyVerifier: readOnlyRec.modifyVerifier !== void 0,
13327
+ handlerRef: integrationHandlerRef,
13059
13328
  dialogs,
13060
13329
  editorOps,
13061
13330
  exportHandlers,
@@ -13156,6 +13425,10 @@ function useViewerBuildingBlocks(input) {
13156
13425
  const {
13157
13426
  dialogs,
13158
13427
  loadVersion,
13428
+ canInsertElement,
13429
+ readOnlyRecommendation: readOnlyRecommendation3,
13430
+ hasModifyVerifier,
13431
+ handlerRef,
13159
13432
  editorOps,
13160
13433
  exportHandlers,
13161
13434
  printHandlers,
@@ -13196,6 +13469,26 @@ function useViewerBuildingBlocks(input) {
13196
13469
  embedFonts: dialogs.embedFontsEnabled,
13197
13470
  onReadOnlyChange: setCollaborationReadOnly
13198
13471
  });
13472
+ const blockActions = useViewerBuildingBlocksActions({
13473
+ state,
13474
+ canEdit,
13475
+ canInsert: canInsertElement,
13476
+ mode,
13477
+ slides,
13478
+ activeSlide,
13479
+ activeSlideIndex,
13480
+ dialogs,
13481
+ editorOps,
13482
+ history,
13483
+ handlerRef,
13484
+ propertyHandlers,
13485
+ content,
13486
+ readOnlyRecommendation: readOnlyRecommendation3,
13487
+ hasModifyVerifier,
13488
+ presentation,
13489
+ onRequest: input.onRequest,
13490
+ fileLimits: input.fileLimits
13491
+ });
13199
13492
  const toolbarProps = buildToolbarProps({
13200
13493
  mode,
13201
13494
  canEdit,
@@ -13224,7 +13517,12 @@ function useViewerBuildingBlocks(input) {
13224
13517
  onOpenRecentFile,
13225
13518
  fileName,
13226
13519
  hiddenActions,
13227
- viewPreferencesSync
13520
+ viewPreferencesSync,
13521
+ onOpenImagePicker: blockActions.requestImagePicker,
13522
+ onOpenMediaPicker: blockActions.requestMediaPicker,
13523
+ onApplyLayout: blockActions.applyLayout,
13524
+ onResetSlide: blockActions.resetSlide,
13525
+ loadLayoutPreviews: blockActions.loadLayoutPreviews
13228
13526
  });
13229
13527
  const canvasProps = buildCanvasProps({
13230
13528
  mode,
@@ -13249,6 +13547,7 @@ function useViewerBuildingBlocks(input) {
13249
13547
  t
13250
13548
  });
13251
13549
  canvasProps.collaborationOverlay = overlay;
13550
+ canvasProps.onElementRenderError = input.onElementRenderError;
13252
13551
  const slidesPaneProps = useSlidesPaneProps({
13253
13552
  state,
13254
13553
  slides,
@@ -13260,15 +13559,29 @@ function useViewerBuildingBlocks(input) {
13260
13559
  recordedTimings: presentation.recordedTimings,
13261
13560
  onOpenLayoutGallery
13262
13561
  });
13263
- const shellState = useMemo(
13264
- () => resolveCollaborationShellState({
13265
- authorizedCanEdit: requestedCanEdit,
13266
- configured: Boolean(collaborationConfig),
13267
- readOnly: collaborationReadOnly,
13268
- sourcePending: Boolean(content) && loading,
13269
- sourceError: Boolean(error),
13270
- status: collaboration?.status ?? "disconnected",
13271
- remoteUsers: collaboration?.remoteUsers ?? []
13562
+ slidesPaneProps.onElementRenderError = input.onElementRenderError;
13563
+ const { shellState, collaborationState } = useMemo(
13564
+ () => describeBuildingBlockShell({
13565
+ shell: {
13566
+ authorizedCanEdit: requestedCanEdit,
13567
+ configured: Boolean(collaborationConfig),
13568
+ readOnly: collaborationReadOnly,
13569
+ sourcePending: Boolean(content) && loading,
13570
+ sourceError: Boolean(error),
13571
+ status: collaboration?.status ?? "disconnected",
13572
+ remoteUsers: collaboration?.remoteUsers ?? []
13573
+ },
13574
+ collaboration: {
13575
+ active: Boolean(collaboration?.config),
13576
+ roomId: collaboration?.config.roomId,
13577
+ status: collaboration?.status ?? "disconnected",
13578
+ synced: collaboration?.synced ?? false,
13579
+ clientId: collaboration?.clientId,
13580
+ userName: collaboration?.config.userName,
13581
+ userColor: collaboration?.config.userColor,
13582
+ remoteUsers: collaboration?.remoteUsers ?? [],
13583
+ writeBack: writeBackReport(collaboration?.config, collaboration?.writeBack)
13584
+ }
13272
13585
  }),
13273
13586
  [
13274
13587
  requestedCanEdit,
@@ -13278,19 +13591,27 @@ function useViewerBuildingBlocks(input) {
13278
13591
  loading,
13279
13592
  error,
13280
13593
  collaboration?.status,
13281
- collaboration?.remoteUsers
13594
+ collaboration?.remoteUsers,
13595
+ collaboration?.config,
13596
+ collaboration?.synced,
13597
+ collaboration?.clientId,
13598
+ collaboration?.writeBack
13282
13599
  ]
13283
13600
  );
13284
13601
  return {
13285
13602
  toolbarProps,
13286
13603
  canvasProps,
13287
13604
  slidesPaneProps,
13288
- mode,
13605
+ // The effective mode: `preview` while the blocks may not edit, as in every binding.
13606
+ mode: resolveBuildingBlockMode(mode, canEdit),
13289
13607
  loading,
13290
13608
  error,
13291
13609
  autosaveStatus,
13292
13610
  collaboration,
13293
- shellState
13611
+ shellState,
13612
+ collaborationState,
13613
+ // Read last, so action groups registered by the hooks above are included.
13614
+ actions: blockActions.session.actions()
13294
13615
  };
13295
13616
  }
13296
13617
  function ColorChangedImage({
@@ -13600,6 +13921,65 @@ function withDisplayName(component, displayName) {
13600
13921
  component.displayName = displayName;
13601
13922
  return component;
13602
13923
  }
13924
+ var ElementRenderErrorReportingContext = createContext(
13925
+ void 0
13926
+ );
13927
+ var ElementErrorBoundaryState = class extends React18.Component {
13928
+ state = { element: this.props.element, failed: false };
13929
+ static getDerivedStateFromProps(props, state) {
13930
+ return props.element !== state.element ? { element: props.element, failed: false } : null;
13931
+ }
13932
+ static getDerivedStateFromError() {
13933
+ return { failed: true };
13934
+ }
13935
+ componentDidCatch(error) {
13936
+ const { element, slideId, onElementRenderError } = this.props;
13937
+ reportElementRenderError(
13938
+ onElementRenderError,
13939
+ error,
13940
+ elementRenderErrorContext(element, slideId)
13941
+ );
13942
+ }
13943
+ render() {
13944
+ return this.state.failed ? null : this.props.children;
13945
+ }
13946
+ };
13947
+ function ElementRenderErrorScope({
13948
+ onElementRenderError,
13949
+ children
13950
+ }) {
13951
+ const inherited = useContext(ElementRenderErrorReportingContext);
13952
+ const reporter = onElementRenderError ?? inherited?.onElementRenderError;
13953
+ const scope = useMemo(
13954
+ () => ({ slideId: inherited?.slideId, onElementRenderError: reporter }),
13955
+ [inherited?.slideId, reporter]
13956
+ );
13957
+ return /* @__PURE__ */ jsx(ElementRenderErrorReportingContext.Provider, { value: scope, children });
13958
+ }
13959
+ function ElementErrorBoundary({
13960
+ element,
13961
+ slideId,
13962
+ onElementRenderError,
13963
+ children
13964
+ }) {
13965
+ const inherited = useContext(ElementRenderErrorReportingContext);
13966
+ const effectiveSlideId = slideId ?? inherited?.slideId;
13967
+ const reporter = onElementRenderError ?? inherited?.onElementRenderError;
13968
+ const scope = useMemo(
13969
+ () => ({ slideId: effectiveSlideId, onElementRenderError: reporter }),
13970
+ [effectiveSlideId, reporter]
13971
+ );
13972
+ return /* @__PURE__ */ jsx(ElementRenderErrorReportingContext.Provider, { value: scope, children: /* @__PURE__ */ jsx(
13973
+ ElementErrorBoundaryState,
13974
+ {
13975
+ element,
13976
+ slideId: effectiveSlideId,
13977
+ onElementRenderError: reporter,
13978
+ children
13979
+ },
13980
+ element.id
13981
+ ) });
13982
+ }
13603
13983
  var ChartFormatContext = /* @__PURE__ */ createContext(null);
13604
13984
  function useChartFormatContext() {
13605
13985
  return useContext(ChartFormatContext);
@@ -14421,7 +14801,7 @@ function ResizeHandles({
14421
14801
  ))
14422
14802
  ] });
14423
14803
  }
14424
- var ConnectorElementRendererMemo = /* @__PURE__ */ React17.memo(
14804
+ var ConnectorElementRendererMemo = /* @__PURE__ */ React18.memo(
14425
14805
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the memo component its displayName
14426
14806
  function ConnectorElementRendererInner({
14427
14807
  el,
@@ -14835,7 +15215,7 @@ function shapeParams(element) {
14835
15215
  const hasFill = style?.fillColor !== void 0 && style.fillColor !== "transparent" || Boolean(buildCssGradientFromShapeStyle(style) || style?.fillGradient) || style?.fillMode === "pattern" && Boolean(style.fillPatternPreset);
14836
15216
  return { hf: hasFill, fc: fillColor, sw: strokeWidth, sc: strokeColor };
14837
15217
  }
14838
- var Extrusion3DOverlayMemo = /* @__PURE__ */ React17.memo(
15218
+ var Extrusion3DOverlayMemo = /* @__PURE__ */ React18.memo(
14839
15219
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the memo component its displayName
14840
15220
  function Extrusion3DOverlayInner({ data }) {
14841
15221
  if (!data.hasExtrusion || data.panels.length === 0) {
@@ -15106,9 +15486,24 @@ function ShapeEffectOverlay({
15106
15486
  ) : null
15107
15487
  ] });
15108
15488
  }
15109
- var ElementRenderer = /* @__PURE__ */ React17.memo(
15489
+ var ElementRenderer = /* @__PURE__ */ React18.memo(
15110
15490
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the memo component its displayName
15111
- function ElementRendererInner({
15491
+ function ElementRendererInner(props) {
15492
+ return /* @__PURE__ */ jsx(
15493
+ ElementErrorBoundary,
15494
+ {
15495
+ element: props.element,
15496
+ slideId: props.activeSlide?.id,
15497
+ onElementRenderError: props.onElementRenderError,
15498
+ children: /* @__PURE__ */ jsx(ElementRendererImpl, { ...props })
15499
+ },
15500
+ props.element.id
15501
+ );
15502
+ }
15503
+ );
15504
+ var ElementRendererImpl = /* @__PURE__ */ React18.memo(
15505
+ // oxlint-disable-next-line prefer-arrow-callback -- keep the implementation named in React stacks
15506
+ function ElementRendererImpl2({
15112
15507
  element: el,
15113
15508
  activeSlide,
15114
15509
  isSelected,
@@ -15152,6 +15547,7 @@ var ElementRenderer = /* @__PURE__ */ React17.memo(
15152
15547
  fieldContext,
15153
15548
  tableStyleContext
15154
15549
  }) {
15550
+ probeElementRenderFault(el);
15155
15551
  const {
15156
15552
  cellSelectHandler,
15157
15553
  cellCommitHandler,
@@ -16170,18 +16566,7 @@ function InlineTextEditor({
16170
16566
  list.seed?.paragraphs[0].token ?? "plain"
16171
16567
  );
16172
16568
  }
16173
- function FailedToLoad() {
16174
- return null;
16175
- }
16176
- var LazyModel3DScene = /* @__PURE__ */ React17.lazy(
16177
- async () => {
16178
- try {
16179
- return await import('./Model3DScene-NUJH2UKM.mjs');
16180
- } catch {
16181
- return { default: FailedToLoad };
16182
- }
16183
- }
16184
- );
16569
+ var LazyModel3DScene = /* @__PURE__ */ React18.lazy(() => import('./Model3DScene-NUJH2UKM.mjs'));
16185
16570
  function dataUrlToBlobUrl(dataUrl, mimeType) {
16186
16571
  return modelDataToBlobUrl(dataUrl, mimeType);
16187
16572
  }
@@ -16238,21 +16623,6 @@ function PosterFallback({
16238
16623
  }
16239
16624
  );
16240
16625
  }
16241
- var Model3DErrorBoundary = class extends React17.Component {
16242
- constructor(props) {
16243
- super(props);
16244
- this.state = { hasError: false };
16245
- }
16246
- static getDerivedStateFromError() {
16247
- return { hasError: true };
16248
- }
16249
- render() {
16250
- if (this.state.hasError) {
16251
- return this.props.fallback;
16252
- }
16253
- return this.props.children;
16254
- }
16255
- };
16256
16626
  function Model3DRenderer({ element, width, height, interactive }) {
16257
16627
  const [threeAvailable, setThreeAvailable] = useState(null);
16258
16628
  useEffect(() => {
@@ -16289,7 +16659,7 @@ function Model3DRenderer({ element, width, height, interactive }) {
16289
16659
  if (!threeAvailable || !blobUrl) {
16290
16660
  return posterFallback;
16291
16661
  }
16292
- return /* @__PURE__ */ jsx(Model3DErrorBoundary, { fallback: posterFallback, children: /* @__PURE__ */ jsx(Suspense, { fallback: posterFallback, children: /* @__PURE__ */ jsx(
16662
+ return /* @__PURE__ */ jsx(Suspense, { fallback: posterFallback, children: /* @__PURE__ */ jsx(
16293
16663
  LazyModel3DScene,
16294
16664
  {
16295
16665
  modelUrl: blobUrl,
@@ -16298,7 +16668,7 @@ function Model3DRenderer({ element, width, height, interactive }) {
16298
16668
  height,
16299
16669
  scene: element.scene
16300
16670
  }
16301
- ) }) });
16671
+ ) });
16302
16672
  }
16303
16673
  function buildEmbedInfo(el) {
16304
16674
  const canDownload = Boolean(el.oleEmbeddedData);
@@ -16440,10 +16810,10 @@ function SmartArtInlineNodeEditor({
16440
16810
  onCancel
16441
16811
  }) {
16442
16812
  const { t } = useTranslation();
16443
- const ref = React17.useRef(null);
16444
- const [value, setValue] = React17.useState(initialText);
16445
- const settled = React17.useRef(false);
16446
- React17.useEffect(() => {
16813
+ const ref = React18.useRef(null);
16814
+ const [value, setValue] = React18.useState(initialText);
16815
+ const settled = React18.useRef(false);
16816
+ React18.useEffect(() => {
16447
16817
  const el = ref.current;
16448
16818
  if (el) {
16449
16819
  el.focus();
@@ -16539,16 +16909,16 @@ function findNodeFromMouseEvent(e, host) {
16539
16909
  return (host ? smartArtNodeAtPoint(host, e.clientX, e.clientY) : null) ?? findNodeIdFromEvent(e.target);
16540
16910
  }
16541
16911
  function useSmartArtHoverState(containerRef, measureNodeRect = measureScreenNodeRect) {
16542
- const [hoveredNodeId, setHoveredNodeId] = React17.useState(null);
16543
- const [hoveredNodeRect, setHoveredNodeRect] = React17.useState(null);
16544
- const hideTimeoutRef = React17.useRef(null);
16545
- const cancelPendingHide = React17.useCallback(() => {
16912
+ const [hoveredNodeId, setHoveredNodeId] = React18.useState(null);
16913
+ const [hoveredNodeRect, setHoveredNodeRect] = React18.useState(null);
16914
+ const hideTimeoutRef = React18.useRef(null);
16915
+ const cancelPendingHide = React18.useCallback(() => {
16546
16916
  if (hideTimeoutRef.current !== null) {
16547
16917
  window.clearTimeout(hideTimeoutRef.current);
16548
16918
  hideTimeoutRef.current = null;
16549
16919
  }
16550
16920
  }, []);
16551
- const handleMouseMove = React17.useCallback(
16921
+ const handleMouseMove = React18.useCallback(
16552
16922
  (e, ignoreRef) => {
16553
16923
  const nodeEl = findNodeFromMouseEvent(e, containerRef.current);
16554
16924
  const container = containerRef.current;
@@ -16571,12 +16941,12 @@ function useSmartArtHoverState(containerRef, measureNodeRect = measureScreenNode
16571
16941
  },
16572
16942
  [containerRef, cancelPendingHide, measureNodeRect]
16573
16943
  );
16574
- const clearHover = React17.useCallback(() => {
16944
+ const clearHover = React18.useCallback(() => {
16575
16945
  cancelPendingHide();
16576
16946
  setHoveredNodeId(null);
16577
16947
  setHoveredNodeRect(null);
16578
16948
  }, [cancelPendingHide]);
16579
- React17.useEffect(() => cancelPendingHide, [cancelPendingHide]);
16949
+ React18.useEffect(() => cancelPendingHide, [cancelPendingHide]);
16580
16950
  return { hoveredNodeId, hoveredNodeRect, handleMouseMove, clearHover };
16581
16951
  }
16582
16952
  var EDITOR_PADDING = 4;
@@ -16592,14 +16962,14 @@ function SmartArtEditableLayer({
16592
16962
  measureNodeRect = measureScreenNodeRect,
16593
16963
  children
16594
16964
  }) {
16595
- const containerRef = React17.useRef(null);
16596
- const styleBarRef = React17.useRef(null);
16597
- const [edit, setEdit] = React17.useState(null);
16965
+ const containerRef = React18.useRef(null);
16966
+ const styleBarRef = React18.useRef(null);
16967
+ const [edit, setEdit] = React18.useState(null);
16598
16968
  const { hoveredNodeId, hoveredNodeRect, handleMouseMove, clearHover } = useSmartArtHoverState(
16599
16969
  containerRef,
16600
16970
  measureNodeRect
16601
16971
  );
16602
- const openEditor = React17.useCallback(
16972
+ const openEditor = React18.useCallback(
16603
16973
  (nodeEl) => {
16604
16974
  const container = containerRef.current;
16605
16975
  if (!nodeEl || !container) {
@@ -17229,7 +17599,7 @@ function sameDiagramReveal(prev, next) {
17229
17599
  }
17230
17600
  return true;
17231
17601
  }
17232
- var SmartArtRenderer = /* @__PURE__ */ React17.memo(SmartArtRendererImpl, arePropsEqual);
17602
+ var SmartArtRenderer = /* @__PURE__ */ React18.memo(SmartArtRendererImpl, arePropsEqual);
17233
17603
  function SmartArt3DView({
17234
17604
  element,
17235
17605
  className,
@@ -17378,7 +17748,7 @@ function EnvelopeGlyph({
17378
17748
  }
17379
17749
  return /* @__PURE__ */ jsx("g", { "data-glyph-slices": glyph.slices.length, children: glyph.slices.map((slice, si) => {
17380
17750
  const clipId = `${glyphKey}-s${si}`;
17381
- return /* @__PURE__ */ jsxs(React17.Fragment, { children: [
17751
+ return /* @__PURE__ */ jsxs(React18.Fragment, { children: [
17382
17752
  /* @__PURE__ */ jsx("clipPath", { id: clipId, clipPathUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
17383
17753
  "rect",
17384
17754
  {
@@ -17585,7 +17955,7 @@ function renderEquationBox(el, interactive) {
17585
17955
  }
17586
17956
  );
17587
17957
  if (!segment.equationNumber) {
17588
- return [/* @__PURE__ */ jsx(React17.Fragment, { children: math }, `${el.id}-eq-${index}`)];
17958
+ return [/* @__PURE__ */ jsx(React18.Fragment, { children: math }, `${el.id}-eq-${index}`)];
17589
17959
  }
17590
17960
  const label = `(${segment.equationNumber})`;
17591
17961
  return [
@@ -18230,6 +18600,7 @@ function StaticElementRendererImpl({
18230
18600
  exposeElementId = false,
18231
18601
  suppressReflection = false
18232
18602
  }) {
18603
+ probeElementRenderFault(element);
18233
18604
  if (!isElementRendered(element)) {
18234
18605
  return null;
18235
18606
  }
@@ -18372,13 +18743,28 @@ function StaticElementRendererImpl({
18372
18743
  );
18373
18744
  }
18374
18745
  var StaticElementRenderer = /* @__PURE__ */ withDisplayName(
18375
- /* @__PURE__ */ React17.memo(StaticElementRendererImpl),
18746
+ /* @__PURE__ */ React18.memo(
18747
+ // oxlint-disable-next-line prefer-arrow-callback -- keep the wrapper named in React stacks
18748
+ function StaticElementRendererBoundary(props) {
18749
+ return /* @__PURE__ */ jsx(
18750
+ ElementErrorBoundary,
18751
+ {
18752
+ element: props.element,
18753
+ slideId: props.activeSlide?.id,
18754
+ onElementRenderError: props.onElementRenderError,
18755
+ children: /* @__PURE__ */ jsx(StaticElementRendererImpl, { ...props })
18756
+ },
18757
+ props.element.id
18758
+ );
18759
+ }
18760
+ ),
18376
18761
  "StaticElementRenderer"
18377
18762
  );
18378
18763
  function SlideLayer({
18379
18764
  slide,
18380
18765
  templateElements,
18381
- canvasSize
18766
+ canvasSize,
18767
+ onElementRenderError
18382
18768
  }) {
18383
18769
  const safeWidth = Math.max(canvasSize.width, 1);
18384
18770
  const safeHeight = Math.max(canvasSize.height, 1);
@@ -18403,7 +18789,8 @@ function SlideLayer({
18403
18789
  element,
18404
18790
  activeSlide: slide,
18405
18791
  allSlides: [slide],
18406
- zIndex: index
18792
+ zIndex: index,
18793
+ onElementRenderError
18407
18794
  },
18408
18795
  element.id
18409
18796
  ))
@@ -18418,7 +18805,8 @@ function FragmentedTransitionLayer({
18418
18805
  canvasSize,
18419
18806
  scale,
18420
18807
  zIndex,
18421
- layerName
18808
+ layerName,
18809
+ onElementRenderError
18422
18810
  }) {
18423
18811
  return /* @__PURE__ */ jsx(
18424
18812
  "div",
@@ -18454,7 +18842,15 @@ function FragmentedTransitionLayer({
18454
18842
  transformOrigin: "center",
18455
18843
  ...deviceStrokeStageStyle(scale)
18456
18844
  },
18457
- children: /* @__PURE__ */ jsx(SlideLayer, { slide, templateElements, canvasSize })
18845
+ children: /* @__PURE__ */ jsx(
18846
+ SlideLayer,
18847
+ {
18848
+ slide,
18849
+ templateElements,
18850
+ canvasSize,
18851
+ onElementRenderError
18852
+ }
18853
+ )
18458
18854
  }
18459
18855
  )
18460
18856
  },
@@ -18473,7 +18869,8 @@ function MorphTransitionOverlay({
18473
18869
  morphPlan,
18474
18870
  outgoingSlide,
18475
18871
  incomingSlide,
18476
- containerRef
18872
+ containerRef,
18873
+ onElementRenderError
18477
18874
  }) {
18478
18875
  const groupSlots = morphOverlayElementSlots(morphPlan).groups;
18479
18876
  return /* @__PURE__ */ jsxs(
@@ -18521,6 +18918,7 @@ function MorphTransitionOverlay({
18521
18918
  StaticElementRenderer,
18522
18919
  {
18523
18920
  element,
18921
+ onElementRenderError,
18524
18922
  activeSlide: outgoingSlide,
18525
18923
  allSlides: [outgoingSlide],
18526
18924
  zIndex,
@@ -18539,6 +18937,7 @@ function MorphTransitionOverlay({
18539
18937
  StaticElementRenderer,
18540
18938
  {
18541
18939
  element,
18940
+ onElementRenderError,
18542
18941
  activeSlide: incomingSlide,
18543
18942
  allSlides: [incomingSlide],
18544
18943
  zIndex,
@@ -18567,6 +18966,7 @@ function MorphTransitionOverlay({
18567
18966
  StaticElementRenderer,
18568
18967
  {
18569
18968
  element: group.outgoing,
18969
+ onElementRenderError,
18570
18970
  activeSlide: outgoingSlide,
18571
18971
  allSlides: [outgoingSlide],
18572
18972
  zIndex: 0,
@@ -18585,6 +18985,7 @@ function MorphTransitionOverlay({
18585
18985
  StaticElementRenderer,
18586
18986
  {
18587
18987
  element: group.incoming,
18988
+ onElementRenderError,
18588
18989
  activeSlide: incomingSlide,
18589
18990
  allSlides: [incomingSlide],
18590
18991
  zIndex: 0,
@@ -18604,7 +19005,13 @@ function MorphTransitionOverlay({
18604
19005
  }
18605
19006
  );
18606
19007
  }
18607
- function PresentationTransitionOverlay({
19008
+ function PresentationTransitionOverlay(props) {
19009
+ const inherited = React18.useContext(ElementRenderErrorReportingContext);
19010
+ const reporter = props.onElementRenderError ?? inherited?.onElementRenderError;
19011
+ const errorReporting = useMemo(() => ({ onElementRenderError: reporter }), [reporter]);
19012
+ return /* @__PURE__ */ jsx(ElementRenderErrorReportingContext.Provider, { value: errorReporting, children: /* @__PURE__ */ jsx(PresentationTransitionOverlayContent, { ...props }) });
19013
+ }
19014
+ function PresentationTransitionOverlayContent({
18608
19015
  outgoingSlide,
18609
19016
  templateElements,
18610
19017
  canvasSize,
@@ -18861,4 +19268,4 @@ function useResizablePanels() {
18861
19268
  };
18862
19269
  }
18863
19270
 
18864
- export { ACTION_VERB_MAP, ChartFormatContext, ChartPartSelectionProvider, CollaborationCursorOverlay, CollaborationProvider, ElementRenderer, FragmentedTransitionLayer, InlineCollaborationContext, MIN_TOUCH_TARGET, MorphTransitionOverlay, PresentationTransitionOverlay, RemoteSelectionOverlay, RemoteUserCursors, Rendering3DFlagsContext, ResizeHandles, SlideBackgroundImageLayer, SlideLayer, StaticElementRenderer, ViewerOptionsContext, ViewerOptionsStoreContext, computeToolbarVisibility, createReviewCommentsHost, detectTargetType, imgSrc, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, playAnimationSound, renderStrokeView, renderToCanvas, resolveSmartArtDataPalette, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useChartFormatContext, useChartPartSelection, useClearSelectionOnSlideChange, useClipboardHandlers, useCollaboration, useCollaborationDocumentSync, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, useContentLifecycle, useController, 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, useReportOnChange, 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, withDisplayName };
19271
+ export { ChartFormatContext, ChartPartSelectionProvider, CollaborationCursorOverlay, CollaborationProvider, ElementRenderErrorReportingContext, ElementRenderErrorScope, ElementRenderer, FragmentedTransitionLayer, InlineCollaborationContext, MIN_TOUCH_TARGET, MorphTransitionOverlay, PresentationTransitionOverlay, RemoteSelectionOverlay, RemoteUserCursors, Rendering3DFlagsContext, ResizeHandles, SlideBackgroundImageLayer, SlideLayer, StaticElementRenderer, ViewerOptionsContext, ViewerOptionsStoreContext, computeToolbarVisibility, createReviewCommentsHost, imgSrc, isAudienceTab, parseAudienceNonce, playAnimationSound, renderStrokeView, renderToCanvas, resolveSmartArtDataPalette, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useChartFormatContext, useChartPartSelection, useClearSelectionOnSlideChange, useClipboardHandlers, useCollaboration, useCollaborationDocumentSync, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, useContentLifecycle, useController, 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, useReportOnChange, 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, withDisplayName };