@pixodesk/svg-animator-web 1.0.35 → 1.0.39

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.
@@ -51,13 +51,12 @@ var PixodeskAnimator = (() => {
51
51
  // src/index.player.ts
52
52
  var index_player_exports = {};
53
53
  __export(index_player_exports, {
54
- PX_ANIMATOR_DATA_KEY: () => PX_ANIMATOR_DATA_KEY,
54
+ PX_ANIMATOR_DOC_KEY: () => PX_ANIMATOR_DOC_KEY,
55
55
  PX_ANIM_ATTR_NAME: () => PX_ANIM_ATTR_NAME,
56
56
  PX_ANIM_SRC_ATTR_NAME: () => PX_ANIM_SRC_ATTR_NAME,
57
57
  PxTimelineEngine: () => PxTimelineEngine,
58
58
  PxTimelineEngineExtra: () => PxTimelineEngineExtra,
59
59
  createAnimator: () => createAnimator,
60
- createAnimatorImpl: () => createAnimatorImpl,
61
60
  generateNewIds: () => generateNewIds,
62
61
  loadTagAnimators: () => loadTagAnimators,
63
62
  setupAnimationTriggers: () => setupAnimationTriggers,
@@ -66,7 +65,7 @@ var PixodeskAnimator = (() => {
66
65
 
67
66
  // ../svg-animator-core/src/util/PxAnimatorUtil.ts
68
67
  function bezierToSvgPath(path, forceCurves = false) {
69
- var _a, _b, _c, _d;
68
+ var _a2, _b, _c, _d;
70
69
  const v = path.v;
71
70
  const i = path.i;
72
71
  const o = path.o;
@@ -77,7 +76,7 @@ var PixodeskAnimator = (() => {
77
76
  d.push("M" + v[0][0] + "," + v[0][1]);
78
77
  for (let idx = 1; idx < len; idx++) {
79
78
  const prevV = v[idx - 1];
80
- const prevO = (_a = o == null ? void 0 : o[idx - 1]) != null ? _a : prevV;
79
+ const prevO = (_a2 = o == null ? void 0 : o[idx - 1]) != null ? _a2 : prevV;
81
80
  const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
82
81
  const currV = v[idx];
83
82
  const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) && (currI[0] === currV[0] && currI[1] === currV[1]);
@@ -128,7 +127,7 @@ var PixodeskAnimator = (() => {
128
127
  return res;
129
128
  }
130
129
  function interpolateBezier(path1, path2, progress) {
131
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
130
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
132
131
  if (!path1 || !path2) return path1 || path2 || { v: [] };
133
132
  const t = Math.min(Math.max(progress, 0), 1);
134
133
  const len = Math.min(path1.v.length, path2.v.length);
@@ -139,7 +138,7 @@ var PixodeskAnimator = (() => {
139
138
  const v1 = path1.v[idx];
140
139
  const v2 = path2.v[idx];
141
140
  v.push(interpolateVec(v1, v2, t));
142
- const i1 = (_b = (_a = path1.i) == null ? void 0 : _a[idx]) != null ? _b : v1;
141
+ const i1 = (_b = (_a2 = path1.i) == null ? void 0 : _a2[idx]) != null ? _b : v1;
143
142
  const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
144
143
  i.push(interpolateVec(i1, i2, t));
145
144
  const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
@@ -258,8 +257,8 @@ var PixodeskAnimator = (() => {
258
257
  return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
259
258
  }
260
259
  function parseRgba(s) {
261
- var _a;
262
- const inner = (_a = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a[1];
260
+ var _a2;
261
+ const inner = (_a2 = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a2[1];
263
262
  if (!inner) throw new Error("Invalid rgb/rgba format");
264
263
  const parts = inner.split(",").map((v) => +v.trim());
265
264
  return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
@@ -294,13 +293,13 @@ var PixodeskAnimator = (() => {
294
293
  }
295
294
  return void 0;
296
295
  }
297
- var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
296
+ var COLOR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
298
297
  var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
299
298
  var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
300
299
  function composeTransformParts(parts, opts) {
301
- var _a;
300
+ var _a2;
302
301
  if (!parts) return "";
303
- const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
302
+ const withUnits = (_a2 = opts == null ? void 0 : opts.withUnits) != null ? _a2 : true;
304
303
  const segs = [];
305
304
  const t = parts.translate;
306
305
  const o = parts.origin;
@@ -318,7 +317,7 @@ var PixodeskAnimator = (() => {
318
317
  return segs.join("");
319
318
  }
320
319
  function parseTransformParts(str2) {
321
- var _a, _b;
320
+ var _a2, _b;
322
321
  if (!str2 || typeof str2 !== "string") return void 0;
323
322
  const out = {};
324
323
  const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
@@ -334,7 +333,7 @@ var PixodeskAnimator = (() => {
334
333
  if (nums.some((n) => Number.isNaN(n))) return void 0;
335
334
  if (fn === "translate") {
336
335
  if (nums.length < 1 || nums.length > 2) return void 0;
337
- out.translate = [nums[0], (_a = nums[1]) != null ? _a : 0];
336
+ out.translate = [nums[0], (_a2 = nums[1]) != null ? _a2 : 0];
338
337
  } else if (fn === "rotate") {
339
338
  if (nums.length !== 1) return void 0;
340
339
  out.rotate = nums[0];
@@ -540,8 +539,8 @@ var PixodeskAnimator = (() => {
540
539
  }
541
540
  var DEFAULT_PHASE = "cover";
542
541
  function resolveRangePointU(point, defaultFraction, subjectSize, scrollportSize) {
543
- var _a;
544
- const [u0, u1] = scrollPhaseInterval((_a = point == null ? void 0 : point.phase) != null ? _a : DEFAULT_PHASE, subjectSize, scrollportSize);
542
+ var _a2;
543
+ const [u0, u1] = scrollPhaseInterval((_a2 = point == null ? void 0 : point.phase) != null ? _a2 : DEFAULT_PHASE, subjectSize, scrollportSize);
545
544
  const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
546
545
  return u0 + fraction * (u1 - u0);
547
546
  }
@@ -553,9 +552,9 @@ var PixodeskAnimator = (() => {
553
552
  return clamp((u - uStart) / (uEnd - uStart), 0, 1);
554
553
  }
555
554
  function scrollOffsetProgress(offset, maxOffset, range) {
556
- var _a, _b;
555
+ var _a2, _b;
557
556
  const raw = maxOffset > 0 ? clamp(offset / maxOffset, 0, 1) : 1;
558
- const start = typeof ((_a = range == null ? void 0 : range.start) == null ? void 0 : _a.fraction) === "number" ? range.start.fraction : 0;
557
+ const start = typeof ((_a2 = range == null ? void 0 : range.start) == null ? void 0 : _a2.fraction) === "number" ? range.start.fraction : 0;
559
558
  const end = typeof ((_b = range == null ? void 0 : range.end) == null ? void 0 : _b.fraction) === "number" ? range.end.fraction : 1;
560
559
  if (end <= start) return raw >= end ? 1 : 0;
561
560
  return clamp((raw - start) / (end - start), 0, 1);
@@ -677,6 +676,7 @@ var PixodeskAnimator = (() => {
677
676
  return false;
678
677
  }
679
678
  };
679
+ var UNION_MEMBER_ERROR_LIMIT = 4;
680
680
  var Union = class extends Base {
681
681
  constructor(schemas, defaultVal) {
682
682
  super();
@@ -692,10 +692,38 @@ var PixodeskAnimator = (() => {
692
692
  return this._default;
693
693
  }
694
694
  isValid(raw, ctx, path) {
695
- var _a;
695
+ var _a2;
696
696
  const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
697
697
  if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
698
- 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));
698
+ if (!ctx) return false;
699
+ const base = pathStr(path != null ? path : []);
700
+ ctx.errors.push(base + ": no union member matched for value " + ((_a2 = JSON.stringify(raw)) != null ? _a2 : "").slice(0, 240));
701
+ let best;
702
+ let bestDepth = -1;
703
+ const leafExpectations = [];
704
+ for (const member of this.schemas) {
705
+ const sink = { errors: [], warnings: [], strict: ctx.strict };
706
+ member.isValid(raw, sink, path ? [...path] : void 0);
707
+ if (!sink.errors.length) continue;
708
+ const depth = Math.max(...sink.errors.map((e) => e.slice(0, e.indexOf(":")).length));
709
+ if (depth > bestDepth || depth === bestDepth && best && sink.errors.length < best.length) {
710
+ bestDepth = depth;
711
+ best = sink.errors;
712
+ }
713
+ if (depth <= base.length) {
714
+ for (const e of sink.errors) {
715
+ const m = /: expected (.+?), got /.exec(e);
716
+ if (m && !leafExpectations.includes(m[1])) leafExpectations.push(m[1]);
717
+ }
718
+ }
719
+ }
720
+ if (best && bestDepth > base.length) {
721
+ for (const e of best.slice(0, UNION_MEMBER_ERROR_LIMIT)) {
722
+ if (!ctx.errors.includes(e)) ctx.errors.push(e);
723
+ }
724
+ } else if (leafExpectations.length) {
725
+ ctx.errors.push(base + ": expected " + leafExpectations.join(" | "));
726
+ }
699
727
  return false;
700
728
  }
701
729
  _canSanitize(raw) {
@@ -704,7 +732,7 @@ var PixodeskAnimator = (() => {
704
732
  };
705
733
  var DiscriminatedUnion = class extends Base {
706
734
  constructor(_key, _schemas, defaultVal) {
707
- var _a;
735
+ var _a2;
708
736
  super();
709
737
  this._key = _key;
710
738
  this._schemas = _schemas;
@@ -715,7 +743,7 @@ var PixodeskAnimator = (() => {
715
743
  for (const s of _schemas) {
716
744
  const keySchema = s._shape[_key];
717
745
  if (!keySchema) continue;
718
- const literal = (_a = keySchema.inner) != null ? _a : keySchema;
746
+ const literal = (_a2 = keySchema.inner) != null ? _a2 : keySchema;
719
747
  this._map.set(literal._default, s);
720
748
  if (keySchema.inner) this._absentMember = s;
721
749
  }
@@ -727,8 +755,8 @@ var PixodeskAnimator = (() => {
727
755
  return this._map.get(val);
728
756
  }
729
757
  sanitize(raw) {
730
- var _a;
731
- return ((_a = this._findSchema(raw)) != null ? _a : this._schemas[0]).sanitize(raw);
758
+ var _a2;
759
+ return ((_a2 = this._findSchema(raw)) != null ? _a2 : this._schemas[0]).sanitize(raw);
732
760
  }
733
761
  isValid(raw, ctx, path) {
734
762
  const schema = this._findSchema(raw);
@@ -947,8 +975,8 @@ var PixodeskAnimator = (() => {
947
975
  this.resolved = null;
948
976
  }
949
977
  get schema() {
950
- var _a;
951
- return (_a = this.resolved) != null ? _a : this.resolved = this.fn();
978
+ var _a2;
979
+ return (_a2 = this.resolved) != null ? _a2 : this.resolved = this.fn();
952
980
  }
953
981
  sanitize(raw) {
954
982
  return this.schema.sanitize(raw);
@@ -1046,11 +1074,93 @@ var PixodeskAnimator = (() => {
1046
1074
  lazy: (fn, defaultVal) => new Lazy(fn, defaultVal)
1047
1075
  };
1048
1076
 
1077
+ // ../svg-animator-core/src/version/PxSchemaVersion.ts
1078
+ var PX_PLAYER_SCHEMA_VERSION = "1.1";
1079
+
1080
+ // ../svg-animator-core/src/version/PxWireVersion.ts
1081
+ var VERSION_RE = /^(\d+)\.(\d+)(?:\.(\d+))?$/;
1082
+ function parseWireVersion(raw) {
1083
+ if (typeof raw !== "string") return void 0;
1084
+ const m = VERSION_RE.exec(raw.trim());
1085
+ if (!m) return void 0;
1086
+ return { a: Number(m[1]), b: Number(m[2]), c: m[3] === void 0 ? 0 : Number(m[3]) };
1087
+ }
1088
+ var _a;
1089
+ var PLAYER_WIRE_VERSION = (_a = parseWireVersion(PX_PLAYER_SCHEMA_VERSION)) != null ? _a : { a: 1, b: 1, c: 0 };
1090
+
1049
1091
  // ../svg-animator-core/src/format/PxAnimatorConstants.ts
1092
+ var PxFillMode = {
1093
+ forwards: "forwards",
1094
+ backwards: "backwards",
1095
+ both: "both",
1096
+ none: "none"
1097
+ };
1098
+ var PxPlaybackDirection = {
1099
+ normal: "normal",
1100
+ reverse: "reverse",
1101
+ alternate: "alternate",
1102
+ alternateReverse: "alternate-reverse"
1103
+ };
1050
1104
  var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
1051
1105
  var PX_ANIM_ATTR_NAME = "_px_animator";
1106
+ var PxStartOn = {
1107
+ load: "load",
1108
+ mouseOver: "mouseOver",
1109
+ click: "click",
1110
+ scrollIntoView: "scrollIntoView",
1111
+ programmatic: "programmatic"
1112
+ };
1113
+ var PxOutAction = {
1114
+ continue: "continue",
1115
+ pause: "pause",
1116
+ reset: "reset",
1117
+ reverse: "reverse"
1118
+ };
1119
+ var PxFinishAction = {
1120
+ hold: "hold",
1121
+ reset: "reset"
1122
+ };
1123
+ var PxScrollKind = {
1124
+ view: "view",
1125
+ scroll: "scroll"
1126
+ };
1127
+ var PxScrollAxis = {
1128
+ block: "block",
1129
+ inline: "inline",
1130
+ x: "x",
1131
+ y: "y"
1132
+ };
1133
+ var PxScrollSource = {
1134
+ nearest: "nearest",
1135
+ root: "root"
1136
+ };
1137
+ var PxPinAlign = {
1138
+ top: "top",
1139
+ center: "center",
1140
+ bottom: "bottom"
1141
+ };
1142
+ var PxScrollPhase = {
1143
+ cover: "cover",
1144
+ contain: "contain",
1145
+ entry: "entry",
1146
+ exit: "exit",
1147
+ entryCrossing: "entry-crossing",
1148
+ exitCrossing: "exit-crossing"
1149
+ };
1150
+ var PxAlongPathMode = {
1151
+ sampled: "sampled",
1152
+ offsetPath: "offsetPath"
1153
+ };
1052
1154
  var PX_TIMELINE_SHARED_KEYS = ["duration", "iterations", "engine", "frameRate"];
1053
1155
  var PX_TIME_ONLY_TIMELINE_KEYS = ["trigger", "delay", "fillMode", "direction"];
1156
+ var PX_FLAT_RUNTIME_VIEW_KEYS = [
1157
+ ...PX_TIMELINE_SHARED_KEYS,
1158
+ ...PX_TIME_ONLY_TIMELINE_KEYS,
1159
+ "fill",
1160
+ "resetOnFinish",
1161
+ "timelineSource",
1162
+ "scroll"
1163
+ ];
1054
1164
  var PxTimelineEngine = {
1055
1165
  native: "native",
1056
1166
  js: "js"
@@ -1067,6 +1177,19 @@ var PixodeskAnimator = (() => {
1067
1177
  function mayUseNativeScrollTimeline(engine) {
1068
1178
  return engine !== PxTimelineEngineExtra.js;
1069
1179
  }
1180
+ var PX_TRIGGER_DEFAULTS = {
1181
+ startOn: "load",
1182
+ outAction: "continue",
1183
+ scrollIntoViewThreshold: 0
1184
+ };
1185
+ function resolveTrigger(trigger) {
1186
+ var _a2, _b, _c;
1187
+ return {
1188
+ startOn: (_a2 = trigger == null ? void 0 : trigger.startOn) != null ? _a2 : PX_TRIGGER_DEFAULTS.startOn,
1189
+ outAction: (_b = trigger == null ? void 0 : trigger.outAction) != null ? _b : PX_TRIGGER_DEFAULTS.outAction,
1190
+ scrollIntoViewThreshold: (_c = trigger == null ? void 0 : trigger.scrollIntoViewThreshold) != null ? _c : PX_TRIGGER_DEFAULTS.scrollIntoViewThreshold
1191
+ };
1192
+ }
1070
1193
  var PxLoopRepeatAt = {
1071
1194
  /** Segment from the START; the repetition runs BEFORE the first keyframe
1072
1195
  * (intro loops that play until the main timeline begins). */
@@ -1113,7 +1236,6 @@ var PixodeskAnimator = (() => {
1113
1236
  separate: "separate",
1114
1237
  combined: "combined"
1115
1238
  };
1116
- var TEXT_ATTR = "text";
1117
1239
  var TEXT_CONTENT_ATTR = "textContent";
1118
1240
  var CLASS_ATTR = "class";
1119
1241
  var TRANSFORM_ATTR = "transform";
@@ -1125,7 +1247,6 @@ var PixodeskAnimator = (() => {
1125
1247
  "meta",
1126
1248
  "animate",
1127
1249
  "effects",
1128
- TEXT_ATTR,
1129
1250
  TEXT_CONTENT_ATTR
1130
1251
  ]);
1131
1252
  var TRANSFORM_PART = {
@@ -1140,10 +1261,6 @@ var PixodeskAnimator = (() => {
1140
1261
  TRANSFORM_PART.scale,
1141
1262
  TRANSFORM_PART.origin
1142
1263
  ];
1143
- var PxGradientUnits = {
1144
- userSpaceOnUse: "userSpaceOnUse",
1145
- objectBoundingBox: "objectBoundingBox"
1146
- };
1147
1264
  var PxGradientSpreadMethod = {
1148
1265
  pad: "pad",
1149
1266
  reflect: "reflect",
@@ -1160,17 +1277,27 @@ var PixodeskAnimator = (() => {
1160
1277
  return fileJson.type === "svg";
1161
1278
  }
1162
1279
  function getAnimatorConfig(doc) {
1163
- var _a;
1164
- const cfg = (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
1165
- return cfg ? flattenAnimatorTimeline(cfg) : void 0;
1166
- }
1280
+ var _a2;
1281
+ const cfg = (doc == null ? void 0 : doc.animator) || ((_a2 = doc == null ? void 0 : doc.meta) == null ? void 0 : _a2.animator);
1282
+ if (!cfg) return void 0;
1283
+ const memoised = wireViewMemo.get(cfg);
1284
+ if (memoised) return memoised;
1285
+ const wire = cfg;
1286
+ const stray = PX_FLAT_RUNTIME_VIEW_KEYS.filter((k) => wire[k] !== void 0);
1287
+ const source = stray.length ? __spreadValues({}, wire) : cfg;
1288
+ for (const k of stray) delete source[k];
1289
+ const view = flattenAnimatorTimeline(source);
1290
+ wireViewMemo.set(cfg, view);
1291
+ return view;
1292
+ }
1293
+ var wireViewMemo = /* @__PURE__ */ new WeakMap();
1167
1294
  var flattenMemo = /* @__PURE__ */ new WeakMap();
1168
1295
  function flattenAnimatorTimeline(cfg) {
1169
1296
  const timeline = cfg.timeline;
1170
1297
  if (timeline === void 0 || timeline === null || typeof timeline !== "object") return cfg;
1171
1298
  const memoised = flattenMemo.get(cfg);
1172
1299
  if (memoised) return memoised;
1173
- const _a = cfg, { timeline: _dropped } = _a, flat = __objRest(_a, ["timeline"]);
1300
+ const _a2 = cfg, { timeline: _dropped } = _a2, flat = __objRest(_a2, ["timeline"]);
1174
1301
  if (timeline.engine !== void 0) flat.engine = timeline.engine;
1175
1302
  if (timeline.frameRate !== void 0) flat.frameRate = timeline.frameRate;
1176
1303
  if (timeline.type === "scroll" || timeline.type === "view") {
@@ -1189,7 +1316,7 @@ var PixodeskAnimator = (() => {
1189
1316
  else if (pin && typeof pin === "object") {
1190
1317
  scroll.pin = true;
1191
1318
  if (pin.align !== void 0) scroll.pinAlign = pin.align;
1192
- if (pin.top !== void 0) scroll.pinTop = pin.top;
1319
+ if (pin.offset !== void 0) scroll.pinOffset = pin.offset;
1193
1320
  if (pin.distance !== void 0) scroll.pinDistance = pin.distance;
1194
1321
  }
1195
1322
  flat.scroll = scroll;
@@ -1209,14 +1336,14 @@ var PixodeskAnimator = (() => {
1209
1336
  return flat;
1210
1337
  }
1211
1338
  function getDefs(doc) {
1212
- var _a;
1339
+ var _a2;
1213
1340
  if (!doc) return void 0;
1214
- return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
1341
+ return (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
1215
1342
  }
1216
1343
  function getBindings(doc) {
1217
- var _a;
1344
+ var _a2;
1218
1345
  if (!doc) return void 0;
1219
- const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
1346
+ const animateById = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.animateById;
1220
1347
  if (!animateById) return void 0;
1221
1348
  return Object.entries(animateById).map(([id, anim]) => ({ id: id.startsWith("#") ? id.slice(1) : id, animate: anim }));
1222
1349
  }
@@ -1231,14 +1358,13 @@ var PixodeskAnimator = (() => {
1231
1358
  // e.g. for colors
1232
1359
  px.number(),
1233
1360
  px.array(px.number()),
1234
- // ORDER LAW: the key-discriminated object shapes (`{path}`, `{paths}`) come BEFORE the
1361
+ // ORDER LAW: the key-discriminated object shape (`{pathData}`) comes BEFORE the
1235
1362
  // all-optional transform-parts record. In default (non-strict) mode that record accepts
1236
1363
  // ANY object (every key optional, unknown keys ignored), so listing it earlier made
1237
- // Union.sanitize route `{path}`/`{paths}` values into it and strip them to `{}` —
1364
+ // Union.sanitize route `{pathData}` values into it and strip them to `{}` —
1238
1365
  // silent morph-data loss (repro: the editor's keyframeValueSanitize spec). Validity is
1239
1366
  // order-independent (`some()`); only sanitize routing depends on this order.
1240
- px.object({ path: px.string() }),
1241
- px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),
1367
+ px.object({ pathData: px.string() }),
1242
1368
  // Gradient `stops` timeline — each kf value is the full stops-array snapshot.
1243
1369
  px.lazy(() => px.array(PxGradientStopSchema), []),
1244
1370
  px.lazy(() => PxTransformPartsSchema, {})
@@ -1255,16 +1381,16 @@ var PixodeskAnimator = (() => {
1255
1381
  }));
1256
1382
  var anyKf = (kf) => kf;
1257
1383
  var kfTime = (kf) => {
1258
- var _a, _b;
1259
- return (_b = (_a = anyKf(kf).time) != null ? _a : anyKf(kf).t) != null ? _b : 0;
1384
+ var _a2, _b;
1385
+ return (_b = (_a2 = anyKf(kf).time) != null ? _a2 : anyKf(kf).t) != null ? _b : 0;
1260
1386
  };
1261
1387
  var kfValue = (kf) => {
1262
- var _a;
1263
- return (_a = anyKf(kf).value) != null ? _a : anyKf(kf).v;
1388
+ var _a2;
1389
+ return (_a2 = anyKf(kf).value) != null ? _a2 : anyKf(kf).v;
1264
1390
  };
1265
1391
  var kfEasing = (kf) => {
1266
- var _a;
1267
- return (_a = anyKf(kf).easing) != null ? _a : anyKf(kf).e;
1392
+ var _a2;
1393
+ return (_a2 = anyKf(kf).easing) != null ? _a2 : anyKf(kf).e;
1268
1394
  };
1269
1395
  var kfTangentIn = (kf) => anyKf(kf).tangentIn;
1270
1396
  var kfTangentOut = (kf) => anyKf(kf).tangentOut;
@@ -1278,7 +1404,7 @@ var PixodeskAnimator = (() => {
1278
1404
  keyframes: px.array(PxKeyframeSchema).optional(),
1279
1405
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
1280
1406
  autoOrient: px.boolean().optional(),
1281
- alongPathMode: px.enum(["sampled", "offsetPath"]).optional()
1407
+ alongPathMode: px.enum([PxAlongPathMode.sampled, PxAlongPathMode.offsetPath]).optional()
1282
1408
  }));
1283
1409
  var PxTransformPartsSchema = implementsInterface()(px.object({
1284
1410
  translate: px.tuple([px.number(), px.number()]).optional(),
@@ -1302,17 +1428,17 @@ var PixodeskAnimator = (() => {
1302
1428
  PxAnimationDefinitionSchema
1303
1429
  ]));
1304
1430
  var PxTriggerSchema = implementsInterface()(px.object({
1305
- startOn: px.enum(["load", "mouseOver", "click", "scrollIntoView", "programmatic"]).optional(),
1306
- outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
1431
+ startOn: px.enum([PxStartOn.load, PxStartOn.mouseOver, PxStartOn.click, PxStartOn.scrollIntoView, PxStartOn.programmatic], PX_TRIGGER_DEFAULTS.startOn).optional(),
1432
+ outAction: px.enum([PxOutAction.continue, PxOutAction.pause, PxOutAction.reset, PxOutAction.reverse], PX_TRIGGER_DEFAULTS.outAction).optional(),
1307
1433
  // What happens after a NATURAL finish — `'hold'` (default: keep the end state per
1308
1434
  // `fill`) or `'reset'` (snap back to the start state). Pairs with `outAction` ("what
1309
1435
  // happens when the trigger condition ends"); both end-of-life knobs now read alike.
1310
- finishAction: px.enum(["hold", "reset"]).optional(),
1436
+ finishAction: px.enum([PxFinishAction.hold, PxFinishAction.reset]).optional(),
1311
1437
  scrollIntoViewThreshold: px.number().optional()
1312
1438
  }));
1313
1439
  var PxGlyphSchema = implementsInterface()(px.object({
1314
1440
  width: px.number(),
1315
- d: px.string()
1441
+ pathData: px.string()
1316
1442
  }));
1317
1443
  var PxGlyphFontSchema = implementsInterface()(px.object({
1318
1444
  fontFamily: px.string(),
@@ -1329,9 +1455,15 @@ var PixodeskAnimator = (() => {
1329
1455
  styles: px.record(px.record(px.union([px.string(), px.number()]))).optional(),
1330
1456
  fonts: px.record(PxGlyphFontSchema).optional()
1331
1457
  }));
1332
- var PX_SCROLL_PHASES = ["cover", "contain", "entry", "exit", "entry-crossing", "exit-crossing"];
1333
1458
  var PxScrollRangePointSchema = implementsInterface()(px.object({
1334
- phase: px.enum(PX_SCROLL_PHASES).optional(),
1459
+ phase: px.enum([
1460
+ PxScrollPhase.cover,
1461
+ PxScrollPhase.contain,
1462
+ PxScrollPhase.entry,
1463
+ PxScrollPhase.exit,
1464
+ PxScrollPhase.entryCrossing,
1465
+ PxScrollPhase.exitCrossing
1466
+ ]).optional(),
1335
1467
  fraction: px.number().optional()
1336
1468
  }));
1337
1469
  var PxScrollRangeSchema = px.object({
@@ -1339,21 +1471,21 @@ var PixodeskAnimator = (() => {
1339
1471
  end: PxScrollRangePointSchema.optional()
1340
1472
  });
1341
1473
  var PxScrollSchema = implementsInterface()(px.object({
1342
- kind: px.enum(["view", "scroll"]).optional(),
1343
- axis: px.enum(["block", "inline", "x", "y"]).optional(),
1344
- source: px.enum(["nearest", "root"]).optional(),
1474
+ kind: px.enum([PxScrollKind.view, PxScrollKind.scroll]).optional(),
1475
+ axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
1476
+ source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
1345
1477
  // Free-form: the two keywords `parent`/`scroller` plus any CSS selector.
1346
1478
  subject: px.string().optional(),
1347
1479
  smoothing: px.number().optional(),
1348
1480
  pin: px.boolean().optional(),
1349
- pinAlign: px.enum(["top", "center", "bottom"]).optional(),
1350
- pinTop: px.number().optional(),
1481
+ pinAlign: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
1482
+ pinOffset: px.number().optional(),
1351
1483
  pinDistance: px.number().optional(),
1352
1484
  range: PxScrollRangeSchema.optional()
1353
1485
  }));
1354
1486
  var PxTimelinePinSchema = implementsInterface()(px.object({
1355
- align: px.enum(["top", "center", "bottom"]).optional(),
1356
- top: px.number().optional(),
1487
+ align: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
1488
+ offset: px.number().optional(),
1357
1489
  distance: px.number().optional()
1358
1490
  }));
1359
1491
  var PxTimelineEngineSchema = px.enum([PxTimelineEngineExtra.auto, PxTimelineEngineExtra.native, PxTimelineEngineExtra.js]).optional();
@@ -1368,8 +1500,8 @@ var PixodeskAnimator = (() => {
1368
1500
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
1369
1501
  // `fillMode` on the wire (CSS `animation-fill-mode`; the runtime view calls it `fill`)
1370
1502
  // — never `fill`, which is paint everywhere else in the format.
1371
- fillMode: px.enum(["forwards", "backwards", "both", "none"]).optional(),
1372
- direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional()
1503
+ fillMode: px.enum([PxFillMode.forwards, PxFillMode.backwards, PxFillMode.both, PxFillMode.none]).optional(),
1504
+ direction: px.enum([PxPlaybackDirection.normal, PxPlaybackDirection.reverse, PxPlaybackDirection.alternate, PxPlaybackDirection.alternateReverse]).optional()
1373
1505
  }));
1374
1506
  var scrollishTimelineShape = {
1375
1507
  // §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
@@ -1380,8 +1512,8 @@ var PixodeskAnimator = (() => {
1380
1512
  iterations: px.number().optional(),
1381
1513
  engine: PxTimelineEngineSchema,
1382
1514
  frameRate: px.number().optional(),
1383
- axis: px.enum(["block", "inline", "x", "y"]).optional(),
1384
- source: px.enum(["nearest", "root"]).optional(),
1515
+ axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
1516
+ source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
1385
1517
  subject: px.string().optional(),
1386
1518
  // 'parent' | 'scroller' | any CSS selector
1387
1519
  smoothing: px.number().optional(),
@@ -1470,7 +1602,7 @@ var PixodeskAnimator = (() => {
1470
1602
  height: px.number().optional()
1471
1603
  }));
1472
1604
  var PxClipPathEffectSchema = implementsInterface()(px.object({
1473
- d: PxAnimatableStringSchema.optional()
1605
+ pathData: PxAnimatableStringSchema.optional()
1474
1606
  }));
1475
1607
  var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
1476
1608
  offset: PxAnimatableNumberSchema.optional(),
@@ -1507,7 +1639,7 @@ var PixodeskAnimator = (() => {
1507
1639
  radius: PxAnimatableNumberSchema.optional(),
1508
1640
  focal: PxAnimatableVec2Schema.optional(),
1509
1641
  stops: PxAnimatableGradientStopsSchema.optional(),
1510
- gradientUnits: px.enum([PxGradientUnits.userSpaceOnUse, PxGradientUnits.objectBoundingBox]).optional(),
1642
+ gradientUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1511
1643
  spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
1512
1644
  gradientTransform: px.string().optional()
1513
1645
  }));
@@ -1553,11 +1685,71 @@ var PixodeskAnimator = (() => {
1553
1685
  walk(root, "root");
1554
1686
  return warnings;
1555
1687
  }
1556
- function validateDocument(doc) {
1557
- const ctx = { errors: [], warnings: [], strict: true };
1688
+ function validateGlyphFontRefs(root, fonts) {
1689
+ if (!fonts || !Object.keys(fonts).length) return [];
1690
+ const problems = [];
1691
+ const walk = (node, path, inherited, inGlyphText) => {
1692
+ var _a2, _b;
1693
+ if (!node) return;
1694
+ const own = typeof node.fontFamily === "string" ? node.fontFamily : void 0;
1695
+ const family = own != null ? own : inherited;
1696
+ const isGlyphText = inGlyphText || node.type === "text" && !!((_b = (_a2 = node.effects) == null ? void 0 : _a2.text) == null ? void 0 : _b.useGlyphs);
1697
+ if (isGlyphText && own && !Object.prototype.hasOwnProperty.call(fonts, own)) {
1698
+ const problem = path + ': glyph-mode text uses font-family "' + own + '", which has no entry in animator.definitions.fonts';
1699
+ if (!problems.includes(problem)) problems.push(problem);
1700
+ }
1701
+ if (Array.isArray(node.children)) {
1702
+ node.children.forEach((c, i) => walk(c, path + ".children[" + i + "]", family, isGlyphText));
1703
+ }
1704
+ };
1705
+ walk(root, "root", void 0, false);
1706
+ return problems;
1707
+ }
1708
+ function validateEasingRefs(root, easings) {
1709
+ const problems = [];
1710
+ const walk = (node, path) => {
1711
+ if (Array.isArray(node)) {
1712
+ node.forEach((item, i) => walk(item, path + "[" + i + "]"));
1713
+ return;
1714
+ }
1715
+ if (!node || typeof node !== "object") return;
1716
+ const easing = node.easing;
1717
+ if (typeof easing === "string" && !(easings && Object.prototype.hasOwnProperty.call(easings, easing))) {
1718
+ const problem = path + '.easing: "' + easing + '" names no entry in animator.definitions.easings \u2014 it will play linear';
1719
+ if (!problems.includes(problem)) problems.push(problem);
1720
+ }
1721
+ for (const [key, value] of Object.entries(node)) {
1722
+ if (key === "easing") continue;
1723
+ if (value && typeof value === "object") walk(value, path + "." + key);
1724
+ }
1725
+ };
1726
+ walk(root, "root");
1727
+ return problems;
1728
+ }
1729
+ function validateVersionStamp(doc) {
1730
+ var _a2;
1731
+ const version = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.version;
1732
+ if (version === void 0) return [];
1733
+ if (parseWireVersion(version) !== void 0) return [];
1734
+ return ["root.animator.version: " + JSON.stringify(version) + ' is not a version stamp ("a.b" or "a.b.c") \u2014 it reads as unstamped'];
1735
+ }
1736
+ function validateDocument(doc, opts) {
1737
+ var _a2;
1738
+ const strict = (opts == null ? void 0 : opts.strict) !== false;
1739
+ const ctx = { errors: [], warnings: [], strict };
1558
1740
  const problems = PxAnimatedSvgDocumentSchema.isValid(doc, ctx, ["root"]) ? [] : [...ctx.errors];
1559
1741
  if (doc && typeof doc === "object") {
1560
- for (const w of validateNodeEffects(doc, { strict: true })) {
1742
+ for (const w of validateNodeEffects(doc, { strict })) {
1743
+ if (!problems.includes(w)) problems.push(w);
1744
+ }
1745
+ const defs = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
1746
+ for (const w of validateGlyphFontRefs(doc, defs == null ? void 0 : defs.fonts)) {
1747
+ if (!problems.includes(w)) problems.push(w);
1748
+ }
1749
+ for (const w of validateEasingRefs(doc, defs == null ? void 0 : defs.easings)) {
1750
+ if (!problems.includes(w)) problems.push(w);
1751
+ }
1752
+ for (const w of validateVersionStamp(doc)) {
1561
1753
  if (!problems.includes(w)) problems.push(w);
1562
1754
  }
1563
1755
  }
@@ -1580,10 +1772,13 @@ var PixodeskAnimator = (() => {
1580
1772
  // documented — because a wire key that is not in a schema is invisible to the
1581
1773
  // minifier's reserve list and gets renamed (MINIFICATION-BOUNDARY-PLAN.md §1.1).
1582
1774
  domType: px.string().optional(),
1775
+ // Text content of a `<text>` / `<tspan>`. Declared, so a non-string value is a schema error
1776
+ // and the minifier reserves the key; `text` is NOT an alias for it and is not read anywhere.
1777
+ textContent: px.string().optional(),
1583
1778
  id: px.string().optional(),
1584
1779
  meta: px.any().optional(),
1585
1780
  // Player-effects bucket emitted by the Editor's lightweight design format.
1586
- // Consumed and removed by `applyPlayerEffects` before any other normalisation
1781
+ // Consumed and removed by `applyPlayerEffects` before any other normalization
1587
1782
  // (see `createAnimatorImpl`), so downstream code never sees it.
1588
1783
  effects: PxEffectsSchema.optional(),
1589
1784
  // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
@@ -1634,7 +1829,7 @@ var PixodeskAnimator = (() => {
1634
1829
  return cloned;
1635
1830
  }
1636
1831
  function generateNewIds(doc) {
1637
- var _a, _b;
1832
+ var _a2, _b;
1638
1833
  const cloned = deepClone(doc);
1639
1834
  const idMap = /* @__PURE__ */ new Map();
1640
1835
  const hashRefAttrs = /* @__PURE__ */ new Set(["href", "xlink:href"]);
@@ -1712,7 +1907,7 @@ var PixodeskAnimator = (() => {
1712
1907
  }
1713
1908
  collectIds(cloned);
1714
1909
  updateRefs(cloned);
1715
- const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animateById;
1910
+ const docAnimate = (_a2 = cloned.animator) == null ? void 0 : _a2.animateById;
1716
1911
  if (docAnimate && typeof docAnimate === "object") {
1717
1912
  const updatedAnimate = {};
1718
1913
  for (const [key, anim] of Object.entries(docAnimate)) {
@@ -1771,7 +1966,7 @@ var PixodeskAnimator = (() => {
1771
1966
  if (nameLower.startsWith("on")) return true;
1772
1967
  return false;
1773
1968
  }
1774
- function sanitiseAttributeValue(name, value) {
1969
+ function sanitizeAttributeValue(name, value) {
1775
1970
  const nameLower = name.toLowerCase();
1776
1971
  if (isDangerousAttrName(nameLower)) {
1777
1972
  console.warn("Attribute blocked (event handler / dangerous): ", nameLower);
@@ -1796,10 +1991,10 @@ var PixodeskAnimator = (() => {
1796
1991
  return value;
1797
1992
  }
1798
1993
  function resolveStyle(style, defs) {
1799
- var _a;
1994
+ var _a2;
1800
1995
  if (!style) return void 0;
1801
1996
  if (typeof style === "string") {
1802
- return (_a = defs == null ? void 0 : defs.styles) == null ? void 0 : _a[style];
1997
+ return (_a2 = defs == null ? void 0 : defs.styles) == null ? void 0 : _a2[style];
1803
1998
  }
1804
1999
  return style;
1805
2000
  }
@@ -1810,7 +2005,7 @@ var PixodeskAnimator = (() => {
1810
2005
  if (INTERNAL_ATTRS.has(key)) continue;
1811
2006
  if (key === "style") continue;
1812
2007
  let value = props[rawKey];
1813
- if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
2008
+ if (COLOR_ATTR_NAMES.has(key) && Array.isArray(value)) {
1814
2009
  propsCopy[key] = toRGBA(value);
1815
2010
  } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes) {
1816
2011
  const parts = value.value && typeof value.value === "object" ? value.value : value;
@@ -1831,7 +2026,7 @@ var PixodeskAnimator = (() => {
1831
2026
  return propsCopy;
1832
2027
  }
1833
2028
 
1834
- // ../svg-animator-core/src/materialise/PxMotionPath.ts
2029
+ // ../svg-animator-core/src/materialize/PxMotionPath.ts
1835
2030
  function getKfTranslate(kf) {
1836
2031
  const v = kfValue(kf);
1837
2032
  if (!v) return void 0;
@@ -1912,13 +2107,13 @@ var PixodeskAnimator = (() => {
1912
2107
  var DEFAULT_FLATNESS_TOL = 0.5;
1913
2108
  var DEFAULT_ROTATION_TOL = 5;
1914
2109
  var DEFAULT_MAX_SAMPLES = 32;
1915
- function materialiseMotionPathInPropAnim(anim, opts) {
1916
- var _a, _b, _c;
2110
+ function materializeMotionPathInPropAnim(anim, opts) {
2111
+ var _a2, _b, _c;
1917
2112
  if (!propAnimIsMotionPath(anim)) return anim;
1918
2113
  const kfs = anim.keyframes;
1919
2114
  if (!Array.isArray(kfs) || kfs.length < 2) return anim;
1920
2115
  const autoOrient = !!anim.autoOrient;
1921
- const flatnessTol = (_a = opts == null ? void 0 : opts.flatnessTolerance) != null ? _a : DEFAULT_FLATNESS_TOL;
2116
+ const flatnessTol = (_a2 = opts == null ? void 0 : opts.flatnessTolerance) != null ? _a2 : DEFAULT_FLATNESS_TOL;
1922
2117
  const rotationTol = (_b = opts == null ? void 0 : opts.rotationTolerance) != null ? _b : DEFAULT_ROTATION_TOL;
1923
2118
  const maxSamples = (_c = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _c : DEFAULT_MAX_SAMPLES;
1924
2119
  const out = [];
@@ -1944,7 +2139,7 @@ var PixodeskAnimator = (() => {
1944
2139
  if (autoOrient && i > 0) {
1945
2140
  insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);
1946
2141
  }
1947
- materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
2142
+ materializeSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
1948
2143
  }
1949
2144
  const lastInE = getKfEasing(kfs[kfs.length - 1]);
1950
2145
  if (lastInE) out[out.length - 1].e = lastInE;
@@ -2058,7 +2253,7 @@ var PixodeskAnimator = (() => {
2058
2253
  out.push(makeOutKf(stepTime, dupValue));
2059
2254
  }
2060
2255
  var CORNER_STEP_AFTER_BOUNDARY_MS = 0.05;
2061
- function materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
2256
+ function materializeSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
2062
2257
  const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
2063
2258
  const prevTime = getKfTime(prevKf);
2064
2259
  const nextTime = getKfTime(nextKf);
@@ -2181,16 +2376,16 @@ var PixodeskAnimator = (() => {
2181
2376
  const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
2182
2377
  return Math.abs(cross) / Math.sqrt(len2);
2183
2378
  }
2184
- function materialiseMotionPathsInTree(root, opts) {
2185
- const out = walkAndMaterialise(root, opts);
2379
+ function materializeMotionPathsInTree(root, opts) {
2380
+ const out = walkAndMaterialize(root, opts);
2186
2381
  return out != null ? out : root;
2187
2382
  }
2188
- function walkAndMaterialise(node, opts) {
2383
+ function walkAndMaterialize(node, opts) {
2189
2384
  let newChildren;
2190
2385
  if (node.children) {
2191
2386
  for (let i = 0; i < node.children.length; i++) {
2192
2387
  const ch = node.children[i];
2193
- const ret = walkAndMaterialise(ch, opts);
2388
+ const ret = walkAndMaterialize(ch, opts);
2194
2389
  if (ret !== null) {
2195
2390
  if (!newChildren) newChildren = node.children.slice();
2196
2391
  newChildren[i] = ret;
@@ -2203,9 +2398,9 @@ var PixodeskAnimator = (() => {
2203
2398
  const animDef = animBucket;
2204
2399
  const transformAnim = animDef.transform;
2205
2400
  if (transformAnim && typeof transformAnim === "object" && propAnimIsMotionPath(transformAnim)) {
2206
- const materialised = materialiseMotionPathInPropAnim(transformAnim, opts);
2207
- if (materialised !== transformAnim) {
2208
- newAnimate = __spreadProps(__spreadValues({}, animDef), { transform: materialised });
2401
+ const materialized = materializeMotionPathInPropAnim(transformAnim, opts);
2402
+ if (materialized !== transformAnim) {
2403
+ newAnimate = __spreadProps(__spreadValues({}, animDef), { transform: materialized });
2209
2404
  }
2210
2405
  }
2211
2406
  }
@@ -2308,8 +2503,8 @@ var PixodeskAnimator = (() => {
2308
2503
  return typeof value === "string" && extractPathData(value) !== void 0;
2309
2504
  }
2310
2505
  function normalizePathValue(value) {
2311
- if (value && typeof value === "object" && typeof value.path === "string") {
2312
- const d = extractPathData(value.path);
2506
+ if (value && typeof value === "object" && typeof value.pathData === "string") {
2507
+ const d = extractPathData(value.pathData);
2313
2508
  return d ? { paths: parseSvgPathToBezier(d) } : value;
2314
2509
  }
2315
2510
  if (value && typeof value === "object" && "paths" in value) {
@@ -2348,21 +2543,21 @@ var PixodeskAnimator = (() => {
2348
2543
  return value;
2349
2544
  }
2350
2545
  function resolveEasing(easing, defs) {
2351
- var _a;
2546
+ var _a2;
2352
2547
  if (!easing) return void 0;
2353
2548
  if (Array.isArray(easing)) {
2354
2549
  return easing;
2355
2550
  }
2356
- if ((_a = defs == null ? void 0 : defs.easings) == null ? void 0 : _a[easing]) {
2551
+ if ((_a2 = defs == null ? void 0 : defs.easings) == null ? void 0 : _a2[easing]) {
2357
2552
  return defs.easings[easing];
2358
2553
  }
2359
2554
  console.warn("Unknown easing name: " + easing);
2360
2555
  return void 0;
2361
2556
  }
2362
2557
  function resolveAnimation(animRef, defs) {
2363
- var _a;
2558
+ var _a2;
2364
2559
  if (typeof animRef === "string") {
2365
- const resolved = (_a = defs == null ? void 0 : defs.animations) == null ? void 0 : _a[animRef];
2560
+ const resolved = (_a2 = defs == null ? void 0 : defs.animations) == null ? void 0 : _a2[animRef];
2366
2561
  if (!resolved) {
2367
2562
  console.warn("Unknown animation name: " + animRef);
2368
2563
  }
@@ -2387,13 +2582,13 @@ var PixodeskAnimator = (() => {
2387
2582
  return results;
2388
2583
  }
2389
2584
  function interpolateValue(propName, a, b, t) {
2390
- var _a, _b;
2585
+ var _a2, _b;
2391
2586
  if (propName === "d") {
2392
- const aPaths = (_a = a == null ? void 0 : a.paths) != null ? _a : Array.isArray(a) ? a : [];
2587
+ const aPaths = (_a2 = a == null ? void 0 : a.paths) != null ? _a2 : Array.isArray(a) ? a : [];
2393
2588
  const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
2394
2589
  return { paths: interpolateBeziers(aPaths, bPaths, t) };
2395
2590
  }
2396
- if (COLOUR_ATTR_NAMES.has(propName)) {
2591
+ if (COLOR_ATTR_NAMES.has(propName)) {
2397
2592
  return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
2398
2593
  }
2399
2594
  if (propName === "transform" && typeof a === "object" && a !== null && !Array.isArray(a) && typeof b === "object" && b !== null && !Array.isArray(b)) {
@@ -2425,9 +2620,9 @@ var PixodeskAnimator = (() => {
2425
2620
  return out;
2426
2621
  }
2427
2622
  function expandLoopKeyframes(propName, keyframes, loop, duration) {
2428
- var _a, _b, _c, _d, _e;
2623
+ var _a2, _b, _c, _d, _e;
2429
2624
  const totalIntervals = keyframes.length - 1;
2430
- const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
2625
+ const segCount = clamp((_a2 = loop.segmentCount) != null ? _a2 : totalIntervals, 1, totalIntervals);
2431
2626
  let segKfs;
2432
2627
  if (loop.repeatAt === PxLoopRepeatAt.start) {
2433
2628
  segKfs = keyframes.slice(0, segCount + 1);
@@ -2466,7 +2661,7 @@ var PixodeskAnimator = (() => {
2466
2661
  let terminalEasingOverride;
2467
2662
  let hasTerminalEasingOverride = false;
2468
2663
  function appendRep(repStart, isReversed, partial) {
2469
- var _a2;
2664
+ var _a3;
2470
2665
  let entries;
2471
2666
  if (isReversed) {
2472
2667
  entries = [];
@@ -2503,7 +2698,7 @@ var PixodeskAnimator = (() => {
2503
2698
  return;
2504
2699
  }
2505
2700
  const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
2506
- const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
2701
+ const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a3 = prevKf.t) != null ? _a3 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
2507
2702
  if (isBoundary) {
2508
2703
  if (deepEqualValue(prevKf.v, entry.v)) {
2509
2704
  if (looped.length > 0) {
@@ -2604,7 +2799,7 @@ var PixodeskAnimator = (() => {
2604
2799
  }
2605
2800
  }
2606
2801
  function normalizeKeyframes(propName, propAnim, duration, defs) {
2607
- var _a;
2802
+ var _a2;
2608
2803
  const keyframes = propAnim.keyframes || [];
2609
2804
  const normalized = [];
2610
2805
  for (const kf of keyframes) {
@@ -2615,8 +2810,8 @@ var PixodeskAnimator = (() => {
2615
2810
  value = normalizePathValue(value);
2616
2811
  }
2617
2812
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2618
- if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
2619
- value = (_a = parseColor(value)) != null ? _a : value;
2813
+ if (COLOR_ATTR_NAMES.has(propNameKebab)) {
2814
+ value = (_a2 = parseColor(value)) != null ? _a2 : value;
2620
2815
  }
2621
2816
  const normKf = {
2622
2817
  t: timePct,
@@ -2630,8 +2825,8 @@ var PixodeskAnimator = (() => {
2630
2825
  normalized.push(normKf);
2631
2826
  }
2632
2827
  normalized.sort((a, b) => {
2633
- var _a2, _b;
2634
- return ((_a2 = a.t) != null ? _a2 : 0) - ((_b = b.t) != null ? _b : 0);
2828
+ var _a3, _b;
2829
+ return ((_a3 = a.t) != null ? _a3 : 0) - ((_b = b.t) != null ? _b : 0);
2635
2830
  });
2636
2831
  const loopRaw = propAnim.loop;
2637
2832
  const loop = loopRaw === true ? {} : loopRaw || void 0;
@@ -2649,20 +2844,20 @@ var PixodeskAnimator = (() => {
2649
2844
  }
2650
2845
  return merged;
2651
2846
  }
2652
- function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
2847
+ function materializeInternalLoopsInPropAnim(propName, propAnim, duration) {
2653
2848
  const loopRaw = propAnim.loop;
2654
2849
  if (loopRaw === void 0 || loopRaw === null || loopRaw === false) return propAnim;
2655
2850
  const loop = loopRaw === true ? {} : loopRaw;
2656
2851
  const rawKfs = propAnim.keyframes;
2657
2852
  if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
2658
2853
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2659
- const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);
2854
+ const isColor = COLOR_ATTR_NAMES.has(propNameKebab);
2660
2855
  const kfs = rawKfs.map((kf) => {
2661
- var _a;
2856
+ var _a2;
2662
2857
  const t = kfTime(kf);
2663
2858
  let v = kfValue(kf);
2664
2859
  if (propName === "d") v = normalizePathValue(v);
2665
- if (isColour) v = (_a = parseColor(v)) != null ? _a : v;
2860
+ if (isColor) v = (_a2 = parseColor(v)) != null ? _a2 : v;
2666
2861
  const e = kfEasing(kf);
2667
2862
  const out2 = { t, v, e };
2668
2863
  const tIn = kfTangentIn(kf);
@@ -2676,15 +2871,15 @@ var PixodeskAnimator = (() => {
2676
2871
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2677
2872
  return out;
2678
2873
  }
2679
- function materialiseInternalLoopsInTree(root, duration) {
2680
- const ret = walkAndMaterialiseLoops(root, duration);
2874
+ function materializeInternalLoopsInTree(root, duration) {
2875
+ const ret = walkAndMaterializeLoops(root, duration);
2681
2876
  return ret != null ? ret : root;
2682
2877
  }
2683
- function walkAndMaterialiseLoops(node, duration) {
2878
+ function walkAndMaterializeLoops(node, duration) {
2684
2879
  let newChildren;
2685
2880
  if (node.children) {
2686
2881
  for (let i = 0; i < node.children.length; i++) {
2687
- const ret = walkAndMaterialiseLoops(node.children[i], duration);
2882
+ const ret = walkAndMaterializeLoops(node.children[i], duration);
2688
2883
  if (ret !== null) {
2689
2884
  if (!newChildren) newChildren = node.children.slice();
2690
2885
  newChildren[i] = ret;
@@ -2697,10 +2892,10 @@ var PixodeskAnimator = (() => {
2697
2892
  const animDef = animBucket;
2698
2893
  for (const propName of Object.keys(animDef)) {
2699
2894
  const propAnim = animDef[propName];
2700
- const materialised = materialiseInternalLoopsInPropAnim(propName, propAnim, duration);
2701
- if (materialised !== propAnim) {
2895
+ const materialized = materializeInternalLoopsInPropAnim(propName, propAnim, duration);
2896
+ if (materialized !== propAnim) {
2702
2897
  if (!newAnimate) newAnimate = __spreadValues({}, animDef);
2703
- newAnimate[propName] = materialised;
2898
+ newAnimate[propName] = materialized;
2704
2899
  }
2705
2900
  }
2706
2901
  }
@@ -2755,12 +2950,12 @@ var PixodeskAnimator = (() => {
2755
2950
  const out = { keyframes: normalizedKfs };
2756
2951
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2757
2952
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
2758
- normalized[propName] = engine === PxTimelineEngine.native && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
2953
+ normalized[propName] = engine === PxTimelineEngine.native && propName === "transform" ? materializeMotionPathInPropAnim(out) : out;
2759
2954
  }
2760
2955
  }
2761
2956
  return normalized;
2762
2957
  }
2763
- function getNormalisedBindings(doc, engine = PxTimelineEngine.native) {
2958
+ function getNormalizedBindings(doc, engine = PxTimelineEngine.native) {
2764
2959
  const animatorConfig = getAnimatorConfig(doc) || {};
2765
2960
  const defs = getDefs(doc);
2766
2961
  const duration = animatorConfig.duration || 1e3;
@@ -2806,12 +3001,12 @@ var PixodeskAnimator = (() => {
2806
3001
  return bindings;
2807
3002
  }
2808
3003
  function getKeyframesPair(keyframes, progress) {
2809
- var _a, _b;
3004
+ var _a2, _b;
2810
3005
  const last = keyframes.length - 1;
2811
3006
  let prevKf = keyframes[0];
2812
3007
  let nextKf = keyframes[last > 0 ? 1 : 0];
2813
3008
  for (let j = 0; j < last; j++) {
2814
- const aOff = (_a = keyframes[j].t) != null ? _a : 0;
3009
+ const aOff = (_a2 = keyframes[j].t) != null ? _a2 : 0;
2815
3010
  const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
2816
3011
  if (aOff <= progress && progress <= bOff) {
2817
3012
  prevKf = keyframes[j];
@@ -2826,11 +3021,11 @@ var PixodeskAnimator = (() => {
2826
3021
  return { prevKf, nextKf };
2827
3022
  }
2828
3023
  function calcPropertyValue(propName, propAnim, progress) {
2829
- var _a, _b, _c, _d;
3024
+ var _a2, _b, _c, _d;
2830
3025
  const keyframes = propAnim.keyframes || [];
2831
3026
  if (keyframes.length === 0) return null;
2832
3027
  const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
2833
- let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
3028
+ let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a2 = prevKf.t) != null ? _a2 : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
2834
3029
  localProgress = clamp(localProgress, 0, 1);
2835
3030
  const easing = kfEasing(prevKf);
2836
3031
  if (easing && Array.isArray(easing)) {
@@ -2851,7 +3046,7 @@ var PixodeskAnimator = (() => {
2851
3046
  nextPaths,
2852
3047
  localProgress
2853
3048
  ).map((bz) => bezierToSvgPath(bz)).join("");
2854
- } else if (COLOUR_ATTR_NAMES.has(cssAttrName)) {
3049
+ } else if (COLOR_ATTR_NAMES.has(cssAttrName)) {
2855
3050
  cssValue = toRGBA(interpolateColor(
2856
3051
  prevV || [0, 0, 0, 1],
2857
3052
  nextV || [0, 0, 0, 1],
@@ -2959,13 +3154,13 @@ var PixodeskAnimator = (() => {
2959
3154
  function regenerateIdsAndRewriteRefs(root, genId3) {
2960
3155
  const oldToNew = /* @__PURE__ */ new Map();
2961
3156
  const walkAssign = (n) => {
2962
- var _a;
3157
+ var _a2;
2963
3158
  if (typeof n.id === "string") {
2964
3159
  const newId = genId3();
2965
3160
  oldToNew.set(n.id, newId);
2966
3161
  n.id = newId;
2967
3162
  }
2968
- (_a = n.children) == null ? void 0 : _a.forEach(walkAssign);
3163
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walkAssign);
2969
3164
  };
2970
3165
  walkAssign(root);
2971
3166
  const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
@@ -2973,7 +3168,7 @@ var PixodeskAnimator = (() => {
2973
3168
  return newId ? "url(#" + newId + ")" : m;
2974
3169
  });
2975
3170
  const walkRewrite = (n) => {
2976
- var _a;
3171
+ var _a2;
2977
3172
  if (typeof n.href === "string" && n.href.startsWith("#")) {
2978
3173
  const newId = oldToNew.get(n.href.slice(1));
2979
3174
  if (newId) n.href = "#" + newId;
@@ -2985,7 +3180,7 @@ var PixodeskAnimator = (() => {
2985
3180
  n[k] = rewriteUrl(v);
2986
3181
  }
2987
3182
  }
2988
- (_a = n.children) == null ? void 0 : _a.forEach(walkRewrite);
3183
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walkRewrite);
2989
3184
  };
2990
3185
  walkRewrite(root);
2991
3186
  return oldToNew;
@@ -2995,7 +3190,7 @@ var PixodeskAnimator = (() => {
2995
3190
  return Number.isFinite(n) ? n : 0;
2996
3191
  }
2997
3192
  function applyUseOffsetToG(gNode) {
2998
- var _a;
3193
+ var _a2;
2999
3194
  const x = toFiniteNum(gNode.x);
3000
3195
  const y = toFiniteNum(gNode.y);
3001
3196
  delete gNode.x;
@@ -3004,7 +3199,7 @@ var PixodeskAnimator = (() => {
3004
3199
  const offset = "translate(" + x + "," + y + ")";
3005
3200
  const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
3006
3201
  if (carriesTransform) {
3007
- const inner = { type: "g", transform: offset, children: (_a = gNode.children) != null ? _a : [] };
3202
+ const inner = { type: "g", transform: offset, children: (_a2 = gNode.children) != null ? _a2 : [] };
3008
3203
  gNode.children = [inner];
3009
3204
  } else {
3010
3205
  gNode.transform = offset;
@@ -3012,9 +3207,9 @@ var PixodeskAnimator = (() => {
3012
3207
  return gNode;
3013
3208
  }
3014
3209
 
3015
- // ../svg-animator-core/src/materialise/PxAnimatorUseMaterialiser.ts
3016
- function materialiseAnimatedUseInstances(root) {
3017
- var _a;
3210
+ // ../svg-animator-core/src/materialize/PxAnimatorUseMaterializer.ts
3211
+ function materializeAnimatedUseInstances(root) {
3212
+ var _a2;
3018
3213
  const idMap = buildIdMap(root);
3019
3214
  const animatedIds = computeAnimatedSubtreeIds(root, idMap);
3020
3215
  if (animatedIds.size === 0) return root;
@@ -3022,10 +3217,10 @@ var PixodeskAnimator = (() => {
3022
3217
  const genId3 = () => "_lw_use_mat_" + ++idCounter;
3023
3218
  const rootViewport = readRootViewport(root);
3024
3219
  const defsCollector = [];
3025
- const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
3220
+ const walked = walkAndMaterialize2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
3026
3221
  if (defsCollector.length === 0) return walked;
3027
3222
  const defsNode = { type: "defs", children: defsCollector };
3028
- const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
3223
+ const newChildren = [...(_a2 = walked.children) != null ? _a2 : [], defsNode];
3029
3224
  return __spreadProps(__spreadValues({}, walked), { children: newChildren });
3030
3225
  }
3031
3226
  function readRootViewport(root) {
@@ -3047,9 +3242,9 @@ var PixodeskAnimator = (() => {
3047
3242
  function buildIdMap(root) {
3048
3243
  const map = /* @__PURE__ */ new Map();
3049
3244
  const visit = (n) => {
3050
- var _a;
3245
+ var _a2;
3051
3246
  if (typeof n.id === "string") map.set(n.id, n);
3052
- (_a = n.children) == null ? void 0 : _a.forEach(visit);
3247
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
3053
3248
  };
3054
3249
  visit(root);
3055
3250
  return map;
@@ -3095,16 +3290,16 @@ var PixodeskAnimator = (() => {
3095
3290
  if (typeof href !== "string") return void 0;
3096
3291
  return href.startsWith("#") ? href.slice(1) : href;
3097
3292
  }
3098
- function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3099
- var _a, _b, _c, _d;
3293
+ function materializeOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3294
+ var _a2, _b, _c, _d;
3100
3295
  const clone2 = deepClonePxNode(target);
3101
3296
  regenerateIdsAndRewriteRefs(clone2, genId3);
3102
3297
  const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
3103
- const useW = (_b = (_a = numericAttr(useNode.width)) != null ? _a : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
3298
+ const useW = (_b = (_a2 = numericAttr(useNode.width)) != null ? _a2 : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
3104
3299
  const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
3105
3300
  const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
3106
- const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
3107
- const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materialisedClone] });
3301
+ const materializedClone = walkAndMaterialize2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
3302
+ const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materializedClone] });
3108
3303
  delete newNode.href;
3109
3304
  delete newNode.width;
3110
3305
  delete newNode.height;
@@ -3142,18 +3337,18 @@ var PixodeskAnimator = (() => {
3142
3337
  if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
3143
3338
  return [parts[0], parts[1], parts[2], parts[3]];
3144
3339
  }
3145
- function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3340
+ function walkAndMaterialize2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3146
3341
  if (node.type === "use" && typeof node.href === "string") {
3147
3342
  const targetId = stripHash(node.href);
3148
3343
  if (targetId && animatedIds.has(targetId)) {
3149
3344
  const target = idMap.get(targetId);
3150
- if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
3345
+ if (target) return materializeOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
3151
3346
  }
3152
3347
  }
3153
3348
  if (!node.children) return node;
3154
3349
  let changed = false;
3155
3350
  const newChildren = node.children.map((ch) => {
3156
- const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
3351
+ const m = walkAndMaterialize2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
3157
3352
  if (m !== ch) changed = true;
3158
3353
  return m;
3159
3354
  });
@@ -3171,15 +3366,15 @@ var PixodeskAnimator = (() => {
3171
3366
  return rec;
3172
3367
  }
3173
3368
  function readAnimatable(raw) {
3174
- var _a, _b;
3369
+ var _a2, _b;
3175
3370
  if (raw === void 0) return { kind: "absent" /* Absent */ };
3176
3371
  if (Array.isArray(raw)) return { kind: "static" /* Static */, value: raw };
3177
3372
  if (typeof raw === "object") {
3178
3373
  const obj = raw;
3179
3374
  const kfs = obj.keyframes;
3180
3375
  if (kfs) {
3181
- const out = { kind: "animated" /* Animated */, keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
3182
- const base = (_a = obj.value) != null ? _a : obj.v;
3376
+ const out = { kind: "animated" /* Animated */, keyframes: kfs.map(normalizeKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
3377
+ const base = (_a2 = obj.value) != null ? _a2 : obj.v;
3183
3378
  if (base !== void 0 && out.kind === "animated" /* Animated */) out.base = base;
3184
3379
  return out;
3185
3380
  }
@@ -3189,7 +3384,7 @@ var PixodeskAnimator = (() => {
3189
3384
  return { kind: "static" /* Static */, value: raw };
3190
3385
  }
3191
3386
  function writeAnimatableChannel(node, attrName, read, opts) {
3192
- var _a, _b, _c, _d;
3387
+ var _a2, _b, _c, _d;
3193
3388
  const toOut = (v) => (opts == null ? void 0 : opts.asString) && v !== void 0 && v !== null ? String(v) : v;
3194
3389
  if (read.kind === "absent" /* Absent */) return;
3195
3390
  if (read.kind === "static" /* Static */) {
@@ -3203,10 +3398,10 @@ var PixodeskAnimator = (() => {
3203
3398
  if (read.autoOrient !== void 0) block.autoOrient = read.autoOrient;
3204
3399
  animate[attrName] = block;
3205
3400
  node.animate = animate;
3206
- 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;
3401
+ const baseline = (_d = (_b = read.base) != null ? _b : (_a2 = read.keyframes[0]) == null ? void 0 : _a2.value) != null ? _d : (_c = read.keyframes[0]) == null ? void 0 : _c.v;
3207
3402
  if (baseline !== void 0) node[attrName] = toOut(baseline);
3208
3403
  }
3209
- function normaliseKeyframe(kf) {
3404
+ function normalizeKeyframe(kf) {
3210
3405
  if (!kf || typeof kf !== "object") return kf;
3211
3406
  const k = kf;
3212
3407
  if (k.t === void 0 && k.v === void 0 && k.e === void 0 && k.to === void 0 && k.ti === void 0) {
@@ -3221,12 +3416,12 @@ var PixodeskAnimator = (() => {
3221
3416
  return out;
3222
3417
  }
3223
3418
  function readStaticOrigin(raw, ctx) {
3224
- var _a;
3419
+ var _a2;
3225
3420
  const o = readAnimatable(raw);
3226
3421
  if (o.kind === "absent" /* Absent */) return void 0;
3227
3422
  if (o.kind === "static" /* Static */) return o.value;
3228
3423
  ctx.warnings.push("transformBy.origin: animated origin approximated by its first keyframe");
3229
- return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
3424
+ return (_a2 = o.keyframes[0]) == null ? void 0 : _a2.value;
3230
3425
  }
3231
3426
  function keyframeWith(kf, value) {
3232
3427
  const out = { value };
@@ -3336,9 +3531,9 @@ var PixodeskAnimator = (() => {
3336
3531
  return typeof href === "string" ? href.replace(/^#/, "") : void 0;
3337
3532
  }
3338
3533
  function indexById(node, map) {
3339
- var _a;
3534
+ var _a2;
3340
3535
  if (typeof node.id === "string") map.set(node.id, node);
3341
- (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
3536
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((child) => indexById(child, map));
3342
3537
  }
3343
3538
  function spliceDefs(root, defs) {
3344
3539
  if (!defs.length) return;
@@ -3352,8 +3547,8 @@ var PixodeskAnimator = (() => {
3352
3547
 
3353
3548
  // ../svg-animator-core/src/effects/reference/contentRefSplit.ts
3354
3549
  function identifyContentRefTargets(node, ctx, allocator) {
3355
- var _a, _b, _c;
3356
- if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.without) === "translate") {
3550
+ var _a2, _b, _c;
3551
+ if (node.type === "use" && ((_b = (_a2 = node.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.without) === "translate") {
3357
3552
  const sourceId = stripHash2(node.effects.clone.source);
3358
3553
  if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
3359
3554
  ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
@@ -3379,10 +3574,10 @@ var PixodeskAnimator = (() => {
3379
3574
  return outerWrapper;
3380
3575
  }
3381
3576
  function liftBodyTranslate(node, transformBy) {
3382
- var _a, _b, _c;
3577
+ var _a2, _b, _c;
3383
3578
  const out = {};
3384
3579
  let didLiftAnimate = false;
3385
- const animTr = (_a = node.animate) == null ? void 0 : _a.transform;
3580
+ const animTr = (_a2 = node.animate) == null ? void 0 : _a2.transform;
3386
3581
  if (animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes)) {
3387
3582
  const kfs = animTr.keyframes;
3388
3583
  const hasTranslate = kfs.some((kf) => kf.value && kf.value.translate);
@@ -3600,7 +3795,7 @@ var PixodeskAnimator = (() => {
3600
3795
  return out;
3601
3796
  }
3602
3797
  function applyGeomVec(out, xAttr, yAttr, raw) {
3603
- var _a, _b, _c;
3798
+ var _a2, _b, _c;
3604
3799
  const read = readAnimatable(raw);
3605
3800
  if (read.kind === "absent" /* Absent */) return;
3606
3801
  if (read.kind === "static" /* Static */) {
@@ -3619,7 +3814,7 @@ var PixodeskAnimator = (() => {
3619
3814
  if (read.loop !== void 0) block.loop = read.loop;
3620
3815
  return block;
3621
3816
  };
3622
- const animate = (_a = out.animate) != null ? _a : {};
3817
+ const animate = (_a2 = out.animate) != null ? _a2 : {};
3623
3818
  animate[xAttr] = axisChannel(0);
3624
3819
  animate[yAttr] = axisChannel(1);
3625
3820
  out.animate = animate;
@@ -3635,7 +3830,7 @@ var PixodeskAnimator = (() => {
3635
3830
  writeAnimatableChannel(out, attrName, read, { asString: true });
3636
3831
  }
3637
3832
  function buildStopChildren(stops, ctx) {
3638
- var _a, _b;
3833
+ var _a2, _b;
3639
3834
  if (!stops) return [];
3640
3835
  const read = readAnimatable(stops);
3641
3836
  if (read.kind === "absent" /* Absent */) return [];
@@ -3652,7 +3847,7 @@ var PixodeskAnimator = (() => {
3652
3847
  const firstKfValue = kfValue(kfs[0]);
3653
3848
  const baselineStops = [];
3654
3849
  for (let i = 0; i < stopCount; i++) {
3655
- const s = (_b = (_a = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _a : prevDefinedStop(kfs, 0, i)) != null ? _b : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
3850
+ const s = (_b = (_a2 = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _a2 : prevDefinedStop(kfs, 0, i)) != null ? _b : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
3656
3851
  baselineStops.push({ offset: s.offset, color: s.color });
3657
3852
  }
3658
3853
  return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));
@@ -3665,14 +3860,14 @@ var PixodeskAnimator = (() => {
3665
3860
  };
3666
3861
  }
3667
3862
  function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
3668
- var _a;
3863
+ var _a2;
3669
3864
  const colorKfs = [];
3670
3865
  const offsetKfs = [];
3671
3866
  let offsetVaries = false;
3672
3867
  for (const kf of kfs) {
3673
3868
  const t = kfTime(kf);
3674
3869
  const arr = kfValue(kf);
3675
- const sliced = (_a = arr == null ? void 0 : arr[stopIdx]) != null ? _a : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
3870
+ const sliced = (_a2 = arr == null ? void 0 : arr[stopIdx]) != null ? _a2 : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
3676
3871
  if (!sliced) continue;
3677
3872
  const easing = kfEasing(kf);
3678
3873
  const colorOut = { time: t, value: sliced.color };
@@ -3718,10 +3913,10 @@ var PixodeskAnimator = (() => {
3718
3913
 
3719
3914
  // ../svg-animator-core/src/effects/clipping/clipPathEffect.ts
3720
3915
  function applyClipPathEffect(node, fx, ctx) {
3721
- if (!(fx == null ? void 0 : fx.d)) return node;
3916
+ if (!(fx == null ? void 0 : fx.pathData)) return node;
3722
3917
  const clipId = genId(ctx, "clip");
3723
3918
  const pathChild = { type: "path" };
3724
- const read = readAnimatable(fx.d);
3919
+ const read = readAnimatable(fx.pathData);
3725
3920
  if (read.kind !== "absent" /* Absent */) {
3726
3921
  if (read.kind === "static" /* Static */) {
3727
3922
  pathChild.d = pathString(read.value);
@@ -3736,7 +3931,7 @@ var PixodeskAnimator = (() => {
3736
3931
  }
3737
3932
  function pathString(v) {
3738
3933
  if (typeof v === "string") return v;
3739
- if (v && typeof v === "object" && typeof v.path === "string") return v.path;
3934
+ if (v && typeof v === "object" && typeof v.pathData === "string") return v.pathData;
3740
3935
  return void 0;
3741
3936
  }
3742
3937
 
@@ -3783,8 +3978,8 @@ var PixodeskAnimator = (() => {
3783
3978
  }
3784
3979
  function wrapInversePart(inner, part, raw, origin, ctx) {
3785
3980
  if (raw === void 0) return inner;
3786
- const normalisedRaw = part === "scale" /* Scale */ && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
3787
- const v = readAnimatable(normalisedRaw);
3981
+ const normalizedRaw = part === "scale" /* Scale */ && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
3982
+ const v = readAnimatable(normalizedRaw);
3788
3983
  if (v.kind === "static" /* Static */) {
3789
3984
  return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
3790
3985
  }
@@ -3808,16 +4003,16 @@ var PixodeskAnimator = (() => {
3808
4003
  return [1 / value[0], 1 / value[1]];
3809
4004
  }
3810
4005
  function negatedSpatialTangents(kf) {
3811
- var _a, _b;
4006
+ var _a2, _b;
3812
4007
  const out = {};
3813
- const to = (_a = kf.tangentOut) != null ? _a : kf.to;
4008
+ const to = (_a2 = kf.tangentOut) != null ? _a2 : kf.to;
3814
4009
  const ti = (_b = kf.tangentIn) != null ? _b : kf.ti;
3815
4010
  if (Array.isArray(to)) out.tangentOut = [-to[0], -to[1]];
3816
4011
  if (Array.isArray(ti)) out.tangentIn = [-ti[0], -ti[1]];
3817
4012
  return out;
3818
4013
  }
3819
4014
  function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
3820
- var _a;
4015
+ var _a2;
3821
4016
  const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
3822
4017
  const animTr = animate == null ? void 0 : animate.transform;
3823
4018
  const kfs = animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes) ? animTr.keyframes : void 0;
@@ -3826,7 +4021,7 @@ var PixodeskAnimator = (() => {
3826
4021
  const rotateKfs = [];
3827
4022
  const scaleKfs = [];
3828
4023
  for (const kf of kfs) {
3829
- const v = ((_a = kf.value) != null ? _a : kf.v) || {};
4024
+ const v = ((_a2 = kf.value) != null ? _a2 : kf.v) || {};
3830
4025
  const baseKf = keyframeWith(kf, void 0);
3831
4026
  if (Array.isArray(v.translate)) {
3832
4027
  translateKfs.push(__spreadProps(__spreadValues(__spreadValues({}, baseKf), negatedSpatialTangents(kf)), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
@@ -3890,7 +4085,7 @@ var PixodeskAnimator = (() => {
3890
4085
  return void 0;
3891
4086
  }
3892
4087
  function parseTransformStringToParts(s) {
3893
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
4088
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
3894
4089
  const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
3895
4090
  let m;
3896
4091
  const ops = [];
@@ -3904,7 +4099,7 @@ var PixodeskAnimator = (() => {
3904
4099
  for (let j = ops.length - 2; j >= 0; j--) {
3905
4100
  const cand = ops[j];
3906
4101
  if (cand.name !== "translate") continue;
3907
- const ox = (_a = cand.args[0]) != null ? _a : 0;
4102
+ const ox = (_a2 = cand.args[0]) != null ? _a2 : 0;
3908
4103
  const oy = (_b = cand.args[1]) != null ? _b : 0;
3909
4104
  const lx = (_c = last.args[0]) != null ? _c : 0;
3910
4105
  const ly = (_d = last.args[1]) != null ? _d : 0;
@@ -4019,8 +4214,8 @@ var PixodeskAnimator = (() => {
4019
4214
  function collectMaskAncestorChains(root, ctx) {
4020
4215
  const interestingNodes = /* @__PURE__ */ new Set();
4021
4216
  const collectInterestingNodes = (n) => {
4022
- var _a, _b;
4023
- const maskSourceId = stripHash2((_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.source);
4217
+ var _a2, _b;
4218
+ const maskSourceId = stripHash2((_b = (_a2 = n.effects) == null ? void 0 : _a2.maskedBy) == null ? void 0 : _b.source);
4024
4219
  if (typeof maskSourceId === "string") {
4025
4220
  interestingNodes.add(n);
4026
4221
  const sourceNode = ctx.idMap.get(maskSourceId);
@@ -4041,7 +4236,7 @@ var PixodeskAnimator = (() => {
4041
4236
  walk(root, []);
4042
4237
  }
4043
4238
  function extractTranslateOnly(node, ctx) {
4044
- var _a, _b, _c;
4239
+ var _a2, _b, _c;
4045
4240
  const tr = node.transform;
4046
4241
  const animateBlock = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate.transform : void 0;
4047
4242
  if (tr === void 0 && !animateBlock) return void 0;
@@ -4063,7 +4258,7 @@ var PixodeskAnimator = (() => {
4063
4258
  const kfs = animateBlock.keyframes;
4064
4259
  const translateKfs = [];
4065
4260
  for (const kf of kfs) {
4066
- const v = (_a = kf.value) != null ? _a : kf.v;
4261
+ const v = (_a2 = kf.value) != null ? _a2 : kf.v;
4067
4262
  const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
4068
4263
  if (v && typeof v === "object" && Array.isArray(v.translate)) {
4069
4264
  translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });
@@ -4115,9 +4310,9 @@ var PixodeskAnimator = (() => {
4115
4310
 
4116
4311
  // ../svg-animator-core/src/effects/transform/repeaterEffect.ts
4117
4312
  function applyRepeaterEffect(node, fx, ctx) {
4118
- var _a, _b;
4313
+ var _a2, _b;
4119
4314
  if (!fx) return node;
4120
- const copies = (_a = fx.copies) != null ? _a : 1;
4315
+ const copies = (_a2 = fx.copies) != null ? _a2 : 1;
4121
4316
  if (copies < 1) {
4122
4317
  ctx.errors.push("repeater.copies invalid: " + fx.copies);
4123
4318
  return node;
@@ -4185,10 +4380,10 @@ var PixodeskAnimator = (() => {
4185
4380
  }
4186
4381
 
4187
4382
  // ../svg-animator-core/src/effects/reference/retimeEffect.ts
4188
- var RETIME_MATERIALISATION_MODE_INLINE_G = false;
4383
+ var RETIME_MATERIALIZATION_MODE_INLINE_G = false;
4189
4384
  function asRetime(r) {
4190
- var _a, _b;
4191
- return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
4385
+ var _a2, _b;
4386
+ return { start: (_a2 = r.start) != null ? _a2 : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
4192
4387
  }
4193
4388
  var CROP_EDGE_MS = 1;
4194
4389
  function applyTimeCrop(useNode, crop, ctx) {
@@ -4216,12 +4411,12 @@ var PixodeskAnimator = (() => {
4216
4411
  };
4217
4412
  }
4218
4413
  function readCloneRetime(n) {
4219
- var _a, _b;
4220
- return (_b = (_a = n.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.retime;
4414
+ var _a2, _b;
4415
+ return (_b = (_a2 = n.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.retime;
4221
4416
  }
4222
4417
  function clearCloneRetime(n) {
4223
- var _a;
4224
- const clone2 = (_a = n.effects) == null ? void 0 : _a.clone;
4418
+ var _a2;
4419
+ const clone2 = (_a2 = n.effects) == null ? void 0 : _a2.clone;
4225
4420
  if (!clone2) return;
4226
4421
  delete clone2.retime;
4227
4422
  if (Object.keys(clone2).length === 0) delete n.effects.clone;
@@ -4232,9 +4427,9 @@ var PixodeskAnimator = (() => {
4232
4427
  indexById(root, ctx.idMap);
4233
4428
  const sites = [];
4234
4429
  const collect = (n) => {
4235
- var _a;
4430
+ var _a2;
4236
4431
  if (readCloneRetime(n)) sites.push(n);
4237
- (_a = n.children) == null ? void 0 : _a.forEach(collect);
4432
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(collect);
4238
4433
  };
4239
4434
  collect(root);
4240
4435
  const reachCount = /* @__PURE__ */ new Map();
@@ -4242,7 +4437,7 @@ var PixodeskAnimator = (() => {
4242
4437
  let count = 0;
4243
4438
  const visited = /* @__PURE__ */ new Set();
4244
4439
  const walk = (n) => {
4245
- var _a;
4440
+ var _a2;
4246
4441
  if (!n) return;
4247
4442
  if (n !== site && readCloneRetime(n)) count++;
4248
4443
  if (n.type === "use" && n.href) {
@@ -4252,7 +4447,7 @@ var PixodeskAnimator = (() => {
4252
4447
  walk(ctx.idMap.get(id));
4253
4448
  }
4254
4449
  }
4255
- (_a = n.children) == null ? void 0 : _a.forEach(walk);
4450
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walk);
4256
4451
  };
4257
4452
  const rootId = stripHash2(site.href);
4258
4453
  if (rootId) {
@@ -4262,19 +4457,19 @@ var PixodeskAnimator = (() => {
4262
4457
  reachCount.set(site, count);
4263
4458
  }
4264
4459
  sites.sort((a, b) => {
4265
- var _a, _b;
4266
- return ((_a = reachCount.get(b)) != null ? _a : 0) - ((_b = reachCount.get(a)) != null ? _b : 0);
4460
+ var _a2, _b;
4461
+ return ((_a2 = reachCount.get(b)) != null ? _a2 : 0) - ((_b = reachCount.get(a)) != null ? _b : 0);
4267
4462
  });
4268
4463
  for (const useNode of sites) {
4269
4464
  const retime = readCloneRetime(useNode);
4270
4465
  if (!retime) continue;
4271
4466
  const crop = retime.timeCrop;
4272
4467
  clearCloneRetime(useNode);
4273
- materialiseRetime(useNode, asRetime(retime), ctx);
4468
+ materializeRetime(useNode, asRetime(retime), ctx);
4274
4469
  if (crop) applyTimeCrop(useNode, crop, ctx);
4275
4470
  }
4276
4471
  }
4277
- function materialiseRetime(useNode, retime, ctx) {
4472
+ function materializeRetime(useNode, retime, ctx) {
4278
4473
  const targetId = stripHash2(useNode.href);
4279
4474
  if (!targetId) {
4280
4475
  ctx.errors.push("retime: <use> has no href to follow");
@@ -4282,7 +4477,7 @@ var PixodeskAnimator = (() => {
4282
4477
  }
4283
4478
  const chainRootId = buildChainClone(targetId, retime, ctx, /* @__PURE__ */ new Set());
4284
4479
  if (!chainRootId) return;
4285
- if (RETIME_MATERIALISATION_MODE_INLINE_G) {
4480
+ if (RETIME_MATERIALIZATION_MODE_INLINE_G) {
4286
4481
  const cloneNode = ctx.idMap.get(chainRootId);
4287
4482
  useNode.type = "g";
4288
4483
  delete useNode.href;
@@ -4322,15 +4517,15 @@ var PixodeskAnimator = (() => {
4322
4517
  if (subId2) cloneNode.href = "#" + subId2;
4323
4518
  }
4324
4519
  } else {
4325
- materialiseNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
4520
+ materializeNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
4326
4521
  }
4327
4522
  ctx.defs.push(cloneNode);
4328
4523
  if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
4329
4524
  return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
4330
4525
  }
4331
- function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4526
+ function materializeNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4332
4527
  const visit = (n) => {
4333
- var _a;
4528
+ var _a2;
4334
4529
  const retime = readCloneRetime(n);
4335
4530
  if (n.type === "use" && retime && n.href) {
4336
4531
  const subId = stripHash2(n.href);
@@ -4343,14 +4538,14 @@ var PixodeskAnimator = (() => {
4343
4538
  }
4344
4539
  clearCloneRetime(n);
4345
4540
  }
4346
- (_a = n.children) == null ? void 0 : _a.forEach(visit);
4541
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
4347
4542
  };
4348
4543
  visit(node);
4349
4544
  }
4350
4545
  function remapKeyframeTimes(node, start, stretch) {
4351
- var _a;
4546
+ var _a2;
4352
4547
  remapKeyframeTimesOnly(node, start, stretch);
4353
- (_a = node.children) == null ? void 0 : _a.forEach((c) => remapKeyframeTimes(c, start, stretch));
4548
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => remapKeyframeTimes(c, start, stretch));
4354
4549
  }
4355
4550
  function remapKeyframeTimesOnly(node, start, stretch) {
4356
4551
  const remap2 = (kfs) => {
@@ -4529,10 +4724,10 @@ var PixodeskAnimator = (() => {
4529
4724
  function estimateTextAdvance(node) {
4530
4725
  let chars = 0, maxFont = 16;
4531
4726
  const walk = (el) => {
4532
- var _a, _b;
4533
- const fs = parseFloat(String((_a = el.fontSize) != null ? _a : "")) || 0;
4727
+ var _a2;
4728
+ const fs = parseFloat(String((_a2 = el.fontSize) != null ? _a2 : "")) || 0;
4534
4729
  if (fs) maxFont = Math.max(maxFont, fs);
4535
- const t = (_b = el.text) != null ? _b : el.textContent;
4730
+ const t = el.textContent;
4536
4731
  if (typeof t === "string") chars += t.length;
4537
4732
  if (el.children) for (const c of el.children) walk(c);
4538
4733
  };
@@ -4554,14 +4749,14 @@ var PixodeskAnimator = (() => {
4554
4749
  return out;
4555
4750
  }
4556
4751
  function extendedPathForBrowser(pathD, opts) {
4557
- var _a;
4752
+ var _a2;
4558
4753
  if (opts.pathOverflow === "clip") return { d: pathD, startShift: 0 };
4559
4754
  const sampler = createPathSampler(pathD);
4560
4755
  if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };
4561
4756
  const L = sampler.totalLength;
4562
4757
  const margin = EXTEND_MARGIN_FRAC * L;
4563
4758
  const so = numRange(opts.startOffset);
4564
- const runWidth = numRange(opts.textLength).max || ((_a = opts.advance) != null ? _a : 0);
4759
+ const runWidth = numRange(opts.textLength).max || ((_a2 = opts.advance) != null ? _a2 : 0);
4565
4760
  const startOverflow = Math.max(0, -so.min);
4566
4761
  const endOverflow = Math.max(0, so.max + runWidth - L);
4567
4762
  const startExt = startOverflow > 0 ? startOverflow + margin : 0;
@@ -4582,7 +4777,7 @@ var PixodeskAnimator = (() => {
4582
4777
  return { d, startShift: startExt };
4583
4778
  }
4584
4779
  function applyTextPathEffect(node, fx, ctx) {
4585
- var _a;
4780
+ var _a2;
4586
4781
  if (!fx || typeof fx.pathData !== "string" || !fx.pathData) return node;
4587
4782
  const pathId = genId(ctx, "tpath");
4588
4783
  const { d, startShift } = extendedPathForBrowser(fx.pathData, {
@@ -4595,7 +4790,7 @@ var PixodeskAnimator = (() => {
4595
4790
  const textPath = {
4596
4791
  type: "textPath",
4597
4792
  href: "#" + pathId,
4598
- children: (_a = node.children) != null ? _a : []
4793
+ children: (_a2 = node.children) != null ? _a2 : []
4599
4794
  };
4600
4795
  if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
4601
4796
  if (fx.method !== void 0) textPath.method = fx.method;
@@ -4687,7 +4882,6 @@ var PixodeskAnimator = (() => {
4687
4882
  "stroke",
4688
4883
  "strokeWidth",
4689
4884
  "effects",
4690
- TEXT_ATTR,
4691
4885
  TEXT_CONTENT_ATTR,
4692
4886
  "xml:space"
4693
4887
  ];
@@ -4725,15 +4919,15 @@ var PixodeskAnimator = (() => {
4725
4919
  return out;
4726
4920
  }
4727
4921
  function resolveStyle2(node, parent) {
4728
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4922
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4729
4923
  const isTextRoot = node.type === "text";
4730
4924
  const nodeStyle = node.style;
4731
4925
  const own = (key) => {
4732
- var _a2;
4733
- return isTextRoot ? void 0 : (_a2 = node[key]) != null ? _a2 : nodeStyle == null ? void 0 : nodeStyle[key];
4926
+ var _a3;
4927
+ return isTextRoot ? void 0 : (_a3 = node[key]) != null ? _a3 : nodeStyle == null ? void 0 : nodeStyle[key];
4734
4928
  };
4735
4929
  const res = {
4736
- fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
4930
+ fontFamily: (_a2 = str(node.fontFamily)) != null ? _a2 : parent.fontFamily,
4737
4931
  fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
4738
4932
  fill: (_c = node.fill) != null ? _c : parent.fill,
4739
4933
  stroke: (_d = node.stroke) != null ? _d : parent.stroke,
@@ -4750,10 +4944,10 @@ var PixodeskAnimator = (() => {
4750
4944
  return res;
4751
4945
  }
4752
4946
  function rootStyleOf(node) {
4753
- var _a, _b, _c;
4947
+ var _a2, _b, _c;
4754
4948
  return {
4755
4949
  fontFamily: str(node.fontFamily),
4756
- fontSize: (_a = parseLen(node.fontSize)) != null ? _a : DEFAULT_FONT_SIZE,
4950
+ fontSize: (_a2 = parseLen(node.fontSize)) != null ? _a2 : DEFAULT_FONT_SIZE,
4757
4951
  fill: node.fill,
4758
4952
  stroke: node.stroke,
4759
4953
  strokeWidth: node.strokeWidth,
@@ -4774,9 +4968,9 @@ var PixodeskAnimator = (() => {
4774
4968
  return p;
4775
4969
  }
4776
4970
  function glyphFontFor(s, glyphs, soleFont, warnings) {
4777
- var _a;
4971
+ var _a2;
4778
4972
  const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;
4779
- if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a = s.fontFamily) != null ? _a : "") + '"');
4973
+ if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a2 = s.fontFamily) != null ? _a2 : "") + '"');
4780
4974
  return gf;
4781
4975
  }
4782
4976
  function soleFontOf(glyphs) {
@@ -4797,26 +4991,26 @@ var PixodeskAnimator = (() => {
4797
4991
  const ix0 = x0 + t, ix1 = x1 - t, iyb = -t, iyt = y1 + t;
4798
4992
  return outer + "M" + ix0 + " " + iyb + "L" + ix0 + " " + iyt + "L" + ix1 + " " + iyt + "L" + ix1 + " " + iyb + "Z";
4799
4993
  }
4800
- function materialiseGlyphTextHorizontal(node, opts) {
4801
- var _a, _b, _c, _d;
4994
+ function materializeGlyphTextHorizontal(node, opts) {
4995
+ var _a2, _b, _c;
4802
4996
  const { glyphs, create = jsonElementFactory, warnings } = opts;
4803
4997
  const soleFont = soleFontOf(glyphs);
4804
- const pen = { x: (_a = parseLen(node.x)) != null ? _a : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
4998
+ const pen = { x: (_a2 = parseLen(node.x)) != null ? _a2 : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
4805
4999
  const placements = [];
4806
5000
  const lines = [{ start: pen.x, end: pen.x }];
4807
5001
  let line = 0;
4808
5002
  const renderChars = (content, s) => {
4809
- var _a2;
5003
+ var _a3;
4810
5004
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4811
5005
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4812
5006
  const scale = s.fontSize / upm;
4813
- const ascentEm = (_a2 = gf == null ? void 0 : gf.ascent) != null ? _a2 : 0.9 * upm;
5007
+ const ascentEm = (_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm;
4814
5008
  const paint = paintOf(s);
4815
5009
  for (let i = 0; i < content.length; i++) {
4816
5010
  const ch = content.charAt(i);
4817
5011
  const g = gf == null ? void 0 : gf.glyphs[ch];
4818
- if (g && g.d) {
4819
- placements.push({ glyphD: g.d, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
5012
+ if (g && g.pathData) {
5013
+ placements.push({ glyphD: g.pathData, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
4820
5014
  pen.x += g.width * scale;
4821
5015
  } else if (/\S/.test(ch)) {
4822
5016
  const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
@@ -4830,7 +5024,7 @@ var PixodeskAnimator = (() => {
4830
5024
  }
4831
5025
  };
4832
5026
  const walk = (el, parentStyle) => {
4833
- var _a2, _b2, _c2, _d2;
5027
+ var _a3, _b2, _c2;
4834
5028
  const s = resolveStyle2(el, parentStyle);
4835
5029
  const x = parseLen(el.x);
4836
5030
  const y = parseLen(el.y);
@@ -4840,16 +5034,16 @@ var PixodeskAnimator = (() => {
4840
5034
  lines.push({ start: pen.x, end: pen.x });
4841
5035
  }
4842
5036
  if (y !== void 0) pen.y = y;
4843
- pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
5037
+ pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
4844
5038
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4845
- const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
4846
- if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
5039
+ const content = str(el[TEXT_CONTENT_ATTR]);
5040
+ if (content && !((_c2 = el.children) == null ? void 0 : _c2.length)) renderChars(content, s);
4847
5041
  if (el.children) for (const ch of el.children) walk(ch, s);
4848
5042
  };
4849
5043
  const rootStyle = rootStyleOf(node);
4850
5044
  if (node.children) for (const ch of node.children) walk(ch, rootStyle);
4851
- const rootContent = (_c = str(node[TEXT_CONTENT_ATTR])) != null ? _c : str(node[TEXT_ATTR]);
4852
- if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
5045
+ const rootContent = str(node[TEXT_CONTENT_ATTR]);
5046
+ if (rootContent && !((_c = node.children) == null ? void 0 : _c.length)) renderChars(rootContent, rootStyle);
4853
5047
  const anchor = str(node.textAnchor);
4854
5048
  if (anchor === "middle" || anchor === "end") {
4855
5049
  for (const p of placements) {
@@ -4864,21 +5058,21 @@ var PixodeskAnimator = (() => {
4864
5058
  const cells = [];
4865
5059
  let adv = 0;
4866
5060
  const walk = (el, parentStyle) => {
4867
- var _a, _b, _c;
5061
+ var _a2, _b;
4868
5062
  const s = resolveStyle2(el, parentStyle);
4869
- const content = (_a = str(el[TEXT_CONTENT_ATTR])) != null ? _a : str(el[TEXT_ATTR]);
4870
- if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
5063
+ const content = str(el[TEXT_CONTENT_ATTR]);
5064
+ if (content && !((_a2 = el.children) == null ? void 0 : _a2.length)) {
4871
5065
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4872
5066
  if (gf) {
4873
5067
  const scale = s.fontSize / gf.unitsPerEm;
4874
- const ascentEm = (_c = gf.ascent) != null ? _c : 0.9 * gf.unitsPerEm;
5068
+ const ascentEm = (_b = gf.ascent) != null ? _b : 0.9 * gf.unitsPerEm;
4875
5069
  const paint = paintOf(s);
4876
5070
  for (let i = 0; i < content.length; i++) {
4877
5071
  const ch = content.charAt(i);
4878
5072
  const g = gf.glyphs[ch];
4879
- if (g && g.d) {
5073
+ if (g && g.pathData) {
4880
5074
  const glyphAdv = g.width * scale;
4881
- cells.push({ glyphD: g.d, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
5075
+ cells.push({ glyphD: g.pathData, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
4882
5076
  adv += glyphAdv;
4883
5077
  } else if (/\S/.test(ch)) {
4884
5078
  const wEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;
@@ -4903,13 +5097,13 @@ var PixodeskAnimator = (() => {
4903
5097
  return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw - perp * sin, y - scale * sin * hw + perp * cos];
4904
5098
  }
4905
5099
  function alongPathNodeOffsets(node) {
4906
- var _a, _b, _c;
5100
+ var _a2, _b, _c;
4907
5101
  return {
4908
- along: ((_a = parseLen(node.x)) != null ? _a : 0) + ((_b = parseLen(node.dx)) != null ? _b : 0),
5102
+ along: ((_a2 = parseLen(node.x)) != null ? _a2 : 0) + ((_b = parseLen(node.dx)) != null ? _b : 0),
4909
5103
  perp: (_c = parseLen(node.dy)) != null ? _c : 0
4910
5104
  };
4911
5105
  }
4912
- function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
5106
+ function materializeGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
4913
5107
  const { glyphs, create = jsonElementFactory, warnings } = opts;
4914
5108
  const sampler = pathD ? createPathSampler(pathD) : null;
4915
5109
  if (!sampler) {
@@ -4945,7 +5139,7 @@ var PixodeskAnimator = (() => {
4945
5139
  return toGroup(node, buildPaths(placements, create, warnings), create);
4946
5140
  }
4947
5141
  function numTrackOf(raw) {
4948
- var _a;
5142
+ var _a2;
4949
5143
  const r = readAnimatable(raw);
4950
5144
  if (r.kind === "animated" /* Animated */ && r.keyframes.length >= 2) {
4951
5145
  const kfs = [...r.keyframes].sort((k1, k2) => (Number(k1.time) || 0) - (Number(k2.time) || 0));
@@ -4968,7 +5162,7 @@ var PixodeskAnimator = (() => {
4968
5162
  }
4969
5163
  };
4970
5164
  }
4971
- 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;
5165
+ const v = r.kind === "animated" /* Animated */ ? Number((_a2 = r.keyframes[0]) == null ? void 0 : _a2.value) || 0 : r.kind === "static" /* Static */ ? Number(r.value) || 0 : 0;
4972
5166
  return { animated: false, times: [], at: () => v };
4973
5167
  }
4974
5168
  function mergeTrackTimes(a, b) {
@@ -4988,8 +5182,8 @@ var PixodeskAnimator = (() => {
4988
5182
  const onPath = (dist) => dist >= 0 && dist <= sampler.totalLength;
4989
5183
  const out = [];
4990
5184
  for (const c of cells) {
4991
- const centred = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
4992
- const d = transformPathData(c.glyphD, centred);
5185
+ const centered = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
5186
+ const d = transformPathData(c.glyphD, centered);
4993
5187
  const sampleKf = (dist, time) => {
4994
5188
  const { x, y, angle } = sampler.sampleAtDistance(dist);
4995
5189
  const cos = Math.cos(angle), sin = Math.sin(angle);
@@ -5087,14 +5281,14 @@ var PixodeskAnimator = (() => {
5087
5281
  ctx.warnings.push("textGlyphs: no definitions.fonts \u2014 left as native <text>");
5088
5282
  return node;
5089
5283
  }
5090
- return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
5284
+ return materializeGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
5091
5285
  }
5092
5286
  function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pathOverflow) {
5093
5287
  if (!ctx.glyphs) {
5094
5288
  ctx.warnings.push("textGlyphs: no definitions.fonts");
5095
5289
  return null;
5096
5290
  }
5097
- return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
5291
+ return materializeGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
5098
5292
  }
5099
5293
 
5100
5294
  // ../svg-animator-core/src/effects/stroke/strokeTrimEffect.ts
@@ -5397,20 +5591,20 @@ var PixodeskAnimator = (() => {
5397
5591
  return total;
5398
5592
  }
5399
5593
  function segmentLength(path, from, to) {
5400
- var _a, _b, _c, _d;
5594
+ var _a2, _b, _c, _d;
5401
5595
  const v = path.v;
5402
5596
  const p0 = v[from];
5403
5597
  const p3 = v[to];
5404
- const p1 = (_b = (_a = path.o) == null ? void 0 : _a[from]) != null ? _b : p0;
5598
+ const p1 = (_b = (_a2 = path.o) == null ? void 0 : _a2[from]) != null ? _b : p0;
5405
5599
  const p2 = (_d = (_c = path.i) == null ? void 0 : _c[to]) != null ? _d : p3;
5406
5600
  const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);
5407
5601
  return lut.ds[lut.ds.length - 1];
5408
5602
  }
5409
5603
  var ARC_KAPPA = 0.5522847498307936;
5410
5604
  function shapeToPathD(node) {
5411
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5605
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5412
5606
  if (node.type === "rect") {
5413
- const x = Number((_a = node.x) != null ? _a : 0), y = Number((_b = node.y) != null ? _b : 0);
5607
+ const x = Number((_a2 = node.x) != null ? _a2 : 0), y = Number((_b = node.y) != null ? _b : 0);
5414
5608
  const w = Number((_c = node.width) != null ? _c : 0), h = Number((_d = node.height) != null ? _d : 0);
5415
5609
  return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
5416
5610
  }
@@ -5428,7 +5622,7 @@ var PixodeskAnimator = (() => {
5428
5622
 
5429
5623
  // ../svg-animator-core/src/effects/PlayerEffectsUtil.ts
5430
5624
  function applyPlayerEffects(root) {
5431
- var _a, _b;
5625
+ var _a2, _b;
5432
5626
  const ctx = {
5433
5627
  defs: [],
5434
5628
  warnings: [],
@@ -5439,7 +5633,7 @@ var PixodeskAnimator = (() => {
5439
5633
  maskAncestorChains: /* @__PURE__ */ new Map(),
5440
5634
  // Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
5441
5635
  // waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
5442
- engine: resolveTimelineEngine((_a = getAnimatorConfig(root)) == null ? void 0 : _a.engine),
5636
+ engine: resolveTimelineEngine((_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.engine),
5443
5637
  glyphs: (_b = getDefs(root)) == null ? void 0 : _b.fonts
5444
5638
  };
5445
5639
  const working = clone(root);
@@ -5496,7 +5690,7 @@ var PixodeskAnimator = (() => {
5496
5690
  return node;
5497
5691
  }
5498
5692
 
5499
- // ../svg-animator-core/src/materialise/PxOffsetPathMaterialiser.ts
5693
+ // ../svg-animator-core/src/materialize/PxOffsetPathMaterializer.ts
5500
5694
  function cubicAt(p0, c1, c2, p1, t) {
5501
5695
  const u = 1 - t;
5502
5696
  const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
@@ -5520,7 +5714,7 @@ var PixodeskAnimator = (() => {
5520
5714
  return Object.is(r, -0) ? "0" : String(r);
5521
5715
  };
5522
5716
  function buildOffsetPath(propAnim) {
5523
- var _a, _b, _c;
5717
+ var _a2, _b, _c;
5524
5718
  if (propAnim.alongPathMode !== "offsetPath") return void 0;
5525
5719
  const kfs = propAnim.keyframes;
5526
5720
  if (!kfs || kfs.length < 2) return void 0;
@@ -5533,7 +5727,7 @@ var PixodeskAnimator = (() => {
5533
5727
  if (!tr || tr.length < 2) return void 0;
5534
5728
  const parts = Object.keys(v);
5535
5729
  if (parts.some((p) => p !== "translate" && p !== "origin")) return void 0;
5536
- const o = (_a = v == null ? void 0 : v.origin) != null ? _a : [0, 0];
5730
+ const o = (_a2 = v == null ? void 0 : v.origin) != null ? _a2 : [0, 0];
5537
5731
  if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
5538
5732
  points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
5539
5733
  }
@@ -5562,9 +5756,9 @@ var PixodeskAnimator = (() => {
5562
5756
  }
5563
5757
  return { pathStr: d, distanceKfs, autoOrient: !!propAnim.autoOrient, anchor };
5564
5758
  }
5565
- function materialiseOffsetPathsInTree(root) {
5759
+ function materializeOffsetPathsInTree(root) {
5566
5760
  const walk = (node) => {
5567
- var _a;
5761
+ var _a2;
5568
5762
  let out = node;
5569
5763
  const anim = node.animate;
5570
5764
  const transform = anim == null ? void 0 : anim["transform"];
@@ -5597,7 +5791,7 @@ var PixodeskAnimator = (() => {
5597
5791
  else delete out.transform;
5598
5792
  }
5599
5793
  }
5600
- if ((_a = out.children) == null ? void 0 : _a.length) {
5794
+ if ((_a2 = out.children) == null ? void 0 : _a2.length) {
5601
5795
  const children = out.children.map(walk);
5602
5796
  if (children.some((c, i) => c !== out.children[i])) out = __spreadProps(__spreadValues({}, out), { children });
5603
5797
  }
@@ -5606,16 +5800,16 @@ var PixodeskAnimator = (() => {
5606
5800
  return walk(root);
5607
5801
  }
5608
5802
 
5609
- // ../svg-animator-core/src/materialise/PxAnimatorMaterialiseAll.ts
5610
- function materialiseAllInTree(doc, engine, opts) {
5611
- var _a, _b;
5803
+ // ../svg-animator-core/src/materialize/PxAnimatorMaterializeAll.ts
5804
+ function materializeAllInTree(doc, engine, opts) {
5805
+ var _a2, _b;
5612
5806
  let root = applyPlayerEffects(doc).root;
5613
- root = materialiseOffsetPathsInTree(root);
5614
- const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
5615
- root = materialiseInternalLoopsInTree(root, duration);
5807
+ root = materializeOffsetPathsInTree(root);
5808
+ const duration = (_b = (_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.duration) != null ? _b : DEFAULT_DURATION_MS;
5809
+ root = materializeInternalLoopsInTree(root, duration);
5616
5810
  if (engine === PxTimelineEngine.native) {
5617
- root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
5618
- root = materialiseAnimatedUseInstances(root);
5811
+ root = materializeMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
5812
+ root = materializeAnimatedUseInstances(root);
5619
5813
  root = pruneUnreferencedDefs(root);
5620
5814
  }
5621
5815
  return root;
@@ -5623,9 +5817,9 @@ var PixodeskAnimator = (() => {
5623
5817
  function pruneUnreferencedDefs(root) {
5624
5818
  const stripHash3 = (h) => h.startsWith("#") ? h.slice(1) : h;
5625
5819
  const walk = (n, fn) => {
5626
- var _a;
5820
+ var _a2;
5627
5821
  fn(n);
5628
- (_a = n.children) == null ? void 0 : _a.forEach((c) => walk(c, fn));
5822
+ (_a2 = n.children) == null ? void 0 : _a2.forEach((c) => walk(c, fn));
5629
5823
  };
5630
5824
  let changed = true;
5631
5825
  while (changed) {
@@ -5650,6 +5844,40 @@ var PixodeskAnimator = (() => {
5650
5844
  return root;
5651
5845
  }
5652
5846
 
5847
+ // ../svg-animator-core/src/playback/PxPlaybackTime.ts
5848
+ var PX_RATE_REJECTED = "setPlaybackRate: rate must be finite and non-zero";
5849
+ function isValidPlaybackRate(rate) {
5850
+ return Number.isFinite(rate) && rate !== 0;
5851
+ }
5852
+ function seekCeilingMs(durationMs, iterations) {
5853
+ if (!(durationMs > 0)) return 0;
5854
+ if (iterations === Infinity) return Infinity;
5855
+ return durationMs * (iterations > 0 ? iterations : 1);
5856
+ }
5857
+ function progressSpanMs(durationMs, iterations) {
5858
+ if (!(durationMs > 0)) return 0;
5859
+ if (iterations === Infinity) return durationMs;
5860
+ return durationMs * (iterations > 0 ? iterations : 1);
5861
+ }
5862
+ function clampSeekMs(timeMs, ceilingMs) {
5863
+ if (Number.isNaN(timeMs) || timeMs < 0) return 0;
5864
+ if (Number.isFinite(ceilingMs)) return timeMs > ceilingMs ? ceilingMs : timeMs;
5865
+ return Number.isFinite(timeMs) ? timeMs : 0;
5866
+ }
5867
+ function timeToProgress(timeMs, durationMs, iterations) {
5868
+ const span = progressSpanMs(durationMs, iterations);
5869
+ if (!(span > 0) || !Number.isFinite(timeMs)) return 0;
5870
+ if (timeMs <= 0) return 0;
5871
+ if (iterations === Infinity) return timeMs % span / span;
5872
+ return timeMs >= span ? 1 : timeMs / span;
5873
+ }
5874
+ function progressToTimeMs(progress, durationMs, iterations) {
5875
+ const span = progressSpanMs(durationMs, iterations);
5876
+ if (!(span > 0) || !Number.isFinite(progress)) return 0;
5877
+ if (progress <= 0) return 0;
5878
+ return progress >= 1 ? span : progress * span;
5879
+ }
5880
+
5653
5881
  // ../svg-animator-core/src/playback/PxFrameLoop.ts
5654
5882
  function requestFrame(cb) {
5655
5883
  const g = globalThis;
@@ -5665,9 +5893,9 @@ var PixodeskAnimator = (() => {
5665
5893
  g.clearTimeout(handle);
5666
5894
  }
5667
5895
  function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5668
- var _a;
5896
+ var _a2;
5669
5897
  const config = getAnimatorConfig(doc) || {};
5670
- const bindings = getNormalisedBindings(doc, PxTimelineEngine.js);
5898
+ const bindings = getNormalizedBindings(doc, PxTimelineEngine.js);
5671
5899
  const _iterations = config.iterations;
5672
5900
  let iterations = 1;
5673
5901
  if (typeof _iterations === "number") iterations = _iterations || 1;
@@ -5676,7 +5904,7 @@ var PixodeskAnimator = (() => {
5676
5904
  const duration = +(config.duration || DEFAULT_DURATION_MS);
5677
5905
  const totalDuration = duration && iterations ? duration * (iterations === Infinity ? Infinity : iterations) : duration ? (iterations != null ? iterations : 1) * duration : 0;
5678
5906
  const direction = config.direction || "normal";
5679
- const fill = (_a = config.fill) != null ? _a : "forwards";
5907
+ const fill = (_a2 = config.fill) != null ? _a2 : "forwards";
5680
5908
  const fillsForwards = fill === "forwards" || fill === "both";
5681
5909
  const fillsBackwards = fill === "backwards" || fill === "both";
5682
5910
  let timerId = null;
@@ -5738,7 +5966,7 @@ var PixodeskAnimator = (() => {
5738
5966
  }
5739
5967
  }
5740
5968
  const tick = () => {
5741
- var _a2, _b;
5969
+ var _a3, _b;
5742
5970
  if (!adapter.isConnected()) {
5743
5971
  pauseAnim();
5744
5972
  return;
@@ -5754,7 +5982,7 @@ var PixodeskAnimator = (() => {
5754
5982
  renderFrame(0);
5755
5983
  if (!finishCalled) {
5756
5984
  finishCalled = true;
5757
- (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
5985
+ (_a3 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
5758
5986
  }
5759
5987
  return;
5760
5988
  }
@@ -5846,17 +6074,17 @@ var PixodeskAnimator = (() => {
5846
6074
  }
5847
6075
  };
5848
6076
  const cancelAnim = () => {
5849
- var _a2;
6077
+ var _a3;
5850
6078
  pauseAnim();
5851
6079
  timeBeforeLastStartMs = 0;
5852
6080
  lastStartedTs = 0;
5853
6081
  playing = false;
5854
6082
  finishCalled = false;
5855
6083
  renderFrame(timeBeforeLastStartMs);
5856
- (_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
6084
+ (_a3 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a3.call(callbacks);
5857
6085
  };
5858
6086
  const finishAnim = (callOnFinish = true) => {
5859
- var _a2;
6087
+ var _a3;
5860
6088
  if (Number.isFinite(totalDuration)) {
5861
6089
  timeBeforeLastStartMs = totalDuration;
5862
6090
  } else {
@@ -5871,7 +6099,7 @@ var PixodeskAnimator = (() => {
5871
6099
  renderFrame(fillsForwards ? timeBeforeLastStartMs : 0);
5872
6100
  if (callOnFinish && !finishCalled) {
5873
6101
  finishCalled = true;
5874
- (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
6102
+ (_a3 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
5875
6103
  }
5876
6104
  };
5877
6105
  const api = {
@@ -5881,14 +6109,14 @@ var PixodeskAnimator = (() => {
5881
6109
  return _isPlaying();
5882
6110
  },
5883
6111
  "play": () => {
5884
- var _a2;
6112
+ var _a3;
5885
6113
  startAnim();
5886
- (_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
6114
+ (_a3 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a3.call(callbacks);
5887
6115
  },
5888
6116
  "pause": () => {
5889
- var _a2;
6117
+ var _a3;
5890
6118
  pauseAnim();
5891
- (_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
6119
+ (_a3 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a3.call(callbacks);
5892
6120
  },
5893
6121
  "cancel": () => {
5894
6122
  cancelAnim();
@@ -5897,8 +6125,8 @@ var PixodeskAnimator = (() => {
5897
6125
  finishAnim(true);
5898
6126
  },
5899
6127
  "setPlaybackRate": (rate) => {
5900
- if (!isFinite(rate) || rate === 0) {
5901
- console.warn("setPlaybackRate: rate must be finite and non-zero");
6128
+ if (!isValidPlaybackRate(rate)) {
6129
+ console.warn(PX_RATE_REJECTED);
5902
6130
  return;
5903
6131
  }
5904
6132
  let current = getRawAnimTime();
@@ -5912,22 +6140,70 @@ var PixodeskAnimator = (() => {
5912
6140
  return getAnimCurrentTime();
5913
6141
  },
5914
6142
  "setCurrentTime": (newTime) => {
5915
- if (newTime < 0) newTime = 0;
5916
- if (Number.isFinite(totalDuration) && newTime > totalDuration) newTime = totalDuration;
6143
+ newTime = clampSeekMs(newTime, totalDuration);
5917
6144
  timeBeforeLastStartMs = newTime;
5918
6145
  if (playing) lastStartedTs = Date.now();
5919
6146
  if (!Number.isFinite(totalDuration) || newTime < totalDuration) finishCalled = false;
5920
6147
  renderFrame(getAnimCurrentTime());
5921
6148
  },
6149
+ "getCurrentProgress": () => timeToProgress(getAnimCurrentTime(), duration, iterations),
6150
+ "setCurrentProgress": (progress) => {
6151
+ api.setCurrentTime(progressToTimeMs(progress, duration, iterations));
6152
+ },
5922
6153
  "destroy": () => {
5923
- var _a2;
6154
+ var _a3;
5924
6155
  api.cancel();
5925
- (_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
6156
+ (_a3 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
5926
6157
  }
5927
6158
  };
5928
6159
  return api;
5929
6160
  }
5930
6161
 
6162
+ // ../svg-animator-core/src/playback/PxDiagnostics.ts
6163
+ var PxDiagnosticKind = {
6164
+ /** The document is wrong — regenerate or repair the file. */
6165
+ document: "document",
6166
+ /** The page or app cannot provide what the document asks for — fix the mount. */
6167
+ host: "host",
6168
+ /** The platform cannot do it and the player degraded — usually nothing to fix. */
6169
+ platform: "platform",
6170
+ /** The call is wrong or self-contradictory — fix the options or props you passed. */
6171
+ usage: "usage",
6172
+ /** The player failed where it did not expect to — report it to us. */
6173
+ internal: "internal"
6174
+ };
6175
+ function asError(error) {
6176
+ return typeof error === "string" ? new Error(error) : error;
6177
+ }
6178
+ function isSilenced(silent, kind) {
6179
+ if (!silent) return false;
6180
+ return silent === true || silent.includes(kind);
6181
+ }
6182
+ function createDiagnostics(config, prefix) {
6183
+ const tag = prefix ? prefix + " " : "";
6184
+ return {
6185
+ warn: (kind, message, detail) => {
6186
+ if (config == null ? void 0 : config.onWarn) {
6187
+ config.onWarn({ kind, message, detail });
6188
+ return;
6189
+ }
6190
+ if (isSilenced(config == null ? void 0 : config.silent, kind)) return;
6191
+ const line = tag + kind + ": " + message;
6192
+ if (detail === void 0) console.warn(line);
6193
+ else console.warn(line, detail);
6194
+ },
6195
+ error: (kind, error) => {
6196
+ const err = asError(error);
6197
+ if (config == null ? void 0 : config.onError) {
6198
+ config.onError({ kind, message: err.message, error: err });
6199
+ return;
6200
+ }
6201
+ if (isSilenced(config == null ? void 0 : config.silent, kind)) return;
6202
+ console.error(tag + kind + ": " + err.message);
6203
+ }
6204
+ };
6205
+ }
6206
+
5931
6207
  // ../svg-animator-core/src/playback/PxAnimatorConfigPatch.ts
5932
6208
  var FLAT_ONLY_KEYS = [
5933
6209
  "timelineSource",
@@ -5991,32 +6267,30 @@ var PixodeskAnimator = (() => {
5991
6267
  }
5992
6268
  return merged;
5993
6269
  }
5994
- function foldAnimatorConfigShortcuts(config, shortcuts) {
6270
+ function foldTimelineOverride(timeline, shortcuts) {
5995
6271
  let base;
5996
- if (typeof config === "string") {
6272
+ if (typeof timeline === "string") {
5997
6273
  try {
5998
- base = JSON.parse(config);
6274
+ base = JSON.parse(timeline);
5999
6275
  } catch (e) {
6000
- console.warn("animator config: not valid JSON \u2014 ignored", e);
6276
+ console.warn("timeline override: not valid JSON \u2014 ignored", e);
6001
6277
  base = void 0;
6002
6278
  }
6003
6279
  } else {
6004
- base = config != null ? config : void 0;
6280
+ base = timeline != null ? timeline : void 0;
6005
6281
  }
6006
6282
  const { duration, delay, iterations, startOn } = shortcuts;
6007
6283
  if (duration === void 0 && delay === void 0 && iterations === void 0 && startOn === void 0) {
6008
- return base;
6284
+ return base === void 0 ? void 0 : { timeline: base };
6009
6285
  }
6010
6286
  const out = isPlainObject(base) ? __spreadValues({}, base) : {};
6011
- const timeline = __spreadValues({}, out.timeline);
6012
- if (duration !== void 0) timeline.duration = duration;
6013
- if (delay !== void 0) timeline.delay = delay;
6014
- if (iterations !== void 0) timeline.iterations = iterations;
6287
+ if (duration !== void 0) out.duration = duration;
6288
+ if (delay !== void 0) out.delay = delay;
6289
+ if (iterations !== void 0) out.iterations = iterations;
6015
6290
  if (startOn !== void 0) {
6016
- timeline.trigger = __spreadProps(__spreadValues({}, timeline.trigger), { startOn });
6291
+ out.trigger = __spreadProps(__spreadValues({}, out.trigger), { startOn });
6017
6292
  }
6018
- out.timeline = timeline;
6019
- return out;
6293
+ return { timeline: out };
6020
6294
  }
6021
6295
  function mergeAnimatorConfig(base, patch) {
6022
6296
  const warnings = [];
@@ -6049,14 +6323,14 @@ var PixodeskAnimator = (() => {
6049
6323
  return { config: out, warnings };
6050
6324
  }
6051
6325
  function applyAnimatorConfig(doc, patch, opts) {
6052
- var _a, _b;
6326
+ var _a2, _b;
6053
6327
  const reset = !!(opts == null ? void 0 : opts.resetDefaults);
6054
6328
  if (!doc || (patch === void 0 || !reset && (patch === null || !isPlainObject(patch) || !Object.keys(patch).length))) {
6055
6329
  return { doc, warnings: [] };
6056
6330
  }
6057
6331
  const anyDoc = doc;
6058
6332
  const atRoot = isPlainObject(anyDoc.animator);
6059
- const atMeta = !atRoot && isPlainObject((_a = anyDoc.meta) == null ? void 0 : _a.animator);
6333
+ const atMeta = !atRoot && isPlainObject((_a2 = anyDoc.meta) == null ? void 0 : _a2.animator);
6060
6334
  const current = atRoot ? anyDoc.animator : atMeta ? anyDoc.meta.animator : void 0;
6061
6335
  const warnings = [];
6062
6336
  if (atRoot && isPlainObject((_b = anyDoc.meta) == null ? void 0 : _b.animator)) {
@@ -6084,26 +6358,12 @@ var PixodeskAnimator = (() => {
6084
6358
 
6085
6359
  // ../svg-animator-core/src/format/PxDocumentDiagnostic.ts
6086
6360
  var MAX_REPORTED = 6;
6087
- var LEGACY_FLAT_KEYS = [
6088
- ...PX_TIMELINE_SHARED_KEYS,
6089
- ...PX_TIME_ONLY_TIMELINE_KEYS,
6090
- "fill",
6091
- "resetOnFinish",
6092
- "timelineSource",
6093
- "scroll"
6094
- ];
6095
- var isLegacyFlatAnimatorKey = (w) => LEGACY_FLAT_KEYS.some((k) => w.indexOf("animator." + k + ":") >= 0);
6096
6361
  function diagnoseDocument(doc) {
6097
- let all;
6098
6362
  try {
6099
- all = validateDocument(doc);
6363
+ return { problems: validateDocument(doc) };
6100
6364
  } catch (e) {
6101
- return { problems: [], legacy: [] };
6365
+ return { problems: [] };
6102
6366
  }
6103
- const problems = [];
6104
- const legacy = [];
6105
- for (const w of all) (isLegacyFlatAnimatorKey(w) ? legacy : problems).push(w);
6106
- return { problems, legacy };
6107
6367
  }
6108
6368
  function reportDocumentDiagnostics(doc, where) {
6109
6369
  const { problems } = diagnoseDocument(doc);
@@ -6115,13 +6375,37 @@ var PixodeskAnimator = (() => {
6115
6375
  );
6116
6376
  }
6117
6377
 
6378
+ // src/shared/PxAnimatorCallbacks.ts
6379
+ function toEngineCallbacks(inline) {
6380
+ const { onPlay, onPause, onCancel, onFinish, onRemove, onStop, onWarn, onError, silent } = inline != null ? inline : {};
6381
+ const withStop = (own) => own || onStop ? () => {
6382
+ own == null ? void 0 : own();
6383
+ onStop == null ? void 0 : onStop();
6384
+ } : void 0;
6385
+ return {
6386
+ onPlay,
6387
+ onPause: withStop(onPause),
6388
+ onCancel: withStop(onCancel),
6389
+ onFinish: withStop(onFinish),
6390
+ onRemove: withStop(onRemove),
6391
+ onWarn,
6392
+ onError,
6393
+ silent
6394
+ };
6395
+ }
6396
+
6118
6397
  // src/triggers/PxAnimatorTriggers.ts
6119
- function setupAnimationTriggers(api, config) {
6120
- const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
6398
+ function setupAnimationTriggers(api, config, diag) {
6399
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6400
+ const cleanups = [];
6401
+ const dispose = () => {
6402
+ for (const undo of cleanups.splice(0)) undo();
6403
+ };
6404
+ const { startOn, outAction, scrollIntoViewThreshold } = resolveTrigger(config);
6121
6405
  const root = api.getRootElement();
6122
6406
  if (!root) {
6123
- console.warn("setupAnimationTriggers: No root element found for animation.");
6124
- return api;
6407
+ report.warn(PxDiagnosticKind.host, "setupAnimationTriggers: No root element found for animation.");
6408
+ return dispose;
6125
6409
  }
6126
6410
  let reversed = false;
6127
6411
  const start = () => {
@@ -6156,6 +6440,7 @@ var PixodeskAnimator = (() => {
6156
6440
  startHandler();
6157
6441
  } else {
6158
6442
  window.addEventListener("load", startHandler, { once: true });
6443
+ cleanups.push(() => window.removeEventListener("load", startHandler));
6159
6444
  }
6160
6445
  break;
6161
6446
  }
@@ -6170,6 +6455,10 @@ var PixodeskAnimator = (() => {
6170
6455
  };
6171
6456
  root.addEventListener("mouseenter", mouseOverHandler);
6172
6457
  root.addEventListener("mouseleave", mouseOutHandler);
6458
+ cleanups.push(() => {
6459
+ root.removeEventListener("mouseenter", mouseOverHandler);
6460
+ root.removeEventListener("mouseleave", mouseOutHandler);
6461
+ });
6173
6462
  break;
6174
6463
  }
6175
6464
  case "click": {
@@ -6181,16 +6470,17 @@ var PixodeskAnimator = (() => {
6181
6470
  }
6182
6471
  };
6183
6472
  root.addEventListener("click", clickHandler);
6473
+ cleanups.push(() => root.removeEventListener("click", clickHandler));
6184
6474
  break;
6185
6475
  }
6186
6476
  case "scrollIntoView": {
6187
6477
  const effectiveRatio = (entry) => {
6188
- var _a, _b;
6478
+ var _a2, _b;
6189
6479
  const target = entry.boundingClientRect;
6190
6480
  const visible = entry.intersectionRect;
6191
6481
  if (!(target == null ? void 0 : target.height) || !visible) return entry.intersectionRatio;
6192
6482
  const live = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : Infinity;
6193
- const declared = (_b = (_a = entry.rootBounds) == null ? void 0 : _a.height) != null ? _b : Infinity;
6483
+ const declared = (_b = (_a2 = entry.rootBounds) == null ? void 0 : _a2.height) != null ? _b : Infinity;
6194
6484
  const viewport = Math.min(live, declared);
6195
6485
  const denom = Math.min(target.height, Number.isFinite(viewport) ? viewport : target.height);
6196
6486
  return denom > 0 ? visible.height / denom : entry.intersectionRatio;
@@ -6212,12 +6502,13 @@ var PixodeskAnimator = (() => {
6212
6502
  { threshold: thresholdSteps }
6213
6503
  );
6214
6504
  observer.observe(root);
6505
+ cleanups.push(() => observer.disconnect());
6215
6506
  break;
6216
6507
  }
6217
6508
  case "programmatic":
6218
6509
  break;
6219
6510
  }
6220
- return api;
6511
+ return dispose;
6221
6512
  }
6222
6513
 
6223
6514
  // src/engines/PxAnimatorFrameLoop.ts
@@ -6225,35 +6516,41 @@ var PixodeskAnimator = (() => {
6225
6516
  return "#" + id;
6226
6517
  }
6227
6518
  function createFrameLoopAnimator(doc, adapter, callbacks, rootElement) {
6519
+ var _a2;
6228
6520
  const config = getAnimatorConfig(doc) || {};
6521
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
6229
6522
  if (!rootElement) {
6230
6523
  if (doc.id) {
6231
6524
  const rootSelector = getSelector(doc.id);
6232
6525
  rootElement = document.querySelector(rootSelector);
6233
- if (!rootElement) console.warn("createFrameLoopAnimator: No root element found for selector: ", rootSelector);
6526
+ if (!rootElement) diag.warn(PxDiagnosticKind.host, "createFrameLoopAnimator: No root element found for selector: " + rootSelector);
6234
6527
  } else {
6235
- console.warn("createFrameLoopAnimator: No root element provided");
6528
+ diag.warn(PxDiagnosticKind.host, "createFrameLoopAnimator: No root element provided");
6236
6529
  }
6237
6530
  }
6238
6531
  const basicApi = createBasicFrameLoopAnimator(
6239
6532
  doc,
6240
- adapter || createDomAdapter(rootElement),
6533
+ adapter || createDomAdapter(rootElement, diag),
6241
6534
  callbacks
6242
6535
  );
6243
6536
  const api = __spreadProps(__spreadValues({}, basicApi), {
6244
6537
  "getRootElement": () => rootElement || null
6245
6538
  });
6246
- if (config.trigger) {
6247
- if (isScrollTimeline(config)) {
6248
- console.warn("scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
6249
- } else {
6250
- setupAnimationTriggers(api, config.trigger);
6251
- }
6539
+ if (isScrollTimeline(config)) {
6540
+ if (config.trigger) diag.warn(PxDiagnosticKind.usage, "scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
6541
+ } else {
6542
+ const detachTriggers = setupAnimationTriggers(api, (_a2 = config.trigger) != null ? _a2 : {}, diag);
6543
+ const destroyEngine = api.destroy.bind(api);
6544
+ api.destroy = () => {
6545
+ detachTriggers();
6546
+ destroyEngine();
6547
+ };
6252
6548
  }
6253
6549
  return api;
6254
6550
  }
6255
- function createDomAdapter(rootElement) {
6551
+ function createDomAdapter(rootElement, diag) {
6256
6552
  const warnedSelectors = /* @__PURE__ */ new Set();
6553
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6257
6554
  const adapter = {
6258
6555
  isConnected: () => {
6259
6556
  if (!rootElement) return true;
@@ -6265,7 +6562,7 @@ var PixodeskAnimator = (() => {
6265
6562
  const elements = (rootElement == null ? void 0 : rootElement.querySelectorAll(selector)) || document.querySelectorAll(selector);
6266
6563
  if (elements.length === 0 && !warnedSelectors.has(selector)) {
6267
6564
  warnedSelectors.add(selector);
6268
- console.warn('setAttribute: No elements found for selector "' + selector + '"');
6565
+ report.warn(PxDiagnosticKind.host, 'setAttribute: No elements found for selector "' + selector + '"');
6269
6566
  }
6270
6567
  for (let i = 0; i < elements.length; i++) {
6271
6568
  const element = elements[i];
@@ -6290,7 +6587,7 @@ var PixodeskAnimator = (() => {
6290
6587
  };
6291
6588
  let cssValue;
6292
6589
  let cssKey = propName;
6293
- if (COLOUR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
6590
+ if (COLOR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
6294
6591
  cssValue = toRGBA(value);
6295
6592
  } else if (propName === "transform" && value !== null && typeof value === "object" && !Array.isArray(value)) {
6296
6593
  cssValue = composeTransformParts(value, { withUnits: true });
@@ -6317,11 +6614,11 @@ var PixodeskAnimator = (() => {
6317
6614
  return cssKf;
6318
6615
  }
6319
6616
  function clipKeyframesToDuration(propName, keyframes, duration) {
6320
- var _a, _b, _c, _d, _e;
6617
+ var _a2, _b, _c, _d, _e;
6321
6618
  const result = [];
6322
6619
  for (let i = 0; i < keyframes.length; i++) {
6323
6620
  const kf = keyframes[i];
6324
- const t = (_a = kf.t) != null ? _a : 0;
6621
+ const t = (_a2 = kf.t) != null ? _a2 : 0;
6325
6622
  if (t < 0) {
6326
6623
  const next = keyframes[i + 1];
6327
6624
  if (next && ((_b = next.t) != null ? _b : 0) >= 0) {
@@ -6350,7 +6647,7 @@ var PixodeskAnimator = (() => {
6350
6647
  return result;
6351
6648
  }
6352
6649
  function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6353
- var _a;
6650
+ var _a2;
6354
6651
  const result = /* @__PURE__ */ new Map();
6355
6652
  for (const [propName, propAnim] of Object.entries(animDef)) {
6356
6653
  const duration = config.duration || 1;
@@ -6358,7 +6655,7 @@ var PixodeskAnimator = (() => {
6358
6655
  const cssKeyframes = [];
6359
6656
  for (let i = 0; i < clippedKeyframes.length; i++) {
6360
6657
  const kf = clippedKeyframes[i];
6361
- const t = clamp(((_a = kf.t) != null ? _a : 0) / duration, 0, 1);
6658
+ const t = clamp(((_a2 = kf.t) != null ? _a2 : 0) / duration, 0, 1);
6362
6659
  const cssKf = createCssKf(kf, t, propName, unsupportedSet);
6363
6660
  if (i === 0 && (cssKf.offset || 0) > 0) {
6364
6661
  cssKeyframes.push(__spreadProps(__spreadValues({}, cssKf), { offset: 0 }));
@@ -6377,18 +6674,19 @@ var PixodeskAnimator = (() => {
6377
6674
  return result;
6378
6675
  }
6379
6676
  function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs, scrollTimeline) {
6380
- var _a;
6677
+ var _a2, _b;
6381
6678
  const config = getAnimatorConfig(doc) || {};
6679
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
6382
6680
  if (!rootElement) {
6383
6681
  if (doc.id) {
6384
6682
  const rootSelector = getSelector(doc.id);
6385
6683
  rootElement = document.querySelector(rootSelector);
6386
- if (!rootElement) console.warn("createFrameLoopAnimator: No root element found for selector: ", rootSelector);
6684
+ if (!rootElement) diag.warn(PxDiagnosticKind.host, "createWebApiAnimator: No root element found for selector: " + rootSelector);
6387
6685
  } else {
6388
- console.warn("createFrameLoopAnimator: No root element provided");
6686
+ diag.warn(PxDiagnosticKind.host, "createWebApiAnimator: No root element provided");
6389
6687
  }
6390
6688
  }
6391
- const bindings = getNormalisedBindings(doc, PxTimelineEngine.native);
6689
+ const bindings = getNormalizedBindings(doc, PxTimelineEngine.native);
6392
6690
  const animations = [];
6393
6691
  const _iterations = config.iterations;
6394
6692
  let iterations;
@@ -6398,18 +6696,18 @@ var PixodeskAnimator = (() => {
6398
6696
  let finishNotified = false;
6399
6697
  let removeCalled = false;
6400
6698
  if (!(bindings == null ? void 0 : bindings.length)) {
6401
- console.warn("createWebApiAnimator: No animation bindings defined");
6699
+ diag.warn(PxDiagnosticKind.document, "createWebApiAnimator: No animation bindings defined");
6402
6700
  }
6403
6701
  for (const binding of bindings || []) {
6404
6702
  const animDef = binding.animate;
6405
6703
  if (!animDef || typeof animDef !== "object" || Array.isArray(animDef)) {
6406
- console.warn("createWebApiAnimator: Empty or unresolved binding", binding);
6704
+ diag.warn(PxDiagnosticKind.document, "createWebApiAnimator: Empty or unresolved binding", binding);
6407
6705
  continue;
6408
6706
  }
6409
6707
  const selector = getSelector(binding.id);
6410
6708
  const elements = (rootElement == null ? void 0 : rootElement.querySelectorAll(selector)) || document.querySelectorAll(selector);
6411
6709
  if (elements.length === 0) {
6412
- console.warn('createWebApiAnimator: No elements found for selector "' + selector + '"');
6710
+ diag.warn(PxDiagnosticKind.host, 'createWebApiAnimator: No elements found for selector "' + selector + '"');
6413
6711
  }
6414
6712
  const keyframesMap = convertToWebApiKeyframes(animDef, unsupportedSet, config);
6415
6713
  const positiveDelay = config.delay && config.delay > 0 ? config.delay : void 0;
@@ -6425,7 +6723,7 @@ var PixodeskAnimator = (() => {
6425
6723
  // animation ends — consistent with Lottie and other animation runtimes.
6426
6724
  // Without this, seeking to the last frame reverts elements to their
6427
6725
  // pre-animation state (the Web Animations API "after" phase with fill:'none').
6428
- fill: (_a = config.fill) != null ? _a : "forwards",
6726
+ fill: (_a2 = config.fill) != null ? _a2 : "forwards",
6429
6727
  direction: config.direction,
6430
6728
  iterations
6431
6729
  };
@@ -6442,61 +6740,61 @@ var PixodeskAnimator = (() => {
6442
6740
  if (scrollTimeline.rangeEnd) a.rangeEnd = scrollTimeline.rangeEnd;
6443
6741
  }
6444
6742
  if (callbacks == null ? void 0 : callbacks.onFinish) anim.onfinish = () => {
6445
- var _a2;
6743
+ var _a3;
6446
6744
  if (finishNotified) return;
6447
6745
  finishNotified = true;
6448
- (_a2 = callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
6746
+ (_a3 = callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
6449
6747
  };
6450
6748
  if (callbacks == null ? void 0 : callbacks.onRemove) anim.onremove = () => {
6451
- var _a2;
6749
+ var _a3;
6452
6750
  if (removeCalled) return;
6453
6751
  removeCalled = true;
6454
- (_a2 = callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
6752
+ (_a3 = callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
6455
6753
  };
6456
6754
  if (seekPosition !== void 0) {
6457
6755
  anim.currentTime = seekPosition;
6458
6756
  }
6459
6757
  animations.push(anim);
6460
6758
  } catch (e) {
6461
- console.warn(e);
6759
+ diag.warn(PxDiagnosticKind.internal, "createWebApiAnimator: could not build the animation", e);
6462
6760
  }
6463
6761
  }
6464
6762
  }
6465
6763
  }
6466
6764
  }
6467
6765
  if (!forceEvenIfHasUnsupportedAttrs && unsupportedSet.size) {
6468
- console.warn("Unsupported CSS attrs: " + [...unsupportedSet].join(", "));
6766
+ diag.warn(PxDiagnosticKind.platform, "Unsupported CSS attrs: " + [...unsupportedSet].join(", "));
6469
6767
  return null;
6470
6768
  }
6471
6769
  const api = {
6472
6770
  "isReady": () => true,
6473
6771
  "getRootElement": () => rootElement || null,
6474
6772
  "isPlaying": () => {
6475
- var _a2;
6476
- return ((_a2 = animations[0]) == null ? void 0 : _a2.playState) === "running";
6773
+ var _a3;
6774
+ return ((_a3 = animations[0]) == null ? void 0 : _a3.playState) === "running";
6477
6775
  },
6478
6776
  "play": () => {
6479
- var _a2;
6777
+ var _a3;
6480
6778
  finishNotified = false;
6481
6779
  animations.forEach((a) => a.play());
6482
- (_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
6780
+ (_a3 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a3.call(callbacks);
6483
6781
  },
6484
6782
  "pause": () => {
6485
- var _a2;
6783
+ var _a3;
6486
6784
  animations.forEach((a) => a.pause());
6487
- (_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
6785
+ (_a3 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a3.call(callbacks);
6488
6786
  },
6489
6787
  "cancel": () => {
6490
- var _a2;
6788
+ var _a3;
6491
6789
  finishNotified = false;
6492
6790
  animations.forEach((a) => a.cancel());
6493
- (_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
6791
+ (_a3 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a3.call(callbacks);
6494
6792
  },
6495
6793
  "finish": () => {
6496
- var _a2;
6794
+ var _a3;
6497
6795
  for (const a of animations) {
6498
6796
  try {
6499
- if (((_a2 = a.effect) == null ? void 0 : _a2.getTiming().iterations) === Infinity) {
6797
+ if (((_a3 = a.effect) == null ? void 0 : _a3.getTiming().iterations) === Infinity) {
6500
6798
  a.effect.updateTiming({ iterations: 1 });
6501
6799
  a.finish();
6502
6800
  a.effect.updateTiming({ iterations: Infinity });
@@ -6509,36 +6807,55 @@ var PixodeskAnimator = (() => {
6509
6807
  }
6510
6808
  },
6511
6809
  "setPlaybackRate": (rate) => {
6810
+ if (!isValidPlaybackRate(rate)) {
6811
+ diag.warn(PxDiagnosticKind.usage, PX_RATE_REJECTED);
6812
+ return api;
6813
+ }
6512
6814
  animations.forEach((a) => a.playbackRate = rate);
6513
6815
  return api;
6514
6816
  },
6515
6817
  "getCurrentTime": () => {
6516
- var _a2, _b;
6517
- const res = (_b = (_a2 = animations[0]) == null ? void 0 : _a2.currentTime) != null ? _b : null;
6818
+ var _a3, _b2;
6819
+ const res = (_b2 = (_a3 = animations[0]) == null ? void 0 : _a3.currentTime) != null ? _b2 : null;
6518
6820
  return res !== null ? +res : null;
6519
6821
  },
6520
6822
  "setCurrentTime": (time) => {
6823
+ var _a3;
6824
+ const ceiling = seekCeilingMs((_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1);
6825
+ const seek = ceiling > 0 ? clampSeekMs(time, ceiling) : Math.max(0, time);
6521
6826
  finishNotified = false;
6522
6827
  animations.forEach((a) => {
6523
- a.currentTime = time;
6828
+ a.currentTime = seek;
6524
6829
  });
6525
6830
  },
6831
+ "getCurrentProgress": () => {
6832
+ var _a3;
6833
+ const t = api.getCurrentTime();
6834
+ return t === null ? null : timeToProgress(t, (_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1);
6835
+ },
6836
+ "setCurrentProgress": (progress) => {
6837
+ var _a3;
6838
+ api.setCurrentTime(progressToTimeMs(progress, (_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1));
6839
+ },
6526
6840
  "destroy": () => {
6527
- var _a2;
6841
+ var _a3;
6528
6842
  api.cancel();
6529
6843
  animations.splice(0, animations.length);
6530
6844
  if (!removeCalled) {
6531
6845
  removeCalled = true;
6532
- (_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
6846
+ (_a3 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
6533
6847
  }
6534
6848
  }
6535
6849
  };
6536
- if (config.trigger) {
6537
- if (config.timelineSource === "scroll") {
6538
- console.warn("scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
6539
- } else {
6540
- setupAnimationTriggers(api, config.trigger);
6541
- }
6850
+ if (config.timelineSource === "scroll") {
6851
+ if (config.trigger) diag.warn(PxDiagnosticKind.usage, "scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
6852
+ } else {
6853
+ const detachTriggers = setupAnimationTriggers(api, (_b = config.trigger) != null ? _b : {}, diag);
6854
+ const destroyEngine = api.destroy.bind(api);
6855
+ api.destroy = () => {
6856
+ detachTriggers();
6857
+ destroyEngine();
6858
+ };
6542
6859
  }
6543
6860
  if (scrollTimeline) {
6544
6861
  animations.forEach((a) => a.play());
@@ -6548,19 +6865,20 @@ var PixodeskAnimator = (() => {
6548
6865
 
6549
6866
  // src/scroll/PxScrollDriver.ts
6550
6867
  function nativeRangeOffset(point, defaultFraction, view) {
6551
- var _a, _b, _c;
6868
+ var _a2, _b, _c;
6552
6869
  const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
6553
- const pct = (_b = (_a = globalThis.CSS) == null ? void 0 : _a.percent) == null ? void 0 : _b.call(_a, fraction * 100);
6870
+ const pct = (_b = (_a2 = globalThis.CSS) == null ? void 0 : _a2.percent) == null ? void 0 : _b.call(_a2, fraction * 100);
6554
6871
  if (pct === void 0) return void 0;
6555
6872
  return view ? { rangeName: (_c = point == null ? void 0 : point.phase) != null ? _c : "cover", offset: pct } : { offset: pct };
6556
6873
  }
6557
- function createNativeScrollTimeline(subject, config) {
6558
- var _a, _b, _c, _d;
6874
+ function createNativeScrollTimeline(subject, config, diag) {
6875
+ var _a2, _b, _c, _d;
6876
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6559
6877
  if (!config || !isScrollTimeline(config)) return null;
6560
6878
  const scroll = config.scroll || {};
6561
- const kind = (_a = scroll.kind) != null ? _a : "view";
6879
+ const kind = (_a2 = scroll.kind) != null ? _a2 : "view";
6562
6880
  if (scroll.smoothing) {
6563
- console.warn("scroll timeline: `smoothing` needs the built-in driver \u2014 using the built-in driver instead of the browser timeline");
6881
+ report.warn(PxDiagnosticKind.platform, "scroll timeline: `smoothing` needs the built-in driver \u2014 using the built-in driver instead of the browser timeline");
6564
6882
  return null;
6565
6883
  }
6566
6884
  const g = globalThis;
@@ -6571,13 +6889,13 @@ var PixodeskAnimator = (() => {
6571
6889
  let timeline;
6572
6890
  try {
6573
6891
  if (view) {
6574
- timeline = new Ctor({ subject: resolveScrollSubject(subject, scroll.subject), axis });
6892
+ timeline = new Ctor({ subject: resolveScrollSubject(subject, scroll.subject, report), axis });
6575
6893
  } else {
6576
6894
  const source = scroll.source === "root" ? documentScroller() : findNearestScroller(subject, "y") || findNearestScroller(subject, "x") || documentScroller();
6577
6895
  timeline = new Ctor({ source, axis });
6578
6896
  }
6579
6897
  } catch (e) {
6580
- console.warn("scroll timeline: native timeline construction failed \u2014 falling back to the player measuring progress itself", e);
6898
+ report.warn(PxDiagnosticKind.platform, "scroll timeline: native timeline construction failed \u2014 falling back to the player measuring progress itself", e);
6581
6899
  return null;
6582
6900
  }
6583
6901
  return {
@@ -6604,8 +6922,9 @@ var PixodeskAnimator = (() => {
6604
6922
  }
6605
6923
  var SUBJECT_PARENT = "parent";
6606
6924
  var SUBJECT_SCROLLER = "scroller";
6607
- function resolveScrollSubject(svgRoot, subject) {
6608
- var _a, _b;
6925
+ function resolveScrollSubject(svgRoot, subject, diag) {
6926
+ var _a2, _b;
6927
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6609
6928
  const spec = subject == null ? void 0 : subject.trim();
6610
6929
  if (!spec) return svgRoot;
6611
6930
  if (spec === SUBJECT_PARENT) {
@@ -6614,7 +6933,7 @@ var PixodeskAnimator = (() => {
6614
6933
  const position = getComputedStyle(p).position;
6615
6934
  if (position === "sticky" || position === "fixed") outermostPinned = p;
6616
6935
  }
6617
- return (_b = (_a = outermostPinned == null ? void 0 : outermostPinned.parentElement) != null ? _a : svgRoot.parentElement) != null ? _b : svgRoot;
6936
+ return (_b = (_a2 = outermostPinned == null ? void 0 : outermostPinned.parentElement) != null ? _a2 : svgRoot.parentElement) != null ? _b : svgRoot;
6618
6937
  }
6619
6938
  if (spec === SUBJECT_SCROLLER) {
6620
6939
  return findNearestScroller(svgRoot, "y") || findNearestScroller(svgRoot, "x") || documentScroller();
@@ -6623,21 +6942,22 @@ var PixodeskAnimator = (() => {
6623
6942
  try {
6624
6943
  found = document.querySelector(spec);
6625
6944
  } catch (e) {
6626
- console.warn('scroll timeline: subject "' + spec + '" is not a valid selector \u2014 measuring the SVG itself');
6945
+ report.warn(PxDiagnosticKind.document, 'scroll timeline: subject "' + spec + '" is not a valid selector \u2014 measuring the SVG itself');
6627
6946
  return svgRoot;
6628
6947
  }
6629
6948
  if (!found) {
6630
- console.warn('scroll timeline: subject "' + spec + '" matched no element \u2014 measuring the SVG itself');
6949
+ report.warn(PxDiagnosticKind.host, 'scroll timeline: subject "' + spec + '" matched no element \u2014 measuring the SVG itself');
6631
6950
  return svgRoot;
6632
6951
  }
6633
6952
  return found;
6634
6953
  }
6635
- function createScrollDriver(subject, config, onProgress) {
6636
- var _a, _b;
6954
+ function createScrollDriver(subject, config, onProgress, diag) {
6955
+ var _a2, _b;
6637
6956
  if (!config || !isScrollTimeline(config)) return null;
6957
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6638
6958
  const scroll = config.scroll || {};
6639
- const kind = (_a = scroll.kind) != null ? _a : "view";
6640
- const measured = resolveScrollSubject(subject, scroll.subject);
6959
+ const kind = (_a2 = scroll.kind) != null ? _a2 : "view";
6960
+ const measured = resolveScrollSubject(subject, scroll.subject, report);
6641
6961
  const nearest = findNearestScroller(subject, "y") || findNearestScroller(subject, "x");
6642
6962
  const scroller = kind === "scroll" && scroll.source === "root" ? documentScroller() : nearest || documentScroller();
6643
6963
  const isRootScroller = scroller === documentScroller();
@@ -6755,8 +7075,8 @@ var PixodeskAnimator = (() => {
6755
7075
  style.position = "sticky";
6756
7076
  const alignFactor = scroll.pinAlign === "center" ? 0.5 : scroll.pinAlign === "bottom" ? 1 : 0;
6757
7077
  const applyTop = () => {
6758
- var _a;
6759
- const extra = (_a = scroll.pinTop) != null ? _a : 0;
7078
+ var _a2;
7079
+ const extra = (_a2 = scroll.pinOffset) != null ? _a2 : 0;
6760
7080
  if (!alignFactor) {
6761
7081
  style.top = extra + "px";
6762
7082
  return;
@@ -6803,8 +7123,8 @@ var PixodeskAnimator = (() => {
6803
7123
  if (animatorConfig.resetOnFinish) {
6804
7124
  effectiveCallbacks = __spreadProps(__spreadValues({}, callbacks), {
6805
7125
  onFinish: () => {
6806
- var _a;
6807
- (_a = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a.call(callbacks);
7126
+ var _a2;
7127
+ (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
6808
7128
  apiRef == null ? void 0 : apiRef.cancel();
6809
7129
  }
6810
7130
  });
@@ -6818,14 +7138,15 @@ var PixodeskAnimator = (() => {
6818
7138
  }
6819
7139
  function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
6820
7140
  const animatorConfig = getAnimatorConfig(doc) || {};
7141
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
6821
7142
  if (isScrollTimeline(animatorConfig)) {
6822
7143
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
6823
- var _a;
7144
+ var _a2;
6824
7145
  let unpin = () => {
6825
7146
  };
6826
7147
  if (mayUseNativeScrollTimeline(animatorConfig.engine) && rootElement) {
6827
7148
  unpin = applyScrollPin(rootElement, animatorConfig.scroll);
6828
- const native = createNativeScrollTimeline(rootElement, animatorConfig);
7149
+ const native = createNativeScrollTimeline(rootElement, animatorConfig, diag);
6829
7150
  if (native) {
6830
7151
  const api2 = createWebApiAnimator(
6831
7152
  doc,
@@ -6848,14 +7169,15 @@ var PixodeskAnimator = (() => {
6848
7169
  };
6849
7170
  }
6850
7171
  const api = (animatorConfig.engine !== PxTimelineEngineExtra.js ? createWebApiAnimator(doc, cb, rootElement, isNativeForced(animatorConfig.engine)) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
6851
- const subject = ((_a = api.getRootElement) == null ? void 0 : _a.call(api)) || rootElement;
7172
+ const subject = ((_a2 = api.getRootElement) == null ? void 0 : _a2.call(api)) || rootElement;
6852
7173
  if (subject) {
6853
7174
  unpin = applyScrollPin(subject, animatorConfig.scroll);
6854
7175
  const totalMs = scrollTotalDurationMs(animatorConfig);
6855
7176
  const driver = createScrollDriver(
6856
7177
  subject,
6857
7178
  animatorConfig,
6858
- (progress) => api.setCurrentTime(progress * totalMs)
7179
+ (progress) => api.setCurrentTime(progress * totalMs),
7180
+ diag
6859
7181
  );
6860
7182
  if (driver) {
6861
7183
  const destroy = api.destroy.bind(api);
@@ -6866,7 +7188,7 @@ var PixodeskAnimator = (() => {
6866
7188
  };
6867
7189
  }
6868
7190
  } else {
6869
- console.warn("scroll timeline: no root element to observe \u2014 animation will stay at frame 0");
7191
+ diag.warn(PxDiagnosticKind.host, "scroll timeline: no root element to observe \u2014 animation will stay at frame 0");
6870
7192
  }
6871
7193
  return api;
6872
7194
  });
@@ -6886,37 +7208,38 @@ var PixodeskAnimator = (() => {
6886
7208
 
6887
7209
  // src/dom/PxAnimatorDOM.ts
6888
7210
  var SVG_NS = "http://www.w3.org/2000/svg";
6889
- function createElement(tagName, normalisedProps, style, children, textContent) {
7211
+ function createElement(tagName, normalizedProps, style, children, textContent, diag) {
6890
7212
  if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
6891
- console.warn("SVG tag blocked (dangerous): ", tagName);
7213
+ (diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]")).warn(PxDiagnosticKind.document, "SVG tag blocked (dangerous): " + tagName);
6892
7214
  return null;
6893
7215
  }
6894
7216
  const element = document.createElementNS(SVG_NS, tagName);
6895
- for (const propName in normalisedProps) {
6896
- const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
6897
- if (sanitised === void 0) continue;
7217
+ for (const propName in normalizedProps) {
7218
+ const sanitized = sanitizeAttributeValue(propName, normalizedProps[propName]);
7219
+ if (sanitized === void 0) continue;
6898
7220
  if (CSS_ONLY_STYLE_PROPS.has(propName)) {
6899
- element.style[propName] = String(sanitised);
7221
+ element.style[propName] = String(sanitized);
6900
7222
  continue;
6901
7223
  }
6902
- element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
7224
+ element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitized);
6903
7225
  }
6904
7226
  if (style) {
6905
7227
  for (const styleProp in style) {
6906
7228
  element.style[styleProp] = String(style[styleProp]);
6907
7229
  }
6908
7230
  }
6909
- if (children) {
7231
+ if (children == null ? void 0 : children.length) {
6910
7232
  for (const child of children) {
6911
7233
  element.appendChild(child);
6912
7234
  }
7235
+ } else if (textContent) {
7236
+ element.textContent = textContent;
6913
7237
  }
6914
- if (textContent) element.textContent = textContent;
6915
7238
  return element;
6916
7239
  }
6917
- function renderNode(node, defs) {
7240
+ function renderNode(node, defs, diag) {
6918
7241
  if (!node) return null;
6919
- const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
7242
+ const _a2 = node, { type, children, style } = _a2, props = __objRest(_a2, ["type", "children", "style"]);
6920
7243
  const domType = props.domType;
6921
7244
  if (domType !== void 0) delete props.domType;
6922
7245
  const nodeDefs = getDefs(node) || defs;
@@ -6924,7 +7247,7 @@ var PixodeskAnimator = (() => {
6924
7247
  let childElements;
6925
7248
  if (children) {
6926
7249
  for (const ch of children) {
6927
- const child = renderNode(ch, nodeDefs);
7250
+ const child = renderNode(ch, nodeDefs, diag);
6928
7251
  if (child) {
6929
7252
  if (!childElements) childElements = [];
6930
7253
  childElements.push(child);
@@ -6936,37 +7259,39 @@ var PixodeskAnimator = (() => {
6936
7259
  getNormalizedProps(props),
6937
7260
  resolvedStyle,
6938
7261
  childElements,
6939
- props[TEXT_CONTENT_ATTR] || props[TEXT_ATTR]
7262
+ props[TEXT_CONTENT_ATTR],
7263
+ diag
6940
7264
  );
6941
7265
  if (element && domType !== void 0) element.setAttribute("type", domType);
6942
7266
  return element;
6943
7267
  }
6944
7268
 
6945
7269
  // src/shared/PxAnimatorKeys.ts
6946
- var PX_ANIMATOR_DATA_KEY = "data";
7270
+ var PX_ANIMATOR_DOC_KEY = "doc";
6947
7271
 
6948
7272
  // src/animator/PxAnimator.ts
6949
7273
  function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
6950
7274
  return bindWithEngineChoice(doc, adapter, callbacks, rootElement);
6951
7275
  }
6952
- function createAnimatorImpl(doc, adapter, callbacks, containerElement, config, resetDocDefaults) {
7276
+ function createAnimatorImpl(doc, adapter, callbacks, containerElement, patch, resetTimeline) {
7277
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
6953
7278
  const effectsWarnings = validateNodeEffects(doc);
6954
- for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
7279
+ for (const w of effectsWarnings) diag.warn(PxDiagnosticKind.document, "effects shape: " + w);
6955
7280
  reportDocumentDiagnostics(doc, "[PxAnimator] createAnimator");
6956
- if (config !== void 0 || resetDocDefaults) {
6957
- const patched = applyAnimatorConfig(doc, config != null ? config : {}, { resetDefaults: !!resetDocDefaults });
6958
- for (const w of patched.warnings) console.warn("[PxAnimator] config override:", w);
7281
+ if (patch !== void 0 || resetTimeline) {
7282
+ const patched = applyAnimatorConfig(doc, patch != null ? patch : {}, { resetDefaults: !!resetTimeline });
7283
+ for (const w of patched.warnings) diag.warn(PxDiagnosticKind.usage, "timeline override: " + w);
6959
7284
  doc = patched.doc;
6960
7285
  }
6961
7286
  const animatorConfig = getAnimatorConfig(doc) || {};
6962
7287
  const engine = resolveTimelineEngine(animatorConfig.engine);
6963
- doc = materialiseAllInTree(doc, engine);
7288
+ doc = materializeAllInTree(doc, engine);
6964
7289
  let rootElement = null;
6965
7290
  if (containerElement) {
6966
7291
  doc = generateNewIds(doc);
6967
7292
  const containerEl = typeof containerElement === "string" ? document.querySelector(containerElement) : containerElement;
6968
7293
  if (containerEl) {
6969
- rootElement = renderNode(doc);
7294
+ rootElement = renderNode(doc, void 0, diag);
6970
7295
  if (rootElement) {
6971
7296
  containerEl.replaceChildren(rootElement);
6972
7297
  }
@@ -6983,21 +7308,22 @@ var PixodeskAnimator = (() => {
6983
7308
  }
6984
7309
  return api;
6985
7310
  }
6986
- function resolveAnimatorConfigOption(options) {
6987
- const { config, duration, delay, iterations, startOn } = options;
6988
- return foldAnimatorConfigShortcuts(config, { duration, delay, iterations, startOn });
7311
+ function resolveTimelineOption(options) {
7312
+ const { timeline, duration, delay, iterations, startOn } = options;
7313
+ return foldTimelineOverride(timeline, { duration, delay, iterations, startOn });
6989
7314
  }
6990
7315
  function createAnimator(options) {
6991
- const { src, data, adapter, callbacks, container, resetDocDefaults } = options;
6992
- const config = resolveAnimatorConfigOption(options);
6993
- if (data !== void 0 && src !== void 0) {
6994
- throw new Error("createAnimator: provide either `src` or `data`, not both");
7316
+ const { src, doc, adapter, container, resetTimeline } = options;
7317
+ const patch = resolveTimelineOption(options);
7318
+ const callbacks = toEngineCallbacks(options);
7319
+ if (doc !== void 0 && src !== void 0) {
7320
+ throw new Error("createAnimator: provide either `src` or `doc`, not both");
6995
7321
  }
6996
- if (data === void 0 && src === void 0) {
6997
- throw new Error("createAnimator: either `src` or `data` is required");
7322
+ if (doc === void 0 && src === void 0) {
7323
+ throw new Error("createAnimator: either `src` or `doc` is required");
6998
7324
  }
6999
- if (data !== void 0) {
7000
- return createAnimatorImpl(data, adapter, callbacks, container, config, resetDocDefaults);
7325
+ if (doc !== void 0) {
7326
+ return createAnimatorImpl(doc, adapter, callbacks, container, patch, resetTimeline);
7001
7327
  }
7002
7328
  let animator = null;
7003
7329
  let pending = [];
@@ -7009,19 +7335,27 @@ var PixodeskAnimator = (() => {
7009
7335
  pending.push(call);
7010
7336
  }
7011
7337
  };
7338
+ const loadDiag = createDiagnostics(callbacks, "[PxAnimator]");
7012
7339
  fetch(src).then((res) => res.json()).then((json) => {
7013
7340
  if (destroyed) return;
7014
7341
  if (isPxElementFileFormat(json)) {
7015
- animator = createAnimatorImpl(json, adapter, callbacks, container, config, resetDocDefaults);
7342
+ animator = createAnimatorImpl(json, adapter, callbacks, container, patch, resetTimeline);
7016
7343
  const queued = pending;
7017
7344
  pending = null;
7018
7345
  queued == null ? void 0 : queued.forEach((call) => call(animator));
7019
7346
  } else {
7020
- console.error('createAnimator: invalid animation document format at "' + src + '"');
7347
+ loadDiag.error(
7348
+ PxDiagnosticKind.document,
7349
+ 'createAnimator: invalid animation document format at "' + src + '"'
7350
+ );
7021
7351
  }
7022
7352
  }).catch((err) => {
7353
+ var _a2;
7023
7354
  pending = null;
7024
- console.error('createAnimator: failed to load "' + src + '"', err);
7355
+ loadDiag.error(
7356
+ PxDiagnosticKind.host,
7357
+ 'createAnimator: failed to load "' + src + '" \u2014 ' + ((_a2 = err == null ? void 0 : err.message) != null ? _a2 : String(err))
7358
+ );
7025
7359
  });
7026
7360
  return {
7027
7361
  "isReady": () => !!animator,
@@ -7046,6 +7380,10 @@ var PixodeskAnimator = (() => {
7046
7380
  "setCurrentTime": (time) => {
7047
7381
  enqueue((api) => api.setCurrentTime(time));
7048
7382
  },
7383
+ "getCurrentProgress": () => animator ? animator.getCurrentProgress() : null,
7384
+ "setCurrentProgress": (progress) => {
7385
+ enqueue((api) => api.setCurrentProgress(progress));
7386
+ },
7049
7387
  "destroy": () => {
7050
7388
  destroyed = true;
7051
7389
  pending = null;
@@ -7053,23 +7391,18 @@ var PixodeskAnimator = (() => {
7053
7391
  }
7054
7392
  };
7055
7393
  }
7056
- function loadTagAnimators() {
7394
+ function loadTagAnimators(options) {
7057
7395
  const elements = document.querySelectorAll("[" + PX_ANIM_SRC_ATTR_NAME + "]");
7058
7396
  for (let i = 0; i < elements.length; i++) {
7059
7397
  const element = elements[i];
7060
7398
  if (!element[PX_ANIM_ATTR_NAME]) {
7061
7399
  const src = element.getAttribute(PX_ANIM_SRC_ATTR_NAME);
7062
7400
  if (src) {
7063
- element[PX_ANIM_ATTR_NAME] = createAnimator({ src, container: element });
7401
+ element[PX_ANIM_ATTR_NAME] = createAnimator(__spreadProps(__spreadValues({}, options), { src, container: element }));
7064
7402
  }
7065
7403
  }
7066
7404
  }
7067
7405
  }
7068
- if (typeof window !== "undefined") {
7069
- window["loadTagAnimators"] = loadTagAnimators;
7070
- window["createAnimator"] = createAnimator;
7071
- window["setupAnimationTriggers"] = setupAnimationTriggers;
7072
- }
7073
7406
  return __toCommonJS(index_player_exports);
7074
7407
  })();
7075
7408
  //# sourceMappingURL=pixodesk-svg-animator.umd.js.map