presenter 0.9.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/3d/index.d.ts +17 -0
  2. package/dist/3d/objects/ThreeBox.d.ts +9 -0
  3. package/dist/3d/objects/ThreeCameraType.d.ts +5 -0
  4. package/dist/3d/objects/ThreeMesh.d.ts +30 -0
  5. package/dist/3d/objects/ThreeModel.d.ts +18 -0
  6. package/dist/3d/objects/ThreeModelMaterial.d.ts +11 -0
  7. package/dist/3d/objects/ThreeModelNode.d.ts +24 -0
  8. package/dist/3d/objects/ThreeModelTarget.d.ts +9 -0
  9. package/dist/3d/objects/ThreeObjectType.d.ts +10 -0
  10. package/dist/3d/objects/ThreePresenterGroup.d.ts +13 -0
  11. package/dist/3d/objects/ThreeScene.d.ts +39 -0
  12. package/dist/3d/objects/ThreeSphere.d.ts +9 -0
  13. package/dist/3d/renderers/getThreeObjectRenderers.d.ts +6 -0
  14. package/dist/3d/renderers/renderThreeSceneFallback.d.ts +3 -0
  15. package/dist/3d/renderers/renderThreeScenePowerPointFallback.d.ts +3 -0
  16. package/dist/3d/renderers/threeFallbackRenderers.d.ts +5 -0
  17. package/dist/3d/types/ThreeModules.d.ts +10 -0
  18. package/dist/3d/utils/colorToThreeHex.d.ts +2 -0
  19. package/dist/3d/utils/inspectThreeModel.d.ts +4 -0
  20. package/dist/3d/utils/installThreeSceneCaptureApi.d.ts +21 -0
  21. package/dist/3d/utils/loadThreeModules.d.ts +2 -0
  22. package/dist/3d/utils/modelCache.d.ts +6 -0
  23. package/dist/3d/utils/modelInspection.d.ts +23 -0
  24. package/dist/3d/utils/modelInspection.test.d.ts +1 -0
  25. package/dist/3d/utils/modelPaths.d.ts +14 -0
  26. package/dist/3d/utils/modelPaths.test.d.ts +1 -0
  27. package/dist/3d.js +2 -0
  28. package/dist/3d.js.map +1 -0
  29. package/dist/3d.mjs +1055 -0
  30. package/dist/3d.mjs.map +1 -0
  31. package/dist/export/browser-image-renderer/BrowserImageRenderer.d.ts +7 -0
  32. package/dist/export/browser-image-renderer/types/BrowserImageRendererProps.d.ts +36 -0
  33. package/dist/export/browser.d.ts +2 -0
  34. package/dist/export/image-renderer/ImageRenderer.d.ts +1 -1
  35. package/dist/export/index.d.ts +2 -0
  36. package/dist/export/utils/getImageExportFrames.d.ts +14 -0
  37. package/dist/export/utils/getImageExportFrames.test.d.ts +1 -0
  38. package/dist/export-browser.js +6 -0
  39. package/dist/export-browser.js.map +1 -0
  40. package/dist/export-browser.mjs +2231 -0
  41. package/dist/export-browser.mjs.map +1 -0
  42. package/dist/export.js +74 -72
  43. package/dist/export.js.map +1 -1
  44. package/dist/export.mjs +5443 -4333
  45. package/dist/export.mjs.map +1 -1
  46. package/dist/objects/Image.d.ts +2 -1
  47. package/dist/presenter.js +5 -5
  48. package/dist/presenter.js.map +1 -1
  49. package/dist/presenter.mjs +1820 -1794
  50. package/dist/presenter.mjs.map +1 -1
  51. package/dist/renderer/browser-canvas/types/BrowserCanvasObjectRenderer.d.ts +8 -1
  52. package/dist/renderer/browser-canvas/utils/text/getTextLayout.d.ts +4 -11
  53. package/dist/renderer/browser-canvas/utils/text/getTextUnitMeasurements.d.ts +9 -0
  54. package/dist/utils/presentation/getImagePathUrlById.d.ts +2 -0
  55. package/dist/utils/presentation/getObjectChildren.d.ts +1 -1
  56. package/package.json +23 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-browser.mjs","sources":["../src/navigator/navigatorHotReload.ts","../src/types/Slide.ts","../src/utils/dom/hasModifierKey.ts","../src/utils/dom/isInteractiveElement.ts","../src/utils/presentation/getPresentationShortcuts.ts","../src/utils/presentation/resolvePresentationShortcutCommand.ts","../src/utils/presentation/setupKeyEventListeners.ts","../src/utils/slide/getSpeakerNotes.ts","../src/navigator/openNavigator.ts","../src/types/Color.ts","../src/types/Size.ts","../src/types/Presentation.ts","../src/types/AnimationType.ts","../src/utils/core/assertNever.ts","../src/utils/animate/getSlideAnimationDuration.ts","../src/utils/color/getAlphaForColor.ts","../src/utils/color/getRgbStringForColor.ts","../src/utils/presentation/isFullBodyPresentation.ts","../src/utils/presentation/createPresentationContainer.ts","../src/utils/presentation/getObjectChildren.ts","../src/utils/presentation/getImagePathUrlById.ts","../src/utils/interpolate/interpolateColor.ts","../src/utils/interpolate/interpolateFallback.ts","../src/utils/interpolate/interpolateNumber.ts","../src/utils/interpolate/defaultInterpolators.ts","../src/utils/interpolate/interpolate.ts","../src/utils/animate/updateObjectStateWithAnimation.ts","../src/utils/presentation/getObjectState.ts","../src/types/ObjectType.ts","../src/utils/presentation/getSvgImageUrlById.ts","../src/utils/storage/storageConsts.ts","../src/utils/storage/loadPresentationState.ts","../src/utils/storage/storePresentationState.ts","../src/renderer/browser-canvas/types/BrowserCanvasRendererState.ts","../src/renderer/browser-canvas/types/UnifiedCanvasContext.ts","../src/utils/objects/text/getTextUnitsFromTextContent.ts","../src/renderer/browser-canvas/utils/accessibility/accessibleDescription.ts","../src/renderer/browser-canvas/utils/clearCanvas.ts","../src/renderer/browser-canvas/utils/createCanvasElement.ts","../src/renderer/browser-canvas/types/UnifiedPath2D.ts","../src/renderer/browser-canvas/utils/createPath2D.ts","../src/utils/objects/arrow/getArrowPoints.ts","../src/utils/color/getHexStringForColor.ts","../src/renderer/browser-canvas/utils/drawStroke.ts","../src/renderer/browser-canvas/utils/fillPath.ts","../src/renderer/browser-canvas/utils/getPathFromPoints.ts","../src/renderer/browser-canvas/objects/renderArrow.ts","../src/utils/objects/circle/getCircleInsetFillPath.ts","../src/utils/objects/circle/getCirclePath.ts","../src/renderer/browser-canvas/utils/clipToPath.ts","../src/renderer/browser-canvas/objects/renderCircle.ts","../src/types/Position.ts","../src/types/Anchor.ts","../src/types/BoundingBox.ts","../src/utils/layout/getBoundingBox.ts","../src/renderer/browser-canvas/objects/renderGroup.ts","../src/utils/objects/rectangle/getRoundedRectanglePath.ts","../src/renderer/browser-canvas/types/UnifiedImage.ts","../src/renderer/browser-canvas/objects/renderImage.ts","../src/utils/objects/line/getLinePath.ts","../src/renderer/browser-canvas/objects/renderLine.ts","../src/renderer/browser-canvas/objects/renderMask.ts","../src/renderer/browser-canvas/objects/renderPath.ts","../src/utils/objects/polygon/getPolygonPath.ts","../src/renderer/browser-canvas/objects/renderPolygon.ts","../src/utils/objects/rectangle/getRectangleInsetFillPath.ts","../src/utils/objects/rectangle/getRectanglePath.ts","../src/renderer/browser-canvas/objects/renderRectangle.ts","../src/utils/objects/spotlight/getSpotlightCutout.ts","../src/utils/objects/spotlight/getSpotlightPath.ts","../src/renderer/browser-canvas/objects/renderSpotlight.ts","../src/renderer/browser-canvas/objects/renderSvg.ts","../src/types/Alignment.ts","../src/utils/objects/text/getTextStyleFromText.ts","../src/renderer/browser-canvas/utils/text/getTextLayout.ts","../src/utils/objects/text/getTextScriptVariant.ts","../src/renderer/browser-canvas/utils/getSizeFromTextMetrics.ts","../src/renderer/browser-canvas/utils/text/setContextWithTextStyle.ts","../src/renderer/browser-canvas/utils/text/getTextUnitMeasurements.ts","../src/renderer/browser-canvas/objects/renderText.ts","../src/renderer/browser-canvas/utils/defaultObjectRenderers.ts","../src/renderer/browser-canvas/utils/extras/createExtrasElement.ts","../src/renderer/browser-canvas/utils/extras/mountWebExtra.ts","../src/renderer/browser-canvas/utils/loadPresentationImages.ts","../src/utils/storage/variableStorage.ts","../src/types/Variable.ts","../src/renderer/browser-canvas/utils/variables/createVariableControlsElement.ts","../src/renderer/browser-canvas/utils/variables/mountVariableControls.ts","../src/renderer/browser-canvas/BrowserCanvasRenderer.ts","../src/utils/slide/getKeySlideBuildIndices.ts","../src/export/utils/getImageExportFrames.ts","../src/export/browser-image-renderer/BrowserImageRenderer.ts"],"sourcesContent":["// Tracks the navigator state that should be restored when Vite hot reloads the presentation.\nconst NAVIGATOR_STATE_SESSION_KEY = \"presenter.navigator.state\";\n\nexport interface NavigatorState {\n readonly open: boolean;\n readonly visibility: {\n readonly slides: boolean;\n readonly current: boolean;\n readonly next: boolean;\n readonly notes: boolean;\n };\n}\n\nconst DEFAULT_NAVIGATOR_STATE: NavigatorState = {\n open: false,\n visibility: {\n slides: true,\n current: true,\n next: true,\n notes: false,\n },\n};\n\n// Detects Vite development mode by looking for Vite's injected HMR client script.\nexport function isNavigatorHotReloadEnabled(): boolean {\n if (typeof document === \"undefined\") {\n return false;\n }\n\n return Array.from(document.scripts).some((script) => script.src.includes(\"/@vite/client\"));\n}\n\n// Returns true when an open navigator should be restored after a hot reload.\nexport function shouldRestoreNavigatorAfterHotReload(): boolean {\n if (!isNavigatorHotReloadEnabled()) {\n return false;\n }\n\n return loadNavigatorStateForHotReload().open;\n}\n\n// Records that the navigator is open so the next Vite reload can rebuild it.\nexport function markNavigatorOpenForHotReload(): void {\n saveNavigatorStateForHotReload({\n ...loadNavigatorStateForHotReload(),\n open: true,\n });\n}\n\n// Clears the navigator state when the user closes the navigator.\nexport function markNavigatorClosedForHotReload(): void {\n getSessionStorage()?.removeItem(NAVIGATOR_STATE_SESSION_KEY);\n}\n\nexport function loadNavigatorStateForHotReload(): NavigatorState {\n if (!isNavigatorHotReloadEnabled()) {\n return DEFAULT_NAVIGATOR_STATE;\n }\n\n try {\n const storedState = getSessionStorage()?.getItem(NAVIGATOR_STATE_SESSION_KEY);\n if (storedState === null || storedState === undefined) {\n return DEFAULT_NAVIGATOR_STATE;\n }\n\n const state = JSON.parse(storedState) as Partial<NavigatorState>;\n return {\n open: typeof state.open === \"boolean\" ? state.open : DEFAULT_NAVIGATOR_STATE.open,\n visibility: {\n slides:\n typeof state.visibility?.slides === \"boolean\"\n ? state.visibility.slides\n : DEFAULT_NAVIGATOR_STATE.visibility.slides,\n current:\n typeof state.visibility?.current === \"boolean\"\n ? state.visibility.current\n : DEFAULT_NAVIGATOR_STATE.visibility.current,\n next:\n typeof state.visibility?.next === \"boolean\"\n ? state.visibility.next\n : DEFAULT_NAVIGATOR_STATE.visibility.next,\n notes:\n typeof state.visibility?.notes === \"boolean\"\n ? state.visibility.notes\n : DEFAULT_NAVIGATOR_STATE.visibility.notes,\n },\n };\n } catch {\n return DEFAULT_NAVIGATOR_STATE;\n }\n}\n\nexport function saveNavigatorStateForHotReload(state: NavigatorState): void {\n if (!isNavigatorHotReloadEnabled()) {\n return;\n }\n\n getSessionStorage()?.setItem(NAVIGATOR_STATE_SESSION_KEY, JSON.stringify(state));\n}\n\n// Reads sessionStorage defensively in case the browser blocks access.\nfunction getSessionStorage(): Storage | null {\n try {\n return window.sessionStorage;\n } catch {\n return null;\n }\n}\n","import { SlideAnimation } from \"./SlideAnimation\";\nimport { SlideObject } from \"./SlideObject\";\nimport { SlideWebExtra } from \"./SlideWebExtra\";\n\nexport interface Slide {\n readonly objects: SlideObject[];\n readonly animations: SlideAnimation[];\n readonly extras: SlideWebExtra[];\n /** A screen-reader description of the slide. */\n readonly description: string | null;\n readonly isAllKey: boolean;\n readonly isEndKey: boolean;\n readonly isStartKey: boolean;\n readonly notes: string | null;\n readonly shortcut: string | string[] | null;\n readonly title: string;\n}\n\nexport function Slide(props: Partial<Slide> | null = null): Slide {\n return {\n objects: [],\n animations: [],\n extras: [],\n description: null,\n isAllKey: false,\n isEndKey: true,\n isStartKey: false,\n notes: null,\n shortcut: null,\n title: \"\",\n ...props,\n };\n}\n","export function hasModifierKey(event: KeyboardEvent): boolean {\n return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\n}\n","export function isInteractiveElement(target: EventTarget | null): boolean {\n if (target === null) {\n return false;\n }\n\n const element = target as HTMLElement;\n const tagName = element.tagName?.toLowerCase();\n if (\n tagName === \"input\" ||\n tagName === \"textarea\" ||\n tagName === \"select\" ||\n tagName === \"button\" ||\n element.isContentEditable\n ) {\n return true;\n }\n\n return (element.closest?.(\"[contenteditable=''], [contenteditable='true']\") ?? null) !== null;\n}\n","import { Presentation } from \"../../types/Presentation\";\nimport { ShortcutConfig } from \"../../types/ShortcutState\";\n\nexport function getPresentationShortcuts(\n presentation: Presentation,\n): Record<string, ShortcutConfig> {\n const { slides } = presentation;\n const shortcuts: Record<string, ShortcutConfig> = {\n // First build of first slide\n s: { slideIndex: 0, buildIndex: 0 },\n\n // First build of current slide\n c: { slideIndex: null, buildIndex: 0 },\n\n // Last build of last slide\n e: {\n slideIndex: slides.length - 1,\n buildIndex: slides[slides.length - 1]?.animations.length ?? 0,\n },\n };\n\n for (let slideIndex = 0; slideIndex < slides.length; slideIndex++) {\n const slide = slides[slideIndex];\n if (slide === undefined) {\n continue;\n }\n\n // Add shortcuts that jump directly to slides\n const shortcut = slide.shortcut;\n addShortcut(shortcuts, shortcut, slideIndex, 0);\n\n // Add shortcuts that jump directly to builds within slides\n for (let animationIndex = 0; animationIndex < slide.animations.length; animationIndex++) {\n const animation = slide.animations[animationIndex];\n if (animation === undefined) {\n continue;\n }\n\n if (Array.isArray(animation)) {\n for (const anim of animation) {\n addShortcut(shortcuts, anim.shortcut, slideIndex, animationIndex + 1);\n }\n } else {\n addShortcut(shortcuts, animation.shortcut, slideIndex, animationIndex + 1);\n }\n }\n }\n\n return shortcuts;\n}\n\nfunction addShortcut(\n shortcuts: Record<string, ShortcutConfig>,\n shortcut: string | string[] | null,\n slideIndex: number,\n buildIndex: number,\n) {\n if (shortcut === null) {\n return;\n }\n\n if (Array.isArray(shortcut)) {\n for (const key of shortcut) {\n shortcuts[key] = { slideIndex, buildIndex };\n }\n } else {\n shortcuts[shortcut] = { slideIndex, buildIndex };\n }\n}\n","import { ShortcutConfig } from \"../../types/ShortcutState\";\n\nexport function resolvePresentationShortcutCommand(\n shortcuts: Record<string, ShortcutConfig>,\n command: string,\n): ShortcutConfig | null {\n const shortcutConfig = shortcuts[command];\n if (shortcutConfig !== undefined) {\n return shortcutConfig;\n }\n\n if (!isNaN(Number(command))) {\n return { slideIndex: Number(command) - 1, buildIndex: 0 };\n }\n\n return null;\n}\n","import { Presentation } from \"../../types/Presentation\";\nimport { ShortcutState } from \"../../types/ShortcutState\";\nimport { hasModifierKey } from \"../dom/hasModifierKey\";\nimport { isInteractiveElement } from \"../dom/isInteractiveElement\";\nimport { getPresentationShortcuts } from \"./getPresentationShortcuts\";\nimport { resolvePresentationShortcutCommand } from \"./resolvePresentationShortcutCommand\";\n\ninterface Callbacks {\n readonly onNext: (skipIntermediateBuilds: boolean) => void;\n readonly onPrevious: (skipIntermediateBuilds: boolean) => void;\n readonly onRenderSlide: (slideIndex: number | null, buildIndex: number) => void;\n readonly onShowNavigator: () => void;\n}\n\ninterface Options {\n // For non-full-screen presentations, click should focus the presentation to accept keyboard events\n readonly focusOnPointerDown?: boolean;\n readonly keyEventTarget?: HTMLElement | Window;\n // Allows callers to remove all listeners created by this setup call at once.\n readonly signal?: AbortSignal;\n}\n\nexport function setupKeyEventListeners(\n presentation: Presentation,\n element: HTMLElement,\n shortcutState: ShortcutState,\n { onNext, onPrevious, onRenderSlide, onShowNavigator }: Callbacks,\n { focusOnPointerDown = false, keyEventTarget = element, signal }: Options = {},\n) {\n shortcutState.shortcuts = getPresentationShortcuts(presentation);\n const listenerOptions = signal === undefined ? undefined : { signal };\n\n if (focusOnPointerDown) {\n if (!element.hasAttribute(\"tabindex\")) {\n element.tabIndex = -1;\n }\n element.addEventListener(\n \"pointerdown\",\n (event) => {\n if (isInteractiveElement(event.target)) {\n return;\n }\n\n element.focus({ preventScroll: true });\n },\n listenerOptions,\n );\n }\n\n // Show cursor when mouse moves\n element.addEventListener(\n \"mousemove\",\n () => {\n element.style.cursor = \"auto\";\n },\n listenerOptions,\n );\n\n keyEventTarget.addEventListener(\n \"keyup\",\n (event) => {\n const keyEvent = event as KeyboardEvent;\n if (isInteractiveElement(keyEvent.target)) {\n return;\n }\n\n // Reset command\n if (keyEvent.code === \"Escape\") {\n shortcutState.textCommand = null;\n return;\n }\n\n // Next slide\n if (keyEvent.code === \"ArrowRight\" || keyEvent.code === \"Space\") {\n onNext(keyEvent.shiftKey);\n return;\n }\n\n // Previous slide\n if (keyEvent.code === \"ArrowLeft\") {\n onPrevious(keyEvent.shiftKey);\n return;\n }\n\n const altCommand = getAltShortcutCommand(keyEvent);\n if (altCommand !== null) {\n const shortcutConfig = resolvePresentationShortcutCommand(\n shortcutState.shortcuts,\n altCommand,\n );\n shortcutState.textCommand = null;\n\n if (shortcutConfig !== null) {\n keyEvent.preventDefault();\n onRenderSlide(shortcutConfig.slideIndex, shortcutConfig.buildIndex);\n }\n\n return;\n }\n\n // Check for an active text command\n if (shortcutState.textCommand !== null) {\n // Submitting a text command\n if (keyEvent.code === \"Enter\") {\n const command = shortcutState.textCommand;\n shortcutState.textCommand = null;\n\n const shortcutConfig = resolvePresentationShortcutCommand(\n shortcutState.shortcuts,\n command,\n );\n if (shortcutConfig !== null) {\n onRenderSlide(shortcutConfig.slideIndex, shortcutConfig.buildIndex);\n }\n\n return;\n } else if (keyEvent.code === \"Backspace\") {\n // Backspace to delete last character\n shortcutState.textCommand = shortcutState.textCommand.slice(0, -1);\n } else {\n // Add character to text command\n shortcutState.textCommand += keyEvent.key;\n }\n return;\n }\n\n // Start a new text command\n if (keyEvent.key === \"g\") {\n shortcutState.textCommand = \"\";\n return;\n }\n\n // Show navigator\n if (keyEvent.key === \"`\" && !hasModifierKey(keyEvent)) {\n onShowNavigator();\n return;\n }\n },\n listenerOptions,\n );\n}\n\nfunction getAltShortcutCommand(keyEvent: KeyboardEvent): string | null {\n if (!keyEvent.altKey || keyEvent.ctrlKey || keyEvent.metaKey || keyEvent.shiftKey) {\n return null;\n }\n\n if (keyEvent.code.startsWith(\"Key\") && keyEvent.code.length === 4) {\n return keyEvent.code.slice(3).toLowerCase();\n }\n\n if (keyEvent.code.startsWith(\"Digit\") && keyEvent.code.length === 6) {\n return keyEvent.code.slice(5);\n }\n\n if (keyEvent.code.startsWith(\"Numpad\") && keyEvent.code.length === 7) {\n return keyEvent.code.slice(6);\n }\n\n return null;\n}\n","import { Slide } from \"../../types/Slide\";\nimport { SlideAnimation } from \"../../types/SlideAnimation\";\n\n/**\n * Returns the speaker notes for a slide at a given build index, carrying forward notes from earlier\n * builds if necessary.\n */\nexport function getSpeakerNotes(slide: Slide, buildIndex: number): string | null {\n for (\n let currentBuildIndex = Math.min(buildIndex, slide.animations.length);\n currentBuildIndex >= 0;\n currentBuildIndex--\n ) {\n const notes = getSpeakerNotesForBuild(slide, currentBuildIndex);\n if (notes !== null) {\n return notes;\n }\n }\n\n return null;\n}\n\n/**\n * Returns only the notes attached directly to a build, without carrying notes forward from an\n * earlier build.\n */\nexport function getSpeakerNotesForBuild(slide: Slide, buildIndex: number): string | null {\n if (buildIndex === 0) {\n return slide.notes;\n }\n\n const animation = slide.animations[buildIndex - 1];\n return animation === undefined ? null : getAnimationNotes(animation);\n}\n\n/**\n * Returns all notes attached to the inclusive range of builds without carrying notes forward from\n * before the range.\n */\nexport function getSpeakerNotesForBuildRange(\n slide: Slide,\n startBuildIndex: number,\n endBuildIndex: number,\n): string | null {\n const notes: string[] = [];\n\n for (\n let buildIndex = Math.max(startBuildIndex, 0);\n buildIndex <= Math.min(endBuildIndex, slide.animations.length);\n buildIndex++\n ) {\n const buildNotes = getSpeakerNotesForBuild(slide, buildIndex);\n if (buildNotes !== null) {\n notes.push(buildNotes);\n }\n }\n\n return notes.length === 0 ? null : notes.join(\"\\n\\n\");\n}\n\nfunction getAnimationNotes(animation: SlideAnimation): string | null {\n if (!Array.isArray(animation)) {\n return animation.notes;\n }\n\n const notes = animation\n .map(({ notes }) => notes)\n .filter((notes): notes is string => notes !== null);\n return notes.length > 0 ? notes.join(\"\\n\\n\") : null;\n}\n","import { Presentation } from \"../types/Presentation\";\nimport { ShortcutState } from \"../types/ShortcutState\";\nimport { Slide } from \"../types/Slide\";\nimport { hasModifierKey } from \"../utils/dom/hasModifierKey\";\nimport { setupKeyEventListeners } from \"../utils/presentation/setupKeyEventListeners\";\nimport { getSpeakerNotes } from \"../utils/slide/getSpeakerNotes\";\nimport {\n loadNavigatorStateForHotReload,\n markNavigatorClosedForHotReload,\n markNavigatorOpenForHotReload,\n saveNavigatorStateForHotReload,\n} from \"./navigatorHotReload\";\n\nlet navigatorWindow: Window | null = null;\nlet navigatorApi: NavigatorApi | null = null;\n// Aborts listeners from the current navigator instance before replacing or closing it.\nlet navigatorCleanup: (() => void) | null = null;\n// Stored on the navigator window to tell fresh callbacks apart from stale HMR callbacks.\nconst NAVIGATOR_INSTANCE_ID_KEY = \"__presenterNavigatorInstanceId\";\n\nexport let navigatorWindowBounds = {\n width: 700,\n height: 680,\n left: 20,\n top: 50,\n};\n\ninterface Args {\n readonly presentation: Presentation;\n readonly shortcutState: ShortcutState;\n readonly onNavigateToSlide: (slideIndex: number) => void;\n readonly onRenderSlide: (slideIndex: number | null, buildIndex: number) => void;\n readonly onNext: (skipIntermediateBuilds?: boolean) => void;\n readonly onPrevious: (skipIntermediateBuilds?: boolean) => void;\n // Rebuilds an already-open navigator instead of focusing and reusing it.\n readonly forceRefresh?: boolean;\n}\n\nexport interface NavigatorApi {\n readonly currentCanvas: HTMLCanvasElement;\n readonly nextCanvas: HTMLCanvasElement;\n readonly currentLabel: HTMLDivElement;\n readonly nextLabel: HTMLDivElement;\n readonly isOpen: () => boolean;\n readonly update: (\n slideIndex: number,\n buildIndex: number,\n nextSlideIndex: number | null,\n nextBuildIndex: number,\n ) => void;\n}\n\ntype NavigatorElementApi = NavigatorApi & { readonly element: HTMLDivElement };\n\nexport function openNavigator({\n presentation,\n shortcutState,\n onNavigateToSlide,\n onRenderSlide,\n onNext,\n onPrevious,\n forceRefresh = false,\n}: Args): NavigatorApi | null {\n if (navigatorWindow !== null && !navigatorWindow.closed) {\n saveNavigatorWindowBounds(navigatorWindow);\n\n if (!forceRefresh) {\n navigatorWindow.focus();\n return navigatorApi;\n }\n }\n\n if (navigatorWindow === null || navigatorWindow.closed) {\n navigatorWindow = window.open(\"\", \"Navigator\", getNavigatorWindowFeatures());\n }\n\n if (navigatorWindow === null) {\n console.error(\"Failed to open navigator window.\");\n return null;\n }\n\n navigatorCleanup?.();\n\n const navigatorInstance = createNavigatorInstance(navigatorWindow);\n // Lets a refreshed navigator detach the previous instance's window listeners.\n const abortController = new AbortController();\n navigatorCleanup = () => abortController.abort();\n const elementApi = createNavigatorElement(\n presentation,\n onNavigateToSlide,\n onNext,\n navigatorInstance.isActive,\n );\n navigatorApi = elementApi;\n markNavigatorOpenForHotReload();\n\n navigatorWindow.document.title = presentation.title;\n navigatorWindow.document.body.replaceChildren(elementApi.element);\n\n setupKeyEventListeners(\n presentation,\n elementApi.element,\n shortcutState,\n {\n onNext: (skipIntermediateBuilds: boolean) => {\n if (navigatorInstance.isActive()) {\n onNext(skipIntermediateBuilds);\n }\n },\n onPrevious: (skipIntermediateBuilds: boolean) => {\n if (navigatorInstance.isActive()) {\n onPrevious(skipIntermediateBuilds);\n }\n },\n onRenderSlide: (slideIndex, buildIndex) => {\n if (navigatorInstance.isActive()) {\n onRenderSlide(slideIndex, buildIndex);\n }\n },\n onShowNavigator: () => {\n if (navigatorInstance.isActive()) {\n closeNavigatorWindow();\n }\n },\n },\n {\n keyEventTarget: navigatorWindow,\n signal: abortController.signal,\n },\n );\n\n navigatorWindow.addEventListener(\"resize\", () => saveNavigatorWindowBounds(navigatorWindow), {\n signal: abortController.signal,\n });\n navigatorWindow.addEventListener(\n \"beforeunload\",\n () => {\n saveNavigatorWindowBounds(navigatorWindow);\n markNavigatorClosedForHotReload();\n },\n {\n signal: abortController.signal,\n },\n );\n\n navigatorWindow.addEventListener(\n \"keyup\",\n (event) => {\n if (!navigatorInstance.isActive()) {\n return;\n }\n\n if (event.key === \"Escape\" || (event.key === \"`\" && !hasModifierKey(event))) {\n closeNavigatorWindow();\n }\n },\n {\n signal: abortController.signal,\n },\n );\n\n return navigatorApi;\n}\n\nexport function createNavigatorElement(\n presentation: Presentation,\n onNavigateToSlide: (slideIndex: number) => void,\n onNext: () => void,\n isActive: () => boolean = () => true,\n): NavigatorElementApi {\n const doc = navigatorWindow?.document ?? document;\n\n // Set up container\n const navigatorElement = doc.createElement(\"div\");\n navigatorElement.style.boxSizing = \"border-box\";\n navigatorElement.style.display = \"grid\";\n navigatorElement.style.gridTemplateColumns = \"260px 1fr\";\n navigatorElement.style.gap = \"18px\";\n navigatorElement.style.height = \"100vh\";\n navigatorElement.style.overflow = \"hidden\";\n navigatorElement.style.padding = \"18px\";\n navigatorElement.style.fontFamily = '-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif';\n navigatorElement.style.backgroundColor = \"#f5f6f8\";\n navigatorElement.style.color = \"#1f2937\";\n\n doc.body.style.margin = \"0\";\n doc.body.style.overflow = \"hidden\";\n\n // List of all slides on the left\n const slideList = doc.createElement(\"div\");\n slideList.style.display = \"flex\";\n slideList.style.flexDirection = \"column\";\n slideList.style.gap = \"8px\";\n slideList.style.minHeight = \"0\";\n slideList.style.overflowY = \"auto\";\n slideList.style.paddingRight = \"4px\";\n\n // Preview of current and next slide\n const previewColumn = doc.createElement(\"div\");\n previewColumn.style.display = \"flex\";\n previewColumn.style.flexDirection = \"column\";\n previewColumn.style.gap = \"14px\";\n previewColumn.style.minHeight = \"0\";\n previewColumn.style.minWidth = \"0\";\n previewColumn.style.overflow = \"hidden\";\n\n // Options to show what's visible in navigator\n const controls = doc.createElement(\"div\");\n controls.style.display = \"flex\";\n controls.style.gap = \"14px\";\n controls.style.alignItems = \"center\";\n controls.style.flexWrap = \"wrap\";\n controls.style.fontSize = \"13px\";\n controls.style.color = \"#4b5563\";\n\n const previewGrid = doc.createElement(\"div\");\n previewGrid.style.display = \"flex\";\n previewGrid.style.gap = \"14px\";\n previewGrid.style.flex = \"1 1 auto\";\n previewGrid.style.minHeight = \"0\";\n previewGrid.style.minWidth = \"0\";\n previewGrid.style.overflow = \"hidden\";\n\n const currentPreview = createPreviewElement(\"Current\", presentation);\n const nextPreview = createPreviewElement(\"Next\", presentation);\n const notesPanel = createNotesElement();\n const navigatorState = loadNavigatorStateForHotReload();\n nextPreview.container.style.cursor = \"pointer\";\n nextPreview.container.addEventListener(\"click\", () => {\n if (isActive()) {\n onNext();\n }\n });\n\n const slideElements = presentation.slides.map((slide, index) => {\n const slideElement = createSlideElement(slide, index);\n slideElement.style.cursor = \"pointer\";\n slideElement.addEventListener(\"click\", (event) => {\n if (!isActive()) {\n return;\n }\n\n // If shift key is pressed, close window\n if (event.shiftKey) {\n closeNavigatorWindow();\n }\n onNavigateToSlide(index);\n });\n slideList.appendChild(slideElement);\n return slideElement;\n });\n\n const slidesToggle = createToggleElement(\"Slides\", slideList, navigatorState.visibility.slides);\n const currentToggle = createToggleElement(\n \"Current\",\n currentPreview.container,\n navigatorState.visibility.current,\n );\n const nextToggle = createToggleElement(\n \"Next\",\n nextPreview.container,\n navigatorState.visibility.next,\n );\n const notesToggle = createToggleElement(\n \"Notes\",\n notesPanel.container,\n navigatorState.visibility.notes,\n );\n\n const updateLayout = () => {\n const shouldStackPreviews =\n currentToggle.input.checked && nextToggle.input.checked && isNarrowPreviewLayout();\n navigatorElement.style.gridTemplateColumns = slidesToggle.input.checked ? \"260px 1fr\" : \"1fr\";\n previewGrid.style.flexDirection = shouldStackPreviews ? \"column\" : \"row\";\n currentPreview.container.style.flex = \"1 1 0\";\n nextPreview.container.style.flex = \"1 1 0\";\n requestAnimationFrame(() => {\n currentPreview.resize();\n nextPreview.resize();\n });\n saveNavigatorStateForHotReload({\n ...navigatorState,\n open: true,\n visibility: {\n slides: slidesToggle.input.checked,\n current: currentToggle.input.checked,\n next: nextToggle.input.checked,\n notes: notesToggle.input.checked,\n },\n });\n };\n slidesToggle.input.addEventListener(\"change\", updateLayout);\n currentToggle.input.addEventListener(\"change\", updateLayout);\n nextToggle.input.addEventListener(\"change\", updateLayout);\n notesToggle.input.addEventListener(\"change\", updateLayout);\n navigatorWindow?.addEventListener(\"resize\", updateLayout);\n\n controls.appendChild(slidesToggle.element);\n controls.appendChild(currentToggle.element);\n controls.appendChild(nextToggle.element);\n controls.appendChild(notesToggle.element);\n\n previewGrid.appendChild(currentPreview.container);\n previewGrid.appendChild(nextPreview.container);\n previewColumn.appendChild(controls);\n previewColumn.appendChild(previewGrid);\n previewColumn.appendChild(notesPanel.container);\n navigatorElement.appendChild(slideList);\n navigatorElement.appendChild(previewColumn);\n\n function update(\n slideIndex: number,\n buildIndex: number,\n nextSlideIndex: number | null,\n nextBuildIndex: number,\n ) {\n if (!isActive()) {\n return;\n }\n\n slideElements.forEach((element, index) => {\n const isActive = index === slideIndex;\n element.style.backgroundColor = isActive ? \"#dbeafe\" : \"#ffffff\";\n element.style.borderColor = isActive ? \"#60a5fa\" : \"#e5e7eb\";\n element.style.color = isActive ? \"#1e3a8a\" : \"#1f2937\";\n });\n\n currentPreview.label.textContent = getBuildLabel(presentation, slideIndex, buildIndex);\n nextPreview.label.textContent = getBuildLabel(presentation, nextSlideIndex, nextBuildIndex);\n notesPanel.content.textContent =\n getSpeakerNotes(presentation.slides[slideIndex] ?? Slide(), buildIndex) ?? \"\";\n scrollSlideIntoView(slideElements[slideIndex], slideList);\n updateLayout();\n }\n\n function isNarrowPreviewLayout() {\n const win = navigatorWindow;\n if (win === null) {\n return false;\n }\n\n const slideListWidth = slidesToggle.input.checked ? 260 + 18 : 0;\n const availableWidth = win.innerWidth - 36 - slideListWidth;\n const availableHeight = win.innerHeight - 36 - controls.offsetHeight - 14;\n if (availableWidth <= 0 || availableHeight <= 0) {\n return false;\n }\n\n return availableWidth / availableHeight < 1.1;\n }\n\n return {\n element: navigatorElement,\n currentCanvas: currentPreview.canvas,\n nextCanvas: nextPreview.canvas,\n currentLabel: currentPreview.label,\n nextLabel: nextPreview.label,\n isOpen: () => navigatorWindow !== null && !navigatorWindow.closed,\n update,\n };\n}\n\nfunction createNotesElement(): {\n readonly container: HTMLDivElement;\n readonly content: HTMLDivElement;\n} {\n const doc = navigatorWindow?.document ?? document;\n const container = doc.createElement(\"div\");\n container.style.display = \"flex\";\n container.style.flex = \"0 1 180px\";\n container.style.flexDirection = \"column\";\n container.style.minHeight = \"100px\";\n container.style.maxHeight = \"30vh\";\n container.style.overflow = \"hidden\";\n container.style.backgroundColor = \"#ffffff\";\n container.style.border = \"1px solid #e5e7eb\";\n container.style.borderRadius = \"6px\";\n container.style.boxShadow = \"0 1px 2px rgba(15, 23, 42, 0.06)\";\n\n const title = doc.createElement(\"div\");\n title.textContent = \"Notes\";\n title.style.padding = \"10px 12px 6px\";\n title.style.fontSize = \"12px\";\n title.style.fontWeight = \"700\";\n title.style.textTransform = \"uppercase\";\n title.style.color = \"#6b7280\";\n\n const content = doc.createElement(\"div\");\n content.style.flex = \"1 1 auto\";\n content.style.minHeight = \"0\";\n content.style.overflowY = \"auto\";\n content.style.padding = \"4px 12px 12px\";\n content.style.fontSize = \"16px\";\n content.style.lineHeight = \"1.5\";\n content.style.whiteSpace = \"pre-wrap\";\n\n container.appendChild(title);\n container.appendChild(content);\n\n return { container, content };\n}\n\nfunction createSlideElement(slide: Slide, slideIndex: number): HTMLDivElement {\n const doc = navigatorWindow?.document ?? document;\n const slideElement = doc.createElement(\"div\");\n slideElement.style.display = \"flex\";\n slideElement.style.alignItems = \"center\";\n slideElement.style.gap = \"10px\";\n slideElement.style.padding = \"8px 10px\";\n slideElement.style.backgroundColor = \"#ffffff\";\n slideElement.style.border = \"1px solid #e5e7eb\";\n slideElement.style.borderRadius = \"6px\";\n slideElement.style.boxShadow = \"0 1px 2px rgba(15, 23, 42, 0.06)\";\n slideElement.style.fontSize = \"14px\";\n slideElement.style.lineHeight = \"1\";\n slideElement.style.userSelect = \"none\";\n\n const countElement = doc.createElement(\"div\");\n countElement.textContent = `${slideIndex + 1}`;\n countElement.style.minWidth = \"24px\";\n countElement.style.fontWeight = \"700\";\n countElement.style.color = \"#6b7280\";\n\n const titleElement = doc.createElement(\"div\");\n titleElement.textContent = slide.title.length > 0 ? slide.title : `Slide ${slideIndex + 1}`;\n titleElement.style.overflow = \"hidden\";\n titleElement.style.textOverflow = \"ellipsis\";\n titleElement.style.whiteSpace = \"nowrap\";\n\n slideElement.appendChild(countElement);\n slideElement.appendChild(titleElement);\n\n return slideElement;\n}\n\nfunction createPreviewElement(title: string, presentation: Presentation) {\n const doc = navigatorWindow?.document ?? document;\n const container = doc.createElement(\"div\");\n container.style.display = \"flex\";\n container.style.alignItems = \"center\";\n container.style.flexDirection = \"column\";\n container.style.minHeight = \"0\";\n container.style.minWidth = \"0\";\n\n const titleElement = doc.createElement(\"div\");\n titleElement.textContent = title;\n titleElement.style.marginBottom = \"4px\";\n titleElement.style.fontSize = \"12px\";\n titleElement.style.fontWeight = \"700\";\n titleElement.style.textAlign = \"center\";\n titleElement.style.textTransform = \"uppercase\";\n titleElement.style.color = \"#6b7280\";\n\n const label = doc.createElement(\"div\");\n label.style.marginBottom = \"6px\";\n label.style.fontSize = \"14px\";\n label.style.fontWeight = \"600\";\n label.style.textAlign = \"center\";\n\n const frame = doc.createElement(\"div\");\n frame.style.flex = \"1 1 auto\";\n frame.style.display = \"flex\";\n frame.style.alignItems = \"flex-start\";\n frame.style.justifyContent = \"center\";\n frame.style.minHeight = \"0\";\n frame.style.width = \"100%\";\n frame.style.overflow = \"hidden\";\n\n const canvas = doc.createElement(\"canvas\");\n canvas.style.display = \"block\";\n canvas.style.width = \"0\";\n canvas.style.height = \"0\";\n\n function resize() {\n const frameWidth = frame.clientWidth;\n const frameHeight = frame.clientHeight;\n if (frameWidth <= 0 || frameHeight <= 0) {\n return;\n }\n\n const aspectRatio = presentation.size.width / presentation.size.height;\n const width = Math.min(frameWidth, frameHeight * aspectRatio);\n const height = width / aspectRatio;\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n }\n\n const ResizeObserverCtor = doc.defaultView?.ResizeObserver;\n if (ResizeObserverCtor !== undefined) {\n new ResizeObserverCtor(resize).observe(frame);\n }\n navigatorWindow?.addEventListener(\"resize\", resize);\n\n frame.appendChild(canvas);\n container.appendChild(titleElement);\n container.appendChild(label);\n container.appendChild(frame);\n\n return { container, label, canvas, resize };\n}\n\nfunction createToggleElement(\n label: string,\n target: HTMLElement,\n checked: boolean,\n): { readonly element: HTMLLabelElement; readonly input: HTMLInputElement } {\n const doc = navigatorWindow?.document ?? document;\n const visibleDisplay = target.style.display || \"block\";\n const toggle = doc.createElement(\"label\");\n toggle.style.display = \"inline-flex\";\n toggle.style.alignItems = \"center\";\n toggle.style.gap = \"6px\";\n toggle.style.userSelect = \"none\";\n\n const checkbox = doc.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.checked = checked;\n target.style.display = checked ? visibleDisplay : \"none\";\n checkbox.addEventListener(\"change\", () => {\n target.style.display = checkbox.checked ? visibleDisplay : \"none\";\n });\n\n toggle.appendChild(checkbox);\n toggle.appendChild(doc.createTextNode(label));\n\n return { element: toggle, input: checkbox };\n}\n\nfunction getBuildLabel(\n presentation: Presentation,\n slideIndex: number | null,\n buildIndex: number,\n): string {\n if (slideIndex === null) {\n return \"End of presentation\";\n }\n\n const slide = presentation.slides[slideIndex];\n if (slide === undefined) {\n return \"No slide\";\n }\n\n return `Slide ${slideIndex + 1} of ${presentation.slides.length}, Build ${buildIndex + 1} of ${\n slide.animations.length + 1\n }`;\n}\n\nfunction scrollSlideIntoView(slideElement: HTMLDivElement | undefined, slideList: HTMLDivElement) {\n if (slideElement === undefined) {\n return;\n }\n\n const slideTop = slideElement.offsetTop;\n const slideBottom = slideTop + slideElement.offsetHeight;\n const listTop = slideList.scrollTop;\n const listBottom = listTop + slideList.clientHeight;\n\n if (slideTop < listTop || slideBottom > listBottom) {\n slideElement.scrollIntoView({ block: \"nearest\" });\n }\n}\n\nfunction closeNavigatorWindow(): void {\n saveNavigatorWindowBounds(navigatorWindow);\n markNavigatorClosedForHotReload();\n navigatorCleanup?.();\n navigatorWindow?.close();\n navigatorWindow = null;\n navigatorApi = null;\n navigatorCleanup = null;\n}\n\nfunction getNavigatorWindowFeatures(): string {\n const { width, height, left, top } = navigatorWindowBounds;\n return `width=${width},height=${height},left=${left},top=${top}`;\n}\n\nfunction saveNavigatorWindowBounds(win: Window | null): void {\n if (win === null || win.closed) {\n return;\n }\n\n navigatorWindowBounds = {\n width: win.outerWidth,\n height: win.outerHeight,\n left: win.screenX,\n top: win.screenY,\n };\n}\n\n// Creates a token that keeps callbacks from older navigator instances inert after a refresh.\nfunction createNavigatorInstance(win: Window): { readonly isActive: () => boolean } {\n const instanceId =\n typeof globalThis.crypto?.randomUUID === \"function\"\n ? globalThis.crypto.randomUUID()\n : `${Date.now()}-${Math.random()}`;\n const instanceWindow = win as Window & { [NAVIGATOR_INSTANCE_ID_KEY]?: string };\n instanceWindow[NAVIGATOR_INSTANCE_ID_KEY] = instanceId;\n\n return {\n isActive: () => !win.closed && instanceWindow[NAVIGATOR_INSTANCE_ID_KEY] === instanceId,\n };\n}\n","export interface Color {\n /** Red channel, in [0, 255] */\n red: number;\n\n /** Green channel, in [0, 255] */\n green: number;\n\n /** Blue channel, in [0, 255] */\n blue: number;\n\n /** Alpha channel, in [0, 1] */\n alpha: number;\n}\n\nexport function Color(color: Partial<Color> | string): Color;\nexport function Color(red: number, green: number, blue: number, alpha?: number): Color;\nexport function Color(\n color: Partial<Color> | string | number,\n green: number = 0,\n blue: number = 0,\n alpha: number = 1,\n): Color {\n if (typeof color === \"string\") {\n const hexString = color.replace(\"#\", \"\");\n const hex = parseInt(hexString, 16);\n\n if (isNaN(hex)) {\n console.warn(\"Invalid hex color format:\", color);\n return DEFAULT_COLOR;\n }\n\n if (hexString.length === 6) {\n return {\n red: (hex >> 16) & 255,\n green: (hex >> 8) & 255,\n blue: hex & 255,\n alpha: 1,\n };\n } else if (hexString.length === 8) {\n return {\n red: (hex >> 24) & 255,\n green: (hex >> 16) & 255,\n blue: (hex >> 8) & 255,\n alpha: (hex & 255) / 255,\n };\n } else {\n console.warn(\"Invalid hex color format:\", color);\n return DEFAULT_COLOR;\n }\n } else if (typeof color === \"number\") {\n return {\n red: color,\n green: green ?? 0,\n blue: blue ?? 0,\n alpha: alpha ?? 1,\n };\n }\n\n return {\n red: 0,\n green: 0,\n blue: 0,\n alpha: 1,\n ...color,\n };\n}\n\nColor.BLACK = Color(0, 0, 0);\nColor.BLUE = Color(0, 0, 255);\nColor.GREEN = Color(0, 255, 0);\nColor.RED = Color(255, 0, 0);\nColor.TRANSPARENT = Color(0, 0, 0, 0);\nColor.WHITE = Color(255, 255, 255);\n\nexport const DEFAULT_COLOR: Color = { red: 0, green: 0, blue: 0, alpha: 1 };\n","export interface Size {\n readonly height: number;\n readonly width: number;\n}\n\nexport function Size(props: Partial<Size> | null = null): Size {\n return {\n height: 0,\n width: 0,\n ...props,\n };\n}\n\nexport const DEFAULT_SIZE: Size = Size({ width: 0, height: 0 });\n","import { Color } from \"./Color\";\nimport { Resources } from \"./Resources\";\nimport { Size } from \"./Size\";\nimport { Slide } from \"./Slide\";\n\nexport interface Presentation {\n /** The background color of the presentation. */\n readonly backgroundColor: Color;\n\n /** The slides to present as part of the presentation. */\n readonly slides: Slide[];\n\n /** The title of the presentation. */\n readonly title: string;\n\n /** The resources used in the presentation. */\n readonly resources: Resources;\n\n /** The dimensions of the presentation's viewport. */\n readonly size: Size;\n}\n\nexport function Presentation(props: Partial<Presentation> | null = null): Presentation {\n return {\n backgroundColor: Color.WHITE,\n slides: [],\n title: \"Presentation\",\n size: Size({ width: 3840, height: 2160 }),\n resources: {\n images: {},\n },\n ...props,\n };\n}\n","export const AnimationType = {\n /** Represents an animated change in an object's properties. */\n ANIMATE: \"Animate\",\n\n /** Represents a pause in the animation timeline. */\n PAUSE: \"Pause\",\n\n /** Represents an immediate update to an object's properties without animation. */\n UPDATE: \"Update\",\n} as const;\n\nexport type AnimationType = (typeof AnimationType)[keyof typeof AnimationType];\n","export function assertNever(value: never, message?: string): never {\n throw new Error((message ?? \"Unexpected value\") + \": \" + value);\n}\n","import { AnimationType } from \"../../types/AnimationType\";\nimport { SlideAnimation } from \"../../types/SlideAnimation\";\nimport { assertNever } from \"../core/assertNever\";\n\nexport function getSlideAnimationDuration(slideAnimation: SlideAnimation): number {\n const animations = Array.isArray(slideAnimation) ? slideAnimation : [slideAnimation];\n let startTime = 0;\n let duration = 0;\n\n for (const animation of animations) {\n switch (animation.type) {\n case AnimationType.PAUSE:\n startTime += animation.duration;\n break;\n case AnimationType.ANIMATE:\n duration = Math.max(duration, startTime + animation.delay + animation.duration);\n if (animation.block) {\n startTime += animation.delay + animation.duration;\n }\n break;\n case AnimationType.UPDATE:\n // No-op, instantaneous update.\n break;\n default:\n assertNever(animation);\n }\n }\n\n return duration;\n}\n","import { Color } from \"../../types/Color\";\n\n/**\n * Returns the alpha value for a color in [0, 1], given the color and the overall opacity of a shape.\n * Combines the color's alpha and the overall opacity.\n */\nexport function getAlphaForColor(color: Color, opacity: number | null = null): number {\n return color.alpha * (opacity ?? 1);\n}\n","import { Color } from \"../../types/Color\";\nimport { getAlphaForColor } from \"./getAlphaForColor\";\n\nexport function getRgbStringForColor(color: Color, opacity: number | null = null): string {\n const { red, green, blue } = color;\n const alpha = getAlphaForColor(color, opacity);\n return `rgba(${red}, ${green}, ${blue}, ${alpha})`;\n}\n","export function isFullBodyPresentation(element: HTMLElement): boolean {\n return element === document.body;\n}\n","import { Presentation } from \"../../types/Presentation\";\nimport { isFullBodyPresentation } from \"./isFullBodyPresentation\";\n\nexport function createPresentationContainer(\n presentation: Presentation,\n root: HTMLElement,\n): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.style.width = \"100%\";\n container.style.aspectRatio = `${presentation.size.width} / ${presentation.size.height}`;\n container.style.position = \"relative\";\n\n if (isFullBodyPresentation(root)) {\n // Set container to be vertically centered.\n container.style.top = \"50%\";\n container.style.transform = \"translateY(-50%)\";\n\n // Set container to be horizontally centered.\n container.style.marginLeft = \"auto\";\n container.style.marginRight = \"auto\";\n\n // Don't allow scrolling of container\n container.style.overflowY = \"clip\";\n\n // Set document title to title of presentation.\n document.title = presentation.title;\n\n // Set root element styles.\n document.documentElement.style.height = \"100%\";\n\n // Set body styles.\n document.body.style.margin = \"0\";\n document.body.style.height = \"100%\";\n document.body.style.width = \"100%\";\n document.body.style.backgroundColor = \"#000000\";\n\n // Ensure style properties change to maintain aspect ratio fit.\n const targetAspectRatio = presentation.size.height / presentation.size.width;\n updateContainerSize(container, targetAspectRatio);\n\n window\n .matchMedia(`(min-aspect-ratio: ${presentation.size.width} / ${presentation.size.height})`)\n .addEventListener(\"change\", () => updateContainerSize(container, targetAspectRatio));\n }\n\n return container;\n}\n\nfunction updateContainerSize(container: HTMLElement, targetAspectRatio: number) {\n if (window.innerHeight / window.innerWidth > targetAspectRatio) {\n container.style.width = \"100%\";\n container.style.height = \"auto\";\n } else {\n container.style.width = \"auto\";\n container.style.height = \"100%\";\n }\n}\n","import { SlideObject } from \"../../types/SlideObject\";\n\n/**\n * Returns the children of a SlideObject if they exist.\n */\nexport function getObjectChildren(object: SlideObject): SlideObject[] {\n const children: SlideObject[] = [];\n const childContainers = object as SlideObject &\n Partial<Record<\"objects\" | \"meshes\" | \"nodes\" | \"materials\", unknown>>;\n\n for (const key of [\"objects\", \"meshes\", \"nodes\", \"materials\"] as const) {\n const value = childContainers[key];\n if (Array.isArray(value)) {\n children.push(...getSlideObjects(value));\n }\n }\n return children;\n}\n\nfunction getSlideObjects(objects: unknown[]): SlideObject[] {\n return objects.filter(\n (object): object is SlideObject =>\n typeof object === \"object\" && object !== null && \"objectType\" in object,\n );\n}\n","import { Presentation } from \"../../types/Presentation\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { getObjectChildren } from \"./getObjectChildren\";\n\ninterface ImagePathObject {\n readonly imagePath?: string | null;\n readonly fallbackImagePath?: string | null;\n}\n\nexport function getImagePathUrlById(presentation: Presentation): Record<string, string> {\n const imageUrls: Record<string, string> = {};\n\n function addImagePath(imagePath: string | null | undefined): void {\n if (imagePath !== undefined && imagePath !== null && imagePath.length > 0) {\n imageUrls[imagePath] = imagePath;\n }\n }\n\n function walkSlideObject(object: SlideObject): void {\n const imageObject = object as SlideObject & ImagePathObject;\n addImagePath(imageObject.imagePath);\n addImagePath(imageObject.fallbackImagePath);\n\n for (const child of getObjectChildren(object)) {\n walkSlideObject(child);\n }\n }\n\n for (const slide of presentation.slides) {\n for (const object of slide.objects) {\n walkSlideObject(object);\n }\n }\n\n return imageUrls;\n}\n","import { Color } from \"../../types/Color\";\nimport { Interpolator } from \"../../types/Interpolator\";\n\nexport const interpolateColor: Interpolator<Color> = {\n check: (value: unknown): value is Color => {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as Color).red === \"number\" &&\n typeof (value as Color).green === \"number\" &&\n typeof (value as Color).blue === \"number\" &&\n typeof (value as Color).alpha === \"number\"\n );\n },\n interpolate: (from: Color, to: Color, proportion: number): Color => {\n return {\n red: Math.round(from.red + (to.red - from.red) * proportion),\n green: Math.round(from.green + (to.green - from.green) * proportion),\n blue: Math.round(from.blue + (to.blue - from.blue) * proportion),\n alpha: from.alpha + (to.alpha - from.alpha) * proportion,\n };\n },\n};\n","import { Interpolator } from \"../../types/Interpolator\";\n\n/** Fallback interpolation function when no other interpolators apply. */\nexport const interpolateFallback: Interpolator<unknown> = {\n check: (_value: unknown): _value is unknown => {\n return true;\n },\n interpolate: (_from: unknown, to: unknown): unknown => {\n return to;\n },\n};\n","import { Interpolator } from \"../../types/Interpolator\";\n\nexport const interpolateNumber: Interpolator<number> = {\n check: (value: unknown): value is number => {\n return typeof value === \"number\";\n },\n interpolate: (from: number, to: number, proportion: number): number => {\n return from + (to - from) * proportion;\n },\n};\n","import { Interpolator } from \"../../types/Interpolator\";\nimport { interpolateColor } from \"./interpolateColor\";\nimport { interpolateFallback } from \"./interpolateFallback\";\nimport { interpolateNumber } from \"./interpolateNumber\";\n\nexport const DEFAULT_INTERPOLATORS: Interpolator<any>[] = [\n interpolateNumber,\n interpolateColor,\n interpolateFallback,\n];\n","import { Interpolator } from \"../../types/Interpolator\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { DEFAULT_INTERPOLATORS } from \"./defaultInterpolators\";\n\nexport function interpolate<T extends SlideObject>(\n object: T,\n props: Partial<T>,\n proportion: number,\n customInterpolators: Interpolator<any>[] | null = null,\n): T {\n if (proportion === 0) {\n return object;\n } else if (proportion === 1) {\n return { ...object, ...props };\n }\n\n const interpolators =\n customInterpolators != null\n ? [...customInterpolators, ...DEFAULT_INTERPOLATORS]\n : DEFAULT_INTERPOLATORS;\n\n const interpolatedProps: Partial<T> = {};\n for (const key in props) {\n const fromValue = object[key];\n const toValue = props[key];\n\n for (const interpolator of interpolators) {\n if (interpolator.check(fromValue, key) && interpolator.check(toValue, key)) {\n interpolatedProps[key] = (interpolator as Interpolator<typeof toValue>).interpolate(\n fromValue,\n toValue,\n proportion,\n );\n break;\n }\n }\n }\n\n return { ...object, ...interpolatedProps };\n}\n","import { AnimationType } from \"../../types/AnimationType\";\nimport { SlideAnimation } from \"../../types/SlideAnimation\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { assertNever } from \"../core/assertNever\";\nimport { interpolate } from \"../interpolate/interpolate\";\n\n/**\n * Mutably updates the object state to reflect the end state of the animation.\n *\n * If a build time is provided, the object state is updated to the state at that\n * time into the animation.\n *\n * @param objectState Map from original objects to current object state.\n * @param slideAnimation The animation to apply.\n * @param buildTime Optional time (in ms) into the animation to apply.\n */\nexport function updateObjectStateWithAnimation(\n objectState: Map<SlideObject, SlideObject>,\n slideAnimation: SlideAnimation | null,\n buildTime: number | null = null,\n) {\n if (slideAnimation === null) {\n return;\n }\n\n const animations = Array.isArray(slideAnimation) ? slideAnimation : [slideAnimation];\n\n let elapsedTime = 0;\n for (const animation of animations) {\n if (buildTime !== null && elapsedTime > buildTime) {\n // We've reached the current build time, so no more state to update.\n break;\n }\n\n switch (animation.type) {\n case AnimationType.ANIMATE: {\n const currentObject = objectState.get(animation.object);\n if (currentObject === undefined) {\n break;\n }\n\n const timeIntoAnimation = buildTime !== null ? buildTime - elapsedTime : null;\n const proportion = Math.max(\n Math.min(\n timeIntoAnimation !== null\n ? (timeIntoAnimation - animation.delay) / animation.duration\n : 1,\n 1,\n ),\n 0,\n );\n\n objectState.set(animation.object, {\n ...currentObject,\n ...interpolate(\n currentObject,\n animation.props,\n animation.easing(proportion),\n animation.interpolators,\n ),\n });\n\n if (animation.block) {\n elapsedTime += animation.delay + animation.duration;\n }\n break;\n }\n case AnimationType.UPDATE: {\n const currentObject = objectState.get(animation.object);\n if (currentObject === undefined) {\n break;\n }\n\n objectState.set(animation.object, {\n ...currentObject,\n ...animation.props,\n });\n break;\n }\n case AnimationType.PAUSE:\n elapsedTime += animation.duration;\n break;\n default:\n assertNever(animation);\n }\n }\n}\n","import { Slide } from \"../../types/Slide\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { updateObjectStateWithAnimation } from \"../animate/updateObjectStateWithAnimation\";\nimport { getObjectChildren } from \"./getObjectChildren\";\n\ninterface Args {\n readonly slide: Slide;\n readonly buildIndex: number;\n readonly buildTime: number | null;\n}\n\n/**\n * Returns a mapping from original object (by reference equality) to its current state.\n */\nexport function getObjectState({\n slide,\n buildIndex,\n buildTime,\n}: Args): Map<SlideObject, SlideObject> {\n const objectState: Map<SlideObject, SlideObject> = new Map();\n\n function addObjectToState(object: SlideObject) {\n objectState.set(object, object);\n for (const childObject of getObjectChildren(object)) {\n addObjectToState(childObject);\n }\n }\n\n for (const object of slide.objects) {\n addObjectToState(object);\n }\n\n // Process animations that have already completed.\n const completedBuildCount = buildTime === null ? buildIndex : buildIndex - 1;\n for (let i = 0; i < completedBuildCount; i++) {\n const animation = slide.animations[i] ?? null;\n updateObjectStateWithAnimation(objectState, animation);\n }\n\n // Process the current animation, if any.\n if (buildTime !== null && buildIndex > 0) {\n const animation = slide.animations[buildIndex - 1] ?? null;\n updateObjectStateWithAnimation(objectState, animation, buildTime);\n }\n\n return objectState;\n}\n","export const ObjectType = {\n ARROW: \"Arrow\",\n CIRCLE: \"Circle\",\n GROUP: \"Group\",\n IMAGE: \"Image\",\n LINE: \"Line\",\n MASK: \"Mask\",\n PATH: \"Path\",\n POLYGON: \"Polygon\",\n RECTANGLE: \"Rectangle\",\n SLIDE_OBJECT: \"SlideObject\",\n SPOTLIGHT: \"Spotlight\",\n SVG: \"SVG\",\n TEXT: \"Text\",\n} as const;\n\nexport type ObjectType = (typeof ObjectType)[keyof typeof ObjectType];\n","import { ObjectType } from \"../../types/ObjectType\";\nimport { Presentation } from \"../../types/Presentation\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { getObjectChildren } from \"./getObjectChildren\";\n\n/**\n * Extracts all SVG objects from slides and returns a mapping from image ID to URL.\n * In the case of SVGs, the image URL and path are both the SVG string itself.\n * SVG strings are transformed into data URLs in the image loading process.\n */\nexport function getSvgImageUrlById(presentation: Presentation): Record<string, string> {\n const svgStrings: Record<string, string> = {};\n\n function walkSlideObject(object: SlideObject): void {\n if (object.objectType === ObjectType.SVG) {\n const svg = (object as SlideObject & { svg: string }).svg;\n if (svg !== undefined && svg.length > 0) {\n svgStrings[svg] = svg;\n }\n }\n\n const children = getObjectChildren(object);\n for (const child of children) {\n walkSlideObject(child);\n }\n }\n\n for (const slide of presentation.slides) {\n for (const object of slide.objects) {\n walkSlideObject(object);\n }\n }\n\n return svgStrings;\n}\n","export const LOCAL_STORAGE_KEY = \"presenterState\";\n","import { Presentation } from \"../../types/Presentation\";\nimport { LOCAL_STORAGE_KEY } from \"./storageConsts\";\nimport { StorageState } from \"./StorageState\";\n\nexport function loadPresentationState(\n presentation: Presentation,\n ttlMinutes: number | null,\n): StorageState | null {\n const state = localStorage.getItem(LOCAL_STORAGE_KEY);\n if (state === null) {\n return null;\n }\n\n // If no TTL is provided, don't use any cached data.\n if (ttlMinutes === null) {\n localStorage.removeItem(LOCAL_STORAGE_KEY);\n return null;\n }\n\n // Check if the value is valid JSON.\n let data: unknown;\n try {\n data = JSON.parse(state);\n } catch (error) {\n console.error(\"Failed to parse presentation state from localStorage:\", error);\n localStorage.removeItem(LOCAL_STORAGE_KEY);\n return null;\n }\n\n const { title, timestamp } = data as any;\n let { slideIndex, buildIndex } = data as any;\n\n if (\n typeof title !== \"string\" ||\n typeof slideIndex !== \"number\" ||\n typeof buildIndex !== \"number\" ||\n typeof timestamp !== \"number\"\n ) {\n localStorage.removeItem(LOCAL_STORAGE_KEY);\n return null;\n }\n\n // If title doesn't match, ignore the cache.\n if (title !== presentation.title) {\n localStorage.removeItem(LOCAL_STORAGE_KEY);\n return null;\n }\n\n // Check if the value is older than the cache limit.\n if (Date.now() - timestamp > 1000 * 60 * ttlMinutes) {\n localStorage.removeItem(LOCAL_STORAGE_KEY);\n return null;\n }\n\n // Validate slide index\n if (slideIndex > presentation.slides.length - 1) {\n slideIndex = presentation.slides.length - 1;\n buildIndex = 0;\n }\n\n const slide = presentation.slides[slideIndex];\n if (slide === undefined) {\n localStorage.removeItem(LOCAL_STORAGE_KEY);\n return null;\n }\n\n // Validate build index\n if (buildIndex > slide.animations.length) {\n buildIndex = slide.animations.length;\n }\n\n return {\n title,\n slideIndex,\n buildIndex,\n };\n}\n","import { LOCAL_STORAGE_KEY } from \"./storageConsts\";\nimport { StorageState } from \"./StorageState\";\n\nexport function storePresentationState({ title, slideIndex, buildIndex }: StorageState) {\n localStorage.setItem(\n LOCAL_STORAGE_KEY,\n JSON.stringify({ title, slideIndex, buildIndex, timestamp: Date.now() }),\n );\n}\n","import { ShortcutState } from \"../../../types/ShortcutState\";\nimport { UnifiedImage } from \"./UnifiedImage\";\n\nexport interface BrowserCanvasRendererState {\n accessibleDescriptionElement: HTMLDivElement | null;\n canvas: HTMLCanvasElement | null;\n extrasContainer: SVGSVGElement | null;\n mountedExtrasCleanups: (() => void)[];\n\n /** The index of the currently displayed slide. */\n slideIndex: number;\n\n /** The index of the current build within the current slide.\n * If there are N animations on the slide, this will range from 0 to N inclusive.\n */\n buildIndex: number;\n\n /** The ID of the currently running animation, if any. */\n currentAnimationId: number | null;\n\n imageById: Record<string, UnifiedImage>;\n\n shortcutState: ShortcutState;\n}\n\nexport const BROWSER_CANVAS_RENDERER_DEFAULT_STATE: BrowserCanvasRendererState = Object.freeze({\n accessibleDescriptionElement: null,\n canvas: null,\n extrasContainer: null,\n mountedExtrasCleanups: [],\n slideIndex: 0,\n buildIndex: 0,\n currentAnimationId: null,\n imageById: {},\n shortcutState: {\n textCommand: null,\n shortcuts: {},\n },\n});\n","import { type CanvasRenderingContext2D as SkiaCanvasRenderingContext2D } from \"skia-canvas\";\n\nexport const CanvasContextType = {\n Browser: \"browser\",\n Node: \"node\",\n} as const;\n\nexport type CanvasContextType = (typeof CanvasContextType)[keyof typeof CanvasContextType];\n\nexport interface BrowserCanvasContext {\n readonly type: typeof CanvasContextType.Browser;\n readonly context: CanvasRenderingContext2D;\n}\n\nexport interface NodeCanvasContext {\n readonly type: typeof CanvasContextType.Node;\n readonly context: SkiaCanvasRenderingContext2D;\n}\n\n/**\n * A unified CanvasRenderingContext2D type that works in both browser and Node.js environments.\n */\nexport type UnifiedCanvasContext = BrowserCanvasContext | NodeCanvasContext;\n","import { TextContent } from \"../../../types/TextContent\";\nimport { TextUnit } from \"../../../types/TextUnit\";\n\nexport function getTextUnitsFromTextContent(text: TextContent): TextUnit[][] {\n if (typeof text === \"string\") {\n return [[{ text }]];\n }\n return text.map((line) => line.map((unit) => (typeof unit === \"string\" ? { text: unit } : unit)));\n}\n","import type { Text } from \"../../../../objects/Text\";\nimport { ObjectType } from \"../../../../types/ObjectType\";\nimport { Slide } from \"../../../../types/Slide\";\nimport { SlideObject } from \"../../../../types/SlideObject\";\nimport { getTextUnitsFromTextContent } from \"../../../../utils/objects/text/getTextUnitsFromTextContent\";\nimport { getObjectChildren } from \"../../../../utils/presentation/getObjectChildren\";\n\nexport function createAccessibleDescriptionElement(presentationTitle: string): HTMLDivElement {\n const element = document.createElement(\"div\");\n // Treat the element as a live region so that screen readers announce changes to its content\n element.setAttribute(\"role\", \"status\");\n element.setAttribute(\"aria-label\", presentationTitle);\n element.setAttribute(\"aria-atomic\", \"true\");\n\n // Hide visually without removing the element from the accessibility tree\n Object.assign(element.style, {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n overflow: \"hidden\",\n clipPath: \"inset(50%)\",\n whiteSpace: \"nowrap\",\n });\n\n return element;\n}\n\nexport function getAccessibleDescription(\n slide: Slide,\n objectState: Map<SlideObject, SlideObject>,\n): string {\n const descriptions = slide.description ? [slide.description] : [];\n\n function addObjectDescriptions(object: SlideObject, parentOpacity: number): void {\n const currentObject = objectState.get(object);\n if (currentObject === undefined) {\n return;\n }\n\n const effectiveOpacity = parentOpacity * currentObject.opacity;\n if (!isVisible(currentObject, effectiveOpacity)) {\n return;\n }\n\n const description = getObjectDescription(currentObject);\n if (description) {\n descriptions.push(description);\n }\n\n for (const childObject of getObjectChildren(object)) {\n addObjectDescriptions(childObject, effectiveOpacity);\n }\n }\n\n for (const object of slide.objects) {\n addObjectDescriptions(object, 1);\n }\n\n return descriptions.join(\"\\n\");\n}\n\nfunction isVisible(object: SlideObject, opacity: number): boolean {\n return opacity !== 0 && (!(\"drawn\" in object) || object.drawn !== 0);\n}\n\nfunction getObjectDescription(object: SlideObject): string | null {\n if (object.description !== null) {\n return object.description;\n }\n return isTextObject(object) ? getTextDescription(object) : null;\n}\n\nfunction isTextObject(object: SlideObject): object is Text {\n return object.objectType === ObjectType.TEXT;\n}\n\nfunction getTextDescription(text: Text): string {\n let remainingLength = text.length;\n\n return getTextUnitsFromTextContent(text.text)\n .map((line) =>\n line\n .map((unit) => {\n if (remainingLength === null) {\n return unit.text;\n }\n if (remainingLength <= 0) {\n return \"\";\n }\n\n const visibleText = unit.text.slice(0, remainingLength);\n remainingLength -= visibleText.length;\n return visibleText;\n })\n .join(\"\"),\n )\n .join(\"\\n\");\n}\n\nexport function updateAccessibleDescription(element: HTMLElement, description: string): void {\n if (element.textContent !== description) {\n element.textContent = description;\n }\n}\n","import { UnifiedCanvasContext } from \"../types/UnifiedCanvasContext\";\n\nexport function clearCanvas(canvas: HTMLCanvasElement, ctx: UnifiedCanvasContext): void {\n ctx.context.clearRect(0, 0, canvas.width, canvas.height);\n}\n","import { Size } from \"../../../types/Size\";\n\nexport function createCanvasElement(size: Size): HTMLCanvasElement {\n const canvas = document.createElement(\"canvas\");\n canvas.setAttribute(\"width\", size.width.toString());\n canvas.setAttribute(\"height\", size.height.toString());\n canvas.setAttribute(\"aria-hidden\", \"true\");\n\n canvas.style.position = \"absolute\";\n canvas.style.width = \"100%\";\n\n return canvas;\n}\n","import { type Path2D as SkiaPath2D } from \"skia-canvas\";\n\nexport const Path2DType = {\n Browser: \"browser\",\n Node: \"node\",\n} as const;\n\nexport type Path2DType = (typeof Path2DType)[keyof typeof Path2DType];\n\nexport interface BrowserPath2D {\n readonly type: typeof Path2DType.Browser;\n readonly path: Path2D;\n}\n\nexport interface NodePath2D {\n readonly type: typeof Path2DType.Node;\n readonly path: SkiaPath2D;\n}\n\n/**\n * A unified Path2D type that works in both browser and Node.js environments.\n */\nexport type UnifiedPath2D = BrowserPath2D | NodePath2D;\n","import { Path2DType, UnifiedPath2D } from \"../types/UnifiedPath2D\";\n\nexport function createPath2D(pathData?: string | undefined): UnifiedPath2D {\n const path = new Path2D(pathData);\n return {\n type: Path2DType.Browser,\n path,\n };\n}\n","import { Arrow } from \"../../../objects/Arrow\";\nimport { Position } from \"../../../types/Position\";\n\ninterface Return {\n readonly arrowPoints: Position[];\n readonly arrowheadPoints: Position[];\n readonly doubledArrowheadPoints: Position[];\n}\n\nexport function getArrowPoints(arrow: Arrow): Return {\n const { drawn, startX, startY, endX, endY, arrowheadSize, isArrowheadFilled, isDrawnFromCenter } =\n arrow;\n const start = { x: startX, y: startY };\n const end = { x: endX, y: endY };\n\n const angle = Math.atan2(end.y - start.y, end.x - start.x);\n const midpoint = { x: start.x + (end.x - start.x) / 2, y: start.y + (end.y - start.y) / 2 };\n\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const length = Math.hypot(dx, dy);\n\n const drawnLength = length * drawn;\n const unitX = Math.cos(angle);\n const unitY = Math.sin(angle);\n\n const drawnStart = isDrawnFromCenter\n ? { x: midpoint.x - (unitX * drawnLength) / 2, y: midpoint.y - (unitY * drawnLength) / 2 }\n : start;\n const drawnEnd = isDrawnFromCenter\n ? { x: midpoint.x + (unitX * drawnLength) / 2, y: midpoint.y + (unitY * drawnLength) / 2 }\n : { x: start.x + unitX * drawnLength, y: start.y + unitY * drawnLength };\n\n const arrowAngle = isArrowheadFilled ? Math.PI / 6 : Math.PI / 4.5;\n const adjustedArrowheadSize = drawnLength < arrowheadSize * 2 ? drawnLength / 2 : arrowheadSize;\n\n const arrowheadBase1 = {\n x: drawnEnd.x - adjustedArrowheadSize * Math.cos(angle - arrowAngle),\n y: drawnEnd.y - adjustedArrowheadSize * Math.sin(angle - arrowAngle),\n };\n\n const arrowheadBase2 = {\n x: drawnEnd.x - adjustedArrowheadSize * Math.cos(angle + arrowAngle),\n y: drawnEnd.y - adjustedArrowheadSize * Math.sin(angle + arrowAngle),\n };\n\n const doubledArrowheadBase1 = {\n x: drawnStart.x + adjustedArrowheadSize * Math.cos(angle - arrowAngle),\n y: drawnStart.y + adjustedArrowheadSize * Math.sin(angle - arrowAngle),\n };\n\n const doubledArrowheadBase2 = {\n x: drawnStart.x + adjustedArrowheadSize * Math.cos(angle + arrowAngle),\n y: drawnStart.y + adjustedArrowheadSize * Math.sin(angle + arrowAngle),\n };\n\n return {\n arrowPoints: [drawnStart, drawnEnd],\n arrowheadPoints: [arrowheadBase1, drawnEnd, arrowheadBase2],\n doubledArrowheadPoints: [doubledArrowheadBase1, drawnStart, doubledArrowheadBase2],\n };\n}\n","import { Color } from \"../../types/Color\";\nimport { getAlphaForColor } from \"./getAlphaForColor\";\n\nexport function getHexStringForColor(color: Color, opacity: number | null = null): string {\n const { red, green, blue } = color;\n const hex = (red << 16) | (green << 8) | blue;\n const alphaHex = Math.round(getAlphaForColor(color, opacity) * 255);\n return `#${hex.toString(16).padStart(6, \"0\")}${alphaHex !== 255 ? alphaHex.toString(16).padStart(2, \"0\") : \"\"}`;\n}\n","import { Color } from \"../../../types/Color\";\nimport { getHexStringForColor } from \"../../../utils/color/getHexStringForColor\";\nimport { assertNever } from \"../../../utils/core/assertNever\";\nimport { CanvasContextType, UnifiedCanvasContext } from \"../types/UnifiedCanvasContext\";\nimport { Path2DType, UnifiedPath2D } from \"../types/UnifiedPath2D\";\n\ninterface Args {\n readonly color: Color;\n readonly ctx: UnifiedCanvasContext;\n readonly drawn?: number | null;\n readonly isDrawnFromCenter?: boolean;\n readonly isRounded?: boolean;\n readonly opacity?: number | null;\n readonly path: UnifiedPath2D | undefined;\n readonly pathLength?: number | null;\n readonly width: number;\n}\n\nexport function drawStroke({\n ctx,\n color,\n drawn = null,\n isDrawnFromCenter = false,\n isRounded = false,\n opacity = null,\n path,\n pathLength = null,\n width,\n}: Args) {\n if (width === 0 || drawn === 0) {\n return;\n }\n\n if (drawn !== null && pathLength !== null && drawn !== 1) {\n const fullPathLength = pathLength + (isRounded ? width : 0);\n const drawnLength = pathLength * drawn;\n if (!isDrawnFromCenter) {\n ctx.context.setLineDash([drawnLength, fullPathLength - drawnLength]);\n ctx.context.lineDashOffset = 0;\n } else {\n const gapLength = fullPathLength - drawnLength;\n ctx.context.setLineDash([drawnLength, gapLength]);\n ctx.context.lineDashOffset = -gapLength / 2;\n }\n } else {\n ctx.context.setLineDash([]);\n ctx.context.lineDashOffset = 0;\n }\n\n ctx.context.lineWidth = width;\n ctx.context.strokeStyle = getHexStringForColor(color, opacity);\n ctx.context.lineCap = isRounded ? \"round\" : \"butt\";\n\n if (path === undefined) {\n ctx.context.stroke();\n return;\n }\n\n switch (ctx.type) {\n case CanvasContextType.Browser:\n if (path.type === Path2DType.Browser) {\n ctx.context.stroke(path.path);\n } else {\n console.warn(\"Attempted to use Node Path2D in Browser Canvas context\");\n }\n break;\n case CanvasContextType.Node:\n if (path.type === Path2DType.Node) {\n ctx.context.stroke(path.path);\n } else {\n console.warn(\"Attempted to use Browser Path2D in Node Canvas context\");\n }\n break;\n default:\n assertNever(ctx);\n }\n}\n","import { Color } from \"../../../types/Color\";\nimport { getRgbStringForColor } from \"../../../utils/color/getRgbStringForColor\";\nimport { assertNever } from \"../../../utils/core/assertNever\";\nimport { CanvasContextType, UnifiedCanvasContext } from \"../types/UnifiedCanvasContext\";\nimport { Path2DType, UnifiedPath2D } from \"../types/UnifiedPath2D\";\n\ninterface Args {\n readonly ctx: UnifiedCanvasContext;\n readonly path: UnifiedPath2D | undefined;\n readonly color: Color;\n readonly opacity?: number | null;\n}\n\nexport function fillPath({ ctx, path, color, opacity = null }: Args) {\n ctx.context.fillStyle = getRgbStringForColor(color, opacity);\n\n if (path === undefined) {\n ctx.context.fill();\n return;\n }\n\n switch (ctx.type) {\n case CanvasContextType.Browser:\n if (path.type === Path2DType.Browser) {\n ctx.context.fill(path.path);\n } else {\n console.warn(\"Attempted to use Node Path2D in Browser Canvas context\");\n }\n break;\n case CanvasContextType.Node:\n if (path.type === Path2DType.Node) {\n ctx.context.fill(path.path);\n } else {\n console.warn(\"Attempted to use Browser Path2D in Node Canvas context\");\n }\n break;\n default:\n assertNever(ctx);\n }\n}\n","import { PathWithLength } from \"../../../types/PathWithLength\";\nimport { Position } from \"../../../types/Position\";\nimport { UnifiedPath2D } from \"../types/UnifiedPath2D\";\n\nexport function getPathFromPositions(\n positions: Position[],\n createPath: () => UnifiedPath2D,\n): PathWithLength {\n const path = createPath();\n\n const firstPosition = positions[0];\n if (firstPosition === undefined) {\n return { path, length: 0 };\n }\n\n path.path.moveTo(firstPosition.x, firstPosition.y);\n\n let length = 0;\n\n for (let i = 1; i < positions.length; i++) {\n const position = positions[i];\n const prevPosition = positions[i - 1];\n\n if (position === undefined || prevPosition === undefined) {\n continue;\n }\n\n const dx = position.x - prevPosition.x;\n const dy = position.y - prevPosition.y;\n length += Math.hypot(dx, dy);\n path.path.lineTo(position.x, position.y);\n }\n\n return { path, length };\n}\n","import { Arrow } from \"../../../objects/Arrow\";\nimport { getArrowPoints } from \"../../../utils/objects/arrow/getArrowPoints\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { drawStroke } from \"../utils/drawStroke\";\nimport { fillPath } from \"../utils/fillPath\";\nimport { getPathFromPositions } from \"../utils/getPathFromPoints\";\n\nexport const renderArrow: BrowserCanvasObjectRenderer<Arrow> = ({\n ctx,\n object: arrow,\n opacity,\n createPath2D,\n}) => {\n const targetOpacity = arrow.opacity * opacity;\n if (targetOpacity === 0 || arrow.drawn === 0) {\n return;\n }\n\n const { arrowPoints, arrowheadPoints, doubledArrowheadPoints } = getArrowPoints(arrow);\n\n const { path: arrowPath } = getPathFromPositions(arrowPoints, createPath2D);\n const { path: arrowheadPath } = getPathFromPositions(arrowheadPoints, createPath2D);\n\n // Draw main arrow line\n drawStroke({\n color: arrow.color,\n ctx,\n path: arrowPath,\n opacity: targetOpacity,\n width: arrow.width,\n });\n\n // Draw arrowhead\n if (arrow.isArrowheadFilled) {\n arrowheadPath.path.closePath();\n fillPath({\n ctx,\n path: arrowheadPath,\n color: arrow.color,\n opacity: targetOpacity,\n });\n }\n drawStroke({\n color: arrow.color,\n ctx,\n path: arrowheadPath,\n opacity: targetOpacity,\n width: arrow.width,\n });\n\n if (arrow.isArrowheadDoubled) {\n // Draw doubled arrowhead\n const { path: doubledArrowheadPath } = getPathFromPositions(\n doubledArrowheadPoints,\n createPath2D,\n );\n if (arrow.isArrowheadFilled) {\n doubledArrowheadPath.path.closePath();\n fillPath({\n ctx,\n path: doubledArrowheadPath,\n color: arrow.color,\n opacity: targetOpacity,\n });\n }\n drawStroke({\n color: arrow.color,\n ctx,\n path: doubledArrowheadPath,\n opacity: targetOpacity,\n width: arrow.width,\n });\n }\n};\n","import { Circle } from \"../../../objects/Circle\";\nimport { UnifiedPath2D } from \"../../../renderer/browser-canvas/types/UnifiedPath2D\";\n\n/**\n * Returns a circle path that is smaller than the original by half the stroke width.\n * This is used as a clip region when drawing semi-transparent shapes.\n */\nexport function getCircleInsetFillPath(\n circle: Circle,\n createPath: () => UnifiedPath2D,\n): UnifiedPath2D | undefined {\n const insetRadius = circle.radius - circle.strokeWidth / 2;\n if (insetRadius <= 0) {\n return undefined;\n }\n\n const path = createPath();\n const startAngle = -Math.PI / 2;\n path.path.arc(circle.x, circle.y, insetRadius, startAngle, startAngle + 2 * Math.PI);\n return path;\n}\n","import { Circle } from \"../../../objects/Circle\";\nimport { UnifiedPath2D } from \"../../../renderer/browser-canvas/types/UnifiedPath2D\";\nimport { PathWithLength } from \"../../../types/PathWithLength\";\n\nexport function getCirclePath(circle: Circle, createPath: () => UnifiedPath2D): PathWithLength {\n const path = createPath();\n const startAngle = -Math.PI / 2;\n\n path.path.arc(circle.x, circle.y, circle.radius, startAngle, startAngle + 2 * Math.PI);\n const length = 2 * Math.PI * circle.radius;\n return { path, length };\n}\n","import { assertNever } from \"../../../utils/core/assertNever\";\nimport { CanvasContextType, UnifiedCanvasContext } from \"../types/UnifiedCanvasContext\";\nimport { Path2DType, UnifiedPath2D } from \"../types/UnifiedPath2D\";\n\n/**\n * Clips the canvas context to the interior of the given path.\n * Must be called between ctx.context.save() and ctx.context.restore().\n */\nexport function clipToPath(ctx: UnifiedCanvasContext, path: UnifiedPath2D): void {\n switch (ctx.type) {\n case CanvasContextType.Browser:\n if (path.type === Path2DType.Browser) {\n ctx.context.clip(path.path);\n } else {\n console.warn(\"Attempted to use Node Path2D in Browser Canvas context\");\n }\n break;\n case CanvasContextType.Node:\n if (path.type === Path2DType.Node) {\n ctx.context.clip(path.path);\n } else {\n console.warn(\"Attempted to use Browser Path2D in Node Canvas context\");\n }\n break;\n default:\n assertNever(ctx);\n }\n}\n","import { Circle } from \"../../../objects/Circle\";\nimport { getCircleInsetFillPath } from \"../../../utils/objects/circle/getCircleInsetFillPath\";\nimport { getCirclePath } from \"../../../utils/objects/circle/getCirclePath\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { clipToPath } from \"../utils/clipToPath\";\nimport { drawStroke } from \"../utils/drawStroke\";\nimport { fillPath } from \"../utils/fillPath\";\n\nexport const renderCircle: BrowserCanvasObjectRenderer<Circle> = ({\n ctx,\n object: circle,\n opacity,\n createPath2D,\n}) => {\n const targetOpacity = circle.opacity * opacity;\n if (targetOpacity === 0 || (circle.drawn === 0 && circle.fillColor.alpha === 0)) {\n return;\n }\n\n const { path, length } = getCirclePath(circle, createPath2D);\n\n if (targetOpacity < 1 && circle.strokeWidth > 0) {\n // Clip fill to an inset path so it doesn't extend under the stroke,\n // avoiding the visual artifact on semi-transparent circles.\n const insetFillPath = getCircleInsetFillPath(circle, createPath2D);\n if (insetFillPath !== undefined) {\n ctx.context.save();\n clipToPath(ctx, insetFillPath);\n fillPath({ ctx, path, color: circle.fillColor, opacity: targetOpacity });\n ctx.context.restore();\n }\n } else {\n fillPath({ ctx, path, color: circle.fillColor, opacity: targetOpacity });\n }\n\n drawStroke({\n color: circle.strokeColor,\n ctx,\n drawn: circle.drawn,\n path,\n pathLength: length,\n opacity: targetOpacity,\n width: circle.strokeWidth,\n });\n};\n","export interface Position {\n readonly x: number;\n readonly y: number;\n}\n\nexport function Position(props: Partial<Position> | null = null): Position {\n return {\n x: 0,\n y: 0,\n ...props,\n };\n}\n\nexport const DEFAULT_POSITION = Position();\n","export const Anchor = {\n TOP_LEFT: \"TopLeft\",\n TOP: \"Top\",\n TOP_RIGHT: \"TopRight\",\n LEFT: \"Left\",\n CENTER: \"Center\",\n RIGHT: \"Right\",\n BOTTOM_LEFT: \"BottomLeft\",\n BOTTOM: \"Bottom\",\n BOTTOM_RIGHT: \"BottomRight\",\n} as const;\n\nexport type Anchor = (typeof Anchor)[keyof typeof Anchor];\n\nexport const DEFAULT_ANCHOR: Anchor = Anchor.TOP_LEFT;\n","import { DEFAULT_POSITION, Position } from \"./Position\";\nimport { DEFAULT_SIZE, Size } from \"./Size\";\n\nexport interface BoundingBox {\n /** The position of the top-left corner of the bounding box */\n readonly origin: Position;\n\n /** The size of the bounding box */\n readonly size: Size;\n}\n\nexport function BoundingBox(props: Partial<BoundingBox> | null = null): BoundingBox {\n return {\n origin: DEFAULT_POSITION,\n size: DEFAULT_SIZE,\n ...props,\n };\n}\n\nexport const DEFAULT_BOUNDING_BOX: BoundingBox = BoundingBox();\n","import { Anchor } from \"../../types/Anchor\";\nimport { BoundingBox } from \"../../types/BoundingBox\";\nimport { Position } from \"../../types/Position\";\nimport { Size } from \"../../types/Size\";\nimport { assertNever } from \"../core/assertNever\";\n\nexport function getBoundingBox(position: Position, anchor: Anchor, size: Size): BoundingBox {\n const { x, y } = position;\n const { width, height } = size;\n\n switch (anchor) {\n case Anchor.TOP_LEFT:\n return BoundingBox({\n origin: Position({ x, y }),\n size,\n });\n case Anchor.TOP:\n return BoundingBox({\n origin: Position({ x: x - width / 2, y }),\n size,\n });\n case Anchor.TOP_RIGHT:\n return BoundingBox({\n origin: Position({ x: x - width, y }),\n size,\n });\n case Anchor.LEFT:\n return BoundingBox({\n origin: Position({ x, y: y - height / 2 }),\n size,\n });\n case Anchor.CENTER:\n return BoundingBox({\n origin: Position({ x: x - width / 2, y: y - height / 2 }),\n size,\n });\n case Anchor.RIGHT:\n return BoundingBox({\n origin: Position({ x: x - width, y: y - height / 2 }),\n size,\n });\n case Anchor.BOTTOM_LEFT:\n return BoundingBox({\n origin: Position({ x, y: y - height }),\n size,\n });\n case Anchor.BOTTOM:\n return BoundingBox({\n origin: Position({ x: x - width / 2, y: y - height }),\n size,\n });\n case Anchor.BOTTOM_RIGHT:\n return BoundingBox({\n origin: Position({ x: x - width, y: y - height }),\n size,\n });\n default:\n assertNever(anchor);\n }\n}\n","import { Group } from \"../../../objects/Group\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { getHexStringForColor } from \"../../../utils/color/getHexStringForColor\";\nimport { getBoundingBox } from \"../../../utils/layout/getBoundingBox\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\n\nexport const renderGroup: BrowserCanvasObjectRenderer<Group> = ({\n ctx,\n object: group,\n renderObject,\n opacity,\n}) => {\n const scaleX = group.scale * group.scaleX;\n const scaleY = group.scale * group.scaleY;\n const boundingBox = getBoundingBox(\n Position({ x: group.x, y: group.y }),\n group.anchor,\n Size({\n width: group.width * Math.abs(scaleX),\n height: group.height * Math.abs(scaleY),\n }),\n );\n\n const { rotation, rotateOriginX, rotateOriginY, skewOriginX, skewOriginY, skewX, skewY } = group;\n\n // Prevent rendering if scale is zero\n if (scaleX === 0 || scaleY === 0) {\n return;\n }\n\n ctx.context.save();\n\n // Apply translation and scale transformations\n ctx.context.translate(boundingBox.origin.x, boundingBox.origin.y);\n ctx.context.scale(scaleX, scaleY);\n\n // Apply rotation transformation\n ctx.context.translate(rotateOriginX, rotateOriginY);\n ctx.context.rotate((rotation * Math.PI) / 180);\n ctx.context.translate(-rotateOriginX, -rotateOriginY);\n\n // Apply skew transformation\n ctx.context.translate(skewOriginX, skewOriginY);\n ctx.context.transform(\n 1,\n Math.tan((skewY * Math.PI) / 180),\n Math.tan((skewX * Math.PI) / 180),\n 1,\n 0,\n 0,\n );\n ctx.context.translate(-skewOriginX, -skewOriginY);\n\n for (const child of group.objects) {\n renderObject(child, opacity * group.opacity);\n }\n\n // If there's a preview color, render it to help with debugging group size/position\n if (group.previewColor !== null) {\n ctx.context.fillStyle = getHexStringForColor(group.previewColor);\n ctx.context.fillRect(0, 0, group.width, group.height);\n }\n\n // Show indicator for rotation origin, to help with developing and debugging rotation\n if (group.rotateOriginPreviewSize > 0) {\n ctx.context.fillStyle = \"red\";\n ctx.context.beginPath();\n ctx.context.arc(rotateOriginX, rotateOriginY, group.rotateOriginPreviewSize, 0, 2 * Math.PI);\n ctx.context.fill();\n }\n\n // Show indicator for skew origin, to help with developing and debugging skew\n if (group.skewOriginPreviewSize > 0) {\n ctx.context.fillStyle = \"blue\";\n ctx.context.beginPath();\n ctx.context.arc(skewOriginX, skewOriginY, group.skewOriginPreviewSize, 0, 2 * Math.PI);\n ctx.context.fill();\n }\n\n ctx.context.restore();\n};\n","import { UnifiedPath2D } from \"../../../renderer/browser-canvas/types/UnifiedPath2D\";\nimport { PathWithLength } from \"../../../types/PathWithLength\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\n\nexport function getRoundedRectanglePath(\n origin: Position,\n size: Size,\n cornerRadius: number,\n createPath: () => UnifiedPath2D,\n overshoot: number = 0,\n): PathWithLength {\n const path = createPath();\n\n path.path.moveTo(origin.x + cornerRadius, origin.y);\n path.path.lineTo(origin.x + size.width - cornerRadius, origin.y);\n path.path.arcTo(\n origin.x + size.width,\n origin.y,\n origin.x + size.width,\n origin.y + cornerRadius,\n cornerRadius,\n );\n path.path.lineTo(origin.x + size.width, origin.y + size.height - cornerRadius);\n path.path.arcTo(\n origin.x + size.width,\n origin.y + size.height,\n origin.x + size.width - cornerRadius,\n origin.y + size.height,\n cornerRadius,\n );\n path.path.lineTo(origin.x + cornerRadius, origin.y + size.height);\n path.path.arcTo(\n origin.x,\n origin.y + size.height,\n origin.x,\n origin.y + size.height - cornerRadius,\n cornerRadius,\n );\n path.path.lineTo(origin.x, origin.y + cornerRadius);\n path.path.arcTo(origin.x, origin.y, origin.x + cornerRadius, origin.y, cornerRadius);\n if (overshoot > 0) {\n path.path.lineTo(origin.x + cornerRadius + overshoot, origin.y);\n }\n\n const length =\n 2 * (size.width + size.height - 4 * cornerRadius) + 2 * Math.PI * cornerRadius + overshoot;\n return { path, length };\n}\n","import { type Image } from \"skia-canvas\";\n\nexport const ImageType = {\n Browser: \"browser\",\n Node: \"node\",\n} as const;\n\nexport type ImageType = (typeof ImageType)[keyof typeof ImageType];\n\nexport interface BrowserImage {\n readonly type: typeof ImageType.Browser;\n readonly image: HTMLImageElement;\n}\n\nexport interface NodeImage {\n readonly type: typeof ImageType.Node;\n readonly image: Image;\n}\n\n/**\n * A unified Image type that works in both browser and Node.js environments.\n */\nexport type UnifiedImage = BrowserImage | NodeImage;\n","import { Image } from \"../../../objects/Image\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { assertNever } from \"../../../utils/core/assertNever\";\nimport { getBoundingBox } from \"../../../utils/layout/getBoundingBox\";\nimport { getRoundedRectanglePath } from \"../../../utils/objects/rectangle/getRoundedRectanglePath\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { CanvasContextType } from \"../types/UnifiedCanvasContext\";\nimport { ImageType } from \"../types/UnifiedImage\";\nimport { Path2DType } from \"../types/UnifiedPath2D\";\n\nexport const renderImage: BrowserCanvasObjectRenderer<Image> = ({\n ctx,\n imageById,\n object: image,\n opacity,\n createPath2D,\n}) => {\n const boundingBox = getBoundingBox(\n Position({ x: image.x, y: image.y }),\n image.anchor,\n Size({ width: image.width, height: image.height }),\n );\n\n const imageId =\n image.imageId != null && image.imageId.length > 0 ? image.imageId : image.imagePath;\n if (imageId == null) {\n return;\n }\n\n const imageData = imageById[imageId];\n if (imageData === undefined) {\n return;\n }\n\n ctx.context.save();\n\n if (image.cornerRadius > 0) {\n const roundedRectPath = getRoundedRectanglePath(\n boundingBox.origin,\n boundingBox.size,\n image.cornerRadius,\n createPath2D,\n );\n\n switch (ctx.type) {\n case CanvasContextType.Browser:\n if (roundedRectPath.path.type === Path2DType.Browser) {\n ctx.context.clip(roundedRectPath.path.path);\n } else {\n console.warn(\"Attempted to use Node Path2D in Browser Canvas context\");\n }\n break;\n case CanvasContextType.Node:\n if (roundedRectPath.path.type === Path2DType.Node) {\n ctx.context.clip(roundedRectPath.path.path);\n } else {\n console.warn(\"Attempted to use Browser Path2D in Node Canvas context\");\n }\n break;\n default:\n assertNever(ctx);\n }\n }\n\n ctx.context.globalAlpha = opacity * image.opacity;\n ctx.context.imageSmoothingEnabled = image.smooth;\n\n switch (ctx.type) {\n case CanvasContextType.Browser:\n if (imageData.type === ImageType.Browser) {\n ctx.context.drawImage(\n imageData.image,\n boundingBox.origin.x,\n boundingBox.origin.y,\n boundingBox.size.width,\n boundingBox.size.height,\n );\n } else {\n console.warn(\"Attempted to use Node Image in Browser Canvas context\");\n }\n break;\n case CanvasContextType.Node:\n if (imageData.type === ImageType.Node) {\n ctx.context.drawImage(\n imageData.image,\n boundingBox.origin.x,\n boundingBox.origin.y,\n boundingBox.size.width,\n boundingBox.size.height,\n );\n } else {\n console.warn(\"Attempted to use Browser Image in Node Canvas context\");\n }\n break;\n default:\n assertNever(ctx);\n }\n\n // Restore opacity state\n ctx.context.restore();\n};\n","import { Line } from \"../../../objects/Line\";\nimport { UnifiedPath2D } from \"../../../renderer/browser-canvas/types/UnifiedPath2D\";\nimport { PathWithLength } from \"../../../types/PathWithLength\";\n\nexport function getLinePath(line: Line, createPath: () => UnifiedPath2D): PathWithLength {\n const path = createPath();\n\n path.path.moveTo(line.startX, line.startY);\n path.path.lineTo(line.endX, line.endY);\n\n const length = Math.hypot(line.endX - line.startX, line.endY - line.startY);\n\n return { path, length };\n}\n","import { Line } from \"../../../objects/Line\";\nimport { getLinePath } from \"../../../utils/objects/line/getLinePath\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { drawStroke } from \"../utils/drawStroke\";\n\nexport const renderLine: BrowserCanvasObjectRenderer<Line> = ({\n ctx,\n object: line,\n opacity,\n createPath2D,\n}) => {\n const targetOpacity = line.opacity * opacity;\n if (targetOpacity === 0 || line.drawn === 0) {\n return;\n }\n\n const { path, length } = getLinePath(line, createPath2D);\n\n drawStroke({\n color: line.color,\n ctx,\n drawn: line.drawn,\n isDrawnFromCenter: line.isDrawnFromCenter,\n isRounded: line.isRounded,\n path,\n pathLength: length,\n opacity: targetOpacity,\n width: line.width,\n });\n};\n","import { Mask } from \"../../../objects/Mask\";\nimport { Color } from \"../../../types/Color\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { getHexStringForColor } from \"../../../utils/color/getHexStringForColor\";\nimport { getBoundingBox } from \"../../../utils/layout/getBoundingBox\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\n\nexport const renderMask: BrowserCanvasObjectRenderer<Mask> = ({\n ctx,\n object: mask,\n opacity,\n renderObject,\n}) => {\n ctx.context.save();\n\n const bbox = getBoundingBox(\n Position({ x: mask.x, y: mask.y }),\n mask.anchor,\n Size({ width: mask.width, height: mask.height }),\n );\n\n if (mask.preview) {\n ctx.context.lineWidth = 4;\n ctx.context.strokeStyle = getHexStringForColor(Color.RED);\n ctx.context.rect(bbox.origin.x, bbox.origin.y, bbox.size.width, bbox.size.height);\n ctx.context.stroke();\n }\n\n ctx.context.beginPath();\n ctx.context.rect(bbox.origin.x, bbox.origin.y, bbox.size.width, bbox.size.height);\n ctx.context.closePath();\n ctx.context.clip();\n\n for (const child of mask.objects) {\n renderObject(child, opacity * mask.opacity);\n }\n\n ctx.context.restore();\n};\n","import { Path } from \"../../../objects/Path\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { getBoundingBox } from \"../../../utils/layout/getBoundingBox\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { drawStroke } from \"../utils/drawStroke\";\nimport { fillPath } from \"../utils/fillPath\";\n\nexport const renderPath: BrowserCanvasObjectRenderer<Path> = ({\n ctx,\n object: path,\n opacity,\n createPath2D,\n}) => {\n const targetOpacity = path.opacity * opacity;\n if (targetOpacity === 0 || (path.drawn === 0 && path.fillColor.alpha === 0)) {\n return;\n }\n\n const { origin } = getBoundingBox(\n Position({ x: path.x, y: path.y }),\n path.anchor,\n Size({ width: path.width, height: path.height }),\n );\n const path2D = createPath2D(path.path);\n\n ctx.context.save();\n ctx.context.translate(origin.x, origin.y);\n ctx.context.scale(path.width / path.viewboxWidth, path.height / path.viewboxHeight);\n\n fillPath({\n ctx,\n path: path2D,\n color: path.fillColor,\n opacity: targetOpacity,\n });\n\n drawStroke({\n color: path.strokeColor,\n ctx,\n drawn: path.drawn,\n isRounded: path.isRounded,\n path: path2D,\n pathLength: path.pathLength,\n opacity: targetOpacity,\n width: path.strokeWidth,\n });\n\n // Undo transformations\n ctx.context.restore();\n};\n","import { Polygon } from \"../../../objects/Polygon\";\nimport { UnifiedPath2D } from \"../../../renderer/browser-canvas/types/UnifiedPath2D\";\nimport { PathWithLength } from \"../../../types/PathWithLength\";\n\nexport function getPolygonPath(polygon: Polygon, createPath: () => UnifiedPath2D): PathWithLength {\n const path = createPath();\n const points = polygon.points;\n\n const firstPoint = points[0];\n if (firstPoint === undefined) {\n return { path, length: 0 };\n }\n\n path.path.moveTo(firstPoint.x, firstPoint.y);\n\n let length = 0;\n let previousPoint = firstPoint;\n for (let i = 1; i < points.length; i++) {\n const point = points[i];\n if (point === undefined) {\n continue;\n }\n path.path.lineTo(point.x, point.y);\n const segmentLength = Math.hypot(point.x - previousPoint.x, point.y - previousPoint.y);\n length += segmentLength;\n previousPoint = point;\n }\n\n path.path.closePath();\n const closingSegmentLength = Math.hypot(\n firstPoint.x - previousPoint.x,\n firstPoint.y - previousPoint.y,\n );\n length += closingSegmentLength;\n\n return { path, length };\n}\n","import { Polygon } from \"../../../objects/Polygon\";\nimport { getPolygonPath } from \"../../../utils/objects/polygon/getPolygonPath\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { drawStroke } from \"../utils/drawStroke\";\nimport { fillPath } from \"../utils/fillPath\";\n\nexport const renderPolygon: BrowserCanvasObjectRenderer<Polygon> = ({\n ctx,\n object: polygon,\n opacity,\n createPath2D,\n}) => {\n const targetOpacity = polygon.opacity * opacity;\n if (targetOpacity === 0 || (polygon.drawn === 0 && polygon.fillColor.alpha === 0)) {\n return;\n }\n\n const { path, length } = getPolygonPath(polygon, createPath2D);\n\n fillPath({\n ctx,\n path,\n color: polygon.fillColor,\n opacity: targetOpacity,\n });\n\n drawStroke({\n color: polygon.strokeColor,\n ctx,\n drawn: polygon.drawn,\n path,\n pathLength: length,\n opacity: targetOpacity,\n width: polygon.strokeWidth,\n });\n};\n","import { Rectangle } from \"../../../objects/Rectangle\";\nimport { UnifiedPath2D } from \"../../../renderer/browser-canvas/types/UnifiedPath2D\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { getBoundingBox } from \"../../layout/getBoundingBox\";\nimport { getRoundedRectanglePath } from \"./getRoundedRectanglePath\";\n\n/**\n * Returns a rectangle path that is smaller than the original by half the stroke width\n * on each side. This is used as a clip region when drawing semi-transparent shapes.\n */\nexport function getRectangleInsetFillPath(\n rectangle: Rectangle,\n createPath: () => UnifiedPath2D,\n): UnifiedPath2D | undefined {\n const inset = rectangle.strokeWidth / 2;\n\n const { origin, size } = getBoundingBox(\n Position({ x: rectangle.x, y: rectangle.y }),\n rectangle.anchor,\n Size({ width: rectangle.width, height: rectangle.height }),\n );\n\n const insetWidth = size.width - rectangle.strokeWidth;\n const insetHeight = size.height - rectangle.strokeWidth;\n if (insetWidth <= 0 || insetHeight <= 0) {\n return undefined;\n }\n\n const insetOrigin = Position({ x: origin.x + inset, y: origin.y + inset });\n const insetSize = Size({ width: insetWidth, height: insetHeight });\n\n const cornerRadius = Math.max(\n 0,\n Math.min(rectangle.cornerRadius - inset, Math.min(insetWidth, insetHeight) / 2),\n );\n\n if (cornerRadius > 0) {\n return getRoundedRectanglePath(insetOrigin, insetSize, cornerRadius, createPath).path;\n }\n\n const path = createPath();\n path.path.moveTo(insetOrigin.x, insetOrigin.y);\n path.path.lineTo(insetOrigin.x + insetWidth, insetOrigin.y);\n path.path.lineTo(insetOrigin.x + insetWidth, insetOrigin.y + insetHeight);\n path.path.lineTo(insetOrigin.x, insetOrigin.y + insetHeight);\n path.path.closePath();\n return path;\n}\n","import { Rectangle } from \"../../../objects/Rectangle\";\nimport { UnifiedPath2D } from \"../../../renderer/browser-canvas/types/UnifiedPath2D\";\nimport { PathWithLength } from \"../../../types/PathWithLength\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { getBoundingBox } from \"../../layout/getBoundingBox\";\nimport { getRoundedRectanglePath } from \"./getRoundedRectanglePath\";\n\nexport function getRectanglePath(\n rectangle: Rectangle,\n createPath: () => UnifiedPath2D,\n): PathWithLength {\n const { origin, size } = getBoundingBox(\n Position({ x: rectangle.x, y: rectangle.y }),\n rectangle.anchor,\n Size({ width: rectangle.width, height: rectangle.height }),\n );\n\n const cornerRadius = Math.max(\n 0,\n Math.min(rectangle.cornerRadius, Math.min(size.width, size.height) / 2),\n );\n\n // Overshoot needed so that when path is drawn, the line caps cover the corners fully\n const overshoot = Math.min(rectangle.strokeWidth * 2, size.width - cornerRadius);\n\n if (cornerRadius > 0) {\n return getRoundedRectanglePath(origin, size, cornerRadius, createPath, overshoot);\n } else {\n const path = createPath();\n path.path.moveTo(origin.x, origin.y);\n path.path.lineTo(origin.x + size.width, origin.y);\n path.path.lineTo(origin.x + size.width, origin.y + size.height);\n path.path.lineTo(origin.x, origin.y + size.height);\n path.path.lineTo(origin.x, origin.y);\n path.path.lineTo(origin.x + overshoot, origin.y);\n\n const length = 2 * (size.width + size.height) + overshoot;\n return { path, length };\n }\n}\n","import { Rectangle } from \"../../../objects/Rectangle\";\nimport { getRectangleInsetFillPath } from \"../../../utils/objects/rectangle/getRectangleInsetFillPath\";\nimport { getRectanglePath } from \"../../../utils/objects/rectangle/getRectanglePath\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { clipToPath } from \"../utils/clipToPath\";\nimport { drawStroke } from \"../utils/drawStroke\";\nimport { fillPath } from \"../utils/fillPath\";\n\nexport const renderRectangle: BrowserCanvasObjectRenderer<Rectangle> = ({\n ctx,\n object: rectangle,\n opacity,\n createPath2D,\n}) => {\n const targetOpacity = rectangle.opacity * opacity;\n if (targetOpacity === 0 || (rectangle.drawn === 0 && rectangle.fillColor.alpha === 0)) {\n return;\n }\n\n const { path, length } = getRectanglePath(rectangle, createPath2D);\n\n if (targetOpacity < 1 && rectangle.strokeWidth > 0) {\n // Clip fill to an inset path so it doesn't extend under the stroke.\n const insetFillPath = getRectangleInsetFillPath(rectangle, createPath2D);\n if (insetFillPath !== undefined) {\n ctx.context.save();\n clipToPath(ctx, insetFillPath);\n fillPath({ ctx, path, color: rectangle.fillColor, opacity: targetOpacity });\n ctx.context.restore();\n }\n } else {\n fillPath({ ctx, path, color: rectangle.fillColor, opacity: targetOpacity });\n }\n\n drawStroke({\n color: rectangle.strokeColor,\n ctx,\n drawn: rectangle.drawn,\n path,\n pathLength: length,\n opacity: targetOpacity,\n width: rectangle.strokeWidth,\n });\n};\n","import { Spotlight } from \"../../../objects/Spotlight\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { getBoundingBox } from \"../../layout/getBoundingBox\";\n\nexport function getSpotlightCutout(spotlight: Spotlight) {\n const { origin, size } = getBoundingBox(\n Position({ x: spotlight.x, y: spotlight.y }),\n spotlight.anchor,\n Size({ width: spotlight.width, height: spotlight.height }),\n );\n\n return {\n origin,\n size,\n cornerRadius: Math.max(\n 0,\n Math.min(spotlight.cornerRadius, Math.min(size.width, size.height) / 2),\n ),\n };\n}\n","import { Spotlight } from \"../../../objects/Spotlight\";\nimport { UnifiedPath2D } from \"../../../renderer/browser-canvas/types/UnifiedPath2D\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { getSpotlightCutout } from \"./getSpotlightCutout\";\n\ninterface SpotlightPathBounds {\n readonly origin: Position;\n readonly size: Size;\n}\n\nexport function getSpotlightPath(\n spotlight: Spotlight,\n slideSize: Size,\n createPath: () => UnifiedPath2D,\n bounds: SpotlightPathBounds = {\n origin: Position({ x: 0, y: 0 }),\n size: slideSize,\n },\n): UnifiedPath2D {\n const path = createPath();\n const { origin, size, cornerRadius } = getSpotlightCutout(spotlight);\n const { origin: boundsOrigin, size: boundsSize } = bounds;\n\n path.path.moveTo(boundsOrigin.x, boundsOrigin.y);\n path.path.lineTo(boundsOrigin.x + boundsSize.width, boundsOrigin.y);\n path.path.lineTo(boundsOrigin.x + boundsSize.width, boundsOrigin.y + boundsSize.height);\n path.path.lineTo(boundsOrigin.x, boundsOrigin.y + boundsSize.height);\n path.path.lineTo(boundsOrigin.x, boundsOrigin.y);\n\n // Draw the cutout in the opposite direction so the non-zero fill rule leaves it transparent.\n if (cornerRadius === 0) {\n path.path.moveTo(origin.x, origin.y);\n path.path.lineTo(origin.x, origin.y + size.height);\n path.path.lineTo(origin.x + size.width, origin.y + size.height);\n path.path.lineTo(origin.x + size.width, origin.y);\n path.path.lineTo(origin.x, origin.y);\n return path;\n }\n\n path.path.moveTo(origin.x + cornerRadius, origin.y);\n path.path.arcTo(origin.x, origin.y, origin.x, origin.y + cornerRadius, cornerRadius);\n path.path.lineTo(origin.x, origin.y + size.height - cornerRadius);\n path.path.arcTo(\n origin.x,\n origin.y + size.height,\n origin.x + cornerRadius,\n origin.y + size.height,\n cornerRadius,\n );\n path.path.lineTo(origin.x + size.width - cornerRadius, origin.y + size.height);\n path.path.arcTo(\n origin.x + size.width,\n origin.y + size.height,\n origin.x + size.width,\n origin.y + size.height - cornerRadius,\n cornerRadius,\n );\n path.path.lineTo(origin.x + size.width, origin.y + cornerRadius);\n path.path.arcTo(\n origin.x + size.width,\n origin.y,\n origin.x + size.width - cornerRadius,\n origin.y,\n cornerRadius,\n );\n path.path.lineTo(origin.x + cornerRadius, origin.y);\n\n return path;\n}\n","import { Spotlight } from \"../../../objects/Spotlight\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { getSpotlightPath } from \"../../../utils/objects/spotlight/getSpotlightPath\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { fillPath } from \"../utils/fillPath\";\n\nexport const renderSpotlight: BrowserCanvasObjectRenderer<Spotlight> = ({\n createPath2D,\n ctx,\n object: spotlight,\n opacity,\n renderScale,\n slideSize,\n}) => {\n const targetOpacity = spotlight.opacity * opacity;\n if (targetOpacity === 0 || spotlight.color.alpha === 0) {\n return;\n }\n\n const overlaySize = Size({\n width: slideSize.width / renderScale,\n height: slideSize.height / renderScale,\n });\n const overlayOrigin = Position({\n x: (slideSize.width - overlaySize.width) / 2,\n y: (slideSize.height - overlaySize.height) / 2,\n });\n\n // The slide content may be scaled down by BrowserCanvasRenderer; expand the dimmer in\n // slide coordinates so it still covers the whole canvas after that transform is applied.\n const path = getSpotlightPath(spotlight, slideSize, createPath2D, {\n origin: overlayOrigin,\n size: overlaySize,\n });\n fillPath({ ctx, path, color: spotlight.color, opacity: targetOpacity });\n};\n","import { SVG } from \"../../../objects/SVG\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { assertNever } from \"../../../utils/core/assertNever\";\nimport { getBoundingBox } from \"../../../utils/layout/getBoundingBox\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { CanvasContextType } from \"../types/UnifiedCanvasContext\";\nimport { ImageType } from \"../types/UnifiedImage\";\n\nexport const renderSvg: BrowserCanvasObjectRenderer<SVG> = ({\n ctx,\n imageById,\n object: svg,\n opacity,\n}) => {\n const targetOpacity = svg.opacity * opacity;\n if (targetOpacity === 0 || !svg.svg) {\n return;\n }\n\n const imageData = imageById[svg.svg];\n if (imageData === undefined) {\n return;\n }\n\n const boundingBox = getBoundingBox(\n Position({ x: svg.x, y: svg.y }),\n svg.anchor,\n Size({ width: svg.width, height: svg.height }),\n );\n\n ctx.context.save();\n ctx.context.globalAlpha = targetOpacity;\n\n switch (ctx.type) {\n case CanvasContextType.Browser:\n if (imageData.type === ImageType.Browser) {\n ctx.context.drawImage(\n imageData.image,\n boundingBox.origin.x,\n boundingBox.origin.y,\n boundingBox.size.width,\n boundingBox.size.height,\n );\n }\n break;\n case CanvasContextType.Node:\n if (imageData.type === ImageType.Node) {\n ctx.context.drawImage(\n imageData.image,\n boundingBox.origin.x,\n boundingBox.origin.y,\n boundingBox.size.width,\n boundingBox.size.height,\n );\n }\n break;\n default:\n assertNever(ctx);\n }\n\n ctx.context.restore();\n};\n","export const Alignment = {\n LEFT: \"left\",\n CENTER: \"center\",\n RIGHT: \"right\",\n} as const;\n\nexport type Alignment = (typeof Alignment)[keyof typeof Alignment];\n\nexport const DEFAULT_ALIGNMENT: Alignment = Alignment.LEFT;\n","import { Text } from \"../../../objects/Text\";\nimport { TextStyle } from \"../../../types/TextStyle\";\n\nexport function getTextStyleFromText(text: Text): TextStyle {\n return {\n color: text.color,\n fontFamily: text.fontFamily,\n fontSize: text.fontSize,\n fontStyle: text.fontStyle,\n fontWeight: text.fontWeight,\n ligatures: text.ligatures,\n subscript: text.subscript,\n superscript: text.superscript,\n };\n}\n","import { Size } from \"../../../../types/Size\";\nimport { TextUnitMeasurement } from \"./getTextUnitMeasurements\";\n\n// Units flow horizontally, so widths add; their vertical extents share a baseline,\n// so the largest ascent, descent, and line advance define the line.\nfunction getLineLayout(lineMeasurements: readonly TextUnitMeasurement[]) {\n const bottom = Math.max(...lineMeasurements.map((unit) => unit.bottom), 0);\n const top = Math.max(...lineMeasurements.map((unit) => unit.top), 0);\n\n return {\n bottom,\n height: top + bottom,\n lineAdvance: Math.max(...lineMeasurements.map((unit) => unit.lineAdvance), 0),\n top,\n width: lineMeasurements.reduce((acc, curr) => acc + curr.width, 0),\n };\n}\n\n/**\n * Computes text block bounds and per-line baseline positions.\n *\n * Accepts as input per-line measurements for each text unit, plus a desired line spacing.\n */\nexport function getTextLayout(\n lineMeasurements: readonly (readonly TextUnitMeasurement[])[],\n lineSpacing: number = 1,\n) {\n const lines = lineMeasurements.map(getLineLayout);\n\n if (lines.length === 0) {\n return {\n baselines: [],\n size: Size(),\n };\n }\n\n let baselineY = 0;\n let previousLineBoxBottom: number | undefined;\n let layoutTop = 0;\n let layoutBottom = 0;\n const baselines: number[] = [];\n\n for (const line of lines) {\n // lineSpacing scales the nominal font size. Any extra (or negative) leading\n // is split evenly above and below the measured font bounds.\n const lineHeight = line.lineAdvance * lineSpacing;\n const halfLeading = (lineHeight - line.height) / 2;\n const lineBoxTop = line.top + halfLeading;\n\n if (previousLineBoxBottom === undefined) {\n baselineY = lineBoxTop;\n } else {\n // Adjacent line boxes meet at the previous descent and current ascent.\n baselineY += previousLineBoxBottom + lineBoxTop;\n }\n\n baselines.push(baselineY);\n\n // Use font bounds for the final block size because they can extend beyond\n // the nominal line boxes when leading is negative.\n layoutTop = Math.min(layoutTop, baselineY - line.top);\n layoutBottom = Math.max(layoutBottom, baselineY + line.bottom);\n previousLineBoxBottom = line.bottom + halfLeading;\n }\n\n // Return baselines relative to the top edge of the measured text block.\n const baselineOffset = -layoutTop;\n\n return {\n baselines: baselines.map((baseline) => baseline + baselineOffset),\n size: Size({\n height: layoutBottom - layoutTop,\n width: Math.max(...lines.map((line) => line.width), 0),\n }),\n };\n}\n","import { TextStyle } from \"../../../types/TextStyle\";\n\nconst SCRIPT_FONT_SIZE_SCALE = 0.7;\nconst SCRIPT_BASELINE_SHIFT_SCALE = 0.3;\n\nexport interface TextScriptVariant {\n readonly baselineShift: number;\n readonly fontSize: number;\n readonly isSubscript: boolean;\n readonly isSuperscript: boolean;\n}\n\nexport function getTextScriptVariant(textStyle: TextStyle): TextScriptVariant {\n const isSuperscript = textStyle.superscript;\n const isSubscript = textStyle.subscript && !isSuperscript;\n\n if (!isSuperscript && !isSubscript) {\n return {\n baselineShift: 0,\n fontSize: textStyle.fontSize,\n isSubscript: false,\n isSuperscript: false,\n };\n }\n\n return {\n baselineShift: textStyle.fontSize * SCRIPT_BASELINE_SHIFT_SCALE * (isSuperscript ? -1 : 1),\n fontSize: textStyle.fontSize * SCRIPT_FONT_SIZE_SCALE,\n isSubscript,\n isSuperscript,\n };\n}\n","import { Size } from \"../../../types/Size\";\n\nexport interface TextMetricsSize extends Size {\n readonly bottom: number;\n readonly top: number;\n}\n\nfunction getMetricValue(value: number | undefined, fallback: number = 0): number {\n return value != null ? value : fallback;\n}\n\nexport function getSizeFromTextMetrics(textMetrics: TextMetrics): TextMetricsSize {\n // Distance from baseline up to top of font box\n const top = getMetricValue(\n textMetrics.fontBoundingBoxAscent,\n textMetrics.actualBoundingBoxAscent,\n );\n\n // Distance from baseline to bottom of font box\n const bottom = getMetricValue(\n textMetrics.fontBoundingBoxDescent,\n textMetrics.actualBoundingBoxDescent,\n );\n\n return {\n bottom,\n height: top + bottom,\n top,\n width: textMetrics.width,\n };\n}\n","import { TextStyle } from \"../../../../types/TextStyle\";\nimport { getRgbStringForColor } from \"../../../../utils/color/getRgbStringForColor\";\nimport { getTextScriptVariant } from \"../../../../utils/objects/text/getTextScriptVariant\";\nimport { CanvasContextType, UnifiedCanvasContext } from \"../../types/UnifiedCanvasContext\";\n\nexport function setContextWithTextStyle(\n ctx: UnifiedCanvasContext,\n textStyle: TextStyle,\n opacity: number = 1,\n) {\n const scriptVariant = getTextScriptVariant(textStyle);\n\n ctx.context.fillStyle = getRgbStringForColor(textStyle.color, opacity);\n ctx.context.font = `${textStyle.fontStyle} ${textStyle.fontWeight} ${scriptVariant.fontSize}px ${textStyle.fontFamily}`;\n\n if (ctx.type === CanvasContextType.Browser) {\n ctx.context.textRendering = textStyle.ligatures ? \"optimizeLegibility\" : \"optimizeSpeed\";\n } else {\n ctx.context.fontVariant = textStyle.ligatures ? \"common-ligatures\" : \"no-common-ligatures\";\n }\n}\n","import { Size } from \"../../../../types/Size\";\nimport { TextStyle } from \"../../../../types/TextStyle\";\nimport { TextUnit } from \"../../../../types/TextUnit\";\nimport { getTextScriptVariant } from \"../../../../utils/objects/text/getTextScriptVariant\";\nimport { UnifiedCanvasContext } from \"../../types/UnifiedCanvasContext\";\nimport { getSizeFromTextMetrics } from \"../getSizeFromTextMetrics\";\nimport { setContextWithTextStyle } from \"./setContextWithTextStyle\";\n\n/**\n * Font measurements for one styled text unit, in canvas pixels.\n *\n * The inherited `width` is the horizontal advance, while `height` is `top + bottom`.\n */\nexport interface TextUnitMeasurement extends Size {\n /** Offset added to the line baseline when drawing; negative values move text upward. */\n readonly baselineShift: number;\n /** Distance from the line baseline to the bottom of the font bounds. */\n readonly bottom: number;\n /** Font size used to calculate the line box height. */\n readonly lineAdvance: number;\n /** Distance from the line baseline to the top of the font bounds. */\n readonly top: number;\n}\n\nexport function getTextUnitMeasurements(\n textUnits: TextUnit[][],\n style: TextStyle,\n ctx: UnifiedCanvasContext,\n): TextUnitMeasurement[][] {\n const sizes: TextUnitMeasurement[][] = [];\n\n for (const line of textUnits) {\n const lineSizes: TextUnitMeasurement[] = [];\n // Empty lines still need the base style's metrics so they occupy a line box\n const measurementUnits = line.length === 0 ? [{ text: \"\" }] : line;\n\n for (const unit of measurementUnits) {\n const { text, ...unitStyle } = unit;\n const combinedStyle: TextStyle = { ...style, ...unitStyle };\n setContextWithTextStyle(ctx, combinedStyle);\n const metrics = ctx.context.measureText(text);\n const size = getSizeFromTextMetrics(metrics);\n const { baselineShift } = getTextScriptVariant(combinedStyle);\n const top = Math.max(0, size.top - baselineShift);\n const bottom = Math.max(0, size.bottom + baselineShift);\n lineSizes.push({\n ...size,\n baselineShift,\n bottom,\n height: top + bottom,\n lineAdvance: combinedStyle.fontSize,\n top,\n });\n }\n sizes.push(lineSizes);\n }\n\n return sizes;\n}\n","import { Text } from \"../../../objects/Text\";\nimport { Alignment } from \"../../../types/Alignment\";\nimport { Position } from \"../../../types/Position\";\nimport { TextStyle } from \"../../../types/TextStyle\";\nimport { assertNever } from \"../../../utils/core/assertNever\";\nimport { getBoundingBox } from \"../../../utils/layout/getBoundingBox\";\nimport { getTextStyleFromText } from \"../../../utils/objects/text/getTextStyleFromText\";\nimport { getTextUnitsFromTextContent } from \"../../../utils/objects/text/getTextUnitsFromTextContent\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { getTextLayout } from \"../utils/text/getTextLayout\";\nimport { getTextUnitMeasurements } from \"../utils/text/getTextUnitMeasurements\";\nimport { setContextWithTextStyle } from \"../utils/text/setContextWithTextStyle\";\n\nexport const renderText: BrowserCanvasObjectRenderer<Text> = ({ ctx, object: text, opacity }) => {\n const targetOpacity = text.opacity * opacity;\n if (targetOpacity === 0) {\n return;\n }\n\n const { length } = text;\n const textUnits = getTextUnitsFromTextContent(text.text);\n const style = getTextStyleFromText(text);\n\n const sizes = getTextUnitMeasurements(textUnits, style, ctx);\n const layout = getTextLayout(sizes, text.lineSpacing);\n const boundingBox = getBoundingBox(Position({ x: text.x, y: text.y }), text.anchor, layout.size);\n\n let x = boundingBox.origin.x;\n let consumedLength = 0;\n\n for (let lineIndex = 0; lineIndex < textUnits.length; lineIndex++) {\n const line = textUnits[lineIndex];\n const lineSizes = sizes[lineIndex];\n const baseline = layout.baselines[lineIndex];\n\n if (line == undefined || lineSizes == undefined || baseline == undefined) {\n console.error(\"Could not determine text units or sizes for line\");\n continue;\n }\n\n const lineWidth = lineSizes.reduce((acc, curr) => acc + curr.width, 0);\n\n switch (text.alignment) {\n case Alignment.LEFT:\n x = boundingBox.origin.x;\n break;\n case Alignment.CENTER:\n x = boundingBox.origin.x + (boundingBox.size.width - lineWidth) / 2;\n break;\n case Alignment.RIGHT:\n x = boundingBox.origin.x + (boundingBox.size.width - lineWidth);\n break;\n default:\n assertNever(text.alignment);\n break;\n }\n const baselineY = boundingBox.origin.y + baseline;\n\n for (let unitIndex = 0; unitIndex < line.length; unitIndex++) {\n if (length !== null && consumedLength >= length) {\n break;\n }\n\n const unit = line[unitIndex];\n const unitSize = lineSizes[unitIndex];\n\n if (unit == undefined || unitSize == undefined) {\n console.error(\"Could not determine text unit or size for unit\");\n continue;\n }\n\n const { text: unitText, ...unitStyle } = unit;\n\n let truncatedUnitText: string | undefined;\n if (length !== null && consumedLength + unitText.length > length) {\n const remainingLength = length - consumedLength;\n truncatedUnitText = unitText.slice(0, remainingLength);\n }\n const targetUnitText = truncatedUnitText ?? unitText;\n consumedLength += targetUnitText.length;\n\n const combinedStyle: TextStyle = { ...style, ...unitStyle };\n setContextWithTextStyle(ctx, combinedStyle, targetOpacity);\n ctx.context.fillText(targetUnitText, x, baselineY + unitSize.baselineShift);\n x += unitSize.width;\n }\n }\n};\n","import { ObjectType } from \"../../../types/ObjectType\";\nimport { renderArrow } from \"../objects/renderArrow\";\nimport { renderCircle } from \"../objects/renderCircle\";\nimport { renderGroup } from \"../objects/renderGroup\";\nimport { renderImage } from \"../objects/renderImage\";\nimport { renderLine } from \"../objects/renderLine\";\nimport { renderMask } from \"../objects/renderMask\";\nimport { renderPath } from \"../objects/renderPath\";\nimport { renderPolygon } from \"../objects/renderPolygon\";\nimport { renderRectangle } from \"../objects/renderRectangle\";\nimport { renderSpotlight } from \"../objects/renderSpotlight\";\nimport { renderSvg } from \"../objects/renderSvg\";\nimport { renderText } from \"../objects/renderText\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\n\ntype ObjectRendererMap = Record<ObjectType, BrowserCanvasObjectRenderer<any>>;\n\nexport const DEFAULT_OBJECT_RENDERERS: ObjectRendererMap = {\n [ObjectType.ARROW]: renderArrow,\n [ObjectType.CIRCLE]: renderCircle,\n [ObjectType.GROUP]: renderGroup,\n [ObjectType.IMAGE]: renderImage,\n [ObjectType.LINE]: renderLine,\n [ObjectType.MASK]: renderMask,\n [ObjectType.PATH]: renderPath,\n [ObjectType.POLYGON]: renderPolygon,\n [ObjectType.RECTANGLE]: renderRectangle,\n [ObjectType.SLIDE_OBJECT]: () => {},\n [ObjectType.SPOTLIGHT]: renderSpotlight,\n [ObjectType.SVG]: renderSvg,\n [ObjectType.TEXT]: renderText,\n};\n","import { Size } from \"../../../../types/Size\";\n\n/**\n * Extra elements are treated as foreignObjects in an SVG container element.\n * This function creates the extras container SVG element to host the slide extras.\n */\nexport function createExtrasElement(size: Size): SVGSVGElement {\n const extrasElement = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n extrasElement.setAttribute(\"viewBox\", `0 0 ${size.width} ${size.height}`);\n extrasElement.style.backgroundColor = \"transparent\";\n extrasElement.style.position = \"absolute\";\n extrasElement.style.width = \"100%\";\n\n return extrasElement;\n}\n","import { Position } from \"../../../../types/Position\";\nimport { Size } from \"../../../../types/Size\";\nimport { SlideWebExtra } from \"../../../../types/SlideWebExtra\";\nimport { getBoundingBox } from \"../../../../utils/layout/getBoundingBox\";\n\nexport function mountWebExtra(\n container: SVGSVGElement | null,\n extra: SlideWebExtra,\n): (() => void) | null {\n if (container === null) {\n return null;\n }\n\n const boundingBox = getBoundingBox(\n Position({ x: extra.x, y: extra.y }),\n extra.anchor,\n Size({ width: extra.width, height: extra.height }),\n );\n\n const foreignObject = document.createElementNS(\"http://www.w3.org/2000/svg\", \"foreignObject\");\n foreignObject.setAttribute(\"x\", boundingBox.origin.x.toString());\n foreignObject.setAttribute(\"y\", boundingBox.origin.y.toString());\n foreignObject.setAttribute(\"width\", extra.width.toString());\n foreignObject.setAttribute(\"height\", extra.height.toString());\n\n const extraElement = extra.content;\n if (extraElement !== null) {\n foreignObject.appendChild(extraElement);\n }\n\n container.appendChild(foreignObject);\n\n let cleanup: (() => void) | null = null;\n if (extra.setup !== null) {\n const cleanupResult = extra.setup(foreignObject);\n if (cleanupResult !== undefined) {\n cleanup = cleanupResult;\n }\n }\n\n // Return cleanup function\n return () => {\n if (cleanup !== null) {\n cleanup();\n }\n container.removeChild(foreignObject);\n };\n}\n","import { ImageType, UnifiedImage } from \"../types/UnifiedImage\";\n\nexport async function loadPresentationImages(\n imagePathById: Record<string, string>,\n): Promise<Record<string, UnifiedImage>> {\n if (Object.keys(imagePathById).length === 0) {\n return {};\n }\n\n const imageById: Record<string, UnifiedImage> = {};\n\n const loadImage = (src: string): Promise<HTMLImageElement> => {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (err) => reject(err);\n\n // Handle SVGs that aren't already in URL form\n const isRawSVG = src.includes(\"</svg>\");\n if (isRawSVG) {\n // Remove XML header tag, can cause parsing to fail and isn't necessary for SVG rendering\n const sanitized = src.replace(/<\\?xml[^?]*\\?>\\s*/g, \"\");\n\n const svgBlob = new Blob([sanitized], { type: \"image/svg+xml;charset=utf-8\" });\n const url = URL.createObjectURL(svgBlob);\n img.src = url;\n } else {\n img.src = src;\n }\n });\n };\n\n const loadPromises = Object.entries(imagePathById).map(async ([id, path]) => {\n const img = await loadImage(path);\n imageById[id] = {\n type: ImageType.Browser,\n image: img,\n };\n });\n\n try {\n await Promise.all(loadPromises);\n } catch (error) {\n console.error(\"Error loading images:\", error);\n }\n\n return imageById;\n}\n","// New variable values to use on next reload\nconst PENDING_VARIABLE_STORAGE_KEY_PREFIX = \"presenterPendingVariables:\";\n\ninterface StoredPendingVariableValues {\n readonly values: Record<string, number>;\n}\n\nexport function loadPendingVariableValues(): Record<string, number> {\n const storage = getStorage();\n if (storage === null) {\n return {};\n }\n\n try {\n const storageKey = getPendingVariableStorageKey();\n const storedState = storage.getItem(storageKey);\n storage.removeItem(storageKey);\n\n if (storedState === null) {\n return {};\n }\n\n const parsedState = JSON.parse(storedState) as Partial<StoredPendingVariableValues>;\n if (parsedState.values === undefined || typeof parsedState.values !== \"object\") {\n return {};\n }\n\n const values: Record<string, number> = {};\n for (const [id, value] of Object.entries(parsedState.values)) {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n values[id] = value;\n }\n }\n\n return values;\n } catch (error) {\n console.error(\"Failed to parse pending presenter variable state from sessionStorage:\", error);\n storage.removeItem(getPendingVariableStorageKey());\n return {};\n }\n}\n\nexport function storePendingVariableValues(values: Record<string, number>): void {\n const storage = getStorage();\n if (storage === null) {\n return;\n }\n\n storage.setItem(getPendingVariableStorageKey(), JSON.stringify({ values }));\n}\n\nfunction getPendingVariableStorageKey(): string {\n if (typeof window === \"undefined\") {\n return PENDING_VARIABLE_STORAGE_KEY_PREFIX;\n }\n\n return `${PENDING_VARIABLE_STORAGE_KEY_PREFIX}${window.location.origin}${window.location.pathname}`;\n}\n\nfunction getStorage(): Storage | null {\n try {\n return typeof sessionStorage === \"undefined\" ? null : sessionStorage;\n } catch {\n return null;\n }\n}\n","import { loadPendingVariableValues } from \"../utils/storage/variableStorage\";\n\nexport interface VariableProps {\n readonly name?: string;\n readonly min?: number;\n readonly max?: number;\n readonly default?: number;\n readonly increment?: number;\n}\n\nexport interface VariableDefinition {\n readonly id: string;\n readonly name: string;\n readonly min: number;\n readonly max: number;\n readonly default: number;\n readonly increment: number;\n}\n\nconst DEFAULT_VARIABLE_MIN = 0;\nconst DEFAULT_VARIABLE_MAX = 1;\nconst DEFAULT_VARIABLE_DEFAULT = 0;\nconst DEFAULT_VARIABLE_INCREMENT = 0.01;\n\nconst definitionsById = new Map<string, VariableDefinition>();\n\nlet variableValuesById = new Map<string, number>();\nlet didLoadPendingValues = false;\nlet nextVariableIndex = 1;\n\nexport function Variable(props: VariableProps | null = null): number {\n loadPendingValues();\n\n const options = props ?? {};\n const id = getNextVariableId();\n const definition = createDefinition(id, options);\n const activeValue = variableValuesById.get(definition.id);\n\n if (activeValue !== undefined) {\n const clampedValue = clampValue(activeValue, definition);\n variableValuesById.set(definition.id, clampedValue);\n return clampedValue;\n }\n\n return definition.default;\n}\n\nexport function getRegisteredVariables(): VariableDefinition[] {\n return Array.from(definitionsById.values());\n}\n\nexport function getVariableValue(id: string): number {\n const definition = definitionsById.get(id);\n if (definition === undefined) {\n return DEFAULT_VARIABLE_DEFAULT;\n }\n\n return variableValuesById.get(definition.id) ?? definition.default;\n}\n\nexport function setVariableValue(id: string, value: number): number {\n const definition = definitionsById.get(id);\n if (definition === undefined) {\n return value;\n }\n\n const nextValue = clampValue(value, definition);\n variableValuesById.set(definition.id, nextValue);\n return nextValue;\n}\n\nfunction createDefinition(id: string, props: VariableProps): VariableDefinition {\n const min = props.min ?? DEFAULT_VARIABLE_MIN;\n const max = props.max ?? DEFAULT_VARIABLE_MAX;\n const normalizedMin = Math.min(min, max);\n const normalizedMax = Math.max(min, max);\n const increment =\n props.increment !== undefined && props.increment > 0\n ? props.increment\n : DEFAULT_VARIABLE_INCREMENT;\n\n const definition: VariableDefinition = {\n id,\n name: props.name ?? id,\n min: normalizedMin,\n max: normalizedMax,\n default: clampNumber(props.default ?? DEFAULT_VARIABLE_DEFAULT, normalizedMin, normalizedMax),\n increment,\n };\n definitionsById.set(id, definition);\n\n return definition;\n}\n\nfunction getNextVariableId(): string {\n const id = `var${nextVariableIndex}`;\n nextVariableIndex += 1;\n return id;\n}\n\nfunction loadPendingValues(): void {\n if (didLoadPendingValues) {\n return;\n }\n\n // Slider edits need to survive the reload that re-evaluates slide modules, but\n // should not become stale state that follows later code changes.\n variableValuesById = new Map(Object.entries(loadPendingVariableValues()));\n didLoadPendingValues = true;\n}\n\nfunction clampValue(value: number, definition: VariableDefinition): number {\n return clampNumber(value, definition.min, definition.max);\n}\n\nfunction clampNumber(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n","import {\n getRegisteredVariables,\n getVariableValue,\n VariableDefinition,\n} from \"../../../../types/Variable\";\n\ninterface Args {\n readonly onCommit: () => void;\n readonly onPreview: (id: string, value: number) => number;\n}\n\nexport function createVariableControlsElement({\n onCommit,\n onPreview,\n}: Args): HTMLDivElement | null {\n const variables = getRegisteredVariables();\n if (variables.length === 0) {\n return null;\n }\n\n const container = document.createElement(\"div\");\n Object.assign(container.style, {\n position: \"absolute\",\n right: \"16px\",\n bottom: \"16px\",\n zIndex: \"20\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"8px\",\n width: \"min(360px, calc(100% - 32px))\",\n padding: \"10px\",\n boxSizing: \"border-box\",\n border: \"1px solid rgba(255, 255, 255, 0.18)\",\n borderRadius: \"8px\",\n background: \"rgba(16, 18, 22, 0.82)\",\n color: \"#ffffff\",\n fontFamily:\n 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n fontSize: \"12px\",\n lineHeight: \"1.25\",\n pointerEvents: \"auto\",\n boxShadow: \"0 12px 36px rgba(0, 0, 0, 0.28)\",\n backdropFilter: \"blur(10px)\",\n });\n\n for (const variable of variables) {\n container.appendChild(createVariableControl(variable, onPreview, onCommit));\n }\n\n return container;\n}\n\nfunction createVariableControl(\n variable: VariableDefinition,\n onPreview: (id: string, value: number) => number,\n onCommit: () => void,\n): HTMLDivElement {\n const row = document.createElement(\"div\");\n row.dataset.presenterVariableId = variable.id;\n row.dataset.presenterVariableName = variable.name;\n Object.assign(row.style, {\n display: \"grid\",\n gridTemplateColumns: \"72px minmax(0, 1fr) 74px\",\n alignItems: \"center\",\n gap: \"8px\",\n });\n\n const name = document.createElement(\"div\");\n name.textContent = variable.name;\n name.title = variable.name;\n Object.assign(name.style, {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n color: \"rgba(255, 255, 255, 0.86)\",\n fontWeight: \"600\",\n });\n\n const slider = document.createElement(\"input\");\n slider.type = \"range\";\n slider.min = variable.min.toString();\n slider.max = variable.max.toString();\n slider.step = variable.increment.toString();\n Object.assign(slider.style, {\n width: \"100%\",\n minWidth: \"0\",\n accentColor: \"#8bc7ff\",\n });\n\n const input = document.createElement(\"input\");\n input.type = \"number\";\n input.min = variable.min.toString();\n input.max = variable.max.toString();\n input.step = variable.increment.toString();\n Object.assign(input.style, {\n width: \"100%\",\n boxSizing: \"border-box\",\n border: \"1px solid rgba(255, 255, 255, 0.24)\",\n borderRadius: \"6px\",\n padding: \"4px 6px\",\n background: \"rgba(255, 255, 255, 0.1)\",\n color: \"#ffffff\",\n font: \"inherit\",\n });\n\n let currentValue = getVariableValue(variable.id);\n\n const updateInputs = (value: number) => {\n const formattedValue = formatVariableValue(value);\n slider.value = formattedValue;\n input.value = formattedValue;\n };\n\n const previewValue = (value: number) => {\n if (!Number.isFinite(value)) {\n return;\n }\n\n currentValue = onPreview(variable.id, value);\n updateInputs(currentValue);\n };\n\n const commitValue = (value: number) => {\n if (!Number.isFinite(value)) {\n return;\n }\n\n if (value !== currentValue) {\n previewValue(value);\n }\n onCommit();\n };\n\n // Sliders emit `input` continuously while dragging. We preview those values in\n // storage, then wait for `change` so the page reload happens after release.\n slider.addEventListener(\"input\", () => previewValue(slider.valueAsNumber));\n slider.addEventListener(\"change\", () => commitValue(slider.valueAsNumber));\n input.addEventListener(\"change\", () => commitValue(input.valueAsNumber));\n\n updateInputs(currentValue);\n\n row.appendChild(name);\n row.appendChild(slider);\n row.appendChild(input);\n\n return row;\n}\n\nfunction formatVariableValue(value: number): string {\n return Number.isInteger(value) ? value.toString() : parseFloat(value.toFixed(6)).toString();\n}\n","import {\n getRegisteredVariables,\n getVariableValue,\n setVariableValue,\n} from \"../../../../types/Variable\";\nimport { storePendingVariableValues } from \"../../../../utils/storage/variableStorage\";\nimport { createVariableControlsElement } from \"./createVariableControlsElement\";\n\ninterface Args {\n readonly container: HTMLElement;\n readonly onCommit: () => void;\n}\n\nexport function mountVariableControls({ container, onCommit }: Args): void {\n const variablesContainer = createVariableControlsElement({\n onPreview: (id, value) => {\n const nextValue = setVariableValue(id, value);\n storePendingVariableValues(getCurrentVariableValues());\n return nextValue;\n },\n onCommit,\n });\n\n if (variablesContainer !== null) {\n container.appendChild(variablesContainer);\n }\n}\n\nfunction getCurrentVariableValues(): Record<string, number> {\n const values: Record<string, number> = {};\n\n for (const variable of getRegisteredVariables()) {\n values[variable.id] = getVariableValue(variable.id);\n }\n\n return values;\n}\n","import { shouldRestoreNavigatorAfterHotReload } from \"../../navigator/navigatorHotReload\";\nimport { NavigatorApi, openNavigator } from \"../../navigator/openNavigator\";\nimport { Presentation } from \"../../types/Presentation\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { getSlideAnimationDuration } from \"../../utils/animate/getSlideAnimationDuration\";\nimport { getRgbStringForColor } from \"../../utils/color/getRgbStringForColor\";\nimport { createPresentationContainer } from \"../../utils/presentation/createPresentationContainer\";\nimport { getImagePathUrlById } from \"../../utils/presentation/getImagePathUrlById\";\nimport { getObjectState } from \"../../utils/presentation/getObjectState\";\nimport { getSvgImageUrlById } from \"../../utils/presentation/getSvgImageUrlById\";\nimport { isFullBodyPresentation } from \"../../utils/presentation/isFullBodyPresentation\";\nimport { setupKeyEventListeners } from \"../../utils/presentation/setupKeyEventListeners\";\nimport { loadPresentationState } from \"../../utils/storage/loadPresentationState\";\nimport { storePresentationState } from \"../../utils/storage/storePresentationState\";\nimport { BrowserCanvasRendererProps } from \"./types/BrowserCanvasRendererProps\";\nimport {\n BROWSER_CANVAS_RENDERER_DEFAULT_STATE,\n BrowserCanvasRendererState,\n} from \"./types/BrowserCanvasRendererState\";\nimport { CanvasContextType, UnifiedCanvasContext } from \"./types/UnifiedCanvasContext\";\nimport {\n createAccessibleDescriptionElement,\n getAccessibleDescription,\n updateAccessibleDescription,\n} from \"./utils/accessibility/accessibleDescription\";\nimport { clearCanvas } from \"./utils/clearCanvas\";\nimport { createCanvasElement } from \"./utils/createCanvasElement\";\nimport { createPath2D } from \"./utils/createPath2D\";\nimport { DEFAULT_OBJECT_RENDERERS } from \"./utils/defaultObjectRenderers\";\nimport { createExtrasElement } from \"./utils/extras/createExtrasElement\";\nimport { mountWebExtra } from \"./utils/extras/mountWebExtra\";\nimport { loadPresentationImages } from \"./utils/loadPresentationImages\";\nimport { mountVariableControls } from \"./utils/variables/mountVariableControls\";\n\nexport class BrowserCanvasRenderer {\n props: BrowserCanvasRendererProps;\n state: BrowserCanvasRendererState;\n navigator: NavigatorApi | null = null;\n\n constructor(props: Partial<BrowserCanvasRendererProps>) {\n const { objectRenderers, scale = 1, ...rest } = props;\n this.props = {\n presentation: Presentation(),\n element: document.body,\n objectRenderers: {\n ...DEFAULT_OBJECT_RENDERERS,\n ...objectRenderers,\n },\n cacheDurationMinutes: 15,\n scale: getValidScale(scale),\n ...rest,\n };\n this.state = { ...BROWSER_CANVAS_RENDERER_DEFAULT_STATE };\n }\n\n /** Starts the presentation. */\n async present(): Promise<void> {\n const { presentation, element, scale } = this.props;\n this.hideCursor();\n\n const accessibleDescriptionElement = createAccessibleDescriptionElement(presentation.title);\n const canvas = createCanvasElement(presentation.size);\n const extrasContainer = createExtrasElement(presentation.size);\n extrasContainer.style.transformOrigin = \"center center\";\n extrasContainer.style.transform = `scale(${scale})`;\n\n this.state = {\n ...BROWSER_CANVAS_RENDERER_DEFAULT_STATE,\n accessibleDescriptionElement,\n imageById: await loadPresentationImages({\n ...getImagePathUrlById(presentation),\n ...presentation.resources.images,\n ...getSvgImageUrlById(presentation),\n }),\n canvas,\n extrasContainer,\n };\n\n const container = createPresentationContainer(presentation, element);\n const isFullBody = isFullBodyPresentation(element);\n const renderSlideFromShortcut = (slideIndex: number | null, buildIndex: number) => {\n // Set up a shortcut for going back to this slide/build\n this.state.shortcutState.shortcuts.b = {\n slideIndex: this.state.slideIndex,\n buildIndex: this.state.buildIndex,\n };\n\n this.renderSlide(slideIndex ?? this.state.slideIndex, buildIndex);\n };\n\n const showNavigator = (forceRefresh: boolean = false) => {\n if (!isFullBody) {\n return;\n }\n\n this.navigator = openNavigator({\n presentation,\n shortcutState: this.state.shortcutState,\n onNavigateToSlide: (slideIndex) => this.renderSlide(slideIndex),\n onRenderSlide: renderSlideFromShortcut,\n onNext: (skipIntermediateBuilds) => this.next(skipIntermediateBuilds),\n onPrevious: (skipIntermediateBuilds) => this.previous(skipIntermediateBuilds),\n forceRefresh,\n });\n this.updateNavigator();\n };\n\n setupKeyEventListeners(\n presentation,\n container,\n this.state.shortcutState,\n {\n onNext: (skipIntermediateBuilds: boolean) => this.next(skipIntermediateBuilds),\n onPrevious: (skipIntermediateBuilds: boolean) => this.previous(skipIntermediateBuilds),\n onRenderSlide: renderSlideFromShortcut,\n onShowNavigator: () => showNavigator(),\n },\n {\n focusOnPointerDown: !isFullBody,\n keyEventTarget: isFullBody ? window : container,\n },\n );\n\n element.replaceChildren();\n container.appendChild(accessibleDescriptionElement);\n container.appendChild(canvas);\n container.appendChild(extrasContainer);\n mountVariableControls({\n container,\n onCommit: () => this.reloadAfterVariableChange(),\n });\n element.appendChild(container);\n\n const loadedState = loadPresentationState(presentation, this.props.cacheDurationMinutes);\n if (loadedState !== null) {\n this.renderSlide(loadedState.slideIndex, loadedState.buildIndex);\n } else {\n this.renderSlide(0);\n }\n\n if (shouldRestoreNavigatorAfterHotReload()) {\n showNavigator(true);\n }\n }\n\n private reloadAfterVariableChange(): void {\n const { presentation } = this.props;\n\n if (this.state.currentAnimationId !== null) {\n cancelAnimationFrame(this.state.currentAnimationId);\n this.state.currentAnimationId = null;\n }\n\n storePresentationState({\n title: presentation.title,\n slideIndex: this.state.slideIndex,\n buildIndex: this.state.buildIndex,\n });\n window.location.reload();\n }\n\n renderSlide(slideIndex: number, buildIndex: number = 0, buildTime: number | null = null): void {\n const { presentation } = this.props;\n const { canvas } = this.state;\n\n const didSlideIndexChange = this.state.slideIndex !== slideIndex;\n this.state.slideIndex = slideIndex;\n this.state.buildIndex = buildIndex;\n\n // Store state in local storage\n if (buildTime === null) {\n storePresentationState({ title: presentation.title, slideIndex, buildIndex });\n }\n\n const slide = presentation.slides[slideIndex];\n if (slide === undefined || canvas === null) {\n return;\n }\n\n // Handle mounting/unmounting web extras when slide index changes.\n // Also handle it if there are no mounted extras but the slide has extras to mount\n // (e.g. on a presentation's first slide, where slide index will have stayed 0).\n if (\n didSlideIndexChange ||\n (this.state.mountedExtrasCleanups.length === 0 && slide.extras.length > 0)\n ) {\n // Clean up any existing extras\n for (const cleanup of this.state.mountedExtrasCleanups) {\n cleanup();\n }\n this.state.mountedExtrasCleanups = [];\n\n // Mount new extras\n for (const extra of slide.extras) {\n const cleanup = mountWebExtra(this.state.extrasContainer, extra);\n if (cleanup !== null) {\n this.state.mountedExtrasCleanups.push(cleanup);\n }\n }\n }\n\n this.renderCanvas(canvas, slideIndex, buildIndex, buildTime, this.props.scale);\n\n if (buildTime === null) {\n if (this.state.accessibleDescriptionElement !== null) {\n const objectState = getObjectState({ slide, buildIndex, buildTime });\n updateAccessibleDescription(\n this.state.accessibleDescriptionElement,\n getAccessibleDescription(slide, objectState),\n );\n }\n this.updateNavigator();\n }\n }\n\n renderCanvas(\n canvas: HTMLCanvasElement,\n slideIndex: number,\n buildIndex: number = 0,\n buildTime: number | null = null,\n scale: number = 1,\n ): void {\n const { objectRenderers, presentation } = this.props;\n const { imageById } = this.state;\n\n canvas.width = presentation.size.width;\n canvas.height = presentation.size.height;\n\n const ctx = canvas.getContext(\"2d\");\n if (ctx === null) {\n return;\n }\n\n const context: UnifiedCanvasContext = {\n type: CanvasContextType.Browser,\n context: ctx,\n };\n\n clearCanvas(canvas, context);\n\n const slide = presentation.slides[slideIndex];\n if (slide === undefined) {\n return;\n }\n\n const objectState = getObjectState({\n slide,\n buildIndex,\n buildTime,\n });\n\n // Render background color.\n context.context.fillStyle = getRgbStringForColor(presentation.backgroundColor);\n context.context.fillRect(0, 0, canvas.width, canvas.height);\n\n function renderObject(\n object: SlideObject,\n opacity: number,\n targetContext: UnifiedCanvasContext = context,\n ) {\n const objectRenderer = objectRenderers[object.objectType];\n const currentObject = objectState.get(object);\n if (objectRenderer === undefined || currentObject === undefined) {\n return;\n }\n objectRenderer({\n ctx: targetContext,\n originalObject: object,\n imageById,\n object: currentObject,\n opacity,\n renderScale: scale,\n renderObject: (childObject, childOpacity, childContext = targetContext) =>\n renderObject(childObject, childOpacity, childContext),\n getCurrentObject: <TObject extends SlideObject>(object: TObject) =>\n objectState.get(object) as TObject | undefined,\n createPath2D,\n slideSize: presentation.size,\n });\n }\n\n const needsScaleTransformation = scale !== 1;\n if (needsScaleTransformation) {\n context.context.save();\n context.context.translate(\n (canvas.width * (1 - scale)) / 2,\n (canvas.height * (1 - scale)) / 2,\n );\n context.context.scale(scale, scale);\n }\n\n // Render all objects in the slide.\n for (const object of slide.objects) {\n renderObject(object, 1.0);\n }\n\n if (needsScaleTransformation) {\n context.context.restore();\n }\n }\n\n updateNavigator(): void {\n const { navigator } = this;\n if (navigator === null) {\n return;\n }\n if (!navigator.isOpen()) {\n this.navigator = null;\n return;\n }\n\n const { slideIndex, buildIndex } = this.state;\n const next = this.getNextSlideBuild(slideIndex, buildIndex);\n navigator.update(slideIndex, buildIndex, next.slideIndex, next.buildIndex);\n this.renderCanvas(navigator.currentCanvas, slideIndex, buildIndex);\n if (next.slideIndex === null) {\n this.renderEndCanvas(navigator.nextCanvas);\n } else {\n this.renderCanvas(navigator.nextCanvas, next.slideIndex, next.buildIndex);\n }\n }\n\n getNextSlideBuild(\n slideIndex: number,\n buildIndex: number,\n ): { slideIndex: number | null; buildIndex: number } {\n const { presentation } = this.props;\n const currentSlide = presentation.slides[slideIndex];\n if (currentSlide === undefined) {\n return { slideIndex, buildIndex };\n }\n if (buildIndex < currentSlide.animations.length) {\n return { slideIndex, buildIndex: buildIndex + 1 };\n }\n if (slideIndex + 1 < presentation.slides.length) {\n return { slideIndex: slideIndex + 1, buildIndex: 0 };\n }\n return { slideIndex: null, buildIndex: 0 };\n }\n\n renderEndCanvas(canvas: HTMLCanvasElement): void {\n const { presentation } = this.props;\n canvas.width = presentation.size.width;\n canvas.height = presentation.size.height;\n\n const ctx = canvas.getContext(\"2d\");\n if (ctx === null) {\n return;\n }\n\n ctx.fillStyle = \"#000000\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n\n next(skipIntermediateBuilds: boolean = false) {\n const { presentation } = this.props;\n const { currentAnimationId, slideIndex, buildIndex } = this.state;\n\n this.hideCursor();\n\n if (currentAnimationId !== null) {\n cancelAnimationFrame(currentAnimationId);\n }\n\n const currentSlide = presentation.slides[slideIndex];\n if (currentSlide === undefined) {\n return;\n }\n\n const nextAnimation = currentSlide.animations[buildIndex];\n\n if (nextAnimation !== undefined && !skipIntermediateBuilds) {\n const startTime = performance.now();\n const animationDuration = getSlideAnimationDuration(nextAnimation);\n\n const animate = (currentTime: number) => {\n const elapsed = currentTime - startTime;\n\n if (elapsed < animationDuration) {\n this.renderSlide(slideIndex, buildIndex + 1, elapsed);\n this.state.currentAnimationId = requestAnimationFrame(animate);\n } else {\n this.renderSlide(slideIndex, buildIndex + 1, null);\n }\n };\n\n this.state.currentAnimationId = requestAnimationFrame(animate);\n } else if (slideIndex + 1 < presentation.slides.length) {\n this.renderSlide(slideIndex + 1);\n }\n }\n\n previous(skipIntermediateBuilds: boolean = false) {\n const { currentAnimationId, slideIndex, buildIndex } = this.state;\n\n this.hideCursor();\n\n if (currentAnimationId !== null) {\n cancelAnimationFrame(currentAnimationId);\n }\n\n if (buildIndex > 0) {\n if (skipIntermediateBuilds) {\n this.renderSlide(slideIndex, 0);\n } else {\n this.renderSlide(slideIndex, buildIndex - 1);\n }\n } else if (slideIndex > 0) {\n const previousSlide = this.props.presentation.slides[slideIndex - 1];\n const buildIndex = skipIntermediateBuilds ? 0 : (previousSlide?.animations.length ?? 0);\n\n this.renderSlide(slideIndex - 1, buildIndex);\n } else {\n this.renderSlide(0, 0);\n }\n }\n\n hasNext(): boolean {\n const { presentation } = this.props;\n const { slideIndex, buildIndex } = this.state;\n\n const currentSlide = presentation.slides[slideIndex];\n if (currentSlide === undefined) {\n return false;\n }\n\n const nextAnimation = currentSlide.animations[buildIndex];\n if (nextAnimation !== undefined) {\n return true;\n } else if (slideIndex + 1 < presentation.slides.length) {\n return true;\n }\n\n return false;\n }\n\n hasPrevious(): boolean {\n const { slideIndex, buildIndex } = this.state;\n return buildIndex > 0 || slideIndex > 0;\n }\n\n hideCursor(): void {\n this.props.element.style.cursor = \"none\";\n this.state.canvas?.parentElement?.style.setProperty(\"cursor\", \"none\");\n }\n}\n\nfunction getValidScale(scale: number): number {\n if (scale <= 0 || scale > 1) {\n console.warn(\n `BrowserCanvasRenderer scale must be positive and no greater than 1. Received ${scale}; using 1 instead.`,\n );\n return 1;\n }\n\n return scale;\n}\n","import { Slide } from \"../../types/Slide\";\n\n/**\n * Slides can define which builds are considered \"key\", e.g. to indicate which builds should be included in exports.\n */\nexport function getKeySlideBuildIndices(slide: Slide): number[] {\n const buildIndices: number[] = [];\n\n // If every build is key, include all build indices\n if (slide.isAllKey) {\n for (let i = 0; i <= slide.animations.length; i++) {\n buildIndices.push(i);\n }\n return buildIndices;\n }\n\n // Slide can configure its own starting state to be key\n if (slide.isStartKey) {\n buildIndices.push(0);\n }\n\n // Check animations for key build indicators\n slide.animations.forEach((animation, animationIndex) => {\n if (Array.isArray(animation)) {\n if (animation.some((anim) => anim.isKey)) {\n buildIndices.push(animationIndex + 1);\n }\n } else {\n if (animation.isKey) {\n buildIndices.push(animationIndex + 1);\n }\n }\n });\n\n // Slide can configure its own ending state to be key\n if (slide.isEndKey && buildIndices[buildIndices.length - 1] !== slide.animations.length) {\n buildIndices.push(slide.animations.length);\n }\n\n return buildIndices;\n}\n","import { Presentation } from \"../../types/Presentation\";\nimport { getSlideAnimationDuration } from \"../../utils/animate/getSlideAnimationDuration\";\nimport { getKeySlideBuildIndices } from \"../../utils/slide/getKeySlideBuildIndices\";\n\nexport interface ImageExportFrame {\n readonly imageIndex: number;\n readonly slideIndex: number;\n readonly buildIndex: number;\n readonly buildTime: number | null;\n}\n\nexport interface GetImageExportFramesProps {\n readonly presentation: Presentation;\n readonly isAnimatedExport: boolean;\n readonly animationHoldFrames: number;\n readonly framesPerSecond: number;\n}\n\nexport function* getImageExportFrames({\n presentation,\n isAnimatedExport,\n animationHoldFrames,\n framesPerSecond,\n}: GetImageExportFramesProps): Generator<ImageExportFrame> {\n let imageIndex = 0;\n\n for (let slideIndex = 0; slideIndex < presentation.slides.length; slideIndex++) {\n const slide = presentation.slides[slideIndex];\n if (slide === undefined) {\n continue;\n }\n\n if (isAnimatedExport) {\n for (let i = 0; i < animationHoldFrames; i++) {\n yield { imageIndex: imageIndex++, slideIndex, buildIndex: 0, buildTime: null };\n }\n\n for (let animationIndex = 0; animationIndex < slide.animations.length; animationIndex++) {\n const animation = slide.animations[animationIndex];\n if (animation === undefined) {\n continue;\n }\n\n const durationMs = getSlideAnimationDuration(animation);\n const totalFrames = Math.ceil((durationMs / 1000) * framesPerSecond);\n\n for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {\n yield {\n imageIndex: imageIndex++,\n slideIndex,\n buildIndex: animationIndex + 1,\n buildTime: frameIndex * (durationMs / totalFrames),\n };\n }\n\n for (let i = 0; i < animationHoldFrames; i++) {\n yield {\n imageIndex: imageIndex++,\n slideIndex,\n buildIndex: animationIndex + 1,\n buildTime: null,\n };\n }\n }\n } else {\n const keyBuildIndices = getKeySlideBuildIndices(slide);\n for (const buildIndex of keyBuildIndices) {\n yield { imageIndex: imageIndex++, slideIndex, buildIndex, buildTime: null };\n }\n }\n }\n}\n","import { BrowserCanvasRenderer } from \"../../renderer/browser-canvas/BrowserCanvasRenderer\";\nimport { createCanvasElement } from \"../../renderer/browser-canvas/utils/createCanvasElement\";\nimport { loadPresentationImages } from \"../../renderer/browser-canvas/utils/loadPresentationImages\";\nimport { Presentation } from \"../../types/Presentation\";\nimport { getImagePathUrlById } from \"../../utils/presentation/getImagePathUrlById\";\nimport { getSvgImageUrlById } from \"../../utils/presentation/getSvgImageUrlById\";\nimport { getImageExportFrames, ImageExportFrame } from \"../utils/getImageExportFrames\";\nimport {\n BrowserImageFormat,\n BrowserImageRendererImage,\n BrowserImageRendererProps,\n} from \"./types/BrowserImageRendererProps\";\n\nexport class BrowserImageRenderer {\n props: BrowserImageRendererProps;\n\n constructor(props: Partial<BrowserImageRendererProps>) {\n const { imageFormat = \"png\", ...rest } = props;\n this.props = {\n presentation: Presentation(),\n imageFormat,\n imageQuality: undefined,\n animationHoldFrames: 1,\n framesPerSecond: 30,\n isAnimatedExport: false,\n getFilenameForImage: (imageIndex: number) =>\n `${imageIndex.toString().padStart(4, \"0\")}.${imageFormat}`,\n logFrequency: 0,\n objectRenderers: {},\n onRenderImage: () => undefined,\n renderScale: 1,\n resourcePathPrefix: \"\",\n waitForFonts: true,\n ...rest,\n };\n }\n\n async render(startImageIndex: number = 0): Promise<void> {\n assertBrowserEnvironment();\n\n const { presentation } = this.props;\n const imageById = await loadPresentationImages(\n prefixImagePaths(\n {\n ...getImagePathUrlById(presentation),\n ...presentation.resources.images,\n ...getSvgImageUrlById(presentation),\n },\n this.props.resourcePathPrefix,\n ),\n );\n\n if (this.props.waitForFonts) {\n await document.fonts.ready;\n }\n\n const canvas = createCanvasElement(presentation.size);\n const renderer = new BrowserCanvasRenderer({\n presentation,\n objectRenderers: this.props.objectRenderers,\n scale: this.props.renderScale,\n element: document.createElement(\"div\"),\n });\n renderer.state = {\n ...renderer.state,\n imageById,\n };\n\n for (const frame of getImageExportFrames(this.props)) {\n if (frame.imageIndex < startImageIndex) {\n continue;\n }\n\n await this.renderFrame(renderer, canvas, frame);\n }\n }\n\n private async renderFrame(\n renderer: BrowserCanvasRenderer,\n canvas: HTMLCanvasElement,\n frame: ImageExportFrame,\n ): Promise<void> {\n const { getFilenameForImage, imageFormat, imageQuality, logFrequency, onRenderImage } =\n this.props;\n\n renderer.renderCanvas(\n canvas,\n frame.slideIndex,\n frame.buildIndex,\n frame.buildTime,\n this.props.renderScale,\n );\n\n const blob = await canvasToBlob(canvas, getImageMimeType(imageFormat), imageQuality);\n const filename = getFilenameForImage(frame.imageIndex);\n const image: BrowserImageRendererImage = {\n ...frame,\n blob,\n filename,\n };\n\n await onRenderImage(image);\n if (logFrequency > 0 && frame.imageIndex % logFrequency === 0) {\n console.log(`Rendered image ${frame.imageIndex}: ${filename}`);\n }\n }\n}\n\nfunction canvasToBlob(\n canvas: HTMLCanvasElement,\n imageType: string,\n quality: number | undefined,\n): Promise<Blob> {\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (blob === null) {\n reject(new Error(\"Unable to encode browser image export frame.\"));\n return;\n }\n resolve(blob);\n },\n imageType,\n quality,\n );\n });\n}\n\nfunction getImageMimeType(imageFormat: BrowserImageFormat): string {\n switch (imageFormat) {\n case \"jpeg\":\n return \"image/jpeg\";\n case \"webp\":\n return \"image/webp\";\n case \"png\":\n return \"image/png\";\n }\n}\n\nfunction prefixImagePaths(\n imagePathById: Record<string, string>,\n resourcePathPrefix: string,\n): Record<string, string> {\n if (resourcePathPrefix === \"\") {\n return imagePathById;\n }\n\n const prefixedImagePathById: Record<string, string> = {};\n for (const [id, imagePath] of Object.entries(imagePathById)) {\n prefixedImagePathById[id] = shouldPrefixImagePath(imagePath)\n ? joinUrlPath(resourcePathPrefix, imagePath)\n : imagePath;\n }\n return prefixedImagePathById;\n}\n\nfunction shouldPrefixImagePath(imagePath: string): boolean {\n return (\n !imagePath.includes(\"</svg>\") &&\n !imagePath.startsWith(\"/\") &&\n !imagePath.startsWith(\"data:\") &&\n !imagePath.startsWith(\"blob:\") &&\n !/^[a-z][a-z0-9+.-]*:\\/\\//i.test(imagePath)\n );\n}\n\nfunction joinUrlPath(prefix: string, imagePath: string): string {\n return `${prefix.replace(/\\/$/, \"\")}/${imagePath.replace(/^\\//, \"\")}`;\n}\n\nfunction assertBrowserEnvironment(): void {\n if (typeof document === \"undefined\") {\n throw new Error(\"BrowserImageRenderer must run in a browser environment.\");\n }\n}\n"],"names":["NAVIGATOR_STATE_SESSION_KEY","DEFAULT_NAVIGATOR_STATE","isNavigatorHotReloadEnabled","script","shouldRestoreNavigatorAfterHotReload","loadNavigatorStateForHotReload","markNavigatorOpenForHotReload","saveNavigatorStateForHotReload","markNavigatorClosedForHotReload","_a","getSessionStorage","_b","_c","_d","_e","storedState","state","Slide","props","hasModifierKey","event","isInteractiveElement","target","element","tagName","getPresentationShortcuts","presentation","slides","shortcuts","slideIndex","slide","shortcut","addShortcut","animationIndex","animation","anim","buildIndex","key","resolvePresentationShortcutCommand","command","shortcutConfig","setupKeyEventListeners","shortcutState","onNext","onPrevious","onRenderSlide","onShowNavigator","focusOnPointerDown","keyEventTarget","signal","listenerOptions","keyEvent","altCommand","getAltShortcutCommand","getSpeakerNotes","currentBuildIndex","notes","getSpeakerNotesForBuild","getAnimationNotes","navigatorWindow","navigatorApi","navigatorCleanup","NAVIGATOR_INSTANCE_ID_KEY","navigatorWindowBounds","openNavigator","onNavigateToSlide","forceRefresh","saveNavigatorWindowBounds","getNavigatorWindowFeatures","navigatorInstance","createNavigatorInstance","abortController","elementApi","createNavigatorElement","skipIntermediateBuilds","closeNavigatorWindow","isActive","doc","navigatorElement","slideList","previewColumn","controls","previewGrid","currentPreview","createPreviewElement","nextPreview","notesPanel","createNotesElement","navigatorState","slideElements","index","slideElement","createSlideElement","slidesToggle","createToggleElement","currentToggle","nextToggle","notesToggle","updateLayout","shouldStackPreviews","isNarrowPreviewLayout","update","nextSlideIndex","nextBuildIndex","getBuildLabel","scrollSlideIntoView","win","slideListWidth","availableWidth","availableHeight","container","title","content","countElement","titleElement","label","frame","canvas","resize","frameWidth","frameHeight","aspectRatio","width","height","ResizeObserverCtor","checked","visibleDisplay","toggle","checkbox","slideTop","slideBottom","listTop","listBottom","left","top","instanceId","instanceWindow","Color","color","green","blue","alpha","hexString","hex","DEFAULT_COLOR","Size","DEFAULT_SIZE","Presentation","AnimationType","assertNever","value","message","getSlideAnimationDuration","slideAnimation","animations","startTime","duration","getAlphaForColor","opacity","getRgbStringForColor","red","isFullBodyPresentation","createPresentationContainer","root","targetAspectRatio","updateContainerSize","getObjectChildren","object","children","childContainers","getSlideObjects","objects","getImagePathUrlById","imageUrls","addImagePath","imagePath","walkSlideObject","imageObject","child","interpolateColor","from","to","proportion","interpolateFallback","_value","_from","interpolateNumber","DEFAULT_INTERPOLATORS","interpolate","customInterpolators","interpolators","interpolatedProps","fromValue","toValue","interpolator","updateObjectStateWithAnimation","objectState","buildTime","elapsedTime","currentObject","timeIntoAnimation","getObjectState","addObjectToState","childObject","completedBuildCount","i","ObjectType","getSvgImageUrlById","svgStrings","svg","LOCAL_STORAGE_KEY","loadPresentationState","ttlMinutes","data","error","timestamp","storePresentationState","BROWSER_CANVAS_RENDERER_DEFAULT_STATE","CanvasContextType","getTextUnitsFromTextContent","text","line","unit","createAccessibleDescriptionElement","presentationTitle","getAccessibleDescription","descriptions","addObjectDescriptions","parentOpacity","effectiveOpacity","isVisible","description","getObjectDescription","isTextObject","getTextDescription","remainingLength","visibleText","updateAccessibleDescription","clearCanvas","ctx","createCanvasElement","size","Path2DType","createPath2D","pathData","path","getArrowPoints","arrow","drawn","startX","startY","endX","endY","arrowheadSize","isArrowheadFilled","isDrawnFromCenter","start","end","angle","midpoint","dx","dy","drawnLength","unitX","unitY","drawnStart","drawnEnd","arrowAngle","adjustedArrowheadSize","arrowheadBase1","arrowheadBase2","doubledArrowheadBase1","doubledArrowheadBase2","getHexStringForColor","alphaHex","drawStroke","isRounded","pathLength","fullPathLength","gapLength","fillPath","getPathFromPositions","positions","createPath","firstPosition","length","position","prevPosition","renderArrow","targetOpacity","arrowPoints","arrowheadPoints","doubledArrowheadPoints","arrowPath","arrowheadPath","doubledArrowheadPath","getCircleInsetFillPath","circle","insetRadius","startAngle","getCirclePath","clipToPath","renderCircle","insetFillPath","Position","DEFAULT_POSITION","Anchor","BoundingBox","getBoundingBox","anchor","x","y","renderGroup","group","renderObject","scaleX","scaleY","boundingBox","rotation","rotateOriginX","rotateOriginY","skewOriginX","skewOriginY","skewX","skewY","getRoundedRectanglePath","origin","cornerRadius","overshoot","ImageType","renderImage","imageById","image","imageId","imageData","roundedRectPath","getLinePath","renderLine","renderMask","mask","bbox","renderPath","path2D","getPolygonPath","polygon","points","firstPoint","previousPoint","point","segmentLength","closingSegmentLength","renderPolygon","getRectangleInsetFillPath","rectangle","inset","insetWidth","insetHeight","insetOrigin","insetSize","getRectanglePath","renderRectangle","getSpotlightCutout","spotlight","getSpotlightPath","slideSize","bounds","boundsOrigin","boundsSize","renderSpotlight","renderScale","overlaySize","overlayOrigin","renderSvg","Alignment","getTextStyleFromText","getLineLayout","lineMeasurements","bottom","acc","curr","getTextLayout","lineSpacing","lines","baselineY","previousLineBoxBottom","layoutTop","layoutBottom","baselines","halfLeading","lineBoxTop","baselineOffset","baseline","SCRIPT_FONT_SIZE_SCALE","SCRIPT_BASELINE_SHIFT_SCALE","getTextScriptVariant","textStyle","isSuperscript","isSubscript","getMetricValue","fallback","getSizeFromTextMetrics","textMetrics","setContextWithTextStyle","scriptVariant","getTextUnitMeasurements","textUnits","style","sizes","lineSizes","measurementUnits","unitStyle","combinedStyle","metrics","baselineShift","renderText","layout","consumedLength","lineIndex","lineWidth","unitIndex","unitSize","unitText","truncatedUnitText","targetUnitText","DEFAULT_OBJECT_RENDERERS","createExtrasElement","extrasElement","mountWebExtra","extra","foreignObject","extraElement","cleanup","cleanupResult","loadPresentationImages","imagePathById","loadImage","src","resolve","reject","img","err","sanitized","svgBlob","url","loadPromises","id","PENDING_VARIABLE_STORAGE_KEY_PREFIX","storePendingVariableValues","values","storage","getStorage","getPendingVariableStorageKey","DEFAULT_VARIABLE_DEFAULT","definitionsById","variableValuesById","getRegisteredVariables","getVariableValue","definition","setVariableValue","nextValue","clampValue","clampNumber","min","max","createVariableControlsElement","onCommit","onPreview","variables","variable","createVariableControl","row","name","slider","input","currentValue","updateInputs","formattedValue","formatVariableValue","previewValue","commitValue","mountVariableControls","variablesContainer","getCurrentVariableValues","BrowserCanvasRenderer","objectRenderers","scale","rest","getValidScale","accessibleDescriptionElement","extrasContainer","isFullBody","renderSlideFromShortcut","showNavigator","loadedState","didSlideIndexChange","context","targetContext","objectRenderer","childOpacity","childContext","needsScaleTransformation","navigator","next","currentSlide","currentAnimationId","nextAnimation","animationDuration","animate","currentTime","elapsed","previousSlide","getKeySlideBuildIndices","buildIndices","getImageExportFrames","isAnimatedExport","animationHoldFrames","framesPerSecond","imageIndex","durationMs","totalFrames","frameIndex","keyBuildIndices","BrowserImageRenderer","imageFormat","startImageIndex","assertBrowserEnvironment","prefixImagePaths","renderer","getFilenameForImage","imageQuality","logFrequency","onRenderImage","blob","canvasToBlob","getImageMimeType","filename","imageType","quality","resourcePathPrefix","prefixedImagePathById","shouldPrefixImagePath","joinUrlPath","prefix"],"mappings":"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"}