@pixodesk/svg-animator-web 1.0.35 → 1.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -292,7 +292,7 @@ function parseColor(s) {
292
292
  }
293
293
  return void 0;
294
294
  }
295
- var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
295
+ var COLOR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
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) {
@@ -671,6 +671,7 @@ var Enum = class extends Base {
671
671
  return false;
672
672
  }
673
673
  };
674
+ var UNION_MEMBER_ERROR_LIMIT = 4;
674
675
  var Union = class extends Base {
675
676
  constructor(schemas, defaultVal) {
676
677
  super();
@@ -688,7 +689,35 @@ var Union = class extends Base {
688
689
  var _a2;
689
690
  const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
690
691
  if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
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));
692
+ if (!ctx) return false;
693
+ const base = pathStr(path != null ? path : []);
694
+ ctx.errors.push(base + ": no union member matched for value " + ((_a2 = JSON.stringify(raw)) != null ? _a2 : "").slice(0, 240));
695
+ let best;
696
+ let bestDepth = -1;
697
+ const leafExpectations = [];
698
+ for (const member of this.schemas) {
699
+ const sink = { errors: [], warnings: [], strict: ctx.strict };
700
+ member.isValid(raw, sink, path ? [...path] : void 0);
701
+ if (!sink.errors.length) continue;
702
+ const depth = Math.max(...sink.errors.map((e) => e.slice(0, e.indexOf(":")).length));
703
+ if (depth > bestDepth || depth === bestDepth && best && sink.errors.length < best.length) {
704
+ bestDepth = depth;
705
+ best = sink.errors;
706
+ }
707
+ if (depth <= base.length) {
708
+ for (const e of sink.errors) {
709
+ const m = /: expected (.+?), got /.exec(e);
710
+ if (m && !leafExpectations.includes(m[1])) leafExpectations.push(m[1]);
711
+ }
712
+ }
713
+ }
714
+ if (best && bestDepth > base.length) {
715
+ for (const e of best.slice(0, UNION_MEMBER_ERROR_LIMIT)) {
716
+ if (!ctx.errors.includes(e)) ctx.errors.push(e);
717
+ }
718
+ } else if (leafExpectations.length) {
719
+ ctx.errors.push(base + ": expected " + leafExpectations.join(" | "));
720
+ }
692
721
  return false;
693
722
  }
694
723
  _canSanitize(raw) {
@@ -1060,6 +1089,17 @@ var px = {
1060
1089
  lazy: (fn, defaultVal) => new Lazy(fn, defaultVal)
1061
1090
  };
1062
1091
  var PX_PLAYER_SCHEMA_VERSION = "1.1";
1092
+ var WIRE_VERSION_KEY = "version";
1093
+ var ANIMATOR_KEY = "animator";
1094
+ var META_KEY = "meta";
1095
+ var WireVersionRelation = /* @__PURE__ */ ((WireVersionRelation2) => {
1096
+ WireVersionRelation2["unstamped"] = "unstamped";
1097
+ WireVersionRelation2["same"] = "same";
1098
+ WireVersionRelation2["older"] = "older";
1099
+ WireVersionRelation2["newer"] = "newer";
1100
+ WireVersionRelation2["otherGeneration"] = "otherGeneration";
1101
+ return WireVersionRelation2;
1102
+ })(WireVersionRelation || {});
1063
1103
  var VERSION_RE = /^(\d+)\.(\d+)(?:\.(\d+))?$/;
1064
1104
  function parseWireVersion(raw) {
1065
1105
  if (typeof raw !== "string") return void 0;
@@ -1067,12 +1107,235 @@ function parseWireVersion(raw) {
1067
1107
  if (!m) return void 0;
1068
1108
  return { a: Number(m[1]), b: Number(m[2]), c: m[3] === void 0 ? 0 : Number(m[3]) };
1069
1109
  }
1110
+ function formatWireVersion(v) {
1111
+ return v.a + "." + v.b + "." + v.c;
1112
+ }
1070
1113
  var _a;
1071
1114
  var PLAYER_WIRE_VERSION = (_a = parseWireVersion(PX_PLAYER_SCHEMA_VERSION)) != null ? _a : { a: 1, b: 1, c: 0 };
1115
+ function getAnimatorBlock(doc) {
1116
+ if (!doc || typeof doc !== "object") return void 0;
1117
+ const atRoot = readObjectProp(doc, ANIMATOR_KEY);
1118
+ if (atRoot) return atRoot;
1119
+ const meta = readObjectProp(doc, META_KEY);
1120
+ return meta ? readObjectProp(meta, ANIMATOR_KEY) : void 0;
1121
+ }
1122
+ function readObjectProp(obj, key) {
1123
+ const value = obj[key];
1124
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
1125
+ }
1126
+ function readWireVersion(doc) {
1127
+ const animator = getAnimatorBlock(doc);
1128
+ return animator ? parseWireVersion(animator[WIRE_VERSION_KEY]) : void 0;
1129
+ }
1130
+ function compareWireVersion(file, mine, readerReadsEditorPart) {
1131
+ if (!file) return "unstamped";
1132
+ if (file.a !== mine.a) return "otherGeneration";
1133
+ if (file.b !== mine.b) return file.b > mine.b ? "newer" : "older";
1134
+ if (!readerReadsEditorPart || file.c === mine.c) return "same";
1135
+ return file.c > mine.c ? "newer" : "older";
1136
+ }
1137
+ function versionAdvice(relation, file, mine, isPlayer) {
1138
+ if (!file) return void 0;
1139
+ const target = isPlayer ? "player" : "editor";
1140
+ const gap = "written for schema " + formatWireVersion(file) + ", this " + target + " reads " + formatWireVersion(mine);
1141
+ switch (relation) {
1142
+ case "newer":
1143
+ return "This file is " + gap + ". Update the " + target + " to open it fully.";
1144
+ case "older":
1145
+ return "This file is " + gap + ". Saving it from this " + target + " rewrites it in the current format.";
1146
+ case "otherGeneration":
1147
+ return "This file is " + gap + " \u2014 a different format generation, which no conversion bridges. Open it in a " + target + " of that generation, or accept this document without the parts named above.";
1148
+ default:
1149
+ return void 0;
1150
+ }
1151
+ }
1152
+ var WireStepKind = /* @__PURE__ */ ((WireStepKind2) => {
1153
+ WireStepKind2["additive"] = "additive";
1154
+ WireStepKind2["converted"] = "converted";
1155
+ return WireStepKind2;
1156
+ })(WireStepKind || {});
1157
+ var BASELINE_PLAYER_VERSION = "1.1";
1158
+ var PLAYER_WIRE_STEPS = [];
1159
+ function applyWireSteps(doc, cfg) {
1160
+ const from = readWireVersion(doc);
1161
+ const relation = compareWireVersion(from, cfg.target, cfg.readerReadsEditorPart);
1162
+ if (!from || relation !== "older") {
1163
+ return {
1164
+ doc,
1165
+ from,
1166
+ relation,
1167
+ applied: [],
1168
+ advice: versionAdvice(relation, from, cfg.target, !cfg.readerReadsEditorPart)
1169
+ };
1170
+ }
1171
+ const due = [];
1172
+ for (const step of cfg.steps) {
1173
+ const stepTo = parseWireVersion(step.to);
1174
+ if (!stepTo) continue;
1175
+ if (compareWireVersion(from, stepTo, cfg.readerReadsEditorPart) !== "older") continue;
1176
+ if (!step.up) continue;
1177
+ due.push(step);
1178
+ }
1179
+ if (!due.length || !doc || typeof doc !== "object") return { doc, from, relation, applied: [] };
1180
+ const target = clonePlain(doc);
1181
+ const applied = [];
1182
+ for (const step of due) {
1183
+ try {
1184
+ step.up(target);
1185
+ applied.push(step);
1186
+ } catch (e) {
1187
+ break;
1188
+ }
1189
+ }
1190
+ if (!applied.length) return { doc, from, relation, applied: [] };
1191
+ stampVersion(target, cfg.target, cfg.readerReadsEditorPart);
1192
+ return { doc: target, from, relation, applied };
1193
+ }
1194
+ function convertPlayerDocument(doc) {
1195
+ return applyWireSteps(doc, {
1196
+ steps: PLAYER_WIRE_STEPS,
1197
+ target: PLAYER_WIRE_VERSION,
1198
+ readerReadsEditorPart: false
1199
+ });
1200
+ }
1201
+ function clonePlain(value) {
1202
+ const structured = globalThis.structuredClone;
1203
+ return structured ? structured(value) : JSON.parse(JSON.stringify(value));
1204
+ }
1205
+ function stampVersion(doc, target, readerReadsEditorPart) {
1206
+ const animator = getAnimatorBlock(doc);
1207
+ if (!animator) return;
1208
+ const previous = parseWireVersion(animator[WIRE_VERSION_KEY]);
1209
+ animator[WIRE_VERSION_KEY] = formatWireVersion({
1210
+ a: target.a,
1211
+ b: target.b,
1212
+ c: readerReadsEditorPart ? target.c : previous ? previous.c : 0
1213
+ });
1214
+ }
1215
+ function applyWireStepsDown(doc, cfg) {
1216
+ const from = readWireVersion(doc);
1217
+ if (!from) {
1218
+ return { ok: false, blocking: [], reason: "The document carries no version, so there is nothing to convert down from." };
1219
+ }
1220
+ const relation = compareWireVersion(from, cfg.target, cfg.readerReadsEditorPart);
1221
+ if (relation === "otherGeneration") {
1222
+ return {
1223
+ ok: false,
1224
+ blocking: [],
1225
+ reason: "Schema " + formatWireVersion(from) + " and " + formatWireVersion(cfg.target) + " are different generations; no conversion bridges them."
1226
+ };
1227
+ }
1228
+ if (relation !== "newer") return { ok: true, doc, applied: [] };
1229
+ const toUndo = [];
1230
+ for (const step of cfg.steps) {
1231
+ const stepTo = parseWireVersion(step.to);
1232
+ if (!stepTo) continue;
1233
+ if (compareWireVersion(stepTo, cfg.target, cfg.readerReadsEditorPart) !== "newer") continue;
1234
+ if (compareWireVersion(stepTo, from, cfg.readerReadsEditorPart) === "newer") continue;
1235
+ toUndo.push(step);
1236
+ }
1237
+ toUndo.reverse();
1238
+ const blocking = toUndo.filter((s) => s.kind === "converted" && !s.down);
1239
+ if (blocking.length) {
1240
+ return {
1241
+ ok: false,
1242
+ blocking,
1243
+ reason: "Cannot convert down to " + formatWireVersion(cfg.target) + ": " + blocking.map((s) => s.from + " \u2192 " + s.to + " (" + s.reason + ")").join("; ") + " cannot be undone."
1244
+ };
1245
+ }
1246
+ const target = clonePlain(doc);
1247
+ const applied = [];
1248
+ for (const step of toUndo) {
1249
+ if (!step.down) continue;
1250
+ try {
1251
+ step.down(target);
1252
+ applied.push(step);
1253
+ } catch (e) {
1254
+ return {
1255
+ ok: false,
1256
+ blocking: [step],
1257
+ reason: "Undoing " + step.from + " \u2192 " + step.to + " failed: " + String(e)
1258
+ };
1259
+ }
1260
+ }
1261
+ stampVersion(target, cfg.target, cfg.readerReadsEditorPart);
1262
+ return { ok: true, doc: target, applied };
1263
+ }
1264
+ function downgradePlayerDocument(doc, target) {
1265
+ return applyWireStepsDown(doc, { steps: PLAYER_WIRE_STEPS, target, readerReadsEditorPart: false });
1266
+ }
1267
+ var PxFillMode = {
1268
+ forwards: "forwards",
1269
+ backwards: "backwards",
1270
+ both: "both",
1271
+ none: "none"
1272
+ };
1273
+ var PxPlaybackDirection = {
1274
+ normal: "normal",
1275
+ reverse: "reverse",
1276
+ alternate: "alternate",
1277
+ alternateReverse: "alternate-reverse"
1278
+ };
1072
1279
  var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
1073
1280
  var PX_ANIM_ATTR_NAME = "_px_animator";
1281
+ var PxStartOn = {
1282
+ load: "load",
1283
+ mouseOver: "mouseOver",
1284
+ click: "click",
1285
+ scrollIntoView: "scrollIntoView",
1286
+ programmatic: "programmatic"
1287
+ };
1288
+ var PxOutAction = {
1289
+ continue: "continue",
1290
+ pause: "pause",
1291
+ reset: "reset",
1292
+ reverse: "reverse"
1293
+ };
1294
+ var PxFinishAction = {
1295
+ hold: "hold",
1296
+ reset: "reset"
1297
+ };
1298
+ var PxScrollKind = {
1299
+ view: "view",
1300
+ scroll: "scroll"
1301
+ };
1302
+ var PxScrollAxis = {
1303
+ block: "block",
1304
+ inline: "inline",
1305
+ x: "x",
1306
+ y: "y"
1307
+ };
1308
+ var PxScrollSource = {
1309
+ nearest: "nearest",
1310
+ root: "root"
1311
+ };
1312
+ var PxPinAlign = {
1313
+ top: "top",
1314
+ center: "center",
1315
+ bottom: "bottom"
1316
+ };
1317
+ var PxScrollPhase = {
1318
+ cover: "cover",
1319
+ contain: "contain",
1320
+ entry: "entry",
1321
+ exit: "exit",
1322
+ entryCrossing: "entry-crossing",
1323
+ exitCrossing: "exit-crossing"
1324
+ };
1325
+ var PxAlongPathMode = {
1326
+ sampled: "sampled",
1327
+ offsetPath: "offsetPath"
1328
+ };
1074
1329
  var PX_TIMELINE_SHARED_KEYS = ["duration", "iterations", "engine", "frameRate"];
1075
1330
  var PX_TIME_ONLY_TIMELINE_KEYS = ["trigger", "delay", "fillMode", "direction"];
1331
+ var PX_FLAT_RUNTIME_VIEW_KEYS = [
1332
+ ...PX_TIMELINE_SHARED_KEYS,
1333
+ ...PX_TIME_ONLY_TIMELINE_KEYS,
1334
+ "fill",
1335
+ "resetOnFinish",
1336
+ "timelineSource",
1337
+ "scroll"
1338
+ ];
1076
1339
  var PxTimelineEngine = {
1077
1340
  native: "native",
1078
1341
  js: "js"
@@ -1089,6 +1352,50 @@ function isNativeForced(engine) {
1089
1352
  function mayUseNativeScrollTimeline(engine) {
1090
1353
  return engine !== PxTimelineEngineExtra.js;
1091
1354
  }
1355
+ var PX_TRIGGER_DEFAULTS = {
1356
+ startOn: "load",
1357
+ outAction: "continue",
1358
+ scrollIntoViewThreshold: 0
1359
+ };
1360
+ var PxControlMode = {
1361
+ /** No control props — the document's trigger decides, and nothing is taken over. */
1362
+ static: "static",
1363
+ /** `progress` / `time` — the host scrubs; the component seeks and stays paused. */
1364
+ fixedTime: "fixedTime",
1365
+ /** `play` / `pause` — the host drives playback with booleans. */
1366
+ play: "play",
1367
+ /** `autoplay` — the document's own trigger starts it. */
1368
+ autoplay: "autoplay"
1369
+ };
1370
+ function resolveControlMode(props) {
1371
+ const hasFixedTime = props.progress !== void 0 || props.time !== void 0;
1372
+ const hasPlayPause = props.play !== void 0 || props.pause !== void 0;
1373
+ const hasAutoplay = !!props.autoplay;
1374
+ const warnings = [];
1375
+ const named = (a, b, winner) => a + " and " + b + " were both set \u2014 " + winner + " wins, " + (winner === a ? b : a) + " is ignored.";
1376
+ if (hasFixedTime) {
1377
+ if (hasPlayPause) warnings.push(named("progress/time", "play/pause", "progress/time"));
1378
+ if (hasAutoplay) warnings.push(named("progress/time", "autoplay", "progress/time"));
1379
+ return { mode: PxControlMode.fixedTime, warnings };
1380
+ }
1381
+ if (hasPlayPause) {
1382
+ if (hasAutoplay) warnings.push(named("play/pause", "autoplay", "play/pause"));
1383
+ return { mode: PxControlMode.play, warnings };
1384
+ }
1385
+ if (hasAutoplay) return { mode: PxControlMode.autoplay, warnings };
1386
+ return { mode: PxControlMode.static, warnings };
1387
+ }
1388
+ function controlModeTakesOverTrigger(mode) {
1389
+ return mode !== PxControlMode.autoplay;
1390
+ }
1391
+ function resolveTrigger(trigger) {
1392
+ var _a2, _b, _c;
1393
+ return {
1394
+ startOn: (_a2 = trigger == null ? void 0 : trigger.startOn) != null ? _a2 : PX_TRIGGER_DEFAULTS.startOn,
1395
+ outAction: (_b = trigger == null ? void 0 : trigger.outAction) != null ? _b : PX_TRIGGER_DEFAULTS.outAction,
1396
+ scrollIntoViewThreshold: (_c = trigger == null ? void 0 : trigger.scrollIntoViewThreshold) != null ? _c : PX_TRIGGER_DEFAULTS.scrollIntoViewThreshold
1397
+ };
1398
+ }
1092
1399
  var PxLoopRepeatAt = {
1093
1400
  /** Segment from the START; the repetition runs BEFORE the first keyframe
1094
1401
  * (intro loops that play until the main timeline begins). */
@@ -1135,7 +1442,6 @@ var PxStrokeTrimSubPaths = {
1135
1442
  separate: "separate",
1136
1443
  combined: "combined"
1137
1444
  };
1138
- var TEXT_ATTR = "text";
1139
1445
  var TEXT_CONTENT_ATTR = "textContent";
1140
1446
  var CLASS_ATTR = "class";
1141
1447
  var TRANSFORM_ATTR = "transform";
@@ -1147,7 +1453,6 @@ var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
1147
1453
  "meta",
1148
1454
  "animate",
1149
1455
  "effects",
1150
- TEXT_ATTR,
1151
1456
  TEXT_CONTENT_ATTR
1152
1457
  ]);
1153
1458
  var TRANSFORM_PART = {
@@ -1162,10 +1467,6 @@ var PX_TRANSFORM_PART_KEYS = [
1162
1467
  TRANSFORM_PART.scale,
1163
1468
  TRANSFORM_PART.origin
1164
1469
  ];
1165
- var PxGradientUnits = {
1166
- userSpaceOnUse: "userSpaceOnUse",
1167
- objectBoundingBox: "objectBoundingBox"
1168
- };
1169
1470
  var PxGradientSpreadMethod = {
1170
1471
  pad: "pad",
1171
1472
  reflect: "reflect",
@@ -1184,8 +1485,18 @@ function isPxElementFileFormat(fileJson) {
1184
1485
  function getAnimatorConfig(doc) {
1185
1486
  var _a2;
1186
1487
  const cfg = (doc == null ? void 0 : doc.animator) || ((_a2 = doc == null ? void 0 : doc.meta) == null ? void 0 : _a2.animator);
1187
- return cfg ? flattenAnimatorTimeline(cfg) : void 0;
1188
- }
1488
+ if (!cfg) return void 0;
1489
+ const memoised = wireViewMemo.get(cfg);
1490
+ if (memoised) return memoised;
1491
+ const wire = cfg;
1492
+ const stray = PX_FLAT_RUNTIME_VIEW_KEYS.filter((k) => wire[k] !== void 0);
1493
+ const source = stray.length ? __spreadValues2({}, wire) : cfg;
1494
+ for (const k of stray) delete source[k];
1495
+ const view = flattenAnimatorTimeline(source);
1496
+ wireViewMemo.set(cfg, view);
1497
+ return view;
1498
+ }
1499
+ var wireViewMemo = /* @__PURE__ */ new WeakMap();
1189
1500
  var flattenMemo = /* @__PURE__ */ new WeakMap();
1190
1501
  function flattenAnimatorTimeline(cfg) {
1191
1502
  const timeline = cfg.timeline;
@@ -1211,7 +1522,7 @@ function flattenAnimatorTimeline(cfg) {
1211
1522
  else if (pin && typeof pin === "object") {
1212
1523
  scroll.pin = true;
1213
1524
  if (pin.align !== void 0) scroll.pinAlign = pin.align;
1214
- if (pin.top !== void 0) scroll.pinTop = pin.top;
1525
+ if (pin.offset !== void 0) scroll.pinOffset = pin.offset;
1215
1526
  if (pin.distance !== void 0) scroll.pinDistance = pin.distance;
1216
1527
  }
1217
1528
  flat.scroll = scroll;
@@ -1254,14 +1565,13 @@ var PxKeyframeValueSchema = implementsInterface()(px.union([
1254
1565
  // e.g. for colors
1255
1566
  px.number(),
1256
1567
  px.array(px.number()),
1257
- // ORDER LAW: the key-discriminated object shapes (`{path}`, `{paths}`) come BEFORE the
1568
+ // ORDER LAW: the key-discriminated object shape (`{pathData}`) comes BEFORE the
1258
1569
  // all-optional transform-parts record. In default (non-strict) mode that record accepts
1259
1570
  // ANY object (every key optional, unknown keys ignored), so listing it earlier made
1260
- // Union.sanitize route `{path}`/`{paths}` values into it and strip them to `{}` —
1571
+ // Union.sanitize route `{pathData}` values into it and strip them to `{}` —
1261
1572
  // silent morph-data loss (repro: the editor's keyframeValueSanitize spec). Validity is
1262
1573
  // order-independent (`some()`); only sanitize routing depends on this order.
1263
- px.object({ path: px.string() }),
1264
- px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),
1574
+ px.object({ pathData: px.string() }),
1265
1575
  // Gradient `stops` timeline — each kf value is the full stops-array snapshot.
1266
1576
  px.lazy(() => px.array(PxGradientStopSchema), []),
1267
1577
  px.lazy(() => PxTransformPartsSchema, {})
@@ -1301,7 +1611,7 @@ var PxPropertyAnimationSchema = implementsInterface()(px.object({
1301
1611
  keyframes: px.array(PxKeyframeSchema).optional(),
1302
1612
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
1303
1613
  autoOrient: px.boolean().optional(),
1304
- alongPathMode: px.enum(["sampled", "offsetPath"]).optional()
1614
+ alongPathMode: px.enum([PxAlongPathMode.sampled, PxAlongPathMode.offsetPath]).optional()
1305
1615
  }));
1306
1616
  var PxTransformPartsSchema = implementsInterface()(px.object({
1307
1617
  translate: px.tuple([px.number(), px.number()]).optional(),
@@ -1325,17 +1635,17 @@ var PxElementAnimationSchema = implementsInterface()(px.union([
1325
1635
  PxAnimationDefinitionSchema
1326
1636
  ]));
1327
1637
  var PxTriggerSchema = implementsInterface()(px.object({
1328
- startOn: px.enum(["load", "mouseOver", "click", "scrollIntoView", "programmatic"]).optional(),
1329
- outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
1638
+ startOn: px.enum([PxStartOn.load, PxStartOn.mouseOver, PxStartOn.click, PxStartOn.scrollIntoView, PxStartOn.programmatic], PX_TRIGGER_DEFAULTS.startOn).optional(),
1639
+ outAction: px.enum([PxOutAction.continue, PxOutAction.pause, PxOutAction.reset, PxOutAction.reverse], PX_TRIGGER_DEFAULTS.outAction).optional(),
1330
1640
  // What happens after a NATURAL finish — `'hold'` (default: keep the end state per
1331
1641
  // `fill`) or `'reset'` (snap back to the start state). Pairs with `outAction` ("what
1332
1642
  // happens when the trigger condition ends"); both end-of-life knobs now read alike.
1333
- finishAction: px.enum(["hold", "reset"]).optional(),
1643
+ finishAction: px.enum([PxFinishAction.hold, PxFinishAction.reset]).optional(),
1334
1644
  scrollIntoViewThreshold: px.number().optional()
1335
1645
  }));
1336
1646
  var PxGlyphSchema = implementsInterface()(px.object({
1337
1647
  width: px.number(),
1338
- d: px.string()
1648
+ pathData: px.string()
1339
1649
  }));
1340
1650
  var PxGlyphFontSchema = implementsInterface()(px.object({
1341
1651
  fontFamily: px.string(),
@@ -1352,9 +1662,15 @@ var PxDefsSchema = implementsInterface()(px.object({
1352
1662
  styles: px.record(px.record(px.union([px.string(), px.number()]))).optional(),
1353
1663
  fonts: px.record(PxGlyphFontSchema).optional()
1354
1664
  }));
1355
- var PX_SCROLL_PHASES = ["cover", "contain", "entry", "exit", "entry-crossing", "exit-crossing"];
1356
1665
  var PxScrollRangePointSchema = implementsInterface()(px.object({
1357
- phase: px.enum(PX_SCROLL_PHASES).optional(),
1666
+ phase: px.enum([
1667
+ PxScrollPhase.cover,
1668
+ PxScrollPhase.contain,
1669
+ PxScrollPhase.entry,
1670
+ PxScrollPhase.exit,
1671
+ PxScrollPhase.entryCrossing,
1672
+ PxScrollPhase.exitCrossing
1673
+ ]).optional(),
1358
1674
  fraction: px.number().optional()
1359
1675
  }));
1360
1676
  var PxScrollRangeSchema = px.object({
@@ -1362,21 +1678,21 @@ var PxScrollRangeSchema = px.object({
1362
1678
  end: PxScrollRangePointSchema.optional()
1363
1679
  });
1364
1680
  var PxScrollSchema = implementsInterface()(px.object({
1365
- kind: px.enum(["view", "scroll"]).optional(),
1366
- axis: px.enum(["block", "inline", "x", "y"]).optional(),
1367
- source: px.enum(["nearest", "root"]).optional(),
1681
+ kind: px.enum([PxScrollKind.view, PxScrollKind.scroll]).optional(),
1682
+ axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
1683
+ source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
1368
1684
  // Free-form: the two keywords `parent`/`scroller` plus any CSS selector.
1369
1685
  subject: px.string().optional(),
1370
1686
  smoothing: px.number().optional(),
1371
1687
  pin: px.boolean().optional(),
1372
- pinAlign: px.enum(["top", "center", "bottom"]).optional(),
1373
- pinTop: px.number().optional(),
1688
+ pinAlign: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
1689
+ pinOffset: px.number().optional(),
1374
1690
  pinDistance: px.number().optional(),
1375
1691
  range: PxScrollRangeSchema.optional()
1376
1692
  }));
1377
1693
  var PxTimelinePinSchema = implementsInterface()(px.object({
1378
- align: px.enum(["top", "center", "bottom"]).optional(),
1379
- top: px.number().optional(),
1694
+ align: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
1695
+ offset: px.number().optional(),
1380
1696
  distance: px.number().optional()
1381
1697
  }));
1382
1698
  var PxTimelineEngineSchema = px.enum([PxTimelineEngineExtra.auto, PxTimelineEngineExtra.native, PxTimelineEngineExtra.js]).optional();
@@ -1391,8 +1707,8 @@ var PxTimeTimelineSchema = implementsInterface()(px.object({
1391
1707
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
1392
1708
  // `fillMode` on the wire (CSS `animation-fill-mode`; the runtime view calls it `fill`)
1393
1709
  // — never `fill`, which is paint everywhere else in the format.
1394
- fillMode: px.enum(["forwards", "backwards", "both", "none"]).optional(),
1395
- direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional()
1710
+ fillMode: px.enum([PxFillMode.forwards, PxFillMode.backwards, PxFillMode.both, PxFillMode.none]).optional(),
1711
+ direction: px.enum([PxPlaybackDirection.normal, PxPlaybackDirection.reverse, PxPlaybackDirection.alternate, PxPlaybackDirection.alternateReverse]).optional()
1396
1712
  }));
1397
1713
  var scrollishTimelineShape = {
1398
1714
  // §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
@@ -1403,8 +1719,8 @@ var scrollishTimelineShape = {
1403
1719
  iterations: px.number().optional(),
1404
1720
  engine: PxTimelineEngineSchema,
1405
1721
  frameRate: px.number().optional(),
1406
- axis: px.enum(["block", "inline", "x", "y"]).optional(),
1407
- source: px.enum(["nearest", "root"]).optional(),
1722
+ axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
1723
+ source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
1408
1724
  subject: px.string().optional(),
1409
1725
  // 'parent' | 'scroller' | any CSS selector
1410
1726
  smoothing: px.number().optional(),
@@ -1493,7 +1809,7 @@ var PxMaskedByEffectSchema = implementsInterface()(px.object({
1493
1809
  height: px.number().optional()
1494
1810
  }));
1495
1811
  var PxClipPathEffectSchema = implementsInterface()(px.object({
1496
- d: PxAnimatableStringSchema.optional()
1812
+ pathData: PxAnimatableStringSchema.optional()
1497
1813
  }));
1498
1814
  var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
1499
1815
  offset: PxAnimatableNumberSchema.optional(),
@@ -1530,7 +1846,7 @@ var PxFillGradientEffectSchema = implementsInterface()(px.object({
1530
1846
  radius: PxAnimatableNumberSchema.optional(),
1531
1847
  focal: PxAnimatableVec2Schema.optional(),
1532
1848
  stops: PxAnimatableGradientStopsSchema.optional(),
1533
- gradientUnits: px.enum([PxGradientUnits.userSpaceOnUse, PxGradientUnits.objectBoundingBox]).optional(),
1849
+ gradientUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1534
1850
  spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
1535
1851
  gradientTransform: px.string().optional()
1536
1852
  }));
@@ -1576,11 +1892,71 @@ function validateNodeEffects(root, opts) {
1576
1892
  walk(root, "root");
1577
1893
  return warnings;
1578
1894
  }
1579
- function validateDocument(doc) {
1580
- const ctx = { errors: [], warnings: [], strict: true };
1895
+ function validateGlyphFontRefs(root, fonts) {
1896
+ if (!fonts || !Object.keys(fonts).length) return [];
1897
+ const problems = [];
1898
+ const walk = (node, path, inherited, inGlyphText) => {
1899
+ var _a2, _b;
1900
+ if (!node) return;
1901
+ const own = typeof node.fontFamily === "string" ? node.fontFamily : void 0;
1902
+ const family = own != null ? own : inherited;
1903
+ const isGlyphText = inGlyphText || node.type === "text" && !!((_b = (_a2 = node.effects) == null ? void 0 : _a2.text) == null ? void 0 : _b.useGlyphs);
1904
+ if (isGlyphText && own && !Object.prototype.hasOwnProperty.call(fonts, own)) {
1905
+ const problem = path + ': glyph-mode text uses font-family "' + own + '", which has no entry in animator.definitions.fonts';
1906
+ if (!problems.includes(problem)) problems.push(problem);
1907
+ }
1908
+ if (Array.isArray(node.children)) {
1909
+ node.children.forEach((c, i) => walk(c, path + ".children[" + i + "]", family, isGlyphText));
1910
+ }
1911
+ };
1912
+ walk(root, "root", void 0, false);
1913
+ return problems;
1914
+ }
1915
+ function validateEasingRefs(root, easings) {
1916
+ const problems = [];
1917
+ const walk = (node, path) => {
1918
+ if (Array.isArray(node)) {
1919
+ node.forEach((item, i) => walk(item, path + "[" + i + "]"));
1920
+ return;
1921
+ }
1922
+ if (!node || typeof node !== "object") return;
1923
+ const easing = node.easing;
1924
+ if (typeof easing === "string" && !(easings && Object.prototype.hasOwnProperty.call(easings, easing))) {
1925
+ const problem = path + '.easing: "' + easing + '" names no entry in animator.definitions.easings \u2014 it will play linear';
1926
+ if (!problems.includes(problem)) problems.push(problem);
1927
+ }
1928
+ for (const [key, value] of Object.entries(node)) {
1929
+ if (key === "easing") continue;
1930
+ if (value && typeof value === "object") walk(value, path + "." + key);
1931
+ }
1932
+ };
1933
+ walk(root, "root");
1934
+ return problems;
1935
+ }
1936
+ function validateVersionStamp(doc) {
1937
+ var _a2;
1938
+ const version = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.version;
1939
+ if (version === void 0) return [];
1940
+ if (parseWireVersion(version) !== void 0) return [];
1941
+ return ["root.animator.version: " + JSON.stringify(version) + ' is not a version stamp ("a.b" or "a.b.c") \u2014 it reads as unstamped'];
1942
+ }
1943
+ function validateDocument(doc, opts) {
1944
+ var _a2;
1945
+ const strict = (opts == null ? void 0 : opts.strict) !== false;
1946
+ const ctx = { errors: [], warnings: [], strict };
1581
1947
  const problems = PxAnimatedSvgDocumentSchema.isValid(doc, ctx, ["root"]) ? [] : [...ctx.errors];
1582
1948
  if (doc && typeof doc === "object") {
1583
- for (const w of validateNodeEffects(doc, { strict: true })) {
1949
+ for (const w of validateNodeEffects(doc, { strict })) {
1950
+ if (!problems.includes(w)) problems.push(w);
1951
+ }
1952
+ const defs = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
1953
+ for (const w of validateGlyphFontRefs(doc, defs == null ? void 0 : defs.fonts)) {
1954
+ if (!problems.includes(w)) problems.push(w);
1955
+ }
1956
+ for (const w of validateEasingRefs(doc, defs == null ? void 0 : defs.easings)) {
1957
+ if (!problems.includes(w)) problems.push(w);
1958
+ }
1959
+ for (const w of validateVersionStamp(doc)) {
1584
1960
  if (!problems.includes(w)) problems.push(w);
1585
1961
  }
1586
1962
  }
@@ -1603,10 +1979,13 @@ var PxNodeBase = px.openObject({
1603
1979
  // documented — because a wire key that is not in a schema is invisible to the
1604
1980
  // minifier's reserve list and gets renamed (MINIFICATION-BOUNDARY-PLAN.md §1.1).
1605
1981
  domType: px.string().optional(),
1982
+ // Text content of a `<text>` / `<tspan>`. Declared, so a non-string value is a schema error
1983
+ // and the minifier reserves the key; `text` is NOT an alias for it and is not read anywhere.
1984
+ textContent: px.string().optional(),
1606
1985
  id: px.string().optional(),
1607
1986
  meta: px.any().optional(),
1608
1987
  // Player-effects bucket emitted by the Editor's lightweight design format.
1609
- // Consumed and removed by `applyPlayerEffects` before any other normalisation
1988
+ // Consumed and removed by `applyPlayerEffects` before any other normalization
1610
1989
  // (see `createAnimatorImpl`), so downstream code never sees it.
1611
1990
  effects: PxEffectsSchema.optional(),
1612
1991
  // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
@@ -1638,8 +2017,8 @@ var PxBezierPathSchema = implementsInterface()(px.object({
1638
2017
  c: px.boolean().optional()
1639
2018
  }));
1640
2019
  function isPxElementFileFormatDeep(fileJson) {
1641
- const valid = PxAnimatedSvgDocumentSchema.isValid(fileJson);
1642
- return { valid, errors: valid ? [] : ["Document failed schema validation"] };
2020
+ const errors = validateDocument(fileJson, { strict: false });
2021
+ return { valid: errors.length === 0, errors };
1643
2022
  }
1644
2023
  var _idCounter = 0;
1645
2024
  function generateUniqueId() {
@@ -1794,7 +2173,7 @@ function isDangerousAttrName(nameLower) {
1794
2173
  if (nameLower.startsWith("on")) return true;
1795
2174
  return false;
1796
2175
  }
1797
- function sanitiseAttributeValue(name, value) {
2176
+ function sanitizeAttributeValue(name, value) {
1798
2177
  const nameLower = name.toLowerCase();
1799
2178
  if (isDangerousAttrName(nameLower)) {
1800
2179
  console.warn("Attribute blocked (event handler / dangerous): ", nameLower);
@@ -1833,7 +2212,7 @@ function getNormalizedProps(props) {
1833
2212
  if (INTERNAL_ATTRS.has(key)) continue;
1834
2213
  if (key === "style") continue;
1835
2214
  let value = props[rawKey];
1836
- if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
2215
+ if (COLOR_ATTR_NAMES.has(key) && Array.isArray(value)) {
1837
2216
  propsCopy[key] = toRGBA(value);
1838
2217
  } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes) {
1839
2218
  const parts = value.value && typeof value.value === "object" ? value.value : value;
@@ -1933,7 +2312,7 @@ function tFromArcFraction(lut, arcFrac) {
1933
2312
  var DEFAULT_FLATNESS_TOL = 0.5;
1934
2313
  var DEFAULT_ROTATION_TOL = 5;
1935
2314
  var DEFAULT_MAX_SAMPLES = 32;
1936
- function materialiseMotionPathInPropAnim(anim, opts) {
2315
+ function materializeMotionPathInPropAnim(anim, opts) {
1937
2316
  var _a2, _b, _c;
1938
2317
  if (!propAnimIsMotionPath(anim)) return anim;
1939
2318
  const kfs = anim.keyframes;
@@ -1965,7 +2344,7 @@ function materialiseMotionPathInPropAnim(anim, opts) {
1965
2344
  if (autoOrient && i > 0) {
1966
2345
  insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);
1967
2346
  }
1968
- materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
2347
+ materializeSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
1969
2348
  }
1970
2349
  const lastInE = getKfEasing(kfs[kfs.length - 1]);
1971
2350
  if (lastInE) out[out.length - 1].e = lastInE;
@@ -2079,7 +2458,7 @@ function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos,
2079
2458
  out.push(makeOutKf(stepTime, dupValue));
2080
2459
  }
2081
2460
  var CORNER_STEP_AFTER_BOUNDARY_MS = 0.05;
2082
- function materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
2461
+ function materializeSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
2083
2462
  const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
2084
2463
  const prevTime = getKfTime(prevKf);
2085
2464
  const nextTime = getKfTime(nextKf);
@@ -2202,16 +2581,16 @@ function perpDist(q, pA, pB) {
2202
2581
  const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
2203
2582
  return Math.abs(cross) / Math.sqrt(len2);
2204
2583
  }
2205
- function materialiseMotionPathsInTree(root, opts) {
2206
- const out = walkAndMaterialise(root, opts);
2584
+ function materializeMotionPathsInTree(root, opts) {
2585
+ const out = walkAndMaterialize(root, opts);
2207
2586
  return out != null ? out : root;
2208
2587
  }
2209
- function walkAndMaterialise(node, opts) {
2588
+ function walkAndMaterialize(node, opts) {
2210
2589
  let newChildren;
2211
2590
  if (node.children) {
2212
2591
  for (let i = 0; i < node.children.length; i++) {
2213
2592
  const ch = node.children[i];
2214
- const ret = walkAndMaterialise(ch, opts);
2593
+ const ret = walkAndMaterialize(ch, opts);
2215
2594
  if (ret !== null) {
2216
2595
  if (!newChildren) newChildren = node.children.slice();
2217
2596
  newChildren[i] = ret;
@@ -2224,9 +2603,9 @@ function walkAndMaterialise(node, opts) {
2224
2603
  const animDef = animBucket;
2225
2604
  const transformAnim = animDef.transform;
2226
2605
  if (transformAnim && typeof transformAnim === "object" && propAnimIsMotionPath(transformAnim)) {
2227
- const materialised = materialiseMotionPathInPropAnim(transformAnim, opts);
2228
- if (materialised !== transformAnim) {
2229
- newAnimate = __spreadProps2(__spreadValues2({}, animDef), { transform: materialised });
2606
+ const materialized = materializeMotionPathInPropAnim(transformAnim, opts);
2607
+ if (materialized !== transformAnim) {
2608
+ newAnimate = __spreadProps2(__spreadValues2({}, animDef), { transform: materialized });
2230
2609
  }
2231
2610
  }
2232
2611
  }
@@ -2327,8 +2706,8 @@ function isPathString(value) {
2327
2706
  return typeof value === "string" && extractPathData(value) !== void 0;
2328
2707
  }
2329
2708
  function normalizePathValue(value) {
2330
- if (value && typeof value === "object" && typeof value.path === "string") {
2331
- const d = extractPathData(value.path);
2709
+ if (value && typeof value === "object" && typeof value.pathData === "string") {
2710
+ const d = extractPathData(value.pathData);
2332
2711
  return d ? { paths: parseSvgPathToBezier(d) } : value;
2333
2712
  }
2334
2713
  if (value && typeof value === "object" && "paths" in value) {
@@ -2412,7 +2791,7 @@ function interpolateValue(propName, a, b, t) {
2412
2791
  const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
2413
2792
  return { paths: interpolateBeziers(aPaths, bPaths, t) };
2414
2793
  }
2415
- if (COLOUR_ATTR_NAMES.has(propName)) {
2794
+ if (COLOR_ATTR_NAMES.has(propName)) {
2416
2795
  return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
2417
2796
  }
2418
2797
  if (propName === "transform" && typeof a === "object" && a !== null && !Array.isArray(a) && typeof b === "object" && b !== null && !Array.isArray(b)) {
@@ -2634,7 +3013,7 @@ function normalizeKeyframes(propName, propAnim, duration, defs) {
2634
3013
  value = normalizePathValue(value);
2635
3014
  }
2636
3015
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2637
- if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
3016
+ if (COLOR_ATTR_NAMES.has(propNameKebab)) {
2638
3017
  value = (_a2 = parseColor(value)) != null ? _a2 : value;
2639
3018
  }
2640
3019
  const normKf = {
@@ -2668,20 +3047,20 @@ function mergeAnimationDefinitions(animations) {
2668
3047
  }
2669
3048
  return merged;
2670
3049
  }
2671
- function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
3050
+ function materializeInternalLoopsInPropAnim(propName, propAnim, duration) {
2672
3051
  const loopRaw = propAnim.loop;
2673
3052
  if (loopRaw === void 0 || loopRaw === null || loopRaw === false) return propAnim;
2674
3053
  const loop = loopRaw === true ? {} : loopRaw;
2675
3054
  const rawKfs = propAnim.keyframes;
2676
3055
  if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
2677
3056
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
2678
- const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);
3057
+ const isColor = COLOR_ATTR_NAMES.has(propNameKebab);
2679
3058
  const kfs = rawKfs.map((kf) => {
2680
3059
  var _a2;
2681
3060
  const t = kfTime(kf);
2682
3061
  let v = kfValue(kf);
2683
3062
  if (propName === "d") v = normalizePathValue(v);
2684
- if (isColour) v = (_a2 = parseColor(v)) != null ? _a2 : v;
3063
+ if (isColor) v = (_a2 = parseColor(v)) != null ? _a2 : v;
2685
3064
  const e = kfEasing(kf);
2686
3065
  const out2 = { t, v, e };
2687
3066
  const tIn = kfTangentIn(kf);
@@ -2695,15 +3074,15 @@ function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
2695
3074
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2696
3075
  return out;
2697
3076
  }
2698
- function materialiseInternalLoopsInTree(root, duration) {
2699
- const ret = walkAndMaterialiseLoops(root, duration);
3077
+ function materializeInternalLoopsInTree(root, duration) {
3078
+ const ret = walkAndMaterializeLoops(root, duration);
2700
3079
  return ret != null ? ret : root;
2701
3080
  }
2702
- function walkAndMaterialiseLoops(node, duration) {
3081
+ function walkAndMaterializeLoops(node, duration) {
2703
3082
  let newChildren;
2704
3083
  if (node.children) {
2705
3084
  for (let i = 0; i < node.children.length; i++) {
2706
- const ret = walkAndMaterialiseLoops(node.children[i], duration);
3085
+ const ret = walkAndMaterializeLoops(node.children[i], duration);
2707
3086
  if (ret !== null) {
2708
3087
  if (!newChildren) newChildren = node.children.slice();
2709
3088
  newChildren[i] = ret;
@@ -2716,10 +3095,10 @@ function walkAndMaterialiseLoops(node, duration) {
2716
3095
  const animDef = animBucket;
2717
3096
  for (const propName of Object.keys(animDef)) {
2718
3097
  const propAnim = animDef[propName];
2719
- const materialised = materialiseInternalLoopsInPropAnim(propName, propAnim, duration);
2720
- if (materialised !== propAnim) {
3098
+ const materialized = materializeInternalLoopsInPropAnim(propName, propAnim, duration);
3099
+ if (materialized !== propAnim) {
2721
3100
  if (!newAnimate) newAnimate = __spreadValues2({}, animDef);
2722
- newAnimate[propName] = materialised;
3101
+ newAnimate[propName] = materialized;
2723
3102
  }
2724
3103
  }
2725
3104
  }
@@ -2774,12 +3153,12 @@ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxTimeli
2774
3153
  const out = { keyframes: normalizedKfs };
2775
3154
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
2776
3155
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
2777
- normalized[propName] = engine === PxTimelineEngine.native && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
3156
+ normalized[propName] = engine === PxTimelineEngine.native && propName === "transform" ? materializeMotionPathInPropAnim(out) : out;
2778
3157
  }
2779
3158
  }
2780
3159
  return normalized;
2781
3160
  }
2782
- function getNormalisedBindings(doc, engine = PxTimelineEngine.native) {
3161
+ function getNormalizedBindings(doc, engine = PxTimelineEngine.native) {
2783
3162
  const animatorConfig = getAnimatorConfig(doc) || {};
2784
3163
  const defs = getDefs(doc);
2785
3164
  const duration = animatorConfig.duration || 1e3;
@@ -2870,7 +3249,7 @@ function calcPropertyValue(propName, propAnim, progress) {
2870
3249
  nextPaths,
2871
3250
  localProgress
2872
3251
  ).map((bz) => bezierToSvgPath(bz)).join("");
2873
- } else if (COLOUR_ATTR_NAMES.has(cssAttrName)) {
3252
+ } else if (COLOR_ATTR_NAMES.has(cssAttrName)) {
2874
3253
  cssValue = toRGBA(interpolateColor(
2875
3254
  prevV || [0, 0, 0, 1],
2876
3255
  nextV || [0, 0, 0, 1],
@@ -3028,7 +3407,7 @@ function applyUseOffsetToG(gNode) {
3028
3407
  }
3029
3408
  return gNode;
3030
3409
  }
3031
- function materialiseAnimatedUseInstances(root) {
3410
+ function materializeAnimatedUseInstances(root) {
3032
3411
  var _a2;
3033
3412
  const idMap = buildIdMap(root);
3034
3413
  const animatedIds = computeAnimatedSubtreeIds(root, idMap);
@@ -3037,7 +3416,7 @@ function materialiseAnimatedUseInstances(root) {
3037
3416
  const genId3 = () => "_lw_use_mat_" + ++idCounter;
3038
3417
  const rootViewport = readRootViewport(root);
3039
3418
  const defsCollector = [];
3040
- const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
3419
+ const walked = walkAndMaterialize2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
3041
3420
  if (defsCollector.length === 0) return walked;
3042
3421
  const defsNode = { type: "defs", children: defsCollector };
3043
3422
  const newChildren = [...(_a2 = walked.children) != null ? _a2 : [], defsNode];
@@ -3110,7 +3489,7 @@ function stripHash(href) {
3110
3489
  if (typeof href !== "string") return void 0;
3111
3490
  return href.startsWith("#") ? href.slice(1) : href;
3112
3491
  }
3113
- function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3492
+ function materializeOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3114
3493
  var _a2, _b, _c, _d;
3115
3494
  const clone2 = deepClonePxNode(target);
3116
3495
  regenerateIdsAndRewriteRefs(clone2, genId3);
@@ -3118,8 +3497,8 @@ function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsColl
3118
3497
  const useW = (_b = (_a2 = numericAttr(useNode.width)) != null ? _a2 : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
3119
3498
  const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
3120
3499
  const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
3121
- const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
3122
- const newNode = __spreadProps2(__spreadValues2({}, useNode), { type: "g", children: [materialisedClone] });
3500
+ const materializedClone = walkAndMaterialize2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
3501
+ const newNode = __spreadProps2(__spreadValues2({}, useNode), { type: "g", children: [materializedClone] });
3123
3502
  delete newNode.href;
3124
3503
  delete newNode.width;
3125
3504
  delete newNode.height;
@@ -3157,18 +3536,18 @@ function parseViewBox(v) {
3157
3536
  if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
3158
3537
  return [parts[0], parts[1], parts[2], parts[3]];
3159
3538
  }
3160
- function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3539
+ function walkAndMaterialize2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3161
3540
  if (node.type === "use" && typeof node.href === "string") {
3162
3541
  const targetId = stripHash(node.href);
3163
3542
  if (targetId && animatedIds.has(targetId)) {
3164
3543
  const target = idMap.get(targetId);
3165
- if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
3544
+ if (target) return materializeOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
3166
3545
  }
3167
3546
  }
3168
3547
  if (!node.children) return node;
3169
3548
  let changed = false;
3170
3549
  const newChildren = node.children.map((ch) => {
3171
- const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
3550
+ const m = walkAndMaterialize2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
3172
3551
  if (m !== ch) changed = true;
3173
3552
  return m;
3174
3553
  });
@@ -3194,7 +3573,7 @@ function readAnimatable(raw) {
3194
3573
  const obj = raw;
3195
3574
  const kfs = obj.keyframes;
3196
3575
  if (kfs) {
3197
- const out = { kind: "animated", keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
3576
+ const out = { kind: "animated", keyframes: kfs.map(normalizeKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
3198
3577
  const base = (_a2 = obj.value) != null ? _a2 : obj.v;
3199
3578
  if (base !== void 0 && out.kind === "animated") out.base = base;
3200
3579
  return out;
@@ -3222,7 +3601,7 @@ function writeAnimatableChannel(node, attrName, read, opts) {
3222
3601
  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;
3223
3602
  if (baseline !== void 0) node[attrName] = toOut(baseline);
3224
3603
  }
3225
- function normaliseKeyframe(kf) {
3604
+ function normalizeKeyframe(kf) {
3226
3605
  if (!kf || typeof kf !== "object") return kf;
3227
3606
  const k = kf;
3228
3607
  if (k.t === void 0 && k.v === void 0 && k.e === void 0 && k.to === void 0 && k.ti === void 0) {
@@ -3724,10 +4103,10 @@ function formatOffset(o) {
3724
4103
  return pct + "%";
3725
4104
  }
3726
4105
  function applyClipPathEffect(node, fx, ctx) {
3727
- if (!(fx == null ? void 0 : fx.d)) return node;
4106
+ if (!(fx == null ? void 0 : fx.pathData)) return node;
3728
4107
  const clipId = genId(ctx, "clip");
3729
4108
  const pathChild = { type: "path" };
3730
- const read = readAnimatable(fx.d);
4109
+ const read = readAnimatable(fx.pathData);
3731
4110
  if (read.kind !== "absent") {
3732
4111
  if (read.kind === "static") {
3733
4112
  pathChild.d = pathString(read.value);
@@ -3742,7 +4121,7 @@ function applyClipPathEffect(node, fx, ctx) {
3742
4121
  }
3743
4122
  function pathString(v) {
3744
4123
  if (typeof v === "string") return v;
3745
- if (v && typeof v === "object" && typeof v.path === "string") return v.path;
4124
+ if (v && typeof v === "object" && typeof v.pathData === "string") return v.pathData;
3746
4125
  return void 0;
3747
4126
  }
3748
4127
  function applyMaskedByEffect(node, fx, transformBy, ctx) {
@@ -3787,8 +4166,8 @@ function wrapInverseTransform(inner, fx, ctx) {
3787
4166
  }
3788
4167
  function wrapInversePart(inner, part, raw, origin, ctx) {
3789
4168
  if (raw === void 0) return inner;
3790
- const normalisedRaw = part === "scale" && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
3791
- const v = readAnimatable(normalisedRaw);
4169
+ const normalizedRaw = part === "scale" && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
4170
+ const v = readAnimatable(normalizedRaw);
3792
4171
  if (v.kind === "static") {
3793
4172
  return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
3794
4173
  }
@@ -4183,7 +4562,7 @@ function synthesiseScale(raw, i) {
4183
4562
  const scalePower = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
4184
4563
  return mapAnimatable(raw, scalePower, true);
4185
4564
  }
4186
- var RETIME_MATERIALISATION_MODE_INLINE_G = false;
4565
+ var RETIME_MATERIALIZATION_MODE_INLINE_G = false;
4187
4566
  function asRetime(r) {
4188
4567
  var _a2, _b;
4189
4568
  return { start: (_a2 = r.start) != null ? _a2 : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
@@ -4268,11 +4647,11 @@ function applyAllRetimeEffects(root, ctx) {
4268
4647
  if (!retime) continue;
4269
4648
  const crop = retime.timeCrop;
4270
4649
  clearCloneRetime(useNode);
4271
- materialiseRetime(useNode, asRetime(retime), ctx);
4650
+ materializeRetime(useNode, asRetime(retime), ctx);
4272
4651
  if (crop) applyTimeCrop(useNode, crop, ctx);
4273
4652
  }
4274
4653
  }
4275
- function materialiseRetime(useNode, retime, ctx) {
4654
+ function materializeRetime(useNode, retime, ctx) {
4276
4655
  const targetId = stripHash2(useNode.href);
4277
4656
  if (!targetId) {
4278
4657
  ctx.errors.push("retime: <use> has no href to follow");
@@ -4280,7 +4659,7 @@ function materialiseRetime(useNode, retime, ctx) {
4280
4659
  }
4281
4660
  const chainRootId = buildChainClone(targetId, retime, ctx, /* @__PURE__ */ new Set());
4282
4661
  if (!chainRootId) return;
4283
- if (RETIME_MATERIALISATION_MODE_INLINE_G) {
4662
+ if (RETIME_MATERIALIZATION_MODE_INLINE_G) {
4284
4663
  const cloneNode = ctx.idMap.get(chainRootId);
4285
4664
  useNode.type = "g";
4286
4665
  delete useNode.href;
@@ -4320,13 +4699,13 @@ function buildChainClone(targetId, accum, ctx, chain) {
4320
4699
  if (subId2) cloneNode.href = "#" + subId2;
4321
4700
  }
4322
4701
  } else {
4323
- materialiseNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
4702
+ materializeNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
4324
4703
  }
4325
4704
  ctx.defs.push(cloneNode);
4326
4705
  if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
4327
4706
  return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
4328
4707
  }
4329
- function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4708
+ function materializeNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
4330
4709
  const visit = (n) => {
4331
4710
  var _a2;
4332
4711
  const retime = readCloneRetime(n);
@@ -4523,10 +4902,10 @@ function numRange(v) {
4523
4902
  function estimateTextAdvance(node) {
4524
4903
  let chars = 0, maxFont = 16;
4525
4904
  const walk = (el) => {
4526
- var _a2, _b;
4905
+ var _a2;
4527
4906
  const fs = parseFloat(String((_a2 = el.fontSize) != null ? _a2 : "")) || 0;
4528
4907
  if (fs) maxFont = Math.max(maxFont, fs);
4529
- const t = (_b = el.text) != null ? _b : el.textContent;
4908
+ const t = el.textContent;
4530
4909
  if (typeof t === "string") chars += t.length;
4531
4910
  if (el.children) for (const c of el.children) walk(c);
4532
4911
  };
@@ -4675,7 +5054,6 @@ var TEXT_ATTR_KEYS = [
4675
5054
  "stroke",
4676
5055
  "strokeWidth",
4677
5056
  "effects",
4678
- TEXT_ATTR,
4679
5057
  TEXT_CONTENT_ATTR,
4680
5058
  "xml:space"
4681
5059
  ];
@@ -4785,8 +5163,8 @@ function missingGlyphBoxEm(advanceEm, ascentEm) {
4785
5163
  const ix0 = x0 + t, ix1 = x1 - t, iyb = -t, iyt = y1 + t;
4786
5164
  return outer + "M" + ix0 + " " + iyb + "L" + ix0 + " " + iyt + "L" + ix1 + " " + iyt + "L" + ix1 + " " + iyb + "Z";
4787
5165
  }
4788
- function materialiseGlyphTextHorizontal(node, opts) {
4789
- var _a2, _b, _c, _d;
5166
+ function materializeGlyphTextHorizontal(node, opts) {
5167
+ var _a2, _b, _c;
4790
5168
  const { glyphs, create = jsonElementFactory, warnings } = opts;
4791
5169
  const soleFont = soleFontOf(glyphs);
4792
5170
  const pen = { x: (_a2 = parseLen(node.x)) != null ? _a2 : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
@@ -4803,8 +5181,8 @@ function materialiseGlyphTextHorizontal(node, opts) {
4803
5181
  for (let i = 0; i < content.length; i++) {
4804
5182
  const ch = content.charAt(i);
4805
5183
  const g = gf == null ? void 0 : gf.glyphs[ch];
4806
- if (g && g.d) {
4807
- placements.push({ glyphD: g.d, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
5184
+ if (g && g.pathData) {
5185
+ placements.push({ glyphD: g.pathData, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
4808
5186
  pen.x += g.width * scale;
4809
5187
  } else if (/\S/.test(ch)) {
4810
5188
  const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
@@ -4818,7 +5196,7 @@ function materialiseGlyphTextHorizontal(node, opts) {
4818
5196
  }
4819
5197
  };
4820
5198
  const walk = (el, parentStyle) => {
4821
- var _a3, _b2, _c2, _d2;
5199
+ var _a3, _b2, _c2;
4822
5200
  const s = resolveStyle2(el, parentStyle);
4823
5201
  const x = parseLen(el.x);
4824
5202
  const y = parseLen(el.y);
@@ -4830,14 +5208,14 @@ function materialiseGlyphTextHorizontal(node, opts) {
4830
5208
  if (y !== void 0) pen.y = y;
4831
5209
  pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
4832
5210
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4833
- const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
4834
- if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
5211
+ const content = str(el[TEXT_CONTENT_ATTR]);
5212
+ if (content && !((_c2 = el.children) == null ? void 0 : _c2.length)) renderChars(content, s);
4835
5213
  if (el.children) for (const ch of el.children) walk(ch, s);
4836
5214
  };
4837
5215
  const rootStyle = rootStyleOf(node);
4838
5216
  if (node.children) for (const ch of node.children) walk(ch, rootStyle);
4839
- const rootContent = (_c = str(node[TEXT_CONTENT_ATTR])) != null ? _c : str(node[TEXT_ATTR]);
4840
- if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
5217
+ const rootContent = str(node[TEXT_CONTENT_ATTR]);
5218
+ if (rootContent && !((_c = node.children) == null ? void 0 : _c.length)) renderChars(rootContent, rootStyle);
4841
5219
  const anchor = str(node.textAnchor);
4842
5220
  if (anchor === "middle" || anchor === "end") {
4843
5221
  for (const p of placements) {
@@ -4849,7 +5227,7 @@ function materialiseGlyphTextHorizontal(node, opts) {
4849
5227
  return toGroup(node, buildPaths(placements, create, warnings), create);
4850
5228
  }
4851
5229
  function layoutGlyphTextChars(node, opts) {
4852
- var _a2, _b, _c, _d, _e, _f;
5230
+ var _a2, _b, _c, _d, _e;
4853
5231
  if ((_a2 = opts.alongPath) == null ? void 0 : _a2.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
4854
5232
  const { glyphs, warnings } = opts;
4855
5233
  const soleFont = soleFontOf(glyphs);
@@ -4873,7 +5251,7 @@ function layoutGlyphTextChars(node, opts) {
4873
5251
  }
4874
5252
  };
4875
5253
  const walk = (el, parentStyle) => {
4876
- var _a3, _b2, _c2, _d2;
5254
+ var _a3, _b2, _c2;
4877
5255
  const s = resolveStyle2(el, parentStyle);
4878
5256
  const x = parseLen(el.x);
4879
5257
  const y = parseLen(el.y);
@@ -4885,8 +5263,8 @@ function layoutGlyphTextChars(node, opts) {
4885
5263
  if (y !== void 0) pen.y = y;
4886
5264
  pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
4887
5265
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
4888
- const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
4889
- if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
5266
+ const content = str(el[TEXT_CONTENT_ATTR]);
5267
+ if (content && !((_c2 = el.children) == null ? void 0 : _c2.length)) renderChars(content, s);
4890
5268
  if (el.children) for (const ch of el.children) walk(ch, s);
4891
5269
  };
4892
5270
  const rootStyle = rootStyleOf(node);
@@ -4900,8 +5278,8 @@ function layoutGlyphTextChars(node, opts) {
4900
5278
  boxes.push({ x: pen.x, y: pen.y, width: 0, ascent: ((_d = gf == null ? void 0 : gf.ascent) != null ? _d : 0.9 * upm) * (s.fontSize / upm), fontSize: s.fontSize, line });
4901
5279
  }
4902
5280
  }
4903
- const rootContent = (_e = str(node[TEXT_CONTENT_ATTR])) != null ? _e : str(node[TEXT_ATTR]);
4904
- if (rootContent && !((_f = node.children) == null ? void 0 : _f.length)) renderChars(rootContent, rootStyle);
5281
+ const rootContent = str(node[TEXT_CONTENT_ATTR]);
5282
+ if (rootContent && !((_e = node.children) == null ? void 0 : _e.length)) renderChars(rootContent, rootStyle);
4905
5283
  const anchor = str(node.textAnchor);
4906
5284
  if (anchor === "middle" || anchor === "end") {
4907
5285
  for (const b of boxes) {
@@ -4909,8 +5287,8 @@ function layoutGlyphTextChars(node, opts) {
4909
5287
  b.x += anchor === "middle" ? -w / 2 : -w;
4910
5288
  }
4911
5289
  }
4912
- return boxes.map((_g) => {
4913
- var _h = _g, { line: _l } = _h, b = __objRest2(_h, ["line"]);
5290
+ return boxes.map((_f) => {
5291
+ var _g = _f, { line: _l } = _g, b = __objRest2(_g, ["line"]);
4914
5292
  return b;
4915
5293
  });
4916
5294
  }
@@ -4926,14 +5304,14 @@ function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
4926
5304
  const chars = [];
4927
5305
  let adv = 0;
4928
5306
  const walk = (el, parentStyle) => {
4929
- var _a3, _b2, _c;
5307
+ var _a3, _b2;
4930
5308
  const s = resolveStyle2(el, parentStyle);
4931
- const content = (_a3 = str(el[TEXT_CONTENT_ATTR])) != null ? _a3 : str(el[TEXT_ATTR]);
4932
- if (content && !((_b2 = el.children) == null ? void 0 : _b2.length)) {
5309
+ const content = str(el[TEXT_CONTENT_ATTR]);
5310
+ if (content && !((_a3 = el.children) == null ? void 0 : _a3.length)) {
4933
5311
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4934
5312
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
4935
5313
  const scale = s.fontSize / upm;
4936
- const ascent = ((_c = gf == null ? void 0 : gf.ascent) != null ? _c : 0.9 * upm) * scale;
5314
+ const ascent = ((_b2 = gf == null ? void 0 : gf.ascent) != null ? _b2 : 0.9 * upm) * scale;
4937
5315
  for (let i = 0; i < content.length; i++) {
4938
5316
  const ch = content.charAt(i);
4939
5317
  const g = gf == null ? void 0 : gf.glyphs[ch];
@@ -4980,21 +5358,21 @@ function collectAlongPathCells(node, glyphs, soleFont, warnings) {
4980
5358
  const cells = [];
4981
5359
  let adv = 0;
4982
5360
  const walk = (el, parentStyle) => {
4983
- var _a2, _b, _c;
5361
+ var _a2, _b;
4984
5362
  const s = resolveStyle2(el, parentStyle);
4985
- const content = (_a2 = str(el[TEXT_CONTENT_ATTR])) != null ? _a2 : str(el[TEXT_ATTR]);
4986
- if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
5363
+ const content = str(el[TEXT_CONTENT_ATTR]);
5364
+ if (content && !((_a2 = el.children) == null ? void 0 : _a2.length)) {
4987
5365
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
4988
5366
  if (gf) {
4989
5367
  const scale = s.fontSize / gf.unitsPerEm;
4990
- const ascentEm = (_c = gf.ascent) != null ? _c : 0.9 * gf.unitsPerEm;
5368
+ const ascentEm = (_b = gf.ascent) != null ? _b : 0.9 * gf.unitsPerEm;
4991
5369
  const paint = paintOf(s);
4992
5370
  for (let i = 0; i < content.length; i++) {
4993
5371
  const ch = content.charAt(i);
4994
5372
  const g = gf.glyphs[ch];
4995
- if (g && g.d) {
5373
+ if (g && g.pathData) {
4996
5374
  const glyphAdv = g.width * scale;
4997
- cells.push({ glyphD: g.d, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
5375
+ cells.push({ glyphD: g.pathData, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
4998
5376
  adv += glyphAdv;
4999
5377
  } else if (/\S/.test(ch)) {
5000
5378
  const wEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;
@@ -5025,7 +5403,7 @@ function alongPathNodeOffsets(node) {
5025
5403
  perp: (_c = parseLen(node.dy)) != null ? _c : 0
5026
5404
  };
5027
5405
  }
5028
- function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
5406
+ function materializeGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
5029
5407
  const { glyphs, create = jsonElementFactory, warnings } = opts;
5030
5408
  const sampler = pathD ? createPathSampler(pathD) : null;
5031
5409
  if (!sampler) {
@@ -5104,8 +5482,8 @@ function buildAnimatedAlongPath(cells, sampler, distOf, times, loop, create, isC
5104
5482
  const onPath = (dist) => dist >= 0 && dist <= sampler.totalLength;
5105
5483
  const out = [];
5106
5484
  for (const c of cells) {
5107
- const centred = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
5108
- const d = transformPathData(c.glyphD, centred);
5485
+ const centered = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
5486
+ const d = transformPathData(c.glyphD, centered);
5109
5487
  const sampleKf = (dist, time) => {
5110
5488
  const { x, y, angle } = sampler.sampleAtDistance(dist);
5111
5489
  const cos = Math.cos(angle), sin = Math.sin(angle);
@@ -5203,9 +5581,9 @@ function toGroup(node, children, create) {
5203
5581
  }
5204
5582
  return create("g", gProps, children);
5205
5583
  }
5206
- function materialiseGlyphText(node, opts) {
5207
- if (opts.alongPath) return materialiseGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);
5208
- return materialiseGlyphTextHorizontal(node, opts);
5584
+ function materializeGlyphText(node, opts) {
5585
+ if (opts.alongPath) return materializeGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);
5586
+ return materializeGlyphTextHorizontal(node, opts);
5209
5587
  }
5210
5588
  function applyTextGlyphsEffect(node, fx, ctx) {
5211
5589
  if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
@@ -5213,14 +5591,14 @@ function applyTextGlyphsEffect(node, fx, ctx) {
5213
5591
  ctx.warnings.push("textGlyphs: no definitions.fonts \u2014 left as native <text>");
5214
5592
  return node;
5215
5593
  }
5216
- return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
5594
+ return materializeGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
5217
5595
  }
5218
5596
  function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pathOverflow) {
5219
5597
  if (!ctx.glyphs) {
5220
5598
  ctx.warnings.push("textGlyphs: no definitions.fonts");
5221
5599
  return null;
5222
5600
  }
5223
- return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
5601
+ return materializeGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
5224
5602
  }
5225
5603
  function applyStrokeTrimEffect(node, strokeTrim, ctx) {
5226
5604
  if (!strokeTrim) return node;
@@ -5682,7 +6060,7 @@ function buildOffsetPath(propAnim) {
5682
6060
  }
5683
6061
  return { pathStr: d, distanceKfs, autoOrient: !!propAnim.autoOrient, anchor };
5684
6062
  }
5685
- function materialiseOffsetPathsInTree(root) {
6063
+ function materializeOffsetPathsInTree(root) {
5686
6064
  const walk = (node) => {
5687
6065
  var _a2;
5688
6066
  let out = node;
@@ -5725,15 +6103,15 @@ function materialiseOffsetPathsInTree(root) {
5725
6103
  };
5726
6104
  return walk(root);
5727
6105
  }
5728
- function materialiseAllInTree(doc, engine, opts) {
6106
+ function materializeAllInTree(doc, engine, opts) {
5729
6107
  var _a2, _b;
5730
6108
  let root = applyPlayerEffects(doc).root;
5731
- root = materialiseOffsetPathsInTree(root);
6109
+ root = materializeOffsetPathsInTree(root);
5732
6110
  const duration = (_b = (_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.duration) != null ? _b : DEFAULT_DURATION_MS;
5733
- root = materialiseInternalLoopsInTree(root, duration);
6111
+ root = materializeInternalLoopsInTree(root, duration);
5734
6112
  if (engine === PxTimelineEngine.native) {
5735
- root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
5736
- root = materialiseAnimatedUseInstances(root);
6113
+ root = materializeMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
6114
+ root = materializeAnimatedUseInstances(root);
5737
6115
  root = pruneUnreferencedDefs(root);
5738
6116
  }
5739
6117
  return root;
@@ -5767,6 +6145,38 @@ function pruneUnreferencedDefs(root) {
5767
6145
  }
5768
6146
  return root;
5769
6147
  }
6148
+ var PX_RATE_REJECTED = "setPlaybackRate: rate must be finite and non-zero";
6149
+ function isValidPlaybackRate(rate) {
6150
+ return Number.isFinite(rate) && rate !== 0;
6151
+ }
6152
+ function seekCeilingMs(durationMs, iterations) {
6153
+ if (!(durationMs > 0)) return 0;
6154
+ if (iterations === Infinity) return Infinity;
6155
+ return durationMs * (iterations > 0 ? iterations : 1);
6156
+ }
6157
+ function progressSpanMs(durationMs, iterations) {
6158
+ if (!(durationMs > 0)) return 0;
6159
+ if (iterations === Infinity) return durationMs;
6160
+ return durationMs * (iterations > 0 ? iterations : 1);
6161
+ }
6162
+ function clampSeekMs(timeMs, ceilingMs) {
6163
+ if (Number.isNaN(timeMs) || timeMs < 0) return 0;
6164
+ if (Number.isFinite(ceilingMs)) return timeMs > ceilingMs ? ceilingMs : timeMs;
6165
+ return Number.isFinite(timeMs) ? timeMs : 0;
6166
+ }
6167
+ function timeToProgress(timeMs, durationMs, iterations) {
6168
+ const span = progressSpanMs(durationMs, iterations);
6169
+ if (!(span > 0) || !Number.isFinite(timeMs)) return 0;
6170
+ if (timeMs <= 0) return 0;
6171
+ if (iterations === Infinity) return timeMs % span / span;
6172
+ return timeMs >= span ? 1 : timeMs / span;
6173
+ }
6174
+ function progressToTimeMs(progress, durationMs, iterations) {
6175
+ const span = progressSpanMs(durationMs, iterations);
6176
+ if (!(span > 0) || !Number.isFinite(progress)) return 0;
6177
+ if (progress <= 0) return 0;
6178
+ return progress >= 1 ? span : progress * span;
6179
+ }
5770
6180
  function requestFrame(cb) {
5771
6181
  const g = globalThis;
5772
6182
  if (typeof g.requestAnimationFrame === "function") return g.requestAnimationFrame(cb);
@@ -5783,7 +6193,7 @@ function cancelFrame(handle) {
5783
6193
  function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
5784
6194
  var _a2;
5785
6195
  const config = getAnimatorConfig(doc) || {};
5786
- const bindings = getNormalisedBindings(doc, PxTimelineEngine.js);
6196
+ const bindings = getNormalizedBindings(doc, PxTimelineEngine.js);
5787
6197
  const _iterations = config.iterations;
5788
6198
  let iterations = 1;
5789
6199
  if (typeof _iterations === "number") iterations = _iterations || 1;
@@ -6013,8 +6423,8 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
6013
6423
  finishAnim(true);
6014
6424
  },
6015
6425
  "setPlaybackRate": (rate) => {
6016
- if (!isFinite(rate) || rate === 0) {
6017
- console.warn("setPlaybackRate: rate must be finite and non-zero");
6426
+ if (!isValidPlaybackRate(rate)) {
6427
+ console.warn(PX_RATE_REJECTED);
6018
6428
  return;
6019
6429
  }
6020
6430
  let current = getRawAnimTime();
@@ -6028,13 +6438,16 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
6028
6438
  return getAnimCurrentTime();
6029
6439
  },
6030
6440
  "setCurrentTime": (newTime) => {
6031
- if (newTime < 0) newTime = 0;
6032
- if (Number.isFinite(totalDuration) && newTime > totalDuration) newTime = totalDuration;
6441
+ newTime = clampSeekMs(newTime, totalDuration);
6033
6442
  timeBeforeLastStartMs = newTime;
6034
6443
  if (playing) lastStartedTs = Date.now();
6035
6444
  if (!Number.isFinite(totalDuration) || newTime < totalDuration) finishCalled = false;
6036
6445
  renderFrame(getAnimCurrentTime());
6037
6446
  },
6447
+ "getCurrentProgress": () => timeToProgress(getAnimCurrentTime(), duration, iterations),
6448
+ "setCurrentProgress": (progress) => {
6449
+ api.setCurrentTime(progressToTimeMs(progress, duration, iterations));
6450
+ },
6038
6451
  "destroy": () => {
6039
6452
  var _a3;
6040
6453
  api.cancel();
@@ -6043,6 +6456,49 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
6043
6456
  };
6044
6457
  return api;
6045
6458
  }
6459
+ var PxDiagnosticKind = {
6460
+ /** The document is wrong — regenerate or repair the file. */
6461
+ document: "document",
6462
+ /** The page or app cannot provide what the document asks for — fix the mount. */
6463
+ host: "host",
6464
+ /** The platform cannot do it and the player degraded — usually nothing to fix. */
6465
+ platform: "platform",
6466
+ /** The call is wrong or self-contradictory — fix the options or props you passed. */
6467
+ usage: "usage",
6468
+ /** The player failed where it did not expect to — report it to us. */
6469
+ internal: "internal"
6470
+ };
6471
+ function asError(error) {
6472
+ return typeof error === "string" ? new Error(error) : error;
6473
+ }
6474
+ function isSilenced(silent, kind) {
6475
+ if (!silent) return false;
6476
+ return silent === true || silent.includes(kind);
6477
+ }
6478
+ function createDiagnostics(config, prefix) {
6479
+ const tag = prefix ? prefix + " " : "";
6480
+ return {
6481
+ warn: (kind, message, detail) => {
6482
+ if (config == null ? void 0 : config.onWarn) {
6483
+ config.onWarn({ kind, message, detail });
6484
+ return;
6485
+ }
6486
+ if (isSilenced(config == null ? void 0 : config.silent, kind)) return;
6487
+ const line = tag + kind + ": " + message;
6488
+ if (detail === void 0) console.warn(line);
6489
+ else console.warn(line, detail);
6490
+ },
6491
+ error: (kind, error) => {
6492
+ const err = asError(error);
6493
+ if (config == null ? void 0 : config.onError) {
6494
+ config.onError({ kind, message: err.message, error: err });
6495
+ return;
6496
+ }
6497
+ if (isSilenced(config == null ? void 0 : config.silent, kind)) return;
6498
+ console.error(tag + kind + ": " + err.message);
6499
+ }
6500
+ };
6501
+ }
6046
6502
  var IDENTITY = [1, 0, 0, 1, 0, 0];
6047
6503
  function mul(m, n) {
6048
6504
  return [
@@ -6312,32 +6768,30 @@ function mergeTimeline(base, patch, warn) {
6312
6768
  }
6313
6769
  return merged;
6314
6770
  }
6315
- function foldAnimatorConfigShortcuts(config, shortcuts) {
6771
+ function foldTimelineOverride(timeline, shortcuts) {
6316
6772
  let base;
6317
- if (typeof config === "string") {
6773
+ if (typeof timeline === "string") {
6318
6774
  try {
6319
- base = JSON.parse(config);
6775
+ base = JSON.parse(timeline);
6320
6776
  } catch (e) {
6321
- console.warn("animator config: not valid JSON \u2014 ignored", e);
6777
+ console.warn("timeline override: not valid JSON \u2014 ignored", e);
6322
6778
  base = void 0;
6323
6779
  }
6324
6780
  } else {
6325
- base = config != null ? config : void 0;
6781
+ base = timeline != null ? timeline : void 0;
6326
6782
  }
6327
6783
  const { duration, delay, iterations, startOn } = shortcuts;
6328
6784
  if (duration === void 0 && delay === void 0 && iterations === void 0 && startOn === void 0) {
6329
- return base;
6785
+ return base === void 0 ? void 0 : { timeline: base };
6330
6786
  }
6331
6787
  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;
6788
+ if (duration !== void 0) out.duration = duration;
6789
+ if (delay !== void 0) out.delay = delay;
6790
+ if (iterations !== void 0) out.iterations = iterations;
6336
6791
  if (startOn !== void 0) {
6337
- timeline.trigger = __spreadProps2(__spreadValues2({}, timeline.trigger), { startOn });
6792
+ out.trigger = __spreadProps2(__spreadValues2({}, out.trigger), { startOn });
6338
6793
  }
6339
- out.timeline = timeline;
6340
- return out;
6794
+ return { timeline: out };
6341
6795
  }
6342
6796
  function mergeAnimatorConfig(base, patch) {
6343
6797
  const warnings = [];
@@ -6403,26 +6857,12 @@ function applyAnimatorConfig(doc, patch, opts) {
6403
6857
  return { doc: __spreadProps2(__spreadValues2({}, anyDoc), { animator: merged.config }), warnings };
6404
6858
  }
6405
6859
  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
6860
  function diagnoseDocument(doc) {
6416
- let all;
6417
6861
  try {
6418
- all = validateDocument(doc);
6862
+ return { problems: validateDocument(doc) };
6419
6863
  } catch (e) {
6420
- return { problems: [], legacy: [] };
6864
+ return { problems: [] };
6421
6865
  }
6422
- const problems = [];
6423
- const legacy = [];
6424
- for (const w of all) (isLegacyFlatAnimatorKey(w) ? legacy : problems).push(w);
6425
- return { problems, legacy };
6426
6866
  }
6427
6867
  function reportDocumentDiagnostics(doc, where) {
6428
6868
  const { problems } = diagnoseDocument(doc);
@@ -6434,13 +6874,37 @@ function reportDocumentDiagnostics(doc, where) {
6434
6874
  );
6435
6875
  }
6436
6876
 
6877
+ // src/shared/PxAnimatorCallbacks.ts
6878
+ function toEngineCallbacks(inline) {
6879
+ const { onPlay, onPause, onCancel, onFinish, onRemove, onStop, onWarn, onError, silent } = inline != null ? inline : {};
6880
+ const withStop = (own) => own || onStop ? () => {
6881
+ own == null ? void 0 : own();
6882
+ onStop == null ? void 0 : onStop();
6883
+ } : void 0;
6884
+ return {
6885
+ onPlay,
6886
+ onPause: withStop(onPause),
6887
+ onCancel: withStop(onCancel),
6888
+ onFinish: withStop(onFinish),
6889
+ onRemove: withStop(onRemove),
6890
+ onWarn,
6891
+ onError,
6892
+ silent
6893
+ };
6894
+ }
6895
+
6437
6896
  // src/triggers/PxAnimatorTriggers.ts
6438
- function setupAnimationTriggers(api, config) {
6439
- const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
6897
+ function setupAnimationTriggers(api, config, diag) {
6898
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6899
+ const cleanups = [];
6900
+ const dispose = () => {
6901
+ for (const undo of cleanups.splice(0)) undo();
6902
+ };
6903
+ const { startOn, outAction, scrollIntoViewThreshold } = resolveTrigger(config);
6440
6904
  const root = api.getRootElement();
6441
6905
  if (!root) {
6442
- console.warn("setupAnimationTriggers: No root element found for animation.");
6443
- return api;
6906
+ report.warn(PxDiagnosticKind.host, "setupAnimationTriggers: No root element found for animation.");
6907
+ return dispose;
6444
6908
  }
6445
6909
  let reversed = false;
6446
6910
  const start = () => {
@@ -6475,6 +6939,7 @@ function setupAnimationTriggers(api, config) {
6475
6939
  startHandler();
6476
6940
  } else {
6477
6941
  window.addEventListener("load", startHandler, { once: true });
6942
+ cleanups.push(() => window.removeEventListener("load", startHandler));
6478
6943
  }
6479
6944
  break;
6480
6945
  }
@@ -6489,6 +6954,10 @@ function setupAnimationTriggers(api, config) {
6489
6954
  };
6490
6955
  root.addEventListener("mouseenter", mouseOverHandler);
6491
6956
  root.addEventListener("mouseleave", mouseOutHandler);
6957
+ cleanups.push(() => {
6958
+ root.removeEventListener("mouseenter", mouseOverHandler);
6959
+ root.removeEventListener("mouseleave", mouseOutHandler);
6960
+ });
6492
6961
  break;
6493
6962
  }
6494
6963
  case "click": {
@@ -6500,6 +6969,7 @@ function setupAnimationTriggers(api, config) {
6500
6969
  }
6501
6970
  };
6502
6971
  root.addEventListener("click", clickHandler);
6972
+ cleanups.push(() => root.removeEventListener("click", clickHandler));
6503
6973
  break;
6504
6974
  }
6505
6975
  case "scrollIntoView": {
@@ -6531,12 +7001,13 @@ function setupAnimationTriggers(api, config) {
6531
7001
  { threshold: thresholdSteps }
6532
7002
  );
6533
7003
  observer.observe(root);
7004
+ cleanups.push(() => observer.disconnect());
6534
7005
  break;
6535
7006
  }
6536
7007
  case "programmatic":
6537
7008
  break;
6538
7009
  }
6539
- return api;
7010
+ return dispose;
6540
7011
  }
6541
7012
 
6542
7013
  // src/engines/PxAnimatorFrameLoop.ts
@@ -6544,35 +7015,41 @@ function getSelector(id) {
6544
7015
  return "#" + id;
6545
7016
  }
6546
7017
  function createFrameLoopAnimator(doc, adapter, callbacks, rootElement) {
7018
+ var _a2;
6547
7019
  const config = getAnimatorConfig(doc) || {};
7020
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
6548
7021
  if (!rootElement) {
6549
7022
  if (doc.id) {
6550
7023
  const rootSelector = getSelector(doc.id);
6551
7024
  rootElement = document.querySelector(rootSelector);
6552
- if (!rootElement) console.warn("createFrameLoopAnimator: No root element found for selector: ", rootSelector);
7025
+ if (!rootElement) diag.warn(PxDiagnosticKind.host, "createFrameLoopAnimator: No root element found for selector: " + rootSelector);
6553
7026
  } else {
6554
- console.warn("createFrameLoopAnimator: No root element provided");
7027
+ diag.warn(PxDiagnosticKind.host, "createFrameLoopAnimator: No root element provided");
6555
7028
  }
6556
7029
  }
6557
7030
  const basicApi = createBasicFrameLoopAnimator(
6558
7031
  doc,
6559
- adapter || createDomAdapter(rootElement),
7032
+ adapter || createDomAdapter(rootElement, diag),
6560
7033
  callbacks
6561
7034
  );
6562
7035
  const api = __spreadProps(__spreadValues({}, basicApi), {
6563
7036
  "getRootElement": () => rootElement || null
6564
7037
  });
6565
- if (config.trigger) {
6566
- if (isScrollTimeline(config)) {
6567
- console.warn("scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
6568
- } else {
6569
- setupAnimationTriggers(api, config.trigger);
6570
- }
7038
+ if (isScrollTimeline(config)) {
7039
+ if (config.trigger) diag.warn(PxDiagnosticKind.usage, "scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
7040
+ } else {
7041
+ const detachTriggers = setupAnimationTriggers(api, (_a2 = config.trigger) != null ? _a2 : {}, diag);
7042
+ const destroyEngine = api.destroy.bind(api);
7043
+ api.destroy = () => {
7044
+ detachTriggers();
7045
+ destroyEngine();
7046
+ };
6571
7047
  }
6572
7048
  return api;
6573
7049
  }
6574
- function createDomAdapter(rootElement) {
7050
+ function createDomAdapter(rootElement, diag) {
6575
7051
  const warnedSelectors = /* @__PURE__ */ new Set();
7052
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6576
7053
  const adapter = {
6577
7054
  isConnected: () => {
6578
7055
  if (!rootElement) return true;
@@ -6584,7 +7061,7 @@ function createDomAdapter(rootElement) {
6584
7061
  const elements = (rootElement == null ? void 0 : rootElement.querySelectorAll(selector)) || document.querySelectorAll(selector);
6585
7062
  if (elements.length === 0 && !warnedSelectors.has(selector)) {
6586
7063
  warnedSelectors.add(selector);
6587
- console.warn('setAttribute: No elements found for selector "' + selector + '"');
7064
+ report.warn(PxDiagnosticKind.host, 'setAttribute: No elements found for selector "' + selector + '"');
6588
7065
  }
6589
7066
  for (let i = 0; i < elements.length; i++) {
6590
7067
  const element = elements[i];
@@ -6609,7 +7086,7 @@ function createCssKf(kf, t, propName, unsupportedSet) {
6609
7086
  };
6610
7087
  let cssValue;
6611
7088
  let cssKey = propName;
6612
- if (COLOUR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
7089
+ if (COLOR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
6613
7090
  cssValue = toRGBA(value);
6614
7091
  } else if (propName === "transform" && value !== null && typeof value === "object" && !Array.isArray(value)) {
6615
7092
  cssValue = composeTransformParts(value, { withUnits: true });
@@ -6696,18 +7173,19 @@ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
6696
7173
  return result;
6697
7174
  }
6698
7175
  function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs, scrollTimeline) {
6699
- var _a2;
7176
+ var _a2, _b;
6700
7177
  const config = getAnimatorConfig(doc) || {};
7178
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
6701
7179
  if (!rootElement) {
6702
7180
  if (doc.id) {
6703
7181
  const rootSelector = getSelector(doc.id);
6704
7182
  rootElement = document.querySelector(rootSelector);
6705
- if (!rootElement) console.warn("createFrameLoopAnimator: No root element found for selector: ", rootSelector);
7183
+ if (!rootElement) diag.warn(PxDiagnosticKind.host, "createWebApiAnimator: No root element found for selector: " + rootSelector);
6706
7184
  } else {
6707
- console.warn("createFrameLoopAnimator: No root element provided");
7185
+ diag.warn(PxDiagnosticKind.host, "createWebApiAnimator: No root element provided");
6708
7186
  }
6709
7187
  }
6710
- const bindings = getNormalisedBindings(doc, PxTimelineEngine.native);
7188
+ const bindings = getNormalizedBindings(doc, PxTimelineEngine.native);
6711
7189
  const animations = [];
6712
7190
  const _iterations = config.iterations;
6713
7191
  let iterations;
@@ -6717,18 +7195,18 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6717
7195
  let finishNotified = false;
6718
7196
  let removeCalled = false;
6719
7197
  if (!(bindings == null ? void 0 : bindings.length)) {
6720
- console.warn("createWebApiAnimator: No animation bindings defined");
7198
+ diag.warn(PxDiagnosticKind.document, "createWebApiAnimator: No animation bindings defined");
6721
7199
  }
6722
7200
  for (const binding of bindings || []) {
6723
7201
  const animDef = binding.animate;
6724
7202
  if (!animDef || typeof animDef !== "object" || Array.isArray(animDef)) {
6725
- console.warn("createWebApiAnimator: Empty or unresolved binding", binding);
7203
+ diag.warn(PxDiagnosticKind.document, "createWebApiAnimator: Empty or unresolved binding", binding);
6726
7204
  continue;
6727
7205
  }
6728
7206
  const selector = getSelector(binding.id);
6729
7207
  const elements = (rootElement == null ? void 0 : rootElement.querySelectorAll(selector)) || document.querySelectorAll(selector);
6730
7208
  if (elements.length === 0) {
6731
- console.warn('createWebApiAnimator: No elements found for selector "' + selector + '"');
7209
+ diag.warn(PxDiagnosticKind.host, 'createWebApiAnimator: No elements found for selector "' + selector + '"');
6732
7210
  }
6733
7211
  const keyframesMap = convertToWebApiKeyframes(animDef, unsupportedSet, config);
6734
7212
  const positiveDelay = config.delay && config.delay > 0 ? config.delay : void 0;
@@ -6777,14 +7255,14 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6777
7255
  }
6778
7256
  animations.push(anim);
6779
7257
  } catch (e) {
6780
- console.warn(e);
7258
+ diag.warn(PxDiagnosticKind.internal, "createWebApiAnimator: could not build the animation", e);
6781
7259
  }
6782
7260
  }
6783
7261
  }
6784
7262
  }
6785
7263
  }
6786
7264
  if (!forceEvenIfHasUnsupportedAttrs && unsupportedSet.size) {
6787
- console.warn("Unsupported CSS attrs: " + [...unsupportedSet].join(", "));
7265
+ diag.warn(PxDiagnosticKind.platform, "Unsupported CSS attrs: " + [...unsupportedSet].join(", "));
6788
7266
  return null;
6789
7267
  }
6790
7268
  const api = {
@@ -6828,20 +7306,36 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6828
7306
  }
6829
7307
  },
6830
7308
  "setPlaybackRate": (rate) => {
7309
+ if (!isValidPlaybackRate(rate)) {
7310
+ diag.warn(PxDiagnosticKind.usage, PX_RATE_REJECTED);
7311
+ return api;
7312
+ }
6831
7313
  animations.forEach((a) => a.playbackRate = rate);
6832
7314
  return api;
6833
7315
  },
6834
7316
  "getCurrentTime": () => {
6835
- var _a3, _b;
6836
- const res = (_b = (_a3 = animations[0]) == null ? void 0 : _a3.currentTime) != null ? _b : null;
7317
+ var _a3, _b2;
7318
+ const res = (_b2 = (_a3 = animations[0]) == null ? void 0 : _a3.currentTime) != null ? _b2 : null;
6837
7319
  return res !== null ? +res : null;
6838
7320
  },
6839
7321
  "setCurrentTime": (time) => {
7322
+ var _a3;
7323
+ const ceiling = seekCeilingMs((_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1);
7324
+ const seek = ceiling > 0 ? clampSeekMs(time, ceiling) : Math.max(0, time);
6840
7325
  finishNotified = false;
6841
7326
  animations.forEach((a) => {
6842
- a.currentTime = time;
7327
+ a.currentTime = seek;
6843
7328
  });
6844
7329
  },
7330
+ "getCurrentProgress": () => {
7331
+ var _a3;
7332
+ const t = api.getCurrentTime();
7333
+ return t === null ? null : timeToProgress(t, (_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1);
7334
+ },
7335
+ "setCurrentProgress": (progress) => {
7336
+ var _a3;
7337
+ api.setCurrentTime(progressToTimeMs(progress, (_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1));
7338
+ },
6845
7339
  "destroy": () => {
6846
7340
  var _a3;
6847
7341
  api.cancel();
@@ -6852,12 +7346,15 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
6852
7346
  }
6853
7347
  }
6854
7348
  };
6855
- if (config.trigger) {
6856
- if (config.timelineSource === "scroll") {
6857
- console.warn("scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
6858
- } else {
6859
- setupAnimationTriggers(api, config.trigger);
6860
- }
7349
+ if (config.timelineSource === "scroll") {
7350
+ if (config.trigger) diag.warn(PxDiagnosticKind.usage, "scroll timeline: `animator.trigger` is ignored (triggers do not apply to scroll-driven playback)");
7351
+ } else {
7352
+ const detachTriggers = setupAnimationTriggers(api, (_b = config.trigger) != null ? _b : {}, diag);
7353
+ const destroyEngine = api.destroy.bind(api);
7354
+ api.destroy = () => {
7355
+ detachTriggers();
7356
+ destroyEngine();
7357
+ };
6861
7358
  }
6862
7359
  if (scrollTimeline) {
6863
7360
  animations.forEach((a) => a.play());
@@ -6873,13 +7370,14 @@ function nativeRangeOffset(point, defaultFraction, view) {
6873
7370
  if (pct === void 0) return void 0;
6874
7371
  return view ? { rangeName: (_c = point == null ? void 0 : point.phase) != null ? _c : "cover", offset: pct } : { offset: pct };
6875
7372
  }
6876
- function createNativeScrollTimeline(subject, config) {
7373
+ function createNativeScrollTimeline(subject, config, diag) {
6877
7374
  var _a2, _b, _c, _d;
7375
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6878
7376
  if (!config || !isScrollTimeline(config)) return null;
6879
7377
  const scroll = config.scroll || {};
6880
7378
  const kind = (_a2 = scroll.kind) != null ? _a2 : "view";
6881
7379
  if (scroll.smoothing) {
6882
- console.warn("scroll timeline: `smoothing` needs the built-in driver \u2014 using the built-in driver instead of the browser timeline");
7380
+ report.warn(PxDiagnosticKind.platform, "scroll timeline: `smoothing` needs the built-in driver \u2014 using the built-in driver instead of the browser timeline");
6883
7381
  return null;
6884
7382
  }
6885
7383
  const g = globalThis;
@@ -6890,13 +7388,13 @@ function createNativeScrollTimeline(subject, config) {
6890
7388
  let timeline;
6891
7389
  try {
6892
7390
  if (view) {
6893
- timeline = new Ctor({ subject: resolveScrollSubject(subject, scroll.subject), axis });
7391
+ timeline = new Ctor({ subject: resolveScrollSubject(subject, scroll.subject, report), axis });
6894
7392
  } else {
6895
7393
  const source = scroll.source === "root" ? documentScroller() : findNearestScroller(subject, "y") || findNearestScroller(subject, "x") || documentScroller();
6896
7394
  timeline = new Ctor({ source, axis });
6897
7395
  }
6898
7396
  } catch (e) {
6899
- console.warn("scroll timeline: native timeline construction failed \u2014 falling back to the player measuring progress itself", e);
7397
+ report.warn(PxDiagnosticKind.platform, "scroll timeline: native timeline construction failed \u2014 falling back to the player measuring progress itself", e);
6900
7398
  return null;
6901
7399
  }
6902
7400
  return {
@@ -6923,8 +7421,9 @@ function documentScroller() {
6923
7421
  }
6924
7422
  var SUBJECT_PARENT = "parent";
6925
7423
  var SUBJECT_SCROLLER = "scroller";
6926
- function resolveScrollSubject(svgRoot, subject) {
7424
+ function resolveScrollSubject(svgRoot, subject, diag) {
6927
7425
  var _a2, _b;
7426
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6928
7427
  const spec = subject == null ? void 0 : subject.trim();
6929
7428
  if (!spec) return svgRoot;
6930
7429
  if (spec === SUBJECT_PARENT) {
@@ -6942,21 +7441,22 @@ function resolveScrollSubject(svgRoot, subject) {
6942
7441
  try {
6943
7442
  found = document.querySelector(spec);
6944
7443
  } catch (e) {
6945
- console.warn('scroll timeline: subject "' + spec + '" is not a valid selector \u2014 measuring the SVG itself');
7444
+ report.warn(PxDiagnosticKind.document, 'scroll timeline: subject "' + spec + '" is not a valid selector \u2014 measuring the SVG itself');
6946
7445
  return svgRoot;
6947
7446
  }
6948
7447
  if (!found) {
6949
- console.warn('scroll timeline: subject "' + spec + '" matched no element \u2014 measuring the SVG itself');
7448
+ report.warn(PxDiagnosticKind.host, 'scroll timeline: subject "' + spec + '" matched no element \u2014 measuring the SVG itself');
6950
7449
  return svgRoot;
6951
7450
  }
6952
7451
  return found;
6953
7452
  }
6954
- function createScrollDriver(subject, config, onProgress) {
7453
+ function createScrollDriver(subject, config, onProgress, diag) {
6955
7454
  var _a2, _b;
6956
7455
  if (!config || !isScrollTimeline(config)) return null;
7456
+ const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
6957
7457
  const scroll = config.scroll || {};
6958
7458
  const kind = (_a2 = scroll.kind) != null ? _a2 : "view";
6959
- const measured = resolveScrollSubject(subject, scroll.subject);
7459
+ const measured = resolveScrollSubject(subject, scroll.subject, report);
6960
7460
  const nearest = findNearestScroller(subject, "y") || findNearestScroller(subject, "x");
6961
7461
  const scroller = kind === "scroll" && scroll.source === "root" ? documentScroller() : nearest || documentScroller();
6962
7462
  const isRootScroller = scroller === documentScroller();
@@ -7075,7 +7575,7 @@ function applyScrollPin(svgRoot, scroll) {
7075
7575
  const alignFactor = scroll.pinAlign === "center" ? 0.5 : scroll.pinAlign === "bottom" ? 1 : 0;
7076
7576
  const applyTop = () => {
7077
7577
  var _a2;
7078
- const extra = (_a2 = scroll.pinTop) != null ? _a2 : 0;
7578
+ const extra = (_a2 = scroll.pinOffset) != null ? _a2 : 0;
7079
7579
  if (!alignFactor) {
7080
7580
  style.top = extra + "px";
7081
7581
  return;
@@ -7137,6 +7637,7 @@ function finaliseAnimator(animatorConfig, callbacks, make) {
7137
7637
  }
7138
7638
  function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
7139
7639
  const animatorConfig = getAnimatorConfig(doc) || {};
7640
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
7140
7641
  if (isScrollTimeline(animatorConfig)) {
7141
7642
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
7142
7643
  var _a2;
@@ -7144,7 +7645,7 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
7144
7645
  };
7145
7646
  if (mayUseNativeScrollTimeline(animatorConfig.engine) && rootElement) {
7146
7647
  unpin = applyScrollPin(rootElement, animatorConfig.scroll);
7147
- const native = createNativeScrollTimeline(rootElement, animatorConfig);
7648
+ const native = createNativeScrollTimeline(rootElement, animatorConfig, diag);
7148
7649
  if (native) {
7149
7650
  const api2 = createWebApiAnimator(
7150
7651
  doc,
@@ -7174,7 +7675,8 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
7174
7675
  const driver = createScrollDriver(
7175
7676
  subject,
7176
7677
  animatorConfig,
7177
- (progress) => api.setCurrentTime(progress * totalMs)
7678
+ (progress) => api.setCurrentTime(progress * totalMs),
7679
+ diag
7178
7680
  );
7179
7681
  if (driver) {
7180
7682
  const destroy = api.destroy.bind(api);
@@ -7185,7 +7687,7 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
7185
7687
  };
7186
7688
  }
7187
7689
  } else {
7188
- console.warn("scroll timeline: no root element to observe \u2014 animation will stay at frame 0");
7690
+ diag.warn(PxDiagnosticKind.host, "scroll timeline: no root element to observe \u2014 animation will stay at frame 0");
7189
7691
  }
7190
7692
  return api;
7191
7693
  });
@@ -7205,35 +7707,36 @@ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
7205
7707
 
7206
7708
  // src/dom/PxAnimatorDOM.ts
7207
7709
  var SVG_NS = "http://www.w3.org/2000/svg";
7208
- function createElement(tagName, normalisedProps, style, children, textContent) {
7710
+ function createElement(tagName, normalizedProps, style, children, textContent, diag) {
7209
7711
  if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
7210
- console.warn("SVG tag blocked (dangerous): ", tagName);
7712
+ (diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]")).warn(PxDiagnosticKind.document, "SVG tag blocked (dangerous): " + tagName);
7211
7713
  return null;
7212
7714
  }
7213
7715
  const element = document.createElementNS(SVG_NS, tagName);
7214
- for (const propName in normalisedProps) {
7215
- const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
7216
- if (sanitised === void 0) continue;
7716
+ for (const propName in normalizedProps) {
7717
+ const sanitized = sanitizeAttributeValue(propName, normalizedProps[propName]);
7718
+ if (sanitized === void 0) continue;
7217
7719
  if (CSS_ONLY_STYLE_PROPS.has(propName)) {
7218
- element.style[propName] = String(sanitised);
7720
+ element.style[propName] = String(sanitized);
7219
7721
  continue;
7220
7722
  }
7221
- element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
7723
+ element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitized);
7222
7724
  }
7223
7725
  if (style) {
7224
7726
  for (const styleProp in style) {
7225
7727
  element.style[styleProp] = String(style[styleProp]);
7226
7728
  }
7227
7729
  }
7228
- if (children) {
7730
+ if (children == null ? void 0 : children.length) {
7229
7731
  for (const child of children) {
7230
7732
  element.appendChild(child);
7231
7733
  }
7734
+ } else if (textContent) {
7735
+ element.textContent = textContent;
7232
7736
  }
7233
- if (textContent) element.textContent = textContent;
7234
7737
  return element;
7235
7738
  }
7236
- function renderNode(node, defs) {
7739
+ function renderNode(node, defs, diag) {
7237
7740
  if (!node) return null;
7238
7741
  const _a2 = node, { type, children, style } = _a2, props = __objRest(_a2, ["type", "children", "style"]);
7239
7742
  const domType = props.domType;
@@ -7243,7 +7746,7 @@ function renderNode(node, defs) {
7243
7746
  let childElements;
7244
7747
  if (children) {
7245
7748
  for (const ch of children) {
7246
- const child = renderNode(ch, nodeDefs);
7749
+ const child = renderNode(ch, nodeDefs, diag);
7247
7750
  if (child) {
7248
7751
  if (!childElements) childElements = [];
7249
7752
  childElements.push(child);
@@ -7255,37 +7758,39 @@ function renderNode(node, defs) {
7255
7758
  getNormalizedProps(props),
7256
7759
  resolvedStyle,
7257
7760
  childElements,
7258
- props[TEXT_CONTENT_ATTR] || props[TEXT_ATTR]
7761
+ props[TEXT_CONTENT_ATTR],
7762
+ diag
7259
7763
  );
7260
7764
  if (element && domType !== void 0) element.setAttribute("type", domType);
7261
7765
  return element;
7262
7766
  }
7263
7767
 
7264
7768
  // src/shared/PxAnimatorKeys.ts
7265
- var PX_ANIMATOR_DATA_KEY = "data";
7769
+ var PX_ANIMATOR_DOC_KEY = "doc";
7266
7770
 
7267
7771
  // src/animator/PxAnimator.ts
7268
7772
  function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
7269
7773
  return bindWithEngineChoice(doc, adapter, callbacks, rootElement);
7270
7774
  }
7271
- function createAnimatorImpl(doc, adapter, callbacks, containerElement, config, resetDocDefaults) {
7775
+ function createAnimatorImpl(doc, adapter, callbacks, containerElement, patch, resetTimeline) {
7776
+ const diag = createDiagnostics(callbacks, "[PxAnimator]");
7272
7777
  const effectsWarnings = validateNodeEffects(doc);
7273
- for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
7778
+ for (const w of effectsWarnings) diag.warn(PxDiagnosticKind.document, "effects shape: " + w);
7274
7779
  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);
7780
+ if (patch !== void 0 || resetTimeline) {
7781
+ const patched = applyAnimatorConfig(doc, patch != null ? patch : {}, { resetDefaults: !!resetTimeline });
7782
+ for (const w of patched.warnings) diag.warn(PxDiagnosticKind.usage, "timeline override: " + w);
7278
7783
  doc = patched.doc;
7279
7784
  }
7280
7785
  const animatorConfig = getAnimatorConfig(doc) || {};
7281
7786
  const engine = resolveTimelineEngine(animatorConfig.engine);
7282
- doc = materialiseAllInTree(doc, engine);
7787
+ doc = materializeAllInTree(doc, engine);
7283
7788
  let rootElement = null;
7284
7789
  if (containerElement) {
7285
7790
  doc = generateNewIds(doc);
7286
7791
  const containerEl = typeof containerElement === "string" ? document.querySelector(containerElement) : containerElement;
7287
7792
  if (containerEl) {
7288
- rootElement = renderNode(doc);
7793
+ rootElement = renderNode(doc, void 0, diag);
7289
7794
  if (rootElement) {
7290
7795
  containerEl.replaceChildren(rootElement);
7291
7796
  }
@@ -7302,21 +7807,22 @@ function createAnimatorImpl(doc, adapter, callbacks, containerElement, config, r
7302
7807
  }
7303
7808
  return api;
7304
7809
  }
7305
- function resolveAnimatorConfigOption(options) {
7306
- const { config, duration, delay, iterations, startOn } = options;
7307
- return foldAnimatorConfigShortcuts(config, { duration, delay, iterations, startOn });
7810
+ function resolveTimelineOption(options) {
7811
+ const { timeline, duration, delay, iterations, startOn } = options;
7812
+ return foldTimelineOverride(timeline, { duration, delay, iterations, startOn });
7308
7813
  }
7309
7814
  function createAnimator(options) {
7310
- const { src, data, adapter, callbacks, container, resetDocDefaults } = options;
7311
- const config = resolveAnimatorConfigOption(options);
7312
- if (data !== void 0 && src !== void 0) {
7313
- throw new Error("createAnimator: provide either `src` or `data`, not both");
7815
+ const { src, doc, adapter, container, resetTimeline } = options;
7816
+ const patch = resolveTimelineOption(options);
7817
+ const callbacks = toEngineCallbacks(options);
7818
+ if (doc !== void 0 && src !== void 0) {
7819
+ throw new Error("createAnimator: provide either `src` or `doc`, not both");
7314
7820
  }
7315
- if (data === void 0 && src === void 0) {
7316
- throw new Error("createAnimator: either `src` or `data` is required");
7821
+ if (doc === void 0 && src === void 0) {
7822
+ throw new Error("createAnimator: either `src` or `doc` is required");
7317
7823
  }
7318
- if (data !== void 0) {
7319
- return createAnimatorImpl(data, adapter, callbacks, container, config, resetDocDefaults);
7824
+ if (doc !== void 0) {
7825
+ return createAnimatorImpl(doc, adapter, callbacks, container, patch, resetTimeline);
7320
7826
  }
7321
7827
  let animator = null;
7322
7828
  let pending = [];
@@ -7328,19 +7834,27 @@ function createAnimator(options) {
7328
7834
  pending.push(call);
7329
7835
  }
7330
7836
  };
7837
+ const loadDiag = createDiagnostics(callbacks, "[PxAnimator]");
7331
7838
  fetch(src).then((res) => res.json()).then((json) => {
7332
7839
  if (destroyed) return;
7333
7840
  if (isPxElementFileFormat(json)) {
7334
- animator = createAnimatorImpl(json, adapter, callbacks, container, config, resetDocDefaults);
7841
+ animator = createAnimatorImpl(json, adapter, callbacks, container, patch, resetTimeline);
7335
7842
  const queued = pending;
7336
7843
  pending = null;
7337
7844
  queued == null ? void 0 : queued.forEach((call) => call(animator));
7338
7845
  } else {
7339
- console.error('createAnimator: invalid animation document format at "' + src + '"');
7846
+ loadDiag.error(
7847
+ PxDiagnosticKind.document,
7848
+ 'createAnimator: invalid animation document format at "' + src + '"'
7849
+ );
7340
7850
  }
7341
7851
  }).catch((err) => {
7852
+ var _a2;
7342
7853
  pending = null;
7343
- console.error('createAnimator: failed to load "' + src + '"', err);
7854
+ loadDiag.error(
7855
+ PxDiagnosticKind.host,
7856
+ 'createAnimator: failed to load "' + src + '" \u2014 ' + ((_a2 = err == null ? void 0 : err.message) != null ? _a2 : String(err))
7857
+ );
7344
7858
  });
7345
7859
  return {
7346
7860
  "isReady": () => !!animator,
@@ -7365,6 +7879,10 @@ function createAnimator(options) {
7365
7879
  "setCurrentTime": (time) => {
7366
7880
  enqueue((api) => api.setCurrentTime(time));
7367
7881
  },
7882
+ "getCurrentProgress": () => animator ? animator.getCurrentProgress() : null,
7883
+ "setCurrentProgress": (progress) => {
7884
+ enqueue((api) => api.setCurrentProgress(progress));
7885
+ },
7368
7886
  "destroy": () => {
7369
7887
  destroyed = true;
7370
7888
  pending = null;
@@ -7372,88 +7890,118 @@ function createAnimator(options) {
7372
7890
  }
7373
7891
  };
7374
7892
  }
7375
- function loadTagAnimators() {
7893
+ function loadTagAnimators(options) {
7376
7894
  const elements = document.querySelectorAll("[" + PX_ANIM_SRC_ATTR_NAME + "]");
7377
7895
  for (let i = 0; i < elements.length; i++) {
7378
7896
  const element = elements[i];
7379
7897
  if (!element[PX_ANIM_ATTR_NAME]) {
7380
7898
  const src = element.getAttribute(PX_ANIM_SRC_ATTR_NAME);
7381
7899
  if (src) {
7382
- element[PX_ANIM_ATTR_NAME] = createAnimator({ src, container: element });
7900
+ element[PX_ANIM_ATTR_NAME] = createAnimator(__spreadProps(__spreadValues({}, options), { src, container: element }));
7383
7901
  }
7384
7902
  }
7385
7903
  }
7386
7904
  }
7387
- if (typeof window !== "undefined") {
7388
- window["loadTagAnimators"] = loadTagAnimators;
7389
- window["createAnimator"] = createAnimator;
7390
- window["setupAnimationTriggers"] = setupAnimationTriggers;
7391
- }
7392
7905
  export {
7393
- COLOUR_ATTR_NAMES,
7906
+ BASELINE_PLAYER_VERSION,
7907
+ COLOR_ATTR_NAMES,
7908
+ DEFAULT_DURATION_MS,
7394
7909
  MISSING_GLYPH_CLASS_NAME,
7395
- PX_ANIMATOR_DATA_KEY,
7910
+ PLAYER_WIRE_STEPS,
7911
+ PLAYER_WIRE_VERSION,
7912
+ PX_ANIMATOR_DOC_KEY,
7396
7913
  PX_ANIM_ATTR_NAME,
7397
7914
  PX_ANIM_SRC_ATTR_NAME,
7915
+ PX_PLAYER_SCHEMA_VERSION,
7398
7916
  PX_TRANSFORM_PART_KEYS,
7917
+ PX_TRIGGER_DEFAULTS,
7918
+ PxAlongPathMode,
7399
7919
  PxAnimatedSvgDocumentSchema,
7400
7920
  PxAnimationDefinitionSchema,
7401
7921
  PxAnimatorConfigSchema,
7402
7922
  PxAttrValueSchema,
7403
7923
  PxBezierPathSchema,
7404
7924
  PxBindingSchema,
7925
+ PxClipPathEffectSchema,
7405
7926
  PxCloneEffectSchema,
7406
7927
  PxCloneWithout,
7928
+ PxControlMode,
7407
7929
  PxDefsSchema,
7930
+ PxDiagnosticKind,
7408
7931
  PxEasingOrRefSchema,
7409
7932
  PxEffectsSchema,
7410
7933
  PxElementAnimationSchema,
7411
7934
  PxFillGradientEffectSchema,
7935
+ PxFinishAction,
7412
7936
  PxGradientSpreadMethod,
7413
7937
  PxGradientStopSchema,
7414
7938
  PxGradientType,
7415
- PxGradientUnits,
7416
7939
  PxKeyframeSchema,
7417
7940
  PxKeyframeValueSchema,
7941
+ PxLengthAdjust,
7418
7942
  PxLoopDirection,
7419
7943
  PxLoopRepeatAt,
7420
7944
  PxLoopSchema,
7945
+ PxMaskType,
7421
7946
  PxMaskedByEffectSchema,
7422
7947
  PxNodeBase,
7423
7948
  PxNodeSchema,
7949
+ PxPathOverflow,
7950
+ PxPinAlign,
7424
7951
  PxPropertyAnimationSchema,
7425
7952
  PxRepeaterEffectSchema,
7426
7953
  PxRetimeEffectSchema,
7954
+ PxScrollAxis,
7955
+ PxScrollKind,
7956
+ PxScrollPhase,
7957
+ PxScrollRangePointSchema,
7958
+ PxScrollRangeSchema,
7959
+ PxScrollSchema,
7960
+ PxScrollSource,
7427
7961
  PxStrokeGradientEffectSchema,
7428
7962
  PxStrokeTrimEffectSchema,
7429
7963
  PxStrokeTrimSubPaths,
7430
7964
  PxSvgNodeExtra,
7431
7965
  PxTextEffectSchema,
7432
7966
  PxTextPathEffectSchema,
7967
+ PxTextPathMethod,
7968
+ PxTextPathSpacing,
7433
7969
  PxTimelineEngine,
7434
7970
  PxTimelineEngineExtra,
7971
+ PxTimelinePinSchema,
7972
+ PxTimelineSchema,
7435
7973
  PxTransformByEffectSchema,
7436
7974
  PxTransformPartsSchema,
7437
7975
  PxTransformValueSchema,
7438
7976
  PxTriggerSchema,
7977
+ PxUnits,
7439
7978
  STYLE_ATTR_NAMES,
7440
7979
  TRANSFORM_FN_NAMES,
7980
+ WIRE_VERSION_KEY,
7981
+ WireStepKind,
7982
+ WireVersionRelation,
7441
7983
  applyAnimatorConfig,
7442
7984
  applyPlayerEffects,
7443
7985
  calcAnimationValues,
7444
7986
  camelCaseToKebabWordIfNeeded,
7445
7987
  collectSampleTimes,
7988
+ compareWireVersion,
7989
+ controlModeTakesOverTrigger,
7990
+ convertPlayerDocument,
7446
7991
  createAnimator,
7447
- createAnimatorImpl,
7448
7992
  createBasicFrameLoopAnimator,
7993
+ createDiagnostics,
7449
7994
  createFrameLoopAnimator,
7450
7995
  createPathSampler,
7451
7996
  createWebApiAnimator,
7452
7997
  describeSchema,
7998
+ diagnoseDocument,
7453
7999
  diffInEffect,
8000
+ downgradePlayerDocument,
7454
8001
  evaluateMotionPathSegment,
7455
8002
  extendedPathForBrowser,
7456
- foldAnimatorConfigShortcuts,
8003
+ foldTimelineOverride,
8004
+ formatWireVersion,
7457
8005
  generateNewIds,
7458
8006
  getAnimatorConfig,
7459
8007
  getBindings,
@@ -7465,26 +8013,33 @@ export {
7465
8013
  jsonElementFactory,
7466
8014
  layoutGlyphTextChars,
7467
8015
  loadTagAnimators,
7468
- materialiseAllInTree,
7469
- materialiseAnimatedUseInstances,
7470
- materialiseGlyphText,
7471
- materialiseGlyphTextAlongPath,
7472
- materialiseGlyphTextHorizontal,
7473
- materialiseInternalLoopsInPropAnim,
7474
- materialiseInternalLoopsInTree,
7475
- materialiseMotionPathInPropAnim,
7476
- materialiseMotionPathsInTree,
8016
+ materializeAllInTree,
8017
+ materializeAnimatedUseInstances,
8018
+ materializeGlyphText,
8019
+ materializeGlyphTextAlongPath,
8020
+ materializeGlyphTextHorizontal,
8021
+ materializeInternalLoopsInPropAnim,
8022
+ materializeInternalLoopsInTree,
8023
+ materializeMotionPathInPropAnim,
8024
+ materializeMotionPathsInTree,
7477
8025
  mergeAnimatorConfig,
7478
- getNormalisedBindings as normalizeDocument,
8026
+ getNormalizedBindings as normalizeDocument,
8027
+ parseWireVersion,
8028
+ progressToTimeMs,
7479
8029
  propAnimIsMotionPath,
7480
8030
  px,
8031
+ readWireVersion,
7481
8032
  renderNode,
8033
+ resolveControlMode,
8034
+ resolveTrigger,
7482
8035
  schemaKeys,
7483
8036
  setupAnimationTriggers,
7484
8037
  shiftAnimatable,
8038
+ timeToProgress,
7485
8039
  toRGBA,
7486
8040
  validateDocument,
7487
8041
  validateNodeEffects,
8042
+ versionAdvice,
7488
8043
  visualModelAt
7489
8044
  };
7490
8045
  //# sourceMappingURL=index.js.map