markdown-flow-ui 0.2.3-dev.1 → 0.2.3-dev.2

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 (41) hide show
  1. package/dist/components/ContentRender/SandboxApp.cjs.js +2 -2
  2. package/dist/components/ContentRender/SandboxApp.cjs.js.map +1 -1
  3. package/dist/components/ContentRender/SandboxApp.es.js +95 -106
  4. package/dist/components/ContentRender/SandboxApp.es.js.map +1 -1
  5. package/dist/components/Slide/Slide.cjs.js +1 -1
  6. package/dist/components/Slide/Slide.cjs.js.map +1 -1
  7. package/dist/components/Slide/Slide.es.js +732 -776
  8. package/dist/components/Slide/Slide.es.js.map +1 -1
  9. package/dist/components/Slide/Slide.stories.d.ts +4 -4
  10. package/dist/components/Slide/constants.d.ts +0 -1
  11. package/dist/components/Slide/utils/interactionPlayback.cjs.js +1 -1
  12. package/dist/components/Slide/utils/interactionPlayback.cjs.js.map +1 -1
  13. package/dist/components/Slide/utils/interactionPlayback.d.ts +2 -1
  14. package/dist/components/Slide/utils/interactionPlayback.es.js +3 -2
  15. package/dist/components/Slide/utils/interactionPlayback.es.js.map +1 -1
  16. package/dist/components/Slide/utils/streamingNavigation.cjs.js +1 -1
  17. package/dist/components/Slide/utils/streamingNavigation.cjs.js.map +1 -1
  18. package/dist/components/Slide/utils/streamingNavigation.es.js +15 -9
  19. package/dist/components/Slide/utils/streamingNavigation.es.js.map +1 -1
  20. package/package.json +1 -1
  21. package/dist/components/ContentRender/utils/link-targets.cjs.js +0 -2
  22. package/dist/components/ContentRender/utils/link-targets.cjs.js.map +0 -1
  23. package/dist/components/ContentRender/utils/link-targets.d.ts +0 -6
  24. package/dist/components/ContentRender/utils/link-targets.es.js +0 -26
  25. package/dist/components/ContentRender/utils/link-targets.es.js.map +0 -1
  26. package/dist/components/ContentRender/utils/link-targets.test.d.ts +0 -1
  27. package/dist/components/Slide/constants.cjs.js +0 -2
  28. package/dist/components/Slide/constants.cjs.js.map +0 -1
  29. package/dist/components/Slide/constants.es.js +0 -5
  30. package/dist/components/Slide/constants.es.js.map +0 -1
  31. package/dist/components/Slide/utils/imageOnlyStepVisualReady.cjs.js +0 -2
  32. package/dist/components/Slide/utils/imageOnlyStepVisualReady.cjs.js.map +0 -1
  33. package/dist/components/Slide/utils/imageOnlyStepVisualReady.d.ts +0 -13
  34. package/dist/components/Slide/utils/imageOnlyStepVisualReady.es.js +0 -12
  35. package/dist/components/Slide/utils/imageOnlyStepVisualReady.es.js.map +0 -1
  36. package/dist/components/Slide/utils/silentStepAutoAdvance.cjs.js +0 -2
  37. package/dist/components/Slide/utils/silentStepAutoAdvance.cjs.js.map +0 -1
  38. package/dist/components/Slide/utils/silentStepAutoAdvance.d.ts +0 -14
  39. package/dist/components/Slide/utils/silentStepAutoAdvance.es.js +0 -37
  40. package/dist/components/Slide/utils/silentStepAutoAdvance.es.js.map +0 -1
  41. package/dist/components/Slide/utils/silentStepAutoAdvance.test.d.ts +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Slide.cjs.js","sources":["../../../src/components/Slide/Slide.tsx"],"sourcesContent":["import React, {\n memo,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { ChevronLeft } from \"lucide-react\";\n\nimport { isSandboxInteractionMessage } from \"../../lib/sandboxInteraction\";\nimport { cn } from \"../../lib/utils\";\nimport type { MarkdownFlowLocale } from \"../../lib/locale\";\nimport LoadingOverlayCard from \"../ui/loading-overlay-card\";\nimport ContentRender from \"../ContentRender\";\nimport type { ContentRenderProps } from \"../ContentRender/ContentRender\";\nimport IframeSandbox from \"../ContentRender/IframeSandbox\";\nimport type { OnSendContentParams } from \"../types\";\nimport type { InteractionDefaultValueOptions } from \"../../lib/interaction-defaults\";\nimport {\n isLandscapeViewport as getIsFullscreenPreferredViewport,\n isMobileDevice as getIsMobileDevice,\n subscribeMobileDeviceChange,\n} from \"../../lib/mobileDevice\";\nimport Player from \"./Player\";\nimport MarkdownSlideScaling from \"./MarkdownSlideScaling\";\nimport SubtitleOverlay from \"./SubtitleOverlay\";\nimport type {\n PlayerProps,\n SlidePlayerNavigationContext,\n SlidePlayerSubtitleJumpTarget,\n SlidePlayerSubtitleSeekRequest,\n SlidePlayerTexts,\n} from \"./Player\";\nimport type { SlidePlayerLoadingReason } from \"./Player\";\nimport type { Element } from \"./types\";\nimport useSlide from \"./useSlide\";\nimport useWakePlayerFromIframe from \"./useWakePlayerFromIframe\";\nimport { PlayerKeyboardShortcutContext } from \"./utils/playerKeyboardShortcutContext\";\nimport { activatePlayerKeyboardShortcutOwner } from \"./utils/playerKeyboardShortcuts\";\nimport {\n DEFAULT_MOBILE_VIEW_MODE,\n resolveMobileViewModeState,\n type MobileViewMode,\n} from \"./utils/mobileScreenMode\";\nimport {\n shouldPresentInteractionOverlay,\n shouldRenderInteractionOverlay,\n} from \"./utils/interactionPlayback\";\nimport { resolveMarkdownScalingMode } from \"./utils/markdownScaling\";\nimport { shouldWakePlayerControlsAfterNavigation } from \"./utils/playerNavigationContext\";\nimport { shouldAutoAdvanceIntoAppendedMarker } from \"./utils/appendedMarkerAdvance\";\nimport {\n getPlaybackSequenceTransition,\n shouldStartDefaultAudioSequence,\n} from \"./utils/playbackSequence\";\nimport {\n canReachSubtitleJumpTarget,\n hasResolvedInteractionElement,\n} from \"./utils/subtitleJumpNavigation\";\nimport {\n getPlayerCustomActionCount,\n resolvePlayerCustomActionElement,\n} from \"./utils/playerCustomActions\";\nimport { createPlaybackTimeStore } from \"./utils/playbackTimeStore\";\nimport { resolveSlideInteractionState } from \"./utils/interactionResolution\";\nimport { shouldUseAutoAdvanceToggle } from \"./utils/playerToggleMode\";\nimport {\n areImageOnlyStepIframeVisualsReady,\n DEFAULT_IMAGE_ONLY_VISUAL_READY_TIMEOUT_MS,\n} from \"./utils/imageOnlyStepVisualReady\";\nimport { resolveSilentStepAutoAdvanceBehavior } from \"./utils/silentStepAutoAdvance\";\nimport {\n resolveSlidePlayerVisibility,\n type SlidePlayerControlsVisibility,\n} from \"./utils/playerVisibility\";\nimport {\n DEFAULT_SLIDE_BUFFERING_TEXTS,\n getSlideLocaleTexts,\n type SlideBufferingReason,\n} from \"./slideI18n\";\nimport \"./slide.css\";\nexport type {\n Element,\n ElementAudioSegment,\n ElementSubtitleCue,\n SlidePlayerCustomActionContext,\n SlidePlayerCustomActions,\n} from \"./types\";\nexport type { SlidePlayerControlsVisibility } from \"./utils/playerVisibility\";\n\nconst DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS = 2000;\nconst DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS = 300;\nconst DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX = 160;\nconst DEFAULT_INTERACTION_SUBTITLE_GAP_PX = 16;\nconst DEFAULT_BUFFERING_REASON: SlideBufferingReason = \"waitingForAudio\";\n\nexport type { SlideBufferingReason } from \"./slideI18n\";\n\nexport type SlideBufferingTextConfig =\n | string\n | Partial<Record<SlideBufferingReason, string>>;\n\nconst resolveBufferingTextByReason = (\n bufferingText: SlideBufferingTextConfig,\n reason: SlideBufferingReason\n) => {\n if (typeof bufferingText === \"string\") {\n return bufferingText;\n }\n\n return (\n bufferingText[reason] ??\n bufferingText[DEFAULT_BUFFERING_REASON] ??\n DEFAULT_SLIDE_BUFFERING_TEXTS[reason]\n );\n};\n\nconst mergeBufferingTextWithLocaleDefaults = (\n bufferingText: SlideBufferingTextConfig | undefined,\n localeBufferingText: Record<string, string>\n): SlideBufferingTextConfig => {\n if (typeof bufferingText === \"string\") {\n return bufferingText;\n }\n\n return {\n ...localeBufferingText,\n ...bufferingText,\n };\n};\n\nconst shouldShowBufferingOverlay = (\n reason: SlideBufferingReason | null,\n loading: boolean\n) => {\n if (!loading) {\n return false;\n }\n\n // Keep the silent preload/loading phase invisible until audio is actually playable.\n return reason !== \"loadingAudio\";\n};\n\ntype RenderSlideElementOptions = {\n replaceRootScreenHeightWithFull?: boolean;\n};\n\ninterface InteractionOverlayCardProps {\n content: string;\n title: string;\n locale?: MarkdownFlowLocale;\n defaultButtonText?: string;\n defaultInputText?: string;\n defaultSelectedValues?: string[];\n confirmButtonText?: string;\n copyButtonText?: string;\n copiedButtonText?: string;\n onSend?: (content: OnSendContentParams) => void;\n readonly?: boolean;\n}\n\nexport interface SlideInteractionTexts\n extends Pick<\n ContentRenderProps,\n \"confirmButtonText\" | \"copyButtonText\" | \"copiedButtonText\"\n > {\n title?: string;\n}\n\nexport type SlideFullscreenHeader = {\n content?: React.ReactNode;\n backAriaLabel?: string;\n onBack?: () => void;\n};\n\nconst InteractionOverlayCard = memo(\n ({\n content,\n title,\n locale,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n onSend,\n readonly = false,\n }: InteractionOverlayCardProps) => (\n <div className=\"slide-player__interaction-card\">\n <div className=\"slide-player__interaction-header\">\n <p className=\"slide-player__interaction-title\">{title}</p>\n </div>\n <div className=\"slide-player__interaction-body\">\n <ContentRender\n content={content}\n locale={locale}\n defaultButtonText={defaultButtonText}\n defaultInputText={defaultInputText}\n defaultSelectedValues={defaultSelectedValues}\n confirmButtonText={confirmButtonText}\n copyButtonText={copyButtonText}\n copiedButtonText={copiedButtonText}\n onSend={onSend}\n readonly={readonly}\n sandboxMode=\"content\"\n />\n </div>\n </div>\n )\n);\n\nInteractionOverlayCard.displayName = \"InteractionOverlayCard\";\n\nconst areStepElementListsEqual = (\n prevElementList: Element[],\n nextElementList: Element[]\n) =>\n prevElementList.length === nextElementList.length &&\n prevElementList.every((element, index) => {\n const nextElement = nextElementList[index];\n\n return (\n element.sequence_number === nextElement?.sequence_number &&\n element.type === nextElement?.type &&\n element.content === nextElement?.content\n );\n });\n\nexport interface SlideProps extends React.ComponentProps<\"section\"> {\n elementList?: Element[];\n /** Locale used for built-in UI text when a more specific text prop is not provided. */\n locale?: MarkdownFlowLocale;\n /** Enables the player runtime, including audio playback and keyboard shortcuts. */\n playerEnabled?: boolean;\n /**\n * Controls whether the player controls are always visible, always hidden, or auto-hidden.\n *\n * Use `\"hidden\"` to keep audio playback and keyboard shortcuts active while\n * hiding the visual controls.\n *\n * @example\n * ```tsx\n * <Slide playerControlsVisibility=\"hidden\" enableKeyboardShortcuts />\n * ```\n */\n playerControlsVisibility?: SlidePlayerControlsVisibility;\n playerClassName?: string;\n fullscreenHeader?: SlideFullscreenHeader;\n playerCustomActions?: PlayerProps[\"customActions\"];\n playerCustomActionPauseOnActive?: boolean;\n bufferingText?: SlideBufferingTextConfig;\n interactionTitle?: string;\n interactionTexts?: SlideInteractionTexts;\n playerTexts?: SlidePlayerTexts;\n playerAutoHideDelay?: number;\n markerAutoAdvanceDelay?: number;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n onSend?: (content: OnSendContentParams, element?: Element) => void;\n onPlayerVisibilityChange?: (visible: boolean) => void;\n onMobileViewModeChange?: (viewMode: MobileViewMode) => void;\n onStepChange?: (element: Element | undefined, index: number) => void;\n /**\n * Enables keyboard shortcuts for existing player actions.\n *\n * Defaults to `true`. The active slide responds after users click, touch, or\n * focus the slide/player surface; ignored targets include form controls and\n * interaction overlays.\n *\n * @example\n * ```tsx\n * <Slide elementList={slides} enableKeyboardShortcuts={false} />\n * ```\n */\n enableKeyboardShortcuts?: boolean;\n enableIframeScaling?: boolean;\n /**\n * Fits Markdown-only slides to the available presentation viewport.\n *\n * Defaults to `true`. Disable this to preserve the fixed 16px article\n * typography used by standalone ContentRender.\n */\n enableMarkdownScaling?: boolean;\n disableLoadingOverlay?: boolean;\n}\n\nconst Slide: React.FC<SlideProps> = ({\n elementList = [],\n locale,\n playerEnabled,\n playerControlsVisibility,\n playerClassName,\n fullscreenHeader,\n playerCustomActions,\n playerCustomActionPauseOnActive = true,\n bufferingText,\n interactionTitle,\n interactionTexts,\n playerTexts,\n playerAutoHideDelay = 3000,\n markerAutoAdvanceDelay = DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS,\n interactionDefaultValueOptions,\n onSend,\n onPlayerVisibilityChange,\n onMobileViewModeChange,\n onStepChange,\n enableKeyboardShortcuts = true,\n enableIframeScaling = true,\n enableMarkdownScaling = true,\n disableLoadingOverlay = false,\n className,\n onPointerDown,\n onFocusCapture,\n ...props\n}) => {\n const localeTexts = useMemo(() => getSlideLocaleTexts(locale), [locale]);\n const resolvedBufferingText = useMemo(\n () =>\n mergeBufferingTextWithLocaleDefaults(\n bufferingText,\n localeTexts.bufferingText\n ),\n [bufferingText, localeTexts.bufferingText]\n );\n const {\n playerEnabled: resolvedPlayerEnabled,\n playerControlsVisibility: resolvedPlayerControlsVisibility,\n } = resolveSlidePlayerVisibility({\n playerEnabled,\n playerControlsVisibility,\n });\n const keyboardShortcutOwnerId = useId();\n const sectionRef = useRef<HTMLElement | null>(null);\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const stageLayerRef = useRef<HTMLDivElement | null>(null);\n const lastElementRef = useRef<HTMLDivElement | null>(null);\n const playerHideTimerRef = useRef<number | null>(null);\n const isPointerInsidePlayerControlsRef = useRef(false);\n const autoAdvanceTimerRef = useRef<number | null>(null);\n const imageOnlyStepReadyTimeoutRef = useRef<number | null>(null);\n const interactionAutoCloseTimerRef = useRef<number | null>(null);\n const interactionOverlayOpenTimerRef = useRef<number | null>(null);\n const interactionOverlayRef = useRef<HTMLDivElement | null>(null);\n const prevRenderElementKeysRef = useRef<string[]>([]);\n const shouldScrollToBottomRef = useRef(false);\n const pendingInteractionOverlayStepIndexRef = useRef<number | null>(null);\n const pendingSubtitleJumpRef = useRef<{\n audioIndex: number;\n audioKey: string;\n slideIndex: number;\n timeMs: number;\n } | null>(null);\n const subtitleSeekRequestIdRef = useRef(0);\n const playbackResetKeyRef = useRef<string | null>(null);\n const appendedMarkerAdvanceStateRef = useRef({\n markerCount: 0,\n currentIndex: -1,\n canGoNext: false,\n });\n const shouldSkipDefaultAudioStartForSubtitleJumpRef = useRef(false);\n const {\n currentElementList,\n stepElementLists,\n slideElementList,\n currentIndex,\n audioList,\n audioSlideIndexes,\n currentAudioSequenceIndexes,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n canGoPrev,\n canGoNext,\n handlePrev: goPrev,\n handleNext: goNext,\n handleGoTo: goTo,\n } = useSlide(elementList);\n const currentStepElement = useMemo(() => {\n if (currentIndex < 0) {\n return undefined;\n }\n\n return slideElementList[currentIndex];\n }, [currentIndex, slideElementList]);\n const currentRenderElementKeys = useMemo(\n () =>\n currentElementList.map(\n (element, index) =>\n `${element.sequence_number ?? `${element.type}-${index}`}:${String(element.is_new ?? \"\")}`\n ),\n [currentElementList]\n );\n const visibleMarkerCount = slideElementList.filter(\n (element) => element.is_renderable !== false\n ).length;\n const isSingleSlide = visibleMarkerCount === 1;\n const shouldMountPlayer =\n resolvedPlayerEnabled &&\n (slideElementList.length > 0 ||\n audioList.length > 0 ||\n Boolean(currentInteractionElement));\n const keyboardShortcutContextValue = useMemo(\n () => ({\n enabled: enableKeyboardShortcuts,\n ownerId: keyboardShortcutOwnerId,\n }),\n [enableKeyboardShortcuts, keyboardShortcutOwnerId]\n );\n const activateKeyboardShortcutOwner = useCallback(() => {\n if (!enableKeyboardShortcuts || !shouldMountPlayer) {\n return;\n }\n\n activatePlayerKeyboardShortcutOwner(keyboardShortcutOwnerId);\n }, [enableKeyboardShortcuts, keyboardShortcutOwnerId, shouldMountPlayer]);\n const currentAudioSequenceKeys = useMemo(\n () =>\n currentAudioSequenceIndexes\n .map((audioIndex) => audioList[audioIndex]?.audioKey)\n .filter((audioKey): audioKey is string => Boolean(audioKey)),\n [audioList, currentAudioSequenceIndexes]\n );\n const [isPlayerVisible, setIsPlayerVisible] = useState(true);\n const [hasPlayerInteracted, setHasPlayerInteracted] = useState(false);\n const [isPlaybackRequested, setIsPlaybackRequested] = useState(true);\n const [isAutoAdvanceEnabled, setIsAutoAdvanceEnabled] = useState(true);\n const [currentAudioKey, setCurrentAudioKey] = useState<string | null>(null);\n const [subtitleSeekRequest, setSubtitleSeekRequest] =\n useState<SlidePlayerSubtitleSeekRequest | null>(null);\n const [isAudioLoadingVisible, setIsAudioLoadingVisible] = useState(false);\n const [audioLoadingReason, setAudioLoadingReason] =\n useState<SlideBufferingReason>(DEFAULT_BUFFERING_REASON);\n const [hasCompletedCurrentStepAudio, setHasCompletedCurrentStepAudio] =\n useState(false);\n const [hasCurrentAudioPlaybackStarted, setHasCurrentAudioPlaybackStarted] =\n useState(false);\n const [isSubtitleEnabled, setIsSubtitleEnabled] = useState(true);\n const [isPlayerCustomActionActive, setIsPlayerCustomActionActive] =\n useState(false);\n const [activeInteractionElement, setActiveInteractionElement] = useState<\n Element | undefined\n >();\n const [isInteractionOverlayOpen, setIsInteractionOverlayOpen] =\n useState(false);\n const [\n interactionOverlaySubtitleOffset,\n setInteractionOverlaySubtitleOffset,\n ] = useState(0);\n const [isBrowserFullscreen, setIsBrowserFullscreen] = useState(false);\n const isMobileDevice = useMemo(() => getIsMobileDevice(), []);\n const [mobileViewMode, setMobileViewMode] = useState<MobileViewMode>(\n DEFAULT_MOBILE_VIEW_MODE\n );\n const [hasManualMobileViewMode, setHasManualMobileViewMode] = useState(false);\n const [isViewportFullscreenPreferred, setIsViewportFullscreenPreferred] =\n useState(() =>\n isMobileDevice ? getIsFullscreenPreferredViewport() : false\n );\n const playbackTimeStore = useMemo(() => createPlaybackTimeStore(), []);\n const {\n effectiveMobileViewMode,\n isImmersiveMobileFullscreen,\n isNativeMobileFullscreen,\n shouldRotateFullscreenViewport,\n } = useMemo(\n () =>\n resolveMobileViewModeState({\n hasManualMobileViewMode,\n isMobileDevice,\n isViewportFullscreenPreferred,\n mobileViewMode,\n }),\n [\n hasManualMobileViewMode,\n isMobileDevice,\n isViewportFullscreenPreferred,\n mobileViewMode,\n ]\n );\n const previousEffectiveMobileViewModeRef = useRef(effectiveMobileViewMode);\n const playerControlsVisible =\n shouldMountPlayer &&\n resolvedPlayerControlsVisibility !== \"hidden\" &&\n (resolvedPlayerControlsVisibility === \"visible\" || isPlayerVisible);\n const shouldShowFullscreenHeader =\n isImmersiveMobileFullscreen && playerControlsVisible;\n const shouldApplyFullscreenViewportPadding =\n isImmersiveMobileFullscreen && playerControlsVisible;\n const shouldShowMobileFullscreenMask =\n isImmersiveMobileFullscreen || isNativeMobileFullscreen;\n const isDesktopBrowserFullscreen = isBrowserFullscreen && !isMobileDevice;\n const handleMobileViewModeSelect = useCallback(\n (nextViewMode: MobileViewMode) => {\n setHasManualMobileViewMode(true);\n setMobileViewMode(nextViewMode);\n },\n []\n );\n const handleMobileViewModeReset = useCallback(() => {\n // Clear manual override so the effective mode returns to the default non-fullscreen state.\n setHasManualMobileViewMode(false);\n setMobileViewMode(DEFAULT_MOBILE_VIEW_MODE);\n }, []);\n const handleFullscreenHeaderBack = useCallback(() => {\n handleMobileViewModeReset();\n fullscreenHeader?.onBack?.();\n }, [fullscreenHeader, handleMobileViewModeReset]);\n const setPlayerCustomActionActive = useCallback((active: boolean) => {\n setIsPlayerCustomActionActive(active);\n }, []);\n const togglePlayerCustomActionActive = useCallback(() => {\n setIsPlayerCustomActionActive((previous) => !previous);\n }, []);\n const { mountedStepStates, currentMountedStateIndex } = useMemo(() => {\n const nextMountedStepStates: Array<{\n elementList: Element[];\n sourceStepIndexes: number[];\n }> = [];\n const mountedStateIndexByStep = new Map<number, number>();\n\n stepElementLists.forEach((stepElementList, stepIndex) => {\n const existingMountedStateIndex = nextMountedStepStates.findIndex(\n (mountedStepState) =>\n areStepElementListsEqual(\n mountedStepState.elementList,\n stepElementList\n )\n );\n\n if (existingMountedStateIndex >= 0) {\n nextMountedStepStates[\n existingMountedStateIndex\n ]?.sourceStepIndexes.push(stepIndex);\n mountedStateIndexByStep.set(stepIndex, existingMountedStateIndex);\n return;\n }\n\n nextMountedStepStates.push({\n elementList: stepElementList,\n sourceStepIndexes: [stepIndex],\n });\n mountedStateIndexByStep.set(stepIndex, nextMountedStepStates.length - 1);\n });\n\n return {\n mountedStepStates: nextMountedStepStates,\n currentMountedStateIndex:\n currentIndex >= 0\n ? (mountedStateIndexByStep.get(currentIndex) ?? -1)\n : -1,\n };\n }, [currentIndex, stepElementLists]);\n const currentStepKey = useMemo(() => String(currentIndex), [currentIndex]);\n const currentAudioIndex = useMemo(() => {\n if (!currentAudioKey) {\n return -1;\n }\n\n return audioList.findIndex(\n (audioItem) => (audioItem.audioKey ?? \"\") === currentAudioKey\n );\n }, [audioList, currentAudioKey]);\n const currentAudioItem = useMemo(\n () => (currentAudioIndex >= 0 ? audioList[currentAudioIndex] : undefined),\n [audioList, currentAudioIndex]\n );\n const currentSubtitleCues = currentAudioItem?.element?.subtitle_cues ?? [];\n const currentAudioSequenceStartKey = useMemo(\n () => currentAudioSequenceKeys[0] ?? \"none\",\n [currentAudioSequenceKeys]\n );\n const playerCustomActionContext = useMemo(\n () => ({\n currentElement: resolvePlayerCustomActionElement({\n currentAudioIndex,\n currentAudioSequenceIndexes,\n audioList,\n currentInteractionElement: activeInteractionElement,\n currentStepElement,\n }),\n currentIndex,\n currentStepElement,\n isActive: isPlayerCustomActionActive,\n setActive: setPlayerCustomActionActive,\n toggleActive: togglePlayerCustomActionActive,\n }),\n [\n activeInteractionElement,\n audioList,\n currentAudioIndex,\n currentAudioSequenceIndexes,\n currentIndex,\n currentStepElement,\n isPlayerCustomActionActive,\n setPlayerCustomActionActive,\n togglePlayerCustomActionActive,\n ]\n );\n const playerCustomActionCount = useMemo(\n () =>\n getPlayerCustomActionCount(\n playerCustomActions,\n playerCustomActionContext\n ),\n [playerCustomActionContext, playerCustomActions]\n );\n const interactionOverlayStyle = useMemo(\n () =>\n ({\n \"--slide-player-custom-action-count\": String(playerCustomActionCount),\n \"--slide-player-mobile-control-count\": String(\n playerCustomActionCount + 4\n ),\n }) as React.CSSProperties,\n [playerCustomActionCount]\n );\n const hasAvailableStepAudio = currentAudioSequenceKeys.length > 0;\n const currentInteractionResetKey = useMemo(() => {\n if (!currentInteractionElement) {\n return \"none\";\n }\n\n return `${currentInteractionElement.sequence_number ?? \"none\"}:${String(\n currentInteractionElement.content ?? \"\"\n )}`;\n }, [currentInteractionElement]);\n const currentPlaybackResetKey = useMemo(\n () => [currentStepKey, currentInteractionResetKey].join(\"|\"),\n [currentInteractionResetKey, currentStepKey]\n );\n const currentPlaybackStartedResetKey = useMemo(\n () =>\n [\n currentPlaybackResetKey,\n currentAudioItem?.audioKey ?? \"none\",\n String(currentAudioIndex),\n ].join(\"|\"),\n [currentAudioIndex, currentAudioItem?.audioKey, currentPlaybackResetKey]\n );\n const currentStepAudioUrl = useMemo(() => {\n if (\n !currentAudioSequenceStartKey ||\n currentAudioSequenceStartKey === \"none\"\n ) {\n return \"\";\n }\n\n const currentStepAudioItem = audioList.find(\n (audioItem) => audioItem.audioKey === currentAudioSequenceStartKey\n );\n\n return currentStepAudioItem?.audioUrl?.trim() ?? \"\";\n }, [audioList, currentAudioSequenceStartKey]);\n const hasCurrentStepAudioUrl = Boolean(currentStepAudioUrl);\n const shouldPausePlaybackForCustomAction =\n playerCustomActionPauseOnActive &&\n Boolean(playerCustomActions) &&\n isPlayerCustomActionActive;\n const shouldUseSilentStepAutoAdvanceToggle = useMemo(\n () =>\n shouldUseAutoAdvanceToggle({\n canGoNext,\n currentAudioIndex,\n currentStepHasSpeakableElement,\n hasInteraction: Boolean(currentInteractionElement),\n }),\n [\n canGoNext,\n currentAudioIndex,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n ]\n );\n const silentStepAutoAdvanceBehavior = useMemo(\n () =>\n resolveSilentStepAutoAdvanceBehavior({\n currentElementList,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n markerAutoAdvanceDelay,\n }),\n [\n currentElementList,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n markerAutoAdvanceDelay,\n ]\n );\n const silentStepAutoAdvanceDelay = silentStepAutoAdvanceBehavior.delayMs;\n const isImageOnlySilentStep =\n silentStepAutoAdvanceBehavior.usesImageOnlyDelay;\n const imageOnlyStepVisualReadyKey = useMemo(\n () => `${currentIndex}:${currentRenderElementKeys.join(\"|\")}`,\n [currentIndex, currentRenderElementKeys]\n );\n const [readyImageOnlyStepKey, setReadyImageOnlyStepKey] = useState<\n string | null\n >(null);\n const isImageOnlyStepVisualReady =\n !isImageOnlySilentStep ||\n readyImageOnlyStepKey === imageOnlyStepVisualReadyKey;\n\n const clearPlayerHideTimer = useCallback(() => {\n if (playerHideTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(playerHideTimerRef.current);\n playerHideTimerRef.current = null;\n }, []);\n\n const clearInteractionAutoCloseTimer = useCallback(() => {\n if (interactionAutoCloseTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(interactionAutoCloseTimerRef.current);\n interactionAutoCloseTimerRef.current = null;\n }, []);\n\n const clearInteractionOverlayOpenTimer = useCallback(() => {\n if (interactionOverlayOpenTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(interactionOverlayOpenTimerRef.current);\n interactionOverlayOpenTimerRef.current = null;\n }, []);\n\n const clearAutoAdvanceTimer = useCallback(() => {\n if (autoAdvanceTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(autoAdvanceTimerRef.current);\n autoAdvanceTimerRef.current = null;\n }, []);\n\n const clearImageOnlyStepReadyTimeout = useCallback(() => {\n if (imageOnlyStepReadyTimeoutRef.current === null) {\n return;\n }\n\n window.clearTimeout(imageOnlyStepReadyTimeoutRef.current);\n imageOnlyStepReadyTimeoutRef.current = null;\n }, []);\n\n const resetAudioSequence = useCallback(\n (\n options: {\n preservePendingSubtitleJump?: boolean;\n } = {}\n ) => {\n clearAutoAdvanceTimer();\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n clearImageOnlyStepReadyTimeout();\n setCurrentAudioKey(null);\n playbackTimeStore.reset();\n setIsAudioLoadingVisible(false);\n setAudioLoadingReason(DEFAULT_BUFFERING_REASON);\n setHasCompletedCurrentStepAudio(false);\n setHasCurrentAudioPlaybackStarted(false);\n setSubtitleSeekRequest(null);\n if (!options.preservePendingSubtitleJump) {\n pendingSubtitleJumpRef.current = null;\n }\n setActiveInteractionElement(undefined);\n setIsInteractionOverlayOpen(false);\n setInteractionOverlaySubtitleOffset(0);\n },\n [\n clearAutoAdvanceTimer,\n clearImageOnlyStepReadyTimeout,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n playbackTimeStore,\n ]\n );\n\n const requestSubtitleCueSeek = useCallback(\n (target: SlidePlayerSubtitleJumpTarget) => {\n subtitleSeekRequestIdRef.current += 1;\n setSubtitleSeekRequest({\n ...target,\n id: subtitleSeekRequestIdRef.current,\n });\n },\n []\n );\n\n const startCurrentAudioSequence = useCallback(() => {\n const nextAudioKey = currentAudioSequenceKeys[0];\n\n if (!nextAudioKey) {\n return false;\n }\n\n // Start the first audio segment for the current step immediately.\n setCurrentAudioKey(nextAudioKey);\n return true;\n }, [currentAudioSequenceKeys]);\n\n const continueAfterInteraction = useCallback(() => {\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n setIsInteractionOverlayOpen(false);\n setInteractionOverlaySubtitleOffset(0);\n\n if (startCurrentAudioSequence()) {\n return;\n }\n\n if (canGoNext) {\n goNext();\n }\n }, [\n canGoNext,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n goNext,\n startCurrentAudioSequence,\n ]);\n\n const scheduleInteractionOverlayOpen = useCallback(\n (interactionElement?: Element) => {\n clearInteractionOverlayOpenTimer();\n\n if (!interactionElement) {\n return;\n }\n\n const openOverlay = () => {\n interactionOverlayOpenTimerRef.current = null;\n setInteractionOverlaySubtitleOffset(\n DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX\n );\n setIsInteractionOverlayOpen(true);\n pendingInteractionOverlayStepIndexRef.current = null;\n };\n\n interactionOverlayOpenTimerRef.current = window.setTimeout(\n openOverlay,\n DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS\n );\n },\n [clearInteractionOverlayOpenTimer]\n );\n\n const isPlayerControlsHovered = useCallback(\n () =>\n isPointerInsidePlayerControlsRef.current ||\n Boolean(\n sectionRef.current?.querySelector(\".slide-player__controls:hover\")\n ),\n []\n );\n\n const revealPlayerControls = useCallback(\n (enableAutoHide = hasPlayerInteracted) => {\n if (!shouldMountPlayer || resolvedPlayerControlsVisibility === \"hidden\") {\n return;\n }\n\n setIsPlayerVisible(true);\n clearPlayerHideTimer();\n\n if (\n resolvedPlayerControlsVisibility === \"visible\" ||\n !enableAutoHide ||\n playerAutoHideDelay <= 0 ||\n isPlayerControlsHovered()\n ) {\n return;\n }\n\n playerHideTimerRef.current = window.setTimeout(() => {\n if (isPlayerControlsHovered()) {\n playerHideTimerRef.current = null;\n return;\n }\n\n setIsPlayerVisible(false);\n playerHideTimerRef.current = null;\n }, playerAutoHideDelay);\n },\n [\n clearPlayerHideTimer,\n hasPlayerInteracted,\n isPlayerControlsHovered,\n playerAutoHideDelay,\n resolvedPlayerControlsVisibility,\n shouldMountPlayer,\n ]\n );\n\n const hasResolvedCurrentInteraction = Boolean(\n hasResolvedInteractionElement(currentInteractionElement)\n );\n\n const shouldBlockPlaybackForInteraction =\n Boolean(currentInteractionElement) && !hasResolvedCurrentInteraction;\n\n const handlePlaybackPreferenceChange = useCallback((playing: boolean) => {\n setIsPlaybackRequested(playing);\n }, []);\n\n const syncPlaybackPreferenceBeforeNavigation = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n if (context) {\n setIsPlaybackRequested(context.shouldContinuePlayback);\n }\n },\n []\n );\n\n useEffect(() => {\n // Keep silent-step autoplay aligned with the same play/pause preference as audio.\n setIsAutoAdvanceEnabled(isPlaybackRequested);\n }, [currentIndex, isPlaybackRequested, playerCustomActionPauseOnActive]);\n\n useEffect(() => {\n if (playerCustomActionPauseOnActive) {\n setIsPlayerCustomActionActive(false);\n }\n }, [currentIndex, playerCustomActionPauseOnActive]);\n\n useEffect(() => {\n return () => {\n clearAutoAdvanceTimer();\n clearImageOnlyStepReadyTimeout();\n clearPlayerHideTimer();\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n };\n }, [\n clearAutoAdvanceTimer,\n clearImageOnlyStepReadyTimeout,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n clearPlayerHideTimer,\n ]);\n\n useEffect(() => {\n if (!isImageOnlySilentStep) {\n clearImageOnlyStepReadyTimeout();\n return;\n }\n\n let cancelled = false;\n let rafId: number | null = null;\n let cleanupListeners: (() => void) | null = null;\n\n const detachListeners = () => {\n cleanupListeners?.();\n cleanupListeners = null;\n };\n\n const finishVisualReady = () => {\n if (cancelled) {\n return;\n }\n\n detachListeners();\n clearImageOnlyStepReadyTimeout();\n setReadyImageOnlyStepKey(imageOnlyStepVisualReadyKey);\n };\n\n const evaluateVisualReady = () => {\n if (cancelled) {\n return;\n }\n\n detachListeners();\n\n const activeStepContainer = stageLayerRef.current?.querySelector(\n '[data-active-step=\"true\"]'\n ) as HTMLElement | null;\n\n if (!activeStepContainer) {\n return;\n }\n\n const iframeElements = Array.from(\n activeStepContainer.querySelectorAll(\"iframe\")\n ) as HTMLIFrameElement[];\n\n if (\n iframeElements.length === 0 ||\n areImageOnlyStepIframeVisualsReady(iframeElements)\n ) {\n finishVisualReady();\n return;\n }\n\n const cleanupCallbacks: Array<() => void> = [];\n const queueRecheck = () => {\n if (cancelled) {\n return;\n }\n\n if (rafId !== null) {\n window.cancelAnimationFrame(rafId);\n }\n\n rafId = window.requestAnimationFrame(() => {\n rafId = null;\n evaluateVisualReady();\n });\n };\n const registerEvent = (\n target: EventTarget,\n eventName: string,\n listener: EventListener\n ) => {\n target.addEventListener(eventName, listener, { once: true });\n cleanupCallbacks.push(() =>\n target.removeEventListener(eventName, listener)\n );\n };\n\n iframeElements.forEach((iframeElement) => {\n const iframeDocument = iframeElement.contentDocument;\n\n if (!iframeDocument || iframeDocument.readyState !== \"complete\") {\n registerEvent(iframeElement, \"load\", queueRecheck);\n return;\n }\n\n Array.from(iframeDocument.images)\n .filter((image) => !image.complete)\n .forEach((image) => {\n registerEvent(image, \"load\", queueRecheck);\n registerEvent(image, \"error\", queueRecheck);\n });\n });\n\n cleanupListeners = () => {\n cleanupCallbacks.forEach((cleanup) => cleanup());\n };\n };\n\n rafId = window.requestAnimationFrame(() => {\n rafId = null;\n evaluateVisualReady();\n });\n\n imageOnlyStepReadyTimeoutRef.current = window.setTimeout(() => {\n finishVisualReady();\n }, DEFAULT_IMAGE_ONLY_VISUAL_READY_TIMEOUT_MS);\n\n return () => {\n cancelled = true;\n detachListeners();\n clearImageOnlyStepReadyTimeout();\n if (rafId !== null) {\n window.cancelAnimationFrame(rafId);\n }\n };\n }, [\n clearImageOnlyStepReadyTimeout,\n currentElementList,\n currentIndex,\n imageOnlyStepVisualReadyKey,\n isImageOnlySilentStep,\n ]);\n\n useEffect(() => {\n onPlayerVisibilityChange?.(playerControlsVisible);\n\n return () => {\n onPlayerVisibilityChange?.(false);\n };\n }, [onPlayerVisibilityChange, playerControlsVisible]);\n\n useEffect(() => {\n if (playerControlsVisible) {\n return;\n }\n\n isPointerInsidePlayerControlsRef.current = false;\n }, [playerControlsVisible]);\n\n useEffect(() => {\n if (isMobileDevice || mobileViewMode === DEFAULT_MOBILE_VIEW_MODE) {\n return;\n }\n\n setHasManualMobileViewMode(false);\n setMobileViewMode(DEFAULT_MOBILE_VIEW_MODE);\n }, [isMobileDevice, mobileViewMode]);\n\n useEffect(() => {\n if (!isMobileDevice) {\n setIsViewportFullscreenPreferred(false);\n return;\n }\n\n const syncViewportFullscreenPreference = () => {\n setIsViewportFullscreenPreferred(getIsFullscreenPreferredViewport());\n };\n\n syncViewportFullscreenPreference();\n\n return subscribeMobileDeviceChange(syncViewportFullscreenPreference);\n }, [isMobileDevice]);\n\n useEffect(() => {\n onMobileViewModeChange?.(effectiveMobileViewMode);\n }, [effectiveMobileViewMode, onMobileViewModeChange]);\n\n useEffect(() => {\n previousEffectiveMobileViewModeRef.current = effectiveMobileViewMode;\n }, [effectiveMobileViewMode]);\n\n useEffect(() => {\n onStepChange?.(currentStepElement, currentIndex);\n }, [currentIndex, currentStepElement, onStepChange]);\n\n useEffect(() => {\n const previousState = appendedMarkerAdvanceStateRef.current;\n const shouldAdvanceIntoAppendedMarker = shouldAutoAdvanceIntoAppendedMarker(\n {\n previousMarkerCount: previousState.markerCount,\n nextMarkerCount: slideElementList.length,\n previousIndex: previousState.currentIndex,\n previousCanGoNext: previousState.canGoNext,\n nextCanGoNext: canGoNext,\n currentAudioKey,\n hasCompletedCurrentStepAudio,\n hasResolvedCurrentInteraction,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n isAutoAdvanceEnabled,\n shouldUseSilentStepAutoAdvanceToggle,\n }\n );\n\n appendedMarkerAdvanceStateRef.current = {\n markerCount: slideElementList.length,\n currentIndex,\n canGoNext,\n };\n\n if (!shouldAdvanceIntoAppendedMarker) {\n return;\n }\n\n goNext();\n }, [\n canGoNext,\n currentAudioKey,\n currentIndex,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n goNext,\n hasCompletedCurrentStepAudio,\n hasResolvedCurrentInteraction,\n isAutoAdvanceEnabled,\n shouldUseSilentStepAutoAdvanceToggle,\n slideElementList.length,\n ]);\n\n useEffect(() => {\n if (!shouldMountPlayer || resolvedPlayerControlsVisibility === \"hidden\") {\n clearPlayerHideTimer();\n setIsPlayerVisible(false);\n return;\n }\n\n if (resolvedPlayerControlsVisibility === \"visible\") {\n clearPlayerHideTimer();\n setIsPlayerVisible(true);\n return;\n }\n\n if (!hasPlayerInteracted) {\n // Keep the initial player visible briefly, then hide it automatically.\n revealPlayerControls(true);\n }\n }, [\n clearPlayerHideTimer,\n hasPlayerInteracted,\n resolvedPlayerControlsVisibility,\n shouldMountPlayer,\n revealPlayerControls,\n ]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleSandboxInteraction = (event: MessageEvent) => {\n if (event.origin !== window.location.origin) {\n return;\n }\n\n if (!isSandboxInteractionMessage(event.data)) {\n return;\n }\n\n if (event.data.eventType !== \"click\") {\n return;\n }\n\n if (!shouldMountPlayer) {\n return;\n }\n\n // Restore player controls on explicit click/tap without waking on scroll start.\n activateKeyboardShortcutOwner();\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n };\n\n window.addEventListener(\"message\", handleSandboxInteraction);\n\n return () => {\n window.removeEventListener(\"message\", handleSandboxInteraction);\n };\n }, [activateKeyboardShortcutOwner, shouldMountPlayer, revealPlayerControls]);\n\n useWakePlayerFromIframe({\n sectionRef,\n enabled: shouldMountPlayer,\n keyboardShortcutsEnabled: enableKeyboardShortcuts,\n onKeyboardShortcut: activateKeyboardShortcutOwner,\n onWake: () => {\n activateKeyboardShortcutOwner();\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n },\n });\n\n useEffect(() => {\n if (!shouldMountPlayer) {\n resetAudioSequence();\n return;\n }\n\n const { hasPlaybackContextChanged, shouldInitializeAudioSequence } =\n getPlaybackSequenceTransition({\n previousResetKey: playbackResetKeyRef.current,\n nextResetKey: currentPlaybackResetKey,\n currentAudioKey,\n hasCompletedCurrentStepAudio,\n });\n\n playbackResetKeyRef.current = currentPlaybackResetKey;\n\n const shouldOpenInteractionOverlayAfterAudio =\n pendingInteractionOverlayStepIndexRef.current === currentIndex &&\n Boolean(currentInteractionElement);\n const shouldPresentOverlay = shouldPresentInteractionOverlay({\n hasInteraction: Boolean(currentInteractionElement),\n shouldBlockPlaybackForInteraction,\n shouldOpenInteractionOverlayAfterAudio,\n hasPlaybackContextChanged,\n hasResolvedCurrentInteraction,\n currentStepHasSpeakableElement,\n });\n\n const pendingSubtitleJump = pendingSubtitleJumpRef.current;\n const shouldPreservePendingSubtitleJump =\n pendingSubtitleJump?.slideIndex === currentIndex;\n\n if (hasPlaybackContextChanged) {\n resetAudioSequence({\n preservePendingSubtitleJump: shouldPreservePendingSubtitleJump,\n });\n }\n\n if (currentElementList.length === 0 && !currentInteractionElement) {\n return;\n }\n\n if (shouldPausePlaybackForCustomAction) {\n return;\n }\n\n if (pendingSubtitleJump?.slideIndex === currentIndex) {\n if (\n !canReachSubtitleJumpTarget({\n currentIndex,\n resolvedCurrentInteractionElement: activeInteractionElement,\n slideElementList,\n targetSlideIndex: pendingSubtitleJump.slideIndex,\n })\n ) {\n // Keep the pending seek queued while the interaction overlay gates playback.\n } else {\n pendingSubtitleJumpRef.current = null;\n // The default audio-start effect still sees the pre-seek render state.\n // Skip it once so it does not replace the subtitle target audio.\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current = true;\n setCurrentAudioKey(pendingSubtitleJump.audioKey);\n requestSubtitleCueSeek({\n audioIndex: pendingSubtitleJump.audioIndex,\n timeMs: pendingSubtitleJump.timeMs,\n });\n return;\n }\n }\n\n if (currentInteractionElement) {\n setActiveInteractionElement(currentInteractionElement);\n }\n\n if (shouldPresentOverlay) {\n // Delay auto-presenting the overlay so subtitles can settle above it.\n scheduleInteractionOverlayOpen(currentInteractionElement);\n return;\n }\n\n clearInteractionOverlayOpenTimer();\n pendingInteractionOverlayStepIndexRef.current = null;\n\n if (!shouldInitializeAudioSequence) {\n return;\n }\n\n if (startCurrentAudioSequence()) {\n return;\n }\n\n if (currentStepHasSpeakableElement) {\n if (disableLoadingOverlay) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n setIsAudioLoadingVisible(true);\n return;\n }\n\n if (!canGoNext) {\n return;\n }\n\n if (shouldUseSilentStepAutoAdvanceToggle && !isAutoAdvanceEnabled) {\n return;\n }\n\n if (isImageOnlySilentStep && !isImageOnlyStepVisualReady) {\n return;\n }\n\n // Auto-advance silent marker-only steps so playback flow does not stall.\n autoAdvanceTimerRef.current = window.setTimeout(() => {\n autoAdvanceTimerRef.current = null;\n goNext();\n }, silentStepAutoAdvanceDelay);\n\n return () => {\n clearAutoAdvanceTimer();\n };\n }, [\n activeInteractionElement,\n canGoNext,\n clearAutoAdvanceTimer,\n currentElementList.length,\n currentIndex,\n currentInteractionElement,\n currentAudioKey,\n currentPlaybackResetKey,\n currentStepHasSpeakableElement,\n isImageOnlySilentStep,\n isImageOnlyStepVisualReady,\n silentStepAutoAdvanceDelay,\n goNext,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n isAutoAdvanceEnabled,\n hasResolvedCurrentInteraction,\n shouldBlockPlaybackForInteraction,\n clearInteractionOverlayOpenTimer,\n resetAudioSequence,\n requestSubtitleCueSeek,\n scheduleInteractionOverlayOpen,\n shouldMountPlayer,\n slideElementList,\n startCurrentAudioSequence,\n shouldPausePlaybackForCustomAction,\n shouldUseSilentStepAutoAdvanceToggle,\n ]);\n\n useEffect(() => {\n if (\n disableLoadingOverlay ||\n shouldPausePlaybackForCustomAction ||\n !currentStepHasSpeakableElement ||\n shouldBlockPlaybackForInteraction\n ) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (hasCompletedCurrentStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (hasAvailableStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n setAudioLoadingReason(\"waitingForAudio\");\n setIsAudioLoadingVisible(true);\n }, [\n hasAvailableStepAudio,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n shouldPausePlaybackForCustomAction,\n shouldBlockPlaybackForInteraction,\n ]);\n\n useEffect(() => {\n const shouldSkipDefaultAudioStart =\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current;\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current = false;\n\n if (\n !shouldStartDefaultAudioSequence({\n currentAudioKey,\n currentAudioSequenceLength: currentAudioSequenceKeys.length,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n shouldBlockPlaybackForInteraction,\n shouldPausePlaybackForCustomAction,\n shouldSkipDefaultAudioStart,\n })\n ) {\n return;\n }\n\n startCurrentAudioSequence();\n }, [\n currentAudioKey,\n currentAudioSequenceKeys,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n shouldPausePlaybackForCustomAction,\n shouldBlockPlaybackForInteraction,\n startCurrentAudioSequence,\n ]);\n\n useEffect(() => {\n if (!currentAudioKey || currentAudioIndex >= 0) {\n return;\n }\n\n setCurrentAudioKey(null);\n }, [currentAudioIndex, currentAudioKey]);\n\n useEffect(() => {\n if (currentAudioIndex >= 0) {\n return;\n }\n\n playbackTimeStore.reset();\n }, [currentAudioIndex, playbackTimeStore]);\n\n useEffect(() => {\n setHasCurrentAudioPlaybackStarted(false);\n }, [currentPlaybackStartedResetKey]);\n\n const {\n interactionDefaults,\n interactionDefaultSelectedValues,\n isInteractionReadonly,\n shouldAutoContinueInteraction,\n } = useMemo(\n () =>\n resolveSlideInteractionState(activeInteractionElement, {\n interactionDefaultValueOptions,\n }),\n [activeInteractionElement, interactionDefaultValueOptions]\n );\n const shouldShowInteractionOverlay = shouldRenderInteractionOverlay({\n hasActiveInteraction: Boolean(activeInteractionElement),\n isInteractionOverlayOpen,\n shouldBlockPlaybackForInteraction,\n playerControlsVisible,\n shouldMountPlayer,\n });\n\n const handleInteractionSend = useCallback(\n (content: OnSendContentParams) => {\n const submittedValues = [\n ...(content.selectedValues ?? []),\n content.inputText?.trim() ?? \"\",\n content.buttonText?.trim() ?? \"\",\n ].filter(Boolean);\n const resolvedUserInput = submittedValues.join(\", \");\n\n setActiveInteractionElement((prevElement) => {\n if (!prevElement || !resolvedUserInput) {\n return prevElement;\n }\n\n return {\n ...prevElement,\n user_input: resolvedUserInput,\n };\n });\n\n onSend?.(content, activeInteractionElement);\n continueAfterInteraction();\n },\n [activeInteractionElement, continueAfterInteraction, onSend]\n );\n\n useEffect(() => {\n // Keep the player icon in sync with the actual fullscreen owner.\n const syncFullscreenState = () => {\n setIsBrowserFullscreen(document.fullscreenElement === sectionRef.current);\n };\n\n syncFullscreenState();\n document.addEventListener(\"fullscreenchange\", syncFullscreenState);\n\n return () => {\n document.removeEventListener(\"fullscreenchange\", syncFullscreenState);\n };\n }, []);\n\n useEffect(() => {\n if (!shouldShowInteractionOverlay) {\n setInteractionOverlaySubtitleOffset(0);\n return;\n }\n\n const interactionOverlayElement = interactionOverlayRef.current;\n\n if (!interactionOverlayElement) {\n return;\n }\n\n const updateSubtitleOffset = () => {\n const overlayHeight = Math.ceil(\n interactionOverlayElement.getBoundingClientRect().height\n );\n\n setInteractionOverlaySubtitleOffset(\n overlayHeight + DEFAULT_INTERACTION_SUBTITLE_GAP_PX\n );\n };\n\n updateSubtitleOffset();\n\n if (typeof ResizeObserver === \"undefined\") {\n return;\n }\n\n const resizeObserver = new ResizeObserver(() => {\n updateSubtitleOffset();\n });\n\n resizeObserver.observe(interactionOverlayElement);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [shouldShowInteractionOverlay]);\n\n useEffect(() => {\n clearInteractionAutoCloseTimer();\n\n if (!isInteractionOverlayOpen || !shouldAutoContinueInteraction) {\n return;\n }\n\n // Auto-close passive interaction markers to keep playback moving.\n interactionAutoCloseTimerRef.current = window.setTimeout(() => {\n interactionAutoCloseTimerRef.current = null;\n\n continueAfterInteraction();\n }, 2000);\n\n return () => {\n clearInteractionAutoCloseTimer();\n };\n }, [\n clearInteractionAutoCloseTimer,\n continueAfterInteraction,\n isInteractionOverlayOpen,\n shouldAutoContinueInteraction,\n ]);\n\n const renderSlideElement = (\n element?: Element,\n options: RenderSlideElementOptions = {}\n ) => {\n if (!element) {\n return null;\n }\n\n if (element.type === \"slot\") {\n return <>{element.content}</>;\n }\n\n if (element.type === \"html\") {\n return (\n <IframeSandbox\n className=\"content-render-iframe\"\n disableLoadingOverlay={disableLoadingOverlay}\n hideFullScreen\n locale={locale}\n mode=\"blackboard\"\n replaceRootScreenHeightWithFull={\n options.replaceRootScreenHeightWithFull\n }\n type=\"sandbox\"\n content={element.content as string}\n enableScaling={enableIframeScaling}\n />\n );\n }\n\n return (\n <IframeSandbox\n className=\"content-render-iframe\"\n disableLoadingOverlay={disableLoadingOverlay}\n hideFullScreen\n locale={locale}\n mode=\"blackboard\"\n type=\"markdown\"\n content={element.content as string}\n />\n );\n };\n\n const renderSlideElementList = (\n elementList: Element[] = [],\n isActiveStep = false\n ) => {\n if (elementList.length === 0) {\n return null;\n }\n\n const visibleElementCount = elementList.filter(\n (element) => element.is_renderable !== false\n ).length;\n const markdownScalingMode =\n isActiveStep && enableMarkdownScaling\n ? resolveMarkdownScalingMode(elementList)\n : \"disabled\";\n const lastVisibleElementIndex = elementList.reduce(\n (lastVisibleIndex, element, index) =>\n element.is_renderable !== false ? index : lastVisibleIndex,\n -1\n );\n\n return (\n <MarkdownSlideScaling\n className=\"slide-stage__content flex w-full flex-col gap-4\"\n mode={markdownScalingMode}\n >\n {elementList.map((element, index) => {\n const isPreRenderedHtml =\n element.type === \"html\" && element.is_renderable === false;\n\n return (\n <div\n key={element.sequence_number ?? `${element.type}-${index}`}\n ref={\n isActiveStep && index === lastVisibleElementIndex\n ? lastElementRef\n : null\n }\n aria-hidden={isPreRenderedHtml || undefined}\n className={cn(\n \"w-full shrink-0\",\n visibleElementCount === 1 &&\n element.is_renderable !== false &&\n \"slide-element--single\",\n isPreRenderedHtml\n ? \"pointer-events-none fixed left-[-200vw] top-0 -z-10 h-[100dvh] w-[100vw] overflow-hidden opacity-0\"\n : element.is_renderable === false && \"hidden\"\n )}\n >\n {renderSlideElement(element, {\n replaceRootScreenHeightWithFull:\n visibleElementCount === 1 &&\n element.type === \"html\" &&\n element.is_renderable !== false,\n })}\n </div>\n );\n })}\n </MarkdownSlideScaling>\n );\n };\n\n const handleFullscreen = useCallback(() => {\n const target = sectionRef.current;\n if (!target) {\n return;\n }\n\n if (document.fullscreenElement === target) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n\n target.requestFullscreen?.().catch(() => {});\n }, []);\n\n const scrollStageToBottom = useCallback(() => {\n const stageLayerElement = stageLayerRef.current;\n\n if (!stageLayerElement) {\n return;\n }\n\n // Keep the latest content visible after manual player navigation.\n stageLayerElement.scrollTo({\n top: stageLayerElement.scrollHeight,\n behavior: \"smooth\",\n });\n }, []);\n\n const canJumpToSubtitleTarget = useCallback(\n (target: SlidePlayerSubtitleJumpTarget) =>\n canReachSubtitleJumpTarget({\n currentIndex,\n resolvedCurrentInteractionElement: activeInteractionElement,\n slideElementList,\n targetSlideIndex: audioSlideIndexes[target.audioIndex],\n }),\n [\n activeInteractionElement,\n audioSlideIndexes,\n currentIndex,\n slideElementList,\n ]\n );\n\n const handleSubtitleJump = useCallback(\n (\n target: SlidePlayerSubtitleJumpTarget,\n context: SlidePlayerNavigationContext\n ) => {\n const targetAudio = audioList[target.audioIndex];\n const targetAudioKey = targetAudio?.audioKey;\n const targetSlideIndex = audioSlideIndexes[target.audioIndex];\n\n if (!targetAudioKey || targetSlideIndex == null) {\n return false;\n }\n\n if (!canJumpToSubtitleTarget(target)) {\n return false;\n }\n\n syncPlaybackPreferenceBeforeNavigation(context);\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n setHasCompletedCurrentStepAudio(false);\n setHasCurrentAudioPlaybackStarted(false);\n\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n\n if (targetSlideIndex === currentIndex) {\n pendingSubtitleJumpRef.current = null;\n resetAudioSequence();\n setCurrentAudioKey(targetAudioKey);\n requestSubtitleCueSeek(target);\n return true;\n }\n\n shouldScrollToBottomRef.current = true;\n resetAudioSequence();\n pendingSubtitleJumpRef.current = {\n audioIndex: target.audioIndex,\n audioKey: targetAudioKey,\n slideIndex: targetSlideIndex,\n timeMs: target.timeMs,\n };\n goTo(targetSlideIndex);\n\n return true;\n },\n [\n audioList,\n audioSlideIndexes,\n canJumpToSubtitleTarget,\n currentIndex,\n goTo,\n requestSubtitleCueSeek,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handlePrev = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n syncPlaybackPreferenceBeforeNavigation(context);\n shouldScrollToBottomRef.current = true;\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n resetAudioSequence();\n goPrev();\n },\n [\n goPrev,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handleNext = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n syncPlaybackPreferenceBeforeNavigation(context);\n shouldScrollToBottomRef.current = true;\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n resetAudioSequence();\n goNext();\n },\n [\n goNext,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handlePlayerLoadingChange = useCallback(\n ({\n loading,\n reason,\n }: {\n loading: boolean;\n reason: SlidePlayerLoadingReason | null;\n }) => {\n if (disableLoadingOverlay) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (!currentStepHasSpeakableElement || hasCompletedCurrentStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (loading && reason) {\n setAudioLoadingReason(reason);\n }\n setIsAudioLoadingVisible(shouldShowBufferingOverlay(reason, loading));\n },\n [\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n ]\n );\n\n useEffect(() => {\n if (!disableLoadingOverlay) {\n return;\n }\n\n setIsAudioLoadingVisible(false);\n }, [disableLoadingOverlay]);\n\n const handlePlayerEnded = useCallback(\n (audioIndex: number) => {\n const endedAudioKey = audioList[audioIndex]?.audioKey;\n\n if (!endedAudioKey || !currentAudioKey) {\n return;\n }\n\n if (endedAudioKey !== currentAudioKey) {\n return;\n }\n\n const activeSequencePosition = currentAudioSequenceKeys.findIndex(\n (audioSequenceKey) => audioSequenceKey === endedAudioKey\n );\n if (activeSequencePosition < 0) {\n setCurrentAudioKey(null);\n return;\n }\n\n const nextSequencePosition = activeSequencePosition + 1;\n const nextAudioKey = currentAudioSequenceKeys[nextSequencePosition];\n\n if (nextAudioKey) {\n setCurrentAudioKey(nextAudioKey);\n return;\n }\n\n setCurrentAudioKey(null);\n setHasCompletedCurrentStepAudio(true);\n setIsAudioLoadingVisible(false);\n\n if (canGoNext) {\n const nextStepIndex = currentIndex + 1;\n const nextStepElement = slideElementList[nextStepIndex];\n\n if (hasCurrentStepAudioUrl && nextStepElement?.type === \"interaction\") {\n pendingInteractionOverlayStepIndexRef.current = nextStepIndex;\n }\n\n goNext();\n return;\n }\n },\n [\n audioList,\n canGoNext,\n currentIndex,\n currentAudioKey,\n currentAudioSequenceKeys,\n goNext,\n hasCurrentStepAudioUrl,\n slideElementList,\n ]\n );\n\n const handleInteractionToggle = useCallback(() => {\n if (!activeInteractionElement) {\n return;\n }\n\n setIsInteractionOverlayOpen((prevOpen) => !prevOpen);\n }, [activeInteractionElement]);\n\n const handlePlayerControlsPointerEnter = useCallback(() => {\n isPointerInsidePlayerControlsRef.current = true;\n clearPlayerHideTimer();\n\n if (shouldMountPlayer) {\n setIsPlayerVisible(true);\n }\n }, [clearPlayerHideTimer, shouldMountPlayer]);\n\n const handlePlayerControlsPointerLeave = useCallback(() => {\n isPointerInsidePlayerControlsRef.current = false;\n revealPlayerControls(true);\n }, [revealPlayerControls]);\n\n const stopOverlayPropagation = useCallback(\n (\n event:\n | React.PointerEvent<HTMLDivElement>\n | React.MouseEvent<HTMLDivElement>\n ) => {\n event.stopPropagation();\n\n // Keep the player visible a bit longer when users interact with the overlay.\n if (playerControlsVisible) {\n revealPlayerControls(true);\n }\n },\n [playerControlsVisible, revealPlayerControls]\n );\n\n const handleSurfacePointerDown = useCallback(\n (event: React.PointerEvent<HTMLElement>) => {\n activateKeyboardShortcutOwner();\n onPointerDown?.(event);\n },\n [activateKeyboardShortcutOwner, onPointerDown]\n );\n\n const handleSurfaceFocusCapture = useCallback(\n (event: React.FocusEvent<HTMLElement>) => {\n activateKeyboardShortcutOwner();\n onFocusCapture?.(event);\n },\n [activateKeyboardShortcutOwner, onFocusCapture]\n );\n\n const handleSurfaceClick = useCallback(() => {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }, [revealPlayerControls]);\n useEffect(() => {\n const prevKeys = prevRenderElementKeysRef.current;\n const hasStablePrefix =\n prevKeys.length > 0 &&\n prevKeys.length < currentRenderElementKeys.length &&\n prevKeys.every((key, index) => key === currentRenderElementKeys[index]);\n const appendedElements = hasStablePrefix\n ? currentElementList.slice(prevKeys.length)\n : [];\n const shouldAutoScrollToAppend = appendedElements.some(\n (element) => element.is_new === false\n );\n\n prevRenderElementKeysRef.current = currentRenderElementKeys;\n\n if (!shouldAutoScrollToAppend) {\n return;\n }\n\n const animationFrameId = window.requestAnimationFrame(() => {\n const stageLayerElement = stageLayerRef.current;\n const targetElement = lastElementRef.current;\n\n if (!stageLayerElement || !targetElement) {\n return;\n }\n\n const stageLayerRect = stageLayerElement.getBoundingClientRect();\n const targetRect = targetElement.getBoundingClientRect();\n const nextScrollTop =\n stageLayerElement.scrollTop + (targetRect.top - stageLayerRect.top);\n\n // Keep newly appended content visible when the current slide grows downward.\n stageLayerElement.scrollTo({\n top: Math.max(nextScrollTop, 0),\n behavior: \"smooth\",\n });\n });\n\n return () => {\n window.cancelAnimationFrame(animationFrameId);\n };\n }, [currentElementList, currentRenderElementKeys]);\n\n useEffect(() => {\n if (!shouldScrollToBottomRef.current) {\n return;\n }\n\n shouldScrollToBottomRef.current = false;\n\n if (currentElementList.length === 0) {\n return;\n }\n\n const animationFrameId = window.requestAnimationFrame(() => {\n scrollStageToBottom();\n });\n\n return () => {\n window.cancelAnimationFrame(animationFrameId);\n };\n }, [currentElementList, scrollStageToBottom]);\n\n return (\n <section\n ref={sectionRef}\n className={cn(\n \"relative h-full w-full\",\n isMobileDevice && \"slide--mobile-device\",\n isDesktopBrowserFullscreen && \"slide--browser-fullscreen\",\n isImmersiveMobileFullscreen && \"slide--mobile-landscape\",\n isNativeMobileFullscreen && \"slide--mobile-landscape-native\",\n className\n )}\n onClick={handleSurfaceClick}\n onFocusCapture={handleSurfaceFocusCapture}\n onPointerDown={handleSurfacePointerDown}\n {...props}\n >\n {shouldShowMobileFullscreenMask ? (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none fixed left-0 top-0 z-[9999] h-[100vh] max-h-[100vh] w-[100vw]\"\n />\n ) : null}\n\n <div\n ref={viewportRef}\n className={cn(\n \"slide__viewport relative h-full min-h-0 w-full\",\n isImmersiveMobileFullscreen && \"slide__viewport--mobile-landscape\",\n isImmersiveMobileFullscreen &&\n !shouldRotateFullscreenViewport &&\n \"slide__viewport--mobile-landscape-native\"\n )}\n >\n {shouldShowFullscreenHeader ? (\n <div className=\"slide-landscape-header\">\n <button\n aria-label={\n fullscreenHeader?.backAriaLabel ??\n localeTexts.fullscreenBackAriaLabel\n }\n className=\"slide-landscape-header__back\"\n onClick={handleFullscreenHeaderBack}\n type=\"button\"\n >\n <ChevronLeft\n className=\"slide-landscape-header__icon h-6 w-6\"\n strokeWidth={2.25}\n />\n </button>\n\n {fullscreenHeader?.content ? (\n <div className=\"min-w-0 flex-1 overflow-hidden\">\n {fullscreenHeader.content}\n </div>\n ) : null}\n </div>\n ) : null}\n\n <div\n className={cn(\n \"h-full min-h-0 w-full\",\n shouldApplyFullscreenViewportPadding &&\n \"slide__viewport-content--with-header\",\n isSingleSlide ? \"slide-content--single\" : \"grid gap-4\"\n )}\n >\n {currentElementList.length > 0 ? (\n <div className=\"slide-stage\">\n <div ref={stageLayerRef} className=\"slide-stage__layer w-full\">\n {mountedStepStates.map(\n (mountedStepState, mountedStepStateIndex) => {\n const isActiveStep =\n mountedStepStateIndex === currentMountedStateIndex;\n\n return (\n <div\n key={\n mountedStepState.sourceStepIndexes[0] ??\n mountedStepStateIndex\n }\n data-active-step={isActiveStep ? \"true\" : undefined}\n aria-hidden={!isActiveStep || undefined}\n className=\"w-full h-full\"\n style={{ display: isActiveStep ? undefined : \"none\" }}\n >\n {renderSlideElementList(\n mountedStepState.elementList,\n isActiveStep\n )}\n </div>\n );\n }\n )}\n </div>\n </div>\n ) : null}\n </div>\n\n {isAudioLoadingVisible ? (\n <LoadingOverlayCard\n message={resolveBufferingTextByReason(\n resolvedBufferingText,\n audioLoadingReason\n )}\n className=\"absolute left-1/2 top-1/2 z-[3] -translate-x-1/2 -translate-y-1/2\"\n />\n ) : null}\n\n <SubtitleOverlay\n extraBottomOffset={interactionOverlaySubtitleOffset}\n hasPlayerGap={playerControlsVisible}\n isEnabled={isSubtitleEnabled && hasCurrentAudioPlaybackStarted}\n isPlayerHidden={shouldMountPlayer && !playerControlsVisible}\n playbackTimeStore={playbackTimeStore}\n subtitleCues={currentSubtitleCues}\n />\n\n {shouldShowInteractionOverlay ? (\n <div\n ref={interactionOverlayRef}\n data-player-keyboard-shortcuts-ignore=\"true\"\n className={cn(\n \"slide-interaction-overlay\",\n playerControlsVisible && shouldMountPlayer\n ? \"slide-interaction-overlay--with-player\"\n : \"slide-interaction-overlay--standalone\"\n )}\n onClick={stopOverlayPropagation}\n onPointerDown={stopOverlayPropagation}\n style={interactionOverlayStyle}\n >\n <InteractionOverlayCard\n content={String(activeInteractionElement?.content ?? \"\")}\n locale={locale}\n defaultButtonText={interactionDefaults.buttonText ?? \"\"}\n defaultInputText={interactionDefaults.inputText ?? \"\"}\n defaultSelectedValues={interactionDefaultSelectedValues}\n confirmButtonText={\n interactionTexts?.confirmButtonText ??\n localeTexts.interactionTexts.confirmButtonText\n }\n copyButtonText={\n interactionTexts?.copyButtonText ??\n localeTexts.interactionTexts.copyButtonText\n }\n copiedButtonText={\n interactionTexts?.copiedButtonText ??\n localeTexts.interactionTexts.copiedButtonText\n }\n onSend={handleInteractionSend}\n readonly={isInteractionReadonly}\n title={\n interactionTexts?.title ??\n interactionTitle ??\n localeTexts.interactionTexts.title\n }\n />\n </div>\n ) : null}\n\n {shouldMountPlayer ? (\n <PlayerKeyboardShortcutContext.Provider\n value={keyboardShortcutContextValue}\n >\n <Player\n audioList={audioList}\n className={cn(\n \"absolute left-1/2 z-[2] -translate-x-1/2\",\n isDesktopBrowserFullscreen ? \"bottom-3\" : \"-bottom-3\",\n playerClassName,\n !playerControlsVisible && \"pointer-events-none opacity-0\"\n )}\n currentAudioIndex={currentAudioIndex}\n defaultPlaying={isPlaybackRequested}\n enableKeyboardShortcuts={enableKeyboardShortcuts}\n isPlaybackPaused={shouldPausePlaybackForCustomAction}\n isAutoAdvanceEnabled={isAutoAdvanceEnabled}\n locale={locale}\n hasInteraction={Boolean(activeInteractionElement)}\n isInteractionOpen={isInteractionOverlayOpen}\n isSubtitleEnabled={isSubtitleEnabled}\n onAutoAdvanceToggle={setIsAutoAdvanceEnabled}\n onLoadingChange={handlePlayerLoadingChange}\n onPlaybackStarted={() => {\n setHasCurrentAudioPlaybackStarted(true);\n }}\n onPlaybackPreferenceChange={handlePlaybackPreferenceChange}\n onPlaybackTimeChange={playbackTimeStore.setTime}\n onSubtitleToggle={() => {\n setIsSubtitleEnabled((previousEnabled) => !previousEnabled);\n }}\n nextDisabled={!canGoNext}\n onEnded={handlePlayerEnded}\n onFullscreen={handleFullscreen}\n isFullscreen={isBrowserFullscreen}\n mobileViewMode={effectiveMobileViewMode}\n settingsPortalContainer={viewportRef.current}\n onMobileViewModeChange={handleMobileViewModeSelect}\n onControlsPointerEnter={handlePlayerControlsPointerEnter}\n onControlsPointerLeave={handlePlayerControlsPointerLeave}\n onInteractionToggle={handleInteractionToggle}\n onNext={handleNext}\n onPrev={handlePrev}\n onSubtitleJump={handleSubtitleJump}\n canJumpToSubtitleTarget={canJumpToSubtitleTarget}\n prevDisabled={!canGoPrev}\n showControls={playerControlsVisible}\n subtitleSeekRequest={subtitleSeekRequest}\n texts={playerTexts}\n customActionContext={playerCustomActionContext}\n customActions={playerCustomActions}\n useAutoAdvanceToggle={shouldUseSilentStepAutoAdvanceToggle}\n />\n </PlayerKeyboardShortcutContext.Provider>\n ) : null}\n </div>\n </section>\n );\n};\n\nexport default Slide;\n"],"names":["DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS","DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS","DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX","DEFAULT_INTERACTION_SUBTITLE_GAP_PX","DEFAULT_BUFFERING_REASON","resolveBufferingTextByReason","bufferingText","reason","DEFAULT_SLIDE_BUFFERING_TEXTS","mergeBufferingTextWithLocaleDefaults","localeBufferingText","shouldShowBufferingOverlay","loading","InteractionOverlayCard","memo","content","title","locale","defaultButtonText","defaultInputText","defaultSelectedValues","confirmButtonText","copyButtonText","copiedButtonText","onSend","readonly","jsxs","jsx","ContentRender","areStepElementListsEqual","prevElementList","nextElementList","element","index","nextElement","Slide","elementList","playerEnabled","playerControlsVisibility","playerClassName","fullscreenHeader","playerCustomActions","playerCustomActionPauseOnActive","interactionTitle","interactionTexts","playerTexts","playerAutoHideDelay","markerAutoAdvanceDelay","interactionDefaultValueOptions","onPlayerVisibilityChange","onMobileViewModeChange","onStepChange","enableKeyboardShortcuts","enableIframeScaling","enableMarkdownScaling","disableLoadingOverlay","className","onPointerDown","onFocusCapture","props","localeTexts","useMemo","getSlideLocaleTexts","resolvedBufferingText","resolvedPlayerEnabled","resolvedPlayerControlsVisibility","resolveSlidePlayerVisibility","keyboardShortcutOwnerId","useId","sectionRef","useRef","viewportRef","stageLayerRef","lastElementRef","playerHideTimerRef","isPointerInsidePlayerControlsRef","autoAdvanceTimerRef","imageOnlyStepReadyTimeoutRef","interactionAutoCloseTimerRef","interactionOverlayOpenTimerRef","interactionOverlayRef","prevRenderElementKeysRef","shouldScrollToBottomRef","pendingInteractionOverlayStepIndexRef","pendingSubtitleJumpRef","subtitleSeekRequestIdRef","playbackResetKeyRef","appendedMarkerAdvanceStateRef","shouldSkipDefaultAudioStartForSubtitleJumpRef","currentElementList","stepElementLists","slideElementList","currentIndex","audioList","audioSlideIndexes","currentAudioSequenceIndexes","currentStepHasSpeakableElement","currentInteractionElement","canGoPrev","canGoNext","goPrev","goNext","goTo","useSlide","currentStepElement","currentRenderElementKeys","isSingleSlide","shouldMountPlayer","keyboardShortcutContextValue","activateKeyboardShortcutOwner","useCallback","activatePlayerKeyboardShortcutOwner","currentAudioSequenceKeys","audioIndex","audioKey","isPlayerVisible","setIsPlayerVisible","useState","hasPlayerInteracted","setHasPlayerInteracted","isPlaybackRequested","setIsPlaybackRequested","isAutoAdvanceEnabled","setIsAutoAdvanceEnabled","currentAudioKey","setCurrentAudioKey","subtitleSeekRequest","setSubtitleSeekRequest","isAudioLoadingVisible","setIsAudioLoadingVisible","audioLoadingReason","setAudioLoadingReason","hasCompletedCurrentStepAudio","setHasCompletedCurrentStepAudio","hasCurrentAudioPlaybackStarted","setHasCurrentAudioPlaybackStarted","isSubtitleEnabled","setIsSubtitleEnabled","isPlayerCustomActionActive","setIsPlayerCustomActionActive","activeInteractionElement","setActiveInteractionElement","isInteractionOverlayOpen","setIsInteractionOverlayOpen","interactionOverlaySubtitleOffset","setInteractionOverlaySubtitleOffset","isBrowserFullscreen","setIsBrowserFullscreen","isMobileDevice","getIsMobileDevice","mobileViewMode","setMobileViewMode","DEFAULT_MOBILE_VIEW_MODE","hasManualMobileViewMode","setHasManualMobileViewMode","isViewportFullscreenPreferred","setIsViewportFullscreenPreferred","getIsFullscreenPreferredViewport","playbackTimeStore","createPlaybackTimeStore","effectiveMobileViewMode","isImmersiveMobileFullscreen","isNativeMobileFullscreen","shouldRotateFullscreenViewport","resolveMobileViewModeState","previousEffectiveMobileViewModeRef","playerControlsVisible","shouldShowFullscreenHeader","shouldApplyFullscreenViewportPadding","shouldShowMobileFullscreenMask","isDesktopBrowserFullscreen","handleMobileViewModeSelect","nextViewMode","handleMobileViewModeReset","handleFullscreenHeaderBack","setPlayerCustomActionActive","active","togglePlayerCustomActionActive","previous","mountedStepStates","currentMountedStateIndex","nextMountedStepStates","mountedStateIndexByStep","stepElementList","stepIndex","existingMountedStateIndex","mountedStepState","currentStepKey","currentAudioIndex","audioItem","currentAudioItem","currentSubtitleCues","currentAudioSequenceStartKey","playerCustomActionContext","resolvePlayerCustomActionElement","playerCustomActionCount","getPlayerCustomActionCount","interactionOverlayStyle","hasAvailableStepAudio","currentInteractionResetKey","currentPlaybackResetKey","currentPlaybackStartedResetKey","hasCurrentStepAudioUrl","shouldPausePlaybackForCustomAction","shouldUseSilentStepAutoAdvanceToggle","shouldUseAutoAdvanceToggle","silentStepAutoAdvanceBehavior","resolveSilentStepAutoAdvanceBehavior","silentStepAutoAdvanceDelay","isImageOnlySilentStep","imageOnlyStepVisualReadyKey","readyImageOnlyStepKey","setReadyImageOnlyStepKey","isImageOnlyStepVisualReady","clearPlayerHideTimer","clearInteractionAutoCloseTimer","clearInteractionOverlayOpenTimer","clearAutoAdvanceTimer","clearImageOnlyStepReadyTimeout","resetAudioSequence","options","requestSubtitleCueSeek","target","startCurrentAudioSequence","nextAudioKey","continueAfterInteraction","scheduleInteractionOverlayOpen","interactionElement","openOverlay","isPlayerControlsHovered","revealPlayerControls","enableAutoHide","hasResolvedCurrentInteraction","hasResolvedInteractionElement","shouldBlockPlaybackForInteraction","handlePlaybackPreferenceChange","playing","syncPlaybackPreferenceBeforeNavigation","context","useEffect","cancelled","rafId","cleanupListeners","detachListeners","finishVisualReady","evaluateVisualReady","activeStepContainer","iframeElements","areImageOnlyStepIframeVisualsReady","cleanupCallbacks","queueRecheck","registerEvent","eventName","listener","iframeElement","iframeDocument","image","cleanup","DEFAULT_IMAGE_ONLY_VISUAL_READY_TIMEOUT_MS","syncViewportFullscreenPreference","subscribeMobileDeviceChange","previousState","shouldAdvanceIntoAppendedMarker","shouldAutoAdvanceIntoAppendedMarker","handleSandboxInteraction","event","isSandboxInteractionMessage","useWakePlayerFromIframe","hasPlaybackContextChanged","shouldInitializeAudioSequence","getPlaybackSequenceTransition","shouldOpenInteractionOverlayAfterAudio","shouldPresentOverlay","shouldPresentInteractionOverlay","pendingSubtitleJump","shouldPreservePendingSubtitleJump","canReachSubtitleJumpTarget","shouldSkipDefaultAudioStart","shouldStartDefaultAudioSequence","interactionDefaults","interactionDefaultSelectedValues","isInteractionReadonly","shouldAutoContinueInteraction","resolveSlideInteractionState","shouldShowInteractionOverlay","shouldRenderInteractionOverlay","handleInteractionSend","resolvedUserInput","prevElement","syncFullscreenState","interactionOverlayElement","updateSubtitleOffset","overlayHeight","resizeObserver","renderSlideElement","Fragment","IframeSandbox","renderSlideElementList","isActiveStep","visibleElementCount","markdownScalingMode","resolveMarkdownScalingMode","lastVisibleElementIndex","lastVisibleIndex","MarkdownSlideScaling","isPreRenderedHtml","cn","handleFullscreen","scrollStageToBottom","stageLayerElement","canJumpToSubtitleTarget","handleSubtitleJump","targetAudioKey","targetSlideIndex","shouldWakePlayerControlsAfterNavigation","handlePrev","handleNext","handlePlayerLoadingChange","handlePlayerEnded","endedAudioKey","activeSequencePosition","audioSequenceKey","nextSequencePosition","nextStepIndex","nextStepElement","handleInteractionToggle","prevOpen","handlePlayerControlsPointerEnter","handlePlayerControlsPointerLeave","stopOverlayPropagation","handleSurfacePointerDown","handleSurfaceFocusCapture","handleSurfaceClick","prevKeys","shouldAutoScrollToAppend","key","animationFrameId","targetElement","stageLayerRect","targetRect","nextScrollTop","ChevronLeft","mountedStepStateIndex","LoadingOverlayCard","SubtitleOverlay","PlayerKeyboardShortcutContext","Player","previousEnabled"],"mappings":"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"}
1
+ {"version":3,"file":"Slide.cjs.js","sources":["../../../src/components/Slide/Slide.tsx"],"sourcesContent":["import React, {\n memo,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { ChevronLeft } from \"lucide-react\";\n\nimport { isSandboxInteractionMessage } from \"../../lib/sandboxInteraction\";\nimport { cn } from \"../../lib/utils\";\nimport type { MarkdownFlowLocale } from \"../../lib/locale\";\nimport LoadingOverlayCard from \"../ui/loading-overlay-card\";\nimport ContentRender from \"../ContentRender\";\nimport type { ContentRenderProps } from \"../ContentRender/ContentRender\";\nimport IframeSandbox from \"../ContentRender/IframeSandbox\";\nimport type { OnSendContentParams } from \"../types\";\nimport type { InteractionDefaultValueOptions } from \"../../lib/interaction-defaults\";\nimport {\n isLandscapeViewport as getIsFullscreenPreferredViewport,\n isMobileDevice as getIsMobileDevice,\n subscribeMobileDeviceChange,\n} from \"../../lib/mobileDevice\";\nimport Player from \"./Player\";\nimport MarkdownSlideScaling from \"./MarkdownSlideScaling\";\nimport SubtitleOverlay from \"./SubtitleOverlay\";\nimport type {\n PlayerProps,\n SlidePlayerNavigationContext,\n SlidePlayerSubtitleJumpTarget,\n SlidePlayerSubtitleSeekRequest,\n SlidePlayerTexts,\n} from \"./Player\";\nimport type { SlidePlayerLoadingReason } from \"./Player\";\nimport type { Element } from \"./types\";\nimport useSlide from \"./useSlide\";\nimport useWakePlayerFromIframe from \"./useWakePlayerFromIframe\";\nimport { PlayerKeyboardShortcutContext } from \"./utils/playerKeyboardShortcutContext\";\nimport { activatePlayerKeyboardShortcutOwner } from \"./utils/playerKeyboardShortcuts\";\nimport {\n DEFAULT_MOBILE_VIEW_MODE,\n resolveMobileViewModeState,\n type MobileViewMode,\n} from \"./utils/mobileScreenMode\";\nimport {\n shouldPresentInteractionOverlay,\n shouldRenderInteractionOverlay,\n} from \"./utils/interactionPlayback\";\nimport { resolveMarkdownScalingMode } from \"./utils/markdownScaling\";\nimport { shouldWakePlayerControlsAfterNavigation } from \"./utils/playerNavigationContext\";\nimport { shouldAutoAdvanceIntoAppendedMarker } from \"./utils/appendedMarkerAdvance\";\nimport {\n getPlaybackSequenceTransition,\n shouldStartDefaultAudioSequence,\n} from \"./utils/playbackSequence\";\nimport {\n canReachSubtitleJumpTarget,\n hasResolvedInteractionElement,\n} from \"./utils/subtitleJumpNavigation\";\nimport {\n getPlayerCustomActionCount,\n resolvePlayerCustomActionElement,\n} from \"./utils/playerCustomActions\";\nimport { createPlaybackTimeStore } from \"./utils/playbackTimeStore\";\nimport { resolveSlideInteractionState } from \"./utils/interactionResolution\";\nimport { shouldUseAutoAdvanceToggle } from \"./utils/playerToggleMode\";\nimport {\n resolveSlidePlayerVisibility,\n type SlidePlayerControlsVisibility,\n} from \"./utils/playerVisibility\";\nimport {\n DEFAULT_SLIDE_BUFFERING_TEXTS,\n getSlideLocaleTexts,\n type SlideBufferingReason,\n} from \"./slideI18n\";\nimport \"./slide.css\";\nexport type {\n Element,\n ElementAudioSegment,\n ElementSubtitleCue,\n SlidePlayerCustomActionContext,\n SlidePlayerCustomActions,\n} from \"./types\";\nexport type { SlidePlayerControlsVisibility } from \"./utils/playerVisibility\";\n\nconst DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS = 2000;\nconst DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS = 300;\nconst DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX = 160;\nconst DEFAULT_INTERACTION_SUBTITLE_GAP_PX = 16;\nconst DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS = 3000;\nconst INTERACTION_ACTIVITY_SELECTOR = [\n \"button\",\n \"input\",\n \"textarea\",\n '[contenteditable=\"\"]',\n '[contenteditable=\"true\"]',\n '[contenteditable=\"plaintext-only\"]',\n].join(\", \");\nconst DEFAULT_BUFFERING_REASON: SlideBufferingReason = \"waitingForAudio\";\n\nexport type { SlideBufferingReason } from \"./slideI18n\";\n\nexport type SlideBufferingTextConfig =\n | string\n | Partial<Record<SlideBufferingReason, string>>;\n\nconst resolveBufferingTextByReason = (\n bufferingText: SlideBufferingTextConfig,\n reason: SlideBufferingReason\n) => {\n if (typeof bufferingText === \"string\") {\n return bufferingText;\n }\n\n return (\n bufferingText[reason] ??\n bufferingText[DEFAULT_BUFFERING_REASON] ??\n DEFAULT_SLIDE_BUFFERING_TEXTS[reason]\n );\n};\n\nconst mergeBufferingTextWithLocaleDefaults = (\n bufferingText: SlideBufferingTextConfig | undefined,\n localeBufferingText: Record<string, string>\n): SlideBufferingTextConfig => {\n if (typeof bufferingText === \"string\") {\n return bufferingText;\n }\n\n return {\n ...localeBufferingText,\n ...bufferingText,\n };\n};\n\nconst shouldShowBufferingOverlay = (\n reason: SlideBufferingReason | null,\n loading: boolean\n) => {\n if (!loading) {\n return false;\n }\n\n // Keep the silent preload/loading phase invisible until audio is actually playable.\n return reason !== \"loadingAudio\";\n};\n\ntype RenderSlideElementOptions = {\n replaceRootScreenHeightWithFull?: boolean;\n};\n\ninterface InteractionOverlayCardProps {\n content: string;\n title: string;\n locale?: MarkdownFlowLocale;\n defaultButtonText?: string;\n defaultInputText?: string;\n defaultSelectedValues?: string[];\n confirmButtonText?: string;\n copyButtonText?: string;\n copiedButtonText?: string;\n onSend?: (content: OnSendContentParams) => void;\n readonly?: boolean;\n}\n\nexport interface SlideInteractionTexts\n extends Pick<\n ContentRenderProps,\n \"confirmButtonText\" | \"copyButtonText\" | \"copiedButtonText\"\n > {\n title?: string;\n}\n\nexport type SlideFullscreenHeader = {\n content?: React.ReactNode;\n backAriaLabel?: string;\n onBack?: () => void;\n};\n\nconst InteractionOverlayCard = memo(\n ({\n content,\n title,\n locale,\n defaultButtonText,\n defaultInputText,\n defaultSelectedValues,\n confirmButtonText,\n copyButtonText,\n copiedButtonText,\n onSend,\n readonly = false,\n }: InteractionOverlayCardProps) => (\n <div className=\"slide-player__interaction-card\">\n <div className=\"slide-player__interaction-header\">\n <p className=\"slide-player__interaction-title\">{title}</p>\n </div>\n <div className=\"slide-player__interaction-body\">\n <ContentRender\n content={content}\n locale={locale}\n defaultButtonText={defaultButtonText}\n defaultInputText={defaultInputText}\n defaultSelectedValues={defaultSelectedValues}\n confirmButtonText={confirmButtonText}\n copyButtonText={copyButtonText}\n copiedButtonText={copiedButtonText}\n onSend={onSend}\n readonly={readonly}\n sandboxMode=\"content\"\n />\n </div>\n </div>\n )\n);\n\nInteractionOverlayCard.displayName = \"InteractionOverlayCard\";\n\nconst areStepElementListsEqual = (\n prevElementList: Element[],\n nextElementList: Element[]\n) =>\n prevElementList.length === nextElementList.length &&\n prevElementList.every((element, index) => {\n const nextElement = nextElementList[index];\n\n return (\n element.sequence_number === nextElement?.sequence_number &&\n element.type === nextElement?.type &&\n element.content === nextElement?.content\n );\n });\n\nconst TEXT_ENTRY_SELECTOR = [\n 'input:not([type=\"button\"]):not([type=\"checkbox\"]):not([type=\"radio\"]):not([type=\"submit\"])',\n \"textarea\",\n '[contenteditable=\"\"]',\n '[contenteditable=\"true\"]',\n '[contenteditable=\"plaintext-only\"]',\n].join(\", \");\n\nconst isTextEntryTarget = (target: EventTarget | null): target is HTMLElement =>\n target instanceof HTMLElement && target.matches(TEXT_ENTRY_SELECTOR);\nconst isInteractionActivityTarget = (\n target: EventTarget | null\n): target is HTMLElement =>\n target instanceof HTMLElement &&\n target.matches(INTERACTION_ACTIVITY_SELECTOR);\n\nexport interface SlideProps extends React.ComponentProps<\"section\"> {\n elementList?: Element[];\n /** Locale used for built-in UI text when a more specific text prop is not provided. */\n locale?: MarkdownFlowLocale;\n /** Enables the player runtime, including audio playback and keyboard shortcuts. */\n playerEnabled?: boolean;\n /**\n * Controls whether the player controls are always visible, always hidden, or auto-hidden.\n *\n * Use `\"hidden\"` to keep audio playback and keyboard shortcuts active while\n * hiding the visual controls.\n *\n * @example\n * ```tsx\n * <Slide playerControlsVisibility=\"hidden\" enableKeyboardShortcuts />\n * ```\n */\n playerControlsVisibility?: SlidePlayerControlsVisibility;\n playerClassName?: string;\n fullscreenHeader?: SlideFullscreenHeader;\n playerCustomActions?: PlayerProps[\"customActions\"];\n playerCustomActionPauseOnActive?: boolean;\n bufferingText?: SlideBufferingTextConfig;\n interactionTitle?: string;\n interactionTexts?: SlideInteractionTexts;\n playerTexts?: SlidePlayerTexts;\n playerAutoHideDelay?: number;\n markerAutoAdvanceDelay?: number;\n interactionDefaultValueOptions?: InteractionDefaultValueOptions;\n onSend?: (content: OnSendContentParams, element?: Element) => void;\n onPlayerVisibilityChange?: (visible: boolean) => void;\n onMobileViewModeChange?: (viewMode: MobileViewMode) => void;\n onStepChange?: (element: Element | undefined, index: number) => void;\n /**\n * Enables keyboard shortcuts for existing player actions.\n *\n * Defaults to `true`. The active slide responds after users click, touch, or\n * focus the slide/player surface; ignored targets include form controls and\n * interaction overlays.\n *\n * @example\n * ```tsx\n * <Slide elementList={slides} enableKeyboardShortcuts={false} />\n * ```\n */\n enableKeyboardShortcuts?: boolean;\n enableIframeScaling?: boolean;\n /**\n * Fits Markdown-only slides to the available presentation viewport.\n *\n * Defaults to `true`. Disable this to preserve the fixed 16px article\n * typography used by standalone ContentRender.\n */\n enableMarkdownScaling?: boolean;\n disableLoadingOverlay?: boolean;\n}\n\nconst Slide: React.FC<SlideProps> = ({\n elementList = [],\n locale,\n playerEnabled,\n playerControlsVisibility,\n playerClassName,\n fullscreenHeader,\n playerCustomActions,\n playerCustomActionPauseOnActive = true,\n bufferingText,\n interactionTitle,\n interactionTexts,\n playerTexts,\n playerAutoHideDelay = 3000,\n markerAutoAdvanceDelay = DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS,\n interactionDefaultValueOptions,\n onSend,\n onPlayerVisibilityChange,\n onMobileViewModeChange,\n onStepChange,\n enableKeyboardShortcuts = true,\n enableIframeScaling = true,\n enableMarkdownScaling = true,\n disableLoadingOverlay = false,\n className,\n onPointerDown,\n onFocusCapture,\n ...props\n}) => {\n const localeTexts = useMemo(() => getSlideLocaleTexts(locale), [locale]);\n const resolvedBufferingText = useMemo(\n () =>\n mergeBufferingTextWithLocaleDefaults(\n bufferingText,\n localeTexts.bufferingText\n ),\n [bufferingText, localeTexts.bufferingText]\n );\n const {\n playerEnabled: resolvedPlayerEnabled,\n playerControlsVisibility: resolvedPlayerControlsVisibility,\n } = resolveSlidePlayerVisibility({\n playerEnabled,\n playerControlsVisibility,\n });\n const keyboardShortcutOwnerId = useId();\n const sectionRef = useRef<HTMLElement | null>(null);\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const stageLayerRef = useRef<HTMLDivElement | null>(null);\n const lastElementRef = useRef<HTMLDivElement | null>(null);\n const playerHideTimerRef = useRef<number | null>(null);\n const isPointerInsidePlayerControlsRef = useRef(false);\n const autoAdvanceTimerRef = useRef<number | null>(null);\n const interactionAutoCloseTimerRef = useRef<number | null>(null);\n const interactionOverlayOpenTimerRef = useRef<number | null>(null);\n const interactionOverlayRef = useRef<HTMLDivElement | null>(null);\n const prevRenderElementKeysRef = useRef<string[]>([]);\n const shouldScrollToBottomRef = useRef(false);\n const pendingInteractionOverlayStepIndexRef = useRef<number | null>(null);\n const pendingSubtitleJumpRef = useRef<{\n audioIndex: number;\n audioKey: string;\n slideIndex: number;\n timeMs: number;\n } | null>(null);\n const subtitleSeekRequestIdRef = useRef(0);\n const playbackResetKeyRef = useRef<string | null>(null);\n const appendedMarkerAdvanceStateRef = useRef({\n markerCount: 0,\n currentIndex: -1,\n canGoNext: false,\n });\n const shouldSkipDefaultAudioStartForSubtitleJumpRef = useRef(false);\n const {\n currentElementList,\n stepElementLists,\n slideElementList,\n currentIndex,\n audioList,\n audioSlideIndexes,\n currentAudioSequenceIndexes,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n canGoPrev,\n canGoNext,\n handlePrev: goPrev,\n handleNext: goNext,\n handleGoTo: goTo,\n } = useSlide(elementList);\n const currentStepElement = useMemo(() => {\n if (currentIndex < 0) {\n return undefined;\n }\n\n return slideElementList[currentIndex];\n }, [currentIndex, slideElementList]);\n const visibleMarkerCount = slideElementList.filter(\n (element) => element.is_renderable !== false\n ).length;\n const isSingleSlide = visibleMarkerCount === 1;\n const shouldMountPlayer =\n resolvedPlayerEnabled &&\n (slideElementList.length > 0 ||\n audioList.length > 0 ||\n Boolean(currentInteractionElement));\n const keyboardShortcutContextValue = useMemo(\n () => ({\n enabled: enableKeyboardShortcuts,\n ownerId: keyboardShortcutOwnerId,\n }),\n [enableKeyboardShortcuts, keyboardShortcutOwnerId]\n );\n const activateKeyboardShortcutOwner = useCallback(() => {\n if (!enableKeyboardShortcuts || !shouldMountPlayer) {\n return;\n }\n\n activatePlayerKeyboardShortcutOwner(keyboardShortcutOwnerId);\n }, [enableKeyboardShortcuts, keyboardShortcutOwnerId, shouldMountPlayer]);\n const currentAudioSequenceKeys = useMemo(\n () =>\n currentAudioSequenceIndexes\n .map((audioIndex) => audioList[audioIndex]?.audioKey)\n .filter((audioKey): audioKey is string => Boolean(audioKey)),\n [audioList, currentAudioSequenceIndexes]\n );\n const [isPlayerVisible, setIsPlayerVisible] = useState(true);\n const [hasPlayerInteracted, setHasPlayerInteracted] = useState(false);\n const [isPlaybackRequested, setIsPlaybackRequested] = useState(true);\n const [isAutoAdvanceEnabled, setIsAutoAdvanceEnabled] = useState(true);\n const [currentAudioKey, setCurrentAudioKey] = useState<string | null>(null);\n const [subtitleSeekRequest, setSubtitleSeekRequest] =\n useState<SlidePlayerSubtitleSeekRequest | null>(null);\n const [isAudioLoadingVisible, setIsAudioLoadingVisible] = useState(false);\n const [audioLoadingReason, setAudioLoadingReason] =\n useState<SlideBufferingReason>(DEFAULT_BUFFERING_REASON);\n const [hasCompletedCurrentStepAudio, setHasCompletedCurrentStepAudio] =\n useState(false);\n const [hasCurrentAudioPlaybackStarted, setHasCurrentAudioPlaybackStarted] =\n useState(false);\n const [isSubtitleEnabled, setIsSubtitleEnabled] = useState(true);\n const [isPlayerCustomActionActive, setIsPlayerCustomActionActive] =\n useState(false);\n const [activeInteractionElement, setActiveInteractionElement] = useState<\n Element | undefined\n >();\n const [isInteractionOverlayOpen, setIsInteractionOverlayOpen] =\n useState(false);\n const [hasFocusedInteractionTextInput, setHasFocusedInteractionTextInput] =\n useState(false);\n const [hasInteractionOverlayActivity, setHasInteractionOverlayActivity] =\n useState(false);\n const [\n interactionOverlaySubtitleOffset,\n setInteractionOverlaySubtitleOffset,\n ] = useState(0);\n const [isBrowserFullscreen, setIsBrowserFullscreen] = useState(false);\n const isMobileDevice = useMemo(() => getIsMobileDevice(), []);\n const [mobileViewMode, setMobileViewMode] = useState<MobileViewMode>(\n DEFAULT_MOBILE_VIEW_MODE\n );\n const [hasManualMobileViewMode, setHasManualMobileViewMode] = useState(false);\n const [isViewportFullscreenPreferred, setIsViewportFullscreenPreferred] =\n useState(() =>\n isMobileDevice ? getIsFullscreenPreferredViewport() : false\n );\n const playbackTimeStore = useMemo(() => createPlaybackTimeStore(), []);\n const {\n effectiveMobileViewMode,\n isImmersiveMobileFullscreen,\n isNativeMobileFullscreen,\n shouldRotateFullscreenViewport,\n } = useMemo(\n () =>\n resolveMobileViewModeState({\n hasManualMobileViewMode,\n isMobileDevice,\n isViewportFullscreenPreferred,\n mobileViewMode,\n }),\n [\n hasManualMobileViewMode,\n isMobileDevice,\n isViewportFullscreenPreferred,\n mobileViewMode,\n ]\n );\n const previousEffectiveMobileViewModeRef = useRef(effectiveMobileViewMode);\n const playerControlsVisible =\n shouldMountPlayer &&\n resolvedPlayerControlsVisibility !== \"hidden\" &&\n (resolvedPlayerControlsVisibility === \"visible\" || isPlayerVisible);\n const shouldShowFullscreenHeader =\n isImmersiveMobileFullscreen && playerControlsVisible;\n const shouldApplyFullscreenViewportPadding =\n isImmersiveMobileFullscreen && playerControlsVisible;\n const shouldShowMobileFullscreenMask =\n isImmersiveMobileFullscreen || isNativeMobileFullscreen;\n const isDesktopBrowserFullscreen = isBrowserFullscreen && !isMobileDevice;\n const handleMobileViewModeSelect = useCallback(\n (nextViewMode: MobileViewMode) => {\n setHasManualMobileViewMode(true);\n setMobileViewMode(nextViewMode);\n },\n []\n );\n const handleMobileViewModeReset = useCallback(() => {\n // Clear manual override so the effective mode returns to the default non-fullscreen state.\n setHasManualMobileViewMode(false);\n setMobileViewMode(DEFAULT_MOBILE_VIEW_MODE);\n }, []);\n const handleFullscreenHeaderBack = useCallback(() => {\n handleMobileViewModeReset();\n fullscreenHeader?.onBack?.();\n }, [fullscreenHeader, handleMobileViewModeReset]);\n const setPlayerCustomActionActive = useCallback((active: boolean) => {\n setIsPlayerCustomActionActive(active);\n }, []);\n const togglePlayerCustomActionActive = useCallback(() => {\n setIsPlayerCustomActionActive((previous) => !previous);\n }, []);\n const { mountedStepStates, currentMountedStateIndex } = useMemo(() => {\n const nextMountedStepStates: Array<{\n elementList: Element[];\n sourceStepIndexes: number[];\n }> = [];\n const mountedStateIndexByStep = new Map<number, number>();\n\n stepElementLists.forEach((stepElementList, stepIndex) => {\n const existingMountedStateIndex = nextMountedStepStates.findIndex(\n (mountedStepState) =>\n areStepElementListsEqual(\n mountedStepState.elementList,\n stepElementList\n )\n );\n\n if (existingMountedStateIndex >= 0) {\n nextMountedStepStates[\n existingMountedStateIndex\n ]?.sourceStepIndexes.push(stepIndex);\n mountedStateIndexByStep.set(stepIndex, existingMountedStateIndex);\n return;\n }\n\n nextMountedStepStates.push({\n elementList: stepElementList,\n sourceStepIndexes: [stepIndex],\n });\n mountedStateIndexByStep.set(stepIndex, nextMountedStepStates.length - 1);\n });\n\n return {\n mountedStepStates: nextMountedStepStates,\n currentMountedStateIndex:\n currentIndex >= 0\n ? (mountedStateIndexByStep.get(currentIndex) ?? -1)\n : -1,\n };\n }, [currentIndex, stepElementLists]);\n const currentStepKey = useMemo(() => String(currentIndex), [currentIndex]);\n const currentAudioIndex = useMemo(() => {\n if (!currentAudioKey) {\n return -1;\n }\n\n return audioList.findIndex(\n (audioItem) => (audioItem.audioKey ?? \"\") === currentAudioKey\n );\n }, [audioList, currentAudioKey]);\n const currentAudioItem = useMemo(\n () => (currentAudioIndex >= 0 ? audioList[currentAudioIndex] : undefined),\n [audioList, currentAudioIndex]\n );\n const currentSubtitleCues = currentAudioItem?.element?.subtitle_cues ?? [];\n const currentAudioSequenceStartKey = useMemo(\n () => currentAudioSequenceKeys[0] ?? \"none\",\n [currentAudioSequenceKeys]\n );\n const playerCustomActionContext = useMemo(\n () => ({\n currentElement: resolvePlayerCustomActionElement({\n currentAudioIndex,\n currentAudioSequenceIndexes,\n audioList,\n currentInteractionElement: activeInteractionElement,\n currentStepElement,\n }),\n currentIndex,\n currentStepElement,\n isActive: isPlayerCustomActionActive,\n setActive: setPlayerCustomActionActive,\n toggleActive: togglePlayerCustomActionActive,\n }),\n [\n activeInteractionElement,\n audioList,\n currentAudioIndex,\n currentAudioSequenceIndexes,\n currentIndex,\n currentStepElement,\n isPlayerCustomActionActive,\n setPlayerCustomActionActive,\n togglePlayerCustomActionActive,\n ]\n );\n const playerCustomActionCount = useMemo(\n () =>\n getPlayerCustomActionCount(\n playerCustomActions,\n playerCustomActionContext\n ),\n [playerCustomActionContext, playerCustomActions]\n );\n const interactionOverlayStyle = useMemo(\n () =>\n ({\n \"--slide-player-custom-action-count\": String(playerCustomActionCount),\n \"--slide-player-mobile-control-count\": String(\n playerCustomActionCount + 4\n ),\n }) as React.CSSProperties,\n [playerCustomActionCount]\n );\n const hasAvailableStepAudio = currentAudioSequenceKeys.length > 0;\n const currentInteractionResetKey = useMemo(() => {\n if (!currentInteractionElement) {\n return \"none\";\n }\n\n return `${currentInteractionElement.sequence_number ?? \"none\"}:${String(\n currentInteractionElement.content ?? \"\"\n )}`;\n }, [currentInteractionElement]);\n const currentPlaybackResetKey = useMemo(\n () => [currentStepKey, currentInteractionResetKey].join(\"|\"),\n [currentInteractionResetKey, currentStepKey]\n );\n const currentPlaybackStartedResetKey = useMemo(\n () =>\n [\n currentPlaybackResetKey,\n currentAudioItem?.audioKey ?? \"none\",\n String(currentAudioIndex),\n ].join(\"|\"),\n [currentAudioIndex, currentAudioItem?.audioKey, currentPlaybackResetKey]\n );\n const currentStepAudioUrl = useMemo(() => {\n if (\n !currentAudioSequenceStartKey ||\n currentAudioSequenceStartKey === \"none\"\n ) {\n return \"\";\n }\n\n const currentStepAudioItem = audioList.find(\n (audioItem) => audioItem.audioKey === currentAudioSequenceStartKey\n );\n\n return currentStepAudioItem?.audioUrl?.trim() ?? \"\";\n }, [audioList, currentAudioSequenceStartKey]);\n const hasCurrentStepAudioUrl = Boolean(currentStepAudioUrl);\n const shouldPausePlaybackForCustomAction =\n playerCustomActionPauseOnActive &&\n Boolean(playerCustomActions) &&\n isPlayerCustomActionActive;\n const shouldUseSilentStepAutoAdvanceToggle = useMemo(\n () =>\n shouldUseAutoAdvanceToggle({\n canGoNext,\n currentAudioIndex,\n currentStepHasSpeakableElement,\n hasInteraction: Boolean(currentInteractionElement),\n }),\n [\n canGoNext,\n currentAudioIndex,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n ]\n );\n\n const clearPlayerHideTimer = useCallback(() => {\n if (playerHideTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(playerHideTimerRef.current);\n playerHideTimerRef.current = null;\n }, []);\n\n const clearInteractionAutoCloseTimer = useCallback(() => {\n if (interactionAutoCloseTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(interactionAutoCloseTimerRef.current);\n interactionAutoCloseTimerRef.current = null;\n }, []);\n\n const clearInteractionOverlayOpenTimer = useCallback(() => {\n if (interactionOverlayOpenTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(interactionOverlayOpenTimerRef.current);\n interactionOverlayOpenTimerRef.current = null;\n }, []);\n\n const clearAutoAdvanceTimer = useCallback(() => {\n if (autoAdvanceTimerRef.current === null) {\n return;\n }\n\n window.clearTimeout(autoAdvanceTimerRef.current);\n autoAdvanceTimerRef.current = null;\n }, []);\n\n const resetAudioSequence = useCallback(\n (\n options: {\n preservePendingSubtitleJump?: boolean;\n } = {}\n ) => {\n clearAutoAdvanceTimer();\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n setCurrentAudioKey(null);\n playbackTimeStore.reset();\n setIsAudioLoadingVisible(false);\n setAudioLoadingReason(DEFAULT_BUFFERING_REASON);\n setHasCompletedCurrentStepAudio(false);\n setHasCurrentAudioPlaybackStarted(false);\n setSubtitleSeekRequest(null);\n if (!options.preservePendingSubtitleJump) {\n pendingSubtitleJumpRef.current = null;\n }\n setActiveInteractionElement(undefined);\n setIsInteractionOverlayOpen(false);\n setInteractionOverlaySubtitleOffset(0);\n },\n [\n clearAutoAdvanceTimer,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n playbackTimeStore,\n ]\n );\n\n const requestSubtitleCueSeek = useCallback(\n (target: SlidePlayerSubtitleJumpTarget) => {\n subtitleSeekRequestIdRef.current += 1;\n setSubtitleSeekRequest({\n ...target,\n id: subtitleSeekRequestIdRef.current,\n });\n },\n []\n );\n\n const startCurrentAudioSequence = useCallback(() => {\n const nextAudioKey = currentAudioSequenceKeys[0];\n\n if (!nextAudioKey) {\n return false;\n }\n\n // Start the first audio segment for the current step immediately.\n setCurrentAudioKey(nextAudioKey);\n return true;\n }, [currentAudioSequenceKeys]);\n\n const continueAfterInteraction = useCallback(() => {\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n setIsInteractionOverlayOpen(false);\n setInteractionOverlaySubtitleOffset(0);\n\n if (startCurrentAudioSequence()) {\n return;\n }\n\n if (canGoNext) {\n goNext();\n }\n }, [\n canGoNext,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n goNext,\n startCurrentAudioSequence,\n ]);\n\n const scheduleInteractionOverlayOpen = useCallback(\n (interactionElement?: Element) => {\n clearInteractionOverlayOpenTimer();\n\n if (!interactionElement) {\n return;\n }\n\n const openOverlay = () => {\n interactionOverlayOpenTimerRef.current = null;\n setInteractionOverlaySubtitleOffset(\n DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX\n );\n setIsInteractionOverlayOpen(true);\n pendingInteractionOverlayStepIndexRef.current = null;\n };\n\n interactionOverlayOpenTimerRef.current = window.setTimeout(\n openOverlay,\n DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS\n );\n },\n [clearInteractionOverlayOpenTimer]\n );\n\n const isPlayerControlsHovered = useCallback(\n () =>\n isPointerInsidePlayerControlsRef.current ||\n Boolean(\n sectionRef.current?.querySelector(\".slide-player__controls:hover\")\n ),\n []\n );\n\n const revealPlayerControls = useCallback(\n (enableAutoHide = hasPlayerInteracted) => {\n if (!shouldMountPlayer || resolvedPlayerControlsVisibility === \"hidden\") {\n return;\n }\n\n setIsPlayerVisible(true);\n clearPlayerHideTimer();\n\n if (\n resolvedPlayerControlsVisibility === \"visible\" ||\n !enableAutoHide ||\n playerAutoHideDelay <= 0 ||\n isPlayerControlsHovered()\n ) {\n return;\n }\n\n playerHideTimerRef.current = window.setTimeout(() => {\n if (isPlayerControlsHovered()) {\n playerHideTimerRef.current = null;\n return;\n }\n\n setIsPlayerVisible(false);\n playerHideTimerRef.current = null;\n }, playerAutoHideDelay);\n },\n [\n clearPlayerHideTimer,\n hasPlayerInteracted,\n isPlayerControlsHovered,\n playerAutoHideDelay,\n resolvedPlayerControlsVisibility,\n shouldMountPlayer,\n ]\n );\n\n const hasResolvedCurrentInteraction = Boolean(\n hasResolvedInteractionElement(currentInteractionElement)\n );\n\n const shouldBlockPlaybackForInteraction =\n Boolean(currentInteractionElement) && !hasResolvedCurrentInteraction;\n\n const handlePlaybackPreferenceChange = useCallback((playing: boolean) => {\n setIsPlaybackRequested(playing);\n }, []);\n\n const syncPlaybackPreferenceBeforeNavigation = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n if (context) {\n setIsPlaybackRequested(context.shouldContinuePlayback);\n }\n },\n []\n );\n\n useEffect(() => {\n // Keep silent-step autoplay aligned with the same play/pause preference as audio.\n setIsAutoAdvanceEnabled(isPlaybackRequested);\n }, [currentIndex, isPlaybackRequested, playerCustomActionPauseOnActive]);\n\n useEffect(() => {\n if (playerCustomActionPauseOnActive) {\n setIsPlayerCustomActionActive(false);\n }\n }, [currentIndex, playerCustomActionPauseOnActive]);\n\n useEffect(() => {\n return () => {\n clearAutoAdvanceTimer();\n clearPlayerHideTimer();\n clearInteractionAutoCloseTimer();\n clearInteractionOverlayOpenTimer();\n };\n }, [\n clearAutoAdvanceTimer,\n clearInteractionAutoCloseTimer,\n clearInteractionOverlayOpenTimer,\n clearPlayerHideTimer,\n ]);\n\n useEffect(() => {\n onPlayerVisibilityChange?.(playerControlsVisible);\n\n return () => {\n onPlayerVisibilityChange?.(false);\n };\n }, [onPlayerVisibilityChange, playerControlsVisible]);\n\n useEffect(() => {\n if (playerControlsVisible) {\n return;\n }\n\n isPointerInsidePlayerControlsRef.current = false;\n }, [playerControlsVisible]);\n\n useEffect(() => {\n if (isMobileDevice || mobileViewMode === DEFAULT_MOBILE_VIEW_MODE) {\n return;\n }\n\n setHasManualMobileViewMode(false);\n setMobileViewMode(DEFAULT_MOBILE_VIEW_MODE);\n }, [isMobileDevice, mobileViewMode]);\n\n useEffect(() => {\n if (!isMobileDevice) {\n setIsViewportFullscreenPreferred(false);\n return;\n }\n\n const syncViewportFullscreenPreference = () => {\n setIsViewportFullscreenPreferred(getIsFullscreenPreferredViewport());\n };\n\n syncViewportFullscreenPreference();\n\n return subscribeMobileDeviceChange(syncViewportFullscreenPreference);\n }, [isMobileDevice]);\n\n useEffect(() => {\n onMobileViewModeChange?.(effectiveMobileViewMode);\n }, [effectiveMobileViewMode, onMobileViewModeChange]);\n\n useEffect(() => {\n previousEffectiveMobileViewModeRef.current = effectiveMobileViewMode;\n }, [effectiveMobileViewMode]);\n\n useEffect(() => {\n onStepChange?.(currentStepElement, currentIndex);\n }, [currentIndex, currentStepElement, onStepChange]);\n\n useEffect(() => {\n const previousState = appendedMarkerAdvanceStateRef.current;\n const shouldAdvanceIntoAppendedMarker = shouldAutoAdvanceIntoAppendedMarker(\n {\n previousMarkerCount: previousState.markerCount,\n nextMarkerCount: slideElementList.length,\n previousIndex: previousState.currentIndex,\n previousCanGoNext: previousState.canGoNext,\n nextCanGoNext: canGoNext,\n currentAudioKey,\n hasCompletedCurrentStepAudio,\n hasResolvedCurrentInteraction,\n currentStepHasSpeakableElement,\n currentInteractionElement,\n isAutoAdvanceEnabled,\n shouldUseSilentStepAutoAdvanceToggle,\n }\n );\n\n appendedMarkerAdvanceStateRef.current = {\n markerCount: slideElementList.length,\n currentIndex,\n canGoNext,\n };\n\n if (!shouldAdvanceIntoAppendedMarker) {\n return;\n }\n\n goNext();\n }, [\n canGoNext,\n currentAudioKey,\n currentIndex,\n currentInteractionElement,\n currentStepHasSpeakableElement,\n goNext,\n hasCompletedCurrentStepAudio,\n hasResolvedCurrentInteraction,\n isAutoAdvanceEnabled,\n shouldUseSilentStepAutoAdvanceToggle,\n slideElementList.length,\n ]);\n\n useEffect(() => {\n if (!shouldMountPlayer || resolvedPlayerControlsVisibility === \"hidden\") {\n clearPlayerHideTimer();\n setIsPlayerVisible(false);\n return;\n }\n\n if (resolvedPlayerControlsVisibility === \"visible\") {\n clearPlayerHideTimer();\n setIsPlayerVisible(true);\n return;\n }\n\n if (!hasPlayerInteracted) {\n // Keep the initial player visible briefly, then hide it automatically.\n revealPlayerControls(true);\n }\n }, [\n clearPlayerHideTimer,\n hasPlayerInteracted,\n resolvedPlayerControlsVisibility,\n shouldMountPlayer,\n revealPlayerControls,\n ]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleSandboxInteraction = (event: MessageEvent) => {\n if (event.origin !== window.location.origin) {\n return;\n }\n\n if (!isSandboxInteractionMessage(event.data)) {\n return;\n }\n\n if (event.data.eventType !== \"click\") {\n return;\n }\n\n if (!shouldMountPlayer) {\n return;\n }\n\n // Restore player controls on explicit click/tap without waking on scroll start.\n activateKeyboardShortcutOwner();\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n };\n\n window.addEventListener(\"message\", handleSandboxInteraction);\n\n return () => {\n window.removeEventListener(\"message\", handleSandboxInteraction);\n };\n }, [activateKeyboardShortcutOwner, shouldMountPlayer, revealPlayerControls]);\n\n useWakePlayerFromIframe({\n sectionRef,\n enabled: shouldMountPlayer,\n keyboardShortcutsEnabled: enableKeyboardShortcuts,\n onKeyboardShortcut: activateKeyboardShortcutOwner,\n onWake: () => {\n activateKeyboardShortcutOwner();\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n },\n });\n\n useEffect(() => {\n if (!shouldMountPlayer) {\n resetAudioSequence();\n return;\n }\n\n const { hasPlaybackContextChanged, shouldInitializeAudioSequence } =\n getPlaybackSequenceTransition({\n previousResetKey: playbackResetKeyRef.current,\n nextResetKey: currentPlaybackResetKey,\n currentAudioKey,\n hasCompletedCurrentStepAudio,\n });\n\n playbackResetKeyRef.current = currentPlaybackResetKey;\n\n const shouldOpenInteractionOverlayAfterAudio =\n pendingInteractionOverlayStepIndexRef.current === currentIndex &&\n Boolean(currentInteractionElement);\n const shouldPresentOverlay = shouldPresentInteractionOverlay({\n hasInteraction: Boolean(currentInteractionElement),\n shouldBlockPlaybackForInteraction,\n shouldOpenInteractionOverlayAfterAudio,\n hasPlaybackContextChanged,\n hasResolvedCurrentInteraction,\n currentStepHasSpeakableElement,\n });\n\n const pendingSubtitleJump = pendingSubtitleJumpRef.current;\n const shouldPreservePendingSubtitleJump =\n pendingSubtitleJump?.slideIndex === currentIndex;\n\n if (hasPlaybackContextChanged) {\n resetAudioSequence({\n preservePendingSubtitleJump: shouldPreservePendingSubtitleJump,\n });\n }\n\n if (currentElementList.length === 0 && !currentInteractionElement) {\n return;\n }\n\n if (shouldPausePlaybackForCustomAction) {\n return;\n }\n\n if (pendingSubtitleJump?.slideIndex === currentIndex) {\n if (\n !canReachSubtitleJumpTarget({\n currentIndex,\n resolvedCurrentInteractionElement: activeInteractionElement,\n slideElementList,\n targetSlideIndex: pendingSubtitleJump.slideIndex,\n })\n ) {\n // Keep the pending seek queued while the interaction overlay gates playback.\n } else {\n pendingSubtitleJumpRef.current = null;\n // The default audio-start effect still sees the pre-seek render state.\n // Skip it once so it does not replace the subtitle target audio.\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current = true;\n setCurrentAudioKey(pendingSubtitleJump.audioKey);\n requestSubtitleCueSeek({\n audioIndex: pendingSubtitleJump.audioIndex,\n timeMs: pendingSubtitleJump.timeMs,\n });\n return;\n }\n }\n\n if (currentInteractionElement) {\n setActiveInteractionElement(currentInteractionElement);\n }\n\n if (shouldPresentOverlay) {\n // Delay auto-presenting the overlay so subtitles can settle above it.\n scheduleInteractionOverlayOpen(currentInteractionElement);\n return;\n }\n\n clearInteractionOverlayOpenTimer();\n pendingInteractionOverlayStepIndexRef.current = null;\n\n if (!shouldInitializeAudioSequence) {\n return;\n }\n\n if (startCurrentAudioSequence()) {\n return;\n }\n\n if (currentStepHasSpeakableElement) {\n if (disableLoadingOverlay) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n setIsAudioLoadingVisible(true);\n return;\n }\n\n if (!canGoNext) {\n return;\n }\n\n if (shouldUseSilentStepAutoAdvanceToggle && !isAutoAdvanceEnabled) {\n return;\n }\n\n // Auto-advance silent marker-only steps so playback flow does not stall.\n autoAdvanceTimerRef.current = window.setTimeout(() => {\n autoAdvanceTimerRef.current = null;\n goNext();\n }, markerAutoAdvanceDelay);\n\n return () => {\n clearAutoAdvanceTimer();\n };\n }, [\n activeInteractionElement,\n canGoNext,\n clearAutoAdvanceTimer,\n currentElementList.length,\n currentIndex,\n currentInteractionElement,\n currentAudioKey,\n currentPlaybackResetKey,\n currentStepHasSpeakableElement,\n markerAutoAdvanceDelay,\n goNext,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n isAutoAdvanceEnabled,\n hasResolvedCurrentInteraction,\n shouldBlockPlaybackForInteraction,\n clearInteractionOverlayOpenTimer,\n resetAudioSequence,\n requestSubtitleCueSeek,\n scheduleInteractionOverlayOpen,\n shouldMountPlayer,\n slideElementList,\n startCurrentAudioSequence,\n shouldPausePlaybackForCustomAction,\n shouldUseSilentStepAutoAdvanceToggle,\n ]);\n\n useEffect(() => {\n if (\n disableLoadingOverlay ||\n shouldPausePlaybackForCustomAction ||\n !currentStepHasSpeakableElement ||\n shouldBlockPlaybackForInteraction\n ) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (hasCompletedCurrentStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (hasAvailableStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n setAudioLoadingReason(\"waitingForAudio\");\n setIsAudioLoadingVisible(true);\n }, [\n hasAvailableStepAudio,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n shouldPausePlaybackForCustomAction,\n shouldBlockPlaybackForInteraction,\n ]);\n\n useEffect(() => {\n const shouldSkipDefaultAudioStart =\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current;\n shouldSkipDefaultAudioStartForSubtitleJumpRef.current = false;\n\n if (\n !shouldStartDefaultAudioSequence({\n currentAudioKey,\n currentAudioSequenceLength: currentAudioSequenceKeys.length,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n shouldBlockPlaybackForInteraction,\n shouldPausePlaybackForCustomAction,\n shouldSkipDefaultAudioStart,\n })\n ) {\n return;\n }\n\n startCurrentAudioSequence();\n }, [\n currentAudioKey,\n currentAudioSequenceKeys,\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n shouldPausePlaybackForCustomAction,\n shouldBlockPlaybackForInteraction,\n startCurrentAudioSequence,\n ]);\n\n useEffect(() => {\n if (!currentAudioKey || currentAudioIndex >= 0) {\n return;\n }\n\n setCurrentAudioKey(null);\n }, [currentAudioIndex, currentAudioKey]);\n\n useEffect(() => {\n if (currentAudioIndex >= 0) {\n return;\n }\n\n playbackTimeStore.reset();\n }, [currentAudioIndex, playbackTimeStore]);\n\n useEffect(() => {\n setHasCurrentAudioPlaybackStarted(false);\n }, [currentPlaybackStartedResetKey]);\n\n const {\n interactionDefaults,\n interactionDefaultSelectedValues,\n hasResolvedInteractionInput,\n isInteractionReadonly,\n shouldAutoContinueInteraction,\n } = useMemo(\n () =>\n resolveSlideInteractionState(activeInteractionElement, {\n interactionDefaultValueOptions,\n }),\n [activeInteractionElement, interactionDefaultValueOptions]\n );\n const shouldShowInteractionOverlay = shouldRenderInteractionOverlay({\n hasActiveInteraction: Boolean(activeInteractionElement),\n isInteractionOverlayOpen,\n shouldBlockPlaybackForInteraction:\n shouldBlockPlaybackForInteraction &&\n !isInteractionReadonly &&\n !hasResolvedInteractionInput,\n playerControlsVisible,\n shouldMountPlayer,\n hasFocusedTextInput: hasFocusedInteractionTextInput,\n });\n\n const handleInteractionSend = useCallback(\n (content: OnSendContentParams) => {\n const submittedValues = [\n ...(content.selectedValues ?? []),\n content.inputText?.trim() ?? \"\",\n content.buttonText?.trim() ?? \"\",\n ].filter(Boolean);\n const resolvedUserInput = submittedValues.join(\", \");\n\n setActiveInteractionElement((prevElement) => {\n if (!prevElement || !resolvedUserInput) {\n return prevElement;\n }\n\n return {\n ...prevElement,\n user_input: resolvedUserInput,\n };\n });\n\n onSend?.(content, activeInteractionElement);\n continueAfterInteraction();\n },\n [activeInteractionElement, continueAfterInteraction, onSend]\n );\n\n useEffect(() => {\n // Keep the player icon in sync with the actual fullscreen owner.\n const syncFullscreenState = () => {\n setIsBrowserFullscreen(document.fullscreenElement === sectionRef.current);\n };\n\n syncFullscreenState();\n document.addEventListener(\"fullscreenchange\", syncFullscreenState);\n\n return () => {\n document.removeEventListener(\"fullscreenchange\", syncFullscreenState);\n };\n }, []);\n\n useEffect(() => {\n if (activeInteractionElement && isInteractionOverlayOpen) {\n return;\n }\n\n setHasFocusedInteractionTextInput(false);\n setHasInteractionOverlayActivity(false);\n }, [activeInteractionElement, isInteractionOverlayOpen]);\n\n useEffect(() => {\n if (!shouldShowInteractionOverlay) {\n setInteractionOverlaySubtitleOffset(0);\n return;\n }\n\n const interactionOverlayElement = interactionOverlayRef.current;\n\n if (!interactionOverlayElement) {\n return;\n }\n\n const updateSubtitleOffset = () => {\n const overlayHeight = Math.ceil(\n interactionOverlayElement.getBoundingClientRect().height\n );\n\n setInteractionOverlaySubtitleOffset(\n overlayHeight + DEFAULT_INTERACTION_SUBTITLE_GAP_PX\n );\n };\n\n updateSubtitleOffset();\n\n if (typeof ResizeObserver === \"undefined\") {\n return;\n }\n\n const resizeObserver = new ResizeObserver(() => {\n updateSubtitleOffset();\n });\n\n resizeObserver.observe(interactionOverlayElement);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [shouldShowInteractionOverlay]);\n\n useEffect(() => {\n clearInteractionAutoCloseTimer();\n\n if (!isInteractionOverlayOpen) {\n return;\n }\n\n if (shouldAutoContinueInteraction) {\n // Auto-close passive interaction markers to keep playback moving.\n interactionAutoCloseTimerRef.current = window.setTimeout(() => {\n interactionAutoCloseTimerRef.current = null;\n\n continueAfterInteraction();\n }, DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS);\n return () => {\n clearInteractionAutoCloseTimer();\n };\n }\n\n if (hasInteractionOverlayActivity || !hasResolvedInteractionInput) {\n return;\n }\n\n // Give resolved history interactions a short revisit window before\n // playback resumes, but stop auto-closing once the learner starts editing.\n interactionAutoCloseTimerRef.current = window.setTimeout(() => {\n interactionAutoCloseTimerRef.current = null;\n\n continueAfterInteraction();\n }, DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS);\n\n return () => {\n clearInteractionAutoCloseTimer();\n };\n }, [\n clearInteractionAutoCloseTimer,\n continueAfterInteraction,\n hasInteractionOverlayActivity,\n hasResolvedInteractionInput,\n isInteractionOverlayOpen,\n shouldAutoContinueInteraction,\n ]);\n\n const renderSlideElement = (\n element?: Element,\n options: RenderSlideElementOptions = {}\n ) => {\n if (!element) {\n return null;\n }\n\n if (element.type === \"slot\") {\n return <>{element.content}</>;\n }\n\n if (element.type === \"html\") {\n return (\n <IframeSandbox\n className=\"content-render-iframe\"\n disableLoadingOverlay={disableLoadingOverlay}\n hideFullScreen\n locale={locale}\n mode=\"blackboard\"\n replaceRootScreenHeightWithFull={\n options.replaceRootScreenHeightWithFull\n }\n type=\"sandbox\"\n content={element.content as string}\n enableScaling={enableIframeScaling}\n />\n );\n }\n\n return (\n <IframeSandbox\n className=\"content-render-iframe\"\n disableLoadingOverlay={disableLoadingOverlay}\n hideFullScreen\n locale={locale}\n mode=\"blackboard\"\n type=\"markdown\"\n content={element.content as string}\n />\n );\n };\n\n const renderSlideElementList = (\n elementList: Element[] = [],\n isActiveStep = false\n ) => {\n if (elementList.length === 0) {\n return null;\n }\n\n const visibleElementCount = elementList.filter(\n (element) => element.is_renderable !== false\n ).length;\n const markdownScalingMode =\n isActiveStep && enableMarkdownScaling\n ? resolveMarkdownScalingMode(elementList)\n : \"disabled\";\n const lastVisibleElementIndex = elementList.reduce(\n (lastVisibleIndex, element, index) =>\n element.is_renderable !== false ? index : lastVisibleIndex,\n -1\n );\n\n return (\n <MarkdownSlideScaling\n className=\"slide-stage__content flex w-full flex-col gap-4\"\n mode={markdownScalingMode}\n >\n {elementList.map((element, index) => {\n const isPreRenderedHtml =\n element.type === \"html\" && element.is_renderable === false;\n\n return (\n <div\n key={element.sequence_number ?? `${element.type}-${index}`}\n ref={\n isActiveStep && index === lastVisibleElementIndex\n ? lastElementRef\n : null\n }\n aria-hidden={isPreRenderedHtml || undefined}\n className={cn(\n \"w-full shrink-0\",\n visibleElementCount === 1 &&\n element.is_renderable !== false &&\n \"slide-element--single\",\n isPreRenderedHtml\n ? \"pointer-events-none fixed left-[-200vw] top-0 -z-10 h-[100dvh] w-[100vw] overflow-hidden opacity-0\"\n : element.is_renderable === false && \"hidden\"\n )}\n >\n {renderSlideElement(element, {\n replaceRootScreenHeightWithFull:\n visibleElementCount === 1 &&\n element.type === \"html\" &&\n element.is_renderable !== false,\n })}\n </div>\n );\n })}\n </MarkdownSlideScaling>\n );\n };\n\n const handleFullscreen = useCallback(() => {\n const target = sectionRef.current;\n if (!target) {\n return;\n }\n\n if (document.fullscreenElement === target) {\n document.exitFullscreen().catch(() => {});\n return;\n }\n\n target.requestFullscreen?.().catch(() => {});\n }, []);\n\n const scrollStageToBottom = useCallback(() => {\n const stageLayerElement = stageLayerRef.current;\n\n if (!stageLayerElement) {\n return;\n }\n\n // Keep the latest content visible after manual player navigation.\n stageLayerElement.scrollTo({\n top: stageLayerElement.scrollHeight,\n behavior: \"smooth\",\n });\n }, []);\n\n const canJumpToSubtitleTarget = useCallback(\n (target: SlidePlayerSubtitleJumpTarget) =>\n canReachSubtitleJumpTarget({\n currentIndex,\n resolvedCurrentInteractionElement: activeInteractionElement,\n slideElementList,\n targetSlideIndex: audioSlideIndexes[target.audioIndex],\n }),\n [\n activeInteractionElement,\n audioSlideIndexes,\n currentIndex,\n slideElementList,\n ]\n );\n\n const handleSubtitleJump = useCallback(\n (\n target: SlidePlayerSubtitleJumpTarget,\n context: SlidePlayerNavigationContext\n ) => {\n const targetAudio = audioList[target.audioIndex];\n const targetAudioKey = targetAudio?.audioKey;\n const targetSlideIndex = audioSlideIndexes[target.audioIndex];\n\n if (!targetAudioKey || targetSlideIndex == null) {\n return false;\n }\n\n if (!canJumpToSubtitleTarget(target)) {\n return false;\n }\n\n syncPlaybackPreferenceBeforeNavigation(context);\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n setHasCompletedCurrentStepAudio(false);\n setHasCurrentAudioPlaybackStarted(false);\n\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n\n if (targetSlideIndex === currentIndex) {\n pendingSubtitleJumpRef.current = null;\n resetAudioSequence();\n setCurrentAudioKey(targetAudioKey);\n requestSubtitleCueSeek(target);\n return true;\n }\n\n shouldScrollToBottomRef.current = true;\n resetAudioSequence();\n pendingSubtitleJumpRef.current = {\n audioIndex: target.audioIndex,\n audioKey: targetAudioKey,\n slideIndex: targetSlideIndex,\n timeMs: target.timeMs,\n };\n goTo(targetSlideIndex);\n\n return true;\n },\n [\n audioList,\n audioSlideIndexes,\n canJumpToSubtitleTarget,\n currentIndex,\n goTo,\n requestSubtitleCueSeek,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handlePrev = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n syncPlaybackPreferenceBeforeNavigation(context);\n shouldScrollToBottomRef.current = true;\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n resetAudioSequence();\n goPrev();\n },\n [\n goPrev,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handleNext = useCallback(\n (context?: SlidePlayerNavigationContext) => {\n syncPlaybackPreferenceBeforeNavigation(context);\n shouldScrollToBottomRef.current = true;\n pendingInteractionOverlayStepIndexRef.current = null;\n setIsAudioLoadingVisible(false);\n if (shouldWakePlayerControlsAfterNavigation(context)) {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }\n resetAudioSequence();\n goNext();\n },\n [\n goNext,\n resetAudioSequence,\n revealPlayerControls,\n syncPlaybackPreferenceBeforeNavigation,\n ]\n );\n\n const handlePlayerLoadingChange = useCallback(\n ({\n loading,\n reason,\n }: {\n loading: boolean;\n reason: SlidePlayerLoadingReason | null;\n }) => {\n if (disableLoadingOverlay) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (!currentStepHasSpeakableElement || hasCompletedCurrentStepAudio) {\n setIsAudioLoadingVisible(false);\n return;\n }\n\n if (loading && reason) {\n setAudioLoadingReason(reason);\n }\n setIsAudioLoadingVisible(shouldShowBufferingOverlay(reason, loading));\n },\n [\n currentStepHasSpeakableElement,\n hasCompletedCurrentStepAudio,\n disableLoadingOverlay,\n ]\n );\n\n useEffect(() => {\n if (!disableLoadingOverlay) {\n return;\n }\n\n setIsAudioLoadingVisible(false);\n }, [disableLoadingOverlay]);\n\n const handlePlayerEnded = useCallback(\n (audioIndex: number) => {\n const endedAudioKey = audioList[audioIndex]?.audioKey;\n\n if (!endedAudioKey || !currentAudioKey) {\n return;\n }\n\n if (endedAudioKey !== currentAudioKey) {\n return;\n }\n\n const activeSequencePosition = currentAudioSequenceKeys.findIndex(\n (audioSequenceKey) => audioSequenceKey === endedAudioKey\n );\n if (activeSequencePosition < 0) {\n setCurrentAudioKey(null);\n return;\n }\n\n const nextSequencePosition = activeSequencePosition + 1;\n const nextAudioKey = currentAudioSequenceKeys[nextSequencePosition];\n\n if (nextAudioKey) {\n setCurrentAudioKey(nextAudioKey);\n return;\n }\n\n setCurrentAudioKey(null);\n setHasCompletedCurrentStepAudio(true);\n setIsAudioLoadingVisible(false);\n\n if (canGoNext) {\n const nextStepIndex = currentIndex + 1;\n const nextStepElement = slideElementList[nextStepIndex];\n\n if (hasCurrentStepAudioUrl && nextStepElement?.type === \"interaction\") {\n pendingInteractionOverlayStepIndexRef.current = nextStepIndex;\n }\n\n goNext();\n return;\n }\n },\n [\n audioList,\n canGoNext,\n currentIndex,\n currentAudioKey,\n currentAudioSequenceKeys,\n goNext,\n hasCurrentStepAudioUrl,\n slideElementList,\n ]\n );\n\n const handleInteractionToggle = useCallback(() => {\n if (!activeInteractionElement) {\n return;\n }\n\n setIsInteractionOverlayOpen((prevOpen) => !prevOpen);\n }, [activeInteractionElement]);\n\n const handlePlayerControlsPointerEnter = useCallback(() => {\n isPointerInsidePlayerControlsRef.current = true;\n clearPlayerHideTimer();\n\n if (shouldMountPlayer) {\n setIsPlayerVisible(true);\n }\n }, [clearPlayerHideTimer, shouldMountPlayer]);\n\n const handlePlayerControlsPointerLeave = useCallback(() => {\n isPointerInsidePlayerControlsRef.current = false;\n revealPlayerControls(true);\n }, [revealPlayerControls]);\n\n const stopOverlayPropagation = useCallback(\n (\n event:\n | React.PointerEvent<HTMLDivElement>\n | React.MouseEvent<HTMLDivElement>\n ) => {\n event.stopPropagation();\n\n // Keep the player visible a bit longer when users interact with the overlay.\n if (playerControlsVisible) {\n revealPlayerControls(true);\n }\n },\n [playerControlsVisible, revealPlayerControls]\n );\n\n const handleSurfacePointerDown = useCallback(\n (event: React.PointerEvent<HTMLElement>) => {\n activateKeyboardShortcutOwner();\n onPointerDown?.(event);\n },\n [activateKeyboardShortcutOwner, onPointerDown]\n );\n\n const handleSurfaceFocusCapture = useCallback(\n (event: React.FocusEvent<HTMLElement>) => {\n activateKeyboardShortcutOwner();\n onFocusCapture?.(event);\n },\n [activateKeyboardShortcutOwner, onFocusCapture]\n );\n\n const handleSurfaceClick = useCallback(() => {\n setHasPlayerInteracted(true);\n revealPlayerControls(true);\n }, [revealPlayerControls]);\n\n const currentRenderElementKeys = useMemo(\n () =>\n currentElementList.map(\n (element, index) =>\n `${element.sequence_number ?? `${element.type}-${index}`}:${String(element.is_new ?? \"\")}`\n ),\n [currentElementList]\n );\n\n useEffect(() => {\n const prevKeys = prevRenderElementKeysRef.current;\n const hasStablePrefix =\n prevKeys.length > 0 &&\n prevKeys.length < currentRenderElementKeys.length &&\n prevKeys.every((key, index) => key === currentRenderElementKeys[index]);\n const appendedElements = hasStablePrefix\n ? currentElementList.slice(prevKeys.length)\n : [];\n const shouldAutoScrollToAppend = appendedElements.some(\n (element) => element.is_new === false\n );\n\n prevRenderElementKeysRef.current = currentRenderElementKeys;\n\n if (!shouldAutoScrollToAppend) {\n return;\n }\n\n const animationFrameId = window.requestAnimationFrame(() => {\n const stageLayerElement = stageLayerRef.current;\n const targetElement = lastElementRef.current;\n\n if (!stageLayerElement || !targetElement) {\n return;\n }\n\n const stageLayerRect = stageLayerElement.getBoundingClientRect();\n const targetRect = targetElement.getBoundingClientRect();\n const nextScrollTop =\n stageLayerElement.scrollTop + (targetRect.top - stageLayerRect.top);\n\n // Keep newly appended content visible when the current slide grows downward.\n stageLayerElement.scrollTo({\n top: Math.max(nextScrollTop, 0),\n behavior: \"smooth\",\n });\n });\n\n return () => {\n window.cancelAnimationFrame(animationFrameId);\n };\n }, [currentElementList, currentRenderElementKeys]);\n\n useEffect(() => {\n if (!shouldScrollToBottomRef.current) {\n return;\n }\n\n shouldScrollToBottomRef.current = false;\n\n if (currentElementList.length === 0) {\n return;\n }\n\n const animationFrameId = window.requestAnimationFrame(() => {\n scrollStageToBottom();\n });\n\n return () => {\n window.cancelAnimationFrame(animationFrameId);\n };\n }, [currentElementList, scrollStageToBottom]);\n\n return (\n <section\n ref={sectionRef}\n className={cn(\n \"relative h-full w-full\",\n isMobileDevice && \"slide--mobile-device\",\n isDesktopBrowserFullscreen && \"slide--browser-fullscreen\",\n isImmersiveMobileFullscreen && \"slide--mobile-landscape\",\n isNativeMobileFullscreen && \"slide--mobile-landscape-native\",\n className\n )}\n onClick={handleSurfaceClick}\n onFocusCapture={handleSurfaceFocusCapture}\n onPointerDown={handleSurfacePointerDown}\n {...props}\n >\n {shouldShowMobileFullscreenMask ? (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none fixed left-0 top-0 z-[9999] h-[100vh] max-h-[100vh] w-[100vw]\"\n />\n ) : null}\n\n <div\n ref={viewportRef}\n className={cn(\n \"slide__viewport relative h-full min-h-0 w-full\",\n isImmersiveMobileFullscreen && \"slide__viewport--mobile-landscape\",\n isImmersiveMobileFullscreen &&\n !shouldRotateFullscreenViewport &&\n \"slide__viewport--mobile-landscape-native\"\n )}\n >\n {shouldShowFullscreenHeader ? (\n <div className=\"slide-landscape-header\">\n <button\n aria-label={\n fullscreenHeader?.backAriaLabel ??\n localeTexts.fullscreenBackAriaLabel\n }\n className=\"slide-landscape-header__back\"\n onClick={handleFullscreenHeaderBack}\n type=\"button\"\n >\n <ChevronLeft\n className=\"slide-landscape-header__icon h-6 w-6\"\n strokeWidth={2.25}\n />\n </button>\n\n {fullscreenHeader?.content ? (\n <div className=\"min-w-0 flex-1 overflow-hidden\">\n {fullscreenHeader.content}\n </div>\n ) : null}\n </div>\n ) : null}\n\n <div\n className={cn(\n \"h-full min-h-0 w-full\",\n shouldApplyFullscreenViewportPadding &&\n \"slide__viewport-content--with-header\",\n isSingleSlide ? \"slide-content--single\" : \"grid gap-4\"\n )}\n >\n {currentElementList.length > 0 ? (\n <div className=\"slide-stage\">\n <div ref={stageLayerRef} className=\"slide-stage__layer w-full\">\n {mountedStepStates.map(\n (mountedStepState, mountedStepStateIndex) => {\n const isActiveStep =\n mountedStepStateIndex === currentMountedStateIndex;\n\n return (\n <div\n key={\n mountedStepState.sourceStepIndexes[0] ??\n mountedStepStateIndex\n }\n aria-hidden={!isActiveStep || undefined}\n className=\"w-full h-full\"\n style={{ display: isActiveStep ? undefined : \"none\" }}\n >\n {renderSlideElementList(\n mountedStepState.elementList,\n isActiveStep\n )}\n </div>\n );\n }\n )}\n </div>\n </div>\n ) : null}\n </div>\n\n {isAudioLoadingVisible ? (\n <LoadingOverlayCard\n message={resolveBufferingTextByReason(\n resolvedBufferingText,\n audioLoadingReason\n )}\n className=\"absolute left-1/2 top-1/2 z-[3] -translate-x-1/2 -translate-y-1/2\"\n />\n ) : null}\n\n <SubtitleOverlay\n extraBottomOffset={interactionOverlaySubtitleOffset}\n hasPlayerGap={playerControlsVisible}\n isEnabled={isSubtitleEnabled && hasCurrentAudioPlaybackStarted}\n isPlayerHidden={shouldMountPlayer && !playerControlsVisible}\n playbackTimeStore={playbackTimeStore}\n subtitleCues={currentSubtitleCues}\n />\n\n {shouldShowInteractionOverlay ? (\n <div\n ref={interactionOverlayRef}\n data-player-keyboard-shortcuts-ignore=\"true\"\n className={cn(\n \"slide-interaction-overlay\",\n playerControlsVisible && shouldMountPlayer\n ? \"slide-interaction-overlay--with-player\"\n : \"slide-interaction-overlay--standalone\"\n )}\n onClick={stopOverlayPropagation}\n onPointerDown={stopOverlayPropagation}\n onFocusCapture={(event) => {\n if (isTextEntryTarget(event.target)) {\n setHasFocusedInteractionTextInput(true);\n }\n\n if (isInteractionActivityTarget(event.target)) {\n setHasInteractionOverlayActivity(true);\n }\n }}\n onBlurCapture={(event) => {\n if (!isTextEntryTarget(event.target)) {\n return;\n }\n\n const nextFocusTarget = event.relatedTarget;\n\n if (\n nextFocusTarget instanceof HTMLElement &&\n interactionOverlayRef.current?.contains(nextFocusTarget)\n ) {\n return;\n }\n\n setHasFocusedInteractionTextInput(false);\n }}\n onPointerDownCapture={(event) => {\n if (isInteractionActivityTarget(event.target)) {\n setHasInteractionOverlayActivity(true);\n }\n }}\n onInputCapture={(event) => {\n if (isInteractionActivityTarget(event.target)) {\n setHasInteractionOverlayActivity(true);\n }\n }}\n style={interactionOverlayStyle}\n >\n <InteractionOverlayCard\n content={String(activeInteractionElement?.content ?? \"\")}\n locale={locale}\n defaultButtonText={interactionDefaults.buttonText ?? \"\"}\n defaultInputText={interactionDefaults.inputText ?? \"\"}\n defaultSelectedValues={interactionDefaultSelectedValues}\n confirmButtonText={\n interactionTexts?.confirmButtonText ??\n localeTexts.interactionTexts.confirmButtonText\n }\n copyButtonText={\n interactionTexts?.copyButtonText ??\n localeTexts.interactionTexts.copyButtonText\n }\n copiedButtonText={\n interactionTexts?.copiedButtonText ??\n localeTexts.interactionTexts.copiedButtonText\n }\n onSend={handleInteractionSend}\n readonly={isInteractionReadonly}\n title={\n interactionTexts?.title ??\n interactionTitle ??\n localeTexts.interactionTexts.title\n }\n />\n </div>\n ) : null}\n\n {shouldMountPlayer ? (\n <PlayerKeyboardShortcutContext.Provider\n value={keyboardShortcutContextValue}\n >\n <Player\n audioList={audioList}\n className={cn(\n \"absolute left-1/2 z-[2] -translate-x-1/2\",\n isDesktopBrowserFullscreen ? \"bottom-3\" : \"-bottom-3\",\n playerClassName,\n !playerControlsVisible && \"pointer-events-none opacity-0\"\n )}\n currentAudioIndex={currentAudioIndex}\n defaultPlaying={isPlaybackRequested}\n enableKeyboardShortcuts={enableKeyboardShortcuts}\n isPlaybackPaused={shouldPausePlaybackForCustomAction}\n isAutoAdvanceEnabled={isAutoAdvanceEnabled}\n locale={locale}\n hasInteraction={Boolean(activeInteractionElement)}\n isInteractionOpen={isInteractionOverlayOpen}\n isSubtitleEnabled={isSubtitleEnabled}\n onAutoAdvanceToggle={setIsAutoAdvanceEnabled}\n onLoadingChange={handlePlayerLoadingChange}\n onPlaybackStarted={() => {\n setHasCurrentAudioPlaybackStarted(true);\n }}\n onPlaybackPreferenceChange={handlePlaybackPreferenceChange}\n onPlaybackTimeChange={playbackTimeStore.setTime}\n onSubtitleToggle={() => {\n setIsSubtitleEnabled((previousEnabled) => !previousEnabled);\n }}\n nextDisabled={!canGoNext}\n onEnded={handlePlayerEnded}\n onFullscreen={handleFullscreen}\n isFullscreen={isBrowserFullscreen}\n mobileViewMode={effectiveMobileViewMode}\n settingsPortalContainer={viewportRef.current}\n onMobileViewModeChange={handleMobileViewModeSelect}\n onControlsPointerEnter={handlePlayerControlsPointerEnter}\n onControlsPointerLeave={handlePlayerControlsPointerLeave}\n onInteractionToggle={handleInteractionToggle}\n onNext={handleNext}\n onPrev={handlePrev}\n onSubtitleJump={handleSubtitleJump}\n canJumpToSubtitleTarget={canJumpToSubtitleTarget}\n prevDisabled={!canGoPrev}\n showControls={playerControlsVisible}\n subtitleSeekRequest={subtitleSeekRequest}\n texts={playerTexts}\n customActionContext={playerCustomActionContext}\n customActions={playerCustomActions}\n useAutoAdvanceToggle={shouldUseSilentStepAutoAdvanceToggle}\n />\n </PlayerKeyboardShortcutContext.Provider>\n ) : null}\n </div>\n </section>\n );\n};\n\nexport default Slide;\n"],"names":["DEFAULT_MARKER_AUTO_ADVANCE_DELAY_MS","DEFAULT_INTERACTION_OVERLAY_OPEN_DELAY_MS","DEFAULT_INTERACTION_OVERLAY_FALLBACK_OFFSET_PX","DEFAULT_INTERACTION_SUBTITLE_GAP_PX","DEFAULT_RESOLVED_INTERACTION_AUTO_CLOSE_DELAY_MS","INTERACTION_ACTIVITY_SELECTOR","DEFAULT_BUFFERING_REASON","resolveBufferingTextByReason","bufferingText","reason","DEFAULT_SLIDE_BUFFERING_TEXTS","mergeBufferingTextWithLocaleDefaults","localeBufferingText","shouldShowBufferingOverlay","loading","InteractionOverlayCard","memo","content","title","locale","defaultButtonText","defaultInputText","defaultSelectedValues","confirmButtonText","copyButtonText","copiedButtonText","onSend","readonly","jsxs","jsx","ContentRender","areStepElementListsEqual","prevElementList","nextElementList","element","index","nextElement","TEXT_ENTRY_SELECTOR","isTextEntryTarget","target","isInteractionActivityTarget","Slide","elementList","playerEnabled","playerControlsVisibility","playerClassName","fullscreenHeader","playerCustomActions","playerCustomActionPauseOnActive","interactionTitle","interactionTexts","playerTexts","playerAutoHideDelay","markerAutoAdvanceDelay","interactionDefaultValueOptions","onPlayerVisibilityChange","onMobileViewModeChange","onStepChange","enableKeyboardShortcuts","enableIframeScaling","enableMarkdownScaling","disableLoadingOverlay","className","onPointerDown","onFocusCapture","props","localeTexts","useMemo","getSlideLocaleTexts","resolvedBufferingText","resolvedPlayerEnabled","resolvedPlayerControlsVisibility","resolveSlidePlayerVisibility","keyboardShortcutOwnerId","useId","sectionRef","useRef","viewportRef","stageLayerRef","lastElementRef","playerHideTimerRef","isPointerInsidePlayerControlsRef","autoAdvanceTimerRef","interactionAutoCloseTimerRef","interactionOverlayOpenTimerRef","interactionOverlayRef","prevRenderElementKeysRef","shouldScrollToBottomRef","pendingInteractionOverlayStepIndexRef","pendingSubtitleJumpRef","subtitleSeekRequestIdRef","playbackResetKeyRef","appendedMarkerAdvanceStateRef","shouldSkipDefaultAudioStartForSubtitleJumpRef","currentElementList","stepElementLists","slideElementList","currentIndex","audioList","audioSlideIndexes","currentAudioSequenceIndexes","currentStepHasSpeakableElement","currentInteractionElement","canGoPrev","canGoNext","goPrev","goNext","goTo","useSlide","currentStepElement","isSingleSlide","shouldMountPlayer","keyboardShortcutContextValue","activateKeyboardShortcutOwner","useCallback","activatePlayerKeyboardShortcutOwner","currentAudioSequenceKeys","audioIndex","audioKey","isPlayerVisible","setIsPlayerVisible","useState","hasPlayerInteracted","setHasPlayerInteracted","isPlaybackRequested","setIsPlaybackRequested","isAutoAdvanceEnabled","setIsAutoAdvanceEnabled","currentAudioKey","setCurrentAudioKey","subtitleSeekRequest","setSubtitleSeekRequest","isAudioLoadingVisible","setIsAudioLoadingVisible","audioLoadingReason","setAudioLoadingReason","hasCompletedCurrentStepAudio","setHasCompletedCurrentStepAudio","hasCurrentAudioPlaybackStarted","setHasCurrentAudioPlaybackStarted","isSubtitleEnabled","setIsSubtitleEnabled","isPlayerCustomActionActive","setIsPlayerCustomActionActive","activeInteractionElement","setActiveInteractionElement","isInteractionOverlayOpen","setIsInteractionOverlayOpen","hasFocusedInteractionTextInput","setHasFocusedInteractionTextInput","hasInteractionOverlayActivity","setHasInteractionOverlayActivity","interactionOverlaySubtitleOffset","setInteractionOverlaySubtitleOffset","isBrowserFullscreen","setIsBrowserFullscreen","isMobileDevice","getIsMobileDevice","mobileViewMode","setMobileViewMode","DEFAULT_MOBILE_VIEW_MODE","hasManualMobileViewMode","setHasManualMobileViewMode","isViewportFullscreenPreferred","setIsViewportFullscreenPreferred","getIsFullscreenPreferredViewport","playbackTimeStore","createPlaybackTimeStore","effectiveMobileViewMode","isImmersiveMobileFullscreen","isNativeMobileFullscreen","shouldRotateFullscreenViewport","resolveMobileViewModeState","previousEffectiveMobileViewModeRef","playerControlsVisible","shouldShowFullscreenHeader","shouldApplyFullscreenViewportPadding","shouldShowMobileFullscreenMask","isDesktopBrowserFullscreen","handleMobileViewModeSelect","nextViewMode","handleMobileViewModeReset","handleFullscreenHeaderBack","setPlayerCustomActionActive","active","togglePlayerCustomActionActive","previous","mountedStepStates","currentMountedStateIndex","nextMountedStepStates","mountedStateIndexByStep","stepElementList","stepIndex","existingMountedStateIndex","mountedStepState","currentStepKey","currentAudioIndex","audioItem","currentAudioItem","currentSubtitleCues","currentAudioSequenceStartKey","playerCustomActionContext","resolvePlayerCustomActionElement","playerCustomActionCount","getPlayerCustomActionCount","interactionOverlayStyle","hasAvailableStepAudio","currentInteractionResetKey","currentPlaybackResetKey","currentPlaybackStartedResetKey","hasCurrentStepAudioUrl","shouldPausePlaybackForCustomAction","shouldUseSilentStepAutoAdvanceToggle","shouldUseAutoAdvanceToggle","clearPlayerHideTimer","clearInteractionAutoCloseTimer","clearInteractionOverlayOpenTimer","clearAutoAdvanceTimer","resetAudioSequence","options","requestSubtitleCueSeek","startCurrentAudioSequence","nextAudioKey","continueAfterInteraction","scheduleInteractionOverlayOpen","interactionElement","openOverlay","isPlayerControlsHovered","revealPlayerControls","enableAutoHide","hasResolvedCurrentInteraction","hasResolvedInteractionElement","shouldBlockPlaybackForInteraction","handlePlaybackPreferenceChange","playing","syncPlaybackPreferenceBeforeNavigation","context","useEffect","syncViewportFullscreenPreference","subscribeMobileDeviceChange","previousState","shouldAdvanceIntoAppendedMarker","shouldAutoAdvanceIntoAppendedMarker","handleSandboxInteraction","event","isSandboxInteractionMessage","useWakePlayerFromIframe","hasPlaybackContextChanged","shouldInitializeAudioSequence","getPlaybackSequenceTransition","shouldOpenInteractionOverlayAfterAudio","shouldPresentOverlay","shouldPresentInteractionOverlay","pendingSubtitleJump","shouldPreservePendingSubtitleJump","canReachSubtitleJumpTarget","shouldSkipDefaultAudioStart","shouldStartDefaultAudioSequence","interactionDefaults","interactionDefaultSelectedValues","hasResolvedInteractionInput","isInteractionReadonly","shouldAutoContinueInteraction","resolveSlideInteractionState","shouldShowInteractionOverlay","shouldRenderInteractionOverlay","handleInteractionSend","resolvedUserInput","prevElement","syncFullscreenState","interactionOverlayElement","updateSubtitleOffset","overlayHeight","resizeObserver","renderSlideElement","Fragment","IframeSandbox","renderSlideElementList","isActiveStep","visibleElementCount","markdownScalingMode","resolveMarkdownScalingMode","lastVisibleElementIndex","lastVisibleIndex","MarkdownSlideScaling","isPreRenderedHtml","cn","handleFullscreen","scrollStageToBottom","stageLayerElement","canJumpToSubtitleTarget","handleSubtitleJump","targetAudioKey","targetSlideIndex","shouldWakePlayerControlsAfterNavigation","handlePrev","handleNext","handlePlayerLoadingChange","handlePlayerEnded","endedAudioKey","activeSequencePosition","audioSequenceKey","nextSequencePosition","nextStepIndex","nextStepElement","handleInteractionToggle","prevOpen","handlePlayerControlsPointerEnter","handlePlayerControlsPointerLeave","stopOverlayPropagation","handleSurfacePointerDown","handleSurfaceFocusCapture","handleSurfaceClick","currentRenderElementKeys","prevKeys","shouldAutoScrollToAppend","key","animationFrameId","targetElement","stageLayerRect","targetRect","nextScrollTop","ChevronLeft","mountedStepStateIndex","LoadingOverlayCard","SubtitleOverlay","nextFocusTarget","PlayerKeyboardShortcutContext","Player","previousEnabled"],"mappings":"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"}