UNPKG

@remotion/studio

Version:

APIs for interacting with the Remotion Studio

1,724 lines (1,680 loc) 1.13 MB
var __create = Object.create; var __getProtoOf = Object.getPrototypeOf; var __defProp = Object.defineProperty; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __toESM = (mod, isNodeMode, target) => { target = mod != null ? __create(__getProtoOf(mod)) : {}; const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target; for (let key of __getOwnPropNames(mod)) if (!__hasOwnProp.call(to, key)) __defProp(to, key, { get: () => mod[key], enumerable: true }); return to; }; var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); // src/previewEntry.tsx import ReactDOM10 from "react-dom/client"; import { Internals as Internals71 } from "remotion"; import { NoReactInternals as NoReactInternals16 } from "remotion/no-react"; // src/components/NoRegisterRoot.tsx import { useEffect, useState } from "react"; import { AbsoluteFill } from "remotion"; import { jsx, jsxs } from "react/jsx-runtime"; var label = { fontSize: 13, color: "white", fontFamily: "Arial, Helvetica, sans-serif" }; var container = { justifyContent: "center", alignItems: "center", flexDirection: "column", textAlign: "center", lineHeight: 1.5 }; var link = { color: "white", textDecoration: "none", borderBottom: "1px solid" }; var NoRegisterRoot = () => { const [show, setShow] = useState(() => false); useEffect(() => { const timeout = setTimeout(() => { setShow(true); }, 2000); return () => { clearTimeout(timeout); }; }, []); if (!show) { return null; } return /* @__PURE__ */ jsxs(AbsoluteFill, { style: container, children: [ /* @__PURE__ */ jsx("div", { style: label, children: "Waiting for registerRoot() to get called." }), /* @__PURE__ */ jsxs("div", { style: label, children: [ "Learn more:", " ", /* @__PURE__ */ jsx("a", { target: "_blank", style: link, href: "https://www.remotion.dev/docs/register-root", children: "remotion.dev/docs/register-root" }) ] }) ] }); }; // src/helpers/url-state.ts var getUrlHandlingType = () => { if (window.remotion_isReadOnlyStudio) { return "query-string"; } return "spa"; }; var pushUrl = (url) => { if (getUrlHandlingType() === "query-string") { window.history.pushState({}, "Studio", `${window.location.pathname}?${url}`); } else { window.history.pushState({}, "Studio", url); } }; var clearUrl = () => { window.location.href = window.location.pathname; }; var reloadUrl = () => { window.location.reload(); }; var getRoute = () => { if (getUrlHandlingType() === "query-string") { return window.location.search.substring(1); } return window.location.pathname; }; // src/error-overlay/react-overlay/index.ts import { Internals as Internals2 } from "remotion"; // src/error-overlay/remotion-overlay/Overlay.tsx import { createRef, useCallback as useCallback12, useImperativeHandle, useState as useState9 } from "react"; import { AbsoluteFill as AbsoluteFill2 } from "remotion"; // src/state/keybindings.tsx import { createContext, useCallback, useMemo, useRef } from "react"; import { jsx as jsx2 } from "react/jsx-runtime"; var KeybindingContext = createContext({ registerKeybinding: () => { throw new Error("Has no keybinding context"); }, unregisterKeybinding: () => { return; }, unregisterPane: () => { return; } }); var KeybindingContextProvider = ({ children }) => { const registered = useRef([]); const registerKeybinding = useCallback((binding) => { registered.current = [...registered.current, binding]; window.addEventListener(binding.event, binding.callback); }, []); const unregisterKeybinding = useCallback((binding) => { registered.current = registered.current.filter((r) => { if (r.id === binding.id) { window.removeEventListener(binding.event, binding.callback); return false; } return true; }); }, []); const unregisterPane = useCallback((paneId) => { const matchedKeybindings = registered.current.filter((r) => r.registeredFromPane === paneId); for (const matched of matchedKeybindings) { unregisterKeybinding(matched); } }, [unregisterKeybinding]); const value = useMemo(() => { return { registerKeybinding, unregisterKeybinding, unregisterPane }; }, [registerKeybinding, unregisterKeybinding, unregisterPane]); return /* @__PURE__ */ jsx2(KeybindingContext.Provider, { value, children }); }; // src/error-overlay/remotion-overlay/ErrorLoader.tsx import { useEffect as useEffect10, useState as useState8 } from "react"; // src/error-overlay/remotion-overlay/ErrorDisplay.tsx import { getLocationFromBuildError } from "@remotion/studio-shared"; import { useMemo as useMemo11 } from "react"; import { MediaPlaybackError } from "remotion"; // src/components/layout.tsx import { useMemo as useMemo2 } from "react"; import { jsx as jsx3 } from "react/jsx-runtime"; var SPACING_UNIT = 8; var Spacing = ({ x = 0, y = 0, block = false }) => { const style = useMemo2(() => { return { display: block ? "block" : "inline-block", width: x * SPACING_UNIT, height: y * SPACING_UNIT, flexShrink: 0 }; }, [block, x, y]); return /* @__PURE__ */ jsx3("div", { style }); }; var flexCss = { flex: 1 }; var Flex = ({ children }) => /* @__PURE__ */ jsx3("div", { style: flexCss, children }); var Row = ({ children, justify, className, align, flex, style = {}, ...other }) => { const finalStyle = useMemo2(() => { return { ...style, display: "flex", flexDirection: "row", justifyContent: justify ?? "flex-start", alignItems: align ?? "flex-start", flex: flex ?? undefined }; }, [align, flex, justify, style]); return /* @__PURE__ */ jsx3("div", { className, style: finalStyle, ...other, children }); }; var Column = ({ children, justify, className, align, style = {} }) => { const finalStyle = useMemo2(() => { return { ...style, display: "flex", flexDirection: "column", justifyContent: justify ?? "flex-start", alignItems: align ?? "flex-start" }; }, [align, justify, style]); return /* @__PURE__ */ jsx3("div", { className, style: finalStyle, children }); }; // src/components/Menu/is-menu-item.tsx var MENU_INITIATOR_CLASSNAME = "__remotion-studio-menu-initiator"; var MENU_ITEM_CLASSNAME = "__remotion-studio-menu-item"; var HORIZONTAL_SCROLLBAR_CLASSNAME = "__remotion-horizontal-scrollbar"; var VERTICAL_SCROLLBAR_CLASSNAME = "__remotion-vertical-scrollbar"; var isMenuItem = (el) => { return Boolean(el.classList.contains(MENU_ITEM_CLASSNAME) || el.closest(`.${MENU_ITEM_CLASSNAME}`) || el.classList.contains(MENU_INITIATOR_CLASSNAME) || el.closest(`.${MENU_INITIATOR_CLASSNAME}`)); }; // src/error-overlay/remotion-overlay/AskOnDiscord.tsx import { useCallback as useCallback4, useEffect as useEffect4 } from "react"; // src/components/Button.tsx import { forwardRef, useMemo as useMemo3 } from "react"; // src/helpers/colors.ts var BACKGROUND = "rgb(31,36,40)"; var BACKGROUND__TRANSPARENT = "rgba(31,36,40, 0)"; var INPUT_BACKGROUND = "#2f363d"; var BORDER_COLOR = "#000"; var LIGHT_COLOR = "#ddd"; var SELECTED_BACKGROUND = "hsla(0, 0%, 100%, 0.15)"; var LIGHT_TEXT = "#A6A7A9"; var RULER_COLOR = "#808080"; var VERY_LIGHT_TEXT = "rgba(255, 255, 255, 0.3)"; var SELECTED_HOVER_BACKGROUND = "hsla(0, 0%, 100%, 0.25)"; var CLEAR_HOVER = "rgba(255, 255, 255, 0.06)"; var INPUT_BORDER_COLOR_UNHOVERED = "rgba(0, 0, 0, 0.6)"; var INPUT_BORDER_COLOR_HOVERED = "rgba(255, 255, 255, 0.05)"; var TIMELINE_BACKGROUND = "#111"; var FAIL_COLOR = "#ff3232"; var TEXT_COLOR = "#fff"; var WARNING_COLOR = "#f1c40f"; var BLUE = "#0b84f3"; var BLUE_DISABLED = "#284f73"; var LIGHT_TRANSPARENT = "rgba(255, 255, 255, 0.7)"; var UNSELECTED_GUIDE = "#7e1219"; var SELECTED_GUIDE = "#d22d3a"; var LINE_COLOR = "#363A3E"; var TIMELINE_TRACK_SEPARATOR = "rgba(0, 0, 0, 0.3)"; var getBackgroundFromHoverState = ({ selected, hovered }) => { if (selected) { if (hovered) { return SELECTED_HOVER_BACKGROUND; } return SELECTED_BACKGROUND; } if (hovered) { return CLEAR_HOVER; } return "transparent"; }; // src/components/Button.tsx import { jsx as jsx4 } from "react/jsx-runtime"; var button = { border: `1px solid ${INPUT_BORDER_COLOR_UNHOVERED}`, borderRadius: 4, backgroundColor: INPUT_BACKGROUND, appearance: "none", fontFamily: "inherit", fontSize: 14, color: "white", flexDirection: "row" }; var ButtonRefForwardFunction = ({ children, onClick, title, disabled, style, id, autoFocus, buttonContainerStyle }, ref) => { const combined = useMemo3(() => { return { ...button, ...style ?? {} }; }, [style]); const buttonContainer = useMemo3(() => { return { padding: 10, cursor: disabled ? "inherit" : "pointer", fontSize: 14, opacity: disabled ? 0.7 : 1, ...buttonContainerStyle ?? {} }; }, [buttonContainerStyle, disabled]); return /* @__PURE__ */ jsx4("button", { ref, id, style: combined, type: "button", disabled, onClick, autoFocus, title, children: /* @__PURE__ */ jsx4("div", { className: "css-reset", style: buttonContainer, children }) }); }; var Button = forwardRef(ButtonRefForwardFunction); // src/helpers/use-keybinding.ts import { useCallback as useCallback3, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo6, useState as useState3 } from "react"; // src/state/z-index.tsx import { createContext as createContext3, useContext, useEffect as useEffect2, useMemo as useMemo5, useRef as useRef2 } from "react"; // src/state/highest-z-index.tsx import { createContext as createContext2, useCallback as useCallback2, useMemo as useMemo4, useState as useState2 } from "react"; import { jsx as jsx5 } from "react/jsx-runtime"; var HighestZIndexContext = createContext2({ highestIndex: 0, registerZIndex: () => { return; }, unregisterZIndex: () => { return; } }); var HighestZIndexProvider = ({ children }) => { const [zIndexes, setZIndexes] = useState2([]); const registerZIndex = useCallback2((newIndex) => { setZIndexes((prev) => [...prev, newIndex]); }, []); const unregisterZIndex = useCallback2((newIndex) => { setZIndexes((prev) => { const index = prev.indexOf(newIndex); if (index === -1) { throw new Error("did not find z-index " + newIndex); } return prev.filter((_n, i) => i !== index); }); }, []); const highestIndex = Math.max(...zIndexes); const value = useMemo4(() => { return { highestIndex, registerZIndex, unregisterZIndex }; }, [registerZIndex, unregisterZIndex, highestIndex]); return /* @__PURE__ */ jsx5(HighestZIndexContext.Provider, { value, children }); }; // src/state/input-dragger-click-lock.ts var clickLock = false; var getClickLock = () => clickLock; var setClickLock = (lock) => { clickLock = lock; }; // src/state/z-index.tsx import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime"; var ZIndexContext = createContext3({ currentIndex: 0 }); var margin = { margin: "auto" }; var EscapeHook = ({ onEscape }) => { const keybindings = useKeybinding(); useEffect2(() => { const escape = keybindings.registerKeybinding({ event: "keydown", key: "Escape", callback: onEscape, commandCtrlKey: false, preventDefault: true, triggerIfInputFieldFocused: true, keepRegisteredWhenNotHighestContext: false }); return () => { escape.unregister(); }; }, [keybindings, onEscape]); return null; }; var HigherZIndex = ({ children, onEscape, onOutsideClick, disabled }) => { const context = useContext(ZIndexContext); const highestContext = useContext(HighestZIndexContext); const containerRef = useRef2(null); const currentIndex = disabled ? context.currentIndex : context.currentIndex + 1; useEffect2(() => { if (disabled) { return; } highestContext.registerZIndex(currentIndex); return () => highestContext.unregisterZIndex(currentIndex); }, [currentIndex, highestContext, disabled]); useEffect2(() => { if (disabled) { return; } let onUp = null; const listener = (downEvent) => { const outsideClick = !containerRef.current?.contains(downEvent.target); if (!outsideClick) { return; } onUp = (upEvent) => { if (highestContext.highestIndex === currentIndex && !getClickLock() && document.contains(upEvent.target)) { upEvent.stopPropagation(); onOutsideClick(upEvent.target); } }; window.addEventListener("pointerup", onUp, { once: true }); }; requestAnimationFrame(() => { window.addEventListener("pointerdown", listener); }); return () => { if (onUp) { window.removeEventListener("pointerup", onUp, { once: true }); } onUp = null; return window.removeEventListener("pointerdown", listener); }; }, [currentIndex, disabled, highestContext.highestIndex, onOutsideClick]); const value = useMemo5(() => { return { currentIndex }; }, [currentIndex]); return /* @__PURE__ */ jsxs2(ZIndexContext.Provider, { value, children: [ disabled ? null : /* @__PURE__ */ jsx6(EscapeHook, { onEscape }), /* @__PURE__ */ jsx6("div", { ref: containerRef, style: margin, children }) ] }); }; var useZIndex = () => { const context = useContext(ZIndexContext); const highestContext = useContext(HighestZIndexContext); const isHighestContext = highestContext.highestIndex === context.currentIndex; return useMemo5(() => ({ currentZIndex: context.currentIndex, highestZIndex: highestContext.highestIndex, isHighestContext, tabIndex: isHighestContext ? 0 : -1 }), [context.currentIndex, highestContext.highestIndex, isHighestContext]); }; // src/helpers/use-keybinding.ts if (!process.env.KEYBOARD_SHORTCUTS_ENABLED) { console.warn("Keyboard shortcuts disabled either due to: a) --disable-keyboard-shortcuts being passed b) Config.setKeyboardShortcutsEnabled(false) being set or c) a Remotion version mismatch."); } var areKeyboardShortcutsDisabled = () => { return !process.env.KEYBOARD_SHORTCUTS_ENABLED; }; var useKeybinding = () => { const [paneId] = useState3(() => String(Math.random())); const context = useContext2(KeybindingContext); const { isHighestContext } = useZIndex(); const registerKeybinding = useCallback3((options) => { if (!process.env.KEYBOARD_SHORTCUTS_ENABLED) { return { unregister: () => { return; } }; } if (!isHighestContext && !options.keepRegisteredWhenNotHighestContext) { return { unregister: () => { return; } }; } const listener = (e) => { const commandKey = window.navigator.platform.startsWith("Mac") ? e.metaKey : e.ctrlKey; if (!e.key) { return; } if (e.key.toLowerCase() === options.key.toLowerCase() && options.commandCtrlKey === commandKey) { if (!options.triggerIfInputFieldFocused) { const { activeElement } = document; if (activeElement instanceof HTMLInputElement) { return; } if (activeElement instanceof HTMLTextAreaElement) { return; } } options.callback(e); if (options.preventDefault) { e.preventDefault(); } } }; const toRegister = { registeredFromPane: paneId, event: options.event, key: options.key, callback: listener, id: String(Math.random()) }; context.registerKeybinding(toRegister); return { unregister: () => context.unregisterKeybinding(toRegister) }; }, [context, isHighestContext, paneId]); useEffect3(() => { return () => { context.unregisterPane(paneId); }; }, [context, paneId]); return useMemo6(() => ({ registerKeybinding, isHighestContext }), [registerKeybinding, isHighestContext]); }; // src/error-overlay/remotion-overlay/ShortcutHint.tsx import { useMemo as useMemo7 } from "react"; import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime"; var cmdOrCtrlCharacter = window.navigator.platform.startsWith("Mac") ? "⌘" : "Ctrl"; var container2 = { display: "inline-block", marginLeft: 6, opacity: 0.6, verticalAlign: "middle", fontSize: 14 }; var ShortcutHint = ({ keyToPress, cmdOrCtrl }) => { const style = useMemo7(() => { if (keyToPress === "↵") { return { display: "inline-block", transform: `translateY(2px)`, fontSize: 14 }; } return {}; }, [keyToPress]); if (areKeyboardShortcutsDisabled()) { return null; } return /* @__PURE__ */ jsxs3("span", { style: container2, children: [ cmdOrCtrl ? `${cmdOrCtrlCharacter}` : "", /* @__PURE__ */ jsx7("span", { style, children: keyToPress.toUpperCase() }) ] }); }; // src/error-overlay/remotion-overlay/AskOnDiscord.tsx import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime"; var DISCORD_LINK = "https://remotion.dev/discord"; var AskOnDiscord = ({ canHaveKeyboardShortcuts }) => { const openInBrowser = useCallback4(() => { window.open(DISCORD_LINK, "_blank"); }, []); const { registerKeybinding } = useKeybinding(); useEffect4(() => { if (!canHaveKeyboardShortcuts) { return; } const onEditor = () => { openInBrowser(); }; const { unregister } = registerKeybinding({ event: "keydown", key: "d", callback: onEditor, commandCtrlKey: true, preventDefault: true, triggerIfInputFieldFocused: false, keepRegisteredWhenNotHighestContext: false }); return () => unregister(); }, [canHaveKeyboardShortcuts, openInBrowser, registerKeybinding]); return /* @__PURE__ */ jsxs4(Button, { onClick: openInBrowser, children: [ "Ask on Discord", " ", canHaveKeyboardShortcuts ? /* @__PURE__ */ jsx8(ShortcutHint, { keyToPress: "d", cmdOrCtrl: true }) : null ] }); }; // src/components/Menu/styles.ts var MENU_VERTICAL_PADDING = 4; var SUBMENU_LEFT_INSET = -8; var MAX_MENU_WIDTH = 400; var MAX_MOBILE_MENU_WIDTH = 300; var menuContainer = { backgroundColor: BACKGROUND, position: "fixed", color: "white", userSelect: "none", WebkitUserSelect: "none" }; var SHADOW_TOWARDS_BOTTOM = "0 2px 8px rgba(0, 0, 0, 0.5)"; var SHADOW_TOWARDS_TOP = "0 -2px 8px rgba(0, 0, 0, 0.5)"; var menuContainerTowardsBottom = { ...menuContainer, boxShadow: SHADOW_TOWARDS_BOTTOM }; var menuContainerTowardsTop = { ...menuContainer, boxShadow: SHADOW_TOWARDS_TOP }; var fullScreenOverlay = { position: "fixed", top: 0, left: 0, right: 0, bottom: 0 }; var outerPortal = { position: "fixed" }; var inlineCodeSnippet = { fontSize: 14, color: BLUE, fontFamily: "monospace" }; // src/error-overlay/remotion-overlay/CalculateMetadataErrorExplainer.tsx import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime"; var CalculateMetadataErrorExplainer = () => { return /* @__PURE__ */ jsxs5("div", { style, children: [ "This error occured while calling", " ", /* @__PURE__ */ jsx9("code", { style: inlineCodeSnippet, children: "calculateMetadata()" }), "." ] }); }; var style = { borderRadius: 3, color: "white", padding: 12, backgroundColor: BORDER_COLOR, fontSize: 14, fontFamily: "sans-serif" }; // src/error-overlay/remotion-overlay/CopyStackTrace.tsx import { useCallback as useCallback5, useEffect as useEffect5, useMemo as useMemo8, useState as useState4 } from "react"; import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime"; var CopyStackTrace = ({ canHaveKeyboardShortcuts, errorText }) => { const [copyState, setCopyState] = useState4("idle"); const handleCopyToClipboard = useCallback5(() => { navigator.clipboard.writeText(errorText).then(() => { setCopyState("copied"); setTimeout(() => setCopyState("idle"), 2000); }).catch(() => { setCopyState("failed"); setTimeout(() => setCopyState("idle"), 2000); }); }, [errorText]); const { registerKeybinding } = useKeybinding(); useEffect5(() => { if (!canHaveKeyboardShortcuts) { return; } const { unregister } = registerKeybinding({ event: "keydown", key: "t", callback: handleCopyToClipboard, commandCtrlKey: true, preventDefault: true, triggerIfInputFieldFocused: false, keepRegisteredWhenNotHighestContext: false }); return () => unregister(); }, [canHaveKeyboardShortcuts, handleCopyToClipboard, registerKeybinding]); const label2 = useMemo8(() => { if (copyState === "copied") { return "Copied!"; } if (copyState === "failed") { return "Failed!"; } return "Copy Stacktrace"; }, [copyState]); return /* @__PURE__ */ jsxs6(Button, { onClick: handleCopyToClipboard, children: [ label2, " ", copyState === "idle" && canHaveKeyboardShortcuts ? /* @__PURE__ */ jsx10(ShortcutHint, { cmdOrCtrl: true, keyToPress: "t" }) : null ] }); }; // src/error-overlay/remotion-overlay/DismissButton.tsx import { useCallback as useCallback6 } from "react"; import { jsx as jsx11 } from "react/jsx-runtime"; var size = { height: 20, width: 20 }; var style2 = { appearance: "none", WebkitAppearance: "none", backgroundColor: "transparent", border: "none", cursor: "pointer" }; var DismissButton = () => { const dismiss = useCallback6(() => { clearUrl(); }, []); return /* @__PURE__ */ jsx11("button", { type: "button", style: style2, onClick: dismiss, children: /* @__PURE__ */ jsx11("svg", { focusable: "false", role: "img", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 352 512", style: size, children: /* @__PURE__ */ jsx11("path", { fill: "white", d: "M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z" }) }) }); }; // src/error-overlay/remotion-overlay/ErrorMessage.tsx import { PlayerInternals } from "@remotion/player"; import { useCallback as useCallback7, useMemo as useMemo9, useRef as useRef3, useState as useState5 } from "react"; // src/error-overlay/remotion-overlay/carets.tsx import { jsx as jsx12 } from "react/jsx-runtime"; var CaretRight = ({ size: size2 }) => { return /* @__PURE__ */ jsx12("svg", { style: { height: size2 ?? 20 }, "aria-hidden": "true", focusable: "false", role: "img", viewBox: "0 0 192 512", children: /* @__PURE__ */ jsx12("path", { fill: "currentColor", d: "M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z" }) }); }; var CaretDown = ({ invert, size: size2 }) => { return /* @__PURE__ */ jsx12("svg", { "aria-hidden": "true", focusable: "false", role: "img", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 320 512", style: { height: size2 ?? 20, transform: invert ? `rotate(180deg)` : "" }, children: /* @__PURE__ */ jsx12("path", { fill: "currentColor", d: "M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z" }) }); }; // src/error-overlay/remotion-overlay/ErrorMessage.tsx import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime"; var fontSize = 24; var lineHeight = 1.5; var maxLines = 2; var buttonSize = 32; var maskImage = "linear-gradient(to bottom, white 60%, transparent)"; var container3 = { position: "relative", marginBottom: 15 }; var messageContainer = { overflow: "hidden" }; var textContainer = { fontSize, lineHeight }; var moreLine = { width: "100%", display: "flex", justifyContent: "center", position: "absolute", border: `1px solid ${INPUT_BORDER_COLOR_HOVERED}`, height: 0, marginTop: 4 }; var moreButton = { height: buttonSize, width: buttonSize, borderRadius: buttonSize / 2, backgroundColor: INPUT_BACKGROUND, border: `1px solid ${INPUT_BORDER_COLOR_UNHOVERED}`, marginTop: -buttonSize / 2, display: "flex", justifyContent: "center", alignItems: "center", cursor: "pointer", color: "white" }; var ErrorMessage = ({ message }) => { const [expanded, setExpanded] = useState5(false); const ref = useRef3(null); const size2 = PlayerInternals.useElementSize(ref, { shouldApplyCssTransforms: false, triggerOnWindowResize: true }); const errorLines = size2 ? size2.height / (lineHeight * fontSize) : null; const style3 = useMemo9(() => { const isExpanded = expanded || errorLines !== null && errorLines <= maxLines; return { ...messageContainer, maxHeight: isExpanded ? undefined : fontSize * lineHeight * maxLines, maskImage: isExpanded ? undefined : maskImage, WebkitMaskImage: isExpanded ? undefined : maskImage }; }, [errorLines, expanded]); const toggle = useCallback7(() => { setExpanded((e) => !e); }, []); return /* @__PURE__ */ jsxs7("div", { style: container3, children: [ /* @__PURE__ */ jsx13("div", { style: style3, children: /* @__PURE__ */ jsx13("div", { ref, style: textContainer, children: message }) }), errorLines !== null && errorLines > maxLines ? /* @__PURE__ */ jsx13("div", { style: moreLine, children: /* @__PURE__ */ jsx13("button", { type: "button", onClick: toggle, style: moreButton, children: /* @__PURE__ */ jsx13(CaretDown, { invert: expanded }) }) }) : null ] }); }; // src/error-overlay/remotion-overlay/Symbolicating.tsx import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime"; var Symbolicating = (props) => { return /* @__PURE__ */ jsxs8("svg", { id: "loading", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 32 32", width: "16", height: "16", fill: "white", ...props, children: [ /* @__PURE__ */ jsx14("path", { opacity: ".1", d: "M14 0 H18 V8 H14 z", transform: "rotate(0 16 16)", children: /* @__PURE__ */ jsx14("animate", { attributeName: "opacity", from: "1", to: ".1", dur: "1s", repeatCount: "indefinite", begin: "0" }) }), /* @__PURE__ */ jsx14("path", { opacity: ".1", d: "M14 0 H18 V8 H14 z", transform: "rotate(45 16 16)", children: /* @__PURE__ */ jsx14("animate", { attributeName: "opacity", from: "1", to: ".1", dur: "1s", repeatCount: "indefinite", begin: "0.125s" }) }), /* @__PURE__ */ jsx14("path", { opacity: ".1", d: "M14 0 H18 V8 H14 z", transform: "rotate(90 16 16)", children: /* @__PURE__ */ jsx14("animate", { attributeName: "opacity", from: "1", to: ".1", dur: "1s", repeatCount: "indefinite", begin: "0.25s" }) }), /* @__PURE__ */ jsx14("path", { opacity: ".1", d: "M14 0 H18 V8 H14 z", transform: "rotate(135 16 16)", children: /* @__PURE__ */ jsx14("animate", { attributeName: "opacity", from: "1", to: ".1", dur: "1s", repeatCount: "indefinite", begin: "0.375s" }) }), /* @__PURE__ */ jsx14("path", { opacity: ".1", d: "M14 0 H18 V8 H14 z", transform: "rotate(180 16 16)", children: /* @__PURE__ */ jsx14("animate", { attributeName: "opacity", from: "1", to: ".1", dur: "1s", repeatCount: "indefinite", begin: "0.5s" }) }), /* @__PURE__ */ jsx14("path", { opacity: ".1", d: "M14 0 H18 V8 H14 z", transform: "rotate(225 16 16)", children: /* @__PURE__ */ jsx14("animate", { attributeName: "opacity", from: "1", to: ".1", dur: "1s", repeatCount: "indefinite", begin: "0.675s" }) }), /* @__PURE__ */ jsx14("path", { opacity: ".1", d: "M14 0 H18 V8 H14 z", transform: "rotate(270 16 16)", children: /* @__PURE__ */ jsx14("animate", { attributeName: "opacity", from: "1", to: ".1", dur: "1s", repeatCount: "indefinite", begin: "0.75s" }) }), /* @__PURE__ */ jsx14("path", { opacity: ".1", d: "M14 0 H18 V8 H14 z", transform: "rotate(315 16 16)", children: /* @__PURE__ */ jsx14("animate", { attributeName: "opacity", from: "1", to: ".1", dur: "1s", repeatCount: "indefinite", begin: "0.875s" }) }) ] }); }; // src/error-overlay/remotion-overlay/ErrorTitle.tsx import { jsx as jsx15, jsxs as jsxs9, Fragment } from "react/jsx-runtime"; var title = { marginBottom: 8, display: "flex", flexDirection: "row", justifyContent: "center" }; var left = { flex: 1, paddingRight: 14, fontWeight: "bold", maxWidth: "100%" }; var errName = { fontSize: 18, color: BLUE, display: "inline-block" }; var row = { display: "flex", flexDirection: "row", alignItems: "center" }; var spacer = { width: 5 }; var ErrorTitle = ({ name, message, symbolicating, canHaveDismissButton }) => { return /* @__PURE__ */ jsxs9("div", { style: title, className: "css-reset", children: [ /* @__PURE__ */ jsxs9("div", { style: left, children: [ /* @__PURE__ */ jsx15("span", { style: errName, children: name }), /* @__PURE__ */ jsx15("br", {}), /* @__PURE__ */ jsxs9("div", { style: row, children: [ symbolicating ? /* @__PURE__ */ jsxs9(Fragment, { children: [ /* @__PURE__ */ jsx15(Symbolicating, {}), /* @__PURE__ */ jsx15("div", { style: spacer }) ] }) : null, /* @__PURE__ */ jsx15(ErrorMessage, { message }) ] }) ] }), didUnmountReactApp() ? null : canHaveDismissButton ? /* @__PURE__ */ jsx15(DismissButton, {}) : null ] }); }; // src/error-overlay/remotion-overlay/get-help-link.ts var getHelpLink = (message) => { if (message.includes("See https://www.remotion.dev/docs/the-fundamentals#defining-compositions")) { return { title: "Defining compositions", url: "See https://www.remotion.dev/docs/the-fundamentals#defining-compositions" }; } if (message.includes("https://remotion.dev/docs/wrong-composition-mount")) { return { title: "Wrongly mounted <Composition>", url: "https://remotion.dev/docs/wrong-composition-mount" }; } if (message.includes("https://remotion.dev/docs/staticfile-relative-paths")) { return { title: "staticFile() relative paths", url: "https://remotion.dev/docs/staticfile-relative-paths" }; } if (message.includes("https://remotion.dev/docs/staticfile-remote-urls")) { return { title: "staticFile() remote URLs", url: "https://remotion.dev/docs/staticfile-remote-urls" }; } if (message.includes("https://remotion.dev/docs/non-seekable-media")) { return { title: "Non-seekable media", url: "https://remotion.dev/docs/non-seekable-media" }; } if (message.includes("https://remotion.dev/docs/media-playback-error")) { return { title: "Media playback error", url: "https://remotion.dev/docs/media-playback-error" }; } if (message.includes("Div is not part of the THREE")) { return { title: "<Sequence> inside <ThreeCanvas>", url: "https://remotion.dev/docs/sequence#note-for-remotionthree" }; } return null; }; // src/error-overlay/remotion-overlay/HelpLink.tsx import { useCallback as useCallback8, useEffect as useEffect6 } from "react"; import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime"; var buttonStyle = { backgroundColor: BLUE, color: "white" }; var HelpLink = ({ canHaveKeyboardShortcuts, link: link2 }) => { const openLink = useCallback8(() => { window.open(link2.url, "_blank"); }, [link2]); const { registerKeybinding } = useKeybinding(); useEffect6(() => { if (!canHaveKeyboardShortcuts) { return; } const onEditor = () => { openLink(); }; const { unregister } = registerKeybinding({ event: "keydown", key: "h", callback: onEditor, commandCtrlKey: true, preventDefault: true, triggerIfInputFieldFocused: false, keepRegisteredWhenNotHighestContext: false }); return () => unregister(); }, [canHaveKeyboardShortcuts, openLink, registerKeybinding]); return /* @__PURE__ */ jsxs10(Button, { style: buttonStyle, onClick: openLink, children: [ "Help: ", '"', link2.title, '"', canHaveKeyboardShortcuts ? /* @__PURE__ */ jsx16(ShortcutHint, { keyToPress: "h", cmdOrCtrl: true }) : null ] }); }; // src/error-overlay/remotion-overlay/MediaPlaybackErrorExplainer.tsx import { useEffect as useEffect7, useState as useState6 } from "react"; import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime"; var container4 = { borderRadius: 3, color: "white", padding: 12, backgroundColor: BORDER_COLOR, fontSize: 14, fontFamily: "sans-serif", lineHeight: 1.5 }; var codeStyle = { backgroundColor: "rgba(255,255,255,0.1)", padding: "2px 5px", borderRadius: 3, fontFamily: "monospace", fontSize: 13 }; var linkStyle = { color: "#58a6ff" }; var MediaPlaybackErrorExplainer = ({ src }) => { const [result, setResult] = useState6({ type: "loading" }); useEffect7(() => { fetch(src, { method: "HEAD" }).then((res) => { if (res.status === 404) { setResult({ type: "not-found" }); } else if (!res.ok) { setResult({ type: "other-error", statusCode: res.status }); } else { const contentType = res.headers.get("content-type") ?? ""; if (contentType.includes("text/html") || contentType.includes("application/json")) { setResult({ type: "wrong-content-type", contentType }); } else { setResult({ type: "ok" }); } } }).catch(() => { setResult({ type: "fetch-error" }); }); }, [src]); if (result.type === "loading") { return null; } if (result.type === "not-found") { return /* @__PURE__ */ jsxs11("div", { style: container4, children: [ "The file ", /* @__PURE__ */ jsx17("code", { style: codeStyle, children: src }), " was not found (404).", /* @__PURE__ */ jsx17("br", {}), "If the file is in your ", /* @__PURE__ */ jsx17("code", { style: codeStyle, children: "public/" }), " folder, make sure to use", " ", /* @__PURE__ */ jsx17("a", { style: linkStyle, href: "https://remotion.dev/docs/staticfile", target: "_blank", children: /* @__PURE__ */ jsx17("code", { style: codeStyle, children: "staticFile()" }) }), " ", "to reference it.", /* @__PURE__ */ jsx17("br", {}), /* @__PURE__ */ jsx17("a", { style: linkStyle, href: "https://remotion.dev/docs/media-playback-error", target: "_blank", children: "Learn more" }) ] }); } if (result.type === "other-error") { return /* @__PURE__ */ jsxs11("div", { style: container4, children: [ "⚠️ Fetching ", /* @__PURE__ */ jsx17("code", { style: codeStyle, children: src }), " returned status code", " ", result.statusCode, ".", /* @__PURE__ */ jsx17("br", {}), /* @__PURE__ */ jsx17("a", { style: linkStyle, href: "https://remotion.dev/docs/media-playback-error", target: "_blank", children: "Learn more" }) ] }); } if (result.type === "wrong-content-type") { return /* @__PURE__ */ jsxs11("div", { style: container4, children: [ "⚠️ Fetching ", /* @__PURE__ */ jsx17("code", { style: codeStyle, children: src }), " returned a", " ", /* @__PURE__ */ jsx17("code", { style: codeStyle, children: result.contentType }), " content type.", /* @__PURE__ */ jsx17("br", {}), "\uD83D\uDC49 If the file is in your ", /* @__PURE__ */ jsx17("code", { style: codeStyle, children: "public/" }), " ", "folder, make sure to use", " ", /* @__PURE__ */ jsx17("a", { style: linkStyle, href: "https://remotion.dev/docs/staticfile", target: "_blank", children: /* @__PURE__ */ jsx17("code", { style: codeStyle, children: "staticFile()" }) }), " ", "to reference it.", /* @__PURE__ */ jsx17("br", {}), /* @__PURE__ */ jsx17("a", { style: linkStyle, href: "https://remotion.dev/docs/media-playback-error", target: "_blank", children: "Learn more" }) ] }); } return null; }; // src/error-overlay/remotion-overlay/OpenInEditor.tsx import { useCallback as useCallback9, useEffect as useEffect8, useMemo as useMemo10, useReducer, useRef as useRef4 } from "react"; // src/helpers/open-in-editor.ts var openInEditor = (stack) => { const { originalFileName, originalLineNumber, originalColumnNumber, originalFunctionName, originalScriptCode } = stack; return fetch(`/api/open-in-editor`, { method: "post", headers: { "content-type": "application/json" }, body: JSON.stringify({ stack: { originalFileName, originalLineNumber, originalColumnNumber, originalFunctionName, originalScriptCode } }) }); }; var openOriginalPositionInEditor = async (originalPosition) => { await openInEditor({ originalColumnNumber: originalPosition.column, originalFileName: originalPosition.source, originalFunctionName: null, originalLineNumber: originalPosition.line, originalScriptCode: null }); }; // src/error-overlay/remotion-overlay/OpenInEditor.tsx import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime"; var initialState = { type: "idle" }; var reducer = (state, action) => { if (action.type === "start") { return { type: "load" }; } if (action.type === "fail") { return { type: "error" }; } if (action.type === "reset") { return { type: "idle" }; } if (action.type === "succeed") { return { type: "success" }; } return state; }; var OpenInEditor = ({ stack, canHaveKeyboardShortcuts }) => { const isMounted = useRef4(true); const [state, dispatch] = useReducer(reducer, initialState); const { registerKeybinding } = useKeybinding(); const dispatchIfMounted = useCallback9((payload) => { if (isMounted.current === false) return; dispatch(payload); }, []); const openInBrowser = useCallback9(() => { dispatch({ type: "start" }); openInEditor(stack).then((res) => res.json()).then((data) => { if (data.success) { dispatchIfMounted({ type: "succeed" }); } else { dispatchIfMounted({ type: "fail" }); } }).catch((err) => { dispatchIfMounted({ type: "fail" }); console.log("Could not open browser", err); }).finally(() => { setTimeout(() => { dispatchIfMounted({ type: "reset" }); }, 2000); }); }, [dispatchIfMounted, stack]); useEffect8(() => { return () => { isMounted.current = false; }; }, []); useEffect8(() => { if (!canHaveKeyboardShortcuts) { return; } const onEditor = () => { openInBrowser(); }; const { unregister } = registerKeybinding({ event: "keydown", key: "o", callback: onEditor, commandCtrlKey: true, preventDefault: true, triggerIfInputFieldFocused: false, keepRegisteredWhenNotHighestContext: false }); return () => unregister(); }, [canHaveKeyboardShortcuts, openInBrowser, registerKeybinding]); const label2 = useMemo10(() => { switch (state.type) { case "error": return "Failed to open"; case "idle": return `Open in ${window.remotion_editorName}`; case "success": return `Opened in ${window.remotion_editorName}`; case "load": return `Opening...`; default: throw new Error("invalid state"); } }, [state.type]); return /* @__PURE__ */ jsxs12(Button, { onClick: openInBrowser, disabled: state.type !== "idle", children: [ label2, canHaveKeyboardShortcuts ? /* @__PURE__ */ jsx18(ShortcutHint, { keyToPress: "o", cmdOrCtrl: true }) : null ] }); }; // src/error-overlay/remotion-overlay/Retry.tsx import { jsx as jsx19 } from "react/jsx-runtime"; var RetryButton = ({ onClick }) => { return /* @__PURE__ */ jsx19(Button, { onClick, children: "Retry calculateMetadata()" }); }; // src/error-overlay/remotion-overlay/SearchGitHubIssues.tsx import { useCallback as useCallback10, useEffect as useEffect9 } from "react"; import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime"; var SearchGithubIssues = ({ message, canHaveKeyboardShortcuts }) => { const openInBrowser = useCallback10(() => { window.open(`https://github.com/remotion-dev/remotion/issues?q=${encodeURIComponent(message)}`, "_blank"); }, [message]); const { registerKeybinding } = useKeybinding(); useEffect9(() => { if (!canHaveKeyboardShortcuts) { return; } const onEditor = () => { openInBrowser(); }; const { unregister } = registerKeybinding({ event: "keydown", key: "g", callback: onEditor, commandCtrlKey: true, preventDefault: true, triggerIfInputFieldFocused: false, keepRegisteredWhenNotHighestContext: false }); return () => unregister(); }, [canHaveKeyboardShortcuts, openInBrowser, registerKeybinding]); return /* @__PURE__ */ jsxs13(Button, { onClick: openInBrowser, children: [ "Search GitHub Issues", " ", canHaveKeyboardShortcuts ? /* @__PURE__ */ jsx20(ShortcutHint, { keyToPress: "g", cmdOrCtrl: true }) : null ] }); }; // src/error-overlay/remotion-overlay/StackFrame.tsx import { useCallback as useCallback11, useState as useState7 } from "react"; // src/error-overlay/remotion-overlay/CodeFrame.tsx import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime"; var container5 = { display: "flex", flexDirection: "row", width: "100%" }; var frame = { backgroundColor: "#070707", marginBottom: 20, overflowY: "auto" }; var lineNumber = { whiteSpace: "pre", paddingRight: 12, color: "inherit", fontSize: 14, lineHeight: 1.7, width: 60, flexShrink: 0, display: "inline-flex", alignItems: "center", justifyContent: "flex-end", fontFamily: "monospace" }; var CodeFrame = ({ source, lineNumberWidth }) => { return /* @__PURE__ */ jsx21("div", { style: frame, className: HORIZONTAL_SCROLLBAR_CLASSNAME, children: source.map((s, j) => { return /* @__PURE__ */ jsxs14("div", { style: container5, children: [ /* @__PURE__ */ jsx21("div", { style: { ...lineNumber, backgroundColor: s.highlight ? "white" : "#121212", color: s.highlight ? "black" : "rgba(255, 255, 255, 0.6)" }, children: String(s.lineNumber).padStart(lineNumberWidth, " ") }), /* @__PURE__ */ jsx21("div", { style: { fontFamily: "monospace", whiteSpace: "pre", tabSize: 2, color: s.highlight ? "white" : "rgba(255, 255, 255, 0.6)", backgroundColor: s.highlight ? BLUE : "transparent", lineHeight: 1.7, paddingRight: 12, paddingLeft: 12 }, children: s.content }) ] }, j); }) }); }; // src/error-overlay/remotion-overlay/format-location.ts var formatLocation = (location) => { if (location.startsWith("webpack://")) { return location.replace("webpack://", ""); } return location; }; // src/error-overlay/remotion-overlay/StackFrame.tsx import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime"; var location = { color: "rgba(255, 255, 255, 0.6)", fontFamily: "monospace", fontSize: 14 }; var header = { paddingLeft: 14, paddingTop: 10, paddingBottom: 10, paddingRight: 14, display: "flex", flexDirection: "row", alignItems: "center", borderBottom: "1px solid rgb(66, 144, 245)", backgroundColor: "black" }; var left2 = { paddingRight: 14, flex: 1 }; var fnName = { fontSize: 14, lineHeight: 1.5, marginBottom: 3 }; var StackElement = ({ s, lineNumberWidth, isFirst, defaultFunctionName }) => { const [showCodeFrame, setShowCodeFrame] = useState7(() => !s.originalFileName?.includes("node_modules") && !s.originalFileName?.startsWith("webpack/") || isFirst); const toggleCodeFrame = useCallback11(() => { setShowCodeFrame((f) => !f); }, []); return /* @__PURE__ */ jsxs15("div", { className: "css-reset", children: [ /* @__PURE__ */ jsxs15("div", { style: header, children: [ /* @__PURE__ */ jsxs15("div", { style: left2, children: [ /* @__PURE__ */ jsx22("div", { style: fnName, children: s.originalFunctionName ?? defaultFunctionName }), s.originalFileName ? /* @__PURE__ */ jsxs15("div", { style: location, children: [ formatLocation(s.originalFileName), ":", s.originalLineNumber ] }) : null ] }), s.originalScriptCode && s.originalScriptCode.length > 0 ? /* @__PURE__ */ jsx22(Button, { onClick: toggleCodeFrame, children: showCodeFrame ? /* @__PURE__ */ jsx22(CaretDown, { invert: false }) : /* @__PURE__ */ jsx22(CaretRight, {}) }) : null ] }), /* @__PURE__ */ jsx22("div", { children: s.originalScriptCode && s.originalScriptCode.length > 0 && showCodeFrame ? /* @__PURE__ */ jsx22(CodeFrame, { lineNumberWidth, source: s.originalScriptCode }) : null }) ] }); }; // src/error-overlay/remotion-overlay/ErrorDisplay.tsx import { jsx as jsx23, jsxs as jsxs16, Fragment as Fragment2 } from "react/jsx-runtime"; var stack = { marginTop: 17, overflowX: "scroll", marginBottom: "10vh" }; var spacer2 = { width: 5, display: "inline-block" }; var ErrorDisplay = ({ display, keyboardShortcuts, onRetry, canHaveDismissButton, calculateMetadata }) => { const highestLineNumber = Math.max(...display.stackFrames.map((s) => s.originalScriptCode).flat(1).map((s) => s?.lineNumber ?? 0)); const message = useMemo11(() => { const location2 = getLocationFromBuildError(display.error); if (!location2) { return display.error.message; } return location2.message.replace(/\\n/g, ` `).replace(/\\t/g, " ").replace(/^error:/, "").trim(); }, [display.error]); const lineNumberWidth = String(highestLineNumber).length; const helpLink = getHelpLink(message); const errorTextForCopy = useMemo11(() => { const header2 = `${display.error.name}: ${message}`; if (display.stackFrames.length > 0) { const stackLines = display.stackFrames.map((frame2) => `at ${frame2.originalFunctionName || "<anonymous>"} (${frame2.originalFileName || "unknown"}:${frame2.originalLineNumber || "?"}:${frame2.originalColumnNumber || "?"})`).join(