@pixerate/flair 0.17.0 → 0.19.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/CHANGELOG.md +18 -0
- package/README.md +32 -4
- package/dist/catalog/index.d.ts +8 -4
- package/dist/catalog/index.js +3 -1
- package/dist/{chunk-PMVJP5I4.js → chunk-HA6FIMH2.js} +107 -4
- package/dist/chunk-HA6FIMH2.js.map +1 -0
- package/dist/{chunk-LKQM3GSQ.js → chunk-HP7CYHS5.js} +45 -10
- package/dist/chunk-HP7CYHS5.js.map +1 -0
- package/dist/{chunk-MILF5MRS.js → chunk-MZ37DE7K.js} +2 -2
- package/dist/{chunk-LURJMWYM.js → chunk-WEDILTUN.js} +3430 -447
- package/dist/chunk-WEDILTUN.js.map +1 -0
- package/dist/{chunk-RM3I6WZH.js → chunk-YCQ5RU74.js} +52 -6
- package/dist/chunk-YCQ5RU74.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/editor/index.d.ts +3 -3
- package/dist/editor/index.js +19 -5
- package/dist/editor/index.js.map +1 -1
- package/dist/index.d.ts +18 -6
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +3 -3
- package/dist/{renderer-Bm0oQ7Bw.d.ts → renderer-Cn4_d5Qs.d.ts} +63 -7
- package/dist/svelte/index.d.ts +2 -2
- package/dist/svelte/index.js +3 -3
- package/dist/{svg-XugR-6Ec.d.ts → svg-BEOJriIW.d.ts} +5 -1
- package/dist/{types-C7g8-lTX.d.ts → types-Cl5n9s-3.d.ts} +22 -3
- package/dist/vector/index.d.ts +2 -2
- package/dist/vector/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-LKQM3GSQ.js.map +0 -1
- package/dist/chunk-LURJMWYM.js.map +0 -1
- package/dist/chunk-PMVJP5I4.js.map +0 -1
- package/dist/chunk-RM3I6WZH.js.map +0 -1
- /package/dist/{chunk-MILF5MRS.js.map → chunk-MZ37DE7K.js.map} +0 -0
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 (or a concise structural outline) and any static validation issues.',\n input_schema: {\n type: 'object',\n properties: {\n view: {\n type: 'string',\n enum: ['full', 'outline'],\n description:\n 'When \"outline\", returns scene hierarchy, timing, and framing without dense commands or raw media sources.',\n },\n },\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 interface SceneOutlineShot {\n shot: number;\n caption?: string;\n title?: string;\n hold?: number;\n camera?: Shot['camera'];\n commandCount: number;\n effects?: string[];\n}\n\nexport interface SceneOutline {\n name: string;\n title?: string;\n description?: string;\n stage?: Scene['stage'];\n target?: Scene['target'];\n mediaIds: string[];\n shots: SceneOutlineShot[];\n}\n\nexport type SceneToolResult =\n | { ok: true; scene: Scene; outline?: SceneOutline; 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 const issues = validateScene(scene);\n if (input.view === 'outline') {\n const outline: SceneOutline = {\n name: scene.name,\n title: scene.title,\n description: scene.description,\n stage: scene.stage,\n target: scene.target,\n mediaIds: Object.keys(scene.media || {}),\n shots: scene.shots.map((s, i) => ({\n shot: i + 1,\n caption: s.caption,\n title: s.title,\n hold: s.hold,\n camera: s.camera,\n commandCount: s.run?.length ?? 0,\n effects: s.effects?.map((e) => e.type),\n })),\n };\n return { ok: true, scene, outline, issues };\n }\n return { ok: true, scene, issues };\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 (or a concise structural outline) and any static validation issues.',\n input_schema: {\n type: 'object',\n properties: {\n view: {\n type: 'string',\n enum: ['full', 'outline'],\n description:\n 'When \"outline\", returns scene hierarchy, timing, and framing without dense commands or raw media sources.',\n },\n },\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 interface SceneOutlineShot {\n shot: number;\n caption?: string;\n title?: string;\n hold?: number;\n camera?: Shot['camera'];\n commandCount: number;\n effects?: string[];\n}\n\nexport interface SceneOutline {\n name: string;\n title?: string;\n description?: string;\n stage?: Scene['stage'];\n target?: Scene['target'];\n mediaIds: string[];\n shots: SceneOutlineShot[];\n}\n\nexport type SceneToolResult =\n | { ok: true; scene: Scene; outline?: SceneOutline; 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 const issues = validateScene(scene);\n if (input.view === 'outline') {\n const outline: SceneOutline = {\n name: scene.name,\n title: scene.title,\n description: scene.description,\n stage: scene.stage,\n target: scene.target,\n mediaIds: Object.keys(scene.media || {}),\n shots: scene.shots.map((s, i) => ({\n shot: i + 1,\n caption: s.caption,\n title: s.title,\n hold: s.hold,\n camera: s.camera,\n commandCount: s.run?.length ?? 0,\n effects: s.effects?.map((e) => e.type),\n })),\n };\n return { ok: true, scene, outline, issues };\n }\n return { ok: true, scene, issues };\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"]}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes } from 'react';
|
|
3
|
-
import { V as VectorEffect$1 } from '../types-
|
|
3
|
+
import { V as VectorEffect$1 } from '../types-Cl5n9s-3.js';
|
|
4
4
|
import { C as ControlValue } from '../controls-Ec6P0Vpy.js';
|
|
5
|
-
import { S as SvgMotion, a as SvgTrigger, C as Clock, b as SvgPlayer } from '../svg-
|
|
5
|
+
import { S as SvgMotion, a as SvgTrigger, C as Clock, b as SvgPlayer } from '../svg-BEOJriIW.js';
|
|
6
6
|
|
|
7
7
|
/** When to leave the still in place of the animation. */
|
|
8
8
|
type ReducedMotion = "user" | "always" | "never";
|
package/dist/react/index.js
CHANGED
|
@@ -2,15 +2,15 @@ import {
|
|
|
2
2
|
effectDefaults,
|
|
3
3
|
getEffect,
|
|
4
4
|
renderVectorEffect
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-WEDILTUN.js";
|
|
6
6
|
import {
|
|
7
7
|
svgFrameMarkup,
|
|
8
8
|
svgInlineLayout,
|
|
9
9
|
svgViewBox
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-MZ37DE7K.js";
|
|
11
11
|
import {
|
|
12
12
|
SvgPlayer
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-YCQ5RU74.js";
|
|
14
14
|
import "../chunk-OHW7UG6D.js";
|
|
15
15
|
import "../chunk-EHDJ3CPJ.js";
|
|
16
16
|
import "../chunk-WMZQCUFJ.js";
|
|
@@ -3,7 +3,7 @@ import { T as TextureSettings, a as ControlDef, C as ControlValue } from './cont
|
|
|
3
3
|
/** Why an image control's URL could not be shown. */
|
|
4
4
|
declare class ImageLoadError extends Error {
|
|
5
5
|
readonly url: string;
|
|
6
|
-
constructor(url: string, cause?: unknown);
|
|
6
|
+
constructor(url: string, cause?: unknown, message?: string);
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* The long edge, in pixels, SVG images are rasterised at. WebGL2 guarantees
|
|
@@ -49,7 +49,26 @@ declare function releaseImages(urls?: Iterable<string>): void;
|
|
|
49
49
|
interface TextureSource {
|
|
50
50
|
/** The texture for `url`: the image once loaded, a 1 × 1 opaque black placeholder until then. */
|
|
51
51
|
texture(url: string): WebGLTexture | null;
|
|
52
|
+
/**
|
|
53
|
+
* The texture of the live source set for the image control `name` (see
|
|
54
|
+
* {@link TextureCache.setLive}), with its current frame; undefined when
|
|
55
|
+
* the control has none, so its URL is drawn instead.
|
|
56
|
+
*/
|
|
57
|
+
liveTexture?(name: string): WebGLTexture | null | undefined;
|
|
52
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* A picture that changes while it is shown, for an image control: a playing
|
|
61
|
+
* `<video>`, or a canvas something else draws on. Videos re-upload when
|
|
62
|
+
* their frame changes; canvases on every frame drawn.
|
|
63
|
+
*/
|
|
64
|
+
type LiveSource = HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas;
|
|
65
|
+
/**
|
|
66
|
+
* Seeks a video to `time` seconds and settles once the frame there can be
|
|
67
|
+
* drawn, for stepping a video in time with `ShaderFrames`: `await
|
|
68
|
+
* seekVideo(video, t); frames.render(t)`. Pause the video first, or it
|
|
69
|
+
* moves on. The time is clamped to the video's length.
|
|
70
|
+
*/
|
|
71
|
+
declare function seekVideo(video: HTMLVideoElement, time: number): Promise<void>;
|
|
53
72
|
/**
|
|
54
73
|
* The textures of one WebGL context, by image URL. A URL starts loading the
|
|
55
74
|
* first time it is asked for; until it arrives the placeholder is drawn, and
|
|
@@ -61,6 +80,7 @@ interface TextureSource {
|
|
|
61
80
|
declare class TextureCache implements TextureSource {
|
|
62
81
|
private readonly gl;
|
|
63
82
|
private readonly entries;
|
|
83
|
+
private readonly live;
|
|
64
84
|
private readonly onLoad;
|
|
65
85
|
private readonly load;
|
|
66
86
|
private placeholder;
|
|
@@ -70,6 +90,27 @@ declare class TextureCache implements TextureSource {
|
|
|
70
90
|
/** Starts loading `url` if it is new. */
|
|
71
91
|
request(url: string): void;
|
|
72
92
|
private entry;
|
|
93
|
+
/**
|
|
94
|
+
* Shows `source` in the image control `name` instead of its URL, frame by
|
|
95
|
+
* frame (`null` goes back to the URL). Its texture is uploaded as it is
|
|
96
|
+
* drawn: a video's whenever it has moved to another frame, a canvas's on
|
|
97
|
+
* every frame. Until a video has a frame it shows black. A video from
|
|
98
|
+
* another site needs CORS (`crossOrigin = "anonymous"` and the site's
|
|
99
|
+
* consent); without it the upload fails, `onLoad` hears an
|
|
100
|
+
* {@link ImageLoadError}, and the control shows black.
|
|
101
|
+
*/
|
|
102
|
+
setLive(name: string, source: LiveSource | null): void;
|
|
103
|
+
liveTexture(name: string): WebGLTexture | null | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* Whether a live video has moved to a frame not yet drawn (or has its
|
|
106
|
+
* first frame ready), so a paused preview knows to draw again.
|
|
107
|
+
*/
|
|
108
|
+
liveChanged(): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Settles once every live video has a frame to show. Rejects with an
|
|
111
|
+
* {@link ImageLoadError} when one fails to load.
|
|
112
|
+
*/
|
|
113
|
+
liveReady(): Promise<void>;
|
|
73
114
|
/** The error for `url`, if it failed to load. */
|
|
74
115
|
error(url: string): ImageLoadError | null;
|
|
75
116
|
/**
|
|
@@ -183,8 +224,9 @@ interface FrameState {
|
|
|
183
224
|
/**
|
|
184
225
|
* Draws one frame of a compiled shader into the bound framebuffer, from (0, 0).
|
|
185
226
|
* Image controls are bound to texture units 0, 1, … in source order, with
|
|
186
|
-
* textures from `textures` (a {@link TextureCache} for the same context)
|
|
187
|
-
*
|
|
227
|
+
* textures from `textures` (a {@link TextureCache} for the same context): a
|
|
228
|
+
* control's live source when it has one, else its URL's image. Without
|
|
229
|
+
* `textures` they sample nothing.
|
|
188
230
|
*/
|
|
189
231
|
declare function drawFrame(gl: WebGL2RenderingContext, shader: CompiledShader, controls: ControlDef[], values: Record<string, ControlValue> | undefined, state: FrameState, textures?: TextureSource): void;
|
|
190
232
|
/**
|
|
@@ -237,6 +279,8 @@ declare class ShaderRenderer {
|
|
|
237
279
|
private readonly alpha;
|
|
238
280
|
private shader;
|
|
239
281
|
private textures;
|
|
282
|
+
/** Live sources by image control, kept to set again on a restored context. */
|
|
283
|
+
private live;
|
|
240
284
|
private controls;
|
|
241
285
|
private values;
|
|
242
286
|
private source;
|
|
@@ -267,7 +311,7 @@ declare class ShaderRenderer {
|
|
|
267
311
|
onStats?: (stats: RendererStats) => void;
|
|
268
312
|
/** Called with `true` when the GL context is lost and `false` once it is restored and recompiled. */
|
|
269
313
|
onContextLost?: (lost: boolean) => void;
|
|
270
|
-
/** Called when an image control's URL cannot be loaded; the control shows black. */
|
|
314
|
+
/** Called when an image control's URL (or live video) cannot be loaded; the control shows black. */
|
|
271
315
|
onImageError?: (error: ImageLoadError) => void;
|
|
272
316
|
/**
|
|
273
317
|
* Creates a canvas in `target` (with `className` or options), or attaches to an existing
|
|
@@ -285,8 +329,20 @@ declare class ShaderRenderer {
|
|
|
285
329
|
*/
|
|
286
330
|
setValues(values: Record<string, ControlValue> | undefined): void;
|
|
287
331
|
/**
|
|
288
|
-
*
|
|
289
|
-
*
|
|
332
|
+
* Shows a `<video>` (or a canvas) in the image control `name` (the
|
|
333
|
+
* uniform's name, such as `uImage`) in place of its URL, frame by frame;
|
|
334
|
+
* `null` goes back to the URL. The preview follows the video even while
|
|
335
|
+
* the shader's own clock is paused, and the video plays, seeks and loops
|
|
336
|
+
* on its own: the renderer never controls it. A video from another site
|
|
337
|
+
* needs `crossOrigin = "anonymous"` and CORS, or `onImageError` hears why
|
|
338
|
+
* it shows black. The value stays as it is, so documents, presets and
|
|
339
|
+
* agents keep seeing the URL.
|
|
340
|
+
*/
|
|
341
|
+
setLiveSource(name: string, source: LiveSource | null): void;
|
|
342
|
+
/**
|
|
343
|
+
* Settles once the images the current controls show have loaded, and
|
|
344
|
+
* every live video has a frame. Rejects with an {@link ImageLoadError}
|
|
345
|
+
* when one cannot be (it shows black).
|
|
290
346
|
*/
|
|
291
347
|
ready(): Promise<void>;
|
|
292
348
|
play(): void;
|
|
@@ -327,4 +383,4 @@ declare class ShaderRenderer {
|
|
|
327
383
|
private onRestored;
|
|
328
384
|
}
|
|
329
385
|
|
|
330
|
-
export { BUILTIN_UNIFORMS as B, type CompileError as C, type FrameState as F, ImageLoadError as I, type RendererStats as R, SVG_EDGE as S, TextureCache as T, VERTEX_SOURCE as V, type CompileStatus as a, type CompileResult as b, type CompiledShader as c, ShaderCompileError as d, ShaderRenderer as e, type ShaderRendererOptions as f, type TextureSource as g, applyTextureSettings as h, compileShader as i, createContext as j, drawFrame as k, formatCompileError as l, isSvgUrl as m, loadImage as n, preloadImages as o, parseCompileLog as p, resetGlCaches as q, releaseImages as r,
|
|
386
|
+
export { BUILTIN_UNIFORMS as B, type CompileError as C, type FrameState as F, ImageLoadError as I, type LiveSource as L, type RendererStats as R, SVG_EDGE as S, TextureCache as T, VERTEX_SOURCE as V, type CompileStatus as a, type CompileResult as b, type CompiledShader as c, ShaderCompileError as d, ShaderRenderer as e, type ShaderRendererOptions as f, type TextureSource as g, applyTextureSettings as h, compileShader as i, createContext as j, drawFrame as k, formatCompileError as l, isSvgUrl as m, loadImage as n, preloadImages as o, parseCompileLog as p, resetGlCaches as q, releaseImages as r, seekVideo as s, sizeSvg as t, wrapSource as w };
|
package/dist/svelte/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ActionReturn } from 'svelte/action';
|
|
2
|
-
import { V as VectorEffect } from '../types-
|
|
2
|
+
import { V as VectorEffect } from '../types-Cl5n9s-3.js';
|
|
3
3
|
import { C as ControlValue } from '../controls-Ec6P0Vpy.js';
|
|
4
|
-
import { a as SvgTrigger, C as Clock, b as SvgPlayer, S as SvgMotion } from '../svg-
|
|
4
|
+
import { a as SvgTrigger, C as Clock, b as SvgPlayer, S as SvgMotion } from '../svg-BEOJriIW.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Svelte 5 bindings for Flair's vector effects, written as plain TypeScript so
|
package/dist/svelte/index.js
CHANGED
|
@@ -2,15 +2,15 @@ import {
|
|
|
2
2
|
effectDefaults,
|
|
3
3
|
getEffect,
|
|
4
4
|
renderVectorEffect
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-WEDILTUN.js";
|
|
6
6
|
import {
|
|
7
7
|
svgFrameMarkup,
|
|
8
8
|
svgInlineLayout,
|
|
9
9
|
svgViewBox
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-MZ37DE7K.js";
|
|
11
11
|
import {
|
|
12
12
|
SvgPlayer
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-YCQ5RU74.js";
|
|
14
14
|
import "../chunk-OHW7UG6D.js";
|
|
15
15
|
import "../chunk-EHDJ3CPJ.js";
|
|
16
16
|
import "../chunk-WMZQCUFJ.js";
|
|
@@ -241,7 +241,11 @@ declare function jitter(key: string, n: number): number;
|
|
|
241
241
|
*/
|
|
242
242
|
declare function parseSvg(markup: string): SVGSVGElement | undefined;
|
|
243
243
|
interface SvgViewOptions {
|
|
244
|
-
/**
|
|
244
|
+
/**
|
|
245
|
+
* Called with the id of the innermost element with an id that is clicked:
|
|
246
|
+
* its id in the motion's markup (in the page, ids carry a suffix that keeps
|
|
247
|
+
* them unique, so several pictures can use the same ones).
|
|
248
|
+
*/
|
|
245
249
|
onPick?: (id: string) => void;
|
|
246
250
|
}
|
|
247
251
|
/** An {@link SvgMotion} drawn into an element; call `draw` with a time to show it then. */
|
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import { C as ControlValue, a as ControlDef } from './controls-Ec6P0Vpy.js';
|
|
2
|
-
import { S as SvgMotion, a as SvgTrigger } from './svg-
|
|
2
|
+
import { S as SvgMotion, a as SvgTrigger } from './svg-BEOJriIW.js';
|
|
3
3
|
|
|
4
4
|
/** What an effect is for, used to group the catalog. */
|
|
5
|
-
type EffectCategory = "gradient" | "organic" | "pattern" | "light" | "space" | "retro" | "image" | "overlay" | "text" | "morph" | "interaction" | "pyrotechnics" | "timewarp" | "melt" | "electric" | "transition" | "loader" | "data" | "icon";
|
|
5
|
+
type EffectCategory = "gradient" | "organic" | "pattern" | "light" | "space" | "retro" | "image" | "overlay" | "text" | "morph" | "interaction" | "pyrotechnics" | "timewarp" | "melt" | "electric" | "splatter" | "bubble" | "sticker" | "transition" | "loader" | "data" | "icon";
|
|
6
6
|
/** Every category, in the order the catalog lists them. */
|
|
7
7
|
declare const EFFECT_CATEGORIES: readonly EffectCategory[];
|
|
8
|
+
/**
|
|
9
|
+
* How a shader effect suits video in its image controls (see
|
|
10
|
+
* `ShaderRenderer.setLiveSource`):
|
|
11
|
+
*
|
|
12
|
+
* - `filter`: it treats each frame on its own, so it works as a live video filter.
|
|
13
|
+
* - `transition`: it blends two pictures, so it works between two clips.
|
|
14
|
+
* - `interactive`: it reacts to the pointer over a picture, and works as well over video.
|
|
15
|
+
* - `stills`: it runs on video but is made for a still picture: it moves the
|
|
16
|
+
* picture to fake motion of its own, or needs shapes or features in fixed places.
|
|
17
|
+
* - `none`: its pictures are not photos (rendered text, a silhouette mask), so video has no place in it.
|
|
18
|
+
*/
|
|
19
|
+
type VideoUse = "filter" | "transition" | "interactive" | "stills" | "none";
|
|
20
|
+
/** Every {@link VideoUse}, best suited to video first. */
|
|
21
|
+
declare const VIDEO_USES: readonly VideoUse[];
|
|
8
22
|
/** Named control values: a look an effect can be switched to. */
|
|
9
23
|
interface EffectPreset {
|
|
10
24
|
name: string;
|
|
@@ -36,6 +50,11 @@ interface ShaderEffect extends EffectBase {
|
|
|
36
50
|
* (`ShaderRenderer`'s `alpha` option) to layer it over a page or picture.
|
|
37
51
|
*/
|
|
38
52
|
transparent?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* How it suits video in its image controls. Every effect with an image
|
|
55
|
+
* control says; effects without one have nothing to show video in.
|
|
56
|
+
*/
|
|
57
|
+
video?: VideoUse;
|
|
39
58
|
}
|
|
40
59
|
/**
|
|
41
60
|
* A control of a vector effect, declared in a list rather than in the
|
|
@@ -117,4 +136,4 @@ declare function colorControl(name: string, hex: string, label?: string): Vector
|
|
|
117
136
|
/** A number control for vector effects. */
|
|
118
137
|
declare function numberControl(name: string, value: number, min: number, max: number, label?: string, step?: number): VectorControl;
|
|
119
138
|
|
|
120
|
-
export { CURRENT_COLOR as C, type EffectDefinition as E, type ShaderEffect as S, type VectorEffect as V, type EffectCategory as a,
|
|
139
|
+
export { CURRENT_COLOR as C, type EffectDefinition as E, type ShaderEffect as S, type VectorEffect as V, type EffectCategory as a, type VideoUse as b, EFFECT_CATEGORIES as c, type EffectPreset as d, VECTOR_CONTROL_TYPES as e, VIDEO_USES as f, type VectorControl as g, colorControl as h, isCurrentColor as i, vectorControlIssues as j, vectorControls as k, vectorEffectControls as l, numberControl as n, renderVectorEffect as r, vectorControlDef as v };
|