@pixerate/editor 0.223.8 → 0.224.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 (41) hide show
  1. package/dist/animation-editor/index.cjs +9 -9
  2. package/dist/animation-editor/index.js +1 -1
  3. package/dist/canvas/index.cjs +7 -7
  4. package/dist/canvas/index.js +1 -1
  5. package/dist/{chunk-6DUEV36F.cjs → chunk-7AAS3JO6.cjs} +14 -14
  6. package/dist/{chunk-6G2NLMVK.js → chunk-HKPLKISO.js} +58 -9
  7. package/dist/{chunk-Z64NRDEH.cjs → chunk-MDNYYOBZ.cjs} +7 -7
  8. package/dist/{chunk-A3A5TI6R.cjs → chunk-NTWR5TQB.cjs} +59 -10
  9. package/dist/{chunk-OZSA5YEJ.js → chunk-RDTCG5MS.js} +1 -1
  10. package/dist/{chunk-WMVEYSOA.js → chunk-WA4IS2EY.js} +1 -1
  11. package/dist/effects/fake.d.cts +6 -1
  12. package/dist/effects/fake.d.ts +6 -1
  13. package/dist/effects/helpers.d.cts +24 -1
  14. package/dist/effects/helpers.d.ts +24 -1
  15. package/dist/effects/index.cjs +257 -62
  16. package/dist/effects/index.js +202 -7
  17. package/dist/effects/types.d.cts +121 -4
  18. package/dist/effects/types.d.ts +121 -4
  19. package/dist/image-editor/index.cjs +13 -13
  20. package/dist/image-editor/index.js +1 -1
  21. package/dist/paint-editor/index.cjs +7 -7
  22. package/dist/paint-editor/index.js +2 -2
  23. package/dist/tools/skill-evals.d.cts +8 -1
  24. package/dist/tools/skill-evals.d.ts +8 -1
  25. package/dist/vector/index.cjs +6 -6
  26. package/dist/vector/index.js +1 -1
  27. package/dist/video-editor/index.cjs +309 -309
  28. package/dist/video-editor/index.js +3 -3
  29. package/package.json +1 -1
  30. package/skills/README.md +4 -1
  31. package/skills/pixerate-animation-editor/SKILL.md +1 -1
  32. package/skills/pixerate-canvas/SKILL.md +8 -0
  33. package/skills/pixerate-canvas-design-system-components/SKILL.md +103 -0
  34. package/skills/pixerate-canvas-design-system-components/evals/add-variant.json +172 -0
  35. package/skills/pixerate-canvas-design-system-components/evals/combine-variants.json +172 -0
  36. package/skills/pixerate-canvas-design-system-components/evals/make-component.json +103 -0
  37. package/skills/pixerate-canvas-layout/SKILL.md +95 -0
  38. package/skills/pixerate-canvas-layout/evals/align-tops.json +98 -0
  39. package/skills/pixerate-canvas-layout/evals/distribute-evenly.json +98 -0
  40. package/skills/pixerate-canvas-layout/evals/order-and-lock.json +110 -0
  41. package/skills/pixerate-video-editor/SKILL.md +1 -1
@@ -3,7 +3,7 @@
3
3
  var _chunk4XSBOGMKcjs = require('../chunk-4XSBOGMK.cjs');
4
4
 
5
5
 
6
- var _chunk6DUEV36Fcjs = require('../chunk-6DUEV36F.cjs');
6
+ var _chunk7AAS3JO6cjs = require('../chunk-7AAS3JO6.cjs');
7
7
 
8
8
 
9
9
  var _chunkPY4GWSE2cjs = require('../chunk-PY4GWSE2.cjs');
@@ -32,7 +32,12 @@ var _chunkPY4GWSE2cjs = require('../chunk-PY4GWSE2.cjs');
32
32
 
33
33
 
34
34
 
35
- var _chunkA3A5TI6Rcjs = require('../chunk-A3A5TI6R.cjs');
35
+
36
+
37
+
38
+
39
+
40
+ var _chunkNTWR5TQBcjs = require('../chunk-NTWR5TQB.cjs');
36
41
  require('../chunk-WOFXZ3XU.cjs');
37
42
  require('../chunk-FJ2MSI43.cjs');
38
43
 
@@ -40,7 +45,7 @@ require('../chunk-FJ2MSI43.cjs');
40
45
  var _chunkDWJJI6RTcjs = require('../chunk-DWJJI6RT.cjs');
41
46
 
42
47
  // src/effects/conformance.ts
43
- var codeOf = (e) => _chunkA3A5TI6Rcjs.isEffectError.call(void 0, e) ? e.code : e instanceof Error ? `untyped ${e.name}: ${e.message}` : String(e);
48
+ var codeOf = (e) => _chunkNTWR5TQBcjs.isEffectError.call(void 0, e) ? e.code : e instanceof Error ? `untyped ${e.name}: ${e.message}` : String(e);
44
49
  async function rejectsWith(code, run) {
45
50
  try {
46
51
  await run();
@@ -54,33 +59,47 @@ function checkSummary(e, issues) {
54
59
  const at = (message) => issues.push({ effectId: e.id, message });
55
60
  if (!e.id || typeof e.id !== "string") at("summary has no id");
56
61
  if (!e.name) at("summary has no name");
57
- if (!_chunkA3A5TI6Rcjs.EFFECT_KINDS.includes(e.kind)) at(`kind "${e.kind}" is not one of ${_chunkA3A5TI6Rcjs.EFFECT_KINDS.join(", ")}`);
62
+ if (!_chunkNTWR5TQBcjs.EFFECT_KINDS.includes(e.kind)) at(`kind "${e.kind}" is not one of ${_chunkNTWR5TQBcjs.EFFECT_KINDS.join(", ")}`);
58
63
  if (!e.category) at("summary has no category");
59
64
  if (!Array.isArray(e.uses) || !e.uses.length) at("summary has no uses");
60
- for (const u of _nullishCoalesce(e.uses, () => ( []))) if (!_chunkA3A5TI6Rcjs.EFFECT_USES.includes(u)) at(`use "${u}" is not one of ${_chunkA3A5TI6Rcjs.EFFECT_USES.join(", ")}`);
65
+ for (const u of _nullishCoalesce(e.uses, () => ( []))) if (!_chunkNTWR5TQBcjs.EFFECT_USES.includes(u)) at(`use "${u}" is not one of ${_chunkNTWR5TQBcjs.EFFECT_USES.join(", ")}`);
61
66
  if (typeof e.transparent !== "boolean") at("transparent is not a boolean");
62
67
  if (typeof e.loop !== "boolean") at("loop is not a boolean");
63
68
  if (e.duration !== void 0 && !(e.duration > 0)) at("duration must be a positive number of ms when present");
64
69
  if (e.backgroundOpacity !== void 0 && (typeof e.backgroundOpacity !== "string" || !e.backgroundOpacity)) at("backgroundOpacity must name a control when present");
70
+ if (e.kind === "camera") {
71
+ if (_optionalChain([e, 'access', _ => _.uses, 'optionalAccess', _2 => _2.length]) !== 1 || e.uses[0] !== "camera") at('a camera effect must have exactly the use "camera"');
72
+ const m = e.camera;
73
+ if (!m) at("a camera effect needs camera: { role, durationMs }");
74
+ else {
75
+ if (!_chunkNTWR5TQBcjs.CAMERA_MOVE_ROLES.includes(m.role)) at(`camera.role "${m.role}" is not one of ${_chunkNTWR5TQBcjs.CAMERA_MOVE_ROLES.join(", ")}`);
76
+ if (!(Number.isFinite(m.durationMs) && m.durationMs >= 0)) at("camera.durationMs must be a number of ms \u2265 0");
77
+ if (m.cut !== void 0 && !(m.cut >= 0 && m.cut <= 1)) at("camera.cut must be 0\u20131 when present");
78
+ if (e.duration !== void 0 && e.duration !== m.durationMs) at(`duration ${e.duration} differs from camera.durationMs ${m.durationMs}`);
79
+ }
80
+ } else {
81
+ if (_optionalChain([e, 'access', _3 => _3.uses, 'optionalAccess', _4 => _4.includes, 'call', _5 => _5("camera")])) at('only camera effects may have the use "camera"');
82
+ if (e.camera !== void 0) at("only camera effects may have camera");
83
+ }
65
84
  }
66
85
  function checkDescription(id, d, issues) {
67
86
  const at = (message) => issues.push({ effectId: id, message });
68
87
  if (d.id !== id) at(`describe("${id}") returned id "${d.id}"`);
69
88
  const c = d.controls;
70
89
  if (!c || c.type !== "object") at("controls is not an object schema");
71
- if (_optionalChain([c, 'optionalAccess', _ => _.additionalProperties]) !== false) at("controls must set additionalProperties: false");
72
- for (const [name, schema] of Object.entries(_nullishCoalesce(_optionalChain([c, 'optionalAccess', _2 => _2.properties]), () => ( {})))) {
90
+ if (_optionalChain([c, 'optionalAccess', _6 => _6.additionalProperties]) !== false) at("controls must set additionalProperties: false");
91
+ for (const [name, schema] of Object.entries(_nullishCoalesce(_optionalChain([c, 'optionalAccess', _7 => _7.properties]), () => ( {})))) {
73
92
  if (!schema.description || !String(schema.description).trim()) at(`control "${name}" has no description`);
74
93
  if (!(name in (_nullishCoalesce(d.defaults, () => ( {}))))) at(`control "${name}" has no default`);
75
94
  }
76
- for (const name of Object.keys(_nullishCoalesce(d.defaults, () => ( {})))) if (!(name in (_nullishCoalesce(_optionalChain([c, 'optionalAccess', _3 => _3.properties]), () => ( {}))))) at(`default "${name}" is not a control`);
95
+ for (const name of Object.keys(_nullishCoalesce(d.defaults, () => ( {})))) if (!(name in (_nullishCoalesce(_optionalChain([c, 'optionalAccess', _8 => _8.properties]), () => ( {}))))) at(`default "${name}" is not a control`);
77
96
  if (d.backgroundOpacity !== void 0) {
78
- const control = _optionalChain([c, 'optionalAccess', _4 => _4.properties, 'optionalAccess', _5 => _5[d.backgroundOpacity]]);
97
+ const control = _optionalChain([c, 'optionalAccess', _9 => _9.properties, 'optionalAccess', _10 => _10[d.backgroundOpacity]]);
79
98
  if (!control) at(`backgroundOpacity "${d.backgroundOpacity}" is not a control`);
80
99
  else if (control.type !== "number" || control.minimum !== 0 || control.maximum !== 1) at(`backgroundOpacity "${d.backgroundOpacity}" must be a number control from 0 to 1`);
81
100
  }
82
- for (const e of _chunkA3A5TI6Rcjs.effectValueErrors.call(void 0, d, d.defaults)) at(`default ${e.path}: ${e.message}`);
83
- for (const p of _nullishCoalesce(d.presets, () => ( []))) for (const e of _chunkA3A5TI6Rcjs.effectValueErrors.call(void 0, d, p.values)) at(`preset "${p.name}" ${e.path}: ${e.message}`);
101
+ for (const e of _chunkNTWR5TQBcjs.effectValueErrors.call(void 0, d, d.defaults)) at(`default ${e.path}: ${e.message}`);
102
+ for (const p of _nullishCoalesce(d.presets, () => ( []))) for (const e of _chunkNTWR5TQBcjs.effectValueErrors.call(void 0, d, p.values)) at(`preset "${p.name}" ${e.path}: ${e.message}`);
84
103
  for (const input2 of _nullishCoalesce(d.inputs, () => ( []))) {
85
104
  if (!input2.name || !input2.description) at("every input needs a name and a description");
86
105
  if (input2.kind !== "image" && input2.kind !== "audio") at(`input "${input2.name}" has kind "${input2.kind}"`);
@@ -91,7 +110,7 @@ function checkDescription(id, d, issues) {
91
110
  }
92
111
  }
93
112
  function grey(size) {
94
- const p = _chunkA3A5TI6Rcjs.createEffectPixels.call(void 0, size, size);
113
+ const p = _chunkNTWR5TQBcjs.createEffectPixels.call(void 0, size, size);
95
114
  p.data.fill(128);
96
115
  return p;
97
116
  }
@@ -102,12 +121,13 @@ async function checkRender(provider, d, size, issues) {
102
121
  try {
103
122
  renderer = await provider.createRenderer(d.id, { width: size, height: size });
104
123
  } catch (e) {
105
- if (!(d.kind === "vector" && codeOf(e) === "unsupported")) at(`createRenderer failed: ${codeOf(e)}`);
124
+ if (!((d.kind === "vector" || d.kind === "camera") && codeOf(e) === "unsupported")) at(`createRenderer failed: ${codeOf(e)}`);
125
+ else if (!(e instanceof Error && e.message.trim())) at("createRenderer refused without saying why");
106
126
  return;
107
127
  }
108
128
  try {
109
129
  const out = await renderer.render({ time: 0, inputs });
110
- if (!_chunkA3A5TI6Rcjs.isEffectPixels.call(void 0, out)) at("render did not return EffectPixels");
130
+ if (!_chunkNTWR5TQBcjs.isEffectPixels.call(void 0, out)) at("render did not return EffectPixels");
111
131
  else if (out.width !== size || out.height !== size || out.data.length !== size * size * 4) at(`render returned ${out.width}\xD7${out.height}, not ${size}\xD7${size}`);
112
132
  } catch (e) {
113
133
  at(`render failed: ${codeOf(e)}`);
@@ -118,17 +138,65 @@ async function checkRender(provider, d, size, issues) {
118
138
  const after = await rejectsWith("disposed", () => renderer.render({ time: 0, inputs }));
119
139
  if (after) at(`render after dispose ${after}`);
120
140
  }
141
+ var sameView = (a, b) => JSON.stringify(a) === JSON.stringify(b);
142
+ var near = (a, b) => ["zoom", "scrollX", "scrollY", "tilt", "turn", "roll", "perspective", "blur", "blurAngle"].every((k) => Math.abs((_nullishCoalesce(a[k], () => ( 0))) - (_nullishCoalesce(b[k], () => ( 0)))) <= 1e-6 * Math.max(1, Math.abs(_nullishCoalesce(a[k], () => ( 0)))));
143
+ var STAGE = { width: 320, height: 180 };
144
+ var WIDE = { zoom: 1, scrollX: 0, scrollY: 0 };
145
+ var CLOSE = { zoom: 2, scrollX: 0, scrollY: 0 };
146
+ async function checkCamera(provider, d, issues) {
147
+ const at = (message) => issues.push({ effectId: d.id, message });
148
+ const camera = d.camera;
149
+ const to = camera.role === "hold" ? WIDE : CLOSE;
150
+ const ms = camera.durationMs || 1e3;
151
+ const ctx = (u) => ({ from: WIDE, to, u, ms, stage: STAGE });
152
+ const views = [];
153
+ for (const u of [0, 0.25, 0.5, 0.75, 1]) {
154
+ try {
155
+ const view = provider.cameraView(d.id, ctx(u));
156
+ if (view instanceof Promise) {
157
+ at("cameraView must be synchronous; it returned a Promise");
158
+ return;
159
+ }
160
+ if (!_chunkNTWR5TQBcjs.isCameraView.call(void 0, view)) at(`cameraView at u ${u} is not a CameraView (zoom > 0, finite scrollX and scrollY): ${JSON.stringify(view)}`);
161
+ else views.push(view);
162
+ const again = provider.cameraView(d.id, ctx(u));
163
+ if (_chunkNTWR5TQBcjs.isCameraView.call(void 0, view) && !sameView(view, again)) at(`cameraView is not pure: two calls at u ${u} gave different views`);
164
+ } catch (e) {
165
+ at(`cameraView at u ${u} failed: ${codeOf(e)}`);
166
+ }
167
+ }
168
+ const bad = await rejectsWith("invalid_values", () => provider.cameraView(d.id, ctx(0.5), { __not_a_control__: 1 }));
169
+ if (bad) at(`cameraView with an unknown control ${bad}`);
170
+ if (provider.sampleCameraMove && views.length === 5) {
171
+ try {
172
+ const sample = await provider.sampleCameraMove(d.id, { from: WIDE, to, ms, stage: STAGE, fps: 10 });
173
+ const keys = _optionalChain([sample, 'optionalAccess', _11 => _11.keys]);
174
+ if (!Array.isArray(keys) || keys.length < 2) at("sampleCameraMove returned fewer than two keys");
175
+ else {
176
+ if (keys.some((k, i) => !_chunkNTWR5TQBcjs.isCameraView.call(void 0, k.view) || !Number.isFinite(k.t) || i > 0 && k.t < keys[i - 1].t)) at("sampleCameraMove keys must be CameraViews in time order");
177
+ if (keys[0].t !== 0 || keys[keys.length - 1].t !== ms) at(`sampleCameraMove keys must run from 0 to ${ms} ms, got ${keys[0].t} to ${keys[keys.length - 1].t}`);
178
+ else if (!near(keys[0].view, views[0]) || !near(keys[keys.length - 1].view, views[4])) at("sampleCameraMove disagrees with cameraView at the start or end of the move");
179
+ if (camera.cut !== void 0 && sample.cut === void 0) at("sampleCameraMove gave no cut for a move that cuts");
180
+ }
181
+ } catch (e) {
182
+ at(`sampleCameraMove failed: ${codeOf(e)}`);
183
+ }
184
+ }
185
+ }
121
186
  async function checkEffectProvider(provider, options = {}) {
122
187
  const issues = [];
123
188
  const top = (message) => issues.push({ message });
124
189
  if (!provider.id) top("provider has no id");
125
190
  const caps = provider.capabilities;
126
191
  for (const k of ["supportsWorker", "supportsFloat", "supportsMask", "supportsHostImages", "supportsVector"]) {
127
- if (typeof _optionalChain([caps, 'optionalAccess', _6 => _6[k]]) !== "boolean") top(`capabilities.${k} is not a boolean`);
192
+ if (typeof _optionalChain([caps, 'optionalAccess', _12 => _12[k]]) !== "boolean") top(`capabilities.${k} is not a boolean`);
128
193
  }
129
- if (_optionalChain([caps, 'optionalAccess', _7 => _7.supportsAuthoring]) !== void 0 && typeof caps.supportsAuthoring !== "boolean") top("capabilities.supportsAuthoring is not a boolean");
130
- if (_optionalChain([caps, 'optionalAccess', _8 => _8.supportsVector]) && typeof provider.applyVectorEffect !== "function") top("supportsVector is set but applyVectorEffect is missing");
131
- if (_optionalChain([caps, 'optionalAccess', _9 => _9.supportsAuthoring]) && typeof provider.openAuthoring !== "function") top("supportsAuthoring is set but openAuthoring is missing");
194
+ if (_optionalChain([caps, 'optionalAccess', _13 => _13.supportsAuthoring]) !== void 0 && typeof caps.supportsAuthoring !== "boolean") top("capabilities.supportsAuthoring is not a boolean");
195
+ if (_optionalChain([caps, 'optionalAccess', _14 => _14.supportsVector]) && typeof provider.applyVectorEffect !== "function") top("supportsVector is set but applyVectorEffect is missing");
196
+ if (_optionalChain([caps, 'optionalAccess', _15 => _15.supportsAuthoring]) && typeof provider.openAuthoring !== "function") top("supportsAuthoring is set but openAuthoring is missing");
197
+ if (_optionalChain([caps, 'optionalAccess', _16 => _16.supportsCamera]) !== void 0 && typeof caps.supportsCamera !== "boolean") top("capabilities.supportsCamera is not a boolean");
198
+ if (_optionalChain([caps, 'optionalAccess', _17 => _17.supportsCamera]) && typeof provider.cameraView !== "function") top("supportsCamera is set but cameraView is missing");
199
+ if (provider.sampleCameraMove && typeof provider.cameraView !== "function") top("sampleCameraMove is present but cameraView is missing");
132
200
  const list = await provider.list();
133
201
  const ids = /* @__PURE__ */ new Set();
134
202
  for (const e of list) {
@@ -136,9 +204,10 @@ async function checkEffectProvider(provider, options = {}) {
136
204
  ids.add(e.id);
137
205
  checkSummary(e, issues);
138
206
  }
207
+ if (!_optionalChain([caps, 'optionalAccess', _18 => _18.supportsCamera]) && list.some((e) => e.kind === "camera")) top("the catalog lists camera effects but capabilities.supportsCamera is not set");
139
208
  const all = await provider.search("");
140
209
  if (all.length !== list.length) top(`search("") returned ${all.length} effects, list() ${list.length}`);
141
- const firstUse = _optionalChain([list, 'access', _10 => _10[0], 'optionalAccess', _11 => _11.uses, 'access', _12 => _12[0]]);
210
+ const firstUse = _optionalChain([list, 'access', _19 => _19[0], 'optionalAccess', _20 => _20.uses, 'access', _21 => _21[0]]);
142
211
  if (firstUse) {
143
212
  const filtered = await provider.search("", { use: firstUse });
144
213
  if (filtered.some((e) => !e.uses.includes(firstUse))) top(`search("", { use: "${firstUse}" }) returned effects without that use`);
@@ -147,6 +216,14 @@ async function checkEffectProvider(provider, options = {}) {
147
216
  if (unknown) top(`describe of an unknown id ${unknown}`);
148
217
  const unknownRenderer = await rejectsWith("unknown_effect", () => provider.createRenderer("__no_such_effect__", { width: 4, height: 4 }));
149
218
  if (unknownRenderer) top(`createRenderer of an unknown id ${unknownRenderer}`);
219
+ if (_optionalChain([caps, 'optionalAccess', _22 => _22.supportsCamera]) && provider.cameraView) {
220
+ const probe = { from: WIDE, to: CLOSE, u: 0.5, ms: 1e3, stage: STAGE };
221
+ const unknownCamera = await rejectsWith("unknown_effect", () => provider.cameraView("__no_such_effect__", probe));
222
+ if (unknownCamera) top(`cameraView of an unknown id ${unknownCamera}`);
223
+ const notCamera = list.find((e) => e.kind !== "camera");
224
+ const wrongKind = notCamera && await rejectsWith("unsupported", () => provider.cameraView(notCamera.id, probe));
225
+ if (wrongKind) issues.push({ effectId: notCamera.id, message: `cameraView of a ${notCamera.kind} effect ${wrongKind}` });
226
+ }
150
227
  const size = _nullishCoalesce(options.size, () => ( 8));
151
228
  for (const id of _nullishCoalesce(options.ids, () => ( [...ids]))) {
152
229
  let d;
@@ -158,6 +235,7 @@ async function checkEffectProvider(provider, options = {}) {
158
235
  }
159
236
  checkDescription(id, d, issues);
160
237
  if (options.render !== false && d.kind !== "motion") await checkRender(provider, d, size, issues);
238
+ if (d.kind === "camera" && d.camera && caps.supportsCamera && provider.cameraView) await checkCamera(provider, d, issues);
161
239
  if ((d.kind === "vector" || d.kind === "motion") && caps.supportsVector && provider.applyVectorEffect) {
162
240
  try {
163
241
  const m = await provider.applyVectorEffect(id, '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><rect id="r" width="10" height="10"/></svg>');
@@ -170,9 +248,9 @@ async function checkEffectProvider(provider, options = {}) {
170
248
  if (bad) issues.push({ effectId: id, message: `applyVectorEffect with an unknown control ${bad}` });
171
249
  }
172
250
  }
173
- if (_optionalChain([caps, 'optionalAccess', _13 => _13.supportsAuthoring]) && options.authoring !== false && typeof provider.openAuthoring === "function") {
251
+ if (_optionalChain([caps, 'optionalAccess', _23 => _23.supportsAuthoring]) && options.authoring !== false && typeof provider.openAuthoring === "function") {
174
252
  const targetEffect = (await Promise.all((_nullishCoalesce(options.ids, () => ( [...ids]))).map((id) => provider.describe(id)))).find(
175
- (d) => d.kind !== "motion" && d.kind !== "vector"
253
+ (d) => d.kind !== "motion" && d.kind !== "vector" && d.kind !== "camera"
176
254
  );
177
255
  if (targetEffect) {
178
256
  try {
@@ -394,21 +472,86 @@ var DESCRIPTIONS = [
394
472
  inputs: []
395
473
  }
396
474
  ];
475
+ var CAMERA_DESCRIPTIONS = [
476
+ {
477
+ id: "fake.glide",
478
+ name: "Glide",
479
+ kind: "camera",
480
+ category: "camera",
481
+ uses: ["camera"],
482
+ description: "Moves the camera smoothly from one framing to the next.",
483
+ tags: ["move", "smooth"],
484
+ transparent: false,
485
+ loop: false,
486
+ duration: 800,
487
+ camera: { role: "transition", durationMs: 800 },
488
+ controls: {
489
+ type: "object",
490
+ additionalProperties: false,
491
+ properties: { curve: { type: "string", enum: ["linear", "smooth"], description: "Speed curve: linear, or smooth (ease in and out). Default smooth." } }
492
+ },
493
+ defaults: { curve: "smooth" },
494
+ presets: [],
495
+ inputs: []
496
+ },
497
+ {
498
+ id: "fake.whip",
499
+ name: "Whip pan",
500
+ kind: "camera",
501
+ category: "camera",
502
+ uses: ["camera"],
503
+ description: "Whips the camera away from one framing, cuts halfway in a blur, and lands on the next.",
504
+ tags: ["move", "fast", "cut"],
505
+ transparent: false,
506
+ loop: false,
507
+ duration: 400,
508
+ camera: { role: "transition", durationMs: 400, cut: 0.5 },
509
+ controls: {
510
+ type: "object",
511
+ additionalProperties: false,
512
+ properties: { blur: { type: "number", minimum: 0, maximum: 100, description: "Motion blur at the cut, in stage pixels. Default 40." } }
513
+ },
514
+ defaults: { blur: 40 },
515
+ presets: [{ name: "Clean", values: { blur: 0 } }],
516
+ inputs: []
517
+ },
518
+ {
519
+ id: "fake.drift",
520
+ name: "Drift",
521
+ kind: "camera",
522
+ category: "camera",
523
+ uses: ["camera"],
524
+ description: "Zooms slowly into the middle of the framing while the shot holds.",
525
+ tags: ["ken burns", "slow"],
526
+ transparent: false,
527
+ loop: false,
528
+ duration: 4e3,
529
+ camera: { role: "hold", durationMs: 4e3 },
530
+ controls: {
531
+ type: "object",
532
+ additionalProperties: false,
533
+ properties: { scale: { type: "number", minimum: 1, maximum: 2, description: "Zoom at the end of the hold, as a multiple of the framing's zoom. Default 1.15." } }
534
+ },
535
+ defaults: { scale: 1.15 },
536
+ presets: [],
537
+ inputs: []
538
+ }
539
+ ];
397
540
  var summaryOf = ({ controls: _c, defaults: _d, presets: _p, inputs: _i, ...summary }) => summary;
398
541
  var hexToRgb = (hex) => [1, 3, 5].map((i) => parseInt(hex.slice(i, i + 2), 16));
399
542
  var smooth = (t) => t * t * (3 - 2 * t);
400
543
  var clamp01 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
401
544
  function input(request, name, id, width, height) {
402
- const src = _optionalChain([request, 'access', _14 => _14.inputs, 'optionalAccess', _15 => _15[name]]);
403
- if (!src) throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`Effect "${id}" needs an input named "${name}".`, id);
404
- if (!_chunkA3A5TI6Rcjs.isEffectPixels.call(void 0, src)) throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`The fake provider only takes EffectPixels inputs ("${name}").`, id);
545
+ const src = _optionalChain([request, 'access', _24 => _24.inputs, 'optionalAccess', _25 => _25[name]]);
546
+ if (!src) throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`Effect "${id}" needs an input named "${name}".`, id);
547
+ if (!_chunkNTWR5TQBcjs.isEffectPixels.call(void 0, src)) throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`The fake provider only takes EffectPixels inputs ("${name}").`, id);
405
548
  if (src.width !== width || src.height !== height) {
406
- throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`Input "${name}" is ${src.width}\xD7${src.height}; the renderer is ${width}\xD7${height}.`, id);
549
+ throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`Input "${name}" is ${src.width}\xD7${src.height}; the renderer is ${width}\xD7${height}.`, id);
407
550
  }
408
551
  return src;
409
552
  }
410
553
  function renderPixels(d, v, request, width, height) {
411
- const out = _chunkA3A5TI6Rcjs.createEffectPixels.call(void 0, width, height);
554
+ const out = _chunkNTWR5TQBcjs.createEffectPixels.call(void 0, width, height);
412
555
  const o = out.data;
413
556
  switch (d.id) {
414
557
  case "fake.invert": {
@@ -474,23 +617,52 @@ function renderPixels(d, v, request, width, height) {
474
617
  break;
475
618
  }
476
619
  default:
477
- throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`"${d.id}" is a ${d.kind} effect; use applyVectorEffect.`, d.id);
620
+ throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`"${d.id}" is a ${d.kind} effect; use applyVectorEffect.`, d.id);
478
621
  }
479
622
  return out;
480
623
  }
624
+ var lerp = (a, b, t) => a + (b - a) * t;
625
+ var viewAt = (cx, cy, zoom, ctx) => ({ zoom, scrollX: ctx.stage.width / (2 * zoom) - cx, scrollY: ctx.stage.height / (2 * zoom) - cy });
626
+ var centreOf = (v, ctx) => [ctx.stage.width / (2 * v.zoom) - v.scrollX, ctx.stage.height / (2 * v.zoom) - v.scrollY];
627
+ function cameraViewOf(d, ctx, v) {
628
+ const { from, to, u } = ctx;
629
+ const [x0, y0] = centreOf(from, ctx);
630
+ const [x1, y1] = centreOf(to, ctx);
631
+ switch (d.id) {
632
+ case "fake.glide": {
633
+ const k = v.curve === "smooth" ? smooth(u) : u;
634
+ return viewAt(lerp(x0, x1, k), lerp(y0, y1, k), lerp(from.zoom, to.zoom, k), ctx);
635
+ }
636
+ case "fake.whip": {
637
+ const out = u < 0.5;
638
+ const at = out ? from : to;
639
+ const off = out ? Math.pow(u * 2, 3) : 1 - (1 - Math.pow(1 - (u - 0.5) * 2, 3));
640
+ const dist = Math.hypot(x1 - x0, y1 - y0);
641
+ const [dx, dy] = dist > 1e-6 ? [(x1 - x0) / dist, (y1 - y0) / dist] : [1, 0];
642
+ const reach = ctx.stage.width / at.zoom * off * (out ? 1 : -1);
643
+ const [cx, cy] = centreOf(at, ctx);
644
+ const blur = v.blur * off;
645
+ return { ...viewAt(cx + dx * reach, cy + dy * reach, at.zoom, ctx), ...blur > 0 ? { blur, blurAngle: Math.atan2(dy, dx) * 180 / Math.PI } : {} };
646
+ }
647
+ case "fake.drift":
648
+ return viewAt(x0, y0, from.zoom * lerp(1, v.scale, smooth(u)), ctx);
649
+ default:
650
+ throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`"${d.id}" is a ${d.kind} effect, not a camera move.`, d.id);
651
+ }
652
+ }
481
653
  function toFloat(p) {
482
654
  const f = new Float32Array(p.data.length);
483
655
  for (let i = 0; i < f.length; i += 4) {
484
- f[i] = _chunkA3A5TI6Rcjs.srgbToLinear.call(void 0, p.data[i] / 255);
485
- f[i + 1] = _chunkA3A5TI6Rcjs.srgbToLinear.call(void 0, p.data[i + 1] / 255);
486
- f[i + 2] = _chunkA3A5TI6Rcjs.srgbToLinear.call(void 0, p.data[i + 2] / 255);
656
+ f[i] = _chunkNTWR5TQBcjs.srgbToLinear.call(void 0, p.data[i] / 255);
657
+ f[i + 1] = _chunkNTWR5TQBcjs.srgbToLinear.call(void 0, p.data[i + 1] / 255);
658
+ f[i + 2] = _chunkNTWR5TQBcjs.srgbToLinear.call(void 0, p.data[i + 2] / 255);
487
659
  f[i + 3] = p.data[i + 3] / 255;
488
660
  }
489
- return _chunkA3A5TI6Rcjs.encodeEffectFloat.call(void 0, { ...p, float: f });
661
+ return _chunkNTWR5TQBcjs.encodeEffectFloat.call(void 0, { ...p, float: f });
490
662
  }
491
663
  function maskResult(out, mask, source, id) {
492
- if (!_chunkA3A5TI6Rcjs.isEffectPixels.call(void 0, mask) || mask.width !== out.width || mask.height !== out.height) {
493
- throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)("The mask must be EffectPixels the size of the renderer.", id);
664
+ if (!_chunkNTWR5TQBcjs.isEffectPixels.call(void 0, mask) || mask.width !== out.width || mask.height !== out.height) {
665
+ throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)("The mask must be EffectPixels the size of the renderer.", id);
494
666
  }
495
667
  const o = out.data;
496
668
  for (let i = 0; i < o.length; i += 4) {
@@ -508,31 +680,40 @@ function createFakeEffectProvider(options = {}) {
508
680
  supportsHostImages: false,
509
681
  supportsVector: true,
510
682
  supportsAuthoring,
683
+ ...options.camera ? { supportsCamera: true } : {},
511
684
  maxSize: 8192,
512
685
  ...options.capabilities
513
686
  };
514
- const byId = new Map(DESCRIPTIONS.map((d) => [d.id, d]));
687
+ const all = options.camera ? [...DESCRIPTIONS, ...CAMERA_DESCRIPTIONS] : DESCRIPTIONS;
688
+ const byId = new Map(all.map((d) => [d.id, d]));
515
689
  const get = (id) => {
516
690
  const d = byId.get(id);
517
- if (!d) throw new (0, _chunkA3A5TI6Rcjs.UnknownEffectError)(id, "the fake provider");
691
+ if (!d) throw new (0, _chunkNTWR5TQBcjs.UnknownEffectError)(id, "the fake provider");
518
692
  return d;
519
693
  };
520
- const summaries = DESCRIPTIONS.map(summaryOf);
694
+ const summaries = all.map(summaryOf);
695
+ const camera = (id, ctx, values) => {
696
+ const d = get(id);
697
+ if (d.kind !== "camera") throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`"${id}" is a ${d.kind} effect, not a camera move.`, id);
698
+ if (!(ctx.u >= 0 && ctx.u <= 1)) throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`u must be 0\u20131 through the move, got ${ctx.u}.`, id);
699
+ return cameraViewOf(d, ctx, _chunkNTWR5TQBcjs.resolveEffectValues.call(void 0, d, values));
700
+ };
521
701
  const provider = {
522
702
  id: "fake",
523
703
  name: "Fake effects",
524
704
  version: "1",
525
705
  capabilities,
526
- list: (o) => _chunkA3A5TI6Rcjs.searchEffectSummaries.call(void 0, summaries, "", o),
527
- search: (q, o) => _chunkA3A5TI6Rcjs.searchEffectSummaries.call(void 0, summaries, q, o),
706
+ list: (o) => _chunkNTWR5TQBcjs.searchEffectSummaries.call(void 0, summaries, "", o),
707
+ search: (q, o) => _chunkNTWR5TQBcjs.searchEffectSummaries.call(void 0, summaries, q, o),
528
708
  describe: (id) => structuredClone(get(id)),
529
709
  createRenderer(id, ro) {
530
710
  const d = get(id);
531
- if (d.kind !== "shader") throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`"${id}" is a ${d.kind} effect; use applyVectorEffect.`, id);
711
+ if (d.kind === "camera") throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`"${id}" is a camera move: it moves a scene's camera and draws no pixels. Use cameraView.`, id);
712
+ if (d.kind !== "shader") throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`"${id}" is a ${d.kind} effect; use applyVectorEffect.`, id);
532
713
  const { width, height } = ro;
533
714
  const depth = _nullishCoalesce(ro.depth, () => ( 8));
534
715
  if (!(width > 0 && height > 0) || width > capabilities.maxSize || height > capabilities.maxSize) {
535
- throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`Renderer size ${width}\xD7${height} is outside 1\u2013${capabilities.maxSize}.`, id);
716
+ throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`Renderer size ${width}\xD7${height} is outside 1\u2013${capabilities.maxSize}.`, id);
536
717
  }
537
718
  let disposed = false;
538
719
  return {
@@ -541,16 +722,16 @@ function createFakeEffectProvider(options = {}) {
541
722
  height,
542
723
  depth,
543
724
  async render(request) {
544
- if (disposed) throw new (0, _chunkA3A5TI6Rcjs.EffectDisposedError)(id);
725
+ if (disposed) throw new (0, _chunkNTWR5TQBcjs.EffectDisposedError)(id);
545
726
  if (!Number.isFinite(request.time) || request.time < 0) {
546
- throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`time must be a finite number of ms \u2265 0, got ${request.time}.`, id);
727
+ throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`time must be a finite number of ms \u2265 0, got ${request.time}.`, id);
547
728
  }
548
- const values = _chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, d, request.values);
549
- _optionalChain([options, 'access', _16 => _16.onRender, 'optionalCall', _17 => _17(id, request)]);
729
+ const values = _chunkNTWR5TQBcjs.resolveEffectValues.call(void 0, d, request.values);
730
+ _optionalChain([options, 'access', _26 => _26.onRender, 'optionalCall', _27 => _27(id, request)]);
550
731
  const out = renderPixels(d, values, request, width, height);
551
732
  if (request.mask) {
552
- if (!capabilities.supportsMask) throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)("This provider does not take masks.", id);
553
- const source = d.uses.includes("filter") ? _optionalChain([request, 'access', _18 => _18.inputs, 'optionalAccess', _19 => _19.source]) : void 0;
733
+ if (!capabilities.supportsMask) throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)("This provider does not take masks.", id);
734
+ const source = d.uses.includes("filter") ? _optionalChain([request, 'access', _28 => _28.inputs, 'optionalAccess', _29 => _29.source]) : void 0;
554
735
  maskResult(out, request.mask, source, id);
555
736
  }
556
737
  return depth > 8 && capabilities.supportsFloat ? toFloat(out) : out;
@@ -562,8 +743,8 @@ function createFakeEffectProvider(options = {}) {
562
743
  },
563
744
  applyVectorEffect(id, target, values) {
564
745
  const d = get(id);
565
- if (d.kind !== "motion" && d.kind !== "vector") throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`"${id}" is a ${d.kind} effect, not a vector one.`, id);
566
- const v = _chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, d, values);
746
+ if (d.kind !== "motion" && d.kind !== "vector") throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`"${id}" is a ${d.kind} effect, not a vector one.`, id);
747
+ const v = _chunkNTWR5TQBcjs.resolveEffectValues.call(void 0, d, values);
567
748
  if (d.kind === "vector") {
568
749
  return { svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100"><circle id="badge" cx="50" cy="50" r="40" fill="${v.color}"/></svg>`, animate: [{ id: "badge", ms: v.ms, attrs: { opacity: [0, 1] } }], duration: v.ms, loop: false };
569
750
  }
@@ -578,8 +759,16 @@ function createFakeEffectProvider(options = {}) {
578
759
  loop: false
579
760
  };
580
761
  },
762
+ ...options.camera ? {
763
+ cameraView: camera,
764
+ sampleCameraMove: (id, request) => {
765
+ const d = get(id);
766
+ const { from, to, ms, stage, fps, values } = request;
767
+ return _chunkNTWR5TQBcjs.sampleCameraViews.call(void 0, (u) => camera(id, { from, to, u, ms, stage }, values), { ms, fps, cut: _optionalChain([d, 'access', _30 => _30.camera, 'optionalAccess', _31 => _31.cut]) });
768
+ }
769
+ } : {},
581
770
  ...supportsAuthoring ? {
582
- openAuthoring: (from) => _chunk6DUEV36Fcjs.createEffectAuthoringSession.call(void 0, from, { provider })
771
+ openAuthoring: (from) => _chunk7AAS3JO6cjs.createEffectAuthoringSession.call(void 0, from, { provider })
583
772
  } : {}
584
773
  };
585
774
  return provider;
@@ -593,7 +782,8 @@ var EFFECT_USE_LABELS = {
593
782
  overlay: "Overlay",
594
783
  title: "Title",
595
784
  motion: "Motion",
596
- interactive: "Interactive"
785
+ interactive: "Interactive",
786
+ camera: "Camera"
597
787
  };
598
788
  var HEX2 = /^#[0-9a-f]{6}([0-9a-f]{2})?$/i;
599
789
  var typeOf = (s) => Array.isArray(s.type) ? s.type.find((t) => t !== "null") : s.type;
@@ -614,7 +804,7 @@ function jsonTypeOf(value) {
614
804
  function effectControlField(name, schema, fallback, options = {}) {
615
805
  const base = { id: name, ...schema.title ? { label: schema.title } : {}, ...schema.description ? { description: schema.description } : {} };
616
806
  const def = _nullishCoalesce(schema.default, () => ( fallback));
617
- const type = _nullishCoalesce(typeOf(schema), () => ( typeOf(_nullishCoalesce(_optionalChain([schema, 'access', _20 => _20.anyOf, 'optionalAccess', _21 => _21.find, 'call', _22 => _22((s) => typeOf(s) === jsonTypeOf(def))]), () => ( {})))));
807
+ const type = _nullishCoalesce(typeOf(schema), () => ( typeOf(_nullishCoalesce(_optionalChain([schema, 'access', _32 => _32.anyOf, 'optionalAccess', _33 => _33.find, 'call', _34 => _34((s) => typeOf(s) === jsonTypeOf(def))]), () => ( {})))));
618
808
  if (Array.isArray(schema.enum) && schema.enum.length) {
619
809
  const options2 = schema.enum.filter((v) => typeof v === "string" || typeof v === "number");
620
810
  return { ...base, type: "choice", options: options2, default: typeof def === "string" || typeof def === "number" ? def : options2[0], control: options2.length <= 4 ? "segmented" : "select" };
@@ -628,7 +818,7 @@ function effectControlField(name, schema, fallback, options = {}) {
628
818
  if (isEffectFontControl(schema)) {
629
819
  const fonts = _nullishCoalesce(options.fonts, () => ( _chunk4XSBOGMKcjs.SYSTEM_FONT_CATALOG));
630
820
  const opts = fonts.map((f) => ({ value: f.family, label: f.family, description: f.category }));
631
- const current = typeof def === "string" && def ? def : _nullishCoalesce(_optionalChain([opts, 'access', _23 => _23[0], 'optionalAccess', _24 => _24.value]), () => ( "sans-serif"));
821
+ const current = typeof def === "string" && def ? def : _nullishCoalesce(_optionalChain([opts, 'access', _35 => _35[0], 'optionalAccess', _36 => _36.value]), () => ( "sans-serif"));
632
822
  if (!opts.some((o) => o.value.toLowerCase() === current.toLowerCase())) opts.unshift({ value: current, label: current, description: "current" });
633
823
  return { ...base, type: "choice", options: opts, default: opts.find((o) => o.value.toLowerCase() === current.toLowerCase()).value, control: "select" };
634
824
  }
@@ -637,7 +827,7 @@ function effectControlField(name, schema, fallback, options = {}) {
637
827
  return { ...base, type: "text", default: typeof def === "string" ? def : "", ...schema.maxLength ? { maxLength: schema.maxLength } : {} };
638
828
  }
639
829
  if (type === "array" && Array.isArray(def) && def.length >= 2 && def.length <= 4 && def.every((n) => typeof n === "number")) {
640
- const items = _nullishCoalesce(_nullishCoalesce(schema.items, () => ( _optionalChain([schema, 'access', _25 => _25.anyOf, 'optionalAccess', _26 => _26.find, 'call', _27 => _27((s) => typeOf(s) === "array"), 'optionalAccess', _28 => _28.items]))), () => ( {}));
830
+ const items = _nullishCoalesce(_nullishCoalesce(schema.items, () => ( _optionalChain([schema, 'access', _37 => _37.anyOf, 'optionalAccess', _38 => _38.find, 'call', _39 => _39((s) => typeOf(s) === "array"), 'optionalAccess', _40 => _40.items]))), () => ( {}));
641
831
  return { ...base, type: "vector", size: def.length, default: [...def], ...items.minimum !== void 0 ? { min: items.minimum } : {}, ...items.maximum !== void 0 ? { max: items.maximum } : {} };
642
832
  }
643
833
  return null;
@@ -659,7 +849,7 @@ var effectFieldValue = (field, value) => {
659
849
  return value === void 0 || value === null || typeof value === "object" && !Array.isArray(value) ? field.default : value;
660
850
  };
661
851
  function effectSamplePicture(width, height, variant = 0) {
662
- const p = _chunkA3A5TI6Rcjs.createEffectPixels.call(void 0, width, height);
852
+ const p = _chunkNTWR5TQBcjs.createEffectPixels.call(void 0, width, height);
663
853
  for (let y = 0, i = 0; y < height; y++) {
664
854
  for (let x = 0; x < width; x++, i += 4) {
665
855
  const u = x / Math.max(1, width - 1);
@@ -750,11 +940,11 @@ var EASING_SCHEMA = {
750
940
  };
751
941
  var NO_SESSION = "No effect authoring session is currently open. Open an effect using EffectProvider.openAuthoring() or in an authoring editor before calling effect authoring tools.";
752
942
  function createEffectAuthoringToolProvider(host, options) {
753
- const id = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _29 => _29.id]), () => ( "effect-authoring"));
754
- const namespace = _optionalChain([options, 'optionalAccess', _30 => _30.namespace]);
755
- const title = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _31 => _31.title]), () => ( "Effect authoring"));
756
- const description = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _32 => _32.description]), () => ( "Author shaders and procedural effects, inspect parameters, adjust values, and manage keyframe animations."));
757
- const skill = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _33 => _33.skill]), () => ( "pixerate-effect-authoring"));
943
+ const id = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _41 => _41.id]), () => ( "effect-authoring"));
944
+ const namespace = _optionalChain([options, 'optionalAccess', _42 => _42.namespace]);
945
+ const title = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _43 => _43.title]), () => ( "Effect authoring"));
946
+ const description = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _44 => _44.description]), () => ( "Author shaders and procedural effects, inspect parameters, adjust values, and manage keyframe animations."));
947
+ const skill = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _45 => _45.skill]), () => ( "pixerate-effect-authoring"));
758
948
  const requireSession = () => {
759
949
  const s = host.session();
760
950
  if (!s) throw new Error(NO_SESSION);
@@ -775,7 +965,7 @@ function createEffectAuthoringToolProvider(host, options) {
775
965
  sourceLanguage: state.sourceLanguage,
776
966
  controls: effectParameterFields(state.description),
777
967
  values: state.values,
778
- presets: _nullishCoalesce(_optionalChain([state, 'access', _34 => _34.description, 'access', _35 => _35.presets, 'optionalAccess', _36 => _36.map, 'call', _37 => _37((p) => p.name)]), () => ( [])),
968
+ presets: _nullishCoalesce(_optionalChain([state, 'access', _46 => _46.description, 'access', _47 => _47.presets, 'optionalAccess', _48 => _48.map, 'call', _49 => _49((p) => p.name)]), () => ( [])),
779
969
  tracks: Object.entries(state.tracks).map(([control, track]) => ({
780
970
  control,
781
971
  keyframes: track.length
@@ -1082,7 +1272,7 @@ function createEffectAuthoringToolProvider(host, options) {
1082
1272
  const tools = [
1083
1273
  describeTool,
1084
1274
  getSourceTool,
1085
- ..._optionalChain([session, 'optionalAccess', _38 => _38.setSource]) ? [setSourceTool] : [],
1275
+ ..._optionalChain([session, 'optionalAccess', _50 => _50.setSource]) ? [setSourceTool] : [],
1086
1276
  setValuesTool,
1087
1277
  resetValuesTool,
1088
1278
  applyPresetTool,
@@ -1141,4 +1331,9 @@ function createEffectAuthoringToolProvider(host, options) {
1141
1331
 
1142
1332
 
1143
1333
 
1144
- exports.EFFECT_ERROR_CODES = _chunkA3A5TI6Rcjs.EFFECT_ERROR_CODES; exports.EFFECT_KINDS = _chunkA3A5TI6Rcjs.EFFECT_KINDS; exports.EFFECT_USES = _chunkA3A5TI6Rcjs.EFFECT_USES; exports.EFFECT_USE_LABELS = EFFECT_USE_LABELS; exports.EffectControlError = _chunkA3A5TI6Rcjs.EffectControlError; exports.EffectDisposedError = _chunkA3A5TI6Rcjs.EffectDisposedError; exports.EffectError = _chunkA3A5TI6Rcjs.EffectError; exports.EffectRendererPool = _chunkPY4GWSE2cjs.EffectRendererPool; exports.EffectUnsupportedError = _chunkA3A5TI6Rcjs.EffectUnsupportedError; exports.EffectsSlot = _chunkA3A5TI6Rcjs.EffectsSlot; exports.NoEffectsProviderError = _chunkA3A5TI6Rcjs.NoEffectsProviderError; exports.UnknownEffectError = _chunkA3A5TI6Rcjs.UnknownEffectError; exports.applyEffectMask = _chunkA3A5TI6Rcjs.applyEffectMask; exports.checkEffectProvider = checkEffectProvider; exports.countEffectTags = _chunkA3A5TI6Rcjs.countEffectTags; exports.createEffectAuthoringSession = _chunk6DUEV36Fcjs.createEffectAuthoringSession; exports.createEffectAuthoringToolProvider = createEffectAuthoringToolProvider; exports.createEffectPixels = _chunkA3A5TI6Rcjs.createEffectPixels; exports.createEffectToolProvider = _chunkA3A5TI6Rcjs.createEffectToolProvider; exports.createFakeEffectProvider = createFakeEffectProvider; exports.effectControlField = effectControlField; exports.effectFieldValue = effectFieldValue; exports.effectFontFamilies = effectFontFamilies; exports.effectParameterFields = effectParameterFields; exports.effectSampleInputs = effectSampleInputs; exports.effectSamplePicture = effectSamplePicture; exports.effectValueErrors = _chunkA3A5TI6Rcjs.effectValueErrors; exports.encodeEffectFloat = _chunkA3A5TI6Rcjs.encodeEffectFloat; exports.groupEffectsByCategory = groupEffectsByCategory; exports.hasEffectTags = _chunkA3A5TI6Rcjs.hasEffectTags; exports.isEffectError = _chunkA3A5TI6Rcjs.isEffectError; exports.isEffectFontControl = isEffectFontControl; exports.isEffectPixels = _chunkA3A5TI6Rcjs.isEffectPixels; exports.linearToSrgb = _chunkA3A5TI6Rcjs.linearToSrgb; exports.normaliseEffectTag = _chunkA3A5TI6Rcjs.normaliseEffectTag; exports.renderEffectThumbnail = renderEffectThumbnail; exports.resolveEffectValues = _chunkA3A5TI6Rcjs.resolveEffectValues; exports.searchEffectSummaries = _chunkA3A5TI6Rcjs.searchEffectSummaries; exports.srgbToLinear = _chunkA3A5TI6Rcjs.srgbToLinear;
1334
+
1335
+
1336
+
1337
+
1338
+
1339
+ exports.CAMERA_MOVE_ROLES = _chunkNTWR5TQBcjs.CAMERA_MOVE_ROLES; exports.EFFECT_ERROR_CODES = _chunkNTWR5TQBcjs.EFFECT_ERROR_CODES; exports.EFFECT_KINDS = _chunkNTWR5TQBcjs.EFFECT_KINDS; exports.EFFECT_USES = _chunkNTWR5TQBcjs.EFFECT_USES; exports.EFFECT_USE_LABELS = EFFECT_USE_LABELS; exports.EffectControlError = _chunkNTWR5TQBcjs.EffectControlError; exports.EffectDisposedError = _chunkNTWR5TQBcjs.EffectDisposedError; exports.EffectError = _chunkNTWR5TQBcjs.EffectError; exports.EffectRendererPool = _chunkPY4GWSE2cjs.EffectRendererPool; exports.EffectUnsupportedError = _chunkNTWR5TQBcjs.EffectUnsupportedError; exports.EffectsSlot = _chunkNTWR5TQBcjs.EffectsSlot; exports.NoEffectsProviderError = _chunkNTWR5TQBcjs.NoEffectsProviderError; exports.UnknownEffectError = _chunkNTWR5TQBcjs.UnknownEffectError; exports.applyEffectMask = _chunkNTWR5TQBcjs.applyEffectMask; exports.checkEffectProvider = checkEffectProvider; exports.countEffectTags = _chunkNTWR5TQBcjs.countEffectTags; exports.createEffectAuthoringSession = _chunk7AAS3JO6cjs.createEffectAuthoringSession; exports.createEffectAuthoringToolProvider = createEffectAuthoringToolProvider; exports.createEffectPixels = _chunkNTWR5TQBcjs.createEffectPixels; exports.createEffectToolProvider = _chunkNTWR5TQBcjs.createEffectToolProvider; exports.createFakeEffectProvider = createFakeEffectProvider; exports.effectControlField = effectControlField; exports.effectFieldValue = effectFieldValue; exports.effectFontFamilies = effectFontFamilies; exports.effectOffered = _chunkNTWR5TQBcjs.effectOffered; exports.effectParameterFields = effectParameterFields; exports.effectSampleInputs = effectSampleInputs; exports.effectSamplePicture = effectSamplePicture; exports.effectValueErrors = _chunkNTWR5TQBcjs.effectValueErrors; exports.encodeEffectFloat = _chunkNTWR5TQBcjs.encodeEffectFloat; exports.groupEffectsByCategory = groupEffectsByCategory; exports.hasEffectTags = _chunkNTWR5TQBcjs.hasEffectTags; exports.isCameraView = _chunkNTWR5TQBcjs.isCameraView; exports.isEffectError = _chunkNTWR5TQBcjs.isEffectError; exports.isEffectFontControl = isEffectFontControl; exports.isEffectPixels = _chunkNTWR5TQBcjs.isEffectPixels; exports.linearToSrgb = _chunkNTWR5TQBcjs.linearToSrgb; exports.normaliseEffectTag = _chunkNTWR5TQBcjs.normaliseEffectTag; exports.renderEffectThumbnail = renderEffectThumbnail; exports.resolveEffectValues = _chunkNTWR5TQBcjs.resolveEffectValues; exports.sampleCameraViews = _chunkNTWR5TQBcjs.sampleCameraViews; exports.sampleEffectCameraMove = _chunkNTWR5TQBcjs.sampleEffectCameraMove; exports.searchEffectSummaries = _chunkNTWR5TQBcjs.searchEffectSummaries; exports.srgbToLinear = _chunkNTWR5TQBcjs.srgbToLinear;