@pixerate/flair 0.9.0 → 0.11.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.
package/dist/index.d.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  import { C as ControlValue, a as ControlDef } from './controls-Syr6drzO.js';
2
2
  export { c as ControlCheck, b as ControlType, T as TextureSettings, d as checkControlValue, e as coerceControlValue, f as componentCount, g as controlValue, h as describeValue, i as hexToRgb, j as humanise, k as imageUrls, l as isImageUrl, p as parseControls, r as rgbToHex } from './controls-Syr6drzO.js';
3
- export { B as BUILTIN_UNIFORMS, C as CompileError, b as CompileResult, a as CompileStatus, c as CompiledShader, F as FrameState, I as ImageLoadError, R as RendererStats, S as SVG_EDGE, d as ShaderCompileError, e as ShaderRenderer, f as ShaderRendererOptions, T as TextureCache, g as TextureSource, V as VERTEX_SOURCE, h as applyTextureSettings, i as compileShader, j as createContext, k as drawFrame, l as formatCompileError, m as isSvgUrl, n as loadImage, p as parseCompileLog, o as preloadImages, r as releaseImages, q as resetGlCaches, s as sizeSvg, w as wrapSource } from './renderer-0_Ap1tyi.js';
4
- import { C as Clock } from './clock-BhdXWH-n.js';
5
- export { M as ManualClock, j as jitter, p as pageHidden, r as realClock } from './clock-BhdXWH-n.js';
6
- export { AnimateCountOptions, MorphOptions, SvgPlayer, SvgPlayerOptions, SvgView, SvgViewOptions, animateCount, morphPaths, morphSequence, parseSvg, svgDuration, svgView } from './vector/index.js';
7
- export { D as DataKey, E as EASES, a as EaseName, b as SCRAMBLE_MS, c as STEP_MS, d as SVG_PICTURE, e as SvgAnimation, f as SvgBox, g as SvgElementFrame, S as SvgMotion, h as defaultDataKey, i as formatCount, l as lerpAttr, j as lerpData, s as stepData, k as stepProgress, m as stepStart, n as svgFrame, o as svgMotionIssues, p as svgOpeningTag, w as writtenText } from './motion-Ce0lmzm3.js';
3
+ export { B as BUILTIN_UNIFORMS, C as CompileError, b as CompileResult, a as CompileStatus, c as CompiledShader, F as FrameState, I as ImageLoadError, R as RendererStats, S as SVG_EDGE, d as ShaderCompileError, e as ShaderRenderer, f as ShaderRendererOptions, T as TextureCache, g as TextureSource, V as VERTEX_SOURCE, h as applyTextureSettings, i as compileShader, j as createContext, k as drawFrame, l as formatCompileError, m as isSvgUrl, n as loadImage, p as parseCompileLog, o as preloadImages, r as releaseImages, q as resetGlCaches, s as sizeSvg, w as wrapSource } from './renderer-SNYZu__R.js';
4
+ import { C as Clock } from './svg-CpeanaE_.js';
5
+ export { A as AnimateCountOptions, D as DataKey, E as EASES, b as EaseName, M as ManualClock, c as SCRAMBLE_MS, d as STEP_MS, e as SVG_PICTURE, f as SvgAnimation, g as SvgBox, h as SvgElementFrame, S as SvgMotion, i as SvgPlayer, j as SvgPlayerOptions, a as SvgTrigger, k as SvgView, l as SvgViewOptions, m as animateCount, n as defaultDataKey, o as formatCount, p as jitter, q as lerpAttr, r as lerpData, s as pageHidden, t as parseSvg, u as realClock, v as stepData, w as stepProgress, x as stepStart, y as svgDuration, z as svgFrame, B as svgMotionIssues, F as svgOpeningTag, G as svgView, H as writtenText } from './svg-CpeanaE_.js';
6
+ export { MorphOptions, morphPaths, morphSequence } from './vector/index.js';
8
7
 
9
8
  /** Controls a registered thumbnail. */
10
9
  interface ThumbnailHandle {
@@ -84,6 +83,62 @@ declare function sharedThumbnailPool(): ThumbnailPool;
84
83
  /** Registers a thumbnail with the shared pool. See {@link ThumbnailPool.register}. */
85
84
  declare function registerThumbnail(canvas: HTMLCanvasElement, source: string, values?: Record<string, ControlValue>, onStatus?: (ok: boolean) => void): ThumbnailHandle;
86
85
 
86
+ /**
87
+ * The pointer as shaders see it, beyond Shadertoy's `iMouse`: where it is
88
+ * while it is over the canvas, how hovered the canvas is (eased in and out),
89
+ * how long it has been pressed, and the last few clicks, so effects can
90
+ * answer hovers, presses and taps. Times are in `iTime` seconds, so a
91
+ * recording can script them (see `ShaderFrames`' `pointer` and `clicks`).
92
+ */
93
+ /** How many clicks `iClicks` holds; older ones drop off. */
94
+ declare const MAX_CLICKS = 8;
95
+ /** How long hovering eases in or out, in seconds. */
96
+ declare const HOVER_SECONDS = 0.25;
97
+ /** A click: where (pixels from the bottom left, like `iMouse`) and when (`iTime` seconds). */
98
+ interface ShaderClick {
99
+ x: number;
100
+ y: number;
101
+ time: number;
102
+ }
103
+ /**
104
+ * `iClicks` from a list of clicks, newest first: `vec4(x, y, time, 1)` for
105
+ * each click at or before `time`, zeros for the rest.
106
+ */
107
+ declare function clicksUniform(clicks: readonly ShaderClick[], time: number): Float32Array;
108
+ /**
109
+ * Follows one canvas's pointer for `iPointer` and `iClicks`: feed it pointer
110
+ * events with the `iTime` they happen at, and read the uniforms for a frame.
111
+ */
112
+ declare class PointerTracker {
113
+ private x;
114
+ private y;
115
+ private over;
116
+ private hoverFrom;
117
+ private changedAt;
118
+ private pressedAt;
119
+ private releasedAt;
120
+ private clicks;
121
+ /** The pointer moved to (x, y), in pixels from the bottom left. */
122
+ move(x: number, y: number): void;
123
+ /** The pointer came over the canvas (`true`) or left it. */
124
+ hover(over: boolean, time: number): void;
125
+ /** A press at (x, y): counts as a click. */
126
+ down(x: number, y: number, time: number): void;
127
+ up(time: number): void;
128
+ /** Forgets clicks and presses (when time jumps back, say). */
129
+ clear(): void;
130
+ /** How hovered the canvas is at `time`, 0–1, eased. */
131
+ hovered(time: number): number;
132
+ /**
133
+ * `iPointer` at `time`: x, y, how hovered (0–1), and the press: seconds
134
+ * held while pressed, minus the seconds since it was let go after, 0
135
+ * before the first press.
136
+ */
137
+ pointer(time: number): [number, number, number, number];
138
+ /** `iClicks` at `time` (see {@link clicksUniform}). */
139
+ clicksAt(time: number): Float32Array;
140
+ }
141
+
87
142
  interface ShaderFramesOptions {
88
143
  source: string;
89
144
  values?: Record<string, ControlValue>;
@@ -99,6 +154,10 @@ interface RenderOptions {
99
154
  delta?: number;
100
155
  /** `iMouse` (default: all zero, as on a page nobody has touched). */
101
156
  mouse?: [number, number, number, number];
157
+ /** `iPointer`: x, y, how hovered (0–1), the press (seconds held, or minus seconds since release; default all zero). */
158
+ pointer?: [number, number, number, number];
159
+ /** Clicks so far, for `iClicks` (the latest `MAX_CLICKS` at or before the frame's time count). */
160
+ clicks?: readonly ShaderClick[];
102
161
  }
103
162
  /**
104
163
  * Renders a shader at exact times you choose, off screen. There is no
@@ -1611,4 +1670,4 @@ declare function exportFcp7Xml(scene: Scene, options?: Fcp7ExportOptions): strin
1611
1670
  */
1612
1671
  declare function exportCmx3600Edl(scene: Scene, options?: EdlExportOptions): string;
1613
1672
 
1614
- export { ALL_BLEND_MODES, ALL_TRANSITION_TYPES, type AgentToolDefinition, type AscCdl, type BatchCommand, type BatchExecutionResult, type BatchExecutionStepResult, type Behavior, type BehaviorBase, type BlendMode, type BlockDissolveOptions, type BlurEffect, type BurstEffect, CAMERA_MS, CAMERA_STEP_MS, COMMON_FRAME_RATES, type CameraAngle, type CameraLens, type CameraSample, type CameraShot, type ClearCommand, Clock, type ColorRGB, type ColorRGBA, type ColorRgba, type ColorSpace, ControlDef, ControlValue, type CounterEffect, type CrossZoomOptions, type CustomCommand, DEFAULT_PERSPECTIVE, DEFAULT_STAGE, type DeleteCommand, type DynamicFraming, EASY_EASE, EFFECT_FADE_MS, EFFECT_TYPES, type EasingCurve, type EdlExportOptions, type Effect, type EffectBase, type ElementCommand, FLAIR_AGENT_TOOLS, type Fcp7ExportOptions, type FlowEffect, type FramingOptions, type GifOptions, type GlassWipeOptions, type GlowEffect, type GradientEffect, type GridWipeOptions, type HighlightEffect, type KeyframeEase, type LiftGammaGain, type LightLeakOptions, type LinearWipeOptions, type LottieAnimatable, type LottieAnimation, type LottieExportOptions, type LottieKeyframe, type LottieLayer, type LottieShapeItem, type LottieTransform, MAX_TILT, type MediaEffect, MemorySceneBoard, type MotnExportOptions, NO_CHECK, type OscillateBehavior, type OvershootBehavior, type PathWaypoint, type PlayOptions, type PlayResult, type Point, type PopupWidget, type RadialIrisOptions, type RampBehavior, type RateBehavior, type RationalFrameRate, type Rect, type RenderOptions, type ReplicatorConfig, type ReplicatorPattern, type ReplicatorSequence, type Review, type ReviewOptions, type RigWidget, type RippleEffect, type RunningEffect, SMALL_TEXT_PX, type SMPTEFields, type Scene, type SceneBoard, type SceneCommand, type SceneElement, type SceneIssue, type SceneMedia, type SceneRig, type SceneToolResult, ShaderFrames, type ShaderFramesOptions, type ShimmerEffect, type Shot, type ShotCamera, type ShotCheck, type ShotLog, type ShotTiming, type SliderSnapshot, type SliderWidget, type SpatialMotionPath, type SpatialPathSample, type SpotlightEffect, type Stage, type StandaloneOptions, type StandardFrameRateKey, type ThrowBehavior, type ThumbnailHandle, ThumbnailPool, type ThumbnailPoolOptions, type TimerEffect, type ToggleWidget, type TransitionOptions, type TransitionSample, type TransitionType, type TwisterOptions, type UpdateCommand, type Vec2, type Vec3, type View, type WriggleBehavior, applyAscCdl, applyLiftGammaGain, applyRig, applySceneBatch, applySceneTool, applyVibrance, areaOf, between, bez1d, bez1dDerivative, blendRgba, blendTransitionPixel, boardHeight, boundsOf, calculateFramingRect, calculateShotTimings, cameraAngle, cameraAt, cameraBlur, cameraFilter, cameraSamples, cameraTrack, cameraTransform, centreOf, checkShot, convertColorSpace, createFrameRate, createLottieEase, createMotionPath, easeInOutCubic, easeProgress, effectGone, effectOpacity, evaluateBehavior, evaluateKeyframeSegment, expandReplicator, exportCmx3600Edl, exportFcp7Xml, exportLottie, exportMotn, formatTimecode, fractalWiggle, frame, framesToSMPTE, framesToTimecode, getColorGradingGLSL, getDropFrameCount, getGlslBlendFunction, getOklabGLSL, getTimecodeBase, getTransitionGLSL, getWhiteBalanceGains, hash64, holdTime, interpolateOklab, interpolateOklch, isAngled, isDeleteCommand, isElementCommand, isUpdateCommand, linearRgbToSrgb, linearSrgbToOklab, linearToSrgb, loopTime, mixSeeds, motionBlur, motionBlurAngle, moveBlur, noise1d, noise3d, oklabToLinearSrgb, oklabToOklch, oklabToSrgb, oklchToOklab, overlapArea, parseTimecode, pingPongTime, playScene, projectPoint, quinticFade, recordGif, registerThumbnail, reviewScene, sampleMotionPath, sampleMotionPathAtTime, sampleTransition, sceneStage, screenBox, setRigWidget, sharedThumbnailPool, shotView, simulateScene, smpteToFrames, solveBezierU, speedRampTime, srgbToLinear, srgbToLinearRgb, srgbToOklab, standaloneHtml, standaloneSceneHtml, strobeTime, substituteVariables, supportsDropFrame, timecodeToFrames, titleBox, touchedIds, unitFloat, validateScene, viewAt, visibleRect };
1673
+ export { ALL_BLEND_MODES, ALL_TRANSITION_TYPES, type AgentToolDefinition, type AscCdl, type BatchCommand, type BatchExecutionResult, type BatchExecutionStepResult, type Behavior, type BehaviorBase, type BlendMode, type BlockDissolveOptions, type BlurEffect, type BurstEffect, CAMERA_MS, CAMERA_STEP_MS, COMMON_FRAME_RATES, type CameraAngle, type CameraLens, type CameraSample, type CameraShot, type ClearCommand, Clock, type ColorRGB, type ColorRGBA, type ColorRgba, type ColorSpace, ControlDef, ControlValue, type CounterEffect, type CrossZoomOptions, type CustomCommand, DEFAULT_PERSPECTIVE, DEFAULT_STAGE, type DeleteCommand, type DynamicFraming, EASY_EASE, EFFECT_FADE_MS, EFFECT_TYPES, type EasingCurve, type EdlExportOptions, type Effect, type EffectBase, type ElementCommand, FLAIR_AGENT_TOOLS, type Fcp7ExportOptions, type FlowEffect, type FramingOptions, type GifOptions, type GlassWipeOptions, type GlowEffect, type GradientEffect, type GridWipeOptions, HOVER_SECONDS, type HighlightEffect, type KeyframeEase, type LiftGammaGain, type LightLeakOptions, type LinearWipeOptions, type LottieAnimatable, type LottieAnimation, type LottieExportOptions, type LottieKeyframe, type LottieLayer, type LottieShapeItem, type LottieTransform, MAX_CLICKS, MAX_TILT, type MediaEffect, MemorySceneBoard, type MotnExportOptions, NO_CHECK, type OscillateBehavior, type OvershootBehavior, type PathWaypoint, type PlayOptions, type PlayResult, type Point, PointerTracker, type PopupWidget, type RadialIrisOptions, type RampBehavior, type RateBehavior, type RationalFrameRate, type Rect, type RenderOptions, type ReplicatorConfig, type ReplicatorPattern, type ReplicatorSequence, type Review, type ReviewOptions, type RigWidget, type RippleEffect, type RunningEffect, SMALL_TEXT_PX, type SMPTEFields, type Scene, type SceneBoard, type SceneCommand, type SceneElement, type SceneIssue, type SceneMedia, type SceneRig, type SceneToolResult, type ShaderClick, ShaderFrames, type ShaderFramesOptions, type ShimmerEffect, type Shot, type ShotCamera, type ShotCheck, type ShotLog, type ShotTiming, type SliderSnapshot, type SliderWidget, type SpatialMotionPath, type SpatialPathSample, type SpotlightEffect, type Stage, type StandaloneOptions, type StandardFrameRateKey, type ThrowBehavior, type ThumbnailHandle, ThumbnailPool, type ThumbnailPoolOptions, type TimerEffect, type ToggleWidget, type TransitionOptions, type TransitionSample, type TransitionType, type TwisterOptions, type UpdateCommand, type Vec2, type Vec3, type View, type WriggleBehavior, applyAscCdl, applyLiftGammaGain, applyRig, applySceneBatch, applySceneTool, applyVibrance, areaOf, between, bez1d, bez1dDerivative, blendRgba, blendTransitionPixel, boardHeight, boundsOf, calculateFramingRect, calculateShotTimings, cameraAngle, cameraAt, cameraBlur, cameraFilter, cameraSamples, cameraTrack, cameraTransform, centreOf, checkShot, clicksUniform, convertColorSpace, createFrameRate, createLottieEase, createMotionPath, easeInOutCubic, easeProgress, effectGone, effectOpacity, evaluateBehavior, evaluateKeyframeSegment, expandReplicator, exportCmx3600Edl, exportFcp7Xml, exportLottie, exportMotn, formatTimecode, fractalWiggle, frame, framesToSMPTE, framesToTimecode, getColorGradingGLSL, getDropFrameCount, getGlslBlendFunction, getOklabGLSL, getTimecodeBase, getTransitionGLSL, getWhiteBalanceGains, hash64, holdTime, interpolateOklab, interpolateOklch, isAngled, isDeleteCommand, isElementCommand, isUpdateCommand, linearRgbToSrgb, linearSrgbToOklab, linearToSrgb, loopTime, mixSeeds, motionBlur, motionBlurAngle, moveBlur, noise1d, noise3d, oklabToLinearSrgb, oklabToOklch, oklabToSrgb, oklchToOklab, overlapArea, parseTimecode, pingPongTime, playScene, projectPoint, quinticFade, recordGif, registerThumbnail, reviewScene, sampleMotionPath, sampleMotionPathAtTime, sampleTransition, sceneStage, screenBox, setRigWidget, sharedThumbnailPool, shotView, simulateScene, smpteToFrames, solveBezierU, speedRampTime, srgbToLinear, srgbToLinearRgb, srgbToOklab, standaloneHtml, standaloneSceneHtml, strobeTime, substituteVariables, supportsDropFrame, timecodeToFrames, titleBox, touchedIds, unitFloat, validateScene, viewAt, visibleRect };
package/dist/index.js CHANGED
@@ -20,7 +20,7 @@ import {
20
20
  svgOpeningTag,
21
21
  svgView,
22
22
  writtenText
23
- } from "./chunk-TDMD5XAU.js";
23
+ } from "./chunk-YACVME3D.js";
24
24
  import {
25
25
  morphPaths,
26
26
  morphSequence
@@ -38,10 +38,13 @@ import {
38
38
  standaloneHtml,
39
39
  standaloneSceneHtml,
40
40
  validateScene
41
- } from "./chunk-EQS4EXNM.js";
41
+ } from "./chunk-SH66CNLC.js";
42
42
  import {
43
43
  BUILTIN_UNIFORMS,
44
+ HOVER_SECONDS,
44
45
  ImageLoadError,
46
+ MAX_CLICKS,
47
+ PointerTracker,
45
48
  SVG_EDGE,
46
49
  ShaderCompileError,
47
50
  TextureCache,
@@ -50,6 +53,7 @@ import {
50
53
  applyLiftGammaGain,
51
54
  applyTextureSettings,
52
55
  applyVibrance,
56
+ clicksUniform,
53
57
  compileShader,
54
58
  convertColorSpace,
55
59
  createContext,
@@ -78,7 +82,7 @@ import {
78
82
  srgbToLinearRgb,
79
83
  srgbToOklab,
80
84
  wrapSource
81
- } from "./chunk-EZRRKQFV.js";
85
+ } from "./chunk-YLJWC4N2.js";
82
86
  import {
83
87
  ALL_TRANSITION_TYPES,
84
88
  blendTransitionPixel,
@@ -1138,11 +1142,14 @@ export {
1138
1142
  EFFECT_FADE_MS,
1139
1143
  EFFECT_TYPES,
1140
1144
  FLAIR_AGENT_TOOLS,
1145
+ HOVER_SECONDS,
1141
1146
  ImageLoadError,
1147
+ MAX_CLICKS,
1142
1148
  MAX_TILT,
1143
1149
  ManualClock,
1144
1150
  MemorySceneBoard,
1145
1151
  NO_CHECK,
1152
+ PointerTracker,
1146
1153
  SCRAMBLE_MS,
1147
1154
  SMALL_TEXT_PX,
1148
1155
  STEP_MS,
@@ -1183,6 +1190,7 @@ export {
1183
1190
  centreOf,
1184
1191
  checkControlValue,
1185
1192
  checkShot,
1193
+ clicksUniform,
1186
1194
  coerceControlValue,
1187
1195
  compileShader,
1188
1196
  componentCount,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/time/retiming.ts","../src/time/keyframe.ts","../src/time/timecode.ts","../src/scene/rig.ts","../src/scene/replicator.ts","../src/scene/motionpath.ts","../src/agent/tools.ts","../src/agent/batch.ts"],"sourcesContent":["/**\n * Retiming math engine inspired by Apple Motion's RetimingMath framework.\n * Provides deterministic time transformation functors for looping, bouncing (ping-pong),\n * freezing (hold), posterizing/stepping (strobe), and non-linear speed ramps.\n */\n\nexport type EasingCurve = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';\n\n/**\n * Loops time within [start, start + duration).\n * Handles negative time values smoothly.\n */\nexport function loopTime(t: number, duration: number, start = 0): number {\n if (duration <= 0) return start;\n const rel = t - start;\n const mod = ((rel % duration) + duration) % duration;\n return start + mod;\n}\n\n/**\n * Reflects time back and forth (triangle wave) between start and start + duration.\n */\nexport function pingPongTime(t: number, duration: number, start = 0): number {\n if (duration <= 0) return start;\n const period = 2 * duration;\n const rel = t - start;\n const mod = ((rel % period) + period) % period;\n const offset = mod <= duration ? mod : period - mod;\n return start + offset;\n}\n\n/**\n * Freezes time at a specified timestamp.\n */\nexport function holdTime(_t: number, holdAt: number): number {\n return holdAt;\n}\n\n/**\n * Quantizes continuous time into discrete intervals matching a target frame rate (posterize time).\n * @param t Current timestamp.\n * @param fps Target stepped frame rate (e.g. 12 for stop-motion).\n * @param unit 'ms' (default) if t is in milliseconds, or 'sec' if t is in seconds.\n */\nexport function strobeTime(t: number, fps: number, unit: 'ms' | 'sec' = 'ms'): number {\n if (fps <= 0) return t;\n const interval = (unit === 'ms' ? 1000 : 1) / fps;\n return Math.floor(t / interval) * interval;\n}\n\n/**\n * Applies a non-linear speed ramp curve to time progression within an interval [start, start + duration].\n */\nexport function speedRampTime(\n t: number,\n start: number,\n duration: number,\n ease: EasingCurve = 'easeInOut',\n): number {\n if (duration <= 0 || t <= start) return t;\n if (t >= start + duration) return t;\n\n const p = (t - start) / duration;\n let eased: number;\n switch (ease) {\n case 'linear':\n eased = p;\n break;\n case 'easeIn':\n eased = p * p;\n break;\n case 'easeOut':\n eased = p * (2 - p);\n break;\n case 'easeInOut':\n default:\n eased = p < 0.5 ? 2 * p * p : -1 + (4 - 2 * p) * p;\n break;\n }\n\n return start + eased * duration;\n}\n","/**\n * Keyframe velocity and cubic Bezier easing engine matching Adobe After Effects interpolation semantics.\n *\n * Temporal interpolation between two keyframes is characterized by:\n * - Speed (units / second)\n * - Influence (fraction 0..1, corresponding to 0.1%..100% in the Keyframe Velocity dialog)\n *\n * For normalized values going from 0 to 1 over a segment, easeProgress(outSpeedNorm, outInf, inSpeedNorm, inInf, x)\n * solves the monotone cubic Bezier root x(u) = x and computes value y(u).\n */\n\nexport interface KeyframeEase {\n /** Speed in value units per second (or normalized speed if evaluating normalized segment). */\n speed: number;\n /** Influence as a fraction between 0.0 and 1.0 (e.g. 0.3333 for 33.33%). */\n influence: number;\n}\n\n/** Easy Ease preset: 0 speed, 33.333% influence. */\nexport const EASY_EASE: KeyframeEase = {\n speed: 0,\n influence: 1 / 3,\n};\n\n/** Evaluates a 1D cubic Bezier polynomial at parameter u in [0, 1]. */\nexport function bez1d(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const v = 1.0 - u;\n return v * v * v * p0 + 3.0 * v * v * u * p1 + 3.0 * v * u * u * p2 + u * u * u * p3;\n}\n\n/** Evaluates the first derivative of a 1D cubic Bezier polynomial at parameter u. */\nexport function bez1dDerivative(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const v = 1.0 - u;\n return 3.0 * v * v * (p1 - p0) + 6.0 * v * u * (p2 - p1) + 3.0 * u * u * (p3 - p2);\n}\n\n/**\n * Solves bez1d(x0, x1, x2, x3, u) = x for u in [0, 1] assuming x(u) is monotone.\n * Uses closed-form inverse for 100% influence midpoint, Newton-Raphson iteration,\n * and high-precision bisection fallback.\n */\nexport function solveBezierU(x0: number, x1: number, x2: number, x3: number, x: number): number {\n if (x <= x0) return 0.0;\n if (x >= x3) return 1.0;\n\n // Closed-form solution for 100% influence on both sides (x1 === x3 && x2 === x0).\n // x(u) = x0 + (x3 - x0) * (0.5 + 4 * (u - 0.5)^3)\n if (Math.abs(x1 - x3) < 1e-12 && Math.abs(x2 - x0) < 1e-12) {\n const progress = (x - x0) / (x3 - x0);\n return 0.5 + Math.cbrt((progress - 0.5) * 0.25);\n }\n\n // Initial estimate\n let u = (x - x0) / (x3 - x0);\n\n // Up to 8 Newton-Raphson iterations\n for (let iter = 0; iter < 8; iter++) {\n const f = bez1d(x0, x1, x2, x3, u) - x;\n const d = bez1dDerivative(x0, x1, x2, x3, u);\n if (Math.abs(d) < 1e-12) break;\n if (Math.abs(f / d) < 1e-12) return u;\n const nextU = u - f / d;\n if (nextU < 0.0 || nextU > 1.0) break;\n u = nextU;\n }\n\n // Bisection fallback for robustness\n let lo = 0.0;\n let hi = 1.0;\n for (let iter = 0; iter < 60; iter++) {\n const mid = (lo + hi) * 0.5;\n if (bez1d(x0, x1, x2, x3, mid) < x) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n\n return (lo + hi) * 0.5;\n}\n\n/**\n * Fraction of progress 0..1 through a 1D Bezier temporal segment whose value goes from 0 to 1,\n * with normalized out/in speeds (speed * duration / deltaValue) and influences.\n *\n * @param outSpeedNorm Normalized outgoing speed (speed * duration / deltaValue).\n * @param outInfluence Outgoing influence fraction [0, 1].\n * @param inSpeedNorm Normalized incoming speed (speed * duration / deltaValue).\n * @param inInfluence Incoming influence fraction [0, 1].\n * @param x Normalized time progress in segment [0, 1].\n */\nexport function easeProgress(\n outSpeedNorm: number,\n outInfluence: number,\n inSpeedNorm: number,\n inInfluence: number,\n x: number,\n): number {\n const i0 = Math.min(1.0, Math.max(0.0, outInfluence));\n const i1 = Math.min(1.0, Math.max(0.0, inInfluence));\n const u = solveBezierU(0.0, i0, 1.0 - i1, 1.0, x);\n return bez1d(0.0, outSpeedNorm * i0, 1.0 - inSpeedNorm * i1, 1.0, u);\n}\n\n/**\n * Evaluates an interpolated keyframe segment between two values over duration.\n *\n * @param from Starting value at t = 0.\n * @param to Ending value at t = duration.\n * @param duration Duration of the keyframe segment in seconds.\n * @param t Current elapsed time in seconds (0 <= t <= duration).\n * @param outEase Outgoing ease specification at start keyframe.\n * @param inEase Incoming ease specification at end keyframe.\n */\nexport function evaluateKeyframeSegment(\n from: number,\n to: number,\n duration: number,\n t: number,\n outEase: KeyframeEase = EASY_EASE,\n inEase: KeyframeEase = EASY_EASE,\n): number {\n if (duration <= 0 || t <= 0) return from;\n if (t >= duration) return to;\n\n const delta = to - from;\n const x = t / duration;\n\n // Zero delta: maintain from\n if (Math.abs(delta) < 1e-12) {\n return from;\n }\n\n const outSpeedNorm = (outEase.speed * duration) / delta;\n const inSpeedNorm = (inEase.speed * duration) / delta;\n\n const progress = easeProgress(outSpeedNorm, outEase.influence, inSpeedNorm, inEase.influence, x);\n return from + progress * delta;\n}\n","/**\n * SMPTE 12M Timecode engine and broadcast frame-rate converter.\n *\n * Supports non-drop-frame (NDF) and drop-frame (DF) timecode for broadcast standards\n * (23.976, 24, 25, 29.97, 30, 48, 50, 59.94, 60, 120 fps).\n *\n * Drop-frame timecode drops frames 00 and 01 at the start of each minute,\n * except every 10th minute (e.g. 00:01:00;02 instead of 00:01:00;00).\n */\n\nexport interface RationalFrameRate {\n readonly num: number;\n readonly den: number;\n}\n\nexport const COMMON_FRAME_RATES = {\n FPS_23_976: { num: 24000, den: 1001 },\n FPS_24: { num: 24, den: 1 },\n FPS_25: { num: 25, den: 1 },\n FPS_29_97: { num: 30000, den: 1001 },\n FPS_30: { num: 30, den: 1 },\n FPS_48: { num: 48, den: 1 },\n FPS_50: { num: 50, den: 1 },\n FPS_59_94: { num: 60000, den: 1001 },\n FPS_60: { num: 60, den: 1 },\n FPS_120: { num: 120, den: 1 },\n} as const;\n\nexport type StandardFrameRateKey = keyof typeof COMMON_FRAME_RATES;\n\n/** Greatest common divisor helper. */\nfunction gcd(a: number, b: number): number {\n let x = Math.abs(Math.round(a));\n let y = Math.abs(Math.round(b));\n while (y !== 0) {\n const t = y;\n y = x % y;\n x = t;\n }\n return x || 1;\n}\n\n/** Creates a reduced rational frame rate. */\nexport function createFrameRate(num: number, den = 1): RationalFrameRate {\n if (den <= 0 || num <= 0) {\n return { num: 30, den: 1 };\n }\n const g = gcd(num, den);\n return { num: Math.round(num / g), den: Math.round(den / g) };\n}\n\n/** Returns the timecode base (frames counted per second in timecode display). */\nexport function getTimecodeBase(rate: RationalFrameRate): number {\n return Math.ceil(rate.num / rate.den);\n}\n\n/** Whether a given frame rate supports drop-frame counting (29.97, 59.94, etc.). */\nexport function supportsDropFrame(rate: RationalFrameRate): boolean {\n return rate.den === 1001 && getTimecodeBase(rate) % 30 === 0;\n}\n\n/** Number of dropped frames per minute (e.g. 2 for 29.97, 4 for 59.94). */\nexport function getDropFrameCount(rate: RationalFrameRate): number {\n const base = getTimecodeBase(rate);\n return Math.floor(base / 15);\n}\n\nexport interface SMPTEFields {\n negative: boolean;\n hours: number;\n minutes: number;\n seconds: number;\n frames: number;\n}\n\n/**\n * Converts a continuous frame count to SMPTE fields (hours, minutes, seconds, frames).\n */\nexport function framesToSMPTE(\n frame: number,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): SMPTEFields {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const neg = frame < 0;\n let n = Math.abs(Math.round(frame));\n const base = getTimecodeBase(rate);\n const drop = getDropFrameCount(rate);\n\n if (isDrop) {\n const perMinute = base * 60 - drop;\n const per10Minutes = perMinute * 10 + drop;\n const d = Math.floor(n / per10Minutes);\n const m = n % per10Minutes;\n\n n += drop * 9 * d;\n if (m > drop) {\n n += drop * Math.floor((m - drop) / perMinute);\n }\n }\n\n const frames = n % base;\n const seconds = Math.floor(n / base) % 60;\n const minutes = Math.floor(n / (base * 60)) % 60;\n const hours = Math.floor(n / (base * 3600));\n\n return { negative: neg, hours, minutes, seconds, frames };\n}\n\n/**\n * Converts SMPTE fields back to a continuous frame number.\n */\nexport function smpteToFrames(\n fields: { hours: number; minutes: number; seconds: number; frames: number },\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): number {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const base = getTimecodeBase(rate);\n const drop = getDropFrameCount(rate);\n\n const totalSecs = fields.hours * 3600 + fields.minutes * 60 + fields.seconds;\n let n = totalSecs * base + fields.frames;\n\n if (isDrop) {\n const totalMinutes = fields.hours * 60 + fields.minutes;\n n -= drop * (totalMinutes - Math.floor(totalMinutes / 10));\n }\n\n return n;\n}\n\n/**\n * Formats a frame number as standard SMPTE timecode (HH:MM:SS:FF or HH;MM;SS;FF).\n */\nexport function formatTimecode(\n frame: number,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): string {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const { negative, hours, minutes, seconds, frames } = framesToSMPTE(frame, rate, isDrop);\n const sep = isDrop ? ';' : ':';\n const base = getTimecodeBase(rate);\n const frameWidth = base >= 100 ? 3 : 2;\n\n const hStr = String(hours).padStart(2, '0');\n const mStr = String(minutes).padStart(2, '0');\n const sStr = String(seconds).padStart(2, '0');\n const fStr = String(frames).padStart(frameWidth, '0');\n\n return `${negative ? '-' : ''}${hStr}${sep}${mStr}${sep}${sStr}${sep}${fStr}`;\n}\n\n/**\n * Parses user or NLE input into a frame number.\n * Supports:\n * - Standard timecodes: `01:00:00:00`, `01;00;00;00`, `00.01.20.15`\n * - Right-aligned numbers: `1000` -> `00:00:10:00`\n * - Relative offsets: `+15` (+15 frames), `-1.00` (-1 second)\n *\n * @param input The timecode string to parse.\n * @param rate Rational frame rate (default: 30 fps).\n * @param dropFrame Whether drop-frame arithmetic applies.\n * @param currentFrame Current playhead position for relative additions.\n */\nexport function parseTimecode(\n input: string,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n currentFrame = 0,\n): number {\n const s = input.trim();\n if (!s) {\n throw new Error('Empty timecode string');\n }\n\n let relativeSign: 1 | -1 | null = null;\n let body = s;\n if (s.startsWith('+')) {\n relativeSign = 1;\n body = s.slice(1);\n } else if (s.startsWith('-')) {\n relativeSign = -1;\n body = s.slice(1);\n }\n\n const parts = body.split(/[:;.,]/);\n let parsedFrame = 0;\n\n if (parts.length === 1) {\n const digits = parts[0]!;\n if (!/^\\d+$/.test(digits)) {\n throw new Error(`Invalid timecode: \"${input}\"`);\n }\n\n if (relativeSign !== null) {\n // Relative bare digits are treated as frames\n const count = parseInt(digits, 10);\n return currentFrame + relativeSign * count;\n }\n\n // Right-aligned pairs: e.g. \"1000\" -> HH=0, MM=0, SS=10, FF=0\n const nums: number[] = [];\n let end = digits.length;\n while (end > 0) {\n const start = Math.max(0, end - 2);\n nums.unshift(parseInt(digits.slice(start, end), 10));\n end = start;\n }\n\n const padded = [0, 0, 0, 0];\n const offset = 4 - nums.length;\n for (let i = 0; i < nums.length; i++) {\n padded[offset + i] = nums[i]!;\n }\n const [h, m, sec, fr] = padded;\n parsedFrame = smpteToFrames(\n { hours: h!, minutes: m!, seconds: sec!, frames: fr! },\n rate,\n dropFrame,\n );\n } else {\n if (parts.length > 4) {\n throw new Error(`Too many timecode fields in \"${input}\"`);\n }\n const nums = parts.map((p) => (p.length === 0 ? 0 : parseInt(p, 10)));\n if (nums.some((n) => isNaN(n))) {\n throw new Error(`Invalid number in timecode: \"${input}\"`);\n }\n\n const padded = [0, 0, 0, 0];\n const offset = 4 - nums.length;\n for (let i = 0; i < nums.length; i++) {\n padded[offset + i] = nums[i]!;\n }\n const [h, m, sec, fr] = padded;\n parsedFrame = smpteToFrames(\n { hours: h!, minutes: m!, seconds: sec!, frames: fr! },\n rate,\n dropFrame,\n );\n }\n\n if (relativeSign !== null) {\n return currentFrame + relativeSign * parsedFrame;\n }\n\n return parsedFrame;\n}\n","import type { Scene } from './types.js';\n\nexport interface SliderSnapshot {\n at: number;\n values: Record<string, number | string>;\n}\n\nexport interface SliderWidget {\n type: 'slider';\n name: string;\n value: number;\n snapshots: SliderSnapshot[];\n}\n\nexport interface PopupWidget {\n type: 'popup';\n name: string;\n selected: string;\n options: Record<string, Record<string, number | string>>;\n}\n\nexport interface ToggleWidget {\n type: 'toggle';\n name: string;\n enabled: boolean;\n on: Record<string, number | string>;\n off: Record<string, number | string>;\n}\n\nexport type RigWidget = SliderWidget | PopupWidget | ToggleWidget;\n\nexport interface SceneRig {\n widgets: Record<string, RigWidget>;\n}\n\n/**\n * Updates a widget within a SceneRig and returns the updated SceneRig.\n */\nexport function setRigWidget(\n rig: SceneRig,\n widgetName: string,\n value: number | string | boolean,\n): SceneRig {\n const widget = rig.widgets[widgetName];\n if (!widget) {\n throw new Error(`Rig widget \"${widgetName}\" not found.`);\n }\n\n const updatedWidgets = { ...rig.widgets };\n\n if (widget.type === 'slider') {\n if (typeof value !== 'number') {\n throw new Error(`Slider widget \"${widgetName}\" expects numeric value.`);\n }\n updatedWidgets[widgetName] = { ...widget, value };\n } else if (widget.type === 'popup') {\n if (typeof value !== 'string') {\n throw new Error(`Popup widget \"${widgetName}\" expects string value.`);\n }\n updatedWidgets[widgetName] = { ...widget, selected: value };\n } else if (widget.type === 'toggle') {\n if (typeof value !== 'boolean') {\n throw new Error(`Toggle widget \"${widgetName}\" expects boolean value.`);\n }\n updatedWidgets[widgetName] = { ...widget, enabled: value };\n }\n\n return { widgets: updatedWidgets };\n}\n\n/**\n * Evaluates resolved values for a given widget.\n */\nfunction resolveWidgetValues(widget: RigWidget): Record<string, number | string> {\n if (widget.type === 'popup') {\n return widget.options[widget.selected] ?? {};\n }\n\n if (widget.type === 'toggle') {\n return widget.enabled ? widget.on : widget.off;\n }\n\n if (widget.type === 'slider') {\n const { snapshots, value } = widget;\n if (!snapshots || snapshots.length === 0) return {};\n\n const sorted = [...snapshots].sort((a, b) => a.at - b.at);\n if (value <= sorted[0]!.at) {\n return { ...sorted[0]!.values };\n }\n if (value >= sorted[sorted.length - 1]!.at) {\n return { ...sorted[sorted.length - 1]!.values };\n }\n\n // Find bounding snapshots\n let idx = 0;\n while (idx < sorted.length - 1 && sorted[idx + 1]!.at < value) {\n idx++;\n }\n\n const s0 = sorted[idx]!;\n const s1 = sorted[idx + 1]!;\n const span = s1.at - s0.at;\n const t = span > 0 ? (value - s0.at) / span : 0;\n\n const result: Record<string, number | string> = {};\n const allKeys = new Set([...Object.keys(s0.values), ...Object.keys(s1.values)]);\n\n for (const k of allKeys) {\n const v0 = s0.values[k];\n const v1 = s1.values[k];\n if (typeof v0 === 'number' && typeof v1 === 'number') {\n result[k] = v0 + (v1 - v0) * t;\n } else if (v0 !== undefined && v1 !== undefined) {\n result[k] = t < 0.5 ? v0 : v1;\n } else {\n result[k] = v1 !== undefined ? v1 : (v0 as number | string);\n }\n }\n\n return result;\n }\n\n return {};\n}\n\n/**\n * Propagates rig widget state into the scene's shader uniforms and elements.\n */\nexport function applyRig(rig: SceneRig, scene: Scene): Scene {\n // Deep clone media and shots to prevent mutation\n const nextMedia: Record<string, any> = {};\n if (scene.media) {\n for (const [id, m] of Object.entries(scene.media)) {\n nextMedia[id] = {\n ...m,\n values: { ...(m.values ?? {}) },\n };\n }\n }\n\n const nextShots = scene.shots.map((shot) => {\n if (!shot.run) return { ...shot };\n return {\n ...shot,\n run: shot.run.map((cmd) => {\n if (cmd.type === 'element' && 'element' in cmd && cmd.element) {\n return { ...cmd, element: { ...cmd.element } };\n }\n if (cmd.type === 'update' && 'props' in cmd && (cmd as any).props) {\n return { ...cmd, props: { ...(cmd as any).props } };\n }\n return { ...cmd };\n }),\n };\n });\n\n // Collect all resolved values across all widgets in the rig\n const resolvedAll: Record<string, number | string> = {};\n for (const widget of Object.values(rig.widgets)) {\n Object.assign(resolvedAll, resolveWidgetValues(widget));\n }\n\n // Apply resolved values\n for (const [targetKey, val] of Object.entries(resolvedAll)) {\n if (targetKey.startsWith('media.')) {\n const parts = targetKey.split('.');\n const mediaId = parts[1]!;\n const prop = parts.length > 3 && parts[2] === 'values' ? parts[3]! : parts[2]!;\n if (nextMedia[mediaId]) {\n nextMedia[mediaId].values[prop] = val;\n }\n } else if (targetKey.startsWith('element.')) {\n const parts = targetKey.split('.');\n const elId = parts[1]!;\n const prop = parts[2]!;\n for (const shot of nextShots) {\n if (shot.run) {\n for (const cmd of shot.run) {\n if (cmd.type === 'element' && 'element' in cmd && (cmd as any).element?.id === elId) {\n (cmd.element as any)[prop] = val;\n } else if (cmd.type === 'update' && 'id' in cmd && cmd.id === elId) {\n (cmd as any).props[prop] = val;\n }\n }\n }\n }\n } else {\n // General uniform shorthand: uniforms.<name> or simply <name>\n const uniformName = targetKey.replace(/^uniforms\\./, '');\n for (const m of Object.values(nextMedia)) {\n m.values[uniformName] = val;\n }\n }\n }\n\n return {\n ...scene,\n media: Object.keys(nextMedia).length > 0 ? nextMedia : scene.media,\n shots: nextShots,\n rig,\n };\n}\n","import type { SceneElement } from './geometry.js';\n\nexport type ReplicatorPattern = 'grid' | 'line' | 'circle' | 'spiral';\n\nexport interface ReplicatorSequence {\n /** Property to modulate per item. */\n property?: 'opacity' | 'rotation' | 'scale' | 'x' | 'y';\n /** Incremental offset or delta added per instance. */\n offset?: number;\n /** Milliseconds delay per instance for staggered triggers. */\n delayPerItem?: number;\n}\n\nexport interface ReplicatorConfig {\n pattern: ReplicatorPattern;\n count: number;\n /** Origin point [x, y] to anchor the layout (defaults to prototype.x, prototype.y). */\n origin?: [number, number];\n\n // Grid options\n columns?: number;\n rows?: number;\n columnSpacing?: number;\n rowSpacing?: number;\n\n // Line options\n startPoint?: [number, number];\n endPoint?: [number, number];\n spacing?: number;\n\n // Circle / Spiral options\n radius?: number;\n startAngle?: number; // radians\n spiralTightness?: number; // radius expansion per instance\n\n // Sequence modulation\n sequence?: ReplicatorSequence;\n}\n\n/**\n * Procedurally replicates a prototype SceneElement into an array of positioned\n * and sequenced instances (grid, circular array, line, or spiral).\n */\nexport function expandReplicator(\n prototype: SceneElement,\n config: ReplicatorConfig,\n): SceneElement[] {\n const count = Math.max(0, Math.floor(config.count));\n if (count === 0) return [];\n\n const originX = config.origin ? config.origin[0] : prototype.x;\n const originY = config.origin ? config.origin[1] : prototype.y;\n const elements: SceneElement[] = [];\n\n for (let i = 0; i < count; i++) {\n const el: SceneElement = {\n ...prototype,\n id: `${prototype.id}_${i}`,\n };\n\n let px = originX;\n let py = originY;\n\n switch (config.pattern) {\n case 'grid': {\n const cols = config.columns ?? Math.ceil(Math.sqrt(count));\n const colSpacing = config.columnSpacing ?? (prototype.width + 20);\n const rowSpacing = config.rowSpacing ?? (prototype.height + 20);\n const col = i % cols;\n const row = Math.floor(i / cols);\n px = originX + col * colSpacing;\n py = originY + row * rowSpacing;\n break;\n }\n\n case 'line': {\n if (config.startPoint && config.endPoint) {\n const t = count > 1 ? i / (count - 1) : 0;\n px = config.startPoint[0] + (config.endPoint[0] - config.startPoint[0]) * t;\n py = config.startPoint[1] + (config.endPoint[1] - config.startPoint[1]) * t;\n } else {\n const spacing = config.spacing ?? (prototype.width + 20);\n px = originX + i * spacing;\n py = originY;\n }\n break;\n }\n\n case 'circle': {\n const radius = config.radius ?? 150;\n const angleStep = (2 * Math.PI) / count;\n const angle = (config.startAngle ?? 0) + i * angleStep;\n px = originX + radius * Math.cos(angle);\n py = originY + radius * Math.sin(angle);\n break;\n }\n\n case 'spiral': {\n const baseRadius = config.radius ?? 40;\n const tightness = config.spiralTightness ?? 12;\n const angleStep = Math.PI / 4; // 45 degrees per step\n const angle = (config.startAngle ?? 0) + i * angleStep;\n const r = baseRadius + tightness * i;\n px = originX + r * Math.cos(angle);\n py = originY + r * Math.sin(angle);\n break;\n }\n }\n\n el.x = px;\n el.y = py;\n\n // Apply sequence property modulation\n if (config.sequence && config.sequence.offset !== undefined) {\n const { property, offset } = config.sequence;\n if (property === 'opacity') {\n const base = prototype.opacity ?? 1.0;\n el.opacity = Math.max(0, Math.min(1, base + i * offset));\n } else if (property === 'rotation') {\n const base = (prototype as any).rotation ?? 0;\n (el as any).rotation = base + i * offset;\n } else if (property === 'scale') {\n const factor = 1 + i * offset;\n el.width = Math.max(1, prototype.width * factor);\n el.height = Math.max(1, prototype.height * factor);\n } else if (property === 'x') {\n el.x += i * offset;\n } else if (property === 'y') {\n el.y += i * offset;\n }\n }\n\n elements.push(el);\n }\n\n return elements;\n}\n","/**\n * Constant-Velocity Spatial Motion Paths & Arc-Length Parameterization.\n *\n * Implements multi-segment cubic Bezier spatial trajectories with numerical\n * arc-length integration, ensuring constant pixel-speed traversal, tangent heading,\n * normal vectors, curvature, and seamless combination with temporal AE keyframe easing.\n */\n\nimport { evaluateKeyframeSegment, type KeyframeEase } from '../time/keyframe.js';\n\nexport type Vec2 = [number, number];\nexport type Vec3 = [number, number, number];\n\nexport interface PathWaypoint {\n /** Anchor position in 2D or 3D scene coordinates [x, y] or [x, y, z]. */\n point: Vec2 | Vec3;\n /** In-tangent handle relative to anchor point (vector pointing from handle to anchor or vice-versa). Default: [0, 0, 0] */\n inTangent?: Vec2 | Vec3;\n /** Out-tangent handle relative to anchor point (vector pointing from anchor toward next handle). Default: [0, 0, 0] */\n outTangent?: Vec2 | Vec3;\n}\n\nexport interface SpatialPathSample {\n /** Position on curve [x, y, z]. */\n position: Vec3;\n /** Normalized unit tangent vector [dx, dy, dz]. */\n tangent: Vec3;\n /** 2D heading angle in radians (atan2(dy, dx)). */\n heading: number;\n /** 2D unit normal vector [-dy, dx, 0]. */\n normal: Vec3;\n /** Instantaneous curvature kappa (1 / radius of curvature). */\n curvature: number;\n /** Distance traversed along the path in absolute units. */\n distance: number;\n}\n\ninterface SegmentSample {\n t: number;\n s: number;\n pos: Vec3;\n}\n\ninterface PathSegment {\n p0: Vec3;\n p1: Vec3;\n p2: Vec3;\n p3: Vec3;\n length: number;\n samples: SegmentSample[];\n}\n\nexport interface SpatialMotionPath {\n waypoints: PathWaypoint[];\n closed: boolean;\n totalLength: number;\n segments: PathSegment[];\n}\n\nfunction toVec3(p: Vec2 | Vec3 | undefined): Vec3 {\n if (!p) return [0, 0, 0];\n return [p[0], p[1], p[2] ?? 0];\n}\n\nfunction cubicPos(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = u * u * u;\n const b = 3 * u * u * t;\n const c = 3 * u * t * t;\n const d = t * t * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction cubicVel(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = -3 * u * u;\n const b = 3 * u * u - 6 * u * t;\n const c = 6 * u * t - 3 * t * t;\n const d = 3 * t * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction cubicAcc(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = 6 * u;\n const b = -12 * u + 6 * t;\n const c = 6 * u - 12 * t;\n const d = 6 * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction dist3(a: Vec3, b: Vec3): number {\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const dz = b[2] - a[2];\n return Math.sqrt(dx * dx + dy * dy + dz * dz);\n}\n\n/**\n * Creates and compiles a constant-velocity SpatialMotionPath from a sequence of waypoints.\n * Computes fine-grained arc-length tables along all Bezier segments.\n */\nexport function createMotionPath(\n waypoints: PathWaypoint[],\n options?: { closed?: boolean; resolution?: number }\n): SpatialMotionPath {\n if (waypoints.length < 2) {\n throw new Error('SpatialMotionPath requires at least 2 waypoints.');\n }\n\n const closed = options?.closed ?? false;\n const segmentCount = closed ? waypoints.length : waypoints.length - 1;\n const segments: PathSegment[] = [];\n let totalLength = 0;\n\n for (let i = 0; i < segmentCount; i++) {\n const nextIdx = (i + 1) % waypoints.length;\n const w0 = waypoints[i];\n const w1 = waypoints[nextIdx];\n\n const p0 = toVec3(w0.point);\n const outT = toVec3(w0.outTangent);\n const p1: Vec3 = [p0[0] + outT[0], p0[1] + outT[1], p0[2] + outT[2]];\n\n const p3 = toVec3(w1.point);\n const inT = toVec3(w1.inTangent);\n const p2: Vec3 = [p3[0] + inT[0], p3[1] + inT[1], p3[2] + inT[2]];\n\n // Chord length estimate\n const chord = dist3(p0, p1) + dist3(p1, p2) + dist3(p2, p3);\n const stepCount = Math.max(16, Math.min(256, Math.ceil(chord / (options?.resolution ?? 2))));\n\n const samples: SegmentSample[] = [];\n let segLen = 0;\n let prev = p0;\n samples.push({ t: 0, s: 0, pos: p0 });\n\n for (let k = 1; k <= stepCount; k++) {\n const t = k / stepCount;\n const pos = cubicPos(p0, p1, p2, p3, t);\n segLen += dist3(prev, pos);\n samples.push({ t, s: segLen, pos });\n prev = pos;\n }\n\n segments.push({\n p0,\n p1,\n p2,\n p3,\n length: segLen,\n samples,\n });\n totalLength += segLen;\n }\n\n return {\n waypoints,\n closed,\n totalLength,\n segments,\n };\n}\n\n/**\n * Samples the spatial motion path at a normalized distance fraction [0..1].\n * Guarantees strictly constant pixel speed regardless of control handle asymmetry.\n */\nexport function sampleMotionPath(path: SpatialMotionPath, distanceFraction: number): SpatialPathSample {\n const clampedFraction = Math.max(0, Math.min(1, distanceFraction));\n const targetDistance = clampedFraction * path.totalLength;\n\n if (path.totalLength === 0) {\n const p = toVec3(path.waypoints[0].point);\n return {\n position: p,\n tangent: [1, 0, 0],\n heading: 0,\n normal: [0, 1, 0],\n curvature: 0,\n distance: 0,\n };\n }\n\n // Find target segment\n let accumulated = 0;\n let targetSeg = path.segments[0];\n let segDistance = targetDistance;\n\n for (const seg of path.segments) {\n if (accumulated + seg.length >= targetDistance || seg === path.segments[path.segments.length - 1]) {\n targetSeg = seg;\n segDistance = Math.max(0, Math.min(seg.length, targetDistance - accumulated));\n break;\n }\n accumulated += seg.length;\n }\n\n // Binary search for exact sample in target segment's arc length table\n const samples = targetSeg.samples;\n let low = 0;\n let high = samples.length - 1;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n if (samples[mid].s < segDistance) {\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n const idx = Math.max(0, Math.min(samples.length - 2, high));\n const s0 = samples[idx];\n const s1 = samples[idx + 1];\n\n const segRange = s1.s - s0.s;\n const factor = segRange > 1e-7 ? (segDistance - s0.s) / segRange : 0;\n const t = s0.t + factor * (s1.t - s0.t);\n\n // Evaluate exact position, velocity, acceleration at t\n const pos = cubicPos(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n const vel = cubicVel(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n const acc = cubicAcc(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n\n const speed = Math.sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]);\n const safeSpeed = speed > 1e-6 ? speed : 1;\n const tangent: Vec3 = [vel[0] / safeSpeed, vel[1] / safeSpeed, vel[2] / safeSpeed];\n\n const heading = Math.atan2(tangent[1], tangent[0]);\n const normal: Vec3 = [-tangent[1], tangent[0], 0];\n\n // Curvature: kappa = |v x a| / |v|^3\n const cx = vel[1] * acc[2] - vel[2] * acc[1];\n const cy = vel[2] * acc[0] - vel[0] * acc[2];\n const cz = vel[0] * acc[1] - vel[1] * acc[0];\n const crossMag = Math.sqrt(cx * cx + cy * cy + cz * cz);\n const curvature = crossMag / (safeSpeed * safeSpeed * safeSpeed);\n\n return {\n position: pos,\n tangent,\n heading,\n normal,\n curvature,\n distance: targetDistance,\n };\n}\n\n/**\n * Samples a spatial motion path driven by elapsed time and AE keyframe velocity easing.\n * Combines spatial arc-length constancy with temporal speed curves.\n */\nexport function sampleMotionPathAtTime(\n path: SpatialMotionPath,\n time: number,\n duration: number,\n ease?: {\n easeIn?: KeyframeEase;\n easeOut?: KeyframeEase;\n }\n): SpatialPathSample {\n const distanceFraction = evaluateKeyframeSegment(\n 0,\n 1,\n duration,\n time,\n ease?.easeOut,\n ease?.easeIn\n );\n return sampleMotionPath(path, distanceFraction);\n}\n\n","import type { Scene, SceneMedia, Shot } from '../scene/types.js';\nimport { validateScene, type SceneIssue } from '../scene/validate.js';\nimport { simulateScene } from '../scene/player.js';\nimport type { Review } from '../scene/report.js';\nimport { applyRig, setRigWidget } from '../scene/rig.js';\n\nexport interface AgentToolDefinition {\n name: string;\n description: string;\n input_schema: Record<string, unknown>;\n}\n\nexport const FLAIR_AGENT_TOOLS: AgentToolDefinition[] = [\n {\n name: 'get_scene',\n description: 'Returns the current scene JSON and any static validation issues.',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n },\n {\n name: 'write_scene',\n description: 'Overwrites the entire scene with a new specification and validates it.',\n input_schema: {\n type: 'object',\n properties: {\n scene: {\n type: 'object',\n description:\n 'Full Scene object with name, stage, media, and shots. A shot camera frames a box {x, y, width, height} or elements {frame: [ids]}, and may add tilt, turn, roll (degrees, tilt/turn up to 75), perspective (default 1.2) and motionBlur (0-3, 1 natural); angles persist until changed.',\n },\n },\n required: ['scene'],\n additionalProperties: false,\n },\n },\n {\n name: 'update_shot',\n description: 'Updates fields of a specific shot (1-based index) without rewriting the whole scene.',\n input_schema: {\n type: 'object',\n properties: {\n shot: { type: 'integer', minimum: 1, description: '1-based index of the shot to update.' },\n set: { type: 'object', description: 'Fields to set or replace on this shot.' },\n remove: {\n type: 'array',\n items: { type: 'string' },\n description: 'Field names to delete from this shot.',\n },\n },\n required: ['shot'],\n additionalProperties: false,\n },\n },\n {\n name: 'insert_shots',\n description: 'Inserts one or more shots at a given position.',\n input_schema: {\n type: 'object',\n properties: {\n after: {\n type: 'integer',\n minimum: 0,\n description: '0 to insert at the beginning, or 1-based index of shot to insert after.',\n },\n shots: {\n type: 'array',\n items: { type: 'object' },\n description: 'Array of Shot objects to insert.',\n },\n },\n required: ['after', 'shots'],\n additionalProperties: false,\n },\n },\n {\n name: 'delete_shots',\n description: 'Deletes one or more shots by 1-based index.',\n input_schema: {\n type: 'object',\n properties: {\n shots: {\n type: 'array',\n items: { type: 'integer', minimum: 1 },\n description: '1-based shot numbers to delete.',\n },\n },\n required: ['shots'],\n additionalProperties: false,\n },\n },\n {\n name: 'set_media',\n description: 'Adds, updates, or removes embedded media (e.g. bespoke WebGL shaders) by ID.',\n input_schema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Media identifier.' },\n media: {\n type: ['object', 'null'],\n description: 'SceneMedia object (e.g. { type: \"shader\", source: \"...\" }), or null to remove.',\n },\n },\n required: ['id', 'media'],\n additionalProperties: false,\n },\n },\n {\n name: 'preview_scene',\n description: 'Simulates the scene fast and off-screen, returning timing, layout checks, and review report.',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n },\n {\n name: 'set_rig_widget',\n description: 'Adjusts a high-level creative rig widget (slider, popup, or toggle) and propagates parameters to shaders and elements.',\n input_schema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Rig widget identifier/name.' },\n value: {\n type: ['number', 'string', 'boolean'],\n description: 'New value (number for slider, string for popup, boolean for toggle).',\n },\n },\n required: ['name', 'value'],\n additionalProperties: false,\n },\n },\n];\n\nexport type SceneToolResult =\n | { ok: true; scene: Scene; issues: SceneIssue[]; review?: Review }\n | { ok: false; error: string };\n\n/**\n * Pure state machine that applies tool operations to a Scene.\n */\nexport async function applySceneTool(\n scene: Scene,\n toolName: string,\n input: Record<string, any> = {},\n): Promise<SceneToolResult> {\n switch (toolName) {\n case 'get_scene': {\n return { ok: true, scene, issues: validateScene(scene) };\n }\n\n case 'write_scene': {\n if (!input.scene || typeof input.scene !== 'object') {\n return { ok: false, error: 'Expected scene object in arguments.' };\n }\n const newScene = input.scene as Scene;\n const issues = validateScene(newScene);\n return { ok: true, scene: newScene, issues };\n }\n\n case 'update_shot': {\n const idx = input.shot - 1;\n if (idx < 0 || idx >= scene.shots.length) {\n return { ok: false, error: `Invalid shot number ${input.shot}; scene has ${scene.shots.length} shots.` };\n }\n const existing = scene.shots[idx]!;\n const updated: Record<string, any> = { ...existing, ...(input.set || {}) };\n if (Array.isArray(input.remove)) {\n for (const k of input.remove) {\n delete updated[k];\n }\n }\n const shots = [...scene.shots];\n shots[idx] = updated as Shot;\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'insert_shots': {\n const after = input.after ?? scene.shots.length;\n if (after < 0 || after > scene.shots.length) {\n return { ok: false, error: `Invalid after index ${after}.` };\n }\n if (!Array.isArray(input.shots) || input.shots.length === 0) {\n return { ok: false, error: 'Expected non-empty shots array to insert.' };\n }\n const shots = [...scene.shots.slice(0, after), ...input.shots, ...scene.shots.slice(after)];\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'delete_shots': {\n if (!Array.isArray(input.shots) || input.shots.length === 0) {\n return { ok: false, error: 'Expected non-empty shots array to delete.' };\n }\n const toDelete = new Set(input.shots.map((n: number) => n - 1));\n const shots = scene.shots.filter((_, i) => !toDelete.has(i));\n if (shots.length === 0) {\n return { ok: false, error: 'Cannot delete all shots in scene.' };\n }\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'set_media': {\n if (!input.id || typeof input.id !== 'string') {\n return { ok: false, error: 'Expected string media id.' };\n }\n const media = { ...(scene.media || {}) };\n if (input.media === null) {\n delete media[input.id];\n } else {\n media[input.id] = input.media as SceneMedia;\n }\n const newScene = { ...scene, media };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'preview_scene': {\n const { review } = await simulateScene(scene);\n return { ok: true, scene, issues: validateScene(scene), review };\n }\n\n case 'set_rig_widget': {\n if (!scene.rig || !scene.rig.widgets || !scene.rig.widgets[input.name]) {\n return { ok: false, error: `Scene does not have a rig widget named \"${input.name}\".` };\n }\n try {\n const updatedRig = setRigWidget(scene.rig, input.name, input.value);\n const newScene = applyRig(updatedRig, scene);\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n } catch (err: any) {\n return { ok: false, error: err.message || String(err) };\n }\n }\n\n default:\n return { ok: false, error: `Unknown tool name: ${toolName}` };\n }\n}\n","/**\n * Atomic Agent Multi-Tool Batching with Result Variable Substitution.\n * Inspired by EffectCraft's atomic batch execution protocol.\n *\n * Allows AI agents to execute multi-step modifications to a Scene in a single turn,\n * with atomic rollback on failure and cross-step variable substitution ($1.prop, $2.prop).\n */\n\nimport type { Scene } from '../scene/types.js';\nimport { applySceneTool, type SceneToolResult } from './tools.js';\n\nexport interface BatchCommand {\n /** Name of the tool to execute (e.g. 'update_shot', 'insert_shots', 'set_rig_widget'). */\n tool: string;\n /** Parameters for the tool call. */\n params?: Record<string, any>;\n}\n\nexport interface BatchExecutionStepResult {\n step: number;\n tool: string;\n result: SceneToolResult;\n}\n\nexport interface BatchExecutionResult {\n ok: boolean;\n scene: Scene;\n steps: BatchExecutionStepResult[];\n error?: string;\n failedStep?: number;\n}\n\n/**\n * Resolves nested property path on an object (e.g. \"a.b[0].c\").\n */\nfunction getByPath(obj: any, path: string): any {\n if (!obj || typeof obj !== 'object') return undefined;\n const parts = path.replace(/\\[(\\w+)\\]/g, '.$1').split('.');\n let curr = obj;\n for (const part of parts) {\n if (curr === undefined || curr === null) return undefined;\n curr = curr[part];\n }\n return curr;\n}\n\n/**\n * Recursively substitutes `$stepIndex.path` references in parameters using previous step results.\n * E.g., \"$1.scene.shots[0].duration\" -> substituted with the duration value from step 1 result.\n */\nexport function substituteVariables(\n value: any,\n stepResults: Map<number, SceneToolResult>,\n): any {\n if (typeof value === 'string') {\n // Check if the entire string is a substitution reference: \"$1.path.to.prop\"\n const match = /^\\$(\\d+)\\.(.+)$/.exec(value);\n if (match) {\n const stepIdx = parseInt(match[1]!, 10);\n const path = match[2]!;\n const prevResult = stepResults.get(stepIdx);\n if (prevResult) {\n const resolved = getByPath(prevResult, path);\n if (resolved !== undefined) {\n return resolved;\n }\n }\n }\n // Partial template string substitution: \"Hello $1.scene.name\"\n return value.replace(/\\$(\\d+)\\.([a-zA-Z0-9_.[\\]]+)/g, (fullMatch, stepStr, path) => {\n const stepIdx = parseInt(stepStr, 10);\n const prevResult = stepResults.get(stepIdx);\n if (prevResult) {\n const resolved = getByPath(prevResult, path);\n if (resolved !== undefined) {\n return String(resolved);\n }\n }\n return fullMatch;\n });\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => substituteVariables(item, stepResults));\n }\n\n if (value !== null && typeof value === 'object') {\n const copy: Record<string, any> = {};\n for (const [k, v] of Object.entries(value)) {\n copy[k] = substituteVariables(v, stepResults);\n }\n return copy;\n }\n\n return value;\n}\n\n/**\n * Executes an atomic batch of scene tools with transactional rollback.\n * If any step fails, the scene rolls back to the initial state and returns the failure.\n *\n * @param scene Initial scene state before batch.\n * @param commands Ordered array of tool commands to execute.\n */\nexport async function applySceneBatch(\n scene: Scene,\n commands: BatchCommand[],\n): Promise<BatchExecutionResult> {\n let currentScene = scene;\n const stepResults = new Map<number, SceneToolResult>();\n const executedSteps: BatchExecutionStepResult[] = [];\n\n for (let i = 0; i < commands.length; i++) {\n const stepNumber = i + 1; // 1-based indexing for user/agent ergonomics\n const cmd = commands[i]!;\n\n // Perform variable substitution using results of earlier steps\n const resolvedParams = substituteVariables(cmd.params || {}, stepResults);\n\n // Prevent recursive batch execution to avoid cycles\n if (cmd.tool === 'batch_scene_tool') {\n return {\n ok: false,\n scene, // Rollback\n steps: executedSteps,\n error: `Nested batch_scene_tool is not allowed at step ${stepNumber}.`,\n failedStep: stepNumber,\n };\n }\n\n const stepResult = await applySceneTool(currentScene, cmd.tool, resolvedParams);\n stepResults.set(stepNumber, stepResult);\n executedSteps.push({\n step: stepNumber,\n tool: cmd.tool,\n result: stepResult,\n });\n\n if (!stepResult.ok) {\n // Transactional rollback: discard intermediate scenes and return original\n return {\n ok: false,\n scene, // Rollback to initial\n steps: executedSteps,\n error: `Step ${stepNumber} (${cmd.tool}) failed: ${stepResult.error}`,\n failedStep: stepNumber,\n };\n }\n\n currentScene = stepResult.scene;\n }\n\n return {\n ok: true,\n scene: currentScene,\n steps: executedSteps,\n };\n}\n"],"mappings":"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","names":["frame"]}
1
+ {"version":3,"sources":["../src/time/retiming.ts","../src/time/keyframe.ts","../src/time/timecode.ts","../src/scene/rig.ts","../src/scene/replicator.ts","../src/scene/motionpath.ts","../src/agent/tools.ts","../src/agent/batch.ts"],"sourcesContent":["/**\n * Retiming math engine inspired by Apple Motion's RetimingMath framework.\n * Provides deterministic time transformation functors for looping, bouncing (ping-pong),\n * freezing (hold), posterizing/stepping (strobe), and non-linear speed ramps.\n */\n\nexport type EasingCurve = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';\n\n/**\n * Loops time within [start, start + duration).\n * Handles negative time values smoothly.\n */\nexport function loopTime(t: number, duration: number, start = 0): number {\n if (duration <= 0) return start;\n const rel = t - start;\n const mod = ((rel % duration) + duration) % duration;\n return start + mod;\n}\n\n/**\n * Reflects time back and forth (triangle wave) between start and start + duration.\n */\nexport function pingPongTime(t: number, duration: number, start = 0): number {\n if (duration <= 0) return start;\n const period = 2 * duration;\n const rel = t - start;\n const mod = ((rel % period) + period) % period;\n const offset = mod <= duration ? mod : period - mod;\n return start + offset;\n}\n\n/**\n * Freezes time at a specified timestamp.\n */\nexport function holdTime(_t: number, holdAt: number): number {\n return holdAt;\n}\n\n/**\n * Quantizes continuous time into discrete intervals matching a target frame rate (posterize time).\n * @param t Current timestamp.\n * @param fps Target stepped frame rate (e.g. 12 for stop-motion).\n * @param unit 'ms' (default) if t is in milliseconds, or 'sec' if t is in seconds.\n */\nexport function strobeTime(t: number, fps: number, unit: 'ms' | 'sec' = 'ms'): number {\n if (fps <= 0) return t;\n const interval = (unit === 'ms' ? 1000 : 1) / fps;\n return Math.floor(t / interval) * interval;\n}\n\n/**\n * Applies a non-linear speed ramp curve to time progression within an interval [start, start + duration].\n */\nexport function speedRampTime(\n t: number,\n start: number,\n duration: number,\n ease: EasingCurve = 'easeInOut',\n): number {\n if (duration <= 0 || t <= start) return t;\n if (t >= start + duration) return t;\n\n const p = (t - start) / duration;\n let eased: number;\n switch (ease) {\n case 'linear':\n eased = p;\n break;\n case 'easeIn':\n eased = p * p;\n break;\n case 'easeOut':\n eased = p * (2 - p);\n break;\n case 'easeInOut':\n default:\n eased = p < 0.5 ? 2 * p * p : -1 + (4 - 2 * p) * p;\n break;\n }\n\n return start + eased * duration;\n}\n","/**\n * Keyframe velocity and cubic Bezier easing engine matching Adobe After Effects interpolation semantics.\n *\n * Temporal interpolation between two keyframes is characterized by:\n * - Speed (units / second)\n * - Influence (fraction 0..1, corresponding to 0.1%..100% in the Keyframe Velocity dialog)\n *\n * For normalized values going from 0 to 1 over a segment, easeProgress(outSpeedNorm, outInf, inSpeedNorm, inInf, x)\n * solves the monotone cubic Bezier root x(u) = x and computes value y(u).\n */\n\nexport interface KeyframeEase {\n /** Speed in value units per second (or normalized speed if evaluating normalized segment). */\n speed: number;\n /** Influence as a fraction between 0.0 and 1.0 (e.g. 0.3333 for 33.33%). */\n influence: number;\n}\n\n/** Easy Ease preset: 0 speed, 33.333% influence. */\nexport const EASY_EASE: KeyframeEase = {\n speed: 0,\n influence: 1 / 3,\n};\n\n/** Evaluates a 1D cubic Bezier polynomial at parameter u in [0, 1]. */\nexport function bez1d(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const v = 1.0 - u;\n return v * v * v * p0 + 3.0 * v * v * u * p1 + 3.0 * v * u * u * p2 + u * u * u * p3;\n}\n\n/** Evaluates the first derivative of a 1D cubic Bezier polynomial at parameter u. */\nexport function bez1dDerivative(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const v = 1.0 - u;\n return 3.0 * v * v * (p1 - p0) + 6.0 * v * u * (p2 - p1) + 3.0 * u * u * (p3 - p2);\n}\n\n/**\n * Solves bez1d(x0, x1, x2, x3, u) = x for u in [0, 1] assuming x(u) is monotone.\n * Uses closed-form inverse for 100% influence midpoint, Newton-Raphson iteration,\n * and high-precision bisection fallback.\n */\nexport function solveBezierU(x0: number, x1: number, x2: number, x3: number, x: number): number {\n if (x <= x0) return 0.0;\n if (x >= x3) return 1.0;\n\n // Closed-form solution for 100% influence on both sides (x1 === x3 && x2 === x0).\n // x(u) = x0 + (x3 - x0) * (0.5 + 4 * (u - 0.5)^3)\n if (Math.abs(x1 - x3) < 1e-12 && Math.abs(x2 - x0) < 1e-12) {\n const progress = (x - x0) / (x3 - x0);\n return 0.5 + Math.cbrt((progress - 0.5) * 0.25);\n }\n\n // Initial estimate\n let u = (x - x0) / (x3 - x0);\n\n // Up to 8 Newton-Raphson iterations\n for (let iter = 0; iter < 8; iter++) {\n const f = bez1d(x0, x1, x2, x3, u) - x;\n const d = bez1dDerivative(x0, x1, x2, x3, u);\n if (Math.abs(d) < 1e-12) break;\n if (Math.abs(f / d) < 1e-12) return u;\n const nextU = u - f / d;\n if (nextU < 0.0 || nextU > 1.0) break;\n u = nextU;\n }\n\n // Bisection fallback for robustness\n let lo = 0.0;\n let hi = 1.0;\n for (let iter = 0; iter < 60; iter++) {\n const mid = (lo + hi) * 0.5;\n if (bez1d(x0, x1, x2, x3, mid) < x) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n\n return (lo + hi) * 0.5;\n}\n\n/**\n * Fraction of progress 0..1 through a 1D Bezier temporal segment whose value goes from 0 to 1,\n * with normalized out/in speeds (speed * duration / deltaValue) and influences.\n *\n * @param outSpeedNorm Normalized outgoing speed (speed * duration / deltaValue).\n * @param outInfluence Outgoing influence fraction [0, 1].\n * @param inSpeedNorm Normalized incoming speed (speed * duration / deltaValue).\n * @param inInfluence Incoming influence fraction [0, 1].\n * @param x Normalized time progress in segment [0, 1].\n */\nexport function easeProgress(\n outSpeedNorm: number,\n outInfluence: number,\n inSpeedNorm: number,\n inInfluence: number,\n x: number,\n): number {\n const i0 = Math.min(1.0, Math.max(0.0, outInfluence));\n const i1 = Math.min(1.0, Math.max(0.0, inInfluence));\n const u = solveBezierU(0.0, i0, 1.0 - i1, 1.0, x);\n return bez1d(0.0, outSpeedNorm * i0, 1.0 - inSpeedNorm * i1, 1.0, u);\n}\n\n/**\n * Evaluates an interpolated keyframe segment between two values over duration.\n *\n * @param from Starting value at t = 0.\n * @param to Ending value at t = duration.\n * @param duration Duration of the keyframe segment in seconds.\n * @param t Current elapsed time in seconds (0 <= t <= duration).\n * @param outEase Outgoing ease specification at start keyframe.\n * @param inEase Incoming ease specification at end keyframe.\n */\nexport function evaluateKeyframeSegment(\n from: number,\n to: number,\n duration: number,\n t: number,\n outEase: KeyframeEase = EASY_EASE,\n inEase: KeyframeEase = EASY_EASE,\n): number {\n if (duration <= 0 || t <= 0) return from;\n if (t >= duration) return to;\n\n const delta = to - from;\n const x = t / duration;\n\n // Zero delta: maintain from\n if (Math.abs(delta) < 1e-12) {\n return from;\n }\n\n const outSpeedNorm = (outEase.speed * duration) / delta;\n const inSpeedNorm = (inEase.speed * duration) / delta;\n\n const progress = easeProgress(outSpeedNorm, outEase.influence, inSpeedNorm, inEase.influence, x);\n return from + progress * delta;\n}\n","/**\n * SMPTE 12M Timecode engine and broadcast frame-rate converter.\n *\n * Supports non-drop-frame (NDF) and drop-frame (DF) timecode for broadcast standards\n * (23.976, 24, 25, 29.97, 30, 48, 50, 59.94, 60, 120 fps).\n *\n * Drop-frame timecode drops frames 00 and 01 at the start of each minute,\n * except every 10th minute (e.g. 00:01:00;02 instead of 00:01:00;00).\n */\n\nexport interface RationalFrameRate {\n readonly num: number;\n readonly den: number;\n}\n\nexport const COMMON_FRAME_RATES = {\n FPS_23_976: { num: 24000, den: 1001 },\n FPS_24: { num: 24, den: 1 },\n FPS_25: { num: 25, den: 1 },\n FPS_29_97: { num: 30000, den: 1001 },\n FPS_30: { num: 30, den: 1 },\n FPS_48: { num: 48, den: 1 },\n FPS_50: { num: 50, den: 1 },\n FPS_59_94: { num: 60000, den: 1001 },\n FPS_60: { num: 60, den: 1 },\n FPS_120: { num: 120, den: 1 },\n} as const;\n\nexport type StandardFrameRateKey = keyof typeof COMMON_FRAME_RATES;\n\n/** Greatest common divisor helper. */\nfunction gcd(a: number, b: number): number {\n let x = Math.abs(Math.round(a));\n let y = Math.abs(Math.round(b));\n while (y !== 0) {\n const t = y;\n y = x % y;\n x = t;\n }\n return x || 1;\n}\n\n/** Creates a reduced rational frame rate. */\nexport function createFrameRate(num: number, den = 1): RationalFrameRate {\n if (den <= 0 || num <= 0) {\n return { num: 30, den: 1 };\n }\n const g = gcd(num, den);\n return { num: Math.round(num / g), den: Math.round(den / g) };\n}\n\n/** Returns the timecode base (frames counted per second in timecode display). */\nexport function getTimecodeBase(rate: RationalFrameRate): number {\n return Math.ceil(rate.num / rate.den);\n}\n\n/** Whether a given frame rate supports drop-frame counting (29.97, 59.94, etc.). */\nexport function supportsDropFrame(rate: RationalFrameRate): boolean {\n return rate.den === 1001 && getTimecodeBase(rate) % 30 === 0;\n}\n\n/** Number of dropped frames per minute (e.g. 2 for 29.97, 4 for 59.94). */\nexport function getDropFrameCount(rate: RationalFrameRate): number {\n const base = getTimecodeBase(rate);\n return Math.floor(base / 15);\n}\n\nexport interface SMPTEFields {\n negative: boolean;\n hours: number;\n minutes: number;\n seconds: number;\n frames: number;\n}\n\n/**\n * Converts a continuous frame count to SMPTE fields (hours, minutes, seconds, frames).\n */\nexport function framesToSMPTE(\n frame: number,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): SMPTEFields {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const neg = frame < 0;\n let n = Math.abs(Math.round(frame));\n const base = getTimecodeBase(rate);\n const drop = getDropFrameCount(rate);\n\n if (isDrop) {\n const perMinute = base * 60 - drop;\n const per10Minutes = perMinute * 10 + drop;\n const d = Math.floor(n / per10Minutes);\n const m = n % per10Minutes;\n\n n += drop * 9 * d;\n if (m > drop) {\n n += drop * Math.floor((m - drop) / perMinute);\n }\n }\n\n const frames = n % base;\n const seconds = Math.floor(n / base) % 60;\n const minutes = Math.floor(n / (base * 60)) % 60;\n const hours = Math.floor(n / (base * 3600));\n\n return { negative: neg, hours, minutes, seconds, frames };\n}\n\n/**\n * Converts SMPTE fields back to a continuous frame number.\n */\nexport function smpteToFrames(\n fields: { hours: number; minutes: number; seconds: number; frames: number },\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): number {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const base = getTimecodeBase(rate);\n const drop = getDropFrameCount(rate);\n\n const totalSecs = fields.hours * 3600 + fields.minutes * 60 + fields.seconds;\n let n = totalSecs * base + fields.frames;\n\n if (isDrop) {\n const totalMinutes = fields.hours * 60 + fields.minutes;\n n -= drop * (totalMinutes - Math.floor(totalMinutes / 10));\n }\n\n return n;\n}\n\n/**\n * Formats a frame number as standard SMPTE timecode (HH:MM:SS:FF or HH;MM;SS;FF).\n */\nexport function formatTimecode(\n frame: number,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n): string {\n const isDrop = dropFrame && supportsDropFrame(rate);\n const { negative, hours, minutes, seconds, frames } = framesToSMPTE(frame, rate, isDrop);\n const sep = isDrop ? ';' : ':';\n const base = getTimecodeBase(rate);\n const frameWidth = base >= 100 ? 3 : 2;\n\n const hStr = String(hours).padStart(2, '0');\n const mStr = String(minutes).padStart(2, '0');\n const sStr = String(seconds).padStart(2, '0');\n const fStr = String(frames).padStart(frameWidth, '0');\n\n return `${negative ? '-' : ''}${hStr}${sep}${mStr}${sep}${sStr}${sep}${fStr}`;\n}\n\n/**\n * Parses user or NLE input into a frame number.\n * Supports:\n * - Standard timecodes: `01:00:00:00`, `01;00;00;00`, `00.01.20.15`\n * - Right-aligned numbers: `1000` -> `00:00:10:00`\n * - Relative offsets: `+15` (+15 frames), `-1.00` (-1 second)\n *\n * @param input The timecode string to parse.\n * @param rate Rational frame rate (default: 30 fps).\n * @param dropFrame Whether drop-frame arithmetic applies.\n * @param currentFrame Current playhead position for relative additions.\n */\nexport function parseTimecode(\n input: string,\n rate: RationalFrameRate = COMMON_FRAME_RATES.FPS_30,\n dropFrame = false,\n currentFrame = 0,\n): number {\n const s = input.trim();\n if (!s) {\n throw new Error('Empty timecode string');\n }\n\n let relativeSign: 1 | -1 | null = null;\n let body = s;\n if (s.startsWith('+')) {\n relativeSign = 1;\n body = s.slice(1);\n } else if (s.startsWith('-')) {\n relativeSign = -1;\n body = s.slice(1);\n }\n\n const parts = body.split(/[:;.,]/);\n let parsedFrame = 0;\n\n if (parts.length === 1) {\n const digits = parts[0]!;\n if (!/^\\d+$/.test(digits)) {\n throw new Error(`Invalid timecode: \"${input}\"`);\n }\n\n if (relativeSign !== null) {\n // Relative bare digits are treated as frames\n const count = parseInt(digits, 10);\n return currentFrame + relativeSign * count;\n }\n\n // Right-aligned pairs: e.g. \"1000\" -> HH=0, MM=0, SS=10, FF=0\n const nums: number[] = [];\n let end = digits.length;\n while (end > 0) {\n const start = Math.max(0, end - 2);\n nums.unshift(parseInt(digits.slice(start, end), 10));\n end = start;\n }\n\n const padded = [0, 0, 0, 0];\n const offset = 4 - nums.length;\n for (let i = 0; i < nums.length; i++) {\n padded[offset + i] = nums[i]!;\n }\n const [h, m, sec, fr] = padded;\n parsedFrame = smpteToFrames(\n { hours: h!, minutes: m!, seconds: sec!, frames: fr! },\n rate,\n dropFrame,\n );\n } else {\n if (parts.length > 4) {\n throw new Error(`Too many timecode fields in \"${input}\"`);\n }\n const nums = parts.map((p) => (p.length === 0 ? 0 : parseInt(p, 10)));\n if (nums.some((n) => isNaN(n))) {\n throw new Error(`Invalid number in timecode: \"${input}\"`);\n }\n\n const padded = [0, 0, 0, 0];\n const offset = 4 - nums.length;\n for (let i = 0; i < nums.length; i++) {\n padded[offset + i] = nums[i]!;\n }\n const [h, m, sec, fr] = padded;\n parsedFrame = smpteToFrames(\n { hours: h!, minutes: m!, seconds: sec!, frames: fr! },\n rate,\n dropFrame,\n );\n }\n\n if (relativeSign !== null) {\n return currentFrame + relativeSign * parsedFrame;\n }\n\n return parsedFrame;\n}\n","import type { Scene } from './types.js';\n\nexport interface SliderSnapshot {\n at: number;\n values: Record<string, number | string>;\n}\n\nexport interface SliderWidget {\n type: 'slider';\n name: string;\n value: number;\n snapshots: SliderSnapshot[];\n}\n\nexport interface PopupWidget {\n type: 'popup';\n name: string;\n selected: string;\n options: Record<string, Record<string, number | string>>;\n}\n\nexport interface ToggleWidget {\n type: 'toggle';\n name: string;\n enabled: boolean;\n on: Record<string, number | string>;\n off: Record<string, number | string>;\n}\n\nexport type RigWidget = SliderWidget | PopupWidget | ToggleWidget;\n\nexport interface SceneRig {\n widgets: Record<string, RigWidget>;\n}\n\n/**\n * Updates a widget within a SceneRig and returns the updated SceneRig.\n */\nexport function setRigWidget(\n rig: SceneRig,\n widgetName: string,\n value: number | string | boolean,\n): SceneRig {\n const widget = rig.widgets[widgetName];\n if (!widget) {\n throw new Error(`Rig widget \"${widgetName}\" not found.`);\n }\n\n const updatedWidgets = { ...rig.widgets };\n\n if (widget.type === 'slider') {\n if (typeof value !== 'number') {\n throw new Error(`Slider widget \"${widgetName}\" expects numeric value.`);\n }\n updatedWidgets[widgetName] = { ...widget, value };\n } else if (widget.type === 'popup') {\n if (typeof value !== 'string') {\n throw new Error(`Popup widget \"${widgetName}\" expects string value.`);\n }\n updatedWidgets[widgetName] = { ...widget, selected: value };\n } else if (widget.type === 'toggle') {\n if (typeof value !== 'boolean') {\n throw new Error(`Toggle widget \"${widgetName}\" expects boolean value.`);\n }\n updatedWidgets[widgetName] = { ...widget, enabled: value };\n }\n\n return { widgets: updatedWidgets };\n}\n\n/**\n * Evaluates resolved values for a given widget.\n */\nfunction resolveWidgetValues(widget: RigWidget): Record<string, number | string> {\n if (widget.type === 'popup') {\n return widget.options[widget.selected] ?? {};\n }\n\n if (widget.type === 'toggle') {\n return widget.enabled ? widget.on : widget.off;\n }\n\n if (widget.type === 'slider') {\n const { snapshots, value } = widget;\n if (!snapshots || snapshots.length === 0) return {};\n\n const sorted = [...snapshots].sort((a, b) => a.at - b.at);\n if (value <= sorted[0]!.at) {\n return { ...sorted[0]!.values };\n }\n if (value >= sorted[sorted.length - 1]!.at) {\n return { ...sorted[sorted.length - 1]!.values };\n }\n\n // Find bounding snapshots\n let idx = 0;\n while (idx < sorted.length - 1 && sorted[idx + 1]!.at < value) {\n idx++;\n }\n\n const s0 = sorted[idx]!;\n const s1 = sorted[idx + 1]!;\n const span = s1.at - s0.at;\n const t = span > 0 ? (value - s0.at) / span : 0;\n\n const result: Record<string, number | string> = {};\n const allKeys = new Set([...Object.keys(s0.values), ...Object.keys(s1.values)]);\n\n for (const k of allKeys) {\n const v0 = s0.values[k];\n const v1 = s1.values[k];\n if (typeof v0 === 'number' && typeof v1 === 'number') {\n result[k] = v0 + (v1 - v0) * t;\n } else if (v0 !== undefined && v1 !== undefined) {\n result[k] = t < 0.5 ? v0 : v1;\n } else {\n result[k] = v1 !== undefined ? v1 : (v0 as number | string);\n }\n }\n\n return result;\n }\n\n return {};\n}\n\n/**\n * Propagates rig widget state into the scene's shader uniforms and elements.\n */\nexport function applyRig(rig: SceneRig, scene: Scene): Scene {\n // Deep clone media and shots to prevent mutation\n const nextMedia: Record<string, any> = {};\n if (scene.media) {\n for (const [id, m] of Object.entries(scene.media)) {\n nextMedia[id] = {\n ...m,\n values: { ...(m.values ?? {}) },\n };\n }\n }\n\n const nextShots = scene.shots.map((shot) => {\n if (!shot.run) return { ...shot };\n return {\n ...shot,\n run: shot.run.map((cmd) => {\n if (cmd.type === 'element' && 'element' in cmd && cmd.element) {\n return { ...cmd, element: { ...cmd.element } };\n }\n if (cmd.type === 'update' && 'props' in cmd && (cmd as any).props) {\n return { ...cmd, props: { ...(cmd as any).props } };\n }\n return { ...cmd };\n }),\n };\n });\n\n // Collect all resolved values across all widgets in the rig\n const resolvedAll: Record<string, number | string> = {};\n for (const widget of Object.values(rig.widgets)) {\n Object.assign(resolvedAll, resolveWidgetValues(widget));\n }\n\n // Apply resolved values\n for (const [targetKey, val] of Object.entries(resolvedAll)) {\n if (targetKey.startsWith('media.')) {\n const parts = targetKey.split('.');\n const mediaId = parts[1]!;\n const prop = parts.length > 3 && parts[2] === 'values' ? parts[3]! : parts[2]!;\n if (nextMedia[mediaId]) {\n nextMedia[mediaId].values[prop] = val;\n }\n } else if (targetKey.startsWith('element.')) {\n const parts = targetKey.split('.');\n const elId = parts[1]!;\n const prop = parts[2]!;\n for (const shot of nextShots) {\n if (shot.run) {\n for (const cmd of shot.run) {\n if (cmd.type === 'element' && 'element' in cmd && (cmd as any).element?.id === elId) {\n (cmd.element as any)[prop] = val;\n } else if (cmd.type === 'update' && 'id' in cmd && cmd.id === elId) {\n (cmd as any).props[prop] = val;\n }\n }\n }\n }\n } else {\n // General uniform shorthand: uniforms.<name> or simply <name>\n const uniformName = targetKey.replace(/^uniforms\\./, '');\n for (const m of Object.values(nextMedia)) {\n m.values[uniformName] = val;\n }\n }\n }\n\n return {\n ...scene,\n media: Object.keys(nextMedia).length > 0 ? nextMedia : scene.media,\n shots: nextShots,\n rig,\n };\n}\n","import type { SceneElement } from './geometry.js';\n\nexport type ReplicatorPattern = 'grid' | 'line' | 'circle' | 'spiral';\n\nexport interface ReplicatorSequence {\n /** Property to modulate per item. */\n property?: 'opacity' | 'rotation' | 'scale' | 'x' | 'y';\n /** Incremental offset or delta added per instance. */\n offset?: number;\n /** Milliseconds delay per instance for staggered triggers. */\n delayPerItem?: number;\n}\n\nexport interface ReplicatorConfig {\n pattern: ReplicatorPattern;\n count: number;\n /** Origin point [x, y] to anchor the layout (defaults to prototype.x, prototype.y). */\n origin?: [number, number];\n\n // Grid options\n columns?: number;\n rows?: number;\n columnSpacing?: number;\n rowSpacing?: number;\n\n // Line options\n startPoint?: [number, number];\n endPoint?: [number, number];\n spacing?: number;\n\n // Circle / Spiral options\n radius?: number;\n startAngle?: number; // radians\n spiralTightness?: number; // radius expansion per instance\n\n // Sequence modulation\n sequence?: ReplicatorSequence;\n}\n\n/**\n * Procedurally replicates a prototype SceneElement into an array of positioned\n * and sequenced instances (grid, circular array, line, or spiral).\n */\nexport function expandReplicator(\n prototype: SceneElement,\n config: ReplicatorConfig,\n): SceneElement[] {\n const count = Math.max(0, Math.floor(config.count));\n if (count === 0) return [];\n\n const originX = config.origin ? config.origin[0] : prototype.x;\n const originY = config.origin ? config.origin[1] : prototype.y;\n const elements: SceneElement[] = [];\n\n for (let i = 0; i < count; i++) {\n const el: SceneElement = {\n ...prototype,\n id: `${prototype.id}_${i}`,\n };\n\n let px = originX;\n let py = originY;\n\n switch (config.pattern) {\n case 'grid': {\n const cols = config.columns ?? Math.ceil(Math.sqrt(count));\n const colSpacing = config.columnSpacing ?? (prototype.width + 20);\n const rowSpacing = config.rowSpacing ?? (prototype.height + 20);\n const col = i % cols;\n const row = Math.floor(i / cols);\n px = originX + col * colSpacing;\n py = originY + row * rowSpacing;\n break;\n }\n\n case 'line': {\n if (config.startPoint && config.endPoint) {\n const t = count > 1 ? i / (count - 1) : 0;\n px = config.startPoint[0] + (config.endPoint[0] - config.startPoint[0]) * t;\n py = config.startPoint[1] + (config.endPoint[1] - config.startPoint[1]) * t;\n } else {\n const spacing = config.spacing ?? (prototype.width + 20);\n px = originX + i * spacing;\n py = originY;\n }\n break;\n }\n\n case 'circle': {\n const radius = config.radius ?? 150;\n const angleStep = (2 * Math.PI) / count;\n const angle = (config.startAngle ?? 0) + i * angleStep;\n px = originX + radius * Math.cos(angle);\n py = originY + radius * Math.sin(angle);\n break;\n }\n\n case 'spiral': {\n const baseRadius = config.radius ?? 40;\n const tightness = config.spiralTightness ?? 12;\n const angleStep = Math.PI / 4; // 45 degrees per step\n const angle = (config.startAngle ?? 0) + i * angleStep;\n const r = baseRadius + tightness * i;\n px = originX + r * Math.cos(angle);\n py = originY + r * Math.sin(angle);\n break;\n }\n }\n\n el.x = px;\n el.y = py;\n\n // Apply sequence property modulation\n if (config.sequence && config.sequence.offset !== undefined) {\n const { property, offset } = config.sequence;\n if (property === 'opacity') {\n const base = prototype.opacity ?? 1.0;\n el.opacity = Math.max(0, Math.min(1, base + i * offset));\n } else if (property === 'rotation') {\n const base = (prototype as any).rotation ?? 0;\n (el as any).rotation = base + i * offset;\n } else if (property === 'scale') {\n const factor = 1 + i * offset;\n el.width = Math.max(1, prototype.width * factor);\n el.height = Math.max(1, prototype.height * factor);\n } else if (property === 'x') {\n el.x += i * offset;\n } else if (property === 'y') {\n el.y += i * offset;\n }\n }\n\n elements.push(el);\n }\n\n return elements;\n}\n","/**\n * Constant-Velocity Spatial Motion Paths & Arc-Length Parameterization.\n *\n * Implements multi-segment cubic Bezier spatial trajectories with numerical\n * arc-length integration, ensuring constant pixel-speed traversal, tangent heading,\n * normal vectors, curvature, and seamless combination with temporal AE keyframe easing.\n */\n\nimport { evaluateKeyframeSegment, type KeyframeEase } from '../time/keyframe.js';\n\nexport type Vec2 = [number, number];\nexport type Vec3 = [number, number, number];\n\nexport interface PathWaypoint {\n /** Anchor position in 2D or 3D scene coordinates [x, y] or [x, y, z]. */\n point: Vec2 | Vec3;\n /** In-tangent handle relative to anchor point (vector pointing from handle to anchor or vice-versa). Default: [0, 0, 0] */\n inTangent?: Vec2 | Vec3;\n /** Out-tangent handle relative to anchor point (vector pointing from anchor toward next handle). Default: [0, 0, 0] */\n outTangent?: Vec2 | Vec3;\n}\n\nexport interface SpatialPathSample {\n /** Position on curve [x, y, z]. */\n position: Vec3;\n /** Normalized unit tangent vector [dx, dy, dz]. */\n tangent: Vec3;\n /** 2D heading angle in radians (atan2(dy, dx)). */\n heading: number;\n /** 2D unit normal vector [-dy, dx, 0]. */\n normal: Vec3;\n /** Instantaneous curvature kappa (1 / radius of curvature). */\n curvature: number;\n /** Distance traversed along the path in absolute units. */\n distance: number;\n}\n\ninterface SegmentSample {\n t: number;\n s: number;\n pos: Vec3;\n}\n\ninterface PathSegment {\n p0: Vec3;\n p1: Vec3;\n p2: Vec3;\n p3: Vec3;\n length: number;\n samples: SegmentSample[];\n}\n\nexport interface SpatialMotionPath {\n waypoints: PathWaypoint[];\n closed: boolean;\n totalLength: number;\n segments: PathSegment[];\n}\n\nfunction toVec3(p: Vec2 | Vec3 | undefined): Vec3 {\n if (!p) return [0, 0, 0];\n return [p[0], p[1], p[2] ?? 0];\n}\n\nfunction cubicPos(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = u * u * u;\n const b = 3 * u * u * t;\n const c = 3 * u * t * t;\n const d = t * t * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction cubicVel(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = -3 * u * u;\n const b = 3 * u * u - 6 * u * t;\n const c = 6 * u * t - 3 * t * t;\n const d = 3 * t * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction cubicAcc(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const u = 1 - t;\n const a = 6 * u;\n const b = -12 * u + 6 * t;\n const c = 6 * u - 12 * t;\n const d = 6 * t;\n\n return [\n a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0],\n a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1],\n a * p0[2] + b * p1[2] + c * p2[2] + d * p3[2],\n ];\n}\n\nfunction dist3(a: Vec3, b: Vec3): number {\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const dz = b[2] - a[2];\n return Math.sqrt(dx * dx + dy * dy + dz * dz);\n}\n\n/**\n * Creates and compiles a constant-velocity SpatialMotionPath from a sequence of waypoints.\n * Computes fine-grained arc-length tables along all Bezier segments.\n */\nexport function createMotionPath(\n waypoints: PathWaypoint[],\n options?: { closed?: boolean; resolution?: number }\n): SpatialMotionPath {\n if (waypoints.length < 2) {\n throw new Error('SpatialMotionPath requires at least 2 waypoints.');\n }\n\n const closed = options?.closed ?? false;\n const segmentCount = closed ? waypoints.length : waypoints.length - 1;\n const segments: PathSegment[] = [];\n let totalLength = 0;\n\n for (let i = 0; i < segmentCount; i++) {\n const nextIdx = (i + 1) % waypoints.length;\n const w0 = waypoints[i];\n const w1 = waypoints[nextIdx];\n\n const p0 = toVec3(w0.point);\n const outT = toVec3(w0.outTangent);\n const p1: Vec3 = [p0[0] + outT[0], p0[1] + outT[1], p0[2] + outT[2]];\n\n const p3 = toVec3(w1.point);\n const inT = toVec3(w1.inTangent);\n const p2: Vec3 = [p3[0] + inT[0], p3[1] + inT[1], p3[2] + inT[2]];\n\n // Chord length estimate\n const chord = dist3(p0, p1) + dist3(p1, p2) + dist3(p2, p3);\n const stepCount = Math.max(16, Math.min(256, Math.ceil(chord / (options?.resolution ?? 2))));\n\n const samples: SegmentSample[] = [];\n let segLen = 0;\n let prev = p0;\n samples.push({ t: 0, s: 0, pos: p0 });\n\n for (let k = 1; k <= stepCount; k++) {\n const t = k / stepCount;\n const pos = cubicPos(p0, p1, p2, p3, t);\n segLen += dist3(prev, pos);\n samples.push({ t, s: segLen, pos });\n prev = pos;\n }\n\n segments.push({\n p0,\n p1,\n p2,\n p3,\n length: segLen,\n samples,\n });\n totalLength += segLen;\n }\n\n return {\n waypoints,\n closed,\n totalLength,\n segments,\n };\n}\n\n/**\n * Samples the spatial motion path at a normalized distance fraction [0..1].\n * Guarantees strictly constant pixel speed regardless of control handle asymmetry.\n */\nexport function sampleMotionPath(path: SpatialMotionPath, distanceFraction: number): SpatialPathSample {\n const clampedFraction = Math.max(0, Math.min(1, distanceFraction));\n const targetDistance = clampedFraction * path.totalLength;\n\n if (path.totalLength === 0) {\n const p = toVec3(path.waypoints[0].point);\n return {\n position: p,\n tangent: [1, 0, 0],\n heading: 0,\n normal: [0, 1, 0],\n curvature: 0,\n distance: 0,\n };\n }\n\n // Find target segment\n let accumulated = 0;\n let targetSeg = path.segments[0];\n let segDistance = targetDistance;\n\n for (const seg of path.segments) {\n if (accumulated + seg.length >= targetDistance || seg === path.segments[path.segments.length - 1]) {\n targetSeg = seg;\n segDistance = Math.max(0, Math.min(seg.length, targetDistance - accumulated));\n break;\n }\n accumulated += seg.length;\n }\n\n // Binary search for exact sample in target segment's arc length table\n const samples = targetSeg.samples;\n let low = 0;\n let high = samples.length - 1;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n if (samples[mid].s < segDistance) {\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n const idx = Math.max(0, Math.min(samples.length - 2, high));\n const s0 = samples[idx];\n const s1 = samples[idx + 1];\n\n const segRange = s1.s - s0.s;\n const factor = segRange > 1e-7 ? (segDistance - s0.s) / segRange : 0;\n const t = s0.t + factor * (s1.t - s0.t);\n\n // Evaluate exact position, velocity, acceleration at t\n const pos = cubicPos(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n const vel = cubicVel(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n const acc = cubicAcc(targetSeg.p0, targetSeg.p1, targetSeg.p2, targetSeg.p3, t);\n\n const speed = Math.sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]);\n const safeSpeed = speed > 1e-6 ? speed : 1;\n const tangent: Vec3 = [vel[0] / safeSpeed, vel[1] / safeSpeed, vel[2] / safeSpeed];\n\n const heading = Math.atan2(tangent[1], tangent[0]);\n const normal: Vec3 = [-tangent[1], tangent[0], 0];\n\n // Curvature: kappa = |v x a| / |v|^3\n const cx = vel[1] * acc[2] - vel[2] * acc[1];\n const cy = vel[2] * acc[0] - vel[0] * acc[2];\n const cz = vel[0] * acc[1] - vel[1] * acc[0];\n const crossMag = Math.sqrt(cx * cx + cy * cy + cz * cz);\n const curvature = crossMag / (safeSpeed * safeSpeed * safeSpeed);\n\n return {\n position: pos,\n tangent,\n heading,\n normal,\n curvature,\n distance: targetDistance,\n };\n}\n\n/**\n * Samples a spatial motion path driven by elapsed time and AE keyframe velocity easing.\n * Combines spatial arc-length constancy with temporal speed curves.\n */\nexport function sampleMotionPathAtTime(\n path: SpatialMotionPath,\n time: number,\n duration: number,\n ease?: {\n easeIn?: KeyframeEase;\n easeOut?: KeyframeEase;\n }\n): SpatialPathSample {\n const distanceFraction = evaluateKeyframeSegment(\n 0,\n 1,\n duration,\n time,\n ease?.easeOut,\n ease?.easeIn\n );\n return sampleMotionPath(path, distanceFraction);\n}\n\n","import type { Scene, SceneMedia, Shot } from '../scene/types.js';\nimport { validateScene, type SceneIssue } from '../scene/validate.js';\nimport { simulateScene } from '../scene/player.js';\nimport type { Review } from '../scene/report.js';\nimport { applyRig, setRigWidget } from '../scene/rig.js';\n\nexport interface AgentToolDefinition {\n name: string;\n description: string;\n input_schema: Record<string, unknown>;\n}\n\nexport const FLAIR_AGENT_TOOLS: AgentToolDefinition[] = [\n {\n name: 'get_scene',\n description: 'Returns the current scene JSON and any static validation issues.',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n },\n {\n name: 'write_scene',\n description: 'Overwrites the entire scene with a new specification and validates it.',\n input_schema: {\n type: 'object',\n properties: {\n scene: {\n type: 'object',\n description:\n 'Full Scene object with name, stage, media, and shots. A shot camera frames a box {x, y, width, height} or elements {frame: [ids]}, and may add tilt, turn, roll (degrees, tilt/turn up to 75), perspective (default 1.2) and motionBlur (0-3, 1 natural); angles persist until changed.',\n },\n },\n required: ['scene'],\n additionalProperties: false,\n },\n },\n {\n name: 'update_shot',\n description: 'Updates fields of a specific shot (1-based index) without rewriting the whole scene.',\n input_schema: {\n type: 'object',\n properties: {\n shot: { type: 'integer', minimum: 1, description: '1-based index of the shot to update.' },\n set: { type: 'object', description: 'Fields to set or replace on this shot.' },\n remove: {\n type: 'array',\n items: { type: 'string' },\n description: 'Field names to delete from this shot.',\n },\n },\n required: ['shot'],\n additionalProperties: false,\n },\n },\n {\n name: 'insert_shots',\n description: 'Inserts one or more shots at a given position.',\n input_schema: {\n type: 'object',\n properties: {\n after: {\n type: 'integer',\n minimum: 0,\n description: '0 to insert at the beginning, or 1-based index of shot to insert after.',\n },\n shots: {\n type: 'array',\n items: { type: 'object' },\n description: 'Array of Shot objects to insert.',\n },\n },\n required: ['after', 'shots'],\n additionalProperties: false,\n },\n },\n {\n name: 'delete_shots',\n description: 'Deletes one or more shots by 1-based index.',\n input_schema: {\n type: 'object',\n properties: {\n shots: {\n type: 'array',\n items: { type: 'integer', minimum: 1 },\n description: '1-based shot numbers to delete.',\n },\n },\n required: ['shots'],\n additionalProperties: false,\n },\n },\n {\n name: 'set_media',\n description: 'Adds, updates, or removes embedded media (e.g. bespoke WebGL shaders) by ID.',\n input_schema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Media identifier.' },\n media: {\n type: ['object', 'null'],\n description: 'SceneMedia object (e.g. { type: \"shader\", source: \"...\" }), or null to remove.',\n },\n },\n required: ['id', 'media'],\n additionalProperties: false,\n },\n },\n {\n name: 'preview_scene',\n description: 'Simulates the scene fast and off-screen, returning timing, layout checks, and review report.',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n },\n {\n name: 'set_rig_widget',\n description: 'Adjusts a high-level creative rig widget (slider, popup, or toggle) and propagates parameters to shaders and elements.',\n input_schema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Rig widget identifier/name.' },\n value: {\n type: ['number', 'string', 'boolean'],\n description: 'New value (number for slider, string for popup, boolean for toggle).',\n },\n },\n required: ['name', 'value'],\n additionalProperties: false,\n },\n },\n];\n\nexport type SceneToolResult =\n | { ok: true; scene: Scene; issues: SceneIssue[]; review?: Review }\n | { ok: false; error: string };\n\n/**\n * Pure state machine that applies tool operations to a Scene.\n */\nexport async function applySceneTool(\n scene: Scene,\n toolName: string,\n input: Record<string, any> = {},\n): Promise<SceneToolResult> {\n switch (toolName) {\n case 'get_scene': {\n return { ok: true, scene, issues: validateScene(scene) };\n }\n\n case 'write_scene': {\n if (!input.scene || typeof input.scene !== 'object') {\n return { ok: false, error: 'Expected scene object in arguments.' };\n }\n const newScene = input.scene as Scene;\n const issues = validateScene(newScene);\n return { ok: true, scene: newScene, issues };\n }\n\n case 'update_shot': {\n const idx = input.shot - 1;\n if (idx < 0 || idx >= scene.shots.length) {\n return { ok: false, error: `Invalid shot number ${input.shot}; scene has ${scene.shots.length} shots.` };\n }\n const existing = scene.shots[idx]!;\n const updated: Record<string, any> = { ...existing, ...(input.set || {}) };\n if (Array.isArray(input.remove)) {\n for (const k of input.remove) {\n delete updated[k];\n }\n }\n const shots = [...scene.shots];\n shots[idx] = updated as Shot;\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'insert_shots': {\n const after = input.after ?? scene.shots.length;\n if (after < 0 || after > scene.shots.length) {\n return { ok: false, error: `Invalid after index ${after}.` };\n }\n if (!Array.isArray(input.shots) || input.shots.length === 0) {\n return { ok: false, error: 'Expected non-empty shots array to insert.' };\n }\n const shots = [...scene.shots.slice(0, after), ...input.shots, ...scene.shots.slice(after)];\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'delete_shots': {\n if (!Array.isArray(input.shots) || input.shots.length === 0) {\n return { ok: false, error: 'Expected non-empty shots array to delete.' };\n }\n const toDelete = new Set(input.shots.map((n: number) => n - 1));\n const shots = scene.shots.filter((_, i) => !toDelete.has(i));\n if (shots.length === 0) {\n return { ok: false, error: 'Cannot delete all shots in scene.' };\n }\n const newScene = { ...scene, shots };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'set_media': {\n if (!input.id || typeof input.id !== 'string') {\n return { ok: false, error: 'Expected string media id.' };\n }\n const media = { ...(scene.media || {}) };\n if (input.media === null) {\n delete media[input.id];\n } else {\n media[input.id] = input.media as SceneMedia;\n }\n const newScene = { ...scene, media };\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n }\n\n case 'preview_scene': {\n const { review } = await simulateScene(scene);\n return { ok: true, scene, issues: validateScene(scene), review };\n }\n\n case 'set_rig_widget': {\n if (!scene.rig || !scene.rig.widgets || !scene.rig.widgets[input.name]) {\n return { ok: false, error: `Scene does not have a rig widget named \"${input.name}\".` };\n }\n try {\n const updatedRig = setRigWidget(scene.rig, input.name, input.value);\n const newScene = applyRig(updatedRig, scene);\n return { ok: true, scene: newScene, issues: validateScene(newScene) };\n } catch (err: any) {\n return { ok: false, error: err.message || String(err) };\n }\n }\n\n default:\n return { ok: false, error: `Unknown tool name: ${toolName}` };\n }\n}\n","/**\n * Atomic Agent Multi-Tool Batching with Result Variable Substitution.\n * Inspired by EffectCraft's atomic batch execution protocol.\n *\n * Allows AI agents to execute multi-step modifications to a Scene in a single turn,\n * with atomic rollback on failure and cross-step variable substitution ($1.prop, $2.prop).\n */\n\nimport type { Scene } from '../scene/types.js';\nimport { applySceneTool, type SceneToolResult } from './tools.js';\n\nexport interface BatchCommand {\n /** Name of the tool to execute (e.g. 'update_shot', 'insert_shots', 'set_rig_widget'). */\n tool: string;\n /** Parameters for the tool call. */\n params?: Record<string, any>;\n}\n\nexport interface BatchExecutionStepResult {\n step: number;\n tool: string;\n result: SceneToolResult;\n}\n\nexport interface BatchExecutionResult {\n ok: boolean;\n scene: Scene;\n steps: BatchExecutionStepResult[];\n error?: string;\n failedStep?: number;\n}\n\n/**\n * Resolves nested property path on an object (e.g. \"a.b[0].c\").\n */\nfunction getByPath(obj: any, path: string): any {\n if (!obj || typeof obj !== 'object') return undefined;\n const parts = path.replace(/\\[(\\w+)\\]/g, '.$1').split('.');\n let curr = obj;\n for (const part of parts) {\n if (curr === undefined || curr === null) return undefined;\n curr = curr[part];\n }\n return curr;\n}\n\n/**\n * Recursively substitutes `$stepIndex.path` references in parameters using previous step results.\n * E.g., \"$1.scene.shots[0].duration\" -> substituted with the duration value from step 1 result.\n */\nexport function substituteVariables(\n value: any,\n stepResults: Map<number, SceneToolResult>,\n): any {\n if (typeof value === 'string') {\n // Check if the entire string is a substitution reference: \"$1.path.to.prop\"\n const match = /^\\$(\\d+)\\.(.+)$/.exec(value);\n if (match) {\n const stepIdx = parseInt(match[1]!, 10);\n const path = match[2]!;\n const prevResult = stepResults.get(stepIdx);\n if (prevResult) {\n const resolved = getByPath(prevResult, path);\n if (resolved !== undefined) {\n return resolved;\n }\n }\n }\n // Partial template string substitution: \"Hello $1.scene.name\"\n return value.replace(/\\$(\\d+)\\.([a-zA-Z0-9_.[\\]]+)/g, (fullMatch, stepStr, path) => {\n const stepIdx = parseInt(stepStr, 10);\n const prevResult = stepResults.get(stepIdx);\n if (prevResult) {\n const resolved = getByPath(prevResult, path);\n if (resolved !== undefined) {\n return String(resolved);\n }\n }\n return fullMatch;\n });\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => substituteVariables(item, stepResults));\n }\n\n if (value !== null && typeof value === 'object') {\n const copy: Record<string, any> = {};\n for (const [k, v] of Object.entries(value)) {\n copy[k] = substituteVariables(v, stepResults);\n }\n return copy;\n }\n\n return value;\n}\n\n/**\n * Executes an atomic batch of scene tools with transactional rollback.\n * If any step fails, the scene rolls back to the initial state and returns the failure.\n *\n * @param scene Initial scene state before batch.\n * @param commands Ordered array of tool commands to execute.\n */\nexport async function applySceneBatch(\n scene: Scene,\n commands: BatchCommand[],\n): Promise<BatchExecutionResult> {\n let currentScene = scene;\n const stepResults = new Map<number, SceneToolResult>();\n const executedSteps: BatchExecutionStepResult[] = [];\n\n for (let i = 0; i < commands.length; i++) {\n const stepNumber = i + 1; // 1-based indexing for user/agent ergonomics\n const cmd = commands[i]!;\n\n // Perform variable substitution using results of earlier steps\n const resolvedParams = substituteVariables(cmd.params || {}, stepResults);\n\n // Prevent recursive batch execution to avoid cycles\n if (cmd.tool === 'batch_scene_tool') {\n return {\n ok: false,\n scene, // Rollback\n steps: executedSteps,\n error: `Nested batch_scene_tool is not allowed at step ${stepNumber}.`,\n failedStep: stepNumber,\n };\n }\n\n const stepResult = await applySceneTool(currentScene, cmd.tool, resolvedParams);\n stepResults.set(stepNumber, stepResult);\n executedSteps.push({\n step: stepNumber,\n tool: cmd.tool,\n result: stepResult,\n });\n\n if (!stepResult.ok) {\n // Transactional rollback: discard intermediate scenes and return original\n return {\n ok: false,\n scene, // Rollback to initial\n steps: executedSteps,\n error: `Step ${stepNumber} (${cmd.tool}) failed: ${stepResult.error}`,\n failedStep: stepNumber,\n };\n }\n\n currentScene = stepResult.scene;\n }\n\n return {\n ok: true,\n scene: currentScene,\n steps: executedSteps,\n };\n}\n"],"mappings":"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","names":["frame"]}
@@ -113,6 +113,15 @@ declare const BUILTIN_UNIFORMS: readonly [{
113
113
  readonly name: "iMouse";
114
114
  readonly type: "vec4";
115
115
  readonly doc: "xy = pointer while pressed (pixels), zw = press position (negative once released)";
116
+ }, {
117
+ readonly name: "iPointer";
118
+ readonly type: "vec4";
119
+ readonly doc: "xy = pointer while over the canvas (pixels), z = how hovered (0–1, eased), w = seconds held while pressed, minus seconds since release after (0 before any press)";
120
+ }, {
121
+ readonly name: "iClicks";
122
+ readonly type: "vec4";
123
+ readonly size: 8;
124
+ readonly doc: "the latest clicks, newest first: xy = where (pixels), z = when (iTime seconds), w = 1 for a click, 0 for an empty slot";
116
125
  }];
117
126
  /** A full-screen triangle from `gl_VertexID` alone: no buffers or attributes. */
118
127
  declare const VERTEX_SOURCE = "#version 300 es\nvoid main() {\n vec2 p = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));\n gl_Position = vec4(p * 2.0 - 1.0, 0.0, 1.0);\n}\n";
@@ -166,6 +175,10 @@ interface FrameState {
166
175
  frame: number;
167
176
  /** `iMouse`, Shadertoy semantics. */
168
177
  mouse: [number, number, number, number];
178
+ /** `iPointer` (default all zero: nobody is pointing). */
179
+ pointer?: readonly [number, number, number, number];
180
+ /** `iClicks`: {@link MAX_CLICKS} × (x, y, time, 1), newest first (default none; see `clicksUniform`). */
181
+ clicks?: Float32Array;
169
182
  }
170
183
  /**
171
184
  * Draws one frame of a compiled shader into the bound framebuffer, from (0, 0).
@@ -238,6 +251,8 @@ declare class ShaderRenderer {
238
251
  private wasPlayingBeforeHidden;
239
252
  private hasEnteredViewport;
240
253
  private mouse;
254
+ /** `iPointer` and `iClicks`. */
255
+ private pointer;
241
256
  private disposed;
242
257
  /** The latest source's status. */
243
258
  status: CompileStatus;
@@ -305,6 +320,8 @@ declare class ShaderRenderer {
305
320
  private toPixels;
306
321
  private onPointerDown;
307
322
  private onPointerMove;
323
+ private onPointerEnter;
324
+ private onPointerLeave;
308
325
  private onPointerUp;
309
326
  private onLost;
310
327
  private onRestored;