@pixodesk/svg-animator-react 1.0.22 → 1.0.24

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.umd.js CHANGED
@@ -1936,8 +1936,9 @@ var PixodeskAnimatorReact = (() => {
1936
1936
  }
1937
1937
  isValid(raw, ctx, path) {
1938
1938
  var _a;
1939
- if (this.schemas.some((s) => s.isValid(raw))) return true;
1940
- ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a = JSON.stringify(raw)) != null ? _a : "").slice(0, 60));
1939
+ const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
1940
+ if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
1941
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a = JSON.stringify(raw)) != null ? _a : "").slice(0, 240));
1941
1942
  return false;
1942
1943
  }
1943
1944
  _canSanitize(raw) {
@@ -2013,6 +2014,7 @@ var PixodeskAnimatorReact = (() => {
2013
2014
  if (ctx == null ? void 0 : ctx.strict) {
2014
2015
  for (const key of Object.keys(obj)) {
2015
2016
  if (key in this._shape) continue;
2017
+ if (obj[key] === void 0) continue;
2016
2018
  p.push(key);
2017
2019
  ctx.errors.push(pathStr(p) + ": unexpected extra key");
2018
2020
  p.pop();
@@ -2153,6 +2155,23 @@ var PixodeskAnimatorReact = (() => {
2153
2155
  return true;
2154
2156
  }
2155
2157
  };
2158
+ var Defined = class extends Base {
2159
+ constructor() {
2160
+ super(...arguments);
2161
+ this._default = void 0;
2162
+ }
2163
+ sanitize(raw) {
2164
+ return raw;
2165
+ }
2166
+ isValid(raw, ctx, path) {
2167
+ if (raw !== void 0) return true;
2168
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": required value is missing");
2169
+ return false;
2170
+ }
2171
+ _canSanitize(raw) {
2172
+ return raw !== void 0;
2173
+ }
2174
+ };
2156
2175
  var Lazy = class extends Base {
2157
2176
  constructor(fn, _default) {
2158
2177
  super();
@@ -2250,6 +2269,8 @@ var PixodeskAnimatorReact = (() => {
2250
2269
  record: (value) => new Rec(value),
2251
2270
  /** Passes anything through unchanged — always valid. */
2252
2271
  any: () => new Any(),
2272
+ /** Anything EXCEPT `undefined` — an open type whose presence is required (V6). */
2273
+ defined: () => new Defined(),
2253
2274
  /** Fixed-length tuple — validates element count and each position individually. */
2254
2275
  tuple: (schemas) => new Tuple(schemas),
2255
2276
  /** Defers schema creation — required for recursive types. Must supply a default value. */
@@ -2259,13 +2280,52 @@ var PixodeskAnimatorReact = (() => {
2259
2280
  var PX_ANIM_ATTR_NAME = "_px_animator";
2260
2281
  var PxAnimatorMode = {
2261
2282
  auto: "auto",
2262
- webapi: "webapi",
2283
+ waapi: "waapi",
2263
2284
  frames: "frames"
2264
2285
  };
2265
2286
  var PxAnimatorEngine = {
2266
- webapi: PxAnimatorMode.webapi,
2287
+ waapi: PxAnimatorMode.waapi,
2267
2288
  frames: PxAnimatorMode.frames
2268
2289
  };
2290
+ var PxLoopExtend = {
2291
+ /** Segment from the START; the animation is extended BEFORE the first keyframe
2292
+ * (intro loops that run before the main timeline begins). */
2293
+ before: "before",
2294
+ /** DEFAULT — segment from the END; extended AFTER the last keyframe (idle/outro
2295
+ * loops that continue once the main timeline has finished). */
2296
+ after: "after"
2297
+ };
2298
+ var PxMaskType = {
2299
+ luminance: "luminance",
2300
+ alpha: "alpha"
2301
+ };
2302
+ var PxUnits = {
2303
+ userSpaceOnUse: "userSpaceOnUse",
2304
+ objectBoundingBox: "objectBoundingBox"
2305
+ };
2306
+ var PxCloneType = {
2307
+ content: "content"
2308
+ };
2309
+ var PxPathOverflow = {
2310
+ clip: "clip",
2311
+ extend: "extend"
2312
+ };
2313
+ var PxLengthAdjust = {
2314
+ spacing: "spacing",
2315
+ spacingAndGlyphs: "spacingAndGlyphs"
2316
+ };
2317
+ var PxTextPathMethod = {
2318
+ align: "align",
2319
+ stretch: "stretch"
2320
+ };
2321
+ var PxTextPathSpacing = {
2322
+ auto: "auto",
2323
+ exact: "exact"
2324
+ };
2325
+ var PxTrimSubPaths = {
2326
+ separate: "separate",
2327
+ combined: "combined"
2328
+ };
2269
2329
  var TEXT_ATTR = "text";
2270
2330
  var TEXT_CONTENT_ATTR = "textContent";
2271
2331
  var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
@@ -2274,9 +2334,45 @@ var PixodeskAnimatorReact = (() => {
2274
2334
  "animator",
2275
2335
  "meta",
2276
2336
  "animate",
2337
+ "effects",
2277
2338
  TEXT_ATTR,
2278
2339
  TEXT_CONTENT_ATTR
2279
2340
  ]);
2341
+ var PxGradientUnits = {
2342
+ userSpaceOnUse: "userSpaceOnUse",
2343
+ objectBoundingBox: "objectBoundingBox"
2344
+ };
2345
+ var PxGradientSpreadMethod = {
2346
+ pad: "pad",
2347
+ reflect: "reflect",
2348
+ repeat: "repeat"
2349
+ };
2350
+ var PxGradientType = {
2351
+ linear: "linear",
2352
+ radial: "radial"
2353
+ };
2354
+ function isPxElementFileFormat(fileJson) {
2355
+ if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
2356
+ return false;
2357
+ }
2358
+ return fileJson["type"] === "svg";
2359
+ }
2360
+ function getAnimatorConfig(doc) {
2361
+ var _a;
2362
+ return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
2363
+ }
2364
+ function getDefs(doc) {
2365
+ var _a;
2366
+ if (!doc) return void 0;
2367
+ return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
2368
+ }
2369
+ function getBindings(doc) {
2370
+ var _a;
2371
+ if (!doc) return void 0;
2372
+ const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
2373
+ if (!animateById) return void 0;
2374
+ return Object.entries(animateById).map(([id, anim]) => ({ id, animate: anim }));
2375
+ }
2280
2376
  var PxEasingOrRefSchema = px.union([
2281
2377
  px.string(),
2282
2378
  px.tuple([px.number(), px.number(), px.number(), px.number()])
@@ -2288,13 +2384,15 @@ var PixodeskAnimatorReact = (() => {
2288
2384
  px.array(px.number()),
2289
2385
  px.lazy(() => PxTransformPartsSchema, {}),
2290
2386
  px.object({ path: px.string() }),
2291
- px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] })
2387
+ px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),
2388
+ // Gradient `stops` timeline — each kf value is the full stops-array snapshot.
2389
+ px.lazy(() => px.array(PxGradientStopSchema), [])
2292
2390
  ]));
2293
2391
  var PxKeyframeSchema = implementsInterface()(px.object({
2294
2392
  time: px.number().optional(),
2295
2393
  t: px.number().optional(),
2296
- value: px.any().optional(),
2297
- v: px.any().optional(),
2394
+ value: PxKeyframeValueSchema.optional(),
2395
+ v: PxKeyframeValueSchema.optional(),
2298
2396
  easing: PxEasingOrRefSchema.optional(),
2299
2397
  e: PxEasingOrRefSchema.optional(),
2300
2398
  tangentOut: px.tuple([px.number(), px.number()]).optional(),
@@ -2308,10 +2406,11 @@ var PixodeskAnimatorReact = (() => {
2308
2406
  }));
2309
2407
  var PxLoopSchema = implementsInterface()(px.object({
2310
2408
  segmentCount: px.number().optional(),
2311
- before: px.boolean().optional(),
2409
+ extend: px.enum([PxLoopExtend.before, PxLoopExtend.after]).optional(),
2312
2410
  alternate: px.boolean().optional()
2313
2411
  }));
2314
2412
  var PxPropertyAnimationSchema = implementsInterface()(px.object({
2413
+ value: PxKeyframeValueSchema.optional(),
2315
2414
  keyframes: px.array(PxKeyframeSchema).optional(),
2316
2415
  kfs: px.array(PxKeyframeSchema).optional(),
2317
2416
  loop: px.union([PxLoopSchema, px.boolean()]).optional(),
@@ -2326,6 +2425,7 @@ var PixodeskAnimatorReact = (() => {
2326
2425
  }));
2327
2426
  var PxTransformValueSchema = px.union([
2328
2427
  px.string(),
2428
+ PxTransformPartsSchema,
2329
2429
  px.object({ value: PxTransformPartsSchema }),
2330
2430
  PxPropertyAnimationSchema
2331
2431
  ]);
@@ -2360,9 +2460,11 @@ var PixodeskAnimatorReact = (() => {
2360
2460
  glyphs: px.record(PxGlyphFontSchema).optional()
2361
2461
  }));
2362
2462
  var PxAnimatorConfigSchema = implementsInterface()(px.object({
2363
- mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
2463
+ mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.waapi, PxAnimatorMode.frames]).optional(),
2364
2464
  duration: px.number().optional(),
2365
2465
  delay: px.number().optional(),
2466
+ // LAW (SCHEMA-DESIGN R3, S10): the ONE sanctioned string-in-number union
2467
+ // (CSS animation-iteration-count familiarity) — do not add more mixed unions.
2366
2468
  iterations: px.union([px.number(), px.literal("infinite")]).optional(),
2367
2469
  fill: px.enum(["forwards", "backwards", "both", "none"]).optional(),
2368
2470
  direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional(),
@@ -2370,9 +2472,8 @@ var PixodeskAnimatorReact = (() => {
2370
2472
  trigger: PxTriggerSchema.optional(),
2371
2473
  resetOnFinish: px.boolean().optional(),
2372
2474
  definitions: PxDefsSchema.optional(),
2373
- animate: px.record(PxElementAnimationSchema).optional(),
2374
- timeline: px.string().optional(),
2375
- debug: px.boolean().optional(),
2475
+ animateById: px.record(PxElementAnimationSchema).optional(),
2476
+ timelineSource: px.string().optional(),
2376
2477
  debugInstName: px.string().optional()
2377
2478
  }));
2378
2479
  var PxBindingSchema = implementsInterface()(px.object({
@@ -2382,26 +2483,29 @@ var PixodeskAnimatorReact = (() => {
2382
2483
  var PxAttrValueSchema = px.union([
2383
2484
  px.string(),
2384
2485
  px.number(),
2385
- px.object({ value: px.any() }),
2386
- PxPropertyAnimationSchema
2486
+ px.array(px.number()),
2487
+ // Structured static — `{value: …}` (read-accepted transitional spelling, S1).
2488
+ // `defined`, not `any`: the KEY's presence is what identifies this branch (V6).
2489
+ px.object({ value: px.defined() }),
2490
+ // Bare transform parts record — the canonical static `transform` on the wire (T2).
2491
+ PxTransformPartsSchema
2387
2492
  ]);
2388
2493
  var PxAnimatableNumberSchema = px.union([
2389
2494
  px.number(),
2390
2495
  px.object({ value: px.number() }),
2391
- px.object({
2392
- keyframes: px.array(PxKeyframeSchema),
2393
- autoOrient: px.boolean().optional()
2394
- })
2496
+ PxPropertyAnimationSchema
2395
2497
  ]);
2396
2498
  var PxAnimatableVec2Schema = px.union([
2397
2499
  px.tuple([px.number(), px.number()]),
2398
2500
  px.object({ value: px.tuple([px.number(), px.number()]) }),
2399
- px.object({
2400
- keyframes: px.array(PxKeyframeSchema),
2401
- autoOrient: px.boolean().optional()
2402
- })
2501
+ PxPropertyAnimationSchema
2403
2502
  ]);
2404
- var PxTransformationEffectSchema = implementsInterface()(px.object({
2503
+ var PxAnimatableStringSchema = px.union([
2504
+ px.string(),
2505
+ px.object({ value: px.string() }),
2506
+ PxPropertyAnimationSchema
2507
+ ]);
2508
+ var PxTransformByEffectSchema = implementsInterface()(px.object({
2405
2509
  translate: PxAnimatableVec2Schema.optional(),
2406
2510
  rotate: PxAnimatableNumberSchema.optional(),
2407
2511
  scale: PxAnimatableVec2Schema.optional(),
@@ -2409,42 +2513,46 @@ var PixodeskAnimatorReact = (() => {
2409
2513
  origin: PxAnimatableVec2Schema.optional()
2410
2514
  }));
2411
2515
  var PxRepeaterEffectSchema = implementsInterface()(px.object({
2516
+ // STATIC config, not a channel (V2/SCHEMA-DESIGN R5): the copy COUNT is read
2517
+ // once at expansion time and never sampled — plain number, no `keyframes`.
2412
2518
  copies: px.number().optional(),
2413
2519
  translate: PxAnimatableVec2Schema.optional(),
2414
2520
  rotate: PxAnimatableNumberSchema.optional(),
2521
+ skew: PxAnimatableNumberSchema.optional(),
2415
2522
  scale: PxAnimatableVec2Schema.optional(),
2416
2523
  origin: PxAnimatableVec2Schema.optional()
2417
2524
  }));
2418
2525
  var PxMaskedByEffectSchema = implementsInterface()(px.object({
2419
- href: px.string().optional(),
2420
- maskType: px.string().optional(),
2421
- maskUnits: px.string().optional(),
2422
- maskContentUnits: px.string().optional()
2526
+ sourceId: px.string().optional(),
2527
+ maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
2528
+ maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
2529
+ maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
2530
+ x: px.number().optional(),
2531
+ y: px.number().optional(),
2532
+ width: px.number().optional(),
2533
+ height: px.number().optional()
2423
2534
  }));
2424
2535
  var PxClipPathEffectSchema = implementsInterface()(px.object({
2425
- d: px.string().optional(),
2536
+ d: PxAnimatableStringSchema.optional(),
2426
2537
  animate: PxPropertyAnimationSchema.optional()
2427
2538
  }));
2428
2539
  var PxTrimPathEffectSchema = implementsInterface()(px.object({
2429
2540
  offset: PxAnimatableNumberSchema.optional(),
2430
2541
  range: PxAnimatableVec2Schema.optional(),
2431
- trimAllAsOne: px.boolean().optional()
2542
+ subPaths: px.enum([PxTrimSubPaths.separate, PxTrimSubPaths.combined]).optional()
2432
2543
  }));
2433
2544
  var PxRetimeEffectSchema = implementsInterface()(px.object({
2434
- baseId: px.string().optional(),
2545
+ sourceId: px.string().optional(),
2435
2546
  start: px.number().optional(),
2436
2547
  stretch: px.number().optional(),
2437
2548
  timeCrop: px.tuple([px.number(), px.number()]).optional()
2438
2549
  }));
2439
2550
  var PxCloneEffectSchema = implementsInterface()(px.object({
2440
- type: px.string().optional(),
2441
- baseId: px.string().optional(),
2551
+ // Contextual kind — the `type` convention, see `PxNodeBase.type`.
2552
+ type: px.enum([PxCloneType.content]).optional(),
2553
+ sourceId: px.string().optional(),
2442
2554
  retime: PxRetimeEffectSchema.optional()
2443
2555
  }));
2444
- var PxGradientType = {
2445
- linear: "linear",
2446
- radial: "radial"
2447
- };
2448
2556
  var PxGradientStopSchema = implementsInterface()(px.object({
2449
2557
  offset: px.number(),
2450
2558
  color: px.string()
@@ -2452,39 +2560,28 @@ var PixodeskAnimatorReact = (() => {
2452
2560
  var PxAnimatableGradientStopsSchema = px.union([
2453
2561
  px.array(PxGradientStopSchema),
2454
2562
  px.object({ value: px.array(PxGradientStopSchema) }),
2455
- px.object({ keyframes: px.array(PxKeyframeSchema) })
2563
+ PxPropertyAnimationSchema
2456
2564
  ]);
2457
- var PxGradientGeometryAnimationSchema = implementsInterface()(px.object({
2458
- gradientX1: PxPropertyAnimationSchema.optional(),
2459
- gradientY1: PxPropertyAnimationSchema.optional(),
2460
- gradientX2: PxPropertyAnimationSchema.optional(),
2461
- gradientY2: PxPropertyAnimationSchema.optional(),
2462
- gradientCx: PxPropertyAnimationSchema.optional(),
2463
- gradientCy: PxPropertyAnimationSchema.optional(),
2464
- gradientFx: PxPropertyAnimationSchema.optional(),
2465
- gradientFy: PxPropertyAnimationSchema.optional(),
2466
- gradientR: PxPropertyAnimationSchema.optional()
2467
- }));
2468
2565
  var PxFillGradientEffectSchema = implementsInterface()(px.object({
2566
+ // Contextual kind — the `type` convention, see `PxNodeBase.type`.
2469
2567
  type: px.enum([PxGradientType.linear, PxGradientType.radial]),
2470
- p1: px.tuple([px.number(), px.number()]).optional(),
2471
- p2: px.tuple([px.number(), px.number()]).optional(),
2472
- c: px.tuple([px.number(), px.number()]).optional(),
2473
- r: px.number().optional(),
2474
- fp: px.tuple([px.number(), px.number()]).optional(),
2568
+ p1: PxAnimatableVec2Schema.optional(),
2569
+ p2: PxAnimatableVec2Schema.optional(),
2570
+ c: PxAnimatableVec2Schema.optional(),
2571
+ r: PxAnimatableNumberSchema.optional(),
2572
+ fp: PxAnimatableVec2Schema.optional(),
2475
2573
  stops: PxAnimatableGradientStopsSchema.optional(),
2476
- gradientUnits: px.string().optional(),
2477
- spreadMethod: px.string().optional(),
2478
- gradientTransform: px.string().optional(),
2479
- animate: PxGradientGeometryAnimationSchema.optional()
2574
+ gradientUnits: px.enum([PxGradientUnits.userSpaceOnUse, PxGradientUnits.objectBoundingBox]).optional(),
2575
+ spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
2576
+ gradientTransform: px.string().optional()
2480
2577
  }));
2481
2578
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
2482
2579
  var PxTextPathEffectSchema = implementsInterface()(px.object({
2483
2580
  path: px.string(),
2484
- pathOverflow: px.string().optional(),
2485
- lengthAdjust: px.string().optional(),
2486
- method: px.string().optional(),
2487
- spacing: px.string().optional(),
2581
+ pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
2582
+ lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
2583
+ method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
2584
+ spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact]).optional(),
2488
2585
  startOffset: PxAnimatableNumberSchema.optional(),
2489
2586
  textLength: PxAnimatableNumberSchema.optional()
2490
2587
  }));
@@ -2492,13 +2589,12 @@ var PixodeskAnimatorReact = (() => {
2492
2589
  useGlyphs: px.boolean().optional()
2493
2590
  }));
2494
2591
  var PxEffectsSchema = implementsInterface()(px.object({
2495
- transformation: PxTransformationEffectSchema.optional(),
2592
+ transformBy: PxTransformByEffectSchema.optional(),
2496
2593
  repeater: PxRepeaterEffectSchema.optional(),
2497
2594
  maskedBy: PxMaskedByEffectSchema.optional(),
2498
2595
  clipPath: PxClipPathEffectSchema.optional(),
2499
2596
  trimPath: PxTrimPathEffectSchema.optional(),
2500
2597
  clone: PxCloneEffectSchema.optional(),
2501
- isCombinedShape: px.boolean().optional(),
2502
2598
  fillGradient: PxFillGradientEffectSchema.optional(),
2503
2599
  strokeGradient: PxStrokeGradientEffectSchema.optional(),
2504
2600
  textPath: PxTextPathEffectSchema.optional(),
@@ -2522,6 +2618,14 @@ var PixodeskAnimatorReact = (() => {
2522
2618
  return warnings;
2523
2619
  }
2524
2620
  var PxNodeBase = px.openObject({
2621
+ // CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
2622
+ // kind of thing is this", discriminated by its CARRIER — here the node TAG
2623
+ // (`rect`, `text`), and inside a sub-object that object's kind (`clone.type`,
2624
+ // `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
2625
+ // the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
2626
+ // would add words that all mean "type" and still need the carrier to read.
2627
+ // Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
2628
+ // (issues V3), never of distinct key names.
2525
2629
  type: px.string(),
2526
2630
  id: px.string().optional(),
2527
2631
  meta: px.any().optional(),
@@ -2531,7 +2635,7 @@ var PixodeskAnimatorReact = (() => {
2531
2635
  effects: PxEffectsSchema.optional(),
2532
2636
  // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
2533
2637
  // string ref / array of refs / inline definition / mixed array; mirrors
2534
- // `animator.animate` map values and what `processNode` resolves at runtime.
2638
+ // `animator.animateById` map values and what `processNode` resolves at runtime.
2535
2639
  animate: PxElementAnimationSchema.optional(),
2536
2640
  style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional()
2537
2641
  }, PxAttrValueSchema);
@@ -2555,28 +2659,6 @@ var PixodeskAnimatorReact = (() => {
2555
2659
  o: px.array(px.array(px.number())).optional(),
2556
2660
  c: px.boolean().optional()
2557
2661
  }));
2558
- function isPxElementFileFormat(fileJson) {
2559
- if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
2560
- return false;
2561
- }
2562
- return fileJson["type"] === "svg" || fileJson["tagName"] === "svg";
2563
- }
2564
- function getAnimatorConfig(doc) {
2565
- var _a, _b;
2566
- return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator) || (doc == null ? void 0 : doc.animation) || ((_b = doc == null ? void 0 : doc.meta) == null ? void 0 : _b.animation);
2567
- }
2568
- function getDefs(doc) {
2569
- var _a;
2570
- if (!doc) return void 0;
2571
- return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
2572
- }
2573
- function getBindings(doc) {
2574
- var _a;
2575
- if (!doc) return void 0;
2576
- const animate = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animate;
2577
- if (!animate) return void 0;
2578
- return Object.entries(animate).map(([id, anim]) => ({ id, animate: anim }));
2579
- }
2580
2662
  function bezierToSvgPath(path, forceCurves = false) {
2581
2663
  var _a, _b, _c, _d;
2582
2664
  const v = path.v;
@@ -3027,7 +3109,7 @@ var PixodeskAnimatorReact = (() => {
3027
3109
  "flood-color",
3028
3110
  "lighting-color"
3029
3111
  ]);
3030
- const directIdRefAttrs = /* @__PURE__ */ new Set(["baseId", "targetId", "boundElementId"]);
3112
+ const directIdRefAttrs = /* @__PURE__ */ new Set(["sourceId", "targetId", "boundElementId"]);
3031
3113
  function collectIds(node) {
3032
3114
  if (!node || typeof node !== "object") return;
3033
3115
  if (node.id && typeof node.id === "string") {
@@ -3065,9 +3147,10 @@ var PixodeskAnimatorReact = (() => {
3065
3147
  } else if (urlRefAttrs.has(key)) {
3066
3148
  node[key] = replaceUrlRefs(value, idMap);
3067
3149
  } else if (directIdRefAttrs.has(key)) {
3068
- const newId = idMap.get(value);
3150
+ const hasHash = value.startsWith("#");
3151
+ const newId = idMap.get(hasHash ? value.slice(1) : value);
3069
3152
  if (newId) {
3070
- node[key] = newId;
3153
+ node[key] = hasHash ? "#" + newId : newId;
3071
3154
  }
3072
3155
  } else if (value.includes("url(#")) {
3073
3156
  node[key] = replaceUrlRefs(value, idMap);
@@ -3085,14 +3168,14 @@ var PixodeskAnimatorReact = (() => {
3085
3168
  }
3086
3169
  collectIds(cloned);
3087
3170
  updateRefs(cloned);
3088
- const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animate;
3171
+ const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animateById;
3089
3172
  if (docAnimate && typeof docAnimate === "object") {
3090
3173
  const updatedAnimate = {};
3091
3174
  for (const [id, anim] of Object.entries(docAnimate)) {
3092
3175
  const newId = (_b = idMap.get(id)) != null ? _b : id;
3093
3176
  updatedAnimate[newId] = anim;
3094
3177
  }
3095
- cloned.animator = __spreadProps2(__spreadValues2({}, cloned.animator), { animate: updatedAnimate });
3178
+ cloned.animator = __spreadProps2(__spreadValues2({}, cloned.animator), { animateById: updatedAnimate });
3096
3179
  }
3097
3180
  return cloned;
3098
3181
  }
@@ -3181,8 +3264,9 @@ var PixodeskAnimatorReact = (() => {
3181
3264
  let value = props[rawKey];
3182
3265
  if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
3183
3266
  propsCopy[key] = toRGBA(value);
3184
- } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && value.value && typeof value.value === "object") {
3185
- propsCopy["transform"] = composeTransformParts(value.value, { withUnits: false });
3267
+ } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes && !value.kfs) {
3268
+ const parts = value.value && typeof value.value === "object" ? value.value : value;
3269
+ propsCopy["transform"] = composeTransformParts(parts, { withUnits: false });
3186
3270
  } else if (TRANSFORM_FN_NAMES.has(key)) {
3187
3271
  if (Array.isArray(value)) {
3188
3272
  if (key === "translate") value = value.map((v) => v + "px");
@@ -3190,6 +3274,8 @@ var PixodeskAnimatorReact = (() => {
3190
3274
  }
3191
3275
  if (key === "rotate") value = value + "deg";
3192
3276
  propsCopy["transform"] = key + "(" + value + ")";
3277
+ } else if (Array.isArray(value)) {
3278
+ propsCopy[key] = value.join(",");
3193
3279
  } else if (value !== void 0 && value !== null) {
3194
3280
  propsCopy[key] = String(value);
3195
3281
  }
@@ -3587,6 +3673,16 @@ var PixodeskAnimatorReact = (() => {
3587
3673
  if (newAnimate) cloned.animate = newAnimate;
3588
3674
  return cloned;
3589
3675
  }
3676
+ var LOOP_JUMP_SHIFT_MS = 10;
3677
+ function deepEqualValue(a, b) {
3678
+ if (a === b) return true;
3679
+ if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") return false;
3680
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
3681
+ const ka = Object.keys(a);
3682
+ const kb = Object.keys(b);
3683
+ if (ka.length !== kb.length) return false;
3684
+ return ka.every((k) => deepEqualValue(a[k], b[k]));
3685
+ }
3590
3686
  function parsePathCommands(d) {
3591
3687
  const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
3592
3688
  const commands = [];
@@ -3789,7 +3885,7 @@ var PixodeskAnimatorReact = (() => {
3789
3885
  const totalIntervals = keyframes.length - 1;
3790
3886
  const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
3791
3887
  let segKfs;
3792
- if (loop.before) {
3888
+ if (loop.extend === PxLoopExtend.before) {
3793
3889
  segKfs = keyframes.slice(0, segCount + 1);
3794
3890
  } else {
3795
3891
  segKfs = keyframes.slice(totalIntervals - segCount);
@@ -3797,7 +3893,7 @@ var PixodeskAnimatorReact = (() => {
3797
3893
  const firstT = (_b = keyframes[0].t) != null ? _b : 0;
3798
3894
  const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
3799
3895
  let fillStart, fillEnd;
3800
- if (loop.before) {
3896
+ if (loop.extend === PxLoopExtend.before) {
3801
3897
  fillStart = 0;
3802
3898
  fillEnd = firstT;
3803
3899
  } else {
@@ -3824,7 +3920,10 @@ var PixodeskAnimatorReact = (() => {
3824
3920
  const remainder = fillDuration - fullReps * segDuration;
3825
3921
  const partialFraction = remainder / segDuration;
3826
3922
  const looped = [];
3923
+ const separateBoundary = loop.extend !== PxLoopExtend.before;
3924
+ const originalTerminalKf = keyframes[keyframes.length - 1];
3827
3925
  function appendRep(repStart, isReversed, partial) {
3926
+ var _a2;
3828
3927
  let entries;
3829
3928
  if (isReversed) {
3830
3929
  entries = [];
@@ -3860,8 +3959,17 @@ var PixodeskAnimatorReact = (() => {
3860
3959
  looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
3861
3960
  return;
3862
3961
  }
3962
+ const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
3963
+ const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
3964
+ if (isBoundary) {
3965
+ if (deepEqualValue(prevKf.v, entry.v)) continue;
3966
+ if (looped.length > 0) {
3967
+ delete prevKf.tangentIn;
3968
+ delete prevKf.tangentOut;
3969
+ }
3970
+ }
3863
3971
  const pushed = {
3864
- t: repStart + entry.relT * segDuration,
3972
+ t: repStart + entry.relT * segDuration + (isBoundary ? LOOP_JUMP_SHIFT_MS : 0),
3865
3973
  v: entry.v,
3866
3974
  e: i < entries.length - 1 ? entry.e : void 0
3867
3975
  };
@@ -3909,7 +4017,7 @@ var PixodeskAnimatorReact = (() => {
3909
4017
  looped.push(pushed);
3910
4018
  }
3911
4019
  }
3912
- if (loop.before) {
4020
+ if (loop.extend === PxLoopExtend.before) {
3913
4021
  if (partialFraction > 1e-9) {
3914
4022
  const isReversed = !!loop.alternate && fullReps % 2 === 0;
3915
4023
  appendRepTail(fillStart, isReversed, partialFraction);
@@ -3932,7 +4040,7 @@ var PixodeskAnimatorReact = (() => {
3932
4040
  appendRep(repStart, isReversed, partialFraction);
3933
4041
  }
3934
4042
  }
3935
- if (loop.before) {
4043
+ if (loop.extend === PxLoopExtend.before) {
3936
4044
  return [...looped, ...keyframes];
3937
4045
  } else {
3938
4046
  return [...keyframes, ...looped];
@@ -4048,7 +4156,7 @@ var PixodeskAnimatorReact = (() => {
4048
4156
  function generateElementId() {
4049
4157
  return "_px_el_" + ++_elementIdCounter;
4050
4158
  }
4051
- function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.webapi) {
4159
+ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
4052
4160
  const normalized = {};
4053
4161
  for (const [propName, propAnim] of Object.entries(animDef)) {
4054
4162
  const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
@@ -4056,12 +4164,12 @@ var PixodeskAnimatorReact = (() => {
4056
4164
  const out = { kfs: normalizedKfs };
4057
4165
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
4058
4166
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
4059
- normalized[propName] = engine === PxAnimatorEngine.webapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
4167
+ normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
4060
4168
  }
4061
4169
  }
4062
4170
  return normalized;
4063
4171
  }
4064
- function getNormalisedBindings(doc, engine = PxAnimatorEngine.webapi) {
4172
+ function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
4065
4173
  const animatorConfig = getAnimatorConfig(doc) || {};
4066
4174
  const defs = getDefs(doc);
4067
4175
  const duration = animatorConfig.duration || 1e3;
@@ -4466,7 +4574,7 @@ var PixodeskAnimatorReact = (() => {
4466
4574
  return rec;
4467
4575
  }
4468
4576
  function readAnimatable(raw) {
4469
- var _a, _b;
4577
+ var _a, _b, _c;
4470
4578
  if (raw === void 0) return {
4471
4579
  kind: "absent"
4472
4580
  /* Absent */
@@ -4476,13 +4584,34 @@ var PixodeskAnimatorReact = (() => {
4476
4584
  const obj = raw;
4477
4585
  const kfs = (_a = obj.keyframes) != null ? _a : obj.kfs;
4478
4586
  if (kfs) {
4479
- return { kind: "animated", keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
4587
+ const out = { kind: "animated", keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
4588
+ const base = (_b = obj.value) != null ? _b : obj.v;
4589
+ if (base !== void 0 && out.kind === "animated") out.base = base;
4590
+ return out;
4480
4591
  }
4481
- const staticValue = (_b = obj.value) != null ? _b : obj.v;
4592
+ const staticValue = (_c = obj.value) != null ? _c : obj.v;
4482
4593
  if (staticValue !== void 0) return { kind: "static", value: staticValue };
4483
4594
  }
4484
4595
  return { kind: "static", value: raw };
4485
4596
  }
4597
+ function writeAnimatableChannel(node, attrName, read, opts) {
4598
+ var _a, _b, _c, _d;
4599
+ const toOut = (v) => (opts == null ? void 0 : opts.asString) && v !== void 0 && v !== null ? String(v) : v;
4600
+ if (read.kind === "absent") return;
4601
+ if (read.kind === "static") {
4602
+ node[attrName] = toOut(read.value);
4603
+ return;
4604
+ }
4605
+ const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
4606
+ const animate = __spreadValues2({}, prevAnimate || {});
4607
+ const block = { keyframes: read.keyframes };
4608
+ if (read.loop !== void 0) block.loop = read.loop;
4609
+ if (read.autoOrient !== void 0) block.autoOrient = read.autoOrient;
4610
+ animate[attrName] = block;
4611
+ node.animate = animate;
4612
+ const baseline = (_d = (_b = read.base) != null ? _b : (_a = read.keyframes[0]) == null ? void 0 : _a.value) != null ? _d : (_c = read.keyframes[0]) == null ? void 0 : _c.v;
4613
+ if (baseline !== void 0) node[attrName] = toOut(baseline);
4614
+ }
4486
4615
  function normaliseKeyframe(kf) {
4487
4616
  if (!kf || typeof kf !== "object") return kf;
4488
4617
  const k = kf;
@@ -4502,7 +4631,7 @@ var PixodeskAnimatorReact = (() => {
4502
4631
  const o = readAnimatable(raw);
4503
4632
  if (o.kind === "absent") return void 0;
4504
4633
  if (o.kind === "static") return o.value;
4505
- ctx.warnings.push("transformation.origin: animated origin approximated by its first keyframe");
4634
+ ctx.warnings.push("transformBy.origin: animated origin approximated by its first keyframe");
4506
4635
  return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
4507
4636
  }
4508
4637
  function keyframeWith(kf, value) {
@@ -4513,7 +4642,7 @@ var PixodeskAnimatorReact = (() => {
4513
4642
  if (kf.tangentIn !== void 0) out.tangentIn = kf.tangentIn;
4514
4643
  return out;
4515
4644
  }
4516
- function applyTransformationEffect(node, fx, ctx) {
4645
+ function applyTransformByEffect(node, fx, ctx) {
4517
4646
  if (!fx) return node;
4518
4647
  delete node.transform;
4519
4648
  let n = node;
@@ -4549,6 +4678,10 @@ var PixodeskAnimatorReact = (() => {
4549
4678
  } else {
4550
4679
  n = wrapTransformPart(n, "translate", fx.translate, ctx);
4551
4680
  }
4681
+ if (n !== node && node.id) {
4682
+ n.id = node.id;
4683
+ delete node.id;
4684
+ }
4552
4685
  return n;
4553
4686
  }
4554
4687
  function translateHasAutoOrient(translate) {
@@ -4558,8 +4691,6 @@ var PixodeskAnimatorReact = (() => {
4558
4691
  return Array.isArray(obj.keyframes) && obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
4559
4692
  }
4560
4693
  function normalizeScale(raw) {
4561
- if (raw === void 0) return void 0;
4562
- if (Array.isArray(raw)) return [raw[0] / 100, raw[1] / 100];
4563
4694
  return raw;
4564
4695
  }
4565
4696
  function wrapTransformPart(inner, part, raw, ctx) {
@@ -4600,34 +4731,54 @@ var PixodeskAnimatorReact = (() => {
4600
4731
  }
4601
4732
  return inner;
4602
4733
  }
4734
+ function genId(ctx, prefix) {
4735
+ return "_lw_" + prefix + "_" + ctx.nextId++;
4736
+ }
4737
+ function stripHash2(href) {
4738
+ return typeof href === "string" ? href.replace(/^#/, "") : void 0;
4739
+ }
4740
+ function indexById(node, map) {
4741
+ var _a;
4742
+ if (typeof node.id === "string") map.set(node.id, node);
4743
+ (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
4744
+ }
4745
+ function spliceDefs(root, defs) {
4746
+ if (!defs.length) return;
4747
+ const existing = root.children || (root.children = []);
4748
+ existing.unshift({ type: "defs", children: defs });
4749
+ }
4750
+ var clone = deepClonePxNode;
4751
+ function regenerateIdsInClone(root, ctx) {
4752
+ return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
4753
+ }
4603
4754
  function identifyContentRefTargets(node, ctx, allocator) {
4604
4755
  var _a, _b, _c;
4605
4756
  if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.type) === "content") {
4606
- const baseId = node.effects.clone.baseId;
4607
- if (typeof baseId === "string" && baseId && !ctx.contentRefInnerIds.has(baseId)) {
4608
- ctx.contentRefInnerIds.set(baseId, allocator(baseId));
4757
+ const sourceId = stripHash2(node.effects.clone.sourceId);
4758
+ if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
4759
+ ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
4609
4760
  }
4610
4761
  }
4611
4762
  (_c = node.children) == null ? void 0 : _c.forEach((c) => identifyContentRefTargets(c, ctx, allocator));
4612
4763
  }
4613
- function splitForContentRef(node, transformation, originalId, innerId, ctx) {
4614
- const outerBody = liftBodyTranslate(node, transformation);
4764
+ function splitForContentRef(node, transformBy, originalId, innerId, ctx) {
4765
+ const outerBody = liftBodyTranslate(node, transformBy);
4615
4766
  if (typeof node.id === "string") delete node.id;
4616
- const { outer: outerTr, inner: innerTr } = splitTransformationEffect(transformation);
4767
+ const { outer: outerTr, inner: innerTr } = splitTransformByEffect(transformBy);
4617
4768
  let innerNode = node;
4618
- innerNode = applyTransformationEffect(innerNode, innerTr, ctx);
4769
+ innerNode = applyTransformByEffect(innerNode, innerTr, ctx);
4619
4770
  const innerWrapper = { type: "g", id: innerId, children: [innerNode] };
4620
4771
  let outerWrapper = { type: "g", id: originalId, children: [innerWrapper] };
4621
4772
  if (outerBody.transform !== void 0) outerWrapper.transform = outerBody.transform;
4622
4773
  if (outerBody.animate !== void 0) outerWrapper.animate = outerBody.animate;
4623
4774
  if (outerTr) {
4624
4775
  delete outerWrapper.id;
4625
- outerWrapper = applyTransformationEffect(outerWrapper, outerTr, ctx);
4776
+ outerWrapper = applyTransformByEffect(outerWrapper, outerTr, ctx);
4626
4777
  outerWrapper.id = originalId;
4627
4778
  }
4628
4779
  return outerWrapper;
4629
4780
  }
4630
- function liftBodyTranslate(node, transformation) {
4781
+ function liftBodyTranslate(node, transformBy) {
4631
4782
  var _a, _b, _c;
4632
4783
  const out = {};
4633
4784
  let didLiftAnimate = false;
@@ -4681,7 +4832,7 @@ var PixodeskAnimatorReact = (() => {
4681
4832
  didLiftAnimate = true;
4682
4833
  }
4683
4834
  }
4684
- const transformationHasTranslate = (transformation == null ? void 0 : transformation.translate) !== void 0;
4835
+ const transformationHasTranslate = (transformBy == null ? void 0 : transformBy.translate) !== void 0;
4685
4836
  const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;
4686
4837
  const liftedAnimateIsAutoOriented = didLiftAnimate && needsOriginOnOuter(((_b = node.animate) == null ? void 0 : _b.transform) || void 0) || didLiftAnimate && needsOriginOnOuter(((_c = out.animate) == null ? void 0 : _c.transform) || void 0);
4687
4838
  if (typeof node.transform === "string") {
@@ -4700,6 +4851,24 @@ var PixodeskAnimatorReact = (() => {
4700
4851
  if (split.rest) node.transform = split.rest;
4701
4852
  else delete node.transform;
4702
4853
  }
4854
+ } else if (node.transform && typeof node.transform === "object" && !Array.isArray(node.transform) && !node.transform.keyframes && !node.transform.kfs) {
4855
+ const wrapped = node.transform.value;
4856
+ const isWrapped = !!(wrapped && typeof wrapped === "object");
4857
+ const value = isWrapped ? wrapped : node.transform;
4858
+ const rewrap = (rec) => isWrapped ? { value: rec } : rec;
4859
+ if (Array.isArray(value.translate)) {
4860
+ const rest = __spreadValues2({}, value);
4861
+ delete rest.translate;
4862
+ const hasRest = Object.keys(rest).length > 0;
4863
+ if (stripBodyTranslateOnly) {
4864
+ if (hasRest) node.transform = rewrap(rest);
4865
+ else delete node.transform;
4866
+ } else {
4867
+ out.transform = rewrap({ translate: value.translate });
4868
+ if (hasRest) node.transform = rewrap(rest);
4869
+ else delete node.transform;
4870
+ }
4871
+ }
4703
4872
  }
4704
4873
  return out;
4705
4874
  }
@@ -4769,7 +4938,7 @@ var PixodeskAnimatorReact = (() => {
4769
4938
  const nums = m[1].split(/[\s,]+/).filter(Boolean).map(Number);
4770
4939
  return [nums[0] || 0, nums[1] || 0];
4771
4940
  }
4772
- function splitTransformationEffect(fx) {
4941
+ function splitTransformByEffect(fx) {
4773
4942
  if (!fx) return {};
4774
4943
  const originOnOuter = needsOriginOnOuter(fx.translate);
4775
4944
  const innerHasPivotedPart = fx.rotate !== void 0 || fx.scale !== void 0;
@@ -4795,26 +4964,6 @@ var PixodeskAnimatorReact = (() => {
4795
4964
  }
4796
4965
  return false;
4797
4966
  }
4798
- function genId(ctx, prefix) {
4799
- return "_lw_" + prefix + "_" + ctx.nextId++;
4800
- }
4801
- function stripHash2(href) {
4802
- return typeof href === "string" ? href.replace(/^#/, "") : void 0;
4803
- }
4804
- function indexById(node, map) {
4805
- var _a;
4806
- if (typeof node.id === "string") map.set(node.id, node);
4807
- (_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
4808
- }
4809
- function spliceDefs(root, defs) {
4810
- if (!defs.length) return;
4811
- const existing = root.children || (root.children = []);
4812
- existing.unshift({ type: "defs", children: defs });
4813
- }
4814
- var clone = deepClonePxNode;
4815
- function regenerateIdsInClone(root, ctx) {
4816
- return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
4817
- }
4818
4967
  function applyFillGradientEffect(node, fx, ctx) {
4819
4968
  return applyGradient(node, fx, ctx, "fill");
4820
4969
  }
@@ -4835,62 +4984,63 @@ var PixodeskAnimatorReact = (() => {
4835
4984
  id
4836
4985
  };
4837
4986
  if (fx.type === PxGradientType.linear) {
4838
- if (fx.p1) {
4839
- out.x1 = String(fx.p1[0]);
4840
- out.y1 = String(fx.p1[1]);
4841
- }
4842
- if (fx.p2) {
4843
- out.x2 = String(fx.p2[0]);
4844
- out.y2 = String(fx.p2[1]);
4845
- }
4987
+ applyGeomVec(out, "x1", "y1", fx.p1);
4988
+ applyGeomVec(out, "x2", "y2", fx.p2);
4846
4989
  } else {
4847
- if (fx.c) {
4848
- out.cx = String(fx.c[0]);
4849
- out.cy = String(fx.c[1]);
4850
- }
4851
- if (fx.r !== void 0) out.r = String(fx.r);
4852
- if (fx.fp) {
4853
- out.fx = String(fx.fp[0]);
4854
- out.fy = String(fx.fp[1]);
4855
- }
4990
+ applyGeomVec(out, "cx", "cy", fx.c);
4991
+ applyGeomNumber(out, "r", fx.r);
4992
+ applyGeomVec(out, "fx", "fy", fx.fp);
4856
4993
  }
4857
4994
  if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
4858
4995
  if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
4859
4996
  if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;
4860
- const animate = fx.animate;
4861
- if (animate) {
4862
- const mapped = {};
4863
- for (const wireKey of Object.keys(animate)) {
4864
- const attr = GRADIENT_ANIM_CHANNEL_TO_ATTR[wireKey];
4865
- if (attr) mapped[attr] = animate[wireKey];
4866
- }
4867
- if (Object.keys(mapped).length) out.animate = mapped;
4868
- }
4869
4997
  out.children = buildStopChildren(fx.stops, ctx);
4870
4998
  return out;
4871
4999
  }
4872
- var GRADIENT_ANIM_CHANNEL_TO_ATTR = {
4873
- gradientX1: "x1",
4874
- gradientY1: "y1",
4875
- gradientX2: "x2",
4876
- gradientY2: "y2",
4877
- gradientCx: "cx",
4878
- gradientCy: "cy",
4879
- gradientFx: "fx",
4880
- gradientFy: "fy",
4881
- gradientR: "r"
4882
- };
5000
+ function applyGeomVec(out, xAttr, yAttr, raw) {
5001
+ var _a, _b, _c;
5002
+ const read = readAnimatable(raw);
5003
+ if (read.kind === "absent") return;
5004
+ if (read.kind === "static") {
5005
+ out[xAttr] = String(read.value[0]);
5006
+ out[yAttr] = String(read.value[1]);
5007
+ return;
5008
+ }
5009
+ const axisChannel = (idx) => {
5010
+ const block = {
5011
+ keyframes: read.keyframes.map((kf) => {
5012
+ const axisKf = { time: kf.time, value: Array.isArray(kf.value) ? kf.value[idx] : void 0 };
5013
+ if (kf.easing !== void 0) axisKf.easing = kf.easing;
5014
+ return axisKf;
5015
+ })
5016
+ };
5017
+ if (read.loop !== void 0) block.loop = read.loop;
5018
+ return block;
5019
+ };
5020
+ const animate = (_a = out.animate) != null ? _a : {};
5021
+ animate[xAttr] = axisChannel(0);
5022
+ animate[yAttr] = axisChannel(1);
5023
+ out.animate = animate;
5024
+ const baseline = (_c = read.base) != null ? _c : (_b = read.keyframes[0]) == null ? void 0 : _b.value;
5025
+ if (Array.isArray(baseline)) {
5026
+ out[xAttr] = String(baseline[0]);
5027
+ out[yAttr] = String(baseline[1]);
5028
+ }
5029
+ }
5030
+ function applyGeomNumber(out, attrName, raw) {
5031
+ const read = readAnimatable(raw);
5032
+ if (read.kind === "absent") return;
5033
+ writeAnimatableChannel(out, attrName, read, { asString: true });
5034
+ }
4883
5035
  function buildStopChildren(stops, ctx) {
4884
5036
  var _a, _b, _c, _d;
4885
5037
  if (!stops) return [];
4886
- if (Array.isArray(stops)) return stops.map(staticStopNode);
4887
- if (typeof stops === "object" && Array.isArray(stops.value)) {
4888
- return stops.value.map(staticStopNode);
4889
- }
4890
- const animBlock = stops;
4891
- const kfs = animBlock.keyframes;
4892
- if (!Array.isArray(kfs) || !kfs.length) return [];
4893
- const loopFromSource = animBlock.loop;
5038
+ const read = readAnimatable(stops);
5039
+ if (read.kind === "absent") return [];
5040
+ if (read.kind === "static") return Array.isArray(read.value) ? read.value.map(staticStopNode) : [];
5041
+ const kfs = read.keyframes;
5042
+ if (!kfs.length) return [];
5043
+ const loopFromSource = read.loop;
4894
5044
  let stopCount = 0;
4895
5045
  for (const kf of kfs) {
4896
5046
  const v = (_a = kf.value) != null ? _a : kf.v;
@@ -4965,36 +5115,60 @@ var PixodeskAnimatorReact = (() => {
4965
5115
  return pct + "%";
4966
5116
  }
4967
5117
  function applyClipPathEffect(node, fx, ctx) {
5118
+ var _a, _b;
4968
5119
  if (!fx || !fx.d && !fx.animate) return node;
4969
5120
  const clipId = genId(ctx, "clip");
4970
- const pathChild = { type: "path", d: fx.d };
4971
- if (fx.animate) pathChild.animate = { d: fx.animate };
5121
+ const pathChild = { type: "path" };
5122
+ const read = readAnimatable(fx.d);
5123
+ if (read.kind !== "absent") {
5124
+ if (read.kind === "static") {
5125
+ pathChild.d = pathString(read.value);
5126
+ } else {
5127
+ writeAnimatableChannel(pathChild, "d", read);
5128
+ if (pathChild.d !== void 0) pathChild.d = pathString(pathChild.d);
5129
+ }
5130
+ }
5131
+ if (fx.animate && !((_a = pathChild.animate) == null ? void 0 : _a.d)) {
5132
+ const animate = (_b = pathChild.animate) != null ? _b : {};
5133
+ animate.d = fx.animate;
5134
+ pathChild.animate = animate;
5135
+ }
4972
5136
  ctx.defs.push({ type: "clipPath", id: clipId, children: [pathChild] });
4973
5137
  node.clipPath = "url(#" + clipId + ")";
4974
5138
  return node;
4975
5139
  }
4976
- function applyMaskedByEffect(node, fx, transformation, ctx) {
5140
+ function pathString(v) {
5141
+ if (typeof v === "string") return v;
5142
+ if (v && typeof v === "object" && typeof v.path === "string") return v.path;
5143
+ return void 0;
5144
+ }
5145
+ function applyMaskedByEffect(node, fx, transformBy, ctx) {
4977
5146
  if (!fx) return node;
4978
- if (!fx.href) {
4979
- ctx.errors.push("maskedBy.href missing \u2014 cannot build mask");
5147
+ const sourceId = stripHash2(fx.sourceId);
5148
+ if (!sourceId) {
5149
+ ctx.errors.push("maskedBy.sourceId missing \u2014 cannot build mask");
4980
5150
  return node;
4981
5151
  }
4982
5152
  const maskId = genId(ctx, "mask");
4983
- let content = { type: "use", href: "#" + fx.href };
4984
- if (transformation) {
4985
- content = wrapInverseTransform(content, transformation, ctx);
5153
+ let content = { type: "use", href: "#" + sourceId };
5154
+ if (transformBy) {
5155
+ content = wrapInverseTransform(content, transformBy, ctx);
4986
5156
  } else if (hasAnimateTransform(node)) {
4987
5157
  content = wrapInverseAnimatedBodyTransform(content, node, ctx);
4988
5158
  } else {
4989
5159
  const bodyStatic = readTransformationFromBody(node);
4990
5160
  if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);
4991
5161
  }
4992
- const includeTargetOwn = transformation === void 0 && !nodeHasBodyTransform(node);
4993
- content = wrapAncestorChainCompensation(content, node, fx.href, ctx, includeTargetOwn);
5162
+ const includeTargetOwn = transformBy === void 0 && !nodeHasBodyTransform(node);
5163
+ content = wrapAncestorChainCompensation(content, node, sourceId, ctx, includeTargetOwn);
4994
5164
  const mask = { type: "mask", id: maskId, children: [content] };
4995
5165
  if (fx.maskType) mask.maskType = fx.maskType;
4996
5166
  if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
4997
5167
  if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
5168
+ if (fx.x !== void 0) mask.x = String(fx.x);
5169
+ if (fx.y !== void 0) mask.y = String(fx.y);
5170
+ if (fx.width !== void 0) mask.width = String(fx.width);
5171
+ if (fx.height !== void 0) mask.height = String(fx.height);
4998
5172
  ctx.defs.push(mask);
4999
5173
  node.mask = "url(#" + maskId + ")";
5000
5174
  return node;
@@ -5101,6 +5275,19 @@ var PixodeskAnimatorReact = (() => {
5101
5275
  if (parts.origin) out.origin = parts.origin;
5102
5276
  return Object.keys(out).length ? out : void 0;
5103
5277
  }
5278
+ if (node.transform && typeof node.transform === "object" && !node.transform.keyframes && !node.transform.kfs) {
5279
+ const wrapped = node.transform.value;
5280
+ const value = wrapped && typeof wrapped === "object" ? wrapped : node.transform;
5281
+ if (value && typeof value === "object") {
5282
+ const out = {};
5283
+ if (Array.isArray(value.translate)) out.translate = value.translate;
5284
+ if (typeof value.rotate === "number") out.rotate = value.rotate;
5285
+ if (typeof value.skew === "number") out.skew = value.skew;
5286
+ if (Array.isArray(value.scale)) out.scale = { value: value.scale };
5287
+ if (Array.isArray(value.origin)) out.origin = value.origin;
5288
+ return Object.keys(out).length ? out : void 0;
5289
+ }
5290
+ }
5104
5291
  return void 0;
5105
5292
  }
5106
5293
  function parseTransformStringToParts(s) {
@@ -5234,10 +5421,10 @@ var PixodeskAnimatorReact = (() => {
5234
5421
  const interestingNodes = /* @__PURE__ */ new Set();
5235
5422
  const collectInterestingNodes = (n) => {
5236
5423
  var _a, _b;
5237
- const href = (_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.href;
5238
- if (typeof href === "string") {
5424
+ const maskSourceId = stripHash2((_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.sourceId);
5425
+ if (typeof maskSourceId === "string") {
5239
5426
  interestingNodes.add(n);
5240
- const sourceNode = ctx.idMap.get(href);
5427
+ const sourceNode = ctx.idMap.get(maskSourceId);
5241
5428
  if (sourceNode) interestingNodes.add(sourceNode);
5242
5429
  }
5243
5430
  if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);
@@ -5263,8 +5450,9 @@ var PixodeskAnimatorReact = (() => {
5263
5450
  if (typeof tr === "string") {
5264
5451
  const parts = parseTranslateOnlyFromString(tr, ctx);
5265
5452
  if (parts) out.translate = parts;
5266
- } else if (tr && typeof tr === "object") {
5267
- const value = tr.value;
5453
+ } else if (tr && typeof tr === "object" && !tr.keyframes && !tr.kfs) {
5454
+ const wrapped = tr.value;
5455
+ const value = wrapped && typeof wrapped === "object" ? wrapped : tr;
5268
5456
  if (value && typeof value === "object" && Array.isArray(value.translate)) {
5269
5457
  out.translate = [value.translate[0] || 0, value.translate[1] || 0];
5270
5458
  }
@@ -5312,17 +5500,17 @@ var PixodeskAnimatorReact = (() => {
5312
5500
  var CONTENT_SUBREF = "content";
5313
5501
  function applyRefHref(node, clone2, ctx) {
5314
5502
  if (!clone2) return;
5315
- const baseId = clone2.baseId;
5316
- if (!baseId) {
5317
- if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing baseId");
5503
+ const sourceId = stripHash2(clone2.sourceId);
5504
+ if (!sourceId) {
5505
+ if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing sourceId");
5318
5506
  return;
5319
5507
  }
5320
- const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
5508
+ const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
5321
5509
  node.href = "#" + targetId;
5322
5510
  }
5323
- function applyRefAndTransformationEffect(node, clone2, transformation, ctx) {
5511
+ function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
5324
5512
  applyRefHref(node, clone2, ctx);
5325
- return applyTransformationEffect(node, transformation, ctx);
5513
+ return applyTransformByEffect(node, transformBy, ctx);
5326
5514
  }
5327
5515
  function applyRepeaterEffect(node, fx, ctx) {
5328
5516
  var _a, _b;
@@ -5345,7 +5533,7 @@ var PixodeskAnimatorReact = (() => {
5345
5533
  for (let i = 1; i < copies; i++) {
5346
5534
  const baseClone = clone(base);
5347
5535
  const synthFx = synthesisePerCopyFx(fx, i);
5348
- const wrapped = synthFx ? applyTransformationEffect(baseClone, synthFx, ctx) : baseClone;
5536
+ const wrapped = synthFx ? applyTransformByEffect(baseClone, synthFx, ctx) : baseClone;
5349
5537
  children.push(wrapped);
5350
5538
  }
5351
5539
  const wrapper = { type: "g", children };
@@ -5357,10 +5545,13 @@ var PixodeskAnimatorReact = (() => {
5357
5545
  function synthesisePerCopyFx(fx, i) {
5358
5546
  const out = {};
5359
5547
  if (fx.translate !== void 0) {
5360
- out.translate = mapAnimatableVec2(fx.translate, (v) => [v[0] * i, v[1] * i]);
5548
+ out.translate = mapAnimatable(fx.translate, (v) => [v[0] * i, v[1] * i]);
5361
5549
  }
5362
5550
  if (fx.rotate !== void 0) {
5363
- out.rotate = mapAnimatableNumber(fx.rotate, (v) => v * i);
5551
+ out.rotate = mapAnimatable(fx.rotate, (v) => v * i);
5552
+ }
5553
+ if (fx.skew !== void 0) {
5554
+ out.skew = mapAnimatable(fx.skew, (v) => v * i);
5364
5555
  }
5365
5556
  if (fx.scale !== void 0) {
5366
5557
  out.scale = synthesiseScale(fx.scale, i);
@@ -5370,63 +5561,50 @@ var PixodeskAnimatorReact = (() => {
5370
5561
  }
5371
5562
  return Object.keys(out).length ? out : void 0;
5372
5563
  }
5373
- function mapAnimatableVec2(raw, fn) {
5374
- if (Array.isArray(raw)) return fn(raw);
5375
- if (raw && typeof raw === "object") {
5376
- const obj = raw;
5377
- if (Array.isArray(obj.keyframes)) {
5378
- return __spreadProps2(__spreadValues2({}, obj), {
5379
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
5380
- });
5381
- }
5382
- if (obj.value !== void 0) {
5383
- return __spreadProps2(__spreadValues2({}, obj), { value: fn(obj.value) });
5384
- }
5385
- }
5386
- return raw;
5387
- }
5388
- function mapAnimatableNumber(raw, fn) {
5389
- if (typeof raw === "number") return fn(raw);
5390
- if (raw && typeof raw === "object") {
5391
- const obj = raw;
5392
- if (Array.isArray(obj.keyframes)) {
5393
- return __spreadProps2(__spreadValues2({}, obj), {
5394
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
5395
- });
5396
- }
5397
- if (obj.value !== void 0) {
5398
- return __spreadProps2(__spreadValues2({}, obj), { value: fn(obj.value) });
5399
- }
5564
+ function mapAnimatable(raw, fn, wrapStatic = false) {
5565
+ const read = readAnimatable(raw);
5566
+ if (read.kind === "absent") return raw;
5567
+ if (read.kind === "static") {
5568
+ const mapped = fn(read.value);
5569
+ const wasRawStatic = typeof raw === "number" || Array.isArray(raw);
5570
+ return wasRawStatic && !wrapStatic ? mapped : { value: mapped };
5400
5571
  }
5401
- return raw;
5572
+ const out = {
5573
+ keyframes: read.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: fn(kf.value) }) : kf)
5574
+ };
5575
+ if (read.loop !== void 0) out.loop = read.loop;
5576
+ if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
5577
+ if (read.base !== void 0) out.value = fn(read.base);
5578
+ return out;
5402
5579
  }
5403
5580
  function synthesiseScale(raw, i) {
5404
- const scalePowerFromPercent = (v) => [Math.pow(v[0] / 100, i), Math.pow(v[1] / 100, i)];
5405
- const scalePowerFromUnits = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
5406
- if (Array.isArray(raw)) {
5407
- return { value: scalePowerFromPercent(raw) };
5408
- }
5409
- if (raw && typeof raw === "object") {
5410
- const obj = raw;
5411
- if (Array.isArray(obj.keyframes)) {
5412
- return __spreadProps2(__spreadValues2({}, obj), {
5413
- keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps2(__spreadValues2({}, kf), { value: scalePowerFromUnits(kf.value) }) : kf)
5414
- });
5415
- }
5416
- if (obj.value !== void 0) {
5417
- return __spreadProps2(__spreadValues2({}, obj), { value: scalePowerFromPercent(obj.value) });
5418
- }
5419
- }
5420
- return raw;
5581
+ const scalePower = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
5582
+ return mapAnimatable(raw, scalePower, true);
5421
5583
  }
5422
5584
  var RETIME_MATERIALISATION_MODE_INLINE_G = false;
5423
5585
  function asRetime(r) {
5424
5586
  var _a, _b;
5425
- if (r.timeCrop) {
5426
- console.warn("retime: `timeCrop` is not supported yet and will be ignored");
5427
- }
5428
5587
  return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
5429
5588
  }
5589
+ var CROP_EDGE_MS = 1;
5590
+ function applyTimeCrop(useNode, crop, ctx) {
5591
+ const [start, end] = crop;
5592
+ if (!Number.isFinite(start) || !Number.isFinite(end)) {
5593
+ ctx.warnings.push("retime: timeCrop is not a pair of finite numbers \u2014 ignored");
5594
+ return;
5595
+ }
5596
+ const keyframes = end <= start ? [{ time: 0, value: 0 }] : [
5597
+ ...start > 0 ? [{ time: Math.max(0, start - CROP_EDGE_MS), value: 0 }] : [],
5598
+ { time: Math.max(0, start), value: 1 },
5599
+ { time: end, value: 1 },
5600
+ { time: end + CROP_EDGE_MS, value: 0 }
5601
+ ];
5602
+ const inner = __spreadValues2({}, useNode);
5603
+ for (const k of Object.keys(useNode)) delete useNode[k];
5604
+ useNode.type = "g";
5605
+ useNode.children = [inner];
5606
+ useNode.animate = { opacity: { keyframes } };
5607
+ }
5430
5608
  function concatRetime(child, parent) {
5431
5609
  return {
5432
5610
  start: parent.start + parent.stretch * child.start,
@@ -5486,8 +5664,10 @@ var PixodeskAnimatorReact = (() => {
5486
5664
  for (const useNode of sites) {
5487
5665
  const retime = readCloneRetime(useNode);
5488
5666
  if (!retime) continue;
5667
+ const crop = retime.timeCrop;
5489
5668
  clearCloneRetime(useNode);
5490
5669
  materialiseRetime(useNode, asRetime(retime), ctx);
5670
+ if (crop) applyTimeCrop(useNode, crop, ctx);
5491
5671
  }
5492
5672
  }
5493
5673
  function materialiseRetime(useNode, retime, ctx) {
@@ -5730,14 +5910,11 @@ var PixodeskAnimatorReact = (() => {
5730
5910
  }
5731
5911
  var EXTEND_MARGIN_FRAC = 0.15;
5732
5912
  function numRange(v) {
5733
- if (typeof v === "number") return { min: v, max: v };
5734
- if (v && typeof v === "object") {
5735
- const o = v;
5736
- if (typeof o.value === "number") return { min: o.value, max: o.value };
5737
- if (Array.isArray(o.keyframes) && o.keyframes.length) {
5738
- const vals = o.keyframes.map((k) => Number(k.value) || 0);
5739
- return { min: Math.min(...vals), max: Math.max(...vals) };
5740
- }
5913
+ const read = readAnimatable(v);
5914
+ if (read.kind === "static" && typeof read.value === "number") return { min: read.value, max: read.value };
5915
+ if (read.kind === "animated" && read.keyframes.length) {
5916
+ const vals = read.keyframes.map((k) => Number(k.value) || 0);
5917
+ return { min: Math.min(...vals), max: Math.max(...vals) };
5741
5918
  }
5742
5919
  return { min: 0, max: 0 };
5743
5920
  }
@@ -5757,11 +5934,16 @@ var PixodeskAnimatorReact = (() => {
5757
5934
  var r3 = (n) => Math.round(n * 1e3) / 1e3;
5758
5935
  function shiftAnimatable(v, by) {
5759
5936
  if (!by || v === void 0 || v === null) return v;
5760
- if (typeof v === "number") return v + by;
5761
- const o = v;
5762
- if (typeof o.value === "number") return __spreadProps2(__spreadValues2({}, o), { value: o.value + by });
5763
- if (Array.isArray(o.keyframes)) return __spreadProps2(__spreadValues2({}, o), { keyframes: o.keyframes.map((k) => __spreadProps2(__spreadValues2({}, k), { value: (Number(k.value) || 0) + by })) });
5764
- return v;
5937
+ const read = readAnimatable(v);
5938
+ if (read.kind === "absent") return v;
5939
+ if (read.kind === "static") return typeof v === "number" ? read.value + by : { value: read.value + by };
5940
+ const out = {
5941
+ keyframes: read.keyframes.map((k) => __spreadProps2(__spreadValues2({}, k), { value: (Number(k.value) || 0) + by }))
5942
+ };
5943
+ if (read.loop !== void 0) out.loop = read.loop;
5944
+ if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
5945
+ if (read.base !== void 0) out.value = read.base + by;
5946
+ return out;
5765
5947
  }
5766
5948
  function extendedPathForBrowser(pathD, opts) {
5767
5949
  var _a;
@@ -5817,26 +5999,7 @@ var PixodeskAnimatorReact = (() => {
5817
5999
  }
5818
6000
  function applyAnimatableNumber(node, attrName, raw) {
5819
6001
  if (raw === void 0 || raw === null) return;
5820
- if (typeof raw === "number") {
5821
- node[attrName] = String(raw);
5822
- return;
5823
- }
5824
- if (typeof raw === "object" && raw !== null) {
5825
- const obj = raw;
5826
- if (Array.isArray(obj.keyframes)) {
5827
- const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
5828
- const animate = __spreadValues2({}, prevAnimate || {});
5829
- const block = { keyframes: obj.keyframes };
5830
- if (obj.loop !== void 0) block.loop = obj.loop;
5831
- animate[attrName] = block;
5832
- node.animate = animate;
5833
- return;
5834
- }
5835
- if (typeof obj.value === "number") {
5836
- node[attrName] = String(obj.value);
5837
- return;
5838
- }
5839
- }
6002
+ writeAnimatableChannel(node, attrName, readAnimatable(raw), { asString: true });
5840
6003
  }
5841
6004
  var jsonElementFactory = (type, props, children) => {
5842
6005
  const node = { type };
@@ -6024,13 +6187,13 @@ var PixodeskAnimatorReact = (() => {
6024
6187
  if (y !== void 0) pen.y = y;
6025
6188
  pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
6026
6189
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
6027
- const content = (_c2 = str(el[TEXT_ATTR])) != null ? _c2 : str(el[TEXT_CONTENT_ATTR]);
6190
+ const content = (_c2 = str(el[TEXT_CONTENT_ATTR])) != null ? _c2 : str(el[TEXT_ATTR]);
6028
6191
  if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
6029
6192
  if (el.children) for (const ch of el.children) walk(ch, s);
6030
6193
  };
6031
6194
  const rootStyle = rootStyleOf(node);
6032
6195
  if (node.children) for (const ch of node.children) walk(ch, rootStyle);
6033
- const rootContent = (_c = str(node[TEXT_ATTR])) != null ? _c : str(node[TEXT_CONTENT_ATTR]);
6196
+ const rootContent = (_c = str(node[TEXT_CONTENT_ATTR])) != null ? _c : str(node[TEXT_ATTR]);
6034
6197
  if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
6035
6198
  const anchor = str(node.textAnchor);
6036
6199
  if (anchor === "middle" || anchor === "end") {
@@ -6048,7 +6211,7 @@ var PixodeskAnimatorReact = (() => {
6048
6211
  const walk = (el, parentStyle) => {
6049
6212
  var _a, _b, _c;
6050
6213
  const s = resolveStyle2(el, parentStyle);
6051
- const content = (_a = str(el[TEXT_ATTR])) != null ? _a : str(el[TEXT_CONTENT_ATTR]);
6214
+ const content = (_a = str(el[TEXT_CONTENT_ATTR])) != null ? _a : str(el[TEXT_ATTR]);
6052
6215
  if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
6053
6216
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
6054
6217
  if (gf) {
@@ -6272,9 +6435,9 @@ var PixodeskAnimatorReact = (() => {
6272
6435
  }
6273
6436
  return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
6274
6437
  }
6275
- function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
6438
+ function applyTrimPathEffect(node, trimPath, ctx) {
6276
6439
  if (!trimPath) return node;
6277
- const trimAllAsOne = !!trimPath.trimAllAsOne;
6440
+ const combined = trimPath.subPaths === PxTrimSubPaths.combined;
6278
6441
  const leafEntries = [];
6279
6442
  const measure = (n) => {
6280
6443
  if (Array.isArray(n.children) && n.children.length > 0) {
@@ -6295,16 +6458,16 @@ var PixodeskAnimatorReact = (() => {
6295
6458
  measure(node);
6296
6459
  if (!leafEntries.length) return node;
6297
6460
  let acc = 0;
6298
- const iterOrder = trimAllAsOne ? [...leafEntries].reverse() : leafEntries;
6461
+ const iterOrder = combined ? [...leafEntries].reverse() : leafEntries;
6299
6462
  for (const entry of iterOrder) {
6300
6463
  for (const sp of entry.subpaths) {
6301
- if (!trimAllAsOne) acc = 0;
6464
+ if (!combined) acc = 0;
6302
6465
  sp.startOffsetPx = acc;
6303
6466
  acc += sp.lengthPx;
6304
6467
  }
6305
6468
  }
6306
6469
  const chainLengthPx = acc;
6307
- if (trimAllAsOne && chainLengthPx < 1e-3) return node;
6470
+ if (combined && chainLengthPx < 1e-3) return node;
6308
6471
  const offsetReadRaw = readAnimatable(trimPath.offset);
6309
6472
  const offsetRead = offsetReadRaw.kind === "absent" ? { kind: "static", value: 0 } : offsetReadRaw;
6310
6473
  const rangeReadRaw = readRangeWithCrossings(trimPath.range);
@@ -6316,18 +6479,18 @@ var PixodeskAnimatorReact = (() => {
6316
6479
  if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {
6317
6480
  const entry = leafEntries[0];
6318
6481
  const sp = entry.subpaths[0];
6319
- const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
6482
+ const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
6320
6483
  if (pathLengthPx < 1e-3) return node;
6321
- const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
6484
+ const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
6322
6485
  return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);
6323
6486
  }
6324
6487
  const replacements = /* @__PURE__ */ new Map();
6325
6488
  for (const entry of leafEntries) {
6326
6489
  const newChildren = [];
6327
6490
  for (const sp of entry.subpaths) {
6328
- const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
6491
+ const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
6329
6492
  if (pathLengthPx < 1e-3) continue;
6330
- const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
6493
+ const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
6331
6494
  newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));
6332
6495
  }
6333
6496
  replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));
@@ -6434,22 +6597,8 @@ var PixodeskAnimatorReact = (() => {
6434
6597
  };
6435
6598
  }
6436
6599
  function applyAttr(node, attrName, attr) {
6437
- var _a, _b;
6438
6600
  if (!attr) return;
6439
- if (attr.kind === "static") {
6440
- node[attrName] = attr.value;
6441
- return;
6442
- }
6443
- const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
6444
- const animate = __spreadValues2({}, prevAnimate || {});
6445
- const block = { keyframes: attr.keyframes };
6446
- if (attr.loop !== void 0) block.loop = attr.loop;
6447
- animate[attrName] = block;
6448
- node.animate = animate;
6449
- const firstKf = attr.keyframes[0];
6450
- if (firstKf && ((_a = firstKf.value) != null ? _a : firstKf.v) !== void 0) {
6451
- node[attrName] = (_b = firstKf.value) != null ? _b : firstKf.v;
6452
- }
6601
+ writeAnimatableChannel(node, attrName, attr);
6453
6602
  }
6454
6603
  var OPACITY_STEP_MS = 10;
6455
6604
  function computeOpacityFromRange(rangeRead) {
@@ -6631,9 +6780,9 @@ var PixodeskAnimatorReact = (() => {
6631
6780
  nextId: 0,
6632
6781
  contentRefInnerIds: /* @__PURE__ */ new Map(),
6633
6782
  maskAncestorChains: /* @__PURE__ */ new Map(),
6634
- // Resolved engine: `frames` ONLY when explicitly set; auto/webapi/unset →
6635
- // webapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
6636
- engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi,
6783
+ // Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
6784
+ // waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
6785
+ engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi,
6637
6786
  glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
6638
6787
  };
6639
6788
  const working = clone(root);
@@ -6651,8 +6800,7 @@ var PixodeskAnimatorReact = (() => {
6651
6800
  const originalId = typeof node.id === "string" ? node.id : void 0;
6652
6801
  const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
6653
6802
  if (!fx && !innerIdForContentRef) return node;
6654
- const { transformation, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
6655
- const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
6803
+ const { transformBy, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
6656
6804
  if (fx) delete node.effects;
6657
6805
  let n = node;
6658
6806
  let consumedByGlyphs = false;
@@ -6672,15 +6820,15 @@ var PixodeskAnimatorReact = (() => {
6672
6820
  if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
6673
6821
  n = applyFillGradientEffect(n, fillGradient, ctx);
6674
6822
  n = applyStrokeGradientEffect(n, strokeGradient, ctx);
6675
- n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
6823
+ n = applyTrimPathEffect(n, trimPath, ctx);
6676
6824
  n = applyRepeaterEffect(n, repeater, ctx);
6677
- n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
6825
+ n = applyMaskedByEffect(n, maskedBy, transformBy, ctx);
6678
6826
  n = applyClipPathEffect(n, clipPath, ctx);
6679
6827
  if (innerIdForContentRef) {
6680
6828
  applyRefHref(n, cloneFx, ctx);
6681
- n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
6829
+ n = splitForContentRef(n, transformBy, originalId, innerIdForContentRef, ctx);
6682
6830
  } else {
6683
- n = applyRefAndTransformationEffect(n, cloneFx, transformation, ctx);
6831
+ n = applyRefAndTransformationEffect(n, cloneFx, transformBy, ctx);
6684
6832
  }
6685
6833
  if (cloneFx == null ? void 0 : cloneFx.retime) node.effects = { clone: { retime: cloneFx.retime } };
6686
6834
  if (originalId) ctx.idMap.set(originalId, n);
@@ -6695,7 +6843,7 @@ var PixodeskAnimatorReact = (() => {
6695
6843
  let root = applyPlayerEffects(doc).root;
6696
6844
  const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
6697
6845
  root = materialiseInternalLoopsInTree(root, duration);
6698
- if (engine === PxAnimatorEngine.webapi) {
6846
+ if (engine === PxAnimatorEngine.waapi) {
6699
6847
  root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
6700
6848
  root = materialiseAnimatedUseInstances(root);
6701
6849
  root = pruneUnreferencedDefs(root);
@@ -7007,62 +7155,6 @@ var PixodeskAnimatorReact = (() => {
7007
7155
  };
7008
7156
  return api;
7009
7157
  }
7010
- var SVG_NS = "http://www.w3.org/2000/svg";
7011
- function createElement(tagName, normalisedProps, style, children, textContent) {
7012
- if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
7013
- console.warn("SVG tag blocked (dangerous): ", tagName);
7014
- return null;
7015
- }
7016
- const element = document.createElementNS(SVG_NS, tagName);
7017
- for (const propName in normalisedProps) {
7018
- const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
7019
- if (sanitised === void 0) continue;
7020
- if (CSS_ONLY_STYLE_PROPS.has(propName)) {
7021
- element.style[propName] = String(sanitised);
7022
- continue;
7023
- }
7024
- element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
7025
- }
7026
- if (style) {
7027
- for (const styleProp in style) {
7028
- element.style[styleProp] = String(style[styleProp]);
7029
- }
7030
- }
7031
- if (children) {
7032
- for (const child of children) {
7033
- element.appendChild(child);
7034
- }
7035
- }
7036
- if (textContent) element.textContent = textContent;
7037
- return element;
7038
- }
7039
- function renderNode(node, defs) {
7040
- if (!node) return null;
7041
- const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
7042
- const feFuncType = props.funcType;
7043
- if (feFuncType !== void 0) delete props.funcType;
7044
- const nodeDefs = getDefs(node) || defs;
7045
- const resolvedStyle = resolveStyle(style, nodeDefs);
7046
- let childElements;
7047
- if (children) {
7048
- for (const ch of children) {
7049
- const child = renderNode(ch, nodeDefs);
7050
- if (child) {
7051
- if (!childElements) childElements = [];
7052
- childElements.push(child);
7053
- }
7054
- }
7055
- }
7056
- const element = createElement(
7057
- type || "g",
7058
- getNormalizedProps(props),
7059
- resolvedStyle,
7060
- childElements,
7061
- props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
7062
- );
7063
- if (element && feFuncType !== void 0) element.setAttribute("type", feFuncType);
7064
- return element;
7065
- }
7066
7158
  function setupAnimationTriggers(api, config) {
7067
7159
  const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
7068
7160
  const root = api.getRootElement();
@@ -7247,7 +7339,7 @@ var PixodeskAnimatorReact = (() => {
7247
7339
  } else {
7248
7340
  cssValue = "" + value;
7249
7341
  }
7250
- if (!CSS.supports(cssKey, cssValue)) unsupportedSet.add(cssKey);
7342
+ if (!CSS.supports(camelCaseToKebabWordIfNeeded(cssKey), cssValue)) unsupportedSet.add(cssKey);
7251
7343
  cssKey = kebabToCamelCaseWord(cssKey);
7252
7344
  cssKf[cssKey] = cssValue;
7253
7345
  return cssKf;
@@ -7324,7 +7416,7 @@ var PixodeskAnimatorReact = (() => {
7324
7416
  console.warn("createFrameLoopAnimator: No root element provided");
7325
7417
  }
7326
7418
  }
7327
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.webapi);
7419
+ const bindings = getNormalisedBindings(doc, PxAnimatorEngine.waapi);
7328
7420
  const animations = [];
7329
7421
  const _iterations = config.iterations;
7330
7422
  let iterations;
@@ -7469,8 +7561,7 @@ var PixodeskAnimatorReact = (() => {
7469
7561
  }
7470
7562
  return api;
7471
7563
  }
7472
- function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
7473
- const animatorConfig = getAnimatorConfig(doc) || {};
7564
+ function finaliseAnimator(animatorConfig, callbacks, make) {
7474
7565
  let apiRef;
7475
7566
  let effectiveCallbacks = callbacks;
7476
7567
  if (animatorConfig.resetOnFinish) {
@@ -7482,29 +7573,92 @@ var PixodeskAnimatorReact = (() => {
7482
7573
  }
7483
7574
  });
7484
7575
  }
7485
- let res;
7486
- if (animatorConfig.mode === PxAnimatorMode.frames) {
7487
- res = createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement);
7488
- } else {
7489
- res = createWebApiAnimator(
7490
- doc,
7491
- effectiveCallbacks,
7492
- rootElement,
7493
- animatorConfig.mode === PxAnimatorMode.webapi
7494
- // forcing webapi
7495
- ) || createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement);
7496
- }
7576
+ const res = make(effectiveCallbacks);
7497
7577
  apiRef = res;
7498
7578
  if (animatorConfig.debugInstName) {
7499
7579
  window[animatorConfig.debugInstName] = res;
7500
7580
  }
7501
7581
  return res;
7502
7582
  }
7583
+ function bindWithEngineChoice(doc, adapter, callbacks, rootElement) {
7584
+ const animatorConfig = getAnimatorConfig(doc) || {};
7585
+ return finaliseAnimator(animatorConfig, callbacks, (cb) => {
7586
+ if (animatorConfig.mode === PxAnimatorMode.frames) {
7587
+ return createFrameLoopAnimator(doc, adapter, cb, rootElement);
7588
+ }
7589
+ return createWebApiAnimator(
7590
+ doc,
7591
+ cb,
7592
+ rootElement,
7593
+ animatorConfig.mode === PxAnimatorMode.waapi
7594
+ // forcing waapi
7595
+ ) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
7596
+ });
7597
+ }
7598
+ var SVG_NS = "http://www.w3.org/2000/svg";
7599
+ function createElement(tagName, normalisedProps, style, children, textContent) {
7600
+ if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
7601
+ console.warn("SVG tag blocked (dangerous): ", tagName);
7602
+ return null;
7603
+ }
7604
+ const element = document.createElementNS(SVG_NS, tagName);
7605
+ for (const propName in normalisedProps) {
7606
+ const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
7607
+ if (sanitised === void 0) continue;
7608
+ if (CSS_ONLY_STYLE_PROPS.has(propName)) {
7609
+ element.style[propName] = String(sanitised);
7610
+ continue;
7611
+ }
7612
+ element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
7613
+ }
7614
+ if (style) {
7615
+ for (const styleProp in style) {
7616
+ element.style[styleProp] = String(style[styleProp]);
7617
+ }
7618
+ }
7619
+ if (children) {
7620
+ for (const child of children) {
7621
+ element.appendChild(child);
7622
+ }
7623
+ }
7624
+ if (textContent) element.textContent = textContent;
7625
+ return element;
7626
+ }
7627
+ function renderNode(node, defs) {
7628
+ if (!node) return null;
7629
+ const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
7630
+ const domType = props.domType;
7631
+ if (domType !== void 0) delete props.domType;
7632
+ const nodeDefs = getDefs(node) || defs;
7633
+ const resolvedStyle = resolveStyle(style, nodeDefs);
7634
+ let childElements;
7635
+ if (children) {
7636
+ for (const ch of children) {
7637
+ const child = renderNode(ch, nodeDefs);
7638
+ if (child) {
7639
+ if (!childElements) childElements = [];
7640
+ childElements.push(child);
7641
+ }
7642
+ }
7643
+ }
7644
+ const element = createElement(
7645
+ type || "g",
7646
+ getNormalizedProps(props),
7647
+ resolvedStyle,
7648
+ childElements,
7649
+ props[TEXT_CONTENT_ATTR] || props[TEXT_ATTR]
7650
+ );
7651
+ if (element && domType !== void 0) element.setAttribute("type", domType);
7652
+ return element;
7653
+ }
7654
+ function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
7655
+ return bindWithEngineChoice(doc, adapter, callbacks, rootElement);
7656
+ }
7503
7657
  function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
7504
7658
  const effectsWarnings = validateNodeEffects(doc);
7505
7659
  for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
7506
7660
  const animatorConfig = getAnimatorConfig(doc) || {};
7507
- const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi;
7661
+ const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.waapi;
7508
7662
  doc = materialiseAllInTree(doc, engine);
7509
7663
  let rootElement = null;
7510
7664
  if (containerElement) {