@pixodesk/svg-animator-web 1.0.34 → 1.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -64,7 +64,7 @@ var __objRest2 = (source, exclude) => {
64
64
  return target;
65
65
  };
66
66
  function bezierToSvgPath(path, forceCurves = false) {
67
- var _a, _b, _c, _d;
67
+ var _a2, _b, _c, _d;
68
68
  const v = path.v;
69
69
  const i = path.i;
70
70
  const o = path.o;
@@ -75,7 +75,7 @@ function bezierToSvgPath(path, forceCurves = false) {
75
75
  d.push("M" + v[0][0] + "," + v[0][1]);
76
76
  for (let idx = 1; idx < len; idx++) {
77
77
  const prevV = v[idx - 1];
78
- const prevO = (_a = o == null ? void 0 : o[idx - 1]) != null ? _a : prevV;
78
+ const prevO = (_a2 = o == null ? void 0 : o[idx - 1]) != null ? _a2 : prevV;
79
79
  const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
80
80
  const currV = v[idx];
81
81
  const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) && (currI[0] === currV[0] && currI[1] === currV[1]);
@@ -126,7 +126,7 @@ function interpolateBeziers(paths1, paths2, progress) {
126
126
  return res;
127
127
  }
128
128
  function interpolateBezier(path1, path2, progress) {
129
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
129
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
130
130
  if (!path1 || !path2) return path1 || path2 || { v: [] };
131
131
  const t = Math.min(Math.max(progress, 0), 1);
132
132
  const len = Math.min(path1.v.length, path2.v.length);
@@ -137,7 +137,7 @@ function interpolateBezier(path1, path2, progress) {
137
137
  const v1 = path1.v[idx];
138
138
  const v2 = path2.v[idx];
139
139
  v.push(interpolateVec(v1, v2, t));
140
- const i1 = (_b = (_a = path1.i) == null ? void 0 : _a[idx]) != null ? _b : v1;
140
+ const i1 = (_b = (_a2 = path1.i) == null ? void 0 : _a2[idx]) != null ? _b : v1;
141
141
  const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
142
142
  i.push(interpolateVec(i1, i2, t));
143
143
  const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
@@ -256,8 +256,8 @@ function toRGBA(color) {
256
256
  return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
257
257
  }
258
258
  function parseRgba(s) {
259
- var _a;
260
- const inner = (_a = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a[1];
259
+ var _a2;
260
+ const inner = (_a2 = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a2[1];
261
261
  if (!inner) throw new Error("Invalid rgb/rgba format");
262
262
  const parts = inner.split(",").map((v) => +v.trim());
263
263
  return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
@@ -296,9 +296,9 @@ var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color",
296
296
  var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
297
297
  var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
298
298
  function composeTransformParts(parts, opts) {
299
- var _a;
299
+ var _a2;
300
300
  if (!parts) return "";
301
- const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
301
+ const withUnits = (_a2 = opts == null ? void 0 : opts.withUnits) != null ? _a2 : true;
302
302
  const segs = [];
303
303
  const t = parts.translate;
304
304
  const o = parts.origin;
@@ -316,7 +316,7 @@ function composeTransformParts(parts, opts) {
316
316
  return segs.join("");
317
317
  }
318
318
  function parseTransformParts(str2) {
319
- var _a, _b;
319
+ var _a2, _b;
320
320
  if (!str2 || typeof str2 !== "string") return void 0;
321
321
  const out = {};
322
322
  const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
@@ -332,7 +332,7 @@ function parseTransformParts(str2) {
332
332
  if (nums.some((n) => Number.isNaN(n))) return void 0;
333
333
  if (fn === "translate") {
334
334
  if (nums.length < 1 || nums.length > 2) return void 0;
335
- out.translate = [nums[0], (_a = nums[1]) != null ? _a : 0];
335
+ out.translate = [nums[0], (_a2 = nums[1]) != null ? _a2 : 0];
336
336
  } else if (fn === "rotate") {
337
337
  if (nums.length !== 1) return void 0;
338
338
  out.rotate = nums[0];
@@ -536,8 +536,8 @@ function scrollPhaseInterval(phase, subjectSize, scrollportSize) {
536
536
  }
537
537
  var DEFAULT_PHASE = "cover";
538
538
  function resolveRangePointU(point, defaultFraction, subjectSize, scrollportSize) {
539
- var _a;
540
- const [u0, u1] = scrollPhaseInterval((_a = point == null ? void 0 : point.phase) != null ? _a : DEFAULT_PHASE, subjectSize, scrollportSize);
539
+ var _a2;
540
+ const [u0, u1] = scrollPhaseInterval((_a2 = point == null ? void 0 : point.phase) != null ? _a2 : DEFAULT_PHASE, subjectSize, scrollportSize);
541
541
  const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
542
542
  return u0 + fraction * (u1 - u0);
543
543
  }
@@ -549,9 +549,9 @@ function scrollViewProgress(subjectStart, subjectSize, scrollportSize, range) {
549
549
  return clamp((u - uStart) / (uEnd - uStart), 0, 1);
550
550
  }
551
551
  function scrollOffsetProgress(offset, maxOffset, range) {
552
- var _a, _b;
552
+ var _a2, _b;
553
553
  const raw = maxOffset > 0 ? clamp(offset / maxOffset, 0, 1) : 1;
554
- const start = typeof ((_a = range == null ? void 0 : range.start) == null ? void 0 : _a.fraction) === "number" ? range.start.fraction : 0;
554
+ const start = typeof ((_a2 = range == null ? void 0 : range.start) == null ? void 0 : _a2.fraction) === "number" ? range.start.fraction : 0;
555
555
  const end = typeof ((_b = range == null ? void 0 : range.end) == null ? void 0 : _b.fraction) === "number" ? range.end.fraction : 1;
556
556
  if (end <= start) return raw >= end ? 1 : 0;
557
557
  return clamp((raw - start) / (end - start), 0, 1);
@@ -563,6 +563,7 @@ function scrollResolveAxis(axis, writingMode) {
563
563
  if (a === "inline") return vertical ? "y" : "x";
564
564
  return vertical ? "x" : "y";
565
565
  }
566
+ var PX_UNKNOWN_KEY_ERROR = "unexpected extra key";
566
567
  function pathStr(path) {
567
568
  if (!path.length) return ".";
568
569
  let result = "";
@@ -684,10 +685,10 @@ var Union = class extends Base {
684
685
  return this._default;
685
686
  }
686
687
  isValid(raw, ctx, path) {
687
- var _a;
688
+ var _a2;
688
689
  const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
689
690
  if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
690
- 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));
691
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a2 = JSON.stringify(raw)) != null ? _a2 : "").slice(0, 240));
691
692
  return false;
692
693
  }
693
694
  _canSanitize(raw) {
@@ -696,6 +697,7 @@ var Union = class extends Base {
696
697
  };
697
698
  var DiscriminatedUnion = class extends Base {
698
699
  constructor(_key, _schemas, defaultVal) {
700
+ var _a2;
699
701
  super();
700
702
  this._key = _key;
701
703
  this._schemas = _schemas;
@@ -704,18 +706,21 @@ var DiscriminatedUnion = class extends Base {
704
706
  this._map = /* @__PURE__ */ new Map();
705
707
  for (const s of _schemas) {
706
708
  const keySchema = s._shape[_key];
707
- if (keySchema) this._map.set(keySchema._default, s);
709
+ if (!keySchema) continue;
710
+ const literal = (_a2 = keySchema.inner) != null ? _a2 : keySchema;
711
+ this._map.set(literal._default, s);
712
+ if (keySchema.inner) this._absentMember = s;
708
713
  }
709
714
  }
710
715
  _findSchema(raw) {
711
716
  if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
712
717
  const val = raw[this._key];
713
- if (val === void 0 || val === null) return void 0;
718
+ if (val === void 0 || val === null) return this._absentMember;
714
719
  return this._map.get(val);
715
720
  }
716
721
  sanitize(raw) {
717
- var _a;
718
- return ((_a = this._findSchema(raw)) != null ? _a : this._schemas[0]).sanitize(raw);
722
+ var _a2;
723
+ return ((_a2 = this._findSchema(raw)) != null ? _a2 : this._schemas[0]).sanitize(raw);
719
724
  }
720
725
  isValid(raw, ctx, path) {
721
726
  const schema = this._findSchema(raw);
@@ -744,7 +749,8 @@ var Obj = class extends Base {
744
749
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
745
750
  const out = {};
746
751
  for (const key of Object.keys(this._shape)) {
747
- out[key] = this._shape[key].sanitize(src[key]);
752
+ const v = this._shape[key].sanitize(src[key]);
753
+ if (v !== void 0) out[key] = v;
748
754
  }
749
755
  return out;
750
756
  }
@@ -766,7 +772,7 @@ var Obj = class extends Base {
766
772
  if (key in this._shape) continue;
767
773
  if (obj[key] === void 0) continue;
768
774
  p.push(key);
769
- ctx.errors.push(pathStr(p) + ": unexpected extra key");
775
+ ctx.errors.push(pathStr(p) + ": " + PX_UNKNOWN_KEY_ERROR);
770
776
  p.pop();
771
777
  ok = false;
772
778
  }
@@ -790,7 +796,8 @@ var OpenObj = class extends Base {
790
796
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
791
797
  const out = __spreadValues2({}, src);
792
798
  for (const key of Object.keys(this._shape)) {
793
- out[key] = this._shape[key].sanitize(src[key]);
799
+ const v = this._shape[key].sanitize(src[key]);
800
+ if (v !== void 0) out[key] = v;
794
801
  }
795
802
  if (this._openSchema) {
796
803
  for (const key of Object.keys(src)) {
@@ -931,8 +938,8 @@ var Lazy = class extends Base {
931
938
  this.resolved = null;
932
939
  }
933
940
  get schema() {
934
- var _a;
935
- return (_a = this.resolved) != null ? _a : this.resolved = this.fn();
941
+ var _a2;
942
+ return (_a2 = this.resolved) != null ? _a2 : this.resolved = this.fn();
936
943
  }
937
944
  sanitize(raw) {
938
945
  return this.schema.sanitize(raw);
@@ -983,7 +990,7 @@ function schemaKeys(schema) {
983
990
  );
984
991
  }
985
992
  function describeSchema(schema) {
986
- var _a;
993
+ var _a2;
987
994
  const s = schema;
988
995
  switch (s._kind) {
989
996
  case "union":
@@ -998,7 +1005,7 @@ function describeSchema(schema) {
998
1005
  if ("_shape" in s) return { kind: "shape", shape: s._shape, openValue: s._openSchema };
999
1006
  if ("item" in s) return { kind: "array", item: s.item };
1000
1007
  if ("inner" in s) return { kind: "optional", inner: s.inner };
1001
- if ("fn" in s) return { kind: "lazy", resolved: (_a = s.resolved) != null ? _a : s.resolved = s.fn() };
1008
+ if ("fn" in s) return { kind: "lazy", resolved: (_a2 = s.resolved) != null ? _a2 : s.resolved = s.fn() };
1002
1009
  return { kind: "leaf" };
1003
1010
  }
1004
1011
  var px = {
@@ -1052,24 +1059,49 @@ var px = {
1052
1059
  /** Defers schema creation — required for recursive types. Must supply a default value. */
1053
1060
  lazy: (fn, defaultVal) => new Lazy(fn, defaultVal)
1054
1061
  };
1062
+ var PX_PLAYER_SCHEMA_VERSION = "1.1";
1063
+ var VERSION_RE = /^(\d+)\.(\d+)(?:\.(\d+))?$/;
1064
+ function parseWireVersion(raw) {
1065
+ if (typeof raw !== "string") return void 0;
1066
+ const m = VERSION_RE.exec(raw.trim());
1067
+ if (!m) return void 0;
1068
+ return { a: Number(m[1]), b: Number(m[2]), c: m[3] === void 0 ? 0 : Number(m[3]) };
1069
+ }
1070
+ var _a;
1071
+ var PLAYER_WIRE_VERSION = (_a = parseWireVersion(PX_PLAYER_SCHEMA_VERSION)) != null ? _a : { a: 1, b: 1, c: 0 };
1055
1072
  var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
1056
1073
  var PX_ANIM_ATTR_NAME = "_px_animator";
1057
- var PxAnimatorMode = {
1058
- auto: "auto",
1059
- waapi: "waapi",
1060
- frames: "frames"
1074
+ var PX_TIMELINE_SHARED_KEYS = ["duration", "iterations", "engine", "frameRate"];
1075
+ var PX_TIME_ONLY_TIMELINE_KEYS = ["trigger", "delay", "fillMode", "direction"];
1076
+ var PxTimelineEngine = {
1077
+ native: "native",
1078
+ js: "js"
1061
1079
  };
1062
- var PxAnimatorEngine = {
1063
- waapi: PxAnimatorMode.waapi,
1064
- frames: PxAnimatorMode.frames
1080
+ var PxTimelineEngineExtra = __spreadProps2(__spreadValues2({}, PxTimelineEngine), {
1081
+ auto: "auto"
1082
+ });
1083
+ function resolveTimelineEngine(engine) {
1084
+ return engine === PxTimelineEngineExtra.js ? PxTimelineEngine.js : PxTimelineEngine.native;
1085
+ }
1086
+ function isNativeForced(engine) {
1087
+ return engine === PxTimelineEngineExtra.native;
1088
+ }
1089
+ function mayUseNativeScrollTimeline(engine) {
1090
+ return engine !== PxTimelineEngineExtra.js;
1091
+ }
1092
+ var PxLoopRepeatAt = {
1093
+ /** Segment from the START; the repetition runs BEFORE the first keyframe
1094
+ * (intro loops that play until the main timeline begins). */
1095
+ start: "start",
1096
+ /** DEFAULT — segment from the END; the repetition runs AFTER the last keyframe
1097
+ * (idle/outro loops that continue once the main timeline has finished). */
1098
+ end: "end"
1065
1099
  };
1066
- var PxLoopExtend = {
1067
- /** Segment from the START; the animation is extended BEFORE the first keyframe
1068
- * (intro loops that run before the main timeline begins). */
1069
- before: "before",
1070
- /** DEFAULT — segment from the END; extended AFTER the last keyframe (idle/outro
1071
- * loops that continue once the main timeline has finished). */
1072
- after: "after"
1100
+ var PxLoopDirection = {
1101
+ /** DEFAULT — cycle: every repetition replays the segment the same way round. */
1102
+ normal: "normal",
1103
+ /** Ping-pong: repetitions alternate forward / backward. */
1104
+ alternate: "alternate"
1073
1105
  };
1074
1106
  var PxMaskType = {
1075
1107
  luminance: "luminance",
@@ -1079,8 +1111,9 @@ var PxUnits = {
1079
1111
  userSpaceOnUse: "userSpaceOnUse",
1080
1112
  objectBoundingBox: "objectBoundingBox"
1081
1113
  };
1082
- var PxCloneType = {
1083
- content: "content"
1114
+ var PxCloneWithout = {
1115
+ translate: "translate"
1116
+ // transform: 'transform', // future: drop rotate/scale too (content only)
1084
1117
  };
1085
1118
  var PxPathOverflow = {
1086
1119
  clip: "clip",
@@ -1104,6 +1137,9 @@ var PxStrokeTrimSubPaths = {
1104
1137
  };
1105
1138
  var TEXT_ATTR = "text";
1106
1139
  var TEXT_CONTENT_ATTR = "textContent";
1140
+ var CLASS_ATTR = "class";
1141
+ var TRANSFORM_ATTR = "transform";
1142
+ var OFFSET_DISTANCE_ATTR = "offsetDistance";
1107
1143
  var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
1108
1144
  "type",
1109
1145
  "children",
@@ -1114,7 +1150,18 @@ var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
1114
1150
  TEXT_ATTR,
1115
1151
  TEXT_CONTENT_ATTR
1116
1152
  ]);
1117
- var PX_TRANSFORM_PART_KEYS = ["translate", "rotate", "scale", "origin"];
1153
+ var TRANSFORM_PART = {
1154
+ translate: "translate",
1155
+ rotate: "rotate",
1156
+ scale: "scale",
1157
+ origin: "origin"
1158
+ };
1159
+ var PX_TRANSFORM_PART_KEYS = [
1160
+ TRANSFORM_PART.translate,
1161
+ TRANSFORM_PART.rotate,
1162
+ TRANSFORM_PART.scale,
1163
+ TRANSFORM_PART.origin
1164
+ ];
1118
1165
  var PxGradientUnits = {
1119
1166
  userSpaceOnUse: "userSpaceOnUse",
1120
1167
  objectBoundingBox: "objectBoundingBox"
@@ -1132,11 +1179,11 @@ function isPxElementFileFormat(fileJson) {
1132
1179
  if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
1133
1180
  return false;
1134
1181
  }
1135
- return fileJson["type"] === "svg";
1182
+ return fileJson.type === "svg";
1136
1183
  }
1137
1184
  function getAnimatorConfig(doc) {
1138
- var _a;
1139
- const cfg = (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
1185
+ var _a2;
1186
+ const cfg = (doc == null ? void 0 : doc.animator) || ((_a2 = doc == null ? void 0 : doc.meta) == null ? void 0 : _a2.animator);
1140
1187
  return cfg ? flattenAnimatorTimeline(cfg) : void 0;
1141
1188
  }
1142
1189
  var flattenMemo = /* @__PURE__ */ new WeakMap();
@@ -1145,14 +1192,15 @@ function flattenAnimatorTimeline(cfg) {
1145
1192
  if (timeline === void 0 || timeline === null || typeof timeline !== "object") return cfg;
1146
1193
  const memoised = flattenMemo.get(cfg);
1147
1194
  if (memoised) return memoised;
1148
- const _a = cfg, { timeline: _dropped } = _a, flat = __objRest2(_a, ["timeline"]);
1195
+ const _a2 = cfg, { timeline: _dropped } = _a2, flat = __objRest2(_a2, ["timeline"]);
1196
+ if (timeline.engine !== void 0) flat.engine = timeline.engine;
1197
+ if (timeline.frameRate !== void 0) flat.frameRate = timeline.frameRate;
1149
1198
  if (timeline.type === "scroll" || timeline.type === "view") {
1150
1199
  flat.timelineSource = "scroll";
1151
1200
  if (timeline.duration !== void 0) flat.duration = timeline.duration;
1152
1201
  if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
1153
1202
  const scroll = __spreadValues2({}, flat.scroll || {});
1154
1203
  scroll.kind = timeline.type;
1155
- if (timeline.engine !== void 0) scroll.driver = timeline.engine;
1156
1204
  if (timeline.axis !== void 0) scroll.axis = timeline.axis;
1157
1205
  if (timeline.source !== void 0) scroll.source = timeline.source;
1158
1206
  if (timeline.subject !== void 0) scroll.subject = timeline.subject;
@@ -1170,27 +1218,27 @@ function flattenAnimatorTimeline(cfg) {
1170
1218
  } else {
1171
1219
  if (timeline.duration !== void 0) flat.duration = timeline.duration;
1172
1220
  if (timeline.trigger !== void 0) {
1173
- const _b = timeline.trigger, { onFinish } = _b, restTrigger = __objRest2(_b, ["onFinish"]);
1221
+ const _b = timeline.trigger, { finishAction } = _b, restTrigger = __objRest2(_b, ["finishAction"]);
1174
1222
  if (Object.keys(restTrigger).length) flat.trigger = restTrigger;
1175
- if (onFinish !== void 0) flat.resetOnFinish = onFinish === "reset";
1223
+ if (finishAction !== void 0) flat.resetOnFinish = finishAction === "reset";
1176
1224
  }
1177
1225
  if (timeline.delay !== void 0) flat.delay = timeline.delay;
1178
1226
  if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
1179
1227
  if (timeline.direction !== void 0) flat.direction = timeline.direction;
1180
- if (timeline.fill !== void 0) flat.fill = timeline.fill;
1228
+ if (timeline.fillMode !== void 0) flat.fill = timeline.fillMode;
1181
1229
  }
1182
1230
  flattenMemo.set(cfg, flat);
1183
1231
  return flat;
1184
1232
  }
1185
1233
  function getDefs(doc) {
1186
- var _a;
1234
+ var _a2;
1187
1235
  if (!doc) return void 0;
1188
- return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
1236
+ return (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
1189
1237
  }
1190
1238
  function getBindings(doc) {
1191
- var _a;
1239
+ var _a2;
1192
1240
  if (!doc) return void 0;
1193
- const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
1241
+ const animateById = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.animateById;
1194
1242
  if (!animateById) return void 0;
1195
1243
  return Object.entries(animateById).map(([id, anim]) => ({ id: id.startsWith("#") ? id.slice(1) : id, animate: anim }));
1196
1244
  }
@@ -1228,16 +1276,32 @@ var PxKeyframeSchema = implementsInterface()(px.object({
1228
1276
  // (review §1.3): editor data lives under `meta`. The editor still carries it on
1229
1277
  // its internal COPY-PASTE payload, which never validates against this schema.)
1230
1278
  }));
1279
+ var anyKf = (kf) => kf;
1280
+ var kfTime = (kf) => {
1281
+ var _a2, _b;
1282
+ return (_b = (_a2 = anyKf(kf).time) != null ? _a2 : anyKf(kf).t) != null ? _b : 0;
1283
+ };
1284
+ var kfValue = (kf) => {
1285
+ var _a2;
1286
+ return (_a2 = anyKf(kf).value) != null ? _a2 : anyKf(kf).v;
1287
+ };
1288
+ var kfEasing = (kf) => {
1289
+ var _a2;
1290
+ return (_a2 = anyKf(kf).easing) != null ? _a2 : anyKf(kf).e;
1291
+ };
1292
+ var kfTangentIn = (kf) => anyKf(kf).tangentIn;
1293
+ var kfTangentOut = (kf) => anyKf(kf).tangentOut;
1231
1294
  var PxLoopSchema = implementsInterface()(px.object({
1232
1295
  segmentCount: px.number().optional(),
1233
- extend: px.enum([PxLoopExtend.before, PxLoopExtend.after]).optional(),
1234
- alternate: px.boolean().optional()
1296
+ repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end]).optional(),
1297
+ direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate]).optional()
1235
1298
  }));
1236
1299
  var PxPropertyAnimationSchema = implementsInterface()(px.object({
1237
1300
  value: PxKeyframeValueSchema.optional(),
1238
1301
  keyframes: px.array(PxKeyframeSchema).optional(),
1239
1302
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
1240
- autoOrient: px.boolean().optional()
1303
+ autoOrient: px.boolean().optional(),
1304
+ alongPathMode: px.enum(["sampled", "offsetPath"]).optional()
1241
1305
  }));
1242
1306
  var PxTransformPartsSchema = implementsInterface()(px.object({
1243
1307
  translate: px.tuple([px.number(), px.number()]).optional(),
@@ -1264,10 +1328,9 @@ var PxTriggerSchema = implementsInterface()(px.object({
1264
1328
  startOn: px.enum(["load", "mouseOver", "click", "scrollIntoView", "programmatic"]).optional(),
1265
1329
  outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
1266
1330
  // What happens after a NATURAL finish — `'hold'` (default: keep the end state per
1267
- // `fill`) or `'reset'` (snap back to the start state). The trigger-vocabulary home of
1268
- // the old top-level `resetOnFinish: boolean` (read-legacy) — review §2.3: both
1269
- // "what happens at the end" knobs now sit side by side and share one style of value.
1270
- onFinish: px.enum(["hold", "reset"]).optional(),
1331
+ // `fill`) or `'reset'` (snap back to the start state). Pairs with `outAction` ("what
1332
+ // happens when the trigger condition ends"); both end-of-life knobs now read alike.
1333
+ finishAction: px.enum(["hold", "reset"]).optional(),
1271
1334
  scrollIntoViewThreshold: px.number().optional()
1272
1335
  }));
1273
1336
  var PxGlyphSchema = implementsInterface()(px.object({
@@ -1287,7 +1350,7 @@ var PxDefsSchema = implementsInterface()(px.object({
1287
1350
  // Review §2.6: the schema now matches the declared type — a style preset is a flat
1288
1351
  // record of string|number attribute values, nothing nested.
1289
1352
  styles: px.record(px.record(px.union([px.string(), px.number()]))).optional(),
1290
- glyphs: px.record(PxGlyphFontSchema).optional()
1353
+ fonts: px.record(PxGlyphFontSchema).optional()
1291
1354
  }));
1292
1355
  var PX_SCROLL_PHASES = ["cover", "contain", "entry", "exit", "entry-crossing", "exit-crossing"];
1293
1356
  var PxScrollRangePointSchema = implementsInterface()(px.object({
@@ -1299,7 +1362,6 @@ var PxScrollRangeSchema = px.object({
1299
1362
  end: PxScrollRangePointSchema.optional()
1300
1363
  });
1301
1364
  var PxScrollSchema = implementsInterface()(px.object({
1302
- driver: px.enum(["custom", "native"]).optional(),
1303
1365
  kind: px.enum(["view", "scroll"]).optional(),
1304
1366
  axis: px.enum(["block", "inline", "x", "y"]).optional(),
1305
1367
  source: px.enum(["nearest", "root"]).optional(),
@@ -1312,21 +1374,26 @@ var PxScrollSchema = implementsInterface()(px.object({
1312
1374
  pinDistance: px.number().optional(),
1313
1375
  range: PxScrollRangeSchema.optional()
1314
1376
  }));
1315
- var PxTimelinePinSchema = px.object({
1377
+ var PxTimelinePinSchema = implementsInterface()(px.object({
1316
1378
  align: px.enum(["top", "center", "bottom"]).optional(),
1317
1379
  top: px.number().optional(),
1318
1380
  distance: px.number().optional()
1319
- });
1320
- var PxClockTimelineSchema = px.object({
1321
- type: px.literal("clock"),
1381
+ }));
1382
+ var PxTimelineEngineSchema = px.enum([PxTimelineEngineExtra.auto, PxTimelineEngineExtra.native, PxTimelineEngineExtra.js]).optional();
1383
+ var PxTimeTimelineSchema = implementsInterface()(px.object({
1384
+ type: px.literal("time").optional(),
1385
+ engine: PxTimelineEngineSchema,
1386
+ frameRate: px.number().optional(),
1322
1387
  // §2.8: duration is a property of the TIMELINE — how long one pass takes.
1323
1388
  duration: px.number().optional(),
1324
1389
  trigger: PxTriggerSchema.optional(),
1325
1390
  delay: px.number().optional(),
1326
1391
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
1327
- fill: px.enum(["forwards", "backwards", "both", "none"]).optional(),
1392
+ // `fillMode` on the wire (CSS `animation-fill-mode`; the runtime view calls it `fill`)
1393
+ // — never `fill`, which is paint everywhere else in the format.
1394
+ fillMode: px.enum(["forwards", "backwards", "both", "none"]).optional(),
1328
1395
  direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional()
1329
- });
1396
+ }));
1330
1397
  var scrollishTimelineShape = {
1331
1398
  // §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
1332
1399
  // span the scroll range maps onto.
@@ -1334,7 +1401,8 @@ var scrollishTimelineShape = {
1334
1401
  // Finite repeat count IS meaningful when scrubbing — the scroll range maps onto
1335
1402
  // duration × iterations (rule D4; `'infinite'` cannot map to a range, so no literal here).
1336
1403
  iterations: px.number().optional(),
1337
- engine: px.enum(["custom", "native"]).optional(),
1404
+ engine: PxTimelineEngineSchema,
1405
+ frameRate: px.number().optional(),
1338
1406
  axis: px.enum(["block", "inline", "x", "y"]).optional(),
1339
1407
  source: px.enum(["nearest", "root"]).optional(),
1340
1408
  subject: px.string().optional(),
@@ -1344,23 +1412,29 @@ var scrollishTimelineShape = {
1344
1412
  pin: px.union([px.boolean(), PxTimelinePinSchema]).optional(),
1345
1413
  range: PxScrollRangeSchema.optional()
1346
1414
  };
1347
- var PxScrollTimelineSchema = px.object(__spreadValues2({ type: px.literal("scroll") }, scrollishTimelineShape));
1348
- var PxViewTimelineSchema = px.object(__spreadValues2({ type: px.literal("view") }, scrollishTimelineShape));
1415
+ var PxScrollTimelineSchema = implementsInterface()(
1416
+ px.object(__spreadValues2({ type: px.literal("scroll") }, scrollishTimelineShape))
1417
+ );
1418
+ var PxViewTimelineSchema = implementsInterface()(
1419
+ px.object(__spreadValues2({ type: px.literal("view") }, scrollishTimelineShape))
1420
+ );
1349
1421
  var PxTimelineSchema = px.discriminatedUnion("type", [
1350
- PxClockTimelineSchema,
1422
+ PxTimeTimelineSchema,
1423
+ // first = the member an absent `type` selects
1351
1424
  PxScrollTimelineSchema,
1352
1425
  PxViewTimelineSchema
1353
1426
  ]);
1354
1427
  var PxAnimatorConfigSchema = implementsInterface()(px.object({
1355
- mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.waapi, PxAnimatorMode.frames]).optional(),
1356
- // (`duration` lives INSIDE `timeline` on the wire — §2.8; the flat field below
1357
- // exists only on the runtime view, like the rest of the playback dynamics.)
1358
- frameRate: px.number().optional(),
1428
+ // (`mode`, `duration` and `frameRate` live INSIDE `timeline` on the wire — §2.8; they exist
1429
+ // at this level only on the runtime view, like the rest of the playback dynamics.)
1359
1430
  // THE spelling of "what advances progress" — clock / scroll / view (review §2.1).
1360
1431
  timeline: PxTimelineSchema.optional(),
1361
1432
  definitions: PxDefsSchema.optional(),
1362
1433
  animateById: px.record(PxElementAnimationSchema).optional(),
1363
- debugInstName: px.string().optional()
1434
+ debugGlobalName: px.string().optional(),
1435
+ // Declared HERE because this is a closed object: an undeclared key would be stripped by
1436
+ // `sanitize` and flagged by strict validation on our own files.
1437
+ version: px.string().optional()
1364
1438
  }));
1365
1439
  var PxBindingSchema = implementsInterface()(px.object({
1366
1440
  id: px.string(),
@@ -1409,7 +1483,7 @@ var PxRepeaterEffectSchema = implementsInterface()(px.object({
1409
1483
  origin: PxAnimatableVec2Schema.optional()
1410
1484
  }));
1411
1485
  var PxMaskedByEffectSchema = implementsInterface()(px.object({
1412
- sourceId: px.string().optional(),
1486
+ source: px.string().optional(),
1413
1487
  maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
1414
1488
  maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1415
1489
  maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
@@ -1432,9 +1506,10 @@ var PxRetimeEffectSchema = implementsInterface()(px.object({
1432
1506
  timeCrop: px.tuple([px.number(), px.number()]).optional()
1433
1507
  }));
1434
1508
  var PxCloneEffectSchema = implementsInterface()(px.object({
1435
- // Contextual kind — the `type` convention, see `PxNodeBase.type`.
1436
- type: px.enum([PxCloneType.content]).optional(),
1437
- sourceId: px.string().optional(),
1509
+ // Subtractive on purpose: the `<use>` can only point at one wrapper layer of the
1510
+ // source, so the choices form a ladder — 'translate' now, maybe 'transform' later.
1511
+ without: px.enum([PxCloneWithout.translate]).optional(),
1512
+ source: px.string().optional(),
1438
1513
  retime: PxRetimeEffectSchema.optional()
1439
1514
  }));
1440
1515
  var PxGradientStopSchema = implementsInterface()(px.object({
@@ -1461,7 +1536,7 @@ var PxFillGradientEffectSchema = implementsInterface()(px.object({
1461
1536
  }));
1462
1537
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
1463
1538
  var PxTextPathEffectSchema = implementsInterface()(px.object({
1464
- path: px.string(),
1539
+ pathData: px.string(),
1465
1540
  pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
1466
1541
  lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
1467
1542
  method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
@@ -1501,16 +1576,33 @@ function validateNodeEffects(root, opts) {
1501
1576
  walk(root, "root");
1502
1577
  return warnings;
1503
1578
  }
1579
+ function validateDocument(doc) {
1580
+ const ctx = { errors: [], warnings: [], strict: true };
1581
+ const problems = PxAnimatedSvgDocumentSchema.isValid(doc, ctx, ["root"]) ? [] : [...ctx.errors];
1582
+ if (doc && typeof doc === "object") {
1583
+ for (const w of validateNodeEffects(doc, { strict: true })) {
1584
+ if (!problems.includes(w)) problems.push(w);
1585
+ }
1586
+ }
1587
+ return problems;
1588
+ }
1504
1589
  var PxNodeBase = px.openObject({
1505
1590
  // CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
1506
1591
  // kind of thing is this", discriminated by its CARRIER — here the node TAG
1507
- // (`rect`, `text`), and inside a sub-object that object's kind (`clone.type`,
1592
+ // (`rect`, `text`), and inside a sub-object that object's kind (`fillGradient.type`,
1508
1593
  // `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
1509
1594
  // the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
1510
1595
  // would add words that all mean "type" and still need the carrier to read.
1511
1596
  // Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
1512
1597
  // (issues V3), never of distinct key names.
1513
1598
  type: px.string(),
1599
+ // The escape hatch for elements that carry a REAL `type` attribute — `<feTurbulence
1600
+ // type="fractalNoise">`, `<feFuncR type="table">`, `<feColorMatrix type="saturate">`.
1601
+ // `type` is taken by the tag name, so the attribute travels here and the renderer puts
1602
+ // it back (`PxAnimatorDOM.renderNode`, `PxRnRender`). Declared here — not merely
1603
+ // documented — because a wire key that is not in a schema is invisible to the
1604
+ // minifier's reserve list and gets renamed (MINIFICATION-BOUNDARY-PLAN.md §1.1).
1605
+ domType: px.string().optional(),
1514
1606
  id: px.string().optional(),
1515
1607
  meta: px.any().optional(),
1516
1608
  // Player-effects bucket emitted by the Editor's lightweight design format.
@@ -1567,7 +1659,7 @@ function deepClone(value) {
1567
1659
  return cloned;
1568
1660
  }
1569
1661
  function generateNewIds(doc) {
1570
- var _a, _b;
1662
+ var _a2, _b;
1571
1663
  const cloned = deepClone(doc);
1572
1664
  const idMap = /* @__PURE__ */ new Map();
1573
1665
  const hashRefAttrs = /* @__PURE__ */ new Set(["href", "xlink:href"]);
@@ -1585,7 +1677,8 @@ function generateNewIds(doc) {
1585
1677
  "flood-color",
1586
1678
  "lighting-color"
1587
1679
  ]);
1588
- const directIdRefAttrs = /* @__PURE__ */ new Set(["sourceId", "targetId", "boundElementId"]);
1680
+ const directIdRefAttrs = /* @__PURE__ */ new Set(["targetId", "boundElementId"]);
1681
+ const isEffectSourceRef = (key, parentKey) => key === "source" && (parentKey === "maskedBy" || parentKey === "clone");
1589
1682
  function collectIds(node) {
1590
1683
  if (!node || typeof node !== "object") return;
1591
1684
  if (node.id && typeof node.id === "string") {
@@ -1602,7 +1695,7 @@ function generateNewIds(doc) {
1602
1695
  }
1603
1696
  }
1604
1697
  }
1605
- function updateRefs(node) {
1698
+ function updateRefs(node, parentKey) {
1606
1699
  if (!node || typeof node !== "object") return;
1607
1700
  for (const [key, value] of Object.entries(node)) {
1608
1701
  if (key === "children") {
@@ -1622,7 +1715,7 @@ function generateNewIds(doc) {
1622
1715
  }
1623
1716
  } else if (urlRefAttrs.has(key)) {
1624
1717
  node[key] = replaceUrlRefs(value, idMap);
1625
- } else if (directIdRefAttrs.has(key)) {
1718
+ } else if (directIdRefAttrs.has(key) || isEffectSourceRef(key, parentKey)) {
1626
1719
  const hasHash = value.startsWith("#");
1627
1720
  const newId = idMap.get(hasHash ? value.slice(1) : value);
1628
1721
  if (newId) {
@@ -1638,13 +1731,13 @@ function generateNewIds(doc) {
1638
1731
  }
1639
1732
  }
1640
1733
  } else if (typeof value === "object" && value !== null) {
1641
- updateRefs(value);
1734
+ updateRefs(value, key);
1642
1735
  }
1643
1736
  }
1644
1737
  }
1645
1738
  collectIds(cloned);
1646
1739
  updateRefs(cloned);
1647
- const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animateById;
1740
+ const docAnimate = (_a2 = cloned.animator) == null ? void 0 : _a2.animateById;
1648
1741
  if (docAnimate && typeof docAnimate === "object") {
1649
1742
  const updatedAnimate = {};
1650
1743
  for (const [key, anim] of Object.entries(docAnimate)) {
@@ -1726,10 +1819,10 @@ function sanitiseAttributeValue(name, value) {
1726
1819
  return value;
1727
1820
  }
1728
1821
  function resolveStyle(style, defs) {
1729
- var _a;
1822
+ var _a2;
1730
1823
  if (!style) return void 0;
1731
1824
  if (typeof style === "string") {
1732
- return (_a = defs == null ? void 0 : defs.styles) == null ? void 0 : _a[style];
1825
+ return (_a2 = defs == null ? void 0 : defs.styles) == null ? void 0 : _a2[style];
1733
1826
  }
1734
1827
  return style;
1735
1828
  }
@@ -1744,14 +1837,14 @@ function getNormalizedProps(props) {
1744
1837
  propsCopy[key] = toRGBA(value);
1745
1838
  } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes) {
1746
1839
  const parts = value.value && typeof value.value === "object" ? value.value : value;
1747
- propsCopy["transform"] = composeTransformParts(parts, { withUnits: false });
1840
+ propsCopy[TRANSFORM_ATTR] = composeTransformParts(parts, { withUnits: false });
1748
1841
  } else if (TRANSFORM_FN_NAMES.has(key)) {
1749
1842
  if (Array.isArray(value)) {
1750
1843
  if (key === "translate") value = value.map((v) => v + "px");
1751
1844
  value = value.join(",");
1752
1845
  }
1753
1846
  if (key === "rotate") value = value + "deg";
1754
- propsCopy["transform"] = key + "(" + value + ")";
1847
+ propsCopy[TRANSFORM_ATTR] = key + "(" + value + ")";
1755
1848
  } else if (Array.isArray(value)) {
1756
1849
  propsCopy[key] = value.join(",");
1757
1850
  } else if (value !== void 0 && value !== null) {
@@ -1761,8 +1854,7 @@ function getNormalizedProps(props) {
1761
1854
  return propsCopy;
1762
1855
  }
1763
1856
  function getKfTranslate(kf) {
1764
- var _a;
1765
- const v = (_a = kf.value) != null ? _a : kf.v;
1857
+ const v = kfValue(kf);
1766
1858
  if (!v) return void 0;
1767
1859
  if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
1768
1860
  return [v[0], v[1]];
@@ -1772,31 +1864,27 @@ function getKfTranslate(kf) {
1772
1864
  return void 0;
1773
1865
  }
1774
1866
  function getKfTime(kf) {
1775
- var _a, _b;
1776
- return (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
1867
+ return kfTime(kf);
1777
1868
  }
1778
1869
  function getKfEasing(kf) {
1779
- var _a;
1780
- return (_a = kf.easing) != null ? _a : kf.e;
1870
+ return kfEasing(kf);
1781
1871
  }
1782
1872
  function propAnimIsMotionPath(anim) {
1783
- var _a, _b;
1784
1873
  const kfs = anim.keyframes;
1785
1874
  if (!Array.isArray(kfs)) return false;
1786
1875
  if (anim.autoOrient) return true;
1787
1876
  for (const kf of kfs) {
1788
- if (((_a = kf.tangentIn) != null ? _a : kf.ti) || ((_b = kf.tangentOut) != null ? _b : kf.to)) return true;
1877
+ if (kfTangentIn(kf) || kfTangentOut(kf)) return true;
1789
1878
  }
1790
1879
  return false;
1791
1880
  }
1792
1881
  var _segmentCache = /* @__PURE__ */ new WeakMap();
1793
1882
  function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
1794
- var _a, _b;
1795
1883
  let byNext = _segmentCache.get(prevKf);
1796
1884
  const existing = byNext == null ? void 0 : byNext.get(nextKf);
1797
1885
  if (existing) return existing;
1798
- const to = (_a = prevKf.tangentOut) != null ? _a : prevKf.to;
1799
- const ti = (_b = nextKf.tangentIn) != null ? _b : nextKf.ti;
1886
+ const to = kfTangentOut(prevKf);
1887
+ const ti = kfTangentIn(nextKf);
1800
1888
  const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
1801
1889
  const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
1802
1890
  const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
@@ -1846,12 +1934,12 @@ var DEFAULT_FLATNESS_TOL = 0.5;
1846
1934
  var DEFAULT_ROTATION_TOL = 5;
1847
1935
  var DEFAULT_MAX_SAMPLES = 32;
1848
1936
  function materialiseMotionPathInPropAnim(anim, opts) {
1849
- var _a, _b, _c;
1937
+ var _a2, _b, _c;
1850
1938
  if (!propAnimIsMotionPath(anim)) return anim;
1851
1939
  const kfs = anim.keyframes;
1852
1940
  if (!Array.isArray(kfs) || kfs.length < 2) return anim;
1853
1941
  const autoOrient = !!anim.autoOrient;
1854
- const flatnessTol = (_a = opts == null ? void 0 : opts.flatnessTolerance) != null ? _a : DEFAULT_FLATNESS_TOL;
1942
+ const flatnessTol = (_a2 = opts == null ? void 0 : opts.flatnessTolerance) != null ? _a2 : DEFAULT_FLATNESS_TOL;
1855
1943
  const rotationTol = (_b = opts == null ? void 0 : opts.rotationTolerance) != null ? _b : DEFAULT_ROTATION_TOL;
1856
1944
  const maxSamples = (_c = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _c : DEFAULT_MAX_SAMPLES;
1857
1945
  const out = [];
@@ -1887,10 +1975,9 @@ function materialiseMotionPathInPropAnim(anim, opts) {
1887
1975
  return result;
1888
1976
  }
1889
1977
  function unwrapAutoOrientRotations(kfs) {
1890
- var _a;
1891
1978
  let prev;
1892
1979
  for (const kf of kfs) {
1893
- const v = (_a = kf.v) != null ? _a : kf.value;
1980
+ const v = kfValue(kf);
1894
1981
  if (!v || typeof v.rotate !== "number") continue;
1895
1982
  if (prev === void 0) {
1896
1983
  prev = v.rotate;
@@ -1907,8 +1994,7 @@ function makeOutKf(time, value) {
1907
1994
  return { t: time, v: value };
1908
1995
  }
1909
1996
  function getKfValueParts(kf) {
1910
- var _a;
1911
- const v = (_a = kf.value) != null ? _a : kf.v;
1997
+ const v = kfValue(kf);
1912
1998
  if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
1913
1999
  return v;
1914
2000
  }
@@ -1969,9 +2055,8 @@ function wrappedAngleDelta(a, b) {
1969
2055
  return d;
1970
2056
  }
1971
2057
  function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
1972
- var _a;
1973
2058
  const lastKf = out[out.length - 1];
1974
- const lastV = (_a = lastKf.v) != null ? _a : lastKf.value;
2059
+ const lastV = kfValue(lastKf);
1975
2060
  const prevExit = lastV == null ? void 0 : lastV.rotate;
1976
2061
  if (typeof prevExit !== "number") return;
1977
2062
  const boundaryV = getKfValueParts(prevKf);
@@ -2282,21 +2367,21 @@ function normalizePathValue(value) {
2282
2367
  return value;
2283
2368
  }
2284
2369
  function resolveEasing(easing, defs) {
2285
- var _a;
2370
+ var _a2;
2286
2371
  if (!easing) return void 0;
2287
2372
  if (Array.isArray(easing)) {
2288
2373
  return easing;
2289
2374
  }
2290
- if ((_a = defs == null ? void 0 : defs.easings) == null ? void 0 : _a[easing]) {
2375
+ if ((_a2 = defs == null ? void 0 : defs.easings) == null ? void 0 : _a2[easing]) {
2291
2376
  return defs.easings[easing];
2292
2377
  }
2293
2378
  console.warn("Unknown easing name: " + easing);
2294
2379
  return void 0;
2295
2380
  }
2296
2381
  function resolveAnimation(animRef, defs) {
2297
- var _a;
2382
+ var _a2;
2298
2383
  if (typeof animRef === "string") {
2299
- const resolved = (_a = defs == null ? void 0 : defs.animations) == null ? void 0 : _a[animRef];
2384
+ const resolved = (_a2 = defs == null ? void 0 : defs.animations) == null ? void 0 : _a2[animRef];
2300
2385
  if (!resolved) {
2301
2386
  console.warn("Unknown animation name: " + animRef);
2302
2387
  }
@@ -2321,9 +2406,9 @@ function resolveElementAnimation(animate, defs) {
2321
2406
  return results;
2322
2407
  }
2323
2408
  function interpolateValue(propName, a, b, t) {
2324
- var _a, _b;
2409
+ var _a2, _b;
2325
2410
  if (propName === "d") {
2326
- const aPaths = (_a = a == null ? void 0 : a.paths) != null ? _a : Array.isArray(a) ? a : [];
2411
+ const aPaths = (_a2 = a == null ? void 0 : a.paths) != null ? _a2 : Array.isArray(a) ? a : [];
2327
2412
  const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
2328
2413
  return { paths: interpolateBeziers(aPaths, bPaths, t) };
2329
2414
  }
@@ -2359,11 +2444,11 @@ function interpolateTransformParts(a, b, t) {
2359
2444
  return out;
2360
2445
  }
2361
2446
  function expandLoopKeyframes(propName, keyframes, loop, duration) {
2362
- var _a, _b, _c, _d, _e;
2447
+ var _a2, _b, _c, _d, _e;
2363
2448
  const totalIntervals = keyframes.length - 1;
2364
- const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
2449
+ const segCount = clamp((_a2 = loop.segmentCount) != null ? _a2 : totalIntervals, 1, totalIntervals);
2365
2450
  let segKfs;
2366
- if (loop.extend === PxLoopExtend.before) {
2451
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2367
2452
  segKfs = keyframes.slice(0, segCount + 1);
2368
2453
  } else {
2369
2454
  segKfs = keyframes.slice(totalIntervals - segCount);
@@ -2371,7 +2456,7 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2371
2456
  const firstT = (_b = keyframes[0].t) != null ? _b : 0;
2372
2457
  const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
2373
2458
  let fillStart, fillEnd;
2374
- if (loop.extend === PxLoopExtend.before) {
2459
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2375
2460
  fillStart = 0;
2376
2461
  fillEnd = firstT;
2377
2462
  } else {
@@ -2384,26 +2469,23 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2384
2469
  const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
2385
2470
  const segDuration = segEndT - segStartT;
2386
2471
  if (segDuration <= 0) return keyframes;
2387
- const template = segKfs.map((kf) => {
2388
- var _a2, _b2;
2389
- return {
2390
- relT: (kf.t - segStartT) / segDuration,
2391
- v: kf.v,
2392
- e: kf.e,
2393
- tangentIn: (_a2 = kf.tangentIn) != null ? _a2 : kf.ti,
2394
- tangentOut: (_b2 = kf.tangentOut) != null ? _b2 : kf.to
2395
- };
2396
- });
2472
+ const template = segKfs.map((kf) => ({
2473
+ relT: (kf.t - segStartT) / segDuration,
2474
+ v: kf.v,
2475
+ e: kf.e,
2476
+ tangentIn: kfTangentIn(kf),
2477
+ tangentOut: kfTangentOut(kf)
2478
+ }));
2397
2479
  const fullReps = Math.floor(fillDuration / segDuration);
2398
2480
  const remainder = fillDuration - fullReps * segDuration;
2399
2481
  const partialFraction = remainder / segDuration;
2400
2482
  const looped = [];
2401
- const separateBoundary = loop.extend !== PxLoopExtend.before;
2483
+ const separateBoundary = loop.repeatAt !== PxLoopRepeatAt.start;
2402
2484
  const originalTerminalKf = keyframes[keyframes.length - 1];
2403
2485
  let terminalEasingOverride;
2404
2486
  let hasTerminalEasingOverride = false;
2405
2487
  function appendRep(repStart, isReversed, partial) {
2406
- var _a2;
2488
+ var _a3;
2407
2489
  let entries;
2408
2490
  if (isReversed) {
2409
2491
  entries = [];
@@ -2440,7 +2522,7 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2440
2522
  return;
2441
2523
  }
2442
2524
  const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
2443
- const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
2525
+ const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a3 = prevKf.t) != null ? _a3 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
2444
2526
  if (isBoundary) {
2445
2527
  if (deepEqualValue(prevKf.v, entry.v)) {
2446
2528
  if (looped.length > 0) {
@@ -2506,30 +2588,30 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2506
2588
  looped.push(pushed);
2507
2589
  }
2508
2590
  }
2509
- if (loop.extend === PxLoopExtend.before) {
2591
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2510
2592
  if (partialFraction > 1e-9) {
2511
- const isReversed = !!loop.alternate && fullReps % 2 === 0;
2593
+ const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
2512
2594
  appendRepTail(fillStart, isReversed, partialFraction);
2513
2595
  }
2514
2596
  for (let rep = 0; rep < fullReps; rep++) {
2515
2597
  const distFromBoundary = fullReps - 1 - rep;
2516
- const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
2598
+ const isReversed = loop.direction === PxLoopDirection.alternate && distFromBoundary % 2 === 0;
2517
2599
  const repStart = fillStart + remainder + rep * segDuration;
2518
2600
  appendRep(repStart, isReversed);
2519
2601
  }
2520
2602
  } else {
2521
2603
  for (let rep = 0; rep < fullReps; rep++) {
2522
- const isReversed = !!loop.alternate && rep % 2 === 0;
2604
+ const isReversed = loop.direction === PxLoopDirection.alternate && rep % 2 === 0;
2523
2605
  const repStart = fillStart + rep * segDuration;
2524
2606
  appendRep(repStart, isReversed);
2525
2607
  }
2526
2608
  if (partialFraction > 1e-9) {
2527
- const isReversed = !!loop.alternate && fullReps % 2 === 0;
2609
+ const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
2528
2610
  const repStart = fillStart + fullReps * segDuration;
2529
2611
  appendRep(repStart, isReversed, partialFraction);
2530
2612
  }
2531
2613
  }
2532
- if (loop.extend === PxLoopExtend.before) {
2614
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
2533
2615
  return [...looped, ...keyframes];
2534
2616
  } else {
2535
2617
  if (hasTerminalEasingOverride && keyframes.length > 0) {
@@ -2541,34 +2623,34 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
2541
2623
  }
2542
2624
  }
2543
2625
  function normalizeKeyframes(propName, propAnim, duration, defs) {
2544
- var _a, _b, _c, _d, _e, _f, _g;
2626
+ var _a2;
2545
2627
  const keyframes = propAnim.keyframes || [];
2546
2628
  const normalized = [];
2547
2629
  for (const kf of keyframes) {
2548
- const timePct = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
2549
- let value = (_c = kf.value) != null ? _c : kf.v;
2550
- const easing = (_d = kf.easing) != null ? _d : kf.e;
2630
+ const timePct = kfTime(kf);
2631
+ let value = kfValue(kf);
2632
+ const easing = kfEasing(kf);
2551
2633
  if (propName === "d") {
2552
2634
  value = normalizePathValue(value);
2553
2635
  }
2554
2636
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2555
2637
  if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
2556
- value = (_e = parseColor(value)) != null ? _e : value;
2638
+ value = (_a2 = parseColor(value)) != null ? _a2 : value;
2557
2639
  }
2558
2640
  const normKf = {
2559
2641
  t: timePct,
2560
2642
  v: value,
2561
2643
  e: resolveEasing(easing, defs)
2562
2644
  };
2563
- const tIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
2564
- const tOut = (_g = kf.tangentOut) != null ? _g : kf.to;
2645
+ const tIn = kfTangentIn(kf);
2646
+ const tOut = kfTangentOut(kf);
2565
2647
  if (tIn) normKf.tangentIn = tIn;
2566
2648
  if (tOut) normKf.tangentOut = tOut;
2567
2649
  normalized.push(normKf);
2568
2650
  }
2569
2651
  normalized.sort((a, b) => {
2570
- var _a2, _b2;
2571
- return ((_a2 = a.t) != null ? _a2 : 0) - ((_b2 = b.t) != null ? _b2 : 0);
2652
+ var _a3, _b;
2653
+ return ((_a3 = a.t) != null ? _a3 : 0) - ((_b = b.t) != null ? _b : 0);
2572
2654
  });
2573
2655
  const loopRaw = propAnim.loop;
2574
2656
  const loop = loopRaw === true ? {} : loopRaw || void 0;
@@ -2595,15 +2677,17 @@ function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
2595
2677
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2596
2678
  const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);
2597
2679
  const kfs = rawKfs.map((kf) => {
2598
- var _a, _b, _c, _d, _e, _f, _g, _h;
2599
- const t = (_a = kf.t) != null ? _a : kf.time;
2600
- let v = (_b = kf.v) != null ? _b : kf.value;
2680
+ var _a2;
2681
+ const t = kfTime(kf);
2682
+ let v = kfValue(kf);
2601
2683
  if (propName === "d") v = normalizePathValue(v);
2602
- if (isColour) v = (_c = parseColor(v)) != null ? _c : v;
2603
- const e = (_d = kf.e) != null ? _d : kf.easing;
2684
+ if (isColour) v = (_a2 = parseColor(v)) != null ? _a2 : v;
2685
+ const e = kfEasing(kf);
2604
2686
  const out2 = { t, v, e };
2605
- if ((_e = kf.tangentIn) != null ? _e : kf.ti) out2.tangentIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
2606
- if ((_g = kf.tangentOut) != null ? _g : kf.to) out2.tangentOut = (_h = kf.tangentOut) != null ? _h : kf.to;
2687
+ const tIn = kfTangentIn(kf);
2688
+ const tOut = kfTangentOut(kf);
2689
+ if (tIn) out2.tangentIn = tIn;
2690
+ if (tOut) out2.tangentOut = tOut;
2607
2691
  return out2;
2608
2692
  });
2609
2693
  const expanded = expandLoopKeyframes(propName, kfs, loop, duration);
@@ -2654,7 +2738,7 @@ function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
2654
2738
  const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
2655
2739
  if (!staticParts || !Object.keys(staticParts).length) return animDef;
2656
2740
  const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues2(__spreadValues2({}, staticParts), v) : v;
2657
- const transformAnim = animDef["transform"];
2741
+ const transformAnim = animDef[TRANSFORM_ATTR];
2658
2742
  if (transformAnim && typeof transformAnim === "object") {
2659
2743
  const anim = transformAnim;
2660
2744
  if (Array.isArray(anim.keyframes)) {
@@ -2679,7 +2763,7 @@ function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
2679
2763
  delete rest[ch];
2680
2764
  return __spreadProps2(__spreadValues2({}, rest), { transform: lifted });
2681
2765
  }
2682
- function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
2766
+ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxTimelineEngine.native) {
2683
2767
  const normalized = {};
2684
2768
  for (const [propName, propAnim] of Object.entries(animDef)) {
2685
2769
  if (propName === "transform" && propAnim.alongPathMode === "offsetPath" && animDef["offsetDistance"] !== void 0) {
@@ -2690,12 +2774,12 @@ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimat
2690
2774
  const out = { keyframes: normalizedKfs };
2691
2775
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2692
2776
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
2693
- normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
2777
+ normalized[propName] = engine === PxTimelineEngine.native && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
2694
2778
  }
2695
2779
  }
2696
2780
  return normalized;
2697
2781
  }
2698
- function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
2782
+ function getNormalisedBindings(doc, engine = PxTimelineEngine.native) {
2699
2783
  const animatorConfig = getAnimatorConfig(doc) || {};
2700
2784
  const defs = getDefs(doc);
2701
2785
  const duration = animatorConfig.duration || 1e3;
@@ -2741,12 +2825,12 @@ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
2741
2825
  return bindings;
2742
2826
  }
2743
2827
  function getKeyframesPair(keyframes, progress) {
2744
- var _a, _b;
2828
+ var _a2, _b;
2745
2829
  const last = keyframes.length - 1;
2746
2830
  let prevKf = keyframes[0];
2747
2831
  let nextKf = keyframes[last > 0 ? 1 : 0];
2748
2832
  for (let j = 0; j < last; j++) {
2749
- const aOff = (_a = keyframes[j].t) != null ? _a : 0;
2833
+ const aOff = (_a2 = keyframes[j].t) != null ? _a2 : 0;
2750
2834
  const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
2751
2835
  if (aOff <= progress && progress <= bOff) {
2752
2836
  prevKf = keyframes[j];
@@ -2761,13 +2845,13 @@ function getKeyframesPair(keyframes, progress) {
2761
2845
  return { prevKf, nextKf };
2762
2846
  }
2763
2847
  function calcPropertyValue(propName, propAnim, progress) {
2764
- var _a, _b, _c, _d, _e, _f, _g;
2848
+ var _a2, _b, _c, _d;
2765
2849
  const keyframes = propAnim.keyframes || [];
2766
2850
  if (keyframes.length === 0) return null;
2767
2851
  const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
2768
- let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
2852
+ let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a2 = prevKf.t) != null ? _a2 : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
2769
2853
  localProgress = clamp(localProgress, 0, 1);
2770
- const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
2854
+ const easing = kfEasing(prevKf);
2771
2855
  if (easing && Array.isArray(easing)) {
2772
2856
  try {
2773
2857
  localProgress = cubicBezier(easing)(localProgress);
@@ -2776,11 +2860,11 @@ function calcPropertyValue(propName, propAnim, progress) {
2776
2860
  }
2777
2861
  let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2778
2862
  let cssValue = null;
2779
- const prevV = (_d = prevKf == null ? void 0 : prevKf.v) != null ? _d : prevKf == null ? void 0 : prevKf.value;
2780
- const nextV = (_e = nextKf == null ? void 0 : nextKf.v) != null ? _e : nextKf == null ? void 0 : nextKf.value;
2863
+ const prevV = prevKf == null ? void 0 : prevKf.v;
2864
+ const nextV = nextKf == null ? void 0 : nextKf.v;
2781
2865
  if (cssAttrName === "d") {
2782
- const prevPaths = (_f = prevV == null ? void 0 : prevV.paths) != null ? _f : Array.isArray(prevV) ? prevV : [];
2783
- const nextPaths = (_g = nextV == null ? void 0 : nextV.paths) != null ? _g : Array.isArray(nextV) ? nextV : [];
2866
+ const prevPaths = (_c = prevV == null ? void 0 : prevV.paths) != null ? _c : Array.isArray(prevV) ? prevV : [];
2867
+ const nextPaths = (_d = nextV == null ? void 0 : nextV.paths) != null ? _d : Array.isArray(nextV) ? nextV : [];
2784
2868
  cssValue = interpolateBeziers(
2785
2869
  prevPaths,
2786
2870
  nextPaths,
@@ -2892,13 +2976,13 @@ function deepClonePxNode(value) {
2892
2976
  function regenerateIdsAndRewriteRefs(root, genId3) {
2893
2977
  const oldToNew = /* @__PURE__ */ new Map();
2894
2978
  const walkAssign = (n) => {
2895
- var _a;
2979
+ var _a2;
2896
2980
  if (typeof n.id === "string") {
2897
2981
  const newId = genId3();
2898
2982
  oldToNew.set(n.id, newId);
2899
2983
  n.id = newId;
2900
2984
  }
2901
- (_a = n.children) == null ? void 0 : _a.forEach(walkAssign);
2985
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walkAssign);
2902
2986
  };
2903
2987
  walkAssign(root);
2904
2988
  const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
@@ -2906,7 +2990,7 @@ function regenerateIdsAndRewriteRefs(root, genId3) {
2906
2990
  return newId ? "url(#" + newId + ")" : m;
2907
2991
  });
2908
2992
  const walkRewrite = (n) => {
2909
- var _a;
2993
+ var _a2;
2910
2994
  if (typeof n.href === "string" && n.href.startsWith("#")) {
2911
2995
  const newId = oldToNew.get(n.href.slice(1));
2912
2996
  if (newId) n.href = "#" + newId;
@@ -2918,7 +3002,7 @@ function regenerateIdsAndRewriteRefs(root, genId3) {
2918
3002
  n[k] = rewriteUrl(v);
2919
3003
  }
2920
3004
  }
2921
- (_a = n.children) == null ? void 0 : _a.forEach(walkRewrite);
3005
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walkRewrite);
2922
3006
  };
2923
3007
  walkRewrite(root);
2924
3008
  return oldToNew;
@@ -2928,7 +3012,7 @@ function toFiniteNum(v) {
2928
3012
  return Number.isFinite(n) ? n : 0;
2929
3013
  }
2930
3014
  function applyUseOffsetToG(gNode) {
2931
- var _a;
3015
+ var _a2;
2932
3016
  const x = toFiniteNum(gNode.x);
2933
3017
  const y = toFiniteNum(gNode.y);
2934
3018
  delete gNode.x;
@@ -2937,7 +3021,7 @@ function applyUseOffsetToG(gNode) {
2937
3021
  const offset = "translate(" + x + "," + y + ")";
2938
3022
  const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
2939
3023
  if (carriesTransform) {
2940
- const inner = { type: "g", transform: offset, children: (_a = gNode.children) != null ? _a : [] };
3024
+ const inner = { type: "g", transform: offset, children: (_a2 = gNode.children) != null ? _a2 : [] };
2941
3025
  gNode.children = [inner];
2942
3026
  } else {
2943
3027
  gNode.transform = offset;
@@ -2945,7 +3029,7 @@ function applyUseOffsetToG(gNode) {
2945
3029
  return gNode;
2946
3030
  }
2947
3031
  function materialiseAnimatedUseInstances(root) {
2948
- var _a;
3032
+ var _a2;
2949
3033
  const idMap = buildIdMap(root);
2950
3034
  const animatedIds = computeAnimatedSubtreeIds(root, idMap);
2951
3035
  if (animatedIds.size === 0) return root;
@@ -2956,7 +3040,7 @@ function materialiseAnimatedUseInstances(root) {
2956
3040
  const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
2957
3041
  if (defsCollector.length === 0) return walked;
2958
3042
  const defsNode = { type: "defs", children: defsCollector };
2959
- const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
3043
+ const newChildren = [...(_a2 = walked.children) != null ? _a2 : [], defsNode];
2960
3044
  return __spreadProps2(__spreadValues2({}, walked), { children: newChildren });
2961
3045
  }
2962
3046
  function readRootViewport(root) {
@@ -2978,9 +3062,9 @@ function numericAttr(v) {
2978
3062
  function buildIdMap(root) {
2979
3063
  const map = /* @__PURE__ */ new Map();
2980
3064
  const visit = (n) => {
2981
- var _a;
3065
+ var _a2;
2982
3066
  if (typeof n.id === "string") map.set(n.id, n);
2983
- (_a = n.children) == null ? void 0 : _a.forEach(visit);
3067
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
2984
3068
  };
2985
3069
  visit(root);
2986
3070
  return map;
@@ -3027,11 +3111,11 @@ function stripHash(href) {
3027
3111
  return href.startsWith("#") ? href.slice(1) : href;
3028
3112
  }
3029
3113
  function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3030
- var _a, _b, _c, _d;
3114
+ var _a2, _b, _c, _d;
3031
3115
  const clone2 = deepClonePxNode(target);
3032
3116
  regenerateIdsAndRewriteRefs(clone2, genId3);
3033
3117
  const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
3034
- const useW = (_b = (_a = numericAttr(useNode.width)) != null ? _a : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
3118
+ const useW = (_b = (_a2 = numericAttr(useNode.width)) != null ? _a2 : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
3035
3119
  const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
3036
3120
  const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
3037
3121
  const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
@@ -3100,7 +3184,7 @@ function partsRecord(part, value, origin) {
3100
3184
  return rec;
3101
3185
  }
3102
3186
  function readAnimatable(raw) {
3103
- var _a, _b, _c;
3187
+ var _a2, _b;
3104
3188
  if (raw === void 0) return {
3105
3189
  kind: "absent"
3106
3190
  /* Absent */
@@ -3108,20 +3192,20 @@ function readAnimatable(raw) {
3108
3192
  if (Array.isArray(raw)) return { kind: "static", value: raw };
3109
3193
  if (typeof raw === "object") {
3110
3194
  const obj = raw;
3111
- const kfs = (_a = obj.keyframes) != null ? _a : obj.kfs;
3195
+ const kfs = obj.keyframes;
3112
3196
  if (kfs) {
3113
3197
  const out = { kind: "animated", keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
3114
- const base = (_b = obj.value) != null ? _b : obj.v;
3198
+ const base = (_a2 = obj.value) != null ? _a2 : obj.v;
3115
3199
  if (base !== void 0 && out.kind === "animated") out.base = base;
3116
3200
  return out;
3117
3201
  }
3118
- const staticValue = (_c = obj.value) != null ? _c : obj.v;
3202
+ const staticValue = (_b = obj.value) != null ? _b : obj.v;
3119
3203
  if (staticValue !== void 0) return { kind: "static", value: staticValue };
3120
3204
  }
3121
3205
  return { kind: "static", value: raw };
3122
3206
  }
3123
3207
  function writeAnimatableChannel(node, attrName, read, opts) {
3124
- var _a, _b, _c, _d;
3208
+ var _a2, _b, _c, _d;
3125
3209
  const toOut = (v) => (opts == null ? void 0 : opts.asString) && v !== void 0 && v !== null ? String(v) : v;
3126
3210
  if (read.kind === "absent") return;
3127
3211
  if (read.kind === "static") {
@@ -3135,7 +3219,7 @@ function writeAnimatableChannel(node, attrName, read, opts) {
3135
3219
  if (read.autoOrient !== void 0) block.autoOrient = read.autoOrient;
3136
3220
  animate[attrName] = block;
3137
3221
  node.animate = animate;
3138
- 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;
3222
+ 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;
3139
3223
  if (baseline !== void 0) node[attrName] = toOut(baseline);
3140
3224
  }
3141
3225
  function normaliseKeyframe(kf) {
@@ -3153,12 +3237,12 @@ function normaliseKeyframe(kf) {
3153
3237
  return out;
3154
3238
  }
3155
3239
  function readStaticOrigin(raw, ctx) {
3156
- var _a;
3240
+ var _a2;
3157
3241
  const o = readAnimatable(raw);
3158
3242
  if (o.kind === "absent") return void 0;
3159
3243
  if (o.kind === "static") return o.value;
3160
3244
  ctx.warnings.push("transformBy.origin: animated origin approximated by its first keyframe");
3161
- return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
3245
+ return (_a2 = o.keyframes[0]) == null ? void 0 : _a2.value;
3162
3246
  }
3163
3247
  function keyframeWith(kf, value) {
3164
3248
  const out = { value };
@@ -3264,9 +3348,9 @@ function stripHash2(href) {
3264
3348
  return typeof href === "string" ? href.replace(/^#/, "") : void 0;
3265
3349
  }
3266
3350
  function indexById(node, map) {
3267
- var _a;
3351
+ var _a2;
3268
3352
  if (typeof node.id === "string") map.set(node.id, node);
3269
- (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
3353
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((child) => indexById(child, map));
3270
3354
  }
3271
3355
  function spliceDefs(root, defs) {
3272
3356
  if (!defs.length) return;
@@ -3278,9 +3362,9 @@ function regenerateIdsInClone(root, ctx) {
3278
3362
  return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
3279
3363
  }
3280
3364
  function identifyContentRefTargets(node, ctx, allocator) {
3281
- var _a, _b, _c;
3282
- if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.type) === "content") {
3283
- const sourceId = stripHash2(node.effects.clone.sourceId);
3365
+ var _a2, _b, _c;
3366
+ if (node.type === "use" && ((_b = (_a2 = node.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.without) === "translate") {
3367
+ const sourceId = stripHash2(node.effects.clone.source);
3284
3368
  if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
3285
3369
  ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
3286
3370
  }
@@ -3305,10 +3389,10 @@ function splitForContentRef(node, transformBy, originalId, innerId, ctx) {
3305
3389
  return outerWrapper;
3306
3390
  }
3307
3391
  function liftBodyTranslate(node, transformBy) {
3308
- var _a, _b, _c;
3392
+ var _a2, _b, _c;
3309
3393
  const out = {};
3310
3394
  let didLiftAnimate = false;
3311
- const animTr = (_a = node.animate) == null ? void 0 : _a.transform;
3395
+ const animTr = (_a2 = node.animate) == null ? void 0 : _a2.transform;
3312
3396
  if (animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes)) {
3313
3397
  const kfs = animTr.keyframes;
3314
3398
  const hasTranslate = kfs.some((kf) => kf.value && kf.value.translate);
@@ -3524,7 +3608,7 @@ function synthesiseGradientDef(fx, id, ctx) {
3524
3608
  return out;
3525
3609
  }
3526
3610
  function applyGeomVec(out, xAttr, yAttr, raw) {
3527
- var _a, _b, _c;
3611
+ var _a2, _b, _c;
3528
3612
  const read = readAnimatable(raw);
3529
3613
  if (read.kind === "absent") return;
3530
3614
  if (read.kind === "static") {
@@ -3543,7 +3627,7 @@ function applyGeomVec(out, xAttr, yAttr, raw) {
3543
3627
  if (read.loop !== void 0) block.loop = read.loop;
3544
3628
  return block;
3545
3629
  };
3546
- const animate = (_a = out.animate) != null ? _a : {};
3630
+ const animate = (_a2 = out.animate) != null ? _a2 : {};
3547
3631
  animate[xAttr] = axisChannel(0);
3548
3632
  animate[yAttr] = axisChannel(1);
3549
3633
  out.animate = animate;
@@ -3559,7 +3643,7 @@ function applyGeomNumber(out, attrName, raw) {
3559
3643
  writeAnimatableChannel(out, attrName, read, { asString: true });
3560
3644
  }
3561
3645
  function buildStopChildren(stops, ctx) {
3562
- var _a, _b, _c, _d;
3646
+ var _a2, _b;
3563
3647
  if (!stops) return [];
3564
3648
  const read = readAnimatable(stops);
3565
3649
  if (read.kind === "absent") return [];
@@ -3569,14 +3653,14 @@ function buildStopChildren(stops, ctx) {
3569
3653
  const loopFromSource = read.loop;
3570
3654
  let stopCount = 0;
3571
3655
  for (const kf of kfs) {
3572
- const v = (_a = kf.value) != null ? _a : kf.v;
3656
+ const v = kfValue(kf);
3573
3657
  if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;
3574
3658
  }
3575
3659
  if (!stopCount) return [];
3576
- const firstKfValue = (_b = kfs[0].value) != null ? _b : kfs[0].v;
3660
+ const firstKfValue = kfValue(kfs[0]);
3577
3661
  const baselineStops = [];
3578
3662
  for (let i = 0; i < stopCount; i++) {
3579
- const s = (_d = (_c = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _c : prevDefinedStop(kfs, 0, i)) != null ? _d : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
3663
+ 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" };
3580
3664
  baselineStops.push({ offset: s.offset, color: s.color });
3581
3665
  }
3582
3666
  return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));
@@ -3589,16 +3673,16 @@ function staticStopNode(s) {
3589
3673
  };
3590
3674
  }
3591
3675
  function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
3592
- var _a, _b, _c, _d, _e;
3676
+ var _a2;
3593
3677
  const colorKfs = [];
3594
3678
  const offsetKfs = [];
3595
3679
  let offsetVaries = false;
3596
3680
  for (const kf of kfs) {
3597
- const t = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
3598
- const arr = (_c = kf.value) != null ? _c : kf.v;
3599
- const sliced = (_d = arr == null ? void 0 : arr[stopIdx]) != null ? _d : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
3681
+ const t = kfTime(kf);
3682
+ const arr = kfValue(kf);
3683
+ const sliced = (_a2 = arr == null ? void 0 : arr[stopIdx]) != null ? _a2 : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
3600
3684
  if (!sliced) continue;
3601
- const easing = (_e = kf.easing) != null ? _e : kf.e;
3685
+ const easing = kfEasing(kf);
3602
3686
  const colorOut = { time: t, value: sliced.color };
3603
3687
  if (easing !== void 0) colorOut.easing = easing;
3604
3688
  colorKfs.push(colorOut);
@@ -3625,13 +3709,12 @@ function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
3625
3709
  return stop;
3626
3710
  }
3627
3711
  function prevDefinedStop(kfs, fromIdx, stopIdx) {
3628
- var _a, _b;
3629
3712
  for (let i = fromIdx; i >= 0; i--) {
3630
- const arr = (_a = kfs[i].value) != null ? _a : kfs[i].v;
3713
+ const arr = kfValue(kfs[i]);
3631
3714
  if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
3632
3715
  }
3633
3716
  for (let i = fromIdx + 1; i < kfs.length; i++) {
3634
- const arr = (_b = kfs[i].value) != null ? _b : kfs[i].v;
3717
+ const arr = kfValue(kfs[i]);
3635
3718
  if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
3636
3719
  }
3637
3720
  return void 0;
@@ -3664,9 +3747,9 @@ function pathString(v) {
3664
3747
  }
3665
3748
  function applyMaskedByEffect(node, fx, transformBy, ctx) {
3666
3749
  if (!fx) return node;
3667
- const sourceId = stripHash2(fx.sourceId);
3750
+ const sourceId = stripHash2(fx.source);
3668
3751
  if (!sourceId) {
3669
- ctx.errors.push("maskedBy.sourceId missing \u2014 cannot build mask");
3752
+ ctx.errors.push("maskedBy.source missing \u2014 cannot build mask");
3670
3753
  return node;
3671
3754
  }
3672
3755
  const maskId = genId(ctx, "mask");
@@ -3729,16 +3812,16 @@ function invertPartValue(part, value) {
3729
3812
  return [1 / value[0], 1 / value[1]];
3730
3813
  }
3731
3814
  function negatedSpatialTangents(kf) {
3732
- var _a, _b;
3815
+ var _a2, _b;
3733
3816
  const out = {};
3734
- const to = (_a = kf.tangentOut) != null ? _a : kf.to;
3817
+ const to = (_a2 = kf.tangentOut) != null ? _a2 : kf.to;
3735
3818
  const ti = (_b = kf.tangentIn) != null ? _b : kf.ti;
3736
3819
  if (Array.isArray(to)) out.tangentOut = [-to[0], -to[1]];
3737
3820
  if (Array.isArray(ti)) out.tangentIn = [-ti[0], -ti[1]];
3738
3821
  return out;
3739
3822
  }
3740
3823
  function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
3741
- var _a;
3824
+ var _a2;
3742
3825
  const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
3743
3826
  const animTr = animate == null ? void 0 : animate.transform;
3744
3827
  const kfs = animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes) ? animTr.keyframes : void 0;
@@ -3747,7 +3830,7 @@ function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
3747
3830
  const rotateKfs = [];
3748
3831
  const scaleKfs = [];
3749
3832
  for (const kf of kfs) {
3750
- const v = ((_a = kf.value) != null ? _a : kf.v) || {};
3833
+ const v = ((_a2 = kf.value) != null ? _a2 : kf.v) || {};
3751
3834
  const baseKf = keyframeWith(kf, void 0);
3752
3835
  if (Array.isArray(v.translate)) {
3753
3836
  translateKfs.push(__spreadProps2(__spreadValues2(__spreadValues2({}, baseKf), negatedSpatialTangents(kf)), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
@@ -3811,7 +3894,7 @@ function readTransformationFromBody(node) {
3811
3894
  return void 0;
3812
3895
  }
3813
3896
  function parseTransformStringToParts(s) {
3814
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
3897
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
3815
3898
  const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
3816
3899
  let m;
3817
3900
  const ops = [];
@@ -3825,7 +3908,7 @@ function parseTransformStringToParts(s) {
3825
3908
  for (let j = ops.length - 2; j >= 0; j--) {
3826
3909
  const cand = ops[j];
3827
3910
  if (cand.name !== "translate") continue;
3828
- const ox = (_a = cand.args[0]) != null ? _a : 0;
3911
+ const ox = (_a2 = cand.args[0]) != null ? _a2 : 0;
3829
3912
  const oy = (_b = cand.args[1]) != null ? _b : 0;
3830
3913
  const lx = (_c = last.args[0]) != null ? _c : 0;
3831
3914
  const ly = (_d = last.args[1]) != null ? _d : 0;
@@ -3940,8 +4023,8 @@ function interpKfs(kfs, t) {
3940
4023
  function collectMaskAncestorChains(root, ctx) {
3941
4024
  const interestingNodes = /* @__PURE__ */ new Set();
3942
4025
  const collectInterestingNodes = (n) => {
3943
- var _a, _b;
3944
- const maskSourceId = stripHash2((_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.sourceId);
4026
+ var _a2, _b;
4027
+ const maskSourceId = stripHash2((_b = (_a2 = n.effects) == null ? void 0 : _a2.maskedBy) == null ? void 0 : _b.source);
3945
4028
  if (typeof maskSourceId === "string") {
3946
4029
  interestingNodes.add(n);
3947
4030
  const sourceNode = ctx.idMap.get(maskSourceId);
@@ -3962,7 +4045,7 @@ function collectMaskAncestorChains(root, ctx) {
3962
4045
  walk(root, []);
3963
4046
  }
3964
4047
  function extractTranslateOnly(node, ctx) {
3965
- var _a, _b, _c;
4048
+ var _a2, _b, _c;
3966
4049
  const tr = node.transform;
3967
4050
  const animateBlock = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate.transform : void 0;
3968
4051
  if (tr === void 0 && !animateBlock) return void 0;
@@ -3970,7 +4053,7 @@ function extractTranslateOnly(node, ctx) {
3970
4053
  if (typeof tr === "string") {
3971
4054
  const parts = parseTranslateOnlyFromString(tr, ctx);
3972
4055
  if (parts) out.translate = parts;
3973
- } else if (tr && typeof tr === "object" && !tr.keyframes && !tr.kfs) {
4056
+ } else if (tr && typeof tr === "object" && !tr.keyframes) {
3974
4057
  const wrapped = tr.value;
3975
4058
  const value = wrapped && typeof wrapped === "object" ? wrapped : tr;
3976
4059
  if (value && typeof value === "object" && Array.isArray(value.translate)) {
@@ -3984,7 +4067,7 @@ function extractTranslateOnly(node, ctx) {
3984
4067
  const kfs = animateBlock.keyframes;
3985
4068
  const translateKfs = [];
3986
4069
  for (const kf of kfs) {
3987
- const v = (_a = kf.value) != null ? _a : kf.v;
4070
+ const v = (_a2 = kf.value) != null ? _a2 : kf.v;
3988
4071
  const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
3989
4072
  if (v && typeof v === "object" && Array.isArray(v.translate)) {
3990
4073
  translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });
@@ -4017,15 +4100,14 @@ function parseTranslateOnlyFromString(s, ctx) {
4017
4100
  if (droppedNonTranslate) ctx.warnings.push("maskedBy ancestor: non-translate transform in string ignored: " + s);
4018
4101
  return seen ? [x, y] : void 0;
4019
4102
  }
4020
- var CONTENT_SUBREF = "content";
4021
4103
  function applyRefHref(node, clone2, ctx) {
4022
4104
  if (!clone2) return;
4023
- const sourceId = stripHash2(clone2.sourceId);
4105
+ const sourceId = stripHash2(clone2.source);
4024
4106
  if (!sourceId) {
4025
- if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing sourceId");
4107
+ if (clone2.without === PxCloneWithout.translate) ctx.errors.push("clone: content ref missing `source`");
4026
4108
  return;
4027
4109
  }
4028
- const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
4110
+ const targetId = clone2.without === PxCloneWithout.translate ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
4029
4111
  node.href = "#" + targetId;
4030
4112
  }
4031
4113
  function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
@@ -4033,9 +4115,9 @@ function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
4033
4115
  return applyTransformByEffect(node, transformBy, ctx);
4034
4116
  }
4035
4117
  function applyRepeaterEffect(node, fx, ctx) {
4036
- var _a, _b;
4118
+ var _a2, _b;
4037
4119
  if (!fx) return node;
4038
- const copies = (_a = fx.copies) != null ? _a : 1;
4120
+ const copies = (_a2 = fx.copies) != null ? _a2 : 1;
4039
4121
  if (copies < 1) {
4040
4122
  ctx.errors.push("repeater.copies invalid: " + fx.copies);
4041
4123
  return node;
@@ -4103,8 +4185,8 @@ function synthesiseScale(raw, i) {
4103
4185
  }
4104
4186
  var RETIME_MATERIALISATION_MODE_INLINE_G = false;
4105
4187
  function asRetime(r) {
4106
- var _a, _b;
4107
- return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
4188
+ var _a2, _b;
4189
+ return { start: (_a2 = r.start) != null ? _a2 : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
4108
4190
  }
4109
4191
  var CROP_EDGE_MS = 1;
4110
4192
  function applyTimeCrop(useNode, crop, ctx) {
@@ -4132,12 +4214,12 @@ function concatRetime(child, parent) {
4132
4214
  };
4133
4215
  }
4134
4216
  function readCloneRetime(n) {
4135
- var _a, _b;
4136
- return (_b = (_a = n.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.retime;
4217
+ var _a2, _b;
4218
+ return (_b = (_a2 = n.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.retime;
4137
4219
  }
4138
4220
  function clearCloneRetime(n) {
4139
- var _a;
4140
- const clone2 = (_a = n.effects) == null ? void 0 : _a.clone;
4221
+ var _a2;
4222
+ const clone2 = (_a2 = n.effects) == null ? void 0 : _a2.clone;
4141
4223
  if (!clone2) return;
4142
4224
  delete clone2.retime;
4143
4225
  if (Object.keys(clone2).length === 0) delete n.effects.clone;
@@ -4148,9 +4230,9 @@ function applyAllRetimeEffects(root, ctx) {
4148
4230
  indexById(root, ctx.idMap);
4149
4231
  const sites = [];
4150
4232
  const collect = (n) => {
4151
- var _a;
4233
+ var _a2;
4152
4234
  if (readCloneRetime(n)) sites.push(n);
4153
- (_a = n.children) == null ? void 0 : _a.forEach(collect);
4235
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(collect);
4154
4236
  };
4155
4237
  collect(root);
4156
4238
  const reachCount = /* @__PURE__ */ new Map();
@@ -4158,7 +4240,7 @@ function applyAllRetimeEffects(root, ctx) {
4158
4240
  let count = 0;
4159
4241
  const visited = /* @__PURE__ */ new Set();
4160
4242
  const walk = (n) => {
4161
- var _a;
4243
+ var _a2;
4162
4244
  if (!n) return;
4163
4245
  if (n !== site && readCloneRetime(n)) count++;
4164
4246
  if (n.type === "use" && n.href) {
@@ -4168,7 +4250,7 @@ function applyAllRetimeEffects(root, ctx) {
4168
4250
  walk(ctx.idMap.get(id));
4169
4251
  }
4170
4252
  }
4171
- (_a = n.children) == null ? void 0 : _a.forEach(walk);
4253
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walk);
4172
4254
  };
4173
4255
  const rootId = stripHash2(site.href);
4174
4256
  if (rootId) {
@@ -4178,8 +4260,8 @@ function applyAllRetimeEffects(root, ctx) {
4178
4260
  reachCount.set(site, count);
4179
4261
  }
4180
4262
  sites.sort((a, b) => {
4181
- var _a, _b;
4182
- return ((_a = reachCount.get(b)) != null ? _a : 0) - ((_b = reachCount.get(a)) != null ? _b : 0);
4263
+ var _a2, _b;
4264
+ return ((_a2 = reachCount.get(b)) != null ? _a2 : 0) - ((_b = reachCount.get(a)) != null ? _b : 0);
4183
4265
  });
4184
4266
  for (const useNode of sites) {
4185
4267
  const retime = readCloneRetime(useNode);
@@ -4246,7 +4328,7 @@ function buildChainClone(targetId, accum, ctx, chain) {
4246
4328
  }
4247
4329
  function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4248
4330
  const visit = (n) => {
4249
- var _a;
4331
+ var _a2;
4250
4332
  const retime = readCloneRetime(n);
4251
4333
  if (n.type === "use" && retime && n.href) {
4252
4334
  const subId = stripHash2(n.href);
@@ -4259,14 +4341,14 @@ function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4259
4341
  }
4260
4342
  clearCloneRetime(n);
4261
4343
  }
4262
- (_a = n.children) == null ? void 0 : _a.forEach(visit);
4344
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
4263
4345
  };
4264
4346
  visit(node);
4265
4347
  }
4266
4348
  function remapKeyframeTimes(node, start, stretch) {
4267
- var _a;
4349
+ var _a2;
4268
4350
  remapKeyframeTimesOnly(node, start, stretch);
4269
- (_a = node.children) == null ? void 0 : _a.forEach((c) => remapKeyframeTimes(c, start, stretch));
4351
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => remapKeyframeTimes(c, start, stretch));
4270
4352
  }
4271
4353
  function remapKeyframeTimesOnly(node, start, stretch) {
4272
4354
  const remap2 = (kfs) => {
@@ -4441,8 +4523,8 @@ function numRange(v) {
4441
4523
  function estimateTextAdvance(node) {
4442
4524
  let chars = 0, maxFont = 16;
4443
4525
  const walk = (el) => {
4444
- var _a, _b;
4445
- const fs = parseFloat(String((_a = el.fontSize) != null ? _a : "")) || 0;
4526
+ var _a2, _b;
4527
+ const fs = parseFloat(String((_a2 = el.fontSize) != null ? _a2 : "")) || 0;
4446
4528
  if (fs) maxFont = Math.max(maxFont, fs);
4447
4529
  const t = (_b = el.text) != null ? _b : el.textContent;
4448
4530
  if (typeof t === "string") chars += t.length;
@@ -4466,14 +4548,14 @@ function shiftAnimatable(v, by) {
4466
4548
  return out;
4467
4549
  }
4468
4550
  function extendedPathForBrowser(pathD, opts) {
4469
- var _a;
4551
+ var _a2;
4470
4552
  if (opts.pathOverflow === "clip") return { d: pathD, startShift: 0 };
4471
4553
  const sampler = createPathSampler(pathD);
4472
4554
  if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };
4473
4555
  const L = sampler.totalLength;
4474
4556
  const margin = EXTEND_MARGIN_FRAC * L;
4475
4557
  const so = numRange(opts.startOffset);
4476
- const runWidth = numRange(opts.textLength).max || ((_a = opts.advance) != null ? _a : 0);
4558
+ const runWidth = numRange(opts.textLength).max || ((_a2 = opts.advance) != null ? _a2 : 0);
4477
4559
  const startOverflow = Math.max(0, -so.min);
4478
4560
  const endOverflow = Math.max(0, so.max + runWidth - L);
4479
4561
  const startExt = startOverflow > 0 ? startOverflow + margin : 0;
@@ -4494,10 +4576,10 @@ function extendedPathForBrowser(pathD, opts) {
4494
4576
  return { d, startShift: startExt };
4495
4577
  }
4496
4578
  function applyTextPathEffect(node, fx, ctx) {
4497
- var _a;
4498
- if (!fx || typeof fx.path !== "string" || !fx.path) return node;
4579
+ var _a2;
4580
+ if (!fx || typeof fx.pathData !== "string" || !fx.pathData) return node;
4499
4581
  const pathId = genId(ctx, "tpath");
4500
- const { d, startShift } = extendedPathForBrowser(fx.path, {
4582
+ const { d, startShift } = extendedPathForBrowser(fx.pathData, {
4501
4583
  pathOverflow: fx.pathOverflow,
4502
4584
  startOffset: fx.startOffset,
4503
4585
  textLength: fx.textLength,
@@ -4507,7 +4589,7 @@ function applyTextPathEffect(node, fx, ctx) {
4507
4589
  const textPath = {
4508
4590
  type: "textPath",
4509
4591
  href: "#" + pathId,
4510
- children: (_a = node.children) != null ? _a : []
4592
+ children: (_a2 = node.children) != null ? _a2 : []
4511
4593
  };
4512
4594
  if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
4513
4595
  if (fx.method !== void 0) textPath.method = fx.method;
@@ -4631,15 +4713,15 @@ function paintAnimateOf(node) {
4631
4713
  return out;
4632
4714
  }
4633
4715
  function resolveStyle2(node, parent) {
4634
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4716
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4635
4717
  const isTextRoot = node.type === "text";
4636
4718
  const nodeStyle = node.style;
4637
4719
  const own = (key) => {
4638
- var _a2;
4639
- return isTextRoot ? void 0 : (_a2 = node[key]) != null ? _a2 : nodeStyle == null ? void 0 : nodeStyle[key];
4720
+ var _a3;
4721
+ return isTextRoot ? void 0 : (_a3 = node[key]) != null ? _a3 : nodeStyle == null ? void 0 : nodeStyle[key];
4640
4722
  };
4641
4723
  const res = {
4642
- fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
4724
+ fontFamily: (_a2 = str(node.fontFamily)) != null ? _a2 : parent.fontFamily,
4643
4725
  fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
4644
4726
  fill: (_c = node.fill) != null ? _c : parent.fill,
4645
4727
  stroke: (_d = node.stroke) != null ? _d : parent.stroke,
@@ -4656,10 +4738,10 @@ function resolveStyle2(node, parent) {
4656
4738
  return res;
4657
4739
  }
4658
4740
  function rootStyleOf(node) {
4659
- var _a, _b, _c;
4741
+ var _a2, _b, _c;
4660
4742
  return {
4661
4743
  fontFamily: str(node.fontFamily),
4662
- fontSize: (_a = parseLen(node.fontSize)) != null ? _a : DEFAULT_FONT_SIZE,
4744
+ fontSize: (_a2 = parseLen(node.fontSize)) != null ? _a2 : DEFAULT_FONT_SIZE,
4663
4745
  fill: node.fill,
4664
4746
  stroke: node.stroke,
4665
4747
  strokeWidth: node.strokeWidth,
@@ -4680,9 +4762,9 @@ function paintOf(s) {
4680
4762
  return p;
4681
4763
  }
4682
4764
  function glyphFontFor(s, glyphs, soleFont, warnings) {
4683
- var _a;
4765
+ var _a2;
4684
4766
  const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;
4685
- if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a = s.fontFamily) != null ? _a : "") + '"');
4767
+ if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a2 = s.fontFamily) != null ? _a2 : "") + '"');
4686
4768
  return gf;
4687
4769
  }
4688
4770
  function soleFontOf(glyphs) {
@@ -4704,19 +4786,19 @@ function missingGlyphBoxEm(advanceEm, ascentEm) {
4704
4786
  return outer + "M" + ix0 + " " + iyb + "L" + ix0 + " " + iyt + "L" + ix1 + " " + iyt + "L" + ix1 + " " + iyb + "Z";
4705
4787
  }
4706
4788
  function materialiseGlyphTextHorizontal(node, opts) {
4707
- var _a, _b, _c, _d;
4789
+ var _a2, _b, _c, _d;
4708
4790
  const { glyphs, create = jsonElementFactory, warnings } = opts;
4709
4791
  const soleFont = soleFontOf(glyphs);
4710
- const pen = { x: (_a = parseLen(node.x)) != null ? _a : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
4792
+ const pen = { x: (_a2 = parseLen(node.x)) != null ? _a2 : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
4711
4793
  const placements = [];
4712
4794
  const lines = [{ start: pen.x, end: pen.x }];
4713
4795
  let line = 0;
4714
4796
  const renderChars = (content, s) => {
4715
- var _a2;
4797
+ var _a3;
4716
4798
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4717
4799
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4718
4800
  const scale = s.fontSize / upm;
4719
- const ascentEm = (_a2 = gf == null ? void 0 : gf.ascent) != null ? _a2 : 0.9 * upm;
4801
+ const ascentEm = (_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm;
4720
4802
  const paint = paintOf(s);
4721
4803
  for (let i = 0; i < content.length; i++) {
4722
4804
  const ch = content.charAt(i);
@@ -4736,7 +4818,7 @@ function materialiseGlyphTextHorizontal(node, opts) {
4736
4818
  }
4737
4819
  };
4738
4820
  const walk = (el, parentStyle) => {
4739
- var _a2, _b2, _c2, _d2;
4821
+ var _a3, _b2, _c2, _d2;
4740
4822
  const s = resolveStyle2(el, parentStyle);
4741
4823
  const x = parseLen(el.x);
4742
4824
  const y = parseLen(el.y);
@@ -4746,7 +4828,7 @@ function materialiseGlyphTextHorizontal(node, opts) {
4746
4828
  lines.push({ start: pen.x, end: pen.x });
4747
4829
  }
4748
4830
  if (y !== void 0) pen.y = y;
4749
- pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
4831
+ pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
4750
4832
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4751
4833
  const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
4752
4834
  if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
@@ -4767,8 +4849,8 @@ function materialiseGlyphTextHorizontal(node, opts) {
4767
4849
  return toGroup(node, buildPaths(placements, create, warnings), create);
4768
4850
  }
4769
4851
  function layoutGlyphTextChars(node, opts) {
4770
- var _a, _b, _c, _d, _e, _f;
4771
- if ((_a = opts.alongPath) == null ? void 0 : _a.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
4852
+ var _a2, _b, _c, _d, _e, _f;
4853
+ if ((_a2 = opts.alongPath) == null ? void 0 : _a2.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
4772
4854
  const { glyphs, warnings } = opts;
4773
4855
  const soleFont = soleFontOf(glyphs);
4774
4856
  const pen = { x: (_b = parseLen(node.x)) != null ? _b : 0, y: (_c = parseLen(node.y)) != null ? _c : 0 };
@@ -4776,11 +4858,11 @@ function layoutGlyphTextChars(node, opts) {
4776
4858
  const lines = [{ start: pen.x, end: pen.x }];
4777
4859
  let line = 0;
4778
4860
  const renderChars = (content, s) => {
4779
- var _a2;
4861
+ var _a3;
4780
4862
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4781
4863
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4782
4864
  const scale = s.fontSize / upm;
4783
- const ascent = ((_a2 = gf == null ? void 0 : gf.ascent) != null ? _a2 : 0.9 * upm) * scale;
4865
+ const ascent = ((_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm) * scale;
4784
4866
  for (let i = 0; i < content.length; i++) {
4785
4867
  const ch = content.charAt(i);
4786
4868
  const g = gf == null ? void 0 : gf.glyphs[ch];
@@ -4791,7 +4873,7 @@ function layoutGlyphTextChars(node, opts) {
4791
4873
  }
4792
4874
  };
4793
4875
  const walk = (el, parentStyle) => {
4794
- var _a2, _b2, _c2, _d2;
4876
+ var _a3, _b2, _c2, _d2;
4795
4877
  const s = resolveStyle2(el, parentStyle);
4796
4878
  const x = parseLen(el.x);
4797
4879
  const y = parseLen(el.y);
@@ -4801,7 +4883,7 @@ function layoutGlyphTextChars(node, opts) {
4801
4883
  lines.push({ start: pen.x, end: pen.x });
4802
4884
  }
4803
4885
  if (y !== void 0) pen.y = y;
4804
- pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
4886
+ pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
4805
4887
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4806
4888
  const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
4807
4889
  if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
@@ -4833,7 +4915,7 @@ function layoutGlyphTextChars(node, opts) {
4833
4915
  });
4834
4916
  }
4835
4917
  function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4836
- var _a, _b;
4918
+ var _a2, _b;
4837
4919
  const { glyphs, warnings, alongPath } = opts;
4838
4920
  const sampler = createPathSampler(pathD);
4839
4921
  if (!sampler) {
@@ -4844,9 +4926,9 @@ function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4844
4926
  const chars = [];
4845
4927
  let adv = 0;
4846
4928
  const walk = (el, parentStyle) => {
4847
- var _a2, _b2, _c;
4929
+ var _a3, _b2, _c;
4848
4930
  const s = resolveStyle2(el, parentStyle);
4849
- const content = (_a2 = str(el[TEXT_CONTENT_ATTR])) != null ? _a2 : str(el[TEXT_ATTR]);
4931
+ const content = (_a3 = str(el[TEXT_CONTENT_ATTR])) != null ? _a3 : str(el[TEXT_ATTR]);
4850
4932
  if (content && !((_b2 = el.children) == null ? void 0 : _b2.length)) {
4851
4933
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4852
4934
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
@@ -4866,7 +4948,7 @@ function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4866
4948
  walk(node, rootStyleOf(node));
4867
4949
  const width = adv;
4868
4950
  const tlr = readAnimatable(alongPath == null ? void 0 : alongPath.textLength);
4869
- const tlv = tlr.kind === "animated" ? Number((_a = tlr.keyframes[0]) == null ? void 0 : _a.value) || 0 : tlr.kind === "static" ? Number(tlr.value) || 0 : 0;
4951
+ const tlv = tlr.kind === "animated" ? Number((_a2 = tlr.keyframes[0]) == null ? void 0 : _a2.value) || 0 : tlr.kind === "static" ? Number(tlr.value) || 0 : 0;
4870
4952
  const k = tlv > 0 && width > 0 ? tlv / width : 1;
4871
4953
  const so = readAnimatable(alongPath == null ? void 0 : alongPath.startOffset);
4872
4954
  const { along: alongOffset, perp } = alongPathNodeOffsets(node);
@@ -4898,9 +4980,9 @@ function collectAlongPathCells(node, glyphs, soleFont, warnings) {
4898
4980
  const cells = [];
4899
4981
  let adv = 0;
4900
4982
  const walk = (el, parentStyle) => {
4901
- var _a, _b, _c;
4983
+ var _a2, _b, _c;
4902
4984
  const s = resolveStyle2(el, parentStyle);
4903
- const content = (_a = str(el[TEXT_CONTENT_ATTR])) != null ? _a : str(el[TEXT_ATTR]);
4985
+ const content = (_a2 = str(el[TEXT_CONTENT_ATTR])) != null ? _a2 : str(el[TEXT_ATTR]);
4904
4986
  if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
4905
4987
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4906
4988
  if (gf) {
@@ -4937,9 +5019,9 @@ function alongAffine(sampler, dist, scale, widthEm, perp = 0) {
4937
5019
  return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw - perp * sin, y - scale * sin * hw + perp * cos];
4938
5020
  }
4939
5021
  function alongPathNodeOffsets(node) {
4940
- var _a, _b, _c;
5022
+ var _a2, _b, _c;
4941
5023
  return {
4942
- along: ((_a = parseLen(node.x)) != null ? _a : 0) + ((_b = parseLen(node.dx)) != null ? _b : 0),
5024
+ along: ((_a2 = parseLen(node.x)) != null ? _a2 : 0) + ((_b = parseLen(node.dx)) != null ? _b : 0),
4943
5025
  perp: (_c = parseLen(node.dy)) != null ? _c : 0
4944
5026
  };
4945
5027
  }
@@ -4979,7 +5061,7 @@ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLengt
4979
5061
  return toGroup(node, buildPaths(placements, create, warnings), create);
4980
5062
  }
4981
5063
  function numTrackOf(raw) {
4982
- var _a;
5064
+ var _a2;
4983
5065
  const r = readAnimatable(raw);
4984
5066
  if (r.kind === "animated" && r.keyframes.length >= 2) {
4985
5067
  const kfs = [...r.keyframes].sort((k1, k2) => (Number(k1.time) || 0) - (Number(k2.time) || 0));
@@ -5002,7 +5084,7 @@ function numTrackOf(raw) {
5002
5084
  }
5003
5085
  };
5004
5086
  }
5005
- const v = r.kind === "animated" ? Number((_a = r.keyframes[0]) == null ? void 0 : _a.value) || 0 : r.kind === "static" ? Number(r.value) || 0 : 0;
5087
+ const v = r.kind === "animated" ? Number((_a2 = r.keyframes[0]) == null ? void 0 : _a2.value) || 0 : r.kind === "static" ? Number(r.value) || 0 : 0;
5006
5088
  return { animated: false, times: [], at: () => v };
5007
5089
  }
5008
5090
  function mergeTrackTimes(a, b) {
@@ -5084,7 +5166,7 @@ function paintProps(paint) {
5084
5166
  return p;
5085
5167
  }
5086
5168
  function missingGlyphProps(isMissing) {
5087
- return isMissing ? { class: MISSING_GLYPH_CLASS_NAME } : {};
5169
+ return isMissing ? { [CLASS_ATTR]: MISSING_GLYPH_CLASS_NAME } : {};
5088
5170
  }
5089
5171
  function buildPaths(placements, create, warnings) {
5090
5172
  if (!placements.length) {
@@ -5128,14 +5210,14 @@ function materialiseGlyphText(node, opts) {
5128
5210
  function applyTextGlyphsEffect(node, fx, ctx) {
5129
5211
  if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
5130
5212
  if (!ctx.glyphs) {
5131
- ctx.warnings.push("textGlyphs: no definitions.glyphs \u2014 left as native <text>");
5213
+ ctx.warnings.push("textGlyphs: no definitions.fonts \u2014 left as native <text>");
5132
5214
  return node;
5133
5215
  }
5134
5216
  return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
5135
5217
  }
5136
5218
  function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pathOverflow) {
5137
5219
  if (!ctx.glyphs) {
5138
- ctx.warnings.push("textGlyphs: no definitions.glyphs");
5220
+ ctx.warnings.push("textGlyphs: no definitions.fonts");
5139
5221
  return null;
5140
5222
  }
5141
5223
  return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
@@ -5275,12 +5357,11 @@ function getOffsetIndexRange(minMaxOffset) {
5275
5357
  ];
5276
5358
  }
5277
5359
  function readScalarValues(r) {
5278
- var _a;
5279
5360
  if (r.kind === "absent") return [];
5280
5361
  if (r.kind === "static") return [r.value];
5281
5362
  const out = [];
5282
5363
  for (const kf of r.keyframes) {
5283
- const v = (_a = kf.value) != null ? _a : kf.v;
5364
+ const v = kfValue(kf);
5284
5365
  if (typeof v === "number") out.push(v);
5285
5366
  }
5286
5367
  return out;
@@ -5290,14 +5371,11 @@ function computeAnimAttr(read, map) {
5290
5371
  if (read.kind === "static") return { kind: "static", value: map(read.value) };
5291
5372
  return {
5292
5373
  kind: "animated",
5293
- keyframes: read.keyframes.map((kf) => {
5294
- var _a, _b, _c, _d;
5295
- return {
5296
- time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
5297
- value: map((_c = kf.value) != null ? _c : kf.v),
5298
- easing: (_d = kf.easing) != null ? _d : kf.e
5299
- };
5300
- }),
5374
+ keyframes: read.keyframes.map((kf) => ({
5375
+ time: kfTime(kf),
5376
+ value: map(kfValue(kf)),
5377
+ easing: kfEasing(kf)
5378
+ })),
5301
5379
  loop: read.loop
5302
5380
  };
5303
5381
  }
@@ -5307,7 +5385,6 @@ function applyAttr(node, attrName, attr) {
5307
5385
  }
5308
5386
  var OPACITY_STEP_MS = 10;
5309
5387
  function computeOpacityFromRange(rangeRead) {
5310
- var _a, _b, _c, _d, _e, _f;
5311
5388
  const hide = (v) => v[0] === v[1];
5312
5389
  if (rangeRead.kind === "absent") return void 0;
5313
5390
  if (rangeRead.kind === "static") return hide(rangeRead.value) ? { kind: "static", value: 0 } : void 0;
@@ -5315,7 +5392,7 @@ function computeOpacityFromRange(rangeRead) {
5315
5392
  let anyHide = false;
5316
5393
  let allHide = true;
5317
5394
  for (const kf of kfs) {
5318
- if (hide((_a = kf.value) != null ? _a : kf.v)) anyHide = true;
5395
+ if (hide(kfValue(kf))) anyHide = true;
5319
5396
  else allHide = false;
5320
5397
  }
5321
5398
  if (!anyHide) return void 0;
@@ -5325,10 +5402,10 @@ function computeOpacityFromRange(rangeRead) {
5325
5402
  const kf = kfs[i];
5326
5403
  const prevKf = i > 0 ? kfs[i - 1] : void 0;
5327
5404
  const nextKf = i < kfs.length - 1 ? kfs[i + 1] : void 0;
5328
- const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
5329
- const thisHide = hide((_d = kf.value) != null ? _d : kf.v);
5330
- const prevHide = prevKf ? thisHide && hide((_e = prevKf.value) != null ? _e : prevKf.v) : thisHide;
5331
- const nextHide = nextKf ? thisHide && hide((_f = nextKf.value) != null ? _f : nextKf.v) : thisHide;
5405
+ const t = kfTime(kf);
5406
+ const thisHide = hide(kfValue(kf));
5407
+ const prevHide = prevKf ? thisHide && hide(kfValue(prevKf)) : thisHide;
5408
+ const nextHide = nextKf ? thisHide && hide(kfValue(nextKf)) : thisHide;
5332
5409
  if (prevHide && !nextHide) {
5333
5410
  out.push({ time: t, value: 0 });
5334
5411
  out.push({ time: t + OPACITY_STEP_MS, value: 1 });
@@ -5343,14 +5420,11 @@ function computeOpacityFromRange(rangeRead) {
5343
5420
  function readRangeWithCrossings(raw) {
5344
5421
  const r = readAnimatable(raw);
5345
5422
  if (r.kind !== "animated") return r;
5346
- const kfs = r.keyframes.map((kf) => {
5347
- var _a, _b, _c, _d;
5348
- return {
5349
- time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
5350
- value: (_c = kf.value) != null ? _c : kf.v,
5351
- easing: (_d = kf.easing) != null ? _d : kf.e
5352
- };
5353
- });
5423
+ const kfs = r.keyframes.map((kf) => ({
5424
+ time: kfTime(kf),
5425
+ value: kfValue(kf),
5426
+ easing: kfEasing(kf)
5427
+ }));
5354
5428
  const hasReverse = kfs.some((kf) => kf.value[0] > kf.value[1]);
5355
5429
  if (!hasReverse) {
5356
5430
  return {
@@ -5447,20 +5521,20 @@ function pxBezierPathLength(path) {
5447
5521
  return total;
5448
5522
  }
5449
5523
  function segmentLength(path, from, to) {
5450
- var _a, _b, _c, _d;
5524
+ var _a2, _b, _c, _d;
5451
5525
  const v = path.v;
5452
5526
  const p0 = v[from];
5453
5527
  const p3 = v[to];
5454
- const p1 = (_b = (_a = path.o) == null ? void 0 : _a[from]) != null ? _b : p0;
5528
+ const p1 = (_b = (_a2 = path.o) == null ? void 0 : _a2[from]) != null ? _b : p0;
5455
5529
  const p2 = (_d = (_c = path.i) == null ? void 0 : _c[to]) != null ? _d : p3;
5456
5530
  const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);
5457
5531
  return lut.ds[lut.ds.length - 1];
5458
5532
  }
5459
5533
  var ARC_KAPPA = 0.5522847498307936;
5460
5534
  function shapeToPathD(node) {
5461
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5535
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5462
5536
  if (node.type === "rect") {
5463
- const x = Number((_a = node.x) != null ? _a : 0), y = Number((_b = node.y) != null ? _b : 0);
5537
+ const x = Number((_a2 = node.x) != null ? _a2 : 0), y = Number((_b = node.y) != null ? _b : 0);
5464
5538
  const w = Number((_c = node.width) != null ? _c : 0), h = Number((_d = node.height) != null ? _d : 0);
5465
5539
  return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
5466
5540
  }
@@ -5476,7 +5550,7 @@ function shapeToPathD(node) {
5476
5550
  return void 0;
5477
5551
  }
5478
5552
  function applyPlayerEffects(root) {
5479
- var _a, _b;
5553
+ var _a2, _b;
5480
5554
  const ctx = {
5481
5555
  defs: [],
5482
5556
  warnings: [],
@@ -5487,8 +5561,8 @@ function applyPlayerEffects(root) {
5487
5561
  maskAncestorChains: /* @__PURE__ */ new Map(),
5488
5562
  // Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
5489
5563
  // waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
5490
- engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi,
5491
- glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
5564
+ engine: resolveTimelineEngine((_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.engine),
5565
+ glyphs: (_b = getDefs(root)) == null ? void 0 : _b.fonts
5492
5566
  };
5493
5567
  const working = clone(root);
5494
5568
  indexById(working, ctx.idMap);
@@ -5511,7 +5585,7 @@ function applyPlayerEffects_exceptRetime(node, ctx) {
5511
5585
  let consumedByGlyphs = false;
5512
5586
  if (text == null ? void 0 : text.useGlyphs) {
5513
5587
  if (textPath) {
5514
- const pathD = typeof textPath.path === "string" ? textPath.path : void 0;
5588
+ const pathD = typeof textPath.pathData === "string" ? textPath.pathData : void 0;
5515
5589
  const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textPath.startOffset, textPath.textLength, textPath.pathOverflow);
5516
5590
  if (glyphed) {
5517
5591
  n = glyphed;
@@ -5543,26 +5617,6 @@ function applyPlayerEffects_retime(node, ctx) {
5543
5617
  applyAllRetimeEffects(node, ctx);
5544
5618
  return node;
5545
5619
  }
5546
- var kfTime = (kf) => {
5547
- var _a, _b;
5548
- return (_b = (_a = kf.t) != null ? _a : kf.time) != null ? _b : 0;
5549
- };
5550
- var kfValue = (kf) => {
5551
- var _a;
5552
- return (_a = kf.v) != null ? _a : kf.value;
5553
- };
5554
- var kfEasing = (kf) => {
5555
- var _a;
5556
- return (_a = kf.e) != null ? _a : kf.easing;
5557
- };
5558
- var kfTangentIn = (kf) => {
5559
- var _a;
5560
- return (_a = kf.tangentIn) != null ? _a : kf.ti;
5561
- };
5562
- var kfTangentOut = (kf) => {
5563
- var _a;
5564
- return (_a = kf.tangentOut) != null ? _a : kf.to;
5565
- };
5566
5620
  function cubicAt(p0, c1, c2, p1, t) {
5567
5621
  const u = 1 - t;
5568
5622
  const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
@@ -5586,7 +5640,7 @@ var fmt2 = (n) => {
5586
5640
  return Object.is(r, -0) ? "0" : String(r);
5587
5641
  };
5588
5642
  function buildOffsetPath(propAnim) {
5589
- var _a, _b, _c;
5643
+ var _a2, _b, _c;
5590
5644
  if (propAnim.alongPathMode !== "offsetPath") return void 0;
5591
5645
  const kfs = propAnim.keyframes;
5592
5646
  if (!kfs || kfs.length < 2) return void 0;
@@ -5599,7 +5653,7 @@ function buildOffsetPath(propAnim) {
5599
5653
  if (!tr || tr.length < 2) return void 0;
5600
5654
  const parts = Object.keys(v);
5601
5655
  if (parts.some((p) => p !== "translate" && p !== "origin")) return void 0;
5602
- const o = (_a = v == null ? void 0 : v.origin) != null ? _a : [0, 0];
5656
+ const o = (_a2 = v == null ? void 0 : v.origin) != null ? _a2 : [0, 0];
5603
5657
  if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
5604
5658
  points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
5605
5659
  }
@@ -5630,7 +5684,7 @@ function buildOffsetPath(propAnim) {
5630
5684
  }
5631
5685
  function materialiseOffsetPathsInTree(root) {
5632
5686
  const walk = (node) => {
5633
- var _a;
5687
+ var _a2;
5634
5688
  let out = node;
5635
5689
  const anim = node.animate;
5636
5690
  const transform = anim == null ? void 0 : anim["transform"];
@@ -5638,16 +5692,16 @@ function materialiseOffsetPathsInTree(root) {
5638
5692
  const built = buildOffsetPath(transform);
5639
5693
  if (built) {
5640
5694
  const newAnimate = __spreadValues2({}, anim);
5641
- delete newAnimate["transform"];
5695
+ delete newAnimate[TRANSFORM_ATTR];
5642
5696
  const distance = { keyframes: built.distanceKfs };
5643
5697
  if (transform.loop !== void 0) distance.loop = transform.loop;
5644
- newAnimate["offsetDistance"] = distance;
5698
+ newAnimate[OFFSET_DISTANCE_ATTR] = distance;
5645
5699
  const staticTr = node.transform;
5646
5700
  let newTransform = staticTr;
5647
5701
  if (staticTr && typeof staticTr === "object") {
5648
5702
  const t = __spreadValues2({}, staticTr);
5649
- delete t["translate"];
5650
- delete t["origin"];
5703
+ delete t[TRANSFORM_PART.translate];
5704
+ delete t[TRANSFORM_PART.origin];
5651
5705
  newTransform = Object.keys(t).length ? t : void 0;
5652
5706
  }
5653
5707
  out = __spreadProps2(__spreadValues2({}, node), {
@@ -5663,7 +5717,7 @@ function materialiseOffsetPathsInTree(root) {
5663
5717
  else delete out.transform;
5664
5718
  }
5665
5719
  }
5666
- if ((_a = out.children) == null ? void 0 : _a.length) {
5720
+ if ((_a2 = out.children) == null ? void 0 : _a2.length) {
5667
5721
  const children = out.children.map(walk);
5668
5722
  if (children.some((c, i) => c !== out.children[i])) out = __spreadProps2(__spreadValues2({}, out), { children });
5669
5723
  }
@@ -5672,12 +5726,12 @@ function materialiseOffsetPathsInTree(root) {
5672
5726
  return walk(root);
5673
5727
  }
5674
5728
  function materialiseAllInTree(doc, engine, opts) {
5675
- var _a, _b;
5729
+ var _a2, _b;
5676
5730
  let root = applyPlayerEffects(doc).root;
5677
5731
  root = materialiseOffsetPathsInTree(root);
5678
- const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
5732
+ const duration = (_b = (_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.duration) != null ? _b : DEFAULT_DURATION_MS;
5679
5733
  root = materialiseInternalLoopsInTree(root, duration);
5680
- if (engine === PxAnimatorEngine.waapi) {
5734
+ if (engine === PxTimelineEngine.native) {
5681
5735
  root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
5682
5736
  root = materialiseAnimatedUseInstances(root);
5683
5737
  root = pruneUnreferencedDefs(root);
@@ -5687,9 +5741,9 @@ function materialiseAllInTree(doc, engine, opts) {
5687
5741
  function pruneUnreferencedDefs(root) {
5688
5742
  const stripHash3 = (h) => h.startsWith("#") ? h.slice(1) : h;
5689
5743
  const walk = (n, fn) => {
5690
- var _a;
5744
+ var _a2;
5691
5745
  fn(n);
5692
- (_a = n.children) == null ? void 0 : _a.forEach((c) => walk(c, fn));
5746
+ (_a2 = n.children) == null ? void 0 : _a2.forEach((c) => walk(c, fn));
5693
5747
  };
5694
5748
  let changed = true;
5695
5749
  while (changed) {
@@ -5727,9 +5781,9 @@ function cancelFrame(handle) {
5727
5781
  g.clearTimeout(handle);
5728
5782
  }
5729
5783
  function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5730
- var _a;
5784
+ var _a2;
5731
5785
  const config = getAnimatorConfig(doc) || {};
5732
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);
5786
+ const bindings = getNormalisedBindings(doc, PxTimelineEngine.js);
5733
5787
  const _iterations = config.iterations;
5734
5788
  let iterations = 1;
5735
5789
  if (typeof _iterations === "number") iterations = _iterations || 1;
@@ -5738,7 +5792,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5738
5792
  const duration = +(config.duration || DEFAULT_DURATION_MS);
5739
5793
  const totalDuration = duration && iterations ? duration * (iterations === Infinity ? Infinity : iterations) : duration ? (iterations != null ? iterations : 1) * duration : 0;
5740
5794
  const direction = config.direction || "normal";
5741
- const fill = (_a = config.fill) != null ? _a : "forwards";
5795
+ const fill = (_a2 = config.fill) != null ? _a2 : "forwards";
5742
5796
  const fillsForwards = fill === "forwards" || fill === "both";
5743
5797
  const fillsBackwards = fill === "backwards" || fill === "both";
5744
5798
  let timerId = null;
@@ -5800,7 +5854,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5800
5854
  }
5801
5855
  }
5802
5856
  const tick = () => {
5803
- var _a2, _b;
5857
+ var _a3, _b;
5804
5858
  if (!adapter.isConnected()) {
5805
5859
  pauseAnim();
5806
5860
  return;
@@ -5816,7 +5870,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5816
5870
  renderFrame(0);
5817
5871
  if (!finishCalled) {
5818
5872
  finishCalled = true;
5819
- (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
5873
+ (_a3 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
5820
5874
  }
5821
5875
  return;
5822
5876
  }
@@ -5908,17 +5962,17 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5908
5962
  }
5909
5963
  };
5910
5964
  const cancelAnim = () => {
5911
- var _a2;
5965
+ var _a3;
5912
5966
  pauseAnim();
5913
5967
  timeBeforeLastStartMs = 0;
5914
5968
  lastStartedTs = 0;
5915
5969
  playing = false;
5916
5970
  finishCalled = false;
5917
5971
  renderFrame(timeBeforeLastStartMs);
5918
- (_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
5972
+ (_a3 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a3.call(callbacks);
5919
5973
  };
5920
5974
  const finishAnim = (callOnFinish = true) => {
5921
- var _a2;
5975
+ var _a3;
5922
5976
  if (Number.isFinite(totalDuration)) {
5923
5977
  timeBeforeLastStartMs = totalDuration;
5924
5978
  } else {
@@ -5933,7 +5987,7 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5933
5987
  renderFrame(fillsForwards ? timeBeforeLastStartMs : 0);
5934
5988
  if (callOnFinish && !finishCalled) {
5935
5989
  finishCalled = true;
5936
- (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
5990
+ (_a3 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
5937
5991
  }
5938
5992
  };
5939
5993
  const api = {
@@ -5943,14 +5997,14 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5943
5997
  return _isPlaying();
5944
5998
  },
5945
5999
  "play": () => {
5946
- var _a2;
6000
+ var _a3;
5947
6001
  startAnim();
5948
- (_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
6002
+ (_a3 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a3.call(callbacks);
5949
6003
  },
5950
6004
  "pause": () => {
5951
- var _a2;
6005
+ var _a3;
5952
6006
  pauseAnim();
5953
- (_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
6007
+ (_a3 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a3.call(callbacks);
5954
6008
  },
5955
6009
  "cancel": () => {
5956
6010
  cancelAnim();
@@ -5982,9 +6036,9 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5982
6036
  renderFrame(getAnimCurrentTime());
5983
6037
  },
5984
6038
  "destroy": () => {
5985
- var _a2;
6039
+ var _a3;
5986
6040
  api.cancel();
5987
- (_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
6041
+ (_a3 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
5988
6042
  }
5989
6043
  };
5990
6044
  return api;
@@ -6038,9 +6092,9 @@ function lerp(a, b, f) {
6038
6092
  return a + (b - a) * f;
6039
6093
  }
6040
6094
  function interpParts(kfs, t) {
6041
- var _a, _b, _c, _d, _e, _f, _g;
6095
+ var _a2, _b, _c, _d, _e, _f, _g;
6042
6096
  if (!kfs.length) return {};
6043
- if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value || {};
6097
+ if (t <= ((_a2 = kfs[0].time) != null ? _a2 : 0)) return kfs[0].value || {};
6044
6098
  if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value || {};
6045
6099
  let i = 0;
6046
6100
  while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
@@ -6071,10 +6125,10 @@ function nodeMatrix(node, t) {
6071
6125
  return IDENTITY;
6072
6126
  }
6073
6127
  function evalScalar(animated, staticVal, fallback, t) {
6074
- var _a, _b, _c, _d, _e, _f;
6128
+ var _a2, _b, _c, _d, _e, _f;
6075
6129
  if (animated && animated.keyframes && animated.keyframes.length) {
6076
6130
  const kfs = animated.keyframes;
6077
- if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value;
6131
+ if (t <= ((_a2 = kfs[0].time) != null ? _a2 : 0)) return kfs[0].value;
6078
6132
  if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value;
6079
6133
  let i = 0;
6080
6134
  while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
@@ -6087,9 +6141,9 @@ function evalScalar(animated, staticVal, fallback, t) {
6087
6141
  var CONTAINER_TYPES = /* @__PURE__ */ new Set(["svg", "g", "symbol"]);
6088
6142
  var SKIP_TYPES = /* @__PURE__ */ new Set(["defs", "mask", "clipPath", "title"]);
6089
6143
  function buildIdMap2(node, map) {
6090
- var _a;
6144
+ var _a2;
6091
6145
  if (typeof node.id === "string") map.set(node.id, node);
6092
- (_a = node.children) == null ? void 0 : _a.forEach((c) => buildIdMap2(c, map));
6146
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => buildIdMap2(c, map));
6093
6147
  }
6094
6148
  function num(v) {
6095
6149
  return v === void 0 || v === null ? 0 : Number(v);
@@ -6098,7 +6152,7 @@ function round(n) {
6098
6152
  return Math.round(n * 100) / 100 + 0;
6099
6153
  }
6100
6154
  function geomKey(node) {
6101
- var _a;
6155
+ var _a2;
6102
6156
  switch (node.type) {
6103
6157
  case "rect":
6104
6158
  return num(node.width) + "," + num(node.height) + "," + num(node.x) + "," + num(node.y);
@@ -6107,14 +6161,14 @@ function geomKey(node) {
6107
6161
  case "circle":
6108
6162
  return num(node.r) + "," + num(node.cx) + "," + num(node.cy);
6109
6163
  case "path":
6110
- return String((_a = node.d) != null ? _a : "");
6164
+ return String((_a2 = node.d) != null ? _a2 : "");
6111
6165
  default:
6112
6166
  return "";
6113
6167
  }
6114
6168
  }
6115
6169
  function describePrimitive(node, m, t) {
6116
- var _a, _b, _c, _d, _e;
6117
- const fill = (_a = node.fill) != null ? _a : "";
6170
+ var _a2, _b, _c, _d, _e;
6171
+ const fill = (_a2 = node.fill) != null ? _a2 : "";
6118
6172
  const stroke = (_b = node.stroke) != null ? _b : "";
6119
6173
  const sw = (_d = (_c = node["stroke-width"]) != null ? _c : node.strokeWidth) != null ? _d : "";
6120
6174
  const opacity = round(evalScalar((_e = node.animate) == null ? void 0 : _e.opacity, node.opacity, 1, t));
@@ -6123,7 +6177,7 @@ function describePrimitive(node, m, t) {
6123
6177
  return node.type + "|" + geomKey(node) + "|[" + mat + "]|f:" + fill + "|s:" + stroke + "|sw:" + (num(sw) || "") + "|o:" + opacity + "|m:" + masked;
6124
6178
  }
6125
6179
  function flatten(node, parent, t, idMap, out) {
6126
- var _a;
6180
+ var _a2;
6127
6181
  const type = node.type || "";
6128
6182
  if (SKIP_TYPES.has(type)) return;
6129
6183
  const m = mul(parent, nodeMatrix(node, t));
@@ -6136,33 +6190,33 @@ function flatten(node, parent, t, idMap, out) {
6136
6190
  return;
6137
6191
  }
6138
6192
  if (CONTAINER_TYPES.has(type)) {
6139
- (_a = node.children) == null ? void 0 : _a.forEach((c) => flatten(c, m, t, idMap, out));
6193
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => flatten(c, m, t, idMap, out));
6140
6194
  return;
6141
6195
  }
6142
6196
  out.push(describePrimitive(node, m, t));
6143
6197
  }
6144
6198
  function collectSampleTimes(node, into) {
6145
- var _a;
6199
+ var _a2;
6146
6200
  into.add(0);
6147
6201
  const scanAnim = (anim) => {
6148
- var _a2;
6202
+ var _a3;
6149
6203
  if (!anim || typeof anim !== "object") return;
6150
6204
  for (const key of Object.keys(anim)) {
6151
- const kfs = (_a2 = anim[key]) == null ? void 0 : _a2.keyframes;
6205
+ const kfs = (_a3 = anim[key]) == null ? void 0 : _a3.keyframes;
6152
6206
  if (Array.isArray(kfs)) kfs.forEach((kf) => {
6153
- var _a3;
6154
- return into.add((_a3 = kf.time) != null ? _a3 : 0);
6207
+ var _a4;
6208
+ return into.add((_a4 = kf.time) != null ? _a4 : 0);
6155
6209
  });
6156
6210
  }
6157
6211
  };
6158
6212
  scanAnim(node.animate);
6159
6213
  if (node.transform && typeof node.transform === "object" && node.transform.keyframes) {
6160
6214
  node.transform.keyframes.forEach((kf) => {
6161
- var _a2;
6162
- return into.add((_a2 = kf.time) != null ? _a2 : 0);
6215
+ var _a3;
6216
+ return into.add((_a3 = kf.time) != null ? _a3 : 0);
6163
6217
  });
6164
6218
  }
6165
- (_a = node.children) == null ? void 0 : _a.forEach((c) => collectSampleTimes(c, into));
6219
+ (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => collectSampleTimes(c, into));
6166
6220
  }
6167
6221
  function visualModelAt(root, t) {
6168
6222
  const idMap = /* @__PURE__ */ new Map();
@@ -6196,8 +6250,191 @@ function subtractMultiset(a, b) {
6196
6250
  }
6197
6251
  return extra;
6198
6252
  }
6253
+ var FLAT_ONLY_KEYS = [
6254
+ "timelineSource",
6255
+ "scroll",
6256
+ "trigger",
6257
+ "delay",
6258
+ "iterations",
6259
+ "direction",
6260
+ "fill",
6261
+ "resetOnFinish",
6262
+ "duration",
6263
+ "mode",
6264
+ "frameRate"
6265
+ ];
6266
+ var CONTENT_KEYS = ["definitions", "animateById"];
6267
+ var isPlainObject = (v) => !!v && typeof v === "object" && !Array.isArray(v);
6268
+ var timelineTypeOf = (t) => isPlainObject(t) && typeof t.type === "string" ? t.type : "time";
6269
+ var isScrollish = (type) => type === "scroll" || type === "view";
6270
+ function mergePlain(base, patch) {
6271
+ const out = isPlainObject(base) ? __spreadValues2({}, base) : {};
6272
+ for (const key of Object.keys(patch)) {
6273
+ const value = patch[key];
6274
+ if (value === null) {
6275
+ delete out[key];
6276
+ continue;
6277
+ }
6278
+ if (isPlainObject(value)) {
6279
+ out[key] = mergePlain(out[key], value);
6280
+ continue;
6281
+ }
6282
+ out[key] = value;
6283
+ }
6284
+ return out;
6285
+ }
6286
+ function mergeTimeline(base, patch, warn) {
6287
+ const baseType = timelineTypeOf(base);
6288
+ const patchNamesType = isPlainObject(patch) && typeof patch.type === "string";
6289
+ const patchType = patchNamesType ? String(patch.type) : baseType;
6290
+ let merged;
6291
+ if (patchType !== baseType) {
6292
+ const carried = {};
6293
+ if (isPlainObject(base)) {
6294
+ for (const k of PX_TIMELINE_SHARED_KEYS) {
6295
+ if (base[k] !== void 0) carried[k] = base[k];
6296
+ }
6297
+ }
6298
+ merged = mergePlain(carried, patch);
6299
+ } else {
6300
+ merged = mergePlain(base, patch);
6301
+ }
6302
+ if (isScrollish(patchType)) {
6303
+ for (const k of PX_TIME_ONLY_TIMELINE_KEYS) {
6304
+ if (merged[k] === void 0) continue;
6305
+ warn("animator.timeline." + k + ": no slot on a '" + patchType + "' timeline \u2014 dropped");
6306
+ delete merged[k];
6307
+ }
6308
+ if (merged.iterations === "infinite") {
6309
+ warn("animator.timeline.iterations: 'infinite' cannot map onto a scroll range \u2014 dropped");
6310
+ delete merged.iterations;
6311
+ }
6312
+ }
6313
+ return merged;
6314
+ }
6315
+ function foldAnimatorConfigShortcuts(config, shortcuts) {
6316
+ let base;
6317
+ if (typeof config === "string") {
6318
+ try {
6319
+ base = JSON.parse(config);
6320
+ } catch (e) {
6321
+ console.warn("animator config: not valid JSON \u2014 ignored", e);
6322
+ base = void 0;
6323
+ }
6324
+ } else {
6325
+ base = config != null ? config : void 0;
6326
+ }
6327
+ const { duration, delay, iterations, startOn } = shortcuts;
6328
+ if (duration === void 0 && delay === void 0 && iterations === void 0 && startOn === void 0) {
6329
+ return base;
6330
+ }
6331
+ const out = isPlainObject(base) ? __spreadValues2({}, base) : {};
6332
+ const timeline = __spreadValues2({}, out.timeline);
6333
+ if (duration !== void 0) timeline.duration = duration;
6334
+ if (delay !== void 0) timeline.delay = delay;
6335
+ if (iterations !== void 0) timeline.iterations = iterations;
6336
+ if (startOn !== void 0) {
6337
+ timeline.trigger = __spreadProps2(__spreadValues2({}, timeline.trigger), { startOn });
6338
+ }
6339
+ out.timeline = timeline;
6340
+ return out;
6341
+ }
6342
+ function mergeAnimatorConfig(base, patch) {
6343
+ const warnings = [];
6344
+ const warn = (m) => warnings.push(m);
6345
+ if (patch === null) return { config: void 0, warnings };
6346
+ if (!isPlainObject(patch) || Object.keys(patch).length === 0) {
6347
+ return { config: base, warnings };
6348
+ }
6349
+ const flatInBase = isPlainObject(base) ? FLAT_ONLY_KEYS.filter((k) => base[k] !== void 0) : [];
6350
+ if (flatInBase.length) {
6351
+ warn("animator: the base carries the flat runtime spelling (" + flatInBase.join(", ") + "); the patch merges the wire spelling only");
6352
+ }
6353
+ const out = isPlainObject(base) ? __spreadValues2({}, base) : {};
6354
+ for (const key of Object.keys(patch)) {
6355
+ const value = patch[key];
6356
+ if (value === null) {
6357
+ delete out[key];
6358
+ continue;
6359
+ }
6360
+ if (key === "timeline") {
6361
+ out.timeline = isPlainObject(value) ? mergeTimeline(out.timeline, value, warn) : value;
6362
+ continue;
6363
+ }
6364
+ if (isPlainObject(value)) {
6365
+ out[key] = mergePlain(out[key], value);
6366
+ continue;
6367
+ }
6368
+ out[key] = value;
6369
+ }
6370
+ return { config: out, warnings };
6371
+ }
6372
+ function applyAnimatorConfig(doc, patch, opts) {
6373
+ var _a2, _b;
6374
+ const reset = !!(opts == null ? void 0 : opts.resetDefaults);
6375
+ if (!doc || (patch === void 0 || !reset && (patch === null || !isPlainObject(patch) || !Object.keys(patch).length))) {
6376
+ return { doc, warnings: [] };
6377
+ }
6378
+ const anyDoc = doc;
6379
+ const atRoot = isPlainObject(anyDoc.animator);
6380
+ const atMeta = !atRoot && isPlainObject((_a2 = anyDoc.meta) == null ? void 0 : _a2.animator);
6381
+ const current = atRoot ? anyDoc.animator : atMeta ? anyDoc.meta.animator : void 0;
6382
+ const warnings = [];
6383
+ if (atRoot && isPlainObject((_b = anyDoc.meta) == null ? void 0 : _b.animator)) {
6384
+ warnings.push("animator: doc.meta.animator is shadowed by doc.animator and was not patched");
6385
+ }
6386
+ let base = current;
6387
+ if (reset) {
6388
+ const kept = {};
6389
+ for (const k of CONTENT_KEYS) {
6390
+ if (isPlainObject(current) && current[k] !== void 0) kept[k] = current[k];
6391
+ }
6392
+ base = kept;
6393
+ }
6394
+ const merged = mergeAnimatorConfig(base, patch != null ? patch : {});
6395
+ warnings.push(...merged.warnings);
6396
+ if (merged.config === current) return { doc, warnings };
6397
+ if (atMeta) {
6398
+ return {
6399
+ doc: __spreadProps2(__spreadValues2({}, anyDoc), { meta: __spreadProps2(__spreadValues2({}, anyDoc.meta), { animator: merged.config }) }),
6400
+ warnings
6401
+ };
6402
+ }
6403
+ return { doc: __spreadProps2(__spreadValues2({}, anyDoc), { animator: merged.config }), warnings };
6404
+ }
6405
+ var MAX_REPORTED = 6;
6406
+ var LEGACY_FLAT_KEYS = [
6407
+ ...PX_TIMELINE_SHARED_KEYS,
6408
+ ...PX_TIME_ONLY_TIMELINE_KEYS,
6409
+ "fill",
6410
+ "resetOnFinish",
6411
+ "timelineSource",
6412
+ "scroll"
6413
+ ];
6414
+ var isLegacyFlatAnimatorKey = (w) => LEGACY_FLAT_KEYS.some((k) => w.indexOf("animator." + k + ":") >= 0);
6415
+ function diagnoseDocument(doc) {
6416
+ let all;
6417
+ try {
6418
+ all = validateDocument(doc);
6419
+ } catch (e) {
6420
+ return { problems: [], legacy: [] };
6421
+ }
6422
+ const problems = [];
6423
+ const legacy = [];
6424
+ for (const w of all) (isLegacyFlatAnimatorKey(w) ? legacy : problems).push(w);
6425
+ return { problems, legacy };
6426
+ }
6427
+ function reportDocumentDiagnostics(doc, where) {
6428
+ const { problems } = diagnoseDocument(doc);
6429
+ if (!problems.length) return;
6430
+ const shown = problems.slice(0, MAX_REPORTED);
6431
+ const more = problems.length - shown.length;
6432
+ console.warn(
6433
+ where + ": this document does not match the animation schema in " + problems.length + " place" + (problems.length === 1 ? "" : "s") + ".\n" + shown.map((p) => " - " + p).join("\n") + (more > 0 ? "\n \u2026 and " + more + " more" : "") + "\n\nIf you did not author these keys, the usual cause is a build that MANGLES PROPERTY NAMES. An animation document is data loaded at runtime, so renaming the property reads inside the player stops them matching the keys in the JSON, and the animation silently does nothing. Feed the published reserved-name list to your minifier \u2014 @pixodesk/svg-animator-web/mangle-reserved.json \u2014 see docs/library/minification.md."
6434
+ );
6435
+ }
6199
6436
 
6200
- // src/PxAnimatorTriggers.ts
6437
+ // src/triggers/PxAnimatorTriggers.ts
6201
6438
  function setupAnimationTriggers(api, config) {
6202
6439
  const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
6203
6440
  const root = api.getRootElement();
@@ -6267,12 +6504,12 @@ function setupAnimationTriggers(api, config) {
6267
6504
  }
6268
6505
  case "scrollIntoView": {
6269
6506
  const effectiveRatio = (entry) => {
6270
- var _a, _b;
6507
+ var _a2, _b;
6271
6508
  const target = entry.boundingClientRect;
6272
6509
  const visible = entry.intersectionRect;
6273
6510
  if (!(target == null ? void 0 : target.height) || !visible) return entry.intersectionRatio;
6274
6511
  const live = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : Infinity;
6275
- const declared = (_b = (_a = entry.rootBounds) == null ? void 0 : _a.height) != null ? _b : Infinity;
6512
+ const declared = (_b = (_a2 = entry.rootBounds) == null ? void 0 : _a2.height) != null ? _b : Infinity;
6276
6513
  const viewport = Math.min(live, declared);
6277
6514
  const denom = Math.min(target.height, Number.isFinite(viewport) ? viewport : target.height);
6278
6515
  return denom > 0 ? visible.height / denom : entry.intersectionRatio;
@@ -6302,7 +6539,7 @@ function setupAnimationTriggers(api, config) {
6302
6539
  return api;
6303
6540
  }
6304
6541
 
6305
- // src/PxAnimatorFrameLoop.ts
6542
+ // src/engines/PxAnimatorFrameLoop.ts
6306
6543
  function getSelector(id) {
6307
6544
  return "#" + id;
6308
6545
  }
@@ -6362,11 +6599,10 @@ function createDomAdapter(rootElement) {
6362
6599
  return adapter;
6363
6600
  }
6364
6601
 
6365
- // src/PxAnimatorWebApi.ts
6602
+ // src/engines/PxAnimatorWebApi.ts
6366
6603
  function createCssKf(kf, t, propName, unsupportedSet) {
6367
- var _a, _b;
6368
- let value = (_a = kf.v) != null ? _a : kf.value;
6369
- const e = (_b = kf.e) != null ? _b : kf.easing;
6604
+ let value = kfValue(kf);
6605
+ const e = kfEasing(kf);
6370
6606
  const cssKf = {
6371
6607
  offset: t,
6372
6608
  easing: e && Array.isArray(e) ? "cubic-bezier(" + e.join(",") + ")" : void 0
@@ -6400,11 +6636,11 @@ function createCssKf(kf, t, propName, unsupportedSet) {
6400
6636
  return cssKf;
6401
6637
  }
6402
6638
  function clipKeyframesToDuration(propName, keyframes, duration) {
6403
- var _a, _b, _c, _d, _e;
6639
+ var _a2, _b, _c, _d, _e;
6404
6640
  const result = [];
6405
6641
  for (let i = 0; i < keyframes.length; i++) {
6406
6642
  const kf = keyframes[i];
6407
- const t = (_a = kf.t) != null ? _a : 0;
6643
+ const t = (_a2 = kf.t) != null ? _a2 : 0;
6408
6644
  if (t < 0) {
6409
6645
  const next = keyframes[i + 1];
6410
6646
  if (next && ((_b = next.t) != null ? _b : 0) >= 0) {
@@ -6433,7 +6669,7 @@ function clipKeyframesToDuration(propName, keyframes, duration) {
6433
6669
  return result;
6434
6670
  }
6435
6671
  function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6436
- var _a;
6672
+ var _a2;
6437
6673
  const result = /* @__PURE__ */ new Map();
6438
6674
  for (const [propName, propAnim] of Object.entries(animDef)) {
6439
6675
  const duration = config.duration || 1;
@@ -6441,7 +6677,7 @@ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6441
6677
  const cssKeyframes = [];
6442
6678
  for (let i = 0; i < clippedKeyframes.length; i++) {
6443
6679
  const kf = clippedKeyframes[i];
6444
- const t = clamp(((_a = kf.t) != null ? _a : 0) / duration, 0, 1);
6680
+ const t = clamp(((_a2 = kf.t) != null ? _a2 : 0) / duration, 0, 1);
6445
6681
  const cssKf = createCssKf(kf, t, propName, unsupportedSet);
6446
6682
  if (i === 0 && (cssKf.offset || 0) > 0) {
6447
6683
  cssKeyframes.push(__spreadProps(__spreadValues({}, cssKf), { offset: 0 }));
@@ -6460,7 +6696,7 @@ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6460
6696
  return result;
6461
6697
  }
6462
6698
  function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs, scrollTimeline) {
6463
- var _a;
6699
+ var _a2;
6464
6700
  const config = getAnimatorConfig(doc) || {};
6465
6701
  if (!rootElement) {
6466
6702
  if (doc.id) {
@@ -6471,7 +6707,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6471
6707
  console.warn("createFrameLoopAnimator: No root element provided");
6472
6708
  }
6473
6709
  }
6474
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.waapi);
6710
+ const bindings = getNormalisedBindings(doc, PxTimelineEngine.native);
6475
6711
  const animations = [];
6476
6712
  const _iterations = config.iterations;
6477
6713
  let iterations;
@@ -6508,7 +6744,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6508
6744
  // animation ends — consistent with Lottie and other animation runtimes.
6509
6745
  // Without this, seeking to the last frame reverts elements to their
6510
6746
  // pre-animation state (the Web Animations API "after" phase with fill:'none').
6511
- fill: (_a = config.fill) != null ? _a : "forwards",
6747
+ fill: (_a2 = config.fill) != null ? _a2 : "forwards",
6512
6748
  direction: config.direction,
6513
6749
  iterations
6514
6750
  };
@@ -6525,16 +6761,16 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6525
6761
  if (scrollTimeline.rangeEnd) a.rangeEnd = scrollTimeline.rangeEnd;
6526
6762
  }
6527
6763
  if (callbacks == null ? void 0 : callbacks.onFinish) anim.onfinish = () => {
6528
- var _a2;
6764
+ var _a3;
6529
6765
  if (finishNotified) return;
6530
6766
  finishNotified = true;
6531
- (_a2 = callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
6767
+ (_a3 = callbacks.onFinish) == null ? void 0 : _a3.call(callbacks);
6532
6768
  };
6533
6769
  if (callbacks == null ? void 0 : callbacks.onRemove) anim.onremove = () => {
6534
- var _a2;
6770
+ var _a3;
6535
6771
  if (removeCalled) return;
6536
6772
  removeCalled = true;
6537
- (_a2 = callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
6773
+ (_a3 = callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
6538
6774
  };
6539
6775
  if (seekPosition !== void 0) {
6540
6776
  anim.currentTime = seekPosition;
@@ -6555,31 +6791,31 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6555
6791
  "isReady": () => true,
6556
6792
  "getRootElement": () => rootElement || null,
6557
6793
  "isPlaying": () => {
6558
- var _a2;
6559
- return ((_a2 = animations[0]) == null ? void 0 : _a2.playState) === "running";
6794
+ var _a3;
6795
+ return ((_a3 = animations[0]) == null ? void 0 : _a3.playState) === "running";
6560
6796
  },
6561
6797
  "play": () => {
6562
- var _a2;
6798
+ var _a3;
6563
6799
  finishNotified = false;
6564
6800
  animations.forEach((a) => a.play());
6565
- (_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
6801
+ (_a3 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a3.call(callbacks);
6566
6802
  },
6567
6803
  "pause": () => {
6568
- var _a2;
6804
+ var _a3;
6569
6805
  animations.forEach((a) => a.pause());
6570
- (_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
6806
+ (_a3 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a3.call(callbacks);
6571
6807
  },
6572
6808
  "cancel": () => {
6573
- var _a2;
6809
+ var _a3;
6574
6810
  finishNotified = false;
6575
6811
  animations.forEach((a) => a.cancel());
6576
- (_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
6812
+ (_a3 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a3.call(callbacks);
6577
6813
  },
6578
6814
  "finish": () => {
6579
- var _a2;
6815
+ var _a3;
6580
6816
  for (const a of animations) {
6581
6817
  try {
6582
- if (((_a2 = a.effect) == null ? void 0 : _a2.getTiming().iterations) === Infinity) {
6818
+ if (((_a3 = a.effect) == null ? void 0 : _a3.getTiming().iterations) === Infinity) {
6583
6819
  a.effect.updateTiming({ iterations: 1 });
6584
6820
  a.finish();
6585
6821
  a.effect.updateTiming({ iterations: Infinity });
@@ -6596,8 +6832,8 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6596
6832
  return api;
6597
6833
  },
6598
6834
  "getCurrentTime": () => {
6599
- var _a2, _b;
6600
- const res = (_b = (_a2 = animations[0]) == null ? void 0 : _a2.currentTime) != null ? _b : null;
6835
+ var _a3, _b;
6836
+ const res = (_b = (_a3 = animations[0]) == null ? void 0 : _a3.currentTime) != null ? _b : null;
6601
6837
  return res !== null ? +res : null;
6602
6838
  },
6603
6839
  "setCurrentTime": (time) => {
@@ -6607,12 +6843,12 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6607
6843
  });
6608
6844
  },
6609
6845
  "destroy": () => {
6610
- var _a2;
6846
+ var _a3;
6611
6847
  api.cancel();
6612
6848
  animations.splice(0, animations.length);
6613
6849
  if (!removeCalled) {
6614
6850
  removeCalled = true;
6615
- (_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
6851
+ (_a3 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a3.call(callbacks);
6616
6852
  }
6617
6853
  }
6618
6854
  };
@@ -6629,21 +6865,21 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6629
6865
  return api;
6630
6866
  }
6631
6867
 
6632
- // src/PxScrollDriver.ts
6868
+ // src/scroll/PxScrollDriver.ts
6633
6869
  function nativeRangeOffset(point, defaultFraction, view) {
6634
- var _a, _b, _c;
6870
+ var _a2, _b, _c;
6635
6871
  const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
6636
- const pct = (_b = (_a = globalThis.CSS) == null ? void 0 : _a.percent) == null ? void 0 : _b.call(_a, fraction * 100);
6872
+ const pct = (_b = (_a2 = globalThis.CSS) == null ? void 0 : _a2.percent) == null ? void 0 : _b.call(_a2, fraction * 100);
6637
6873
  if (pct === void 0) return void 0;
6638
6874
  return view ? { rangeName: (_c = point == null ? void 0 : point.phase) != null ? _c : "cover", offset: pct } : { offset: pct };
6639
6875
  }
6640
6876
  function createNativeScrollTimeline(subject, config) {
6641
- var _a, _b, _c, _d;
6877
+ var _a2, _b, _c, _d;
6642
6878
  if (!config || !isScrollTimeline(config)) return null;
6643
6879
  const scroll = config.scroll || {};
6644
- const kind = (_a = scroll.kind) != null ? _a : "view";
6880
+ const kind = (_a2 = scroll.kind) != null ? _a2 : "view";
6645
6881
  if (scroll.smoothing) {
6646
- console.warn('scroll timeline: `smoothing` needs the built-in driver \u2014 ignoring `driver: "native"`');
6882
+ console.warn("scroll timeline: `smoothing` needs the built-in driver \u2014 using the built-in driver instead of the browser timeline");
6647
6883
  return null;
6648
6884
  }
6649
6885
  const g = globalThis;
@@ -6660,7 +6896,7 @@ function createNativeScrollTimeline(subject, config) {
6660
6896
  timeline = new Ctor({ source, axis });
6661
6897
  }
6662
6898
  } catch (e) {
6663
- console.warn("scroll timeline: native timeline construction failed \u2014 falling back to the custom driver", e);
6899
+ console.warn("scroll timeline: native timeline construction failed \u2014 falling back to the player measuring progress itself", e);
6664
6900
  return null;
6665
6901
  }
6666
6902
  return {
@@ -6688,7 +6924,7 @@ function documentScroller() {
6688
6924
  var SUBJECT_PARENT = "parent";
6689
6925
  var SUBJECT_SCROLLER = "scroller";
6690
6926
  function resolveScrollSubject(svgRoot, subject) {
6691
- var _a, _b;
6927
+ var _a2, _b;
6692
6928
  const spec = subject == null ? void 0 : subject.trim();
6693
6929
  if (!spec) return svgRoot;
6694
6930
  if (spec === SUBJECT_PARENT) {
@@ -6697,7 +6933,7 @@ function resolveScrollSubject(svgRoot, subject) {
6697
6933
  const position = getComputedStyle(p).position;
6698
6934
  if (position === "sticky" || position === "fixed") outermostPinned = p;
6699
6935
  }
6700
- 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;
6701
6937
  }
6702
6938
  if (spec === SUBJECT_SCROLLER) {
6703
6939
  return findNearestScroller(svgRoot, "y") || findNearestScroller(svgRoot, "x") || documentScroller();
@@ -6716,10 +6952,10 @@ function resolveScrollSubject(svgRoot, subject) {
6716
6952
  return found;
6717
6953
  }
6718
6954
  function createScrollDriver(subject, config, onProgress) {
6719
- var _a, _b;
6955
+ var _a2, _b;
6720
6956
  if (!config || !isScrollTimeline(config)) return null;
6721
6957
  const scroll = config.scroll || {};
6722
- const kind = (_a = scroll.kind) != null ? _a : "view";
6958
+ const kind = (_a2 = scroll.kind) != null ? _a2 : "view";
6723
6959
  const measured = resolveScrollSubject(subject, scroll.subject);
6724
6960
  const nearest = findNearestScroller(subject, "y") || findNearestScroller(subject, "x");
6725
6961
  const scroller = kind === "scroll" && scroll.source === "root" ? documentScroller() : nearest || documentScroller();
@@ -6838,8 +7074,8 @@ function applyScrollPin(svgRoot, scroll) {
6838
7074
  style.position = "sticky";
6839
7075
  const alignFactor = scroll.pinAlign === "center" ? 0.5 : scroll.pinAlign === "bottom" ? 1 : 0;
6840
7076
  const applyTop = () => {
6841
- var _a;
6842
- const extra = (_a = scroll.pinTop) != null ? _a : 0;
7077
+ var _a2;
7078
+ const extra = (_a2 = scroll.pinTop) != null ? _a2 : 0;
6843
7079
  if (!alignFactor) {
6844
7080
  style.top = extra + "px";
6845
7081
  return;
@@ -6879,23 +7115,23 @@ function applyScrollPin(svgRoot, scroll) {
6879
7115
  };
6880
7116
  }
6881
7117
 
6882
- // src/PxAnimatorBind.ts
7118
+ // src/engines/PxAnimatorBind.ts
6883
7119
  function finaliseAnimator(animatorConfig, callbacks, make) {
6884
7120
  let apiRef;
6885
7121
  let effectiveCallbacks = callbacks;
6886
7122
  if (animatorConfig.resetOnFinish) {
6887
7123
  effectiveCallbacks = __spreadProps(__spreadValues({}, callbacks), {
6888
7124
  onFinish: () => {
6889
- var _a;
6890
- (_a = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a.call(callbacks);
7125
+ var _a2;
7126
+ (_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
6891
7127
  apiRef == null ? void 0 : apiRef.cancel();
6892
7128
  }
6893
7129
  });
6894
7130
  }
6895
7131
  const res = make(effectiveCallbacks);
6896
7132
  apiRef = res;
6897
- if (animatorConfig.debugInstName) {
6898
- window[animatorConfig.debugInstName] = res;
7133
+ if (animatorConfig.debugGlobalName) {
7134
+ window[animatorConfig.debugGlobalName] = res;
6899
7135
  }
6900
7136
  return res;
6901
7137
  }
@@ -6903,10 +7139,10 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
6903
7139
  const animatorConfig = getAnimatorConfig(doc) || {};
6904
7140
  if (isScrollTimeline(animatorConfig)) {
6905
7141
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
6906
- var _a, _b;
7142
+ var _a2;
6907
7143
  let unpin = () => {
6908
7144
  };
6909
- if (animatorConfig.mode !== PxAnimatorMode.frames && ((_a = animatorConfig.scroll) == null ? void 0 : _a.driver) === "native" && rootElement) {
7145
+ if (mayUseNativeScrollTimeline(animatorConfig.engine) && rootElement) {
6910
7146
  unpin = applyScrollPin(rootElement, animatorConfig.scroll);
6911
7147
  const native = createNativeScrollTimeline(rootElement, animatorConfig);
6912
7148
  if (native) {
@@ -6914,7 +7150,7 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
6914
7150
  doc,
6915
7151
  cb,
6916
7152
  rootElement,
6917
- animatorConfig.mode === PxAnimatorMode.waapi,
7153
+ isNativeForced(animatorConfig.engine),
6918
7154
  native
6919
7155
  );
6920
7156
  if (api2) {
@@ -6930,8 +7166,8 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
6930
7166
  unpin = () => {
6931
7167
  };
6932
7168
  }
6933
- const api = (animatorConfig.mode !== PxAnimatorMode.frames ? createWebApiAnimator(doc, cb, rootElement, animatorConfig.mode === PxAnimatorMode.waapi) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
6934
- const subject = ((_b = api.getRootElement) == null ? void 0 : _b.call(api)) || rootElement;
7169
+ const api = (animatorConfig.engine !== PxTimelineEngineExtra.js ? createWebApiAnimator(doc, cb, rootElement, isNativeForced(animatorConfig.engine)) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
7170
+ const subject = ((_a2 = api.getRootElement) == null ? void 0 : _a2.call(api)) || rootElement;
6935
7171
  if (subject) {
6936
7172
  unpin = applyScrollPin(subject, animatorConfig.scroll);
6937
7173
  const totalMs = scrollTotalDurationMs(animatorConfig);
@@ -6955,20 +7191,19 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
6955
7191
  });
6956
7192
  }
6957
7193
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
6958
- if (animatorConfig.mode === PxAnimatorMode.frames) {
7194
+ if (animatorConfig.engine === PxTimelineEngineExtra.js) {
6959
7195
  return createFrameLoopAnimator(doc, adapter, cb, rootElement);
6960
7196
  }
6961
7197
  return createWebApiAnimator(
6962
7198
  doc,
6963
7199
  cb,
6964
7200
  rootElement,
6965
- animatorConfig.mode === PxAnimatorMode.waapi
6966
- // forcing waapi
7201
+ isNativeForced(animatorConfig.engine)
6967
7202
  ) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
6968
7203
  });
6969
7204
  }
6970
7205
 
6971
- // src/PxAnimatorDOM.ts
7206
+ // src/dom/PxAnimatorDOM.ts
6972
7207
  var SVG_NS = "http://www.w3.org/2000/svg";
6973
7208
  function createElement(tagName, normalisedProps, style, children, textContent) {
6974
7209
  if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
@@ -7000,7 +7235,7 @@ function createElement(tagName, normalisedProps, style, children, textContent) {
7000
7235
  }
7001
7236
  function renderNode(node, defs) {
7002
7237
  if (!node) return null;
7003
- const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
7238
+ const _a2 = node, { type, children, style } = _a2, props = __objRest(_a2, ["type", "children", "style"]);
7004
7239
  const domType = props.domType;
7005
7240
  if (domType !== void 0) delete props.domType;
7006
7241
  const nodeDefs = getDefs(node) || defs;
@@ -7026,18 +7261,24 @@ function renderNode(node, defs) {
7026
7261
  return element;
7027
7262
  }
7028
7263
 
7029
- // src/PxAnimatorKeys.ts
7264
+ // src/shared/PxAnimatorKeys.ts
7030
7265
  var PX_ANIMATOR_DATA_KEY = "data";
7031
7266
 
7032
- // src/PxAnimator.ts
7267
+ // src/animator/PxAnimator.ts
7033
7268
  function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
7034
7269
  return bindWithEngineChoice(doc, adapter, callbacks, rootElement);
7035
7270
  }
7036
- function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
7271
+ function createAnimatorImpl(doc, adapter, callbacks, containerElement, config, resetDocDefaults) {
7037
7272
  const effectsWarnings = validateNodeEffects(doc);
7038
7273
  for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
7274
+ reportDocumentDiagnostics(doc, "[PxAnimator] createAnimator");
7275
+ if (config !== void 0 || resetDocDefaults) {
7276
+ const patched = applyAnimatorConfig(doc, config != null ? config : {}, { resetDefaults: !!resetDocDefaults });
7277
+ for (const w of patched.warnings) console.warn("[PxAnimator] config override:", w);
7278
+ doc = patched.doc;
7279
+ }
7039
7280
  const animatorConfig = getAnimatorConfig(doc) || {};
7040
- const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi;
7281
+ const engine = resolveTimelineEngine(animatorConfig.engine);
7041
7282
  doc = materialiseAllInTree(doc, engine);
7042
7283
  let rootElement = null;
7043
7284
  if (containerElement) {
@@ -7061,8 +7302,13 @@ function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
7061
7302
  }
7062
7303
  return api;
7063
7304
  }
7305
+ function resolveAnimatorConfigOption(options) {
7306
+ const { config, duration, delay, iterations, startOn } = options;
7307
+ return foldAnimatorConfigShortcuts(config, { duration, delay, iterations, startOn });
7308
+ }
7064
7309
  function createAnimator(options) {
7065
- const { src, data, adapter, callbacks, container } = options;
7310
+ const { src, data, adapter, callbacks, container, resetDocDefaults } = options;
7311
+ const config = resolveAnimatorConfigOption(options);
7066
7312
  if (data !== void 0 && src !== void 0) {
7067
7313
  throw new Error("createAnimator: provide either `src` or `data`, not both");
7068
7314
  }
@@ -7070,7 +7316,7 @@ function createAnimator(options) {
7070
7316
  throw new Error("createAnimator: either `src` or `data` is required");
7071
7317
  }
7072
7318
  if (data !== void 0) {
7073
- return createAnimatorImpl(data, adapter, callbacks, container);
7319
+ return createAnimatorImpl(data, adapter, callbacks, container, config, resetDocDefaults);
7074
7320
  }
7075
7321
  let animator = null;
7076
7322
  let pending = [];
@@ -7085,7 +7331,7 @@ function createAnimator(options) {
7085
7331
  fetch(src).then((res) => res.json()).then((json) => {
7086
7332
  if (destroyed) return;
7087
7333
  if (isPxElementFileFormat(json)) {
7088
- animator = createAnimatorImpl(json, adapter, callbacks, container);
7334
+ animator = createAnimatorImpl(json, adapter, callbacks, container, config, resetDocDefaults);
7089
7335
  const queued = pending;
7090
7336
  pending = null;
7091
7337
  queued == null ? void 0 : queued.forEach((call) => call(animator));
@@ -7153,12 +7399,11 @@ export {
7153
7399
  PxAnimatedSvgDocumentSchema,
7154
7400
  PxAnimationDefinitionSchema,
7155
7401
  PxAnimatorConfigSchema,
7156
- PxAnimatorEngine,
7157
- PxAnimatorMode,
7158
7402
  PxAttrValueSchema,
7159
7403
  PxBezierPathSchema,
7160
7404
  PxBindingSchema,
7161
7405
  PxCloneEffectSchema,
7406
+ PxCloneWithout,
7162
7407
  PxDefsSchema,
7163
7408
  PxEasingOrRefSchema,
7164
7409
  PxEffectsSchema,
@@ -7170,6 +7415,8 @@ export {
7170
7415
  PxGradientUnits,
7171
7416
  PxKeyframeSchema,
7172
7417
  PxKeyframeValueSchema,
7418
+ PxLoopDirection,
7419
+ PxLoopRepeatAt,
7173
7420
  PxLoopSchema,
7174
7421
  PxMaskedByEffectSchema,
7175
7422
  PxNodeBase,
@@ -7179,15 +7426,19 @@ export {
7179
7426
  PxRetimeEffectSchema,
7180
7427
  PxStrokeGradientEffectSchema,
7181
7428
  PxStrokeTrimEffectSchema,
7429
+ PxStrokeTrimSubPaths,
7182
7430
  PxSvgNodeExtra,
7183
7431
  PxTextEffectSchema,
7184
7432
  PxTextPathEffectSchema,
7433
+ PxTimelineEngine,
7434
+ PxTimelineEngineExtra,
7185
7435
  PxTransformByEffectSchema,
7186
7436
  PxTransformPartsSchema,
7187
7437
  PxTransformValueSchema,
7188
7438
  PxTriggerSchema,
7189
7439
  STYLE_ATTR_NAMES,
7190
7440
  TRANSFORM_FN_NAMES,
7441
+ applyAnimatorConfig,
7191
7442
  applyPlayerEffects,
7192
7443
  calcAnimationValues,
7193
7444
  camelCaseToKebabWordIfNeeded,
@@ -7202,6 +7453,7 @@ export {
7202
7453
  diffInEffect,
7203
7454
  evaluateMotionPathSegment,
7204
7455
  extendedPathForBrowser,
7456
+ foldAnimatorConfigShortcuts,
7205
7457
  generateNewIds,
7206
7458
  getAnimatorConfig,
7207
7459
  getBindings,
@@ -7222,6 +7474,7 @@ export {
7222
7474
  materialiseInternalLoopsInTree,
7223
7475
  materialiseMotionPathInPropAnim,
7224
7476
  materialiseMotionPathsInTree,
7477
+ mergeAnimatorConfig,
7225
7478
  getNormalisedBindings as normalizeDocument,
7226
7479
  propAnimIsMotionPath,
7227
7480
  px,
@@ -7230,6 +7483,7 @@ export {
7230
7483
  setupAnimationTriggers,
7231
7484
  shiftAnimatable,
7232
7485
  toRGBA,
7486
+ validateDocument,
7233
7487
  validateNodeEffects,
7234
7488
  visualModelAt
7235
7489
  };