@pixodesk/svg-animator-core 1.0.45 → 1.0.47

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.
@@ -43,19 +43,31 @@ function pathStr(path) {
43
43
  return result;
44
44
  }
45
45
  var Base = class {
46
+ /** Structural schemas (objects, arrays, unions of objects…) pass `false`: they state no scalar default. */
47
+ constructor(_statesDefault) {
48
+ this._statesDefault = _statesDefault;
49
+ }
46
50
  _canSanitize(raw) {
47
51
  return this.isValid(raw);
48
52
  }
53
+ /** A REQUIRED field is never absent; its default is the repair value. */
54
+ absentDefault() {
55
+ return this._default;
56
+ }
49
57
  optional() {
50
58
  return new Optional(this);
51
59
  }
52
60
  };
53
61
  var Optional = class extends Base {
54
62
  constructor(inner) {
55
- super();
63
+ super(inner._statesDefault);
56
64
  this.inner = inner;
57
65
  this._default = void 0;
58
66
  }
67
+ /** Absent means the inner schema's STATED default — or nothing at all when it states none. */
68
+ absentDefault() {
69
+ return this.inner._statesDefault ? this.inner._default : void 0;
70
+ }
59
71
  sanitize(raw) {
60
72
  if (raw === void 0 || raw === null) return void 0;
61
73
  return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : void 0;
@@ -69,8 +81,8 @@ var Optional = class extends Base {
69
81
  }
70
82
  };
71
83
  var Str = class extends Base {
72
- constructor(_default = "") {
73
- super();
84
+ constructor(_default, statesDefault) {
85
+ super(statesDefault);
74
86
  this._default = _default;
75
87
  }
76
88
  sanitize(raw) {
@@ -83,8 +95,8 @@ var Str = class extends Base {
83
95
  }
84
96
  };
85
97
  var Num = class extends Base {
86
- constructor(_default = 0) {
87
- super();
98
+ constructor(_default, statesDefault) {
99
+ super(statesDefault);
88
100
  this._default = _default;
89
101
  }
90
102
  sanitize(raw) {
@@ -97,8 +109,8 @@ var Num = class extends Base {
97
109
  }
98
110
  };
99
111
  var Bool = class extends Base {
100
- constructor(_default = false) {
101
- super();
112
+ constructor(_default, statesDefault) {
113
+ super(statesDefault);
102
114
  this._default = _default;
103
115
  }
104
116
  sanitize(raw) {
@@ -111,8 +123,9 @@ var Bool = class extends Base {
111
123
  }
112
124
  };
113
125
  var Literal = class extends Base {
126
+ /** A literal IS its own value: absent means it. */
114
127
  constructor(value) {
115
- super();
128
+ super(true);
116
129
  this.value = value;
117
130
  this._default = value;
118
131
  }
@@ -126,8 +139,8 @@ var Literal = class extends Base {
126
139
  }
127
140
  };
128
141
  var Enum = class extends Base {
129
- constructor(values, defaultVal) {
130
- super();
142
+ constructor(values, defaultVal, statesDefault) {
143
+ super(statesDefault);
131
144
  this.values = values;
132
145
  this._default = defaultVal != null ? defaultVal : values[0];
133
146
  }
@@ -142,8 +155,8 @@ var Enum = class extends Base {
142
155
  };
143
156
  var UNION_MEMBER_ERROR_LIMIT = 4;
144
157
  var Union = class extends Base {
145
- constructor(schemas, defaultVal) {
146
- super();
158
+ constructor(schemas, defaultVal, statesDefault) {
159
+ super(statesDefault);
147
160
  this.schemas = schemas;
148
161
  /** Structural tag read by {@link describeSchema} — `schemas` alone cannot tell Union from Tuple. */
149
162
  this._kind = "union";
@@ -197,7 +210,7 @@ var Union = class extends Base {
197
210
  var DiscriminatedUnion = class extends Base {
198
211
  constructor(_key, _schemas, defaultVal) {
199
212
  var _a2;
200
- super();
213
+ super(false);
201
214
  this._key = _key;
202
215
  this._schemas = _schemas;
203
216
  /** Structural tag read by {@link describeSchema}. */
@@ -237,13 +250,19 @@ var DiscriminatedUnion = class extends Base {
237
250
  return schema ? schema._canSanitize(raw) : this._schemas[0]._canSanitize(raw);
238
251
  }
239
252
  };
253
+ function statedDefaults(shape) {
254
+ const out = {};
255
+ for (const key of Object.keys(shape)) if (shape[key]._statesDefault) out[key] = shape[key].absentDefault();
256
+ return Object.freeze(out);
257
+ }
240
258
  var Obj = class extends Base {
241
259
  constructor(_shape) {
242
- super();
260
+ super(false);
243
261
  this._shape = _shape;
244
262
  const d = {};
245
263
  for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
246
264
  this._default = d;
265
+ this.defaults = statedDefaults(_shape);
247
266
  }
248
267
  sanitize(raw) {
249
268
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
@@ -285,12 +304,13 @@ var Obj = class extends Base {
285
304
  };
286
305
  var OpenObj = class extends Base {
287
306
  constructor(_shape, _openSchema) {
288
- super();
307
+ super(false);
289
308
  this._shape = _shape;
290
309
  this._openSchema = _openSchema;
291
310
  const d = {};
292
311
  for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
293
312
  this._default = d;
313
+ this.defaults = statedDefaults(_shape);
294
314
  }
295
315
  sanitize(raw) {
296
316
  const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
@@ -335,7 +355,7 @@ var OpenObj = class extends Base {
335
355
  };
336
356
  var Arr = class extends Base {
337
357
  constructor(item) {
338
- super();
358
+ super(false);
339
359
  this.item = item;
340
360
  this._default = [];
341
361
  }
@@ -367,7 +387,7 @@ var Arr = class extends Base {
367
387
  };
368
388
  var Rec = class extends Base {
369
389
  constructor(value) {
370
- super();
390
+ super(false);
371
391
  this.value = value;
372
392
  /** Structural tag read by {@link describeSchema}. */
373
393
  this._kind = "record";
@@ -401,7 +421,7 @@ var Rec = class extends Base {
401
421
  };
402
422
  var Any = class extends Base {
403
423
  constructor() {
404
- super(...arguments);
424
+ super(false);
405
425
  this._default = void 0;
406
426
  }
407
427
  sanitize(raw) {
@@ -416,7 +436,7 @@ var Any = class extends Base {
416
436
  };
417
437
  var Defined = class extends Base {
418
438
  constructor() {
419
- super(...arguments);
439
+ super(false);
420
440
  this._default = void 0;
421
441
  }
422
442
  sanitize(raw) {
@@ -433,7 +453,7 @@ var Defined = class extends Base {
433
453
  };
434
454
  var Lazy = class extends Base {
435
455
  constructor(fn, _default) {
436
- super();
456
+ super(false);
437
457
  this.fn = fn;
438
458
  this._default = _default;
439
459
  this.resolved = null;
@@ -454,7 +474,7 @@ var Lazy = class extends Base {
454
474
  };
455
475
  var Tuple = class extends Base {
456
476
  constructor(schemas) {
457
- super();
477
+ super(false);
458
478
  this.schemas = schemas;
459
479
  /** Structural tag read by {@link describeSchema} — `schemas` alone cannot tell Tuple from Union. */
460
480
  this._kind = "tuple";
@@ -510,22 +530,29 @@ function describeSchema(schema) {
510
530
  if ("fn" in s) return { kind: "lazy", resolved: (_a2 = s.resolved) != null ? _a2 : s.resolved = s.fn() };
511
531
  return { kind: "leaf" };
512
532
  }
533
+ function string(defaultVal) {
534
+ return defaultVal === void 0 ? new Str("", false) : new Str(defaultVal, true);
535
+ }
536
+ function number(defaultVal) {
537
+ return defaultVal === void 0 ? new Num(0, false) : new Num(defaultVal, true);
538
+ }
539
+ function boolean(defaultVal) {
540
+ return defaultVal === void 0 ? new Bool(false, false) : new Bool(defaultVal, true);
541
+ }
542
+ function oneOf(values, defaultVal) {
543
+ return defaultVal === void 0 ? new Enum(values, void 0, false) : new Enum(values, defaultVal, true);
544
+ }
545
+ function unionOf(schemas, defaultVal) {
546
+ return defaultVal === void 0 ? new Union(schemas, void 0, false) : new Union(schemas, defaultVal, true);
547
+ }
513
548
  var px = {
514
- /** Matches a string. Default: '' or provided value. */
515
- string: (defaultVal = "") => new Str(defaultVal),
516
- /** Matches a finite number. Default: 0 or provided value. */
517
- number: (defaultVal = 0) => new Num(defaultVal),
518
- /** Matches a boolean. Default: false or provided value. */
519
- boolean: (defaultVal = false) => new Bool(defaultVal),
520
- /** Matches one exact primitive value; its default is the value itself. */
549
+ string,
550
+ number,
551
+ boolean,
552
+ /** Matches one exact primitive value; absent means the value itself. */
521
553
  literal: (value) => new Literal(value),
522
- /** Matches one of a fixed set of string/number values. Default: first value. */
523
- enum: (values, defaultVal) => new Enum(values, defaultVal),
524
- /**
525
- * Returns the first schema whose isValid passes.
526
- * TypeScript infers the union of all member types automatically.
527
- */
528
- union: (schemas, defaultVal) => new Union(schemas, defaultVal),
554
+ enum: oneOf,
555
+ union: unionOf,
529
556
  /**
530
557
  * Discriminated union — reads `raw[key]`, finds the member schema whose
531
558
  * literal at `key` matches, then delegates sanitize/isValid to that member.
@@ -533,7 +560,8 @@ var px = {
533
560
  * TypeScript infers the union of all member types automatically.
534
561
  */
535
562
  discriminatedUnion: (key, schemas) => new DiscriminatedUnion(key, schemas),
536
- /** Typed object — unknown keys are stripped. Required fields fall back to their default. */
563
+ /** Typed object — unknown keys are stripped. Required fields fall back to their default.
564
+ * Its `defaults` say what each stated field means when a document leaves it out. */
537
565
  object: (shape) => new Obj(shape),
538
566
  /**
539
567
  * Open object — validates known keys; passes unknown keys through as-is,
@@ -879,8 +907,11 @@ var PX_TRIGGER_DEFAULTS = {
879
907
  offScreen: "pause",
880
908
  mouseOut: "continue",
881
909
  visibilityThreshold: 0.5,
882
- visibilityDebounce: 150
910
+ visibilityDebounce: 150,
911
+ finish: "hold"
883
912
  };
913
+ var PX_DEFAULT_DURATION_MS = 1e3;
914
+ var PX_DEFAULT_ITERATIONS = 1;
884
915
  var PxControlMode = {
885
916
  /** No control props — the document's trigger decides, and nothing is taken over. */
886
917
  static: "static",
@@ -1195,15 +1226,15 @@ var keyframeTangentIn = (kf) => anyKf(kf).tangentIn;
1195
1226
  var keyframeTangentOut = (kf) => anyKf(kf).tangentOut;
1196
1227
  var PxLoopSchema = implementsInterface()(px.object({
1197
1228
  segmentCount: px.number().optional(),
1198
- repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end]).optional(),
1199
- direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate]).optional()
1229
+ repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end], PxLoopRepeatAt.end).optional(),
1230
+ direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate], PxLoopDirection.normal).optional()
1200
1231
  }));
1201
1232
  var PxPropertyAnimationSchema = implementsInterface()(px.object({
1202
1233
  value: PxKeyframeValueSchema.optional(),
1203
1234
  keyframes: px.array(PxKeyframeSchema).optional(),
1204
1235
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
1205
1236
  autoOrient: px.boolean().optional(),
1206
- alongPathMode: px.enum([PxAlongPathMode.sampled, PxAlongPathMode.offsetPath]).optional()
1237
+ alongPathMode: px.enum([PxAlongPathMode.sampled, PxAlongPathMode.offsetPath], PxAlongPathMode.sampled).optional()
1207
1238
  }));
1208
1239
  var PxTransformPartsSchema = implementsInterface()(px.object({
1209
1240
  translate: px.tuple([px.number(), px.number()]).optional(),
@@ -1233,9 +1264,9 @@ var PxTriggerSchema = implementsInterface()(px.object({
1233
1264
  // What happens after a NATURAL finish — `'hold'` (default: keep the end state per
1234
1265
  // `fill`) or `'reset'` (snap back to the start state). One of four occasion keys
1235
1266
  // (`start`, `offScreen`, `mouseOut`, `finish`), all named the same way.
1236
- finish: px.enum([PxFinishAction.hold, PxFinishAction.reset]).optional(),
1237
- visibilityThreshold: px.number().optional(),
1238
- visibilityDebounce: px.number().optional()
1267
+ finish: px.enum([PxFinishAction.hold, PxFinishAction.reset], PX_TRIGGER_DEFAULTS.finish).optional(),
1268
+ visibilityThreshold: px.number(PX_TRIGGER_DEFAULTS.visibilityThreshold).optional(),
1269
+ visibilityDebounce: px.number(PX_TRIGGER_DEFAULTS.visibilityDebounce).optional()
1239
1270
  }));
1240
1271
  var PxGlyphSchema = implementsInterface()(px.object({
1241
1272
  width: px.number(),
@@ -1261,7 +1292,7 @@ var PxScrollRangePointSchema = implementsInterface()(px.object({
1261
1292
  PxScrollPhase.exit,
1262
1293
  PxScrollPhase.entryCrossing,
1263
1294
  PxScrollPhase.exitCrossing
1264
- ]).optional(),
1295
+ ], PxScrollPhase.cover).optional(),
1265
1296
  fraction: px.number().optional()
1266
1297
  }));
1267
1298
  var PxScrollRangeSchema = px.object({
@@ -1269,37 +1300,37 @@ var PxScrollRangeSchema = px.object({
1269
1300
  end: PxScrollRangePointSchema.optional()
1270
1301
  });
1271
1302
  var PxScrollSchema = implementsInterface()(px.object({
1272
- kind: px.enum([PxScrollKind.view, PxScrollKind.scroll]).optional(),
1273
- axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
1274
- source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
1303
+ kind: px.enum([PxScrollKind.view, PxScrollKind.scroll], PxScrollKind.view).optional(),
1304
+ axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y], PxScrollAxis.block).optional(),
1305
+ source: px.enum([PxScrollSource.nearest, PxScrollSource.root], PxScrollSource.nearest).optional(),
1275
1306
  // Free-form: the two keywords `parent`/`scroller` plus any CSS selector.
1276
1307
  subject: px.string().optional(),
1277
1308
  smoothing: px.number().optional(),
1278
- pin: px.boolean().optional(),
1279
- pinAlign: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
1309
+ pin: px.boolean(false).optional(),
1310
+ pinAlign: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom], PxPinAlign.top).optional(),
1280
1311
  pinOffset: px.number().optional(),
1281
1312
  pinDistance: px.number().optional(),
1282
1313
  range: PxScrollRangeSchema.optional()
1283
1314
  }));
1284
1315
  var PxTimelinePinSchema = implementsInterface()(px.object({
1285
- align: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
1316
+ align: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom], PxPinAlign.top).optional(),
1286
1317
  offset: px.number().optional(),
1287
1318
  distance: px.number().optional()
1288
1319
  }));
1289
- var PxTimelineEngineSchema = px.enum([PxTimelineEngineSetting.auto, PxTimelineEngineSetting.native, PxTimelineEngineSetting.js]).optional();
1320
+ var PxTimelineEngineSchema = px.enum([PxTimelineEngineSetting.auto, PxTimelineEngineSetting.native, PxTimelineEngineSetting.js], PxTimelineEngineSetting.auto).optional();
1290
1321
  var PxTimeTimelineSchema = implementsInterface()(px.object({
1291
1322
  type: px.literal("time").optional(),
1292
1323
  engine: PxTimelineEngineSchema,
1293
1324
  frameRate: px.number().optional(),
1294
1325
  // §2.8: duration is a property of the TIMELINE — how long one pass takes.
1295
- duration: px.number().optional(),
1326
+ duration: px.number(PX_DEFAULT_DURATION_MS).optional(),
1296
1327
  trigger: PxTriggerSchema.optional(),
1297
- delay: px.number().optional(),
1298
- iterations: px.union([px.number(), px.literal("infinite")]).optional(),
1328
+ delay: px.number(0).optional(),
1329
+ iterations: px.union([px.number(PX_DEFAULT_ITERATIONS), px.literal("infinite")], PX_DEFAULT_ITERATIONS).optional(),
1299
1330
  // `fillMode` on the wire (CSS `animation-fill-mode`; the runtime view calls it `fill`)
1300
1331
  // — never `fill`, which is paint everywhere else in the format.
1301
- fillMode: px.enum([PxFillMode.forwards, PxFillMode.backwards, PxFillMode.both, PxFillMode.none]).optional(),
1302
- direction: px.enum([PxPlaybackDirection.normal, PxPlaybackDirection.reverse, PxPlaybackDirection.alternate, PxPlaybackDirection.alternateReverse]).optional()
1332
+ fillMode: px.enum([PxFillMode.forwards, PxFillMode.backwards, PxFillMode.both, PxFillMode.none], PxFillMode.forwards).optional(),
1333
+ direction: px.enum([PxPlaybackDirection.normal, PxPlaybackDirection.reverse, PxPlaybackDirection.alternate, PxPlaybackDirection.alternateReverse], PxPlaybackDirection.normal).optional()
1303
1334
  }));
1304
1335
  var scrollishTimelineShape = {
1305
1336
  // §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
@@ -1310,8 +1341,8 @@ var scrollishTimelineShape = {
1310
1341
  iterations: px.number().optional(),
1311
1342
  engine: PxTimelineEngineSchema,
1312
1343
  frameRate: px.number().optional(),
1313
- axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
1314
- source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
1344
+ axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y], PxScrollAxis.block).optional(),
1345
+ source: px.enum([PxScrollSource.nearest, PxScrollSource.root], PxScrollSource.nearest).optional(),
1315
1346
  subject: px.string().optional(),
1316
1347
  // 'parent' | 'scroller' | any CSS selector
1317
1348
  smoothing: px.number().optional(),
@@ -1391,9 +1422,10 @@ var PxRepeaterEffectSchema = implementsInterface()(px.object({
1391
1422
  }));
1392
1423
  var PxMaskedByEffectSchema = implementsInterface()(px.object({
1393
1424
  source: px.string().optional(),
1394
- maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
1395
- maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1396
- maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1425
+ // SVG's own initial values — what a <mask> does when the attribute is not there.
1426
+ maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha], PxMaskType.luminance).optional(),
1427
+ maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox], PxUnits.objectBoundingBox).optional(),
1428
+ maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox], PxUnits.userSpaceOnUse).optional(),
1397
1429
  x: px.number().optional(),
1398
1430
  y: px.number().optional(),
1399
1431
  width: px.number().optional(),
@@ -1405,7 +1437,7 @@ var PxClipPathEffectSchema = implementsInterface()(px.object({
1405
1437
  var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
1406
1438
  offset: PxAnimatableNumberSchema.optional(),
1407
1439
  range: PxAnimatableVec2Schema.optional(),
1408
- subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined]).optional()
1440
+ subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined], PxStrokeTrimSubPaths.separate).optional()
1409
1441
  }));
1410
1442
  var PxRetimeEffectSchema = implementsInterface()(px.object({
1411
1443
  start: px.number().optional(),
@@ -1437,17 +1469,20 @@ var PxFillGradientEffectSchema = implementsInterface()(px.object({
1437
1469
  radius: PxAnimatableNumberSchema.optional(),
1438
1470
  focal: PxAnimatableVec2Schema.optional(),
1439
1471
  stops: PxAnimatableGradientStopsSchema.optional(),
1440
- gradientUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1441
- spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
1472
+ // SVG's own initial values — what a gradient does when the attribute is not there.
1473
+ gradientUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox], PxUnits.objectBoundingBox).optional(),
1474
+ spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat], PxGradientSpreadMethod.pad).optional(),
1442
1475
  gradientTransform: px.string().optional()
1443
1476
  }));
1444
1477
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
1445
1478
  var PxTextPathEffectSchema = implementsInterface()(px.object({
1446
1479
  pathData: px.string(),
1447
- pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
1448
- lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
1449
- method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
1450
- spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact]).optional(),
1480
+ // `extend` is what an omitted pathOverflow means (glyphs continue along the tangent); the
1481
+ // other three are SVG's own initial values for the native <textPath> attributes.
1482
+ pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend], PxPathOverflow.extend).optional(),
1483
+ lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs], PxLengthAdjust.spacing).optional(),
1484
+ method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch], PxTextPathMethod.align).optional(),
1485
+ spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact], PxTextPathSpacing.exact).optional(),
1451
1486
  startOffset: PxAnimatableNumberSchema.optional(),
1452
1487
  textLength: PxAnimatableNumberSchema.optional()
1453
1488
  }));
@@ -2015,7 +2050,6 @@ function parseTransformParts(str2) {
2015
2050
  return Object.keys(out).length ? out : void 0;
2016
2051
  }
2017
2052
  var PX_STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
2018
- var PX_DEFAULT_DURATION_MS = 1e3;
2019
2053
  function kebabToCamelCaseWord(kebab) {
2020
2054
  return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
2021
2055
  }
@@ -6185,9 +6219,10 @@ function walkAndMaterialize2(node, idMap, animatedIds, genId3, defsCollector, ro
6185
6219
  // src/materialize/PxRestPose.ts
6186
6220
  var TRANSFORM_CHANNEL = "transform";
6187
6221
  var REVERSED_DIRECTIONS = /* @__PURE__ */ new Set(["reverse", "alternate-reverse"]);
6222
+ var VERIFY_SAMPLE_FRACTIONS = [0, 0.25, 0.5, 0.75, 1];
6188
6223
  var SCRATCH_ID_PREFIX = "__px_rest_";
6189
6224
  function materializeRestPosesInTree(root, engine) {
6190
- var _a2;
6225
+ var _a2, _b;
6191
6226
  const out = deepClone(root);
6192
6227
  const config = getAnimatorConfig(out) || {};
6193
6228
  const duration = +(config.duration || PX_DEFAULT_DURATION_MS);
@@ -6199,18 +6234,27 @@ function materializeRestPosesInTree(root, engine) {
6199
6234
  for (const [key, animate] of before) {
6200
6235
  const node = nodes.get(key);
6201
6236
  if (!node) continue;
6202
- for (const channel of Object.keys(animate)) {
6237
+ const channels = Object.keys(animate);
6238
+ for (const channel of channels) {
6239
+ if (PX_TRANSFORM_FN_NAMES.has(channel)) continue;
6203
6240
  if (!mayCarryRestPose(node, channel)) continue;
6204
6241
  const value = firstFrameValue(animate, channel, firstFrameTime);
6205
6242
  if (value === void 0) continue;
6206
6243
  node[channel] = value;
6207
6244
  added.set(key, [...(_a2 = added.get(key)) != null ? _a2 : [], channel]);
6208
6245
  }
6246
+ if (channels.some((channel) => PX_TRANSFORM_FN_NAMES.has(channel)) && mayCarryTransformRestPose(node)) {
6247
+ const parts = firstFrameTransformParts(animate, firstFrameTime);
6248
+ if (parts) {
6249
+ node[TRANSFORM_CHANNEL] = parts;
6250
+ added.set(key, [...(_b = added.get(key)) != null ? _b : [], TRANSFORM_CHANNEL]);
6251
+ }
6252
+ }
6209
6253
  }
6210
6254
  if (added.size) {
6211
6255
  const after = bindingsOf(out, engine);
6212
6256
  for (const [key, channels] of added) {
6213
- if (JSON.stringify(after.get(key)) === JSON.stringify(before.get(key))) continue;
6257
+ if (writesTheSameFrames(before.get(key), after.get(key), duration)) continue;
6214
6258
  const node = nodes.get(key);
6215
6259
  if (node) for (const channel of channels) delete node[channel];
6216
6260
  }
@@ -6219,16 +6263,31 @@ function materializeRestPosesInTree(root, engine) {
6219
6263
  }
6220
6264
  function mayCarryRestPose(node, channel) {
6221
6265
  if (node[channel] !== void 0) return false;
6222
- if (PX_TRANSFORM_FN_NAMES.has(channel)) return false;
6223
- if (channel === TRANSFORM_CHANNEL) {
6224
- for (const part of PX_TRANSFORM_FN_NAMES) if (node[part] !== void 0) return false;
6225
- }
6266
+ if (channel === TRANSFORM_CHANNEL) return mayCarryTransformRestPose(node);
6267
+ return true;
6268
+ }
6269
+ function mayCarryTransformRestPose(node) {
6270
+ if (node[TRANSFORM_CHANNEL] !== void 0) return false;
6271
+ for (const part of PX_TRANSFORM_FN_NAMES) if (node[part] !== void 0) return false;
6226
6272
  return true;
6227
6273
  }
6228
6274
  function firstFrameValue(animate, channel, timeMs) {
6229
6275
  const values = Object.values(calcAnimationValues({ [channel]: animate[channel] }, timeMs));
6230
6276
  return values.length === 1 && values[0] !== "" ? values[0] : void 0;
6231
6277
  }
6278
+ function firstFrameTransformParts(animate, timeMs) {
6279
+ const family = {};
6280
+ for (const channel of Object.keys(animate)) if (PX_TRANSFORM_FN_NAMES.has(channel)) family[channel] = animate[channel];
6281
+ const written = calcAnimationValues(family, timeMs)[TRANSFORM_CHANNEL];
6282
+ if (!written) return void 0;
6283
+ const parts = parseTransformParts(written.replace(/(px|deg)\b/g, ""));
6284
+ return parts && Object.keys(parts).length ? parts : void 0;
6285
+ }
6286
+ function writesTheSameFrames(a, b, durationMs) {
6287
+ if (!a || !b) return a === b;
6288
+ const frame = (animate, t) => JSON.stringify(calcAnimationValues(animate, t)).replace(/\s+/g, "");
6289
+ return VERIFY_SAMPLE_FRACTIONS.every((fraction) => frame(a, fraction * durationMs) === frame(b, fraction * durationMs));
6290
+ }
6232
6291
  function bindingsOf(tree, engine) {
6233
6292
  const scratch = deepClone(tree);
6234
6293
  const keyById = /* @__PURE__ */ new Map();
@@ -6445,6 +6504,8 @@ export {
6445
6504
  isNativeForced,
6446
6505
  mayUseNativeScrollTimeline,
6447
6506
  PX_TRIGGER_DEFAULTS,
6507
+ PX_DEFAULT_DURATION_MS,
6508
+ PX_DEFAULT_ITERATIONS,
6448
6509
  PxControlMode,
6449
6510
  resolveControlMode,
6450
6511
  controlModeTakesOverTrigger,
@@ -6484,6 +6545,7 @@ export {
6484
6545
  PxScrollRangePointSchema,
6485
6546
  PxScrollRangeSchema,
6486
6547
  PxScrollSchema,
6548
+ PxTimeTimelineSchema,
6487
6549
  PxTimelineSchema,
6488
6550
  PxAnimatorConfigSchema,
6489
6551
  PxAttrValueSchema,
@@ -6521,7 +6583,6 @@ export {
6521
6583
  PX_PCT_BASED_ATTR_NAMES,
6522
6584
  composeTransformParts,
6523
6585
  PX_STYLE_ATTR_NAMES,
6524
- PX_DEFAULT_DURATION_MS,
6525
6586
  kebabToCamelCaseWord,
6526
6587
  camelCaseToKebabWordIfNeeded,
6527
6588
  clamp,
@@ -6549,4 +6610,4 @@ export {
6549
6610
  diagnoseDocument,
6550
6611
  reportDocumentDiagnostics
6551
6612
  };
6552
- //# sourceMappingURL=chunk-YVKMPBHE.js.map
6613
+ //# sourceMappingURL=chunk-37OFJ3RX.js.map