@elucim/dsl 0.13.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { default as default_2 } from 'react';
2
+ import { JSX as JSX_2 } from 'react/jsx-runtime';
2
3
 
3
4
  export declare interface ArrowNode {
4
5
  type: 'arrow';
@@ -225,6 +226,12 @@ export declare interface DslRendererProps {
225
226
  path: string;
226
227
  message: string;
227
228
  }>) => void;
229
+ /**
230
+ * Image resolver for consumer-managed assets.
231
+ * When provided, `<Image>` elements with a `ref` field call this function
232
+ * to obtain a renderable URL instead of using `src` directly.
233
+ */
234
+ imageResolver?: ImageResolverFn;
228
235
  }
229
236
 
230
237
  export declare interface DslRendererRef {
@@ -398,7 +405,12 @@ export declare interface GroupNode {
398
405
  export declare interface ImageNode {
399
406
  type: 'image';
400
407
  id?: string;
401
- src: string;
408
+ /** Image URL or data URI. Used directly, or as fallback when ref is set. */
409
+ src?: string;
410
+ /** Opaque consumer reference resolved via ImageResolverProvider at render time. */
411
+ ref?: string;
412
+ /** Human-readable label for the image (shown in editor inspector). */
413
+ displayName?: string;
402
414
  x: number;
403
415
  y: number;
404
416
  width: number;
@@ -417,6 +429,45 @@ export declare interface ImageNode {
417
429
  zIndex?: number;
418
430
  }
419
431
 
432
+ /**
433
+ * A function that resolves an opaque image reference to a renderable URL.
434
+ *
435
+ * - Return a `string` for synchronous resolution (CDN rewrites, path prefixing).
436
+ * - Return a `Promise<string>` for async resolution (auth tokens, signed URLs).
437
+ *
438
+ * @example
439
+ * ```ts
440
+ * // Sync: prefix a CDN base URL
441
+ * const resolver: ImageResolverFn = (ref) => `https://cdn.example.com/${ref}`;
442
+ *
443
+ * // Async: fetch a signed URL from an API
444
+ * const resolver: ImageResolverFn = async (ref) => {
445
+ * const res = await fetch(`/api/assets/${ref}/url`);
446
+ * return res.text();
447
+ * };
448
+ * ```
449
+ */
450
+ export declare type ImageResolverFn = (ref: string) => string | Promise<string>;
451
+
452
+ /**
453
+ * Provides an image resolver to all Elucim components below.
454
+ *
455
+ * When present, `<Image>` elements with a `ref` prop will call this resolver
456
+ * to obtain a renderable URL instead of using `src` directly.
457
+ *
458
+ * Works with `DslRenderer`, `ElucimEditor`, or any custom composition.
459
+ *
460
+ * @example
461
+ * ```tsx
462
+ * <ImageResolverProvider resolver={(ref) => `https://cdn.acme.com/${ref}`}>
463
+ * <DslRenderer dsl={doc} />
464
+ * </ImageResolverProvider>
465
+ * ```
466
+ */
467
+ export declare function ImageResolverProvider({ resolver, children, }: default_2.PropsWithChildren<{
468
+ resolver: ImageResolverFn;
469
+ }>): JSX_2.Element;
470
+
420
471
  export declare interface LaTeXNode {
421
472
  type: 'latex';
422
473
  id?: string;
@@ -1087,6 +1138,12 @@ export declare interface TransformNode {
1087
1138
 
1088
1139
  declare type TransitionType = 'none' | 'fade' | 'slide-left' | 'slide-up' | 'zoom';
1089
1140
 
1141
+ /**
1142
+ * Returns the image resolver if an `ImageResolverProvider` is present,
1143
+ * or `undefined` otherwise.
1144
+ */
1145
+ export declare function useImageResolver(): ImageResolverFn | undefined;
1146
+
1090
1147
  export declare function validate(doc: unknown): ValidationResult;
1091
1148
 
1092
1149
  /**
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { easeOutBounce as xe, easeOutElastic as de, easeOutBack as we, easeInBack as ve, easeInOutExpo as ke, easeOutExpo as Ie, easeInExpo as Se, easeInOutSine as $e, easeOutSine as Ce, easeInSine as Oe, easeInOutQuart as Ae, easeOutQuart as pe, easeInQuart as ze, easeInOutCubic as Ee, easeOutCubic as Re, easeInCubic as Te, easeInOutQuad as Fe, easeOutQuad as Pe, easeInQuad as Me, linear as _e, spring as De, cubicBezier as Ne, Presentation as We, resolveColor as u, Scene as Le, Player as Ve, Slide as Be, Parallel as je, Stagger as qe, Morph as Ue, Transform as He, Write as Ge, Draw as Ke, FadeOut as Qe, FadeIn as Xe, BarChart as Je, LaTeX as Ye, Graph as Ze, Matrix as et, Text as U, VectorField as tt, Vector as at, FunctionPlot as rt, Axes as it, Image as nt, Polygon as st, Rect as ct, Arrow as lt, Line as ut, Circle as ht, BezierCurve as ft, Group as gt, Sequence as ot, themeToVars as mt, DARK_THEME_VARS as yt, LIGHT_THEME_VARS as bt } from "@elucim/core";
2
- import { DARK_THEME as $a, DARK_THEME_VARS as Ca, LIGHT_THEME as Oa, LIGHT_THEME_VARS as Aa, SEMANTIC_TOKENS as pa, TOKEN_NAMES as za, resolveColor as Ea, themeToVars as Ra } from "@elucim/core";
1
+ import { easeOutBounce as we, easeOutElastic as ve, easeOutBack as ke, easeInBack as Ie, easeInOutExpo as Se, easeOutExpo as $e, easeInExpo as Ce, easeInOutSine as Oe, easeOutSine as Ae, easeInSine as pe, easeInOutQuart as ze, easeOutQuart as Ee, easeInQuart as Re, easeInOutCubic as Pe, easeOutCubic as Te, easeInCubic as Fe, easeInOutQuad as Me, easeOutQuad as _e, easeInQuad as De, linear as Ne, spring as We, cubicBezier as Le, Presentation as Ve, resolveColor as u, Scene as Be, Player as je, Slide as qe, Parallel as Ue, Stagger as He, Morph as Ge, Transform as Ke, Write as Qe, Draw as Xe, FadeOut as Je, FadeIn as Ye, BarChart as Ze, LaTeX as et, Graph as tt, Matrix as at, Text as U, VectorField as rt, Vector as it, FunctionPlot as nt, Axes as st, Image as ct, Polygon as lt, Rect as ut, Arrow as ht, Line as ft, Circle as ot, BezierCurve as gt, Group as mt, Sequence as yt, themeToVars as bt, ImageResolverProvider as xt, DARK_THEME_VARS as dt, LIGHT_THEME_VARS as wt } from "@elucim/core";
2
+ import { DARK_THEME as Aa, DARK_THEME_VARS as pa, ImageResolverProvider as za, LIGHT_THEME as Ea, LIGHT_THEME_VARS as Ra, SEMANTIC_TOKENS as Pa, TOKEN_NAMES as Ta, resolveColor as Fa, themeToVars as Ma, useImageResolver as _a } from "@elucim/core";
3
3
  import { jsx as l, jsxs as E } from "react/jsx-runtime";
4
- import K, { forwardRef as xt, useRef as dt, useImperativeHandle as wt, useSyncExternalStore as vt } from "react";
5
- import { renderToStaticMarkup as kt } from "react-dom/server";
4
+ import K, { forwardRef as vt, useRef as kt, useImperativeHandle as It, useSyncExternalStore as St } from "react";
5
+ import { renderToStaticMarkup as $t } from "react-dom/server";
6
6
  const Q = {
7
7
  sin: Math.sin,
8
8
  cos: Math.cos,
@@ -23,7 +23,7 @@ const Q = {
23
23
  max: (...e) => Math.max(...e),
24
24
  sign: Math.sign,
25
25
  pow: Math.pow
26
- }, ae = {
26
+ }, ie = {
27
27
  PI: Math.PI,
28
28
  E: Math.E,
29
29
  TAU: Math.PI * 2
@@ -176,7 +176,7 @@ class Z {
176
176
  );
177
177
  return { kind: "call", name: t, args: r };
178
178
  }
179
- return Object.prototype.hasOwnProperty.call(ae, t) ? { kind: "number", value: ae[t] } : { kind: "variable", name: t };
179
+ return Object.prototype.hasOwnProperty.call(ie, t) ? { kind: "number", value: ie[t] } : { kind: "variable", name: t };
180
180
  }
181
181
  if (a.type === "LPAREN") {
182
182
  this.advance();
@@ -237,11 +237,11 @@ class A extends Error {
237
237
  super(a), this.name = "ExpressionError", this.position = t;
238
238
  }
239
239
  }
240
- function It(e) {
240
+ function Ct(e) {
241
241
  const a = Y(e), t = new Z(a).parse();
242
242
  return (r) => R(t, r);
243
243
  }
244
- function St(e) {
244
+ function Ot(e) {
245
245
  const a = Y(e), t = new Z(a).parse();
246
246
  if (t.kind !== "array" || t.elements.length !== 2)
247
247
  throw new A(
@@ -250,7 +250,7 @@ function St(e) {
250
250
  );
251
251
  return (r) => R(t, r);
252
252
  }
253
- function ce(e) {
253
+ function ue(e) {
254
254
  try {
255
255
  const a = Y(e);
256
256
  return new Z(a).parse(), null;
@@ -259,26 +259,26 @@ function ce(e) {
259
259
  }
260
260
  }
261
261
  const X = {
262
- linear: _e,
263
- easeInQuad: Me,
264
- easeOutQuad: Pe,
265
- easeInOutQuad: Fe,
266
- easeInCubic: Te,
267
- easeOutCubic: Re,
268
- easeInOutCubic: Ee,
269
- easeInQuart: ze,
270
- easeOutQuart: pe,
271
- easeInOutQuart: Ae,
272
- easeInSine: Oe,
273
- easeOutSine: Ce,
274
- easeInOutSine: $e,
275
- easeInExpo: Se,
276
- easeOutExpo: Ie,
277
- easeInOutExpo: ke,
278
- easeInBack: ve,
279
- easeOutBack: we,
280
- easeOutElastic: de,
281
- easeOutBounce: xe
262
+ linear: Ne,
263
+ easeInQuad: De,
264
+ easeOutQuad: _e,
265
+ easeInOutQuad: Me,
266
+ easeInCubic: Fe,
267
+ easeOutCubic: Te,
268
+ easeInOutCubic: Pe,
269
+ easeInQuart: Re,
270
+ easeOutQuart: Ee,
271
+ easeInOutQuart: ze,
272
+ easeInSine: pe,
273
+ easeOutSine: Ae,
274
+ easeInOutSine: Oe,
275
+ easeInExpo: Ce,
276
+ easeOutExpo: $e,
277
+ easeInOutExpo: Se,
278
+ easeInBack: Ie,
279
+ easeOutBack: ke,
280
+ easeOutElastic: ve,
281
+ easeOutBounce: we
282
282
  };
283
283
  function f(e) {
284
284
  if (e !== void 0) {
@@ -291,28 +291,28 @@ function f(e) {
291
291
  return a;
292
292
  }
293
293
  if (e.type === "spring")
294
- return De({
294
+ return We({
295
295
  stiffness: e.stiffness,
296
296
  damping: e.damping,
297
297
  mass: e.mass
298
298
  });
299
299
  if (e.type === "cubicBezier")
300
- return Ne(e.x1, e.y1, e.x2, e.y2);
300
+ return Le(e.x1, e.y1, e.x2, e.y2);
301
301
  throw new Error(`Unknown easing type: ${e.type}`);
302
302
  }
303
303
  }
304
304
  const H = Object.keys(X);
305
- function le(e) {
305
+ function he(e) {
306
306
  const a = [];
307
307
  if (!e || typeof e != "object")
308
308
  return a.push({ path: "", message: "Document must be an object", severity: "error" }), { valid: !1, errors: a };
309
309
  const t = e;
310
- return t.version !== "1.0" && a.push({ path: "version", message: `Expected version "1.0", got "${t.version}"`, severity: "error" }), !t.root || typeof t.root != "object" ? (a.push({ path: "root", message: 'Missing or invalid "root" node', severity: "error" }), { valid: a.filter((r) => r.severity === "error").length === 0, errors: a }) : ($t(t.root, "root", a), {
310
+ return t.version !== "1.0" && a.push({ path: "version", message: `Expected version "1.0", got "${t.version}"`, severity: "error" }), !t.root || typeof t.root != "object" ? (a.push({ path: "root", message: 'Missing or invalid "root" node', severity: "error" }), { valid: a.filter((r) => r.severity === "error").length === 0, errors: a }) : (At(t.root, "root", a), {
311
311
  valid: a.filter((r) => r.severity === "error").length === 0,
312
312
  errors: a
313
313
  });
314
314
  }
315
- const re = ["scene", "player", "presentation"], V = ["card", "slide", "square"], G = [
315
+ const ne = ["scene", "player", "presentation"], V = ["card", "slide", "square"], G = [
316
316
  "sequence",
317
317
  "group",
318
318
  "bezierCurve",
@@ -341,38 +341,38 @@ const re = ["scene", "player", "presentation"], V = ["card", "slide", "square"],
341
341
  "parallel",
342
342
  "player",
343
343
  "scene"
344
- ], ie = ["none", "fade", "slide-left", "slide-up", "zoom"];
345
- function $t(e, a, t) {
344
+ ], se = ["none", "fade", "slide-left", "slide-up", "zoom"];
345
+ function At(e, a, t) {
346
346
  const r = e.type;
347
- if (!re.includes(r)) {
348
- t.push({ path: `${a}.type`, message: `Root type must be one of: ${re.join(", ")}. Got "${r}"`, severity: "error" });
347
+ if (!ne.includes(r)) {
348
+ t.push({ path: `${a}.type`, message: `Root type must be one of: ${ne.join(", ")}. Got "${r}"`, severity: "error" });
349
349
  return;
350
350
  }
351
- r === "scene" || r === "player" ? ue(e, a, r, t) : r === "presentation" && Ct(e, a, t);
351
+ r === "scene" || r === "player" ? fe(e, a, r, t) : r === "presentation" && pt(e, a, t);
352
352
  }
353
- function ue(e, a, t, r) {
354
- Jt(e, "durationInFrames", a, r), m(e, "width", a, r), m(e, "height", a, r), m(e, "fps", a, r), p(e, "background", a, r), e.preset !== void 0 && (typeof e.preset != "string" || !V.includes(e.preset)) && r.push({ path: `${a}.preset`, message: `preset must be one of: ${V.join(", ")}. Got "${e.preset}"`, severity: "error" }), t === "player" && (W(e, "controls", a, r), W(e, "loop", a, r), W(e, "autoPlay", a, r)), z(e, a, r);
353
+ function fe(e, a, t, r) {
354
+ ea(e, "durationInFrames", a, r), m(e, "width", a, r), m(e, "height", a, r), m(e, "fps", a, r), p(e, "background", a, r), e.preset !== void 0 && (typeof e.preset != "string" || !V.includes(e.preset)) && r.push({ path: `${a}.preset`, message: `preset must be one of: ${V.join(", ")}. Got "${e.preset}"`, severity: "error" }), t === "player" && (N(e, "controls", a, r), N(e, "loop", a, r), N(e, "autoPlay", a, r)), z(e, a, r);
355
355
  }
356
- function Ct(e, a, t) {
357
- if (m(e, "width", a, t), m(e, "height", a, t), p(e, "background", a, t), m(e, "transitionDuration", a, t), W(e, "showHud", a, t), W(e, "showNotes", a, t), e.preset !== void 0 && (typeof e.preset != "string" || !V.includes(e.preset)) && t.push({ path: `${a}.preset`, message: `preset must be one of: ${V.join(", ")}. Got "${e.preset}"`, severity: "error" }), e.transition !== void 0 && (ie.includes(e.transition) || t.push({
356
+ function pt(e, a, t) {
357
+ if (m(e, "width", a, t), m(e, "height", a, t), p(e, "background", a, t), m(e, "transitionDuration", a, t), N(e, "showHud", a, t), N(e, "showNotes", a, t), e.preset !== void 0 && (typeof e.preset != "string" || !V.includes(e.preset)) && t.push({ path: `${a}.preset`, message: `preset must be one of: ${V.join(", ")}. Got "${e.preset}"`, severity: "error" }), e.transition !== void 0 && (se.includes(e.transition) || t.push({
358
358
  path: `${a}.transition`,
359
- message: `Invalid transition "${e.transition}". Must be one of: ${ie.join(", ")}`,
359
+ message: `Invalid transition "${e.transition}". Must be one of: ${se.join(", ")}`,
360
360
  severity: "error"
361
361
  })), !Array.isArray(e.slides)) {
362
362
  t.push({ path: `${a}.slides`, message: 'Presentation must have a "slides" array', severity: "error" });
363
363
  return;
364
364
  }
365
365
  e.slides.length === 0 && t.push({ path: `${a}.slides`, message: "Presentation must have at least one slide", severity: "warning" }), e.slides.forEach((r, i) => {
366
- Ot(r, `${a}.slides[${i}]`, t);
366
+ zt(r, `${a}.slides[${i}]`, t);
367
367
  });
368
368
  }
369
- function Ot(e, a, t) {
369
+ function zt(e, a, t) {
370
370
  if (!e || typeof e != "object") {
371
371
  t.push({ path: a, message: "Slide must be an object", severity: "error" });
372
372
  return;
373
373
  }
374
374
  p(e, "title", a, t), p(e, "notes", a, t), p(e, "background", a, t), e.children !== void 0 && (Array.isArray(e.children) ? e.children.forEach((r, i) => {
375
- he(r, `${a}.children[${i}]`, t);
375
+ oe(r, `${a}.children[${i}]`, t);
376
376
  }) : t.push({ path: `${a}.children`, message: "Slide children must be an array", severity: "error" }));
377
377
  }
378
378
  function z(e, a, t) {
@@ -381,17 +381,17 @@ function z(e, a, t) {
381
381
  return;
382
382
  }
383
383
  e.children.forEach((r, i) => {
384
- he(r, `${a}.children[${i}]`, t);
384
+ oe(r, `${a}.children[${i}]`, t);
385
385
  });
386
386
  }
387
- function he(e, a, t) {
387
+ function oe(e, a, t) {
388
388
  if (!e || typeof e != "object") {
389
389
  t.push({ path: a, message: "Element must be an object", severity: "error" });
390
390
  return;
391
391
  }
392
392
  const r = e.type;
393
393
  if (!r || !G.includes(r)) {
394
- const i = r ? fe(r, G) : "";
394
+ const i = r ? ge(r, G) : "";
395
395
  t.push({
396
396
  path: `${a}.type`,
397
397
  message: `Unknown element type "${r}".${i} Valid types: ${G.join(", ")}`,
@@ -401,58 +401,58 @@ function he(e, a, t) {
401
401
  }
402
402
  switch (r) {
403
403
  case "bezierCurve":
404
- At(e, a, t);
404
+ Et(e, a, t);
405
405
  break;
406
406
  case "circle":
407
- pt(e, a, t);
407
+ Rt(e, a, t);
408
408
  break;
409
409
  case "line":
410
- zt(e, a, t);
410
+ Pt(e, a, t);
411
411
  break;
412
412
  case "arrow":
413
- Et(e, a, t);
413
+ Tt(e, a, t);
414
414
  break;
415
415
  case "rect":
416
- Rt(e, a, t);
416
+ Ft(e, a, t);
417
417
  break;
418
418
  case "polygon":
419
- Tt(e, a, t);
419
+ Mt(e, a, t);
420
420
  break;
421
421
  case "text":
422
- Ft(e, a, t);
422
+ _t(e, a, t);
423
423
  break;
424
424
  case "image":
425
- Kt(e, a, t);
425
+ Jt(e, a, t);
426
426
  break;
427
427
  case "axes":
428
- Pt(e, a, t);
428
+ Dt(e, a, t);
429
429
  break;
430
430
  case "functionPlot":
431
- Mt(e, a, t);
431
+ Nt(e, a, t);
432
432
  break;
433
433
  case "vector":
434
- _t(e, a, t);
434
+ Wt(e, a, t);
435
435
  break;
436
436
  case "vectorField":
437
- Dt(e, a, t);
437
+ Lt(e, a, t);
438
438
  break;
439
439
  case "matrix":
440
- Nt(e, a, t);
440
+ Vt(e, a, t);
441
441
  break;
442
442
  case "graph":
443
- Wt(e, a, t);
443
+ Bt(e, a, t);
444
444
  break;
445
445
  case "latex":
446
- Lt(e, a, t);
446
+ jt(e, a, t);
447
447
  break;
448
448
  case "barChart":
449
- Xt(e, a, t);
449
+ Zt(e, a, t);
450
450
  break;
451
451
  case "sequence":
452
- Vt(e, a, t);
452
+ qt(e, a, t);
453
453
  break;
454
454
  case "group":
455
- Qt(e, a, t);
455
+ Yt(e, a, t);
456
456
  break;
457
457
  case "parallel":
458
458
  z(e, a, t);
@@ -461,76 +461,76 @@ function he(e, a, t) {
461
461
  case "fadeOut":
462
462
  case "draw":
463
463
  case "write":
464
- Bt(e, a, t);
464
+ Ut(e, a, t);
465
465
  break;
466
466
  case "transform":
467
- jt(e, a, t);
467
+ Ht(e, a, t);
468
468
  break;
469
469
  case "morph":
470
- qt(e, a, t);
470
+ Gt(e, a, t);
471
471
  break;
472
472
  case "stagger":
473
- Ut(e, a, t);
473
+ Kt(e, a, t);
474
474
  break;
475
475
  case "scene":
476
476
  case "player":
477
- ue(e, a, r, t);
477
+ fe(e, a, r, t);
478
478
  break;
479
479
  }
480
480
  }
481
- function At(e, a, t) {
482
- h(e, "x1", a, t), h(e, "y1", a, t), h(e, "cx1", a, t), h(e, "cy1", a, t), h(e, "x2", a, t), h(e, "y2", a, t), e.cx2 !== void 0 && P(e, "cx2", a, t), e.cy2 !== void 0 && P(e, "cy2", a, t), v(e, a, t);
481
+ function Et(e, a, t) {
482
+ h(e, "x1", a, t), h(e, "y1", a, t), h(e, "cx1", a, t), h(e, "cy1", a, t), h(e, "x2", a, t), h(e, "y2", a, t), e.cx2 !== void 0 && F(e, "cx2", a, t), e.cy2 !== void 0 && F(e, "cy2", a, t), v(e, a, t);
483
483
  }
484
- function pt(e, a, t) {
485
- h(e, "cx", a, t), h(e, "cy", a, t), T(e, "r", a, t), v(e, a, t);
484
+ function Rt(e, a, t) {
485
+ h(e, "cx", a, t), h(e, "cy", a, t), P(e, "r", a, t), v(e, a, t);
486
486
  }
487
- function zt(e, a, t) {
487
+ function Pt(e, a, t) {
488
488
  h(e, "x1", a, t), h(e, "y1", a, t), h(e, "x2", a, t), h(e, "y2", a, t), v(e, a, t);
489
489
  }
490
- function Et(e, a, t) {
490
+ function Tt(e, a, t) {
491
491
  h(e, "x1", a, t), h(e, "y1", a, t), h(e, "x2", a, t), h(e, "y2", a, t), v(e, a, t);
492
492
  }
493
- function Rt(e, a, t) {
494
- h(e, "x", a, t), h(e, "y", a, t), T(e, "width", a, t), T(e, "height", a, t), v(e, a, t);
493
+ function Ft(e, a, t) {
494
+ h(e, "x", a, t), h(e, "y", a, t), P(e, "width", a, t), P(e, "height", a, t), v(e, a, t);
495
495
  }
496
- function Tt(e, a, t) {
496
+ function Mt(e, a, t) {
497
497
  Array.isArray(e.points) ? e.points.length < 3 ? t.push({ path: `${a}.points`, message: "Polygon requires at least 3 points", severity: "error" }) : e.points.forEach((r, i) => {
498
498
  (!Array.isArray(r) || r.length !== 2 || typeof r[0] != "number" || typeof r[1] != "number") && t.push({ path: `${a}.points[${i}]`, message: "Each point must be [number, number]", severity: "error" });
499
499
  }) : t.push({ path: `${a}.points`, message: 'Polygon requires a "points" array', severity: "error" }), v(e, a, t);
500
500
  }
501
- function Ft(e, a, t) {
501
+ function _t(e, a, t) {
502
502
  h(e, "x", a, t), h(e, "y", a, t), typeof e.content != "string" && t.push({ path: `${a}.content`, message: 'Text requires a "content" string', severity: "error" }), v(e, a, t);
503
503
  }
504
- function Pt(e, a, t) {
504
+ function Dt(e, a, t) {
505
505
  I(e, "domain", a, t), I(e, "range", a, t), I(e, "origin", a, t), B(e, a, t);
506
506
  }
507
- function Mt(e, a, t) {
507
+ function Nt(e, a, t) {
508
508
  if (typeof e.fn != "string")
509
509
  t.push({ path: `${a}.fn`, message: 'FunctionPlot requires a "fn" expression string', severity: "error" });
510
510
  else {
511
- const r = ce(e.fn);
511
+ const r = ue(e.fn);
512
512
  r && t.push({ path: `${a}.fn`, message: `Invalid expression: ${r}`, severity: "error" });
513
513
  }
514
514
  I(e, "domain", a, t), B(e, a, t);
515
515
  }
516
- function _t(e, a, t) {
516
+ function Wt(e, a, t) {
517
517
  (!Array.isArray(e.to) || e.to.length !== 2) && t.push({ path: `${a}.to`, message: 'Vector requires a "to" array of [number, number]', severity: "error" }), I(e, "from", a, t), B(e, a, t);
518
518
  }
519
- function Dt(e, a, t) {
519
+ function Lt(e, a, t) {
520
520
  if (typeof e.fn != "string")
521
521
  t.push({ path: `${a}.fn`, message: 'VectorField requires a "fn" expression string', severity: "error" });
522
522
  else {
523
- const r = ce(e.fn);
523
+ const r = ue(e.fn);
524
524
  r && t.push({ path: `${a}.fn`, message: `Invalid vector expression: ${r}`, severity: "error" });
525
525
  }
526
526
  I(e, "domain", a, t), I(e, "range", a, t), B(e, a, t);
527
527
  }
528
- function Nt(e, a, t) {
528
+ function Vt(e, a, t) {
529
529
  Array.isArray(e.values) ? e.values.forEach((r, i) => {
530
530
  Array.isArray(r) || t.push({ path: `${a}.values[${i}]`, message: "Each matrix row must be an array", severity: "error" });
531
531
  }) : t.push({ path: `${a}.values`, message: 'Matrix requires a "values" 2D array', severity: "error" }), v(e, a, t);
532
532
  }
533
- function Wt(e, a, t) {
533
+ function Bt(e, a, t) {
534
534
  if (!Array.isArray(e.nodes))
535
535
  t.push({ path: `${a}.nodes`, message: 'Graph requires a "nodes" array', severity: "error" });
536
536
  else {
@@ -543,16 +543,16 @@ function Wt(e, a, t) {
543
543
  }
544
544
  v(e, a, t);
545
545
  }
546
- function Lt(e, a, t) {
546
+ function jt(e, a, t) {
547
547
  typeof e.expression != "string" && t.push({ path: `${a}.expression`, message: 'LaTeX requires an "expression" string', severity: "error" }), h(e, "x", a, t), h(e, "y", a, t), v(e, a, t);
548
548
  }
549
- function Vt(e, a, t) {
550
- h(e, "from", a, t), Yt(e, "durationInFrames", a, t), z(e, a, t);
549
+ function qt(e, a, t) {
550
+ h(e, "from", a, t), ta(e, "durationInFrames", a, t), z(e, a, t);
551
551
  }
552
- function Bt(e, a, t) {
552
+ function Ut(e, a, t) {
553
553
  m(e, "duration", a, t), M(e, a, t), z(e, a, t);
554
554
  }
555
- function jt(e, a, t) {
555
+ function Ht(e, a, t) {
556
556
  if (m(e, "duration", a, t), M(e, a, t), e.translate !== void 0) {
557
557
  const r = e.translate;
558
558
  (!r || typeof r != "object") && t.push({ path: `${a}.translate`, message: "translate must be { from: [x,y], to: [x,y] }", severity: "error" });
@@ -571,46 +571,47 @@ function jt(e, a, t) {
571
571
  }
572
572
  z(e, a, t);
573
573
  }
574
- function qt(e, a, t) {
574
+ function Gt(e, a, t) {
575
575
  m(e, "duration", a, t), M(e, a, t), p(e, "fromColor", a, t), p(e, "toColor", a, t), z(e, a, t);
576
576
  }
577
- function Ut(e, a, t) {
577
+ function Kt(e, a, t) {
578
578
  m(e, "staggerDelay", a, t), M(e, a, t), z(e, a, t);
579
579
  }
580
580
  function v(e, a, t) {
581
- m(e, "fadeIn", a, t), m(e, "fadeOut", a, t), m(e, "draw", a, t), M(e, a, t), Ht(e, a, t);
581
+ m(e, "fadeIn", a, t), m(e, "fadeOut", a, t), m(e, "draw", a, t), M(e, a, t), Qt(e, a, t);
582
582
  }
583
583
  function B(e, a, t) {
584
- m(e, "fadeIn", a, t), m(e, "fadeOut", a, t), m(e, "draw", a, t), M(e, a, t), Gt(e, a, t);
584
+ m(e, "fadeIn", a, t), m(e, "fadeOut", a, t), m(e, "draw", a, t), M(e, a, t), Xt(e, a, t);
585
585
  }
586
- const ne = ["none", "circle", "ellipse"];
587
- function Ht(e, a, t) {
588
- if (P(e, "rotation", a, t), I(e, "rotationOrigin", a, t), I(e, "translate", a, t), P(e, "zIndex", a, t), e.scale !== void 0) {
586
+ const ce = ["none", "circle", "ellipse"];
587
+ function Qt(e, a, t) {
588
+ if (F(e, "rotation", a, t), I(e, "rotationOrigin", a, t), I(e, "translate", a, t), F(e, "zIndex", a, t), e.scale !== void 0) {
589
589
  const r = e.scale;
590
590
  typeof r == "number" || Array.isArray(r) && r.length === 2 && typeof r[0] == "number" && typeof r[1] == "number" || t.push({ path: `${a}.scale`, message: '"scale" must be a number or [number, number]', severity: "error" });
591
591
  }
592
592
  }
593
- function Gt(e, a, t) {
594
- P(e, "rotation", a, t), I(e, "rotationOrigin", a, t), I(e, "translate", a, t), P(e, "zIndex", a, t);
593
+ function Xt(e, a, t) {
594
+ F(e, "rotation", a, t), I(e, "rotationOrigin", a, t), I(e, "translate", a, t), F(e, "zIndex", a, t);
595
595
  }
596
- function Kt(e, a, t) {
597
- typeof e.src != "string" && t.push({ path: `${a}.src`, message: 'Image requires a "src" string', severity: "error" }), h(e, "x", a, t), h(e, "y", a, t), T(e, "width", a, t), T(e, "height", a, t), p(e, "preserveAspectRatio", a, t), e.borderRadius !== void 0 && (typeof e.borderRadius != "number" || e.borderRadius < 0) && t.push({ path: `${a}.borderRadius`, message: '"borderRadius" must be a number >= 0', severity: "error" }), e.clipShape !== void 0 && (ne.includes(e.clipShape) || t.push({
596
+ function Jt(e, a, t) {
597
+ const r = typeof e.src == "string", i = typeof e.ref == "string";
598
+ !r && !i && t.push({ path: `${a}.src`, message: 'Image requires a "src" or "ref" string', severity: "error" }), h(e, "x", a, t), h(e, "y", a, t), P(e, "width", a, t), P(e, "height", a, t), p(e, "preserveAspectRatio", a, t), e.borderRadius !== void 0 && (typeof e.borderRadius != "number" || e.borderRadius < 0) && t.push({ path: `${a}.borderRadius`, message: '"borderRadius" must be a number >= 0', severity: "error" }), e.clipShape !== void 0 && (ce.includes(e.clipShape) || t.push({
598
599
  path: `${a}.clipShape`,
599
- message: `Invalid clipShape "${e.clipShape}". Must be one of: ${ne.join(", ")}`,
600
+ message: `Invalid clipShape "${e.clipShape}". Must be one of: ${ce.join(", ")}`,
600
601
  severity: "error"
601
602
  })), v(e, a, t);
602
603
  }
603
- function Qt(e, a, t) {
604
+ function Yt(e, a, t) {
604
605
  z(e, a, t), v(e, a, t);
605
606
  }
606
- function Xt(e, a, t) {
607
- h(e, "x", a, t), h(e, "y", a, t), T(e, "width", a, t), T(e, "height", a, t), Array.isArray(e.bars) || t.push({ path: `${a}.bars`, message: 'BarChart requires a "bars" array', severity: "error" }), v(e, a, t);
607
+ function Zt(e, a, t) {
608
+ h(e, "x", a, t), h(e, "y", a, t), P(e, "width", a, t), P(e, "height", a, t), Array.isArray(e.bars) || t.push({ path: `${a}.bars`, message: 'BarChart requires a "bars" array', severity: "error" }), v(e, a, t);
608
609
  }
609
610
  function M(e, a, t) {
610
611
  if (e.easing !== void 0) {
611
612
  if (typeof e.easing == "string") {
612
613
  if (!H.includes(e.easing)) {
613
- const r = fe(e.easing, H);
614
+ const r = ge(e.easing, H);
614
615
  t.push({
615
616
  path: `${a}.easing`,
616
617
  message: `Unknown easing "${e.easing}".${r} Available: ${H.join(", ")}`,
@@ -636,50 +637,50 @@ function M(e, a, t) {
636
637
  function h(e, a, t, r) {
637
638
  typeof e[a] != "number" && r.push({ path: `${t}.${a}`, message: `Required numeric field "${a}" is missing or not a number`, severity: "error" });
638
639
  }
639
- function T(e, a, t, r) {
640
+ function P(e, a, t, r) {
640
641
  (typeof e[a] != "number" || e[a] <= 0) && r.push({ path: `${t}.${a}`, message: `"${a}" must be a positive number`, severity: "error" });
641
642
  }
642
- function Jt(e, a, t, r) {
643
+ function ea(e, a, t, r) {
643
644
  const i = e[a];
644
645
  (typeof i != "number" || i <= 0 || !Number.isInteger(i)) && r.push({ path: `${t}.${a}`, message: `"${a}" must be a positive integer`, severity: "error" });
645
646
  }
646
647
  function m(e, a, t, r) {
647
648
  e[a] !== void 0 && (typeof e[a] != "number" || e[a] <= 0) && r.push({ path: `${t}.${a}`, message: `"${a}" must be a positive number`, severity: "error" });
648
649
  }
649
- function Yt(e, a, t, r) {
650
+ function ta(e, a, t, r) {
650
651
  const i = e[a];
651
652
  i !== void 0 && (typeof i != "number" || i <= 0 || !Number.isInteger(i)) && r.push({ path: `${t}.${a}`, message: `"${a}" must be a positive integer`, severity: "error" });
652
653
  }
653
654
  function p(e, a, t, r) {
654
655
  e[a] !== void 0 && typeof e[a] != "string" && r.push({ path: `${t}.${a}`, message: `"${a}" must be a string`, severity: "error" });
655
656
  }
656
- function P(e, a, t, r) {
657
+ function F(e, a, t, r) {
657
658
  e[a] !== void 0 && typeof e[a] != "number" && r.push({ path: `${t}.${a}`, message: `"${a}" must be a number`, severity: "error" });
658
659
  }
659
- function W(e, a, t, r) {
660
+ function N(e, a, t, r) {
660
661
  e[a] !== void 0 && typeof e[a] != "boolean" && r.push({ path: `${t}.${a}`, message: `"${a}" must be a boolean`, severity: "error" });
661
662
  }
662
663
  function I(e, a, t, r) {
663
664
  const i = e[a];
664
665
  i !== void 0 && (!Array.isArray(i) || i.length !== 2 || typeof i[0] != "number" || typeof i[1] != "number") && r.push({ path: `${t}.${a}`, message: `"${a}" must be [number, number]`, severity: "error" });
665
666
  }
666
- function fe(e, a) {
667
+ function ge(e, a) {
667
668
  const t = e.toLowerCase(), r = a.find((n) => n.toLowerCase() === t);
668
669
  if (r) return ` Did you mean '${r}'?`;
669
670
  const i = a.find((n) => n.toLowerCase().startsWith(t.slice(0, 4)));
670
671
  return i ? ` Did you mean '${i}'?` : "";
671
672
  }
672
- const Zt = {
673
+ const aa = {
673
674
  card: [640, 360],
674
675
  slide: [1280, 720],
675
676
  square: [600, 600]
676
677
  };
677
678
  function j(e, a, t) {
678
679
  if (!e) return { width: a, height: t };
679
- const [r, i] = Zt[e];
680
+ const [r, i] = aa[e];
680
681
  return { width: a ?? r, height: t ?? i };
681
682
  }
682
- function ge(e, a) {
683
+ function me(e, a) {
683
684
  switch (e.type) {
684
685
  case "scene":
685
686
  return J(e, a);
@@ -698,15 +699,15 @@ function ge(e, a) {
698
699
  a
699
700
  );
700
701
  }
701
- return oe(e, a);
702
+ return ye(e, a);
702
703
  case "presentation":
703
- return ea(e, a);
704
+ return ra(e, a);
704
705
  }
705
706
  }
706
707
  function J(e, a) {
707
708
  const t = (a == null ? void 0 : a.frame) !== void 0, { width: r, height: i } = j(e.preset, e.width, e.height);
708
709
  return /* @__PURE__ */ l(
709
- Le,
710
+ Be,
710
711
  {
711
712
  width: r,
712
713
  height: i,
@@ -720,10 +721,10 @@ function J(e, a) {
720
721
  }
721
722
  );
722
723
  }
723
- function oe(e, a) {
724
+ function ye(e, a) {
724
725
  const { width: t, height: r } = j(e.preset, e.width, e.height);
725
726
  return /* @__PURE__ */ l(
726
- Ve,
727
+ je,
727
728
  {
728
729
  ref: a == null ? void 0 : a.playerRef,
729
730
  width: t,
@@ -741,10 +742,10 @@ function oe(e, a) {
741
742
  }
742
743
  );
743
744
  }
744
- function ea(e, a) {
745
+ function ra(e, a) {
745
746
  const { width: t, height: r } = j(e.preset, e.width, e.height);
746
747
  return /* @__PURE__ */ l(
747
- We,
748
+ Ve,
748
749
  {
749
750
  width: t,
750
751
  height: r,
@@ -754,22 +755,22 @@ function ea(e, a) {
754
755
  showHUD: e.showHud,
755
756
  showNotes: e.showNotes,
756
757
  colorScheme: a == null ? void 0 : a.colorScheme,
757
- children: e.slides.map((i, n) => ta(i, n))
758
+ children: e.slides.map((i, n) => ia(i, n))
758
759
  }
759
760
  );
760
761
  }
761
- function ta(e, a) {
762
+ function ia(e, a) {
762
763
  var t;
763
- return /* @__PURE__ */ l(Be, { title: e.title, notes: e.notes, background: u(e.background), children: (t = e.children) == null ? void 0 : t.map((r, i) => w(r, i)) }, a);
764
+ return /* @__PURE__ */ l(qe, { title: e.title, notes: e.notes, background: u(e.background), children: (t = e.children) == null ? void 0 : t.map((r, i) => w(r, i)) }, a);
764
765
  }
765
766
  function w(e, a) {
766
767
  var t, r, i, n;
767
768
  switch (e.type) {
768
769
  case "sequence":
769
- return /* @__PURE__ */ l(ot, { from: e.from, durationInFrames: e.durationInFrames, name: e.name, children: e.children.map((s, c) => w(s, c)) }, a);
770
+ return /* @__PURE__ */ l(yt, { from: e.from, durationInFrames: e.durationInFrames, name: e.name, children: e.children.map((s, c) => w(s, c)) }, a);
770
771
  case "group":
771
772
  return /* @__PURE__ */ l(
772
- gt,
773
+ mt,
773
774
  {
774
775
  fadeIn: e.fadeIn,
775
776
  fadeOut: e.fadeOut,
@@ -785,7 +786,7 @@ function w(e, a) {
785
786
  );
786
787
  case "bezierCurve":
787
788
  return /* @__PURE__ */ l(
788
- ft,
789
+ gt,
789
790
  {
790
791
  x1: e.x1,
791
792
  y1: e.y1,
@@ -814,7 +815,7 @@ function w(e, a) {
814
815
  );
815
816
  case "circle":
816
817
  return /* @__PURE__ */ l(
817
- ht,
818
+ ot,
818
819
  {
819
820
  cx: e.cx,
820
821
  cy: e.cy,
@@ -837,7 +838,7 @@ function w(e, a) {
837
838
  );
838
839
  case "line":
839
840
  return /* @__PURE__ */ l(
840
- ut,
841
+ ft,
841
842
  {
842
843
  x1: e.x1,
843
844
  y1: e.y1,
@@ -861,7 +862,7 @@ function w(e, a) {
861
862
  );
862
863
  case "arrow":
863
864
  return /* @__PURE__ */ l(
864
- lt,
865
+ ht,
865
866
  {
866
867
  x1: e.x1,
867
868
  y1: e.y1,
@@ -886,7 +887,7 @@ function w(e, a) {
886
887
  );
887
888
  case "rect":
888
889
  return /* @__PURE__ */ l(
889
- ct,
890
+ ut,
890
891
  {
891
892
  x: e.x,
892
893
  y: e.y,
@@ -913,7 +914,7 @@ function w(e, a) {
913
914
  );
914
915
  case "polygon":
915
916
  return /* @__PURE__ */ l(
916
- st,
917
+ lt,
917
918
  {
918
919
  points: e.points,
919
920
  fill: u(e.fill),
@@ -960,9 +961,10 @@ function w(e, a) {
960
961
  );
961
962
  case "image":
962
963
  return /* @__PURE__ */ l(
963
- nt,
964
+ ct,
964
965
  {
965
966
  src: e.src,
967
+ imageRef: e.ref,
966
968
  x: e.x,
967
969
  y: e.y,
968
970
  width: e.width,
@@ -984,7 +986,7 @@ function w(e, a) {
984
986
  );
985
987
  case "axes":
986
988
  return /* @__PURE__ */ l(
987
- it,
989
+ st,
988
990
  {
989
991
  domain: e.domain,
990
992
  range: e.range,
@@ -1012,7 +1014,7 @@ function w(e, a) {
1012
1014
  case "functionPlot": {
1013
1015
  let s;
1014
1016
  try {
1015
- s = It(e.fn);
1017
+ s = Ct(e.fn);
1016
1018
  } catch {
1017
1019
  return /* @__PURE__ */ l(
1018
1020
  U,
@@ -1028,7 +1030,7 @@ function w(e, a) {
1028
1030
  );
1029
1031
  }
1030
1032
  return /* @__PURE__ */ l(
1031
- rt,
1033
+ nt,
1032
1034
  {
1033
1035
  fn: (c) => s({ x: c }),
1034
1036
  domain: e.domain,
@@ -1051,7 +1053,7 @@ function w(e, a) {
1051
1053
  }
1052
1054
  case "vector":
1053
1055
  return /* @__PURE__ */ l(
1054
- at,
1056
+ it,
1055
1057
  {
1056
1058
  from: e.from,
1057
1059
  to: e.to,
@@ -1078,7 +1080,7 @@ function w(e, a) {
1078
1080
  case "vectorField": {
1079
1081
  let s;
1080
1082
  try {
1081
- s = St(e.fn);
1083
+ s = Ot(e.fn);
1082
1084
  } catch {
1083
1085
  return /* @__PURE__ */ l(
1084
1086
  U,
@@ -1094,7 +1096,7 @@ function w(e, a) {
1094
1096
  );
1095
1097
  }
1096
1098
  return /* @__PURE__ */ l(
1097
- tt,
1099
+ rt,
1098
1100
  {
1099
1101
  fn: (c, y) => s({ x: c, y }),
1100
1102
  domain: e.domain,
@@ -1121,7 +1123,7 @@ function w(e, a) {
1121
1123
  }
1122
1124
  case "matrix":
1123
1125
  return /* @__PURE__ */ l(
1124
- et,
1126
+ at,
1125
1127
  {
1126
1128
  values: e.values,
1127
1129
  x: e.x,
@@ -1143,7 +1145,7 @@ function w(e, a) {
1143
1145
  );
1144
1146
  case "graph":
1145
1147
  return /* @__PURE__ */ l(
1146
- Ze,
1148
+ tt,
1147
1149
  {
1148
1150
  nodes: e.nodes,
1149
1151
  edges: e.edges,
@@ -1166,7 +1168,7 @@ function w(e, a) {
1166
1168
  );
1167
1169
  case "latex":
1168
1170
  return /* @__PURE__ */ l(
1169
- Ye,
1171
+ et,
1170
1172
  {
1171
1173
  expression: e.expression,
1172
1174
  x: e.x,
@@ -1187,7 +1189,7 @@ function w(e, a) {
1187
1189
  );
1188
1190
  case "barChart":
1189
1191
  return /* @__PURE__ */ l(
1190
- Je,
1192
+ Ze,
1191
1193
  {
1192
1194
  bars: e.bars,
1193
1195
  x: e.x,
@@ -1213,16 +1215,16 @@ function w(e, a) {
1213
1215
  a
1214
1216
  );
1215
1217
  case "fadeIn":
1216
- return /* @__PURE__ */ l(Xe, { duration: e.duration, easing: f(e.easing), children: e.children.map((s, c) => w(s, c)) }, a);
1218
+ return /* @__PURE__ */ l(Ye, { duration: e.duration, easing: f(e.easing), children: e.children.map((s, c) => w(s, c)) }, a);
1217
1219
  case "fadeOut":
1218
- return /* @__PURE__ */ l(Qe, { duration: e.duration, totalFrames: e.totalFrames, easing: f(e.easing), children: e.children.map((s, c) => w(s, c)) }, a);
1220
+ return /* @__PURE__ */ l(Je, { duration: e.duration, totalFrames: e.totalFrames, easing: f(e.easing), children: e.children.map((s, c) => w(s, c)) }, a);
1219
1221
  case "draw":
1220
- return /* @__PURE__ */ l(Ke, { duration: e.duration, pathLength: e.pathLength, easing: f(e.easing), children: w(e.children[0], 0) }, a);
1222
+ return /* @__PURE__ */ l(Xe, { duration: e.duration, pathLength: e.pathLength, easing: f(e.easing), children: w(e.children[0], 0) }, a);
1221
1223
  case "write":
1222
- return /* @__PURE__ */ l(Ge, { duration: e.duration, easing: f(e.easing), children: e.children.map((s, c) => w(s, c)) }, a);
1224
+ return /* @__PURE__ */ l(Qe, { duration: e.duration, easing: f(e.easing), children: e.children.map((s, c) => w(s, c)) }, a);
1223
1225
  case "transform":
1224
1226
  return /* @__PURE__ */ l(
1225
- He,
1227
+ Ke,
1226
1228
  {
1227
1229
  duration: e.duration,
1228
1230
  easing: f(e.easing),
@@ -1236,7 +1238,7 @@ function w(e, a) {
1236
1238
  );
1237
1239
  case "morph":
1238
1240
  return /* @__PURE__ */ l(
1239
- Ue,
1241
+ Ge,
1240
1242
  {
1241
1243
  duration: e.duration,
1242
1244
  easing: f(e.easing),
@@ -1251,33 +1253,33 @@ function w(e, a) {
1251
1253
  a
1252
1254
  );
1253
1255
  case "stagger":
1254
- return /* @__PURE__ */ l(qe, { staggerDelay: e.staggerDelay, easing: f(e.easing), children: e.children.map((s, c) => w(s, c)) }, a);
1256
+ return /* @__PURE__ */ l(He, { staggerDelay: e.staggerDelay, easing: f(e.easing), children: e.children.map((s, c) => w(s, c)) }, a);
1255
1257
  case "parallel":
1256
- return /* @__PURE__ */ l(je, { children: e.children.map((s, c) => w(s, c)) }, a);
1258
+ return /* @__PURE__ */ l(Ue, { children: e.children.map((s, c) => w(s, c)) }, a);
1257
1259
  case "scene":
1258
1260
  return /* @__PURE__ */ l(K.Fragment, { children: J(e) }, a);
1259
1261
  case "player":
1260
- return /* @__PURE__ */ l(K.Fragment, { children: oe(e) }, a);
1262
+ return /* @__PURE__ */ l(K.Fragment, { children: ye(e) }, a);
1261
1263
  default:
1262
1264
  return null;
1263
1265
  }
1264
1266
  }
1265
- function aa(e) {
1267
+ function na(e) {
1266
1268
  if (typeof window > "u" || typeof window.matchMedia != "function") return () => {
1267
1269
  };
1268
1270
  const a = window.matchMedia("(prefers-color-scheme: dark)");
1269
1271
  return a.addEventListener("change", e), () => a.removeEventListener("change", e);
1270
1272
  }
1271
- function ra() {
1273
+ function sa() {
1272
1274
  return typeof window > "u" || typeof window.matchMedia != "function" ? !0 : window.matchMedia("(prefers-color-scheme: dark)").matches;
1273
1275
  }
1274
- function ia() {
1276
+ function ca() {
1275
1277
  return !0;
1276
1278
  }
1277
- function na() {
1278
- return vt(aa, ra, ia);
1279
+ function la() {
1280
+ return St(na, sa, ca);
1279
1281
  }
1280
- class sa extends K.Component {
1282
+ class ua extends K.Component {
1281
1283
  constructor() {
1282
1284
  super(...arguments), this.state = { error: null };
1283
1285
  }
@@ -1303,42 +1305,42 @@ class sa extends K.Component {
1303
1305
  ) : this.props.children;
1304
1306
  }
1305
1307
  }
1306
- const da = xt(function({ dsl: a, className: t, style: r, theme: i, colorScheme: n, poster: s, controls: c, autoPlay: y, loop: d, fitToContainer: S, onPlayStateChange: b, onRenderError: g, fallback: x, onError: C }, O) {
1307
- const $ = dt(null), _ = na();
1308
- wt(O, () => ({
1308
+ const ka = vt(function({ dsl: a, className: t, style: r, theme: i, colorScheme: n, poster: s, controls: c, autoPlay: y, loop: d, fitToContainer: S, onPlayStateChange: b, onRenderError: o, fallback: x, onError: O, imageResolver: $ }, W) {
1309
+ const C = kt(null), ee = la();
1310
+ It(W, () => ({
1309
1311
  getSvgElement: () => {
1310
- var o;
1311
- return ((o = $.current) == null ? void 0 : o.getSvgElement()) ?? null;
1312
+ var g;
1313
+ return ((g = C.current) == null ? void 0 : g.getSvgElement()) ?? null;
1312
1314
  },
1313
- seekToFrame: (o) => {
1314
- var F;
1315
- return (F = $.current) == null ? void 0 : F.seekToFrame(o);
1315
+ seekToFrame: (g) => {
1316
+ var T;
1317
+ return (T = C.current) == null ? void 0 : T.seekToFrame(g);
1316
1318
  },
1317
1319
  getTotalFrames: () => {
1318
- var o;
1319
- return ((o = $.current) == null ? void 0 : o.getTotalFrames()) ?? 0;
1320
+ var g;
1321
+ return ((g = C.current) == null ? void 0 : g.getTotalFrames()) ?? 0;
1320
1322
  },
1321
1323
  play: () => {
1322
- var o;
1323
- return (o = $.current) == null ? void 0 : o.play();
1324
+ var g;
1325
+ return (g = C.current) == null ? void 0 : g.play();
1324
1326
  },
1325
1327
  pause: () => {
1326
- var o;
1327
- return (o = $.current) == null ? void 0 : o.pause();
1328
+ var g;
1329
+ return (g = C.current) == null ? void 0 : g.pause();
1328
1330
  },
1329
1331
  isPlaying: () => {
1330
- var o;
1331
- return ((o = $.current) == null ? void 0 : o.isPlaying()) ?? !1;
1332
+ var g;
1333
+ return ((g = C.current) == null ? void 0 : g.isPlaying()) ?? !1;
1332
1334
  }
1333
1335
  }));
1334
- const ee = le(a);
1335
- if (!ee.valid) {
1336
- const o = ee.errors.filter((k) => k.severity === "error").map((k) => ({ path: k.path, message: k.message }));
1337
- C == null || C(o);
1338
- const F = /* @__PURE__ */ new Map();
1339
- for (const k of o) {
1340
- const D = k.path.split("."), N = D.length > 1 ? D.slice(0, -1).join(".") : k.path, L = F.get(N) ?? [];
1341
- L.push(k), F.set(N, L);
1336
+ const te = he(a);
1337
+ if (!te.valid) {
1338
+ const g = te.errors.filter((k) => k.severity === "error").map((k) => ({ path: k.path, message: k.message }));
1339
+ O == null || O(g);
1340
+ const T = /* @__PURE__ */ new Map();
1341
+ for (const k of g) {
1342
+ const _ = k.path.split("."), D = _.length > 1 ? _.slice(0, -1).join(".") : k.path, L = T.get(D) ?? [];
1343
+ L.push(k), T.set(D, L);
1342
1344
  }
1343
1345
  return /* @__PURE__ */ E(
1344
1346
  "div",
@@ -1349,20 +1351,20 @@ const da = xt(function({ dsl: a, className: t, style: r, theme: i, colorScheme:
1349
1351
  children: [
1350
1352
  /* @__PURE__ */ E("strong", { children: [
1351
1353
  "Elucim DSL Validation Errors (",
1352
- o.length,
1354
+ g.length,
1353
1355
  "):"
1354
1356
  ] }),
1355
- [...F.entries()].map(([k, D]) => /* @__PURE__ */ E("details", { open: !0, style: { marginTop: 8 }, children: [
1357
+ [...T.entries()].map(([k, _]) => /* @__PURE__ */ E("details", { open: !0, style: { marginTop: 8 }, children: [
1356
1358
  /* @__PURE__ */ E("summary", { style: { cursor: "pointer", fontWeight: "bold" }, children: [
1357
1359
  k,
1358
1360
  " (",
1359
- D.length,
1361
+ _.length,
1360
1362
  ")"
1361
1363
  ] }),
1362
- /* @__PURE__ */ l("ul", { style: { margin: "4px 0", paddingLeft: 20 }, children: D.map((N, L) => /* @__PURE__ */ E("li", { children: [
1363
- /* @__PURE__ */ l("code", { style: { color: "var(--elucim-warning, #ffa07a)" }, children: N.path }),
1364
+ /* @__PURE__ */ l("ul", { style: { margin: "4px 0", paddingLeft: 20 }, children: _.map((D, L) => /* @__PURE__ */ E("li", { children: [
1365
+ /* @__PURE__ */ l("code", { style: { color: "var(--elucim-warning, #ffa07a)" }, children: D.path }),
1364
1366
  ": ",
1365
- N.message
1367
+ D.message
1366
1368
  ] }, L)) })
1367
1369
  ] }, k)),
1368
1370
  /* @__PURE__ */ E("details", { style: { marginTop: 12 }, children: [
@@ -1373,22 +1375,22 @@ const da = xt(function({ dsl: a, className: t, style: r, theme: i, colorScheme:
1373
1375
  }
1374
1376
  );
1375
1377
  }
1376
- const me = mt(i);
1377
- let te = {};
1378
- n && (te = (n === "auto" ? _ : n === "dark") ? yt : bt);
1379
- const q = s !== void 0 ? ca(s, a) : void 0, ye = n ? n === "auto" ? _ ? "dark" : "light" : n : void 0, be = ge(a.root, {
1378
+ const be = bt(i);
1379
+ let ae = {};
1380
+ n && (ae = (n === "auto" ? ee : n === "dark") ? dt : wt);
1381
+ const q = s !== void 0 ? ha(s, a) : void 0, xe = n ? n === "auto" ? ee ? "dark" : "light" : n : void 0, de = me(a.root, {
1380
1382
  frame: q == null ? void 0 : q.frame,
1381
- playerRef: $,
1382
- colorScheme: ye,
1383
+ playerRef: C,
1384
+ colorScheme: xe,
1383
1385
  controls: c,
1384
1386
  autoPlay: y,
1385
1387
  loop: d,
1386
1388
  fitToContainer: S,
1387
1389
  onPlayStateChange: b
1388
- });
1389
- return /* @__PURE__ */ l("div", { className: t, style: { ...te, ...me, ...r }, "data-testid": "dsl-root", children: /* @__PURE__ */ l(sa, { onRenderError: g, fallback: x, children: be }) });
1390
+ }), re = /* @__PURE__ */ l("div", { className: t, style: { ...ae, ...be, ...r }, "data-testid": "dsl-root", children: /* @__PURE__ */ l(ua, { onRenderError: o, fallback: x, children: de }) });
1391
+ return $ ? /* @__PURE__ */ l(xt, { resolver: $, children: re }) : re;
1390
1392
  });
1391
- function ca(e, a) {
1393
+ function ha(e, a) {
1392
1394
  if (e === "first") return { frame: 0 };
1393
1395
  if (e === "last") {
1394
1396
  const r = a.root.durationInFrames ?? 1;
@@ -1396,8 +1398,8 @@ function ca(e, a) {
1396
1398
  }
1397
1399
  return { frame: e };
1398
1400
  }
1399
- function la(e, a, t) {
1400
- const r = le(e);
1401
+ function fa(e, a, t) {
1402
+ const r = he(e);
1401
1403
  if (!r.valid) {
1402
1404
  const s = r.errors.filter((c) => c.severity === "error");
1403
1405
  throw new Error(
@@ -1408,18 +1410,18 @@ ${s.map((c) => ` ${c.path}: ${c.message}`).join(`
1408
1410
  }
1409
1411
  const i = { ...e.root };
1410
1412
  t != null && t.width && (i.width = t.width), t != null && t.height && (i.height = t.height);
1411
- const n = ge(i, { frame: a });
1412
- return kt(n);
1413
+ const n = me(i, { frame: a });
1414
+ return $t(n);
1413
1415
  }
1414
- function se(e) {
1416
+ function le(e) {
1415
1417
  let a;
1416
1418
  do
1417
1419
  a = e, e = e.replace(/var\(--[a-z][\w-]*,\s*([^)]+)\)/gi, "$1");
1418
1420
  while (e !== a);
1419
1421
  return e = e.replace(/var\(--[a-z][\w-]*\)/gi, "none"), e = e.replace(/light-dark\([^,]+,\s*([^)]+)\)/gi, "$1"), e;
1420
1422
  }
1421
- async function wa(e, a, t) {
1422
- const r = (t == null ? void 0 : t.scale) ?? 2, n = la(e, a, {
1423
+ async function Ia(e, a, t) {
1424
+ const r = (t == null ? void 0 : t.scale) ?? 2, n = fa(e, a, {
1423
1425
  width: t == null ? void 0 : t.width,
1424
1426
  height: t == null ? void 0 : t.height
1425
1427
  }).match(/<svg[\s\S]*<\/svg>/);
@@ -1428,24 +1430,24 @@ async function wa(e, a, t) {
1428
1430
  let s = n[0];
1429
1431
  const c = s.match(/viewBox="0 0 (\d+(?:\.\d+)?) (\d+(?:\.\d+)?)"/), y = (t == null ? void 0 : t.width) ?? (c ? parseFloat(c[1]) : 800), d = (t == null ? void 0 : t.height) ?? (c ? parseFloat(c[2]) : 600), S = Math.round(y * r), b = Math.round(d * r);
1430
1432
  s = s.replace(/width="100%"/, `width="${S}"`).replace(/height="100%"/, `height="${b}"`), s.includes("xmlns=") || (s = s.replace("<svg", '<svg xmlns="http://www.w3.org/2000/svg"')), s = s.replace(/style="[^"]*position:\s*absolute[^"]*"/, "");
1431
- let g = e.root.background ?? "#ffffff";
1432
- g.startsWith("$") && (g = u(g) ?? "#ffffff"), g = se(g);
1433
- const x = `<rect width="${y}" height="${d}" fill="${g}"/>`;
1434
- s = s.replace(/>/, `>${x}`), s = se(s);
1435
- const O = `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(s)))}`;
1433
+ let o = e.root.background ?? "#ffffff";
1434
+ o.startsWith("$") && (o = u(o) ?? "#ffffff"), o = le(o);
1435
+ const x = `<rect width="${y}" height="${d}" fill="${o}"/>`;
1436
+ s = s.replace(/>/, `>${x}`), s = le(s);
1437
+ const $ = `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(s)))}`;
1436
1438
  if (typeof Image < "u" && typeof document < "u")
1437
- return ha(O, S, b);
1439
+ return ga($, S, b);
1438
1440
  if (typeof OffscreenCanvas < "u")
1439
- return ua(O, S, b);
1441
+ return oa($, S, b);
1440
1442
  throw new Error("renderToPng requires Image+document (browser) or OffscreenCanvas (worker)");
1441
1443
  }
1442
- async function ua(e, a, t) {
1444
+ async function oa(e, a, t) {
1443
1445
  const i = await (await fetch(e)).blob(), n = await createImageBitmap(i, { resizeWidth: a, resizeHeight: t }), s = new OffscreenCanvas(a, t);
1444
1446
  s.getContext("2d").drawImage(n, 0, 0, a, t), n.close();
1445
1447
  const d = await (await s.convertToBlob({ type: "image/png" })).arrayBuffer();
1446
1448
  return new Uint8Array(d);
1447
1449
  }
1448
- function ha(e, a, t) {
1450
+ function ga(e, a, t) {
1449
1451
  return new Promise((r, i) => {
1450
1452
  const n = new Image();
1451
1453
  n.onload = () => {
@@ -1460,7 +1462,7 @@ function ha(e, a, t) {
1460
1462
  }, n.onerror = () => i(new Error("Failed to load SVG data URI for PNG render")), n.src = e;
1461
1463
  });
1462
1464
  }
1463
- class fa {
1465
+ class ma {
1464
1466
  constructor(a, t = 30, r = 900, i = 640) {
1465
1467
  this.elements = [], this.cursor = 0, this.theme = a, this._fps = t, this._width = r, this._height = i;
1466
1468
  }
@@ -1681,12 +1683,12 @@ class fa {
1681
1683
  boxRow(a, t) {
1682
1684
  const r = (t == null ? void 0 : t.boxWidth) ?? 80, i = (t == null ? void 0 : t.boxHeight) ?? 40, n = (t == null ? void 0 : t.gap) ?? 12, s = (t == null ? void 0 : t.y) ?? 250, c = a.length * r + (a.length - 1) * n, y = (this._width - c) / 2;
1683
1685
  t == null || t.fadeIn;
1684
- const d = a.map((b, g) => {
1685
- const x = y + g * (r + n);
1686
+ const d = a.map((b, o) => {
1687
+ const x = y + o * (r + n);
1686
1688
  return { x, y: s, w: r, h: i, cx: x + r / 2, cy: s + i / 2 };
1687
- }), S = a.map((b, g) => {
1688
- var $, _;
1689
- const x = d[g], C = (($ = t == null ? void 0 : t.colors) == null ? void 0 : $[g]) ?? this.theme.boxFill, O = ((_ = t == null ? void 0 : t.strokeColors) == null ? void 0 : _[g]) ?? this.theme.boxStroke;
1689
+ }), S = a.map((b, o) => {
1690
+ var W, C;
1691
+ const x = d[o], O = ((W = t == null ? void 0 : t.colors) == null ? void 0 : W[o]) ?? this.theme.boxFill, $ = ((C = t == null ? void 0 : t.strokeColors) == null ? void 0 : C[o]) ?? this.theme.boxStroke;
1690
1692
  return {
1691
1693
  type: "group",
1692
1694
  children: [
@@ -1696,8 +1698,8 @@ class fa {
1696
1698
  y: x.y,
1697
1699
  width: r,
1698
1700
  height: i,
1699
- fill: C,
1700
- stroke: O,
1701
+ fill: O,
1702
+ stroke: $,
1701
1703
  strokeWidth: 1.5,
1702
1704
  rx: 6
1703
1705
  },
@@ -1727,29 +1729,29 @@ class fa {
1727
1729
  const r = (t == null ? void 0 : t.boxWidth) ?? 160, i = (t == null ? void 0 : t.boxHeight) ?? 36, n = (t == null ? void 0 : t.gap) ?? 8, s = (t == null ? void 0 : t.y) ?? 150, c = (t == null ? void 0 : t.x) ?? this.cx;
1728
1730
  t == null || t.fadeIn;
1729
1731
  const y = a.map((S, b) => {
1730
- const g = s + b * (i + n);
1731
- return { x: c - r / 2, y: g, w: r, h: i, cx: c, cy: g + i / 2 };
1732
+ const o = s + b * (i + n);
1733
+ return { x: c - r / 2, y: o, w: r, h: i, cx: c, cy: o + i / 2 };
1732
1734
  }), d = a.map((S, b) => {
1733
- var C, O;
1734
- const g = y[b], x = ((C = t == null ? void 0 : t.colors) == null ? void 0 : C[b]) ?? this.theme.boxFill;
1735
+ var O, $;
1736
+ const o = y[b], x = ((O = t == null ? void 0 : t.colors) == null ? void 0 : O[b]) ?? this.theme.boxFill;
1735
1737
  return {
1736
1738
  type: "group",
1737
1739
  children: [
1738
1740
  {
1739
1741
  type: "rect",
1740
- x: g.x,
1741
- y: g.y,
1742
+ x: o.x,
1743
+ y: o.y,
1742
1744
  width: r,
1743
1745
  height: i,
1744
1746
  fill: x,
1745
- stroke: (O = t == null ? void 0 : t.colors) != null && O[b] ? t.colors[b] : this.theme.boxStroke,
1747
+ stroke: ($ = t == null ? void 0 : t.colors) != null && $[b] ? t.colors[b] : this.theme.boxStroke,
1746
1748
  strokeWidth: 1.5,
1747
1749
  rx: 6
1748
1750
  },
1749
1751
  {
1750
1752
  type: "text",
1751
- x: g.cx,
1752
- y: g.cy + 5,
1753
+ x: o.cx,
1754
+ y: o.cy + 5,
1753
1755
  content: S,
1754
1756
  fontSize: (t == null ? void 0 : t.fontSize) ?? 13,
1755
1757
  fill: (t == null ? void 0 : t.textColor) ?? this.theme.foreground,
@@ -1845,7 +1847,7 @@ class fa {
1845
1847
  return { elements: this.elements, durationInFrames: a };
1846
1848
  }
1847
1849
  }
1848
- const ga = {
1850
+ const ya = {
1849
1851
  foreground: "#c8d6e5",
1850
1852
  background: "#0a0a1e",
1851
1853
  title: "#e0e7ff",
@@ -1863,7 +1865,7 @@ const ga = {
1863
1865
  boxFill: "rgba(79,195,247,0.12)",
1864
1866
  boxStroke: "#4fc3f7",
1865
1867
  palette: ["#4fc3f7", "#a78bfa", "#f472b6", "#34d399", "#fbbf24", "#fb923c", "#6366f1", "#22d3ee"]
1866
- }, va = {
1868
+ }, Sa = {
1867
1869
  foreground: "#334155",
1868
1870
  background: "#f8fafc",
1869
1871
  title: "#1e293b",
@@ -1882,9 +1884,9 @@ const ga = {
1882
1884
  boxStroke: "#2563eb",
1883
1885
  palette: ["#2563eb", "#7c3aed", "#db2777", "#16a34a", "#d97706", "#ea580c", "#4f46e5", "#0891b2"]
1884
1886
  };
1885
- class oa {
1887
+ class ba {
1886
1888
  constructor(a, t, r) {
1887
- this._slides = [], this._title = a, this._theme = t ?? ga, this._opts = {
1889
+ this._slides = [], this._title = a, this._theme = t ?? ya, this._opts = {
1888
1890
  width: 900,
1889
1891
  height: 640,
1890
1892
  fps: 30,
@@ -1902,7 +1904,7 @@ class oa {
1902
1904
  /** Build the final ElucimDocument */
1903
1905
  build() {
1904
1906
  const a = this._slides.map((r) => {
1905
- const i = new fa(
1907
+ const i = new ma(
1906
1908
  this._theme,
1907
1909
  this._opts.fps,
1908
1910
  this._opts.width,
@@ -1948,36 +1950,38 @@ class oa {
1948
1950
  return JSON.stringify(this.build(), null, a ? 2 : void 0);
1949
1951
  }
1950
1952
  }
1951
- function ka(e, a, t) {
1952
- return new oa(e, a, t);
1953
+ function $a(e, a, t) {
1954
+ return new ba(e, a, t);
1953
1955
  }
1954
1956
  export {
1955
- $a as DARK_THEME,
1956
- Ca as DARK_THEME_VARS,
1957
- da as DslRenderer,
1958
- Oa as LIGHT_THEME,
1959
- Aa as LIGHT_THEME_VARS,
1960
- oa as PresentationBuilder,
1961
- pa as SEMANTIC_TOKENS,
1962
- fa as SlideBuilder,
1963
- za as TOKEN_NAMES,
1964
- It as compileExpression,
1965
- St as compileVectorExpression,
1966
- ga as darkTheme,
1967
- va as lightTheme,
1968
- ka as presentation,
1957
+ Aa as DARK_THEME,
1958
+ pa as DARK_THEME_VARS,
1959
+ ka as DslRenderer,
1960
+ za as ImageResolverProvider,
1961
+ Ea as LIGHT_THEME,
1962
+ Ra as LIGHT_THEME_VARS,
1963
+ ba as PresentationBuilder,
1964
+ Pa as SEMANTIC_TOKENS,
1965
+ ma as SlideBuilder,
1966
+ Ta as TOKEN_NAMES,
1967
+ Ct as compileExpression,
1968
+ Ot as compileVectorExpression,
1969
+ ya as darkTheme,
1970
+ Sa as lightTheme,
1971
+ $a as presentation,
1969
1972
  w as renderElement,
1970
- oe as renderPlayer,
1971
- ea as renderPresentation,
1972
- ge as renderRoot,
1973
+ ye as renderPlayer,
1974
+ ra as renderPresentation,
1975
+ me as renderRoot,
1973
1976
  J as renderScene,
1974
- ta as renderSlide,
1975
- wa as renderToPng,
1976
- la as renderToSvgString,
1977
- Ea as resolveColor,
1977
+ ia as renderSlide,
1978
+ Ia as renderToPng,
1979
+ fa as renderToSvgString,
1980
+ Fa as resolveColor,
1978
1981
  f as resolveEasing,
1979
- se as stripCssFunctions,
1980
- Ra as themeToVars,
1981
- le as validate,
1982
- ce as validateExpression
1982
+ le as stripCssFunctions,
1983
+ Ma as themeToVars,
1984
+ _a as useImageResolver,
1985
+ he as validate,
1986
+ ue as validateExpression
1983
1987
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elucim/dsl",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "description": "JSON/YAML DSL for declarative Elucim animations — define visualizations without writing React code",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -58,7 +58,7 @@
58
58
  "vite": "^5.4.0",
59
59
  "vite-plugin-dts": "^4.0.0",
60
60
  "vitest": "^2.0.0",
61
- "@elucim/core": "0.13.1"
61
+ "@elucim/core": "0.14.0"
62
62
  },
63
63
  "scripts": {
64
64
  "dev": "vite build --watch",