@pixerate/editor 0.53.0 → 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/agent/index.cjs +20 -12
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.d.cts +4 -3
  4. package/dist/agent/index.d.ts +4 -3
  5. package/dist/agent/index.js +18 -10
  6. package/dist/agent/index.js.map +1 -1
  7. package/dist/animation/index.cjs +16 -2
  8. package/dist/animation/index.cjs.map +1 -1
  9. package/dist/animation/index.d.cts +4 -226
  10. package/dist/animation/index.d.ts +4 -226
  11. package/dist/animation/index.js +15 -1
  12. package/dist/animation-editor/index.cjs +2221 -0
  13. package/dist/animation-editor/index.cjs.map +1 -0
  14. package/dist/animation-editor/index.d.cts +1117 -0
  15. package/dist/animation-editor/index.d.ts +1117 -0
  16. package/dist/animation-editor/index.js +2221 -0
  17. package/dist/animation-editor/index.js.map +1 -0
  18. package/dist/bezier-BfwIbVTl.d.cts +548 -0
  19. package/dist/bezier-DYBvLgUH.d.ts +548 -0
  20. package/dist/bridge/cli.cjs +36 -0
  21. package/dist/bridge/cli.cjs.map +1 -0
  22. package/dist/bridge/cli.d.cts +1 -0
  23. package/dist/bridge/cli.d.ts +1 -0
  24. package/dist/bridge/cli.js +36 -0
  25. package/dist/bridge/cli.js.map +1 -0
  26. package/dist/bridge/index.cjs +16 -0
  27. package/dist/bridge/index.cjs.map +1 -0
  28. package/dist/bridge/index.d.cts +65 -0
  29. package/dist/bridge/index.d.ts +65 -0
  30. package/dist/bridge/index.js +16 -0
  31. package/dist/bridge/index.js.map +1 -0
  32. package/dist/bridge-client-C5OziCRK.d.cts +148 -0
  33. package/dist/bridge-client-C5dRjrz5.d.ts +148 -0
  34. package/dist/canvas/index.cjs +1564 -557
  35. package/dist/canvas/index.cjs.map +1 -1
  36. package/dist/canvas/index.d.cts +411 -7
  37. package/dist/canvas/index.d.ts +411 -7
  38. package/dist/canvas/index.js +1559 -552
  39. package/dist/canvas/index.js.map +1 -1
  40. package/dist/chart/index.cjs +34 -76
  41. package/dist/chart/index.cjs.map +1 -1
  42. package/dist/chart/index.d.cts +9 -38
  43. package/dist/chart/index.d.ts +9 -38
  44. package/dist/chart/index.js +23 -65
  45. package/dist/chart/index.js.map +1 -1
  46. package/dist/chunk-AWKPSOSX.js +401 -0
  47. package/dist/chunk-AWKPSOSX.js.map +1 -0
  48. package/dist/chunk-B6DSIEXA.js +96 -0
  49. package/dist/chunk-B6DSIEXA.js.map +1 -0
  50. package/dist/chunk-EGFUVXKK.cjs +96 -0
  51. package/dist/chunk-EGFUVXKK.cjs.map +1 -0
  52. package/dist/{chunk-AMWXSYCI.js → chunk-GPWNYQ7R.js} +2 -370
  53. package/dist/chunk-GPWNYQ7R.js.map +1 -0
  54. package/dist/{chunk-TO22LX34.js → chunk-GTMJ4Y3S.js} +2208 -2920
  55. package/dist/chunk-GTMJ4Y3S.js.map +1 -0
  56. package/dist/chunk-H5K77C7Y.cjs +3848 -0
  57. package/dist/chunk-H5K77C7Y.cjs.map +1 -0
  58. package/dist/chunk-K73CKYUM.cjs +458 -0
  59. package/dist/chunk-K73CKYUM.cjs.map +1 -0
  60. package/dist/chunk-MLREO6J3.cjs +737 -0
  61. package/dist/chunk-MLREO6J3.cjs.map +1 -0
  62. package/dist/chunk-NONDTTH7.js +5979 -0
  63. package/dist/chunk-NONDTTH7.js.map +1 -0
  64. package/dist/chunk-NV22EMOZ.cjs +401 -0
  65. package/dist/chunk-NV22EMOZ.cjs.map +1 -0
  66. package/dist/{chunk-YNSK4MGT.cjs → chunk-O2UH7LZE.cjs} +1549 -2261
  67. package/dist/chunk-O2UH7LZE.cjs.map +1 -0
  68. package/dist/chunk-PTMIGXZ2.js +467 -0
  69. package/dist/chunk-PTMIGXZ2.js.map +1 -0
  70. package/dist/chunk-QIWFEEWG.cjs +467 -0
  71. package/dist/chunk-QIWFEEWG.cjs.map +1 -0
  72. package/dist/chunk-VWZB6BCY.js +737 -0
  73. package/dist/chunk-VWZB6BCY.js.map +1 -0
  74. package/dist/chunk-WWJNC7SX.js +3848 -0
  75. package/dist/chunk-WWJNC7SX.js.map +1 -0
  76. package/dist/chunk-XCXQDPID.cjs +5979 -0
  77. package/dist/chunk-XCXQDPID.cjs.map +1 -0
  78. package/dist/color-E9pwm--w.d.cts +33 -0
  79. package/dist/color-E9pwm--w.d.ts +33 -0
  80. package/dist/commands/index.cjs +2 -2
  81. package/dist/commands/index.cjs.map +1 -1
  82. package/dist/commands/index.d.cts +1 -1
  83. package/dist/commands/index.d.ts +1 -1
  84. package/dist/commands/index.js +3 -3
  85. package/dist/diagram/index.cjs +1167 -0
  86. package/dist/diagram/index.cjs.map +1 -0
  87. package/dist/diagram/index.d.cts +810 -0
  88. package/dist/diagram/index.d.ts +810 -0
  89. package/dist/diagram/index.js +1167 -0
  90. package/dist/diagram/index.js.map +1 -0
  91. package/dist/{easing-DTmX99QG.d.cts → easing-CNGk-W6d.d.cts} +1 -1
  92. package/dist/{easing-DTmX99QG.d.ts → easing-CNGk-W6d.d.ts} +1 -1
  93. package/dist/generation/index.d.cts +2 -2
  94. package/dist/generation/index.d.ts +2 -2
  95. package/dist/image-editor/index.d.cts +1 -1
  96. package/dist/image-editor/index.d.ts +1 -1
  97. package/dist/parameters/index.d.cts +1 -1
  98. package/dist/parameters/index.d.ts +1 -1
  99. package/dist/pathfinder-BZL8aSu0.d.cts +469 -0
  100. package/dist/pathfinder-CNtsbCRK.d.ts +469 -0
  101. package/dist/player-Dg0FT0UI.d.cts +193 -0
  102. package/dist/player-W-5DX3Go.d.ts +193 -0
  103. package/dist/presence-Cb6WhcrQ.d.cts +77 -0
  104. package/dist/presence-Cb6WhcrQ.d.ts +77 -0
  105. package/dist/{registry-CSlH4iUn.d.ts → registry-7AZFuand.d.ts} +1 -1
  106. package/dist/{registry-B4l-lYts.d.cts → registry-DIpIaCkH.d.cts} +1 -1
  107. package/dist/svg-CLg2zqZA.d.cts +847 -0
  108. package/dist/svg-CPK82TtU.d.ts +847 -0
  109. package/dist/tools/index.cjs +10 -2
  110. package/dist/tools/index.cjs.map +1 -1
  111. package/dist/tools/index.d.cts +3 -74
  112. package/dist/tools/index.d.ts +3 -74
  113. package/dist/tools/index.js +12 -4
  114. package/dist/types-BULrFyuQ.d.cts +316 -0
  115. package/dist/types-BULrFyuQ.d.ts +316 -0
  116. package/dist/vector/index.cjs +1328 -6752
  117. package/dist/vector/index.cjs.map +1 -1
  118. package/dist/vector/index.d.cts +7 -847
  119. package/dist/vector/index.d.ts +7 -847
  120. package/dist/vector/index.js +645 -6069
  121. package/dist/vector/index.js.map +1 -1
  122. package/package.json +19 -1
  123. package/dist/chunk-AMWXSYCI.js.map +0 -1
  124. package/dist/chunk-TO22LX34.js.map +0 -1
  125. package/dist/chunk-XFYUFVAX.cjs +0 -826
  126. package/dist/chunk-XFYUFVAX.cjs.map +0 -1
  127. package/dist/chunk-YNSK4MGT.cjs.map +0 -1
  128. package/dist/pathfinder-B9xh_pCZ.d.ts +0 -1013
  129. package/dist/pathfinder-QdG70sr9.d.cts +0 -1013
@@ -0,0 +1,1117 @@
1
+ import { b as AnimationEasing } from '../easing-CNGk-W6d.cjs';
2
+ import { b as AnimationLoopMode, c as AnimationPlayer, C as Clock } from '../player-Dg0FT0UI.cjs';
3
+ import { V as VectorDocument, a as VectorNode, b as VectorBounds, c as VectorSvgExportOptions } from '../svg-CLg2zqZA.cjs';
4
+ import { A as AffineMatrix } from '../bezier-BfwIbVTl.cjs';
5
+ import { H as HistoryManager } from '../HistoryManager-DeQQMBCj.cjs';
6
+ import { A as AgentToolProvider } from '../registry-DIpIaCkH.cjs';
7
+ import { J as JsonSchema } from '../schema-Di0CS6Pe.cjs';
8
+ import '../types-BFkYA4eF.cjs';
9
+ import '../types-DsiXGmjo.cjs';
10
+
11
+ /**
12
+ * A vector animation as plain JSON: a piece of vector artwork (the editor's `VectorDocument`,
13
+ * as the vector editor draws it) and the shots that bring it to life.
14
+ *
15
+ * Shots, not timelines: a shot frames the camera, plays its commands and holds. Timing comes
16
+ * from the content (each command has a sensible default length, and drawing a line takes as
17
+ * long as the line is long), so there are no keyframes to manage. The same scene plays the
18
+ * same frames every time: every frame is a pure function of time.
19
+ */
20
+ interface MotionScene {
21
+ /** Format version (always 1). */
22
+ version: 1;
23
+ /** A short name, e.g. `logo-reveal`. */
24
+ name: string;
25
+ description?: string;
26
+ /** The artwork in its resting state. Commands target its node ids. */
27
+ artwork: VectorDocument;
28
+ shots: MotionShot[];
29
+ /** Playback past the end: stop (`none`, default), `loop` or `ping-pong`. */
30
+ loop?: AnimationLoopMode;
31
+ /** Frame rate used to sample motion that a target format cannot express exactly (default 30). */
32
+ fps?: number;
33
+ /** Wanted length in seconds `[min, max]`; `check` warns outside it. */
34
+ target?: [number, number];
35
+ /** Parameters a Flair effect made from this scene exposes (see `toFlairVectorEffect`). */
36
+ controls?: MotionControl[];
37
+ /** Named sets of control values. */
38
+ presets?: MotionPreset[];
39
+ }
40
+ /** A rectangle of the artwork, in document units. */
41
+ interface MotionRect {
42
+ x: number;
43
+ y: number;
44
+ width: number;
45
+ height: number;
46
+ }
47
+ /**
48
+ * Where the camera looks: a rectangle, or the id of a node to frame (with `padding` around
49
+ * its bounds, default 24). The camera eases there over `ms` (default 1000; the first shot cuts).
50
+ */
51
+ type MotionCamera = (MotionRect | {
52
+ frame: string;
53
+ padding?: number;
54
+ }) & {
55
+ ease?: AnimationEasing;
56
+ ms?: number;
57
+ };
58
+ /** One beat of the animation. */
59
+ interface MotionShot {
60
+ /** Stable id (unique in the scene), e.g. `intro`. */
61
+ id: string;
62
+ /** What happens in this shot, in a few words (shown on the timeline). */
63
+ label?: string;
64
+ /** Omit to keep the current framing. */
65
+ camera?: MotionCamera;
66
+ /** Commands, played one after another (unless a command says `with: "previous"`). */
67
+ run: MotionCommand[];
68
+ /** Milliseconds to hold after the commands finish (default 600). */
69
+ hold?: number;
70
+ }
71
+ /** Fields every command takes. */
72
+ interface MotionCommandBase {
73
+ /** Node ids from the artwork (groups animate as one). */
74
+ targets: string[];
75
+ /** Length in ms for each target (each type has a default; `draw` follows the path length). */
76
+ duration?: number;
77
+ /** Wait this many ms before starting (default 0). */
78
+ delay?: number;
79
+ /** Start each further target this many ms after the one before (default 0). */
80
+ stagger?: number;
81
+ /** `after` (default) starts when the commands before it finish; `previous` starts with the command before. */
82
+ with?: 'after' | 'previous';
83
+ ease?: AnimationEasing;
84
+ /** Why this command is here (for people and agents reading the scene). */
85
+ note?: string;
86
+ }
87
+ type MotionEnterStyle = 'fade' | 'pop' | 'grow' | 'slide' | 'draw';
88
+ type MotionExitStyle = 'fade' | 'shrink' | 'slide' | 'undraw';
89
+ type MotionDirection = 'up' | 'down' | 'left' | 'right';
90
+ /** Brings hidden targets in. Targets entered in a shot are hidden before it. */
91
+ interface MotionEnterCommand extends MotionCommandBase {
92
+ type: 'enter';
93
+ /** Default `fade`. `draw` draws the outline on, then fades the fill in. */
94
+ style?: MotionEnterStyle;
95
+ /** For `slide`: the direction of travel (default `up`). */
96
+ direction?: MotionDirection;
97
+ /** For `slide`: how far in document units (default 40). */
98
+ distance?: number;
99
+ }
100
+ /** Takes targets out. */
101
+ interface MotionExitCommand extends MotionCommandBase {
102
+ type: 'exit';
103
+ /** Default `fade`. */
104
+ style?: MotionExitStyle;
105
+ direction?: MotionDirection;
106
+ distance?: number;
107
+ }
108
+ /** Draws a stroke on (or off) between two fractions of its length. */
109
+ interface MotionDrawCommand extends MotionCommandBase {
110
+ type: 'draw';
111
+ /** Fraction drawn at the end (default 1). */
112
+ to?: number;
113
+ /** Fraction drawn at the start (default: what is drawn now). */
114
+ from?: number;
115
+ }
116
+ /** Moves targets by an offset, or to a point (their centre lands there). */
117
+ interface MotionMoveCommand extends MotionCommandBase {
118
+ type: 'move';
119
+ by?: {
120
+ x: number;
121
+ y: number;
122
+ };
123
+ to?: {
124
+ x: number;
125
+ y: number;
126
+ };
127
+ }
128
+ /** Turns targets about their centre, by or to an angle in degrees (clockwise). */
129
+ interface MotionRotateCommand extends MotionCommandBase {
130
+ type: 'rotate';
131
+ by?: number;
132
+ to?: number;
133
+ }
134
+ /** Scales targets about their centre (1 = rest size). */
135
+ interface MotionScaleCommand extends MotionCommandBase {
136
+ type: 'scale';
137
+ to: number | {
138
+ x: number;
139
+ y: number;
140
+ };
141
+ }
142
+ /** Changes opacity (0–1). */
143
+ interface MotionFadeCommand extends MotionCommandBase {
144
+ type: 'fade';
145
+ to: number;
146
+ }
147
+ /** Changes solid paints and stroke width. Colours mix in OKLab. */
148
+ interface MotionStyleCommand extends MotionCommandBase {
149
+ type: 'style';
150
+ fill?: string;
151
+ stroke?: string;
152
+ strokeWidth?: number;
153
+ }
154
+ /** Morphs each target into the shape of another node (`into`), which usually stays hidden. */
155
+ interface MotionMorphCommand extends MotionCommandBase {
156
+ type: 'morph';
157
+ into: string;
158
+ }
159
+ /** Moves targets along a path node, centre on the path. */
160
+ interface MotionFollowCommand extends MotionCommandBase {
161
+ type: 'follow';
162
+ /** Id of a path node in the artwork (it can be hidden). */
163
+ path: string;
164
+ /** Turn with the path's direction (default false). */
165
+ rotate?: boolean;
166
+ /** Fractions of the path's length to travel between (default 0 → 1). */
167
+ from?: number;
168
+ to?: number;
169
+ }
170
+ /** Scales up and back, `count` times (draws the eye). */
171
+ interface MotionPulseCommand extends MotionCommandBase {
172
+ type: 'pulse';
173
+ /** Extra scale at the peak (default 0.15). */
174
+ amount?: number;
175
+ count?: number;
176
+ }
177
+ /** Shakes side to side, settling. */
178
+ interface MotionShakeCommand extends MotionCommandBase {
179
+ type: 'shake';
180
+ /** Distance in document units (default 8). */
181
+ amount?: number;
182
+ count?: number;
183
+ }
184
+ /** Tweens a numeric parameter of a live path effect on the target (twist angle, wiggle time, zig zag size…). */
185
+ interface MotionEffectCommand extends MotionCommandBase {
186
+ type: 'effect';
187
+ /** Id of an effect in the target node's `effects`. */
188
+ effect: string;
189
+ /** A numeric parameter of that effect, e.g. `angle`. */
190
+ param: string;
191
+ to: number;
192
+ }
193
+ /** Does nothing for `duration` ms. */
194
+ interface MotionWaitCommand {
195
+ type: 'wait';
196
+ duration: number;
197
+ with?: 'after' | 'previous';
198
+ note?: string;
199
+ }
200
+ type MotionCommand = MotionEnterCommand | MotionExitCommand | MotionDrawCommand | MotionMoveCommand | MotionRotateCommand | MotionScaleCommand | MotionFadeCommand | MotionStyleCommand | MotionMorphCommand | MotionFollowCommand | MotionPulseCommand | MotionShakeCommand | MotionEffectCommand | MotionWaitCommand;
201
+ type MotionCommandType = MotionCommand['type'];
202
+ declare const MOTION_COMMAND_TYPES: readonly MotionCommandType[];
203
+ declare const MOTION_ENTER_STYLES: readonly MotionEnterStyle[];
204
+ declare const MOTION_EXIT_STYLES: readonly MotionExitStyle[];
205
+ declare const MOTION_DIRECTIONS: readonly MotionDirection[];
206
+ /**
207
+ * A colour parameter of the effect made from the scene: it stands for every use of its
208
+ * `default` colour in the artwork and the commands, so recolouring it recolours them all.
209
+ */
210
+ interface MotionControl {
211
+ /** Identifier, e.g. `accent`. */
212
+ name: string;
213
+ type: 'color';
214
+ /** A `#rrggbb` colour used in the scene. */
215
+ default: string;
216
+ label?: string;
217
+ }
218
+ interface MotionPreset {
219
+ name: string;
220
+ values: Record<string, string>;
221
+ }
222
+ /** Default lengths (ms) of commands that give none. */
223
+ declare const MOTION_DEFAULT_DURATIONS: Readonly<Record<Exclude<MotionCommandType, 'wait' | 'draw'>, number>>;
224
+ /** Default hold after a shot's commands (ms). */
225
+ declare const MOTION_DEFAULT_HOLD = 600;
226
+ /** Default camera move (ms). */
227
+ declare const MOTION_CAMERA_MS = 1000;
228
+ /** `draw` lasts `length × MOTION_DRAW_MS_PER_UNIT`, clamped to `MOTION_DRAW_RANGE`. */
229
+ declare const MOTION_DRAW_MS_PER_UNIT = 1.5;
230
+ declare const MOTION_DRAW_RANGE: readonly [number, number];
231
+
232
+ /**
233
+ * Problems with a scene, as data: every issue has a stable `code`, a severity, the shot and
234
+ * command it is in and the ids it is about, beside its prose `message`, so an agent (or a UI)
235
+ * can act on it without parsing sentences.
236
+ */
237
+ /** `error`: the scene does not play as written. `warning`: it plays, but probably not as meant. `note`: may well be intended. */
238
+ type MotionIssueSeverity = 'error' | 'warning' | 'note';
239
+ /** Every issue code with its severity and what it means. */
240
+ declare const MOTION_ISSUE_CODES: {
241
+ readonly 'no-shots': {
242
+ readonly severity: "note";
243
+ readonly wording: "The scene has no shots yet.";
244
+ };
245
+ readonly 'duplicate-shot-id': {
246
+ readonly severity: "error";
247
+ readonly wording: "Two shots share an id.";
248
+ };
249
+ readonly 'unknown-target': {
250
+ readonly severity: "error";
251
+ readonly wording: "A command names a node the artwork does not have.";
252
+ };
253
+ readonly 'unknown-path': {
254
+ readonly severity: "error";
255
+ readonly wording: "A follow command names a path the artwork does not have.";
256
+ };
257
+ readonly 'not-a-path': {
258
+ readonly severity: "error";
259
+ readonly wording: "A follow path must be a path node, not a group.";
260
+ };
261
+ readonly 'unknown-shape': {
262
+ readonly severity: "error";
263
+ readonly wording: "A morph names a shape the artwork does not have.";
264
+ };
265
+ readonly 'unknown-effect': {
266
+ readonly severity: "error";
267
+ readonly wording: "An effect command names an effect the node does not have.";
268
+ };
269
+ readonly 'unknown-effect-param': {
270
+ readonly severity: "error";
271
+ readonly wording: "An effect command names a parameter that is not a number of that effect.";
272
+ };
273
+ readonly 'unknown-frame': {
274
+ readonly severity: "error";
275
+ readonly wording: "A camera frames a node the artwork does not have.";
276
+ };
277
+ readonly 'invalid-camera': {
278
+ readonly severity: "error";
279
+ readonly wording: "A camera rectangle has no area.";
280
+ };
281
+ readonly 'invalid-color': {
282
+ readonly severity: "error";
283
+ readonly wording: "A colour cannot be read.";
284
+ };
285
+ readonly 'paint-not-color': {
286
+ readonly severity: "warning";
287
+ readonly wording: "A style command recolours a gradient or empty paint, which only switches at the end.";
288
+ };
289
+ readonly overlap: {
290
+ readonly severity: "warning";
291
+ readonly wording: "Two commands change the same property of a node at the same time; the later one wins.";
292
+ };
293
+ readonly 'enter-visible': {
294
+ readonly severity: "warning";
295
+ readonly wording: "A node enters while it is already showing, so it blinks out first.";
296
+ };
297
+ readonly 'exit-hidden': {
298
+ readonly severity: "warning";
299
+ readonly wording: "A node exits or animates while it is hidden.";
300
+ };
301
+ readonly 'out-of-frame': {
302
+ readonly severity: "warning";
303
+ readonly wording: "A node a command animates ends up outside the camera.";
304
+ };
305
+ readonly 'too-fast': {
306
+ readonly severity: "warning";
307
+ readonly wording: "A change is too quick to follow.";
308
+ };
309
+ readonly 'scene-too-long': {
310
+ readonly severity: "warning";
311
+ readonly wording: "The scene runs past its target length.";
312
+ };
313
+ readonly 'scene-too-short': {
314
+ readonly severity: "warning";
315
+ readonly wording: "The scene ends before its target length.";
316
+ };
317
+ readonly 'unknown-control-color': {
318
+ readonly severity: "warning";
319
+ readonly wording: "A control stands for a colour the scene never uses.";
320
+ };
321
+ readonly 'empty-shot': {
322
+ readonly severity: "note";
323
+ readonly wording: "A shot neither moves the camera nor runs a command.";
324
+ };
325
+ readonly 'camera-aspect': {
326
+ readonly severity: "note";
327
+ readonly wording: "A camera rectangle has a different shape from the artwork, so it is letterboxed.";
328
+ };
329
+ };
330
+ type MotionIssueCode = keyof typeof MOTION_ISSUE_CODES;
331
+ interface MotionIssue {
332
+ code: MotionIssueCode;
333
+ severity: MotionIssueSeverity;
334
+ message: string;
335
+ /** Id of the shot it is in, when it is in one. */
336
+ shot?: string;
337
+ /** Index of the command in that shot's `run`. */
338
+ command?: number;
339
+ /** Node ids it is about. */
340
+ ids?: string[];
341
+ /** What was measured, what was needed and in what unit (e.g. 80 vs 120 ms). */
342
+ measured?: number;
343
+ needed?: number;
344
+ unit?: 'ms' | 's' | 'units';
345
+ }
346
+ declare function motionIssue(code: MotionIssueCode, message: string, extra?: Omit<MotionIssue, 'code' | 'severity' | 'message'>): MotionIssue;
347
+ /** A stable key for an issue (code and ids, else code and place), to compare two checks. */
348
+ declare function motionIssueKey(issue: MotionIssue): string;
349
+ /** One line: `Shot "intro", command 2: …`. */
350
+ declare function motionIssueLine(issue: MotionIssue): string;
351
+ /** The candidate closest to `word` (case-insensitive), if it is within a third of its length. */
352
+ declare function suggestName(word: string, candidates: Iterable<string>): string | undefined;
353
+ /** `"sunn" (did you mean "sun"?)`, or just `"sunn"`. */
354
+ declare function namedWithSuggestion(word: string, candidates: Iterable<string>): string;
355
+
356
+ /**
357
+ * Shape checking: whether a value is a well-formed scene, listing every problem at once.
358
+ * Meaning (do the ids exist, does the timing work) is `checkMotionScene`'s job.
359
+ */
360
+ declare class MotionSceneFormatError extends Error {
361
+ readonly problems: string[];
362
+ constructor(problems: string[]);
363
+ }
364
+ /** Problems with one command's shape (empty when well formed). `where` prefixes each. */
365
+ declare function commandShapeProblems(command: unknown, where: string): string[];
366
+ /** Problems with one shot's shape. */
367
+ declare function shotShapeProblems(shot: unknown, where: string): string[];
368
+ /** Problems with a scene's shape (empty when well formed). */
369
+ declare function motionSceneShapeProblems(input: unknown): string[];
370
+ /** Reads a scene from JSON (a string or a parsed value). Throws `MotionSceneFormatError` listing every problem. */
371
+ declare function parseMotionScene(input: unknown): MotionScene;
372
+ /** Writes a scene as JSON. */
373
+ declare function motionSceneToJson(scene: MotionScene, space?: number | string): string;
374
+ /** Whether `shot` is a well-formed shot. */
375
+ declare const isMotionShot: (shot: unknown) => shot is MotionShot;
376
+ /** Whether `command` is a well-formed command. */
377
+ declare const isMotionCommand: (command: unknown) => command is MotionCommand;
378
+
379
+ /**
380
+ * Compiling a scene: shots and commands become timed segments, one per (node, property)
381
+ * change. A property's value at a time is that of the latest segment to have started (its
382
+ * `from` before the first one), so a node that enters later is hidden until then. This is
383
+ * also how Flair's vector motion combines changes, which keeps the Flair export exact.
384
+ */
385
+ /**
386
+ * Properties a segment can change. Offsets (`x`, `y`, `rotation`) are relative to the rest
387
+ * pose, scales multiply it, and turns and scales are about the node's centre at rest.
388
+ * `effect:<effectId>:<param>` tweens a live path effect's parameter. `camera` (node `""`) is
389
+ * the view box `[x, y, width, height]`.
390
+ */
391
+ type MotionProperty = 'opacity' | 'x' | 'y' | 'rotation' | 'scaleX' | 'scaleY' | 'fill' | 'stroke' | 'strokeWidth' | 'fillOpacity' | 'drawStart' | 'drawEnd' | 'shape' | 'follow' | 'camera' | `effect:${string}:${string}`;
392
+ type MotionValue = number | string | readonly number[];
393
+ /** An oscillation laid over a segment (`pulse`: scale up and back; `shake`: side to side, settling). */
394
+ interface MotionWave {
395
+ kind: 'pulse' | 'shake';
396
+ amount: number;
397
+ count: number;
398
+ }
399
+ interface MotionSegment {
400
+ /** Node id (`""` for the camera). */
401
+ node: string;
402
+ property: MotionProperty;
403
+ start: number;
404
+ end: number;
405
+ from: MotionValue;
406
+ to: MotionValue;
407
+ ease: AnimationEasing;
408
+ /** The shot and command (index in `run`) it comes from. */
409
+ shot: string;
410
+ command: number;
411
+ wave?: MotionWave;
412
+ /** For `follow`: the path node id, and whether to turn with it. */
413
+ path?: string;
414
+ rotate?: boolean;
415
+ }
416
+ interface MotionShotTiming {
417
+ id: string;
418
+ index: number;
419
+ label?: string;
420
+ start: number;
421
+ /** When the camera move ends and the commands begin. */
422
+ commandsStart: number;
423
+ /** When the last command ends (the hold follows). */
424
+ commandsEnd: number;
425
+ end: number;
426
+ }
427
+ interface MotionCommandTiming {
428
+ shot: string;
429
+ shotIndex: number;
430
+ command: number;
431
+ type: MotionCommand['type'];
432
+ start: number;
433
+ end: number;
434
+ /** Length per target (ms). */
435
+ duration: number;
436
+ }
437
+ interface MotionTimeline {
438
+ /** Total length in ms. */
439
+ duration: number;
440
+ shots: MotionShotTiming[];
441
+ commands: MotionCommandTiming[];
442
+ segments: MotionSegment[];
443
+ /** Segments per `node\u0000property`, in start order. */
444
+ tracks: ReadonlyMap<string, readonly MotionSegment[]>;
445
+ }
446
+ /** Where a node sits in the artwork. */
447
+ interface MotionNodeEntry {
448
+ node: VectorNode;
449
+ /** Ids from the root down to the node's parent. */
450
+ ancestors: string[];
451
+ /** Parent space → document space. */
452
+ parentWorld: AffineMatrix;
453
+ /** Centre of the node's bounds at rest, in its parent's space. */
454
+ center: {
455
+ x: number;
456
+ y: number;
457
+ };
458
+ /** Bounds at rest in document space. */
459
+ bounds: VectorBounds | null;
460
+ }
461
+ /** Every node of the artwork by id (cached per node list). */
462
+ declare function indexMotionNodes(nodes: readonly VectorNode[]): Map<string, MotionNodeEntry>;
463
+ /** A property's value with no animation. */
464
+ declare function motionRestValue(entry: MotionNodeEntry | undefined, property: MotionProperty, artwork: {
465
+ width: number;
466
+ height: number;
467
+ }): MotionValue;
468
+ /** `from` → `to` at eased progress `u` (numbers extrapolate, colours mix in OKLab, others switch at the end). */
469
+ declare function interpolateMotionValue(from: MotionValue, to: MotionValue, u: number): MotionValue;
470
+ /** Progress (0–1, unclamped by the easing) of a segment at `time`. */
471
+ declare function segmentProgress(segment: MotionSegment, time: number): {
472
+ u: number;
473
+ eased: number;
474
+ };
475
+ /** A segment's value at `time`. */
476
+ declare function segmentValue(segment: MotionSegment, time: number): MotionValue;
477
+ /** The segment in effect at `time` (the latest to have started), if any. */
478
+ declare function activeSegment(track: readonly MotionSegment[] | undefined, time: number): MotionSegment | undefined;
479
+ /** A track's value at `time`, or `undefined` when nothing animates it. */
480
+ declare function trackValue(track: readonly MotionSegment[] | undefined, time: number): MotionValue | undefined;
481
+ declare const motionTrackKey: (node: string, property: MotionProperty) => string;
482
+ /** Grows a rectangle to the artwork's aspect ratio (about its centre). */
483
+ declare function fitMotionRect(rect: MotionRect, aspect: number): MotionRect;
484
+ /** The rectangle a camera looks at, or `null` when it frames an unknown node. */
485
+ declare function resolveMotionCamera(camera: MotionCamera, scene: MotionScene): MotionRect | null;
486
+ /** Length of a node's outline (its longest path for a group), in document units. */
487
+ declare function motionPathLength(node: VectorNode, parentWorld?: AffineMatrix): number;
488
+ /** How long one target of a command takes (ms). */
489
+ declare function motionCommandDuration(command: MotionCommand, scene: MotionScene, target?: string): number;
490
+ /** Cubic ease-out, `1 − (1 − t)³` exactly (Flair's `out`): the default for things arriving. */
491
+ declare const MOTION_EASE_OUT: AnimationEasing;
492
+ /** Cubic ease-in-out (close to Flair's `in-out`): the default for moves. */
493
+ declare const MOTION_EASE_IN_OUT: AnimationEasing;
494
+ /**
495
+ * Times every shot and command and turns them into segments. Pure and cached per scene object
496
+ * (treat scenes as immutable). Commands naming unknown nodes are timed but change nothing;
497
+ * `checkMotionScene` reports them.
498
+ */
499
+ declare function compileMotionScene(scene: MotionScene): MotionTimeline;
500
+ /** The shot playing at `time` (the last one at the end). */
501
+ declare function motionShotAt(timeline: MotionTimeline, time: number): MotionShotTiming | undefined;
502
+
503
+ /** The artwork as it stands at one time, and where the camera looks. */
504
+ interface MotionFrame {
505
+ time: number;
506
+ document: VectorDocument;
507
+ camera: MotionRect;
508
+ }
509
+ interface MotionFrameOptions {
510
+ /** Control values (`{ accent: "#0ea5e9" }`): each recolours its control's default colour. */
511
+ values?: Record<string, string>;
512
+ /** Draw-on as a Trim Paths effect (default true). Off leaves strokes whole. */
513
+ draw?: boolean;
514
+ /** Apply moves, turns, scales and follows (default true). Off leaves nodes where they rest. */
515
+ offsets?: boolean;
516
+ }
517
+ /** Id of the trim effect that draws strokes on. */
518
+ declare const MOTION_DRAW_EFFECT_ID = "~draw";
519
+ /** A copy of the scene with each control's default colour replaced by its value (exact, case-insensitive matches). */
520
+ declare function applyMotionControlValues(scene: MotionScene, values: Record<string, string> | undefined): MotionScene;
521
+ /** The transform a node's offsets, turn, scale and follow add (parent space), or null when none. */
522
+ declare function motionNodeOffset(entry: MotionNodeEntry, timeline: MotionTimeline, time: number, nodes?: Map<string, MotionNodeEntry>): {
523
+ matrix: AffineMatrix;
524
+ dx: number;
525
+ dy: number;
526
+ rotation: number;
527
+ scaleX: number;
528
+ scaleY: number;
529
+ } | null;
530
+ /**
531
+ * The scene at `time` (ms): the artwork with every change applied, and the camera. A pure
532
+ * function of time, so frames can be drawn in any order (and the same frames come out every time).
533
+ */
534
+ declare function motionFrameAt(scene: MotionScene, time: number, options?: MotionFrameOptions): MotionFrame;
535
+ interface MotionSvgOptions extends MotionFrameOptions, VectorSvgExportOptions {
536
+ }
537
+ /** The scene at `time` as a standalone SVG (the camera becomes the `viewBox`). */
538
+ declare function motionFrameToSvg(scene: MotionScene, time: number, options?: MotionSvgOptions): string;
539
+ /** Replaces the root `viewBox` of an SVG string. */
540
+ declare function withViewBox(svg: string, box: MotionRect): string;
541
+
542
+ /** Changes shorter than this (ms) are too quick to follow. */
543
+ declare const MOTION_MIN_CHANGE_MS = 120;
544
+ /**
545
+ * What is wrong with a scene's meaning: unknown ids (with a "did you mean"), timing that
546
+ * fights itself, things animated while hidden or off camera, and lengths outside the target.
547
+ * The scene must be well formed (see `parseMotionScene`).
548
+ */
549
+ declare function checkMotionScene(scene: MotionScene): MotionIssue[];
550
+
551
+ /**
552
+ * Edits as data: each is a pure function of the scene, all or nothing. An edit that leaves the
553
+ * scene malformed, or adds an error the scene did not have (an unknown id, say), changes
554
+ * nothing and says why; existing errors do not block unrelated edits, so a broken scene can be
555
+ * fixed a step at a time.
556
+ */
557
+ type MotionEdit = {
558
+ op: 'set_settings';
559
+ name?: string;
560
+ description?: string | null;
561
+ loop?: MotionScene['loop'];
562
+ fps?: number;
563
+ target?: [number, number] | null;
564
+ } | {
565
+ op: 'insert_shots';
566
+ shots: MotionShot[];
567
+ at?: number;
568
+ } | {
569
+ op: 'update_shot';
570
+ shot: string;
571
+ set?: Partial<MotionShot>;
572
+ remove?: ('label' | 'camera' | 'hold')[];
573
+ } | {
574
+ op: 'delete_shots';
575
+ shots: string[];
576
+ } | {
577
+ op: 'move_shot';
578
+ shot: string;
579
+ to: number;
580
+ } | {
581
+ op: 'add_commands';
582
+ shot: string;
583
+ commands: MotionCommand[];
584
+ at?: number;
585
+ } | {
586
+ op: 'update_command';
587
+ shot: string;
588
+ command: number;
589
+ set?: Record<string, unknown>;
590
+ remove?: string[];
591
+ } | {
592
+ op: 'delete_commands';
593
+ shot: string;
594
+ commands: number[];
595
+ } | {
596
+ op: 'set_artwork';
597
+ artwork: VectorDocument;
598
+ } | {
599
+ op: 'set_controls';
600
+ controls: MotionControl[];
601
+ presets?: MotionPreset[];
602
+ } | {
603
+ op: 'replace_scene';
604
+ scene: MotionScene;
605
+ };
606
+ type MotionEditOp = MotionEdit['op'];
607
+ declare const MOTION_EDIT_OPS: readonly MotionEditOp[];
608
+ type MotionEditResult = {
609
+ ok: true;
610
+ scene: MotionScene;
611
+ /** Every issue the edited scene has. */
612
+ issues: MotionIssue[];
613
+ /** Edits that work but may surprise (a later command undoes this one, say). */
614
+ hints: string[];
615
+ } | {
616
+ ok: false;
617
+ error: string;
618
+ };
619
+ /** A free shot id: `base`, then `base-2`, `base-3`… */
620
+ declare function freshShotId(scene: MotionScene, base?: string): string;
621
+ /** Applies edits in order, as one change. Fails without changing anything when one fails. */
622
+ declare function applyMotionEdits(scene: MotionScene, edits: MotionEdit | readonly MotionEdit[]): MotionEditResult;
623
+ /** An empty scene over `artwork`. */
624
+ declare function createMotionScene(artwork: VectorDocument, init?: Partial<Omit<MotionScene, 'artwork' | 'version'>>): MotionScene;
625
+
626
+ /**
627
+ * Export to Flair (`@pixerate/flair`): a scene becomes an `SvgMotion` (one SVG plus a list of
628
+ * from → to changes on its elements), a catalog `VectorEffect`, or an `EffectDocument` for
629
+ * Flair's effect editor. The types are mirrored here so this package does not depend on Flair.
630
+ *
631
+ * Changes are exact where Flair can express them: a change with a linear, cubic-out or
632
+ * cubic-in-out curve (the editor's defaults) is one change. Anything else (other easings,
633
+ * pulses and shakes, follows, morphs and live-effect tweens) is sampled at the scene's `fps`
634
+ * into short linear changes, which Flair plays the same way.
635
+ */
636
+ /** Flair's easing names. */
637
+ type FlairEaseName = 'linear' | 'in-out' | 'out';
638
+ /** Flair's curves, for matching. */
639
+ declare const FLAIR_EASES: Readonly<Record<FlairEaseName, (t: number) => number>>;
640
+ /** One change of a Flair `SvgMotion` (mirrors `SvgAnimation` in `@pixerate/flair/vector`). */
641
+ interface FlairSvgAnimation {
642
+ id?: string;
643
+ step?: number;
644
+ delay?: number;
645
+ ms?: number;
646
+ ease?: FlairEaseName;
647
+ attrs?: Record<string, readonly [string | number, string | number]>;
648
+ draw?: boolean | readonly [number, number];
649
+ view?: readonly [number, number, number, number] | string;
650
+ }
651
+ /** Mirrors `SvgMotion` in `@pixerate/flair/vector`. */
652
+ interface FlairSvgMotion {
653
+ svg: string;
654
+ animate?: FlairSvgAnimation[];
655
+ }
656
+ /** Mirrors Flair's catalog `VectorEffect` (`@pixerate/flair/catalog`). */
657
+ interface FlairVectorEffect {
658
+ kind: 'vector';
659
+ id: string;
660
+ name: string;
661
+ description: string;
662
+ category: string;
663
+ tags: string[];
664
+ motion: FlairSvgMotion;
665
+ presets?: {
666
+ name: string;
667
+ values: Record<string, string>;
668
+ }[];
669
+ /** Ms on the last frame before looping. */
670
+ hold?: number;
671
+ trigger?: 'hover' | 'press' | 'click' | 'scroll';
672
+ }
673
+ /** Mirrors Flair's `EffectDocument` (`@pixerate/flair/editor`) for a vector effect. */
674
+ interface FlairEffectDocument {
675
+ version: 1;
676
+ name: string;
677
+ effect: {
678
+ kind: 'vector';
679
+ motion: FlairSvgMotion;
680
+ hold?: number;
681
+ };
682
+ values: Record<string, string>;
683
+ tracks: Record<string, never>;
684
+ duration: number;
685
+ loop: boolean;
686
+ presets: {
687
+ name: string;
688
+ values: Record<string, string>;
689
+ }[];
690
+ }
691
+ interface FlairMotionExport {
692
+ motion: FlairSvgMotion;
693
+ /** The scene's length (ms). */
694
+ duration: number;
695
+ /** Ms after the last change (Flair's `hold`). */
696
+ hold: number;
697
+ /** Changes sampled into linear steps. */
698
+ sampled: number;
699
+ /** What could not be carried over, in sentences. */
700
+ notes: string[];
701
+ }
702
+ interface FlairExportOptions {
703
+ /** Sampling rate for changes Flair cannot express exactly (default: the scene's `fps`, else 30). */
704
+ fps?: number;
705
+ /** Decimal places (default 3). */
706
+ precision?: number;
707
+ }
708
+ /** The Flair easing that matches `ease` (within 1% everywhere), if any. */
709
+ declare function flairEaseFor(ease: AnimationEasing): FlairEaseName | undefined;
710
+ /** A scene as a Flair `SvgMotion`. */
711
+ declare function toFlairSvgMotion(scene: MotionScene, options?: FlairExportOptions): FlairMotionExport;
712
+ interface FlairEffectOptions extends FlairExportOptions {
713
+ /** Kebab-case id (default: the scene's name). */
714
+ id?: string;
715
+ name?: string;
716
+ description?: string;
717
+ /** Flair catalog category (default `icon`). */
718
+ category?: string;
719
+ tags?: string[];
720
+ trigger?: FlairVectorEffect['trigger'];
721
+ }
722
+ /** A scene as a Flair catalog vector effect, with its colour controls and presets. */
723
+ declare function toFlairVectorEffect(scene: MotionScene, options?: FlairEffectOptions): FlairVectorEffect;
724
+ /** A scene as a document for Flair's `EffectEditor` (`replaceDocument`). */
725
+ declare function toFlairEffectDocument(scene: MotionScene, options?: FlairExportOptions): FlairEffectDocument;
726
+
727
+ interface AnimationEditorOptions {
728
+ /** The scene to open (default: an empty one over a blank 800 × 450 artwork). */
729
+ scene?: MotionScene;
730
+ /** Shared undo history (default: a new one). */
731
+ history?: HistoryManager;
732
+ /** Time source for playback (default: requestAnimationFrame). Pass a `ManualClock` to step frames. */
733
+ clock?: Clock;
734
+ readOnly?: boolean;
735
+ /** Called after every change to the scene (not on playback or selection). */
736
+ onChange?: (scene: MotionScene) => void;
737
+ }
738
+ /** What is selected on the timeline: a shot, and optionally one of its commands. */
739
+ interface AnimationEditorSelection {
740
+ shot: string;
741
+ command?: number;
742
+ }
743
+ /** A snapshot of the editor. The same object is returned until something changes. */
744
+ interface AnimationEditorState {
745
+ scene: MotionScene;
746
+ /** Total length (ms). */
747
+ duration: number;
748
+ /** Each shot's timing. */
749
+ shots: readonly MotionShotTiming[];
750
+ /** The scene's problems (see `checkMotionScene`). */
751
+ issues: readonly MotionIssue[];
752
+ /** Playhead (ms). */
753
+ time: number;
754
+ playing: boolean;
755
+ loop: AnimationLoopMode;
756
+ /** Id of the shot under the playhead. */
757
+ currentShot: string | null;
758
+ selection: AnimationEditorSelection | null;
759
+ readOnly: boolean;
760
+ /** Why the last edit was refused, if it was. */
761
+ error: string | null;
762
+ canUndo: boolean;
763
+ canRedo: boolean;
764
+ undoLabel: string;
765
+ redoLabel: string;
766
+ /** Bumped on every change. */
767
+ revision: number;
768
+ }
769
+ /**
770
+ * Headless editor for a vector animation (a `MotionScene`): undoable, all-or-nothing edits,
771
+ * playback on an injectable clock, a timeline selection and frames at any time. UI-agnostic:
772
+ * React and Svelte bind it with `useAnimationEditor` / `createAnimationEditor`, and agents
773
+ * drive it through `createAnimationEditorToolProvider`. `getState()` returns the same object
774
+ * until something changes, so it works with `useSyncExternalStore` and Svelte runes.
775
+ */
776
+ declare class AnimationEditorController {
777
+ readonly history: HistoryManager;
778
+ readonly player: AnimationPlayer;
779
+ private scene;
780
+ private issues;
781
+ private selection;
782
+ private readOnly;
783
+ private error;
784
+ private revision;
785
+ private applying;
786
+ private readonly onChange?;
787
+ private readonly listeners;
788
+ private readonly unsubscribers;
789
+ private state;
790
+ constructor(options?: AnimationEditorOptions);
791
+ private connect;
792
+ /**
793
+ * Pauses and stops listening to the player and history. Subscribing again reconnects, so a
794
+ * controller survives React StrictMode's unmount / remount.
795
+ */
796
+ destroy(): void;
797
+ getState: () => AnimationEditorState;
798
+ subscribe: (listener: (state: AnimationEditorState) => void) => (() => void);
799
+ /** The current scene (immutable; edit through the controller). */
800
+ getScene(): MotionScene;
801
+ private computeState;
802
+ private notify;
803
+ private setScene;
804
+ private commit;
805
+ private refuse;
806
+ /** Why edits are refused now, or `null` when they are allowed. */
807
+ readOnlyReason(): string | null;
808
+ /**
809
+ * Applies edits as one undo step, all or nothing (see `applyMotionEdits`). With
810
+ * `dryRun` it reports what would happen and changes nothing.
811
+ */
812
+ apply(edits: MotionEdit | readonly MotionEdit[], label?: string, options?: {
813
+ dryRun?: boolean;
814
+ }): MotionEditResult;
815
+ /** Replaces the artwork (e.g. from a vector editor's `onChange`), as one undo step. */
816
+ setArtwork(artwork: VectorDocument, label?: string): MotionEditResult;
817
+ /** Opens a scene (JSON or object). `clearHistory` drops the undo stack (opening a file); otherwise it is one undo step. */
818
+ load(scene: MotionScene | string, options?: {
819
+ clearHistory?: boolean;
820
+ }): MotionEditResult;
821
+ setReadOnly(readOnly: boolean): void;
822
+ /** Selects a shot (and optionally a command in it); `null` clears. Unknown shots clear. */
823
+ select(selection: AnimationEditorSelection | null): void;
824
+ play(): void;
825
+ pause(): void;
826
+ toggle(): void;
827
+ /** Moves the playhead (ms). */
828
+ seek(time: number): void;
829
+ /** Moves the playhead to the start or end of a shot. Returns false for an unknown shot. */
830
+ seekShot(id: string, at?: 'start' | 'end'): boolean;
831
+ undo(): boolean;
832
+ redo(): boolean;
833
+ /** The scene at `time` (default: the playhead). */
834
+ frame(time?: number, options?: MotionFrameOptions): MotionFrame;
835
+ /** The scene at `time` (default: the playhead) as SVG. */
836
+ toSvg(time?: number, options?: MotionSvgOptions): string;
837
+ /** The scene as a Flair `SvgMotion`. */
838
+ toFlairMotion(options?: FlairExportOptions): FlairMotionExport;
839
+ /** The scene as a Flair catalog vector effect. */
840
+ toFlairEffect(options?: FlairEffectOptions): FlairVectorEffect;
841
+ /** The scene as a Flair `EffectDocument`. */
842
+ toFlairDocument(options?: FlairExportOptions): FlairEffectDocument;
843
+ }
844
+
845
+ interface AnimationEditorToolProviderOptions {
846
+ /** Provider id (unique per registry). Default `animation`. */
847
+ id?: string;
848
+ /** Always prefix tool names with `<namespace>__`. */
849
+ namespace?: string;
850
+ /** The animation cannot be edited: write tools are hidden and `get_animation` says why. A string is the reason. */
851
+ readOnly?: boolean | string | (() => boolean | string);
852
+ /** Turns SVG into PNG (e.g. `rasterizeSvg`), so `render_animation_frame` can return an image. */
853
+ rasterize?: (svg: string, size: {
854
+ width: number;
855
+ height: number;
856
+ }) => Promise<{
857
+ data: string;
858
+ mimeType: string;
859
+ }> | {
860
+ data: string;
861
+ mimeType: string;
862
+ };
863
+ }
864
+ /** JSON Schema of one command (each type its own strict branch). */
865
+ declare const MOTION_COMMAND_SCHEMA: JsonSchema;
866
+ /** The elements of a scene's artwork, as agents see them. */
867
+ declare function describeMotionElements(scene: MotionScene): {
868
+ bounds?: {
869
+ x: number;
870
+ y: number;
871
+ width: number;
872
+ height: number;
873
+ } | undefined;
874
+ effects?: {
875
+ id: string;
876
+ type: "trim" | "roundCorners" | "puckerBloat" | "twist" | "zigzag" | "wiggle" | "offset" | "merge" | "repeater" | "envelope";
877
+ numericParams: {
878
+ [k: string]: unknown;
879
+ };
880
+ }[] | undefined;
881
+ children?: string[] | undefined;
882
+ stroke?: string | undefined;
883
+ fill?: string | undefined;
884
+ hidden?: boolean | undefined;
885
+ parent?: string | undefined;
886
+ name?: string | undefined;
887
+ id: string;
888
+ type: "path" | "group";
889
+ }[];
890
+ /** A scene's shots with their timing, as agents see them. */
891
+ declare function describeMotionShots(scene: MotionScene): {
892
+ commands: ({
893
+ start: number;
894
+ end: number;
895
+ type: "enter";
896
+ style?: MotionEnterStyle;
897
+ direction?: MotionDirection;
898
+ distance?: number;
899
+ targets: string[];
900
+ duration?: number;
901
+ delay?: number;
902
+ stagger?: number;
903
+ with?: "after" | "previous";
904
+ ease?: AnimationEasing;
905
+ note?: string;
906
+ index: number;
907
+ } | {
908
+ start: number;
909
+ end: number;
910
+ type: "exit";
911
+ style?: MotionExitStyle;
912
+ direction?: MotionDirection;
913
+ distance?: number;
914
+ targets: string[];
915
+ duration?: number;
916
+ delay?: number;
917
+ stagger?: number;
918
+ with?: "after" | "previous";
919
+ ease?: AnimationEasing;
920
+ note?: string;
921
+ index: number;
922
+ } | {
923
+ start: number;
924
+ end: number;
925
+ type: "draw";
926
+ to?: number;
927
+ from?: number;
928
+ targets: string[];
929
+ duration?: number;
930
+ delay?: number;
931
+ stagger?: number;
932
+ with?: "after" | "previous";
933
+ ease?: AnimationEasing;
934
+ note?: string;
935
+ index: number;
936
+ } | {
937
+ start: number;
938
+ end: number;
939
+ type: "move";
940
+ by?: {
941
+ x: number;
942
+ y: number;
943
+ };
944
+ to?: {
945
+ x: number;
946
+ y: number;
947
+ };
948
+ targets: string[];
949
+ duration?: number;
950
+ delay?: number;
951
+ stagger?: number;
952
+ with?: "after" | "previous";
953
+ ease?: AnimationEasing;
954
+ note?: string;
955
+ index: number;
956
+ } | {
957
+ start: number;
958
+ end: number;
959
+ type: "rotate";
960
+ by?: number;
961
+ to?: number;
962
+ targets: string[];
963
+ duration?: number;
964
+ delay?: number;
965
+ stagger?: number;
966
+ with?: "after" | "previous";
967
+ ease?: AnimationEasing;
968
+ note?: string;
969
+ index: number;
970
+ } | {
971
+ start: number;
972
+ end: number;
973
+ type: "scale";
974
+ to: number | {
975
+ x: number;
976
+ y: number;
977
+ };
978
+ targets: string[];
979
+ duration?: number;
980
+ delay?: number;
981
+ stagger?: number;
982
+ with?: "after" | "previous";
983
+ ease?: AnimationEasing;
984
+ note?: string;
985
+ index: number;
986
+ } | {
987
+ start: number;
988
+ end: number;
989
+ type: "fade";
990
+ to: number;
991
+ targets: string[];
992
+ duration?: number;
993
+ delay?: number;
994
+ stagger?: number;
995
+ with?: "after" | "previous";
996
+ ease?: AnimationEasing;
997
+ note?: string;
998
+ index: number;
999
+ } | {
1000
+ start: number;
1001
+ end: number;
1002
+ type: "style";
1003
+ fill?: string;
1004
+ stroke?: string;
1005
+ strokeWidth?: number;
1006
+ targets: string[];
1007
+ duration?: number;
1008
+ delay?: number;
1009
+ stagger?: number;
1010
+ with?: "after" | "previous";
1011
+ ease?: AnimationEasing;
1012
+ note?: string;
1013
+ index: number;
1014
+ } | {
1015
+ start: number;
1016
+ end: number;
1017
+ type: "morph";
1018
+ into: string;
1019
+ targets: string[];
1020
+ duration?: number;
1021
+ delay?: number;
1022
+ stagger?: number;
1023
+ with?: "after" | "previous";
1024
+ ease?: AnimationEasing;
1025
+ note?: string;
1026
+ index: number;
1027
+ } | {
1028
+ start: number;
1029
+ end: number;
1030
+ type: "follow";
1031
+ path: string;
1032
+ rotate?: boolean;
1033
+ from?: number;
1034
+ to?: number;
1035
+ targets: string[];
1036
+ duration?: number;
1037
+ delay?: number;
1038
+ stagger?: number;
1039
+ with?: "after" | "previous";
1040
+ ease?: AnimationEasing;
1041
+ note?: string;
1042
+ index: number;
1043
+ } | {
1044
+ start: number;
1045
+ end: number;
1046
+ type: "pulse";
1047
+ amount?: number;
1048
+ count?: number;
1049
+ targets: string[];
1050
+ duration?: number;
1051
+ delay?: number;
1052
+ stagger?: number;
1053
+ with?: "after" | "previous";
1054
+ ease?: AnimationEasing;
1055
+ note?: string;
1056
+ index: number;
1057
+ } | {
1058
+ start: number;
1059
+ end: number;
1060
+ type: "shake";
1061
+ amount?: number;
1062
+ count?: number;
1063
+ targets: string[];
1064
+ duration?: number;
1065
+ delay?: number;
1066
+ stagger?: number;
1067
+ with?: "after" | "previous";
1068
+ ease?: AnimationEasing;
1069
+ note?: string;
1070
+ index: number;
1071
+ } | {
1072
+ start: number;
1073
+ end: number;
1074
+ type: "effect";
1075
+ effect: string;
1076
+ param: string;
1077
+ to: number;
1078
+ targets: string[];
1079
+ duration?: number;
1080
+ delay?: number;
1081
+ stagger?: number;
1082
+ with?: "after" | "previous";
1083
+ ease?: AnimationEasing;
1084
+ note?: string;
1085
+ index: number;
1086
+ } | {
1087
+ start: number;
1088
+ end: number;
1089
+ type: "wait";
1090
+ duration: number;
1091
+ with?: "after" | "previous";
1092
+ note?: string;
1093
+ index: number;
1094
+ })[];
1095
+ hold?: number | undefined;
1096
+ camera?: MotionCamera | undefined;
1097
+ start: number;
1098
+ end: number;
1099
+ label?: string | undefined;
1100
+ id: string;
1101
+ }[];
1102
+ /**
1103
+ * Agent tools for an `AnimationEditorController`: read the scene (artwork elements, shots with
1104
+ * their timing, issues), render a frame, export to Flair, and change it a step at a time. Every
1105
+ * write is checked first (unknown ids with "did you mean", malformed commands), applies as one
1106
+ * undo step, and returns the resulting timing and any new issues. Write tools are hidden while
1107
+ * the animation is read-only.
1108
+ */
1109
+ declare function createAnimationEditorToolProvider(controller: AnimationEditorController, options?: AnimationEditorToolProviderOptions): AgentToolProvider;
1110
+
1111
+ /**
1112
+ * A short authoring guide for a model writing vector animations with the animation editor's
1113
+ * tools. Static, so it caches well as part of a system prompt.
1114
+ */
1115
+ declare const ANIMATION_EDITOR_AGENT_INSTRUCTIONS = "You animate vector artwork. A scene is artwork (vector paths and groups, each with an id) plus shots.\n\nHow it plays\n- Shots play in order. A shot optionally moves the camera, plays its commands, then holds (default 600 ms).\n- Commands in a shot play one after another; give \"with\": \"previous\" to start one together with the command before, \"delay\" to wait, \"stagger\" to offset several targets.\n- Timing comes from the content: each command has a default length (enter 600 ms, move 700 ms, draw follows the path length). Only set \"duration\" to change the pace.\n- Anything that enters later is hidden until it enters. Things that never enter are visible from the start.\n- Every frame is a pure function of time: the same scene always plays the same frames.\n\nCommands\n- enter (fade, pop, grow, slide, draw) and exit (fade, shrink, slide, undraw) bring things in and out.\n- draw draws strokes on to a fraction; move, rotate, scale and fade change the pose (about the centre); style blends solid colours and stroke width.\n- morph turns a shape into another node's shape (keep the target hidden); follow moves along a path node; pulse and shake draw the eye.\n- effect tweens a numeric parameter of a live path effect already on the node (twist angle, wiggle time, zig zag size).\n\nWorking method\n1. get_animation to learn the element ids (set_animation_artwork_svg first if there is no artwork: give every element you will animate an id).\n2. Plan a few shots, each one idea. Add them with insert_shots, or edit_animation to make several edits as one step (dry_run first when unsure).\n3. check_animation and fix every error and warning; render_animation_frame (shot + \"end\") to look at the result.\n4. To make a reusable Flair effect, set_animation_controls (colour controls stand for every use of their default colour) and export_flair_effect.\n\nKeep motion purposeful: one thing moving at a time reads best, ease-out for arrivals, ease-in for exits, and hold long enough to see each result.";
1116
+
1117
+ export { ANIMATION_EDITOR_AGENT_INSTRUCTIONS, AnimationEditorController, type AnimationEditorOptions, type AnimationEditorSelection, type AnimationEditorState, type AnimationEditorToolProviderOptions, FLAIR_EASES, type FlairEaseName, type FlairEffectDocument, type FlairEffectOptions, type FlairExportOptions, type FlairMotionExport, type FlairSvgAnimation, type FlairSvgMotion, type FlairVectorEffect, MOTION_CAMERA_MS, MOTION_COMMAND_SCHEMA, MOTION_COMMAND_TYPES, MOTION_DEFAULT_DURATIONS, MOTION_DEFAULT_HOLD, MOTION_DIRECTIONS, MOTION_DRAW_EFFECT_ID, MOTION_DRAW_MS_PER_UNIT, MOTION_DRAW_RANGE, MOTION_EASE_IN_OUT, MOTION_EASE_OUT, MOTION_EDIT_OPS, MOTION_ENTER_STYLES, MOTION_EXIT_STYLES, MOTION_ISSUE_CODES, MOTION_MIN_CHANGE_MS, type MotionCamera, type MotionCommand, type MotionCommandBase, type MotionCommandTiming, type MotionCommandType, type MotionControl, type MotionDirection, type MotionDrawCommand, type MotionEdit, type MotionEditOp, type MotionEditResult, type MotionEffectCommand, type MotionEnterCommand, type MotionEnterStyle, type MotionExitCommand, type MotionExitStyle, type MotionFadeCommand, type MotionFollowCommand, type MotionFrame, type MotionFrameOptions, type MotionIssue, type MotionIssueCode, type MotionIssueSeverity, type MotionMorphCommand, type MotionMoveCommand, type MotionNodeEntry, type MotionPreset, type MotionProperty, type MotionPulseCommand, type MotionRect, type MotionRotateCommand, type MotionScaleCommand, type MotionScene, MotionSceneFormatError, type MotionSegment, type MotionShakeCommand, type MotionShot, type MotionShotTiming, type MotionStyleCommand, type MotionSvgOptions, type MotionTimeline, type MotionValue, type MotionWaitCommand, type MotionWave, activeSegment, applyMotionControlValues, applyMotionEdits, checkMotionScene, commandShapeProblems, compileMotionScene, createAnimationEditorToolProvider, createMotionScene, describeMotionElements, describeMotionShots, fitMotionRect, flairEaseFor, freshShotId, indexMotionNodes, interpolateMotionValue, isMotionCommand, isMotionShot, motionCommandDuration, motionFrameAt, motionFrameToSvg, motionIssue, motionIssueKey, motionIssueLine, motionNodeOffset, motionPathLength, motionRestValue, motionSceneShapeProblems, motionSceneToJson, motionShotAt, motionTrackKey, namedWithSuggestion, parseMotionScene, resolveMotionCamera, segmentProgress, segmentValue, shotShapeProblems, suggestName, toFlairEffectDocument, toFlairSvgMotion, toFlairVectorEffect, trackValue, withViewBox };