@pixodesk/svg-animator-web 1.0.45 → 1.0.46

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.cjs CHANGED
@@ -59,7 +59,7 @@ __export(index_exports, {
59
59
  });
60
60
  module.exports = __toCommonJS(index_exports);
61
61
 
62
- // ../svg-animator-core/dist/chunk-YVKMPBHE.js
62
+ // ../svg-animator-core/dist/chunk-37OFJ3RX.js
63
63
  var __defProp2 = Object.defineProperty;
64
64
  var __defProps2 = Object.defineProperties;
65
65
  var __getOwnPropDescs2 = Object.getOwnPropertyDescriptors;
@@ -103,19 +103,31 @@ function pathStr(path) {
103
103
  return result;
104
104
  }
105
105
  var Base = class {
106
+ /** Structural schemas (objects, arrays, unions of objects…) pass `false`: they state no scalar default. */
107
+ constructor(_statesDefault) {
108
+ this._statesDefault = _statesDefault;
109
+ }
106
110
  _canSanitize(raw) {
107
111
  return this.isValid(raw);
108
112
  }
113
+ /** A REQUIRED field is never absent; its default is the repair value. */
114
+ absentDefault() {
115
+ return this._default;
116
+ }
109
117
  optional() {
110
118
  return new Optional(this);
111
119
  }
112
120
  };
113
121
  var Optional = class extends Base {
114
122
  constructor(inner) {
115
- super();
123
+ super(inner._statesDefault);
116
124
  this.inner = inner;
117
125
  this._default = void 0;
118
126
  }
127
+ /** Absent means the inner schema's STATED default — or nothing at all when it states none. */
128
+ absentDefault() {
129
+ return this.inner._statesDefault ? this.inner._default : void 0;
130
+ }
119
131
  sanitize(raw) {
120
132
  if (raw === void 0 || raw === null) return void 0;
121
133
  return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : void 0;
@@ -129,8 +141,8 @@ var Optional = class extends Base {
129
141
  }
130
142
  };
131
143
  var Str = class extends Base {
132
- constructor(_default = "") {
133
- super();
144
+ constructor(_default, statesDefault) {
145
+ super(statesDefault);
134
146
  this._default = _default;
135
147
  }
136
148
  sanitize(raw) {
@@ -143,8 +155,8 @@ var Str = class extends Base {
143
155
  }
144
156
  };
145
157
  var Num = class extends Base {
146
- constructor(_default = 0) {
147
- super();
158
+ constructor(_default, statesDefault) {
159
+ super(statesDefault);
148
160
  this._default = _default;
149
161
  }
150
162
  sanitize(raw) {
@@ -157,8 +169,8 @@ var Num = class extends Base {
157
169
  }
158
170
  };
159
171
  var Bool = class extends Base {
160
- constructor(_default = false) {
161
- super();
172
+ constructor(_default, statesDefault) {
173
+ super(statesDefault);
162
174
  this._default = _default;
163
175
  }
164
176
  sanitize(raw) {
@@ -171,8 +183,9 @@ var Bool = class extends Base {
171
183
  }
172
184
  };
173
185
  var Literal = class extends Base {
186
+ /** A literal IS its own value: absent means it. */
174
187
  constructor(value) {
175
- super();
188
+ super(true);
176
189
  this.value = value;
177
190
  this._default = value;
178
191
  }
@@ -186,8 +199,8 @@ var Literal = class extends Base {
186
199
  }
187
200
  };
188
201
  var Enum = class extends Base {
189
- constructor(values, defaultVal) {
190
- super();
202
+ constructor(values, defaultVal, statesDefault) {
203
+ super(statesDefault);
191
204
  this.values = values;
192
205
  this._default = defaultVal != null ? defaultVal : values[0];
193
206
  }
@@ -202,8 +215,8 @@ var Enum = class extends Base {
202
215
  };
203
216
  var UNION_MEMBER_ERROR_LIMIT = 4;
204
217
  var Union = class extends Base {
205
- constructor(schemas, defaultVal) {
206
- super();
218
+ constructor(schemas, defaultVal, statesDefault) {
219
+ super(statesDefault);
207
220
  this.schemas = schemas;
208
221
  this._kind = "union";
209
222
  this._default = defaultVal != null ? defaultVal : schemas[0]._default;
@@ -256,7 +269,7 @@ var Union = class extends Base {
256
269
  var DiscriminatedUnion = class extends Base {
257
270
  constructor(_key, _schemas, defaultVal) {
258
271
  var _a2;
259
- super();
272
+ super(false);
260
273
  this._key = _key;
261
274
  this._schemas = _schemas;
262
275
  this._kind = "discriminatedUnion";
@@ -295,13 +308,19 @@ var DiscriminatedUnion = class extends Base {
295
308
  return schema ? schema._canSanitize(raw) : this._schemas[0]._canSanitize(raw);
296
309
  }
297
310
  };
311
+ function statedDefaults(shape) {
312
+ const out = {};
313
+ for (const key of Object.keys(shape)) if (shape[key]._statesDefault) out[key] = shape[key].absentDefault();
314
+ return Object.freeze(out);
315
+ }
298
316
  var Obj = class extends Base {
299
317
  constructor(_shape) {
300
- super();
318
+ super(false);
301
319
  this._shape = _shape;
302
320
  const d = {};
303
321
  for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
304
322
  this._default = d;
323
+ this.defaults = statedDefaults(_shape);
305
324
  }
306
325
  sanitize(raw) {
307
326
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
@@ -343,12 +362,13 @@ var Obj = class extends Base {
343
362
  };
344
363
  var OpenObj = class extends Base {
345
364
  constructor(_shape, _openSchema) {
346
- super();
365
+ super(false);
347
366
  this._shape = _shape;
348
367
  this._openSchema = _openSchema;
349
368
  const d = {};
350
369
  for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
351
370
  this._default = d;
371
+ this.defaults = statedDefaults(_shape);
352
372
  }
353
373
  sanitize(raw) {
354
374
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
@@ -393,7 +413,7 @@ var OpenObj = class extends Base {
393
413
  };
394
414
  var Arr = class extends Base {
395
415
  constructor(item) {
396
- super();
416
+ super(false);
397
417
  this.item = item;
398
418
  this._default = [];
399
419
  }
@@ -425,7 +445,7 @@ var Arr = class extends Base {
425
445
  };
426
446
  var Rec = class extends Base {
427
447
  constructor(value) {
428
- super();
448
+ super(false);
429
449
  this.value = value;
430
450
  this._kind = "record";
431
451
  this._default = {};
@@ -458,7 +478,7 @@ var Rec = class extends Base {
458
478
  };
459
479
  var Any = class extends Base {
460
480
  constructor() {
461
- super(...arguments);
481
+ super(false);
462
482
  this._default = void 0;
463
483
  }
464
484
  sanitize(raw) {
@@ -473,7 +493,7 @@ var Any = class extends Base {
473
493
  };
474
494
  var Defined = class extends Base {
475
495
  constructor() {
476
- super(...arguments);
496
+ super(false);
477
497
  this._default = void 0;
478
498
  }
479
499
  sanitize(raw) {
@@ -490,7 +510,7 @@ var Defined = class extends Base {
490
510
  };
491
511
  var Lazy = class extends Base {
492
512
  constructor(fn, _default) {
493
- super();
513
+ super(false);
494
514
  this.fn = fn;
495
515
  this._default = _default;
496
516
  this.resolved = null;
@@ -511,7 +531,7 @@ var Lazy = class extends Base {
511
531
  };
512
532
  var Tuple = class extends Base {
513
533
  constructor(schemas) {
514
- super();
534
+ super(false);
515
535
  this.schemas = schemas;
516
536
  this._kind = "tuple";
517
537
  this._default = schemas.map((s) => s._default);
@@ -542,22 +562,29 @@ var Tuple = class extends Base {
542
562
  function implementsInterface() {
543
563
  return (schema) => schema;
544
564
  }
565
+ function string(defaultVal) {
566
+ return defaultVal === void 0 ? new Str("", false) : new Str(defaultVal, true);
567
+ }
568
+ function number(defaultVal) {
569
+ return defaultVal === void 0 ? new Num(0, false) : new Num(defaultVal, true);
570
+ }
571
+ function boolean(defaultVal) {
572
+ return defaultVal === void 0 ? new Bool(false, false) : new Bool(defaultVal, true);
573
+ }
574
+ function oneOf(values, defaultVal) {
575
+ return defaultVal === void 0 ? new Enum(values, void 0, false) : new Enum(values, defaultVal, true);
576
+ }
577
+ function unionOf(schemas, defaultVal) {
578
+ return defaultVal === void 0 ? new Union(schemas, void 0, false) : new Union(schemas, defaultVal, true);
579
+ }
545
580
  var px = {
546
- /** Matches a string. Default: '' or provided value. */
547
- string: (defaultVal = "") => new Str(defaultVal),
548
- /** Matches a finite number. Default: 0 or provided value. */
549
- number: (defaultVal = 0) => new Num(defaultVal),
550
- /** Matches a boolean. Default: false or provided value. */
551
- boolean: (defaultVal = false) => new Bool(defaultVal),
552
- /** Matches one exact primitive value; its default is the value itself. */
581
+ string,
582
+ number,
583
+ boolean,
584
+ /** Matches one exact primitive value; absent means the value itself. */
553
585
  literal: (value) => new Literal(value),
554
- /** Matches one of a fixed set of string/number values. Default: first value. */
555
- enum: (values, defaultVal) => new Enum(values, defaultVal),
556
- /**
557
- * Returns the first schema whose isValid passes.
558
- * TypeScript infers the union of all member types automatically.
559
- */
560
- union: (schemas, defaultVal) => new Union(schemas, defaultVal),
586
+ enum: oneOf,
587
+ union: unionOf,
561
588
  /**
562
589
  * Discriminated union — reads `raw[key]`, finds the member schema whose
563
590
  * literal at `key` matches, then delegates sanitize/isValid to that member.
@@ -565,7 +592,8 @@ var px = {
565
592
  * TypeScript infers the union of all member types automatically.
566
593
  */
567
594
  discriminatedUnion: (key, schemas) => new DiscriminatedUnion(key, schemas),
568
- /** Typed object — unknown keys are stripped. Required fields fall back to their default. */
595
+ /** Typed object — unknown keys are stripped. Required fields fall back to their default.
596
+ * Its `defaults` say what each stated field means when a document leaves it out. */
569
597
  object: (shape) => new Obj(shape),
570
598
  /**
571
599
  * Open object — validates known keys; passes unknown keys through as-is,
@@ -700,8 +728,11 @@ var PX_TRIGGER_DEFAULTS = {
700
728
  offScreen: "pause",
701
729
  mouseOut: "continue",
702
730
  visibilityThreshold: 0.5,
703
- visibilityDebounce: 150
731
+ visibilityDebounce: 150,
732
+ finish: "hold"
704
733
  };
734
+ var PX_DEFAULT_DURATION_MS = 1e3;
735
+ var PX_DEFAULT_ITERATIONS = 1;
705
736
  function resolveTrigger(trigger) {
706
737
  var _a2, _b, _c, _d, _e;
707
738
  return {
@@ -914,15 +945,15 @@ var keyframeTangentIn = (kf) => anyKf(kf).tangentIn;
914
945
  var keyframeTangentOut = (kf) => anyKf(kf).tangentOut;
915
946
  var PxLoopSchema = implementsInterface()(px.object({
916
947
  segmentCount: px.number().optional(),
917
- repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end]).optional(),
918
- direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate]).optional()
948
+ repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end], PxLoopRepeatAt.end).optional(),
949
+ direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate], PxLoopDirection.normal).optional()
919
950
  }));
920
951
  var PxPropertyAnimationSchema = implementsInterface()(px.object({
921
952
  value: PxKeyframeValueSchema.optional(),
922
953
  keyframes: px.array(PxKeyframeSchema).optional(),
923
954
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
924
955
  autoOrient: px.boolean().optional(),
925
- alongPathMode: px.enum([PxAlongPathMode.sampled, PxAlongPathMode.offsetPath]).optional()
956
+ alongPathMode: px.enum([PxAlongPathMode.sampled, PxAlongPathMode.offsetPath], PxAlongPathMode.sampled).optional()
926
957
  }));
927
958
  var PxTransformPartsSchema = implementsInterface()(px.object({
928
959
  translate: px.tuple([px.number(), px.number()]).optional(),
@@ -952,9 +983,9 @@ var PxTriggerSchema = implementsInterface()(px.object({
952
983
  // What happens after a NATURAL finish — `'hold'` (default: keep the end state per
953
984
  // `fill`) or `'reset'` (snap back to the start state). One of four occasion keys
954
985
  // (`start`, `offScreen`, `mouseOut`, `finish`), all named the same way.
955
- finish: px.enum([PxFinishAction.hold, PxFinishAction.reset]).optional(),
956
- visibilityThreshold: px.number().optional(),
957
- visibilityDebounce: px.number().optional()
986
+ finish: px.enum([PxFinishAction.hold, PxFinishAction.reset], PX_TRIGGER_DEFAULTS.finish).optional(),
987
+ visibilityThreshold: px.number(PX_TRIGGER_DEFAULTS.visibilityThreshold).optional(),
988
+ visibilityDebounce: px.number(PX_TRIGGER_DEFAULTS.visibilityDebounce).optional()
958
989
  }));
959
990
  var PxGlyphSchema = implementsInterface()(px.object({
960
991
  width: px.number(),
@@ -980,7 +1011,7 @@ var PxScrollRangePointSchema = implementsInterface()(px.object({
980
1011
  PxScrollPhase.exit,
981
1012
  PxScrollPhase.entryCrossing,
982
1013
  PxScrollPhase.exitCrossing
983
- ]).optional(),
1014
+ ], PxScrollPhase.cover).optional(),
984
1015
  fraction: px.number().optional()
985
1016
  }));
986
1017
  var PxScrollRangeSchema = px.object({
@@ -988,37 +1019,37 @@ var PxScrollRangeSchema = px.object({
988
1019
  end: PxScrollRangePointSchema.optional()
989
1020
  });
990
1021
  var PxScrollSchema = implementsInterface()(px.object({
991
- kind: px.enum([PxScrollKind.view, PxScrollKind.scroll]).optional(),
992
- axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
993
- source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
1022
+ kind: px.enum([PxScrollKind.view, PxScrollKind.scroll], PxScrollKind.view).optional(),
1023
+ axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y], PxScrollAxis.block).optional(),
1024
+ source: px.enum([PxScrollSource.nearest, PxScrollSource.root], PxScrollSource.nearest).optional(),
994
1025
  // Free-form: the two keywords `parent`/`scroller` plus any CSS selector.
995
1026
  subject: px.string().optional(),
996
1027
  smoothing: px.number().optional(),
997
- pin: px.boolean().optional(),
998
- pinAlign: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
1028
+ pin: px.boolean(false).optional(),
1029
+ pinAlign: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom], PxPinAlign.top).optional(),
999
1030
  pinOffset: px.number().optional(),
1000
1031
  pinDistance: px.number().optional(),
1001
1032
  range: PxScrollRangeSchema.optional()
1002
1033
  }));
1003
1034
  var PxTimelinePinSchema = implementsInterface()(px.object({
1004
- align: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
1035
+ align: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom], PxPinAlign.top).optional(),
1005
1036
  offset: px.number().optional(),
1006
1037
  distance: px.number().optional()
1007
1038
  }));
1008
- var PxTimelineEngineSchema = px.enum([PxTimelineEngineSetting.auto, PxTimelineEngineSetting.native, PxTimelineEngineSetting.js]).optional();
1039
+ var PxTimelineEngineSchema = px.enum([PxTimelineEngineSetting.auto, PxTimelineEngineSetting.native, PxTimelineEngineSetting.js], PxTimelineEngineSetting.auto).optional();
1009
1040
  var PxTimeTimelineSchema = implementsInterface()(px.object({
1010
1041
  type: px.literal("time").optional(),
1011
1042
  engine: PxTimelineEngineSchema,
1012
1043
  frameRate: px.number().optional(),
1013
1044
  // §2.8: duration is a property of the TIMELINE — how long one pass takes.
1014
- duration: px.number().optional(),
1045
+ duration: px.number(PX_DEFAULT_DURATION_MS).optional(),
1015
1046
  trigger: PxTriggerSchema.optional(),
1016
- delay: px.number().optional(),
1017
- iterations: px.union([px.number(), px.literal("infinite")]).optional(),
1047
+ delay: px.number(0).optional(),
1048
+ iterations: px.union([px.number(PX_DEFAULT_ITERATIONS), px.literal("infinite")], PX_DEFAULT_ITERATIONS).optional(),
1018
1049
  // `fillMode` on the wire (CSS `animation-fill-mode`; the runtime view calls it `fill`)
1019
1050
  // — never `fill`, which is paint everywhere else in the format.
1020
- fillMode: px.enum([PxFillMode.forwards, PxFillMode.backwards, PxFillMode.both, PxFillMode.none]).optional(),
1021
- direction: px.enum([PxPlaybackDirection.normal, PxPlaybackDirection.reverse, PxPlaybackDirection.alternate, PxPlaybackDirection.alternateReverse]).optional()
1051
+ fillMode: px.enum([PxFillMode.forwards, PxFillMode.backwards, PxFillMode.both, PxFillMode.none], PxFillMode.forwards).optional(),
1052
+ direction: px.enum([PxPlaybackDirection.normal, PxPlaybackDirection.reverse, PxPlaybackDirection.alternate, PxPlaybackDirection.alternateReverse], PxPlaybackDirection.normal).optional()
1022
1053
  }));
1023
1054
  var scrollishTimelineShape = {
1024
1055
  // §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
@@ -1029,8 +1060,8 @@ var scrollishTimelineShape = {
1029
1060
  iterations: px.number().optional(),
1030
1061
  engine: PxTimelineEngineSchema,
1031
1062
  frameRate: px.number().optional(),
1032
- axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
1033
- source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
1063
+ axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y], PxScrollAxis.block).optional(),
1064
+ source: px.enum([PxScrollSource.nearest, PxScrollSource.root], PxScrollSource.nearest).optional(),
1034
1065
  subject: px.string().optional(),
1035
1066
  // 'parent' | 'scroller' | any CSS selector
1036
1067
  smoothing: px.number().optional(),
@@ -1110,9 +1141,10 @@ var PxRepeaterEffectSchema = implementsInterface()(px.object({
1110
1141
  }));
1111
1142
  var PxMaskedByEffectSchema = implementsInterface()(px.object({
1112
1143
  source: px.string().optional(),
1113
- maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
1114
- maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1115
- maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1144
+ // SVG's own initial values — what a <mask> does when the attribute is not there.
1145
+ maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha], PxMaskType.luminance).optional(),
1146
+ maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox], PxUnits.objectBoundingBox).optional(),
1147
+ maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox], PxUnits.userSpaceOnUse).optional(),
1116
1148
  x: px.number().optional(),
1117
1149
  y: px.number().optional(),
1118
1150
  width: px.number().optional(),
@@ -1124,7 +1156,7 @@ var PxClipPathEffectSchema = implementsInterface()(px.object({
1124
1156
  var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
1125
1157
  offset: PxAnimatableNumberSchema.optional(),
1126
1158
  range: PxAnimatableVec2Schema.optional(),
1127
- subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined]).optional()
1159
+ subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined], PxStrokeTrimSubPaths.separate).optional()
1128
1160
  }));
1129
1161
  var PxRetimeEffectSchema = implementsInterface()(px.object({
1130
1162
  start: px.number().optional(),
@@ -1156,17 +1188,20 @@ var PxFillGradientEffectSchema = implementsInterface()(px.object({
1156
1188
  radius: PxAnimatableNumberSchema.optional(),
1157
1189
  focal: PxAnimatableVec2Schema.optional(),
1158
1190
  stops: PxAnimatableGradientStopsSchema.optional(),
1159
- gradientUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1160
- spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
1191
+ // SVG's own initial values — what a gradient does when the attribute is not there.
1192
+ gradientUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox], PxUnits.objectBoundingBox).optional(),
1193
+ spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat], PxGradientSpreadMethod.pad).optional(),
1161
1194
  gradientTransform: px.string().optional()
1162
1195
  }));
1163
1196
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
1164
1197
  var PxTextPathEffectSchema = implementsInterface()(px.object({
1165
1198
  pathData: px.string(),
1166
- pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
1167
- lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
1168
- method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
1169
- spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact]).optional(),
1199
+ // `extend` is what an omitted pathOverflow means (glyphs continue along the tangent); the
1200
+ // other three are SVG's own initial values for the native <textPath> attributes.
1201
+ pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend], PxPathOverflow.extend).optional(),
1202
+ lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs], PxLengthAdjust.spacing).optional(),
1203
+ method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch], PxTextPathMethod.align).optional(),
1204
+ spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact], PxTextPathSpacing.exact).optional(),
1170
1205
  startOffset: PxAnimatableNumberSchema.optional(),
1171
1206
  textLength: PxAnimatableNumberSchema.optional()
1172
1207
  }));
@@ -1726,7 +1761,6 @@ function parseTransformParts(str2) {
1726
1761
  return Object.keys(out).length ? out : void 0;
1727
1762
  }
1728
1763
  var PX_STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
1729
- var PX_DEFAULT_DURATION_MS = 1e3;
1730
1764
  function kebabToCamelCaseWord(kebab) {
1731
1765
  return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
1732
1766
  }
@@ -5723,9 +5757,10 @@ function walkAndMaterialize2(node, idMap, animatedIds, genId3, defsCollector, ro
5723
5757
  }
5724
5758
  var TRANSFORM_CHANNEL = "transform";
5725
5759
  var REVERSED_DIRECTIONS = /* @__PURE__ */ new Set(["reverse", "alternate-reverse"]);
5760
+ var VERIFY_SAMPLE_FRACTIONS = [0, 0.25, 0.5, 0.75, 1];
5726
5761
  var SCRATCH_ID_PREFIX = "__px_rest_";
5727
5762
  function materializeRestPosesInTree(root, engine) {
5728
- var _a2;
5763
+ var _a2, _b;
5729
5764
  const out = deepClone(root);
5730
5765
  const config = getAnimatorConfig(out) || {};
5731
5766
  const duration = +(config.duration || PX_DEFAULT_DURATION_MS);
@@ -5737,18 +5772,27 @@ function materializeRestPosesInTree(root, engine) {
5737
5772
  for (const [key, animate] of before) {
5738
5773
  const node = nodes.get(key);
5739
5774
  if (!node) continue;
5740
- for (const channel of Object.keys(animate)) {
5775
+ const channels = Object.keys(animate);
5776
+ for (const channel of channels) {
5777
+ if (PX_TRANSFORM_FN_NAMES.has(channel)) continue;
5741
5778
  if (!mayCarryRestPose(node, channel)) continue;
5742
5779
  const value = firstFrameValue(animate, channel, firstFrameTime);
5743
5780
  if (value === void 0) continue;
5744
5781
  node[channel] = value;
5745
5782
  added.set(key, [...(_a2 = added.get(key)) != null ? _a2 : [], channel]);
5746
5783
  }
5784
+ if (channels.some((channel) => PX_TRANSFORM_FN_NAMES.has(channel)) && mayCarryTransformRestPose(node)) {
5785
+ const parts = firstFrameTransformParts(animate, firstFrameTime);
5786
+ if (parts) {
5787
+ node[TRANSFORM_CHANNEL] = parts;
5788
+ added.set(key, [...(_b = added.get(key)) != null ? _b : [], TRANSFORM_CHANNEL]);
5789
+ }
5790
+ }
5747
5791
  }
5748
5792
  if (added.size) {
5749
5793
  const after = bindingsOf(out, engine);
5750
5794
  for (const [key, channels] of added) {
5751
- if (JSON.stringify(after.get(key)) === JSON.stringify(before.get(key))) continue;
5795
+ if (writesTheSameFrames(before.get(key), after.get(key), duration)) continue;
5752
5796
  const node = nodes.get(key);
5753
5797
  if (node) for (const channel of channels) delete node[channel];
5754
5798
  }
@@ -5757,16 +5801,31 @@ function materializeRestPosesInTree(root, engine) {
5757
5801
  }
5758
5802
  function mayCarryRestPose(node, channel) {
5759
5803
  if (node[channel] !== void 0) return false;
5760
- if (PX_TRANSFORM_FN_NAMES.has(channel)) return false;
5761
- if (channel === TRANSFORM_CHANNEL) {
5762
- for (const part of PX_TRANSFORM_FN_NAMES) if (node[part] !== void 0) return false;
5763
- }
5804
+ if (channel === TRANSFORM_CHANNEL) return mayCarryTransformRestPose(node);
5805
+ return true;
5806
+ }
5807
+ function mayCarryTransformRestPose(node) {
5808
+ if (node[TRANSFORM_CHANNEL] !== void 0) return false;
5809
+ for (const part of PX_TRANSFORM_FN_NAMES) if (node[part] !== void 0) return false;
5764
5810
  return true;
5765
5811
  }
5766
5812
  function firstFrameValue(animate, channel, timeMs) {
5767
5813
  const values = Object.values(calcAnimationValues({ [channel]: animate[channel] }, timeMs));
5768
5814
  return values.length === 1 && values[0] !== "" ? values[0] : void 0;
5769
5815
  }
5816
+ function firstFrameTransformParts(animate, timeMs) {
5817
+ const family = {};
5818
+ for (const channel of Object.keys(animate)) if (PX_TRANSFORM_FN_NAMES.has(channel)) family[channel] = animate[channel];
5819
+ const written = calcAnimationValues(family, timeMs)[TRANSFORM_CHANNEL];
5820
+ if (!written) return void 0;
5821
+ const parts = parseTransformParts(written.replace(/(px|deg)\b/g, ""));
5822
+ return parts && Object.keys(parts).length ? parts : void 0;
5823
+ }
5824
+ function writesTheSameFrames(a, b, durationMs) {
5825
+ if (!a || !b) return a === b;
5826
+ const frame = (animate, t) => JSON.stringify(calcAnimationValues(animate, t)).replace(/\s+/g, "");
5827
+ return VERIFY_SAMPLE_FRACTIONS.every((fraction) => frame(a, fraction * durationMs) === frame(b, fraction * durationMs));
5828
+ }
5770
5829
  function bindingsOf(tree, engine) {
5771
5830
  const scratch = deepClone(tree);
5772
5831
  const keyById = /* @__PURE__ */ new Map();
@@ -5977,13 +6036,13 @@ function createAdapterAnimator(doc, adapter, callbacks) {
5977
6036
  const bindings = normalizeBindings(doc, PxTimelineEngine.js);
5978
6037
  const _iterations = config.iterations;
5979
6038
  let iterations = 1;
5980
- if (typeof _iterations === "number") iterations = _iterations || 1;
6039
+ if (typeof _iterations === "number") iterations = _iterations || PX_DEFAULT_ITERATIONS;
5981
6040
  if (_iterations === "infinite") iterations = Infinity;
5982
6041
  if (iterations < 1) iterations = 1;
5983
6042
  const duration = +(config.duration || PX_DEFAULT_DURATION_MS);
5984
- const totalDuration = duration && iterations ? duration * (iterations === Infinity ? Infinity : iterations) : duration ? (iterations != null ? iterations : 1) * duration : 0;
5985
- const direction = config.direction || "normal";
5986
- const fill = (_a2 = config.fill) != null ? _a2 : "forwards";
6043
+ const totalDuration = duration && iterations ? duration * (iterations === Infinity ? Infinity : iterations) : duration ? (iterations != null ? iterations : PX_DEFAULT_ITERATIONS) * duration : 0;
6044
+ const direction = config.direction || PxTimeTimelineSchema.defaults.direction;
6045
+ const fill = (_a2 = config.fill) != null ? _a2 : PxTimeTimelineSchema.defaults.fillMode;
5987
6046
  const fillsForwards = fill === "forwards" || fill === "both";
5988
6047
  const fillsBackwards = fill === "backwards" || fill === "both";
5989
6048
  let timerId = null;
@@ -7004,7 +7063,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
7004
7063
  let seekPosition;
7005
7064
  if (config.delay && config.delay < 0 && config.duration) {
7006
7065
  const rawSeek = -config.delay;
7007
- seekPosition = iterations === Infinity ? rawSeek % config.duration : Math.min(rawSeek, config.duration * (iterations != null ? iterations : 1));
7066
+ seekPosition = iterations === Infinity ? rawSeek % config.duration : Math.min(rawSeek, config.duration * (iterations != null ? iterations : PX_DEFAULT_ITERATIONS));
7008
7067
  }
7009
7068
  const effectOptions = {
7010
7069
  duration: config.duration,
@@ -7111,7 +7170,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
7111
7170
  },
7112
7171
  "setCurrentTime": (time) => {
7113
7172
  var _a3;
7114
- const ceiling = seekCeilingMs((_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1);
7173
+ const ceiling = seekCeilingMs((_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : PX_DEFAULT_ITERATIONS);
7115
7174
  const seek = ceiling > 0 ? clampSeekMs(time, ceiling) : Math.max(0, time);
7116
7175
  finishNotified = false;
7117
7176
  animations.forEach((a) => {
@@ -7121,11 +7180,11 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
7121
7180
  "getCurrentProgress": () => {
7122
7181
  var _a3;
7123
7182
  const t = api.getCurrentTime();
7124
- return t === null ? null : timeToProgress(t, (_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1);
7183
+ return t === null ? null : timeToProgress(t, (_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : PX_DEFAULT_ITERATIONS);
7125
7184
  },
7126
7185
  "setCurrentProgress": (progress) => {
7127
7186
  var _a3;
7128
- api.setCurrentTime(progressToTimeMs(progress, (_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : 1));
7187
+ api.setCurrentTime(progressToTimeMs(progress, (_a3 = config.duration) != null ? _a3 : 0, iterations != null ? iterations : PX_DEFAULT_ITERATIONS));
7129
7188
  },
7130
7189
  "destroy": () => {
7131
7190
  var _a3;