pptx-react-viewer 4.4.0 → 4.6.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 (136) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +34 -33
  3. package/dist/{AiChatPanel-UFMSTNCB.js → AiChatPanel-3C7GM6ZF.js} +28 -28
  4. package/dist/AiChatPanel-3C7GM6ZF.js.br +0 -0
  5. package/dist/AiChatPanel-3C7GM6ZF.js.gz +0 -0
  6. package/dist/{AiChatPanel-QJHUDIWT.mjs → AiChatPanel-L7DBCWE3.mjs} +4 -4
  7. package/dist/AiChatPanel-L7DBCWE3.mjs.br +0 -0
  8. package/dist/AiChatPanel-L7DBCWE3.mjs.gz +0 -0
  9. package/dist/{Model3DScene-3GOC5HUS.mjs → Model3DScene-IJ7YYTYU.mjs} +1 -1
  10. package/dist/Model3DScene-IJ7YYTYU.mjs.br +0 -0
  11. package/dist/Model3DScene-IJ7YYTYU.mjs.gz +0 -0
  12. package/dist/{Model3DScene-KXNJBAQD.js → Model3DScene-USKNPWWH.js} +2 -2
  13. package/dist/{Model3DScene-KXNJBAQD.js.br → Model3DScene-USKNPWWH.js.br} +0 -0
  14. package/dist/Model3DScene-USKNPWWH.js.gz +0 -0
  15. package/dist/{chunk-I4D6JQOI.js → chunk-3JUZOKFI.js} +13 -0
  16. package/dist/chunk-3JUZOKFI.js.br +0 -0
  17. package/dist/chunk-3JUZOKFI.js.gz +0 -0
  18. package/dist/{chunk-CSY422LU.js → chunk-5V5SMT5A.js} +5 -5
  19. package/dist/chunk-5V5SMT5A.js.br +0 -0
  20. package/dist/chunk-5V5SMT5A.js.gz +0 -0
  21. package/dist/{chunk-AI6K5EAE.js → chunk-DFSWCVRW.js} +1677 -1207
  22. package/dist/chunk-DFSWCVRW.js.br +0 -0
  23. package/dist/chunk-DFSWCVRW.js.gz +0 -0
  24. package/dist/{chunk-7WWINBGF.js → chunk-FZSYLXJT.js} +3293 -1568
  25. package/dist/chunk-FZSYLXJT.js.br +0 -0
  26. package/dist/chunk-FZSYLXJT.js.gz +0 -0
  27. package/dist/{chunk-YJKR7Z3X.js → chunk-IBHIXBC5.js} +885 -845
  28. package/dist/chunk-IBHIXBC5.js.br +0 -0
  29. package/dist/chunk-IBHIXBC5.js.gz +0 -0
  30. package/dist/{chunk-D3TZOCQP.mjs → chunk-ICEZL4TM.mjs} +3260 -1568
  31. package/dist/chunk-ICEZL4TM.mjs.br +0 -0
  32. package/dist/chunk-ICEZL4TM.mjs.gz +0 -0
  33. package/dist/{chunk-WCHKDZP6.mjs → chunk-INX3E37P.mjs} +73 -33
  34. package/dist/chunk-INX3E37P.mjs.br +0 -0
  35. package/dist/chunk-INX3E37P.mjs.gz +0 -0
  36. package/dist/{chunk-WNFHFFYE.mjs → chunk-K6QHGABT.mjs} +17 -7
  37. package/dist/chunk-K6QHGABT.mjs.br +0 -0
  38. package/dist/chunk-K6QHGABT.mjs.gz +0 -0
  39. package/dist/{chunk-JQXN6PO7.mjs → chunk-OOO4JL2N.mjs} +13 -0
  40. package/dist/chunk-OOO4JL2N.mjs.br +0 -0
  41. package/dist/chunk-OOO4JL2N.mjs.gz +0 -0
  42. package/dist/{chunk-XMKLY2SE.mjs → chunk-VCAQSSGD.mjs} +1 -1
  43. package/dist/chunk-VCAQSSGD.mjs.br +0 -0
  44. package/dist/chunk-VCAQSSGD.mjs.gz +0 -0
  45. package/dist/{chunk-OWTHF5N4.js → chunk-Y4QUVWZC.js} +201 -191
  46. package/dist/chunk-Y4QUVWZC.js.br +0 -0
  47. package/dist/chunk-Y4QUVWZC.js.gz +0 -0
  48. package/dist/{chunk-LUHUYBGW.mjs → chunk-ZAQFTO4P.mjs} +623 -153
  49. package/dist/chunk-ZAQFTO4P.mjs.br +0 -0
  50. package/dist/chunk-ZAQFTO4P.mjs.gz +0 -0
  51. package/dist/i18n/de.cjs +11 -0
  52. package/dist/i18n/de.cjs.br +0 -0
  53. package/dist/i18n/de.cjs.gz +0 -0
  54. package/dist/i18n/de.mjs +11 -0
  55. package/dist/i18n/de.mjs.br +0 -0
  56. package/dist/i18n/de.mjs.gz +0 -0
  57. package/dist/i18n/es.cjs +11 -0
  58. package/dist/i18n/es.cjs.br +0 -0
  59. package/dist/i18n/es.cjs.gz +0 -0
  60. package/dist/i18n/es.mjs +11 -0
  61. package/dist/i18n/es.mjs.br +0 -0
  62. package/dist/i18n/es.mjs.gz +0 -0
  63. package/dist/i18n/fr.cjs +11 -0
  64. package/dist/i18n/fr.cjs.br +0 -0
  65. package/dist/i18n/fr.cjs.gz +0 -0
  66. package/dist/i18n/fr.mjs +11 -0
  67. package/dist/i18n/fr.mjs.br +0 -0
  68. package/dist/i18n/fr.mjs.gz +0 -0
  69. package/dist/i18n/zh-CN.cjs +11 -0
  70. package/dist/i18n/zh-CN.cjs.br +0 -0
  71. package/dist/i18n/zh-CN.cjs.gz +0 -0
  72. package/dist/i18n/zh-CN.mjs +11 -0
  73. package/dist/i18n/zh-CN.mjs.br +0 -0
  74. package/dist/i18n/zh-CN.mjs.gz +0 -0
  75. package/dist/i18n.js +4 -4
  76. package/dist/i18n.js.br +0 -0
  77. package/dist/i18n.js.gz +0 -0
  78. package/dist/i18n.mjs +1 -1
  79. package/dist/i18n.mjs.br +0 -0
  80. package/dist/i18n.mjs.gz +0 -0
  81. package/dist/index.d.ts +311 -4
  82. package/dist/index.js +105 -49
  83. package/dist/index.js.br +0 -0
  84. package/dist/index.js.gz +0 -0
  85. package/dist/index.mjs +6 -6
  86. package/dist/index.mjs.br +0 -0
  87. package/dist/index.mjs.gz +0 -0
  88. package/dist/internals.d.ts +328 -3
  89. package/dist/internals.js +105 -105
  90. package/dist/internals.js.br +0 -0
  91. package/dist/internals.js.gz +0 -0
  92. package/dist/internals.mjs +4 -4
  93. package/dist/internals.mjs.br +0 -0
  94. package/dist/internals.mjs.gz +0 -0
  95. package/dist/pptx-viewer.css +1 -1
  96. package/dist/pptx-viewer.css.br +0 -0
  97. package/dist/pptx-viewer.css.gz +0 -0
  98. package/dist/viewer/index.d.ts +416 -2
  99. package/dist/viewer/index.js +27 -27
  100. package/dist/viewer/index.js.br +0 -0
  101. package/dist/viewer/index.js.gz +0 -0
  102. package/dist/viewer/index.mjs +6 -6
  103. package/dist/viewer/index.mjs.br +0 -0
  104. package/dist/viewer/index.mjs.gz +0 -0
  105. package/package.json +1 -1
  106. package/dist/AiChatPanel-QJHUDIWT.mjs.br +0 -0
  107. package/dist/AiChatPanel-QJHUDIWT.mjs.gz +0 -0
  108. package/dist/AiChatPanel-UFMSTNCB.js.br +0 -0
  109. package/dist/AiChatPanel-UFMSTNCB.js.gz +0 -0
  110. package/dist/Model3DScene-3GOC5HUS.mjs.br +0 -0
  111. package/dist/Model3DScene-3GOC5HUS.mjs.gz +0 -0
  112. package/dist/Model3DScene-KXNJBAQD.js.gz +0 -0
  113. package/dist/chunk-7WWINBGF.js.br +0 -0
  114. package/dist/chunk-7WWINBGF.js.gz +0 -0
  115. package/dist/chunk-AI6K5EAE.js.br +0 -0
  116. package/dist/chunk-AI6K5EAE.js.gz +0 -0
  117. package/dist/chunk-CSY422LU.js.br +0 -0
  118. package/dist/chunk-CSY422LU.js.gz +0 -0
  119. package/dist/chunk-D3TZOCQP.mjs.br +0 -0
  120. package/dist/chunk-D3TZOCQP.mjs.gz +0 -0
  121. package/dist/chunk-I4D6JQOI.js.br +0 -0
  122. package/dist/chunk-I4D6JQOI.js.gz +0 -0
  123. package/dist/chunk-JQXN6PO7.mjs.br +0 -0
  124. package/dist/chunk-JQXN6PO7.mjs.gz +0 -0
  125. package/dist/chunk-LUHUYBGW.mjs.br +0 -0
  126. package/dist/chunk-LUHUYBGW.mjs.gz +0 -0
  127. package/dist/chunk-OWTHF5N4.js.br +0 -0
  128. package/dist/chunk-OWTHF5N4.js.gz +0 -0
  129. package/dist/chunk-WCHKDZP6.mjs.br +0 -0
  130. package/dist/chunk-WCHKDZP6.mjs.gz +0 -0
  131. package/dist/chunk-WNFHFFYE.mjs.br +0 -0
  132. package/dist/chunk-WNFHFFYE.mjs.gz +0 -0
  133. package/dist/chunk-XMKLY2SE.mjs.br +0 -0
  134. package/dist/chunk-XMKLY2SE.mjs.gz +0 -0
  135. package/dist/chunk-YJKR7Z3X.js.br +0 -0
  136. package/dist/chunk-YJKR7Z3X.js.gz +0 -0
@@ -1,9 +1,9 @@
1
- import { computeFocusTargets, deckDataFieldChanged, aiChangeAnimationCss, changeGhostStyle, createChatHistoryStore, collectStoredChats, exportAiChatLogs, applyElementUpdate } from './chunk-XMKLY2SE.mjs';
2
- import { useViewerOptions, useReadOnlyRecommendationState, useCompatibilityToastsState, useReducedMotion, useViewerState, useIsMobile, useResizablePanels, useDerivedSlideState, useZoomViewport, useEditorHistory, usePresentationSetup, useTouchGestures, useViewerDialogs, useEditorOperations, useViewerIntegration, useViewPreferencesSync, useLayoutSwitching, ViewerOptionsContext, Rendering3DFlagsContext, CollaborationProvider, useCollaboration, useCollaborationDocumentSync, useFollowMode, useBroadcastFollower, SlideBackgroundImageLayer, StaticElementRenderer, safePrompt, scopeLayoutOptionsToActiveSlide, ChartPartSelectionProvider, useToolbarVisibility, useKeyboardInsets, useModalDismissDrag, useViewerOptionsContext, useVirtualizedSlides, useSwipeNavigation, PresentationTransitionOverlay, RemoteSelectionOverlay, CollaborationCursorOverlay, useSheetDismissDrag, detectTargetType, parseEmailUrl, parseSlideFromUrl, ACTION_VERB_MAP, ElementRenderer, InlineCollaborationContext, SmartArtRenderer, playAnimationSound, ResizeHandles, renderStrokeView, useChartPartSelection, resolveSmartArtDataPalette } from './chunk-WCHKDZP6.mjs';
3
- import { SHAPE_PRESETS, ANIMATION_PRESET_OPTIONS, cn, SLIDE_NAV_THUMBNAIL_WIDTH, TOOLBAR_SECTIONS, DEFAULT_SECTION_GROUP_ID, SHORTCUT_REFERENCE_ITEMS as SHORTCUT_REFERENCE_ITEMS$1, isConnectorOrLineElement, GRID_SIZE, MIN_ELEMENT_SIZE, CONNECTOR_ARROW_OPTIONS, ARROW_SIZE_OPTIONS, DEFAULT_FILL_COLOR, startMotionPathPreview, startPreviewAnimation, stopPreviewAnimation, DEFAULT_STROKE_COLOR, STROKE_DASH_OPTIONS } from './chunk-WNFHFFYE.mjs';
4
- import { SWITCHABLE_LAYOUT_TYPES, compileEquationTemplateMathMl, buildUserFontFaceStyles, readStoredViewerPrefs, resolveThemeCatalogEntry, THEME_CATALOG, writeStoredViewerPrefs, openPptxFile, readBackstageRecentFile, resolveAutosaveActivation, buildThemeColorMap, viewerOptionsToPreferences, applyPreferenceToOptions, resolveHistoryDepth, applyAutoCorrect, resolveImageResolutionScale, resolveAutosaveIntervalMs, resolveAutosaveIntervalSeconds, shouldShowAutosaveRecoveryPrompt, resolveOptionRootClasses, resolve3DRenderingFlags, resolveSlideSizeSelection, RULER_THICKNESS, RULER_FONT_SIZE, buildPreviewElements, deriveSlideFieldContext, SLIDE_TRANSITION_OPTIONS, hiddenSlideCue, HIDDEN_SLIDE_SLASH_GRADIENT, HIDDEN_SLIDE_LABEL_KEY, visibleTemplateElements, normalizeHexColor, themeToCssVars, listAutosaveSnapshots, resolveExpiredAutosaveSnapshots, deleteAutosaveSnapshot, masterViewCrudActions, applyMasterViewCrudAction, masterViewCrudFailureKey, applyMotionPathPreset, resetSlideLayoutPath, DEFAULT_INSERT_CHART_KIND, hasCopyableFormat, templateSchemeFromTheme, createBackstagePresentation, playFeedbackSound, shouldDiscardAutosaveOnSuccessfulSave, setMasterViewBackgroundColor, canUseClipboard, runProgramNoticeStackStyle, compatToastStackStyle, printPropertiesFrameSlides, printPropertiesSlidesPerPage, PASTE_SPECIAL_OPTIONS, getDensePanelTouchTargetPx, shouldStickyActionRow, VIEWER_OPTIONS_TABS, DEFAULT_QUICK_ACCESS_COMMAND_IDS, isHeaderFooterDateTextVisible, isHeaderFooterHeaderTextVisible, isHeaderFooterFooterTextVisible, buildJoinCollaborationConfig, buildCreateCollaborationConfig, generateBroadcastRoomId, DEFAULT_BROADCAST_SERVER_URL, buildBroadcastViewerUrl, resolveTransportForServerUrl, getSlideBackgroundStyle, pushRecentColor, mruColorsPatch, shouldClearAutosaveCacheOnClose, filterCommands, resolveTitleBarStatusKey, TITLE_BAR_CLASSES, TITLE_BAR_DEFAULT_FILE_KEY, resolveScreenTip, masterViewBackgroundColor, buildFieldSubstitutionContext, shouldConfirmExternalHyperlink, safeOpenUrl, resolvePresentationAction, isPpactionUrl, parsePpactionUrl, isPresentationAdvanceClick, toggleBlackboard, PRESENT_TOOLBAR_CLASSES, buildContextMenuEntries, themeColorSchemesEqual, observeElementHeight, EXPANDED_MAX_HEIGHT, STATUS_BAR_CLASSES, buildBarActions, formatVersionTimestamp, formatRelativeTime, scanAvailableFontFamilies, PRESETS, CATEGORIES, convertOmmlToLatex, compileLatexEquation, convertLatexToOmml, EQUATION_TEMPLATES, clampPercent2, resolveDefaultPrintSettings, HANDOUT_OPTIONS, TOOLBAR_TABS, SHORTCUT_REFERENCE_ITEMS, resolveViewerAddinRows, availableQuickAccessCommands, addQuickAccessCommand, removeQuickAccessCommand, moveQuickAccessCommand, CUSTOM_FONT_ACCEPT, activateModalFocus, buildCollaborationShareUrl, buildActiveSessionUsers, SORTER_MIN_ZOOM, SORTER_ZOOM_STEP, SORTER_MAX_ZOOM, canGoPrevious, formatSlideCounter, READING_VIEW_COUNTER_ATTR, canGoNext, READING_VIEW_ATTR, OUTLINE_LEVEL_ATTR, OUTLINE_SLIDE_ATTR, OUTLINE_ROW_ATTR, OUTLINE_VIEW_ATTR, mobileElapsedSince, nextPresentedSlide, presenterPrevDisabled, presenterNextDisabled, formatMobileElapsed, mobileSlideCounter, presenterPaneAdvancesOnClick, presenterTimerProgress, PRESENTER_CONSOLE_CLASSES, formatElapsed, extraQuickAccessCommands, TAB_ROW_ACTION_CLASSES, listBackstageRecentFiles, BACKSTAGE_NAV, BACKSTAGE_BACK_CLASSES, BACKSTAGE_NAV_CLASSES, hasTextProperties, COMMON_FONT_SIZES, textFontSizePtToPx, INSERT_CHART_TYPES, ACTION_BUTTON_PRESETS, CHARACTER_SPACING_OPTIONS, OFFICE_COLOR_SWATCHES, hasShapeProperties, shapeFillChange, shapeOutlineChange, readRibbonTransitionDraft, ribbonTransitionUpdates, playSlideTransitionPreview, RIBBON_TRANSITION_PRESETS, transitionSoundOptions, transitionSoundSelectedValue, DEFAULT_MOTION_PATH_PRESET_ID, SLIDE_SHOW_OPTIONS, slideShowOptionChange, readSlideShowOption, SLIDE_VIRTUALIZATION_THRESHOLD, PRESENTATION_HIT_TEST_CSS, PRESENTATION_STAGE_ATTRIBUTE, buildStrokePathD, cursorForTool, annotationOverlayZIndex, presentationInkPath, resolveNotesSchematicBodyFontSizePx, PRESENTER_NAVIGATOR_LABEL_KEYS, PEN_COLORS, HIGHLIGHTER_COLORS, isBlackboardActive, scaleSlidesForSizeChange, slideSizeToCanvasPx, resolveSelectionPaneRename, PRESET_THEMES, resolveNotesSegments, segmentsToEditorHtml, DEBOUNCE_MS, createPlainNotesSegments, parseSegmentsFromRichEditor, segmentsToPlainText, getCurrentParagraphIndex, segmentsToParagraphs, paragraphsToSegments, MAX_INDENT_LEVEL, INDENT_PX, isUrlSafe, buildNotesPrintHtml, MIN_TOUCH_TARGET_PX, toggleSheet, SMARTART_PREVIEW_ELEMENT_HEIGHT, SMARTART_PREVIEW_ELEMENT_WIDTH, buildSmartArtPreviewElement, sanitizeMathMl, computeHandoutLayout, getPrintableArea, generateNoteLineCount, computeAllNotesPages, getNotesPrintableArea, downloadBlob, clampOptionNumber, QUICK_ACCESS_COMMAND_CATALOG, registerCustomFont, openReadingView, applyReadingViewCommand, createPresentationKeyBuffer, readingViewFitScale, READING_VIEW_STAGE_ATTR, buildOutline, applyOutlineEdit, mapOutlineKey, notesSegmentsToSpans, erasePresentationInkAt, movePresenterPointer, appendPresentationInkPoint, PRESENTER_CONSOLE_CONTROLS, NOTES_FONT_SIZE_DEFAULT, formatTime, NOTES_FONT_SIZE_MIN, clampNotesFontSize, NOTES_FONT_SIZE_STEP, NOTES_FONT_SIZE_MAX, BACKSTAGE_TEMPLATES, formatBackstageDate, formatBackstageSize, backstageCardsFor, DEFAULT_VIEWER_PROFILE, resolveProfileInitial, AVATAR_COLOR_SWATCHES, resolveDefaultFontFamily, textFontSizePxToPt, buildFontCatalog, getSelectionTextStyleFlags, getInlineEditorSelectionResult, selectedParagraphBulletKind, elementBulletKind, selectionBulletKind, TEXT_DECORATION_FLAGS, nextToggleValue, buildThemeColorSwatchGrid, themeColorSwatchRows, findSelectedThemeSwatch, themeSwatchCommit, RIBBON_SHAPE_SWATCHES, canGroupSelection, canUngroupSelection, canSetStrokeWidth, strokeWidthOf, readSoundFileAsDataUrl, applyTransitionSoundFile, TRANSITION_SOUND_OTHER_VALUE, TRANSITION_SOUND_NONE_VALUE, clearTransitionSound, applyTransitionStockSound, transitionStockSoundId, getEffectSoundAsset, ENTRANCE_PRESET_VALUES, EMPHASIS_PRESET_VALUES, EXIT_PRESET_VALUES, MOTION_PATH_FAMILIES, motionPathFamilyLabelKey, motionPathPresetsByFamily, motionPathPresetLabelKey, masterViewPseudoSlide, motionPathFor, setMotionPath, getShapeAdjustmentHandleDescriptors, shouldShowElementHandles, hasMultipleSelectedTableCells, applyTableStyleDelete, applyTableStyleMapChange, themeColorLabel, buildThemeColorGrid, THEME_COLOR_SCHEME_KEYS, COMMON_FONTS, handleReadingViewKey, getLocalStorageUsageSummary, saveViewerProfile, clearAllLocalViewerData, isCurrentLayout, SLIDE_TEMPLATES, computeAnchoredPopupPosition, attachEditorImagePaste, authorConnectorBetweenSites, findEraserHitElementId, generateTicks, rulerDragToGuidePosition, resolveElementInteractivity, getElementTransformWithoutRotation, getElementTransform, buildChartQuickActionsDescriptor, applyChartElementToggle, CHART_QUICK_ACTION_BUTTON_SIZE, applyChartStylePreset, hideChartSeries, restoreFilteredSeries, getActiveXControlOverlayView, buildCommentMarkers, COMMENT_MARKER_SIZE, collectConnectorSiteCandidates, getConnectorEndpointHandles, findConnectorSiteNear, motionPathToSvgD, motionPathEndPixel, isEditableMotionPath, setMotionPathEnd, isElementLocked, isImageLikeElement, mergeSlideTransition, getElementLabel, TRIGGER_OPTIONS, mapSlideSorterKey, isEditorTextInputTarget, clampSorterZoom, buildLayoutPreviewGeometry, buildSlideTemplateContent, buildFreeformShapeElement, buildLiveInkStrokeView, CONNECTOR_SITE_SNAP_PX, resolveConnectorEndpointUpdate, withConnectorEndpointUpdate, getShapeConnectionSites, elementLockTogglePatch, buildTableDataGrid, getDenseGridLayoutPlan, appendTableElementRow, removeLastTableElementRow, appendTableElementColumn, removeLastTableElementColumn, removeTableElementColumn, removeTableElementRow, setTableElementCellText, TABLE_STYLE_PRESETS, applyTableStylePreset, tableStyleAssignmentUpdate, evenColumnWidths, redistributeColumnWidth, evenRowHeights, patchChartData, collapseChartTitleRunsForEdit, chartGridlinesState, chartGridlinesPatch, seriesSecondaryAxisPatch, setChartCategoryLabel, setChartCellValue, addChartCategory, removeChartCategory, addChartSeries, removeChartSeries, setDataLabelsRangeCache, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointExplosion, setChartDataPointMarker, setChartDataPointLabel, describeSmartArtBounds, canAddTopLevelNode, classifyExtraConnections, siblingIndex, siblingCount, canRemoveTopLevelNode, canInteractWithElement, buildOleObjectNamePatch, getOleObjectTypeLabel, sanitizeGradientStops, shouldShowAccessibilitySection, pptxActionToElementAction, withFrameSlides, withSlidesPerPage, applyThemeOverrideToSlide, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, schemaLabel, THEME_COLOR_SLOT_LABEL_KEYS, SLIDE_SIZE_PRESETS, TRANSITION_VALID_DIRECTIONS, TRANSITION_ORIENTATION_TYPES, TRANSITION_PATTERN_OPTIONS, TRANSITION_THRUBLK_TYPES, clampTransitionNumber, TRANSITION_SPEED_OPTIONS, TRANSITION_MORPH_OPTIONS, flattenTagCollections, resolveTemplateBackgroundRows, formatCommentTimestamp, commentMentionQuery, matchCommentMentionAuthors, buildAnimationTimelineRows, clearMotionPath, getEffectSoundState, setEffectSound, setEffectStockSound, setAfterAnimation, setAfterAnimationColor, DIRECTIONAL_PRESETS, buildAnimationTimelineBars, motionPathPresetIdForPath, EFFECT_SOUND_CATALOGUE, hasTiltData, normalizeTableStyleGuid, describeTableStyleEditor, TABLE_STYLE_EDITOR_PARTS, computeMergeCellRight, computeMergeCellDown, computeSplitCell, updateMergeAttrsInRawXml, resolveDisplayedChartType, CHART_TYPE_OPTIONS, chartDataLabelsTogglePatch, BAR3D_SHAPE_OPTIONS, bar3DShapePatch, RADAR_STYLE_OPTIONS, radarStylePatch, SURFACE_WIREFRAME_OPTIONS, surfaceWireframePatch, isSeriesUsingSecondaryAxis, listChartUserShapeRows, withChartUserShapeAdded, createDefaultChartUserShape, withChartUserShapeRowRemoved, withChartUserShapeRowTextUpdated, SMARTART_COLOR_SCHEME_LABEL_KEYS, SMARTART_STYLE_LABEL_KEYS, addSmartArtNodeAsChild, setSmartArtNodeStyle, removeSmartArtNode, addSiblingAfter, removeEmptyNode, demote, promote, updateSmartArtNodeText, reorder, clampCropValue, DUOTONE_PRESETS, ARTISTIC_EFFECTS, mediaTrimEndSeconds, trimmedMediaDurationMs, mediaTrimEndAbsoluteMs, mediaTrimEndMsFromAbsoluteMs, buildOleEditDialogDescriptor, buildOleContentUpdatePatch, applyOleSheetCellEdit, getOleSheetGrid, applyOleDocumentParagraphEdit, getOleDocumentParagraphs, applyOleNestedDeckElementTextEdit, getOleNestedDeckDetail, replaceOleFile, getNonVisualDescriptionFields, resolveActionType, ELEMENT_ACTION_TYPE_OPTIONS, elementActionToPptxAction, canCommitActionType, slideSizeFromPreset, withSlideSizeOrientation, TRANSITION_DIR_ARROWS, buildDirectionGrid, getSlideTransitionAnimations, SLIDE_TRANSITION_KEYFRAMES, updateTagInCollections, deleteTagFromCollections, addTagToCollections, commentTextSegments, COMMENT_MENTION_CLASS, COMMENT_MENTION_ATTRIBUTE, insertCommentMention, reorderAnimationTimelineRows, applyAnimationTimelineOrder, animationEffectLabel, TABLE_STYLE_BORDER_SIDES, applyTableStyleFieldEdit, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, LBL, SEL, FILL_MODE_OPTIONS, SECTION_HEADING, NUM, getChartUserShapeGroupTransform, withChartUserShapeGroupChildAdded, createDefaultChartUserShapeGroupChild, withChartUserShapeRowUpdated, getChartUserShapeRowChartBox, withChartUserShapeRowFlipUpdated, withChartUserShapeRowRotationUpdated, withChartUserShapeRowChartBoxUpdated, switchSmartArtLayout, rebuildDrawingShapesIfCleared, mediaTrimEndMsFromSeconds, validateMediaTrimRange, SHAPE_QUICK_STYLES, quickStyleSwatchCss, PATTERN_PRESET_OPTIONS, getPatternSvg, COMPOUND_LINE_OPTIONS, LINE_JOIN_OPTIONS, LINE_CAP_OPTIONS, TEXT_WARP_PRESETS, warpPreviewPath, text3dPtToEmu, text3dEmuToPt, MATERIAL_PRESETS, toSlideIndex, TABLE_STYLE_BORDER_SIDE_LABEL_KEYS, TABLE_STYLE_DASH_PRESETS, GRADIENT_TYPE_OPTIONS, PATTERN_OPTIONS, FILL_PATTERN_LABEL_KEYS, openNativeEyeDropper, toggleText3dExtrusion, BEVEL_PRESETS } from './chunk-D3TZOCQP.mjs';
5
- import { LOCALE_CATALOG, ALIGNMENT_LABEL_KEYS } from './chunk-JQXN6PO7.mjs';
6
- import React4, { createContext, lazy, forwardRef, useEffect, useState, useCallback, useMemo, useRef, useId, Fragment as Fragment$1, useDeferredValue, useLayoutEffect, Suspense, useContext, useSyncExternalStore } from 'react';
1
+ import { computeFocusTargets, deckDataFieldChanged, aiChangeAnimationCss, changeGhostStyle, createChatHistoryStore, collectStoredChats, exportAiChatLogs, applyElementUpdate } from './chunk-VCAQSSGD.mjs';
2
+ import { useViewerOptions, useReadOnlyRecommendationState, useCompatibilityToastsState, useReducedMotion, useViewerState, useIsMobile, useResizablePanels, useDerivedSlideState, useZoomViewport, useEditorHistory, usePresentationSetup, useTouchGestures, useViewerDialogs, useEditorOperations, useViewerIntegration, useViewPreferencesSync, useLayoutSwitching, ViewerOptionsContext, Rendering3DFlagsContext, CollaborationProvider, useCollaboration, useCollaborationDocumentSync, useFollowMode, useBroadcastFollower, SlideBackgroundImageLayer, StaticElementRenderer, safePrompt, scopeLayoutOptionsToActiveSlide, ChartPartSelectionProvider, useToolbarVisibility, useKeyboardInsets, useModalDismissDrag, useViewerOptionsContext, useVirtualizedSlides, useSwipeNavigation, PresentationTransitionOverlay, RemoteSelectionOverlay, CollaborationCursorOverlay, useSheetDismissDrag, detectTargetType, parseEmailUrl, parseSlideFromUrl, ACTION_VERB_MAP, ElementRenderer, InlineCollaborationContext, SmartArtRenderer, playAnimationSound, ResizeHandles, renderStrokeView, useChartPartSelection, resolveSmartArtDataPalette } from './chunk-INX3E37P.mjs';
3
+ import { SHAPE_PRESETS, ANIMATION_PRESET_OPTIONS, cn, SLIDE_NAV_THUMBNAIL_WIDTH, TOOLBAR_SECTIONS, DEFAULT_SECTION_GROUP_ID, SHORTCUT_REFERENCE_ITEMS as SHORTCUT_REFERENCE_ITEMS$1, isConnectorOrLineElement, GRID_SIZE, MIN_ELEMENT_SIZE, CONNECTOR_ARROW_OPTIONS, ARROW_SIZE_OPTIONS, DEFAULT_FILL_COLOR, startMotionPathPreview, startPreviewAnimation, stopPreviewAnimation, DEFAULT_STROKE_COLOR, STROKE_DASH_OPTIONS } from './chunk-K6QHGABT.mjs';
4
+ import { EMPTY_RESOLVED_CUSTOMIZATION, SWITCHABLE_LAYOUT_TYPES, compileEquationTemplateMathMl, buildUserFontFaceStyles, readStoredViewerPrefs, resolveThemeCatalogEntry, THEME_CATALOG, writeStoredViewerPrefs, openPptxFile, readBackstageRecentFile, isFeatureEnabled, isDialogAvailable, resolveAutosaveActivation, buildThemeColorMap, viewerOptionsToPreferences, applyPreferenceToOptions, resolveHistoryDepth, applyAutoCorrect, resolveImageResolutionScale, resolveAutosaveIntervalMs, resolveAutosaveIntervalSeconds, isPanelVisible, shouldShowAutosaveRecoveryPrompt, resolveOptionRootClasses, resolve3DRenderingFlags, resolveSlideSizeSelection, RULER_THICKNESS, RULER_FONT_SIZE, buildPreviewElements, deriveSlideFieldContext, SLIDE_TRANSITION_OPTIONS, hiddenSlideCue, HIDDEN_SLIDE_SLASH_GRADIENT, HIDDEN_SLIDE_LABEL_KEY, visibleTemplateElements, normalizeHexColor, themeToCssVars, createCustomizationController, resolveEffectiveHiddenActions, listAutosaveSnapshots, resolveExpiredAutosaveSnapshots, deleteAutosaveSnapshot, masterViewCrudActions, applyMasterViewCrudAction, masterViewCrudFailureKey, applyMotionPathPreset, resetSlideLayoutPath, DEFAULT_INSERT_CHART_KIND, hasCopyableFormat, templateSchemeFromTheme, createBackstagePresentation, playFeedbackSound, shouldDiscardAutosaveOnSuccessfulSave, setMasterViewBackgroundColor, canUseClipboard, runProgramNoticeStackStyle, compatToastStackStyle, printPropertiesFrameSlides, printPropertiesSlidesPerPage, PASTE_SPECIAL_OPTIONS, getDensePanelTouchTargetPx, shouldStickyActionRow, customizeOptionsTabs, VIEWER_OPTIONS_TABS, isOptionsPageVisible, DEFAULT_QUICK_ACCESS_COMMAND_IDS, isHeaderFooterDateTextVisible, isHeaderFooterHeaderTextVisible, isHeaderFooterFooterTextVisible, buildJoinCollaborationConfig, buildCreateCollaborationConfig, generateBroadcastRoomId, DEFAULT_BROADCAST_SERVER_URL, buildBroadcastViewerUrl, resolveTransportForServerUrl, getSlideBackgroundStyle, pushRecentColor, mruColorsPatch, shouldClearAutosaveCacheOnClose, filterCommands, resolveTitleBarStatusKey, TITLE_BAR_CLASSES, TITLE_BAR_DEFAULT_FILE_KEY, resolveScreenTip, masterViewBackgroundColor, buildFieldSubstitutionContext, shouldConfirmExternalHyperlink, safeOpenUrl, resolvePresentationAction, isPpactionUrl, parsePpactionUrl, isPresentationAdvanceClick, toggleBlackboard, PRESENT_TOOLBAR_CLASSES, customizeContextMenuEntries, buildContextMenuEntries, customizeCanvasContextMenuEntries, buildCanvasContextMenuEntries, isCurrentLayout, themeColorSchemesEqual, observeElementHeight, EXPANDED_MAX_HEIGHT, STATUS_BAR_CLASSES, buildBarActions, formatVersionTimestamp, formatRelativeTime, scanAvailableFontFamilies, PRESETS, CATEGORIES, convertOmmlToLatex, compileLatexEquation, convertLatexToOmml, EQUATION_TEMPLATES, clampPercent2, resolveDefaultPrintSettings, HANDOUT_OPTIONS, TOOLBAR_TABS, SHORTCUT_REFERENCE_ITEMS, resolveViewerAddinRows, availableQuickAccessCommands, addQuickAccessCommand, removeQuickAccessCommand, moveQuickAccessCommand, CUSTOM_FONT_ACCEPT, activateModalFocus, buildCollaborationShareUrl, buildActiveSessionUsers, SORTER_MIN_ZOOM, SORTER_ZOOM_STEP, SORTER_MAX_ZOOM, canGoPrevious, formatSlideCounter, READING_VIEW_COUNTER_ATTR, canGoNext, READING_VIEW_ATTR, OUTLINE_LEVEL_ATTR, OUTLINE_SLIDE_ATTR, OUTLINE_ROW_ATTR, OUTLINE_VIEW_ATTR, mobileElapsedSince, nextPresentedSlide, presenterPrevDisabled, presenterNextDisabled, formatMobileElapsed, mobileSlideCounter, presenterPaneAdvancesOnClick, presenterTimerProgress, PRESENTER_CONSOLE_CLASSES, formatElapsed, extraQuickAccessCommands, TAB_ROW_ACTION_CLASSES, customizeBackstageNav, BACKSTAGE_NAV, listBackstageRecentFiles, BACKSTAGE_BACK_CLASSES, BACKSTAGE_NAV_CLASSES, hasTextProperties, COMMON_FONT_SIZES, textFontSizePtToPx, INSERT_CHART_TYPES, ACTION_BUTTON_PRESETS, CHARACTER_SPACING_OPTIONS, OFFICE_COLOR_SWATCHES, hasShapeProperties, shapeFillChange, shapeOutlineChange, readRibbonTransitionDraft, ribbonTransitionUpdates, playSlideTransitionPreview, RIBBON_TRANSITION_PRESETS, transitionSoundOptions, transitionSoundSelectedValue, DEFAULT_MOTION_PATH_PRESET_ID, SLIDE_SHOW_OPTIONS, slideShowOptionChange, readSlideShowOption, resolveSlidePaneClick, SLIDE_VIRTUALIZATION_THRESHOLD, buildSlidePaneContextMenuEntries, PRESENTATION_HIT_TEST_CSS, PRESENTATION_STAGE_ATTRIBUTE, buildStrokePathD, cursorForTool, annotationOverlayZIndex, presentationInkPath, resolveNotesSchematicBodyFontSizePx, PRESENTER_NAVIGATOR_LABEL_KEYS, PEN_COLORS, HIGHLIGHTER_COLORS, isBlackboardActive, clampFlyoutPosition, buildLayoutPreviewGeometry, scaleSlidesForSizeChange, slideSizeToCanvasPx, resolveSelectionPaneRename, PRESET_THEMES, resolveNotesSegments, segmentsToEditorHtml, DEBOUNCE_MS, createPlainNotesSegments, parseSegmentsFromRichEditor, segmentsToPlainText, getCurrentParagraphIndex, segmentsToParagraphs, paragraphsToSegments, MAX_INDENT_LEVEL, INDENT_PX, isUrlSafe, buildNotesPrintHtml, MIN_TOUCH_TARGET_PX, toggleSheet, SMARTART_PREVIEW_ELEMENT_HEIGHT, SMARTART_PREVIEW_ELEMENT_WIDTH, buildSmartArtPreviewElement, sanitizeMathMl, computeHandoutLayout, getPrintableArea, generateNoteLineCount, computeAllNotesPages, getNotesPrintableArea, downloadBlob, clampOptionNumber, QUICK_ACCESS_COMMAND_CATALOG, registerCustomFont, openReadingView, applyReadingViewCommand, createPresentationKeyBuffer, readingViewFitScale, READING_VIEW_STAGE_ATTR, buildOutline, applyOutlineEdit, mapOutlineKey, notesSegmentsToSpans, erasePresentationInkAt, movePresenterPointer, appendPresentationInkPoint, PRESENTER_CONSOLE_CONTROLS, NOTES_FONT_SIZE_DEFAULT, formatTime, NOTES_FONT_SIZE_MIN, clampNotesFontSize, NOTES_FONT_SIZE_STEP, NOTES_FONT_SIZE_MAX, BACKSTAGE_TEMPLATES, formatBackstageDate, formatBackstageSize, customizeBackstageCards, backstageCardsFor, DEFAULT_VIEWER_PROFILE, resolveProfileInitial, AVATAR_COLOR_SWATCHES, resolveDefaultFontFamily, textFontSizePxToPt, buildFontCatalog, getSelectionTextStyleFlags, getInlineEditorSelectionResult, selectedParagraphBulletKind, elementBulletKind, selectionBulletKind, TEXT_DECORATION_FLAGS, nextToggleValue, buildThemeColorSwatchGrid, themeColorSwatchRows, findSelectedThemeSwatch, themeSwatchCommit, RIBBON_SHAPE_SWATCHES, canGroupSelection, canUngroupSelection, canSetStrokeWidth, strokeWidthOf, readSoundFileAsDataUrl, applyTransitionSoundFile, TRANSITION_SOUND_OTHER_VALUE, TRANSITION_SOUND_NONE_VALUE, clearTransitionSound, applyTransitionStockSound, transitionStockSoundId, getEffectSoundAsset, playAnimationRibbonPreview, ENTRANCE_PRESET_VALUES, EMPHASIS_PRESET_VALUES, EXIT_PRESET_VALUES, MOTION_PATH_FAMILIES, motionPathFamilyLabelKey, motionPathPresetsByFamily, motionPathPresetLabelKey, masterViewPseudoSlide, motionPathFor, setMotionPath, getShapeAdjustmentHandleDescriptors, shouldShowElementHandles, hasMultipleSelectedTableCells, computeAnchoredPopupPosition, applyTableStyleDelete, applyTableStyleMapChange, themeColorLabel, buildThemeColorGrid, THEME_COLOR_SCHEME_KEYS, COMMON_FONTS, handleReadingViewKey, getLocalStorageUsageSummary, saveViewerProfile, clearAllLocalViewerData, SLIDE_TEMPLATES, attachEditorImagePaste, authorConnectorBetweenSites, findEraserHitElementId, generateTicks, rulerDragToGuidePosition, resolveElementInteractivity, getElementTransformWithoutRotation, getElementTransform, buildChartQuickActionsDescriptor, applyChartElementToggle, CHART_QUICK_ACTION_BUTTON_SIZE, applyChartStylePreset, hideChartSeries, restoreFilteredSeries, getActiveXControlOverlayView, buildCommentMarkers, COMMENT_MARKER_SIZE, collectConnectorSiteCandidates, getConnectorEndpointHandles, findConnectorSiteNear, motionPathToSvgD, motionPathEndPixel, isEditableMotionPath, setMotionPathEnd, isElementLocked, isImageLikeElement, mergeSlideTransition, getElementLabel, TRIGGER_OPTIONS, mapSlideSorterKey, isEditorTextInputTarget, clampSorterZoom, buildSlideTemplateContent, buildFreeformShapeElement, buildLiveInkStrokeView, CONNECTOR_SITE_SNAP_PX, resolveConnectorEndpointUpdate, withConnectorEndpointUpdate, getShapeConnectionSites, elementLockTogglePatch, buildTableDataGrid, getDenseGridLayoutPlan, appendTableElementRow, removeLastTableElementRow, appendTableElementColumn, removeLastTableElementColumn, removeTableElementColumn, removeTableElementRow, setTableElementCellText, TABLE_STYLE_PRESETS, applyTableStylePreset, tableStyleAssignmentUpdate, evenColumnWidths, redistributeColumnWidth, evenRowHeights, patchChartData, collapseChartTitleRunsForEdit, chartGridlinesState, chartGridlinesPatch, seriesSecondaryAxisPatch, setChartCategoryLabel, setChartCellValue, addChartCategory, removeChartCategory, addChartSeries, removeChartSeries, setDataLabelsRangeCache, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointExplosion, setChartDataPointMarker, setChartDataPointLabel, describeSmartArtBounds, canAddTopLevelNode, classifyExtraConnections, siblingIndex, siblingCount, canRemoveTopLevelNode, canInteractWithElement, buildOleObjectNamePatch, getOleObjectTypeLabel, sanitizeGradientStops, shouldShowAccessibilitySection, pptxActionToElementAction, withFrameSlides, withSlidesPerPage, applyThemeOverrideToSlide, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, schemaLabel, THEME_COLOR_SLOT_LABEL_KEYS, SLIDE_SIZE_PRESETS, TRANSITION_VALID_DIRECTIONS, TRANSITION_ORIENTATION_TYPES, TRANSITION_PATTERN_OPTIONS, TRANSITION_THRUBLK_TYPES, clampTransitionNumber, TRANSITION_SPEED_OPTIONS, TRANSITION_MORPH_OPTIONS, flattenTagCollections, resolveTemplateBackgroundRows, formatCommentTimestamp, commentMentionQuery, matchCommentMentionAuthors, buildAnimationTimelineRows, clearMotionPath, getEffectSoundState, setEffectSound, setEffectStockSound, setAfterAnimation, setAfterAnimationColor, DIRECTIONAL_PRESETS, buildAnimationTimelineBars, motionPathPresetIdForPath, EFFECT_SOUND_CATALOGUE, hasTiltData, normalizeTableStyleGuid, describeTableStyleEditor, TABLE_STYLE_EDITOR_PARTS, computeMergeCellRight, computeMergeCellDown, computeSplitCell, updateMergeAttrsInRawXml, resolveDisplayedChartType, CHART_TYPE_OPTIONS, chartDataLabelsTogglePatch, BAR3D_SHAPE_OPTIONS, bar3DShapePatch, RADAR_STYLE_OPTIONS, radarStylePatch, SURFACE_WIREFRAME_OPTIONS, surfaceWireframePatch, isSeriesUsingSecondaryAxis, listChartUserShapeRows, withChartUserShapeAdded, createDefaultChartUserShape, withChartUserShapeRowRemoved, withChartUserShapeRowTextUpdated, SMARTART_COLOR_SCHEME_LABEL_KEYS, SMARTART_STYLE_LABEL_KEYS, addSmartArtNodeAsChild, setSmartArtNodeStyle, removeSmartArtNode, addSiblingAfter, removeEmptyNode, demote, promote, updateSmartArtNodeText, reorder, clampCropValue, DUOTONE_PRESETS, ARTISTIC_EFFECTS, mediaTrimEndSeconds, trimmedMediaDurationMs, mediaTrimEndAbsoluteMs, mediaTrimEndMsFromAbsoluteMs, buildOleEditDialogDescriptor, buildOleContentUpdatePatch, applyOleSheetCellEdit, getOleSheetGrid, applyOleDocumentParagraphEdit, getOleDocumentParagraphs, applyOleNestedDeckElementTextEdit, getOleNestedDeckDetail, replaceOleFile, getNonVisualDescriptionFields, resolveActionType, ELEMENT_ACTION_TYPE_OPTIONS, elementActionToPptxAction, canCommitActionType, slideSizeFromPreset, withSlideSizeOrientation, TRANSITION_DIR_ARROWS, buildDirectionGrid, getSlideTransitionAnimations, SLIDE_TRANSITION_KEYFRAMES, updateTagInCollections, deleteTagFromCollections, addTagToCollections, commentTextSegments, COMMENT_MENTION_CLASS, COMMENT_MENTION_ATTRIBUTE, insertCommentMention, reorderAnimationTimelineRows, applyAnimationTimelineOrder, animationEffectLabel, TABLE_STYLE_BORDER_SIDES, applyTableStyleFieldEdit, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, LBL, SEL, FILL_MODE_OPTIONS, SECTION_HEADING, NUM, getChartUserShapeGroupTransform, withChartUserShapeGroupChildAdded, createDefaultChartUserShapeGroupChild, withChartUserShapeRowUpdated, getChartUserShapeRowChartBox, withChartUserShapeRowFlipUpdated, withChartUserShapeRowRotationUpdated, withChartUserShapeRowChartBoxUpdated, switchSmartArtLayout, rebuildDrawingShapesIfCleared, mediaTrimEndMsFromSeconds, validateMediaTrimRange, SHAPE_QUICK_STYLES, quickStyleSwatchCss, PATTERN_PRESET_OPTIONS, getPatternSvg, COMPOUND_LINE_OPTIONS, LINE_JOIN_OPTIONS, LINE_CAP_OPTIONS, TEXT_WARP_PRESETS, warpPreviewPath, text3dPtToEmu, text3dEmuToPt, MATERIAL_PRESETS, toSlideIndex, TABLE_STYLE_BORDER_SIDE_LABEL_KEYS, TABLE_STYLE_DASH_PRESETS, GRADIENT_TYPE_OPTIONS, PATTERN_OPTIONS, FILL_PATTERN_LABEL_KEYS, openNativeEyeDropper, toggleText3dExtrusion, BEVEL_PRESETS } from './chunk-ICEZL4TM.mjs';
5
+ import { LOCALE_CATALOG, ALIGNMENT_LABEL_KEYS } from './chunk-OOO4JL2N.mjs';
6
+ import React4, { createContext, lazy, forwardRef, useEffect, useState, useCallback, useMemo, useRef, useLayoutEffect, useSyncExternalStore, useId, useContext, Fragment as Fragment$1, useDeferredValue, Suspense } from 'react';
7
7
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
8
  import { useTranslation } from 'react-i18next';
9
9
  import { LuMessageSquare, LuEyeOff, LuHistory, LuTrash2, LuSettings, LuX, LuCalendarDays, LuClock, LuHash, LuFileText, LuText, LuCast, LuSave, LuUndo, LuRedo, LuSearch, LuShieldCheck, LuPlus, LuPanelLeftClose, LuStickyNote, LuMonitor, LuColumns2, LuPresentation, LuMinus, LuSettings2, LuLayers, LuDownload, LuCheck, LuLock, LuEye, LuType, LuLoader, LuShieldAlert, LuSignature, LuInfo, LuTriangleAlert, LuPrinter, LuPenTool, LuBug, LuChevronUp, LuChevronDown, LuUpload, LuWifi, LuWifiOff, LuUsers, LuCopy, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuZoomOut, LuZoomIn, LuSpellCheck, LuFileDown, LuMenu, LuSparkles, LuShare2, LuPanelLeft, LuPanelRight, LuArrowLeft, LuFolderOpen, LuClipboardPaste, LuScissors, LuPaintbrush, LuSquare, LuImage, LuVideo, LuDatabase, LuAArrowUp, LuAArrowDown, LuRemoveFormatting, LuHighlighter, LuList, LuListOrdered, LuIndentDecrease, LuIndentIncrease, LuReplace, LuMousePointer2, LuShapes, LuPaintBucket, LuPenLine, LuPalette, LuPencil, LuStar, LuMoveRight, LuMousePointerClick, LuClock3, LuMonitorPlay, LuListVideo, LuCaptions, LuCamera, LuEraser, LuRotateCcw, LuCircleHelp, LuBookOpen, LuLanguages, LuGlobe, LuGitCompare, LuMessageSquarePlus, LuLockKeyhole, LuPanelTop, LuLayoutGrid, LuGrid3X3, LuPipette, LuRuler, LuMaximize2, LuCode, LuCaseSensitive, LuTimer, LuGripVertical, LuLoaderCircle, LuBold, LuItalic, LuUnderline, LuStrikethrough, LuLink, LuGrid2X2, LuCopyPlus, LuScan, LuMonitorOff, LuCirclePlay, LuCirclePause, LuArrowLeftRight, LuClipboardCopy, LuWand, LuTextCursorInput, LuFile, LuEllipsis, LuUserRound, LuFilePlus2, LuHouse, LuFileJson, LuBox, LuFileImage, LuUser, LuHardDrive, LuLogIn, LuLayoutTemplate, LuFolderPlus, LuAlignLeft, LuAlignCenter, LuAlignRight, LuAlignJustify, LuColumns3, LuSpline, LuAlignHorizontalSpaceAround, LuAlignVerticalSpaceAround, LuGroup, LuUngroup, LuMove, LuRadio, LuFilter, LuLockOpen, LuArrowDown, LuArrowUp, LuArrowRight, LuReply, LuRotateCw, LuBookmark } from 'react-icons/lu';
@@ -658,12 +658,17 @@ function AnimationsSection(p) {
658
658
  const { t } = useTranslation();
659
659
  const [previewActive, setPreviewActive] = useState(false);
660
660
  const disabled = !p.canEdit || p.selectedElement === null;
661
+ const selectedAnimation = useMemo(
662
+ () => p.selectedElement ? (p.activeSlide?.animations ?? []).find((a) => a.elementId === p.selectedElement?.id) : void 0,
663
+ [p.activeSlide?.animations, p.selectedElement]
664
+ );
661
665
  const preview = () => {
662
666
  if (disabled) {
663
667
  return;
664
668
  }
665
669
  setPreviewActive(true);
666
670
  setTimeout(() => setPreviewActive(false), 1200);
671
+ playAnimationRibbonPreview(document, selectedAnimation);
667
672
  };
668
673
  return /* @__PURE__ */ jsxs(Fragment, { children: [
669
674
  /* @__PURE__ */ jsx(RibbonGroup, { label: t("pptx.animations.preview"), children: /* @__PURE__ */ jsx(
@@ -1569,6 +1574,12 @@ function DrawSection(p) {
1569
1574
  ] })
1570
1575
  ] });
1571
1576
  }
1577
+ var ViewerCustomizationContext = createContext(
1578
+ EMPTY_RESOLVED_CUSTOMIZATION
1579
+ );
1580
+ function useViewerCustomizationContext() {
1581
+ return useContext(ViewerCustomizationContext);
1582
+ }
1572
1583
  function useHostEvent(ref, type, handler) {
1573
1584
  useEffect(() => {
1574
1585
  const host = ref.current;
@@ -1683,7 +1694,7 @@ function AccountPage() {
1683
1694
  return void 0;
1684
1695
  });
1685
1696
  };
1686
- const version = "4.3.0" ;
1697
+ const version = "4.5.0" ;
1687
1698
  return /* @__PURE__ */ jsxs("div", { className: "mt-8 max-w-[700px] space-y-6", children: [
1688
1699
  /* @__PURE__ */ jsxs("section", { className: cardClass, children: [
1689
1700
  /* @__PURE__ */ jsxs("h2", { className: "flex items-center gap-2 text-sm font-semibold", children: [
@@ -1897,8 +1908,10 @@ function BackstageCards({
1897
1908
  print: props.onPrint,
1898
1909
  share: props.onOpenShareDialog
1899
1910
  };
1900
- const cards = backstageCardsFor(page).filter(
1901
- (card) => card.id !== "saveAsPptm" || props.hasMacros
1911
+ const customization = useViewerCustomizationContext();
1912
+ const cards = customizeBackstageCards(
1913
+ backstageCardsFor(page).filter((card) => card.id !== "saveAsPptm" || props.hasMacros),
1914
+ customization
1902
1915
  );
1903
1916
  if (cards.length === 0) {
1904
1917
  return null;
@@ -1938,7 +1951,10 @@ function BackstageNavIcon({ page }) {
1938
1951
  }
1939
1952
  function FileSection(p) {
1940
1953
  const { t } = useTranslation();
1941
- const [page, setPage] = useState("home");
1954
+ const [requestedPage, setRequestedPage] = useState("home");
1955
+ const nav = customizeBackstageNav(BACKSTAGE_NAV, useViewerCustomizationContext());
1956
+ const offered = (id) => nav.some((item) => item.id === id);
1957
+ const page = offered(requestedPage) ? requestedPage : offered("home") ? "home" : nav.find((item) => item.id !== "save" && item.id !== "close")?.id ?? "home";
1942
1958
  const [query, setQuery] = useState("");
1943
1959
  const [recent, setRecent] = useState([]);
1944
1960
  const { isHidden } = useToolbarVisibility(p.hiddenActions);
@@ -1956,7 +1972,7 @@ function FileSection(p) {
1956
1972
  p.onClose();
1957
1973
  }
1958
1974
  };
1959
- const current = BACKSTAGE_NAV.find((item) => item.id === page);
1975
+ const current = nav.find((item) => item.id === page);
1960
1976
  const title = current ? t(current.labelKey, { defaultValue: current.label }) : t("pptx.backstage.nav.home");
1961
1977
  return /* @__PURE__ */ jsxs(
1962
1978
  "div",
@@ -1978,15 +1994,13 @@ function FileSection(p) {
1978
1994
  }
1979
1995
  ) }),
1980
1996
  /* @__PURE__ */ jsxs("nav", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto pb-2 max-md:flex-row max-md:items-center max-md:overflow-y-visible max-md:pb-0", children: [
1981
- BACKSTAGE_NAV.filter(
1982
- (item) => !item.group && !(item.id === "export" && exportHidden)
1983
- ).map((item) => /* @__PURE__ */ jsxs(
1997
+ nav.filter((item) => !item.group && !(item.id === "export" && exportHidden)).map((item) => /* @__PURE__ */ jsxs(
1984
1998
  "button",
1985
1999
  {
1986
2000
  type: "button",
1987
2001
  "data-pptx-backstage-nav-item": true,
1988
2002
  "aria-current": page === item.id ? "page" : void 0,
1989
- onClick: () => item.id === "close" ? p.onClose() : item.id === "save" ? run(p.onSaveAsPptx) : setPage(item.id),
2003
+ onClick: () => item.id === "close" ? p.onClose() : item.id === "save" ? run(p.onSaveAsPptx) : setRequestedPage(item.id),
1990
2004
  className: `${BACKSTAGE_NAV_CLASSES.row} ${page === item.id ? BACKSTAGE_NAV_CLASSES.active : BACKSTAGE_NAV_CLASSES.inactive}`,
1991
2005
  children: [
1992
2006
  /* @__PURE__ */ jsx(BackstageNavIcon, { page: item.id }),
@@ -1996,13 +2010,13 @@ function FileSection(p) {
1996
2010
  item.id
1997
2011
  )),
1998
2012
  /* @__PURE__ */ jsx("div", { className: "flex-1 max-md:hidden" }),
1999
- BACKSTAGE_NAV.filter((item) => item.group).map((item) => /* @__PURE__ */ jsxs(
2013
+ nav.filter((item) => item.group).map((item) => /* @__PURE__ */ jsxs(
2000
2014
  "button",
2001
2015
  {
2002
2016
  type: "button",
2003
2017
  "data-pptx-backstage-nav-item": true,
2004
2018
  "aria-current": page === item.id ? "page" : void 0,
2005
- onClick: () => item.id === "options" && p.onOpenSettings ? run(p.onOpenSettings) : setPage(item.id),
2019
+ onClick: () => item.id === "options" && p.onOpenSettings ? run(p.onOpenSettings) : setRequestedPage(item.id),
2006
2020
  className: `${BACKSTAGE_NAV_CLASSES.row} ${page === item.id ? BACKSTAGE_NAV_CLASSES.active : BACKSTAGE_NAV_CLASSES.inactive}`,
2007
2021
  children: [
2008
2022
  /* @__PURE__ */ jsx(BackstageNavIcon, { page: item.id }),
@@ -3176,6 +3190,7 @@ function ReviewSection(p) {
3176
3190
  {
3177
3191
  label: t("pptx.review.language"),
3178
3192
  icon: /* @__PURE__ */ jsx(LuGlobe, {}),
3193
+ disabled: !p.onSetLanguage,
3179
3194
  onClick: p.onSetLanguage
3180
3195
  }
3181
3196
  )
@@ -4911,6 +4926,7 @@ function MobileSectionBody({
4911
4926
  {
4912
4927
  canEdit: p.canEdit,
4913
4928
  selectedElement: p.selectedElement,
4929
+ activeSlide: p.activeSlide,
4914
4930
  isInspectorPaneOpen: p.isInspectorPaneOpen,
4915
4931
  onToggleInspector: p.onToggleInspector,
4916
4932
  onOpenAnimationPanel: p.onOpenAnimationPanel,
@@ -5485,8 +5501,9 @@ function EditingSection(p) {
5485
5501
  }
5486
5502
  function HelpSection(p) {
5487
5503
  const { t } = useTranslation();
5504
+ const showSettings = isDialogAvailable(useViewerCustomizationContext(), "options");
5488
5505
  return /* @__PURE__ */ jsxs(Fragment, { children: [
5489
- /* @__PURE__ */ jsx(
5506
+ showSettings && /* @__PURE__ */ jsx(
5490
5507
  "button",
5491
5508
  {
5492
5509
  type: "button",
@@ -5817,8 +5834,23 @@ function ModeSwitcher({
5817
5834
  }
5818
5835
  );
5819
5836
  }
5837
+ var EXPORT_CARD_OF = {
5838
+ png: "png",
5839
+ pdf: "pdf",
5840
+ video: "video",
5841
+ gif: "gif",
5842
+ copyImg: "copyImage"
5843
+ };
5820
5844
  function OverflowMenu(p) {
5821
5845
  const { t } = useTranslation();
5846
+ const customization = useViewerCustomizationContext();
5847
+ const offered = (k) => {
5848
+ const card = EXPORT_CARD_OF[k];
5849
+ if (card) {
5850
+ return !customization.hiddenBackstageCards.has(card);
5851
+ }
5852
+ return k !== "print" || isDialogAvailable(customization, "print");
5853
+ };
5822
5854
  const ovAct = (k) => {
5823
5855
  p.onSetOverflowMenuOpen(false);
5824
5856
  ({
@@ -5866,7 +5898,7 @@ function OverflowMenu(p) {
5866
5898
  onClick: () => p.onSetOverflowMenuOpen(false)
5867
5899
  }
5868
5900
  ),
5869
- /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-full mt-1 z-50 w-44 rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl py-1", children: OV.filter((o) => o.k !== "pptm" || p.hasMacros).map(
5901
+ /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-full mt-1 z-50 w-44 rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl py-1", children: OV.filter((o) => (o.k !== "pptm" || p.hasMacros) && offered(o.k)).map(
5870
5902
  (o) => o.k.startsWith("---") ? /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border/60" }, o.k) : /* @__PURE__ */ jsxs(
5871
5903
  "button",
5872
5904
  {
@@ -5895,9 +5927,15 @@ function ToolbarPrimaryRow(p) {
5895
5927
  onToggleInspector
5896
5928
  } = p;
5897
5929
  const collab = useCollaboration();
5930
+ const customization = useViewerCustomizationContext();
5931
+ const showSlidesToggle = isPanelVisible(customization, "slidesPane");
5932
+ const showInspectorToggle = isPanelVisible(customization, "inspector");
5933
+ const showComments = isFeatureEnabled(customization, "comments");
5934
+ const showShare = isDialogAvailable(customization, "share");
5935
+ const showSettings = isDialogAvailable(customization, "options");
5898
5936
  const qab = "p-1 max-md:p-2 max-md:min-h-[40px] max-md:min-w-[40px] rounded-sm transition-colors hover:bg-accent/60 disabled:opacity-40 disabled:cursor-not-allowed active:scale-90 active:opacity-70";
5899
5937
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 max-md:gap-0 px-1.5 py-0.5 max-md:px-1", children: [
5900
- mode !== "present" && /* @__PURE__ */ jsx(
5938
+ mode !== "present" && showSlidesToggle && /* @__PURE__ */ jsx(
5901
5939
  "button",
5902
5940
  {
5903
5941
  type: "button",
@@ -5909,7 +5947,7 @@ function ToolbarPrimaryRow(p) {
5909
5947
  }
5910
5948
  ),
5911
5949
  /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-2 max-md:min-w-1" }),
5912
- (mode === "edit" || mode === "master") && /* @__PURE__ */ jsxs(
5950
+ (mode === "edit" || mode === "master") && showComments && /* @__PURE__ */ jsxs(
5913
5951
  "button",
5914
5952
  {
5915
5953
  type: "button",
@@ -5927,7 +5965,7 @@ function ToolbarPrimaryRow(p) {
5927
5965
  ]
5928
5966
  }
5929
5967
  ),
5930
- collab && (collab.status === "connected" || collab.status === "connecting") && collab.remoteUsers.length > 0 && /* @__PURE__ */ jsx(
5968
+ collab && showShare && (collab.status === "connected" || collab.status === "connecting") && collab.remoteUsers.length > 0 && /* @__PURE__ */ jsx(
5931
5969
  "button",
5932
5970
  {
5933
5971
  type: "button",
@@ -5976,7 +6014,7 @@ function ToolbarPrimaryRow(p) {
5976
6014
  }
5977
6015
  ),
5978
6016
  sep,
5979
- (mode === "edit" || mode === "master") && /* @__PURE__ */ jsx(
6017
+ (mode === "edit" || mode === "master") && showInspectorToggle && /* @__PURE__ */ jsx(
5980
6018
  "button",
5981
6019
  {
5982
6020
  type: "button",
@@ -5998,7 +6036,7 @@ function ToolbarPrimaryRow(p) {
5998
6036
  children: /* @__PURE__ */ jsx(LuSparkles, { className: ic })
5999
6037
  }
6000
6038
  ),
6001
- /* @__PURE__ */ jsx(
6039
+ showSettings && /* @__PURE__ */ jsx(
6002
6040
  "button",
6003
6041
  {
6004
6042
  type: "button",
@@ -6027,6 +6065,7 @@ function Toolbar(p) {
6027
6065
  const { t } = useTranslation();
6028
6066
  const { isTabVisible } = useToolbarVisibility(p.hiddenActions);
6029
6067
  const viewerOptions = useViewerOptionsContext();
6068
+ const customization = useViewerCustomizationContext();
6030
6069
  if (isNarrowViewport && mode !== "present") {
6031
6070
  return /* @__PURE__ */ jsx(MobileToolbar, { ...p });
6032
6071
  }
@@ -6102,7 +6141,7 @@ function Toolbar(p) {
6102
6141
  ]
6103
6142
  }
6104
6143
  ),
6105
- showRibbon && viewerOptions.quickAccess.position === "below" && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 border-b border-border/60 px-2 py-1", children: /* @__PURE__ */ jsx(
6144
+ showRibbon && viewerOptions.quickAccess.position === "below" && isPanelVisible(customization, "quickAccessToolbar") && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 border-b border-border/60 px-2 py-1", children: /* @__PURE__ */ jsx(
6106
6145
  TitleBarQuickExtras,
6107
6146
  {
6108
6147
  quickAccess: viewerOptions.quickAccess,
@@ -6293,6 +6332,7 @@ function Toolbar(p) {
6293
6332
  {
6294
6333
  canEdit: p.canEdit,
6295
6334
  selectedElement: p.selectedElement,
6335
+ activeSlide: p.activeSlide,
6296
6336
  isInspectorPaneOpen: p.isInspectorPaneOpen,
6297
6337
  onToggleInspector: p.onToggleInspector,
6298
6338
  onOpenAnimationPanel: p.onOpenAnimationPanel,
@@ -7588,6 +7628,7 @@ function isViewportBackgroundMouseDownTarget(target, currentTarget) {
7588
7628
  function useCanvasEventHandlers({
7589
7629
  cbRef,
7590
7630
  onCanvasMouseDown,
7631
+ onCanvasContextMenu,
7591
7632
  findResults,
7592
7633
  findResultIndex,
7593
7634
  activeSlideIndex,
@@ -7705,9 +7746,11 @@ function useCanvasEventHandlers({
7705
7746
  const id = getElementIdFromEvent(e);
7706
7747
  if (id) {
7707
7748
  cbRef.current.onContextMenu(id, e);
7749
+ return;
7708
7750
  }
7751
+ onCanvasContextMenu?.(e);
7709
7752
  },
7710
- [cbRef]
7753
+ [cbRef, onCanvasContextMenu]
7711
7754
  );
7712
7755
  const [draggingGuide, setDraggingGuide] = useState(null);
7713
7756
  const handleStagePointerMove = useCallback(
@@ -8288,6 +8331,7 @@ function SlideCanvasContent({
8288
8331
  onMouseDown,
8289
8332
  onContextMenu,
8290
8333
  onCanvasMouseDown,
8334
+ onCanvasContextMenu,
8291
8335
  onResizePointerDown,
8292
8336
  onAdjustmentPointerDown,
8293
8337
  onRotate,
@@ -8388,6 +8432,7 @@ function SlideCanvasContent({
8388
8432
  } = useCanvasEventHandlers({
8389
8433
  cbRef,
8390
8434
  onCanvasMouseDown,
8435
+ onCanvasContextMenu,
8391
8436
  findResults,
8392
8437
  findResultIndex,
8393
8438
  activeSlideIndex,
@@ -9276,6 +9321,7 @@ function contextMenuContext(props) {
9276
9321
  table: tableCell(props),
9277
9322
  hasMultiSelection: Boolean(props.hasMultiSelection),
9278
9323
  selectionGroupable: props.selectionGroupable,
9324
+ hasClipboard: props.hasClipboard,
9279
9325
  // Both AI entries appear together or not at all, so a viewer that wired
9280
9326
  // only one of them does not produce a menu the other bindings cannot match.
9281
9327
  aiEnabled: Boolean(props.onAskAi) && Boolean(props.onFixAi)
@@ -9327,27 +9373,58 @@ function ContextMenuItem({
9327
9373
  onSelect,
9328
9374
  danger,
9329
9375
  disabled,
9376
+ checked,
9330
9377
  children
9331
9378
  }) {
9332
- return /* @__PURE__ */ jsx(
9379
+ return /* @__PURE__ */ jsxs(
9333
9380
  "button",
9334
9381
  {
9335
9382
  type: "button",
9336
- role: "menuitem",
9383
+ role: checked === void 0 ? "menuitem" : "menuitemcheckbox",
9384
+ "aria-checked": checked === void 0 ? void 0 : checked,
9337
9385
  disabled,
9338
9386
  className: `${danger ? DANGER_ITEM_CLASS : ITEM_CLASS}${disabled ? DISABLED_CLASS : ""}`,
9339
9387
  onClick: onSelect,
9340
- children
9388
+ children: [
9389
+ checked !== void 0 && /* @__PURE__ */ jsx("span", { className: "mr-1.5 inline-block w-3", "aria-hidden": "true", children: checked ? "\u2713" : "" }),
9390
+ children
9391
+ ]
9341
9392
  }
9342
9393
  );
9343
9394
  }
9344
9395
  function ContextMenuSeparator() {
9345
9396
  return /* @__PURE__ */ jsx("div", { role: "separator", "aria-orientation": "horizontal", className: "my-1 border-t border-border" });
9346
9397
  }
9398
+ function useClampedMenuPosition(x, y) {
9399
+ const [size, setSize] = useState({ width: 0, height: 0 });
9400
+ const ref = useCallback((node) => {
9401
+ if (!node) {
9402
+ return;
9403
+ }
9404
+ const rect = node.getBoundingClientRect();
9405
+ setSize(
9406
+ (previous) => previous.width === rect.width && previous.height === rect.height ? previous : { width: rect.width, height: rect.height }
9407
+ );
9408
+ }, []);
9409
+ const { left, top } = clampFlyoutPosition({
9410
+ x,
9411
+ y,
9412
+ width: size.width,
9413
+ height: size.height,
9414
+ viewportWidth: typeof window === "undefined" ? 0 : window.innerWidth,
9415
+ viewportHeight: typeof window === "undefined" ? 0 : window.innerHeight
9416
+ });
9417
+ return { ref, left, top };
9418
+ }
9347
9419
  function ContextMenu(props) {
9348
9420
  const { contextMenuState, mode, onClose } = props;
9349
9421
  const { t } = useTranslation();
9422
+ const customization = useViewerCustomizationContext();
9350
9423
  const open = Boolean(contextMenuState) && mode === "edit";
9424
+ const menuPosition = useClampedMenuPosition(
9425
+ contextMenuState?.x ?? 0,
9426
+ contextMenuState?.y ?? 0
9427
+ );
9351
9428
  useEffect(() => {
9352
9429
  if (!open) {
9353
9430
  return;
@@ -9365,7 +9442,13 @@ function ContextMenu(props) {
9365
9442
  return null;
9366
9443
  }
9367
9444
  const handlers = contextMenuHandlers(props);
9368
- const entries = buildContextMenuEntries(contextMenuContext(props));
9445
+ const entries = customizeContextMenuEntries(
9446
+ buildContextMenuEntries(contextMenuContext(props)),
9447
+ customization
9448
+ );
9449
+ if (entries.length === 0) {
9450
+ return null;
9451
+ }
9369
9452
  return /* @__PURE__ */ jsxs(Fragment, { children: [
9370
9453
  /* @__PURE__ */ jsx(
9371
9454
  "div",
@@ -9381,13 +9464,14 @@ function ContextMenu(props) {
9381
9464
  /* @__PURE__ */ jsx(
9382
9465
  "div",
9383
9466
  {
9467
+ ref: menuPosition.ref,
9384
9468
  "data-pptx-context-menu": "true",
9385
9469
  role: "menu",
9386
9470
  "aria-label": t("pptx.contextMenu.ariaLabel"),
9387
9471
  className: "fixed z-[120] min-w-[180px] rounded border border-border bg-popover shadow-2xl py-1.5 text-xs text-foreground",
9388
9472
  style: {
9389
- left: Math.max(contextMenuState.x, 8),
9390
- top: Math.max(contextMenuState.y, 8)
9473
+ left: menuPosition.left,
9474
+ top: menuPosition.top
9391
9475
  },
9392
9476
  children: entries.map((entry) => {
9393
9477
  const run = handlers[entry.id];
@@ -9408,6 +9492,106 @@ function ContextMenu(props) {
9408
9492
  )
9409
9493
  ] });
9410
9494
  }
9495
+
9496
+ // src/viewer/components/canvas-context-menu-dispatch.ts
9497
+ function canvasContextMenuContext(props) {
9498
+ return {
9499
+ hasClipboard: props.hasClipboard,
9500
+ showGrid: props.showGrid,
9501
+ showRulers: props.showRulers
9502
+ };
9503
+ }
9504
+ function canvasContextMenuHandlers(props) {
9505
+ const { onClose } = props;
9506
+ const andClose = (run) => () => {
9507
+ run();
9508
+ onClose();
9509
+ };
9510
+ return {
9511
+ paste: andClose(props.onPaste),
9512
+ layout: andClose(props.onOpenLayoutGallery),
9513
+ "reset-slide": andClose(props.onResetSlide),
9514
+ "format-background": andClose(props.onOpenFormatBackground),
9515
+ "grid-and-guides": andClose(props.onToggleGrid),
9516
+ ruler: andClose(props.onToggleRulers)
9517
+ };
9518
+ }
9519
+ function CanvasContextMenu(props) {
9520
+ const { canvasContextMenuState, mode, onClose } = props;
9521
+ const { t } = useTranslation();
9522
+ const customization = useViewerCustomizationContext();
9523
+ const open = Boolean(canvasContextMenuState) && mode === "edit";
9524
+ const menuPosition = useClampedMenuPosition(
9525
+ canvasContextMenuState?.x ?? 0,
9526
+ canvasContextMenuState?.y ?? 0
9527
+ );
9528
+ useEffect(() => {
9529
+ if (!open) {
9530
+ return;
9531
+ }
9532
+ const onKeyDown = (event) => {
9533
+ if (event.key === "Escape") {
9534
+ event.preventDefault();
9535
+ onClose();
9536
+ }
9537
+ };
9538
+ document.addEventListener("keydown", onKeyDown);
9539
+ return () => document.removeEventListener("keydown", onKeyDown);
9540
+ }, [open, onClose]);
9541
+ if (!open) {
9542
+ return null;
9543
+ }
9544
+ const handlers = canvasContextMenuHandlers(props);
9545
+ const entries = customizeCanvasContextMenuEntries(
9546
+ buildCanvasContextMenuEntries(canvasContextMenuContext(props)),
9547
+ customization
9548
+ );
9549
+ if (entries.length === 0) {
9550
+ return null;
9551
+ }
9552
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
9553
+ /* @__PURE__ */ jsx(
9554
+ "div",
9555
+ {
9556
+ className: "fixed inset-0 z-[119]",
9557
+ onClick: onClose,
9558
+ onContextMenu: (e) => {
9559
+ e.preventDefault();
9560
+ onClose();
9561
+ }
9562
+ }
9563
+ ),
9564
+ /* @__PURE__ */ jsx(
9565
+ "div",
9566
+ {
9567
+ ref: menuPosition.ref,
9568
+ "data-pptx-canvas-context-menu": "true",
9569
+ role: "menu",
9570
+ "aria-label": t("pptx.canvasContextMenu.ariaLabel"),
9571
+ className: "fixed z-[120] min-w-[180px] rounded border border-border bg-popover shadow-2xl py-1.5 text-xs text-foreground",
9572
+ style: {
9573
+ left: menuPosition.left,
9574
+ top: menuPosition.top
9575
+ },
9576
+ children: entries.map((entry) => {
9577
+ const run = handlers[entry.id];
9578
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
9579
+ entry.separatorBefore && /* @__PURE__ */ jsx(ContextMenuSeparator, {}),
9580
+ /* @__PURE__ */ jsx(
9581
+ ContextMenuItem,
9582
+ {
9583
+ disabled: entry.disabled || !run,
9584
+ checked: entry.checked,
9585
+ onSelect: () => run?.(),
9586
+ children: t(entry.labelKey)
9587
+ }
9588
+ )
9589
+ ] }, entry.id);
9590
+ })
9591
+ }
9592
+ )
9593
+ ] });
9594
+ }
9411
9595
  var ic2 = "w-3.5 h-3.5";
9412
9596
  var btnBase = "inline-flex items-center justify-center rounded p-1 transition-colors disabled:opacity-40 disabled:cursor-not-allowed";
9413
9597
  var btnGhost = `${btnBase} hover:bg-accent text-muted-foreground hover:text-foreground`;
@@ -9743,30 +9927,83 @@ function SectionHeader({
9743
9927
  }
9744
9928
  function SlideContextMenu({
9745
9929
  state,
9930
+ slides,
9931
+ onAddSlideAfter,
9932
+ onDuplicateSlides,
9933
+ onDeleteSlides,
9934
+ onHideSlides,
9935
+ onOpenLayoutForSlide,
9746
9936
  onAddSection,
9747
9937
  onClose
9748
9938
  }) {
9749
9939
  const { t } = useTranslation();
9750
- return /* @__PURE__ */ jsx(
9751
- "div",
9752
- {
9753
- className: "fixed z-50 min-w-[180px] rounded-md border border-border bg-popover py-1 shadow-xl",
9754
- style: { left: state.x, top: state.y },
9755
- onClick: (e) => e.stopPropagation(),
9756
- children: /* @__PURE__ */ jsx(
9757
- "button",
9758
- {
9759
- type: "button",
9760
- className: "flex w-full items-center px-3 py-1.5 text-xs text-foreground hover:bg-muted",
9761
- onClick: () => {
9762
- onAddSection?.(t("pptx.sections.defaultName"), state.slideIndex);
9763
- onClose();
9764
- },
9765
- children: t("pptx.sections.addBefore")
9766
- }
9767
- )
9940
+ useEffect(() => {
9941
+ const onKeyDown = (event) => {
9942
+ if (event.key === "Escape") {
9943
+ event.preventDefault();
9944
+ onClose();
9945
+ }
9946
+ };
9947
+ document.addEventListener("keydown", onKeyDown);
9948
+ return () => document.removeEventListener("keydown", onKeyDown);
9949
+ }, [onClose]);
9950
+ const selected = state.selectedIndexes;
9951
+ const selectedSlides = selected.map((i) => slides[i]).filter((s) => Boolean(s));
9952
+ const entries = buildSlidePaneContextMenuEntries({
9953
+ selectedCount: selected.length,
9954
+ hasHiddenInSelection: selectedSlides.some((s) => s.hidden),
9955
+ hasVisibleInSelection: selectedSlides.some((s) => !s.hidden),
9956
+ wouldDeleteAllSlides: selected.length >= slides.length
9957
+ });
9958
+ const run = (id) => {
9959
+ switch (id) {
9960
+ case "new-slide":
9961
+ onAddSlideAfter(state.slideIndex);
9962
+ break;
9963
+ case "duplicate":
9964
+ onDuplicateSlides(selected);
9965
+ break;
9966
+ case "delete":
9967
+ onDeleteSlides(selected);
9968
+ break;
9969
+ case "layout":
9970
+ onOpenLayoutForSlide(state.slideIndex, state.x, state.y);
9971
+ break;
9972
+ case "hide":
9973
+ onHideSlides(selected);
9974
+ break;
9975
+ case "add-section":
9976
+ onAddSection?.(t("pptx.sections.defaultName"), state.slideIndex);
9977
+ break;
9768
9978
  }
9769
- );
9979
+ onClose();
9980
+ };
9981
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
9982
+ /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-[119]", onClick: onClose }),
9983
+ /* @__PURE__ */ jsx(
9984
+ "div",
9985
+ {
9986
+ "data-pptx-context-menu": "true",
9987
+ "data-pptx-slide-pane-context-menu": "true",
9988
+ role: "menu",
9989
+ "aria-label": t("pptx.slidesPane.contextMenu.newSlide"),
9990
+ className: "fixed z-[120] min-w-[190px] rounded border border-border bg-popover shadow-2xl py-1.5 text-xs text-foreground",
9991
+ style: { left: state.x, top: state.y },
9992
+ children: entries.map((entry) => /* @__PURE__ */ jsxs("span", { children: [
9993
+ entry.separatorBefore && /* @__PURE__ */ jsx(ContextMenuSeparator, {}),
9994
+ /* @__PURE__ */ jsx(
9995
+ ContextMenuItem,
9996
+ {
9997
+ danger: entry.id === "delete",
9998
+ disabled: entry.disabled,
9999
+ onSelect: () => run(entry.id),
10000
+ children: entry.countLabelKey ? t(entry.labelKey, { count: selected.length }) : t(entry.labelKey)
10001
+ }
10002
+ )
10003
+ ] }, entry.id))
10004
+ }
10005
+ )
10006
+ ] });
9770
10007
  }
9771
10008
  function LazyThumbnailInner({
9772
10009
  slide,
@@ -9865,6 +10102,7 @@ function SlideItemInner({
9865
10102
  templateElements,
9866
10103
  slideIndex,
9867
10104
  isActive,
10105
+ isSelected = false,
9868
10106
  canvasSize,
9869
10107
  canEdit,
9870
10108
  rehearsalTimings,
@@ -9873,7 +10111,6 @@ function SlideItemInner({
9873
10111
  tableStyleContext,
9874
10112
  onSelectSlide,
9875
10113
  onSlideContextMenu,
9876
- onAddSection,
9877
10114
  onOpenSlideCtxMenu,
9878
10115
  onDragStart,
9879
10116
  onDragOver,
@@ -9885,7 +10122,7 @@ function SlideItemInner({
9885
10122
  const cue = hiddenSlideCue(slide.hidden, "rail", slideIndex);
9886
10123
  const handleContextMenu = useCallback(
9887
10124
  (e) => {
9888
- if (canEdit && onAddSection) {
10125
+ if (canEdit) {
9889
10126
  e.preventDefault();
9890
10127
  e.stopPropagation();
9891
10128
  onOpenSlideCtxMenu(e.clientX, e.clientY, slideIndex);
@@ -9893,7 +10130,7 @@ function SlideItemInner({
9893
10130
  onSlideContextMenu(e, slideIndex);
9894
10131
  }
9895
10132
  },
9896
- [canEdit, onAddSection, onOpenSlideCtxMenu, onSlideContextMenu, slideIndex]
10133
+ [canEdit, onOpenSlideCtxMenu, onSlideContextMenu, slideIndex]
9897
10134
  );
9898
10135
  const safeCanvasWidth = Math.max(canvasSize.width, 1);
9899
10136
  const safeCanvasHeight = Math.max(canvasSize.height, 1);
@@ -9911,10 +10148,11 @@ function SlideItemInner({
9911
10148
  className: cn(
9912
10149
  "group relative flex w-full items-center gap-1 cursor-pointer border-0 bg-transparent py-0.5 px-1 text-left transition-all",
9913
10150
  isActive && "bg-accent/40 before:absolute before:left-0 before:top-1 before:bottom-1 before:w-[3px] before:bg-primary before:rounded-r",
10151
+ isSelected && !isActive && "bg-accent/20 ring-1 ring-inset ring-primary/50",
9914
10152
  isHidden && "opacity-50"
9915
10153
  ),
9916
10154
  draggable: canEdit,
9917
- onClick: () => onSelectSlide(slideIndex),
10155
+ onClick: (e) => onSelectSlide(slideIndex, e),
9918
10156
  onContextMenu: handleContextMenu,
9919
10157
  onDragStart: (e) => onDragStart(e, slideIndex),
9920
10158
  onDragOver,
@@ -9988,6 +10226,24 @@ function useSlidePaneCallbacks(onMoveSlide, onRenameSection, onToggleSectionColl
9988
10226
  null
9989
10227
  );
9990
10228
  const [slideCtxMenu, setSlideCtxMenu] = useState(null);
10229
+ const [selectedSlideIds, setSelectedSlideIds] = useState([]);
10230
+ const [selectionAnchorId, setSelectionAnchorId] = useState(null);
10231
+ const handleSlideClick = useCallback(
10232
+ (event, slideId, orderedIds) => {
10233
+ const result = resolveSlidePaneClick({
10234
+ clickedId: slideId,
10235
+ orderedIds,
10236
+ selectedIds: selectedSlideIds,
10237
+ anchorId: selectionAnchorId,
10238
+ ctrlKey: event.ctrlKey,
10239
+ metaKey: event.metaKey,
10240
+ shiftKey: event.shiftKey
10241
+ });
10242
+ setSelectedSlideIds(result.selectedIds);
10243
+ setSelectionAnchorId(result.anchorId);
10244
+ },
10245
+ [selectedSlideIds, selectionAnchorId]
10246
+ );
9991
10247
  useEffect(() => {
9992
10248
  if (!sectionContextMenu && !slideCtxMenu) {
9993
10249
  return;
@@ -10058,9 +10314,12 @@ function useSlidePaneCallbacks(onMoveSlide, onRenameSection, onToggleSectionColl
10058
10314
  },
10059
10315
  []
10060
10316
  );
10061
- const handleOpenSlideCtxMenu = useCallback((x, y, slideIndex) => {
10062
- setSlideCtxMenu({ x, y, slideIndex });
10063
- }, []);
10317
+ const handleOpenSlideCtxMenu = useCallback(
10318
+ (x, y, slideIndex, selectedIndexes) => {
10319
+ setSlideCtxMenu({ x, y, slideIndex, selectedIndexes });
10320
+ },
10321
+ []
10322
+ );
10064
10323
  const closeSectionContextMenu = useCallback(() => {
10065
10324
  setSectionContextMenu(null);
10066
10325
  }, []);
@@ -10084,7 +10343,9 @@ function useSlidePaneCallbacks(onMoveSlide, onRenameSection, onToggleSectionColl
10084
10343
  handleSectionContextMenu,
10085
10344
  handleOpenSlideCtxMenu,
10086
10345
  closeSectionContextMenu,
10087
- closeSlideCtxMenu
10346
+ closeSlideCtxMenu,
10347
+ selectedSlideIds,
10348
+ handleSlideClick
10088
10349
  };
10089
10350
  }
10090
10351
  var EMPTY_TEMPLATE_ELEMENTS = [];
@@ -10101,6 +10362,11 @@ function SlidesPaneSidebar({
10101
10362
  onSlideContextMenu,
10102
10363
  onMoveSlide,
10103
10364
  onAddSlide,
10365
+ onAddSlideAfter,
10366
+ onDuplicateSlides,
10367
+ onDeleteSlides,
10368
+ onHideSlides,
10369
+ onOpenLayoutForSlide,
10104
10370
  onCollapse: _onCollapse,
10105
10371
  onAddSection,
10106
10372
  onRenameSection,
@@ -10156,8 +10422,46 @@ function SlidesPaneSidebar({
10156
10422
  handleSectionContextMenu,
10157
10423
  handleOpenSlideCtxMenu,
10158
10424
  closeSectionContextMenu,
10159
- closeSlideCtxMenu
10425
+ closeSlideCtxMenu,
10426
+ selectedSlideIds,
10427
+ handleSlideClick
10160
10428
  } = useSlidePaneCallbacks(onMoveSlide, onRenameSection, onToggleSectionCollapse);
10429
+ const orderedIds = useMemo(() => slides.map((s) => s.id), [slides]);
10430
+ const selectSlide = useCallback(
10431
+ (index, e) => {
10432
+ const slide = slides[index];
10433
+ if (slide) {
10434
+ handleSlideClick(
10435
+ { ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey },
10436
+ slide.id,
10437
+ orderedIds
10438
+ );
10439
+ }
10440
+ onSelectSlide(index);
10441
+ },
10442
+ [slides, orderedIds, handleSlideClick, onSelectSlide]
10443
+ );
10444
+ const openSlideCtxMenu = useCallback(
10445
+ (x, y, slideIndex) => {
10446
+ const slide = slides[slideIndex];
10447
+ if (!slide) {
10448
+ return;
10449
+ }
10450
+ const idsForMenu = selectedSlideIds.length > 0 && selectedSlideIds.includes(slide.id) ? selectedSlideIds : [slide.id];
10451
+ const selectedIndexes = idsForMenu.map((id) => slides.findIndex((s) => s.id === id)).filter((i) => i !== -1);
10452
+ handleOpenSlideCtxMenu(x, y, slideIndex, selectedIndexes);
10453
+ },
10454
+ [slides, selectedSlideIds, handleOpenSlideCtxMenu]
10455
+ );
10456
+ const onPaneKeyDown = useCallback(
10457
+ (e) => {
10458
+ if (e.key === "Enter" && canEdit) {
10459
+ e.preventDefault();
10460
+ onAddSlideAfter(activeSlideIndex);
10461
+ }
10462
+ },
10463
+ [canEdit, onAddSlideAfter, activeSlideIndex]
10464
+ );
10161
10465
  const effectiveCollapsed = useMemo(() => {
10162
10466
  const map = {};
10163
10467
  for (const group of sectionGroups) {
@@ -10260,16 +10564,16 @@ function SlidesPaneSidebar({
10260
10564
  templateElements: templateElementsBySlideId[slide.id] ?? EMPTY_TEMPLATE_ELEMENTS,
10261
10565
  slideIndex: item.slideIndex,
10262
10566
  isActive: item.slideIndex === activeSlideIndex,
10567
+ isSelected: selectedSlideIds.includes(slide.id),
10263
10568
  canvasSize,
10264
10569
  canEdit,
10265
10570
  rehearsalTimings,
10266
10571
  presenceUsers: slidePresenceMap?.get(item.slideIndex),
10267
10572
  fieldContext,
10268
10573
  tableStyleContext,
10269
- onSelectSlide,
10574
+ onSelectSlide: selectSlide,
10270
10575
  onSlideContextMenu,
10271
- onAddSection,
10272
- onOpenSlideCtxMenu: handleOpenSlideCtxMenu,
10576
+ onOpenSlideCtxMenu: openSlideCtxMenu,
10273
10577
  onDragStart: handleDragStart,
10274
10578
  onDragOver: handleDragOver,
10275
10579
  onDrop: handleDrop,
@@ -10317,16 +10621,16 @@ function SlidesPaneSidebar({
10317
10621
  templateElements: templateElementsBySlideId[slide.id] ?? EMPTY_TEMPLATE_ELEMENTS,
10318
10622
  slideIndex: idx,
10319
10623
  isActive: idx === activeSlideIndex,
10624
+ isSelected: selectedSlideIds.includes(slide.id),
10320
10625
  canvasSize,
10321
10626
  canEdit,
10322
10627
  rehearsalTimings,
10323
10628
  presenceUsers: slidePresenceMap?.get(idx),
10324
10629
  fieldContext,
10325
10630
  tableStyleContext,
10326
- onSelectSlide,
10631
+ onSelectSlide: selectSlide,
10327
10632
  onSlideContextMenu,
10328
- onAddSection,
10329
- onOpenSlideCtxMenu: handleOpenSlideCtxMenu,
10633
+ onOpenSlideCtxMenu: openSlideCtxMenu,
10330
10634
  onDragStart: handleDragStart,
10331
10635
  onDragOver: handleDragOver,
10332
10636
  onDrop: handleDrop,
@@ -10337,52 +10641,62 @@ function SlidesPaneSidebar({
10337
10641
  })
10338
10642
  ] }, section.id);
10339
10643
  }) });
10340
- return /* @__PURE__ */ jsxs(
10341
- "aside",
10342
- {
10343
- role: "navigation",
10344
- "aria-label": t("pptx.sections.slides"),
10345
- className: "flex h-full flex-col border-r border-border bg-secondary/30",
10346
- style: panelWidth ? { width: panelWidth, flexShrink: 0 } : void 0,
10347
- children: [
10348
- shouldVirtualize ? renderVirtualized() : renderNonVirtualized(),
10349
- canEdit && /* @__PURE__ */ jsx("div", { className: "border-t border-border/60 px-2 py-1.5", children: /* @__PURE__ */ jsxs(
10350
- "button",
10351
- {
10352
- type: "button",
10353
- className: "flex w-full items-center justify-center gap-1 rounded-sm px-2 py-1 text-[11px] text-muted-foreground hover:bg-accent hover:text-foreground transition-colors disabled:cursor-not-allowed disabled:opacity-40",
10354
- disabled: !canEdit,
10355
- onClick: onAddSlide,
10356
- children: [
10357
- /* @__PURE__ */ jsx(LuPlus, { className: "h-3 w-3" }),
10358
- t("pptx.sections.addSlide")
10359
- ]
10360
- }
10361
- ) }),
10362
- sectionContextMenu && /* @__PURE__ */ jsx(
10363
- SectionContextMenu,
10364
- {
10365
- state: sectionContextMenu,
10366
- sectionGroups,
10367
- totalSlides: slides.length,
10368
- onStartRename: startRename,
10369
- onDeleteSection,
10370
- onMoveSectionUp,
10371
- onMoveSectionDown,
10372
- onAddSection,
10373
- onClose: closeSectionContextMenu
10374
- }
10375
- ),
10376
- slideCtxMenu && /* @__PURE__ */ jsx(
10377
- SlideContextMenu,
10378
- {
10379
- state: slideCtxMenu,
10380
- onAddSection,
10381
- onClose: closeSlideCtxMenu
10382
- }
10383
- )
10384
- ]
10385
- }
10644
+ return (
10645
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- Enter here only catches the keydown bubbled up from a focused (interactive) thumbnail button; the aside itself has no interactive semantics of its own
10646
+ /* @__PURE__ */ jsxs(
10647
+ "aside",
10648
+ {
10649
+ role: "navigation",
10650
+ "aria-label": t("pptx.sections.slides"),
10651
+ className: "flex h-full flex-col border-r border-border bg-secondary/30",
10652
+ style: panelWidth ? { width: panelWidth, flexShrink: 0 } : void 0,
10653
+ onKeyDown: onPaneKeyDown,
10654
+ children: [
10655
+ shouldVirtualize ? renderVirtualized() : renderNonVirtualized(),
10656
+ canEdit && /* @__PURE__ */ jsx("div", { className: "border-t border-border/60 px-2 py-1.5", children: /* @__PURE__ */ jsxs(
10657
+ "button",
10658
+ {
10659
+ type: "button",
10660
+ className: "flex w-full items-center justify-center gap-1 rounded-sm px-2 py-1 text-[11px] text-muted-foreground hover:bg-accent hover:text-foreground transition-colors disabled:cursor-not-allowed disabled:opacity-40",
10661
+ disabled: !canEdit,
10662
+ onClick: onAddSlide,
10663
+ children: [
10664
+ /* @__PURE__ */ jsx(LuPlus, { className: "h-3 w-3" }),
10665
+ t("pptx.sections.addSlide")
10666
+ ]
10667
+ }
10668
+ ) }),
10669
+ sectionContextMenu && /* @__PURE__ */ jsx(
10670
+ SectionContextMenu,
10671
+ {
10672
+ state: sectionContextMenu,
10673
+ sectionGroups,
10674
+ totalSlides: slides.length,
10675
+ onStartRename: startRename,
10676
+ onDeleteSection,
10677
+ onMoveSectionUp,
10678
+ onMoveSectionDown,
10679
+ onAddSection,
10680
+ onClose: closeSectionContextMenu
10681
+ }
10682
+ ),
10683
+ slideCtxMenu && /* @__PURE__ */ jsx(
10684
+ SlideContextMenu,
10685
+ {
10686
+ state: slideCtxMenu,
10687
+ slides,
10688
+ onAddSlideAfter,
10689
+ onDuplicateSlides,
10690
+ onDeleteSlides,
10691
+ onHideSlides,
10692
+ onOpenLayoutForSlide,
10693
+ onAddSection,
10694
+ onClose: closeSlideCtxMenu
10695
+ }
10696
+ )
10697
+ ]
10698
+ }
10699
+ )
10386
10700
  );
10387
10701
  }
10388
10702
  var HANDOUT_SLIDES_PER_PAGE_OPTIONS = [1, 2, 3, 4, 6, 9];
@@ -30747,9 +31061,11 @@ function ViewerBottomPanels({
30747
31061
  onNotesHeightChange
30748
31062
  }) {
30749
31063
  const { isHidden } = useToolbarVisibility(hiddenActions);
31064
+ const customization = useViewerCustomizationContext();
31065
+ const showNotes = isPanelVisible(customization, "notes");
30750
31066
  return /* @__PURE__ */ jsxs(Fragment, { children: [
30751
- onResizeBottom && !isSlideNotesCollapsed && /* @__PURE__ */ jsx(ResizeHandle, { direction: "vertical", onResize: onResizeBottom }),
30752
- /* @__PURE__ */ jsx(
31067
+ showNotes && onResizeBottom && !isSlideNotesCollapsed && /* @__PURE__ */ jsx(ResizeHandle, { direction: "vertical", onResize: onResizeBottom }),
31068
+ showNotes && /* @__PURE__ */ jsx(
30753
31069
  SlideNotesPanel,
30754
31070
  {
30755
31071
  activeSlide,
@@ -30763,7 +31079,7 @@ function ViewerBottomPanels({
30763
31079
  onHeightChange: onNotesHeightChange
30764
31080
  }
30765
31081
  ),
30766
- !hideStatusBar && /* @__PURE__ */ jsx(
31082
+ !hideStatusBar && isPanelVisible(customization, "statusBar") && /* @__PURE__ */ jsx(
30767
31083
  StatusBar,
30768
31084
  {
30769
31085
  slideCount,
@@ -30781,7 +31097,7 @@ function ViewerBottomPanels({
30781
31097
  onToggleSlideSorter,
30782
31098
  collaborationSlot,
30783
31099
  hideZoomControls: isHidden("zoom"),
30784
- hideNotesToggle: isHidden("notes"),
31100
+ hideNotesToggle: isHidden("notes") || !showNotes,
30785
31101
  hideFullscreenToggle: isHidden("fullscreen")
30786
31102
  }
30787
31103
  )
@@ -30942,6 +31258,7 @@ function TitleBar(p) {
30942
31258
  const editing = (p.mode === "edit" || p.mode === "master") && p.canEdit;
30943
31259
  const { isHidden } = useToolbarVisibility(p.hiddenActions);
30944
31260
  const quickAccess = useViewerOptionsContext().quickAccess;
31261
+ const showQuickAccess = isPanelVisible(useViewerCustomizationContext(), "quickAccessToolbar");
30945
31262
  const [searchQuery, setSearchQuery] = useState("");
30946
31263
  const [searchFocused, setSearchFocused] = useState(false);
30947
31264
  const searchRef = useRef(null);
@@ -31017,7 +31334,7 @@ function TitleBar(p) {
31017
31334
  /* @__PURE__ */ jsx("span", { className: TITLE_BAR_CLASSES.autosaveLabel, children: t(p.autosaveEnabled ? "pptx.titleBar.autoSaveOn" : "pptx.titleBar.autoSaveOff") })
31018
31335
  ] }),
31019
31336
  /* @__PURE__ */ jsx("div", { className: TITLE_BAR_CLASSES.separator }),
31020
- p.onSave && /* @__PURE__ */ jsx(
31337
+ showQuickAccess && p.onSave && /* @__PURE__ */ jsx(
31021
31338
  "button",
31022
31339
  {
31023
31340
  type: "button",
@@ -31028,7 +31345,7 @@ function TitleBar(p) {
31028
31345
  children: /* @__PURE__ */ jsx(LuSave, { className: "w-3.5 h-3.5" })
31029
31346
  }
31030
31347
  ),
31031
- !isHidden("undo") && /* @__PURE__ */ jsx(
31348
+ showQuickAccess && !isHidden("undo") && /* @__PURE__ */ jsx(
31032
31349
  "button",
31033
31350
  {
31034
31351
  type: "button",
@@ -31040,7 +31357,7 @@ function TitleBar(p) {
31040
31357
  children: /* @__PURE__ */ jsx(LuUndo, { className: "w-3.5 h-3.5" })
31041
31358
  }
31042
31359
  ),
31043
- !isHidden("redo") && /* @__PURE__ */ jsx(
31360
+ showQuickAccess && !isHidden("redo") && /* @__PURE__ */ jsx(
31044
31361
  "button",
31045
31362
  {
31046
31363
  type: "button",
@@ -31052,8 +31369,8 @@ function TitleBar(p) {
31052
31369
  children: /* @__PURE__ */ jsx(LuRedo, { className: "w-3.5 h-3.5" })
31053
31370
  }
31054
31371
  ),
31055
- quickAccess.position !== "below" && /* @__PURE__ */ jsx(TitleBarQuickExtras, { quickAccess, onCommand: p.onQuickCommand }),
31056
- /* @__PURE__ */ jsx("div", { className: TITLE_BAR_CLASSES.separator })
31372
+ showQuickAccess && quickAccess.position !== "below" && /* @__PURE__ */ jsx(TitleBarQuickExtras, { quickAccess, onCommand: p.onQuickCommand }),
31373
+ showQuickAccess && /* @__PURE__ */ jsx("div", { className: TITLE_BAR_CLASSES.separator })
31057
31374
  ] }),
31058
31375
  /* @__PURE__ */ jsxs("span", { className: TITLE_BAR_CLASSES.fileGroup, children: [
31059
31376
  /* @__PURE__ */ jsx("span", { className: TITLE_BAR_CLASSES.fileName, children: p.fileName || t(TITLE_BAR_DEFAULT_FILE_KEY) }),
@@ -31179,6 +31496,7 @@ function ViewerToolbarSection(props) {
31179
31496
  onSetShowGuides
31180
31497
  } = props;
31181
31498
  const { t } = useTranslation();
31499
+ const customization = useViewerCustomizationContext();
31182
31500
  const handleAddAnimation = useCallback(
31183
31501
  (preset, group) => {
31184
31502
  if (!selectedElement || !activeSlide) {
@@ -31424,7 +31742,7 @@ function ViewerToolbarSection(props) {
31424
31742
  [onSetMode, onPresentFromBeginning, printHandlers, exportHandlers, slideOps, s, zoom]
31425
31743
  );
31426
31744
  return /* @__PURE__ */ jsxs(Fragment, { children: [
31427
- !dialogs.isNarrowViewport && /* @__PURE__ */ jsx(
31745
+ !dialogs.isNarrowViewport && isPanelVisible(customization, "titleBar") && /* @__PURE__ */ jsx(
31428
31746
  TitleBar,
31429
31747
  {
31430
31748
  mode,
@@ -32105,6 +32423,7 @@ function ViewerDialogGroup(props) {
32105
32423
  onKeepAnnotations,
32106
32424
  onDiscardAnnotations
32107
32425
  } = props;
32426
+ const printAvailable = isDialogAvailable(useViewerCustomizationContext(), "print");
32108
32427
  return /* @__PURE__ */ jsxs(Fragment, { children: [
32109
32428
  /* @__PURE__ */ jsx(
32110
32429
  VersionHistoryPanel,
@@ -32245,7 +32564,7 @@ function ViewerDialogGroup(props) {
32245
32564
  /* @__PURE__ */ jsx(
32246
32565
  PrintDialog,
32247
32566
  {
32248
- open: printHandlers.isPrintDialogOpen,
32567
+ open: printHandlers.isPrintDialogOpen && printAvailable,
32249
32568
  onClose: () => printHandlers.setIsPrintDialogOpen(false),
32250
32569
  onPrint: printHandlers.handlePrintSvg,
32251
32570
  slides,
@@ -32922,6 +33241,7 @@ ${url}`)) {
32922
33241
  onMouseDown: handleElementMouseDown,
32923
33242
  onContextMenu: canvasHandlers.handleElementContextMenu,
32924
33243
  onCanvasMouseDown: canvasHandlers.handleCanvasMouseDown,
33244
+ onCanvasContextMenu: canvasHandlers.handleCanvasContextMenu,
32925
33245
  onResizePointerDown: canvasHandlers.handleResizePointerDown,
32926
33246
  onAdjustmentPointerDown: canvasHandlers.handleAdjustmentPointerDown,
32927
33247
  onRotate: canvasHandlers.handleRotate,
@@ -33100,7 +33420,7 @@ function useTableStyleMapHandlers(input) {
33100
33420
  var AiChatPanel = lazy(async () => {
33101
33421
  const [{ useChat }, { default: Panel }] = await Promise.all([
33102
33422
  import('@ai-sdk/react'),
33103
- import('./AiChatPanel-QJHUDIWT.mjs')
33423
+ import('./AiChatPanel-L7DBCWE3.mjs')
33104
33424
  ]);
33105
33425
  function BoundAiChatPanel(props) {
33106
33426
  return /* @__PURE__ */ jsx(Panel, { ...props, useChat });
@@ -34023,15 +34343,17 @@ function ViewerSidePanels(props) {
34023
34343
  setTableStylesToDelete: s.setTableStylesToDelete
34024
34344
  });
34025
34345
  const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
34346
+ const customization = useViewerCustomizationContext();
34347
+ const inspectorOpen = (mode === "edit" || mode === "master") && s.isInspectorPaneOpen && isPanelVisible(customization, "inspector");
34026
34348
  const currentBuiltInTheme = BUILT_IN_THEMES.find(
34027
34349
  (candidate) => themeColorSchemesEqual(s.theme?.colorScheme, candidate.colorScheme)
34028
34350
  ) ?? null;
34029
34351
  return /* @__PURE__ */ jsxs(Fragment, { children: [
34030
- (mode === "edit" || mode === "master") && s.isInspectorPaneOpen && onResizeRight && /* @__PURE__ */ jsx(ResizeHandle, { direction: "horizontal", onResize: onResizeRight }),
34352
+ inspectorOpen && onResizeRight && /* @__PURE__ */ jsx(ResizeHandle, { direction: "horizontal", onResize: onResizeRight }),
34031
34353
  /* @__PURE__ */ jsx(
34032
34354
  ViewerInspector,
34033
34355
  {
34034
- isOpen: (mode === "edit" || mode === "master") && s.isInspectorPaneOpen,
34356
+ isOpen: inspectorOpen,
34035
34357
  canEdit,
34036
34358
  mode,
34037
34359
  activeSlide: effectiveSlide,
@@ -34201,7 +34523,9 @@ function ViewerMainContent(props) {
34201
34523
  hiddenActions,
34202
34524
  aiConfig,
34203
34525
  aiBridge,
34204
- aiPanel
34526
+ aiPanel,
34527
+ onApplyLayout,
34528
+ loadLayoutPreviews
34205
34529
  } = props;
34206
34530
  const {
34207
34531
  ops,
@@ -34228,6 +34552,11 @@ function ViewerMainContent(props) {
34228
34552
  () => state.theme || state.tableStyleMap ? { theme: state.theme, tableStyleMap: state.tableStyleMap } : void 0,
34229
34553
  [state.theme, state.tableStyleMap]
34230
34554
  );
34555
+ const [layoutGalleryAnchor, setLayoutGalleryAnchor] = useState(
34556
+ null
34557
+ );
34558
+ const layoutGalleryAnchorRef = useRef(null);
34559
+ const layoutGalleryPreviews = useLayoutPreviews(loadLayoutPreviews, layoutGalleryAnchor !== null);
34231
34560
  return /* @__PURE__ */ jsx(ChartPartSelectionProvider, { children: /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-1 min-h-0", children: [
34232
34561
  showSlidesPane && /* @__PURE__ */ jsxs(Fragment, { children: [
34233
34562
  /* @__PURE__ */ jsx(
@@ -34244,6 +34573,14 @@ function ViewerMainContent(props) {
34244
34573
  onSlideContextMenu: slideOps.handleSlideContextMenu,
34245
34574
  onMoveSlide: slideOps.handleMoveSlide,
34246
34575
  onAddSlide: slideOps.handleAddSlide,
34576
+ onAddSlideAfter: slideOps.handleAddSlideAfter,
34577
+ onDuplicateSlides: slideOps.handleDuplicateSlides,
34578
+ onDeleteSlides: slideOps.handleDeleteSlides,
34579
+ onHideSlides: slideOps.handleToggleHideSlides,
34580
+ onOpenLayoutForSlide: (index, x, y) => {
34581
+ state.setActiveSlideIndex(index);
34582
+ setLayoutGalleryAnchor({ x, y });
34583
+ },
34247
34584
  onCollapse: () => state.setIsSlidesPaneOpen(false),
34248
34585
  onAddSection: sectionOps.addSection,
34249
34586
  onRenameSection: sectionOps.renameSection,
@@ -34361,6 +34698,7 @@ function ViewerMainContent(props) {
34361
34698
  tableEditorState: state.tableEditorState,
34362
34699
  hasMultiSelection: state.effectiveSelectedIds.length > 1,
34363
34700
  selectionGroupable: manipulation.selectionGroupable,
34701
+ hasClipboard: Boolean(state.clipboardPayload),
34364
34702
  onAction: manipulation.handleContextMenuAction,
34365
34703
  onInsertTableRow: tableOps.handleInsertTableRow,
34366
34704
  onDeleteTableRow: tableOps.handleDeleteTableRow,
@@ -34381,6 +34719,67 @@ function ViewerMainContent(props) {
34381
34719
  onClose: () => state.setContextMenuState(null)
34382
34720
  }
34383
34721
  ),
34722
+ state.canvasContextMenuState && /* @__PURE__ */ jsx(
34723
+ CanvasContextMenu,
34724
+ {
34725
+ canvasContextMenuState: state.canvasContextMenuState,
34726
+ mode,
34727
+ hasClipboard: Boolean(state.clipboardPayload),
34728
+ showGrid: state.showGrid,
34729
+ showRulers: state.showRulers,
34730
+ onPaste: () => manipulation.handlePaste(),
34731
+ onOpenLayoutGallery: () => {
34732
+ const pos = state.canvasContextMenuState;
34733
+ if (pos) {
34734
+ setLayoutGalleryAnchor(pos);
34735
+ }
34736
+ },
34737
+ onResetSlide: () => {
34738
+ const path = resetSlideLayoutPath(activeSlide);
34739
+ if (path) {
34740
+ onApplyLayout?.(path);
34741
+ }
34742
+ },
34743
+ onOpenFormatBackground: () => {
34744
+ state.setSelectedElementId(null);
34745
+ state.setSelectedElementIds([]);
34746
+ state.setSidebarPanelMode("properties");
34747
+ state.setIsInspectorPaneOpen(true);
34748
+ },
34749
+ onToggleGrid: () => state.setShowGrid((v) => !v),
34750
+ onToggleRulers: () => state.setShowRulers((v) => !v),
34751
+ onClose: () => state.setCanvasContextMenuState(null)
34752
+ }
34753
+ ),
34754
+ layoutGalleryAnchor && /* @__PURE__ */ jsxs(Fragment, { children: [
34755
+ /* @__PURE__ */ jsx(
34756
+ "div",
34757
+ {
34758
+ ref: layoutGalleryAnchorRef,
34759
+ style: {
34760
+ position: "fixed",
34761
+ left: layoutGalleryAnchor.x,
34762
+ top: layoutGalleryAnchor.y,
34763
+ width: 0,
34764
+ height: 0
34765
+ }
34766
+ }
34767
+ ),
34768
+ /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-[119]", onClick: () => setLayoutGalleryAnchor(null) }),
34769
+ /* @__PURE__ */ jsx(
34770
+ LayoutGalleryMenu,
34771
+ {
34772
+ anchorRef: layoutGalleryAnchorRef,
34773
+ layoutOptions: state.layoutOptions,
34774
+ previews: layoutGalleryPreviews,
34775
+ currentLayoutPath: activeSlide?.layoutPath,
34776
+ onSelect: (layout) => {
34777
+ onApplyLayout?.(layout.path);
34778
+ setLayoutGalleryAnchor(null);
34779
+ }
34780
+ }
34781
+ )
34782
+ ] }),
34384
34783
  /* @__PURE__ */ jsx(
34385
34784
  ViewerSidePanels,
34386
34785
  {
@@ -34868,6 +35267,14 @@ function MobileChromeOverlay(props) {
34868
35267
  onSlideContextMenu: editorOps.slideOps.handleSlideContextMenu,
34869
35268
  onMoveSlide: editorOps.slideOps.handleMoveSlide,
34870
35269
  onAddSlide: editorOps.slideOps.handleAddSlide,
35270
+ onAddSlideAfter: editorOps.slideOps.handleAddSlideAfter,
35271
+ onDuplicateSlides: editorOps.slideOps.handleDuplicateSlides,
35272
+ onDeleteSlides: editorOps.slideOps.handleDeleteSlides,
35273
+ onHideSlides: editorOps.slideOps.handleToggleHideSlides,
35274
+ onOpenLayoutForSlide: (index) => {
35275
+ s.setActiveSlideIndex(index);
35276
+ s.setIsSlidesPaneOpen(false);
35277
+ },
34871
35278
  onCollapse: () => s.setIsSlidesPaneOpen(false),
34872
35279
  onAddSection: editorOps.sectionOps.addSection,
34873
35280
  onRenameSection: editorOps.sectionOps.renameSection,
@@ -35145,10 +35552,11 @@ function readValue(options, control) {
35145
35552
  function InfoTip({ text }) {
35146
35553
  return /* @__PURE__ */ jsx("span", { title: text, className: "inline-flex cursor-help align-middle", children: /* @__PURE__ */ jsx(LuInfo, { className: "ml-1 h-3.5 w-3.5 text-primary/70", "aria-label": text }) });
35147
35554
  }
35555
+ var IGNORE_CHANGE = () => void 0;
35148
35556
  function ControlRow({
35149
35557
  control,
35150
35558
  options,
35151
- onOptionChange
35559
+ onOptionChange: emitChange
35152
35560
  }) {
35153
35561
  const { t } = useTranslation();
35154
35562
  const { viewportWidth } = useIsMobile();
@@ -35158,6 +35566,9 @@ function ControlRow({
35158
35566
  const info = control.infoKey ? /* @__PURE__ */ jsx(InfoTip, { text: t(control.infoKey) }) : null;
35159
35567
  const rowClass = cn("flex items-center justify-between gap-3 py-1.5", control.indent && "pl-6");
35160
35568
  const rowStyle = { minHeight: fieldMinHeight };
35569
+ const locked = control.readOnly === true;
35570
+ const lockedTitle = locked ? t("pptx.options.lockedByHost") : void 0;
35571
+ const onOptionChange = locked ? IGNORE_CHANGE : emitChange;
35161
35572
  if (control.kind === "toggle") {
35162
35573
  return /* @__PURE__ */ jsxs("label", { className: cn(rowClass, "cursor-pointer select-none"), style: rowStyle, children: [
35163
35574
  /* @__PURE__ */ jsxs("span", { className: "text-sm text-foreground", children: [
@@ -35169,6 +35580,8 @@ function ControlRow({
35169
35580
  {
35170
35581
  checked: value === true,
35171
35582
  "aria-label": label,
35583
+ disabled: locked,
35584
+ title: lockedTitle,
35172
35585
  onChange: (event) => onOptionChange(
35173
35586
  control.group,
35174
35587
  control.key,
@@ -35188,6 +35601,8 @@ function ControlRow({
35188
35601
  WebSelect,
35189
35602
  {
35190
35603
  "aria-label": label,
35604
+ disabled: locked,
35605
+ title: lockedTitle,
35191
35606
  style: { minHeight: fieldMinHeight },
35192
35607
  value: typeof value === "string" ? value : "",
35193
35608
  onChange: (event) => onOptionChange(
@@ -35212,6 +35627,8 @@ function ControlRow({
35212
35627
  {
35213
35628
  type: "number",
35214
35629
  "aria-label": label,
35630
+ disabled: locked,
35631
+ title: lockedTitle,
35215
35632
  style: { minHeight: fieldMinHeight },
35216
35633
  className: "w-20 rounded border border-border bg-background px-2 py-1 text-right text-xs text-foreground",
35217
35634
  min: control.min,
@@ -35240,6 +35657,8 @@ function ControlRow({
35240
35657
  {
35241
35658
  type: "text",
35242
35659
  "aria-label": label,
35660
+ disabled: locked,
35661
+ title: lockedTitle,
35243
35662
  style: { minHeight: fieldMinHeight },
35244
35663
  className: "w-48 max-w-[55%] rounded border border-border bg-background px-2 py-1 text-xs text-foreground",
35245
35664
  maxLength: control.maxLength,
@@ -35751,6 +36170,7 @@ function SettingsDialog({
35751
36170
  }) {
35752
36171
  const [activeTabId, setActiveTabId] = useState("general");
35753
36172
  const { t } = useTranslation();
36173
+ const customization = useViewerCustomizationContext();
35754
36174
  const { panelStyle, handlers: dragHandlers } = useModalDismissDrag(onClose);
35755
36175
  const { viewportWidth, viewportHeight } = useIsMobile();
35756
36176
  const touchTargetPx = getDensePanelTouchTargetPx(viewportWidth);
@@ -35789,10 +36209,14 @@ function SettingsDialog({
35789
36209
  if (!isOpen) {
35790
36210
  return null;
35791
36211
  }
35792
- const activeTab = VIEWER_OPTIONS_TABS.find((tab) => tab.id === activeTabId) ?? VIEWER_OPTIONS_TABS[0];
36212
+ const tabs = customizeOptionsTabs(VIEWER_OPTIONS_TABS, customization);
36213
+ const showAiTab = Boolean(aiEnabled) && isOptionsPageVisible(customization, AI_TAB_ID);
36214
+ const activeTab = tabs.find((tab) => tab.id === activeTabId) ?? tabs[0];
36215
+ const aiActive = activeTabId === AI_TAB_ID && showAiTab;
35793
36216
  if (!activeTab) {
35794
36217
  return null;
35795
36218
  }
36219
+ const currentTabId = aiActive ? AI_TAB_ID : activeTab.id;
35796
36220
  return /* @__PURE__ */ jsxs(Fragment, { children: [
35797
36221
  /* @__PURE__ */ jsx(
35798
36222
  "button",
@@ -35849,31 +36273,31 @@ function SettingsDialog({
35849
36273
  "aria-label": t("pptx.options.title"),
35850
36274
  className: "w-44 shrink-0 space-y-0.5 overflow-y-auto border-r border-border/60 p-2 max-md:flex max-md:w-full max-md:space-y-0 max-md:gap-1 max-md:overflow-x-auto max-md:border-b max-md:border-r-0",
35851
36275
  children: [
35852
- VIEWER_OPTIONS_TABS.map((tab) => /* @__PURE__ */ jsx(
36276
+ tabs.map((tab) => /* @__PURE__ */ jsx(
35853
36277
  "button",
35854
36278
  {
35855
36279
  type: "button",
35856
36280
  onClick: () => setActiveTabId(tab.id),
35857
- "aria-current": activeTabId === tab.id,
36281
+ "aria-current": currentTabId === tab.id,
35858
36282
  style: navBtnStyle,
35859
36283
  className: cn(
35860
36284
  "flex w-full items-center whitespace-nowrap rounded px-3 py-2 text-left text-sm transition-colors max-md:w-auto",
35861
- activeTabId === tab.id ? "bg-primary/10 font-medium text-primary" : "text-foreground hover:bg-accent"
36285
+ currentTabId === tab.id ? "bg-primary/10 font-medium text-primary" : "text-foreground hover:bg-accent"
35862
36286
  ),
35863
36287
  children: t(tab.labelKey)
35864
36288
  },
35865
36289
  tab.id
35866
36290
  )),
35867
- aiEnabled && /* @__PURE__ */ jsx(
36291
+ showAiTab && /* @__PURE__ */ jsx(
35868
36292
  "button",
35869
36293
  {
35870
36294
  type: "button",
35871
36295
  onClick: () => setActiveTabId(AI_TAB_ID),
35872
- "aria-current": activeTabId === AI_TAB_ID,
36296
+ "aria-current": aiActive,
35873
36297
  style: navBtnStyle,
35874
36298
  className: cn(
35875
36299
  "flex w-full items-center whitespace-nowrap rounded px-3 py-2 text-left text-sm transition-colors max-md:w-auto",
35876
- activeTabId === AI_TAB_ID ? "bg-primary/10 font-medium text-primary" : "text-foreground hover:bg-accent"
36300
+ aiActive ? "bg-primary/10 font-medium text-primary" : "text-foreground hover:bg-accent"
35877
36301
  ),
35878
36302
  children: t("pptx.ai.settingsSectionTitle")
35879
36303
  }
@@ -35881,7 +36305,7 @@ function SettingsDialog({
35881
36305
  ]
35882
36306
  }
35883
36307
  ),
35884
- /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-5 py-4", children: activeTabId === AI_TAB_ID ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
36308
+ /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-5 py-4", children: aiActive ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
35885
36309
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: t("pptx.ai.settingsSectionTitle") }),
35886
36310
  /* @__PURE__ */ jsx(SettingsAiTab, { store: chatStore })
35887
36311
  ] }) : activeTab.custom === "language" ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
@@ -36414,6 +36838,41 @@ function useRunProgramNoticesState() {
36414
36838
  }, []);
36415
36839
  return { notices, addNotice, dismiss, dismissAll };
36416
36840
  }
36841
+ function useViewerCustomization(customization, legacyHiddenActions, optionsStore) {
36842
+ const controllerRef = useRef(null);
36843
+ controllerRef.current ??= createCustomizationController(customization);
36844
+ const controller = controllerRef.current;
36845
+ const appliedRef = useRef(customization);
36846
+ useLayoutEffect(() => {
36847
+ if (appliedRef.current === customization) {
36848
+ return;
36849
+ }
36850
+ appliedRef.current = customization;
36851
+ controller.api.setCustomization(customization ?? {});
36852
+ }, [controller, customization]);
36853
+ const resolved = useSyncExternalStore(
36854
+ controller.subscribe,
36855
+ controller.getResolved,
36856
+ controller.getResolved
36857
+ );
36858
+ const appliedConstraintsRef = useRef(null);
36859
+ useLayoutEffect(() => {
36860
+ const key = JSON.stringify([resolved.lockedSettings, resolved.defaultSettings]);
36861
+ if (appliedConstraintsRef.current === key) {
36862
+ return;
36863
+ }
36864
+ appliedConstraintsRef.current = key;
36865
+ optionsStore.setConstraints({
36866
+ locked: resolved.lockedSettings,
36867
+ defaults: resolved.defaultSettings
36868
+ });
36869
+ }, [optionsStore, resolved]);
36870
+ const hiddenActions = useMemo(
36871
+ () => resolveEffectiveHiddenActions(resolved, legacyHiddenActions),
36872
+ [resolved, legacyHiddenActions]
36873
+ );
36874
+ return { resolved, api: controller.api, hiddenActions };
36875
+ }
36417
36876
  var PowerPointViewer = forwardRef(
36418
36877
  // oxlint-disable-next-line prefer-arrow-callback -- named fn gives the forwardRef component its displayName
36419
36878
  function PowerPointViewer2(props, ref) {
@@ -36452,8 +36911,9 @@ var PowerPointViewer = forwardRef(
36452
36911
  lineChart3D = false,
36453
36912
  areaChart3D = false,
36454
36913
  pieChart3D = false,
36455
- hiddenActions,
36456
- ai
36914
+ hiddenActions: legacyHiddenActions,
36915
+ ai,
36916
+ customization
36457
36917
  } = props;
36458
36918
  useEffect(() => {
36459
36919
  const css = buildUserFontFaceStyles(fonts);
@@ -36552,6 +37012,11 @@ var PowerPointViewer = forwardRef(
36552
37012
  })();
36553
37013
  }, []);
36554
37014
  const { optionsStore, options: viewerOptions } = useViewerOptions();
37015
+ const custom = useViewerCustomization(customization, legacyHiddenActions, optionsStore);
37016
+ const { resolved: customizationResolved, hiddenActions } = custom;
37017
+ const aiEnabled = Boolean(ai) && isFeatureEnabled(customizationResolved, "ai");
37018
+ const optionsAvailable = isDialogAvailable(customizationResolved, "options");
37019
+ const shareAvailable = isDialogAvailable(customizationResolved, "share");
36555
37020
  const [protectedViewOverridden, setProtectedViewOverridden] = useState(false);
36556
37021
  useEffect(() => {
36557
37022
  setProtectedViewOverridden(false);
@@ -36885,7 +37350,8 @@ var PowerPointViewer = forwardRef(
36885
37350
  userName: authorName ?? collaboration?.userName ?? (viewerOptions.general.userName || void 0),
36886
37351
  handlerRef: actionSoundHandlerRef,
36887
37352
  // Options > Proofing > AutoCorrect, applied to committed inline-edit text.
36888
- transformCommittedText: (text) => applyAutoCorrect(text, viewerOptions.proofing)
37353
+ transformCommittedText: (text) => applyAutoCorrect(text, viewerOptions.proofing),
37354
+ keyboard: customizationResolved.keyboard
36889
37355
  });
36890
37356
  const {
36891
37357
  exportHandlers: rawExportHandlers,
@@ -36962,7 +37428,9 @@ var PowerPointViewer = forwardRef(
36962
37428
  onModeChange,
36963
37429
  onZoomChange,
36964
37430
  onSelectionChange,
36965
- onSlideCountChange
37431
+ onSlideCountChange,
37432
+ customizationApi: custom.api,
37433
+ customization: customizationResolved
36966
37434
  });
36967
37435
  const viewPreferencesSync = useViewPreferencesSync({
36968
37436
  loadVersion,
@@ -37083,7 +37551,7 @@ var PowerPointViewer = forwardRef(
37083
37551
  markDirty: history.markDirty,
37084
37552
  applyThemeUpdates: applyAiTheme
37085
37553
  });
37086
- const showSlidesPane = mode === "edit" && !isMobile && !dialogs.isNarrowViewport && state.isSlidesPaneOpen;
37554
+ const showSlidesPane = mode === "edit" && !isMobile && !dialogs.isNarrowViewport && state.isSlidesPaneOpen && isPanelVisible(customizationResolved, "slidesPane");
37087
37555
  const showMasterPane = mode === "master" && !isMobile && state.isSlidesPaneOpen;
37088
37556
  const addinStatus = {
37089
37557
  smartArt3d: smartArt3D && !viewerOptions.advanced.disable3DRendering,
@@ -37136,7 +37604,7 @@ var PowerPointViewer = forwardRef(
37136
37604
  onPresentFromBeginning: presentation.enterPresentModeFromBeginning,
37137
37605
  onEnterPresenterView: handleEnterPresenterView,
37138
37606
  onEnterRehearsalMode: handleEnterRehearsalMode,
37139
- onOpenSettings: () => setIsSettingsOpen(true),
37607
+ onOpenSettings: optionsAvailable ? () => setIsSettingsOpen(true) : void 0,
37140
37608
  onOpenHeaderFooter: () => setIsHeaderFooterOpen(true),
37141
37609
  onOpenShareDialog: () => setIsShareDialogOpen(true),
37142
37610
  onOpenFile: handleOpenFile,
@@ -37151,7 +37619,7 @@ var PowerPointViewer = forwardRef(
37151
37619
  },
37152
37620
  hiddenActions,
37153
37621
  recentPresentationsCount: viewerOptions.advanced.recentPresentationsCount,
37154
- aiEnabled: Boolean(ai),
37622
+ aiEnabled,
37155
37623
  isAiPanelOpen: aiPanel.isOpen,
37156
37624
  onToggleAiPanel: aiPanel.toggle,
37157
37625
  isProtectedView,
@@ -37181,6 +37649,8 @@ var PowerPointViewer = forwardRef(
37181
37649
  canEdit,
37182
37650
  slides,
37183
37651
  activeSlide,
37652
+ onApplyLayout: (path) => void layoutSwitching.applyLayout(path),
37653
+ loadLayoutPreviews: layoutSwitching.loadLayoutPreviews,
37184
37654
  presentationOverlay: (
37185
37655
  // `ppaction://program` ("Run program") notices. Rendered INSIDE
37186
37656
  // the show stage, not beside the viewer: the fullscreen element
@@ -37224,9 +37694,9 @@ var PowerPointViewer = forwardRef(
37224
37694
  rightPanelWidth: isMobile ? void 0 : resizablePanels.rightWidth,
37225
37695
  onResizeRight: isMobile ? void 0 : resizablePanels.onResizeRight,
37226
37696
  hiddenActions,
37227
- aiConfig: ai,
37228
- aiBridge: ai ? aiBridge : void 0,
37229
- aiPanel: ai ? aiPanel : void 0
37697
+ aiConfig: aiEnabled ? ai : void 0,
37698
+ aiBridge: aiEnabled ? aiBridge : void 0,
37699
+ aiPanel: aiEnabled ? aiPanel : void 0
37230
37700
  }
37231
37701
  ),
37232
37702
  mode !== "present" && (!isVirtualKeyboardOpen || !state.isSlideNotesCollapsed) && /* @__PURE__ */ jsx(
@@ -37242,7 +37712,7 @@ var PowerPointViewer = forwardRef(
37242
37712
  autosaveStatus,
37243
37713
  onToggleNotes: () => state.setIsSlideNotesCollapsed((p) => !p),
37244
37714
  onUpdateNotes: propertyHandlers.handleUpdateNotes,
37245
- collaborationSlot: collaboration ? /* @__PURE__ */ jsx(CollaborationStatusStrip, {}) : void 0,
37715
+ collaborationSlot: collaboration && shareAvailable ? /* @__PURE__ */ jsx(CollaborationStatusStrip, {}) : void 0,
37246
37716
  notesPanelHeight: isMobile ? void 0 : resizablePanels.bottomHeight,
37247
37717
  onResizeBottom: isMobile ? void 0 : resizablePanels.onResizeBottom,
37248
37718
  scale: zoom.scale,
@@ -37350,7 +37820,7 @@ var PowerPointViewer = forwardRef(
37350
37820
  /* @__PURE__ */ jsx(
37351
37821
  SettingsDialog,
37352
37822
  {
37353
- isOpen: isSettingsOpen,
37823
+ isOpen: isSettingsOpen && optionsAvailable,
37354
37824
  onClose: () => setIsSettingsOpen(false),
37355
37825
  options: viewerOptions,
37356
37826
  onOptionChange: (group, key, value) => optionsStore.setValue(group, key, value),
@@ -37366,7 +37836,7 @@ var PowerPointViewer = forwardRef(
37366
37836
  localeCode,
37367
37837
  availableLocales: resolvedLocales,
37368
37838
  onSelectLocale: handleLocaleChange,
37369
- aiEnabled: Boolean(ai),
37839
+ aiEnabled,
37370
37840
  customFontFamilies,
37371
37841
  onCustomFontRegistered: handleCustomFontRegistered
37372
37842
  }
@@ -37390,7 +37860,7 @@ var PowerPointViewer = forwardRef(
37390
37860
  /* @__PURE__ */ jsx(
37391
37861
  ShareDialog,
37392
37862
  {
37393
- open: isShareDialogOpen,
37863
+ open: isShareDialogOpen && shareAvailable,
37394
37864
  onClose: () => setIsShareDialogOpen(false),
37395
37865
  activeCollaboration: collaboration,
37396
37866
  onStartCollaboration,
@@ -37404,7 +37874,7 @@ var PowerPointViewer = forwardRef(
37404
37874
  /* @__PURE__ */ jsx(
37405
37875
  BroadcastDialog,
37406
37876
  {
37407
- open: dialogs.isBroadcastDialogOpen,
37877
+ open: dialogs.isBroadcastDialogOpen && isDialogAvailable(customizationResolved, "broadcast"),
37408
37878
  onClose: () => dialogs.setIsBroadcastDialogOpen(false),
37409
37879
  onStartBroadcast: onStartCollaboration,
37410
37880
  onStopBroadcast: onStopCollaboration,
@@ -37482,7 +37952,7 @@ var PowerPointViewer = forwardRef(
37482
37952
  // Nothing previously provided it, so every one of those consumers was
37483
37953
  // silently reading `DEFAULT_VIEWER_OPTIONS` forever, no matter what
37484
37954
  // the user changed in the Options dialog.
37485
- /* @__PURE__ */ jsx(ViewerOptionsContext.Provider, { value: viewerOptions, children: /* @__PURE__ */ jsx(AccountAuthContext.Provider, { value: accountAuth, children: /* @__PURE__ */ jsx(Rendering3DFlagsContext.Provider, { value: effective3D, children: /* @__PURE__ */ jsx(ViewerThemeProvider, { theme: effectiveTheme, children: /* @__PURE__ */ jsxs(
37955
+ /* @__PURE__ */ jsx(ViewerOptionsContext.Provider, { value: viewerOptions, children: /* @__PURE__ */ jsx(ViewerCustomizationContext.Provider, { value: customizationResolved, children: /* @__PURE__ */ jsx(AccountAuthContext.Provider, { value: accountAuth, children: /* @__PURE__ */ jsx(Rendering3DFlagsContext.Provider, { value: effective3D, children: /* @__PURE__ */ jsx(ViewerThemeProvider, { theme: effectiveTheme, children: /* @__PURE__ */ jsxs(
37486
37956
  CollaborationProvider,
37487
37957
  {
37488
37958
  config: collaboration,
@@ -37535,7 +38005,7 @@ var PowerPointViewer = forwardRef(
37535
38005
  viewerContent
37536
38006
  ]
37537
38007
  }
37538
- ) }) }) }) })
38008
+ ) }) }) }) }) })
37539
38009
  );
37540
38010
  }
37541
38011
  );