@pixodesk/svg-animator-web 1.0.22 → 1.0.24

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.umd.js CHANGED
@@ -8,6 +8,7 @@ var PixodeskAnimator = (() => {
8
8
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
9
  var __hasOwnProp = Object.prototype.hasOwnProperty;
10
10
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
+ var __pow = Math.pow;
11
12
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
13
  var __spreadValues = (a, b) => {
13
14
  for (var prop in b || (b = {}))
@@ -47,130 +48,22 @@ var PixodeskAnimator = (() => {
47
48
  };
48
49
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
49
50
 
50
- // src/index.ts
51
- var index_exports = {};
52
- __export(index_exports, {
53
- COLOUR_ATTR_NAMES: () => COLOUR_ATTR_NAMES,
51
+ // src/index.player.ts
52
+ var index_player_exports = {};
53
+ __export(index_player_exports, {
54
54
  PX_ANIMATOR_DATA_KEY: () => PX_ANIMATOR_DATA_KEY,
55
55
  PX_ANIM_ATTR_NAME: () => PX_ANIM_ATTR_NAME,
56
56
  PX_ANIM_SRC_ATTR_NAME: () => PX_ANIM_SRC_ATTR_NAME,
57
- PX_TRANSFORM_PART_KEYS: () => PX_TRANSFORM_PART_KEYS,
58
- PxAnimatedSvgDocumentSchema: () => PxAnimatedSvgDocumentSchema,
59
- PxAnimationDefinitionSchema: () => PxAnimationDefinitionSchema,
60
- PxAnimatorConfigSchema: () => PxAnimatorConfigSchema,
61
57
  PxAnimatorEngine: () => PxAnimatorEngine,
62
58
  PxAnimatorMode: () => PxAnimatorMode,
63
- PxAttrValueSchema: () => PxAttrValueSchema,
64
- PxBezierPathSchema: () => PxBezierPathSchema,
65
- PxBindingSchema: () => PxBindingSchema,
66
- PxCloneEffectSchema: () => PxCloneEffectSchema,
67
- PxDefsSchema: () => PxDefsSchema,
68
- PxEasingOrRefSchema: () => PxEasingOrRefSchema,
69
- PxEffectsSchema: () => PxEffectsSchema,
70
- PxElementAnimationSchema: () => PxElementAnimationSchema,
71
- PxFillGradientEffectSchema: () => PxFillGradientEffectSchema,
72
- PxGradientSpreadMethod: () => PxGradientSpreadMethod,
73
- PxGradientStopSchema: () => PxGradientStopSchema,
74
- PxGradientType: () => PxGradientType,
75
- PxGradientUnits: () => PxGradientUnits,
76
- PxKeyframeSchema: () => PxKeyframeSchema,
77
- PxLoopSchema: () => PxLoopSchema,
78
- PxMaskedByEffectSchema: () => PxMaskedByEffectSchema,
79
- PxNodeBase: () => PxNodeBase,
80
- PxNodeSchema: () => PxNodeSchema,
81
- PxPropertyAnimationSchema: () => PxPropertyAnimationSchema,
82
- PxRepeaterEffectSchema: () => PxRepeaterEffectSchema,
83
- PxRetimeEffectSchema: () => PxRetimeEffectSchema,
84
- PxStrokeGradientEffectSchema: () => PxStrokeGradientEffectSchema,
85
- PxSvgNodeExtra: () => PxSvgNodeExtra,
86
- PxTextEffectSchema: () => PxTextEffectSchema,
87
- PxTextPathEffectSchema: () => PxTextPathEffectSchema,
88
- PxTransformPartsSchema: () => PxTransformPartsSchema,
89
- PxTransformValueSchema: () => PxTransformValueSchema,
90
- PxTransformationEffectSchema: () => PxTransformationEffectSchema,
91
- PxTriggerSchema: () => PxTriggerSchema,
92
- PxTrimPathEffectSchema: () => PxTrimPathEffectSchema,
93
- STYLE_ATTR_NAMES: () => STYLE_ATTR_NAMES,
94
- TRANSFORM_FN_NAMES: () => TRANSFORM_FN_NAMES,
95
- applyPlayerEffects: () => applyPlayerEffects,
96
- calcAnimationValues: () => calcAnimationValues,
97
- camelCaseToKebabWordIfNeeded: () => camelCaseToKebabWordIfNeeded,
98
- collectSampleTimes: () => collectSampleTimes,
99
59
  createAnimator: () => createAnimator,
100
60
  createAnimatorImpl: () => createAnimatorImpl,
101
- createBasicFrameLoopAnimator: () => createBasicFrameLoopAnimator,
102
- createFrameLoopAnimator: () => createFrameLoopAnimator,
103
- createPathSampler: () => createPathSampler,
104
- createWebApiAnimator: () => createWebApiAnimator,
105
- describeSchema: () => describeSchema,
106
- diffInEffect: () => diffInEffect,
107
- evaluateMotionPathSegment: () => evaluateMotionPathSegment,
108
- extendedPathForBrowser: () => extendedPathForBrowser,
109
61
  generateNewIds: () => generateNewIds,
110
- getAnimatorConfig: () => getAnimatorConfig,
111
- getBindings: () => getBindings,
112
- getChildren: () => getChildren,
113
- getDefs: () => getDefs,
114
- getNormalizedProps: () => getNormalizedProps,
115
- isPxElementFileFormat: () => isPxElementFileFormat,
116
- isPxElementFileFormatDeep: () => isPxElementFileFormatDeep,
117
- jsonElementFactory: () => jsonElementFactory,
118
- layoutGlyphTextChars: () => layoutGlyphTextChars,
119
62
  loadTagAnimators: () => loadTagAnimators,
120
- materialiseAllInTree: () => materialiseAllInTree,
121
- materialiseAnimatedUseInstances: () => materialiseAnimatedUseInstances,
122
- materialiseGlyphText: () => materialiseGlyphText,
123
- materialiseGlyphTextAlongPath: () => materialiseGlyphTextAlongPath,
124
- materialiseGlyphTextHorizontal: () => materialiseGlyphTextHorizontal,
125
- materialiseInternalLoopsInPropAnim: () => materialiseInternalLoopsInPropAnim,
126
- materialiseInternalLoopsInTree: () => materialiseInternalLoopsInTree,
127
- materialiseMotionPathInPropAnim: () => materialiseMotionPathInPropAnim,
128
- materialiseMotionPathsInTree: () => materialiseMotionPathsInTree,
129
- normalizeDocument: () => getNormalisedBindings,
130
- propAnimIsMotionPath: () => propAnimIsMotionPath,
131
- px: () => px,
132
- renderNode: () => renderNode,
133
- schemaKeys: () => schemaKeys,
134
- setupAnimationTriggers: () => setupAnimationTriggers,
135
- shiftAnimatable: () => shiftAnimatable,
136
- toRGBA: () => toRGBA,
137
- validateNodeEffects: () => validateNodeEffects,
138
- visualModelAt: () => visualModelAt
63
+ setupAnimationTriggers: () => setupAnimationTriggers
139
64
  });
140
65
 
141
- // ../svg-animator-core/dist/index.js
142
- var __defProp2 = Object.defineProperty;
143
- var __defProps2 = Object.defineProperties;
144
- var __getOwnPropDescs2 = Object.getOwnPropertyDescriptors;
145
- var __getOwnPropSymbols2 = Object.getOwnPropertySymbols;
146
- var __hasOwnProp2 = Object.prototype.hasOwnProperty;
147
- var __propIsEnum2 = Object.prototype.propertyIsEnumerable;
148
- var __pow = Math.pow;
149
- var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
150
- var __spreadValues2 = (a, b) => {
151
- for (var prop in b || (b = {}))
152
- if (__hasOwnProp2.call(b, prop))
153
- __defNormalProp2(a, prop, b[prop]);
154
- if (__getOwnPropSymbols2)
155
- for (var prop of __getOwnPropSymbols2(b)) {
156
- if (__propIsEnum2.call(b, prop))
157
- __defNormalProp2(a, prop, b[prop]);
158
- }
159
- return a;
160
- };
161
- var __spreadProps2 = (a, b) => __defProps2(a, __getOwnPropDescs2(b));
162
- var __objRest2 = (source, exclude) => {
163
- var target = {};
164
- for (var prop in source)
165
- if (__hasOwnProp2.call(source, prop) && exclude.indexOf(prop) < 0)
166
- target[prop] = source[prop];
167
- if (source != null && __getOwnPropSymbols2)
168
- for (var prop of __getOwnPropSymbols2(source)) {
169
- if (exclude.indexOf(prop) < 0 && __propIsEnum2.call(source, prop))
170
- target[prop] = source[prop];
171
- }
172
- return target;
173
- };
66
+ // ../svg-animator-core/src/PxSchema.ts
174
67
  function pathStr(path) {
175
68
  if (!path.length) return ".";
176
69
  let result = "";
@@ -292,8 +185,9 @@ var PixodeskAnimator = (() => {
292
185
  }
293
186
  isValid(raw, ctx, path) {
294
187
  var _a;
295
- if (this.schemas.some((s) => s.isValid(raw))) return true;
296
- ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a = JSON.stringify(raw)) != null ? _a : "").slice(0, 60));
188
+ const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
189
+ if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
190
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a = JSON.stringify(raw)) != null ? _a : "").slice(0, 240));
297
191
  return false;
298
192
  }
299
193
  _canSanitize(raw) {
@@ -369,6 +263,7 @@ var PixodeskAnimator = (() => {
369
263
  if (ctx == null ? void 0 : ctx.strict) {
370
264
  for (const key of Object.keys(obj)) {
371
265
  if (key in this._shape) continue;
266
+ if (obj[key] === void 0) continue;
372
267
  p.push(key);
373
268
  ctx.errors.push(pathStr(p) + ": unexpected extra key");
374
269
  p.pop();
@@ -392,7 +287,7 @@ var PixodeskAnimator = (() => {
392
287
  }
393
288
  sanitize(raw) {
394
289
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
395
- const out = __spreadValues2({}, src);
290
+ const out = __spreadValues({}, src);
396
291
  for (const key of Object.keys(this._shape)) {
397
292
  out[key] = this._shape[key].sanitize(src[key]);
398
293
  }
@@ -509,6 +404,23 @@ var PixodeskAnimator = (() => {
509
404
  return true;
510
405
  }
511
406
  };
407
+ var Defined = class extends Base {
408
+ constructor() {
409
+ super(...arguments);
410
+ this._default = void 0;
411
+ }
412
+ sanitize(raw) {
413
+ return raw;
414
+ }
415
+ isValid(raw, ctx, path) {
416
+ if (raw !== void 0) return true;
417
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": required value is missing");
418
+ return false;
419
+ }
420
+ _canSanitize(raw) {
421
+ return raw !== void 0;
422
+ }
423
+ };
512
424
  var Lazy = class extends Base {
513
425
  constructor(fn, _default) {
514
426
  super();
@@ -562,20 +474,6 @@ var PixodeskAnimator = (() => {
562
474
  function implementsInterface() {
563
475
  return (schema) => schema;
564
476
  }
565
- function schemaKeys(schema) {
566
- return Object.fromEntries(
567
- Object.keys(schema["_shape"]).map((k) => [k, k])
568
- );
569
- }
570
- function describeSchema(schema) {
571
- var _a;
572
- const s = schema;
573
- if ("_shape" in s) return { kind: "shape", shape: s._shape };
574
- if ("item" in s) return { kind: "array", item: s.item };
575
- if ("inner" in s) return { kind: "optional", inner: s.inner };
576
- if ("fn" in s) return { kind: "lazy", resolved: (_a = s.resolved) != null ? _a : s.fn() };
577
- return { kind: "leaf" };
578
- }
579
477
  var px = {
580
478
  /** Matches a string. Default: '' or provided value. */
581
479
  string: (defaultVal = "") => new Str(defaultVal),
@@ -613,29 +511,72 @@ var PixodeskAnimator = (() => {
613
511
  * @example
614
512
  * const PxSvgNodeSchema = px.extendedObject(PxNodeBase, { width: px.number().optional() });
615
513
  */
616
- extendedObject: (base, extra) => new Obj(__spreadValues2(__spreadValues2({}, base._shape), extra)),
514
+ extendedObject: (base, extra) => new Obj(__spreadValues(__spreadValues({}, base._shape), extra)),
617
515
  /** Array whose unrecoverable items are filtered out. Default: []. */
618
516
  array: (item) => new Arr(item),
619
517
  /** String-keyed record whose unrecoverable values are dropped. Default: {}. */
620
518
  record: (value) => new Rec(value),
621
519
  /** Passes anything through unchanged — always valid. */
622
520
  any: () => new Any(),
521
+ /** Anything EXCEPT `undefined` — an open type whose presence is required (V6). */
522
+ defined: () => new Defined(),
623
523
  /** Fixed-length tuple — validates element count and each position individually. */
624
524
  tuple: (schemas) => new Tuple(schemas),
625
525
  /** Defers schema creation — required for recursive types. Must supply a default value. */
626
526
  lazy: (fn, defaultVal) => new Lazy(fn, defaultVal)
627
527
  };
528
+
529
+ // ../svg-animator-core/src/PxAnimatorConstants.ts
628
530
  var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
629
531
  var PX_ANIM_ATTR_NAME = "_px_animator";
630
532
  var PxAnimatorMode = {
631
533
  auto: "auto",
632
- webapi: "webapi",
534
+ waapi: "waapi",
633
535
  frames: "frames"
634
536
  };
635
537
  var PxAnimatorEngine = {
636
- webapi: PxAnimatorMode.webapi,
538
+ waapi: PxAnimatorMode.waapi,
637
539
  frames: PxAnimatorMode.frames
638
540
  };
541
+ var PxLoopExtend = {
542
+ /** Segment from the START; the animation is extended BEFORE the first keyframe
543
+ * (intro loops that run before the main timeline begins). */
544
+ before: "before",
545
+ /** DEFAULT — segment from the END; extended AFTER the last keyframe (idle/outro
546
+ * loops that continue once the main timeline has finished). */
547
+ after: "after"
548
+ };
549
+ var PxMaskType = {
550
+ luminance: "luminance",
551
+ alpha: "alpha"
552
+ };
553
+ var PxUnits = {
554
+ userSpaceOnUse: "userSpaceOnUse",
555
+ objectBoundingBox: "objectBoundingBox"
556
+ };
557
+ var PxCloneType = {
558
+ content: "content"
559
+ };
560
+ var PxPathOverflow = {
561
+ clip: "clip",
562
+ extend: "extend"
563
+ };
564
+ var PxLengthAdjust = {
565
+ spacing: "spacing",
566
+ spacingAndGlyphs: "spacingAndGlyphs"
567
+ };
568
+ var PxTextPathMethod = {
569
+ align: "align",
570
+ stretch: "stretch"
571
+ };
572
+ var PxTextPathSpacing = {
573
+ auto: "auto",
574
+ exact: "exact"
575
+ };
576
+ var PxTrimSubPaths = {
577
+ separate: "separate",
578
+ combined: "combined"
579
+ };
639
580
  var TEXT_ATTR = "text";
640
581
  var TEXT_CONTENT_ATTR = "textContent";
641
582
  var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
@@ -644,9 +585,47 @@ var PixodeskAnimator = (() => {
644
585
  "animator",
645
586
  "meta",
646
587
  "animate",
588
+ "effects",
647
589
  TEXT_ATTR,
648
590
  TEXT_CONTENT_ATTR
649
591
  ]);
592
+ var PxGradientUnits = {
593
+ userSpaceOnUse: "userSpaceOnUse",
594
+ objectBoundingBox: "objectBoundingBox"
595
+ };
596
+ var PxGradientSpreadMethod = {
597
+ pad: "pad",
598
+ reflect: "reflect",
599
+ repeat: "repeat"
600
+ };
601
+ var PxGradientType = {
602
+ linear: "linear",
603
+ radial: "radial"
604
+ };
605
+ function isPxElementFileFormat(fileJson) {
606
+ if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
607
+ return false;
608
+ }
609
+ return fileJson["type"] === "svg";
610
+ }
611
+ function getAnimatorConfig(doc) {
612
+ var _a;
613
+ return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
614
+ }
615
+ function getDefs(doc) {
616
+ var _a;
617
+ if (!doc) return void 0;
618
+ return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
619
+ }
620
+ function getBindings(doc) {
621
+ var _a;
622
+ if (!doc) return void 0;
623
+ const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
624
+ if (!animateById) return void 0;
625
+ return Object.entries(animateById).map(([id, anim]) => ({ id, animate: anim }));
626
+ }
627
+
628
+ // ../svg-animator-core/src/PxAnimatorTypes.ts
650
629
  var PxEasingOrRefSchema = px.union([
651
630
  px.string(),
652
631
  px.tuple([px.number(), px.number(), px.number(), px.number()])
@@ -658,13 +637,15 @@ var PixodeskAnimator = (() => {
658
637
  px.array(px.number()),
659
638
  px.lazy(() => PxTransformPartsSchema, {}),
660
639
  px.object({ path: px.string() }),
661
- px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] })
640
+ px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),
641
+ // Gradient `stops` timeline — each kf value is the full stops-array snapshot.
642
+ px.lazy(() => px.array(PxGradientStopSchema), [])
662
643
  ]));
663
644
  var PxKeyframeSchema = implementsInterface()(px.object({
664
645
  time: px.number().optional(),
665
646
  t: px.number().optional(),
666
- value: px.any().optional(),
667
- v: px.any().optional(),
647
+ value: PxKeyframeValueSchema.optional(),
648
+ v: PxKeyframeValueSchema.optional(),
668
649
  easing: PxEasingOrRefSchema.optional(),
669
650
  e: PxEasingOrRefSchema.optional(),
670
651
  tangentOut: px.tuple([px.number(), px.number()]).optional(),
@@ -678,16 +659,16 @@ var PixodeskAnimator = (() => {
678
659
  }));
679
660
  var PxLoopSchema = implementsInterface()(px.object({
680
661
  segmentCount: px.number().optional(),
681
- before: px.boolean().optional(),
662
+ extend: px.enum([PxLoopExtend.before, PxLoopExtend.after]).optional(),
682
663
  alternate: px.boolean().optional()
683
664
  }));
684
665
  var PxPropertyAnimationSchema = implementsInterface()(px.object({
666
+ value: PxKeyframeValueSchema.optional(),
685
667
  keyframes: px.array(PxKeyframeSchema).optional(),
686
668
  kfs: px.array(PxKeyframeSchema).optional(),
687
669
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
688
670
  autoOrient: px.boolean().optional()
689
671
  }));
690
- var PX_TRANSFORM_PART_KEYS = ["translate", "rotate", "scale", "origin"];
691
672
  var PxTransformPartsSchema = implementsInterface()(px.object({
692
673
  translate: px.tuple([px.number(), px.number()]).optional(),
693
674
  rotate: px.number().optional(),
@@ -697,6 +678,7 @@ var PixodeskAnimator = (() => {
697
678
  }));
698
679
  var PxTransformValueSchema = px.union([
699
680
  px.string(),
681
+ PxTransformPartsSchema,
700
682
  px.object({ value: PxTransformPartsSchema }),
701
683
  PxPropertyAnimationSchema
702
684
  ]);
@@ -731,9 +713,11 @@ var PixodeskAnimator = (() => {
731
713
  glyphs: px.record(PxGlyphFontSchema).optional()
732
714
  }));
733
715
  var PxAnimatorConfigSchema = implementsInterface()(px.object({
734
- mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
716
+ mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.waapi, PxAnimatorMode.frames]).optional(),
735
717
  duration: px.number().optional(),
736
718
  delay: px.number().optional(),
719
+ // LAW (SCHEMA-DESIGN R3, S10): the ONE sanctioned string-in-number union
720
+ // (CSS animation-iteration-count familiarity) — do not add more mixed unions.
737
721
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
738
722
  fill: px.enum(["forwards", "backwards", "both", "none"]).optional(),
739
723
  direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional(),
@@ -741,9 +725,8 @@ var PixodeskAnimator = (() => {
741
725
  trigger: PxTriggerSchema.optional(),
742
726
  resetOnFinish: px.boolean().optional(),
743
727
  definitions: PxDefsSchema.optional(),
744
- animate: px.record(PxElementAnimationSchema).optional(),
745
- timeline: px.string().optional(),
746
- debug: px.boolean().optional(),
728
+ animateById: px.record(PxElementAnimationSchema).optional(),
729
+ timelineSource: px.string().optional(),
747
730
  debugInstName: px.string().optional()
748
731
  }));
749
732
  var PxBindingSchema = implementsInterface()(px.object({
@@ -753,26 +736,29 @@ var PixodeskAnimator = (() => {
753
736
  var PxAttrValueSchema = px.union([
754
737
  px.string(),
755
738
  px.number(),
756
- px.object({ value: px.any() }),
757
- PxPropertyAnimationSchema
739
+ px.array(px.number()),
740
+ // Structured static — `{value: …}` (read-accepted transitional spelling, S1).
741
+ // `defined`, not `any`: the KEY's presence is what identifies this branch (V6).
742
+ px.object({ value: px.defined() }),
743
+ // Bare transform parts record — the canonical static `transform` on the wire (T2).
744
+ PxTransformPartsSchema
758
745
  ]);
759
746
  var PxAnimatableNumberSchema = px.union([
760
747
  px.number(),
761
748
  px.object({ value: px.number() }),
762
- px.object({
763
- keyframes: px.array(PxKeyframeSchema),
764
- autoOrient: px.boolean().optional()
765
- })
749
+ PxPropertyAnimationSchema
766
750
  ]);
767
751
  var PxAnimatableVec2Schema = px.union([
768
752
  px.tuple([px.number(), px.number()]),
769
753
  px.object({ value: px.tuple([px.number(), px.number()]) }),
770
- px.object({
771
- keyframes: px.array(PxKeyframeSchema),
772
- autoOrient: px.boolean().optional()
773
- })
754
+ PxPropertyAnimationSchema
755
+ ]);
756
+ var PxAnimatableStringSchema = px.union([
757
+ px.string(),
758
+ px.object({ value: px.string() }),
759
+ PxPropertyAnimationSchema
774
760
  ]);
775
- var PxTransformationEffectSchema = implementsInterface()(px.object({
761
+ var PxTransformByEffectSchema = implementsInterface()(px.object({
776
762
  translate: PxAnimatableVec2Schema.optional(),
777
763
  rotate: PxAnimatableNumberSchema.optional(),
778
764
  scale: PxAnimatableVec2Schema.optional(),
@@ -780,51 +766,46 @@ var PixodeskAnimator = (() => {
780
766
  origin: PxAnimatableVec2Schema.optional()
781
767
  }));
782
768
  var PxRepeaterEffectSchema = implementsInterface()(px.object({
769
+ // STATIC config, not a channel (V2/SCHEMA-DESIGN R5): the copy COUNT is read
770
+ // once at expansion time and never sampled — plain number, no `keyframes`.
783
771
  copies: px.number().optional(),
784
772
  translate: PxAnimatableVec2Schema.optional(),
785
773
  rotate: PxAnimatableNumberSchema.optional(),
774
+ skew: PxAnimatableNumberSchema.optional(),
786
775
  scale: PxAnimatableVec2Schema.optional(),
787
776
  origin: PxAnimatableVec2Schema.optional()
788
777
  }));
789
778
  var PxMaskedByEffectSchema = implementsInterface()(px.object({
790
- href: px.string().optional(),
791
- maskType: px.string().optional(),
792
- maskUnits: px.string().optional(),
793
- maskContentUnits: px.string().optional()
779
+ sourceId: px.string().optional(),
780
+ maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
781
+ maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
782
+ maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
783
+ x: px.number().optional(),
784
+ y: px.number().optional(),
785
+ width: px.number().optional(),
786
+ height: px.number().optional()
794
787
  }));
795
788
  var PxClipPathEffectSchema = implementsInterface()(px.object({
796
- d: px.string().optional(),
789
+ d: PxAnimatableStringSchema.optional(),
797
790
  animate: PxPropertyAnimationSchema.optional()
798
791
  }));
799
792
  var PxTrimPathEffectSchema = implementsInterface()(px.object({
800
793
  offset: PxAnimatableNumberSchema.optional(),
801
794
  range: PxAnimatableVec2Schema.optional(),
802
- trimAllAsOne: px.boolean().optional()
795
+ subPaths: px.enum([PxTrimSubPaths.separate, PxTrimSubPaths.combined]).optional()
803
796
  }));
804
797
  var PxRetimeEffectSchema = implementsInterface()(px.object({
805
- baseId: px.string().optional(),
798
+ sourceId: px.string().optional(),
806
799
  start: px.number().optional(),
807
800
  stretch: px.number().optional(),
808
801
  timeCrop: px.tuple([px.number(), px.number()]).optional()
809
802
  }));
810
803
  var PxCloneEffectSchema = implementsInterface()(px.object({
811
- type: px.string().optional(),
812
- baseId: px.string().optional(),
804
+ // Contextual kind — the `type` convention, see `PxNodeBase.type`.
805
+ type: px.enum([PxCloneType.content]).optional(),
806
+ sourceId: px.string().optional(),
813
807
  retime: PxRetimeEffectSchema.optional()
814
808
  }));
815
- var PxGradientUnits = {
816
- userSpaceOnUse: "userSpaceOnUse",
817
- objectBoundingBox: "objectBoundingBox"
818
- };
819
- var PxGradientSpreadMethod = {
820
- pad: "pad",
821
- reflect: "reflect",
822
- repeat: "repeat"
823
- };
824
- var PxGradientType = {
825
- linear: "linear",
826
- radial: "radial"
827
- };
828
809
  var PxGradientStopSchema = implementsInterface()(px.object({
829
810
  offset: px.number(),
830
811
  color: px.string()
@@ -832,39 +813,28 @@ var PixodeskAnimator = (() => {
832
813
  var PxAnimatableGradientStopsSchema = px.union([
833
814
  px.array(PxGradientStopSchema),
834
815
  px.object({ value: px.array(PxGradientStopSchema) }),
835
- px.object({ keyframes: px.array(PxKeyframeSchema) })
816
+ PxPropertyAnimationSchema
836
817
  ]);
837
- var PxGradientGeometryAnimationSchema = implementsInterface()(px.object({
838
- gradientX1: PxPropertyAnimationSchema.optional(),
839
- gradientY1: PxPropertyAnimationSchema.optional(),
840
- gradientX2: PxPropertyAnimationSchema.optional(),
841
- gradientY2: PxPropertyAnimationSchema.optional(),
842
- gradientCx: PxPropertyAnimationSchema.optional(),
843
- gradientCy: PxPropertyAnimationSchema.optional(),
844
- gradientFx: PxPropertyAnimationSchema.optional(),
845
- gradientFy: PxPropertyAnimationSchema.optional(),
846
- gradientR: PxPropertyAnimationSchema.optional()
847
- }));
848
818
  var PxFillGradientEffectSchema = implementsInterface()(px.object({
819
+ // Contextual kind — the `type` convention, see `PxNodeBase.type`.
849
820
  type: px.enum([PxGradientType.linear, PxGradientType.radial]),
850
- p1: px.tuple([px.number(), px.number()]).optional(),
851
- p2: px.tuple([px.number(), px.number()]).optional(),
852
- c: px.tuple([px.number(), px.number()]).optional(),
853
- r: px.number().optional(),
854
- fp: px.tuple([px.number(), px.number()]).optional(),
821
+ p1: PxAnimatableVec2Schema.optional(),
822
+ p2: PxAnimatableVec2Schema.optional(),
823
+ c: PxAnimatableVec2Schema.optional(),
824
+ r: PxAnimatableNumberSchema.optional(),
825
+ fp: PxAnimatableVec2Schema.optional(),
855
826
  stops: PxAnimatableGradientStopsSchema.optional(),
856
- gradientUnits: px.string().optional(),
857
- spreadMethod: px.string().optional(),
858
- gradientTransform: px.string().optional(),
859
- animate: PxGradientGeometryAnimationSchema.optional()
827
+ gradientUnits: px.enum([PxGradientUnits.userSpaceOnUse, PxGradientUnits.objectBoundingBox]).optional(),
828
+ spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
829
+ gradientTransform: px.string().optional()
860
830
  }));
861
831
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
862
832
  var PxTextPathEffectSchema = implementsInterface()(px.object({
863
833
  path: px.string(),
864
- pathOverflow: px.string().optional(),
865
- lengthAdjust: px.string().optional(),
866
- method: px.string().optional(),
867
- spacing: px.string().optional(),
834
+ pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
835
+ lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
836
+ method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
837
+ spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact]).optional(),
868
838
  startOffset: PxAnimatableNumberSchema.optional(),
869
839
  textLength: PxAnimatableNumberSchema.optional()
870
840
  }));
@@ -872,13 +842,12 @@ var PixodeskAnimator = (() => {
872
842
  useGlyphs: px.boolean().optional()
873
843
  }));
874
844
  var PxEffectsSchema = implementsInterface()(px.object({
875
- transformation: PxTransformationEffectSchema.optional(),
845
+ transformBy: PxTransformByEffectSchema.optional(),
876
846
  repeater: PxRepeaterEffectSchema.optional(),
877
847
  maskedBy: PxMaskedByEffectSchema.optional(),
878
848
  clipPath: PxClipPathEffectSchema.optional(),
879
849
  trimPath: PxTrimPathEffectSchema.optional(),
880
850
  clone: PxCloneEffectSchema.optional(),
881
- isCombinedShape: px.boolean().optional(),
882
851
  fillGradient: PxFillGradientEffectSchema.optional(),
883
852
  strokeGradient: PxStrokeGradientEffectSchema.optional(),
884
853
  textPath: PxTextPathEffectSchema.optional(),
@@ -902,6 +871,14 @@ var PixodeskAnimator = (() => {
902
871
  return warnings;
903
872
  }
904
873
  var PxNodeBase = px.openObject({
874
+ // CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
875
+ // kind of thing is this", discriminated by its CARRIER — here the node TAG
876
+ // (`rect`, `text`), and inside a sub-object that object's kind (`clone.type`,
877
+ // `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
878
+ // the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
879
+ // would add words that all mean "type" and still need the carrier to read.
880
+ // Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
881
+ // (issues V3), never of distinct key names.
905
882
  type: px.string(),
906
883
  id: px.string().optional(),
907
884
  meta: px.any().optional(),
@@ -911,11 +888,11 @@ var PixodeskAnimator = (() => {
911
888
  effects: PxEffectsSchema.optional(),
912
889
  // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
913
890
  // string ref / array of refs / inline definition / mixed array; mirrors
914
- // `animator.animate` map values and what `processNode` resolves at runtime.
891
+ // `animator.animateById` map values and what `processNode` resolves at runtime.
915
892
  animate: PxElementAnimationSchema.optional(),
916
893
  style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional()
917
894
  }, PxAttrValueSchema);
918
- var PxNodeSchema = px.openObject(__spreadProps2(__spreadValues2({}, PxNodeBase._shape), {
895
+ var PxNodeSchema = px.openObject(__spreadProps(__spreadValues({}, PxNodeBase._shape), {
919
896
  children: px.lazy(() => px.array(PxNodeSchema), []).optional()
920
897
  }), PxAttrValueSchema);
921
898
  var PxSvgNodeExtra = px.object({
@@ -924,7 +901,7 @@ var PixodeskAnimator = (() => {
924
901
  viewBox: px.string().optional(),
925
902
  animator: PxAnimatorConfigSchema.optional()
926
903
  });
927
- var PxAnimatedSvgDocumentSchema = px.openObject(__spreadProps2(__spreadValues2(__spreadValues2({}, PxNodeBase._shape), PxSvgNodeExtra._shape), {
904
+ var PxAnimatedSvgDocumentSchema = px.openObject(__spreadProps(__spreadValues(__spreadValues({}, PxNodeBase._shape), PxSvgNodeExtra._shape), {
928
905
  type: px.literal("svg"),
929
906
  // override string → literal to require 'svg'
930
907
  children: px.array(PxNodeSchema).optional()
@@ -935,35 +912,8 @@ var PixodeskAnimator = (() => {
935
912
  o: px.array(px.array(px.number())).optional(),
936
913
  c: px.boolean().optional()
937
914
  }));
938
- function isPxElementFileFormat(fileJson) {
939
- if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
940
- return false;
941
- }
942
- return fileJson["type"] === "svg" || fileJson["tagName"] === "svg";
943
- }
944
- function isPxElementFileFormatDeep(fileJson) {
945
- const valid = PxAnimatedSvgDocumentSchema.isValid(fileJson);
946
- return { valid, errors: valid ? [] : ["Document failed schema validation"] };
947
- }
948
- function getAnimatorConfig(doc) {
949
- var _a, _b;
950
- return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator) || (doc == null ? void 0 : doc.animation) || ((_b = doc == null ? void 0 : doc.meta) == null ? void 0 : _b.animation);
951
- }
952
- function getDefs(doc) {
953
- var _a;
954
- if (!doc) return void 0;
955
- return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
956
- }
957
- function getBindings(doc) {
958
- var _a;
959
- if (!doc) return void 0;
960
- const animate = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animate;
961
- if (!animate) return void 0;
962
- return Object.entries(animate).map(([id, anim]) => ({ id, animate: anim }));
963
- }
964
- function getChildren(doc) {
965
- return doc == null ? void 0 : doc.children;
966
- }
915
+
916
+ // ../svg-animator-core/src/PxAnimatorUtil.ts
967
917
  function bezierToSvgPath(path, forceCurves = false) {
968
918
  var _a, _b, _c, _d;
969
919
  const v = path.v;
@@ -1378,6 +1328,8 @@ var PixodeskAnimator = (() => {
1378
1328
  const flipped = [easing[1], easing[0], easing[3], easing[2]];
1379
1329
  return cubicBezier(flipped);
1380
1330
  }
1331
+
1332
+ // ../svg-animator-core/src/PxIdUtil.ts
1381
1333
  var _idCounter = 0;
1382
1334
  function generateUniqueId() {
1383
1335
  const timestamp = Date.now().toString(36);
@@ -1414,7 +1366,7 @@ var PixodeskAnimator = (() => {
1414
1366
  "flood-color",
1415
1367
  "lighting-color"
1416
1368
  ]);
1417
- const directIdRefAttrs = /* @__PURE__ */ new Set(["baseId", "targetId", "boundElementId"]);
1369
+ const directIdRefAttrs = /* @__PURE__ */ new Set(["sourceId", "targetId", "boundElementId"]);
1418
1370
  function collectIds(node) {
1419
1371
  if (!node || typeof node !== "object") return;
1420
1372
  if (node.id && typeof node.id === "string") {
@@ -1452,9 +1404,10 @@ var PixodeskAnimator = (() => {
1452
1404
  } else if (urlRefAttrs.has(key)) {
1453
1405
  node[key] = replaceUrlRefs(value, idMap);
1454
1406
  } else if (directIdRefAttrs.has(key)) {
1455
- const newId = idMap.get(value);
1407
+ const hasHash = value.startsWith("#");
1408
+ const newId = idMap.get(hasHash ? value.slice(1) : value);
1456
1409
  if (newId) {
1457
- node[key] = newId;
1410
+ node[key] = hasHash ? "#" + newId : newId;
1458
1411
  }
1459
1412
  } else if (value.includes("url(#")) {
1460
1413
  node[key] = replaceUrlRefs(value, idMap);
@@ -1472,14 +1425,14 @@ var PixodeskAnimator = (() => {
1472
1425
  }
1473
1426
  collectIds(cloned);
1474
1427
  updateRefs(cloned);
1475
- const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animate;
1428
+ const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animateById;
1476
1429
  if (docAnimate && typeof docAnimate === "object") {
1477
1430
  const updatedAnimate = {};
1478
1431
  for (const [id, anim] of Object.entries(docAnimate)) {
1479
1432
  const newId = (_b = idMap.get(id)) != null ? _b : id;
1480
1433
  updatedAnimate[newId] = anim;
1481
1434
  }
1482
- cloned.animator = __spreadProps2(__spreadValues2({}, cloned.animator), { animate: updatedAnimate });
1435
+ cloned.animator = __spreadProps(__spreadValues({}, cloned.animator), { animateById: updatedAnimate });
1483
1436
  }
1484
1437
  return cloned;
1485
1438
  }
@@ -1489,6 +1442,8 @@ var PixodeskAnimator = (() => {
1489
1442
  return newId ? "url(#" + newId + ")" : match;
1490
1443
  });
1491
1444
  }
1445
+
1446
+ // ../svg-animator-core/src/PxNodeProps.ts
1492
1447
  var DISALLOWED_SVG_TAGS_LOWER = /* @__PURE__ */ new Set([
1493
1448
  "script",
1494
1449
  "foreignobject"
@@ -1568,8 +1523,9 @@ var PixodeskAnimator = (() => {
1568
1523
  let value = props[rawKey];
1569
1524
  if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
1570
1525
  propsCopy[key] = toRGBA(value);
1571
- } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && value.value && typeof value.value === "object") {
1572
- propsCopy["transform"] = composeTransformParts(value.value, { withUnits: false });
1526
+ } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes && !value.kfs) {
1527
+ const parts = value.value && typeof value.value === "object" ? value.value : value;
1528
+ propsCopy["transform"] = composeTransformParts(parts, { withUnits: false });
1573
1529
  } else if (TRANSFORM_FN_NAMES.has(key)) {
1574
1530
  if (Array.isArray(value)) {
1575
1531
  if (key === "translate") value = value.map((v) => v + "px");
@@ -1577,12 +1533,16 @@ var PixodeskAnimator = (() => {
1577
1533
  }
1578
1534
  if (key === "rotate") value = value + "deg";
1579
1535
  propsCopy["transform"] = key + "(" + value + ")";
1536
+ } else if (Array.isArray(value)) {
1537
+ propsCopy[key] = value.join(",");
1580
1538
  } else if (value !== void 0 && value !== null) {
1581
1539
  propsCopy[key] = String(value);
1582
1540
  }
1583
1541
  }
1584
1542
  return propsCopy;
1585
1543
  }
1544
+
1545
+ // ../svg-animator-core/src/PxMotionPath.ts
1586
1546
  function getKfTranslate(kf) {
1587
1547
  var _a;
1588
1548
  const v = (_a = kf.value) != null ? _a : kf.v;
@@ -1964,16 +1924,28 @@ var PixodeskAnimator = (() => {
1964
1924
  if (transformAnim && typeof transformAnim === "object" && propAnimIsMotionPath(transformAnim)) {
1965
1925
  const materialised = materialiseMotionPathInPropAnim(transformAnim, opts);
1966
1926
  if (materialised !== transformAnim) {
1967
- newAnimate = __spreadProps2(__spreadValues2({}, animDef), { transform: materialised });
1927
+ newAnimate = __spreadProps(__spreadValues({}, animDef), { transform: materialised });
1968
1928
  }
1969
1929
  }
1970
1930
  }
1971
1931
  if (!newChildren && !newAnimate) return null;
1972
- const cloned = __spreadValues2({}, node);
1932
+ const cloned = __spreadValues({}, node);
1973
1933
  if (newChildren) cloned.children = newChildren;
1974
1934
  if (newAnimate) cloned.animate = newAnimate;
1975
1935
  return cloned;
1976
1936
  }
1937
+
1938
+ // ../svg-animator-core/src/PxDefinitions.ts
1939
+ var LOOP_JUMP_SHIFT_MS = 10;
1940
+ function deepEqualValue(a, b) {
1941
+ if (a === b) return true;
1942
+ if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") return false;
1943
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
1944
+ const ka = Object.keys(a);
1945
+ const kb = Object.keys(b);
1946
+ if (ka.length !== kb.length) return false;
1947
+ return ka.every((k) => deepEqualValue(a[k], b[k]));
1948
+ }
1977
1949
  function parsePathCommands(d) {
1978
1950
  const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
1979
1951
  const commands = [];
@@ -2176,7 +2148,7 @@ var PixodeskAnimator = (() => {
2176
2148
  const totalIntervals = keyframes.length - 1;
2177
2149
  const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
2178
2150
  let segKfs;
2179
- if (loop.before) {
2151
+ if (loop.extend === PxLoopExtend.before) {
2180
2152
  segKfs = keyframes.slice(0, segCount + 1);
2181
2153
  } else {
2182
2154
  segKfs = keyframes.slice(totalIntervals - segCount);
@@ -2184,7 +2156,7 @@ var PixodeskAnimator = (() => {
2184
2156
  const firstT = (_b = keyframes[0].t) != null ? _b : 0;
2185
2157
  const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
2186
2158
  let fillStart, fillEnd;
2187
- if (loop.before) {
2159
+ if (loop.extend === PxLoopExtend.before) {
2188
2160
  fillStart = 0;
2189
2161
  fillEnd = firstT;
2190
2162
  } else {
@@ -2211,7 +2183,10 @@ var PixodeskAnimator = (() => {
2211
2183
  const remainder = fillDuration - fullReps * segDuration;
2212
2184
  const partialFraction = remainder / segDuration;
2213
2185
  const looped = [];
2186
+ const separateBoundary = loop.extend !== PxLoopExtend.before;
2187
+ const originalTerminalKf = keyframes[keyframes.length - 1];
2214
2188
  function appendRep(repStart, isReversed, partial) {
2189
+ var _a2;
2215
2190
  let entries;
2216
2191
  if (isReversed) {
2217
2192
  entries = [];
@@ -2247,8 +2222,17 @@ var PixodeskAnimator = (() => {
2247
2222
  looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
2248
2223
  return;
2249
2224
  }
2225
+ const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
2226
+ const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
2227
+ if (isBoundary) {
2228
+ if (deepEqualValue(prevKf.v, entry.v)) continue;
2229
+ if (looped.length > 0) {
2230
+ delete prevKf.tangentIn;
2231
+ delete prevKf.tangentOut;
2232
+ }
2233
+ }
2250
2234
  const pushed = {
2251
- t: repStart + entry.relT * segDuration,
2235
+ t: repStart + entry.relT * segDuration + (isBoundary ? LOOP_JUMP_SHIFT_MS : 0),
2252
2236
  v: entry.v,
2253
2237
  e: i < entries.length - 1 ? entry.e : void 0
2254
2238
  };
@@ -2296,7 +2280,7 @@ var PixodeskAnimator = (() => {
2296
2280
  looped.push(pushed);
2297
2281
  }
2298
2282
  }
2299
- if (loop.before) {
2283
+ if (loop.extend === PxLoopExtend.before) {
2300
2284
  if (partialFraction > 1e-9) {
2301
2285
  const isReversed = !!loop.alternate && fullReps % 2 === 0;
2302
2286
  appendRepTail(fillStart, isReversed, partialFraction);
@@ -2319,7 +2303,7 @@ var PixodeskAnimator = (() => {
2319
2303
  appendRep(repStart, isReversed, partialFraction);
2320
2304
  }
2321
2305
  }
2322
- if (loop.before) {
2306
+ if (loop.extend === PxLoopExtend.before) {
2323
2307
  return [...looped, ...keyframes];
2324
2308
  } else {
2325
2309
  return [...keyframes, ...looped];
@@ -2420,13 +2404,13 @@ var PixodeskAnimator = (() => {
2420
2404
  const propAnim = animDef[propName];
2421
2405
  const materialised = materialiseInternalLoopsInPropAnim(propName, propAnim, duration);
2422
2406
  if (materialised !== propAnim) {
2423
- if (!newAnimate) newAnimate = __spreadValues2({}, animDef);
2407
+ if (!newAnimate) newAnimate = __spreadValues({}, animDef);
2424
2408
  newAnimate[propName] = materialised;
2425
2409
  }
2426
2410
  }
2427
2411
  }
2428
2412
  if (!newChildren && !newAnimate) return null;
2429
- const cloned = __spreadValues2({}, node);
2413
+ const cloned = __spreadValues({}, node);
2430
2414
  if (newChildren) cloned.children = newChildren;
2431
2415
  if (newAnimate) cloned.animate = newAnimate;
2432
2416
  return cloned;
@@ -2435,7 +2419,7 @@ var PixodeskAnimator = (() => {
2435
2419
  function generateElementId() {
2436
2420
  return "_px_el_" + ++_elementIdCounter;
2437
2421
  }
2438
- function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.webapi) {
2422
+ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
2439
2423
  const normalized = {};
2440
2424
  for (const [propName, propAnim] of Object.entries(animDef)) {
2441
2425
  const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
@@ -2443,12 +2427,12 @@ var PixodeskAnimator = (() => {
2443
2427
  const out = { kfs: normalizedKfs };
2444
2428
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2445
2429
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
2446
- normalized[propName] = engine === PxAnimatorEngine.webapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
2430
+ normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
2447
2431
  }
2448
2432
  }
2449
2433
  return normalized;
2450
2434
  }
2451
- function getNormalisedBindings(doc, engine = PxAnimatorEngine.webapi) {
2435
+ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
2452
2436
  const animatorConfig = getAnimatorConfig(doc) || {};
2453
2437
  const defs = getDefs(doc);
2454
2438
  const duration = animatorConfig.duration || 1e3;
@@ -2613,12 +2597,12 @@ var PixodeskAnimator = (() => {
2613
2597
  cssValue = "scale(" + v.join(",") + ")";
2614
2598
  cssAttrName = "transform";
2615
2599
  } else {
2616
- const num2 = interpolateNum(
2600
+ const num = interpolateNum(
2617
2601
  +(prevV || 0),
2618
2602
  +(nextV || 0),
2619
2603
  localProgress
2620
2604
  );
2621
- cssValue = num2;
2605
+ cssValue = num;
2622
2606
  }
2623
2607
  if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
2624
2608
  cssValue = cssValue * 100 + "%";
@@ -2635,6 +2619,8 @@ var PixodeskAnimator = (() => {
2635
2619
  }
2636
2620
  return result;
2637
2621
  }
2622
+
2623
+ // ../svg-animator-core/src/PxNodeCloneUtil.ts
2638
2624
  function deepClonePxNode(value) {
2639
2625
  if (value === null || typeof value !== "object") return value;
2640
2626
  if (Array.isArray(value)) return value.map(deepClonePxNode);
@@ -2697,6 +2683,8 @@ var PixodeskAnimator = (() => {
2697
2683
  }
2698
2684
  return gNode;
2699
2685
  }
2686
+
2687
+ // ../svg-animator-core/src/PxAnimatorUseMaterialiser.ts
2700
2688
  function materialiseAnimatedUseInstances(root) {
2701
2689
  var _a;
2702
2690
  const idMap = buildIdMap(root);
@@ -2710,7 +2698,7 @@ var PixodeskAnimator = (() => {
2710
2698
  if (defsCollector.length === 0) return walked;
2711
2699
  const defsNode = { type: "defs", children: defsCollector };
2712
2700
  const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
2713
- return __spreadProps2(__spreadValues2({}, walked), { children: newChildren });
2701
+ return __spreadProps(__spreadValues({}, walked), { children: newChildren });
2714
2702
  }
2715
2703
  function readRootViewport(root) {
2716
2704
  const vb = parseViewBox(root.viewBox);
@@ -2788,7 +2776,7 @@ var PixodeskAnimator = (() => {
2788
2776
  const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
2789
2777
  const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
2790
2778
  const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
2791
- const newNode = __spreadProps2(__spreadValues2({}, useNode), { type: "g", children: [materialisedClone] });
2779
+ const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materialisedClone] });
2792
2780
  delete newNode.href;
2793
2781
  delete newNode.width;
2794
2782
  delete newNode.height;
@@ -2796,7 +2784,7 @@ var PixodeskAnimator = (() => {
2796
2784
  }
2797
2785
  function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector, useW, useH) {
2798
2786
  const viewBox = parseViewBox(symbolNode.viewBox);
2799
- const g = __spreadProps2(__spreadValues2({}, symbolNode), { type: "g" });
2787
+ const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
2800
2788
  delete g.viewBox;
2801
2789
  delete g.preserveAspectRatio;
2802
2790
  delete g.width;
@@ -2841,34 +2829,54 @@ var PixodeskAnimator = (() => {
2841
2829
  if (m !== ch) changed = true;
2842
2830
  return m;
2843
2831
  });
2844
- return changed ? __spreadProps2(__spreadValues2({}, node), { children: newChildren }) : node;
2832
+ return changed ? __spreadProps(__spreadValues({}, node), { children: newChildren }) : node;
2845
2833
  }
2834
+
2835
+ // ../svg-animator-core/src/effects/transformParts.ts
2846
2836
  function partsRecord(part, value, origin) {
2847
2837
  const rec = {};
2848
- if (part === "translate") rec.translate = value;
2849
- else if (part === "rotate") rec.rotate = value;
2850
- else if (part === "skew") rec.skew = value;
2838
+ if (part === "translate" /* Translate */) rec.translate = value;
2839
+ else if (part === "rotate" /* Rotate */) rec.rotate = value;
2840
+ else if (part === "skew" /* Skew */) rec.skew = value;
2851
2841
  else rec.scale = value;
2852
- if (origin && part !== "translate") rec.origin = origin;
2842
+ if (origin && part !== "translate" /* Translate */) rec.origin = origin;
2853
2843
  return rec;
2854
2844
  }
2855
2845
  function readAnimatable(raw) {
2856
- var _a, _b;
2857
- if (raw === void 0) return {
2858
- kind: "absent"
2859
- /* Absent */
2860
- };
2861
- if (Array.isArray(raw)) return { kind: "static", value: raw };
2846
+ var _a, _b, _c;
2847
+ if (raw === void 0) return { kind: "absent" /* Absent */ };
2848
+ if (Array.isArray(raw)) return { kind: "static" /* Static */, value: raw };
2862
2849
  if (typeof raw === "object") {
2863
2850
  const obj = raw;
2864
2851
  const kfs = (_a = obj.keyframes) != null ? _a : obj.kfs;
2865
2852
  if (kfs) {
2866
- return { kind: "animated", keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
2853
+ const out = { kind: "animated" /* Animated */, keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
2854
+ const base = (_b = obj.value) != null ? _b : obj.v;
2855
+ if (base !== void 0 && out.kind === "animated" /* Animated */) out.base = base;
2856
+ return out;
2867
2857
  }
2868
- const staticValue = (_b = obj.value) != null ? _b : obj.v;
2869
- if (staticValue !== void 0) return { kind: "static", value: staticValue };
2858
+ const staticValue = (_c = obj.value) != null ? _c : obj.v;
2859
+ if (staticValue !== void 0) return { kind: "static" /* Static */, value: staticValue };
2860
+ }
2861
+ return { kind: "static" /* Static */, value: raw };
2862
+ }
2863
+ function writeAnimatableChannel(node, attrName, read, opts) {
2864
+ var _a, _b, _c, _d;
2865
+ const toOut = (v) => (opts == null ? void 0 : opts.asString) && v !== void 0 && v !== null ? String(v) : v;
2866
+ if (read.kind === "absent" /* Absent */) return;
2867
+ if (read.kind === "static" /* Static */) {
2868
+ node[attrName] = toOut(read.value);
2869
+ return;
2870
2870
  }
2871
- return { kind: "static", value: raw };
2871
+ const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
2872
+ const animate = __spreadValues({}, prevAnimate || {});
2873
+ const block = { keyframes: read.keyframes };
2874
+ if (read.loop !== void 0) block.loop = read.loop;
2875
+ if (read.autoOrient !== void 0) block.autoOrient = read.autoOrient;
2876
+ animate[attrName] = block;
2877
+ node.animate = animate;
2878
+ const baseline = (_d = (_b = read.base) != null ? _b : (_a = read.keyframes[0]) == null ? void 0 : _a.value) != null ? _d : (_c = read.keyframes[0]) == null ? void 0 : _c.v;
2879
+ if (baseline !== void 0) node[attrName] = toOut(baseline);
2872
2880
  }
2873
2881
  function normaliseKeyframe(kf) {
2874
2882
  if (!kf || typeof kf !== "object") return kf;
@@ -2876,7 +2884,7 @@ var PixodeskAnimator = (() => {
2876
2884
  if (k.t === void 0 && k.v === void 0 && k.e === void 0 && k.to === void 0 && k.ti === void 0) {
2877
2885
  return kf;
2878
2886
  }
2879
- const out = __spreadValues2({}, k);
2887
+ const out = __spreadValues({}, k);
2880
2888
  if (out.time === void 0 && k.t !== void 0) out.time = k.t;
2881
2889
  if (out.value === void 0 && k.v !== void 0) out.value = k.v;
2882
2890
  if (out.easing === void 0 && k.e !== void 0) out.easing = k.e;
@@ -2887,9 +2895,9 @@ var PixodeskAnimator = (() => {
2887
2895
  function readStaticOrigin(raw, ctx) {
2888
2896
  var _a;
2889
2897
  const o = readAnimatable(raw);
2890
- if (o.kind === "absent") return void 0;
2891
- if (o.kind === "static") return o.value;
2892
- ctx.warnings.push("transformation.origin: animated origin approximated by its first keyframe");
2898
+ if (o.kind === "absent" /* Absent */) return void 0;
2899
+ if (o.kind === "static" /* Static */) return o.value;
2900
+ ctx.warnings.push("transformBy.origin: animated origin approximated by its first keyframe");
2893
2901
  return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
2894
2902
  }
2895
2903
  function keyframeWith(kf, value) {
@@ -2900,7 +2908,9 @@ var PixodeskAnimator = (() => {
2900
2908
  if (kf.tangentIn !== void 0) out.tangentIn = kf.tangentIn;
2901
2909
  return out;
2902
2910
  }
2903
- function applyTransformationEffect(node, fx, ctx) {
2911
+
2912
+ // ../svg-animator-core/src/effects/transformationEffect.ts
2913
+ function applyTransformByEffect(node, fx, ctx) {
2904
2914
  if (!fx) return node;
2905
2915
  delete node.transform;
2906
2916
  let n = node;
@@ -2910,9 +2920,9 @@ var PixodeskAnimator = (() => {
2910
2920
  /*invert=*/
2911
2921
  true
2912
2922
  );
2913
- n = wrapTransformPart(n, "scale", normalizeScale(fx.scale), ctx);
2914
- n = wrapTransformPart(n, "skew", fx.skew, ctx);
2915
- n = wrapTransformPart(n, "rotate", fx.rotate, ctx);
2923
+ n = wrapTransformPart(n, "scale" /* Scale */, normalizeScale(fx.scale), ctx);
2924
+ n = wrapTransformPart(n, "skew" /* Skew */, fx.skew, ctx);
2925
+ n = wrapTransformPart(n, "rotate" /* Rotate */, fx.rotate, ctx);
2916
2926
  n = wrapOrigin(
2917
2927
  n,
2918
2928
  fx.origin,
@@ -2926,7 +2936,7 @@ var PixodeskAnimator = (() => {
2926
2936
  /*invert=*/
2927
2937
  true
2928
2938
  );
2929
- n = wrapTransformPart(n, "translate", fx.translate, ctx);
2939
+ n = wrapTransformPart(n, "translate" /* Translate */, fx.translate, ctx);
2930
2940
  n = wrapOrigin(
2931
2941
  n,
2932
2942
  fx.origin,
@@ -2934,7 +2944,11 @@ var PixodeskAnimator = (() => {
2934
2944
  false
2935
2945
  );
2936
2946
  } else {
2937
- n = wrapTransformPart(n, "translate", fx.translate, ctx);
2947
+ n = wrapTransformPart(n, "translate" /* Translate */, fx.translate, ctx);
2948
+ }
2949
+ if (n !== node && node.id) {
2950
+ n.id = node.id;
2951
+ delete node.id;
2938
2952
  }
2939
2953
  return n;
2940
2954
  }
@@ -2945,17 +2959,15 @@ var PixodeskAnimator = (() => {
2945
2959
  return Array.isArray(obj.keyframes) && obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
2946
2960
  }
2947
2961
  function normalizeScale(raw) {
2948
- if (raw === void 0) return void 0;
2949
- if (Array.isArray(raw)) return [raw[0] / 100, raw[1] / 100];
2950
2962
  return raw;
2951
2963
  }
2952
2964
  function wrapTransformPart(inner, part, raw, ctx) {
2953
2965
  if (raw === void 0) return inner;
2954
2966
  const v = readAnimatable(raw);
2955
- if (v.kind === "static") {
2967
+ if (v.kind === "static" /* Static */) {
2956
2968
  return { type: "g", transform: { value: partsRecord(part, v.value, void 0) }, children: [inner] };
2957
2969
  }
2958
- if (v.kind === "animated") {
2970
+ if (v.kind === "animated" /* Animated */) {
2959
2971
  const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, kf.value, void 0))) };
2960
2972
  if (v.autoOrient) animTr.autoOrient = true;
2961
2973
  if (v.loop !== void 0) animTr.loop = v.loop;
@@ -2971,12 +2983,12 @@ var PixodeskAnimator = (() => {
2971
2983
  if (raw === void 0) return inner;
2972
2984
  const v = readAnimatable(raw);
2973
2985
  const sign = (value) => invert ? [-value[0], -value[1]] : value;
2974
- if (v.kind === "absent") return inner;
2975
- if (v.kind === "static") {
2986
+ if (v.kind === "absent" /* Absent */) return inner;
2987
+ if (v.kind === "static" /* Static */) {
2976
2988
  if (v.value[0] === 0 && v.value[1] === 0) return inner;
2977
2989
  return { type: "g", transform: { value: { translate: sign(v.value) } }, children: [inner] };
2978
2990
  }
2979
- if (v.kind === "animated") {
2991
+ if (v.kind === "animated" /* Animated */) {
2980
2992
  const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, { translate: sign(kf.value) })) };
2981
2993
  if (v.loop !== void 0) animTr.loop = v.loop;
2982
2994
  return {
@@ -2987,34 +2999,58 @@ var PixodeskAnimator = (() => {
2987
2999
  }
2988
3000
  return inner;
2989
3001
  }
3002
+
3003
+ // ../svg-animator-core/src/effects/util.ts
3004
+ function genId(ctx, prefix) {
3005
+ return "_lw_" + prefix + "_" + ctx.nextId++;
3006
+ }
3007
+ function stripHash2(href) {
3008
+ return typeof href === "string" ? href.replace(/^#/, "") : void 0;
3009
+ }
3010
+ function indexById(node, map) {
3011
+ var _a;
3012
+ if (typeof node.id === "string") map.set(node.id, node);
3013
+ (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
3014
+ }
3015
+ function spliceDefs(root, defs) {
3016
+ if (!defs.length) return;
3017
+ const existing = root.children || (root.children = []);
3018
+ existing.unshift({ type: "defs", children: defs });
3019
+ }
3020
+ var clone = deepClonePxNode;
3021
+ function regenerateIdsInClone(root, ctx) {
3022
+ return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
3023
+ }
3024
+
3025
+ // ../svg-animator-core/src/effects/contentRefSplit.ts
2990
3026
  function identifyContentRefTargets(node, ctx, allocator) {
2991
3027
  var _a, _b, _c;
2992
3028
  if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.type) === "content") {
2993
- const baseId = node.effects.clone.baseId;
2994
- if (typeof baseId === "string" && baseId && !ctx.contentRefInnerIds.has(baseId)) {
2995
- ctx.contentRefInnerIds.set(baseId, allocator(baseId));
3029
+ const sourceId = stripHash2(node.effects.clone.sourceId);
3030
+ if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
3031
+ ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
2996
3032
  }
2997
3033
  }
2998
3034
  (_c = node.children) == null ? void 0 : _c.forEach((c) => identifyContentRefTargets(c, ctx, allocator));
2999
3035
  }
3000
- function splitForContentRef(node, transformation, originalId, innerId, ctx) {
3001
- const outerBody = liftBodyTranslate(node, transformation);
3036
+ function splitForContentRef(node, transformBy, originalId, innerId, ctx) {
3037
+ const outerBody = liftBodyTranslate(node, transformBy);
3002
3038
  if (typeof node.id === "string") delete node.id;
3003
- const { outer: outerTr, inner: innerTr } = splitTransformationEffect(transformation);
3039
+ const { outer: outerTr, inner: innerTr } = splitTransformByEffect(transformBy);
3004
3040
  let innerNode = node;
3005
- innerNode = applyTransformationEffect(innerNode, innerTr, ctx);
3041
+ innerNode = applyTransformByEffect(innerNode, innerTr, ctx);
3006
3042
  const innerWrapper = { type: "g", id: innerId, children: [innerNode] };
3007
3043
  let outerWrapper = { type: "g", id: originalId, children: [innerWrapper] };
3008
3044
  if (outerBody.transform !== void 0) outerWrapper.transform = outerBody.transform;
3009
3045
  if (outerBody.animate !== void 0) outerWrapper.animate = outerBody.animate;
3010
3046
  if (outerTr) {
3011
3047
  delete outerWrapper.id;
3012
- outerWrapper = applyTransformationEffect(outerWrapper, outerTr, ctx);
3048
+ outerWrapper = applyTransformByEffect(outerWrapper, outerTr, ctx);
3013
3049
  outerWrapper.id = originalId;
3014
3050
  }
3015
3051
  return outerWrapper;
3016
3052
  }
3017
- function liftBodyTranslate(node, transformation) {
3053
+ function liftBodyTranslate(node, transformBy) {
3018
3054
  var _a, _b, _c;
3019
3055
  const out = {};
3020
3056
  let didLiftAnimate = false;
@@ -3068,7 +3104,7 @@ var PixodeskAnimator = (() => {
3068
3104
  didLiftAnimate = true;
3069
3105
  }
3070
3106
  }
3071
- const transformationHasTranslate = (transformation == null ? void 0 : transformation.translate) !== void 0;
3107
+ const transformationHasTranslate = (transformBy == null ? void 0 : transformBy.translate) !== void 0;
3072
3108
  const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;
3073
3109
  const liftedAnimateIsAutoOriented = didLiftAnimate && needsOriginOnOuter(((_b = node.animate) == null ? void 0 : _b.transform) || void 0) || didLiftAnimate && needsOriginOnOuter(((_c = out.animate) == null ? void 0 : _c.transform) || void 0);
3074
3110
  if (typeof node.transform === "string") {
@@ -3087,6 +3123,24 @@ var PixodeskAnimator = (() => {
3087
3123
  if (split.rest) node.transform = split.rest;
3088
3124
  else delete node.transform;
3089
3125
  }
3126
+ } else if (node.transform && typeof node.transform === "object" && !Array.isArray(node.transform) && !node.transform.keyframes && !node.transform.kfs) {
3127
+ const wrapped = node.transform.value;
3128
+ const isWrapped = !!(wrapped && typeof wrapped === "object");
3129
+ const value = isWrapped ? wrapped : node.transform;
3130
+ const rewrap = (rec) => isWrapped ? { value: rec } : rec;
3131
+ if (Array.isArray(value.translate)) {
3132
+ const rest = __spreadValues({}, value);
3133
+ delete rest.translate;
3134
+ const hasRest = Object.keys(rest).length > 0;
3135
+ if (stripBodyTranslateOnly) {
3136
+ if (hasRest) node.transform = rewrap(rest);
3137
+ else delete node.transform;
3138
+ } else {
3139
+ out.transform = rewrap({ translate: value.translate });
3140
+ if (hasRest) node.transform = rewrap(rest);
3141
+ else delete node.transform;
3142
+ }
3143
+ }
3090
3144
  }
3091
3145
  return out;
3092
3146
  }
@@ -3156,7 +3210,7 @@ var PixodeskAnimator = (() => {
3156
3210
  const nums = m[1].split(/[\s,]+/).filter(Boolean).map(Number);
3157
3211
  return [nums[0] || 0, nums[1] || 0];
3158
3212
  }
3159
- function splitTransformationEffect(fx) {
3213
+ function splitTransformByEffect(fx) {
3160
3214
  if (!fx) return {};
3161
3215
  const originOnOuter = needsOriginOnOuter(fx.translate);
3162
3216
  const innerHasPivotedPart = fx.rotate !== void 0 || fx.scale !== void 0;
@@ -3182,26 +3236,8 @@ var PixodeskAnimator = (() => {
3182
3236
  }
3183
3237
  return false;
3184
3238
  }
3185
- function genId(ctx, prefix) {
3186
- return "_lw_" + prefix + "_" + ctx.nextId++;
3187
- }
3188
- function stripHash2(href) {
3189
- return typeof href === "string" ? href.replace(/^#/, "") : void 0;
3190
- }
3191
- function indexById(node, map) {
3192
- var _a;
3193
- if (typeof node.id === "string") map.set(node.id, node);
3194
- (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
3195
- }
3196
- function spliceDefs(root, defs) {
3197
- if (!defs.length) return;
3198
- const existing = root.children || (root.children = []);
3199
- existing.unshift({ type: "defs", children: defs });
3200
- }
3201
- var clone = deepClonePxNode;
3202
- function regenerateIdsInClone(root, ctx) {
3203
- return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
3204
- }
3239
+
3240
+ // ../svg-animator-core/src/effects/gradientEffect.ts
3205
3241
  function applyFillGradientEffect(node, fx, ctx) {
3206
3242
  return applyGradient(node, fx, ctx, "fill");
3207
3243
  }
@@ -3222,62 +3258,63 @@ var PixodeskAnimator = (() => {
3222
3258
  id
3223
3259
  };
3224
3260
  if (fx.type === PxGradientType.linear) {
3225
- if (fx.p1) {
3226
- out.x1 = String(fx.p1[0]);
3227
- out.y1 = String(fx.p1[1]);
3228
- }
3229
- if (fx.p2) {
3230
- out.x2 = String(fx.p2[0]);
3231
- out.y2 = String(fx.p2[1]);
3232
- }
3261
+ applyGeomVec(out, "x1", "y1", fx.p1);
3262
+ applyGeomVec(out, "x2", "y2", fx.p2);
3233
3263
  } else {
3234
- if (fx.c) {
3235
- out.cx = String(fx.c[0]);
3236
- out.cy = String(fx.c[1]);
3237
- }
3238
- if (fx.r !== void 0) out.r = String(fx.r);
3239
- if (fx.fp) {
3240
- out.fx = String(fx.fp[0]);
3241
- out.fy = String(fx.fp[1]);
3242
- }
3264
+ applyGeomVec(out, "cx", "cy", fx.c);
3265
+ applyGeomNumber(out, "r", fx.r);
3266
+ applyGeomVec(out, "fx", "fy", fx.fp);
3243
3267
  }
3244
3268
  if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
3245
3269
  if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
3246
3270
  if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;
3247
- const animate = fx.animate;
3248
- if (animate) {
3249
- const mapped = {};
3250
- for (const wireKey of Object.keys(animate)) {
3251
- const attr = GRADIENT_ANIM_CHANNEL_TO_ATTR[wireKey];
3252
- if (attr) mapped[attr] = animate[wireKey];
3253
- }
3254
- if (Object.keys(mapped).length) out.animate = mapped;
3255
- }
3256
3271
  out.children = buildStopChildren(fx.stops, ctx);
3257
3272
  return out;
3258
3273
  }
3259
- var GRADIENT_ANIM_CHANNEL_TO_ATTR = {
3260
- gradientX1: "x1",
3261
- gradientY1: "y1",
3262
- gradientX2: "x2",
3263
- gradientY2: "y2",
3264
- gradientCx: "cx",
3265
- gradientCy: "cy",
3266
- gradientFx: "fx",
3267
- gradientFy: "fy",
3268
- gradientR: "r"
3269
- };
3274
+ function applyGeomVec(out, xAttr, yAttr, raw) {
3275
+ var _a, _b, _c;
3276
+ const read = readAnimatable(raw);
3277
+ if (read.kind === "absent" /* Absent */) return;
3278
+ if (read.kind === "static" /* Static */) {
3279
+ out[xAttr] = String(read.value[0]);
3280
+ out[yAttr] = String(read.value[1]);
3281
+ return;
3282
+ }
3283
+ const axisChannel = (idx) => {
3284
+ const block = {
3285
+ keyframes: read.keyframes.map((kf) => {
3286
+ const axisKf = { time: kf.time, value: Array.isArray(kf.value) ? kf.value[idx] : void 0 };
3287
+ if (kf.easing !== void 0) axisKf.easing = kf.easing;
3288
+ return axisKf;
3289
+ })
3290
+ };
3291
+ if (read.loop !== void 0) block.loop = read.loop;
3292
+ return block;
3293
+ };
3294
+ const animate = (_a = out.animate) != null ? _a : {};
3295
+ animate[xAttr] = axisChannel(0);
3296
+ animate[yAttr] = axisChannel(1);
3297
+ out.animate = animate;
3298
+ const baseline = (_c = read.base) != null ? _c : (_b = read.keyframes[0]) == null ? void 0 : _b.value;
3299
+ if (Array.isArray(baseline)) {
3300
+ out[xAttr] = String(baseline[0]);
3301
+ out[yAttr] = String(baseline[1]);
3302
+ }
3303
+ }
3304
+ function applyGeomNumber(out, attrName, raw) {
3305
+ const read = readAnimatable(raw);
3306
+ if (read.kind === "absent" /* Absent */) return;
3307
+ writeAnimatableChannel(out, attrName, read, { asString: true });
3308
+ }
3270
3309
  function buildStopChildren(stops, ctx) {
3271
3310
  var _a, _b, _c, _d;
3272
3311
  if (!stops) return [];
3273
- if (Array.isArray(stops)) return stops.map(staticStopNode);
3274
- if (typeof stops === "object" && Array.isArray(stops.value)) {
3275
- return stops.value.map(staticStopNode);
3276
- }
3277
- const animBlock = stops;
3278
- const kfs = animBlock.keyframes;
3279
- if (!Array.isArray(kfs) || !kfs.length) return [];
3280
- const loopFromSource = animBlock.loop;
3312
+ const read = readAnimatable(stops);
3313
+ if (read.kind === "absent" /* Absent */) return [];
3314
+ if (read.kind === "static" /* Static */) return Array.isArray(read.value) ? read.value.map(staticStopNode) : [];
3315
+ const kfs = read.keyframes;
3316
+ if (!kfs.length) return [];
3317
+ const loopFromSource = read.loop;
3281
3318
  let stopCount = 0;
3282
3319
  for (const kf of kfs) {
3283
3320
  const v = (_a = kf.value) != null ? _a : kf.v;
@@ -3351,37 +3388,65 @@ var PixodeskAnimator = (() => {
3351
3388
  const pct = Math.round(o * 1e3) / 10;
3352
3389
  return pct + "%";
3353
3390
  }
3391
+
3392
+ // ../svg-animator-core/src/effects/clipPathEffect.ts
3354
3393
  function applyClipPathEffect(node, fx, ctx) {
3394
+ var _a, _b;
3355
3395
  if (!fx || !fx.d && !fx.animate) return node;
3356
3396
  const clipId = genId(ctx, "clip");
3357
- const pathChild = { type: "path", d: fx.d };
3358
- if (fx.animate) pathChild.animate = { d: fx.animate };
3397
+ const pathChild = { type: "path" };
3398
+ const read = readAnimatable(fx.d);
3399
+ if (read.kind !== "absent" /* Absent */) {
3400
+ if (read.kind === "static" /* Static */) {
3401
+ pathChild.d = pathString(read.value);
3402
+ } else {
3403
+ writeAnimatableChannel(pathChild, "d", read);
3404
+ if (pathChild.d !== void 0) pathChild.d = pathString(pathChild.d);
3405
+ }
3406
+ }
3407
+ if (fx.animate && !((_a = pathChild.animate) == null ? void 0 : _a.d)) {
3408
+ const animate = (_b = pathChild.animate) != null ? _b : {};
3409
+ animate.d = fx.animate;
3410
+ pathChild.animate = animate;
3411
+ }
3359
3412
  ctx.defs.push({ type: "clipPath", id: clipId, children: [pathChild] });
3360
3413
  node.clipPath = "url(#" + clipId + ")";
3361
3414
  return node;
3362
3415
  }
3363
- function applyMaskedByEffect(node, fx, transformation, ctx) {
3416
+ function pathString(v) {
3417
+ if (typeof v === "string") return v;
3418
+ if (v && typeof v === "object" && typeof v.path === "string") return v.path;
3419
+ return void 0;
3420
+ }
3421
+
3422
+ // ../svg-animator-core/src/effects/maskedByEffect.ts
3423
+ function applyMaskedByEffect(node, fx, transformBy, ctx) {
3364
3424
  if (!fx) return node;
3365
- if (!fx.href) {
3366
- ctx.errors.push("maskedBy.href missing \u2014 cannot build mask");
3425
+ const sourceId = stripHash2(fx.sourceId);
3426
+ if (!sourceId) {
3427
+ ctx.errors.push("maskedBy.sourceId missing \u2014 cannot build mask");
3367
3428
  return node;
3368
3429
  }
3369
3430
  const maskId = genId(ctx, "mask");
3370
- let content = { type: "use", href: "#" + fx.href };
3371
- if (transformation) {
3372
- content = wrapInverseTransform(content, transformation, ctx);
3431
+ let content = { type: "use", href: "#" + sourceId };
3432
+ if (transformBy) {
3433
+ content = wrapInverseTransform(content, transformBy, ctx);
3373
3434
  } else if (hasAnimateTransform(node)) {
3374
3435
  content = wrapInverseAnimatedBodyTransform(content, node, ctx);
3375
3436
  } else {
3376
3437
  const bodyStatic = readTransformationFromBody(node);
3377
3438
  if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);
3378
3439
  }
3379
- const includeTargetOwn = transformation === void 0 && !nodeHasBodyTransform(node);
3380
- content = wrapAncestorChainCompensation(content, node, fx.href, ctx, includeTargetOwn);
3440
+ const includeTargetOwn = transformBy === void 0 && !nodeHasBodyTransform(node);
3441
+ content = wrapAncestorChainCompensation(content, node, sourceId, ctx, includeTargetOwn);
3381
3442
  const mask = { type: "mask", id: maskId, children: [content] };
3382
3443
  if (fx.maskType) mask.maskType = fx.maskType;
3383
3444
  if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
3384
3445
  if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
3446
+ if (fx.x !== void 0) mask.x = String(fx.x);
3447
+ if (fx.y !== void 0) mask.y = String(fx.y);
3448
+ if (fx.width !== void 0) mask.width = String(fx.width);
3449
+ if (fx.height !== void 0) mask.height = String(fx.height);
3385
3450
  ctx.defs.push(mask);
3386
3451
  node.mask = "url(#" + maskId + ")";
3387
3452
  return node;
@@ -3390,22 +3455,22 @@ var PixodeskAnimator = (() => {
3390
3455
  if (!fx) return inner;
3391
3456
  const origin = readStaticOrigin(fx.origin, ctx);
3392
3457
  let n = inner;
3393
- n = wrapInversePart(n, "translate", fx.translate, void 0, ctx);
3394
- n = wrapInversePart(n, "rotate", fx.rotate, origin, ctx);
3395
- n = wrapInversePart(n, "scale", fx.scale, origin, ctx);
3458
+ n = wrapInversePart(n, "translate" /* Translate */, fx.translate, void 0, ctx);
3459
+ n = wrapInversePart(n, "rotate" /* Rotate */, fx.rotate, origin, ctx);
3460
+ n = wrapInversePart(n, "scale" /* Scale */, fx.scale, origin, ctx);
3396
3461
  return n;
3397
3462
  }
3398
3463
  function wrapInversePart(inner, part, raw, origin, ctx) {
3399
3464
  if (raw === void 0) return inner;
3400
- const normalisedRaw = part === "scale" && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
3465
+ const normalisedRaw = part === "scale" /* Scale */ && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
3401
3466
  const v = readAnimatable(normalisedRaw);
3402
- if (v.kind === "static") {
3467
+ if (v.kind === "static" /* Static */) {
3403
3468
  return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
3404
3469
  }
3405
- if (v.kind === "animated") {
3470
+ if (v.kind === "animated" /* Animated */) {
3406
3471
  const animTr = { keyframes: v.keyframes.map((kf) => {
3407
3472
  const out = keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin));
3408
- return part === "translate" ? __spreadValues2(__spreadValues2({}, out), negatedSpatialTangents(kf)) : out;
3473
+ return part === "translate" /* Translate */ ? __spreadValues(__spreadValues({}, out), negatedSpatialTangents(kf)) : out;
3409
3474
  }) };
3410
3475
  if (v.loop !== void 0) animTr.loop = v.loop;
3411
3476
  return {
@@ -3417,8 +3482,8 @@ var PixodeskAnimator = (() => {
3417
3482
  return inner;
3418
3483
  }
3419
3484
  function invertPartValue(part, value) {
3420
- if (part === "translate") return [-value[0], -value[1]];
3421
- if (part === "rotate") return -value;
3485
+ if (part === "translate" /* Translate */) return [-value[0], -value[1]];
3486
+ if (part === "rotate" /* Rotate */) return -value;
3422
3487
  return [1 / value[0], 1 / value[1]];
3423
3488
  }
3424
3489
  function negatedSpatialTangents(kf) {
@@ -3443,17 +3508,17 @@ var PixodeskAnimator = (() => {
3443
3508
  const v = ((_a = kf.value) != null ? _a : kf.v) || {};
3444
3509
  const baseKf = keyframeWith(kf, void 0);
3445
3510
  if (Array.isArray(v.translate)) {
3446
- translateKfs.push(__spreadProps2(__spreadValues2(__spreadValues2({}, baseKf), negatedSpatialTangents(kf)), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
3511
+ translateKfs.push(__spreadProps(__spreadValues(__spreadValues({}, baseKf), negatedSpatialTangents(kf)), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
3447
3512
  }
3448
3513
  if (typeof v.rotate === "number") {
3449
3514
  const rec = { rotate: -v.rotate };
3450
3515
  if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
3451
- rotateKfs.push(__spreadProps2(__spreadValues2({}, baseKf), { value: rec }));
3516
+ rotateKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
3452
3517
  }
3453
3518
  if (Array.isArray(v.scale)) {
3454
3519
  const rec = { scale: [1 / v.scale[0], 1 / v.scale[1]] };
3455
3520
  if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
3456
- scaleKfs.push(__spreadProps2(__spreadValues2({}, baseKf), { value: rec }));
3521
+ scaleKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
3457
3522
  }
3458
3523
  }
3459
3524
  const srcLoop = animTr == null ? void 0 : animTr.loop;
@@ -3488,6 +3553,19 @@ var PixodeskAnimator = (() => {
3488
3553
  if (parts.origin) out.origin = parts.origin;
3489
3554
  return Object.keys(out).length ? out : void 0;
3490
3555
  }
3556
+ if (node.transform && typeof node.transform === "object" && !node.transform.keyframes && !node.transform.kfs) {
3557
+ const wrapped = node.transform.value;
3558
+ const value = wrapped && typeof wrapped === "object" ? wrapped : node.transform;
3559
+ if (value && typeof value === "object") {
3560
+ const out = {};
3561
+ if (Array.isArray(value.translate)) out.translate = value.translate;
3562
+ if (typeof value.rotate === "number") out.rotate = value.rotate;
3563
+ if (typeof value.skew === "number") out.skew = value.skew;
3564
+ if (Array.isArray(value.scale)) out.scale = { value: value.scale };
3565
+ if (Array.isArray(value.origin)) out.origin = value.origin;
3566
+ return Object.keys(out).length ? out : void 0;
3567
+ }
3568
+ }
3491
3569
  return void 0;
3492
3570
  }
3493
3571
  function parseTransformStringToParts(s) {
@@ -3621,10 +3699,10 @@ var PixodeskAnimator = (() => {
3621
3699
  const interestingNodes = /* @__PURE__ */ new Set();
3622
3700
  const collectInterestingNodes = (n) => {
3623
3701
  var _a, _b;
3624
- const href = (_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.href;
3625
- if (typeof href === "string") {
3702
+ const maskSourceId = stripHash2((_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.sourceId);
3703
+ if (typeof maskSourceId === "string") {
3626
3704
  interestingNodes.add(n);
3627
- const sourceNode = ctx.idMap.get(href);
3705
+ const sourceNode = ctx.idMap.get(maskSourceId);
3628
3706
  if (sourceNode) interestingNodes.add(sourceNode);
3629
3707
  }
3630
3708
  if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);
@@ -3650,8 +3728,9 @@ var PixodeskAnimator = (() => {
3650
3728
  if (typeof tr === "string") {
3651
3729
  const parts = parseTranslateOnlyFromString(tr, ctx);
3652
3730
  if (parts) out.translate = parts;
3653
- } else if (tr && typeof tr === "object") {
3654
- const value = tr.value;
3731
+ } else if (tr && typeof tr === "object" && !tr.keyframes && !tr.kfs) {
3732
+ const wrapped = tr.value;
3733
+ const value = wrapped && typeof wrapped === "object" ? wrapped : tr;
3655
3734
  if (value && typeof value === "object" && Array.isArray(value.translate)) {
3656
3735
  out.translate = [value.translate[0] || 0, value.translate[1] || 0];
3657
3736
  }
@@ -3696,21 +3775,25 @@ var PixodeskAnimator = (() => {
3696
3775
  if (droppedNonTranslate) ctx.warnings.push("maskedBy ancestor: non-translate transform in string ignored: " + s);
3697
3776
  return seen ? [x, y] : void 0;
3698
3777
  }
3778
+
3779
+ // ../svg-animator-core/src/effects/refEffect.ts
3699
3780
  var CONTENT_SUBREF = "content";
3700
3781
  function applyRefHref(node, clone2, ctx) {
3701
3782
  if (!clone2) return;
3702
- const baseId = clone2.baseId;
3703
- if (!baseId) {
3704
- if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing baseId");
3783
+ const sourceId = stripHash2(clone2.sourceId);
3784
+ if (!sourceId) {
3785
+ if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing sourceId");
3705
3786
  return;
3706
3787
  }
3707
- const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
3788
+ const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
3708
3789
  node.href = "#" + targetId;
3709
3790
  }
3710
- function applyRefAndTransformationEffect(node, clone2, transformation, ctx) {
3791
+ function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
3711
3792
  applyRefHref(node, clone2, ctx);
3712
- return applyTransformationEffect(node, transformation, ctx);
3793
+ return applyTransformByEffect(node, transformBy, ctx);
3713
3794
  }
3795
+
3796
+ // ../svg-animator-core/src/effects/repeaterEffect.ts
3714
3797
  function applyRepeaterEffect(node, fx, ctx) {
3715
3798
  var _a, _b;
3716
3799
  if (!fx) return node;
@@ -3732,7 +3815,7 @@ var PixodeskAnimator = (() => {
3732
3815
  for (let i = 1; i < copies; i++) {
3733
3816
  const baseClone = clone(base);
3734
3817
  const synthFx = synthesisePerCopyFx(fx, i);
3735
- const wrapped = synthFx ? applyTransformationEffect(baseClone, synthFx, ctx) : baseClone;
3818
+ const wrapped = synthFx ? applyTransformByEffect(baseClone, synthFx, ctx) : baseClone;
3736
3819
  children.push(wrapped);
3737
3820
  }
3738
3821
  const wrapper = { type: "g", children };
@@ -3744,10 +3827,13 @@ var PixodeskAnimator = (() => {
3744
3827
  function synthesisePerCopyFx(fx, i) {
3745
3828
  const out = {};
3746
3829
  if (fx.translate !== void 0) {
3747
- out.translate = mapAnimatableVec2(fx.translate, (v) => [v[0] * i, v[1] * i]);
3830
+ out.translate = mapAnimatable(fx.translate, (v) => [v[0] * i, v[1] * i]);
3748
3831
  }
3749
3832
  if (fx.rotate !== void 0) {
3750
- out.rotate = mapAnimatableNumber(fx.rotate, (v) => v * i);
3833
+ out.rotate = mapAnimatable(fx.rotate, (v) => v * i);
3834
+ }
3835
+ if (fx.skew !== void 0) {
3836
+ out.skew = mapAnimatable(fx.skew, (v) => v * i);
3751
3837
  }
3752
3838
  if (fx.scale !== void 0) {
3753
3839
  out.scale = synthesiseScale(fx.scale, i);
@@ -3757,63 +3843,52 @@ var PixodeskAnimator = (() => {
3757
3843
  }
3758
3844
  return Object.keys(out).length ? out : void 0;
3759
3845
  }
3760
- function mapAnimatableVec2(raw, fn) {
3761
- if (Array.isArray(raw)) return fn(raw);
3762
- if (raw && typeof raw === "object") {
3763
- const obj = raw;
3764
- if (Array.isArray(obj.keyframes)) {
3765
- return __spreadProps2(__spreadValues2({}, obj), {
3766
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
3767
- });
3768
- }
3769
- if (obj.value !== void 0) {
3770
- return __spreadProps2(__spreadValues2({}, obj), { value: fn(obj.value) });
3771
- }
3772
- }
3773
- return raw;
3774
- }
3775
- function mapAnimatableNumber(raw, fn) {
3776
- if (typeof raw === "number") return fn(raw);
3777
- if (raw && typeof raw === "object") {
3778
- const obj = raw;
3779
- if (Array.isArray(obj.keyframes)) {
3780
- return __spreadProps2(__spreadValues2({}, obj), {
3781
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
3782
- });
3783
- }
3784
- if (obj.value !== void 0) {
3785
- return __spreadProps2(__spreadValues2({}, obj), { value: fn(obj.value) });
3786
- }
3846
+ function mapAnimatable(raw, fn, wrapStatic = false) {
3847
+ const read = readAnimatable(raw);
3848
+ if (read.kind === "absent" /* Absent */) return raw;
3849
+ if (read.kind === "static" /* Static */) {
3850
+ const mapped = fn(read.value);
3851
+ const wasRawStatic = typeof raw === "number" || Array.isArray(raw);
3852
+ return wasRawStatic && !wrapStatic ? mapped : { value: mapped };
3787
3853
  }
3788
- return raw;
3854
+ const out = {
3855
+ keyframes: read.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: fn(kf.value) }) : kf)
3856
+ };
3857
+ if (read.loop !== void 0) out.loop = read.loop;
3858
+ if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
3859
+ if (read.base !== void 0) out.value = fn(read.base);
3860
+ return out;
3789
3861
  }
3790
3862
  function synthesiseScale(raw, i) {
3791
- const scalePowerFromPercent = (v) => [Math.pow(v[0] / 100, i), Math.pow(v[1] / 100, i)];
3792
- const scalePowerFromUnits = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
3793
- if (Array.isArray(raw)) {
3794
- return { value: scalePowerFromPercent(raw) };
3795
- }
3796
- if (raw && typeof raw === "object") {
3797
- const obj = raw;
3798
- if (Array.isArray(obj.keyframes)) {
3799
- return __spreadProps2(__spreadValues2({}, obj), {
3800
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: scalePowerFromUnits(kf.value) }) : kf)
3801
- });
3802
- }
3803
- if (obj.value !== void 0) {
3804
- return __spreadProps2(__spreadValues2({}, obj), { value: scalePowerFromPercent(obj.value) });
3805
- }
3806
- }
3807
- return raw;
3863
+ const scalePower = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
3864
+ return mapAnimatable(raw, scalePower, true);
3808
3865
  }
3866
+
3867
+ // ../svg-animator-core/src/effects/retimeEffect.ts
3809
3868
  var RETIME_MATERIALISATION_MODE_INLINE_G = false;
3810
3869
  function asRetime(r) {
3811
3870
  var _a, _b;
3812
- if (r.timeCrop) {
3813
- console.warn("retime: `timeCrop` is not supported yet and will be ignored");
3814
- }
3815
3871
  return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
3816
3872
  }
3873
+ var CROP_EDGE_MS = 1;
3874
+ function applyTimeCrop(useNode, crop, ctx) {
3875
+ const [start, end] = crop;
3876
+ if (!Number.isFinite(start) || !Number.isFinite(end)) {
3877
+ ctx.warnings.push("retime: timeCrop is not a pair of finite numbers \u2014 ignored");
3878
+ return;
3879
+ }
3880
+ const keyframes = end <= start ? [{ time: 0, value: 0 }] : [
3881
+ ...start > 0 ? [{ time: Math.max(0, start - CROP_EDGE_MS), value: 0 }] : [],
3882
+ { time: Math.max(0, start), value: 1 },
3883
+ { time: end, value: 1 },
3884
+ { time: end + CROP_EDGE_MS, value: 0 }
3885
+ ];
3886
+ const inner = __spreadValues({}, useNode);
3887
+ for (const k of Object.keys(useNode)) delete useNode[k];
3888
+ useNode.type = "g";
3889
+ useNode.children = [inner];
3890
+ useNode.animate = { opacity: { keyframes } };
3891
+ }
3817
3892
  function concatRetime(child, parent) {
3818
3893
  return {
3819
3894
  start: parent.start + parent.stretch * child.start,
@@ -3873,8 +3948,10 @@ var PixodeskAnimator = (() => {
3873
3948
  for (const useNode of sites) {
3874
3949
  const retime = readCloneRetime(useNode);
3875
3950
  if (!retime) continue;
3951
+ const crop = retime.timeCrop;
3876
3952
  clearCloneRetime(useNode);
3877
3953
  materialiseRetime(useNode, asRetime(retime), ctx);
3954
+ if (crop) applyTimeCrop(useNode, crop, ctx);
3878
3955
  }
3879
3956
  }
3880
3957
  function materialiseRetime(useNode, retime, ctx) {
@@ -3969,6 +4046,8 @@ var PixodeskAnimator = (() => {
3969
4046
  }
3970
4047
  }
3971
4048
  }
4049
+
4050
+ // ../svg-animator-core/src/effects/pathSampler.ts
3972
4051
  var LUT_STEPS = 48;
3973
4052
  var CMD_RE = /[MmLlHhVvCcSsQqTtAaZz]/;
3974
4053
  function tokenize(d) {
@@ -3993,7 +4072,7 @@ var PixodeskAnimator = (() => {
3993
4072
  let pcx = 0, pcy = 0;
3994
4073
  let pqx = 0, pqy = 0;
3995
4074
  let prevCmd = "";
3996
- const num2 = () => parseFloat(tokens[i++]);
4075
+ const num = () => parseFloat(tokens[i++]);
3997
4076
  const push = (P1, P2, P3) => {
3998
4077
  const P0 = [cx, cy];
3999
4078
  const lut = bezier2D_arcLengthLUT(P0, P1, P2, P3, LUT_STEPS);
@@ -4022,7 +4101,7 @@ var PixodeskAnimator = (() => {
4022
4101
  continue;
4023
4102
  }
4024
4103
  if (U === "M") {
4025
- const x = num2() + (rel ? cx : 0), y = num2() + (rel ? cy : 0);
4104
+ const x = num() + (rel ? cx : 0), y = num() + (rel ? cy : 0);
4026
4105
  cx = x;
4027
4106
  cy = y;
4028
4107
  sx = x;
@@ -4031,29 +4110,29 @@ var PixodeskAnimator = (() => {
4031
4110
  continue;
4032
4111
  }
4033
4112
  if (U === "L") {
4034
- pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
4113
+ pushLine(num() + (rel ? cx : 0), num() + (rel ? cy : 0));
4035
4114
  } else if (U === "H") {
4036
- pushLine(num2() + (rel ? cx : 0), cy);
4115
+ pushLine(num() + (rel ? cx : 0), cy);
4037
4116
  } else if (U === "V") {
4038
- pushLine(cx, num2() + (rel ? cy : 0));
4117
+ pushLine(cx, num() + (rel ? cy : 0));
4039
4118
  } else if (U === "C") {
4040
- const p1 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4041
- const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4042
- const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4119
+ const p1 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4120
+ const p2 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4121
+ const p3 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4043
4122
  pcx = p2[0];
4044
4123
  pcy = p2[1];
4045
4124
  push(p1, p2, p3);
4046
4125
  } else if (U === "S") {
4047
4126
  const smooth = prevCmd.toUpperCase() === "C" || prevCmd.toUpperCase() === "S";
4048
4127
  const p1 = smooth ? [2 * cx - pcx, 2 * cy - pcy] : [cx, cy];
4049
- const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4050
- const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4128
+ const p2 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4129
+ const p3 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4051
4130
  pcx = p2[0];
4052
4131
  pcy = p2[1];
4053
4132
  push(p1, p2, p3);
4054
4133
  } else if (U === "Q") {
4055
- const qc = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4056
- const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4134
+ const qc = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4135
+ const p3 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4057
4136
  pqx = qc[0];
4058
4137
  pqy = qc[1];
4059
4138
  const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
@@ -4061,14 +4140,14 @@ var PixodeskAnimator = (() => {
4061
4140
  } else if (U === "T") {
4062
4141
  const smooth = prevCmd.toUpperCase() === "Q" || prevCmd.toUpperCase() === "T";
4063
4142
  const qc = smooth ? [2 * cx - pqx, 2 * cy - pqy] : [cx, cy];
4064
- const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4143
+ const p3 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4065
4144
  pqx = qc[0];
4066
4145
  pqy = qc[1];
4067
4146
  const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
4068
4147
  push(P1, P2, p3);
4069
4148
  } else if (U === "A") {
4070
4149
  i += 5;
4071
- pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
4150
+ pushLine(num() + (rel ? cx : 0), num() + (rel ? cy : 0));
4072
4151
  } else {
4073
4152
  i++;
4074
4153
  continue;
@@ -4115,16 +4194,15 @@ var PixodeskAnimator = (() => {
4115
4194
  }
4116
4195
  };
4117
4196
  }
4197
+
4198
+ // ../svg-animator-core/src/effects/textPathEffect.ts
4118
4199
  var EXTEND_MARGIN_FRAC = 0.15;
4119
4200
  function numRange(v) {
4120
- if (typeof v === "number") return { min: v, max: v };
4121
- if (v && typeof v === "object") {
4122
- const o = v;
4123
- if (typeof o.value === "number") return { min: o.value, max: o.value };
4124
- if (Array.isArray(o.keyframes) && o.keyframes.length) {
4125
- const vals = o.keyframes.map((k) => Number(k.value) || 0);
4126
- return { min: Math.min(...vals), max: Math.max(...vals) };
4127
- }
4201
+ const read = readAnimatable(v);
4202
+ if (read.kind === "static" /* Static */ && typeof read.value === "number") return { min: read.value, max: read.value };
4203
+ if (read.kind === "animated" /* Animated */ && read.keyframes.length) {
4204
+ const vals = read.keyframes.map((k) => Number(k.value) || 0);
4205
+ return { min: Math.min(...vals), max: Math.max(...vals) };
4128
4206
  }
4129
4207
  return { min: 0, max: 0 };
4130
4208
  }
@@ -4144,11 +4222,16 @@ var PixodeskAnimator = (() => {
4144
4222
  var r3 = (n) => Math.round(n * 1e3) / 1e3;
4145
4223
  function shiftAnimatable(v, by) {
4146
4224
  if (!by || v === void 0 || v === null) return v;
4147
- if (typeof v === "number") return v + by;
4148
- const o = v;
4149
- if (typeof o.value === "number") return __spreadProps2(__spreadValues2({}, o), { value: o.value + by });
4150
- if (Array.isArray(o.keyframes)) return __spreadProps2(__spreadValues2({}, o), { keyframes: o.keyframes.map((k) => __spreadProps2(__spreadValues2({}, k), { value: (Number(k.value) || 0) + by })) });
4151
- return v;
4225
+ const read = readAnimatable(v);
4226
+ if (read.kind === "absent" /* Absent */) return v;
4227
+ if (read.kind === "static" /* Static */) return typeof v === "number" ? read.value + by : { value: read.value + by };
4228
+ const out = {
4229
+ keyframes: read.keyframes.map((k) => __spreadProps(__spreadValues({}, k), { value: (Number(k.value) || 0) + by }))
4230
+ };
4231
+ if (read.loop !== void 0) out.loop = read.loop;
4232
+ if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
4233
+ if (read.base !== void 0) out.value = read.base + by;
4234
+ return out;
4152
4235
  }
4153
4236
  function extendedPathForBrowser(pathD, opts) {
4154
4237
  var _a;
@@ -4204,27 +4287,10 @@ var PixodeskAnimator = (() => {
4204
4287
  }
4205
4288
  function applyAnimatableNumber(node, attrName, raw) {
4206
4289
  if (raw === void 0 || raw === null) return;
4207
- if (typeof raw === "number") {
4208
- node[attrName] = String(raw);
4209
- return;
4210
- }
4211
- if (typeof raw === "object" && raw !== null) {
4212
- const obj = raw;
4213
- if (Array.isArray(obj.keyframes)) {
4214
- const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
4215
- const animate = __spreadValues2({}, prevAnimate || {});
4216
- const block = { keyframes: obj.keyframes };
4217
- if (obj.loop !== void 0) block.loop = obj.loop;
4218
- animate[attrName] = block;
4219
- node.animate = animate;
4220
- return;
4221
- }
4222
- if (typeof obj.value === "number") {
4223
- node[attrName] = String(obj.value);
4224
- return;
4225
- }
4226
- }
4290
+ writeAnimatableChannel(node, attrName, readAnimatable(raw), { asString: true });
4227
4291
  }
4292
+
4293
+ // ../svg-animator-core/src/effects/elementFactory.ts
4228
4294
  var jsonElementFactory = (type, props, children) => {
4229
4295
  const node = { type };
4230
4296
  for (const k in props) if (props[k] !== void 0) node[k] = props[k];
@@ -4232,6 +4298,8 @@ var PixodeskAnimator = (() => {
4232
4298
  if (arr.length) node.children = arr;
4233
4299
  return node;
4234
4300
  };
4301
+
4302
+ // ../svg-animator-core/src/effects/glyphPathBake.ts
4235
4303
  function fmt(v, decimals) {
4236
4304
  return Math.round(v) === v ? "" + Math.round(v) : v.toFixed(decimals);
4237
4305
  }
@@ -4255,20 +4323,20 @@ var PixodeskAnimator = (() => {
4255
4323
  while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
4256
4324
  let out = "";
4257
4325
  let i = 0;
4258
- const num2 = () => parseFloat(tokens[i++]);
4326
+ const num = () => parseFloat(tokens[i++]);
4259
4327
  while (i < tokens.length) {
4260
4328
  const cmd = tokens[i++];
4261
4329
  if (cmd === "M" || cmd === "L") {
4262
- const [x, y] = apply(m, num2(), num2());
4330
+ const [x, y] = apply(m, num(), num());
4263
4331
  out += cmd + pack([x, y], decimals);
4264
4332
  } else if (cmd === "C") {
4265
- const [x1, y1] = apply(m, num2(), num2());
4266
- const [x2, y2] = apply(m, num2(), num2());
4267
- const [x, y] = apply(m, num2(), num2());
4333
+ const [x1, y1] = apply(m, num(), num());
4334
+ const [x2, y2] = apply(m, num(), num());
4335
+ const [x, y] = apply(m, num(), num());
4268
4336
  out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
4269
4337
  } else if (cmd === "Q") {
4270
- const [x1, y1] = apply(m, num2(), num2());
4271
- const [x, y] = apply(m, num2(), num2());
4338
+ const [x1, y1] = apply(m, num(), num());
4339
+ const [x, y] = apply(m, num(), num());
4272
4340
  out += "Q" + pack([x1, y1, x, y], decimals);
4273
4341
  } else if (cmd === "Z" || cmd === "z") {
4274
4342
  out += "Z";
@@ -4276,6 +4344,8 @@ var PixodeskAnimator = (() => {
4276
4344
  }
4277
4345
  return out;
4278
4346
  }
4347
+
4348
+ // ../svg-animator-core/src/effects/textGlyphsEffect.ts
4279
4349
  var DEFAULT_FONT_SIZE = 16;
4280
4350
  var TEXT_ATTR_KEYS = [
4281
4351
  "fontFamily",
@@ -4411,13 +4481,13 @@ var PixodeskAnimator = (() => {
4411
4481
  if (y !== void 0) pen.y = y;
4412
4482
  pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
4413
4483
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4414
- const content = (_c2 = str(el[TEXT_ATTR])) != null ? _c2 : str(el[TEXT_CONTENT_ATTR]);
4484
+ const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
4415
4485
  if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
4416
4486
  if (el.children) for (const ch of el.children) walk(ch, s);
4417
4487
  };
4418
4488
  const rootStyle = rootStyleOf(node);
4419
4489
  if (node.children) for (const ch of node.children) walk(ch, rootStyle);
4420
- const rootContent = (_c = str(node[TEXT_ATTR])) != null ? _c : str(node[TEXT_CONTENT_ATTR]);
4490
+ const rootContent = (_c = str(node[TEXT_CONTENT_ATTR])) != null ? _c : str(node[TEXT_ATTR]);
4421
4491
  if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
4422
4492
  const anchor = str(node.textAnchor);
4423
4493
  if (anchor === "middle" || anchor === "end") {
@@ -4429,141 +4499,13 @@ var PixodeskAnimator = (() => {
4429
4499
  }
4430
4500
  return toGroup(node, buildPaths(placements, create, warnings), create);
4431
4501
  }
4432
- function layoutGlyphTextChars(node, opts) {
4433
- var _a, _b, _c, _d, _e, _f;
4434
- if ((_a = opts.alongPath) == null ? void 0 : _a.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
4435
- const { glyphs, warnings } = opts;
4436
- const soleFont = soleFontOf(glyphs);
4437
- const pen = { x: (_b = parseLen(node.x)) != null ? _b : 0, y: (_c = parseLen(node.y)) != null ? _c : 0 };
4438
- const boxes = [];
4439
- const lines = [{ start: pen.x, end: pen.x }];
4440
- let line = 0;
4441
- const renderChars = (content, s) => {
4442
- var _a2;
4443
- const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4444
- const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4445
- const scale = s.fontSize / upm;
4446
- const ascent = ((_a2 = gf == null ? void 0 : gf.ascent) != null ? _a2 : 0.9 * upm) * scale;
4447
- for (let i = 0; i < content.length; i++) {
4448
- const ch = content.charAt(i);
4449
- const g = gf == null ? void 0 : gf.glyphs[ch];
4450
- const advance = (g ? g.width : 0) * scale + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
4451
- boxes.push({ x: pen.x, y: pen.y, width: advance, ascent, fontSize: s.fontSize, line });
4452
- pen.x += advance;
4453
- lines[line].end = pen.x;
4454
- }
4455
- };
4456
- const walk = (el, parentStyle) => {
4457
- var _a2, _b2, _c2, _d2;
4458
- const s = resolveStyle2(el, parentStyle);
4459
- const x = parseLen(el.x);
4460
- const y = parseLen(el.y);
4461
- if (x !== void 0) {
4462
- pen.x = x;
4463
- line = lines.length;
4464
- lines.push({ start: pen.x, end: pen.x });
4465
- }
4466
- if (y !== void 0) pen.y = y;
4467
- pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
4468
- pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4469
- const content = (_c2 = str(el[TEXT_ATTR])) != null ? _c2 : str(el[TEXT_CONTENT_ATTR]);
4470
- if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
4471
- if (el.children) for (const ch of el.children) walk(ch, s);
4472
- };
4473
- const rootStyle = rootStyleOf(node);
4474
- if (node.children) for (const ch of node.children) {
4475
- const before = boxes.length;
4476
- walk(ch, rootStyle);
4477
- if (boxes.length === before) {
4478
- const s = resolveStyle2(ch, rootStyle);
4479
- const gf = glyphFontFor(s, glyphs, soleFont);
4480
- const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4481
- boxes.push({ x: pen.x, y: pen.y, width: 0, ascent: ((_d = gf == null ? void 0 : gf.ascent) != null ? _d : 0.9 * upm) * (s.fontSize / upm), fontSize: s.fontSize, line });
4482
- }
4483
- }
4484
- const rootContent = (_e = str(node[TEXT_ATTR])) != null ? _e : str(node[TEXT_CONTENT_ATTR]);
4485
- if (rootContent && !((_f = node.children) == null ? void 0 : _f.length)) renderChars(rootContent, rootStyle);
4486
- const anchor = str(node.textAnchor);
4487
- if (anchor === "middle" || anchor === "end") {
4488
- for (const b of boxes) {
4489
- const w = lines[b.line].end - lines[b.line].start;
4490
- b.x += anchor === "middle" ? -w / 2 : -w;
4491
- }
4492
- }
4493
- return boxes.map((_g) => {
4494
- var _h = _g, { line: _l } = _h, b = __objRest2(_h, ["line"]);
4495
- return b;
4496
- });
4497
- }
4498
- function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4499
- var _a, _b;
4500
- const { glyphs, warnings, alongPath } = opts;
4501
- const sampler = createPathSampler(pathD);
4502
- if (!sampler) {
4503
- warnings == null ? void 0 : warnings.push("textGlyphs: unparsable along-path geometry (caret)");
4504
- return [];
4505
- }
4506
- const soleFont = soleFontOf(glyphs);
4507
- const chars = [];
4508
- let adv = 0;
4509
- const walk = (el, parentStyle) => {
4510
- var _a2, _b2, _c;
4511
- const s = resolveStyle2(el, parentStyle);
4512
- const content = (_a2 = str(el[TEXT_ATTR])) != null ? _a2 : str(el[TEXT_CONTENT_ATTR]);
4513
- if (content && !((_b2 = el.children) == null ? void 0 : _b2.length)) {
4514
- const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4515
- const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4516
- const scale = s.fontSize / upm;
4517
- const ascent = ((_c = gf == null ? void 0 : gf.ascent) != null ? _c : 0.9 * upm) * scale;
4518
- for (let i = 0; i < content.length; i++) {
4519
- const ch = content.charAt(i);
4520
- const g = gf == null ? void 0 : gf.glyphs[ch];
4521
- const glyphW = (g ? g.width : 0) * scale;
4522
- const advance = glyphW + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
4523
- chars.push({ advStart: adv, advEnd: adv + advance, glyphW, ascent, fontSize: s.fontSize });
4524
- adv += advance;
4525
- }
4526
- }
4527
- if (el.children) for (const ch of el.children) walk(ch, s);
4528
- };
4529
- walk(node, rootStyleOf(node));
4530
- const width = adv;
4531
- const tlr = readAnimatable(alongPath == null ? void 0 : alongPath.textLength);
4532
- const tlv = tlr.kind === "animated" ? Number((_a = tlr.keyframes[0]) == null ? void 0 : _a.value) || 0 : tlr.kind === "static" ? Number(tlr.value) || 0 : 0;
4533
- const k = tlv > 0 && width > 0 ? tlv / width : 1;
4534
- const so = readAnimatable(alongPath == null ? void 0 : alongPath.startOffset);
4535
- const { along: alongOffset, perp } = alongPathNodeOffsets(node);
4536
- const base = alongOffset + (so.kind === "animated" ? Number((_b = so.keyframes[0]) == null ? void 0 : _b.value) || 0 : so.kind === "static" ? Number(so.value) || 0 : 0);
4537
- const withPerp = (p) => ({
4538
- x: p.x - perp * Math.sin(p.angle),
4539
- y: p.y + perp * Math.cos(p.angle),
4540
- angle: p.angle
4541
- });
4542
- return chars.map((c) => {
4543
- const dStart = base + c.advStart * k;
4544
- const dEnd = base + c.advEnd * k;
4545
- const p0 = withPerp(sampler.sampleAtDistance(dStart));
4546
- const p1 = withPerp(sampler.sampleAtDistance(dEnd));
4547
- const glyphMid = sampler.sampleAtDistance(base + (c.advStart + c.glyphW / 2) * k);
4548
- return {
4549
- x: p0.x,
4550
- y: p0.y,
4551
- width: c.advEnd - c.advStart,
4552
- ascent: c.ascent,
4553
- fontSize: c.fontSize,
4554
- endX: p1.x,
4555
- endY: p1.y,
4556
- rotation: glyphMid.angle * 180 / Math.PI
4557
- };
4558
- });
4559
- }
4560
4502
  function collectAlongPathCells(node, glyphs, soleFont, warnings) {
4561
4503
  const cells = [];
4562
4504
  let adv = 0;
4563
4505
  const walk = (el, parentStyle) => {
4564
4506
  var _a, _b, _c;
4565
4507
  const s = resolveStyle2(el, parentStyle);
4566
- const content = (_a = str(el[TEXT_ATTR])) != null ? _a : str(el[TEXT_CONTENT_ATTR]);
4508
+ const content = (_a = str(el[TEXT_CONTENT_ATTR])) != null ? _a : str(el[TEXT_ATTR]);
4567
4509
  if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
4568
4510
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4569
4511
  if (gf) {
@@ -4643,7 +4585,7 @@ var PixodeskAnimator = (() => {
4643
4585
  function numTrackOf(raw) {
4644
4586
  var _a;
4645
4587
  const r = readAnimatable(raw);
4646
- if (r.kind === "animated" && r.keyframes.length >= 2) {
4588
+ if (r.kind === "animated" /* Animated */ && r.keyframes.length >= 2) {
4647
4589
  const kfs = [...r.keyframes].sort((k1, k2) => (Number(k1.time) || 0) - (Number(k2.time) || 0));
4648
4590
  const times = kfs.map((kf) => Number(kf.time) || 0);
4649
4591
  const vals = kfs.map((kf) => Number(kf.value) || 0);
@@ -4664,7 +4606,7 @@ var PixodeskAnimator = (() => {
4664
4606
  }
4665
4607
  };
4666
4608
  }
4667
- const v = r.kind === "animated" ? Number((_a = r.keyframes[0]) == null ? void 0 : _a.value) || 0 : r.kind === "static" ? Number(r.value) || 0 : 0;
4609
+ const v = r.kind === "animated" /* Animated */ ? Number((_a = r.keyframes[0]) == null ? void 0 : _a.value) || 0 : r.kind === "static" /* Static */ ? Number(r.value) || 0 : 0;
4668
4610
  return { animated: false, times: [], at: () => v };
4669
4611
  }
4670
4612
  function mergeTrackTimes(a, b) {
@@ -4692,14 +4634,8 @@ var PixodeskAnimator = (() => {
4692
4634
  return {
4693
4635
  time,
4694
4636
  value: {
4695
- [
4696
- "translate"
4697
- /* Translate */
4698
- ]: [roundN(x - perp * sin, 3), roundN(y + perp * cos, 3)],
4699
- [
4700
- "rotate"
4701
- /* Rotate */
4702
- ]: roundN(angle * 180 / Math.PI, 3)
4637
+ ["translate" /* Translate */]: [roundN(x - perp * sin, 3), roundN(y + perp * cos, 3)],
4638
+ ["rotate" /* Rotate */]: roundN(angle * 180 / Math.PI, 3)
4703
4639
  }
4704
4640
  };
4705
4641
  };
@@ -4729,7 +4665,7 @@ var PixodeskAnimator = (() => {
4729
4665
  if (loop !== void 0) op.loop = loop;
4730
4666
  animate.opacity = op;
4731
4667
  }
4732
- out.push(create("path", __spreadProps2(__spreadValues2({ d }, paintProps(c.paint)), { animate }), []));
4668
+ out.push(create("path", __spreadProps(__spreadValues({ d }, paintProps(c.paint)), { animate }), []));
4733
4669
  }
4734
4670
  return out;
4735
4671
  }
@@ -4755,7 +4691,7 @@ var PixodeskAnimator = (() => {
4755
4691
  else byPaint.set(key, { paint: p.paint, d: baked });
4756
4692
  }
4757
4693
  const out = [];
4758
- for (const { paint, d } of byPaint.values()) out.push(create("path", __spreadValues2({ d }, paintProps(paint)), []));
4694
+ for (const { paint, d } of byPaint.values()) out.push(create("path", __spreadValues({ d }, paintProps(paint)), []));
4759
4695
  return out;
4760
4696
  }
4761
4697
  function toGroup(node, children, create) {
@@ -4765,17 +4701,13 @@ var PixodeskAnimator = (() => {
4765
4701
  gProps[k] = node[k];
4766
4702
  }
4767
4703
  if (gProps.style && typeof gProps.style === "object") {
4768
- const style = __spreadValues2({}, gProps.style);
4704
+ const style = __spreadValues({}, gProps.style);
4769
4705
  delete style["white-space"];
4770
4706
  if (Object.keys(style).length) gProps.style = style;
4771
4707
  else delete gProps.style;
4772
4708
  }
4773
4709
  return create("g", gProps, children);
4774
4710
  }
4775
- function materialiseGlyphText(node, opts) {
4776
- if (opts.alongPath) return materialiseGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);
4777
- return materialiseGlyphTextHorizontal(node, opts);
4778
- }
4779
4711
  function applyTextGlyphsEffect(node, fx, ctx) {
4780
4712
  if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
4781
4713
  if (!ctx.glyphs) {
@@ -4791,9 +4723,11 @@ var PixodeskAnimator = (() => {
4791
4723
  }
4792
4724
  return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
4793
4725
  }
4794
- function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
4726
+
4727
+ // ../svg-animator-core/src/effects/trimPathEffect.ts
4728
+ function applyTrimPathEffect(node, trimPath, ctx) {
4795
4729
  if (!trimPath) return node;
4796
- const trimAllAsOne = !!trimPath.trimAllAsOne;
4730
+ const combined = trimPath.subPaths === PxTrimSubPaths.combined;
4797
4731
  const leafEntries = [];
4798
4732
  const measure = (n) => {
4799
4733
  if (Array.isArray(n.children) && n.children.length > 0) {
@@ -4814,20 +4748,20 @@ var PixodeskAnimator = (() => {
4814
4748
  measure(node);
4815
4749
  if (!leafEntries.length) return node;
4816
4750
  let acc = 0;
4817
- const iterOrder = trimAllAsOne ? [...leafEntries].reverse() : leafEntries;
4751
+ const iterOrder = combined ? [...leafEntries].reverse() : leafEntries;
4818
4752
  for (const entry of iterOrder) {
4819
4753
  for (const sp of entry.subpaths) {
4820
- if (!trimAllAsOne) acc = 0;
4754
+ if (!combined) acc = 0;
4821
4755
  sp.startOffsetPx = acc;
4822
4756
  acc += sp.lengthPx;
4823
4757
  }
4824
4758
  }
4825
4759
  const chainLengthPx = acc;
4826
- if (trimAllAsOne && chainLengthPx < 1e-3) return node;
4760
+ if (combined && chainLengthPx < 1e-3) return node;
4827
4761
  const offsetReadRaw = readAnimatable(trimPath.offset);
4828
- const offsetRead = offsetReadRaw.kind === "absent" ? { kind: "static", value: 0 } : offsetReadRaw;
4762
+ const offsetRead = offsetReadRaw.kind === "absent" /* Absent */ ? { kind: "static" /* Static */, value: 0 } : offsetReadRaw;
4829
4763
  const rangeReadRaw = readRangeWithCrossings(trimPath.range);
4830
- const rangeRead = rangeReadRaw.kind === "absent" ? { kind: "static", value: [0, 1] } : rangeReadRaw;
4764
+ const rangeRead = rangeReadRaw.kind === "absent" /* Absent */ ? { kind: "static" /* Static */, value: [0, 1] } : rangeReadRaw;
4831
4765
  const offsetValues = readScalarValues(offsetRead);
4832
4766
  const minOffset = offsetValues.length ? Math.min(...offsetValues) : 0;
4833
4767
  const maxOffset = offsetValues.length ? Math.max(...offsetValues) : 0;
@@ -4835,18 +4769,18 @@ var PixodeskAnimator = (() => {
4835
4769
  if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {
4836
4770
  const entry = leafEntries[0];
4837
4771
  const sp = entry.subpaths[0];
4838
- const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
4772
+ const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
4839
4773
  if (pathLengthPx < 1e-3) return node;
4840
- const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
4774
+ const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
4841
4775
  return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);
4842
4776
  }
4843
4777
  const replacements = /* @__PURE__ */ new Map();
4844
4778
  for (const entry of leafEntries) {
4845
4779
  const newChildren = [];
4846
4780
  for (const sp of entry.subpaths) {
4847
- const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
4781
+ const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
4848
4782
  if (pathLengthPx < 1e-3) continue;
4849
- const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
4783
+ const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
4850
4784
  newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));
4851
4785
  }
4852
4786
  replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));
@@ -4855,14 +4789,14 @@ var PixodeskAnimator = (() => {
4855
4789
  const r = replacements.get(n);
4856
4790
  if (r) return r;
4857
4791
  if (Array.isArray(n.children) && n.children.length > 0) {
4858
- return __spreadProps2(__spreadValues2({}, n), { children: n.children.map(swap) });
4792
+ return __spreadProps(__spreadValues({}, n), { children: n.children.map(swap) });
4859
4793
  }
4860
4794
  return n;
4861
4795
  };
4862
4796
  return swap(node);
4863
4797
  }
4864
4798
  function wrapLeafAsGroup(leaf, children) {
4865
- const wrapper = __spreadProps2(__spreadValues2({}, leaf), { type: "g", children });
4799
+ const wrapper = __spreadProps(__spreadValues({}, leaf), { type: "g", children });
4866
4800
  delete wrapper.d;
4867
4801
  delete wrapper.strokeDasharray;
4868
4802
  delete wrapper.strokeDashoffset;
@@ -4885,7 +4819,7 @@ var PixodeskAnimator = (() => {
4885
4819
  function collapseLeafWithTrim(leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead) {
4886
4820
  const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
4887
4821
  const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
4888
- const node = __spreadValues2({}, leaf);
4822
+ const node = __spreadValues({}, leaf);
4889
4823
  delete node.effects;
4890
4824
  applyAttr(node, "strokeDasharray", computeAnimAttr(rangeRead, rangeToDasharray));
4891
4825
  applyAttr(node, "strokeDashoffset", computeAnimAttr(offsetRead, offsetToDashOffset));
@@ -4927,8 +4861,8 @@ var PixodeskAnimator = (() => {
4927
4861
  }
4928
4862
  function readScalarValues(r) {
4929
4863
  var _a;
4930
- if (r.kind === "absent") return [];
4931
- if (r.kind === "static") return [r.value];
4864
+ if (r.kind === "absent" /* Absent */) return [];
4865
+ if (r.kind === "static" /* Static */) return [r.value];
4932
4866
  const out = [];
4933
4867
  for (const kf of r.keyframes) {
4934
4868
  const v = (_a = kf.value) != null ? _a : kf.v;
@@ -4937,10 +4871,10 @@ var PixodeskAnimator = (() => {
4937
4871
  return out;
4938
4872
  }
4939
4873
  function computeAnimAttr(read, map) {
4940
- if (read.kind === "absent") return void 0;
4941
- if (read.kind === "static") return { kind: "static", value: map(read.value) };
4874
+ if (read.kind === "absent" /* Absent */) return void 0;
4875
+ if (read.kind === "static" /* Static */) return { kind: "static" /* Static */, value: map(read.value) };
4942
4876
  return {
4943
- kind: "animated",
4877
+ kind: "animated" /* Animated */,
4944
4878
  keyframes: read.keyframes.map((kf) => {
4945
4879
  var _a, _b, _c, _d;
4946
4880
  return {
@@ -4953,29 +4887,15 @@ var PixodeskAnimator = (() => {
4953
4887
  };
4954
4888
  }
4955
4889
  function applyAttr(node, attrName, attr) {
4956
- var _a, _b;
4957
4890
  if (!attr) return;
4958
- if (attr.kind === "static") {
4959
- node[attrName] = attr.value;
4960
- return;
4961
- }
4962
- const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
4963
- const animate = __spreadValues2({}, prevAnimate || {});
4964
- const block = { keyframes: attr.keyframes };
4965
- if (attr.loop !== void 0) block.loop = attr.loop;
4966
- animate[attrName] = block;
4967
- node.animate = animate;
4968
- const firstKf = attr.keyframes[0];
4969
- if (firstKf && ((_a = firstKf.value) != null ? _a : firstKf.v) !== void 0) {
4970
- node[attrName] = (_b = firstKf.value) != null ? _b : firstKf.v;
4971
- }
4891
+ writeAnimatableChannel(node, attrName, attr);
4972
4892
  }
4973
4893
  var OPACITY_STEP_MS = 10;
4974
4894
  function computeOpacityFromRange(rangeRead) {
4975
4895
  var _a, _b, _c, _d, _e, _f;
4976
4896
  const hide = (v) => v[0] === v[1];
4977
- if (rangeRead.kind === "absent") return void 0;
4978
- if (rangeRead.kind === "static") return hide(rangeRead.value) ? { kind: "static", value: 0 } : void 0;
4897
+ if (rangeRead.kind === "absent" /* Absent */) return void 0;
4898
+ if (rangeRead.kind === "static" /* Static */) return hide(rangeRead.value) ? { kind: "static" /* Static */, value: 0 } : void 0;
4979
4899
  const kfs = rangeRead.keyframes;
4980
4900
  let anyHide = false;
4981
4901
  let allHide = true;
@@ -4984,7 +4904,7 @@ var PixodeskAnimator = (() => {
4984
4904
  else allHide = false;
4985
4905
  }
4986
4906
  if (!anyHide) return void 0;
4987
- if (allHide) return { kind: "static", value: 0 };
4907
+ if (allHide) return { kind: "static" /* Static */, value: 0 };
4988
4908
  const out = [];
4989
4909
  for (let i = 0; i < kfs.length; i++) {
4990
4910
  const kf = kfs[i];
@@ -5003,11 +4923,11 @@ var PixodeskAnimator = (() => {
5003
4923
  }
5004
4924
  }
5005
4925
  if (out.length <= 1) return void 0;
5006
- return { kind: "animated", keyframes: out };
4926
+ return { kind: "animated" /* Animated */, keyframes: out };
5007
4927
  }
5008
4928
  function readRangeWithCrossings(raw) {
5009
4929
  const r = readAnimatable(raw);
5010
- if (r.kind !== "animated") return r;
4930
+ if (r.kind !== "animated" /* Animated */) return r;
5011
4931
  const kfs = r.keyframes.map((kf) => {
5012
4932
  var _a, _b, _c, _d;
5013
4933
  return {
@@ -5019,7 +4939,7 @@ var PixodeskAnimator = (() => {
5019
4939
  const hasReverse = kfs.some((kf) => kf.value[0] > kf.value[1]);
5020
4940
  if (!hasReverse) {
5021
4941
  return {
5022
- kind: "animated",
4942
+ kind: "animated" /* Animated */,
5023
4943
  keyframes: kfs.map((kf) => ({ time: kf.time, value: kf.value, easing: kf.easing }))
5024
4944
  };
5025
4945
  }
@@ -5055,7 +4975,7 @@ var PixodeskAnimator = (() => {
5055
4975
  const m = (v[0] + v[1]) / 2;
5056
4976
  out.push({ time: t, value: [m, m] });
5057
4977
  }
5058
- return { kind: "animated", keyframes: out };
4978
+ return { kind: "animated" /* Animated */, keyframes: out };
5059
4979
  }
5060
4980
  function bisectionForRangeCrossing(prev, cur) {
5061
4981
  const f = (t) => {
@@ -5140,6 +5060,8 @@ var PixodeskAnimator = (() => {
5140
5060
  }
5141
5061
  return void 0;
5142
5062
  }
5063
+
5064
+ // ../svg-animator-core/src/effects/PlayerEffectsUtil.ts
5143
5065
  function applyPlayerEffects(root) {
5144
5066
  var _a, _b;
5145
5067
  const ctx = {
@@ -5150,9 +5072,9 @@ var PixodeskAnimator = (() => {
5150
5072
  nextId: 0,
5151
5073
  contentRefInnerIds: /* @__PURE__ */ new Map(),
5152
5074
  maskAncestorChains: /* @__PURE__ */ new Map(),
5153
- // Resolved engine: `frames` ONLY when explicitly set; auto/webapi/unset →
5154
- // webapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
5155
- engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi,
5075
+ // Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
5076
+ // waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
5077
+ engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi,
5156
5078
  glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
5157
5079
  };
5158
5080
  const working = clone(root);
@@ -5170,8 +5092,7 @@ var PixodeskAnimator = (() => {
5170
5092
  const originalId = typeof node.id === "string" ? node.id : void 0;
5171
5093
  const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
5172
5094
  if (!fx && !innerIdForContentRef) return node;
5173
- const { transformation, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
5174
- const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
5095
+ const { transformBy, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
5175
5096
  if (fx) delete node.effects;
5176
5097
  let n = node;
5177
5098
  let consumedByGlyphs = false;
@@ -5191,15 +5112,15 @@ var PixodeskAnimator = (() => {
5191
5112
  if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
5192
5113
  n = applyFillGradientEffect(n, fillGradient, ctx);
5193
5114
  n = applyStrokeGradientEffect(n, strokeGradient, ctx);
5194
- n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
5115
+ n = applyTrimPathEffect(n, trimPath, ctx);
5195
5116
  n = applyRepeaterEffect(n, repeater, ctx);
5196
- n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
5117
+ n = applyMaskedByEffect(n, maskedBy, transformBy, ctx);
5197
5118
  n = applyClipPathEffect(n, clipPath, ctx);
5198
5119
  if (innerIdForContentRef) {
5199
5120
  applyRefHref(n, cloneFx, ctx);
5200
- n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
5121
+ n = splitForContentRef(n, transformBy, originalId, innerIdForContentRef, ctx);
5201
5122
  } else {
5202
- n = applyRefAndTransformationEffect(n, cloneFx, transformation, ctx);
5123
+ n = applyRefAndTransformationEffect(n, cloneFx, transformBy, ctx);
5203
5124
  }
5204
5125
  if (cloneFx == null ? void 0 : cloneFx.retime) node.effects = { clone: { retime: cloneFx.retime } };
5205
5126
  if (originalId) ctx.idMap.set(originalId, n);
@@ -5209,12 +5130,14 @@ var PixodeskAnimator = (() => {
5209
5130
  applyAllRetimeEffects(node, ctx);
5210
5131
  return node;
5211
5132
  }
5133
+
5134
+ // ../svg-animator-core/src/PxAnimatorMaterialiseAll.ts
5212
5135
  function materialiseAllInTree(doc, engine, opts) {
5213
5136
  var _a, _b;
5214
5137
  let root = applyPlayerEffects(doc).root;
5215
5138
  const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
5216
5139
  root = materialiseInternalLoopsInTree(root, duration);
5217
- if (engine === PxAnimatorEngine.webapi) {
5140
+ if (engine === PxAnimatorEngine.waapi) {
5218
5141
  root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
5219
5142
  root = materialiseAnimatedUseInstances(root);
5220
5143
  root = pruneUnreferencedDefs(root);
@@ -5250,6 +5173,8 @@ var PixodeskAnimator = (() => {
5250
5173
  }
5251
5174
  return root;
5252
5175
  }
5176
+
5177
+ // ../svg-animator-core/src/PxFrameLoop.ts
5253
5178
  function requestFrame(cb) {
5254
5179
  const g = globalThis;
5255
5180
  if (typeof g.requestAnimationFrame === "function") return g.requestAnimationFrame(cb);
@@ -5526,270 +5451,6 @@ var PixodeskAnimator = (() => {
5526
5451
  };
5527
5452
  return api;
5528
5453
  }
5529
- var IDENTITY = [1, 0, 0, 1, 0, 0];
5530
- function mul(m, n) {
5531
- return [
5532
- m[0] * n[0] + m[2] * n[1],
5533
- m[1] * n[0] + m[3] * n[1],
5534
- m[0] * n[2] + m[2] * n[3],
5535
- m[1] * n[2] + m[3] * n[3],
5536
- m[0] * n[4] + m[2] * n[5] + m[4],
5537
- m[1] * n[4] + m[3] * n[5] + m[5]
5538
- ];
5539
- }
5540
- var translateM = (x, y) => [1, 0, 0, 1, x, y];
5541
- var scaleM = (sx, sy) => [sx, 0, 0, sy, 0, 0];
5542
- function rotateM(deg) {
5543
- const r = deg * Math.PI / 180;
5544
- return [Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0];
5545
- }
5546
- var skewXM = (deg) => [1, 0, Math.tan(deg * Math.PI / 180), 1, 0, 0];
5547
- var skewYM = (deg) => [1, Math.tan(deg * Math.PI / 180), 0, 1, 0, 0];
5548
- function parseTransformString(s) {
5549
- let m = IDENTITY;
5550
- const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
5551
- let hit;
5552
- while (hit = re.exec(s)) {
5553
- const fn = hit[1];
5554
- const a = hit[2].split(/[\s,]+/).filter(Boolean).map(Number);
5555
- if (fn === "translate") m = mul(m, translateM(a[0] || 0, a[1] || 0));
5556
- else if (fn === "scale") m = mul(m, scaleM(a[0], a.length > 1 ? a[1] : a[0]));
5557
- else if (fn === "rotate") m = mul(m, rotateM(a[0]));
5558
- else if (fn === "skewX") m = mul(m, skewXM(a[0]));
5559
- else if (fn === "skewY") m = mul(m, skewYM(a[0]));
5560
- else if (fn === "matrix") m = mul(m, [a[0], a[1], a[2], a[3], a[4], a[5]]);
5561
- }
5562
- return m;
5563
- }
5564
- function partsToMatrix(p) {
5565
- let m = IDENTITY;
5566
- if (p.translate) m = mul(m, translateM(p.translate[0], p.translate[1]));
5567
- const pivot = p.origin && (p.rotate !== void 0 || p.scale);
5568
- if (pivot) m = mul(m, translateM(p.origin[0], p.origin[1]));
5569
- if (p.rotate !== void 0) m = mul(m, rotateM(p.rotate));
5570
- if (p.scale) m = mul(m, scaleM(p.scale[0], p.scale[1]));
5571
- if (pivot) m = mul(m, translateM(-p.origin[0], -p.origin[1]));
5572
- return m;
5573
- }
5574
- function lerp(a, b, f) {
5575
- return a + (b - a) * f;
5576
- }
5577
- function interpParts(kfs, t) {
5578
- var _a, _b, _c, _d, _e, _f, _g;
5579
- if (!kfs.length) return {};
5580
- if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value || {};
5581
- if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value || {};
5582
- let i = 0;
5583
- while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
5584
- const a = kfs[i], b = kfs[i + 1];
5585
- const f = (t - ((_d = a.time) != null ? _d : 0)) / (((_e = b.time) != null ? _e : 0) - ((_f = a.time) != null ? _f : 0) || 1);
5586
- const va = a.value || {}, vb = b.value || {};
5587
- const out = {};
5588
- if (va.translate && vb.translate) out.translate = [lerp(va.translate[0], vb.translate[0], f), lerp(va.translate[1], vb.translate[1], f)];
5589
- else out.translate = va.translate || vb.translate;
5590
- if (va.rotate !== void 0 && vb.rotate !== void 0) out.rotate = lerp(va.rotate, vb.rotate, f);
5591
- else out.rotate = (_g = va.rotate) != null ? _g : vb.rotate;
5592
- if (va.scale && vb.scale) out.scale = [lerp(va.scale[0], vb.scale[0], f), lerp(va.scale[1], vb.scale[1], f)];
5593
- else out.scale = va.scale || vb.scale;
5594
- out.origin = va.origin || vb.origin;
5595
- return out;
5596
- }
5597
- function evalTransformValue(v, t) {
5598
- if (v === void 0 || v === null) return IDENTITY;
5599
- if (typeof v === "string") return parseTransformString(v);
5600
- if (v.keyframes) return partsToMatrix(interpParts(v.keyframes, t));
5601
- if (v.value) return partsToMatrix(v.value);
5602
- return IDENTITY;
5603
- }
5604
- function nodeMatrix(node, t) {
5605
- if (node.animate && node.animate.transform) return evalTransformValue(node.animate.transform, t);
5606
- if (node.transform !== void 0) return evalTransformValue(node.transform, t);
5607
- return IDENTITY;
5608
- }
5609
- function evalScalar(animated, staticVal, fallback, t) {
5610
- var _a, _b, _c, _d, _e, _f;
5611
- if (animated && animated.keyframes && animated.keyframes.length) {
5612
- const kfs = animated.keyframes;
5613
- if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value;
5614
- if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value;
5615
- let i = 0;
5616
- while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
5617
- const a = kfs[i], b = kfs[i + 1];
5618
- const f = (t - ((_d = a.time) != null ? _d : 0)) / (((_e = b.time) != null ? _e : 0) - ((_f = a.time) != null ? _f : 0) || 1);
5619
- return lerp(a.value, b.value, f);
5620
- }
5621
- return staticVal !== void 0 ? Number(staticVal) : fallback;
5622
- }
5623
- var CONTAINER_TYPES = /* @__PURE__ */ new Set(["svg", "g", "symbol"]);
5624
- var SKIP_TYPES = /* @__PURE__ */ new Set(["defs", "mask", "clipPath", "title"]);
5625
- function buildIdMap2(node, map) {
5626
- var _a;
5627
- if (typeof node.id === "string") map.set(node.id, node);
5628
- (_a = node.children) == null ? void 0 : _a.forEach((c) => buildIdMap2(c, map));
5629
- }
5630
- function num(v) {
5631
- return v === void 0 || v === null ? 0 : Number(v);
5632
- }
5633
- function round(n) {
5634
- return Math.round(n * 100) / 100 + 0;
5635
- }
5636
- function geomKey(node) {
5637
- var _a;
5638
- switch (node.type) {
5639
- case "rect":
5640
- return num(node.width) + "," + num(node.height) + "," + num(node.x) + "," + num(node.y);
5641
- case "ellipse":
5642
- return num(node.rx) + "," + num(node.ry) + "," + num(node.cx) + "," + num(node.cy);
5643
- case "circle":
5644
- return num(node.r) + "," + num(node.cx) + "," + num(node.cy);
5645
- case "path":
5646
- return String((_a = node.d) != null ? _a : "");
5647
- default:
5648
- return "";
5649
- }
5650
- }
5651
- function describePrimitive(node, m, t) {
5652
- var _a, _b, _c, _d, _e;
5653
- const fill = (_a = node.fill) != null ? _a : "";
5654
- const stroke = (_b = node.stroke) != null ? _b : "";
5655
- const sw = (_d = (_c = node["stroke-width"]) != null ? _c : node.strokeWidth) != null ? _d : "";
5656
- const opacity = round(evalScalar((_e = node.animate) == null ? void 0 : _e.opacity, node.opacity, 1, t));
5657
- const masked = node.mask ? 1 : 0;
5658
- const mat = m.map(round).join(",");
5659
- return node.type + "|" + geomKey(node) + "|[" + mat + "]|f:" + fill + "|s:" + stroke + "|sw:" + (num(sw) || "") + "|o:" + opacity + "|m:" + masked;
5660
- }
5661
- function flatten(node, parent, t, idMap, out) {
5662
- var _a;
5663
- const type = node.type || "";
5664
- if (SKIP_TYPES.has(type)) return;
5665
- const m = mul(parent, nodeMatrix(node, t));
5666
- if (type === "use") {
5667
- const targetId = typeof node.href === "string" ? node.href.replace(/^#/, "") : "";
5668
- const target = idMap.get(targetId);
5669
- const useM = mul(m, translateM(num(node.x), num(node.y)));
5670
- if (target) flatten(target, useM, t, idMap, out);
5671
- else out.push("UNRESOLVED_USE:#" + targetId);
5672
- return;
5673
- }
5674
- if (CONTAINER_TYPES.has(type)) {
5675
- (_a = node.children) == null ? void 0 : _a.forEach((c) => flatten(c, m, t, idMap, out));
5676
- return;
5677
- }
5678
- out.push(describePrimitive(node, m, t));
5679
- }
5680
- function collectSampleTimes(node, into) {
5681
- var _a;
5682
- into.add(0);
5683
- const scanAnim = (anim) => {
5684
- var _a2;
5685
- if (!anim || typeof anim !== "object") return;
5686
- for (const key of Object.keys(anim)) {
5687
- const kfs = (_a2 = anim[key]) == null ? void 0 : _a2.keyframes;
5688
- if (Array.isArray(kfs)) kfs.forEach((kf) => {
5689
- var _a3;
5690
- return into.add((_a3 = kf.time) != null ? _a3 : 0);
5691
- });
5692
- }
5693
- };
5694
- scanAnim(node.animate);
5695
- if (node.transform && typeof node.transform === "object" && node.transform.keyframes) {
5696
- node.transform.keyframes.forEach((kf) => {
5697
- var _a2;
5698
- return into.add((_a2 = kf.time) != null ? _a2 : 0);
5699
- });
5700
- }
5701
- (_a = node.children) == null ? void 0 : _a.forEach((c) => collectSampleTimes(c, into));
5702
- }
5703
- function visualModelAt(root, t) {
5704
- const idMap = /* @__PURE__ */ new Map();
5705
- buildIdMap2(root, idMap);
5706
- const out = [];
5707
- flatten(root, IDENTITY, t, idMap, out);
5708
- return out.sort();
5709
- }
5710
- function diffInEffect(a, b) {
5711
- const times = /* @__PURE__ */ new Set();
5712
- collectSampleTimes(a, times);
5713
- collectSampleTimes(b, times);
5714
- const diffs = [];
5715
- for (const t of Array.from(times).sort((x, y) => x - y)) {
5716
- const ma = visualModelAt(a, t);
5717
- const mb = visualModelAt(b, t);
5718
- const onlyInA = subtractMultiset(ma, mb);
5719
- const onlyInB = subtractMultiset(mb, ma);
5720
- if (onlyInA.length || onlyInB.length) diffs.push({ time: t, onlyInA, onlyInB });
5721
- }
5722
- return diffs;
5723
- }
5724
- function subtractMultiset(a, b) {
5725
- const counts = /* @__PURE__ */ new Map();
5726
- for (const x of b) counts.set(x, (counts.get(x) || 0) + 1);
5727
- const extra = [];
5728
- for (const x of a) {
5729
- const c = counts.get(x) || 0;
5730
- if (c > 0) counts.set(x, c - 1);
5731
- else extra.push(x);
5732
- }
5733
- return extra;
5734
- }
5735
-
5736
- // src/PxAnimatorDOM.ts
5737
- var SVG_NS = "http://www.w3.org/2000/svg";
5738
- function createElement(tagName, normalisedProps, style, children, textContent) {
5739
- if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
5740
- console.warn("SVG tag blocked (dangerous): ", tagName);
5741
- return null;
5742
- }
5743
- const element = document.createElementNS(SVG_NS, tagName);
5744
- for (const propName in normalisedProps) {
5745
- const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
5746
- if (sanitised === void 0) continue;
5747
- if (CSS_ONLY_STYLE_PROPS.has(propName)) {
5748
- element.style[propName] = String(sanitised);
5749
- continue;
5750
- }
5751
- element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
5752
- }
5753
- if (style) {
5754
- for (const styleProp in style) {
5755
- element.style[styleProp] = String(style[styleProp]);
5756
- }
5757
- }
5758
- if (children) {
5759
- for (const child of children) {
5760
- element.appendChild(child);
5761
- }
5762
- }
5763
- if (textContent) element.textContent = textContent;
5764
- return element;
5765
- }
5766
- function renderNode(node, defs) {
5767
- if (!node) return null;
5768
- const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
5769
- const feFuncType = props.funcType;
5770
- if (feFuncType !== void 0) delete props.funcType;
5771
- const nodeDefs = getDefs(node) || defs;
5772
- const resolvedStyle = resolveStyle(style, nodeDefs);
5773
- let childElements;
5774
- if (children) {
5775
- for (const ch of children) {
5776
- const child = renderNode(ch, nodeDefs);
5777
- if (child) {
5778
- if (!childElements) childElements = [];
5779
- childElements.push(child);
5780
- }
5781
- }
5782
- }
5783
- const element = createElement(
5784
- type || "g",
5785
- getNormalizedProps(props),
5786
- resolvedStyle,
5787
- childElements,
5788
- props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
5789
- );
5790
- if (element && feFuncType !== void 0) element.setAttribute("type", feFuncType);
5791
- return element;
5792
- }
5793
5454
 
5794
5455
  // src/PxAnimatorTriggers.ts
5795
5456
  function setupAnimationTriggers(api, config) {
@@ -5980,7 +5641,7 @@ var PixodeskAnimator = (() => {
5980
5641
  } else {
5981
5642
  cssValue = "" + value;
5982
5643
  }
5983
- if (!CSS.supports(cssKey, cssValue)) unsupportedSet.add(cssKey);
5644
+ if (!CSS.supports(camelCaseToKebabWordIfNeeded(cssKey), cssValue)) unsupportedSet.add(cssKey);
5984
5645
  cssKey = kebabToCamelCaseWord(cssKey);
5985
5646
  cssKf[cssKey] = cssValue;
5986
5647
  return cssKf;
@@ -6057,7 +5718,7 @@ var PixodeskAnimator = (() => {
6057
5718
  console.warn("createFrameLoopAnimator: No root element provided");
6058
5719
  }
6059
5720
  }
6060
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.webapi);
5721
+ const bindings = getNormalisedBindings(doc, PxAnimatorEngine.waapi);
6061
5722
  const animations = [];
6062
5723
  const _iterations = config.iterations;
6063
5724
  let iterations;
@@ -6203,9 +5864,8 @@ var PixodeskAnimator = (() => {
6203
5864
  return api;
6204
5865
  }
6205
5866
 
6206
- // src/PxAnimator.ts
6207
- function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
6208
- const animatorConfig = getAnimatorConfig(doc) || {};
5867
+ // src/PxAnimatorBind.ts
5868
+ function finaliseAnimator(animatorConfig, callbacks, make) {
6209
5869
  let apiRef;
6210
5870
  let effectiveCallbacks = callbacks;
6211
5871
  if (animatorConfig.resetOnFinish) {
@@ -6217,29 +5877,99 @@ var PixodeskAnimator = (() => {
6217
5877
  }
6218
5878
  });
6219
5879
  }
6220
- let res;
6221
- if (animatorConfig.mode === PxAnimatorMode.frames) {
6222
- res = createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement);
6223
- } else {
6224
- res = createWebApiAnimator(
6225
- doc,
6226
- effectiveCallbacks,
6227
- rootElement,
6228
- animatorConfig.mode === PxAnimatorMode.webapi
6229
- // forcing webapi
6230
- ) || createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement);
6231
- }
5880
+ const res = make(effectiveCallbacks);
6232
5881
  apiRef = res;
6233
5882
  if (animatorConfig.debugInstName) {
6234
5883
  window[animatorConfig.debugInstName] = res;
6235
5884
  }
6236
5885
  return res;
6237
5886
  }
5887
+ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
5888
+ const animatorConfig = getAnimatorConfig(doc) || {};
5889
+ return finaliseAnimator(animatorConfig, callbacks, (cb) => {
5890
+ if (animatorConfig.mode === PxAnimatorMode.frames) {
5891
+ return createFrameLoopAnimator(doc, adapter, cb, rootElement);
5892
+ }
5893
+ return createWebApiAnimator(
5894
+ doc,
5895
+ cb,
5896
+ rootElement,
5897
+ animatorConfig.mode === PxAnimatorMode.waapi
5898
+ // forcing waapi
5899
+ ) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
5900
+ });
5901
+ }
5902
+
5903
+ // src/PxAnimatorDOM.ts
5904
+ var SVG_NS = "http://www.w3.org/2000/svg";
5905
+ function createElement(tagName, normalisedProps, style, children, textContent) {
5906
+ if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
5907
+ console.warn("SVG tag blocked (dangerous): ", tagName);
5908
+ return null;
5909
+ }
5910
+ const element = document.createElementNS(SVG_NS, tagName);
5911
+ for (const propName in normalisedProps) {
5912
+ const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
5913
+ if (sanitised === void 0) continue;
5914
+ if (CSS_ONLY_STYLE_PROPS.has(propName)) {
5915
+ element.style[propName] = String(sanitised);
5916
+ continue;
5917
+ }
5918
+ element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
5919
+ }
5920
+ if (style) {
5921
+ for (const styleProp in style) {
5922
+ element.style[styleProp] = String(style[styleProp]);
5923
+ }
5924
+ }
5925
+ if (children) {
5926
+ for (const child of children) {
5927
+ element.appendChild(child);
5928
+ }
5929
+ }
5930
+ if (textContent) element.textContent = textContent;
5931
+ return element;
5932
+ }
5933
+ function renderNode(node, defs) {
5934
+ if (!node) return null;
5935
+ const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
5936
+ const domType = props.domType;
5937
+ if (domType !== void 0) delete props.domType;
5938
+ const nodeDefs = getDefs(node) || defs;
5939
+ const resolvedStyle = resolveStyle(style, nodeDefs);
5940
+ let childElements;
5941
+ if (children) {
5942
+ for (const ch of children) {
5943
+ const child = renderNode(ch, nodeDefs);
5944
+ if (child) {
5945
+ if (!childElements) childElements = [];
5946
+ childElements.push(child);
5947
+ }
5948
+ }
5949
+ }
5950
+ const element = createElement(
5951
+ type || "g",
5952
+ getNormalizedProps(props),
5953
+ resolvedStyle,
5954
+ childElements,
5955
+ props[TEXT_CONTENT_ATTR] || props[TEXT_ATTR]
5956
+ );
5957
+ if (element && domType !== void 0) element.setAttribute("type", domType);
5958
+ return element;
5959
+ }
5960
+
5961
+ // src/PxAnimatorKeys.ts
5962
+ var PX_ANIMATOR_DATA_KEY = "data";
5963
+
5964
+ // src/PxAnimator.ts
5965
+ function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
5966
+ return bindWithEngineChoice(doc, adapter, callbacks, rootElement);
5967
+ }
6238
5968
  function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
6239
5969
  const effectsWarnings = validateNodeEffects(doc);
6240
5970
  for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
6241
5971
  const animatorConfig = getAnimatorConfig(doc) || {};
6242
- const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi;
5972
+ const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi;
6243
5973
  doc = materialiseAllInTree(doc, engine);
6244
5974
  let rootElement = null;
6245
5975
  if (containerElement) {
@@ -6254,7 +5984,6 @@ var PixodeskAnimator = (() => {
6254
5984
  }
6255
5985
  return createAnimatorFromConfig(doc, adapter, callbacks, rootElement);
6256
5986
  }
6257
- var PX_ANIMATOR_DATA_KEY = "data";
6258
5987
  function createAnimator(options) {
6259
5988
  const { src, data, adapter, callbacks, container } = options;
6260
5989
  if (data !== void 0 && src !== void 0) {
@@ -6337,6 +6066,6 @@ var PixodeskAnimator = (() => {
6337
6066
  window["createAnimator"] = createAnimator;
6338
6067
  window["setupAnimationTriggers"] = setupAnimationTriggers;
6339
6068
  }
6340
- return __toCommonJS(index_exports);
6069
+ return __toCommonJS(index_player_exports);
6341
6070
  })();
6342
6071
  //# sourceMappingURL=index.umd.js.map