@pixerate/editor-react 0.78.1 → 0.79.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/animation-editor/index.ts","../../src/animation-editor/useAnimationEditor.ts","../../src/animation-editor/AnimationStage.tsx","../../src/animation-editor/ShotTimeline.tsx","../../src/animation-editor/AnimationEditor.tsx","../../src/animation-editor/CommandInspector.tsx","../../src/animation-editor/EasePicker.tsx","../../src/animation-editor/CommitInput.tsx","../../src/animation-editor/CommandList.tsx","../../src/animation-editor/PlayheadScrubber.tsx","../../src/animation-editor/SceneSettings.tsx","../../src/animation-editor/ShotInspector.tsx"],"sourcesContent":["export * from './useAnimationEditor';\nexport * from './AnimationStage';\nexport * from './ShotTimeline';\nexport * from './AnimationEditor';\nexport * from './PlayheadScrubber';\nexport * from './CommandList';\nexport * from './CommandInspector';\nexport * from './EasePicker';\nexport * from './ShotInspector';\nexport * from './SceneSettings';\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n AnimationEditorController,\n createAnimationEditorToolProvider,\n type AnimationEditorOptions,\n type AnimationEditorState,\n type AnimationEditorToolProviderOptions,\n} from '@pixerate/editor/animation-editor';\nimport type { ToolRegistry } from '@pixerate/editor/tools';\n\n/** An `AnimationEditorController` created once for the component's lifetime (destroyed on unmount). */\nexport function useAnimationEditorController(options: AnimationEditorOptions = {}): AnimationEditorController {\n const ref = useRef<AnimationEditorController | null>(null);\n if (!ref.current) ref.current = new AnimationEditorController(options);\n const controller = ref.current;\n useEffect(() => () => controller.destroy(), [controller]);\n return controller;\n}\n\n/** The controller's state (re-renders on every change, including each played frame). */\nexport function useAnimationEditorState(controller: AnimationEditorController): AnimationEditorState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseAnimationEditorResult {\n controller: AnimationEditorController;\n state: AnimationEditorState;\n play: () => void;\n pause: () => void;\n toggle: () => void;\n seek: (time: number) => void;\n undo: () => void;\n redo: () => void;\n /** The frame at the playhead as SVG. */\n toSvg: () => string;\n}\n\n/**\n * Subscribes to an animation editor controller and exposes its state with bound actions.\n * Pass options instead of a controller to create one for the component's lifetime.\n */\nexport function useAnimationEditor(controllerOrOptions: AnimationEditorController | AnimationEditorOptions = {}): UseAnimationEditorResult {\n const own = useRef<AnimationEditorController | null>(null);\n let controller: AnimationEditorController;\n if (controllerOrOptions instanceof AnimationEditorController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new AnimationEditorController(controllerOrOptions);\n controller = own.current;\n }\n useEffect(() => () => own.current?.destroy(), []);\n const state = useAnimationEditorState(controller);\n const actions = useMemo(\n () => ({\n play: () => controller.play(),\n pause: () => controller.pause(),\n toggle: () => controller.toggle(),\n seek: (time: number) => controller.seek(time),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n toSvg: () => controller.toSvg(),\n }),\n [controller],\n );\n return { controller, state, ...actions };\n}\n\n/**\n * Registers the animation editor's agent tools (`get_animation`, `add_commands`,\n * `export_flair_effect`, …) in `registry` while mounted.\n */\nexport function useAnimationEditorTools(\n registry: ToolRegistry | null | undefined,\n controller: AnimationEditorController,\n options: AnimationEditorToolProviderOptions = {},\n): void {\n const { id, namespace, readOnly, rasterize } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createAnimationEditorToolProvider(controller, { id, namespace, readOnly, rasterize }));\n }, [registry, controller, id, namespace, readOnly, rasterize]);\n}\n","import React, { useMemo } from 'react';\nimport { highlightMotionSvg, motionNodeAtElement, type AnimationEditorController, type MotionFrameOptions, type MotionOnionSkin } from '@pixerate/editor/animation-editor';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface AnimationStageProps {\n controller: AnimationEditorController;\n /** Control values to preview (`{ accent: \"#0ea5e9\" }`). */\n values?: MotionFrameOptions['values'];\n /** Faded frames either side of the playhead. */\n onionSkin?: MotionOnionSkin;\n /** Draw where nodes travel: true for every node whose place changes, or a list of ids. */\n motionPaths?: boolean | readonly string[];\n /**\n * Called when the stage is clicked, with the id of the artwork node under the pointer (the\n * innermost one; null for the background, ghosts and paths). Makes the stage pickable.\n */\n onPick?: (id: string | null, event: React.MouseEvent<HTMLDivElement>) => void;\n /** Node ids to outline (e.g. the picked element and the selected command's targets). */\n highlight?: readonly string[];\n className?: string;\n}\n\n/**\n * The animation's frame at the playhead, drawn as inline SVG scaled to the stage's width. The\n * SVG keeps the artwork's node ids, so `onPick` can say which element was clicked.\n */\nexport function AnimationStage({ controller, values, onionSkin, motionPaths, onPick, highlight, className = '' }: AnimationStageProps) {\n const state = useAnimationEditorState(controller);\n const { scene, time } = state;\n const key = highlight?.join('\\u0000') ?? '';\n const svg = useMemo(\n () =>\n highlightMotionSvg(\n controller.toSvg(time, { pretty: false, idPrefix: 'ae-', values, onionSkin, motionPaths }).replace(/<svg ([^>]*?)width=\"[^\"]*\" height=\"[^\"]*\"/, '<svg $1width=\"100%\" height=\"100%\"'),\n highlight ?? [],\n ),\n [controller, scene, time, values, onionSkin, motionPaths, key],\n );\n return (\n <div\n className={`relative overflow-hidden ${onPick ? 'cursor-crosshair' : ''} ${className}`}\n style={{ aspectRatio: `${scene.artwork.width} / ${scene.artwork.height}` }}\n data-animation-stage=\"\"\n role=\"img\"\n aria-label={`${scene.name} at ${(time / 1000).toFixed(2)} s`}\n onClick={onPick ? (e) => onPick(motionNodeAtElement(scene, e.target as Element, e.currentTarget), e) : undefined}\n dangerouslySetInnerHTML={{ __html: svg }}\n />\n );\n}\n","import React from 'react';\nimport type { AnimationEditorController, MotionIssue } from '@pixerate/editor/animation-editor';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface ShotTimelineProps {\n controller: AnimationEditorController;\n className?: string;\n}\n\nconst seconds = (ms: number) => `${(ms / 1000).toFixed(1)} s`;\n\nfunction worst(issues: readonly MotionIssue[]): 'error' | 'warning' | null {\n if (issues.some((i) => i.severity === 'error')) return 'error';\n if (issues.some((i) => i.severity === 'warning')) return 'warning';\n return null;\n}\n\n/**\n * Play / pause, the playhead and one block per shot (as wide as it is long): click a shot to\n * select it and jump to its start, click the ruler to seek. Shots with errors or warnings are marked.\n */\nexport function ShotTimeline({ controller, className = '' }: ShotTimelineProps) {\n const state = useAnimationEditorState(controller);\n const { duration, shots, time, playing, selection, issues } = state;\n const span = Math.max(1, duration);\n const onRuler = (event: React.PointerEvent<HTMLDivElement>) => {\n const box = event.currentTarget.getBoundingClientRect();\n controller.seek(((event.clientX - box.left) / Math.max(1, box.width)) * span);\n };\n return (\n <div className={`flex flex-col gap-1 ${className}`} data-shot-timeline=\"\">\n <div className=\"flex items-center gap-2 text-xs\">\n <button type=\"button\" className=\"rounded border border-border px-2 py-0.5\" onClick={() => controller.toggle()} aria-label={playing ? 'Pause' : 'Play'} disabled={!shots.length}>\n {playing ? 'Pause' : 'Play'}\n </button>\n <span className=\"tabular-nums text-muted-foreground\">\n {seconds(time)} / {seconds(duration)}\n </span>\n </div>\n <div className=\"relative h-3 cursor-pointer rounded bg-muted\" onPointerDown={onRuler} role=\"slider\" aria-label=\"Playhead\" aria-valuemin={0} aria-valuemax={duration} aria-valuenow={Math.round(time)} tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'ArrowRight') controller.seek(time + 100);\n if (e.key === 'ArrowLeft') controller.seek(time - 100);\n }}>\n <div className=\"absolute inset-y-0 w-0.5 bg-rose-500\" style={{ left: `${(time / span) * 100}%` }} />\n </div>\n <div className=\"flex w-full gap-px\" role=\"group\" aria-label=\"Shots\">\n {shots.map((shot) => {\n const mark = worst(issues.filter((i) => i.shot === shot.id));\n const selected = selection?.shot === shot.id;\n return (\n <button\n key={shot.id}\n type=\"button\"\n className={`min-w-0 truncate rounded border px-1 py-1 text-left text-[11px] ${selected ? 'border-rose-500 bg-rose-500/10' : 'border-border'} ${state.currentShot === shot.id ? 'font-semibold' : ''}`}\n style={{ flexGrow: Math.max(1, shot.end - shot.start), flexBasis: 0 }}\n title={`${shot.label ?? shot.id} · ${seconds(shot.end - shot.start)}`}\n data-shot={shot.id}\n data-issue={mark ?? undefined}\n onClick={() => {\n controller.select({ shot: shot.id });\n controller.seekShot(shot.id);\n }}\n >\n {mark && <span className={mark === 'error' ? 'text-red-500' : 'text-amber-500'}>● </span>}\n {shot.label ?? shot.id}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n","import React, { useMemo, useState } from 'react';\nimport { indexMotionNodes, motionIssueLine, type AnimationEditorController, type MotionFrameOptions, type MotionOnionSkin } from '@pixerate/editor/animation-editor';\nimport { AnimationStage } from './AnimationStage';\nimport { CommandInspector } from './CommandInspector';\nimport { CommandList } from './CommandList';\nimport { PlayheadScrubber } from './PlayheadScrubber';\nimport { SceneSettings } from './SceneSettings';\nimport { ShotInspector } from './ShotInspector';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface AnimationEditorProps {\n controller: AnimationEditorController;\n values?: MotionFrameOptions['values'];\n /** Faded frames either side of the playhead (see `<AnimationStage onionSkin>`). Default: an Onion skin toggle. */\n onionSkin?: MotionOnionSkin;\n /** Draw where nodes travel (see `<AnimationStage motionPaths>`). Default: a Motion paths toggle. */\n motionPaths?: boolean | readonly string[];\n /** List the scene's issues under the timeline (default true). */\n showIssues?: boolean;\n /**\n * Show the hand-editing panels: the command list and inspector, the shot inspector, scene\n * settings, undo / redo and picking on the stage (default true). False shows the stage,\n * scrubber and issues only.\n */\n editable?: boolean;\n className?: string;\n}\n\nconst ONION: MotionOnionSkin = { before: 3, after: 1 };\nconst btn = 'rounded border border-border px-2 py-0.5 text-xs disabled:opacity-40';\n\n/**\n * A whole animation editor for an `AnimationEditorController`: the stage (click an element to\n * pick it, shift-click to add it to or remove it from the selected command's targets), the\n * playhead scrubber, and panels to edit commands, shots and scene settings by hand. Every edit\n * is one undo step.\n */\nexport function AnimationEditor({ controller, values, onionSkin, motionPaths, showIssues = true, editable = true, className = '' }: AnimationEditorProps) {\n const state = useAnimationEditorState(controller);\n const { issues, scene, selection, readOnly } = state;\n const [picked, setPicked] = useState<string | null>(null);\n const [onion, setOnion] = useState(false);\n const [paths, setPaths] = useState(false);\n const command = selection?.command !== undefined ? scene.shots.find((s) => s.id === selection.shot)?.run[selection.command] : undefined;\n const targets = command && 'targets' in command ? command.targets : [];\n const nodes = useMemo(() => indexMotionNodes(scene.artwork.nodes), [scene.artwork]);\n const pickedValid = picked && nodes.has(picked) ? picked : null;\n const onPick = (id: string | null, event: { shiftKey: boolean }) => {\n if (event.shiftKey && id && command && 'targets' in command && selection?.command !== undefined && !readOnly) {\n const next = targets.includes(id) ? targets.filter((t) => t !== id) : [...targets, id];\n if (next.length) controller.apply({ op: 'update_command', shot: selection.shot, command: selection.command, set: { targets: next } }, next.length > targets.length ? 'Add target' : 'Remove target');\n return;\n }\n setPicked(id);\n };\n const stage = (\n <AnimationStage\n controller={controller}\n values={values}\n onionSkin={onionSkin ?? (onion ? ONION : undefined)}\n motionPaths={motionPaths ?? paths}\n onPick={editable ? onPick : undefined}\n highlight={editable ? [...(pickedValid ? [pickedValid] : []), ...targets] : undefined}\n className=\"rounded-md border border-border bg-muted/40\"\n />\n );\n const issueList = showIssues && issues.length > 0 && (\n <ul className=\"space-y-0.5 text-xs\" aria-label=\"Animation issues\">\n {issues.map((issue, i) => (\n <li key={i} className={issue.severity === 'error' ? 'text-red-500' : issue.severity === 'warning' ? 'text-amber-500' : 'text-muted-foreground'}>\n {motionIssueLine(issue)}\n </li>\n ))}\n </ul>\n );\n if (!editable)\n return (\n <div className={`flex flex-col gap-2 ${className}`} data-animation-editor=\"\">\n {stage}\n <PlayheadScrubber controller={controller} />\n {issueList}\n </div>\n );\n\n return (\n <div\n className={`grid gap-3 lg:grid-cols-[minmax(0,1fr)_20rem] ${className}`}\n data-animation-editor=\"\"\n onKeyDown={(e) => {\n const el = e.target as HTMLElement;\n if (!(e.metaKey || e.ctrlKey) || e.key.toLowerCase() !== 'z' || /^(INPUT|TEXTAREA|SELECT)$/.test(el.tagName)) return;\n e.preventDefault();\n if (e.shiftKey) controller.redo();\n else controller.undo();\n }}\n >\n <div className=\"flex min-w-0 flex-col gap-2\">\n {stage}\n <PlayheadScrubber controller={controller} />\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-muted-foreground\">\n <button type=\"button\" className={btn} onClick={() => controller.undo()} disabled={!state.canUndo} title={state.canUndo ? `Undo ${state.undoLabel}` : 'Nothing to undo'} data-undo=\"\">\n Undo\n </button>\n <button type=\"button\" className={btn} onClick={() => controller.redo()} disabled={!state.canRedo} title={state.canRedo ? `Redo ${state.redoLabel}` : 'Nothing to redo'} data-redo=\"\">\n Redo\n </button>\n {onionSkin === undefined && (\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" checked={onion} onChange={(e) => setOnion(e.target.checked)} /> Onion skin\n </label>\n )}\n {motionPaths === undefined && (\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" checked={paths} onChange={(e) => setPaths(e.target.checked)} /> Motion paths\n </label>\n )}\n <span className=\"ml-auto\" data-picked-element={pickedValid ?? undefined}>\n {pickedValid ? (\n <>\n Picked <code className=\"text-rose-500\">{pickedValid}</code>{' '}\n <button type=\"button\" className=\"underline\" onClick={() => setPicked(null)}>\n clear\n </button>\n </>\n ) : (\n 'Click the stage to pick an element; shift-click to toggle it as a target.'\n )}\n </span>\n </div>\n {issueList}\n </div>\n <div className=\"flex min-w-0 flex-col gap-3\">\n <CommandList controller={controller} targets={pickedValid ? [pickedValid] : undefined} />\n <CommandInspector controller={controller} picked={pickedValid} className=\"border-t border-border pt-2\" />\n <details open className=\"border-t border-border pt-2\">\n <summary className=\"cursor-pointer text-xs font-medium\">Shot</summary>\n <ShotInspector controller={controller} className=\"mt-1\" />\n </details>\n <details className=\"border-t border-border pt-2\">\n <summary className=\"cursor-pointer text-xs font-medium\">Scene settings</summary>\n <SceneSettings controller={controller} className=\"mt-1\" />\n </details>\n </div>\n </div>\n );\n}\n","import React, { useMemo, useState } from 'react';\nimport {\n describeMotionElements,\n motionCommandFields,\n motionFieldEdit,\n motionFlairPrimitive,\n type AnimationEditorController,\n type MotionFieldSpec,\n} from '@pixerate/editor/animation-editor';\nimport { EasePicker } from './EasePicker';\nimport { CommitInput } from './CommitInput';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface CommandInspectorProps {\n controller: AnimationEditorController;\n /** An element picked on the stage, offered as a target to add. */\n picked?: string | null;\n className?: string;\n}\n\nconst input = 'w-full min-w-0 rounded border border-border bg-transparent px-1 py-0.5 text-xs';\n\n\n/**\n * A form for the selected command, generated from `MOTION_COMMAND_SCHEMA` (the schema the\n * agent tools take): enums as selects, numbers with their units and limits, node pickers for\n * targets and for `into` / `path`, and an ease picker. Shows the Flair primitive it plays.\n */\nexport function CommandInspector({ controller, picked, className = '' }: CommandInspectorProps) {\n const state = useAnimationEditorState(controller);\n const { scene, selection, readOnly, error } = state;\n const [local, setLocalState] = useState<{ text: string; revision: number } | null>(null);\n const setLocal = (text: string | null) => setLocalState(text ? { text, revision: state.revision } : null);\n const elements = useMemo(() => describeMotionElements(scene), [scene.artwork]);\n const shot = selection ? scene.shots.find((s) => s.id === selection.shot) : undefined;\n const index = selection?.command;\n const command = shot && index !== undefined ? shot.run[index] : undefined;\n if (!shot || index === undefined || !command) {\n return (\n <div className={`text-xs text-muted-foreground ${className}`} data-command-inspector=\"\">\n Select a command to edit it.\n </div>\n );\n }\n const values = command as unknown as Record<string, unknown>;\n const fields = motionCommandFields(command.type);\n const primitive = motionFlairPrimitive(command);\n const commit = (field: MotionFieldSpec, raw: Parameters<typeof motionFieldEdit>[3]) => {\n const edit = motionFieldEdit(shot.id, index, field, raw);\n if ('error' in edit) return setLocal(edit.error);\n setLocal(null);\n controller.apply(edit, `Set ${field.label.toLowerCase()}`);\n };\n const name = (id: string) => elements.find((e) => e.id === id)?.name ?? id;\n const targets = (values.targets as string[] | undefined) ?? [];\n // A local error shows until the editor changes; then the editor's own error (if any) shows.\n const message = (local && local.revision === state.revision ? local.text : null) ?? error;\n\n const control = (field: MotionFieldSpec) => {\n const v = values[field.name];\n const common = { disabled: readOnly, 'aria-label': field.label, title: field.description };\n switch (field.kind) {\n case 'targets':\n return (\n <div className=\"flex flex-wrap items-center gap-1\" data-targets=\"\">\n {targets.map((id) => (\n <span key={id} className=\"flex items-center gap-0.5 rounded bg-muted px-1 text-[11px]\" data-target={id}>\n {name(id)}\n {!readOnly && targets.length > 1 && (\n <button type=\"button\" aria-label={`Remove ${id}`} onClick={() => commit(field, targets.filter((t) => t !== id))}>\n ×\n </button>\n )}\n </span>\n ))}\n {!readOnly && picked && !targets.includes(picked) && (\n <button type=\"button\" className=\"rounded border border-rose-500 px-1 text-[11px] text-rose-500\" onClick={() => commit(field, [...targets, picked])} data-add-picked=\"\">\n + {name(picked)}\n </button>\n )}\n {!readOnly && (\n <select className=\"rounded border border-border bg-transparent px-1 py-0.5 text-[11px]\" aria-label=\"Add target\" value=\"\" onChange={(e) => e.target.value && commit(field, [...targets, e.target.value])}>\n <option value=\"\">+ target…</option>\n {elements.filter((e) => !targets.includes(e.id)).map((e) => (\n <option key={e.id} value={e.id}>\n {e.name ? `${e.name} (${e.id})` : e.id}\n </option>\n ))}\n </select>\n )}\n </div>\n );\n case 'node':\n return (\n <select className={input} {...common} value={typeof v === 'string' ? v : ''} onChange={(e) => commit(field, e.target.value)}>\n {!field.required && <option value=\"\">—</option>}\n {elements.filter((e) => field.name !== 'path' || e.type === 'path').map((e) => (\n <option key={e.id} value={e.id}>\n {e.name ? `${e.name} (${e.id})` : e.id}\n {e.hidden ? ' · hidden' : ''}\n </option>\n ))}\n </select>\n );\n case 'enum':\n return (\n <select className={input} {...common} value={typeof v === 'string' ? v : ''} onChange={(e) => commit(field, e.target.value)}>\n {!field.required && <option value=\"\">default</option>}\n {field.options!.map((o) => (\n <option key={o} value={o}>\n {o}\n </option>\n ))}\n </select>\n );\n case 'boolean':\n return <input type=\"checkbox\" {...common} checked={v === true} onChange={(e) => commit(field, e.target.checked)} />;\n case 'ease':\n return <EasePicker value={v as never} disabled={readOnly} onChange={(ease) => commit(field, ease === undefined ? '' : (ease as string))} />;\n case 'color':\n return (\n <div className=\"flex items-center gap-1\">\n <input type=\"color\" disabled={readOnly} aria-label={`${field.label} swatch`} value={typeof v === 'string' && /^#[0-9a-f]{6}$/i.test(v) ? v : '#000000'} onChange={(e) => commit(field, e.target.value)} />\n <CommitInput className={input} {...common} value={typeof v === 'string' ? v : ''} placeholder=\"unchanged\" onCommit={(raw) => commit(field, raw)} />\n </div>\n );\n case 'point': {\n const p = (v as { x: number; y: number } | undefined) ?? undefined;\n return (\n <div className=\"flex items-center gap-1\">\n {(['x', 'y'] as const).map((axis) => (\n <CommitInput\n key={axis}\n className={input}\n type=\"number\"\n disabled={readOnly}\n aria-label={`${field.label} ${axis}`}\n placeholder={axis}\n value={p ? String(p[axis]) : ''}\n onCommit={(raw) => commit(field, axis === 'x' ? { x: raw, y: p ? String(p.y) : raw ? '0' : '' } : { x: p ? String(p.x) : raw ? '0' : '', y: raw })}\n />\n ))}\n </div>\n );\n }\n case 'scale':\n case 'number':\n case 'integer':\n return (\n <div className=\"flex items-center gap-1\">\n <CommitInput\n className={input}\n type=\"number\"\n {...common}\n min={field.min}\n max={field.max}\n step={field.kind === 'integer' ? 1 : field.unit === 'ms' ? 50 : field.unit === '0–1' ? 0.05 : 'any'}\n placeholder=\"default\"\n value={typeof v === 'number' ? String(v) : ''}\n onCommit={(raw) => commit(field, raw)}\n />\n {field.unit && <span className=\"shrink-0 text-[10px] text-muted-foreground\">{field.unit}</span>}\n </div>\n );\n default:\n return <CommitInput className={input} {...common} value={typeof v === 'string' ? v : ''} onCommit={(raw) => commit(field, raw)} />;\n }\n };\n\n return (\n <div className={`flex flex-col gap-1.5 text-xs ${className}`} data-command-inspector=\"\" data-command-type={command.type}>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">\n {index + 1}. {command.type}\n </span>\n {primitive ? (\n <code className=\"rounded bg-muted px-1 text-[10px]\" data-flair-primitive={primitive} title=\"The Flair motion primitive this command plays\">\n {primitive}\n </code>\n ) : (\n <span className=\"text-[10px] text-muted-foreground\">editor-only (no Flair primitive)</span>\n )}\n </div>\n {(['main', 'timing'] as const).map((group) => (\n <fieldset key={group} className=\"grid grid-cols-[6.5rem_1fr] items-center gap-x-2 gap-y-1\">\n <legend className=\"mb-1 text-[10px] uppercase tracking-wide text-muted-foreground\">{group === 'main' ? 'Command' : 'Timing'}</legend>\n {fields\n .filter((f) => f.group === group)\n .map((field) => (\n <React.Fragment key={field.name}>\n <label className=\"truncate text-muted-foreground\" title={field.description}>\n {field.label}\n {field.required ? ' *' : ''}\n </label>\n <div data-field={field.name}>{control(field)}</div>\n </React.Fragment>\n ))}\n </fieldset>\n ))}\n {message && (\n <p className=\"text-red-500\" role=\"alert\" data-edit-error=\"\">\n {message}\n </p>\n )}\n </div>\n );\n}\n","import React, { useMemo } from 'react';\nimport { MOTION_EASE_CHOICES, motionEaseKey, motionEasingCurve, motionEasingGuides, motionEasingPath, type MotionCommandBase } from '@pixerate/editor/animation-editor';\n\n/** An easing (a preset name or a curve), as commands take it. */\ntype AnimationEasing = NonNullable<MotionCommandBase['ease']>;\n\nexport interface EasePickerProps {\n /** The easing (undefined: the command type's default). */\n value: AnimationEasing | undefined;\n /** Called with the picked preset, or undefined for the default. */\n onChange: (ease: AnimationEasing | undefined) => void;\n disabled?: boolean;\n className?: string;\n}\n\nconst W = 72;\nconst H = 44;\n\n/**\n * Picks an easing preset (springs included) and previews its curve, drawn by sampling\n * `evaluateEasing`; a spring is drawn over the time it takes to settle, overshoot included.\n */\nexport function EasePicker({ value, onChange, disabled, className = '' }: EasePickerProps) {\n const key = motionEaseKey(value);\n const curve = useMemo(() => motionEasingCurve(value ?? 'ease-out'), [value]);\n const guides = motionEasingGuides(curve, H);\n const spring = typeof value === 'string' ? value.startsWith('spring') : value?.type === 'spring';\n return (\n <div className={`flex items-center gap-2 ${className}`} data-ease-picker=\"\">\n <select\n className=\"min-w-0 flex-1 rounded border border-border bg-transparent px-1 py-0.5 text-xs\"\n aria-label=\"Ease\"\n value={key}\n disabled={disabled}\n onChange={(e) => {\n if (e.target.value === 'custom') return;\n onChange(e.target.value ? (e.target.value as AnimationEasing) : undefined);\n }}\n >\n {MOTION_EASE_CHOICES.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n {key === 'custom' && <option value=\"custom\">Custom</option>}\n </select>\n <svg width={W} height={H} viewBox={`0 0 ${W} ${H}`} className=\"shrink-0 rounded border border-border\" data-ease-curve={key || 'default'} aria-hidden=\"true\">\n <line x1={0} x2={W} y1={guides.zero} y2={guides.zero} stroke=\"currentColor\" strokeOpacity={0.2} />\n <line x1={0} x2={W} y1={guides.one} y2={guides.one} stroke=\"currentColor\" strokeOpacity={0.2} strokeDasharray=\"2 2\" />\n <path d={motionEasingPath(curve, W, H)} fill=\"none\" stroke=\"#f43f5e\" strokeWidth={1.5} />\n </svg>\n {spring && <span className=\"text-[10px] tabular-nums text-muted-foreground\">{Math.round(curve.durationMs)} ms</span>}\n </div>\n );\n}\n","import React from 'react';\n\n/** An input that commits on blur or Enter, and resets when its value changes from outside. */\nexport function CommitInput({ value, onCommit, ...rest }: { value: string; onCommit: (raw: string) => void } & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'defaultValue'>) {\n return (\n <input\n key={value}\n {...rest}\n defaultValue={value}\n onKeyDown={(e) => e.key === 'Enter' && e.currentTarget.blur()}\n onBlur={(e) => {\n if (e.currentTarget.value !== value) onCommit(e.currentTarget.value);\n }}\n />\n );\n}\n","import React, { useState } from 'react';\nimport {\n MOTION_COMMAND_TYPES,\n defaultMotionCommand,\n duplicateMotionCommandEdit,\n motionCommandRows,\n type AnimationEditorController,\n type MotionCommandType,\n} from '@pixerate/editor/animation-editor';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface CommandListProps {\n controller: AnimationEditorController;\n /** The shot to list (default: the selected shot, else the first). */\n shot?: string;\n /** Targets for a new command (e.g. the element picked on the stage); default: the selected command's. */\n targets?: readonly string[];\n className?: string;\n}\n\nconst btn = 'rounded border border-border px-1.5 py-0.5 text-[11px] disabled:opacity-40';\n\n/**\n * A shot's commands in order: select one to inspect it, change `with` and `delay` inline, move,\n * duplicate or delete it, and add new ones. Each change is one `controller.apply` edit (one undo\n * step); a refused edit shows its reason.\n */\nexport function CommandList({ controller, shot, targets, className = '' }: CommandListProps) {\n const state = useAnimationEditorState(controller);\n const { scene, selection, readOnly, error } = state;\n const shotId = shot ?? selection?.shot ?? scene.shots[0]?.id;\n const current = scene.shots.find((s) => s.id === shotId);\n const [type, setType] = useState<MotionCommandType>('enter');\n const [local, setLocalState] = useState<{ text: string; revision: number } | null>(null);\n const setLocal = (text: string | null) => setLocalState(text ? { text, revision: state.revision } : null);\n if (!current) return <div className={`text-xs text-muted-foreground ${className}`} data-command-list=\"\">Add a shot to start.</div>;\n const rows = motionCommandRows(scene, current.id);\n const selected = selection?.shot === current.id ? selection.command : undefined;\n const run = (edit: Parameters<AnimationEditorController['apply']>[0], label: string) => {\n setLocal(null);\n return controller.apply(edit, label);\n };\n const add = () => {\n const from = targets?.length ? targets : selected !== undefined ? ((current.run[selected] as { targets?: string[] }).targets ?? []) : [];\n const command = defaultMotionCommand(type, from, scene);\n if ('error' in command) return setLocal(command.error);\n const at = selected !== undefined ? selected + 1 : current.run.length;\n const result = run({ op: 'add_commands', shot: current.id, commands: [command], at }, `Add ${type}`);\n if (result.ok) controller.select({ shot: current.id, command: at });\n };\n // A local error shows until the editor changes; then the editor's own error (if any) shows.\n const message = (local && local.revision === state.revision ? local.text : null) ?? error;\n\n return (\n <div className={`flex flex-col gap-1 text-xs ${className}`} data-command-list=\"\" data-for-shot={current.id}>\n <div className=\"font-medium\">\n Commands in <span className=\"text-rose-500\">{current.label ?? current.id}</span>\n </div>\n <ol className=\"flex flex-col gap-1\" aria-label=\"Commands\">\n {rows.map((row) => {\n const c = row.command as { with?: string; delay?: number };\n const isSelected = row.index === selected;\n return (\n <li\n key={`${row.index}:${row.summary}`}\n className={`flex flex-wrap items-center gap-1 rounded border px-1.5 py-1 ${isSelected ? 'border-rose-500 bg-rose-500/10' : 'border-border'}`}\n data-command={row.index}\n data-selected={isSelected || undefined}\n onClick={() => controller.select({ shot: current.id, command: row.index })}\n >\n <span className=\"min-w-0 flex-1 truncate\" title={row.summary}>\n {row.index + 1}. {row.summary}\n </span>\n {row.flairPrimitive && (\n <code className=\"rounded bg-muted px-1 text-[10px] text-muted-foreground\" data-flair-primitive={row.flairPrimitive}>\n {row.flairPrimitive}\n </code>\n )}\n <span className=\"tabular-nums text-[10px] text-muted-foreground\">{((row.end - row.start) / 1000).toFixed(2)} s</span>\n <div className=\"flex w-full items-center gap-1\" onClick={(e) => e.stopPropagation()}>\n <select\n className=\"rounded border border-border bg-transparent px-1 py-0.5 text-[11px]\"\n aria-label=\"Starts\"\n value={c.with ?? 'after'}\n disabled={readOnly || row.index === 0}\n onChange={(e) =>\n run(\n e.target.value === 'after' ? { op: 'update_command', shot: current.id, command: row.index, remove: ['with'] } : { op: 'update_command', shot: current.id, command: row.index, set: { with: e.target.value } },\n 'Change start',\n )\n }\n >\n <option value=\"after\">after previous</option>\n <option value=\"previous\">with previous</option>\n </select>\n <label className=\"flex items-center gap-0.5 text-muted-foreground\">\n +\n <input\n key={String(c.delay ?? '')}\n className=\"w-14 rounded border border-border bg-transparent px-1 py-0.5 text-[11px] tabular-nums\"\n type=\"number\"\n min={0}\n step={50}\n aria-label=\"Delay\"\n placeholder=\"0\"\n defaultValue={c.delay ?? ''}\n disabled={readOnly}\n onKeyDown={(e) => e.key === 'Enter' && e.currentTarget.blur()}\n onBlur={(e) => {\n const raw = e.currentTarget.value.trim();\n if (raw === String(c.delay ?? '')) return;\n const n = Number(raw);\n if (raw && !(Number.isFinite(n) && n >= 0)) return setLocal('Delay must be a number of ms, 0 or more.');\n run(raw && n > 0 ? { op: 'update_command', shot: current.id, command: row.index, set: { delay: n } } : { op: 'update_command', shot: current.id, command: row.index, remove: ['delay'] }, 'Change delay');\n }}\n />\n ms\n </label>\n <span className=\"ml-auto flex gap-0.5\">\n <button type=\"button\" className={btn} aria-label=\"Move up\" disabled={readOnly || row.index === 0} onClick={() => run({ op: 'move_command', shot: current.id, command: row.index, to: row.index - 1 }, 'Move command').ok && controller.select({ shot: current.id, command: row.index - 1 })}>\n ↑\n </button>\n <button type=\"button\" className={btn} aria-label=\"Move down\" disabled={readOnly || row.index === rows.length - 1} onClick={() => run({ op: 'move_command', shot: current.id, command: row.index, to: row.index + 1 }, 'Move command').ok && controller.select({ shot: current.id, command: row.index + 1 })}>\n ↓\n </button>\n <button type=\"button\" className={btn} aria-label=\"Duplicate\" disabled={readOnly} onClick={() => run(duplicateMotionCommandEdit(scene, current.id, row.index), 'Duplicate command').ok && controller.select({ shot: current.id, command: row.index + 1 })}>\n ⧉\n </button>\n <button type=\"button\" className={btn} aria-label=\"Delete\" disabled={readOnly} onClick={() => run({ op: 'delete_commands', shot: current.id, commands: [row.index] }, 'Delete command')}>\n ✕\n </button>\n </span>\n </div>\n </li>\n );\n })}\n </ol>\n {!readOnly && (\n <div className=\"flex items-center gap-1\">\n <select className=\"flex-1 rounded border border-border bg-transparent px-1 py-0.5\" aria-label=\"New command type\" value={type} onChange={(e) => setType(e.target.value as MotionCommandType)}>\n {MOTION_COMMAND_TYPES.map((t) => (\n <option key={t} value={t}>\n {t}\n </option>\n ))}\n </select>\n <button type=\"button\" className={btn} onClick={add} data-add-command=\"\">\n Add command\n </button>\n </div>\n )}\n {message && (\n <p className=\"text-red-500\" role=\"alert\" data-edit-error=\"\">\n {message}\n </p>\n )}\n </div>\n );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { motionBeatTime, motionCueTime, motionRulerTicks, type AnimationEditorController, type MotionIssue } from '@pixerate/editor/animation-editor';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface PlayheadScrubberProps {\n controller: AnimationEditorController;\n className?: string;\n}\n\nconst seconds = (ms: number) => `${(ms / 1000).toFixed(2)} s`;\n\nfunction worst(issues: readonly MotionIssue[]): 'error' | 'warning' | null {\n if (issues.some((i) => i.severity === 'error')) return 'error';\n if (issues.some((i) => i.severity === 'warning')) return 'warning';\n return null;\n}\n\n/**\n * Play, pause and loop, a time ruler (with the beat grid and narration words when the scene has\n * them) to scrub by dragging, and one band per shot (as wide as it is long): click a band to\n * select the shot and jump to its start. Loop is a scene setting, so changing it is one undo step.\n */\nexport function PlayheadScrubber({ controller, className = '' }: PlayheadScrubberProps) {\n const state = useAnimationEditorState(controller);\n const { duration, shots, time, playing, selection, issues, scene, readOnly } = state;\n const span = Math.max(1, duration);\n const track = useRef<HTMLDivElement>(null);\n const [width, setWidth] = useState(600);\n useEffect(() => {\n const el = track.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => setWidth(el.clientWidth || 600));\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n const ticks = motionRulerTicks(duration, width);\n const pct = (ms: number) => `${(Math.min(span, Math.max(0, ms)) / span) * 100}%`;\n const seekAt = (clientX: number) => {\n const box = track.current!.getBoundingClientRect();\n controller.seek(Math.min(1, Math.max(0, (clientX - box.left) / Math.max(1, box.width))) * span);\n };\n const beats: number[] = [];\n if (scene.beat && scene.beat.bpm > 0) for (let b = 0, t = motionBeatTime(scene.beat, 0); t <= span && beats.length < 400; t = motionBeatTime(scene.beat, ++b)) if (t >= 0) beats.push(t);\n\n return (\n <div className={`flex flex-col gap-1 ${className}`} data-playhead-scrubber=\"\" data-shot-timeline=\"\">\n <div className=\"flex items-center gap-2 text-xs\">\n <button type=\"button\" className=\"rounded border border-border px-2 py-0.5\" onClick={() => controller.toggle()} aria-label={playing ? 'Pause' : 'Play'} disabled={!shots.length}>\n {playing ? 'Pause' : 'Play'}\n </button>\n <button type=\"button\" className=\"rounded border border-border px-2 py-0.5\" onClick={() => { controller.pause(); controller.seek(0); }} aria-label=\"Back to start\">\n ⏮\n </button>\n <label className=\"flex items-center gap-1 text-muted-foreground\">\n Loop\n <select\n className=\"rounded border border-border bg-transparent px-1 py-0.5\"\n value={scene.loop ?? 'none'}\n disabled={readOnly}\n aria-label=\"Loop\"\n onChange={(e) => controller.apply({ op: 'set_settings', loop: e.target.value as 'none' | 'loop' | 'ping-pong' }, 'Change loop')}\n >\n <option value=\"none\">Off</option>\n <option value=\"loop\">Loop</option>\n <option value=\"ping-pong\">Ping-pong</option>\n </select>\n </label>\n <span className=\"ml-auto tabular-nums text-muted-foreground\" data-time=\"\">\n {seconds(time)} / {seconds(duration)}\n </span>\n </div>\n <div\n ref={track}\n className=\"relative cursor-ew-resize select-none touch-none\"\n role=\"slider\"\n aria-label=\"Playhead\"\n aria-valuemin={0}\n aria-valuemax={duration}\n aria-valuenow={Math.round(time)}\n tabIndex={0}\n data-scrub-track=\"\"\n onPointerDown={(e) => {\n e.currentTarget.setPointerCapture?.(e.pointerId);\n seekAt(e.clientX);\n }}\n onPointerMove={(e) => {\n if (e.buttons & 1) seekAt(e.clientX);\n }}\n onKeyDown={(e) => {\n const step = e.shiftKey ? 1000 : 100;\n if (e.key === 'ArrowRight') controller.seek(time + step);\n else if (e.key === 'ArrowLeft') controller.seek(time - step);\n else if (e.key === 'Home') controller.seek(0);\n else if (e.key === 'End') controller.seek(duration);\n else if (e.key === ' ') controller.toggle();\n else return;\n e.preventDefault();\n }}\n >\n <div className=\"relative h-5 border-b border-border text-[10px] text-muted-foreground\" data-ruler=\"\">\n {beats.map((t, i) => (\n <div key={`b${i}`} className=\"absolute bottom-0 h-1.5 w-px bg-sky-500/60\" style={{ left: pct(t) }} data-beat={i} />\n ))}\n {scene.narration?.words.map((w, i) => (\n <div key={`w${i}`} className=\"absolute top-0 h-1.5 w-px bg-emerald-500/70\" style={{ left: pct(w.start) }} title={`“${w.text}” at ${seconds(w.start)}`} data-word={i} />\n ))}\n {ticks.map((t) => (\n <div key={t.time} className={`absolute bottom-0 w-px ${t.major ? 'h-2.5 bg-muted-foreground/70' : 'h-1 bg-muted-foreground/40'}`} style={{ left: pct(t.time) }}>\n {t.label && <span className=\"absolute -top-0.5 left-1 whitespace-nowrap tabular-nums\">{t.label}</span>}\n </div>\n ))}\n </div>\n <div className=\"mt-1 flex w-full gap-px\" role=\"group\" aria-label=\"Shots\">\n {shots.map((shot, i) => {\n const mark = worst(issues.filter((x) => x.shot === shot.id));\n const selected = selection?.shot === shot.id;\n const cue = scene.shots[i]?.at;\n const cueTime = cue ? motionCueTime(scene, cue) : undefined;\n return (\n <button\n key={shot.id}\n type=\"button\"\n className={`relative min-w-0 truncate rounded border px-1 py-1 text-left text-[11px] ${selected ? 'border-rose-500 bg-rose-500/10' : 'border-border bg-muted/40'} ${state.currentShot === shot.id ? 'font-semibold' : ''}`}\n style={{ flexGrow: Math.max(1, shot.end - shot.start), flexBasis: 0 }}\n title={`${shot.label ?? shot.id} · ${seconds(shot.start)}–${seconds(shot.end)}${cueTime !== undefined ? ` · cued at ${seconds(cueTime)}` : ''}`}\n data-shot={shot.id}\n data-issue={mark ?? undefined}\n onPointerDown={(e) => e.stopPropagation()}\n onClick={() => {\n controller.select({ shot: shot.id });\n controller.seekShot(shot.id);\n }}\n >\n {mark && <span className={mark === 'error' ? 'text-red-500' : 'text-amber-500'}>● </span>}\n {shot.label ?? shot.id}\n </button>\n );\n })}\n </div>\n <div className=\"pointer-events-none absolute inset-y-0 w-0.5 -translate-x-1/2 bg-rose-500\" style={{ left: pct(time) }} data-playhead=\"\" />\n </div>\n </div>\n );\n}\n","import React, { useState } from 'react';\nimport { fitMotionSceneEdits, formatMotionDrivers, formatMotionNarration, parseMotionDrivers, parseMotionNarration, type AnimationEditorController, type MotionEdit, type MotionTrigger } from '@pixerate/editor/animation-editor';\nimport { CommitInput } from './CommitInput';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface SceneSettingsProps {\n controller: AnimationEditorController;\n className?: string;\n}\n\nconst input = 'w-full min-w-0 rounded border border-border bg-transparent px-1 py-0.5 text-xs';\nconst btn = 'rounded border border-border px-1.5 py-0.5 text-[11px] disabled:opacity-40';\nconst unit = (u: string) => <span className=\"shrink-0 text-[10px] text-muted-foreground\">{u}</span>;\n\n/**\n * Scene settings: loop, frame rate, stepped time, the wanted length with a Fit button (sets the\n * shots' speeds with `fitMotionScene`, as `fit_animation` does), a beat grid and narration words\n * to cue shots to. Every change is one undo step; refusals show their reason.\n */\nexport function SceneSettings({ controller, className = '' }: SceneSettingsProps) {\n const state = useAnimationEditorState(controller);\n const { scene, readOnly, error, duration } = state;\n const [local, setLocalState] = useState<{ text: string; revision: number } | null>(null);\n const setLocal = (text: string | null) => setLocalState(text ? { text, revision: state.revision } : null);\n const [fitTo, setFitTo] = useState<string>('');\n const apply = (edit: MotionEdit | MotionEdit[], label: string) => {\n setLocal(null);\n return controller.apply(edit, label);\n };\n const settings = (set: Omit<Extract<MotionEdit, { op: 'set_settings' }>, 'op'>, label: string) => apply({ op: 'set_settings', ...set }, label);\n const num = (raw: string, what: string, ok: (n: number) => boolean, then: (n: number | null) => void) => {\n if (raw.trim() === '') return then(null);\n const n = Number(raw);\n if (!Number.isFinite(n) || !ok(n)) return setLocal(what);\n then(n);\n };\n const target = scene.target;\n const fitSeconds = fitTo || String(target ? (target[0] + target[1]) / 2 : Math.round(duration / 100) / 10);\n const fit = () => {\n const s = Number(fitSeconds);\n if (!(Number.isFinite(s) && s > 0)) return setLocal('Give the length to fit in seconds, above 0.');\n try {\n const edits = fitMotionSceneEdits(scene, s * 1000);\n if (edits.length) apply(edits, `Fit to ${s} s`);\n else setLocal(null);\n } catch (e) {\n setLocal((e as Error).message);\n }\n };\n const beat = scene.beat;\n // A local error shows until the editor changes; then the editor's own error (if any) shows.\n const message = (local && local.revision === state.revision ? local.text : null) ?? error;\n\n return (\n <div className={`flex flex-col gap-1.5 text-xs ${className}`} data-scene-settings=\"\">\n <div className=\"grid grid-cols-[6.5rem_1fr] items-center gap-x-2 gap-y-1\">\n <label className=\"text-muted-foreground\">Loop</label>\n <select className={input} aria-label=\"Scene loop\" disabled={readOnly} value={scene.loop ?? 'none'} onChange={(e) => settings({ loop: e.target.value as 'none' }, 'Change loop')}>\n <option value=\"none\">Off</option>\n <option value=\"loop\">Loop</option>\n <option value=\"ping-pong\">Ping-pong</option>\n </select>\n <label className=\"text-muted-foreground\">Motion blur</label>\n <select className={input} aria-label=\"Motion blur\" disabled={readOnly} value={scene.motionBlur ? String(scene.motionBlur.shutter ?? 180) : ''} onChange={(e) => settings({ motionBlur: e.target.value ? { ...(scene.motionBlur ?? {}), shutter: Number(e.target.value) } : null }, 'Change motion blur')}>\n <option value=\"\">Off</option>\n <option value=\"90\">Light (90°)</option>\n <option value=\"180\">Normal (180°)</option>\n <option value=\"360\">Heavy (360°)</option>\n </select>\n <label className=\"text-muted-foreground\">Plays on</label>\n <select className={input} aria-label=\"Scene trigger\" title=\"How a viewer plays it when exported to Flair\" disabled={readOnly} value={scene.trigger ?? ''} onChange={(e) => settings({ trigger: (e.target.value || null) as MotionTrigger | null }, 'Change trigger')}>\n <option value=\"\">Its own (autoplay)</option>\n <option value=\"click\">Click (a shot per click)</option>\n <option value=\"hover\">Hover</option>\n <option value=\"press\">Press</option>\n <option value=\"scroll\">Scroll</option>\n </select>\n <label className=\"text-muted-foreground\">Frame rate</label>\n <div className=\"flex items-center gap-1\">\n <CommitInput className={input} type=\"number\" min={1} max={120} aria-label=\"Frame rate\" placeholder=\"30\" disabled={readOnly} value={scene.fps !== undefined ? String(scene.fps) : ''}\n onCommit={(raw) => num(raw, 'Frame rate must be 1 to 120 fps.', (n) => n >= 1 && n <= 120, (n) => n !== null && settings({ fps: n }, 'Change frame rate'))} />\n {unit('fps')}\n </div>\n <label className=\"text-muted-foreground\" title=\"Hold changes on a grid of this many frames a second (12 = on twos); empty is smooth\">\n Steps\n </label>\n <div className=\"flex items-center gap-1\">\n <CommitInput className={input} type=\"number\" min={1} max={120} aria-label=\"Steps\" placeholder=\"smooth\" disabled={readOnly} value={scene.steps !== undefined ? String(scene.steps) : ''}\n onCommit={(raw) => num(raw, 'Steps must be above 0 and at most 120 fps, or empty for smooth.', (n) => n > 0 && n <= 120, (n) => settings({ steps: n }, 'Change steps'))} />\n {unit('fps')}\n </div>\n <label className=\"text-muted-foreground\">Target length</label>\n <div className=\"flex items-center gap-1\">\n {[0, 1].map((i) => (\n <CommitInput key={i} className={input} type=\"number\" min={0} step={0.5} aria-label={i ? 'Target max' : 'Target min'} placeholder={i ? 'max' : 'min'} disabled={readOnly} value={target ? String(target[i]) : ''}\n onCommit={(raw) =>\n num(raw, 'Target lengths are seconds, 0 or more.', (n) => n >= 0, (n) => {\n if (n === null) return settings({ target: null }, 'Clear target length');\n const next: [number, number] = target ? [...target] : [n, n];\n next[i] = n;\n if (next[0] > next[1]) return setLocal('The shortest target length must not be longer than the longest.');\n settings({ target: next }, 'Change target length');\n })\n } />\n ))}\n {unit('s')}\n </div>\n <label className=\"text-muted-foreground\">Fit to</label>\n <div className=\"flex items-center gap-1\">\n <input className={input} type=\"number\" min={0.1} step={0.5} aria-label=\"Fit to\" value={fitSeconds} onChange={(e) => setFitTo(e.target.value)} />\n {unit('s')}\n <button type=\"button\" className={btn} disabled={readOnly || !scene.shots.length} onClick={fit} data-fit=\"\" title=\"Change the shots' speeds so the scene lasts this long\">\n Fit\n </button>\n </div>\n <label className=\"text-muted-foreground\">Beat grid</label>\n <div className=\"flex items-center gap-1\" data-beat-grid=\"\">\n <CommitInput className={input} type=\"number\" min={1} aria-label=\"BPM\" placeholder=\"bpm\" disabled={readOnly} value={beat ? String(beat.bpm) : ''}\n onCommit={(raw) => num(raw, 'BPM must be above 0.', (n) => n > 0, (n) => settings({ beat: n === null ? null : { ...(beat ?? {}), bpm: n } }, n === null ? 'Clear beat grid' : 'Change tempo'))} />\n <CommitInput className={input} type=\"number\" aria-label=\"Beat offset\" placeholder=\"offset ms\" disabled={readOnly || !beat} value={beat?.offset !== undefined ? String(beat.offset) : ''}\n onCommit={(raw) => beat && num(raw, 'The offset is a number of ms.', () => true, (n) => settings({ beat: { ...beat, offset: n ?? 0 } }, 'Change beat offset'))} />\n <CommitInput className={input} type=\"number\" min={1} step={1} aria-label=\"Meter\" placeholder=\"4/bar\" disabled={readOnly || !beat} value={beat?.meter !== undefined ? String(beat.meter) : ''}\n onCommit={(raw) => beat && num(raw, 'The meter is a whole number of beats a bar.', (n) => Number.isInteger(n) && n >= 1, (n) => settings({ beat: { ...beat, meter: n ?? 4 } }, 'Change meter'))} />\n </div>\n </div>\n <label className=\"flex flex-col gap-0.5\">\n <span className=\"text-muted-foreground\">Narration (a word a line: start ms, then the word)</span>\n <textarea\n key={formatMotionNarration(scene.narration)}\n className={`${input} h-20 font-mono`}\n aria-label=\"Narration\"\n placeholder={'0 Meet\\n320 the\\n480 badge'}\n disabled={readOnly}\n defaultValue={formatMotionNarration(scene.narration)}\n onBlur={(e) => {\n if (e.currentTarget.value === formatMotionNarration(scene.narration)) return;\n const parsed = parseMotionNarration(e.currentTarget.value);\n if ('error' in parsed) return setLocal(parsed.error);\n settings({ narration: parsed.narration }, parsed.narration ? 'Change narration' : 'Clear narration');\n }}\n />\n </label>\n <label className=\"flex flex-col gap-0.5\">\n <span className=\"text-muted-foreground\">Drivers (one a line: target.property &lt;- source.property * factor)</span>\n <textarea\n key={formatMotionDrivers(scene.drivers)}\n className={`${input} h-14 font-mono`}\n aria-label=\"Drivers\"\n placeholder={'back.x <- front.x * 0.5\\nwheel.rotation <- wheel.x * 2.86'}\n disabled={readOnly}\n defaultValue={formatMotionDrivers(scene.drivers)}\n onBlur={(e) => {\n if (e.currentTarget.value === formatMotionDrivers(scene.drivers)) return;\n const parsed = parseMotionDrivers(e.currentTarget.value);\n if ('error' in parsed) return setLocal(parsed.error);\n apply({ op: 'set_drivers', drivers: parsed.drivers }, parsed.drivers.length ? 'Set drivers' : 'Clear drivers');\n }}\n />\n </label>\n {message && (\n <p className=\"text-red-500\" role=\"alert\" data-edit-error=\"\">\n {message}\n </p>\n )}\n </div>\n );\n}\n","import React, { useMemo, useState } from 'react';\nimport { describeMotionElements, freshShotId, motionCueChoices, motionCueFromKey, motionCueKey, type AnimationEditorController, type MotionEdit } from '@pixerate/editor/animation-editor';\nimport { CommitInput } from './CommitInput';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface ShotInspectorProps {\n controller: AnimationEditorController;\n /** The shot to edit (default: the selected shot, else the first). */\n shot?: string;\n className?: string;\n}\n\nconst input = 'w-full min-w-0 rounded border border-border bg-transparent px-1 py-0.5 text-xs';\nconst btn = 'rounded border border-border px-1.5 py-0.5 text-[11px] disabled:opacity-40';\n\n\n/**\n * The selected shot: its label, hold, speed, the node the camera frames, and the cue it starts\n * on (a beat of the scene's grid or a narration word). Also adds, moves and deletes shots.\n * Every change is one undo step.\n */\nexport function ShotInspector({ controller, shot, className = '' }: ShotInspectorProps) {\n const state = useAnimationEditorState(controller);\n const { scene, selection, readOnly, error } = state;\n const [local, setLocalState] = useState<{ text: string; revision: number } | null>(null);\n const setLocal = (text: string | null) => setLocalState(text ? { text, revision: state.revision } : null);\n const elements = useMemo(() => describeMotionElements(scene), [scene.artwork]);\n const cues = useMemo(() => motionCueChoices(scene), [scene]);\n const id = shot ?? selection?.shot ?? scene.shots[0]?.id;\n const index = scene.shots.findIndex((s) => s.id === id);\n const current = scene.shots[index];\n const apply = (edit: MotionEdit | MotionEdit[], label: string) => {\n setLocal(null);\n return controller.apply(edit, label);\n };\n const addShot = () => {\n const newId = freshShotId(scene, 'shot');\n const at = index >= 0 ? index + 1 : scene.shots.length;\n if (apply({ op: 'insert_shots', shots: [{ id: newId, label: 'New shot', run: [] }], at }, 'Add shot').ok) {\n controller.select({ shot: newId });\n controller.seekShot(newId);\n }\n };\n const number = (key: 'hold' | 'speed', raw: string, label: string) => {\n const n = Number(raw);\n if (raw.trim() === '') return apply({ op: 'update_shot', shot: current.id, remove: [key] }, label);\n if (!Number.isFinite(n) || n < 0 || (key === 'speed' && n <= 0)) return setLocal(key === 'speed' ? 'Speed must be a number above 0 (1 = as written).' : 'Hold must be a number of ms, 0 or more.');\n apply({ op: 'update_shot', shot: current.id, set: { [key]: n } }, label);\n };\n // A local error shows until the editor changes; then the editor's own error (if any) shows.\n const message = (local && local.revision === state.revision ? local.text : null) ?? error;\n const cueKey = current ? motionCueKey(current.at) : '';\n const frame = current?.camera && 'frame' in current.camera ? current.camera.frame : '';\n\n return (\n <div className={`flex flex-col gap-1.5 text-xs ${className}`} data-shot-inspector=\"\">\n <div className=\"flex items-center gap-1\">\n <span className=\"font-medium\">Shot</span>\n {current && <code className=\"text-[10px] text-muted-foreground\">{current.id}</code>}\n <span className=\"ml-auto flex gap-0.5\">\n <button type=\"button\" className={btn} disabled={readOnly} onClick={addShot} data-add-shot=\"\">\n + Shot\n </button>\n {current && (\n <>\n <button type=\"button\" className={btn} aria-label=\"Move shot earlier\" disabled={readOnly || index === 0} onClick={() => apply({ op: 'move_shot', shot: current.id, to: index - 1 }, 'Move shot')}>\n ←\n </button>\n <button type=\"button\" className={btn} aria-label=\"Move shot later\" disabled={readOnly || index === scene.shots.length - 1} onClick={() => apply({ op: 'move_shot', shot: current.id, to: index + 1 }, 'Move shot')}>\n →\n </button>\n <button type=\"button\" className={btn} aria-label=\"Delete shot\" disabled={readOnly} onClick={() => apply({ op: 'delete_shots', shots: [current.id] }, 'Delete shot')}>\n ✕\n </button>\n </>\n )}\n </span>\n </div>\n {current && (\n <div className=\"grid grid-cols-[6.5rem_1fr] items-center gap-x-2 gap-y-1\">\n <label className=\"text-muted-foreground\">Label</label>\n <CommitInput className={input} aria-label=\"Shot label\" disabled={readOnly} value={current.label ?? ''} onCommit={(raw) => apply(raw.trim() ? { op: 'update_shot', shot: current.id, set: { label: raw.trim() } } : { op: 'update_shot', shot: current.id, remove: ['label'] }, 'Rename shot')} />\n <label className=\"text-muted-foreground\">Hold</label>\n <div className=\"flex items-center gap-1\">\n <CommitInput className={input} type=\"number\" min={0} step={50} aria-label=\"Hold\" placeholder=\"600\" disabled={readOnly} value={current.hold !== undefined ? String(current.hold) : ''} onCommit={(raw) => number('hold', raw, 'Change hold')} />\n <span className=\"text-[10px] text-muted-foreground\">ms</span>\n </div>\n <label className=\"text-muted-foreground\">Speed</label>\n <div className=\"flex items-center gap-1\">\n <CommitInput className={input} type=\"number\" min={0.05} step={0.05} aria-label=\"Speed\" placeholder=\"1\" disabled={readOnly} value={current.speed !== undefined ? String(current.speed) : ''} onCommit={(raw) => number('speed', raw, 'Change speed')} />\n <span className=\"text-[10px] text-muted-foreground\">×</span>\n </div>\n <label className=\"text-muted-foreground\">Camera</label>\n <select\n className={input}\n aria-label=\"Camera frames\"\n disabled={readOnly}\n value={current.camera ? (frame ? `frame:${frame}` : 'rect') : ''}\n onChange={(e) => {\n const v = e.target.value;\n if (!v) apply({ op: 'update_shot', shot: current.id, remove: ['camera'] }, 'Clear camera');\n else if (v.startsWith('frame:')) apply({ op: 'update_shot', shot: current.id, set: { camera: { frame: v.slice(6), padding: 24 } } }, 'Frame camera');\n }}\n >\n <option value=\"\">keep framing</option>\n {current.camera && !frame && <option value=\"rect\">a rectangle</option>}\n {elements.map((e) => (\n <option key={e.id} value={`frame:${e.id}`}>\n frame {e.name ?? e.id}\n </option>\n ))}\n </select>\n <label className=\"text-muted-foreground\">Starts on</label>\n <select\n className={input}\n aria-label=\"Cue\"\n disabled={readOnly || index === 0}\n value={cueKey}\n onChange={(e) => {\n const cue = motionCueFromKey(e.target.value);\n apply(cue ? { op: 'update_shot', shot: current.id, set: { at: cue } } : { op: 'update_shot', shot: current.id, remove: ['at'] }, 'Cue shot');\n }}\n >\n <option value=\"\">after the shot before</option>\n {cueKey && !cues.some((c) => c.value === cueKey) && <option value={cueKey}>{cueKey}</option>}\n {cues.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n {!cues.length && index > 0 && <p className=\"col-span-2 text-[10px] text-muted-foreground\">Add a beat grid or narration in the scene settings to cue shots to them.</p>}\n </div>\n )}\n {message && (\n <p className=\"text-red-500\" role=\"alert\" data-edit-error=\"\">\n {message}\n </p>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_animation_editor","import_jsx_runtime","import_react","import_animation_editor","import_react","import_animation_editor","import_react","import_animation_editor","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_react","import_animation_editor","import_jsx_runtime","import_react","import_animation_editor","import_jsx_runtime","seconds","worst","import_react","import_animation_editor","import_jsx_runtime","input","btn","import_react","import_animation_editor","import_jsx_runtime","input","btn","import_jsx_runtime","btn"]}
1
+ {"version":3,"sources":["../../src/animation-editor/index.ts","../../src/animation-editor/useAnimationEditor.ts","../../src/animation-editor/AnimationStage.tsx","../../src/animation-editor/ShotTimeline.tsx","../../src/animation-editor/AnimationEditor.tsx","../../src/animation-editor/CommandInspector.tsx","../../src/animation-editor/EasePicker.tsx","../../src/animation-editor/CommitInput.tsx","../../src/animation-editor/CommandList.tsx","../../src/animation-editor/PlayheadScrubber.tsx","../../src/animation-editor/SceneSettings.tsx","../../src/animation-editor/ShotInspector.tsx","../../src/effects/useEffects.ts","../../src/effects/EffectThumbnail.tsx","../../src/effects/EffectsBrowser.tsx","../../src/effects/EffectParameters.tsx","../../src/parameters/fields.tsx","../../src/animation-editor/AnimationEffectsPanel.tsx"],"sourcesContent":["export * from './useAnimationEditor';\nexport * from './AnimationStage';\nexport * from './ShotTimeline';\nexport * from './AnimationEditor';\nexport * from './PlayheadScrubber';\nexport * from './CommandList';\nexport * from './CommandInspector';\nexport * from './EasePicker';\nexport * from './ShotInspector';\nexport * from './SceneSettings';\nexport * from './AnimationEffectsPanel';\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n AnimationEditorController,\n createAnimationEditorToolProvider,\n createAnimationEffectsToolProvider,\n type AnimationEffectsToolProviderOptions,\n type AnimationEditorOptions,\n type AnimationEditorState,\n type AnimationEditorToolProviderOptions,\n} from '@pixerate/editor/animation-editor';\nimport type { ToolRegistry } from '@pixerate/editor/tools';\n\n/** An `AnimationEditorController` created once for the component's lifetime (destroyed on unmount). */\nexport function useAnimationEditorController(options: AnimationEditorOptions = {}): AnimationEditorController {\n const ref = useRef<AnimationEditorController | null>(null);\n if (!ref.current) ref.current = new AnimationEditorController(options);\n const controller = ref.current;\n useEffect(() => () => controller.destroy(), [controller]);\n return controller;\n}\n\n/** The controller's state (re-renders on every change, including each played frame). */\nexport function useAnimationEditorState(controller: AnimationEditorController): AnimationEditorState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseAnimationEditorResult {\n controller: AnimationEditorController;\n state: AnimationEditorState;\n play: () => void;\n pause: () => void;\n toggle: () => void;\n seek: (time: number) => void;\n undo: () => void;\n redo: () => void;\n /** The frame at the playhead as SVG. */\n toSvg: () => string;\n}\n\n/**\n * Subscribes to an animation editor controller and exposes its state with bound actions.\n * Pass options instead of a controller to create one for the component's lifetime.\n */\nexport function useAnimationEditor(controllerOrOptions: AnimationEditorController | AnimationEditorOptions = {}): UseAnimationEditorResult {\n const own = useRef<AnimationEditorController | null>(null);\n let controller: AnimationEditorController;\n if (controllerOrOptions instanceof AnimationEditorController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new AnimationEditorController(controllerOrOptions);\n controller = own.current;\n }\n useEffect(() => () => own.current?.destroy(), []);\n const state = useAnimationEditorState(controller);\n const actions = useMemo(\n () => ({\n play: () => controller.play(),\n pause: () => controller.pause(),\n toggle: () => controller.toggle(),\n seek: (time: number) => controller.seek(time),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n toSvg: () => controller.toSvg(),\n }),\n [controller],\n );\n return { controller, state, ...actions };\n}\n\n/**\n * Registers the animation editor's agent tools (`get_animation`, `add_commands`,\n * `export_flair_effect`, …) in `registry` while mounted.\n */\nexport function useAnimationEditorTools(\n registry: ToolRegistry | null | undefined,\n controller: AnimationEditorController,\n options: AnimationEditorToolProviderOptions = {},\n): void {\n const { id, namespace, readOnly, rasterize } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createAnimationEditorToolProvider(controller, { id, namespace, readOnly, rasterize }));\n }, [registry, controller, id, namespace, readOnly, rasterize]);\n}\n\n/**\n * Registers the animation editor's provider-effect tools (`search_effects`, `apply_effect`,\n * `add_vector_effect`, …) in `registry` while mounted. They work once an effects provider is\n * registered (see `useEffects`).\n */\nexport function useAnimationEffectsTools(\n registry: ToolRegistry | null | undefined,\n controller: AnimationEditorController,\n options: AnimationEffectsToolProviderOptions = {},\n): void {\n const { id, namespace, readOnly } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createAnimationEffectsToolProvider(controller, { id, namespace, readOnly }));\n }, [registry, controller, id, namespace, readOnly]);\n}\n","import React, { useMemo } from 'react';\nimport { highlightMotionSvg, motionNodeAtElement, type AnimationEditorController, type MotionFrameOptions, type MotionOnionSkin } from '@pixerate/editor/animation-editor';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface AnimationStageProps {\n controller: AnimationEditorController;\n /** Control values to preview (`{ accent: \"#0ea5e9\" }`). */\n values?: MotionFrameOptions['values'];\n /** Faded frames either side of the playhead. */\n onionSkin?: MotionOnionSkin;\n /** Draw where nodes travel: true for every node whose place changes, or a list of ids. */\n motionPaths?: boolean | readonly string[];\n /**\n * Called when the stage is clicked, with the id of the artwork node under the pointer (the\n * innermost one; null for the background, ghosts and paths). Makes the stage pickable.\n */\n onPick?: (id: string | null, event: React.MouseEvent<HTMLDivElement>) => void;\n /** Node ids to outline (e.g. the picked element and the selected command's targets). */\n highlight?: readonly string[];\n className?: string;\n}\n\n/**\n * The animation's frame at the playhead, drawn as inline SVG scaled to the stage's width. The\n * SVG keeps the artwork's node ids, so `onPick` can say which element was clicked.\n */\nexport function AnimationStage({ controller, values, onionSkin, motionPaths, onPick, highlight, className = '' }: AnimationStageProps) {\n const state = useAnimationEditorState(controller);\n const { scene, time } = state;\n const key = highlight?.join('\\u0000') ?? '';\n const svg = useMemo(\n () =>\n highlightMotionSvg(\n controller.toSvg(time, { pretty: false, idPrefix: 'ae-', values, onionSkin, motionPaths }).replace(/<svg ([^>]*?)width=\"[^\"]*\" height=\"[^\"]*\"/, '<svg $1width=\"100%\" height=\"100%\"'),\n highlight ?? [],\n ),\n [controller, scene, time, values, onionSkin, motionPaths, key],\n );\n return (\n <div\n className={`relative overflow-hidden ${onPick ? 'cursor-crosshair' : ''} ${className}`}\n style={{ aspectRatio: `${scene.artwork.width} / ${scene.artwork.height}` }}\n data-animation-stage=\"\"\n role=\"img\"\n aria-label={`${scene.name} at ${(time / 1000).toFixed(2)} s`}\n onClick={onPick ? (e) => onPick(motionNodeAtElement(scene, e.target as Element, e.currentTarget), e) : undefined}\n dangerouslySetInnerHTML={{ __html: svg }}\n />\n );\n}\n","import React from 'react';\nimport type { AnimationEditorController, MotionIssue } from '@pixerate/editor/animation-editor';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface ShotTimelineProps {\n controller: AnimationEditorController;\n className?: string;\n}\n\nconst seconds = (ms: number) => `${(ms / 1000).toFixed(1)} s`;\n\nfunction worst(issues: readonly MotionIssue[]): 'error' | 'warning' | null {\n if (issues.some((i) => i.severity === 'error')) return 'error';\n if (issues.some((i) => i.severity === 'warning')) return 'warning';\n return null;\n}\n\n/**\n * Play / pause, the playhead and one block per shot (as wide as it is long): click a shot to\n * select it and jump to its start, click the ruler to seek. Shots with errors or warnings are marked.\n */\nexport function ShotTimeline({ controller, className = '' }: ShotTimelineProps) {\n const state = useAnimationEditorState(controller);\n const { duration, shots, time, playing, selection, issues } = state;\n const span = Math.max(1, duration);\n const onRuler = (event: React.PointerEvent<HTMLDivElement>) => {\n const box = event.currentTarget.getBoundingClientRect();\n controller.seek(((event.clientX - box.left) / Math.max(1, box.width)) * span);\n };\n return (\n <div className={`flex flex-col gap-1 ${className}`} data-shot-timeline=\"\">\n <div className=\"flex items-center gap-2 text-xs\">\n <button type=\"button\" className=\"rounded border border-border px-2 py-0.5\" onClick={() => controller.toggle()} aria-label={playing ? 'Pause' : 'Play'} disabled={!shots.length}>\n {playing ? 'Pause' : 'Play'}\n </button>\n <span className=\"tabular-nums text-muted-foreground\">\n {seconds(time)} / {seconds(duration)}\n </span>\n </div>\n <div className=\"relative h-3 cursor-pointer rounded bg-muted\" onPointerDown={onRuler} role=\"slider\" aria-label=\"Playhead\" aria-valuemin={0} aria-valuemax={duration} aria-valuenow={Math.round(time)} tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'ArrowRight') controller.seek(time + 100);\n if (e.key === 'ArrowLeft') controller.seek(time - 100);\n }}>\n <div className=\"absolute inset-y-0 w-0.5 bg-rose-500\" style={{ left: `${(time / span) * 100}%` }} />\n </div>\n <div className=\"flex w-full gap-px\" role=\"group\" aria-label=\"Shots\">\n {shots.map((shot) => {\n const mark = worst(issues.filter((i) => i.shot === shot.id));\n const selected = selection?.shot === shot.id;\n return (\n <button\n key={shot.id}\n type=\"button\"\n className={`min-w-0 truncate rounded border px-1 py-1 text-left text-[11px] ${selected ? 'border-rose-500 bg-rose-500/10' : 'border-border'} ${state.currentShot === shot.id ? 'font-semibold' : ''}`}\n style={{ flexGrow: Math.max(1, shot.end - shot.start), flexBasis: 0 }}\n title={`${shot.label ?? shot.id} · ${seconds(shot.end - shot.start)}`}\n data-shot={shot.id}\n data-issue={mark ?? undefined}\n onClick={() => {\n controller.select({ shot: shot.id });\n controller.seekShot(shot.id);\n }}\n >\n {mark && <span className={mark === 'error' ? 'text-red-500' : 'text-amber-500'}>● </span>}\n {shot.label ?? shot.id}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n","import React, { useMemo, useState } from 'react';\nimport { indexMotionNodes, motionIssueLine, type AnimationEditorController, type MotionFrameOptions, type MotionOnionSkin } from '@pixerate/editor/animation-editor';\nimport { AnimationStage } from './AnimationStage';\nimport { CommandInspector } from './CommandInspector';\nimport { CommandList } from './CommandList';\nimport { PlayheadScrubber } from './PlayheadScrubber';\nimport { SceneSettings } from './SceneSettings';\nimport { ShotInspector } from './ShotInspector';\nimport { useAnimationEditorState } from './useAnimationEditor';\nimport type { EffectProvider } from '@pixerate/editor/effects';\nimport { useEffects } from '../effects';\nimport { AnimationEffectsPanel } from './AnimationEffectsPanel';\n\nexport interface AnimationEditorProps {\n controller: AnimationEditorController;\n values?: MotionFrameOptions['values'];\n /** Faded frames either side of the playhead (see `<AnimationStage onionSkin>`). Default: an Onion skin toggle. */\n onionSkin?: MotionOnionSkin;\n /** Draw where nodes travel (see `<AnimationStage motionPaths>`). Default: a Motion paths toggle. */\n motionPaths?: boolean | readonly string[];\n /** List the scene's issues under the timeline (default true). */\n showIssues?: boolean;\n /**\n * Show the hand-editing panels: the command list and inspector, the shot inspector, scene\n * settings, undo / redo and picking on the stage (default true). False shows the stage,\n * scrubber and issues only.\n */\n editable?: boolean;\n /**\n * An effects provider (see `@pixerate/editor/effects`), registered with the controller while\n * mounted: provider motion applied to the picked element and vector effects, with an Effects\n * panel. Optional: without one the editor is as before.\n */\n effects?: EffectProvider | null;\n className?: string;\n}\n\nconst ONION: MotionOnionSkin = { before: 3, after: 1 };\nconst btn = 'rounded border border-border px-2 py-0.5 text-xs disabled:opacity-40';\n\n/**\n * A whole animation editor for an `AnimationEditorController`: the stage (click an element to\n * pick it, shift-click to add it to or remove it from the selected command's targets), the\n * playhead scrubber, and panels to edit commands, shots and scene settings by hand. Every edit\n * is one undo step.\n */\nexport function AnimationEditor({ controller, values, onionSkin, motionPaths, showIssues = true, editable = true, effects, className = '' }: AnimationEditorProps) {\n const state = useAnimationEditorState(controller);\n useEffects(controller, effects);\n const { issues, scene, selection, readOnly } = state;\n const [picked, setPicked] = useState<string | null>(null);\n const [onion, setOnion] = useState(false);\n const [paths, setPaths] = useState(false);\n const command = selection?.command !== undefined ? scene.shots.find((s) => s.id === selection.shot)?.run[selection.command] : undefined;\n const targets = command && 'targets' in command ? command.targets : [];\n const nodes = useMemo(() => indexMotionNodes(scene.artwork.nodes), [scene.artwork]);\n const pickedValid = picked && nodes.has(picked) ? picked : null;\n const onPick = (id: string | null, event: { shiftKey: boolean }) => {\n if (event.shiftKey && id && command && 'targets' in command && selection?.command !== undefined && !readOnly) {\n const next = targets.includes(id) ? targets.filter((t) => t !== id) : [...targets, id];\n if (next.length) controller.apply({ op: 'update_command', shot: selection.shot, command: selection.command, set: { targets: next } }, next.length > targets.length ? 'Add target' : 'Remove target');\n return;\n }\n setPicked(id);\n };\n const stage = (\n <AnimationStage\n controller={controller}\n values={values}\n onionSkin={onionSkin ?? (onion ? ONION : undefined)}\n motionPaths={motionPaths ?? paths}\n onPick={editable ? onPick : undefined}\n highlight={editable ? [...(pickedValid ? [pickedValid] : []), ...targets] : undefined}\n className=\"rounded-md border border-border bg-muted/40\"\n />\n );\n const issueList = showIssues && issues.length > 0 && (\n <ul className=\"space-y-0.5 text-xs\" aria-label=\"Animation issues\">\n {issues.map((issue, i) => (\n <li key={i} className={issue.severity === 'error' ? 'text-red-500' : issue.severity === 'warning' ? 'text-amber-500' : 'text-muted-foreground'}>\n {motionIssueLine(issue)}\n </li>\n ))}\n </ul>\n );\n if (!editable)\n return (\n <div className={`flex flex-col gap-2 ${className}`} data-animation-editor=\"\">\n {stage}\n <PlayheadScrubber controller={controller} />\n {issueList}\n </div>\n );\n\n return (\n <div\n className={`grid gap-3 lg:grid-cols-[minmax(0,1fr)_20rem] ${className}`}\n data-animation-editor=\"\"\n onKeyDown={(e) => {\n const el = e.target as HTMLElement;\n if (!(e.metaKey || e.ctrlKey) || e.key.toLowerCase() !== 'z' || /^(INPUT|TEXTAREA|SELECT)$/.test(el.tagName)) return;\n e.preventDefault();\n if (e.shiftKey) controller.redo();\n else controller.undo();\n }}\n >\n <div className=\"flex min-w-0 flex-col gap-2\">\n {stage}\n <PlayheadScrubber controller={controller} />\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-muted-foreground\">\n <button type=\"button\" className={btn} onClick={() => controller.undo()} disabled={!state.canUndo} title={state.canUndo ? `Undo ${state.undoLabel}` : 'Nothing to undo'} data-undo=\"\">\n Undo\n </button>\n <button type=\"button\" className={btn} onClick={() => controller.redo()} disabled={!state.canRedo} title={state.canRedo ? `Redo ${state.redoLabel}` : 'Nothing to redo'} data-redo=\"\">\n Redo\n </button>\n {onionSkin === undefined && (\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" checked={onion} onChange={(e) => setOnion(e.target.checked)} /> Onion skin\n </label>\n )}\n {motionPaths === undefined && (\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" checked={paths} onChange={(e) => setPaths(e.target.checked)} /> Motion paths\n </label>\n )}\n <span className=\"ml-auto\" data-picked-element={pickedValid ?? undefined}>\n {pickedValid ? (\n <>\n Picked <code className=\"text-rose-500\">{pickedValid}</code>{' '}\n <button type=\"button\" className=\"underline\" onClick={() => setPicked(null)}>\n clear\n </button>\n </>\n ) : (\n 'Click the stage to pick an element; shift-click to toggle it as a target.'\n )}\n </span>\n </div>\n {issueList}\n </div>\n <div className=\"flex min-w-0 flex-col gap-3\">\n <CommandList controller={controller} targets={pickedValid ? [pickedValid] : undefined} />\n {(state.effectsProvider || controller.appliedEffects().length > 0) && <AnimationEffectsPanel controller={controller} node={pickedValid} className=\"border-t border-border pt-2\" />}\n <CommandInspector controller={controller} picked={pickedValid} className=\"border-t border-border pt-2\" />\n <details open className=\"border-t border-border pt-2\">\n <summary className=\"cursor-pointer text-xs font-medium\">Shot</summary>\n <ShotInspector controller={controller} className=\"mt-1\" />\n </details>\n <details className=\"border-t border-border pt-2\">\n <summary className=\"cursor-pointer text-xs font-medium\">Scene settings</summary>\n <SceneSettings controller={controller} className=\"mt-1\" />\n </details>\n </div>\n </div>\n );\n}\n","import React, { useMemo, useState } from 'react';\nimport {\n describeMotionElements,\n motionCommandFields,\n motionFieldEdit,\n motionFlairPrimitive,\n type AnimationEditorController,\n type MotionFieldSpec,\n} from '@pixerate/editor/animation-editor';\nimport { EasePicker } from './EasePicker';\nimport { CommitInput } from './CommitInput';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface CommandInspectorProps {\n controller: AnimationEditorController;\n /** An element picked on the stage, offered as a target to add. */\n picked?: string | null;\n className?: string;\n}\n\nconst input = 'w-full min-w-0 rounded border border-border bg-transparent px-1 py-0.5 text-xs';\n\n\n/**\n * A form for the selected command, generated from `MOTION_COMMAND_SCHEMA` (the schema the\n * agent tools take): enums as selects, numbers with their units and limits, node pickers for\n * targets and for `into` / `path`, and an ease picker. Shows the Flair primitive it plays.\n */\nexport function CommandInspector({ controller, picked, className = '' }: CommandInspectorProps) {\n const state = useAnimationEditorState(controller);\n const { scene, selection, readOnly, error } = state;\n const [local, setLocalState] = useState<{ text: string; revision: number } | null>(null);\n const setLocal = (text: string | null) => setLocalState(text ? { text, revision: state.revision } : null);\n const elements = useMemo(() => describeMotionElements(scene), [scene.artwork]);\n const shot = selection ? scene.shots.find((s) => s.id === selection.shot) : undefined;\n const index = selection?.command;\n const command = shot && index !== undefined ? shot.run[index] : undefined;\n if (!shot || index === undefined || !command) {\n return (\n <div className={`text-xs text-muted-foreground ${className}`} data-command-inspector=\"\">\n Select a command to edit it.\n </div>\n );\n }\n const values = command as unknown as Record<string, unknown>;\n const fields = motionCommandFields(command.type);\n const primitive = motionFlairPrimitive(command);\n const commit = (field: MotionFieldSpec, raw: Parameters<typeof motionFieldEdit>[3]) => {\n const edit = motionFieldEdit(shot.id, index, field, raw);\n if ('error' in edit) return setLocal(edit.error);\n setLocal(null);\n controller.apply(edit, `Set ${field.label.toLowerCase()}`);\n };\n const name = (id: string) => elements.find((e) => e.id === id)?.name ?? id;\n const targets = (values.targets as string[] | undefined) ?? [];\n // A local error shows until the editor changes; then the editor's own error (if any) shows.\n const message = (local && local.revision === state.revision ? local.text : null) ?? error;\n\n const control = (field: MotionFieldSpec) => {\n const v = values[field.name];\n const common = { disabled: readOnly, 'aria-label': field.label, title: field.description };\n switch (field.kind) {\n case 'targets':\n return (\n <div className=\"flex flex-wrap items-center gap-1\" data-targets=\"\">\n {targets.map((id) => (\n <span key={id} className=\"flex items-center gap-0.5 rounded bg-muted px-1 text-[11px]\" data-target={id}>\n {name(id)}\n {!readOnly && targets.length > 1 && (\n <button type=\"button\" aria-label={`Remove ${id}`} onClick={() => commit(field, targets.filter((t) => t !== id))}>\n ×\n </button>\n )}\n </span>\n ))}\n {!readOnly && picked && !targets.includes(picked) && (\n <button type=\"button\" className=\"rounded border border-rose-500 px-1 text-[11px] text-rose-500\" onClick={() => commit(field, [...targets, picked])} data-add-picked=\"\">\n + {name(picked)}\n </button>\n )}\n {!readOnly && (\n <select className=\"rounded border border-border bg-transparent px-1 py-0.5 text-[11px]\" aria-label=\"Add target\" value=\"\" onChange={(e) => e.target.value && commit(field, [...targets, e.target.value])}>\n <option value=\"\">+ target…</option>\n {elements.filter((e) => !targets.includes(e.id)).map((e) => (\n <option key={e.id} value={e.id}>\n {e.name ? `${e.name} (${e.id})` : e.id}\n </option>\n ))}\n </select>\n )}\n </div>\n );\n case 'node':\n return (\n <select className={input} {...common} value={typeof v === 'string' ? v : ''} onChange={(e) => commit(field, e.target.value)}>\n {!field.required && <option value=\"\">—</option>}\n {elements.filter((e) => field.name !== 'path' || e.type === 'path').map((e) => (\n <option key={e.id} value={e.id}>\n {e.name ? `${e.name} (${e.id})` : e.id}\n {e.hidden ? ' · hidden' : ''}\n </option>\n ))}\n </select>\n );\n case 'enum':\n return (\n <select className={input} {...common} value={typeof v === 'string' ? v : ''} onChange={(e) => commit(field, e.target.value)}>\n {!field.required && <option value=\"\">default</option>}\n {field.options!.map((o) => (\n <option key={o} value={o}>\n {o}\n </option>\n ))}\n </select>\n );\n case 'boolean':\n return <input type=\"checkbox\" {...common} checked={v === true} onChange={(e) => commit(field, e.target.checked)} />;\n case 'ease':\n return <EasePicker value={v as never} disabled={readOnly} onChange={(ease) => commit(field, ease === undefined ? '' : (ease as string))} />;\n case 'color':\n return (\n <div className=\"flex items-center gap-1\">\n <input type=\"color\" disabled={readOnly} aria-label={`${field.label} swatch`} value={typeof v === 'string' && /^#[0-9a-f]{6}$/i.test(v) ? v : '#000000'} onChange={(e) => commit(field, e.target.value)} />\n <CommitInput className={input} {...common} value={typeof v === 'string' ? v : ''} placeholder=\"unchanged\" onCommit={(raw) => commit(field, raw)} />\n </div>\n );\n case 'point': {\n const p = (v as { x: number; y: number } | undefined) ?? undefined;\n return (\n <div className=\"flex items-center gap-1\">\n {(['x', 'y'] as const).map((axis) => (\n <CommitInput\n key={axis}\n className={input}\n type=\"number\"\n disabled={readOnly}\n aria-label={`${field.label} ${axis}`}\n placeholder={axis}\n value={p ? String(p[axis]) : ''}\n onCommit={(raw) => commit(field, axis === 'x' ? { x: raw, y: p ? String(p.y) : raw ? '0' : '' } : { x: p ? String(p.x) : raw ? '0' : '', y: raw })}\n />\n ))}\n </div>\n );\n }\n case 'scale':\n case 'number':\n case 'integer':\n return (\n <div className=\"flex items-center gap-1\">\n <CommitInput\n className={input}\n type=\"number\"\n {...common}\n min={field.min}\n max={field.max}\n step={field.kind === 'integer' ? 1 : field.unit === 'ms' ? 50 : field.unit === '0–1' ? 0.05 : 'any'}\n placeholder=\"default\"\n value={typeof v === 'number' ? String(v) : ''}\n onCommit={(raw) => commit(field, raw)}\n />\n {field.unit && <span className=\"shrink-0 text-[10px] text-muted-foreground\">{field.unit}</span>}\n </div>\n );\n default:\n return <CommitInput className={input} {...common} value={typeof v === 'string' ? v : ''} onCommit={(raw) => commit(field, raw)} />;\n }\n };\n\n return (\n <div className={`flex flex-col gap-1.5 text-xs ${className}`} data-command-inspector=\"\" data-command-type={command.type}>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">\n {index + 1}. {command.type}\n </span>\n {primitive ? (\n <code className=\"rounded bg-muted px-1 text-[10px]\" data-flair-primitive={primitive} title=\"The Flair motion primitive this command plays\">\n {primitive}\n </code>\n ) : (\n <span className=\"text-[10px] text-muted-foreground\">editor-only (no Flair primitive)</span>\n )}\n </div>\n {(['main', 'timing'] as const).map((group) => (\n <fieldset key={group} className=\"grid grid-cols-[6.5rem_1fr] items-center gap-x-2 gap-y-1\">\n <legend className=\"mb-1 text-[10px] uppercase tracking-wide text-muted-foreground\">{group === 'main' ? 'Command' : 'Timing'}</legend>\n {fields\n .filter((f) => f.group === group)\n .map((field) => (\n <React.Fragment key={field.name}>\n <label className=\"truncate text-muted-foreground\" title={field.description}>\n {field.label}\n {field.required ? ' *' : ''}\n </label>\n <div data-field={field.name}>{control(field)}</div>\n </React.Fragment>\n ))}\n </fieldset>\n ))}\n {message && (\n <p className=\"text-red-500\" role=\"alert\" data-edit-error=\"\">\n {message}\n </p>\n )}\n </div>\n );\n}\n","import React, { useMemo } from 'react';\nimport { MOTION_EASE_CHOICES, motionEaseKey, motionEasingCurve, motionEasingGuides, motionEasingPath, type MotionCommandBase } from '@pixerate/editor/animation-editor';\n\n/** An easing (a preset name or a curve), as commands take it. */\ntype AnimationEasing = NonNullable<MotionCommandBase['ease']>;\n\nexport interface EasePickerProps {\n /** The easing (undefined: the command type's default). */\n value: AnimationEasing | undefined;\n /** Called with the picked preset, or undefined for the default. */\n onChange: (ease: AnimationEasing | undefined) => void;\n disabled?: boolean;\n className?: string;\n}\n\nconst W = 72;\nconst H = 44;\n\n/**\n * Picks an easing preset (springs included) and previews its curve, drawn by sampling\n * `evaluateEasing`; a spring is drawn over the time it takes to settle, overshoot included.\n */\nexport function EasePicker({ value, onChange, disabled, className = '' }: EasePickerProps) {\n const key = motionEaseKey(value);\n const curve = useMemo(() => motionEasingCurve(value ?? 'ease-out'), [value]);\n const guides = motionEasingGuides(curve, H);\n const spring = typeof value === 'string' ? value.startsWith('spring') : value?.type === 'spring';\n return (\n <div className={`flex items-center gap-2 ${className}`} data-ease-picker=\"\">\n <select\n className=\"min-w-0 flex-1 rounded border border-border bg-transparent px-1 py-0.5 text-xs\"\n aria-label=\"Ease\"\n value={key}\n disabled={disabled}\n onChange={(e) => {\n if (e.target.value === 'custom') return;\n onChange(e.target.value ? (e.target.value as AnimationEasing) : undefined);\n }}\n >\n {MOTION_EASE_CHOICES.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n {key === 'custom' && <option value=\"custom\">Custom</option>}\n </select>\n <svg width={W} height={H} viewBox={`0 0 ${W} ${H}`} className=\"shrink-0 rounded border border-border\" data-ease-curve={key || 'default'} aria-hidden=\"true\">\n <line x1={0} x2={W} y1={guides.zero} y2={guides.zero} stroke=\"currentColor\" strokeOpacity={0.2} />\n <line x1={0} x2={W} y1={guides.one} y2={guides.one} stroke=\"currentColor\" strokeOpacity={0.2} strokeDasharray=\"2 2\" />\n <path d={motionEasingPath(curve, W, H)} fill=\"none\" stroke=\"#f43f5e\" strokeWidth={1.5} />\n </svg>\n {spring && <span className=\"text-[10px] tabular-nums text-muted-foreground\">{Math.round(curve.durationMs)} ms</span>}\n </div>\n );\n}\n","import React from 'react';\n\n/** An input that commits on blur or Enter, and resets when its value changes from outside. */\nexport function CommitInput({ value, onCommit, ...rest }: { value: string; onCommit: (raw: string) => void } & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'defaultValue'>) {\n return (\n <input\n key={value}\n {...rest}\n defaultValue={value}\n onKeyDown={(e) => e.key === 'Enter' && e.currentTarget.blur()}\n onBlur={(e) => {\n if (e.currentTarget.value !== value) onCommit(e.currentTarget.value);\n }}\n />\n );\n}\n","import React, { useState } from 'react';\nimport {\n MOTION_COMMAND_TYPES,\n defaultMotionCommand,\n duplicateMotionCommandEdit,\n motionCommandRows,\n type AnimationEditorController,\n type MotionCommandType,\n} from '@pixerate/editor/animation-editor';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface CommandListProps {\n controller: AnimationEditorController;\n /** The shot to list (default: the selected shot, else the first). */\n shot?: string;\n /** Targets for a new command (e.g. the element picked on the stage); default: the selected command's. */\n targets?: readonly string[];\n className?: string;\n}\n\nconst btn = 'rounded border border-border px-1.5 py-0.5 text-[11px] disabled:opacity-40';\n\n/**\n * A shot's commands in order: select one to inspect it, change `with` and `delay` inline, move,\n * duplicate or delete it, and add new ones. Each change is one `controller.apply` edit (one undo\n * step); a refused edit shows its reason.\n */\nexport function CommandList({ controller, shot, targets, className = '' }: CommandListProps) {\n const state = useAnimationEditorState(controller);\n const { scene, selection, readOnly, error } = state;\n const shotId = shot ?? selection?.shot ?? scene.shots[0]?.id;\n const current = scene.shots.find((s) => s.id === shotId);\n const [type, setType] = useState<MotionCommandType>('enter');\n const [local, setLocalState] = useState<{ text: string; revision: number } | null>(null);\n const setLocal = (text: string | null) => setLocalState(text ? { text, revision: state.revision } : null);\n if (!current) return <div className={`text-xs text-muted-foreground ${className}`} data-command-list=\"\">Add a shot to start.</div>;\n const rows = motionCommandRows(scene, current.id);\n const selected = selection?.shot === current.id ? selection.command : undefined;\n const run = (edit: Parameters<AnimationEditorController['apply']>[0], label: string) => {\n setLocal(null);\n return controller.apply(edit, label);\n };\n const add = () => {\n const from = targets?.length ? targets : selected !== undefined ? ((current.run[selected] as { targets?: string[] }).targets ?? []) : [];\n const command = defaultMotionCommand(type, from, scene);\n if ('error' in command) return setLocal(command.error);\n const at = selected !== undefined ? selected + 1 : current.run.length;\n const result = run({ op: 'add_commands', shot: current.id, commands: [command], at }, `Add ${type}`);\n if (result.ok) controller.select({ shot: current.id, command: at });\n };\n // A local error shows until the editor changes; then the editor's own error (if any) shows.\n const message = (local && local.revision === state.revision ? local.text : null) ?? error;\n\n return (\n <div className={`flex flex-col gap-1 text-xs ${className}`} data-command-list=\"\" data-for-shot={current.id}>\n <div className=\"font-medium\">\n Commands in <span className=\"text-rose-500\">{current.label ?? current.id}</span>\n </div>\n <ol className=\"flex flex-col gap-1\" aria-label=\"Commands\">\n {rows.map((row) => {\n const c = row.command as { with?: string; delay?: number };\n const isSelected = row.index === selected;\n return (\n <li\n key={`${row.index}:${row.summary}`}\n className={`flex flex-wrap items-center gap-1 rounded border px-1.5 py-1 ${isSelected ? 'border-rose-500 bg-rose-500/10' : 'border-border'}`}\n data-command={row.index}\n data-selected={isSelected || undefined}\n onClick={() => controller.select({ shot: current.id, command: row.index })}\n >\n <span className=\"min-w-0 flex-1 truncate\" title={row.summary}>\n {row.index + 1}. {row.summary}\n </span>\n {row.flairPrimitive && (\n <code className=\"rounded bg-muted px-1 text-[10px] text-muted-foreground\" data-flair-primitive={row.flairPrimitive}>\n {row.flairPrimitive}\n </code>\n )}\n <span className=\"tabular-nums text-[10px] text-muted-foreground\">{((row.end - row.start) / 1000).toFixed(2)} s</span>\n <div className=\"flex w-full items-center gap-1\" onClick={(e) => e.stopPropagation()}>\n <select\n className=\"rounded border border-border bg-transparent px-1 py-0.5 text-[11px]\"\n aria-label=\"Starts\"\n value={c.with ?? 'after'}\n disabled={readOnly || row.index === 0}\n onChange={(e) =>\n run(\n e.target.value === 'after' ? { op: 'update_command', shot: current.id, command: row.index, remove: ['with'] } : { op: 'update_command', shot: current.id, command: row.index, set: { with: e.target.value } },\n 'Change start',\n )\n }\n >\n <option value=\"after\">after previous</option>\n <option value=\"previous\">with previous</option>\n </select>\n <label className=\"flex items-center gap-0.5 text-muted-foreground\">\n +\n <input\n key={String(c.delay ?? '')}\n className=\"w-14 rounded border border-border bg-transparent px-1 py-0.5 text-[11px] tabular-nums\"\n type=\"number\"\n min={0}\n step={50}\n aria-label=\"Delay\"\n placeholder=\"0\"\n defaultValue={c.delay ?? ''}\n disabled={readOnly}\n onKeyDown={(e) => e.key === 'Enter' && e.currentTarget.blur()}\n onBlur={(e) => {\n const raw = e.currentTarget.value.trim();\n if (raw === String(c.delay ?? '')) return;\n const n = Number(raw);\n if (raw && !(Number.isFinite(n) && n >= 0)) return setLocal('Delay must be a number of ms, 0 or more.');\n run(raw && n > 0 ? { op: 'update_command', shot: current.id, command: row.index, set: { delay: n } } : { op: 'update_command', shot: current.id, command: row.index, remove: ['delay'] }, 'Change delay');\n }}\n />\n ms\n </label>\n <span className=\"ml-auto flex gap-0.5\">\n <button type=\"button\" className={btn} aria-label=\"Move up\" disabled={readOnly || row.index === 0} onClick={() => run({ op: 'move_command', shot: current.id, command: row.index, to: row.index - 1 }, 'Move command').ok && controller.select({ shot: current.id, command: row.index - 1 })}>\n ↑\n </button>\n <button type=\"button\" className={btn} aria-label=\"Move down\" disabled={readOnly || row.index === rows.length - 1} onClick={() => run({ op: 'move_command', shot: current.id, command: row.index, to: row.index + 1 }, 'Move command').ok && controller.select({ shot: current.id, command: row.index + 1 })}>\n ↓\n </button>\n <button type=\"button\" className={btn} aria-label=\"Duplicate\" disabled={readOnly} onClick={() => run(duplicateMotionCommandEdit(scene, current.id, row.index), 'Duplicate command').ok && controller.select({ shot: current.id, command: row.index + 1 })}>\n ⧉\n </button>\n <button type=\"button\" className={btn} aria-label=\"Delete\" disabled={readOnly} onClick={() => run({ op: 'delete_commands', shot: current.id, commands: [row.index] }, 'Delete command')}>\n ✕\n </button>\n </span>\n </div>\n </li>\n );\n })}\n </ol>\n {!readOnly && (\n <div className=\"flex items-center gap-1\">\n <select className=\"flex-1 rounded border border-border bg-transparent px-1 py-0.5\" aria-label=\"New command type\" value={type} onChange={(e) => setType(e.target.value as MotionCommandType)}>\n {MOTION_COMMAND_TYPES.map((t) => (\n <option key={t} value={t}>\n {t}\n </option>\n ))}\n </select>\n <button type=\"button\" className={btn} onClick={add} data-add-command=\"\">\n Add command\n </button>\n </div>\n )}\n {message && (\n <p className=\"text-red-500\" role=\"alert\" data-edit-error=\"\">\n {message}\n </p>\n )}\n </div>\n );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { motionBeatTime, motionCueTime, motionRulerTicks, type AnimationEditorController, type MotionIssue } from '@pixerate/editor/animation-editor';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface PlayheadScrubberProps {\n controller: AnimationEditorController;\n className?: string;\n}\n\nconst seconds = (ms: number) => `${(ms / 1000).toFixed(2)} s`;\n\nfunction worst(issues: readonly MotionIssue[]): 'error' | 'warning' | null {\n if (issues.some((i) => i.severity === 'error')) return 'error';\n if (issues.some((i) => i.severity === 'warning')) return 'warning';\n return null;\n}\n\n/**\n * Play, pause and loop, a time ruler (with the beat grid and narration words when the scene has\n * them) to scrub by dragging, and one band per shot (as wide as it is long): click a band to\n * select the shot and jump to its start. Loop is a scene setting, so changing it is one undo step.\n */\nexport function PlayheadScrubber({ controller, className = '' }: PlayheadScrubberProps) {\n const state = useAnimationEditorState(controller);\n const { duration, shots, time, playing, selection, issues, scene, readOnly } = state;\n const span = Math.max(1, duration);\n const track = useRef<HTMLDivElement>(null);\n const [width, setWidth] = useState(600);\n useEffect(() => {\n const el = track.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => setWidth(el.clientWidth || 600));\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n const ticks = motionRulerTicks(duration, width);\n const pct = (ms: number) => `${(Math.min(span, Math.max(0, ms)) / span) * 100}%`;\n const seekAt = (clientX: number) => {\n const box = track.current!.getBoundingClientRect();\n controller.seek(Math.min(1, Math.max(0, (clientX - box.left) / Math.max(1, box.width))) * span);\n };\n const beats: number[] = [];\n if (scene.beat && scene.beat.bpm > 0) for (let b = 0, t = motionBeatTime(scene.beat, 0); t <= span && beats.length < 400; t = motionBeatTime(scene.beat, ++b)) if (t >= 0) beats.push(t);\n\n return (\n <div className={`flex flex-col gap-1 ${className}`} data-playhead-scrubber=\"\" data-shot-timeline=\"\">\n <div className=\"flex items-center gap-2 text-xs\">\n <button type=\"button\" className=\"rounded border border-border px-2 py-0.5\" onClick={() => controller.toggle()} aria-label={playing ? 'Pause' : 'Play'} disabled={!shots.length}>\n {playing ? 'Pause' : 'Play'}\n </button>\n <button type=\"button\" className=\"rounded border border-border px-2 py-0.5\" onClick={() => { controller.pause(); controller.seek(0); }} aria-label=\"Back to start\">\n ⏮\n </button>\n <label className=\"flex items-center gap-1 text-muted-foreground\">\n Loop\n <select\n className=\"rounded border border-border bg-transparent px-1 py-0.5\"\n value={scene.loop ?? 'none'}\n disabled={readOnly}\n aria-label=\"Loop\"\n onChange={(e) => controller.apply({ op: 'set_settings', loop: e.target.value as 'none' | 'loop' | 'ping-pong' }, 'Change loop')}\n >\n <option value=\"none\">Off</option>\n <option value=\"loop\">Loop</option>\n <option value=\"ping-pong\">Ping-pong</option>\n </select>\n </label>\n <span className=\"ml-auto tabular-nums text-muted-foreground\" data-time=\"\">\n {seconds(time)} / {seconds(duration)}\n </span>\n </div>\n <div\n ref={track}\n className=\"relative cursor-ew-resize select-none touch-none\"\n role=\"slider\"\n aria-label=\"Playhead\"\n aria-valuemin={0}\n aria-valuemax={duration}\n aria-valuenow={Math.round(time)}\n tabIndex={0}\n data-scrub-track=\"\"\n onPointerDown={(e) => {\n e.currentTarget.setPointerCapture?.(e.pointerId);\n seekAt(e.clientX);\n }}\n onPointerMove={(e) => {\n if (e.buttons & 1) seekAt(e.clientX);\n }}\n onKeyDown={(e) => {\n const step = e.shiftKey ? 1000 : 100;\n if (e.key === 'ArrowRight') controller.seek(time + step);\n else if (e.key === 'ArrowLeft') controller.seek(time - step);\n else if (e.key === 'Home') controller.seek(0);\n else if (e.key === 'End') controller.seek(duration);\n else if (e.key === ' ') controller.toggle();\n else return;\n e.preventDefault();\n }}\n >\n <div className=\"relative h-5 border-b border-border text-[10px] text-muted-foreground\" data-ruler=\"\">\n {beats.map((t, i) => (\n <div key={`b${i}`} className=\"absolute bottom-0 h-1.5 w-px bg-sky-500/60\" style={{ left: pct(t) }} data-beat={i} />\n ))}\n {scene.narration?.words.map((w, i) => (\n <div key={`w${i}`} className=\"absolute top-0 h-1.5 w-px bg-emerald-500/70\" style={{ left: pct(w.start) }} title={`“${w.text}” at ${seconds(w.start)}`} data-word={i} />\n ))}\n {ticks.map((t) => (\n <div key={t.time} className={`absolute bottom-0 w-px ${t.major ? 'h-2.5 bg-muted-foreground/70' : 'h-1 bg-muted-foreground/40'}`} style={{ left: pct(t.time) }}>\n {t.label && <span className=\"absolute -top-0.5 left-1 whitespace-nowrap tabular-nums\">{t.label}</span>}\n </div>\n ))}\n </div>\n <div className=\"mt-1 flex w-full gap-px\" role=\"group\" aria-label=\"Shots\">\n {shots.map((shot, i) => {\n const mark = worst(issues.filter((x) => x.shot === shot.id));\n const selected = selection?.shot === shot.id;\n const cue = scene.shots[i]?.at;\n const cueTime = cue ? motionCueTime(scene, cue) : undefined;\n return (\n <button\n key={shot.id}\n type=\"button\"\n className={`relative min-w-0 truncate rounded border px-1 py-1 text-left text-[11px] ${selected ? 'border-rose-500 bg-rose-500/10' : 'border-border bg-muted/40'} ${state.currentShot === shot.id ? 'font-semibold' : ''}`}\n style={{ flexGrow: Math.max(1, shot.end - shot.start), flexBasis: 0 }}\n title={`${shot.label ?? shot.id} · ${seconds(shot.start)}–${seconds(shot.end)}${cueTime !== undefined ? ` · cued at ${seconds(cueTime)}` : ''}`}\n data-shot={shot.id}\n data-issue={mark ?? undefined}\n onPointerDown={(e) => e.stopPropagation()}\n onClick={() => {\n controller.select({ shot: shot.id });\n controller.seekShot(shot.id);\n }}\n >\n {mark && <span className={mark === 'error' ? 'text-red-500' : 'text-amber-500'}>● </span>}\n {shot.label ?? shot.id}\n </button>\n );\n })}\n </div>\n <div className=\"pointer-events-none absolute inset-y-0 w-0.5 -translate-x-1/2 bg-rose-500\" style={{ left: pct(time) }} data-playhead=\"\" />\n </div>\n </div>\n );\n}\n","import React, { useState } from 'react';\nimport { fitMotionSceneEdits, formatMotionDrivers, formatMotionNarration, parseMotionDrivers, parseMotionNarration, type AnimationEditorController, type MotionEdit, type MotionTrigger } from '@pixerate/editor/animation-editor';\nimport { CommitInput } from './CommitInput';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface SceneSettingsProps {\n controller: AnimationEditorController;\n className?: string;\n}\n\nconst input = 'w-full min-w-0 rounded border border-border bg-transparent px-1 py-0.5 text-xs';\nconst btn = 'rounded border border-border px-1.5 py-0.5 text-[11px] disabled:opacity-40';\nconst unit = (u: string) => <span className=\"shrink-0 text-[10px] text-muted-foreground\">{u}</span>;\n\n/**\n * Scene settings: loop, frame rate, stepped time, the wanted length with a Fit button (sets the\n * shots' speeds with `fitMotionScene`, as `fit_animation` does), a beat grid and narration words\n * to cue shots to. Every change is one undo step; refusals show their reason.\n */\nexport function SceneSettings({ controller, className = '' }: SceneSettingsProps) {\n const state = useAnimationEditorState(controller);\n const { scene, readOnly, error, duration } = state;\n const [local, setLocalState] = useState<{ text: string; revision: number } | null>(null);\n const setLocal = (text: string | null) => setLocalState(text ? { text, revision: state.revision } : null);\n const [fitTo, setFitTo] = useState<string>('');\n const apply = (edit: MotionEdit | MotionEdit[], label: string) => {\n setLocal(null);\n return controller.apply(edit, label);\n };\n const settings = (set: Omit<Extract<MotionEdit, { op: 'set_settings' }>, 'op'>, label: string) => apply({ op: 'set_settings', ...set }, label);\n const num = (raw: string, what: string, ok: (n: number) => boolean, then: (n: number | null) => void) => {\n if (raw.trim() === '') return then(null);\n const n = Number(raw);\n if (!Number.isFinite(n) || !ok(n)) return setLocal(what);\n then(n);\n };\n const target = scene.target;\n const fitSeconds = fitTo || String(target ? (target[0] + target[1]) / 2 : Math.round(duration / 100) / 10);\n const fit = () => {\n const s = Number(fitSeconds);\n if (!(Number.isFinite(s) && s > 0)) return setLocal('Give the length to fit in seconds, above 0.');\n try {\n const edits = fitMotionSceneEdits(scene, s * 1000);\n if (edits.length) apply(edits, `Fit to ${s} s`);\n else setLocal(null);\n } catch (e) {\n setLocal((e as Error).message);\n }\n };\n const beat = scene.beat;\n // A local error shows until the editor changes; then the editor's own error (if any) shows.\n const message = (local && local.revision === state.revision ? local.text : null) ?? error;\n\n return (\n <div className={`flex flex-col gap-1.5 text-xs ${className}`} data-scene-settings=\"\">\n <div className=\"grid grid-cols-[6.5rem_1fr] items-center gap-x-2 gap-y-1\">\n <label className=\"text-muted-foreground\">Loop</label>\n <select className={input} aria-label=\"Scene loop\" disabled={readOnly} value={scene.loop ?? 'none'} onChange={(e) => settings({ loop: e.target.value as 'none' }, 'Change loop')}>\n <option value=\"none\">Off</option>\n <option value=\"loop\">Loop</option>\n <option value=\"ping-pong\">Ping-pong</option>\n </select>\n <label className=\"text-muted-foreground\">Motion blur</label>\n <select className={input} aria-label=\"Motion blur\" disabled={readOnly} value={scene.motionBlur ? String(scene.motionBlur.shutter ?? 180) : ''} onChange={(e) => settings({ motionBlur: e.target.value ? { ...(scene.motionBlur ?? {}), shutter: Number(e.target.value) } : null }, 'Change motion blur')}>\n <option value=\"\">Off</option>\n <option value=\"90\">Light (90°)</option>\n <option value=\"180\">Normal (180°)</option>\n <option value=\"360\">Heavy (360°)</option>\n </select>\n <label className=\"text-muted-foreground\">Plays on</label>\n <select className={input} aria-label=\"Scene trigger\" title=\"How a viewer plays it when exported to Flair\" disabled={readOnly} value={scene.trigger ?? ''} onChange={(e) => settings({ trigger: (e.target.value || null) as MotionTrigger | null }, 'Change trigger')}>\n <option value=\"\">Its own (autoplay)</option>\n <option value=\"click\">Click (a shot per click)</option>\n <option value=\"hover\">Hover</option>\n <option value=\"press\">Press</option>\n <option value=\"scroll\">Scroll</option>\n </select>\n <label className=\"text-muted-foreground\">Frame rate</label>\n <div className=\"flex items-center gap-1\">\n <CommitInput className={input} type=\"number\" min={1} max={120} aria-label=\"Frame rate\" placeholder=\"30\" disabled={readOnly} value={scene.fps !== undefined ? String(scene.fps) : ''}\n onCommit={(raw) => num(raw, 'Frame rate must be 1 to 120 fps.', (n) => n >= 1 && n <= 120, (n) => n !== null && settings({ fps: n }, 'Change frame rate'))} />\n {unit('fps')}\n </div>\n <label className=\"text-muted-foreground\" title=\"Hold changes on a grid of this many frames a second (12 = on twos); empty is smooth\">\n Steps\n </label>\n <div className=\"flex items-center gap-1\">\n <CommitInput className={input} type=\"number\" min={1} max={120} aria-label=\"Steps\" placeholder=\"smooth\" disabled={readOnly} value={scene.steps !== undefined ? String(scene.steps) : ''}\n onCommit={(raw) => num(raw, 'Steps must be above 0 and at most 120 fps, or empty for smooth.', (n) => n > 0 && n <= 120, (n) => settings({ steps: n }, 'Change steps'))} />\n {unit('fps')}\n </div>\n <label className=\"text-muted-foreground\">Target length</label>\n <div className=\"flex items-center gap-1\">\n {[0, 1].map((i) => (\n <CommitInput key={i} className={input} type=\"number\" min={0} step={0.5} aria-label={i ? 'Target max' : 'Target min'} placeholder={i ? 'max' : 'min'} disabled={readOnly} value={target ? String(target[i]) : ''}\n onCommit={(raw) =>\n num(raw, 'Target lengths are seconds, 0 or more.', (n) => n >= 0, (n) => {\n if (n === null) return settings({ target: null }, 'Clear target length');\n const next: [number, number] = target ? [...target] : [n, n];\n next[i] = n;\n if (next[0] > next[1]) return setLocal('The shortest target length must not be longer than the longest.');\n settings({ target: next }, 'Change target length');\n })\n } />\n ))}\n {unit('s')}\n </div>\n <label className=\"text-muted-foreground\">Fit to</label>\n <div className=\"flex items-center gap-1\">\n <input className={input} type=\"number\" min={0.1} step={0.5} aria-label=\"Fit to\" value={fitSeconds} onChange={(e) => setFitTo(e.target.value)} />\n {unit('s')}\n <button type=\"button\" className={btn} disabled={readOnly || !scene.shots.length} onClick={fit} data-fit=\"\" title=\"Change the shots' speeds so the scene lasts this long\">\n Fit\n </button>\n </div>\n <label className=\"text-muted-foreground\">Beat grid</label>\n <div className=\"flex items-center gap-1\" data-beat-grid=\"\">\n <CommitInput className={input} type=\"number\" min={1} aria-label=\"BPM\" placeholder=\"bpm\" disabled={readOnly} value={beat ? String(beat.bpm) : ''}\n onCommit={(raw) => num(raw, 'BPM must be above 0.', (n) => n > 0, (n) => settings({ beat: n === null ? null : { ...(beat ?? {}), bpm: n } }, n === null ? 'Clear beat grid' : 'Change tempo'))} />\n <CommitInput className={input} type=\"number\" aria-label=\"Beat offset\" placeholder=\"offset ms\" disabled={readOnly || !beat} value={beat?.offset !== undefined ? String(beat.offset) : ''}\n onCommit={(raw) => beat && num(raw, 'The offset is a number of ms.', () => true, (n) => settings({ beat: { ...beat, offset: n ?? 0 } }, 'Change beat offset'))} />\n <CommitInput className={input} type=\"number\" min={1} step={1} aria-label=\"Meter\" placeholder=\"4/bar\" disabled={readOnly || !beat} value={beat?.meter !== undefined ? String(beat.meter) : ''}\n onCommit={(raw) => beat && num(raw, 'The meter is a whole number of beats a bar.', (n) => Number.isInteger(n) && n >= 1, (n) => settings({ beat: { ...beat, meter: n ?? 4 } }, 'Change meter'))} />\n </div>\n </div>\n <label className=\"flex flex-col gap-0.5\">\n <span className=\"text-muted-foreground\">Narration (a word a line: start ms, then the word)</span>\n <textarea\n key={formatMotionNarration(scene.narration)}\n className={`${input} h-20 font-mono`}\n aria-label=\"Narration\"\n placeholder={'0 Meet\\n320 the\\n480 badge'}\n disabled={readOnly}\n defaultValue={formatMotionNarration(scene.narration)}\n onBlur={(e) => {\n if (e.currentTarget.value === formatMotionNarration(scene.narration)) return;\n const parsed = parseMotionNarration(e.currentTarget.value);\n if ('error' in parsed) return setLocal(parsed.error);\n settings({ narration: parsed.narration }, parsed.narration ? 'Change narration' : 'Clear narration');\n }}\n />\n </label>\n <label className=\"flex flex-col gap-0.5\">\n <span className=\"text-muted-foreground\">Drivers (one a line: target.property &lt;- source.property * factor)</span>\n <textarea\n key={formatMotionDrivers(scene.drivers)}\n className={`${input} h-14 font-mono`}\n aria-label=\"Drivers\"\n placeholder={'back.x <- front.x * 0.5\\nwheel.rotation <- wheel.x * 2.86'}\n disabled={readOnly}\n defaultValue={formatMotionDrivers(scene.drivers)}\n onBlur={(e) => {\n if (e.currentTarget.value === formatMotionDrivers(scene.drivers)) return;\n const parsed = parseMotionDrivers(e.currentTarget.value);\n if ('error' in parsed) return setLocal(parsed.error);\n apply({ op: 'set_drivers', drivers: parsed.drivers }, parsed.drivers.length ? 'Set drivers' : 'Clear drivers');\n }}\n />\n </label>\n {message && (\n <p className=\"text-red-500\" role=\"alert\" data-edit-error=\"\">\n {message}\n </p>\n )}\n </div>\n );\n}\n","import React, { useMemo, useState } from 'react';\nimport { describeMotionElements, freshShotId, motionCueChoices, motionCueFromKey, motionCueKey, type AnimationEditorController, type MotionEdit } from '@pixerate/editor/animation-editor';\nimport { CommitInput } from './CommitInput';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface ShotInspectorProps {\n controller: AnimationEditorController;\n /** The shot to edit (default: the selected shot, else the first). */\n shot?: string;\n className?: string;\n}\n\nconst input = 'w-full min-w-0 rounded border border-border bg-transparent px-1 py-0.5 text-xs';\nconst btn = 'rounded border border-border px-1.5 py-0.5 text-[11px] disabled:opacity-40';\n\n\n/**\n * The selected shot: its label, hold, speed, the node the camera frames, and the cue it starts\n * on (a beat of the scene's grid or a narration word). Also adds, moves and deletes shots.\n * Every change is one undo step.\n */\nexport function ShotInspector({ controller, shot, className = '' }: ShotInspectorProps) {\n const state = useAnimationEditorState(controller);\n const { scene, selection, readOnly, error } = state;\n const [local, setLocalState] = useState<{ text: string; revision: number } | null>(null);\n const setLocal = (text: string | null) => setLocalState(text ? { text, revision: state.revision } : null);\n const elements = useMemo(() => describeMotionElements(scene), [scene.artwork]);\n const cues = useMemo(() => motionCueChoices(scene), [scene]);\n const id = shot ?? selection?.shot ?? scene.shots[0]?.id;\n const index = scene.shots.findIndex((s) => s.id === id);\n const current = scene.shots[index];\n const apply = (edit: MotionEdit | MotionEdit[], label: string) => {\n setLocal(null);\n return controller.apply(edit, label);\n };\n const addShot = () => {\n const newId = freshShotId(scene, 'shot');\n const at = index >= 0 ? index + 1 : scene.shots.length;\n if (apply({ op: 'insert_shots', shots: [{ id: newId, label: 'New shot', run: [] }], at }, 'Add shot').ok) {\n controller.select({ shot: newId });\n controller.seekShot(newId);\n }\n };\n const number = (key: 'hold' | 'speed', raw: string, label: string) => {\n const n = Number(raw);\n if (raw.trim() === '') return apply({ op: 'update_shot', shot: current.id, remove: [key] }, label);\n if (!Number.isFinite(n) || n < 0 || (key === 'speed' && n <= 0)) return setLocal(key === 'speed' ? 'Speed must be a number above 0 (1 = as written).' : 'Hold must be a number of ms, 0 or more.');\n apply({ op: 'update_shot', shot: current.id, set: { [key]: n } }, label);\n };\n // A local error shows until the editor changes; then the editor's own error (if any) shows.\n const message = (local && local.revision === state.revision ? local.text : null) ?? error;\n const cueKey = current ? motionCueKey(current.at) : '';\n const frame = current?.camera && 'frame' in current.camera ? current.camera.frame : '';\n\n return (\n <div className={`flex flex-col gap-1.5 text-xs ${className}`} data-shot-inspector=\"\">\n <div className=\"flex items-center gap-1\">\n <span className=\"font-medium\">Shot</span>\n {current && <code className=\"text-[10px] text-muted-foreground\">{current.id}</code>}\n <span className=\"ml-auto flex gap-0.5\">\n <button type=\"button\" className={btn} disabled={readOnly} onClick={addShot} data-add-shot=\"\">\n + Shot\n </button>\n {current && (\n <>\n <button type=\"button\" className={btn} aria-label=\"Move shot earlier\" disabled={readOnly || index === 0} onClick={() => apply({ op: 'move_shot', shot: current.id, to: index - 1 }, 'Move shot')}>\n ←\n </button>\n <button type=\"button\" className={btn} aria-label=\"Move shot later\" disabled={readOnly || index === scene.shots.length - 1} onClick={() => apply({ op: 'move_shot', shot: current.id, to: index + 1 }, 'Move shot')}>\n →\n </button>\n <button type=\"button\" className={btn} aria-label=\"Delete shot\" disabled={readOnly} onClick={() => apply({ op: 'delete_shots', shots: [current.id] }, 'Delete shot')}>\n ✕\n </button>\n </>\n )}\n </span>\n </div>\n {current && (\n <div className=\"grid grid-cols-[6.5rem_1fr] items-center gap-x-2 gap-y-1\">\n <label className=\"text-muted-foreground\">Label</label>\n <CommitInput className={input} aria-label=\"Shot label\" disabled={readOnly} value={current.label ?? ''} onCommit={(raw) => apply(raw.trim() ? { op: 'update_shot', shot: current.id, set: { label: raw.trim() } } : { op: 'update_shot', shot: current.id, remove: ['label'] }, 'Rename shot')} />\n <label className=\"text-muted-foreground\">Hold</label>\n <div className=\"flex items-center gap-1\">\n <CommitInput className={input} type=\"number\" min={0} step={50} aria-label=\"Hold\" placeholder=\"600\" disabled={readOnly} value={current.hold !== undefined ? String(current.hold) : ''} onCommit={(raw) => number('hold', raw, 'Change hold')} />\n <span className=\"text-[10px] text-muted-foreground\">ms</span>\n </div>\n <label className=\"text-muted-foreground\">Speed</label>\n <div className=\"flex items-center gap-1\">\n <CommitInput className={input} type=\"number\" min={0.05} step={0.05} aria-label=\"Speed\" placeholder=\"1\" disabled={readOnly} value={current.speed !== undefined ? String(current.speed) : ''} onCommit={(raw) => number('speed', raw, 'Change speed')} />\n <span className=\"text-[10px] text-muted-foreground\">×</span>\n </div>\n <label className=\"text-muted-foreground\">Camera</label>\n <select\n className={input}\n aria-label=\"Camera frames\"\n disabled={readOnly}\n value={current.camera ? (frame ? `frame:${frame}` : 'rect') : ''}\n onChange={(e) => {\n const v = e.target.value;\n if (!v) apply({ op: 'update_shot', shot: current.id, remove: ['camera'] }, 'Clear camera');\n else if (v.startsWith('frame:')) apply({ op: 'update_shot', shot: current.id, set: { camera: { frame: v.slice(6), padding: 24 } } }, 'Frame camera');\n }}\n >\n <option value=\"\">keep framing</option>\n {current.camera && !frame && <option value=\"rect\">a rectangle</option>}\n {elements.map((e) => (\n <option key={e.id} value={`frame:${e.id}`}>\n frame {e.name ?? e.id}\n </option>\n ))}\n </select>\n <label className=\"text-muted-foreground\">Starts on</label>\n <select\n className={input}\n aria-label=\"Cue\"\n disabled={readOnly || index === 0}\n value={cueKey}\n onChange={(e) => {\n const cue = motionCueFromKey(e.target.value);\n apply(cue ? { op: 'update_shot', shot: current.id, set: { at: cue } } : { op: 'update_shot', shot: current.id, remove: ['at'] }, 'Cue shot');\n }}\n >\n <option value=\"\">after the shot before</option>\n {cueKey && !cues.some((c) => c.value === cueKey) && <option value={cueKey}>{cueKey}</option>}\n {cues.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n {!cues.length && index > 0 && <p className=\"col-span-2 text-[10px] text-muted-foreground\">Add a beat grid or narration in the scene settings to cue shots to them.</p>}\n </div>\n )}\n {message && (\n <p className=\"text-red-500\" role=\"alert\" data-edit-error=\"\">\n {message}\n </p>\n )}\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\nimport type { EffectDescription, EffectProvider } from '@pixerate/editor/effects';\n\n/** Anything that takes an effects provider: every editor controller with effects support. */\nexport interface EffectsHost {\n useEffects(provider: EffectProvider): () => void;\n}\n\n/**\n * Registers `provider` with an editor while mounted (or while it is the one passed), and removes it\n * again on unmount. Pass `null` or `undefined` for no provider: the editor then behaves as without\n * effects support.\n */\nexport function useEffects(host: EffectsHost | null | undefined, provider: EffectProvider | null | undefined): void {\n useEffect(() => {\n if (!host || !provider) return;\n return host.useEffects(provider);\n }, [host, provider]);\n}\n\n/** An effect's description from the provider, loaded when `effect` changes (`null` while loading or on error). */\nexport function useEffectDescription(provider: EffectProvider | null | undefined, effect: string | null | undefined): { description: EffectDescription | null; error: string | null } {\n const [state, setState] = useState<{ key: string; description: EffectDescription | null; error: string | null }>({ key: '', description: null, error: null });\n const key = provider && effect ? `${provider.id}:${effect}` : '';\n useEffect(() => {\n if (!provider || !effect) return;\n let live = true;\n Promise.resolve()\n .then(() => provider.describe(effect))\n .then(\n (description) => live && setState({ key, description, error: null }),\n (e: unknown) => live && setState({ key, description: null, error: e instanceof Error ? e.message : String(e) }),\n );\n return () => {\n live = false;\n };\n }, [provider, effect, key]);\n return state.key === key ? { description: state.description, error: state.error } : { description: null, error: null };\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { renderEffectThumbnail, type EffectProvider, type EffectSummary } from '@pixerate/editor/effects';\n\nexport interface EffectThumbnailProps {\n provider: EffectProvider;\n effect: EffectSummary;\n /** Pixel size of the preview (default 96 × 54). */\n width?: number;\n height?: number;\n className?: string;\n}\n\n/**\n * A preview of an effect drawn by the provider's own renderer (filters on a sample picture,\n * transitions half way, generators mid-way through). Motion effects and failures show a label.\n */\nexport function EffectThumbnail({ provider, effect, width = 96, height = 54, className = '' }: EffectThumbnailProps) {\n const ref = useRef<HTMLCanvasElement>(null);\n const [failed, setFailed] = useState(effect.kind === 'motion');\n useEffect(() => {\n if (effect.kind === 'motion') return;\n let live = true;\n renderEffectThumbnail(provider, effect, { width, height }).then(\n (pixels) => {\n const ctx = live ? ref.current?.getContext('2d') : null;\n if (!ctx || typeof ImageData === 'undefined') return;\n ctx.putImageData(new ImageData(new Uint8ClampedArray(pixels.data), pixels.width, pixels.height), 0, 0);\n },\n () => live && setFailed(true),\n );\n return () => {\n live = false;\n };\n }, [provider, effect, width, height]);\n return (\n <div\n className={`relative overflow-hidden rounded border border-border bg-[repeating-conic-gradient(#8884_0_25%,transparent_0_50%)] bg-[length:12px_12px] ${className}`}\n style={{ aspectRatio: `${width} / ${height}` }}\n data-effect-thumbnail={effect.id}\n >\n {failed ? (\n <span className=\"absolute inset-0 flex items-center justify-center text-[10px] text-muted-foreground\">{effect.kind === 'motion' ? 'Motion' : 'No preview'}</span>\n ) : (\n <canvas ref={ref} width={width} height={height} className=\"h-full w-full\" aria-hidden=\"true\" />\n )}\n </div>\n );\n}\n","import React, { useEffect, useMemo, useState } from 'react';\nimport { EFFECT_USE_LABELS, type EffectKind, type EffectProvider, type EffectSummary, type EffectUse } from '@pixerate/editor/effects';\nimport { EffectThumbnail } from './EffectThumbnail';\n\nexport interface EffectsBrowserProps {\n /** The editor's provider; without one the browser says effects are unavailable. */\n provider: EffectProvider | null | undefined;\n /** Only effects with one of these uses (default: all but motion). */\n uses?: readonly EffectUse[];\n /** Only effects of these kinds (default: any). */\n kinds?: readonly EffectKind[];\n /** Called with the effect the user picks. */\n onPick: (effect: EffectSummary) => void;\n /** Draw previews with the provider's renderer (default true). */\n thumbnails?: boolean;\n /** Heading (default \"Effects\"). */\n title?: React.ReactNode;\n className?: string;\n}\n\n/**\n * Browses a provider's effects: a search box, a category filter (and a use filter when more than\n * one use is allowed), and a grid of effects with previews. Picking one calls `onPick`.\n */\nexport function EffectsBrowser({ provider, uses, kinds, onPick, thumbnails = true, title = 'Effects', className = '' }: EffectsBrowserProps) {\n const [all, setAll] = useState<readonly EffectSummary[]>([]);\n const [query, setQuery] = useState('');\n const [category, setCategory] = useState('');\n const [use, setUse] = useState<EffectUse | ''>('');\n const [error, setError] = useState<string | null>(null);\n useEffect(() => {\n if (!provider) return setAll([]);\n let live = true;\n Promise.resolve()\n .then(() => provider.list())\n .then(\n (list) => live && (setAll(list), setError(null)),\n (e: unknown) => live && setError(e instanceof Error ? e.message : String(e)),\n );\n return () => {\n live = false;\n };\n }, [provider]);\n const [found, setFound] = useState<readonly EffectSummary[]>([]);\n useEffect(() => {\n if (!provider) return setFound([]);\n let live = true;\n Promise.resolve()\n .then(() => provider.search(query, { ...(category ? { category } : {}), ...(use ? { use } : {}) }))\n .then((list) => live && setFound(list), () => live && setFound([]));\n return () => {\n live = false;\n };\n }, [provider, query, category, use]);\n const allowed = (e: EffectSummary) => (!kinds || kinds.includes(e.kind)) && (uses ? e.kind !== 'motion' || uses.includes('motion') : e.kind !== 'motion') && (!uses || e.uses.some((u) => uses.includes(u)));\n const categories = useMemo(() => [...new Set(all.filter(allowed).map((e) => e.category))], [all, uses, kinds]);\n const shown = found.filter(allowed);\n if (!provider)\n return (\n <div className={`rounded-md border border-dashed border-border p-3 text-xs text-muted-foreground ${className}`} data-effects-browser=\"\" data-effects-unavailable=\"\">\n No effects provider is registered, so effects cannot be added. Effects already in the document are kept.\n </div>\n );\n return (\n <section className={`flex flex-col gap-2 ${className}`} data-effects-browser=\"\" aria-label=\"Effects browser\">\n {title && <h3 className=\"text-xs font-semibold\">{title}</h3>}\n <div className=\"flex flex-wrap gap-1\">\n <input\n type=\"search\"\n className=\"min-w-0 flex-1 rounded border border-border bg-transparent px-1.5 py-0.5 text-xs\"\n placeholder=\"Search effects\"\n aria-label=\"Search effects\"\n value={query}\n onChange={(e) => setQuery(e.currentTarget.value)}\n />\n <select className=\"rounded border border-border bg-transparent px-1 py-0.5 text-xs\" aria-label=\"Category\" value={category} onChange={(e) => setCategory(e.currentTarget.value)}>\n <option value=\"\">All categories</option>\n {categories.map((c) => (\n <option key={c} value={c}>\n {c}\n </option>\n ))}\n </select>\n {uses && uses.length > 1 && (\n <select className=\"rounded border border-border bg-transparent px-1 py-0.5 text-xs\" aria-label=\"Use\" value={use} onChange={(e) => setUse(e.currentTarget.value as EffectUse | '')}>\n <option value=\"\">Any use</option>\n {uses.map((u) => (\n <option key={u} value={u}>\n {EFFECT_USE_LABELS[u]}\n </option>\n ))}\n </select>\n )}\n </div>\n {error && <p role=\"alert\" className=\"text-[11px] text-destructive\">{error}</p>}\n <ul className=\"grid max-h-96 grid-cols-[repeat(auto-fill,minmax(6.5rem,1fr))] gap-1.5 overflow-y-auto\" role=\"list\">\n {shown.map((e) => (\n <li key={e.id}>\n <button\n type=\"button\"\n className=\"flex w-full flex-col gap-1 rounded border border-transparent p-1 text-left hover:border-border focus-visible:border-border\"\n title={e.description ?? e.name}\n data-effect-id={e.id}\n onClick={() => onPick(e)}\n >\n {thumbnails && <EffectThumbnail provider={provider} effect={e} />}\n <span className=\"truncate text-[11px] font-medium\">{e.name}</span>\n <span className=\"truncate text-[10px] text-muted-foreground\">{e.uses.map((u) => EFFECT_USE_LABELS[u]).join(' · ')}</span>\n </button>\n </li>\n ))}\n </ul>\n {!shown.length && !error && <p className=\"text-[11px] text-muted-foreground\">No effects match.</p>}\n </section>\n );\n}\n","import React, { useId, useMemo } from 'react';\nimport { effectFieldValue, effectParameterFields, type EffectDescription } from '@pixerate/editor/effects';\nimport { parameterLabel, parameterValuesEqual, type ParameterValue } from '@pixerate/editor/parameters';\nimport { ParameterFieldControl } from '../parameters/fields';\n\nexport interface EffectParametersProps {\n /** The effect's description (`describe`). */\n description: EffectDescription;\n /** Its saved values; controls left out show their defaults. */\n values: Readonly<Record<string, unknown>>;\n /**\n * A control changed. While a slider or colour drag is under way `gesture` is a key unique to\n * that drag, so the host can fold its changes into one undo step; otherwise `null`.\n */\n onChange: (control: string, value: ParameterValue, gesture: string | null) => void;\n /** Resets one control to its default. */\n onReset?: (control: string) => void;\n /** Controls that are keyframed: shown read-only with a note (edit them as keyframes). */\n keyframed?: ReadonlySet<string>;\n /** Applies a preset's values. */\n onPreset?: (values: Readonly<Record<string, unknown>>) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * The parameter panel of an effect, generated from its JSON Schema controls: sliders for bounded\n * numbers, switches, choices, colour pickers, vectors and text, with each control's description,\n * per-control reset and the effect's presets.\n */\nexport function EffectParameters({ description, values, onChange, onReset, keyframed, onPreset, disabled = false, className = '' }: EffectParametersProps) {\n const fields = useMemo(() => effectParameterFields(description), [description]);\n const idBase = useId();\n const gesture = React.useRef<string | null>(null);\n const count = React.useRef(0);\n return (\n <div className={`space-y-2 ${className}`} data-effect-parameters={description.id}>\n {onPreset && description.presets.length > 0 && (\n <select\n className=\"w-full rounded border border-border bg-transparent px-1 py-0.5 text-xs\"\n aria-label={`${description.name} presets`}\n value=\"\"\n disabled={disabled}\n onChange={(e) => {\n const preset = description.presets.find((p) => p.name === e.currentTarget.value);\n if (preset) onPreset({ ...description.defaults, ...preset.values });\n }}\n >\n <option value=\"\">Presets…</option>\n {description.presets.map((p) => (\n <option key={p.name} value={p.name}>\n {p.name}\n </option>\n ))}\n </select>\n )}\n {fields.map((field) => {\n const label = parameterLabel(field);\n const inputId = `${idBase}-${field.id}`;\n const keyed = keyframed?.has(field.id) ?? false;\n const value = effectFieldValue(field, values[field.id]);\n const changed = !keyed && !parameterValuesEqual(value, field.default);\n return (\n <div key={field.id} className=\"space-y-1\" data-effect-control={field.id}>\n <div className=\"flex items-center gap-1.5\">\n <label htmlFor={inputId} className=\"min-w-0 flex-1 truncate text-xs font-medium\" title={field.description}>\n {label}\n </label>\n {keyed && <span className=\"text-[10px] text-muted-foreground\">keyframed</span>}\n {onReset && changed && !disabled && (\n <button type=\"button\" className=\"rounded px-1 text-[11px] text-muted-foreground hover:text-foreground\" aria-label={`Reset ${label}`} onClick={() => onReset(field.id)}>\n ↺\n </button>\n )}\n </div>\n <ParameterFieldControl\n field={field}\n value={value}\n id={inputId}\n disabled={disabled || keyed}\n onChange={(v) => onChange(field.id, v, gesture.current)}\n onGestureStart={() => (gesture.current = `${idBase}:${field.id}:${++count.current}`)}\n onGestureEnd={() => (gesture.current = null)}\n />\n </div>\n );\n })}\n {!fields.length && <p className=\"text-[11px] text-muted-foreground\">No controls.</p>}\n </div>\n );\n}\n","import React, { useRef } from 'react';\nimport {\n choiceOptionLabel,\n formatParameterNumber,\n getChoiceOptions,\n isSliderField,\n normalizeHexColor,\n parameterLabel,\n parameterStep,\n parseParameterNumberInput,\n clampParameterNumber,\n vectorComponentField,\n vectorSize,\n type BooleanParameterField,\n type ChoiceParameterField,\n type ColorParameterField,\n type ImageParameterField,\n type NumberParameterField,\n type ParameterField,\n type ParameterKeyState,\n type ParameterValue,\n type TextParameterField,\n type VectorParameterField,\n} from '@pixerate/editor/parameters';\n\n/** Props every field control takes. Controls are controller-free: wire them to anything. */\nexport interface ParameterControlProps<F extends ParameterField, V extends ParameterValue> {\n field: F;\n value: V;\n onChange: (value: V) => void;\n /** A continuous edit (slider drag, colour pick) started: merge changes into one undo step. */\n onGestureStart?: () => void;\n onGestureEnd?: () => void;\n disabled?: boolean;\n /** DOM id of the main input (for a `<label htmlFor>`). */\n id?: string;\n}\n\nexport const parameterInputClass =\n 'h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground tabular-nums focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50';\nexport const parameterButtonClass =\n 'inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50';\nconst rangeClass = 'h-4 w-full min-w-0 flex-1 cursor-pointer accent-primary disabled:cursor-not-allowed disabled:opacity-50';\n\ntype CommitInputProps = {\n value: string;\n /** Called with the text and the element (e.g. to show the stored value again after a refused edit). */\n onCommit: (value: string, input: HTMLInputElement | HTMLTextAreaElement) => void;\n multiline?: boolean;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement> & React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange' | 'defaultValue'>;\n\n/** A text box that commits on blur or Enter (Mod+Enter when multiline) and resets on Escape. */\nexport function ParameterCommitInput({ value, onCommit, multiline, className, onKeyDown, ...rest }: CommitInputProps) {\n const commit = (el: HTMLInputElement | HTMLTextAreaElement) => {\n if (el.value !== value) onCommit(el.value, el);\n };\n const keyDown = (e: React.KeyboardEvent<HTMLInputElement & HTMLTextAreaElement>) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === 'Enter' && (!multiline || e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n commit(e.currentTarget);\n }\n if (e.key === 'Escape') e.currentTarget.value = value;\n };\n const props = {\n defaultValue: value,\n className: className ?? parameterInputClass,\n onBlur: (e: React.FocusEvent<HTMLInputElement & HTMLTextAreaElement>) => commit(e.currentTarget),\n onKeyDown: keyDown,\n ...rest,\n };\n // `key` remounts the box when the value changes from outside.\n return multiline ? (\n <textarea key={value} {...props} className={`${props.className} h-auto min-h-[3.5rem] py-1`} />\n ) : (\n <input key={value} type=\"text\" {...props} />\n );\n}\n\nconst plainNumber = (field: NumberParameterField, value: number) => formatParameterNumber({ ...field, unit: undefined }, value);\n\n/** A number box: type a value (units allowed), or step with the arrow keys (Shift ×10). */\nexport function ParameterNumberInput({\n field,\n value,\n onChange,\n disabled,\n id,\n 'aria-label': ariaLabel,\n}: ParameterControlProps<NumberParameterField, number> & { 'aria-label'?: string }) {\n return (\n <div className=\"relative min-w-0 flex-1\">\n <ParameterCommitInput\n id={id}\n inputMode=\"decimal\"\n aria-label={ariaLabel ?? parameterLabel(field)}\n value={plainNumber(field, value)}\n disabled={disabled || field.readOnly}\n className={`${parameterInputClass} ${field.unit ? 'pr-6' : ''}`}\n onCommit={(text, input) => {\n const n = parseParameterNumberInput(field, text);\n // Show the stored value again when the text was not a number or clamps to it.\n if (n === null || n === value) input.value = plainNumber(field, value);\n else onChange(n);\n }}\n onKeyDown={(e) => {\n if (e.key !== 'ArrowUp' && e.key !== 'ArrowDown') return;\n e.preventDefault();\n const step = parameterStep(field) * (e.shiftKey ? 10 : 1);\n onChange(clampParameterNumber(field, value + (e.key === 'ArrowUp' ? step : -step)));\n }}\n />\n {field.unit && (\n <span className=\"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[10px] text-muted-foreground\">{field.unit}</span>\n )}\n </div>\n );\n}\n\n/** A slider plus number box for `number` / `int` fields (number box only for `control: 'input'` or unbounded fields). */\nexport function ParameterSlider(props: ParameterControlProps<NumberParameterField, number>) {\n const { field, value, onChange, onGestureStart, onGestureEnd, disabled } = props;\n const dragging = useRef(false);\n const end = () => {\n if (!dragging.current) return;\n dragging.current = false;\n onGestureEnd?.();\n };\n if (!isSliderField(field)) return <ParameterNumberInput {...props} />;\n const step = parameterStep(field);\n return (\n <div className=\"flex items-center gap-2\">\n <input\n type=\"range\"\n aria-label={parameterLabel(field)}\n aria-valuetext={formatParameterNumber(field, value)}\n min={field.min}\n max={field.max}\n step={step}\n value={value}\n disabled={disabled || field.readOnly}\n className={rangeClass}\n onPointerDown={() => {\n if (dragging.current) return;\n dragging.current = true;\n onGestureStart?.();\n }}\n onPointerUp={end}\n onPointerCancel={end}\n onBlur={end}\n onChange={(e) => onChange(clampParameterNumber(field, Number(e.target.value)))}\n />\n <div className=\"w-20 shrink-0\">\n <ParameterNumberInput {...props} id={props.id} aria-label={`${parameterLabel(field)} value`} />\n </div>\n </div>\n );\n}\n\n/** An on/off switch for `boolean` fields. */\nexport function ParameterToggle({ field, value, onChange, disabled, id }: ParameterControlProps<BooleanParameterField, boolean>) {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n id={id}\n aria-checked={value}\n aria-label={parameterLabel(field)}\n disabled={disabled || field.readOnly}\n onClick={() => onChange(!value)}\n className={`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-transparent transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:opacity-50 ${\n value ? 'bg-primary' : 'bg-muted'\n }`}\n >\n <span\n className={`pointer-events-none block h-4 w-4 rounded-full bg-background shadow transition-transform ${value ? 'translate-x-4' : 'translate-x-0.5'}`}\n />\n </button>\n );\n}\n\n/** A dropdown (or segmented buttons with `control: 'segmented'`) for `choice` fields. */\nexport function ParameterSelect({ field, value, onChange, disabled, id }: ParameterControlProps<ChoiceParameterField, string | number>) {\n const options = getChoiceOptions(field);\n const off = disabled || field.readOnly;\n if (field.control === 'segmented') {\n return (\n <div role=\"radiogroup\" aria-label={parameterLabel(field)} className=\"inline-flex flex-wrap rounded-md border border-input bg-muted p-0.5\">\n {options.map((o) => (\n <button\n key={String(o.value)}\n type=\"button\"\n role=\"radio\"\n aria-checked={o.value === value}\n title={o.description}\n disabled={off}\n onClick={() => onChange(o.value)}\n className={`rounded px-2 py-0.5 text-xs disabled:opacity-50 ${\n o.value === value ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n {choiceOptionLabel(o)}\n </button>\n ))}\n </div>\n );\n }\n const index = options.findIndex((o) => o.value === value);\n return (\n <select\n id={id}\n aria-label={parameterLabel(field)}\n value={String(index)}\n disabled={off}\n onChange={(e) => {\n const option = options[Number(e.target.value)];\n if (option) onChange(option.value);\n }}\n className={parameterInputClass}\n >\n {options.map((o, i) => (\n <option key={String(o.value)} value={String(i)} title={o.description}>\n {choiceOptionLabel(o)}\n </option>\n ))}\n </select>\n );\n}\n\n/** A colour picker with a hex box, an alpha slider (with `alpha`) and swatches. */\nexport function ParameterColor({ field, value, onChange, onGestureStart, onGestureEnd, disabled, id }: ParameterControlProps<ColorParameterField, string>) {\n const picking = useRef(false);\n const alpha = !!field.alpha;\n const hex = normalizeHexColor(value, true) ?? '#000000ff';\n const rgb = hex.slice(0, 7);\n const a = hex.slice(7);\n const off = disabled || field.readOnly;\n const start = () => {\n if (picking.current) return;\n picking.current = true;\n onGestureStart?.();\n };\n const end = () => {\n if (!picking.current) return;\n picking.current = false;\n onGestureEnd?.();\n };\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <span className=\"relative h-7 w-9 shrink-0 overflow-hidden rounded-md border border-input bg-[repeating-conic-gradient(#d4d4d8_0_25%,#fff_0_50%)] bg-[length:8px_8px]\">\n <span className=\"absolute inset-0\" style={{ background: alpha ? hex : rgb }} />\n <input\n type=\"color\"\n aria-label={parameterLabel(field)}\n value={rgb}\n disabled={off}\n className=\"absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n onChange={(e) => {\n start();\n onChange(alpha ? `${e.target.value}${a}` : e.target.value);\n }}\n onBlur={end}\n />\n </span>\n <ParameterCommitInput\n id={id}\n aria-label={`${parameterLabel(field)} hex`}\n value={alpha ? hex : rgb}\n disabled={off}\n spellCheck={false}\n className={`${parameterInputClass} font-mono`}\n onCommit={(text) => {\n const next = normalizeHexColor(text, alpha);\n if (next) onChange(next);\n }}\n />\n </div>\n {alpha && (\n <input\n type=\"range\"\n aria-label={`${parameterLabel(field)} opacity`}\n min={0}\n max={255}\n step={1}\n value={parseInt(a, 16)}\n disabled={off}\n className={rangeClass}\n onPointerDown={start}\n onPointerUp={end}\n onPointerCancel={end}\n onBlur={end}\n onChange={(e) => onChange(`${rgb}${Number(e.target.value).toString(16).padStart(2, '0')}`)}\n />\n )}\n {field.swatches && field.swatches.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {field.swatches.map((s) => {\n const swatch = normalizeHexColor(s, alpha);\n if (!swatch) return null;\n return (\n <button\n key={s}\n type=\"button\"\n title={swatch}\n aria-label={`${parameterLabel(field)} ${swatch}`}\n aria-pressed={swatch === (alpha ? hex : rgb)}\n disabled={off}\n onClick={() => onChange(swatch)}\n className=\"h-5 w-5 rounded border border-input aria-pressed:ring-1 aria-pressed:ring-primary\"\n style={{ background: swatch }}\n />\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\n/** One number box per component for `vector` fields. */\nexport function ParameterVector({ field, value, onChange, disabled, id }: ParameterControlProps<VectorParameterField, number[]>) {\n const size = vectorSize(field);\n return (\n <div className=\"grid gap-1.5\" style={{ gridTemplateColumns: `repeat(${size}, minmax(0, 1fr))` }}>\n {Array.from({ length: size }, (_, i) => {\n const component = vectorComponentField(field, i);\n return (\n <label key={i} className=\"flex min-w-0 items-center gap-1\">\n <span className=\"w-3 shrink-0 text-[10px] uppercase text-muted-foreground\">{component.label}</span>\n <ParameterNumberInput\n field={component}\n value={value[i] ?? 0}\n id={i === 0 ? id : undefined}\n aria-label={`${parameterLabel(field)} ${component.label}`}\n disabled={disabled || field.readOnly}\n onChange={(n) => onChange(Array.from({ length: size }, (_, j) => (j === i ? n : (value[j] ?? 0))))}\n />\n </label>\n );\n })}\n </div>\n );\n}\n\nexport interface ParameterImageProps extends ParameterControlProps<ImageParameterField, string> {\n /** Turns a picked file into a URL (upload it, or `URL.createObjectURL`). Without it there is no file button. */\n resolveFile?: (file: File) => string | Promise<string>;\n}\n\n/** An image picker: suggested thumbnails, a URL box, an optional file button and a clear button. */\nexport function ParameterImage({ field, value, onChange, disabled, id, resolveFile }: ParameterImageProps) {\n const off = disabled || field.readOnly;\n const name = parameterLabel(field);\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-12 w-16 shrink-0 items-center justify-center overflow-hidden rounded-md border border-input bg-muted\">\n {value ? (\n <img src={value} alt={name} className=\"h-full w-full object-cover\" />\n ) : (\n <span className=\"text-[10px] text-muted-foreground\">None</span>\n )}\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <ParameterCommitInput\n id={id}\n aria-label={`${name} URL`}\n placeholder=\"Image URL\"\n value={value.startsWith('data:') ? '' : value}\n disabled={off}\n onCommit={(text) => onChange(text.trim())}\n />\n <div className=\"flex gap-1\">\n {resolveFile && (\n <label className={`${parameterButtonClass} cursor-pointer ${off ? 'pointer-events-none opacity-50' : ''}`}>\n Choose file…\n <input\n type=\"file\"\n className=\"sr-only\"\n accept={field.accept ?? 'image/*'}\n disabled={off}\n aria-label={`${name} file`}\n onChange={async (e) => {\n const file = e.target.files?.[0];\n e.target.value = '';\n if (file) onChange(await resolveFile(file));\n }}\n />\n </label>\n )}\n {value && (\n <button type=\"button\" className={parameterButtonClass} disabled={off} onClick={() => onChange('')} aria-label={`Clear ${name}`}>\n Clear\n </button>\n )}\n </div>\n </div>\n </div>\n {field.options && field.options.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {field.options.map((o) => (\n <button\n key={o.url}\n type=\"button\"\n title={o.label ?? o.url}\n aria-label={o.label ?? o.url}\n aria-pressed={o.url === value}\n disabled={off}\n onClick={() => onChange(o.url)}\n className=\"h-9 w-12 overflow-hidden rounded border border-input aria-pressed:ring-2 aria-pressed:ring-primary\"\n >\n <img src={o.url} alt=\"\" className=\"h-full w-full object-cover\" />\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/** A text box (or textarea with `multiline`) that commits on blur or Enter. */\nexport function ParameterText({ field, value, onChange, disabled, id }: ParameterControlProps<TextParameterField, string>) {\n return (\n <ParameterCommitInput\n id={id}\n aria-label={parameterLabel(field)}\n multiline={field.multiline}\n placeholder={field.placeholder}\n maxLength={field.maxLength}\n value={value}\n disabled={disabled || field.readOnly}\n onCommit={onChange}\n />\n );\n}\n\nexport interface KeyframeDiamondProps {\n state: ParameterKeyState;\n onToggle: () => void;\n /** The parameter's label (for the accessible name). */\n label: string;\n disabled?: boolean;\n className?: string;\n}\n\n/** A keyframe toggle: filled when a key sits at the playhead, tinted when the value is animated. */\nexport function KeyframeDiamond({ state, onToggle, label, disabled, className = '' }: KeyframeDiamondProps) {\n const keyed = state === 'keyed';\n return (\n <button\n type=\"button\"\n data-key-state={state}\n aria-pressed={keyed}\n aria-label={`${keyed ? 'Remove' : 'Add'} keyframe for ${label}`}\n title={keyed ? 'Remove keyframe here' : 'Add keyframe at the playhead'}\n disabled={disabled}\n onClick={onToggle}\n className={`inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:opacity-40 ${\n state === 'none' ? 'text-muted-foreground hover:text-foreground' : 'text-amber-500'\n } ${className}`}\n >\n <svg viewBox=\"0 0 10 10\" className=\"h-2.5 w-2.5\" aria-hidden=\"true\">\n <path\n d=\"M5 0.8 9.2 5 5 9.2 0.8 5Z\"\n fill={keyed ? 'currentColor' : 'none'}\n stroke=\"currentColor\"\n strokeWidth=\"1.3\"\n opacity={state === 'animated' ? 0.7 : 1}\n />\n </svg>\n </button>\n );\n}\n\nexport interface ParameterFieldControlProps extends ParameterControlProps<ParameterField, ParameterValue> {\n resolveFile?: ParameterImageProps['resolveFile'];\n}\n\n/** The control for any field type. */\nexport function ParameterFieldControl({ field, value, onChange, resolveFile, ...rest }: ParameterFieldControlProps) {\n const set = onChange as (value: any) => void;\n switch (field.type) {\n case 'number':\n case 'int':\n return <ParameterSlider field={field} value={value as number} onChange={set} {...rest} />;\n case 'boolean':\n return <ParameterToggle field={field} value={value as boolean} onChange={set} {...rest} />;\n case 'choice':\n return <ParameterSelect field={field} value={value as string | number} onChange={set} {...rest} />;\n case 'color':\n return <ParameterColor field={field} value={value as string} onChange={set} {...rest} />;\n case 'vector':\n return <ParameterVector field={field} value={value as number[]} onChange={set} {...rest} />;\n case 'image':\n return <ParameterImage field={field} value={value as string} onChange={set} resolveFile={resolveFile} {...rest} />;\n case 'text':\n return <ParameterText field={field} value={value as string} onChange={set} {...rest} />;\n }\n}\n\n","import React, { useMemo, useState } from 'react';\nimport { indexMotionNodes, type AnimationEditorController, type MotionEffectResult } from '@pixerate/editor/animation-editor';\nimport { EffectParameters, EffectsBrowser, useEffectDescription } from '../effects';\nimport { useAnimationEditorState } from './useAnimationEditor';\n\nexport interface AnimationEffectsPanelProps {\n controller: AnimationEditorController;\n /** The node motion effects are applied to (e.g. the element picked on the stage). */\n node?: string | null;\n className?: string;\n}\n\nconst btn = 'rounded border border-border px-1.5 py-0.5 text-[11px] disabled:opacity-40';\n\nfunction Controls({ controller, instance, effect, values }: { controller: AnimationEditorController; instance: string; effect: string; values: Readonly<Record<string, unknown>> }) {\n const provider = controller.effectsProvider;\n const { description, error } = useEffectDescription(provider, effect);\n const [message, setMessage] = useState<string | null>(null);\n const report = (r: Promise<MotionEffectResult>) => void r.then((x) => setMessage(x.ok ? null : x.error));\n if (!provider) return <p className=\"text-[11px] text-muted-foreground\">No effects provider: its commands are kept as they are.</p>;\n if (error) return <p className=\"text-[11px] text-amber-500\">{error}</p>;\n if (!description) return <p className=\"text-[11px] text-muted-foreground\">Loading…</p>;\n return (\n <>\n <EffectParameters\n description={description}\n values={values}\n onChange={(k, v, gesture) => report(controller.updateMotionEffect(instance, { [k]: v as never }, { merge: gesture ?? undefined }))}\n onReset={(k) => report(controller.updateMotionEffect(instance, { [k]: null }))}\n onPreset={(v) => report(controller.updateMotionEffect(instance, v as never))}\n />\n {message && <p role=\"alert\" className=\"text-[11px] text-destructive\">{message}</p>}\n </>\n );\n}\n\n/**\n * Provider effects in an animation: apply a motion effect to a node (its changes become commands\n * in a new shot), add a vector effect with its own picture, and change or remove the effects the\n * scene holds. Every change is one undo step (a slider drag is one).\n */\nexport function AnimationEffectsPanel({ controller, node, className = '' }: AnimationEffectsPanelProps) {\n const state = useAnimationEditorState(controller);\n const provider = state.effectsProvider;\n const nodes = useMemo(() => [...indexMotionNodes(state.scene.artwork.nodes).keys()], [state.scene.artwork]);\n const [chosen, setChosen] = useState<string>('');\n const target = node && nodes.includes(node) ? node : chosen && nodes.includes(chosen) ? chosen : '';\n const [browse, setBrowse] = useState<null | 'motion' | 'vector'>(null);\n const [open, setOpen] = useState<string | null>(null);\n const [message, setMessage] = useState<string | null>(null);\n const report = (r: MotionEffectResult | Promise<MotionEffectResult>) => void Promise.resolve(r).then((x) => setMessage(x.ok ? (x.notes.length ? x.notes.join(' ') : null) : x.error));\n const applied = useMemo(() => controller.appliedEffects(), [controller, state.scene]);\n const disabled = state.readOnly;\n return (\n <section className={`flex flex-col gap-2 text-xs ${className}`} aria-label=\"Effects\" data-animation-effects=\"\">\n <div className=\"flex flex-wrap items-center gap-1\">\n <span className=\"flex-1 font-semibold\">Effects</span>\n <select className=\"rounded border border-border bg-transparent px-1 py-0.5 text-[11px]\" aria-label=\"Node to animate\" value={target} disabled={!!node} onChange={(e) => setChosen(e.currentTarget.value)}>\n <option value=\"\">Node…</option>\n {nodes.map((id) => (\n <option key={id} value={id}>\n {id}\n </option>\n ))}\n </select>\n <button type=\"button\" className={btn} disabled={disabled || !provider || !target} aria-pressed={browse === 'motion'} onClick={() => setBrowse(browse === 'motion' ? null : 'motion')}>\n Animate…\n </button>\n <button type=\"button\" className={btn} disabled={disabled || !provider} aria-pressed={browse === 'vector'} onClick={() => setBrowse(browse === 'vector' ? null : 'vector')}>\n Vector effect…\n </button>\n </div>\n {!provider && <p className=\"text-[11px] text-muted-foreground\">No effects provider is registered. Commands effects made are kept.</p>}\n {browse === 'motion' && (\n <EffectsBrowser provider={provider} uses={['motion']} kinds={['motion']} title={`Motion for ${target}`} onPick={(e) => (setBrowse(null), report(controller.applyMotionEffect(e.id, [target])))} />\n )}\n {browse === 'vector' && <EffectsBrowser provider={provider} kinds={['vector']} title=\"Vector effects\" onPick={(e) => (setBrowse(null), report(controller.addVectorEffect(e.id)))} />}\n <ol className=\"space-y-1\">\n {applied.map((e) => (\n <li key={e.instance} className=\"rounded border border-border p-1\" data-motion-effect={e.instance}>\n <div className=\"flex items-center gap-1\">\n <button type=\"button\" className=\"min-w-0 flex-1 truncate text-left\" aria-expanded={open === e.instance} onClick={() => setOpen(open === e.instance ? null : e.instance)}>\n {e.name ?? e.effect} <span className=\"text-muted-foreground\">· {e.kind === 'vector' ? 'picture' : e.targets.join(', ')}</span>\n </button>\n <button type=\"button\" className={btn} disabled={disabled} aria-label={`Remove ${e.name ?? e.effect}`} onClick={() => report(controller.removeMotionEffect(e.instance))}>\n ✕\n </button>\n </div>\n {open === e.instance && <div className=\"mt-1\"><Controls controller={controller} instance={e.instance} effect={e.effect} values={e.values} /></div>}\n </li>\n ))}\n </ol>\n {!applied.length && <p className=\"text-[11px] text-muted-foreground\">No provider effects in this scene.</p>}\n {message && <p role=\"status\" className=\"text-[11px] text-muted-foreground\" data-effects-message=\"\">{message}</p>}\n </section>\n );\n}\n"],"mappings":"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","names":["import_react","import_animation_editor","import_jsx_runtime","import_react","import_animation_editor","import_react","import_animation_editor","import_react","import_animation_editor","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_react","import_animation_editor","import_jsx_runtime","import_react","import_animation_editor","import_jsx_runtime","seconds","worst","import_react","import_animation_editor","import_jsx_runtime","input","btn","import_react","import_animation_editor","import_jsx_runtime","input","btn","import_react","import_react","import_jsx_runtime","import_react","import_effects","import_jsx_runtime","import_react","import_effects","import_parameters","import_react","import_jsx_runtime","input","_","import_jsx_runtime","React","import_react","import_animation_editor","import_jsx_runtime","btn","import_jsx_runtime","btn"]}