funnel-gfx-wc 0.1.239 → 0.1.241

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.
@@ -471,7 +471,7 @@ var consts = {};
471
471
 
472
472
  /**
473
473
  * Anime.js - core - CJS
474
- * @version v4.4.1
474
+ * @version v4.5.0
475
475
  * @license MIT
476
476
  * @copyright 2026 - Julian Garnier
477
477
  */
@@ -548,6 +548,11 @@ function requireConsts () {
548
548
  const emptyString = '';
549
549
  const cssVarPrefix = 'var(';
550
550
 
551
+ // Arrays
552
+
553
+ // Shared sentinel for tween slots that don't hold array data. Never mutated, only read; COMPLEX and COLOR tweens always replace the slot before writing.
554
+ const emptyArray = [];
555
+
551
556
  const shortTransforms = /*#__PURE__*/ (() => {
552
557
  const map = new Map();
553
558
  map.set('x', 'translateX');
@@ -581,6 +586,13 @@ function requireConsts () {
581
586
  /** @return {void} */
582
587
  const noop = () => {};
583
588
 
589
+ /**
590
+ * @template T
591
+ * @param {T} v
592
+ * @return {T}
593
+ */
594
+ const noopModifier = v => v;
595
+
584
596
  // Regex
585
597
 
586
598
  const validRgbHslRgx = /\)\s*[-.\d]/;
@@ -603,6 +615,7 @@ function requireConsts () {
603
615
  consts.cssVariableMatchRgx = cssVariableMatchRgx;
604
616
  consts.digitWithExponentRgx = digitWithExponentRgx;
605
617
  consts.doc = doc;
618
+ consts.emptyArray = emptyArray;
606
619
  consts.emptyString = emptyString;
607
620
  consts.hexTestRgx = hexTestRgx;
608
621
  consts.hslExecRgx = hslExecRgx;
@@ -616,6 +629,7 @@ function requireConsts () {
616
629
  consts.maxValue = maxValue;
617
630
  consts.minValue = minValue;
618
631
  consts.noop = noop;
632
+ consts.noopModifier = noopModifier;
619
633
  consts.proxyTargetSymbol = proxyTargetSymbol;
620
634
  consts.relativeValuesExecRgx = relativeValuesExecRgx;
621
635
  consts.rgbExecRgx = rgbExecRgx;
@@ -639,7 +653,7 @@ var globals = {};
639
653
 
640
654
  /**
641
655
  * Anime.js - core - CJS
642
- * @version v4.4.1
656
+ * @version v4.5.0
643
657
  * @license MIT
644
658
  * @copyright 2026 - Julian Garnier
645
659
  */
@@ -666,10 +680,13 @@ function requireGlobals () {
666
680
  /**
667
681
  * @typedef {Object} EditorGlobals
668
682
  * @property {boolean} showPanel
669
- * @property {boolean} synced
670
683
  * @property {Function} addAnimation
684
+ * @property {Function} addSet
671
685
  * @property {Function} addTimeline
672
686
  * @property {Function} addTimelineChild
687
+ * @property {Function} addTimelineLabel
688
+ * @property {Function} addTimelineCall
689
+ * @property {Function} addTimelineSync
673
690
  * @property {Function} resolveStagger
674
691
  * @property {Object|null} _head
675
692
  * @property {Object|null} _tail
@@ -692,7 +709,7 @@ function requireGlobals () {
692
709
  loopDelay: 0,
693
710
  ease: 'out(2)',
694
711
  composition: consts.compositionTypes.replace,
695
- modifier: v => v,
712
+ modifier: consts.noopModifier,
696
713
  onBegin: consts.noop,
697
714
  onBeforeUpdate: consts.noop,
698
715
  onUpdate: consts.noop,
@@ -722,7 +739,7 @@ function requireGlobals () {
722
739
  editor: null,
723
740
  };
724
741
 
725
- const globalVersions = { version: '4.4.1', engine: null };
742
+ const globalVersions = { version: '4.5.0', engine: null };
726
743
 
727
744
  if (consts.isBrowser) {
728
745
  if (!consts.win.AnimeJS) consts.win.AnimeJS = [];
@@ -738,7 +755,7 @@ function requireGlobals () {
738
755
 
739
756
  /**
740
757
  * Anime.js - core - CJS
741
- * @version v4.4.1
758
+ * @version v4.5.0
742
759
  * @license MIT
743
760
  * @copyright 2026 - Julian Garnier
744
761
  */
@@ -897,7 +914,7 @@ function requireHelpers$1 () {
897
914
  * @param {Number} factor - Interpolation factor in the range [0, 1]
898
915
  * @return {Number} The interpolated value
899
916
  */
900
- const lerp = (start, end, factor) => start + (end - start) * factor;
917
+ const lerp = (start, end, factor) => factor === 1 ? end : factor === 0 ? start : start + (end - start) * factor;
901
918
 
902
919
  /**
903
920
  * Replaces infinity with maximum safe value
@@ -1050,7 +1067,7 @@ var transforms = {};
1050
1067
 
1051
1068
  /**
1052
1069
  * Anime.js - core - CJS
1053
- * @version v4.4.1
1070
+ * @version v4.5.0
1054
1071
  * @license MIT
1055
1072
  * @copyright 2026 - Julian Garnier
1056
1073
  */
@@ -1220,11 +1237,169 @@ function requireTransforms () {
1220
1237
  return transforms;
1221
1238
  }
1222
1239
 
1240
+ var registry = {};
1241
+
1242
+ /**
1243
+ * Anime.js - adapters - CJS
1244
+ * @version v4.5.0
1245
+ * @license MIT
1246
+ * @copyright 2026 - Julian Garnier
1247
+ */
1248
+
1249
+ var hasRequiredRegistry;
1250
+
1251
+ function requireRegistry () {
1252
+ if (hasRequiredRegistry) return registry;
1253
+ hasRequiredRegistry = 1;
1254
+
1255
+ /**
1256
+ * Anime.js adapter API. Each library or class group that wants to extend `animate()` and `utils.set()` calls `registerAdapter()` to create its own `Adapter`. The returned `Adapter` exposes `registerTargetAdapter(detect)` for per-class detection and `registerPropertyResolver(fn)` for global Color / Vector / pattern-based fallbacks.
1257
+ *
1258
+ * import { registerAdapter } from 'animejs/adapters';
1259
+ *
1260
+ * const myAdapter = registerAdapter();
1261
+ * const widget = myAdapter.registerTargetAdapter((t) => t instanceof MyWidget);
1262
+ * widget.registerProperty('value',
1263
+ * (t) => t.getValue(),
1264
+ * (target, value) => target.setValue(value),
1265
+ * );
1266
+ *
1267
+ * For scalar tweens, `value` is the interpolated number. For color and complex tweens it is `undefined`; read `tween._numbers` instead. `gate(target)` scopes the prop to a subset of matching targets.
1268
+ *
1269
+ * Resolution order: every Adapter's target adapters in registration order (first match wins) then every Adapter's property resolvers (first non-null wins) then engine direct property path.
1270
+ */
1271
+
1272
+ /**
1273
+ * @typedef TargetAdapterEntry
1274
+ * @property {(t: any) => any} get
1275
+ * @property {(target: any, value: number, tween: any) => void} set
1276
+ * @property {(t: any) => boolean} [gate]
1277
+ */
1278
+
1279
+ const alwaysTrue = () => true;
1280
+
1281
+ class TargetAdapter {
1282
+ /**
1283
+ * @param {(t: any) => boolean} detect
1284
+ */
1285
+ constructor(detect) {
1286
+ this.detect = detect;
1287
+ /** @type {Record<string, TargetAdapterEntry>} */
1288
+ this.props = {};
1289
+ }
1290
+
1291
+ /**
1292
+ * Registers a property the adapter handles. `setter` receives `(target, value, tween)`. For color and complex tweens `value` is `undefined`, read `tween._numbers` instead. `gate(target)` scopes the prop to a subset of matching targets.
1293
+ *
1294
+ * @param {string} name
1295
+ * @param {(t: any) => any} getter
1296
+ * @param {(target: any, value: number, tween: any) => void} setter
1297
+ * @param {(t: any) => boolean} [gate]
1298
+ */
1299
+ registerProperty(name, getter, setter, gate) {
1300
+ this.props[name] = {
1301
+ get: getter,
1302
+ set: setter,
1303
+ gate: gate || alwaysTrue,
1304
+ };
1305
+ }
1306
+ }
1307
+
1308
+ class Adapter {
1309
+ /**
1310
+ * @param {((t: any) => boolean) | null} [detect]
1311
+ * Optional gate. When provided, every lookup against this Adapter's target adapters and resolvers is skipped if `detect(target)` returns falsy. Lets the Adapter as a whole short-circuit on unrelated targets.
1312
+ */
1313
+ constructor(detect) {
1314
+ /** @type {((t: any) => boolean) | null} */
1315
+ this.detect = detect || null;
1316
+ /** @type {TargetAdapter[]} */
1317
+ this.targetAdapters = [];
1318
+ /** @type {((target: any, name: string) => TargetAdapterEntry | null)[]} */
1319
+ this.propertyResolvers = [];
1320
+ }
1321
+
1322
+ /**
1323
+ * Creates and registers a `TargetAdapter` scoped to this Adapter.
1324
+ *
1325
+ * @param {(t: any) => boolean} detect
1326
+ * @return {TargetAdapter}
1327
+ */
1328
+ registerTargetAdapter(detect) {
1329
+ const ta = new TargetAdapter(detect);
1330
+ this.targetAdapters.push(ta);
1331
+ return ta;
1332
+ }
1333
+
1334
+ /**
1335
+ * Registers a property resolver scoped to this Adapter. Resolvers are functions invoked at tween creation when no target adapter has claimed the name; the function returns an entry for names it handles or `null` to defer. Use for runtime-matched patterns (Color / Vector axis detection, name-prefix conventions, etc.).
1336
+ *
1337
+ * @param {(target: any, name: string) => TargetAdapterEntry | null} resolver
1338
+ */
1339
+ registerPropertyResolver(resolver) {
1340
+ if (this.propertyResolvers.indexOf(resolver) === -1) this.propertyResolvers.push(resolver);
1341
+ }
1342
+ }
1343
+
1344
+ const adapters = /** @type {Adapter[]} */([]);
1345
+
1346
+ /**
1347
+ * Creates and registers an Adapter. Each library extending `animate()` calls this once and uses the returned Adapter to wire up its target adapters and property resolvers. The optional `detect` short-circuits all lookups against the Adapter when the target is unrelated.
1348
+ *
1349
+ * @param {(t: any) => boolean} [detect]
1350
+ * @return {Adapter}
1351
+ */
1352
+ function registerAdapter(detect) {
1353
+ const a = new Adapter(detect);
1354
+ adapters.push(a);
1355
+ return a;
1356
+ }
1357
+
1358
+ /**
1359
+ * Internal resolution. Tries every Adapter's target adapters first (in registration order, first match wins), then every Adapter's property resolvers.
1360
+ *
1361
+ * @param {any} target
1362
+ * @param {string} name
1363
+ * @return {TargetAdapterEntry | null}
1364
+ */
1365
+ function resolveAdapterEntry(target, name) {
1366
+ if (!target) return null;
1367
+ const al = adapters.length;
1368
+ outer: for (let i = 0; i < al; i++) {
1369
+ const a = adapters[i];
1370
+ if (a.detect && !a.detect(target)) continue;
1371
+ const tas = a.targetAdapters;
1372
+ for (let j = 0, m = tas.length; j < m; j++) {
1373
+ const ta = tas[j];
1374
+ if (ta.detect(target)) {
1375
+ const entry = ta.props[name];
1376
+ if (entry && (!entry.gate || entry.gate(target))) return entry;
1377
+ break outer;
1378
+ }
1379
+ }
1380
+ }
1381
+ for (let i = 0; i < al; i++) {
1382
+ const a = adapters[i];
1383
+ if (a.detect && !a.detect(target)) continue;
1384
+ const rs = a.propertyResolvers;
1385
+ for (let j = 0, m = rs.length; j < m; j++) {
1386
+ const entry = rs[j](target, name);
1387
+ if (entry) return entry;
1388
+ }
1389
+ }
1390
+ return null;
1391
+ }
1392
+
1393
+ registry.registerAdapter = registerAdapter;
1394
+ registry.resolveAdapterEntry = resolveAdapterEntry;
1395
+ return registry;
1396
+ }
1397
+
1223
1398
  var colors = {};
1224
1399
 
1225
1400
  /**
1226
1401
  * Anime.js - core - CJS
1227
- * @version v4.4.1
1402
+ * @version v4.5.0
1228
1403
  * @license MIT
1229
1404
  * @copyright 2026 - Julian Garnier
1230
1405
  */
@@ -1333,7 +1508,7 @@ function requireColors () {
1333
1508
 
1334
1509
  /**
1335
1510
  * Anime.js - core - CJS
1336
- * @version v4.4.1
1511
+ * @version v4.5.0
1337
1512
  * @license MIT
1338
1513
  * @copyright 2026 - Julian Garnier
1339
1514
  */
@@ -1347,6 +1522,7 @@ function requireValues () {
1347
1522
  var consts = /*@__PURE__*/ requireConsts();
1348
1523
  var helpers = /*@__PURE__*/ requireHelpers$1();
1349
1524
  var transforms = /*@__PURE__*/ requireTransforms();
1525
+ var registry = requireRegistry();
1350
1526
  var colors = /*@__PURE__*/ requireColors();
1351
1527
 
1352
1528
  /**
@@ -1370,6 +1546,21 @@ function requireValues () {
1370
1546
  return helpers.isUnd(targetValue) ? defaultValue : targetValue;
1371
1547
  };
1372
1548
 
1549
+ /**
1550
+ * Resolve against the target when it's a DOM element, otherwise fall back to :root so non-DOM targets like three.js meshes and custom adapters still pick up CSS variables defined on the document.
1551
+ *
1552
+ * @param {String} value
1553
+ * @param {Target} target
1554
+ * @return {String|Number}
1555
+ */
1556
+ const resolveCssVar = (value, target) => {
1557
+ const match = value.match(consts.cssVariableMatchRgx);
1558
+ const el = target[consts.isDomSymbol] ? target : document.documentElement;
1559
+ let computed = getComputedStyle(/** @type {HTMLElement} */(el))?.getPropertyValue(match[1]);
1560
+ if ((!computed || computed.trim() === consts.emptyString) && match[2]) computed = match[2].trim();
1561
+ return computed || 0;
1562
+ };
1563
+
1373
1564
  /**
1374
1565
  * @param {TweenPropValue} value
1375
1566
  * @param {Target} target
@@ -1380,30 +1571,26 @@ function requireValues () {
1380
1571
  * @return {any}
1381
1572
  */
1382
1573
  const getFunctionValue = (value, target, index, targets, store, prevTween) => {
1383
- let func;
1384
1574
  if (helpers.isFnc(value)) {
1385
- func = () => {
1575
+ if (!store) {
1576
+ const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
1577
+ // Fallback to 0 if the function returns undefined, NaN, null, false or 0
1578
+ return !isNaN(+computed) ? +computed : computed || 0;
1579
+ }
1580
+ const func = () => {
1386
1581
  const computed = /** @type {Function} */(value)(target, index, targets, prevTween);
1387
- // Fallback to 0 if the function returns undefined / NaN / null / false / 0
1388
1582
  return !isNaN(+computed) ? +computed : computed || 0;
1389
1583
  };
1390
- } else if (helpers.isStr(value) && helpers.stringStartsWith(value, consts.cssVarPrefix)) {
1391
- func = () => {
1392
- const match = value.match(consts.cssVariableMatchRgx);
1393
- const cssVarName = match[1];
1394
- const fallbackValue = match[2];
1395
- let computed = getComputedStyle(/** @type {HTMLElement} */(target))?.getPropertyValue(cssVarName);
1396
- // Use fallback if CSS variable is not set or empty
1397
- if ((!computed || computed.trim() === consts.emptyString) && fallbackValue) {
1398
- computed = fallbackValue.trim();
1399
- }
1400
- return computed || 0;
1401
- };
1402
- } else {
1403
- return value;
1584
+ store.func = func;
1585
+ return func();
1404
1586
  }
1405
- if (store) store.func = func;
1406
- return func();
1587
+ if (helpers.isStr(value) && helpers.stringStartsWith(value, consts.cssVarPrefix)) {
1588
+ if (!store) return resolveCssVar(/** @type {String} */(value), target);
1589
+ const func = () => resolveCssVar(/** @type {String} */(value), target);
1590
+ store.func = func;
1591
+ return func();
1592
+ }
1593
+ return value;
1407
1594
  };
1408
1595
 
1409
1596
  /**
@@ -1450,6 +1637,12 @@ function requireValues () {
1450
1637
  */
1451
1638
  const getOriginalAnimatableValue = (target, propName, tweenType, animationInlineStyles) => {
1452
1639
  const type = !helpers.isUnd(tweenType) ? tweenType : getTweenType(target, propName);
1640
+ const adapterProp = registry.resolveAdapterEntry(target, propName);
1641
+ if (adapterProp) {
1642
+ const value = adapterProp.get(target);
1643
+ if (value && animationInlineStyles) animationInlineStyles[propName] = value;
1644
+ return value == null ? 0 : value;
1645
+ }
1453
1646
  if (type === consts.tweenTypes.OBJECT) {
1454
1647
  const value = target[propName];
1455
1648
  if (value && animationInlineStyles) animationInlineStyles[propName] = value;
@@ -1491,7 +1684,7 @@ function requireValues () {
1491
1684
  };
1492
1685
 
1493
1686
  /**
1494
- * @param {String|Number} rawValue
1687
+ * @param {String|Number|Object} rawValue
1495
1688
  * @param {TweenDecomposedValue} targetObject
1496
1689
  * @return {TweenDecomposedValue}
1497
1690
  */
@@ -1509,39 +1702,38 @@ function requireValues () {
1509
1702
  // It's a number
1510
1703
  targetObject.n = num;
1511
1704
  return targetObject;
1705
+ }
1706
+ // let str = /** @type {String} */(rawValue).trim();
1707
+ let str = /** @type {String} */(rawValue);
1708
+ // Parsing operators (+=, -=, *=) manually is much faster than using regex here
1709
+ if (str[1] === '=') {
1710
+ targetObject.o = str[0];
1711
+ str = str.slice(2);
1712
+ }
1713
+ // Skip exec regex if the value type is complex or color to avoid long regex backtracking
1714
+ const unitMatch = str.includes(' ') ? false : consts.unitsExecRgx.exec(str);
1715
+ if (unitMatch) {
1716
+ // Has a number and a unit
1717
+ targetObject.t = consts.valueTypes.UNIT;
1718
+ targetObject.n = +unitMatch[1];
1719
+ targetObject.u = unitMatch[2];
1720
+ return targetObject;
1721
+ } else if (targetObject.o) {
1722
+ // Has an operator (+=, -=, *=)
1723
+ targetObject.n = +str;
1724
+ return targetObject;
1725
+ } else if (helpers.isCol(str)) {
1726
+ // Color string
1727
+ targetObject.t = consts.valueTypes.COLOR;
1728
+ targetObject.d = colors.convertColorStringValuesToRgbaArray(str);
1729
+ return targetObject;
1512
1730
  } else {
1513
- // let str = /** @type {String} */(rawValue).trim();
1514
- let str = /** @type {String} */(rawValue);
1515
- // Parsing operators (+=, -=, *=) manually is much faster than using regex here
1516
- if (str[1] === '=') {
1517
- targetObject.o = str[0];
1518
- str = str.slice(2);
1519
- }
1520
- // Skip exec regex if the value type is complex or color to avoid long regex backtracking
1521
- const unitMatch = str.includes(' ') ? false : consts.unitsExecRgx.exec(str);
1522
- if (unitMatch) {
1523
- // Has a number and a unit
1524
- targetObject.t = consts.valueTypes.UNIT;
1525
- targetObject.n = +unitMatch[1];
1526
- targetObject.u = unitMatch[2];
1527
- return targetObject;
1528
- } else if (targetObject.o) {
1529
- // Has an operator (+=, -=, *=)
1530
- targetObject.n = +str;
1531
- return targetObject;
1532
- } else if (helpers.isCol(str)) {
1533
- // Is a color
1534
- targetObject.t = consts.valueTypes.COLOR;
1535
- targetObject.d = colors.convertColorStringValuesToRgbaArray(str);
1536
- return targetObject;
1537
- } else {
1538
- // Is a more complex string (generally svg coords, calc() or filters CSS values)
1539
- const matchedNumbers = str.match(consts.digitWithExponentRgx);
1540
- targetObject.t = consts.valueTypes.COMPLEX;
1541
- targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
1542
- targetObject.s = str.split(consts.digitWithExponentRgx) || [];
1543
- return targetObject;
1544
- }
1731
+ // Is a more complex string (generally svg coords, calc() or filters CSS values)
1732
+ const matchedNumbers = str.match(consts.digitWithExponentRgx);
1733
+ targetObject.t = consts.valueTypes.COMPLEX;
1734
+ targetObject.d = matchedNumbers ? matchedNumbers.map(Number) : [];
1735
+ targetObject.s = str.split(consts.digitWithExponentRgx) || [];
1736
+ return targetObject;
1545
1737
  }
1546
1738
  };
1547
1739
 
@@ -1562,30 +1754,6 @@ function requireValues () {
1562
1754
 
1563
1755
  const decomposedOriginalValue = createDecomposedValueTargetObject();
1564
1756
 
1565
- /**
1566
- * @param {Tween} tween
1567
- * @param {Number} progress
1568
- * @param {Number} precision
1569
- * @return {String}
1570
- */
1571
- const composeColorValue = (tween, progress, precision) => {
1572
- const mod = tween._modifier;
1573
- const fn = tween._fromNumbers;
1574
- const tn = tween._toNumbers;
1575
- const r = helpers.round(helpers.clamp(/** @type {Number} */(mod(helpers.lerp(fn[0], tn[0], progress))), 0, 255), 0);
1576
- const g = helpers.round(helpers.clamp(/** @type {Number} */(mod(helpers.lerp(fn[1], tn[1], progress))), 0, 255), 0);
1577
- const b = helpers.round(helpers.clamp(/** @type {Number} */(mod(helpers.lerp(fn[2], tn[2], progress))), 0, 255), 0);
1578
- const a = helpers.clamp(/** @type {Number} */(mod(helpers.round(helpers.lerp(fn[3], tn[3], progress), precision))), 0, 1);
1579
- if (tween._composition !== consts.compositionTypes.none) {
1580
- const ns = tween._numbers;
1581
- ns[0] = r;
1582
- ns[1] = g;
1583
- ns[2] = b;
1584
- ns[3] = a;
1585
- }
1586
- return `rgba(${r},${g},${b},${a})`;
1587
- };
1588
-
1589
1757
  /**
1590
1758
  * @param {Tween} tween
1591
1759
  * @param {Number} progress
@@ -1597,20 +1765,18 @@ function requireValues () {
1597
1765
  const fn = tween._fromNumbers;
1598
1766
  const tn = tween._toNumbers;
1599
1767
  const ts = tween._strings;
1600
- const hasComposition = tween._composition !== consts.compositionTypes.none;
1601
1768
  let v = ts[0];
1602
1769
  for (let j = 0, l = tn.length; j < l; j++) {
1603
1770
  const n = /** @type {Number} */(mod(helpers.round(helpers.lerp(fn[j], tn[j], progress), precision)));
1604
1771
  const s = ts[j + 1];
1605
1772
  v += `${s ? n + s : n}`;
1606
- if (hasComposition) {
1607
- tween._numbers[j] = n;
1608
- }
1773
+ // Keep _numbers fresh for every tween, not only composed ones, so a non-composition setter that reads the lerped triplet such as three transformOrigin still animates.
1774
+ // Potential optimization, skip the write when nothing reads it: if (hasComposition || tween._setter) tween._numbers[j] = n;
1775
+ tween._numbers[j] = n;
1609
1776
  }
1610
1777
  return v;
1611
1778
  };
1612
1779
 
1613
- values.composeColorValue = composeColorValue;
1614
1780
  values.composeComplexValue = composeComplexValue;
1615
1781
  values.createDecomposedValueTargetObject = createDecomposedValueTargetObject;
1616
1782
  values.decomposeRawValue = decomposeRawValue;
@@ -1628,7 +1794,7 @@ var render = {};
1628
1794
 
1629
1795
  /**
1630
1796
  * Anime.js - core - CJS
1631
- * @version v4.4.1
1797
+ * @version v4.5.0
1632
1798
  * @license MIT
1633
1799
  * @copyright 2026 - Julian Garnier
1634
1800
  */
@@ -1708,12 +1874,14 @@ function requireRender () {
1708
1874
  // Execute the "expensive" iterations calculations only when necessary
1709
1875
  if (iterationCount > 1) {
1710
1876
  // bitwise NOT operator seems to be generally faster than Math.floor() across browsers
1711
- const currentIteration = ~~(tickableCurrentTime / (iterationDuration + (isCurrentTimeEqualOrAboveDuration ? 0 : _loopDelay)));
1877
+ const period = iterationDuration + (isCurrentTimeEqualOrAboveDuration ? 0 : _loopDelay);
1878
+ const currentIteration = ~~(tickableCurrentTime / period);
1712
1879
  tickable._currentIteration = helpers.clamp(currentIteration, 0, iterationCount);
1713
1880
  // Prevent the iteration count to go above the max iterations when reaching the end of the animation
1714
1881
  if (isCurrentTimeEqualOrAboveDuration) tickable._currentIteration--;
1715
1882
  isOdd = tickable._currentIteration % 2;
1716
- iterationElapsedTime = tickableCurrentTime % (iterationDuration + _loopDelay) || 0;
1883
+ // Derive elapsed from the same `~~` truncation that gave currentIteration. Using `% period` here can disagree with `~~(/period)` under float drift at iteration boundaries and write the wrong end of the tween for one frame.
1884
+ iterationElapsedTime = tickableCurrentTime - currentIteration * period || 0;
1717
1885
  }
1718
1886
 
1719
1887
  // Checks if exactly one of _reversed and (_alternate && isOdd) is true
@@ -1745,12 +1913,14 @@ function requireRender () {
1745
1913
  if (
1746
1914
  forcedTick ||
1747
1915
  tickMode === consts.tickModes.AUTO && (
1748
- time >= tickableDelay && time <= tickableEndTime || // Normal render
1916
+ // Timeline children render from their offset instead of their delay so the gap left by a truncated sibling is covered on seek.
1917
+ time >= (parent && tickableDelay > 0 ? 0 : tickableDelay) && time <= tickableEndTime || // Normal render
1749
1918
  time <= tickableDelay && tickablePrevTime > tickableDelay || // Playhead is before the animation start time so make sure the animation is at its initial state
1750
1919
  time >= tickableEndTime && tickablePrevTime !== duration // Playhead is after the animation end time so make sure the animation is at its end state
1751
1920
  ) ||
1752
1921
  iterationTime >= tickableEndTime && tickablePrevTime !== duration ||
1753
- iterationTime <= tickableDelay && tickablePrevTime > 0 ||
1922
+ // iterationTime is per-iteration, compared to the delay to catch a backward seek into a looped iteration's delay region. Exclude the final settled end, where iterationTime clamps to duration and would falsely match the delay region when the delay exceeds the duration.
1923
+ iterationTime <= tickableDelay && tickablePrevTime > 0 && !isCurrentTimeEqualOrAboveDuration ||
1754
1924
  time <= tickablePrevTime && tickablePrevTime === duration && completed || // Force a render if a seek occurs on an completed animation
1755
1925
  isCurrentTimeEqualOrAboveDuration && !completed && isSetter // This prevents 0 duration tickables to be skipped
1756
1926
  ) {
@@ -1766,7 +1936,8 @@ function requireRender () {
1766
1936
 
1767
1937
  // Time has jumped more than globals.tickThreshold so consider this tick manual
1768
1938
  const forcedRender = forcedTick || (isRunningBackwards ? deltaTime * -1 : deltaTime) >= globals.globals.tickThreshold;
1769
- const absoluteTime = tickable._offset + (parent ? parent._offset : 0) + tickableDelay + iterationTime;
1939
+ // Round to match the precision of tween._absoluteStartTime so equal-time boundary checks compare cleanly without floating point drift from the unrounded _offset.
1940
+ const absoluteTime = helpers.round(tickable._offset + (parent ? parent._offset : 0) + tickableDelay + iterationTime, 12);
1770
1941
 
1771
1942
  // Only Animation can have tweens, Timer returns undefined
1772
1943
  let tween = /** @type {Tween} */(/** @type {JSAnimation} */(tickable)._head);
@@ -1785,15 +1956,38 @@ function requireRender () {
1785
1956
  const tweenNextRep = tween._nextRep;
1786
1957
  const tweenPrevRep = tween._prevRep;
1787
1958
  const tweenHasComposition = tweenComposition !== consts.compositionTypes.none;
1959
+ // The previous sibling stops writing at its truncated end, so this tween takes over the hold from that point.
1960
+ const tweenPrevRepEndTime = tweenPrevRep ? tweenPrevRep._absoluteStartTime + tweenPrevRep._changeDuration : 0;
1961
+ const tweenPrevRepIsCrossParent = tweenPrevRep && tweenPrevRep.parent !== tween.parent;
1962
+ // Same parent keyframes take over at their own start, end plus delay equals the next start by construction.
1963
+ // Cross parent siblings take over at their update start.
1964
+ // Negative delay siblings take over at their own start instead.
1965
+ const tweenNextRepTakeover = !tweenNextRep || tweenNextRep._isOverridden ? tweenAbsEndTime :
1966
+ tweenNextRep.parent === tween.parent ? tweenAbsEndTime + tweenNextRep._delay :
1967
+ tweenNextRep._absoluteStartTime < tweenNextRep._absoluteUpdateStartTime ? tweenNextRep._absoluteStartTime : tweenNextRep._absoluteUpdateStartTime;
1788
1968
 
1789
1969
  if ((forcedRender || (
1790
- (tweenCurrentTime !== tweenChangeDuration || absoluteTime <= tweenAbsEndTime + (tweenNextRep ? tweenNextRep._delay : 0)) &&
1791
- (tweenCurrentTime !== 0 || absoluteTime >= tween._absoluteStartTime)
1792
- )) && (!tweenHasComposition || (
1970
+ // Tail keyframes always re-evaluate the gate so an earlier keyframe cannot leave the target stale by writing past its own range after a backward seek.
1971
+ (tweenCurrentTime !== tweenChangeDuration || absoluteTime <= tweenNextRepTakeover ||
1972
+ (tweenPrevRep && !tweenPrevRepIsCrossParent && (!tweenNextRep || tweenNextRep.parent !== tween.parent))) &&
1973
+ // A cross parent tween re-renders its from value from the previous sibling truncated end so the handoff gap holds.
1974
+ // A keyframe re-renders its from revert while the next keyframe time is stale so a backward jump over its range cannot leave the next value in place.
1975
+ (tweenCurrentTime !== 0 || absoluteTime >= tween._absoluteStartTime ||
1976
+ (tweenPrevRepIsCrossParent && !tween._hasFromValue && !tweenPrevRep._isOverridden && absoluteTime >= tweenPrevRepEndTime) ||
1977
+ (tweenNextRep && !tweenNextRep._isOverridden && tweenNextRep.parent === tween.parent && tweenNextRep._currentTime !== 0 && iterationTime < tweenNextRep._startTime))
1978
+ )) &&
1979
+ // Non-first keyframes wait until the iteration reaches their own start before rendering, so the previous keyframe can handle the from-revert when scrubbed backward past this tween's range.
1980
+ (!tweenPrevRep || tweenPrevRepIsCrossParent || iterationTime >= tween._startTime) &&
1981
+ (!tweenHasComposition || (
1793
1982
  !tween._isOverridden &&
1794
1983
  (!tween._isOverlapped || absoluteTime <= tweenAbsEndTime) &&
1795
- (!tweenNextRep || (tweenNextRep._isOverridden || absoluteTime <= tweenNextRep._absoluteStartTime)) &&
1796
- (!tweenPrevRep || (tweenPrevRep._isOverridden || (absoluteTime >= (tweenPrevRep._absoluteStartTime + tweenPrevRep._changeDuration) + tween._delay)))
1984
+ // The next sibling owns the value past its takeover point, so yielding there keeps writes single owner in both directions.
1985
+ (!tweenNextRep || tweenNextRep._isOverridden || absoluteTime <= tweenNextRepTakeover) &&
1986
+ // The previous sibling owns the value up to its truncated end.
1987
+ // Cross parent tweens take over the hold from that point, explicit from values wait for their own start.
1988
+ (!tweenPrevRep || (tweenPrevRep._isOverridden || (!tweenPrevRepIsCrossParent ?
1989
+ absoluteTime >= tweenPrevRepEndTime + tween._delay :
1990
+ absoluteTime >= tween._absoluteStartTime || (!tween._hasFromValue && absoluteTime >= tweenPrevRepEndTime))))
1797
1991
  ))
1798
1992
  ) {
1799
1993
 
@@ -1804,7 +1998,7 @@ function requireRender () {
1804
1998
  const tweenType = tween._tweenType;
1805
1999
  const tweenIsObject = tweenType === consts.tweenTypes.OBJECT;
1806
2000
  const tweenIsNumber = tweenValueType === consts.valueTypes.NUMBER;
1807
- // Only round the in-between frames values if the final value is a string
2001
+ // Only round the in-between frames values if the final value is a string. Object targets consume raw numbers, so rounding is dead work there.
1808
2002
  const tweenPrecision = (tweenIsNumber && tweenIsObject) || tweenProgress === 0 || tweenProgress === 1 ? -1 : globals.globals.precision;
1809
2003
 
1810
2004
  // Recompose tween value
@@ -1820,7 +2014,22 @@ function requireRender () {
1820
2014
  number = /** @type {Number} */(tweenModifier(helpers.round(helpers.lerp(tween._fromNumber, tween._toNumber, tweenProgress), tweenPrecision)));
1821
2015
  value = `${number}${tween._unit}`;
1822
2016
  } else if (tweenValueType === consts.valueTypes.COLOR) {
1823
- value = values.composeColorValue(tween, tweenProgress, tweenPrecision);
2017
+ const ns = tween._numbers;
2018
+ const fn = tween._fromNumbers;
2019
+ const tn = tween._toNumbers;
2020
+ const omt = 1 - tweenProgress;
2021
+ const fr = fn[0], fg = fn[1], fb = fn[2];
2022
+ const tr = tn[0], tg = tn[1], tb = tn[2];
2023
+ // RGB channels lerp in pseudo-linear space (square inputs, sqrt result) to approximate gamma-correct blending.
2024
+ // See https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-24-importance-being-linear.
2025
+ ns[0] = /** @type {Number} */(tweenModifier(Math.sqrt(fr * fr * omt + tr * tr * tweenProgress)));
2026
+ ns[1] = /** @type {Number} */(tweenModifier(Math.sqrt(fg * fg * omt + tg * tg * tweenProgress)));
2027
+ ns[2] = /** @type {Number} */(tweenModifier(Math.sqrt(fb * fb * omt + tb * tb * tweenProgress)));
2028
+ ns[3] = /** @type {Number} */(tweenModifier(helpers.lerp(fn[3], tn[3], tweenProgress)));
2029
+ // The rgba string is built only for the dispatch path or the internalRender composition tick (setters handles the color comp)
2030
+ if (!tween._setter || internalRender) {
2031
+ value = `rgba(${helpers.round(ns[0], 0)},${helpers.round(ns[1], 0)},${helpers.round(ns[2], 0)},${ns[3]})`;
2032
+ }
1824
2033
  } else if (tweenValueType === consts.valueTypes.COMPLEX) {
1825
2034
  value = values.composeComplexValue(tween, tweenProgress, tweenPrecision);
1826
2035
  }
@@ -1835,7 +2044,9 @@ function requireRender () {
1835
2044
  const tweenProperty = tween.property;
1836
2045
  tweenTarget = tween.target;
1837
2046
 
1838
- if (tweenIsObject) {
2047
+ if (tween._setter) {
2048
+ tween._setter(tweenTarget, number, tween);
2049
+ } else if (tweenIsObject) {
1839
2050
  tweenTarget[tweenProperty] = value;
1840
2051
  } else if (tweenType === consts.tweenTypes.ATTRIBUTE) {
1841
2052
  /** @type {DOMTarget} */(tweenTarget).setAttribute(tweenProperty, /** @type {String} */(value));
@@ -1863,6 +2074,9 @@ function requireRender () {
1863
2074
  tween._value = value;
1864
2075
  }
1865
2076
 
2077
+ } else if (tweenCurrentTime && tweenPrevRep && !tweenPrevRepIsCrossParent && iterationTime < tween._startTime) {
2078
+ // Mark the keyframe as reverted when the playhead moves before its start, the previous keyframe owns the from revert and writes it once.
2079
+ tween._currentTime = 0;
1866
2080
  }
1867
2081
 
1868
2082
  if (tweenTransformsNeedUpdate && tween._renderTransforms) {
@@ -1970,6 +2184,8 @@ function requireRender () {
1970
2184
 
1971
2185
  helpers.forEachChildren(tl, (/** @type {JSAnimation} */child) => {
1972
2186
  const childTime = helpers.round((tlChildrenTime - child._offset) * child._speed, 12); // Rounding is needed when using seconds
2187
+ // Skip past-end siblings on backward iteration so their progress=1 to-values don't render last and overwrite the active sibling's write. Compare against _delay + duration so children with a normalized delay are not skipped while still inside their active range.
2188
+ if (tlIsRunningBackwards && childTime > child._delay + child.duration) return;
1973
2189
  const childTickMode = child._fps < tl._fps ? child.requestTick(tlCildrenTickTime) : tickMode;
1974
2190
  tlChildrenHasRendered += render$1(child, childTime, muteCallbacks, internalRender, childTickMode);
1975
2191
  if (!child.completed && tlChildrenHaveCompleted) tlChildrenHaveCompleted = false;
@@ -2003,7 +2219,7 @@ var styles = {};
2003
2219
 
2004
2220
  /**
2005
2221
  * Anime.js - core - CJS
2006
- * @version v4.4.1
2222
+ * @version v4.5.0
2007
2223
  * @license MIT
2008
2224
  * @copyright 2026 - Julian Garnier
2009
2225
  */
@@ -2017,6 +2233,7 @@ function requireStyles () {
2017
2233
  var consts = /*@__PURE__*/ requireConsts();
2018
2234
  var helpers = /*@__PURE__*/ requireHelpers$1();
2019
2235
  var transforms = /*@__PURE__*/ requireTransforms();
2236
+ var values = /*@__PURE__*/ requireValues();
2020
2237
 
2021
2238
  /**
2022
2239
  * @import {
@@ -2083,7 +2300,20 @@ function requireStyles () {
2083
2300
  const tweenType = tween._tweenType;
2084
2301
  const originalInlinedValue = tween._inlineValue;
2085
2302
  const tweenHadNoInlineValue = helpers.isNil(originalInlinedValue) || originalInlinedValue === consts.emptyString;
2086
- if (tweenType === consts.tweenTypes.OBJECT) {
2303
+ if (tween._setter) {
2304
+ if (!inlineStylesOnly && !tweenHadNoInlineValue) {
2305
+ // Re-seed the original value to the _number / _numbers props so the setter can write the original state instead of re-applying the current frame.
2306
+ values.decomposeRawValue(originalInlinedValue, values.decomposedOriginalValue);
2307
+ if (values.decomposedOriginalValue.d) {
2308
+ const src = values.decomposedOriginalValue.d;
2309
+ const dst = tween._numbers;
2310
+ for (let i = 0, l = src.length; i < l; i++) dst[i] = src[i];
2311
+ } else {
2312
+ tween._number = values.decomposedOriginalValue.n;
2313
+ }
2314
+ tween._setter(tween.target, tween._number, tween);
2315
+ }
2316
+ } else if (tweenType === consts.tweenTypes.OBJECT) {
2087
2317
  if (!inlineStylesOnly && !tweenHadNoInlineValue) {
2088
2318
  tweenTarget[tweenProperty] = originalInlinedValue;
2089
2319
  }
@@ -2151,7 +2381,7 @@ var clock = {};
2151
2381
 
2152
2382
  /**
2153
2383
  * Anime.js - core - CJS
2154
- * @version v4.4.1
2384
+ * @version v4.5.0
2155
2385
  * @license MIT
2156
2386
  * @copyright 2026 - Julian Garnier
2157
2387
  */
@@ -2191,8 +2421,6 @@ function requireClock () {
2191
2421
  /** @type {Number} */
2192
2422
  this._lastTime = initTime;
2193
2423
  /** @type {Number} */
2194
- this._scheduledTime = 0;
2195
- /** @type {Number} */
2196
2424
  this._frameDuration = consts.K / consts.maxFps;
2197
2425
  /** @type {Number} */
2198
2426
  this._fps = consts.maxFps;
@@ -2211,14 +2439,12 @@ function requireClock () {
2211
2439
  }
2212
2440
 
2213
2441
  set fps(frameRate) {
2214
- const previousFrameDuration = this._frameDuration;
2215
2442
  const fr = +frameRate;
2216
2443
  const fps = fr < consts.minValue ? consts.minValue : fr;
2217
2444
  const frameDuration = consts.K / fps;
2218
2445
  if (fps > globals.defaults.frameRate) globals.defaults.frameRate = fps;
2219
2446
  this._fps = fps;
2220
2447
  this._frameDuration = frameDuration;
2221
- this._scheduledTime += frameDuration - previousFrameDuration;
2222
2448
  }
2223
2449
 
2224
2450
  get speed() {
@@ -2235,17 +2461,17 @@ function requireClock () {
2235
2461
  * @return {tickModes}
2236
2462
  */
2237
2463
  requestTick(time) {
2238
- const scheduledTime = this._scheduledTime;
2239
- this._lastTickTime = time;
2240
- // If the current time is lower than the scheduled time
2241
- // this means not enough time has passed to hit one frameDuration
2242
- // so skip that frame
2243
- if (time < scheduledTime) return consts.tickModes.NONE;
2244
2464
  const frameDuration = this._frameDuration;
2245
- const frameDelta = time - scheduledTime;
2246
- // Ensures that _scheduledTime progresses in steps of at least 1 frameDuration.
2247
- // Skips ahead if the actual elapsed time is higher.
2248
- this._scheduledTime += frameDelta < frameDuration ? frameDuration : frameDelta;
2465
+ const elapsed = time - this._lastTickTime;
2466
+ const scaled = frameDuration * .25;
2467
+ const tolerance = scaled < 4 ? scaled : 4;
2468
+ // Tolerance prevents dropping frames that arrive a bit early due to RAF jitter
2469
+ // typically <= ~25% of frame duration and capped at 4ms so it doesn't dominate at high fps.
2470
+ // e.g. at 60fps (frameDuration=16.667ms) a frame arriving after 15ms:
2471
+ // - without tolerance: 15 < 16.667 -> skip
2472
+ // - with tolerance: 15 + 4 >= 16.667 -> tick
2473
+ if (elapsed + tolerance < frameDuration) return consts.tickModes.NONE;
2474
+ this._lastTickTime = elapsed >= frameDuration ? time - (elapsed % frameDuration) : time;
2249
2475
  return consts.tickModes.AUTO;
2250
2476
  }
2251
2477
 
@@ -2270,7 +2496,7 @@ var additive = {};
2270
2496
 
2271
2497
  /**
2272
2498
  * Anime.js - animation - CJS
2273
- * @version v4.4.1
2499
+ * @version v4.5.0
2274
2500
  * @license MIT
2275
2501
  * @copyright 2026 - Julian Garnier
2276
2502
  */
@@ -2359,7 +2585,7 @@ function requireAdditive () {
2359
2585
 
2360
2586
  /**
2361
2587
  * Anime.js - engine - CJS
2362
- * @version v4.4.1
2588
+ * @version v4.5.0
2363
2589
  * @license MIT
2364
2590
  * @copyright 2026 - Julian Garnier
2365
2591
  */
@@ -2466,7 +2692,9 @@ function requireEngine () {
2466
2692
  }
2467
2693
 
2468
2694
  set speed(playbackRate) {
2469
- this._speed = playbackRate * globals.globals.timeScale;
2695
+ const speed = playbackRate * globals.globals.timeScale;
2696
+ if (this._speed === speed) return;
2697
+ this._speed = speed;
2470
2698
  helpers.forEachChildren(this, (/** @type {Tickable} */child) => child.speed = child._speed);
2471
2699
  }
2472
2700
 
@@ -2534,7 +2762,7 @@ function requireEngine () {
2534
2762
 
2535
2763
  /**
2536
2764
  * Anime.js - animation - CJS
2537
- * @version v4.4.1
2765
+ * @version v4.5.0
2538
2766
  * @license MIT
2539
2767
  * @copyright 2026 - Julian Garnier
2540
2768
  */
@@ -2636,7 +2864,7 @@ function requireComposition$1 () {
2636
2864
  if (prevSibling) {
2637
2865
 
2638
2866
  const prevParent = prevSibling.parent;
2639
- const prevAbsEndTime = prevSibling._absoluteStartTime + prevSibling._changeDuration;
2867
+ const prevAbsEndTime = prevSibling._absoluteEndTime;
2640
2868
 
2641
2869
  // Handle looped animations tween
2642
2870
 
@@ -2662,7 +2890,8 @@ function requireComposition$1 () {
2662
2890
 
2663
2891
  }
2664
2892
 
2665
- const absoluteUpdateStartTime = tweenAbsStartTime - tween._delay;
2893
+ // Read the precision-matched update-start instead of subtracting tween._delay live so sequential keyframes touching at a boundary don't trigger a phantom overlap from float drift.
2894
+ const absoluteUpdateStartTime = tween._absoluteUpdateStartTime;
2666
2895
 
2667
2896
  if (prevAbsEndTime > absoluteUpdateStartTime) {
2668
2897
 
@@ -2682,37 +2911,41 @@ function requireComposition$1 () {
2682
2911
  }
2683
2912
  }
2684
2913
 
2685
- // Pause (and cancel) the parent if it only contains overlapped tweens
2914
+ // Skip the cancel cascade when both tweens share the same parent timeline, a timeline cannot replace itself.
2915
+ const tweenParentTL = tween.parent.parent;
2916
+ if (!tweenParentTL || tweenParentTL !== prevParent.parent) {
2686
2917
 
2687
- let pausePrevParentAnimation = true;
2918
+ let pausePrevParentAnimation = true;
2688
2919
 
2689
- helpers.forEachChildren(prevParent, (/** @type Tween */t) => {
2690
- if (!t._isOverlapped) pausePrevParentAnimation = false;
2691
- });
2920
+ helpers.forEachChildren(prevParent, (/** @type Tween */t) => {
2921
+ if (!t._isOverlapped) pausePrevParentAnimation = false;
2922
+ });
2692
2923
 
2693
- if (pausePrevParentAnimation) {
2694
- const prevParentTL = prevParent.parent;
2695
- if (prevParentTL) {
2696
- let pausePrevParentTL = true;
2697
- helpers.forEachChildren(prevParentTL, (/** @type JSAnimation */a) => {
2698
- if (a !== prevParent) {
2699
- helpers.forEachChildren(a, (/** @type Tween */t) => {
2700
- if (!t._isOverlapped) pausePrevParentTL = false;
2701
- });
2924
+ if (pausePrevParentAnimation) {
2925
+ const prevParentTL = prevParent.parent;
2926
+ if (prevParentTL) {
2927
+ let pausePrevParentTL = true;
2928
+ helpers.forEachChildren(prevParentTL, (/** @type JSAnimation */a) => {
2929
+ if (a !== prevParent) {
2930
+ helpers.forEachChildren(a, (/** @type Tween */t) => {
2931
+ if (!t._isOverlapped) pausePrevParentTL = false;
2932
+ });
2933
+ }
2934
+ });
2935
+ if (pausePrevParentTL) {
2936
+ prevParentTL.cancel();
2702
2937
  }
2703
- });
2704
- if (pausePrevParentTL) {
2705
- prevParentTL.cancel();
2938
+ } else {
2939
+ prevParent.cancel();
2940
+ // Previously, calling .cancel() on a timeline child would affect the render order of other children
2941
+ // Worked around this by marking it as .completed and using .pause() for safe removal in the engine loop
2942
+ // This is no longer needed since timeline tween composition is now handled separately
2943
+ // Keeping this here for reference
2944
+ // prevParent.completed = true;
2945
+ // prevParent.pause();
2706
2946
  }
2707
- } else {
2708
- prevParent.cancel();
2709
- // Previously, calling .cancel() on a timeline child would affect the render order of other children
2710
- // Worked around this by marking it as .completed and using .pause() for safe removal in the engine loop
2711
- // This is no longer needed since timeline tween composition is now handled separately
2712
- // Keeping this here for reference
2713
- // prevParent.completed = true;
2714
- // prevParent.pause();
2715
2947
  }
2948
+
2716
2949
  }
2717
2950
 
2718
2951
  }
@@ -2767,14 +3000,12 @@ function requireComposition$1 () {
2767
3000
  tween._number = 0;
2768
3001
  lookupTween._fromNumber = toNumber;
2769
3002
 
2770
- if (tween._toNumbers) {
3003
+ if (tween._toNumbers.length) {
2771
3004
  const toNumbers = helpers.cloneArray(tween._toNumbers);
2772
- if (toNumbers) {
2773
- toNumbers.forEach((value, i) => {
2774
- tween._fromNumbers[i] = lookupTween._fromNumbers[i] - value;
2775
- tween._toNumbers[i] = 0;
2776
- });
2777
- }
3005
+ toNumbers.forEach((value, i) => {
3006
+ tween._fromNumbers[i] = lookupTween._fromNumbers[i] - value;
3007
+ tween._toNumbers[i] = 0;
3008
+ });
2778
3009
  lookupTween._fromNumbers = toNumbers;
2779
3010
  }
2780
3011
 
@@ -2924,7 +3155,7 @@ function requireComposition$1 () {
2924
3155
 
2925
3156
  /**
2926
3157
  * Anime.js - timer - CJS
2927
- * @version v4.4.1
3158
+ * @version v4.5.0
2928
3159
  * @license MIT
2929
3160
  * @copyright 2026 - Julian Garnier
2930
3161
  */
@@ -3439,7 +3670,7 @@ var targets = {};
3439
3670
 
3440
3671
  /**
3441
3672
  * Anime.js - core - CJS
3442
- * @version v4.4.1
3673
+ * @version v4.5.0
3443
3674
  * @license MIT
3444
3675
  * @copyright 2026 - Julian Garnier
3445
3676
  */
@@ -3556,18 +3787,16 @@ function requireTargets () {
3556
3787
  function registerTargets(targets) {
3557
3788
  const parsedTargetsArray = parseTargets(targets);
3558
3789
  const parsedTargetsLength = parsedTargetsArray.length;
3559
- if (parsedTargetsLength) {
3560
- for (let i = 0; i < parsedTargetsLength; i++) {
3561
- const target = parsedTargetsArray[i];
3562
- if (!target[consts.isRegisteredTargetSymbol]) {
3563
- target[consts.isRegisteredTargetSymbol] = true;
3564
- const isSvgType = helpers.isSvg(target);
3565
- const isDom = /** @type {DOMTarget} */(target).nodeType || isSvgType;
3566
- if (isDom) {
3567
- target[consts.isDomSymbol] = true;
3568
- target[consts.isSvgSymbol] = isSvgType;
3569
- target[consts.transformsSymbol] = {};
3570
- }
3790
+ for (let i = 0; i < parsedTargetsLength; i++) {
3791
+ const target = parsedTargetsArray[i];
3792
+ if (!target[consts.isRegisteredTargetSymbol]) {
3793
+ target[consts.isRegisteredTargetSymbol] = true;
3794
+ const isSvgType = helpers.isSvg(target);
3795
+ const isDom = /** @type {DOMTarget} */(target).nodeType || isSvgType;
3796
+ if (isDom) {
3797
+ target[consts.isDomSymbol] = true;
3798
+ target[consts.isSvgSymbol] = isSvgType;
3799
+ target[consts.transformsSymbol] = {};
3571
3800
  }
3572
3801
  }
3573
3802
  }
@@ -3584,7 +3813,7 @@ var units = {};
3584
3813
 
3585
3814
  /**
3586
3815
  * Anime.js - core - CJS
3587
- * @version v4.4.1
3816
+ * @version v4.5.0
3588
3817
  * @license MIT
3589
3818
  * @copyright 2026 - Julian Garnier
3590
3819
  */
@@ -3661,7 +3890,7 @@ var none = {};
3661
3890
 
3662
3891
  /**
3663
3892
  * Anime.js - easings - CJS
3664
- * @version v4.4.1
3893
+ * @version v4.5.0
3665
3894
  * @license MIT
3666
3895
  * @copyright 2026 - Julian Garnier
3667
3896
  */
@@ -3687,7 +3916,7 @@ function requireNone () {
3687
3916
 
3688
3917
  /**
3689
3918
  * Anime.js - easings - CJS
3690
- * @version v4.4.1
3919
+ * @version v4.5.0
3691
3920
  * @license MIT
3692
3921
  * @copyright 2026 - Julian Garnier
3693
3922
  */
@@ -3772,8 +4001,8 @@ function requireParser () {
3772
4001
 
3773
4002
  /**
3774
4003
  * @typedef {Object} EasesFunctions
3775
- * @property {typeof none} linear
3776
- * @property {typeof none} none
4004
+ * @property {EasingFunction} linear
4005
+ * @property {EasingFunction} none
3777
4006
  * @property {PowerEasing} in
3778
4007
  * @property {PowerEasing} out
3779
4008
  * @property {PowerEasing} inOut
@@ -3885,7 +4114,7 @@ function requireParser () {
3885
4114
 
3886
4115
  /**
3887
4116
  * Anime.js - animation - CJS
3888
- * @version v4.4.1
4117
+ * @version v4.5.0
3889
4118
  * @license MIT
3890
4119
  * @copyright 2026 - Julian Garnier
3891
4120
  */
@@ -3900,6 +4129,7 @@ function requireAnimation () {
3900
4129
  var helpers = /*@__PURE__*/ requireHelpers$1();
3901
4130
  var globals = /*@__PURE__*/ requireGlobals();
3902
4131
  var targets = /*@__PURE__*/ requireTargets();
4132
+ var registry = requireRegistry();
3903
4133
  var values = /*@__PURE__*/ requireValues();
3904
4134
  var styles = /*@__PURE__*/ requireStyles();
3905
4135
  var units = /*@__PURE__*/ requireUnits();
@@ -4121,6 +4351,7 @@ function requireAnimation () {
4121
4351
  if (helpers.isKey(p)) {
4122
4352
 
4123
4353
  const tweenType = values.getTweenType(target, p);
4354
+ const adapterProp = registry.resolveAdapterEntry(target, p);
4124
4355
 
4125
4356
  const propName = styles.sanitizePropertyName(p, target, tweenType);
4126
4357
 
@@ -4204,7 +4435,7 @@ function requireAnimation () {
4204
4435
  } else {
4205
4436
  tweenToValue = computedToValue;
4206
4437
  }
4207
- const tweenFromValue = values.getFunctionValue(key.from, target, ti, tl, null, prevSiblingTween);
4438
+ const tweenFromValue = values.getFunctionValue(key.from, target, ti, tl, fromFunctionStore, prevSiblingTween);
4208
4439
  const easeToParse = key.ease || tEasing;
4209
4440
 
4210
4441
  const easeFunctionResult = values.getFunctionValue(easeToParse, target, ti, tl, null, prevSiblingTween);
@@ -4222,9 +4453,13 @@ function requireAnimation () {
4222
4453
  const hasToValue = !helpers.isUnd(tweenToValue);
4223
4454
  const isFromToArray = helpers.isArr(tweenToValue);
4224
4455
  const isFromToValue = isFromToArray || (hasFromvalue && hasToValue);
4456
+ // Capture the update-start in local time, the previous sibling's end for keyframes after the first, zero for the first keyframe. Used to derive a precision-matched _absoluteUpdateStartTime below.
4457
+ const tweenUpdateStartLocal = prevTween ? lastTweenChangeEndTime : 0;
4225
4458
  const tweenStartTime = prevTween ? lastTweenChangeEndTime + tweenDelay : tweenDelay;
4226
4459
  // Rounding is necessary here to minimize floating point errors when working in seconds
4227
4460
  const absoluteStartTime = helpers.round(absoluteOffsetTime + tweenStartTime, 12);
4461
+ // Match the rounding pattern of prevSibling._absoluteEndTime so the composition overlap check compares cleanly when keyframes touch at a boundary.
4462
+ const absoluteUpdateStartTime = helpers.round(absoluteOffsetTime + tweenUpdateStartLocal, 12);
4228
4463
 
4229
4464
  // Force a onRender callback if the animation contains at least one from value and autoplay is set to false
4230
4465
  if (!shouldTriggerRender && (hasFromvalue || isFromToArray)) shouldTriggerRender = 1;
@@ -4233,9 +4468,9 @@ function requireAnimation () {
4233
4468
 
4234
4469
  if (tweenComposition !== consts.compositionTypes.none) {
4235
4470
  let nextSibling = siblings._head;
4236
- // Iterate trough all the next siblings until we find a sibling with an equal or inferior start time
4237
- while (nextSibling && !nextSibling._isOverridden && nextSibling._absoluteStartTime <= absoluteStartTime) {
4238
- prevSibling = nextSibling;
4471
+ // Walk prior siblings up to the new tween, skipping overridden ones so the chain resolves to the latest live value instead of stopping at the first override.
4472
+ while (nextSibling && nextSibling._absoluteStartTime <= absoluteStartTime) {
4473
+ if (!nextSibling._isOverridden) prevSibling = nextSibling;
4239
4474
  nextSibling = nextSibling._nextRep;
4240
4475
  // Overrides all the next siblings if the next sibling starts at the same time of after as the new tween start time
4241
4476
  if (nextSibling && nextSibling._absoluteStartTime >= absoluteStartTime) {
@@ -4289,8 +4524,8 @@ function requireAnimation () {
4289
4524
  if (prevTween) {
4290
4525
  values.decomposeTweenValue(prevTween, fromTargetObject);
4291
4526
  } else {
4292
- values.decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
4293
4527
  // No need to get and parse the original value if the tween is part of a timeline and has a previous sibling part of the same timeline
4528
+ values.decomposeRawValue(parent && prevSibling && prevSibling.parent.parent === parent ? prevSibling._value :
4294
4529
  values.getOriginalAnimatableValue(target, propName, tweenType, inlineStylesStore), fromTargetObject);
4295
4530
  }
4296
4531
  }
@@ -4329,8 +4564,7 @@ function requireAnimation () {
4329
4564
  const colorValue = fromTargetObject.t === consts.valueTypes.COLOR ? fromTargetObject : toTargetObject;
4330
4565
  const notColorValue = fromTargetObject.t === consts.valueTypes.COLOR ? toTargetObject : fromTargetObject;
4331
4566
  notColorValue.t = consts.valueTypes.COLOR;
4332
- notColorValue.s = colorValue.s;
4333
- notColorValue.d = [0, 0, 0, 1];
4567
+ notColorValue.d = colorValue.d.map(() => 0);
4334
4568
  }
4335
4569
  }
4336
4570
 
@@ -4360,6 +4594,16 @@ function requireAnimation () {
4360
4594
  let inlineValue = inlineStylesStore[propName];
4361
4595
  if (!helpers.isNil(inlineValue)) inlineStylesStore[propName] = null;
4362
4596
 
4597
+ // Resolve the adapter setter once so render skips the lookup per frame.
4598
+ const tweenSetter = adapterProp ? adapterProp.set : null;
4599
+
4600
+ // Rounding is necessary here to minimize floating point errors when working in seconds
4601
+ lastTweenChangeEndTime = helpers.round(tweenStartTime + tweenUpdateDuration, 12);
4602
+
4603
+ const fromD = fromTargetObject.d;
4604
+ const toD = toTargetObject.d;
4605
+ const toS = toTargetObject.s;
4606
+
4363
4607
  /** @type {Tween} */
4364
4608
  const tween = {
4365
4609
  parent: this,
@@ -4370,12 +4614,12 @@ function requireAnimation () {
4370
4614
  _toFunc: toFunctionStore.func,
4371
4615
  _fromFunc: fromFunctionStore.func,
4372
4616
  _ease: parser.parseEase(tweenEasing),
4373
- _fromNumbers: helpers.cloneArray(fromTargetObject.d),
4374
- _toNumbers: helpers.cloneArray(toTargetObject.d),
4375
- _strings: helpers.cloneArray(toTargetObject.s),
4617
+ _fromNumbers: fromD ? helpers.cloneArray(fromD) : consts.emptyArray,
4618
+ _toNumbers: toD ? helpers.cloneArray(toD) : consts.emptyArray,
4619
+ _strings: toS ? helpers.cloneArray(toS) : consts.emptyArray,
4376
4620
  _fromNumber: fromTargetObject.n,
4377
4621
  _toNumber: toTargetObject.n,
4378
- _numbers: helpers.cloneArray(fromTargetObject.d), // For additive tween and animatables
4622
+ _numbers: fromD ? helpers.cloneArray(fromD) : consts.emptyArray, // For additive tween and animatables
4379
4623
  _number: fromTargetObject.n, // For additive tween and animatables
4380
4624
  _unit: toTargetObject.u,
4381
4625
  _modifier: tweenModifier,
@@ -4385,8 +4629,12 @@ function requireAnimation () {
4385
4629
  _updateDuration: tweenUpdateDuration,
4386
4630
  _changeDuration: tweenUpdateDuration,
4387
4631
  _absoluteStartTime: absoluteStartTime,
4632
+ _absoluteUpdateStartTime: absoluteUpdateStartTime,
4633
+ _absoluteEndTime: helpers.round(absoluteOffsetTime + lastTweenChangeEndTime, 12),
4634
+ _hasFromValue: hasFromvalue || isFromToArray ? 1 : 0,
4388
4635
  // NOTE: Investigate bit packing to stores ENUM / BOOL
4389
4636
  _tweenType: tweenType,
4637
+ _setter: tweenSetter,
4390
4638
  _valueType: toTargetObject.t,
4391
4639
  _composition: tweenComposition,
4392
4640
  _isOverlapped: 0,
@@ -4409,10 +4657,11 @@ function requireAnimation () {
4409
4657
  const vt = tween._valueType;
4410
4658
  if (vt === consts.valueTypes.COMPLEX) {
4411
4659
  tween._value = values.composeComplexValue(tween, 1, -1);
4412
- } else if (vt === consts.valueTypes.COLOR) {
4413
- tween._value = values.composeColorValue(tween, 1, -1);
4414
4660
  } else if (vt === consts.valueTypes.UNIT) {
4415
4661
  tween._value = `${tweenModifier(tween._toNumber)}${tween._unit}`;
4662
+ } else if (vt === consts.valueTypes.COLOR) {
4663
+ const d = toTargetObject.d;
4664
+ tween._value = `rgba(${helpers.round(d[0], 0)},${helpers.round(d[1], 0)},${helpers.round(d[2], 0)},${d[3]})`;
4416
4665
  } else {
4417
4666
  tween._value = tweenModifier(tween._toNumber);
4418
4667
  }
@@ -4420,8 +4669,7 @@ function requireAnimation () {
4420
4669
  if (isNaN(firstTweenChangeStartTime)) {
4421
4670
  firstTweenChangeStartTime = tween._startTime;
4422
4671
  }
4423
- // Rounding is necessary here to minimize floating point errors when working in seconds
4424
- lastTweenChangeEndTime = helpers.round(tweenStartTime + tweenUpdateDuration, 12);
4672
+
4425
4673
  prevTween = tween;
4426
4674
  animationAnimationLength++;
4427
4675
 
@@ -4527,8 +4775,11 @@ function requireAnimation () {
4527
4775
  tween._updateDuration = helpers.normalizeTime(tween._updateDuration * timeScale);
4528
4776
  tween._changeDuration = helpers.normalizeTime(tween._changeDuration * timeScale);
4529
4777
  tween._currentTime *= timeScale;
4778
+ tween._delay *= timeScale;
4530
4779
  tween._startTime *= timeScale;
4531
4780
  tween._absoluteStartTime *= timeScale;
4781
+ tween._absoluteUpdateStartTime *= timeScale;
4782
+ tween._absoluteEndTime *= timeScale;
4532
4783
  });
4533
4784
  return super.stretch(newDuration);
4534
4785
  }
@@ -4615,7 +4866,7 @@ var position = {};
4615
4866
 
4616
4867
  /**
4617
4868
  * Anime.js - timeline - CJS
4618
- * @version v4.4.1
4869
+ * @version v4.5.0
4619
4870
  * @license MIT
4620
4871
  * @copyright 2026 - Julian Garnier
4621
4872
  */
@@ -4694,7 +4945,7 @@ function requirePosition () {
4694
4945
 
4695
4946
  /**
4696
4947
  * Anime.js - timeline - CJS
4697
- * @version v4.4.1
4948
+ * @version v4.5.0
4698
4949
  * @license MIT
4699
4950
  * @copyright 2026 - Julian Garnier
4700
4951
  */
@@ -4732,6 +4983,7 @@ function requireTimeline () {
4732
4983
  * TimelinePosition,
4733
4984
  * StaggerFunction,
4734
4985
  * TargetsArray,
4986
+ * TweakRegister,
4735
4987
  * } from '../types/index.js'
4736
4988
  */
4737
4989
 
@@ -4741,8 +4993,6 @@ function requireTimeline () {
4741
4993
  * } from '../waapi/waapi.js'
4742
4994
  */
4743
4995
 
4744
- /** @import {TweakRegister} from 'tweaks' */
4745
-
4746
4996
  /**
4747
4997
  * @param {Timeline} tl
4748
4998
  * @return {Number}
@@ -4935,13 +5185,21 @@ function requireTimeline () {
4935
5185
  if (!helpers.isUnd(synced) && !helpers.isUnd(/** @type {WAAPIAnimation} */(synced).persist)) {
4936
5186
  /** @type {WAAPIAnimation} */(synced).persist = true;
4937
5187
  }
4938
- return this.add(synced, { currentTime: [0, duration], duration, delay: 0, ease: 'linear', playbackEase: 'linear' }, position);
5188
+ const editor = globals.globals.editor;
5189
+ const childHook = editor && editor.addTimelineChild;
5190
+ if (editor && editor.addTimelineSync) {
5191
+ position = editor.addTimelineSync(synced, position, this.id);
5192
+ editor.addTimelineChild = null; // Suppress the per-child hook for the internal .add, sync already registered.
5193
+ }
5194
+ const result = this.add(synced, { currentTime: [0, duration], duration, delay: 0, ease: 'linear', playbackEase: 'linear' }, position);
5195
+ if (editor) editor.addTimelineChild = childHook;
5196
+ return result;
4939
5197
  }
4940
5198
 
4941
5199
  /**
4942
5200
  * @param {TargetsParam} targets
4943
5201
  * @param {AnimationParams} parameters
4944
- * @param {TimelinePosition} [position]
5202
+ * @param {TimelinePosition|StaggerFunction<Number|String>|TweakRegister} [position]
4945
5203
  * @return {this}
4946
5204
  */
4947
5205
  set(targets, parameters, position) {
@@ -4958,6 +5216,7 @@ function requireTimeline () {
4958
5216
  */
4959
5217
  call(callback, position) {
4960
5218
  if (helpers.isUnd(callback) || callback && !helpers.isFnc(callback)) return this;
5219
+ if (globals.globals.editor && globals.globals.editor.addTimelineCall) position = globals.globals.editor.addTimelineCall(callback, position, this.id);
4961
5220
  return this.add({ duration: 0, delay: 0, onComplete: () => callback(this) }, position);
4962
5221
  }
4963
5222
 
@@ -4969,6 +5228,7 @@ function requireTimeline () {
4969
5228
  */
4970
5229
  label(labelName, position$1) {
4971
5230
  if (helpers.isUnd(labelName) || labelName && !helpers.isStr(labelName)) return this;
5231
+ if (globals.globals.editor && globals.globals.editor.addTimelineLabel) position$1 = globals.globals.editor.addTimelineLabel(labelName, position$1, this.id);
4972
5232
  this.labels[labelName] = position.parseTimelinePosition(this, position$1);
4973
5233
  return this;
4974
5234
  }
@@ -5049,7 +5309,7 @@ var animatable = {};
5049
5309
 
5050
5310
  /**
5051
5311
  * Anime.js - animatable - CJS
5052
- * @version v4.4.1
5312
+ * @version v4.5.0
5053
5313
  * @license MIT
5054
5314
  * @copyright 2026 - Julian Garnier
5055
5315
  */
@@ -5113,6 +5373,7 @@ function requireAnimatable () {
5113
5373
  const callbacksAnimationParams = { v: 1, autoplay: false };
5114
5374
  const properties = {};
5115
5375
  this.targets = [];
5376
+ /** @type {Record<String, JSAnimation>} */
5116
5377
  this.animations = {};
5117
5378
  /** @type {JSAnimation|null} */
5118
5379
  this.callbacks = null;
@@ -5210,7 +5471,7 @@ var number = {};
5210
5471
 
5211
5472
  /**
5212
5473
  * Anime.js - utils - CJS
5213
- * @version v4.4.1
5474
+ * @version v4.5.0
5214
5475
  * @license MIT
5215
5476
  * @copyright 2026 - Julian Garnier
5216
5477
  */
@@ -5316,7 +5577,7 @@ var spring = {};
5316
5577
 
5317
5578
  /**
5318
5579
  * Anime.js - easings - CJS
5319
- * @version v4.4.1
5580
+ * @version v4.5.0
5320
5581
  * @license MIT
5321
5582
  * @copyright 2026 - Julian Garnier
5322
5583
  */
@@ -5582,7 +5843,7 @@ var composition = {};
5582
5843
 
5583
5844
  /**
5584
5845
  * Anime.js - waapi - CJS
5585
- * @version v4.4.1
5846
+ * @version v4.5.0
5586
5847
  * @license MIT
5587
5848
  * @copyright 2026 - Julian Garnier
5588
5849
  */
@@ -5684,7 +5945,7 @@ function requireComposition () {
5684
5945
 
5685
5946
  /**
5686
5947
  * Anime.js - utils - CJS
5687
- * @version v4.4.1
5948
+ * @version v4.5.0
5688
5949
  * @license MIT
5689
5950
  * @copyright 2026 - Julian Garnier
5690
5951
  */
@@ -5781,6 +6042,9 @@ function requireTarget () {
5781
6042
  */
5782
6043
  const set = (targets, parameters) => {
5783
6044
  if (helpers.isUnd(parameters)) return;
6045
+ if (globals.globals.editor && globals.globals.editor.addSet) {
6046
+ return globals.globals.editor.addSet(targets, parameters);
6047
+ }
5784
6048
  parameters.duration = consts.minValue;
5785
6049
  // Do not overrides currently active tweens by default
5786
6050
  parameters.composition = values.setValue(parameters.composition, consts.compositionTypes.none);
@@ -5821,7 +6085,7 @@ function requireTarget () {
5821
6085
 
5822
6086
  /**
5823
6087
  * Anime.js - draggable - CJS
5824
- * @version v4.4.1
6088
+ * @version v4.5.0
5825
6089
  * @license MIT
5826
6090
  * @copyright 2026 - Julian Garnier
5827
6091
  */
@@ -7071,7 +7335,7 @@ var time = {};
7071
7335
 
7072
7336
  /**
7073
7337
  * Anime.js - utils - CJS
7074
- * @version v4.4.1
7338
+ * @version v4.5.0
7075
7339
  * @license MIT
7076
7340
  * @copyright 2026 - Julian Garnier
7077
7341
  */
@@ -7103,13 +7367,14 @@ function requireTime () {
7103
7367
  };
7104
7368
 
7105
7369
  /**
7106
- * @param {(...args: any[]) => Tickable | ((...args: any[]) => void) | void} constructor
7107
- * @return {(...args: any[]) => Tickable | ((...args: any[]) => void)}
7370
+ * @template {Tickable | ((...args: any[]) => void) | void} T
7371
+ * @param {(...args: any[]) => T} constructor
7372
+ * @return {(...args: any[]) => T extends void ? () => void : T}
7108
7373
  */
7109
7374
  const keepTime = constructor => {
7110
7375
  /** @type {Tickable} */
7111
7376
  let tracked;
7112
- return (...args) => {
7377
+ return /** @type {(...args: any[]) => T extends void ? () => void : T} */(/** @type {*} */((...args) => {
7113
7378
  let currentIteration, currentIterationProgress, reversed, alternate, startTime;
7114
7379
  if (tracked) {
7115
7380
  currentIteration = tracked.currentIteration;
@@ -7127,7 +7392,7 @@ function requireTime () {
7127
7392
  /** @type {Tickable} */(tracked)._startTime = startTime;
7128
7393
  }
7129
7394
  return cleanup || consts.noop;
7130
- }
7395
+ }));
7131
7396
  };
7132
7397
 
7133
7398
  time.keepTime = keepTime;
@@ -7137,7 +7402,7 @@ function requireTime () {
7137
7402
 
7138
7403
  /**
7139
7404
  * Anime.js - scope - CJS
7140
- * @version v4.4.1
7405
+ * @version v4.5.0
7141
7406
  * @license MIT
7142
7407
  * @copyright 2026 - Julian Garnier
7143
7408
  */
@@ -7400,7 +7665,7 @@ var scroll = {};
7400
7665
 
7401
7666
  /**
7402
7667
  * Anime.js - events - CJS
7403
- * @version v4.4.1
7668
+ * @version v4.5.0
7404
7669
  * @license MIT
7405
7670
  * @copyright 2026 - Julian Garnier
7406
7671
  */
@@ -7620,12 +7885,14 @@ function requireScroll () {
7620
7885
 
7621
7886
  refreshScrollObservers() {
7622
7887
  helpers.forEachChildren(this, (/** @type {ScrollObserver} */child) => {
7888
+ if (!child.ready) return;
7623
7889
  if (child._debug) {
7624
7890
  child.removeDebug();
7625
7891
  }
7626
7892
  });
7627
7893
  this.updateBounds();
7628
7894
  helpers.forEachChildren(this, (/** @type {ScrollObserver} */child) => {
7895
+ if (!child.ready) return;
7629
7896
  child.refresh();
7630
7897
  child.onResize(child);
7631
7898
  if (child._debug) {
@@ -8359,7 +8626,7 @@ var cubicBezier = {};
8359
8626
 
8360
8627
  /**
8361
8628
  * Anime.js - easings - CJS
8362
- * @version v4.4.1
8629
+ * @version v4.5.0
8363
8630
  * @license MIT
8364
8631
  * @copyright 2026 - Julian Garnier
8365
8632
  */
@@ -8432,7 +8699,7 @@ var steps = {};
8432
8699
 
8433
8700
  /**
8434
8701
  * Anime.js - easings - CJS
8435
- * @version v4.4.1
8702
+ * @version v4.5.0
8436
8703
  * @license MIT
8437
8704
  * @copyright 2026 - Julian Garnier
8438
8705
  */
@@ -8471,7 +8738,7 @@ var linear = {};
8471
8738
 
8472
8739
  /**
8473
8740
  * Anime.js - easings - CJS
8474
- * @version v4.4.1
8741
+ * @version v4.5.0
8475
8742
  * @license MIT
8476
8743
  * @copyright 2026 - Julian Garnier
8477
8744
  */
@@ -8539,7 +8806,7 @@ var irregular = {};
8539
8806
 
8540
8807
  /**
8541
8808
  * Anime.js - easings - CJS
8542
- * @version v4.4.1
8809
+ * @version v4.5.0
8543
8810
  * @license MIT
8544
8811
  * @copyright 2026 - Julian Garnier
8545
8812
  */
@@ -8587,7 +8854,7 @@ function requireIrregular () {
8587
8854
 
8588
8855
  /**
8589
8856
  * Anime.js - easings - CJS
8590
- * @version v4.4.1
8857
+ * @version v4.5.0
8591
8858
  * @license MIT
8592
8859
  * @copyright 2026 - Julian Garnier
8593
8860
  */
@@ -8624,7 +8891,7 @@ var waapi = {};
8624
8891
 
8625
8892
  /**
8626
8893
  * Anime.js - waapi - CJS
8627
- * @version v4.4.1
8894
+ * @version v4.5.0
8628
8895
  * @license MIT
8629
8896
  * @copyright 2026 - Julian Garnier
8630
8897
  */
@@ -9138,7 +9405,7 @@ function requireWaapi () {
9138
9405
 
9139
9406
  /**
9140
9407
  * Anime.js - layout - CJS
9141
- * @version v4.4.1
9408
+ * @version v4.5.0
9142
9409
  * @license MIT
9143
9410
  * @copyright 2026 - Julian Garnier
9144
9411
  */
@@ -10745,7 +11012,7 @@ var chainable = {};
10745
11012
 
10746
11013
  /**
10747
11014
  * Anime.js - utils - CJS
10748
- * @version v4.4.1
11015
+ * @version v4.5.0
10749
11016
  * @license MIT
10750
11017
  * @copyright 2026 - Julian Garnier
10751
11018
  */
@@ -10947,7 +11214,7 @@ var random = {};
10947
11214
 
10948
11215
  /**
10949
11216
  * Anime.js - utils - CJS
10950
- * @version v4.4.1
11217
+ * @version v4.5.0
10951
11218
  * @license MIT
10952
11219
  * @copyright 2026 - Julian Garnier
10953
11220
  */
@@ -11014,11 +11281,12 @@ function requireRandom () {
11014
11281
  * Adapted from https://bost.ocks.org/mike/shuffle/
11015
11282
  *
11016
11283
  * @param {Array} items - The array to shuffle (will be modified in-place)
11284
+ * @param {RandomNumberGenerator} [rnd] - Optional RNG matching the random() signature (defaults to random)
11017
11285
  * @return {Array} The same array reference, now shuffled
11018
11286
  */
11019
- const shuffle = items => {
11287
+ const shuffle = (items, rnd = random$1) => {
11020
11288
  let m = items.length, t, i;
11021
- while (m) { i = random$1(0, --m); t = items[m]; items[m] = items[i]; items[i] = t; }
11289
+ while (m) { i = rnd(0, --m); t = items[m]; items[m] = items[i]; items[i] = t; }
11022
11290
  return items;
11023
11291
  };
11024
11292
 
@@ -11033,7 +11301,7 @@ var stagger = {};
11033
11301
 
11034
11302
  /**
11035
11303
  * Anime.js - utils - CJS
11036
- * @version v4.4.1
11304
+ * @version v4.5.0
11037
11305
  * @license MIT
11038
11306
  * @copyright 2026 - Julian Garnier
11039
11307
  */
@@ -11103,6 +11371,7 @@ function requireStagger () {
11103
11371
  let values$1 = [];
11104
11372
  let maxValue = 0;
11105
11373
  let cachedOffset;
11374
+ let jitterSamples = null;
11106
11375
  const from = params.from;
11107
11376
  const reversed = params.reversed;
11108
11377
  const ease = params.ease;
@@ -11124,27 +11393,42 @@ function requireStagger () {
11124
11393
  const val2 = isRange ? helpers.parseNumber(val[1]) : 0;
11125
11394
  const unitMatch = consts.unitsExecRgx.exec((isRange ? val[1] : val) + consts.emptyString);
11126
11395
  const start = params.start || 0 + (isRange ? val1 : 0);
11396
+ const seed = params.seed;
11397
+ const hasSeed = !helpers.isUnd(seed) && seed !== false;
11398
+ const rng = hasSeed ? random.createSeededRandom(seed === true ? 0 : /** @type {Number} */(seed)) : random.random;
11399
+ const jitter = params.jitter;
11400
+ const hasJitter = !helpers.isUnd(jitter);
11401
+ const jitterIsArr = helpers.isArr(jitter);
11402
+ const jitterStart = jitterIsArr ? /** @type {[Number,Number]} */(jitter)[0] : /** @type {Number} */(jitter) || 0;
11403
+ const jitterEnd = jitterIsArr ? /** @type {[Number,Number]} */(jitter)[1] : /** @type {Number} */(jitter) || 0;
11127
11404
  let fromIndex = fromFirst ? 0 : helpers.isNum(from) ? from : 0;
11128
11405
  return (target, i, t, _, tl) => {
11129
11406
  const [ registeredTarget ] = targets.registerTargets(target);
11130
11407
  const total = helpers.isUnd(customTotal) ? t.length : customTotal;
11131
11408
  const customIndex = !helpers.isUnd(useProp) ? helpers.isFnc(useProp) ? useProp(registeredTarget, i, total) : values.getOriginalAnimatableValue(registeredTarget, useProp) : false;
11132
- const staggerIndex = helpers.isNum(customIndex) || helpers.isStr(customIndex) && helpers.isNum(+customIndex) ? +customIndex : i;
11409
+ const customIdx = helpers.isNum(customIndex) || helpers.isStr(customIndex) && helpers.isNum(+customIndex) ? +customIndex : i;
11410
+ // Fall back to the natural index when the resolved value lands outside [0, total) so values[staggerIndex] never reads undefined.
11411
+ const staggerIndex = customIdx >= 0 && customIdx < total ? customIdx : i;
11133
11412
  if (fromCenter) fromIndex = (total - 1) / 2;
11134
11413
  if (fromLast) fromIndex = total - 1;
11135
11414
  if (!values$1.length) {
11136
11415
  if (autoGrid) {
11137
11416
  let hasPositions = true;
11417
+ let has3D = false;
11138
11418
  let minPosX = Infinity;
11139
11419
  let minPosY = Infinity;
11420
+ let minPosZ = Infinity;
11140
11421
  let maxPosX = -Infinity;
11141
11422
  let maxPosY = -Infinity;
11423
+ let maxPosZ = -Infinity;
11142
11424
  const pxArr = [];
11143
11425
  const pyArr = [];
11426
+ const pzArr = [];
11144
11427
  for (let index = 0; index < total; index++) {
11145
11428
  const el = t[index];
11146
11429
  let px = 0;
11147
11430
  let py = 0;
11431
+ let pz = 0;
11148
11432
  let found = false;
11149
11433
  if (el && helpers.isFnc(el.getBoundingClientRect)) {
11150
11434
  const rect = el.getBoundingClientRect();
@@ -11156,6 +11440,10 @@ function requireStagger () {
11156
11440
  if (obj && helpers.isNum(obj.x) && helpers.isNum(obj.y)) {
11157
11441
  px = obj.x;
11158
11442
  py = obj.y;
11443
+ if (helpers.isNum(obj.z)) {
11444
+ pz = obj.z;
11445
+ has3D = true;
11446
+ }
11159
11447
  found = true;
11160
11448
  }
11161
11449
  }
@@ -11165,42 +11453,52 @@ function requireStagger () {
11165
11453
  }
11166
11454
  pxArr.push(px);
11167
11455
  pyArr.push(py);
11456
+ pzArr.push(pz);
11168
11457
  if (px < minPosX) minPosX = px;
11169
11458
  if (py < minPosY) minPosY = py;
11459
+ if (pz < minPosZ) minPosZ = pz;
11170
11460
  if (px > maxPosX) maxPosX = px;
11171
11461
  if (py > maxPosY) maxPosY = py;
11462
+ if (pz > maxPosZ) maxPosZ = pz;
11172
11463
  }
11173
11464
  if (hasPositions) {
11174
11465
  let fX = pxArr[0];
11175
11466
  let fY = pyArr[0];
11467
+ let fZ = pzArr[0];
11176
11468
  if (fromArr) {
11177
11469
  fX = minPosX + from[0] * (maxPosX - minPosX);
11178
11470
  fY = minPosY + from[1] * (maxPosY - minPosY);
11471
+ fZ = has3D ? minPosZ + (from.length >= 3 ? from[2] : 0.5) * (maxPosZ - minPosZ) : 0;
11179
11472
  } else if (fromCenter) {
11180
11473
  fX = (minPosX + maxPosX) / 2;
11181
11474
  fY = (minPosY + maxPosY) / 2;
11475
+ fZ = (minPosZ + maxPosZ) / 2;
11182
11476
  } else if (fromLast) {
11183
11477
  fX = pxArr[total - 1];
11184
11478
  fY = pyArr[total - 1];
11479
+ fZ = pzArr[total - 1];
11185
11480
  } else if (helpers.isNum(from)) {
11186
11481
  fX = pxArr[from];
11187
11482
  fY = pyArr[from];
11483
+ fZ = pzArr[from];
11188
11484
  }
11189
11485
  for (let index = 0; index < total; index++) {
11190
11486
  const distanceX = fX - pxArr[index];
11191
11487
  const distanceY = fY - pyArr[index];
11192
- let value = helpers.sqrt(distanceX * distanceX + distanceY * distanceY);
11488
+ const distanceZ = fZ - pzArr[index];
11489
+ let value = helpers.sqrt(distanceX * distanceX + distanceY * distanceY + (has3D ? distanceZ * distanceZ : 0));
11193
11490
  if (axis === 'x') value = -distanceX;
11194
11491
  if (axis === 'y') value = -distanceY;
11492
+ if (axis === 'z') value = -distanceZ;
11195
11493
  values$1.push(value);
11196
11494
  }
11197
11495
  let minDist = Infinity;
11198
- for (let index = 0, l = values$1.length; index < l; index++) {
11496
+ for (let index = 0; index < total; index++) {
11199
11497
  const absVal = helpers.abs(values$1[index]);
11200
11498
  if (absVal > 0 && absVal < minDist) minDist = absVal;
11201
11499
  }
11202
11500
  if (minDist > 0 && minDist < Infinity) {
11203
- for (let index = 0, l = values$1.length; index < l; index++) {
11501
+ for (let index = 0; index < total; index++) {
11204
11502
  values$1[index] = values$1[index] / minDist;
11205
11503
  }
11206
11504
  }
@@ -11214,32 +11512,51 @@ function requireStagger () {
11214
11512
  if (!grid) {
11215
11513
  values$1.push(helpers.abs(fromIndex - index));
11216
11514
  } else {
11217
- let fromX, fromY;
11515
+ const dims = grid.length;
11516
+ const wh = grid[0] * grid[1];
11517
+ let fromX, fromY, fromZ;
11218
11518
  if (fromArr) {
11219
11519
  fromX = from[0] * (grid[0] - 1);
11220
11520
  fromY = from[1] * (grid[1] - 1);
11521
+ fromZ = dims === 3 ? (from.length >= 3 ? from[2] : 0.5) * (grid[2] - 1) : 0;
11221
11522
  } else if (fromCenter) {
11222
11523
  fromX = (grid[0] - 1) / 2;
11223
11524
  fromY = (grid[1] - 1) / 2;
11525
+ fromZ = dims === 3 ? (grid[2] - 1) / 2 : 0;
11224
11526
  } else {
11225
11527
  fromX = fromIndex % grid[0];
11226
- fromY = helpers.floor(fromIndex / grid[0]);
11528
+ fromY = helpers.floor(fromIndex / grid[0]) % grid[1];
11529
+ fromZ = dims === 3 ? helpers.floor(fromIndex / wh) : 0;
11227
11530
  }
11228
11531
  const toX = index % grid[0];
11229
- const toY = helpers.floor(index / grid[0]);
11532
+ const toY = helpers.floor(index / grid[0]) % grid[1];
11533
+ const toZ = dims === 3 ? helpers.floor(index / wh) : 0;
11230
11534
  const distanceX = fromX - toX;
11231
11535
  const distanceY = fromY - toY;
11232
- let value = helpers.sqrt(distanceX * distanceX + distanceY * distanceY);
11536
+ const distanceZ = fromZ - toZ;
11537
+ let value = helpers.sqrt(distanceX * distanceX + distanceY * distanceY + (dims === 3 ? distanceZ * distanceZ : 0));
11233
11538
  if (axis === 'x') value = -distanceX;
11234
11539
  if (axis === 'y') value = -distanceY;
11540
+ if (axis === 'z') value = -distanceZ;
11235
11541
  values$1.push(value);
11236
11542
  }
11237
11543
  }
11238
11544
  }
11239
- maxValue = helpers.max(...values$1);
11240
- if (staggerEase) values$1 = values$1.map(val => staggerEase(val / maxValue) * maxValue);
11241
- if (reversed) values$1 = values$1.map(val => axis ? (val < 0) ? val * -1 : -val : helpers.abs(maxValue - val));
11242
- if (fromRandom) values$1 = random.shuffle(values$1);
11545
+ maxValue = values$1[0];
11546
+ for (let k = 1; k < total; k++) if (values$1[k] > maxValue) maxValue = values$1[k];
11547
+ if (staggerEase || reversed) {
11548
+ for (let k = 0; k < total; k++) {
11549
+ let v = values$1[k];
11550
+ if (staggerEase) v = staggerEase(v / maxValue) * maxValue;
11551
+ if (reversed) v = axis ? -v : helpers.abs(maxValue - v);
11552
+ values$1[k] = v;
11553
+ }
11554
+ }
11555
+ if (hasJitter) {
11556
+ jitterSamples = new Array(total);
11557
+ for (let k = 0; k < total; k++) jitterSamples[k] = rng(-1, 1, 4);
11558
+ }
11559
+ if (fromRandom) values$1 = random.shuffle(values$1, rng);
11243
11560
  }
11244
11561
  const spacing = isRange ? (val2 - val1) / maxValue : val1;
11245
11562
  if (helpers.isUnd(cachedOffset)) {
@@ -11247,6 +11564,11 @@ function requireStagger () {
11247
11564
  }
11248
11565
  /** @type {String|Number} */
11249
11566
  let output = cachedOffset + ((spacing * helpers.round(values$1[staggerIndex], 2)) || 0);
11567
+ if (hasJitter) {
11568
+ const progress = maxValue ? values$1[staggerIndex] / maxValue : 0;
11569
+ const mag = jitterStart + (jitterEnd - jitterStart) * progress;
11570
+ output = /** @type {Number} */(output) + jitterSamples[staggerIndex] * mag;
11571
+ }
11250
11572
  if (params.modifier) output = params.modifier(/** @type {Number} */(output));
11251
11573
  if (unitMatch) output = `${output}${unitMatch[2]}`;
11252
11574
  return output;
@@ -11259,7 +11581,7 @@ function requireStagger () {
11259
11581
 
11260
11582
  /**
11261
11583
  * Anime.js - utils - CJS
11262
- * @version v4.4.1
11584
+ * @version v4.5.0
11263
11585
  * @license MIT
11264
11586
  * @copyright 2026 - Julian Garnier
11265
11587
  */
@@ -11319,7 +11641,7 @@ var helpers = {};
11319
11641
 
11320
11642
  /**
11321
11643
  * Anime.js - svg - CJS
11322
- * @version v4.4.1
11644
+ * @version v4.5.0
11323
11645
  * @license MIT
11324
11646
  * @copyright 2026 - Julian Garnier
11325
11647
  */
@@ -11356,7 +11678,7 @@ function requireHelpers () {
11356
11678
 
11357
11679
  /**
11358
11680
  * Anime.js - svg - CJS
11359
- * @version v4.4.1
11681
+ * @version v4.5.0
11360
11682
  * @license MIT
11361
11683
  * @copyright 2026 - Julian Garnier
11362
11684
  */
@@ -11455,7 +11777,7 @@ var drawable = {};
11455
11777
 
11456
11778
  /**
11457
11779
  * Anime.js - svg - CJS
11458
- * @version v4.4.1
11780
+ * @version v4.5.0
11459
11781
  * @license MIT
11460
11782
  * @copyright 2026 - Julian Garnier
11461
11783
  */
@@ -11583,7 +11905,7 @@ var morphto = {};
11583
11905
 
11584
11906
  /**
11585
11907
  * Anime.js - svg - CJS
11586
- * @version v4.4.1
11908
+ * @version v4.5.0
11587
11909
  * @license MIT
11588
11910
  * @copyright 2026 - Julian Garnier
11589
11911
  */
@@ -11655,7 +11977,7 @@ function requireMorphto () {
11655
11977
 
11656
11978
  /**
11657
11979
  * Anime.js - svg - CJS
11658
- * @version v4.4.1
11980
+ * @version v4.5.0
11659
11981
  * @license MIT
11660
11982
  * @copyright 2026 - Julian Garnier
11661
11983
  */
@@ -11684,7 +12006,7 @@ var split = {};
11684
12006
 
11685
12007
  /**
11686
12008
  * Anime.js - text - CJS
11687
- * @version v4.4.1
12009
+ * @version v4.5.0
11688
12010
  * @license MIT
11689
12011
  * @copyright 2026 - Julian Garnier
11690
12012
  */
@@ -11806,6 +12128,7 @@ function requireSplit () {
11806
12128
  */
11807
12129
  const generateTemplate = (type, params = {}) => {
11808
12130
  let template = ``;
12131
+ if (!params) params = {};
11809
12132
  const classString = helpers.isStr(params.class) ? ` class="${params.class}"` : '';
11810
12133
  const cloneType = values.setValue(params.clone, false);
11811
12134
  const wrapType = values.setValue(params.wrap, false);
@@ -12195,7 +12518,7 @@ var scramble = {};
12195
12518
 
12196
12519
  /**
12197
12520
  * Anime.js - text - CJS
12198
- * @version v4.4.1
12521
+ * @version v4.5.0
12199
12522
  * @license MIT
12200
12523
  * @copyright 2026 - Julian Garnier
12201
12524
  */
@@ -12219,6 +12542,16 @@ function requireScramble () {
12219
12542
  * } from '../types/index.js'
12220
12543
  */
12221
12544
 
12545
+ /**
12546
+ * @typedef {Object} ScrambleTextTween
12547
+ * @property {Number} from
12548
+ * @property {Number} to
12549
+ * @property {Number} duration
12550
+ * @property {Number} delay
12551
+ * @property {String} ease
12552
+ * @property {(v: Number) => String} modifier
12553
+ */
12554
+
12222
12555
  /**
12223
12556
  * '-' is the range operator; place it at the start or end of the string to use it as a literal (e.g. '-abc' or 'abc-')
12224
12557
  * @param {String} str
@@ -12256,7 +12589,7 @@ function requireScramble () {
12256
12589
  * progressively revealing the original text.
12257
12590
  *
12258
12591
  * @param {ScrambleTextParams} [params]
12259
- * @return {FunctionValue}
12592
+ * @return {FunctionValue<ScrambleTextTween>}
12260
12593
  */
12261
12594
  const scrambleText = (params = {}) => {
12262
12595
  if (!params) params = {};
@@ -12474,7 +12807,7 @@ function requireScramble () {
12474
12807
 
12475
12808
  /**
12476
12809
  * Anime.js - text - CJS
12477
- * @version v4.4.1
12810
+ * @version v4.5.0
12478
12811
  * @license MIT
12479
12812
  * @copyright 2026 - Julian Garnier
12480
12813
  */
@@ -12499,7 +12832,7 @@ function requireText () {
12499
12832
 
12500
12833
  /**
12501
12834
  * Anime.js - CJS
12502
- * @version v4.4.1
12835
+ * @version v4.5.0
12503
12836
  * @license MIT
12504
12837
  * @copyright 2026 - Julian Garnier
12505
12838
  */