@tsparticles/fireworks 3.0.3 → 3.1.0

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.
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v3.0.3
7
+ * v3.1.0
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -139,6 +139,7 @@ __webpack_require__.d(__webpack_exports__, {
139
139
  colorToHsl: () => (/* reexport */ colorToHsl),
140
140
  colorToRgb: () => (/* reexport */ colorToRgb),
141
141
  deepExtend: () => (/* reexport */ deepExtend),
142
+ degToRad: () => (/* reexport */ degToRad),
142
143
  divMode: () => (/* reexport */ divMode),
143
144
  divModeExecute: () => (/* reexport */ divModeExecute),
144
145
  drawEffect: () => (/* reexport */ drawEffect),
@@ -172,6 +173,7 @@ __webpack_require__.d(__webpack_exports__, {
172
173
  getSize: () => (/* reexport */ getSize),
173
174
  getStyleFromHsl: () => (/* reexport */ getStyleFromHsl),
174
175
  getStyleFromRgb: () => (/* reexport */ getStyleFromRgb),
176
+ halfRandom: () => (/* reexport */ halfRandom),
175
177
  hasMatchMedia: () => (/* reexport */ hasMatchMedia),
176
178
  hslToRgb: () => (/* reexport */ hslToRgb),
177
179
  hslaToRgba: () => (/* reexport */ hslaToRgba),
@@ -191,6 +193,7 @@ __webpack_require__.d(__webpack_exports__, {
191
193
  loadFont: () => (/* reexport */ loadFont),
192
194
  loadOptions: () => (/* reexport */ loadOptions),
193
195
  loadParticlesOptions: () => (/* reexport */ loadParticlesOptions),
196
+ millisecondsToSeconds: () => (/* reexport */ millisecondsToSeconds),
194
197
  mix: () => (/* reexport */ mix),
195
198
  mouseDownEvent: () => (/* reexport */ mouseDownEvent),
196
199
  mouseLeaveEvent: () => (/* reexport */ mouseLeaveEvent),
@@ -200,6 +203,7 @@ __webpack_require__.d(__webpack_exports__, {
200
203
  paintBase: () => (/* reexport */ paintBase),
201
204
  paintImage: () => (/* reexport */ paintImage),
202
205
  parseAlpha: () => (/* reexport */ parseAlpha),
206
+ percentDenominator: () => (/* reexport */ percentDenominator),
203
207
  randomInRange: () => (/* reexport */ randomInRange),
204
208
  rangeColorToHsl: () => (/* reexport */ rangeColorToHsl),
205
209
  rangeColorToRgb: () => (/* reexport */ rangeColorToRgb),
@@ -220,6 +224,9 @@ __webpack_require__.d(__webpack_exports__, {
220
224
  touchMoveEvent: () => (/* reexport */ touchMoveEvent),
221
225
  touchStartEvent: () => (/* reexport */ touchStartEvent),
222
226
  tsParticles: () => (/* reexport */ tsParticles),
227
+ updateAnimation: () => (/* reexport */ updateAnimation),
228
+ updateColor: () => (/* reexport */ updateColor),
229
+ updateColorValue: () => (/* reexport */ updateColorValue),
223
230
  visibilityChangeEvent: () => (/* reexport */ visibilityChangeEvent)
224
231
  });
225
232
 
@@ -237,9 +244,19 @@ const touchCancelEvent = "touchcancel";
237
244
  const resizeEvent = "resize";
238
245
  const visibilityChangeEvent = "visibilitychange";
239
246
  const errorPrefix = "tsParticles - Error";
247
+ const percentDenominator = 100;
248
+ const halfRandom = 0.5;
249
+ const millisecondsToSeconds = 1000;
240
250
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/Vector3d.js
241
251
 
242
252
 
253
+ const origin = {
254
+ x: 0,
255
+ y: 0,
256
+ z: 0
257
+ },
258
+ squareExp = 2,
259
+ inverseFactorNumerator = 1.0;
243
260
  class Vector3d {
244
261
  constructor(xOrCoords, y, z) {
245
262
  this._updateFromAngle = (angle, length) => {
@@ -250,17 +267,17 @@ class Vector3d {
250
267
  this.x = xOrCoords.x;
251
268
  this.y = xOrCoords.y;
252
269
  const coords3d = xOrCoords;
253
- this.z = coords3d.z ? coords3d.z : 0;
270
+ this.z = coords3d.z ? coords3d.z : origin.z;
254
271
  } else if (xOrCoords !== undefined && y !== undefined) {
255
272
  this.x = xOrCoords;
256
273
  this.y = y;
257
- this.z = z ?? 0;
274
+ this.z = z ?? origin.z;
258
275
  } else {
259
276
  throw new Error(`${errorPrefix} Vector3d not initialized correctly`);
260
277
  }
261
278
  }
262
279
  static get origin() {
263
- return Vector3d.create(0, 0, 0);
280
+ return Vector3d.create(origin.x, origin.y, origin.z);
264
281
  }
265
282
  get angle() {
266
283
  return Math.atan2(this.y, this.x);
@@ -306,7 +323,7 @@ class Vector3d {
306
323
  this.z /= n;
307
324
  }
308
325
  getLengthSq() {
309
- return this.x ** 2 + this.y ** 2;
326
+ return this.x ** squareExp + this.y ** squareExp;
310
327
  }
311
328
  mult(n) {
312
329
  return Vector3d.create(this.x * n, this.y * n, this.z * n);
@@ -317,19 +334,20 @@ class Vector3d {
317
334
  this.z *= n;
318
335
  }
319
336
  normalize() {
320
- const length = this.length;
321
- if (length != 0) {
322
- this.multTo(1.0 / length);
337
+ const length = this.length,
338
+ noLength = 0;
339
+ if (length != noLength) {
340
+ this.multTo(inverseFactorNumerator / length);
323
341
  }
324
342
  }
325
343
  rotate(angle) {
326
- return Vector3d.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle), 0);
344
+ return Vector3d.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle), origin.z);
327
345
  }
328
346
  setTo(c) {
329
347
  this.x = c.x;
330
348
  this.y = c.y;
331
349
  const v3d = c;
332
- this.z = v3d.z ? v3d.z : 0;
350
+ this.z = v3d.z ? v3d.z : origin.z;
333
351
  }
334
352
  sub(v) {
335
353
  return Vector3d.create(this.x - v.x, this.y - v.y, this.z - v.z);
@@ -342,12 +360,17 @@ class Vector3d {
342
360
  }
343
361
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/Vector.js
344
362
 
363
+ const Vector_origin = {
364
+ x: 0,
365
+ y: 0,
366
+ z: 0
367
+ };
345
368
  class Vector extends Vector3d {
346
369
  constructor(xOrCoords, y) {
347
- super(xOrCoords, y, 0);
370
+ super(xOrCoords, y, Vector_origin.z);
348
371
  }
349
372
  static get origin() {
350
- return Vector.create(0, 0);
373
+ return Vector.create(Vector_origin.x, Vector_origin.y);
351
374
  }
352
375
  static clone(source) {
353
376
  return Vector.create(source.x, source.y);
@@ -359,8 +382,11 @@ class Vector extends Vector3d {
359
382
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/NumberUtils.js
360
383
 
361
384
 
385
+
362
386
  let _random = Math.random;
363
- const easings = new Map();
387
+ const easings = new Map(),
388
+ NumberUtils_double = 2,
389
+ doublePI = Math.PI * NumberUtils_double;
364
390
  function addEasing(name, easing) {
365
391
  if (easings.get(name)) {
366
392
  return;
@@ -368,13 +394,15 @@ function addEasing(name, easing) {
368
394
  easings.set(name, easing);
369
395
  }
370
396
  function getEasing(name) {
371
- return easings.get(name) || (value => value);
397
+ return easings.get(name) ?? (value => value);
372
398
  }
373
399
  function setRandom(rnd = Math.random) {
374
400
  _random = rnd;
375
401
  }
376
402
  function getRandom() {
377
- return clamp(_random(), 0, 1 - 1e-16);
403
+ const min = 0,
404
+ max = 1;
405
+ return clamp(_random(), min, max - Number.EPSILON);
378
406
  }
379
407
  function clamp(num, min, max) {
380
408
  return Math.min(Math.max(num, min), max);
@@ -383,10 +411,11 @@ function mix(comp1, comp2, weight1, weight2) {
383
411
  return Math.floor((comp1 * weight1 + comp2 * weight2) / (weight1 + weight2));
384
412
  }
385
413
  function randomInRange(r) {
386
- const max = getRangeMax(r);
414
+ const max = getRangeMax(r),
415
+ minOffset = 0;
387
416
  let min = getRangeMin(r);
388
417
  if (max === min) {
389
- min = 0;
418
+ min = minOffset;
390
419
  }
391
420
  return getRandom() * (max - min) + min;
392
421
  }
@@ -412,43 +441,52 @@ function setRangeValue(source, value) {
412
441
  }
413
442
  function getDistances(pointA, pointB) {
414
443
  const dx = pointA.x - pointB.x,
415
- dy = pointA.y - pointB.y;
444
+ dy = pointA.y - pointB.y,
445
+ squareExp = 2;
416
446
  return {
417
447
  dx: dx,
418
448
  dy: dy,
419
- distance: Math.sqrt(dx ** 2 + dy ** 2)
449
+ distance: Math.sqrt(dx ** squareExp + dy ** squareExp)
420
450
  };
421
451
  }
422
452
  function getDistance(pointA, pointB) {
423
453
  return getDistances(pointA, pointB).distance;
424
454
  }
455
+ function degToRad(degrees) {
456
+ const PIDeg = 180;
457
+ return degrees * Math.PI / PIDeg;
458
+ }
425
459
  function getParticleDirectionAngle(direction, position, center) {
426
460
  if (isNumber(direction)) {
427
- return direction * Math.PI / 180;
461
+ return degToRad(direction);
428
462
  }
463
+ const empty = 0,
464
+ half = 0.5,
465
+ quarter = 0.25,
466
+ threeQuarter = half + quarter;
429
467
  switch (direction) {
430
468
  case "top":
431
- return -Math.PI * 0.5;
469
+ return -Math.PI * half;
432
470
  case "top-right":
433
- return -Math.PI * 0.25;
471
+ return -Math.PI * quarter;
434
472
  case "right":
435
- return 0;
473
+ return empty;
436
474
  case "bottom-right":
437
- return Math.PI * 0.25;
475
+ return Math.PI * quarter;
438
476
  case "bottom":
439
- return Math.PI * 0.5;
477
+ return Math.PI * half;
440
478
  case "bottom-left":
441
- return Math.PI * 0.75;
479
+ return Math.PI * threeQuarter;
442
480
  case "left":
443
481
  return Math.PI;
444
482
  case "top-left":
445
- return -Math.PI * 0.75;
483
+ return -Math.PI * threeQuarter;
446
484
  case "inside":
447
485
  return Math.atan2(center.y - position.y, center.x - position.x);
448
486
  case "outside":
449
487
  return Math.atan2(position.y - center.y, position.x - center.x);
450
488
  default:
451
- return getRandom() * Math.PI * 2;
489
+ return getRandom() * doublePI;
452
490
  }
453
491
  }
454
492
  function getParticleBaseVelocity(direction) {
@@ -458,18 +496,19 @@ function getParticleBaseVelocity(direction) {
458
496
  return baseVelocity;
459
497
  }
460
498
  function collisionVelocity(v1, v2, m1, m2) {
461
- return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * 2 * m2 / (m1 + m2), v1.y);
499
+ const double = 2;
500
+ return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * double * m2 / (m1 + m2), v1.y);
462
501
  }
463
502
  function calcPositionFromSize(data) {
464
- return data.position && data.position.x !== undefined && data.position.y !== undefined ? {
465
- x: data.position.x * data.size.width / 100,
466
- y: data.position.y * data.size.height / 100
503
+ return data.position?.x !== undefined && data.position.y !== undefined ? {
504
+ x: data.position.x * data.size.width / percentDenominator,
505
+ y: data.position.y * data.size.height / percentDenominator
467
506
  } : undefined;
468
507
  }
469
508
  function calcPositionOrRandomFromSize(data) {
470
509
  return {
471
- x: (data.position?.x ?? getRandom() * 100) * data.size.width / 100,
472
- y: (data.position?.y ?? getRandom() * 100) * data.size.height / 100
510
+ x: (data.position?.x ?? getRandom() * percentDenominator) * data.size.width / percentDenominator,
511
+ y: (data.position?.y ?? getRandom() * percentDenominator) * data.size.height / percentDenominator
473
512
  };
474
513
  }
475
514
  function calcPositionOrRandomFromSizeRanged(data) {
@@ -499,11 +538,16 @@ function calcExactPositionOrRandomFromSizeRanged(data) {
499
538
  });
500
539
  }
501
540
  function parseAlpha(input) {
502
- return input ? input.endsWith("%") ? parseFloat(input) / 100 : parseFloat(input) : 1;
541
+ const defaultAlpha = 1;
542
+ if (!input) {
543
+ return defaultAlpha;
544
+ }
545
+ return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
503
546
  }
504
547
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/Utils.js
505
548
 
506
549
 
550
+
507
551
  const _logger = {
508
552
  debug: console.debug,
509
553
  error: console.error,
@@ -534,11 +578,13 @@ function rectSideBounce(data) {
534
578
  rectOtherSide,
535
579
  velocity,
536
580
  factor
537
- } = data;
581
+ } = data,
582
+ half = 0.5,
583
+ minVelocity = 0;
538
584
  if (pOtherSide.min < rectOtherSide.min || pOtherSide.min > rectOtherSide.max || pOtherSide.max < rectOtherSide.min || pOtherSide.max > rectOtherSide.max) {
539
585
  return res;
540
586
  }
541
- if (pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) * 0.5 && velocity > 0 || pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) * 0.5 && velocity < 0) {
587
+ if (pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) * half && velocity > minVelocity || pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) * half && velocity < minVelocity) {
542
588
  res.velocity = velocity * -factor;
543
589
  res.bounced = true;
544
590
  }
@@ -575,7 +621,8 @@ function safeMutationObserver(callback) {
575
621
  return new MutationObserver(callback);
576
622
  }
577
623
  function isInArray(value, array) {
578
- return value === array || isArray(array) && array.indexOf(value) > -1;
624
+ const invalidIndex = -1;
625
+ return value === array || isArray(array) && array.indexOf(value) > invalidIndex;
579
626
  }
580
627
  async function loadFont(font, weight) {
581
628
  try {
@@ -589,7 +636,8 @@ function itemFromArray(array, index, useIndex = true) {
589
636
  return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
590
637
  }
591
638
  function isPointInside(point, size, offset, radius, direction) {
592
- return areBoundsInside(calculateBounds(point, radius ?? 0), size, offset, direction);
639
+ const minRadius = 0;
640
+ return areBoundsInside(calculateBounds(point, radius ?? minRadius), size, offset, direction);
593
641
  }
594
642
  function areBoundsInside(bounds, size, offset, direction) {
595
643
  let inside = true;
@@ -686,8 +734,9 @@ function circleBounce(p1, p2) {
686
734
  {
687
735
  dx: xDist,
688
736
  dy: yDist
689
- } = getDistances(pos2, pos1);
690
- if (xVelocityDiff * xDist + yVelocityDiff * yDist < 0) {
737
+ } = getDistances(pos2, pos1),
738
+ minimumDistance = 0;
739
+ if (xVelocityDiff * xDist + yVelocityDiff * yDist < minimumDistance) {
691
740
  return;
692
741
  }
693
742
  const angle = -Math.atan2(yDist, xDist),
@@ -767,19 +816,24 @@ function rectBounce(particle, divBounds) {
767
816
  }
768
817
  }
769
818
  function executeOnSingleOrMultiple(obj, callback) {
770
- return isArray(obj) ? obj.map((item, index) => callback(item, index)) : callback(obj, 0);
819
+ const defaultIndex = 0;
820
+ return isArray(obj) ? obj.map((item, index) => callback(item, index)) : callback(obj, defaultIndex);
771
821
  }
772
822
  function itemFromSingleOrMultiple(obj, index, useIndex) {
773
823
  return isArray(obj) ? itemFromArray(obj, index, useIndex) : obj;
774
824
  }
775
825
  function findItemFromSingleOrMultiple(obj, callback) {
776
- return isArray(obj) ? obj.find((t, index) => callback(t, index)) : callback(obj, 0) ? obj : undefined;
826
+ if (isArray(obj)) {
827
+ return obj.find((t, index) => callback(t, index));
828
+ }
829
+ const defaultIndex = 0;
830
+ return callback(obj, defaultIndex) ? obj : undefined;
777
831
  }
778
832
  function initParticleNumericAnimationValue(options, pxRatio) {
779
833
  const valueRange = options.value,
780
834
  animationOptions = options.animation,
781
835
  res = {
782
- delayTime: getRangeValue(animationOptions.delay) * 1000,
836
+ delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
783
837
  enable: animationOptions.enable,
784
838
  value: getRangeValue(options.value) * pxRatio,
785
839
  max: getRangeMax(valueRange) * pxRatio,
@@ -787,9 +841,10 @@ function initParticleNumericAnimationValue(options, pxRatio) {
787
841
  loops: 0,
788
842
  maxLoops: getRangeValue(animationOptions.count),
789
843
  time: 0
790
- };
844
+ },
845
+ decayOffset = 1;
791
846
  if (animationOptions.enable) {
792
- res.decay = 1 - getRangeValue(animationOptions.decay);
847
+ res.decay = decayOffset - getRangeValue(animationOptions.decay);
793
848
  switch (animationOptions.mode) {
794
849
  case "increase":
795
850
  res.status = "increasing";
@@ -798,7 +853,7 @@ function initParticleNumericAnimationValue(options, pxRatio) {
798
853
  res.status = "decreasing";
799
854
  break;
800
855
  case "random":
801
- res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
856
+ res.status = getRandom() >= halfRandom ? "increasing" : "decreasing";
802
857
  break;
803
858
  }
804
859
  const autoStatus = animationOptions.mode === "auto";
@@ -819,7 +874,7 @@ function initParticleNumericAnimationValue(options, pxRatio) {
819
874
  default:
820
875
  res.value = randomInRange(res);
821
876
  if (autoStatus) {
822
- res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
877
+ res.status = getRandom() >= halfRandom ? "increasing" : "decreasing";
823
878
  }
824
879
  break;
825
880
  }
@@ -839,13 +894,13 @@ function getPositionOrSize(positionOrSize, canvasSize) {
839
894
  const isPosition = ("x" in positionOrSize);
840
895
  if (isPosition) {
841
896
  return {
842
- x: positionOrSize.x / 100 * canvasSize.width,
843
- y: positionOrSize.y / 100 * canvasSize.height
897
+ x: positionOrSize.x / percentDenominator * canvasSize.width,
898
+ y: positionOrSize.y / percentDenominator * canvasSize.height
844
899
  };
845
900
  } else {
846
901
  return {
847
- width: positionOrSize.width / 100 * canvasSize.width,
848
- height: positionOrSize.height / 100 * canvasSize.height
902
+ width: positionOrSize.width / percentDenominator * canvasSize.width,
903
+ height: positionOrSize.height / percentDenominator * canvasSize.height
849
904
  };
850
905
  }
851
906
  }
@@ -873,9 +928,85 @@ function isObject(arg) {
873
928
  function isArray(arg) {
874
929
  return Array.isArray(arg);
875
930
  }
931
+ function checkDestroy(particle, destroyType, value, minValue, maxValue) {
932
+ switch (destroyType) {
933
+ case "max":
934
+ if (value >= maxValue) {
935
+ particle.destroy();
936
+ }
937
+ break;
938
+ case "min":
939
+ if (value <= minValue) {
940
+ particle.destroy();
941
+ }
942
+ break;
943
+ }
944
+ }
945
+ function updateAnimation(particle, data, changeDirection, destroyType, delta) {
946
+ const minLoops = 0,
947
+ minDelay = 0,
948
+ identity = 1,
949
+ minVelocity = 0,
950
+ minDecay = 1;
951
+ if (particle.destroyed || !data || !data.enable || (data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops)) {
952
+ return;
953
+ }
954
+ const velocity = (data.velocity ?? minVelocity) * delta.factor,
955
+ minValue = data.min,
956
+ maxValue = data.max,
957
+ decay = data.decay ?? minDecay;
958
+ if (!data.time) {
959
+ data.time = 0;
960
+ }
961
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
962
+ data.time += delta.value;
963
+ }
964
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
965
+ return;
966
+ }
967
+ switch (data.status) {
968
+ case "increasing":
969
+ if (data.value >= maxValue) {
970
+ if (changeDirection) {
971
+ data.status = "decreasing";
972
+ } else {
973
+ data.value -= maxValue;
974
+ }
975
+ if (!data.loops) {
976
+ data.loops = minLoops;
977
+ }
978
+ data.loops++;
979
+ } else {
980
+ data.value += velocity;
981
+ }
982
+ break;
983
+ case "decreasing":
984
+ if (data.value <= minValue) {
985
+ if (changeDirection) {
986
+ data.status = "increasing";
987
+ } else {
988
+ data.value += maxValue;
989
+ }
990
+ if (!data.loops) {
991
+ data.loops = minLoops;
992
+ }
993
+ data.loops++;
994
+ } else {
995
+ data.value -= velocity;
996
+ }
997
+ }
998
+ if (data.velocity && decay !== identity) {
999
+ data.velocity *= decay;
1000
+ }
1001
+ checkDestroy(particle, destroyType, data.value, minValue, maxValue);
1002
+ if (!particle.destroyed) {
1003
+ data.value = clamp(data.value, minValue, maxValue);
1004
+ }
1005
+ }
876
1006
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/ColorUtils.js
877
1007
 
878
1008
 
1009
+
879
1010
  const randomColorValue = "random",
880
1011
  midColorValue = "mid",
881
1012
  colorManagers = new Map();
@@ -893,12 +1024,15 @@ function stringToRgba(input) {
893
1024
  return r + r + g + g + b + b + (a !== undefined ? a + a : "");
894
1025
  }),
895
1026
  regex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i,
896
- result = regex.exec(hexFixed);
1027
+ result = regex.exec(hexFixed),
1028
+ radix = 16,
1029
+ defaultAlpha = 1,
1030
+ alphaFactor = 0xff;
897
1031
  return result ? {
898
- a: result[4] !== undefined ? parseInt(result[4], 16) / 0xff : 1,
899
- b: parseInt(result[3], 16),
900
- g: parseInt(result[2], 16),
901
- r: parseInt(result[1], 16)
1032
+ a: result[4] !== undefined ? parseInt(result[4], radix) / alphaFactor : defaultAlpha,
1033
+ b: parseInt(result[3], radix),
1034
+ g: parseInt(result[2], radix),
1035
+ r: parseInt(result[1], radix)
902
1036
  } : undefined;
903
1037
  }
904
1038
  function rangeColorToRgb(input, index, useIndex = true) {
@@ -954,28 +1088,37 @@ function rangeColorToHsl(color, index, useIndex = true) {
954
1088
  return rgb ? rgbToHsl(rgb) : undefined;
955
1089
  }
956
1090
  function rgbToHsl(color) {
957
- const r1 = color.r / 255,
958
- g1 = color.g / 255,
959
- b1 = color.b / 255,
1091
+ const rgbMax = 255,
1092
+ hMax = 360,
1093
+ sMax = 100,
1094
+ lMax = 100,
1095
+ hMin = 0,
1096
+ sMin = 0,
1097
+ hPhase = 60,
1098
+ half = 0.5,
1099
+ double = 2,
1100
+ r1 = color.r / rgbMax,
1101
+ g1 = color.g / rgbMax,
1102
+ b1 = color.b / rgbMax,
960
1103
  max = Math.max(r1, g1, b1),
961
1104
  min = Math.min(r1, g1, b1),
962
1105
  res = {
963
- h: 0,
964
- l: (max + min) * 0.5,
965
- s: 0
1106
+ h: hMin,
1107
+ l: (max + min) * half,
1108
+ s: sMin
966
1109
  };
967
1110
  if (max !== min) {
968
- res.s = res.l < 0.5 ? (max - min) / (max + min) : (max - min) / (2.0 - max - min);
969
- res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? 2.0 + (b1 - r1) / (max - min) : 4.0 + (r1 - g1) / (max - min);
1111
+ res.s = res.l < half ? (max - min) / (max + min) : (max - min) / (double - max - min);
1112
+ res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? double + (b1 - r1) / (max - min) : double * double + (r1 - g1) / (max - min);
970
1113
  }
971
- res.l *= 100;
972
- res.s *= 100;
973
- res.h *= 60;
974
- if (res.h < 0) {
975
- res.h += 360;
1114
+ res.l *= lMax;
1115
+ res.s *= sMax;
1116
+ res.h *= hPhase;
1117
+ if (res.h < hMin) {
1118
+ res.h += hMax;
976
1119
  }
977
- if (res.h >= 360) {
978
- res.h -= 360;
1120
+ if (res.h >= hMax) {
1121
+ res.h -= hMax;
979
1122
  }
980
1123
  return res;
981
1124
  }
@@ -986,43 +1129,59 @@ function stringToRgb(input) {
986
1129
  return stringToRgba(input);
987
1130
  }
988
1131
  function hslToRgb(hsl) {
989
- const h = (hsl.h % 360 + 360) % 360,
990
- s = Math.max(0, Math.min(100, hsl.s)),
991
- l = Math.max(0, Math.min(100, hsl.l)),
992
- hNormalized = h / 360,
993
- sNormalized = s / 100,
994
- lNormalized = l / 100;
995
- if (s === 0) {
996
- const grayscaleValue = Math.round(lNormalized * 255);
1132
+ const hMax = 360,
1133
+ sMax = 100,
1134
+ lMax = 100,
1135
+ sMin = 0,
1136
+ lMin = 0,
1137
+ h = (hsl.h % hMax + hMax) % hMax,
1138
+ s = Math.max(sMin, Math.min(sMax, hsl.s)),
1139
+ l = Math.max(lMin, Math.min(lMax, hsl.l)),
1140
+ hNormalized = h / hMax,
1141
+ sNormalized = s / sMax,
1142
+ lNormalized = l / lMax,
1143
+ rgbFactor = 255,
1144
+ triple = 3;
1145
+ if (s === sMin) {
1146
+ const grayscaleValue = Math.round(lNormalized * rgbFactor);
997
1147
  return {
998
1148
  r: grayscaleValue,
999
1149
  g: grayscaleValue,
1000
1150
  b: grayscaleValue
1001
1151
  };
1002
1152
  }
1003
- const channel = (temp1, temp2, temp3) => {
1004
- if (temp3 < 0) {
1005
- temp3 += 1;
1153
+ const half = 0.5,
1154
+ double = 2,
1155
+ channel = (temp1, temp2, temp3) => {
1156
+ const temp3Min = 0,
1157
+ temp3Max = 1,
1158
+ sextuple = 6;
1159
+ if (temp3 < temp3Min) {
1160
+ temp3++;
1006
1161
  }
1007
- if (temp3 > 1) {
1008
- temp3 -= 1;
1162
+ if (temp3 > temp3Max) {
1163
+ temp3--;
1009
1164
  }
1010
- if (temp3 * 6 < 1) {
1011
- return temp1 + (temp2 - temp1) * 6 * temp3;
1165
+ if (temp3 * sextuple < temp3Max) {
1166
+ return temp1 + (temp2 - temp1) * sextuple * temp3;
1012
1167
  }
1013
- if (temp3 * 2 < 1) {
1168
+ if (temp3 * double < temp3Max) {
1014
1169
  return temp2;
1015
1170
  }
1016
- if (temp3 * 3 < 2) {
1017
- return temp1 + (temp2 - temp1) * (2 / 3 - temp3) * 6;
1171
+ if (temp3 * triple < temp3Max * double) {
1172
+ const temp3Offset = double / triple;
1173
+ return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
1018
1174
  }
1019
1175
  return temp1;
1020
1176
  },
1021
- temp1 = lNormalized < 0.5 ? lNormalized * (1 + sNormalized) : lNormalized + sNormalized - lNormalized * sNormalized,
1022
- temp2 = 2 * lNormalized - temp1,
1023
- red = Math.min(255, 255 * channel(temp2, temp1, hNormalized + 1 / 3)),
1024
- green = Math.min(255, 255 * channel(temp2, temp1, hNormalized)),
1025
- blue = Math.min(255, 255 * channel(temp2, temp1, hNormalized - 1 / 3));
1177
+ sNormalizedOffset = 1,
1178
+ temp1 = lNormalized < half ? lNormalized * (sNormalizedOffset + sNormalized) : lNormalized + sNormalized - lNormalized * sNormalized,
1179
+ temp2 = double * lNormalized - temp1,
1180
+ phaseNumerator = 1,
1181
+ phaseThird = phaseNumerator / triple,
1182
+ red = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized + phaseThird)),
1183
+ green = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized)),
1184
+ blue = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized - phaseThird));
1026
1185
  return {
1027
1186
  r: Math.round(red),
1028
1187
  g: Math.round(green),
@@ -1039,18 +1198,22 @@ function hslaToRgba(hsla) {
1039
1198
  };
1040
1199
  }
1041
1200
  function getRandomRgbColor(min) {
1042
- const fixedMin = min ?? 0;
1201
+ const defaultMin = 0,
1202
+ fixedMin = min ?? defaultMin,
1203
+ rgbMax = 256;
1043
1204
  return {
1044
- b: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1045
- g: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1046
- r: Math.floor(randomInRange(setRangeValue(fixedMin, 256)))
1205
+ b: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
1206
+ g: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
1207
+ r: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax)))
1047
1208
  };
1048
1209
  }
1049
1210
  function getStyleFromRgb(color, opacity) {
1050
- return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity ?? 1})`;
1211
+ const defaultOpacity = 1;
1212
+ return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity ?? defaultOpacity})`;
1051
1213
  }
1052
1214
  function getStyleFromHsl(color, opacity) {
1053
- return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity ?? 1})`;
1215
+ const defaultOpacity = 1;
1216
+ return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity ?? defaultOpacity})`;
1054
1217
  }
1055
1218
  function colorMix(color1, color2, size1, size2) {
1056
1219
  let rgb1 = color1,
@@ -1136,25 +1299,120 @@ function getHslAnimationFromHsl(hsl, animationOptions, reduceFactor) {
1136
1299
  }
1137
1300
  function setColorAnimation(colorValue, colorAnimation, reduceFactor) {
1138
1301
  colorValue.enable = colorAnimation.enable;
1302
+ const defaultVelocity = 0,
1303
+ decayOffset = 1,
1304
+ defaultLoops = 0,
1305
+ defaultTime = 0;
1139
1306
  if (colorValue.enable) {
1140
- colorValue.velocity = getRangeValue(colorAnimation.speed) / 100 * reduceFactor;
1141
- colorValue.decay = 1 - getRangeValue(colorAnimation.decay);
1307
+ colorValue.velocity = getRangeValue(colorAnimation.speed) / percentDenominator * reduceFactor;
1308
+ colorValue.decay = decayOffset - getRangeValue(colorAnimation.decay);
1142
1309
  colorValue.status = "increasing";
1143
- colorValue.loops = 0;
1310
+ colorValue.loops = defaultLoops;
1144
1311
  colorValue.maxLoops = getRangeValue(colorAnimation.count);
1145
- colorValue.time = 0;
1146
- colorValue.delayTime = getRangeValue(colorAnimation.delay) * 1000;
1312
+ colorValue.time = defaultTime;
1313
+ colorValue.delayTime = getRangeValue(colorAnimation.delay) * millisecondsToSeconds;
1147
1314
  if (!colorAnimation.sync) {
1148
1315
  colorValue.velocity *= getRandom();
1149
1316
  colorValue.value *= getRandom();
1150
1317
  }
1151
1318
  colorValue.initialValue = colorValue.value;
1319
+ colorValue.offset = setRangeValue(colorAnimation.offset);
1320
+ } else {
1321
+ colorValue.velocity = defaultVelocity;
1322
+ }
1323
+ }
1324
+ function updateColorValue(data, range, decrease, delta) {
1325
+ const minLoops = 0,
1326
+ minDelay = 0,
1327
+ identity = 1,
1328
+ minVelocity = 0,
1329
+ minOffset = 0,
1330
+ velocityFactor = 3.6;
1331
+ if (!data || !data.enable || (data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops)) {
1332
+ return;
1333
+ }
1334
+ if (!data.time) {
1335
+ data.time = 0;
1336
+ }
1337
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
1338
+ data.time += delta.value;
1339
+ }
1340
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
1341
+ return;
1342
+ }
1343
+ const offset = data.offset ? randomInRange(data.offset) : minOffset,
1344
+ velocity = (data.velocity ?? minVelocity) * delta.factor + offset * velocityFactor,
1345
+ decay = data.decay ?? identity,
1346
+ max = getRangeMax(range),
1347
+ min = getRangeMin(range);
1348
+ if (!decrease || data.status === "increasing") {
1349
+ data.value += velocity;
1350
+ if (data.value > max) {
1351
+ if (!data.loops) {
1352
+ data.loops = 0;
1353
+ }
1354
+ data.loops++;
1355
+ if (decrease) {
1356
+ data.status = "decreasing";
1357
+ } else {
1358
+ data.value -= max;
1359
+ }
1360
+ }
1152
1361
  } else {
1153
- colorValue.velocity = 0;
1362
+ data.value -= velocity;
1363
+ const minValue = 0;
1364
+ if (data.value < minValue) {
1365
+ if (!data.loops) {
1366
+ data.loops = 0;
1367
+ }
1368
+ data.loops++;
1369
+ data.status = "increasing";
1370
+ }
1371
+ }
1372
+ if (data.velocity && decay !== identity) {
1373
+ data.velocity *= decay;
1374
+ }
1375
+ data.value = clamp(data.value, min, max);
1376
+ }
1377
+ function updateColor(color, delta) {
1378
+ if (!color) {
1379
+ return;
1380
+ }
1381
+ const {
1382
+ h,
1383
+ s,
1384
+ l
1385
+ } = color;
1386
+ const ranges = {
1387
+ h: {
1388
+ min: 0,
1389
+ max: 360
1390
+ },
1391
+ s: {
1392
+ min: 0,
1393
+ max: 100
1394
+ },
1395
+ l: {
1396
+ min: 0,
1397
+ max: 100
1398
+ }
1399
+ };
1400
+ if (h) {
1401
+ updateColorValue(h, ranges.h, false, delta);
1402
+ }
1403
+ if (s) {
1404
+ updateColorValue(s, ranges.s, true, delta);
1405
+ }
1406
+ if (l) {
1407
+ updateColorValue(l, ranges.l, true, delta);
1154
1408
  }
1155
1409
  }
1156
1410
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/CanvasUtils.js
1157
1411
 
1412
+ const CanvasUtils_origin = {
1413
+ x: 0,
1414
+ y: 0
1415
+ };
1158
1416
  function drawLine(context, begin, end) {
1159
1417
  context.beginPath();
1160
1418
  context.moveTo(begin.x, begin.y);
@@ -1163,44 +1421,46 @@ function drawLine(context, begin, end) {
1163
1421
  }
1164
1422
  function paintBase(context, dimension, baseColor) {
1165
1423
  context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
1166
- context.fillRect(0, 0, dimension.width, dimension.height);
1424
+ context.fillRect(CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1167
1425
  }
1168
1426
  function paintImage(context, dimension, image, opacity) {
1169
1427
  if (!image) {
1170
1428
  return;
1171
1429
  }
1172
1430
  context.globalAlpha = opacity;
1173
- context.drawImage(image, 0, 0, dimension.width, dimension.height);
1431
+ context.drawImage(image, CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1174
1432
  context.globalAlpha = 1;
1175
1433
  }
1176
1434
  function clear(context, dimension) {
1177
- context.clearRect(0, 0, dimension.width, dimension.height);
1435
+ context.clearRect(CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1178
1436
  }
1179
1437
  function drawParticle(data) {
1180
1438
  const {
1181
- container,
1182
- context,
1183
- particle,
1184
- delta,
1185
- colorStyles,
1186
- backgroundMask,
1187
- composite,
1188
- radius,
1189
- opacity,
1190
- shadow,
1191
- transform
1192
- } = data;
1193
- const pos = particle.getPosition(),
1194
- angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : 0),
1439
+ container,
1440
+ context,
1441
+ particle,
1442
+ delta,
1443
+ colorStyles,
1444
+ backgroundMask,
1445
+ composite,
1446
+ radius,
1447
+ opacity,
1448
+ shadow,
1449
+ transform
1450
+ } = data,
1451
+ pos = particle.getPosition(),
1452
+ defaultAngle = 0,
1453
+ angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : defaultAngle),
1195
1454
  rotateData = {
1196
1455
  sin: Math.sin(angle),
1197
1456
  cos: Math.cos(angle)
1198
1457
  },
1458
+ defaultTransformFactor = 1,
1199
1459
  transformData = {
1200
- a: rotateData.cos * (transform.a ?? 1),
1201
- b: rotateData.sin * (transform.b ?? 1),
1202
- c: -rotateData.sin * (transform.c ?? 1),
1203
- d: rotateData.cos * (transform.d ?? 1)
1460
+ a: rotateData.cos * (transform.a ?? defaultTransformFactor),
1461
+ b: rotateData.sin * (transform.b ?? defaultTransformFactor),
1462
+ c: -rotateData.sin * (transform.c ?? defaultTransformFactor),
1463
+ d: rotateData.cos * (transform.d ?? defaultTransformFactor)
1204
1464
  };
1205
1465
  context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
1206
1466
  if (backgroundMask) {
@@ -1216,7 +1476,8 @@ function drawParticle(data) {
1216
1476
  if (colorStyles.fill) {
1217
1477
  context.fillStyle = colorStyles.fill;
1218
1478
  }
1219
- const strokeWidth = particle.strokeWidth ?? 0;
1479
+ const minStrokeWidth = 0,
1480
+ strokeWidth = particle.strokeWidth ?? minStrokeWidth;
1220
1481
  context.lineWidth = strokeWidth;
1221
1482
  if (colorStyles.stroke) {
1222
1483
  context.strokeStyle = colorStyles.stroke;
@@ -1228,23 +1489,14 @@ function drawParticle(data) {
1228
1489
  radius,
1229
1490
  opacity,
1230
1491
  delta,
1231
- transformData
1492
+ transformData,
1493
+ strokeWidth
1232
1494
  };
1233
- context.beginPath();
1234
1495
  drawShape(drawData);
1235
- if (particle.shapeClose) {
1236
- context.closePath();
1237
- }
1238
- if (strokeWidth > 0) {
1239
- context.stroke();
1240
- }
1241
- if (particle.shapeFill) {
1242
- context.fill();
1243
- }
1244
1496
  drawShapeAfterDraw(drawData);
1245
1497
  drawEffect(drawData);
1246
1498
  context.globalCompositeOperation = "source-over";
1247
- context.setTransform(1, 0, 0, 1, 0, 0);
1499
+ context.resetTransform();
1248
1500
  }
1249
1501
  function drawEffect(data) {
1250
1502
  const {
@@ -1277,14 +1529,16 @@ function drawEffect(data) {
1277
1529
  }
1278
1530
  function drawShape(data) {
1279
1531
  const {
1280
- container,
1281
- context,
1282
- particle,
1283
- radius,
1284
- opacity,
1285
- delta,
1286
- transformData
1287
- } = data;
1532
+ container,
1533
+ context,
1534
+ particle,
1535
+ radius,
1536
+ opacity,
1537
+ delta,
1538
+ strokeWidth,
1539
+ transformData
1540
+ } = data,
1541
+ minStrokeWidth = 0;
1288
1542
  if (!particle.shape) {
1289
1543
  return;
1290
1544
  }
@@ -1292,6 +1546,7 @@ function drawShape(data) {
1292
1546
  if (!drawer) {
1293
1547
  return;
1294
1548
  }
1549
+ context.beginPath();
1295
1550
  drawer.draw({
1296
1551
  context,
1297
1552
  particle,
@@ -1303,6 +1558,15 @@ function drawShape(data) {
1303
1558
  ...transformData
1304
1559
  }
1305
1560
  });
1561
+ if (particle.shapeClose) {
1562
+ context.closePath();
1563
+ }
1564
+ if (strokeWidth > minStrokeWidth) {
1565
+ context.stroke();
1566
+ }
1567
+ if (particle.shapeFill) {
1568
+ context.fill();
1569
+ }
1306
1570
  }
1307
1571
  function drawShapeAfterDraw(data) {
1308
1572
  const {
@@ -1318,7 +1582,7 @@ function drawShapeAfterDraw(data) {
1318
1582
  return;
1319
1583
  }
1320
1584
  const drawer = container.shapeDrawers.get(particle.shape);
1321
- if (!drawer || !drawer.afterDraw) {
1585
+ if (!drawer?.afterDraw) {
1322
1586
  return;
1323
1587
  }
1324
1588
  drawer.afterDraw({
@@ -1346,10 +1610,11 @@ function drawParticlePlugin(context, plugin, particle, delta) {
1346
1610
  plugin.drawParticle(context, particle, delta);
1347
1611
  }
1348
1612
  function alterHsl(color, type, value) {
1613
+ const lFactor = 1;
1349
1614
  return {
1350
1615
  h: color.h,
1351
1616
  s: color.s,
1352
- l: color.l + (type === "darken" ? -1 : 1) * value
1617
+ l: color.l + (type === "darken" ? -lFactor : lFactor) * value
1353
1618
  };
1354
1619
  }
1355
1620
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Canvas.js
@@ -1358,9 +1623,10 @@ function alterHsl(color, type, value) {
1358
1623
 
1359
1624
 
1360
1625
  function setTransformValue(factor, newFactor, key) {
1361
- const newValue = newFactor[key];
1626
+ const newValue = newFactor[key],
1627
+ defaultValue = 1;
1362
1628
  if (newValue !== undefined) {
1363
- factor[key] = (factor[key] ?? 1) * newValue;
1629
+ factor[key] = (factor[key] ?? defaultValue) * newValue;
1364
1630
  }
1365
1631
  }
1366
1632
  class Canvas {
@@ -1368,7 +1634,7 @@ class Canvas {
1368
1634
  this.container = container;
1369
1635
  this._applyPostDrawUpdaters = particle => {
1370
1636
  for (const updater of this._postDrawUpdaters) {
1371
- updater.afterDraw && updater.afterDraw(particle);
1637
+ updater.afterDraw?.(particle);
1372
1638
  }
1373
1639
  };
1374
1640
  this._applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
@@ -1391,12 +1657,12 @@ class Canvas {
1391
1657
  setTransformValue(transform, updaterTransform, key);
1392
1658
  }
1393
1659
  }
1394
- updater.beforeDraw && updater.beforeDraw(particle);
1660
+ updater.beforeDraw?.(particle);
1395
1661
  }
1396
1662
  };
1397
1663
  this._applyResizePlugins = () => {
1398
1664
  for (const plugin of this._resizePlugins) {
1399
- plugin.resize && plugin.resize();
1665
+ plugin.resize?.();
1400
1666
  }
1401
1667
  };
1402
1668
  this._getPluginParticleColors = particle => {
@@ -1457,17 +1723,18 @@ class Canvas {
1457
1723
  if (!trail.enable) {
1458
1724
  return;
1459
1725
  }
1726
+ const factorNumerator = 1,
1727
+ opacity = factorNumerator / trail.length;
1460
1728
  if (trailFill.color) {
1461
1729
  const fillColor = rangeColorToRgb(trailFill.color);
1462
1730
  if (!fillColor) {
1463
1731
  return;
1464
1732
  }
1465
- const trail = options.particles.move.trail;
1466
1733
  this._trailFill = {
1467
1734
  color: {
1468
1735
  ...fillColor
1469
1736
  },
1470
- opacity: 1 / trail.length
1737
+ opacity
1471
1738
  };
1472
1739
  } else {
1473
1740
  await new Promise((resolve, reject) => {
@@ -1478,7 +1745,7 @@ class Canvas {
1478
1745
  img.addEventListener("load", () => {
1479
1746
  this._trailFill = {
1480
1747
  image: img,
1481
- opacity: 1 / trail.length
1748
+ opacity
1482
1749
  };
1483
1750
  resolve();
1484
1751
  });
@@ -1533,9 +1800,10 @@ class Canvas {
1533
1800
  return;
1534
1801
  }
1535
1802
  const priority = "important",
1536
- style = element.style;
1803
+ style = element.style,
1804
+ radix = 10;
1537
1805
  style.setProperty("position", "fixed", priority);
1538
- style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(10), priority);
1806
+ style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(radix), priority);
1539
1807
  style.setProperty("top", "0", priority);
1540
1808
  style.setProperty("left", "0", priority);
1541
1809
  style.setProperty("width", "100%", priority);
@@ -1558,10 +1826,11 @@ class Canvas {
1558
1826
  clear() {
1559
1827
  const options = this.container.actualOptions,
1560
1828
  trail = options.particles.move.trail,
1561
- trailFill = this._trailFill;
1829
+ trailFill = this._trailFill,
1830
+ minimumLength = 0;
1562
1831
  if (options.backgroundMask.enable) {
1563
1832
  this.paint();
1564
- } else if (trail.enable && trail.length > 0 && trailFill) {
1833
+ } else if (trail.enable && trail.length > minimumLength && trailFill) {
1565
1834
  if (trailFill.color) {
1566
1835
  this._paintBase(getStyleFromRgb(trailFill.color, trailFill.opacity));
1567
1836
  } else if (trailFill.image) {
@@ -1577,7 +1846,7 @@ class Canvas {
1577
1846
  this.stop();
1578
1847
  if (this._generated) {
1579
1848
  const element = this.element;
1580
- element && element.remove();
1849
+ element?.remove();
1581
1850
  } else {
1582
1851
  this._resetOriginalStyle();
1583
1852
  }
@@ -1597,8 +1866,9 @@ class Canvas {
1597
1866
  if (particle.spawning || particle.destroyed) {
1598
1867
  return;
1599
1868
  }
1600
- const radius = particle.getRadius();
1601
- if (radius <= 0) {
1869
+ const radius = particle.getRadius(),
1870
+ minimumSize = 0;
1871
+ if (radius <= minimumSize) {
1602
1872
  return;
1603
1873
  }
1604
1874
  const pfColor = particle.getFillColor(),
@@ -1617,8 +1887,11 @@ class Canvas {
1617
1887
  const container = this.container,
1618
1888
  options = container.actualOptions,
1619
1889
  zIndexOptions = particle.options.zIndex,
1620
- zOpacityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.opacityRate,
1621
- opacity = particle.bubble.opacity ?? particle.opacity?.value ?? 1,
1890
+ zIndexFactorOffset = 1,
1891
+ zIndexFactor = zIndexFactorOffset - particle.zIndexFactor,
1892
+ zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate,
1893
+ defaultOpacity = 1,
1894
+ opacity = particle.bubble.opacity ?? particle.opacity?.value ?? defaultOpacity,
1622
1895
  strokeOpacity = particle.strokeOpacity ?? opacity,
1623
1896
  zOpacity = opacity * zOpacityFactor,
1624
1897
  zStrokeOpacity = strokeOpacity * zOpacityFactor,
@@ -1636,7 +1909,7 @@ class Canvas {
1636
1909
  colorStyles,
1637
1910
  backgroundMask: options.backgroundMask.enable,
1638
1911
  composite: options.backgroundMask.composite,
1639
- radius: radius * (1 - particle.zIndexFactor) ** zIndexOptions.sizeRate,
1912
+ radius: radius * zIndexFactor ** zIndexOptions.sizeRate,
1640
1913
  opacity: zOpacity,
1641
1914
  shadow: particle.options.shadow,
1642
1915
  transform
@@ -1708,7 +1981,7 @@ class Canvas {
1708
1981
  if (plugin.resize) {
1709
1982
  this._resizePlugins.push(plugin);
1710
1983
  }
1711
- if (plugin.particleFillColor || plugin.particleStrokeColor) {
1984
+ if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
1712
1985
  this._colorPlugins.push(plugin);
1713
1986
  }
1714
1987
  }
@@ -1720,7 +1993,7 @@ class Canvas {
1720
1993
  if (updater.afterDraw) {
1721
1994
  this._postDrawUpdaters.push(updater);
1722
1995
  }
1723
- if (updater.getColorStyles || updater.getTransformValues || updater.beforeDraw) {
1996
+ if (updater.getColorStyles ?? updater.getTransformValues ?? updater.beforeDraw) {
1724
1997
  this._preDrawUpdaters.push(updater);
1725
1998
  }
1726
1999
  }
@@ -1806,6 +2079,7 @@ class Canvas {
1806
2079
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/EventListeners.js
1807
2080
 
1808
2081
 
2082
+ const EventListeners_double = 2;
1809
2083
  function manageListener(element, event, handler, add, options) {
1810
2084
  if (add) {
1811
2085
  let addOptions = {
@@ -1842,7 +2116,8 @@ class EventListeners {
1842
2116
  executeOnSingleOrMultiple(onClick.mode, mode => this.container.handleClickMode(mode));
1843
2117
  }
1844
2118
  if (e.type === "touchend") {
1845
- setTimeout(() => this._mouseTouchFinish(), 500);
2119
+ const touchDelay = 500;
2120
+ setTimeout(() => this._mouseTouchFinish(), touchDelay);
1846
2121
  }
1847
2122
  };
1848
2123
  this._handleThemeChange = e => {
@@ -1853,7 +2128,7 @@ class EventListeners {
1853
2128
  themeName = mediaEvent.matches ? defaultThemes.dark : defaultThemes.light,
1854
2129
  theme = options.themes.find(theme => theme.name === themeName);
1855
2130
  if (theme && theme.default.auto) {
1856
- container.loadTheme(themeName);
2131
+ void container.loadTheme(themeName);
1857
2132
  }
1858
2133
  };
1859
2134
  this._handleVisibilityChange = () => {
@@ -1875,15 +2150,16 @@ class EventListeners {
1875
2150
  }
1876
2151
  }
1877
2152
  };
1878
- this._handleWindowResize = async () => {
2153
+ this._handleWindowResize = () => {
1879
2154
  if (this._resizeTimeout) {
1880
2155
  clearTimeout(this._resizeTimeout);
1881
2156
  delete this._resizeTimeout;
1882
2157
  }
1883
- this._resizeTimeout = setTimeout(async () => {
2158
+ const handleResize = async () => {
1884
2159
  const canvas = this.container.canvas;
1885
- canvas && (await canvas.windowResize());
1886
- }, this.container.actualOptions.interactivity.events.resize.delay * 1000);
2160
+ await canvas?.windowResize();
2161
+ };
2162
+ this._resizeTimeout = setTimeout(() => void handleResize(), this.container.actualOptions.interactivity.events.resize.delay * millisecondsToSeconds);
1887
2163
  };
1888
2164
  this._manageInteractivityListeners = (mouseLeaveTmpEvent, add) => {
1889
2165
  const handlers = this._handlers,
@@ -1974,12 +2250,12 @@ class EventListeners {
1974
2250
  this._resizeObserver.disconnect();
1975
2251
  delete this._resizeObserver;
1976
2252
  } else if (!this._resizeObserver && add && canvasEl) {
1977
- this._resizeObserver = new ResizeObserver(async entries => {
2253
+ this._resizeObserver = new ResizeObserver(entries => {
1978
2254
  const entry = entries.find(e => e.target === canvasEl);
1979
2255
  if (!entry) {
1980
2256
  return;
1981
2257
  }
1982
- await this._handleWindowResize();
2258
+ this._handleWindowResize();
1983
2259
  });
1984
2260
  this._resizeObserver.observe(canvasEl);
1985
2261
  }
@@ -2041,7 +2317,7 @@ class EventListeners {
2041
2317
  options = container.actualOptions,
2042
2318
  interactivity = container.interactivity,
2043
2319
  canvasEl = container.canvas.element;
2044
- if (!interactivity || !interactivity.element) {
2320
+ if (!interactivity?.element) {
2045
2321
  return;
2046
2322
  }
2047
2323
  interactivity.mouse.inside = true;
@@ -2065,8 +2341,8 @@ class EventListeners {
2065
2341
  targetRect = target.getBoundingClientRect(),
2066
2342
  canvasRect = canvasEl.getBoundingClientRect();
2067
2343
  pos = {
2068
- x: mouseEvent.offsetX + 2 * sourceRect.left - (targetRect.left + canvasRect.left),
2069
- y: mouseEvent.offsetY + 2 * sourceRect.top - (targetRect.top + canvasRect.top)
2344
+ x: mouseEvent.offsetX + EventListeners_double * sourceRect.left - (targetRect.left + canvasRect.left),
2345
+ y: mouseEvent.offsetY + EventListeners_double * sourceRect.top - (targetRect.top + canvasRect.top)
2070
2346
  };
2071
2347
  } else {
2072
2348
  pos = {
@@ -2084,11 +2360,13 @@ class EventListeners {
2084
2360
  this._canPush = e.type !== "touchmove";
2085
2361
  if (canvasEl) {
2086
2362
  const touchEvent = e,
2087
- lastTouch = touchEvent.touches[touchEvent.touches.length - 1],
2088
- canvasRect = canvasEl.getBoundingClientRect();
2363
+ lengthOffset = 1,
2364
+ lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset],
2365
+ canvasRect = canvasEl.getBoundingClientRect(),
2366
+ defaultCoordinate = 0;
2089
2367
  pos = {
2090
- x: lastTouch.clientX - (canvasRect.left ?? 0),
2091
- y: lastTouch.clientY - (canvasRect.top ?? 0)
2368
+ x: lastTouch.clientX - (canvasRect.left ?? defaultCoordinate),
2369
+ y: lastTouch.clientY - (canvasRect.top ?? defaultCoordinate)
2092
2370
  };
2093
2371
  }
2094
2372
  }
@@ -2465,6 +2743,7 @@ class Interactivity {
2465
2743
  }
2466
2744
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/ManualParticle.js
2467
2745
 
2746
+ const defaultPosition = 50;
2468
2747
  class ManualParticle {
2469
2748
  load(data) {
2470
2749
  if (!data) {
@@ -2472,8 +2751,8 @@ class ManualParticle {
2472
2751
  }
2473
2752
  if (data.position) {
2474
2753
  this.position = {
2475
- x: data.position.x ?? 50,
2476
- y: data.position.y ?? 50,
2754
+ x: data.position.x ?? defaultPosition,
2755
+ y: data.position.y ?? defaultPosition,
2477
2756
  mode: data.position.mode ?? "percent"
2478
2757
  };
2479
2758
  }
@@ -3562,6 +3841,9 @@ class Options {
3562
3841
  if (data.clear !== undefined) {
3563
3842
  this.clear = data.clear;
3564
3843
  }
3844
+ if (data.key !== undefined) {
3845
+ this.key = data.key;
3846
+ }
3565
3847
  if (data.name !== undefined) {
3566
3848
  this.name = data.name;
3567
3849
  }
@@ -3674,12 +3956,14 @@ class InteractionManager {
3674
3956
  }
3675
3957
  async externalInteract(delta) {
3676
3958
  for (const interactor of this._externalInteractors) {
3677
- interactor.isEnabled() && (await interactor.interact(delta));
3959
+ if (interactor.isEnabled()) {
3960
+ await interactor.interact(delta);
3961
+ }
3678
3962
  }
3679
3963
  }
3680
3964
  handleClickMode(mode) {
3681
3965
  for (const interactor of this._externalInteractors) {
3682
- interactor.handleClickMode && interactor.handleClickMode(mode);
3966
+ interactor.handleClickMode?.(mode);
3683
3967
  }
3684
3968
  }
3685
3969
  init() {
@@ -3702,15 +3986,21 @@ class InteractionManager {
3702
3986
  interactor.clear(particle, delta);
3703
3987
  }
3704
3988
  for (const interactor of this._particleInteractors) {
3705
- interactor.isEnabled(particle) && (await interactor.interact(particle, delta));
3989
+ if (interactor.isEnabled(particle)) {
3990
+ await interactor.interact(particle, delta);
3991
+ }
3706
3992
  }
3707
3993
  }
3708
- async reset(particle) {
3994
+ reset(particle) {
3709
3995
  for (const interactor of this._externalInteractors) {
3710
- interactor.isEnabled() && interactor.reset(particle);
3996
+ if (interactor.isEnabled()) {
3997
+ interactor.reset(particle);
3998
+ }
3711
3999
  }
3712
4000
  for (const interactor of this._particleInteractors) {
3713
- interactor.isEnabled(particle) && interactor.reset(particle);
4001
+ if (interactor.isEnabled(particle)) {
4002
+ interactor.reset(particle);
4003
+ }
3714
4004
  }
3715
4005
  }
3716
4006
  }
@@ -3724,6 +4014,10 @@ class InteractionManager {
3724
4014
 
3725
4015
 
3726
4016
 
4017
+ const defaultRetryCount = 0,
4018
+ Particle_double = 2,
4019
+ half = 0.5,
4020
+ Particle_squareExp = 2;
3727
4021
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
3728
4022
  const effectData = effectOptions.options[effect];
3729
4023
  if (!effectData) {
@@ -3748,7 +4042,7 @@ function fixOutMode(data) {
3748
4042
  if (!isInArray(data.outMode, data.checkModes)) {
3749
4043
  return;
3750
4044
  }
3751
- const diameter = data.radius * 2;
4045
+ const diameter = data.radius * Particle_double;
3752
4046
  if (data.coord > data.maxCoord - diameter) {
3753
4047
  data.setCb(-data.radius);
3754
4048
  } else if (data.coord < diameter) {
@@ -3758,7 +4052,7 @@ function fixOutMode(data) {
3758
4052
  class Particle {
3759
4053
  constructor(engine, id, container, position, overrideOptions, group) {
3760
4054
  this.container = container;
3761
- this._calcPosition = (container, position, zIndex, tryCount = 0) => {
4055
+ this._calcPosition = (container, position, zIndex, tryCount = defaultRetryCount) => {
3762
4056
  for (const [, plugin] of container.plugins) {
3763
4057
  const pluginPos = plugin.particlePosition !== undefined ? plugin.particlePosition(position, this) : undefined;
3764
4058
  if (pluginPos) {
@@ -3798,7 +4092,8 @@ class Particle {
3798
4092
  fixVertical(outModes.top ?? outModes.default);
3799
4093
  fixVertical(outModes.bottom ?? outModes.default);
3800
4094
  if (this._checkOverlap(pos, tryCount)) {
3801
- return this._calcPosition(container, undefined, zIndex, tryCount + 1);
4095
+ const increment = 1;
4096
+ return this._calcPosition(container, undefined, zIndex, tryCount + increment);
3802
4097
  }
3803
4098
  return pos;
3804
4099
  };
@@ -3809,11 +4104,11 @@ class Particle {
3809
4104
  if (moveOptions.direction === "inside" || moveOptions.direction === "outside") {
3810
4105
  return res;
3811
4106
  }
3812
- const rad = Math.PI / 180 * getRangeValue(moveOptions.angle.value),
3813
- radOffset = Math.PI / 180 * getRangeValue(moveOptions.angle.offset),
4107
+ const rad = degToRad(getRangeValue(moveOptions.angle.value)),
4108
+ radOffset = degToRad(getRangeValue(moveOptions.angle.offset)),
3814
4109
  range = {
3815
- left: radOffset - rad * 0.5,
3816
- right: radOffset + rad * 0.5
4110
+ left: radOffset - rad * half,
4111
+ right: radOffset + rad * half
3817
4112
  };
3818
4113
  if (!moveOptions.straight) {
3819
4114
  res.angle += randomInRange(setRangeValue(range.left, range.right));
@@ -3823,7 +4118,7 @@ class Particle {
3823
4118
  }
3824
4119
  return res;
3825
4120
  };
3826
- this._checkOverlap = (pos, tryCount = 0) => {
4121
+ this._checkOverlap = (pos, tryCount = defaultRetryCount) => {
3827
4122
  const collisionsOptions = this.options.collisions,
3828
4123
  radius = this.getRadius();
3829
4124
  if (!collisionsOptions.enable) {
@@ -3833,8 +4128,9 @@ class Particle {
3833
4128
  if (overlapOptions.enable) {
3834
4129
  return false;
3835
4130
  }
3836
- const retries = overlapOptions.retries;
3837
- if (retries >= 0 && tryCount > retries) {
4131
+ const retries = overlapOptions.retries,
4132
+ minRetries = 0;
4133
+ if (retries >= minRetries && tryCount > retries) {
3838
4134
  throw new Error(`${errorPrefix} particle is overlapping and can't be placed`);
3839
4135
  }
3840
4136
  return !!this.container.particles.find(particle => getDistance(pos, particle.position) < radius + particle.getRadius());
@@ -3843,9 +4139,11 @@ class Particle {
3843
4139
  if (!color || !this.roll || !this.backColor && !this.roll.alter) {
3844
4140
  return color;
3845
4141
  }
3846
- const backFactor = this.roll.horizontal && this.roll.vertical ? 2 : 1,
3847
- backSum = this.roll.horizontal ? Math.PI * 0.5 : 0,
3848
- rolled = Math.floor(((this.roll.angle ?? 0) + backSum) / (Math.PI / backFactor)) % 2;
4142
+ const rollFactor = 1,
4143
+ none = 0,
4144
+ backFactor = this.roll.horizontal && this.roll.vertical ? Particle_double * rollFactor : rollFactor,
4145
+ backSum = this.roll.horizontal ? Math.PI * half : none,
4146
+ rolled = Math.floor(((this.roll.angle ?? none) + backSum) / (Math.PI / backFactor)) % Particle_double;
3849
4147
  if (!rolled) {
3850
4148
  return color;
3851
4149
  }
@@ -3859,13 +4157,15 @@ class Particle {
3859
4157
  };
3860
4158
  this._initPosition = position => {
3861
4159
  const container = this.container,
3862
- zIndexValue = getRangeValue(this.options.zIndex.value);
3863
- this.position = this._calcPosition(container, position, clamp(zIndexValue, 0, container.zLayers));
4160
+ zIndexValue = getRangeValue(this.options.zIndex.value),
4161
+ minZ = 0;
4162
+ this.position = this._calcPosition(container, position, clamp(zIndexValue, minZ, container.zLayers));
3864
4163
  this.initialPosition = this.position.copy();
3865
- const canvasSize = container.canvas.size;
4164
+ const canvasSize = container.canvas.size,
4165
+ defaultRadius = 0;
3866
4166
  this.moveCenter = {
3867
4167
  ...getPosition(this.options.move.center, canvasSize),
3868
- radius: this.options.move.center.radius ?? 0,
4168
+ radius: this.options.move.center.radius ?? defaultRadius,
3869
4169
  mode: this.options.move.center.mode ?? "percent"
3870
4170
  };
3871
4171
  this.direction = getParticleDirectionAngle(this.options.move.direction, this.position, this.moveCenter);
@@ -3892,14 +4192,14 @@ class Particle {
3892
4192
  const container = this.container,
3893
4193
  pathGenerator = this.pathGenerator,
3894
4194
  shapeDrawer = container.shapeDrawers.get(this.shape);
3895
- shapeDrawer && shapeDrawer.particleDestroy && shapeDrawer.particleDestroy(this);
4195
+ shapeDrawer?.particleDestroy?.(this);
3896
4196
  for (const [, plugin] of container.plugins) {
3897
- plugin.particleDestroyed && plugin.particleDestroyed(this, override);
4197
+ plugin.particleDestroyed?.(this, override);
3898
4198
  }
3899
4199
  for (const updater of container.particles.updaters) {
3900
- updater.particleDestroyed && updater.particleDestroyed(this, override);
4200
+ updater.particleDestroyed?.(this, override);
3901
4201
  }
3902
- pathGenerator && pathGenerator.reset(this);
4202
+ pathGenerator?.reset(this);
3903
4203
  this._engine.dispatchEvent("particleDestroyed", {
3904
4204
  container: this.container,
3905
4205
  data: {
@@ -3919,7 +4219,7 @@ class Particle {
3919
4219
  return this._getRollColor(this.bubble.color ?? getHslFromAnimation(this.color));
3920
4220
  }
3921
4221
  getMass() {
3922
- return this.getRadius() ** 2 * Math.PI * 0.5;
4222
+ return this.getRadius() ** Particle_squareExp * Math.PI * half;
3923
4223
  }
3924
4224
  getPosition() {
3925
4225
  return {
@@ -3967,7 +4267,7 @@ class Particle {
3967
4267
  const effectOptions = particlesOptions.effect,
3968
4268
  shapeOptions = particlesOptions.shape;
3969
4269
  if (overrideOptions) {
3970
- if (overrideOptions.effect && overrideOptions.effect.type) {
4270
+ if (overrideOptions.effect?.type) {
3971
4271
  const overrideEffectType = overrideOptions.effect.type,
3972
4272
  effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
3973
4273
  if (effect) {
@@ -3975,7 +4275,7 @@ class Particle {
3975
4275
  effectOptions.load(overrideOptions.effect);
3976
4276
  }
3977
4277
  }
3978
- if (overrideOptions.shape && overrideOptions.shape.type) {
4278
+ if (overrideOptions.shape?.type) {
3979
4279
  const overrideShapeType = overrideOptions.shape.type,
3980
4280
  shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
3981
4281
  if (shape) {
@@ -4005,7 +4305,7 @@ class Particle {
4005
4305
  this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
4006
4306
  this.options = particlesOptions;
4007
4307
  const pathOptions = this.options.move.path;
4008
- this.pathDelay = getRangeValue(pathOptions.delay.value) * 1000;
4308
+ this.pathDelay = getRangeValue(pathOptions.delay.value) * millisecondsToSeconds;
4009
4309
  if (pathOptions.generator) {
4010
4310
  this.pathGenerator = this._engine.getPathGenerator(pathOptions.generator);
4011
4311
  if (this.pathGenerator && container.addPath(pathOptions.generator, this.pathGenerator)) {
@@ -4024,7 +4324,8 @@ class Particle {
4024
4324
  this._initPosition(position);
4025
4325
  this.initialVelocity = this._calculateVelocity();
4026
4326
  this.velocity = this.initialVelocity.copy();
4027
- this.moveDecay = 1 - getRangeValue(this.options.move.decay);
4327
+ const decayOffset = 1;
4328
+ this.moveDecay = decayOffset - getRangeValue(this.options.move.decay);
4028
4329
  const particles = container.particles;
4029
4330
  particles.setLastZIndex(this.position.z);
4030
4331
  this.zIndexFactor = this.position.z / container.zLayers;
@@ -4036,7 +4337,7 @@ class Particle {
4036
4337
  container.effectDrawers.set(this.effect, effectDrawer);
4037
4338
  }
4038
4339
  }
4039
- if (effectDrawer && effectDrawer.loadEffect) {
4340
+ if (effectDrawer?.loadEffect) {
4040
4341
  effectDrawer.loadEffect(this);
4041
4342
  }
4042
4343
  let shapeDrawer = container.shapeDrawers.get(this.shape);
@@ -4046,7 +4347,7 @@ class Particle {
4046
4347
  container.shapeDrawers.set(this.shape, shapeDrawer);
4047
4348
  }
4048
4349
  }
4049
- if (shapeDrawer && shapeDrawer.loadShape) {
4350
+ if (shapeDrawer?.loadShape) {
4050
4351
  shapeDrawer.loadShape(this);
4051
4352
  }
4052
4353
  const sideCountFunc = shapeDrawer?.getSidesCount;
@@ -4059,16 +4360,12 @@ class Particle {
4059
4360
  updater.init(this);
4060
4361
  }
4061
4362
  for (const mover of particles.movers) {
4062
- mover.init && mover.init(this);
4063
- }
4064
- if (effectDrawer && effectDrawer.particleInit) {
4065
- effectDrawer.particleInit(container, this);
4066
- }
4067
- if (shapeDrawer && shapeDrawer.particleInit) {
4068
- shapeDrawer.particleInit(container, this);
4363
+ mover.init?.(this);
4069
4364
  }
4365
+ effectDrawer?.particleInit?.(container, this);
4366
+ shapeDrawer?.particleInit?.(container, this);
4070
4367
  for (const [, plugin] of container.plugins) {
4071
- plugin.particleCreated && plugin.particleCreated(this);
4368
+ plugin.particleCreated?.(this);
4072
4369
  }
4073
4370
  }
4074
4371
  isInsideCanvas() {
@@ -4082,7 +4379,7 @@ class Particle {
4082
4379
  }
4083
4380
  reset() {
4084
4381
  for (const updater of this.container.particles.updaters) {
4085
- updater.reset && updater.reset(this);
4382
+ updater.reset?.(this);
4086
4383
  }
4087
4384
  }
4088
4385
  }
@@ -4140,6 +4437,7 @@ class Rectangle extends Range {
4140
4437
 
4141
4438
 
4142
4439
 
4440
+ const Circle_squareExp = 2;
4143
4441
  class Circle extends Range {
4144
4442
  constructor(x, y, radius) {
4145
4443
  super(x, y);
@@ -4158,15 +4456,15 @@ class Circle extends Range {
4158
4456
  r = this.radius;
4159
4457
  if (range instanceof Circle) {
4160
4458
  const rSum = r + range.radius,
4161
- dist = Math.sqrt(distPos.x ** 2 + distPos.y ** 2);
4459
+ dist = Math.sqrt(distPos.x ** Circle_squareExp + distPos.y ** Circle_squareExp);
4162
4460
  return rSum > dist;
4163
4461
  } else if (range instanceof Rectangle) {
4164
4462
  const {
4165
4463
  width,
4166
4464
  height
4167
4465
  } = range.size,
4168
- edges = Math.pow(distPos.x - width, 2) + Math.pow(distPos.y - height, 2);
4169
- return edges <= r ** 2 || distPos.x <= r + width && distPos.y <= r + height || distPos.x <= width || distPos.y <= height;
4466
+ edges = Math.pow(distPos.x - width, Circle_squareExp) + Math.pow(distPos.y - height, Circle_squareExp);
4467
+ return edges <= r ** Circle_squareExp || distPos.x <= r + width && distPos.y <= r + height || distPos.x <= width || distPos.y <= height;
4170
4468
  }
4171
4469
  return false;
4172
4470
  }
@@ -4175,6 +4473,9 @@ class Circle extends Range {
4175
4473
 
4176
4474
 
4177
4475
 
4476
+ const QuadTree_half = 0.5,
4477
+ QuadTree_double = 2,
4478
+ subdivideCount = 4;
4178
4479
  class QuadTree {
4179
4480
  constructor(rectangle, capacity) {
4180
4481
  this.rectangle = rectangle;
@@ -4191,8 +4492,9 @@ class QuadTree {
4191
4492
  {
4192
4493
  capacity
4193
4494
  } = this;
4194
- for (let i = 0; i < 4; i++) {
4195
- this._subs.push(new QuadTree(new Rectangle(x + width * 0.5 * (i % 2), y + height * 0.5 * (Math.round(i * 0.5) - i % 2), width * 0.5, height * 0.5), capacity));
4495
+ for (let i = 0; i < subdivideCount; i++) {
4496
+ const fixedIndex = i % QuadTree_double;
4497
+ this._subs.push(new QuadTree(new Rectangle(x + width * QuadTree_half * fixedIndex, y + height * QuadTree_half * (Math.round(i * QuadTree_half) - fixedIndex), width * QuadTree_half, height * QuadTree_half), capacity));
4196
4498
  }
4197
4499
  this._divided = true;
4198
4500
  };
@@ -4214,7 +4516,7 @@ class QuadTree {
4214
4516
  return this._subs.some(sub => sub.insert(point));
4215
4517
  }
4216
4518
  query(range, check, found) {
4217
- const res = found || [];
4519
+ const res = found ?? [];
4218
4520
  if (!range.intersects(this.rectangle)) {
4219
4521
  return [];
4220
4522
  }
@@ -4246,7 +4548,9 @@ class QuadTree {
4246
4548
 
4247
4549
 
4248
4550
 
4249
- const qTreeCapacity = 4;
4551
+ const qTreeCapacity = 4,
4552
+ Particles_squareExp = 2,
4553
+ defaultRemoveQuantity = 1;
4250
4554
  const qTreeRectangle = canvasSize => {
4251
4555
  const {
4252
4556
  height,
@@ -4275,7 +4579,8 @@ class Particles {
4275
4579
  }
4276
4580
  const densityFactor = this._initDensityFactor(numberOptions.density),
4277
4581
  optParticlesNumber = numberOptions.value,
4278
- optParticlesLimit = numberOptions.limit.value > 0 ? numberOptions.limit.value : optParticlesNumber,
4582
+ minLimit = 0,
4583
+ optParticlesLimit = numberOptions.limit.value > minLimit ? numberOptions.limit.value : optParticlesNumber,
4279
4584
  particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + manualCount,
4280
4585
  particlesCount = Math.min(this.count, this.filter(t => t.group === group).length);
4281
4586
  if (group === undefined) {
@@ -4290,13 +4595,14 @@ class Particles {
4290
4595
  }
4291
4596
  };
4292
4597
  this._initDensityFactor = densityOptions => {
4293
- const container = this._container;
4598
+ const container = this._container,
4599
+ defaultFactor = 1;
4294
4600
  if (!container.canvas.element || !densityOptions.enable) {
4295
- return 1;
4601
+ return defaultFactor;
4296
4602
  }
4297
4603
  const canvas = container.canvas.element,
4298
4604
  pxRatio = container.retina.pixelRatio;
4299
- return canvas.width * canvas.height / (densityOptions.height * densityOptions.width * pxRatio ** 2);
4605
+ return canvas.width * canvas.height / (densityOptions.height * densityOptions.width * pxRatio ** Particles_squareExp);
4300
4606
  };
4301
4607
  this._pushParticle = (position, overrideOptions, group, initializer) => {
4302
4608
  try {
@@ -4325,7 +4631,6 @@ class Particles {
4325
4631
  return particle;
4326
4632
  } catch (e) {
4327
4633
  getLogger().warning(`${errorPrefix} adding particle: ${e}`);
4328
- return;
4329
4634
  }
4330
4635
  };
4331
4636
  this._removeParticle = (index, group, override) => {
@@ -4333,9 +4638,10 @@ class Particles {
4333
4638
  if (!particle || particle.group !== group) {
4334
4639
  return false;
4335
4640
  }
4336
- const zIdx = this._zArray.indexOf(particle);
4337
- this._array.splice(index, 1);
4338
- this._zArray.splice(zIdx, 1);
4641
+ const zIdx = this._zArray.indexOf(particle),
4642
+ deleteCount = 1;
4643
+ this._array.splice(index, deleteCount);
4644
+ this._zArray.splice(zIdx, deleteCount);
4339
4645
  particle.destroy(override);
4340
4646
  this._engine.dispatchEvent("particleRemoved", {
4341
4647
  container: this._container,
@@ -4375,11 +4681,14 @@ class Particles {
4375
4681
  addParticle(position, overrideOptions, group, initializer) {
4376
4682
  const limitOptions = this._container.actualOptions.particles.number.limit,
4377
4683
  limit = group === undefined ? this._limit : this._groupLimits.get(group) ?? this._limit,
4378
- currentCount = this.count;
4379
- if (limit > 0) {
4684
+ currentCount = this.count,
4685
+ minLimit = 0;
4686
+ if (limit > minLimit) {
4380
4687
  if (limitOptions.mode === "delete") {
4381
- const countToRemove = currentCount + 1 - limit;
4382
- if (countToRemove > 0) {
4688
+ const countOffset = 1,
4689
+ minCount = 0,
4690
+ countToRemove = currentCount + countOffset - limit;
4691
+ if (countToRemove > minCount) {
4383
4692
  this.removeQuantity(countToRemove);
4384
4693
  }
4385
4694
  } else if (limitOptions.mode === "wait") {
@@ -4475,23 +4784,28 @@ class Particles {
4475
4784
  remove(particle, group, override) {
4476
4785
  this.removeAt(this._array.indexOf(particle), undefined, group, override);
4477
4786
  }
4478
- removeAt(index, quantity = 1, group, override) {
4479
- if (index < 0 || index > this.count) {
4787
+ removeAt(index, quantity = defaultRemoveQuantity, group, override) {
4788
+ const minIndex = 0;
4789
+ if (index < minIndex || index > this.count) {
4480
4790
  return;
4481
4791
  }
4482
4792
  let deleted = 0;
4483
4793
  for (let i = index; deleted < quantity && i < this.count; i++) {
4484
- this._removeParticle(i--, group, override) && deleted++;
4794
+ if (this._removeParticle(i--, group, override)) {
4795
+ deleted++;
4796
+ }
4485
4797
  }
4486
4798
  }
4487
4799
  removeQuantity(quantity, group) {
4488
- this.removeAt(0, quantity, group);
4800
+ const defaultIndex = 0;
4801
+ this.removeAt(defaultIndex, quantity, group);
4489
4802
  }
4490
4803
  setDensity() {
4491
4804
  const options = this._container.actualOptions,
4492
- groups = options.particles.groups;
4805
+ groups = options.particles.groups,
4806
+ manualCount = 0;
4493
4807
  for (const group in groups) {
4494
- this._applyDensity(groups[group], 0, group);
4808
+ this._applyDensity(groups[group], manualCount, group);
4495
4809
  }
4496
4810
  this._applyDensity(options.particles, options.manualParticles.length);
4497
4811
  }
@@ -4510,7 +4824,7 @@ class Particles {
4510
4824
  pathGenerator.update();
4511
4825
  }
4512
4826
  for (const [, plugin] of container.plugins) {
4513
- plugin.update && (await plugin.update(delta));
4827
+ await plugin.update?.(delta);
4514
4828
  }
4515
4829
  const resizeFactor = this._resizeFactor;
4516
4830
  for (const particle of this._array) {
@@ -4521,15 +4835,17 @@ class Particles {
4521
4835
  particle.initialPosition.y *= resizeFactor.height;
4522
4836
  }
4523
4837
  particle.ignoresResizeRatio = false;
4524
- await this._interactionManager.reset(particle);
4838
+ this._interactionManager.reset(particle);
4525
4839
  for (const [, plugin] of this._container.plugins) {
4526
4840
  if (particle.destroyed) {
4527
4841
  break;
4528
4842
  }
4529
- plugin.particleUpdate && plugin.particleUpdate(particle, delta);
4843
+ plugin.particleUpdate?.(particle, delta);
4530
4844
  }
4531
4845
  for (const mover of this.movers) {
4532
- mover.isEnabled(particle) && mover.move(particle, delta);
4846
+ if (mover.isEnabled(particle)) {
4847
+ mover.move(particle, delta);
4848
+ }
4533
4849
  }
4534
4850
  if (particle.destroyed) {
4535
4851
  particlesToDelete.add(particle);
@@ -4564,7 +4880,8 @@ class Particles {
4564
4880
  if (this._needsSort) {
4565
4881
  const zArray = this._zArray;
4566
4882
  zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
4567
- this._lastZIndex = zArray[zArray.length - 1].position.z;
4883
+ const lengthOffset = 1;
4884
+ this._lastZIndex = zArray[zArray.length - lengthOffset].position.z;
4568
4885
  this._needsSort = false;
4569
4886
  }
4570
4887
  }
@@ -4572,17 +4889,19 @@ class Particles {
4572
4889
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Retina.js
4573
4890
 
4574
4891
 
4892
+ const defaultRatio = 1,
4893
+ defaultReduceFactor = 1;
4575
4894
  class Retina {
4576
4895
  constructor(container) {
4577
4896
  this.container = container;
4578
- this.pixelRatio = 1;
4579
- this.reduceFactor = 1;
4897
+ this.pixelRatio = defaultRatio;
4898
+ this.reduceFactor = defaultReduceFactor;
4580
4899
  }
4581
4900
  init() {
4582
4901
  const container = this.container,
4583
4902
  options = container.actualOptions;
4584
- this.pixelRatio = !options.detectRetina || isSsr() ? 1 : window.devicePixelRatio;
4585
- this.reduceFactor = 1;
4903
+ this.pixelRatio = !options.detectRetina || isSsr() ? defaultRatio : window.devicePixelRatio;
4904
+ this.reduceFactor = defaultReduceFactor;
4586
4905
  const ratio = this.pixelRatio,
4587
4906
  canvas = container.canvas;
4588
4907
  if (canvas.element) {
@@ -4623,10 +4942,11 @@ class Retina {
4623
4942
  function guardCheck(container) {
4624
4943
  return container && !container.destroyed;
4625
4944
  }
4626
- function initDelta(value, fpsLimit = 60, smooth = false) {
4945
+ const defaultFps = 60;
4946
+ function initDelta(value, fpsLimit = defaultFps, smooth = false) {
4627
4947
  return {
4628
4948
  value,
4629
- factor: smooth ? 60 / fpsLimit : 60 * value / 1000
4949
+ factor: smooth ? defaultFps / fpsLimit : defaultFps * value / millisecondsToSeconds
4630
4950
  };
4631
4951
  }
4632
4952
  function loadContainerOptions(engine, container, ...sourceOptionsArr) {
@@ -4644,12 +4964,16 @@ class Container {
4644
4964
  if (entry.target !== this.interactivity.element) {
4645
4965
  continue;
4646
4966
  }
4647
- (entry.isIntersecting ? this.play : this.pause)();
4967
+ if (entry.isIntersecting) {
4968
+ this.play();
4969
+ } else {
4970
+ this.pause();
4971
+ }
4648
4972
  }
4649
4973
  };
4650
4974
  this._nextFrame = async timestamp => {
4651
4975
  try {
4652
- if (!this._smooth && this._lastFrameTime !== undefined && timestamp < this._lastFrameTime + 1000 / this.fpsLimit) {
4976
+ if (!this._smooth && this._lastFrameTime !== undefined && timestamp < this._lastFrameTime + millisecondsToSeconds / this.fpsLimit) {
4653
4977
  this.draw(false);
4654
4978
  return;
4655
4979
  }
@@ -4657,7 +4981,7 @@ class Container {
4657
4981
  const delta = initDelta(timestamp - this._lastFrameTime, this.fpsLimit, this._smooth);
4658
4982
  this.addLifeTime(delta.value);
4659
4983
  this._lastFrameTime = timestamp;
4660
- if (delta.value > 1000) {
4984
+ if (delta.value > millisecondsToSeconds) {
4661
4985
  this.draw(false);
4662
4986
  return;
4663
4987
  }
@@ -4744,8 +5068,9 @@ class Container {
4744
5068
  pos = {
4745
5069
  x: mouseEvent.offsetX || mouseEvent.clientX,
4746
5070
  y: mouseEvent.offsetY || mouseEvent.clientY
4747
- };
4748
- clickOrTouchHandler(e, pos, 1);
5071
+ },
5072
+ radius = 1;
5073
+ clickOrTouchHandler(e, pos, radius);
4749
5074
  };
4750
5075
  const touchStartHandler = () => {
4751
5076
  if (!guardCheck(this)) {
@@ -4766,18 +5091,20 @@ class Container {
4766
5091
  }
4767
5092
  if (touched && !touchMoved) {
4768
5093
  const touchEvent = e;
4769
- let lastTouch = touchEvent.touches[touchEvent.touches.length - 1];
5094
+ const lengthOffset = 1;
5095
+ let lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset];
4770
5096
  if (!lastTouch) {
4771
- lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - 1];
5097
+ lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - lengthOffset];
4772
5098
  if (!lastTouch) {
4773
5099
  return;
4774
5100
  }
4775
5101
  }
4776
5102
  const element = this.canvas.element,
4777
5103
  canvasRect = element ? element.getBoundingClientRect() : undefined,
5104
+ minCoordinate = 0,
4778
5105
  pos = {
4779
- x: lastTouch.clientX - (canvasRect ? canvasRect.left : 0),
4780
- y: lastTouch.clientY - (canvasRect ? canvasRect.top : 0)
5106
+ x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
5107
+ y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate)
4781
5108
  };
4782
5109
  clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
4783
5110
  }
@@ -4820,10 +5147,10 @@ class Container {
4820
5147
  this.particles.destroy();
4821
5148
  this.canvas.destroy();
4822
5149
  for (const [, effectDrawer] of this.effectDrawers) {
4823
- effectDrawer.destroy && effectDrawer.destroy(this);
5150
+ effectDrawer.destroy?.(this);
4824
5151
  }
4825
5152
  for (const [, shapeDrawer] of this.shapeDrawers) {
4826
- shapeDrawer.destroy && shapeDrawer.destroy(this);
5153
+ shapeDrawer.destroy?.(this);
4827
5154
  }
4828
5155
  for (const key of this.effectDrawers.keys()) {
4829
5156
  this.effectDrawers.delete(key);
@@ -4834,9 +5161,11 @@ class Container {
4834
5161
  this._engine.clearPlugins(this);
4835
5162
  this.destroyed = true;
4836
5163
  const mainArr = this._engine.dom(),
4837
- idx = mainArr.findIndex(t => t === this);
4838
- if (idx >= 0) {
4839
- mainArr.splice(idx, 1);
5164
+ idx = mainArr.findIndex(t => t === this),
5165
+ minIndex = 0;
5166
+ if (idx >= minIndex) {
5167
+ const deleteCount = 1;
5168
+ mainArr.splice(idx, deleteCount);
4840
5169
  }
4841
5170
  this._engine.dispatchEvent("containerDestroyed", {
4842
5171
  container: this
@@ -4847,13 +5176,14 @@ class Container {
4847
5176
  return;
4848
5177
  }
4849
5178
  let refreshTime = force;
4850
- this._drawAnimationFrame = requestAnimationFrame(async timestamp => {
5179
+ const frame = async timestamp => {
4851
5180
  if (refreshTime) {
4852
5181
  this._lastFrameTime = undefined;
4853
5182
  refreshTime = false;
4854
5183
  }
4855
5184
  await this._nextFrame(timestamp);
4856
- });
5185
+ };
5186
+ this._drawAnimationFrame = requestAnimationFrame(timestamp => void frame(timestamp));
4857
5187
  }
4858
5188
  async export(type, options = {}) {
4859
5189
  for (const [, plugin] of this.plugins) {
@@ -4877,7 +5207,7 @@ class Container {
4877
5207
  }
4878
5208
  this.particles.handleClickMode(mode);
4879
5209
  for (const [, plugin] of this.plugins) {
4880
- plugin.handleClickMode && plugin.handleClickMode(mode);
5210
+ plugin.handleClickMode?.(mode);
4881
5211
  }
4882
5212
  }
4883
5213
  async init() {
@@ -4910,19 +5240,21 @@ class Container {
4910
5240
  this.canvas.initBackground();
4911
5241
  this.canvas.resize();
4912
5242
  this.zLayers = this.actualOptions.zLayers;
4913
- this._duration = getRangeValue(this.actualOptions.duration) * 1000;
4914
- this._delay = getRangeValue(this.actualOptions.delay) * 1000;
5243
+ this._duration = getRangeValue(this.actualOptions.duration) * millisecondsToSeconds;
5244
+ this._delay = getRangeValue(this.actualOptions.delay) * millisecondsToSeconds;
4915
5245
  this._lifeTime = 0;
4916
- this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 120;
5246
+ const defaultFpsLimit = 120,
5247
+ minFpsLimit = 0;
5248
+ this.fpsLimit = this.actualOptions.fpsLimit > minFpsLimit ? this.actualOptions.fpsLimit : defaultFpsLimit;
4917
5249
  this._smooth = this.actualOptions.smooth;
4918
5250
  for (const [, drawer] of this.effectDrawers) {
4919
- drawer.init && (await drawer.init(this));
5251
+ await drawer.init?.(this);
4920
5252
  }
4921
5253
  for (const [, drawer] of this.shapeDrawers) {
4922
- drawer.init && (await drawer.init(this));
5254
+ await drawer.init?.(this);
4923
5255
  }
4924
5256
  for (const [, plugin] of this.plugins) {
4925
- plugin.init && (await plugin.init());
5257
+ await plugin.init?.();
4926
5258
  }
4927
5259
  this._engine.dispatchEvent("containerInit", {
4928
5260
  container: this
@@ -4930,7 +5262,7 @@ class Container {
4930
5262
  this.particles.init();
4931
5263
  this.particles.setDensity();
4932
5264
  for (const [, plugin] of this.plugins) {
4933
- plugin.particlesSetup && plugin.particlesSetup();
5265
+ plugin.particlesSetup?.();
4934
5266
  }
4935
5267
  this._engine.dispatchEvent("particlesSetup", {
4936
5268
  container: this
@@ -4955,7 +5287,7 @@ class Container {
4955
5287
  return;
4956
5288
  }
4957
5289
  for (const [, plugin] of this.plugins) {
4958
- plugin.pause && plugin.pause();
5290
+ plugin.pause?.();
4959
5291
  }
4960
5292
  if (!this.pageHidden) {
4961
5293
  this._paused = true;
@@ -4986,7 +5318,7 @@ class Container {
4986
5318
  this._engine.dispatchEvent("containerPlay", {
4987
5319
  container: this
4988
5320
  });
4989
- this.draw(needsUpdate || false);
5321
+ this.draw(needsUpdate ?? false);
4990
5322
  }
4991
5323
  async refresh() {
4992
5324
  if (!guardCheck(this)) {
@@ -5011,20 +5343,21 @@ class Container {
5011
5343
  await this.init();
5012
5344
  this.started = true;
5013
5345
  await new Promise(resolve => {
5014
- this._delayTimeout = setTimeout(async () => {
5346
+ const start = async () => {
5015
5347
  this._eventListeners.addListeners();
5016
5348
  if (this.interactivity.element instanceof HTMLElement && this._intersectionObserver) {
5017
5349
  this._intersectionObserver.observe(this.interactivity.element);
5018
5350
  }
5019
5351
  for (const [, plugin] of this.plugins) {
5020
- plugin.start && (await plugin.start());
5352
+ await plugin.start?.();
5021
5353
  }
5022
5354
  this._engine.dispatchEvent("containerStarted", {
5023
5355
  container: this
5024
5356
  });
5025
5357
  this.play();
5026
5358
  resolve();
5027
- }, this._delay);
5359
+ };
5360
+ this._delayTimeout = setTimeout(() => void start(), this._delay);
5028
5361
  });
5029
5362
  }
5030
5363
  stop() {
@@ -5045,7 +5378,7 @@ class Container {
5045
5378
  this._intersectionObserver.unobserve(this.interactivity.element);
5046
5379
  }
5047
5380
  for (const [, plugin] of this.plugins) {
5048
- plugin.stop && plugin.stop();
5381
+ plugin.stop?.();
5049
5382
  }
5050
5383
  for (const key of this.plugins.keys()) {
5051
5384
  this.plugins.delete(key);
@@ -5082,7 +5415,7 @@ class EventDispatcher {
5082
5415
  }
5083
5416
  dispatchEvent(type, args) {
5084
5417
  const listeners = this._listeners.get(type);
5085
- listeners && listeners.forEach(handler => handler(args));
5418
+ listeners?.forEach(handler => handler(args));
5086
5419
  }
5087
5420
  hasEventListener(type) {
5088
5421
  return !!this._listeners.get(type);
@@ -5100,14 +5433,16 @@ class EventDispatcher {
5100
5433
  return;
5101
5434
  }
5102
5435
  const length = arr.length,
5103
- idx = arr.indexOf(listener);
5104
- if (idx < 0) {
5436
+ idx = arr.indexOf(listener),
5437
+ minIndex = 0;
5438
+ if (idx < minIndex) {
5105
5439
  return;
5106
5440
  }
5107
- if (length === 1) {
5441
+ const deleteCount = 1;
5442
+ if (length === deleteCount) {
5108
5443
  this._listeners.delete(type);
5109
5444
  } else {
5110
- arr.splice(idx, 1);
5445
+ arr.splice(idx, deleteCount);
5111
5446
  }
5112
5447
  }
5113
5448
  }
@@ -5165,21 +5500,23 @@ class Engine {
5165
5500
  return res;
5166
5501
  }
5167
5502
  get version() {
5168
- return "3.0.3";
5503
+ return "3.1.0";
5169
5504
  }
5170
5505
  addConfig(config) {
5171
- const name = config.name ?? "default";
5172
- this._configs.set(name, config);
5506
+ const key = config.key ?? config.name ?? "default";
5507
+ this._configs.set(key, config);
5173
5508
  this._eventDispatcher.dispatchEvent("configAdded", {
5174
5509
  data: {
5175
- name,
5510
+ name: key,
5176
5511
  config
5177
5512
  }
5178
5513
  });
5179
5514
  }
5180
5515
  async addEffect(effect, drawer, refresh = true) {
5181
5516
  executeOnSingleOrMultiple(effect, type => {
5182
- !this.getEffectDrawer(type) && this.effectDrawers.set(type, drawer);
5517
+ if (!this.getEffectDrawer(type)) {
5518
+ this.effectDrawers.set(type, drawer);
5519
+ }
5183
5520
  });
5184
5521
  await this.refresh(refresh);
5185
5522
  }
@@ -5199,20 +5536,28 @@ class Engine {
5199
5536
  await this.refresh(refresh);
5200
5537
  }
5201
5538
  async addPathGenerator(name, generator, refresh = true) {
5202
- !this.getPathGenerator(name) && this.pathGenerators.set(name, generator);
5539
+ if (!this.getPathGenerator(name)) {
5540
+ this.pathGenerators.set(name, generator);
5541
+ }
5203
5542
  await this.refresh(refresh);
5204
5543
  }
5205
5544
  async addPlugin(plugin, refresh = true) {
5206
- !this.getPlugin(plugin.id) && this.plugins.push(plugin);
5545
+ if (!this.getPlugin(plugin.id)) {
5546
+ this.plugins.push(plugin);
5547
+ }
5207
5548
  await this.refresh(refresh);
5208
5549
  }
5209
5550
  async addPreset(preset, options, override = false, refresh = true) {
5210
- (override || !this.getPreset(preset)) && this.presets.set(preset, options);
5551
+ if (override || !this.getPreset(preset)) {
5552
+ this.presets.set(preset, options);
5553
+ }
5211
5554
  await this.refresh(refresh);
5212
5555
  }
5213
5556
  async addShape(shape, drawer, refresh = true) {
5214
5557
  executeOnSingleOrMultiple(shape, type => {
5215
- !this.getShapeDrawer(type) && this.shapeDrawers.set(type, drawer);
5558
+ if (!this.getShapeDrawer(type)) {
5559
+ this.shapeDrawers.set(type, drawer);
5560
+ }
5216
5561
  });
5217
5562
  await this.refresh(refresh);
5218
5563
  }
@@ -5231,7 +5576,8 @@ class Engine {
5231
5576
  const dom = this.dom(),
5232
5577
  item = dom[index];
5233
5578
  if (!item || item.destroyed) {
5234
- dom.splice(index, 1);
5579
+ const deleteCount = 1;
5580
+ dom.splice(index, deleteCount);
5235
5581
  return;
5236
5582
  }
5237
5583
  return item;
@@ -5239,7 +5585,9 @@ class Engine {
5239
5585
  getAvailablePlugins(container) {
5240
5586
  const res = new Map();
5241
5587
  for (const plugin of this.plugins) {
5242
- plugin.needsPlugin(container.actualOptions) && res.set(plugin.id, plugin.getPlugin(container));
5588
+ if (plugin.needsPlugin(container.actualOptions)) {
5589
+ res.set(plugin.id, plugin.getPlugin(container));
5590
+ }
5243
5591
  }
5244
5592
  return res;
5245
5593
  }
@@ -5280,7 +5628,8 @@ class Engine {
5280
5628
  this._initialized = true;
5281
5629
  }
5282
5630
  async load(params) {
5283
- const id = params.id ?? params.element?.id ?? `tsparticles${Math.floor(getRandom() * 10000)}`,
5631
+ const randomFactor = 10000,
5632
+ id = params.id ?? params.element?.id ?? `tsparticles${Math.floor(getRandom() * randomFactor)}`,
5284
5633
  {
5285
5634
  index,
5286
5635
  url
@@ -5298,12 +5647,14 @@ class Engine {
5298
5647
  }
5299
5648
  const currentOptions = itemFromSingleOrMultiple(options, index),
5300
5649
  dom = this.dom(),
5301
- oldIndex = dom.findIndex(v => v.id.description === id);
5302
- if (oldIndex >= 0) {
5650
+ oldIndex = dom.findIndex(v => v.id.description === id),
5651
+ minIndex = 0;
5652
+ if (oldIndex >= minIndex) {
5303
5653
  const old = this.domItem(oldIndex);
5304
5654
  if (old && !old.destroyed) {
5305
5655
  old.destroy();
5306
- dom.splice(oldIndex, 1);
5656
+ const deleteCount = 1;
5657
+ dom.splice(oldIndex, deleteCount);
5307
5658
  }
5308
5659
  }
5309
5660
  let canvasEl;
@@ -5313,7 +5664,8 @@ class Engine {
5313
5664
  } else {
5314
5665
  const existingCanvases = domContainer.getElementsByTagName("canvas");
5315
5666
  if (existingCanvases.length) {
5316
- canvasEl = existingCanvases[0];
5667
+ const firstIndex = 0;
5668
+ canvasEl = existingCanvases[firstIndex];
5317
5669
  canvasEl.dataset[generatedAttribute] = "false";
5318
5670
  } else {
5319
5671
  canvasEl = document.createElement("canvas");
@@ -5328,8 +5680,9 @@ class Engine {
5328
5680
  canvasEl.style.height = "100%";
5329
5681
  }
5330
5682
  const newItem = new Container(this, id, currentOptions);
5331
- if (oldIndex >= 0) {
5332
- dom.splice(oldIndex, 0, newItem);
5683
+ if (oldIndex >= minIndex) {
5684
+ const deleteCount = 0;
5685
+ dom.splice(oldIndex, deleteCount, newItem);
5333
5686
  } else {
5334
5687
  dom.push(newItem);
5335
5688
  }
@@ -5348,14 +5701,14 @@ class Engine {
5348
5701
  return;
5349
5702
  }
5350
5703
  for (const updater of updaters) {
5351
- updater.loadOptions && updater.loadOptions(options, ...sourceOptions);
5704
+ updater.loadOptions?.(options, ...sourceOptions);
5352
5705
  }
5353
5706
  }
5354
5707
  async refresh(refresh = true) {
5355
5708
  if (!refresh) {
5356
5709
  return;
5357
5710
  }
5358
- this.dom().forEach(t => t.refresh());
5711
+ await Promise.allSettled(this.dom().map(t => t.refresh()));
5359
5712
  }
5360
5713
  removeEventListener(type, listener) {
5361
5714
  this._eventDispatcher.removeEventListener(type, listener);
@@ -5401,12 +5754,15 @@ class HslColorManager {
5401
5754
  return;
5402
5755
  }
5403
5756
  const regex = /hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.%]+)\s*)?\)/i,
5404
- result = regex.exec(input);
5757
+ result = regex.exec(input),
5758
+ minLength = 4,
5759
+ defaultAlpha = 1,
5760
+ radix = 10;
5405
5761
  return result ? hslaToRgba({
5406
- a: result.length > 4 ? parseAlpha(result[5]) : 1,
5407
- h: parseInt(result[1], 10),
5408
- l: parseInt(result[3], 10),
5409
- s: parseInt(result[2], 10)
5762
+ a: result.length > minLength ? parseAlpha(result[5]) : defaultAlpha,
5763
+ h: parseInt(result[1], radix),
5764
+ l: parseInt(result[3], radix),
5765
+ s: parseInt(result[2], radix)
5410
5766
  }) : undefined;
5411
5767
  }
5412
5768
  }
@@ -5440,12 +5796,15 @@ class RgbColorManager {
5440
5796
  return;
5441
5797
  }
5442
5798
  const regex = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.%]+)\s*)?\)/i,
5443
- result = regex.exec(input);
5799
+ result = regex.exec(input),
5800
+ radix = 10,
5801
+ minLength = 4,
5802
+ defaultAlpha = 1;
5444
5803
  return result ? {
5445
- a: result.length > 4 ? parseAlpha(result[5]) : 1,
5446
- b: parseInt(result[3], 10),
5447
- g: parseInt(result[2], 10),
5448
- r: parseInt(result[1], 10)
5804
+ a: result.length > minLength ? parseAlpha(result[5]) : defaultAlpha,
5805
+ b: parseInt(result[3], radix),
5806
+ g: parseInt(result[2], radix),
5807
+ r: parseInt(result[1], radix)
5449
5808
  } : undefined;
5450
5809
  }
5451
5810
  }
@@ -5466,15 +5825,15 @@ function init() {
5466
5825
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/ExternalInteractorBase.js
5467
5826
  class ExternalInteractorBase {
5468
5827
  constructor(container) {
5469
- this.container = container;
5470
5828
  this.type = "external";
5829
+ this.container = container;
5471
5830
  }
5472
5831
  }
5473
5832
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/ParticlesInteractorBase.js
5474
5833
  class ParticlesInteractorBase {
5475
5834
  constructor(container) {
5476
- this.container = container;
5477
5835
  this.type = "particles";
5836
+ this.container = container;
5478
5837
  }
5479
5838
  }
5480
5839
  ;// CONCATENATED MODULE: ../../engine/dist/browser/exports.js
@@ -5648,6 +6007,12 @@ class FireworkOptions {
5648
6007
  }
5649
6008
  ;// CONCATENATED MODULE: ../../move/base/dist/browser/Utils.js
5650
6009
 
6010
+ const Utils_half = 0.5,
6011
+ minVelocity = 0,
6012
+ identity = 1,
6013
+ moveSpeedFactor = 60,
6014
+ minSpinRadius = 0,
6015
+ spinFactor = 0.01;
5651
6016
  function applyDistance(particle) {
5652
6017
  const initialPosition = particle.initialPosition,
5653
6018
  {
@@ -5664,23 +6029,25 @@ function applyDistance(particle) {
5664
6029
  if (!hDistance && !vDistance) {
5665
6030
  return;
5666
6031
  }
5667
- if ((hDistance && dxFixed >= hDistance || vDistance && dyFixed >= vDistance) && !particle.misplaced) {
6032
+ const hasHDistance = (hDistance && dxFixed >= hDistance) ?? false,
6033
+ hasVDistance = (vDistance && dyFixed >= vDistance) ?? false;
6034
+ if ((hasHDistance || hasVDistance) && !particle.misplaced) {
5668
6035
  particle.misplaced = !!hDistance && dxFixed > hDistance || !!vDistance && dyFixed > vDistance;
5669
6036
  if (hDistance) {
5670
- particle.velocity.x = particle.velocity.y * 0.5 - particle.velocity.x;
6037
+ particle.velocity.x = particle.velocity.y * Utils_half - particle.velocity.x;
5671
6038
  }
5672
6039
  if (vDistance) {
5673
- particle.velocity.y = particle.velocity.x * 0.5 - particle.velocity.y;
6040
+ particle.velocity.y = particle.velocity.x * Utils_half - particle.velocity.y;
5674
6041
  }
5675
6042
  } else if ((!hDistance || dxFixed < hDistance) && (!vDistance || dyFixed < vDistance) && particle.misplaced) {
5676
6043
  particle.misplaced = false;
5677
6044
  } else if (particle.misplaced) {
5678
6045
  const pos = particle.position,
5679
6046
  vel = particle.velocity;
5680
- if (hDistance && (pos.x < initialPosition.x && vel.x < 0 || pos.x > initialPosition.x && vel.x > 0)) {
6047
+ if (hDistance && (pos.x < initialPosition.x && vel.x < minVelocity || pos.x > initialPosition.x && vel.x > minVelocity)) {
5681
6048
  vel.x *= -getRandom();
5682
6049
  }
5683
- if (vDistance && (pos.y < initialPosition.y && vel.y < 0 || pos.y > initialPosition.y && vel.y > 0)) {
6050
+ if (vDistance && (pos.y < initialPosition.y && vel.y < minVelocity || pos.y > initialPosition.y && vel.y > minVelocity)) {
5684
6051
  vel.y *= -getRandom();
5685
6052
  }
5686
6053
  }
@@ -5688,24 +6055,24 @@ function applyDistance(particle) {
5688
6055
  function move(particle, moveOptions, moveSpeed, maxSpeed, moveDrift, delta) {
5689
6056
  applyPath(particle, delta);
5690
6057
  const gravityOptions = particle.gravity,
5691
- gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -1 : 1;
6058
+ gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -identity : identity;
5692
6059
  if (moveDrift && moveSpeed) {
5693
- particle.velocity.x += moveDrift * delta.factor / (60 * moveSpeed);
6060
+ particle.velocity.x += moveDrift * delta.factor / (moveSpeedFactor * moveSpeed);
5694
6061
  }
5695
6062
  if (gravityOptions?.enable && moveSpeed) {
5696
- particle.velocity.y += gravityFactor * (gravityOptions.acceleration * delta.factor) / (60 * moveSpeed);
6063
+ particle.velocity.y += gravityFactor * (gravityOptions.acceleration * delta.factor) / (moveSpeedFactor * moveSpeed);
5697
6064
  }
5698
6065
  const decay = particle.moveDecay;
5699
6066
  particle.velocity.multTo(decay);
5700
6067
  const velocity = particle.velocity.mult(moveSpeed);
5701
- if (gravityOptions?.enable && maxSpeed > 0 && (!gravityOptions.inverse && velocity.y >= 0 && velocity.y >= maxSpeed || gravityOptions.inverse && velocity.y <= 0 && velocity.y <= -maxSpeed)) {
6068
+ if (gravityOptions?.enable && maxSpeed > minVelocity && (!gravityOptions.inverse && velocity.y >= minVelocity && velocity.y >= maxSpeed || gravityOptions.inverse && velocity.y <= minVelocity && velocity.y <= -maxSpeed)) {
5702
6069
  velocity.y = gravityFactor * maxSpeed;
5703
6070
  if (moveSpeed) {
5704
6071
  particle.velocity.y = velocity.y / moveSpeed;
5705
6072
  }
5706
6073
  }
5707
6074
  const zIndexOptions = particle.options.zIndex,
5708
- zVelocityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
6075
+ zVelocityFactor = (identity - particle.zIndexFactor) ** zIndexOptions.velocityRate;
5709
6076
  velocity.multTo(zVelocityFactor);
5710
6077
  const {
5711
6078
  position
@@ -5729,15 +6096,15 @@ function spin(particle, moveSpeed) {
5729
6096
  particle.position.y = particle.spin.center.y + particle.spin.radius * updateFunc.y(particle.spin.angle);
5730
6097
  particle.spin.radius += particle.spin.acceleration;
5731
6098
  const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height),
5732
- halfMaxSize = maxCanvasSize * 0.5;
6099
+ halfMaxSize = maxCanvasSize * Utils_half;
5733
6100
  if (particle.spin.radius > halfMaxSize) {
5734
6101
  particle.spin.radius = halfMaxSize;
5735
- particle.spin.acceleration *= -1;
5736
- } else if (particle.spin.radius < 0) {
5737
- particle.spin.radius = 0;
5738
- particle.spin.acceleration *= -1;
6102
+ particle.spin.acceleration *= -identity;
6103
+ } else if (particle.spin.radius < minSpinRadius) {
6104
+ particle.spin.radius = minSpinRadius;
6105
+ particle.spin.acceleration *= -identity;
5739
6106
  }
5740
- particle.spin.angle += moveSpeed * 0.01 * (1 - particle.spin.radius / maxCanvasSize);
6107
+ particle.spin.angle += moveSpeed * spinFactor * (identity - particle.spin.radius / maxCanvasSize);
5741
6108
  }
5742
6109
  function applyPath(particle, delta) {
5743
6110
  const particlesOptions = particle.options,
@@ -5755,18 +6122,20 @@ function applyPath(particle, delta) {
5755
6122
  particle.velocity.addTo(path);
5756
6123
  }
5757
6124
  if (pathOptions.clamp) {
5758
- particle.velocity.x = clamp(particle.velocity.x, -1, 1);
5759
- particle.velocity.y = clamp(particle.velocity.y, -1, 1);
6125
+ particle.velocity.x = clamp(particle.velocity.x, -identity, identity);
6126
+ particle.velocity.y = clamp(particle.velocity.y, -identity, identity);
5760
6127
  }
5761
6128
  particle.lastPathTime -= particle.pathDelay;
5762
6129
  }
5763
6130
  function getProximitySpeedFactor(particle) {
5764
- return particle.slow.inRange ? particle.slow.factor : 1;
6131
+ return particle.slow.inRange ? particle.slow.factor : identity;
5765
6132
  }
5766
6133
  ;// CONCATENATED MODULE: ../../move/base/dist/browser/BaseMover.js
5767
6134
 
5768
6135
 
5769
- const diffFactor = 2;
6136
+ const diffFactor = 2,
6137
+ defaultSizeFactor = 1,
6138
+ defaultDeltaFactor = 1;
5770
6139
  class BaseMover {
5771
6140
  constructor() {
5772
6141
  this._initSpin = particle => {
@@ -5780,17 +6149,19 @@ class BaseMover {
5780
6149
  x: 50,
5781
6150
  y: 50
5782
6151
  },
6152
+ spinFactor = 0.01,
5783
6153
  spinCenter = {
5784
- x: spinPos.x * 0.01 * container.canvas.size.width,
5785
- y: spinPos.y * 0.01 * container.canvas.size.height
6154
+ x: spinPos.x * spinFactor * container.canvas.size.width,
6155
+ y: spinPos.y * spinFactor * container.canvas.size.height
5786
6156
  },
5787
6157
  pos = particle.getPosition(),
5788
6158
  distance = getDistance(pos, spinCenter),
5789
6159
  spinAcceleration = getRangeValue(spinOptions.acceleration);
5790
6160
  particle.retina.spinAcceleration = spinAcceleration * container.retina.pixelRatio;
6161
+ const minVelocity = 0;
5791
6162
  particle.spin = {
5792
6163
  center: spinCenter,
5793
- direction: particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise",
6164
+ direction: particle.velocity.x >= minVelocity ? "clockwise" : "counter-clockwise",
5794
6165
  angle: particle.velocity.angle,
5795
6166
  radius: distance,
5796
6167
  acceleration: particle.retina.spinAcceleration
@@ -5817,13 +6188,16 @@ class BaseMover {
5817
6188
  return;
5818
6189
  }
5819
6190
  const container = particle.container,
5820
- pxRatio = container.retina.pixelRatio,
5821
- slowFactor = getProximitySpeedFactor(particle),
5822
- baseSpeed = (particle.retina.moveSpeed ??= getRangeValue(moveOptions.speed) * pxRatio) * container.retina.reduceFactor,
5823
- moveDrift = particle.retina.moveDrift ??= getRangeValue(particle.options.move.drift) * pxRatio,
6191
+ pxRatio = container.retina.pixelRatio;
6192
+ particle.retina.moveSpeed ??= getRangeValue(moveOptions.speed) * pxRatio;
6193
+ particle.retina.moveDrift ??= getRangeValue(particle.options.move.drift) * pxRatio;
6194
+ const slowFactor = getProximitySpeedFactor(particle),
6195
+ baseSpeed = particle.retina.moveSpeed * container.retina.reduceFactor,
6196
+ moveDrift = particle.retina.moveDrift,
5824
6197
  maxSize = getRangeMax(particleOptions.size.value) * pxRatio,
5825
- sizeFactor = moveOptions.size ? particle.getRadius() / maxSize : 1,
5826
- moveSpeed = baseSpeed * sizeFactor * slowFactor * (delta.factor || 1) / diffFactor,
6198
+ sizeFactor = moveOptions.size ? particle.getRadius() / maxSize : defaultSizeFactor,
6199
+ deltaFactor = delta.factor || defaultDeltaFactor,
6200
+ moveSpeed = baseSpeed * sizeFactor * slowFactor * deltaFactor / diffFactor,
5827
6201
  maxSpeed = particle.retina.maxSpeed ?? container.retina.maxSpeed;
5828
6202
  if (moveOptions.spin.enable) {
5829
6203
  spin(particle, moveSpeed);
@@ -5840,6 +6214,15 @@ async function loadBaseMover(engine, refresh = true) {
5840
6214
  }
5841
6215
  ;// CONCATENATED MODULE: ../../shapes/circle/dist/browser/CircleDrawer.js
5842
6216
 
6217
+ const CircleDrawer_double = 2,
6218
+ CircleDrawer_doublePI = Math.PI * CircleDrawer_double,
6219
+ sides = 12,
6220
+ maxAngle = 360,
6221
+ minAngle = 0,
6222
+ CircleDrawer_origin = {
6223
+ x: 0,
6224
+ y: 0
6225
+ };
5843
6226
  class CircleDrawer {
5844
6227
  draw(data) {
5845
6228
  const {
@@ -5849,28 +6232,28 @@ class CircleDrawer {
5849
6232
  } = data;
5850
6233
  if (!particle.circleRange) {
5851
6234
  particle.circleRange = {
5852
- min: 0,
5853
- max: Math.PI * 2
6235
+ min: minAngle,
6236
+ max: CircleDrawer_doublePI
5854
6237
  };
5855
6238
  }
5856
6239
  const circleRange = particle.circleRange;
5857
- context.arc(0, 0, radius, circleRange.min, circleRange.max, false);
6240
+ context.arc(CircleDrawer_origin.x, CircleDrawer_origin.y, radius, circleRange.min, circleRange.max, false);
5858
6241
  }
5859
6242
  getSidesCount() {
5860
- return 12;
6243
+ return sides;
5861
6244
  }
5862
6245
  particleInit(container, particle) {
5863
6246
  const shapeData = particle.shapeData,
5864
6247
  angle = shapeData?.angle ?? {
5865
- max: 360,
5866
- min: 0
6248
+ max: maxAngle,
6249
+ min: minAngle
5867
6250
  };
5868
6251
  particle.circleRange = !isObject(angle) ? {
5869
- min: 0,
5870
- max: angle * Math.PI / 180
6252
+ min: minAngle,
6253
+ max: degToRad(angle)
5871
6254
  } : {
5872
- min: angle.min * Math.PI / 180,
5873
- max: angle.max * Math.PI / 180
6255
+ min: degToRad(angle.min),
6256
+ max: degToRad(angle.max)
5874
6257
  };
5875
6258
  }
5876
6259
  }
@@ -5879,84 +6262,8 @@ class CircleDrawer {
5879
6262
  async function loadCircleShape(engine, refresh = true) {
5880
6263
  await engine.addShape("circle", new CircleDrawer(), refresh);
5881
6264
  }
5882
- ;// CONCATENATED MODULE: ../../updaters/color/dist/browser/Utils.js
5883
-
5884
- function updateColorValue(delta, colorValue, valueAnimation, max, decrease) {
5885
- if (!colorValue || !valueAnimation.enable || (colorValue.maxLoops ?? 0) > 0 && (colorValue.loops ?? 0) > (colorValue.maxLoops ?? 0)) {
5886
- return;
5887
- }
5888
- if (!colorValue.time) {
5889
- colorValue.time = 0;
5890
- }
5891
- if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
5892
- colorValue.time += delta.value;
5893
- }
5894
- if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
5895
- return;
5896
- }
5897
- const offset = randomInRange(valueAnimation.offset),
5898
- velocity = (colorValue.velocity ?? 0) * delta.factor + offset * 3.6,
5899
- decay = colorValue.decay ?? 1;
5900
- if (!decrease || colorValue.status === "increasing") {
5901
- colorValue.value += velocity;
5902
- if (colorValue.value > max) {
5903
- if (!colorValue.loops) {
5904
- colorValue.loops = 0;
5905
- }
5906
- colorValue.loops++;
5907
- if (decrease) {
5908
- colorValue.status = "decreasing";
5909
- colorValue.value -= colorValue.value % max;
5910
- }
5911
- }
5912
- } else {
5913
- colorValue.value -= velocity;
5914
- if (colorValue.value < 0) {
5915
- if (!colorValue.loops) {
5916
- colorValue.loops = 0;
5917
- }
5918
- colorValue.loops++;
5919
- colorValue.status = "increasing";
5920
- colorValue.value += colorValue.value;
5921
- }
5922
- }
5923
- if (colorValue.velocity && decay !== 1) {
5924
- colorValue.velocity *= decay;
5925
- }
5926
- if (colorValue.value > max) {
5927
- colorValue.value %= max;
5928
- }
5929
- }
5930
- function updateColor(particle, delta) {
5931
- const {
5932
- h: hAnimation,
5933
- s: sAnimation,
5934
- l: lAnimation
5935
- } = particle.options.color.animation,
5936
- {
5937
- color
5938
- } = particle;
5939
- if (!color) {
5940
- return;
5941
- }
5942
- const {
5943
- h,
5944
- s,
5945
- l
5946
- } = color;
5947
- if (h) {
5948
- updateColorValue(delta, h, hAnimation, 360, false);
5949
- }
5950
- if (s) {
5951
- updateColorValue(delta, s, sAnimation, 100, true);
5952
- }
5953
- if (l) {
5954
- updateColorValue(delta, l, lAnimation, 100, true);
5955
- }
5956
- }
5957
6265
  ;// CONCATENATED MODULE: ../../updaters/color/dist/browser/ColorUpdater.js
5958
6266
 
5959
-
5960
6267
  class ColorUpdater {
5961
6268
  constructor(container) {
5962
6269
  this.container = container;
@@ -5979,7 +6286,7 @@ class ColorUpdater {
5979
6286
  return !particle.destroyed && !particle.spawning && (color?.h.value !== undefined && hAnimation.enable || color?.s.value !== undefined && sAnimation.enable || color?.l.value !== undefined && lAnimation.enable);
5980
6287
  }
5981
6288
  update(particle, delta) {
5982
- updateColor(particle, delta);
6289
+ updateColor(particle.color, delta);
5983
6290
  }
5984
6291
  }
5985
6292
  ;// CONCATENATED MODULE: ../../updaters/color/dist/browser/index.js
@@ -5987,103 +6294,39 @@ class ColorUpdater {
5987
6294
  async function loadColorUpdater(engine, refresh = true) {
5988
6295
  await engine.addParticleUpdater("color", container => new ColorUpdater(container), refresh);
5989
6296
  }
5990
- ;// CONCATENATED MODULE: ../../updaters/opacity/dist/browser/Utils.js
6297
+ ;// CONCATENATED MODULE: ../../updaters/opacity/dist/browser/OpacityUpdater.js
5991
6298
 
5992
- function checkDestroy(particle, value, minValue, maxValue) {
5993
- switch (particle.options.opacity.animation.destroy) {
5994
- case "max":
5995
- if (value >= maxValue) {
5996
- particle.destroy();
5997
- }
5998
- break;
5999
- case "min":
6000
- if (value <= minValue) {
6001
- particle.destroy();
6299
+ class OpacityUpdater {
6300
+ constructor(container) {
6301
+ this.container = container;
6302
+ }
6303
+ init(particle) {
6304
+ const opacityOptions = particle.options.opacity,
6305
+ pxRatio = 1;
6306
+ particle.opacity = initParticleNumericAnimationValue(opacityOptions, pxRatio);
6307
+ const opacityAnimation = opacityOptions.animation;
6308
+ if (opacityAnimation.enable) {
6309
+ particle.opacity.velocity = getRangeValue(opacityAnimation.speed) / percentDenominator * this.container.retina.reduceFactor;
6310
+ if (!opacityAnimation.sync) {
6311
+ particle.opacity.velocity *= getRandom();
6002
6312
  }
6003
- break;
6313
+ }
6004
6314
  }
6005
- }
6006
- function updateOpacity(particle, delta) {
6007
- const data = particle.opacity;
6008
- if (particle.destroyed || !data?.enable || (data.maxLoops ?? 0) > 0 && (data.loops ?? 0) > (data.maxLoops ?? 0)) {
6009
- return;
6315
+ isEnabled(particle) {
6316
+ const none = 0;
6317
+ return !particle.destroyed && !particle.spawning && !!particle.opacity && particle.opacity.enable && ((particle.opacity.maxLoops ?? none) <= none || (particle.opacity.maxLoops ?? none) > none && (particle.opacity.loops ?? none) < (particle.opacity.maxLoops ?? none));
6010
6318
  }
6011
- const minValue = data.min,
6012
- maxValue = data.max,
6013
- decay = data.decay ?? 1;
6014
- if (!data.time) {
6015
- data.time = 0;
6016
- }
6017
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
6018
- data.time += delta.value;
6019
- }
6020
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
6021
- return;
6022
- }
6023
- switch (data.status) {
6024
- case "increasing":
6025
- if (data.value >= maxValue) {
6026
- data.status = "decreasing";
6027
- if (!data.loops) {
6028
- data.loops = 0;
6029
- }
6030
- data.loops++;
6031
- } else {
6032
- data.value += (data.velocity ?? 0) * delta.factor;
6033
- }
6034
- break;
6035
- case "decreasing":
6036
- if (data.value <= minValue) {
6037
- data.status = "increasing";
6038
- if (!data.loops) {
6039
- data.loops = 0;
6040
- }
6041
- data.loops++;
6042
- } else {
6043
- data.value -= (data.velocity ?? 0) * delta.factor;
6044
- }
6045
- break;
6046
- }
6047
- if (data.velocity && data.decay !== 1) {
6048
- data.velocity *= decay;
6049
- }
6050
- checkDestroy(particle, data.value, minValue, maxValue);
6051
- if (!particle.destroyed) {
6052
- data.value = clamp(data.value, minValue, maxValue);
6053
- }
6054
- }
6055
- ;// CONCATENATED MODULE: ../../updaters/opacity/dist/browser/OpacityUpdater.js
6056
-
6057
-
6058
- class OpacityUpdater {
6059
- constructor(container) {
6060
- this.container = container;
6061
- }
6062
- init(particle) {
6063
- const opacityOptions = particle.options.opacity;
6064
- particle.opacity = initParticleNumericAnimationValue(opacityOptions, 1);
6065
- const opacityAnimation = opacityOptions.animation;
6066
- if (opacityAnimation.enable) {
6067
- particle.opacity.velocity = getRangeValue(opacityAnimation.speed) / 100 * this.container.retina.reduceFactor;
6068
- if (!opacityAnimation.sync) {
6069
- particle.opacity.velocity *= getRandom();
6070
- }
6071
- }
6072
- }
6073
- isEnabled(particle) {
6074
- return !particle.destroyed && !particle.spawning && !!particle.opacity && particle.opacity.enable && ((particle.opacity.maxLoops ?? 0) <= 0 || (particle.opacity.maxLoops ?? 0) > 0 && (particle.opacity.loops ?? 0) < (particle.opacity.maxLoops ?? 0));
6075
- }
6076
- reset(particle) {
6077
- if (particle.opacity) {
6078
- particle.opacity.time = 0;
6079
- particle.opacity.loops = 0;
6080
- }
6319
+ reset(particle) {
6320
+ if (particle.opacity) {
6321
+ particle.opacity.time = 0;
6322
+ particle.opacity.loops = 0;
6323
+ }
6081
6324
  }
6082
6325
  update(particle, delta) {
6083
- if (!this.isEnabled(particle)) {
6326
+ if (!this.isEnabled(particle) || !particle.opacity) {
6084
6327
  return;
6085
6328
  }
6086
- updateOpacity(particle, delta);
6329
+ updateAnimation(particle, particle.opacity, true, particle.options.opacity.animation.destroy, delta);
6087
6330
  }
6088
6331
  }
6089
6332
  ;// CONCATENATED MODULE: ../../updaters/opacity/dist/browser/index.js
@@ -6093,18 +6336,20 @@ async function loadOpacityUpdater(engine, refresh = true) {
6093
6336
  }
6094
6337
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/Utils.js
6095
6338
 
6339
+ const Utils_minVelocity = 0,
6340
+ boundsMin = 0;
6096
6341
  function bounceHorizontal(data) {
6097
6342
  if (data.outMode !== "bounce" && data.outMode !== "bounce-horizontal" && data.outMode !== "bounceHorizontal" && data.outMode !== "split" || data.direction !== "left" && data.direction !== "right") {
6098
6343
  return;
6099
6344
  }
6100
- if (data.bounds.right < 0 && data.direction === "left") {
6345
+ if (data.bounds.right < boundsMin && data.direction === "left") {
6101
6346
  data.particle.position.x = data.size + data.offset.x;
6102
6347
  } else if (data.bounds.left > data.canvasSize.width && data.direction === "right") {
6103
6348
  data.particle.position.x = data.canvasSize.width - data.size - data.offset.x;
6104
6349
  }
6105
6350
  const velocity = data.particle.velocity.x;
6106
6351
  let bounced = false;
6107
- if (data.direction === "right" && data.bounds.right >= data.canvasSize.width && velocity > 0 || data.direction === "left" && data.bounds.left <= 0 && velocity < 0) {
6352
+ if (data.direction === "right" && data.bounds.right >= data.canvasSize.width && velocity > Utils_minVelocity || data.direction === "left" && data.bounds.left <= boundsMin && velocity < Utils_minVelocity) {
6108
6353
  const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
6109
6354
  data.particle.velocity.x *= -newVelocity;
6110
6355
  bounced = true;
@@ -6115,7 +6360,7 @@ function bounceHorizontal(data) {
6115
6360
  const minPos = data.offset.x + data.size;
6116
6361
  if (data.bounds.right >= data.canvasSize.width && data.direction === "right") {
6117
6362
  data.particle.position.x = data.canvasSize.width - minPos;
6118
- } else if (data.bounds.left <= 0 && data.direction === "left") {
6363
+ } else if (data.bounds.left <= boundsMin && data.direction === "left") {
6119
6364
  data.particle.position.x = minPos;
6120
6365
  }
6121
6366
  if (data.outMode === "split") {
@@ -6126,14 +6371,14 @@ function bounceVertical(data) {
6126
6371
  if (data.outMode !== "bounce" && data.outMode !== "bounce-vertical" && data.outMode !== "bounceVertical" && data.outMode !== "split" || data.direction !== "bottom" && data.direction !== "top") {
6127
6372
  return;
6128
6373
  }
6129
- if (data.bounds.bottom < 0 && data.direction === "top") {
6374
+ if (data.bounds.bottom < boundsMin && data.direction === "top") {
6130
6375
  data.particle.position.y = data.size + data.offset.y;
6131
6376
  } else if (data.bounds.top > data.canvasSize.height && data.direction === "bottom") {
6132
6377
  data.particle.position.y = data.canvasSize.height - data.size - data.offset.y;
6133
6378
  }
6134
6379
  const velocity = data.particle.velocity.y;
6135
6380
  let bounced = false;
6136
- if (data.direction === "bottom" && data.bounds.bottom >= data.canvasSize.height && velocity > 0 || data.direction === "top" && data.bounds.top <= 0 && velocity < 0) {
6381
+ if (data.direction === "bottom" && data.bounds.bottom >= data.canvasSize.height && velocity > Utils_minVelocity || data.direction === "top" && data.bounds.top <= boundsMin && velocity < Utils_minVelocity) {
6137
6382
  const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
6138
6383
  data.particle.velocity.y *= -newVelocity;
6139
6384
  bounced = true;
@@ -6144,7 +6389,7 @@ function bounceVertical(data) {
6144
6389
  const minPos = data.offset.y + data.size;
6145
6390
  if (data.bounds.bottom >= data.canvasSize.height && data.direction === "bottom") {
6146
6391
  data.particle.position.y = data.canvasSize.height - minPos;
6147
- } else if (data.bounds.top <= 0 && data.direction === "top") {
6392
+ } else if (data.bounds.top <= boundsMin && data.direction === "top") {
6148
6393
  data.particle.position.y = minPos;
6149
6394
  }
6150
6395
  if (data.outMode === "split") {
@@ -6203,6 +6448,7 @@ class BounceOutMode {
6203
6448
  }
6204
6449
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/DestroyOutMode.js
6205
6450
 
6451
+ const DestroyOutMode_minVelocity = 0;
6206
6452
  class DestroyOutMode {
6207
6453
  constructor(container) {
6208
6454
  this.container = container;
@@ -6230,7 +6476,7 @@ class DestroyOutMode {
6230
6476
  x: vx,
6231
6477
  y: vy
6232
6478
  } = particle.velocity;
6233
- if (vx < 0 && dx > particle.moveCenter.radius || vy < 0 && dy > particle.moveCenter.radius || vx >= 0 && dx < -particle.moveCenter.radius || vy >= 0 && dy < -particle.moveCenter.radius) {
6479
+ if (vx < DestroyOutMode_minVelocity && dx > particle.moveCenter.radius || vy < DestroyOutMode_minVelocity && dy > particle.moveCenter.radius || vx >= DestroyOutMode_minVelocity && dx < -particle.moveCenter.radius || vy >= DestroyOutMode_minVelocity && dy < -particle.moveCenter.radius) {
6234
6480
  return;
6235
6481
  }
6236
6482
  break;
@@ -6241,6 +6487,7 @@ class DestroyOutMode {
6241
6487
  }
6242
6488
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/NoneOutMode.js
6243
6489
 
6490
+ const NoneOutMode_minVelocity = 0;
6244
6491
  class NoneOutMode {
6245
6492
  constructor(container) {
6246
6493
  this.container = container;
@@ -6250,7 +6497,7 @@ class NoneOutMode {
6250
6497
  if (!this.modes.includes(outMode)) {
6251
6498
  return;
6252
6499
  }
6253
- if (particle.options.move.distance.horizontal && (direction === "left" || direction === "right") || particle.options.move.distance.vertical && (direction === "top" || direction === "bottom")) {
6500
+ if ((particle.options.move.distance.horizontal && (direction === "left" || direction === "right")) ?? (particle.options.move.distance.vertical && (direction === "top" || direction === "bottom"))) {
6254
6501
  return;
6255
6502
  }
6256
6503
  const gravityOptions = particle.options.move.gravity,
@@ -6258,7 +6505,7 @@ class NoneOutMode {
6258
6505
  const canvasSize = container.canvas.size;
6259
6506
  const pRadius = particle.getRadius();
6260
6507
  if (!gravityOptions.enable) {
6261
- if (particle.velocity.y > 0 && particle.position.y <= canvasSize.height + pRadius || particle.velocity.y < 0 && particle.position.y >= -pRadius || particle.velocity.x > 0 && particle.position.x <= canvasSize.width + pRadius || particle.velocity.x < 0 && particle.position.x >= -pRadius) {
6508
+ if (particle.velocity.y > NoneOutMode_minVelocity && particle.position.y <= canvasSize.height + pRadius || particle.velocity.y < NoneOutMode_minVelocity && particle.position.y >= -pRadius || particle.velocity.x > NoneOutMode_minVelocity && particle.position.x <= canvasSize.width + pRadius || particle.velocity.x < NoneOutMode_minVelocity && particle.position.x >= -pRadius) {
6262
6509
  return;
6263
6510
  }
6264
6511
  if (!isPointInside(particle.position, container.canvas.size, Vector.origin, pRadius, direction)) {
@@ -6274,6 +6521,8 @@ class NoneOutMode {
6274
6521
  }
6275
6522
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/OutOutMode.js
6276
6523
 
6524
+ const OutOutMode_minVelocity = 0,
6525
+ minDistance = 0;
6277
6526
  class OutOutMode {
6278
6527
  constructor(container) {
6279
6528
  this.container = container;
@@ -6299,7 +6548,7 @@ class OutOutMode {
6299
6548
  dx,
6300
6549
  dy
6301
6550
  } = getDistances(particle.position, circVec);
6302
- if (vx <= 0 && dx >= 0 || vy <= 0 && dy >= 0 || vx >= 0 && dx <= 0 || vy >= 0 && dy <= 0) {
6551
+ if (vx <= OutOutMode_minVelocity && dx >= minDistance || vy <= OutOutMode_minVelocity && dy >= minDistance || vx >= OutOutMode_minVelocity && dx <= minDistance || vy >= OutOutMode_minVelocity && dy <= minDistance) {
6303
6552
  return;
6304
6553
  }
6305
6554
  particle.position.x = Math.floor(randomInRange({
@@ -6401,12 +6650,12 @@ class OutOutMode {
6401
6650
 
6402
6651
  class OutOfCanvasUpdater {
6403
6652
  constructor(container) {
6404
- this.container = container;
6405
6653
  this._updateOutMode = (particle, delta, outMode, direction) => {
6406
6654
  for (const updater of this.updaters) {
6407
6655
  updater.update(particle, direction, delta, outMode);
6408
6656
  }
6409
6657
  };
6658
+ this.container = container;
6410
6659
  this.updaters = [new BounceOutMode(container), new DestroyOutMode(container), new OutOutMode(container), new NoneOutMode(container)];
6411
6660
  }
6412
6661
  init() {}
@@ -6426,97 +6675,32 @@ class OutOfCanvasUpdater {
6426
6675
  async function loadOutModesUpdater(engine, refresh = true) {
6427
6676
  await engine.addParticleUpdater("outModes", container => new OutOfCanvasUpdater(container), refresh);
6428
6677
  }
6429
- ;// CONCATENATED MODULE: ../../updaters/size/dist/browser/Utils.js
6430
-
6431
- function Utils_checkDestroy(particle, value, minValue, maxValue) {
6432
- switch (particle.options.size.animation.destroy) {
6433
- case "max":
6434
- if (value >= maxValue) {
6435
- particle.destroy();
6436
- }
6437
- break;
6438
- case "min":
6439
- if (value <= minValue) {
6440
- particle.destroy();
6441
- }
6442
- break;
6443
- }
6444
- }
6445
- function updateSize(particle, delta) {
6446
- const data = particle.size;
6447
- if (particle.destroyed || !data || !data.enable || (data.maxLoops ?? 0) > 0 && (data.loops ?? 0) > (data.maxLoops ?? 0)) {
6448
- return;
6449
- }
6450
- const sizeVelocity = (data.velocity ?? 0) * delta.factor,
6451
- minValue = data.min,
6452
- maxValue = data.max,
6453
- decay = data.decay ?? 1;
6454
- if (!data.time) {
6455
- data.time = 0;
6456
- }
6457
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
6458
- data.time += delta.value;
6459
- }
6460
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
6461
- return;
6462
- }
6463
- switch (data.status) {
6464
- case "increasing":
6465
- if (data.value >= maxValue) {
6466
- data.status = "decreasing";
6467
- if (!data.loops) {
6468
- data.loops = 0;
6469
- }
6470
- data.loops++;
6471
- } else {
6472
- data.value += sizeVelocity;
6473
- }
6474
- break;
6475
- case "decreasing":
6476
- if (data.value <= minValue) {
6477
- data.status = "increasing";
6478
- if (!data.loops) {
6479
- data.loops = 0;
6480
- }
6481
- data.loops++;
6482
- } else {
6483
- data.value -= sizeVelocity;
6484
- }
6485
- }
6486
- if (data.velocity && decay !== 1) {
6487
- data.velocity *= decay;
6488
- }
6489
- Utils_checkDestroy(particle, data.value, minValue, maxValue);
6490
- if (!particle.destroyed) {
6491
- data.value = clamp(data.value, minValue, maxValue);
6492
- }
6493
- }
6494
6678
  ;// CONCATENATED MODULE: ../../updaters/size/dist/browser/SizeUpdater.js
6495
6679
 
6496
-
6680
+ const minLoops = 0;
6497
6681
  class SizeUpdater {
6498
6682
  init(particle) {
6499
6683
  const container = particle.container,
6500
6684
  sizeOptions = particle.options.size,
6501
6685
  sizeAnimation = sizeOptions.animation;
6502
6686
  if (sizeAnimation.enable) {
6503
- particle.size.velocity = (particle.retina.sizeAnimationSpeed ?? container.retina.sizeAnimationSpeed) / 100 * container.retina.reduceFactor;
6687
+ particle.size.velocity = (particle.retina.sizeAnimationSpeed ?? container.retina.sizeAnimationSpeed) / percentDenominator * container.retina.reduceFactor;
6504
6688
  if (!sizeAnimation.sync) {
6505
6689
  particle.size.velocity *= getRandom();
6506
6690
  }
6507
6691
  }
6508
6692
  }
6509
6693
  isEnabled(particle) {
6510
- return !particle.destroyed && !particle.spawning && particle.size.enable && ((particle.size.maxLoops ?? 0) <= 0 || (particle.size.maxLoops ?? 0) > 0 && (particle.size.loops ?? 0) < (particle.size.maxLoops ?? 0));
6694
+ return !particle.destroyed && !particle.spawning && particle.size.enable && ((particle.size.maxLoops ?? minLoops) <= minLoops || (particle.size.maxLoops ?? minLoops) > minLoops && (particle.size.loops ?? minLoops) < (particle.size.maxLoops ?? minLoops));
6511
6695
  }
6512
6696
  reset(particle) {
6513
- particle.size.loops = 0;
6697
+ particle.size.loops = minLoops;
6514
6698
  }
6515
6699
  update(particle, delta) {
6516
6700
  if (!this.isEnabled(particle)) {
6517
6701
  return;
6518
6702
  }
6519
- updateSize(particle, delta);
6703
+ updateAnimation(particle, particle.size, true, particle.options.size.animation.destroy, delta);
6520
6704
  }
6521
6705
  }
6522
6706
  ;// CONCATENATED MODULE: ../../updaters/size/dist/browser/index.js
@@ -6647,6 +6831,12 @@ class Destroy {
6647
6831
  }
6648
6832
  ;// CONCATENATED MODULE: ../../updaters/destroy/dist/browser/Utils.js
6649
6833
 
6834
+ const defaultOffset = 0,
6835
+ minDestroySize = 0.5,
6836
+ defaultSplitCount = 0,
6837
+ increment = 1,
6838
+ unbreakableTime = 500,
6839
+ minSplitCount = 0;
6650
6840
  function addSplitParticle(engine, container, parent, splitParticlesOptions) {
6651
6841
  const destroyOptions = parent.options.destroy;
6652
6842
  if (!destroyOptions) {
@@ -6662,9 +6852,9 @@ function addSplitParticle(engine, container, parent, splitParticlesOptions) {
6662
6852
  options.color.load({
6663
6853
  value: {
6664
6854
  hsl: {
6665
- h: parentColor.h + getRangeValue(splitOptions.colorOffset.h ?? 0),
6666
- s: parentColor.s + getRangeValue(splitOptions.colorOffset.s ?? 0),
6667
- l: parentColor.l + getRangeValue(splitOptions.colorOffset.l ?? 0)
6855
+ h: parentColor.h + getRangeValue(splitOptions.colorOffset.h ?? defaultOffset),
6856
+ s: parentColor.s + getRangeValue(splitOptions.colorOffset.s ?? defaultOffset),
6857
+ l: parentColor.l + getRangeValue(splitOptions.colorOffset.l ?? defaultOffset)
6668
6858
  }
6669
6859
  }
6670
6860
  });
@@ -6689,21 +6879,21 @@ function addSplitParticle(engine, container, parent, splitParticlesOptions) {
6689
6879
  options.size.value.max /= factor;
6690
6880
  }
6691
6881
  options.load(splitParticlesOptions);
6692
- const offset = splitOptions.sizeOffset ? setRangeValue(-parent.size.value, parent.size.value) : 0,
6882
+ const offset = splitOptions.sizeOffset ? setRangeValue(-parent.size.value, parent.size.value) : defaultOffset,
6693
6883
  position = {
6694
6884
  x: parent.position.x + randomInRange(offset),
6695
6885
  y: parent.position.y + randomInRange(offset)
6696
6886
  };
6697
6887
  return container.particles.addParticle(position, options, parent.group, particle => {
6698
- if (particle.size.value < 0.5) {
6888
+ if (particle.size.value < minDestroySize) {
6699
6889
  return false;
6700
6890
  }
6701
6891
  particle.velocity.length = randomInRange(setRangeValue(parent.velocity.length, particle.velocity.length));
6702
- particle.splitCount = (parent.splitCount ?? 0) + 1;
6892
+ particle.splitCount = (parent.splitCount ?? defaultSplitCount) + increment;
6703
6893
  particle.unbreakable = true;
6704
6894
  setTimeout(() => {
6705
6895
  particle.unbreakable = false;
6706
- }, 500);
6896
+ }, unbreakableTime);
6707
6897
  return true;
6708
6898
  });
6709
6899
  }
@@ -6713,7 +6903,7 @@ function split(engine, container, particle) {
6713
6903
  return;
6714
6904
  }
6715
6905
  const splitOptions = destroyOptions.split;
6716
- if (splitOptions.count >= 0 && (particle.splitCount === undefined || particle.splitCount++ > splitOptions.count)) {
6906
+ if (splitOptions.count >= minSplitCount && (particle.splitCount === undefined || particle.splitCount++ > splitOptions.count)) {
6717
6907
  return;
6718
6908
  }
6719
6909
  const rate = getRangeValue(splitOptions.rate.value),
@@ -6728,8 +6918,8 @@ function split(engine, container, particle) {
6728
6918
 
6729
6919
  class DestroyUpdater {
6730
6920
  constructor(engine, container) {
6731
- this.engine = engine;
6732
6921
  this.container = container;
6922
+ this.engine = engine;
6733
6923
  }
6734
6924
  init(particle) {
6735
6925
  const container = this.container,
@@ -6754,16 +6944,16 @@ class DestroyUpdater {
6754
6944
  } = particle,
6755
6945
  canvasSize = container.canvas.size;
6756
6946
  if (bottom) {
6757
- destroyBounds.bottom = getRangeValue(bottom) * canvasSize.height / 100;
6947
+ destroyBounds.bottom = getRangeValue(bottom) * canvasSize.height / percentDenominator;
6758
6948
  }
6759
6949
  if (left) {
6760
- destroyBounds.left = getRangeValue(left) * canvasSize.width / 100;
6950
+ destroyBounds.left = getRangeValue(left) * canvasSize.width / percentDenominator;
6761
6951
  }
6762
6952
  if (right) {
6763
- destroyBounds.right = getRangeValue(right) * canvasSize.width / 100;
6953
+ destroyBounds.right = getRangeValue(right) * canvasSize.width / percentDenominator;
6764
6954
  }
6765
6955
  if (top) {
6766
- destroyBounds.top = getRangeValue(top) * canvasSize.height / 100;
6956
+ destroyBounds.top = getRangeValue(top) * canvasSize.height / percentDenominator;
6767
6957
  }
6768
6958
  }
6769
6959
  isEnabled(particle) {
@@ -6976,6 +7166,12 @@ class Emitter {
6976
7166
 
6977
7167
 
6978
7168
 
7169
+ const EmitterInstance_half = 0.5,
7170
+ defaultLifeDelay = 0,
7171
+ minLifeCount = 0,
7172
+ defaultSpawnDelay = 0,
7173
+ defaultEmitDelay = 0,
7174
+ defaultLifeCount = -1;
6979
7175
  function setParticlesOptionsColor(particlesOptions, color) {
6980
7176
  if (particlesOptions.color) {
6981
7177
  particlesOptions.color.value = color;
@@ -7006,9 +7202,11 @@ class EmitterInstance {
7006
7202
  if (this._paused) {
7007
7203
  return;
7008
7204
  }
7009
- const duration = this.options.life?.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined;
7010
- if (this.container.retina.reduceFactor && (this._lifeCount > 0 || this._immortal) && duration !== undefined && duration > 0) {
7011
- this._duration = duration * 1000;
7205
+ const duration = this.options.life?.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined,
7206
+ minDuration = 0,
7207
+ minLifeCount = 0;
7208
+ if (this.container.retina.reduceFactor && (this._lifeCount > minLifeCount || this._immortal) && duration !== undefined && duration > minDuration) {
7209
+ this._duration = duration * millisecondsToSeconds;
7012
7210
  }
7013
7211
  };
7014
7212
  this._setColorAnimation = (animation, initValue, maxValue) => {
@@ -7018,9 +7216,11 @@ class EmitterInstance {
7018
7216
  }
7019
7217
  const colorOffset = randomInRange(animation.offset),
7020
7218
  delay = getRangeValue(this.options.rate.delay),
7021
- emitFactor = 1000 * delay / container.retina.reduceFactor,
7022
- colorSpeed = getRangeValue(animation.speed ?? 0);
7023
- return (initValue + colorSpeed * container.fpsLimit / emitFactor + colorOffset * 3.6) % maxValue;
7219
+ emitFactor = delay * millisecondsToSeconds / container.retina.reduceFactor,
7220
+ defaultColorSpeed = 0,
7221
+ colorFactor = 3.6,
7222
+ colorSpeed = getRangeValue(animation.speed ?? defaultColorSpeed);
7223
+ return (initValue + colorSpeed * container.fpsLimit / emitFactor + colorOffset * colorFactor) % maxValue;
7024
7224
  };
7025
7225
  this._engine = engine;
7026
7226
  this._currentDuration = 0;
@@ -7033,7 +7233,7 @@ class EmitterInstance {
7033
7233
  this.options = new Emitter();
7034
7234
  this.options.load(options);
7035
7235
  }
7036
- this._spawnDelay = getRangeValue(this.options.life.delay ?? 0) * 1000 / this.container.retina.reduceFactor;
7236
+ this._spawnDelay = getRangeValue(this.options.life.delay ?? defaultLifeDelay) * millisecondsToSeconds / this.container.retina.reduceFactor;
7037
7237
  this.position = this._initialPosition ?? this._calcPosition();
7038
7238
  this.name = this.options.name;
7039
7239
  this.fill = this.options.fill;
@@ -7050,8 +7250,8 @@ class EmitterInstance {
7050
7250
  this._particlesOptions = particlesOptions;
7051
7251
  this._size = this._calcSize();
7052
7252
  this.size = getSize(this._size, this.container.canvas.size);
7053
- this._lifeCount = this.options.life.count ?? -1;
7054
- this._immortal = this._lifeCount <= 0;
7253
+ this._lifeCount = this.options.life.count ?? defaultLifeCount;
7254
+ this._immortal = this._lifeCount <= minLifeCount;
7055
7255
  if (this.options.domId) {
7056
7256
  const element = document.getElementById(this.options.domId);
7057
7257
  if (element) {
@@ -7102,14 +7302,14 @@ class EmitterInstance {
7102
7302
  if (this._paused) {
7103
7303
  return;
7104
7304
  }
7105
- if (!(this.container.retina.reduceFactor && (this._lifeCount > 0 || this._immortal || !this.options.life.count) && (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? 0)))) {
7305
+ if (!(this.container.retina.reduceFactor && (this._lifeCount > minLifeCount || this._immortal || !this.options.life.count) && (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? defaultSpawnDelay)))) {
7106
7306
  return;
7107
7307
  }
7108
7308
  if (this._emitDelay === undefined) {
7109
7309
  const delay = getRangeValue(this.options.rate.delay);
7110
- this._emitDelay = 1000 * delay / this.container.retina.reduceFactor;
7310
+ this._emitDelay = delay * millisecondsToSeconds / this.container.retina.reduceFactor;
7111
7311
  }
7112
- if (this._lifeCount > 0 || this._immortal) {
7312
+ if (this._lifeCount > minLifeCount || this._immortal) {
7113
7313
  this._prepareToDie();
7114
7314
  }
7115
7315
  }
@@ -7126,8 +7326,8 @@ class EmitterInstance {
7126
7326
  }
7127
7327
  if (this._firstSpawn) {
7128
7328
  this._firstSpawn = false;
7129
- this._currentSpawnDelay = this._spawnDelay ?? 0;
7130
- this._currentEmitDelay = this._emitDelay ?? 0;
7329
+ this._currentSpawnDelay = this._spawnDelay ?? defaultSpawnDelay;
7330
+ this._currentEmitDelay = this._emitDelay ?? defaultEmitDelay;
7131
7331
  }
7132
7332
  if (!this._startParticlesAdded) {
7133
7333
  this._startParticlesAdded = true;
@@ -7143,10 +7343,10 @@ class EmitterInstance {
7143
7343
  if (!this._immortal) {
7144
7344
  this._lifeCount--;
7145
7345
  }
7146
- if (this._lifeCount > 0 || this._immortal) {
7346
+ if (this._lifeCount > minLifeCount || this._immortal) {
7147
7347
  this.position = this._calcPosition();
7148
7348
  this._shape?.resize(this.position, this.size);
7149
- this._spawnDelay = getRangeValue(this.options.life.delay ?? 0) * 1000 / this.container.retina.reduceFactor;
7349
+ this._spawnDelay = getRangeValue(this.options.life.delay ?? defaultLifeDelay) * millisecondsToSeconds / this.container.retina.reduceFactor;
7150
7350
  } else {
7151
7351
  this._destroy();
7152
7352
  }
@@ -7168,7 +7368,7 @@ class EmitterInstance {
7168
7368
  if (this._emitDelay !== undefined) {
7169
7369
  this._currentEmitDelay += delta.value;
7170
7370
  if (this._currentEmitDelay >= this._emitDelay) {
7171
- this._emit();
7371
+ await this._emit();
7172
7372
  this._currentEmitDelay -= this._emitDelay;
7173
7373
  }
7174
7374
  }
@@ -7178,10 +7378,11 @@ class EmitterInstance {
7178
7378
  const container = this.container,
7179
7379
  element = document.getElementById(this.options.domId);
7180
7380
  if (element) {
7181
- const elRect = element.getBoundingClientRect();
7381
+ const elRect = element.getBoundingClientRect(),
7382
+ pxRatio = container.retina.pixelRatio;
7182
7383
  return {
7183
- x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio,
7184
- y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio
7384
+ x: (elRect.x + elRect.width * EmitterInstance_half) * pxRatio,
7385
+ y: (elRect.y + elRect.height * EmitterInstance_half) * pxRatio
7185
7386
  };
7186
7387
  }
7187
7388
  }
@@ -7227,9 +7428,14 @@ class EmitterInstance {
7227
7428
  if (this.spawnColor) {
7228
7429
  const hslAnimation = this.options.spawnColor?.animation;
7229
7430
  if (hslAnimation) {
7230
- this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360);
7231
- this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100);
7232
- this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100);
7431
+ const maxValues = {
7432
+ h: 360,
7433
+ s: 100,
7434
+ l: 100
7435
+ };
7436
+ this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, maxValues.h);
7437
+ this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, maxValues.s);
7438
+ this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, maxValues.l);
7233
7439
  }
7234
7440
  setParticlesOptionsColor(particlesOptions, this.spawnColor);
7235
7441
  }
@@ -7279,7 +7485,8 @@ class Emitters {
7279
7485
  },
7280
7486
  value: []
7281
7487
  };
7282
- container.getEmitter = idxOrName => idxOrName === undefined || isNumber(idxOrName) ? this.array[idxOrName || 0] : this.array.find(t => t.name === idxOrName);
7488
+ const defaultIndex = 0;
7489
+ container.getEmitter = idxOrName => idxOrName === undefined || isNumber(idxOrName) ? this.array[idxOrName ?? defaultIndex] : this.array.find(t => t.name === idxOrName);
7283
7490
  container.addEmitter = async (options, position) => this.addEmitter(options, position);
7284
7491
  container.removeEmitter = idxOrName => {
7285
7492
  const emitter = container.getEmitter(idxOrName);
@@ -7316,7 +7523,8 @@ class Emitters {
7316
7523
  }
7317
7524
  let emittersModeOptions;
7318
7525
  if (modeEmitters && isArray(modeEmitters.value)) {
7319
- if (modeEmitters.value.length > 0 && modeEmitters.random.enable) {
7526
+ const minLength = 0;
7527
+ if (modeEmitters.value.length > minLength && modeEmitters.random.enable) {
7320
7528
  emittersModeOptions = [];
7321
7529
  const usedIndexes = [];
7322
7530
  for (let i = 0; i < modeEmitters.random.count; i++) {
@@ -7336,8 +7544,8 @@ class Emitters {
7336
7544
  }
7337
7545
  const emittersOptions = emittersModeOptions ?? emitterOptions,
7338
7546
  ePosition = this.container.interactivity.mouse.clickPosition;
7339
- executeOnSingleOrMultiple(emittersOptions, emitter => {
7340
- this.addEmitter(emitter, ePosition);
7547
+ void executeOnSingleOrMultiple(emittersOptions, async emitter => {
7548
+ await this.addEmitter(emitter, ePosition);
7341
7549
  });
7342
7550
  }
7343
7551
  async init() {
@@ -7365,9 +7573,11 @@ class Emitters {
7365
7573
  }
7366
7574
  }
7367
7575
  removeEmitter(emitter) {
7368
- const index = this.array.indexOf(emitter);
7369
- if (index >= 0) {
7370
- this.array.splice(index, 1);
7576
+ const index = this.array.indexOf(emitter),
7577
+ minIndex = 0,
7578
+ deleteCount = 1;
7579
+ if (index >= minIndex) {
7580
+ this.array.splice(index, deleteCount);
7371
7581
  }
7372
7582
  }
7373
7583
  resize() {
@@ -7456,10 +7666,11 @@ class EmittersPlugin {
7456
7666
  } else {
7457
7667
  const emitterMode = interactivityEmitters;
7458
7668
  if (emitterMode.value !== undefined) {
7669
+ const defaultCount = 1;
7459
7670
  if (isArray(emitterMode.value)) {
7460
7671
  options.interactivity.modes.emitters = {
7461
7672
  random: {
7462
- count: emitterMode.random.count ?? 1,
7673
+ count: emitterMode.random.count ?? defaultCount,
7463
7674
  enable: emitterMode.random.enable ?? false
7464
7675
  },
7465
7676
  value: emitterMode.value.map(s => {
@@ -7473,7 +7684,7 @@ class EmittersPlugin {
7473
7684
  tmp.load(emitterMode.value);
7474
7685
  options.interactivity.modes.emitters = {
7475
7686
  random: {
7476
- count: emitterMode.random.count ?? 1,
7687
+ count: emitterMode.random.count ?? defaultCount,
7477
7688
  enable: emitterMode.random.enable ?? false
7478
7689
  },
7479
7690
  value: tmp
@@ -7522,8 +7733,11 @@ async function loadEmittersPlugin(engine, refresh = true) {
7522
7733
  ;// CONCATENATED MODULE: ../../plugins/emittersShapes/square/dist/browser/EmittersSquareShape.js
7523
7734
 
7524
7735
 
7736
+ const EmittersSquareShape_half = 0.5,
7737
+ EmittersSquareShape_sides = 4,
7738
+ EmittersSquareShape_double = 2;
7525
7739
  function randomSquareCoordinate(position, offset) {
7526
- return position + offset * (getRandom() - 0.5);
7740
+ return position + offset * (getRandom() - halfRandom);
7527
7741
  }
7528
7742
  class EmittersSquareShape extends EmitterShapeBase {
7529
7743
  constructor(position, size, fill, options) {
@@ -7531,53 +7745,55 @@ class EmittersSquareShape extends EmitterShapeBase {
7531
7745
  }
7532
7746
  async init() {}
7533
7747
  async randomPosition() {
7534
- const fill = this.fill,
7535
- position = this.position,
7536
- size = this.size;
7537
- if (fill) {
7538
- return {
7539
- position: {
7540
- x: randomSquareCoordinate(position.x, size.width),
7541
- y: randomSquareCoordinate(position.y, size.height)
7748
+ return await new Promise(success => {
7749
+ const fill = this.fill,
7750
+ position = this.position,
7751
+ size = this.size;
7752
+ if (fill) {
7753
+ return success({
7754
+ position: {
7755
+ x: randomSquareCoordinate(position.x, size.width),
7756
+ y: randomSquareCoordinate(position.y, size.height)
7757
+ }
7758
+ });
7759
+ } else {
7760
+ const halfW = size.width * EmittersSquareShape_half,
7761
+ halfH = size.height * EmittersSquareShape_half,
7762
+ side = Math.floor(getRandom() * EmittersSquareShape_sides),
7763
+ v = (getRandom() - halfRandom) * EmittersSquareShape_double;
7764
+ switch (side) {
7765
+ case 0:
7766
+ return success({
7767
+ position: {
7768
+ x: position.x + v * halfW,
7769
+ y: position.y - halfH
7770
+ }
7771
+ });
7772
+ case 1:
7773
+ return success({
7774
+ position: {
7775
+ x: position.x - halfW,
7776
+ y: position.y + v * halfH
7777
+ }
7778
+ });
7779
+ case 2:
7780
+ return success({
7781
+ position: {
7782
+ x: position.x + v * halfW,
7783
+ y: position.y + halfH
7784
+ }
7785
+ });
7786
+ case 3:
7787
+ default:
7788
+ return success({
7789
+ position: {
7790
+ x: position.x + halfW,
7791
+ y: position.y + v * halfH
7792
+ }
7793
+ });
7542
7794
  }
7543
- };
7544
- } else {
7545
- const halfW = size.width / 2,
7546
- halfH = size.height / 2,
7547
- side = Math.floor(getRandom() * 4),
7548
- v = (getRandom() - 0.5) * 2;
7549
- switch (side) {
7550
- case 0:
7551
- return {
7552
- position: {
7553
- x: position.x + v * halfW,
7554
- y: position.y - halfH
7555
- }
7556
- };
7557
- case 1:
7558
- return {
7559
- position: {
7560
- x: position.x - halfW,
7561
- y: position.y + v * halfH
7562
- }
7563
- };
7564
- case 2:
7565
- return {
7566
- position: {
7567
- x: position.x + v * halfW,
7568
- y: position.y + halfH
7569
- }
7570
- };
7571
- case 3:
7572
- default:
7573
- return {
7574
- position: {
7575
- x: position.x + halfW,
7576
- y: position.y + v * halfH
7577
- }
7578
- };
7579
7795
  }
7580
- }
7796
+ });
7581
7797
  }
7582
7798
  }
7583
7799
  ;// CONCATENATED MODULE: ../../plugins/emittersShapes/square/dist/browser/EmittersSquareShapeGenerator.js
@@ -7591,7 +7807,7 @@ class EmittersSquareShapeGenerator {
7591
7807
 
7592
7808
  async function loadEmittersShapeSquare(engine, refresh = true) {
7593
7809
  const emittersEngine = engine;
7594
- emittersEngine.addEmitterShapeGenerator && emittersEngine.addEmitterShapeGenerator("square", new EmittersSquareShapeGenerator());
7810
+ emittersEngine.addEmitterShapeGenerator?.("square", new EmittersSquareShapeGenerator());
7595
7811
  await emittersEngine.refresh(refresh);
7596
7812
  }
7597
7813
  ;// CONCATENATED MODULE: ../../updaters/life/dist/browser/Options/Classes/LifeDelay.js
@@ -7651,6 +7867,11 @@ class Life {
7651
7867
  ;// CONCATENATED MODULE: ../../updaters/life/dist/browser/LifeUpdater.js
7652
7868
 
7653
7869
 
7870
+ const noTime = 0,
7871
+ LifeUpdater_identity = 1,
7872
+ infiniteValue = -1,
7873
+ noLife = 0,
7874
+ minCanvasSize = 0;
7654
7875
  class LifeUpdater {
7655
7876
  constructor(container) {
7656
7877
  this.container = container;
@@ -7663,20 +7884,20 @@ class LifeUpdater {
7663
7884
  return;
7664
7885
  }
7665
7886
  particle.life = {
7666
- delay: container.retina.reduceFactor ? getRangeValue(lifeOptions.delay.value) * (lifeOptions.delay.sync ? 1 : getRandom()) / container.retina.reduceFactor * 1000 : 0,
7667
- delayTime: 0,
7668
- duration: container.retina.reduceFactor ? getRangeValue(lifeOptions.duration.value) * (lifeOptions.duration.sync ? 1 : getRandom()) / container.retina.reduceFactor * 1000 : 0,
7669
- time: 0,
7887
+ delay: container.retina.reduceFactor ? getRangeValue(lifeOptions.delay.value) * (lifeOptions.delay.sync ? LifeUpdater_identity : getRandom()) / container.retina.reduceFactor * millisecondsToSeconds : noTime,
7888
+ delayTime: noTime,
7889
+ duration: container.retina.reduceFactor ? getRangeValue(lifeOptions.duration.value) * (lifeOptions.duration.sync ? LifeUpdater_identity : getRandom()) / container.retina.reduceFactor * millisecondsToSeconds : noTime,
7890
+ time: noTime,
7670
7891
  count: lifeOptions.count
7671
7892
  };
7672
- if (particle.life.duration <= 0) {
7673
- particle.life.duration = -1;
7893
+ if (particle.life.duration <= noTime) {
7894
+ particle.life.duration = infiniteValue;
7674
7895
  }
7675
- if (particle.life.count <= 0) {
7676
- particle.life.count = -1;
7896
+ if (particle.life.count <= noTime) {
7897
+ particle.life.count = infiniteValue;
7677
7898
  }
7678
7899
  if (particle.life) {
7679
- particle.spawning = particle.life.delay > 0;
7900
+ particle.spawning = particle.life.delay > noTime;
7680
7901
  }
7681
7902
  }
7682
7903
  isEnabled(particle) {
@@ -7701,47 +7922,47 @@ class LifeUpdater {
7701
7922
  if (life.delayTime >= particle.life.delay) {
7702
7923
  justSpawned = true;
7703
7924
  particle.spawning = false;
7704
- life.delayTime = 0;
7705
- life.time = 0;
7925
+ life.delayTime = noTime;
7926
+ life.time = noTime;
7706
7927
  } else {
7707
7928
  return;
7708
7929
  }
7709
7930
  }
7710
- if (life.duration === -1) {
7931
+ if (life.duration === infiniteValue) {
7711
7932
  return;
7712
7933
  }
7713
7934
  if (particle.spawning) {
7714
7935
  return;
7715
7936
  }
7716
7937
  if (justSpawned) {
7717
- life.time = 0;
7938
+ life.time = noTime;
7718
7939
  } else {
7719
7940
  life.time += delta.value;
7720
7941
  }
7721
7942
  if (life.time < life.duration) {
7722
7943
  return;
7723
7944
  }
7724
- life.time = 0;
7725
- if (particle.life.count > 0) {
7945
+ life.time = noTime;
7946
+ if (particle.life.count > noLife) {
7726
7947
  particle.life.count--;
7727
7948
  }
7728
- if (particle.life.count === 0) {
7949
+ if (particle.life.count === noLife) {
7729
7950
  particle.destroy();
7730
7951
  return;
7731
7952
  }
7732
7953
  const canvasSize = this.container.canvas.size,
7733
- widthRange = setRangeValue(0, canvasSize.width),
7734
- heightRange = setRangeValue(0, canvasSize.width);
7954
+ widthRange = setRangeValue(minCanvasSize, canvasSize.width),
7955
+ heightRange = setRangeValue(minCanvasSize, canvasSize.width);
7735
7956
  particle.position.x = randomInRange(widthRange);
7736
7957
  particle.position.y = randomInRange(heightRange);
7737
7958
  particle.spawning = true;
7738
- life.delayTime = 0;
7739
- life.time = 0;
7959
+ life.delayTime = noTime;
7960
+ life.time = noTime;
7740
7961
  particle.reset();
7741
7962
  const lifeOptions = particle.options.life;
7742
7963
  if (lifeOptions) {
7743
- life.delay = getRangeValue(lifeOptions.delay.value) * 1000;
7744
- life.duration = getRangeValue(lifeOptions.duration.value) * 1000;
7964
+ life.delay = getRangeValue(lifeOptions.delay.value) * millisecondsToSeconds;
7965
+ life.duration = getRangeValue(lifeOptions.duration.value) * millisecondsToSeconds;
7745
7966
  }
7746
7967
  }
7747
7968
  }
@@ -7750,28 +7971,6 @@ class LifeUpdater {
7750
7971
  async function loadLifeUpdater(engine, refresh = true) {
7751
7972
  await engine.addParticleUpdater("life", container => new LifeUpdater(container), refresh);
7752
7973
  }
7753
- ;// CONCATENATED MODULE: ../../shapes/line/dist/browser/LineDrawer.js
7754
- class LineDrawer {
7755
- draw(data) {
7756
- const {
7757
- context,
7758
- particle,
7759
- radius
7760
- } = data,
7761
- shapeData = particle.shapeData;
7762
- context.moveTo(-radius / 2, 0);
7763
- context.lineTo(radius / 2, 0);
7764
- context.lineCap = shapeData?.cap ?? "butt";
7765
- }
7766
- getSidesCount() {
7767
- return 1;
7768
- }
7769
- }
7770
- ;// CONCATENATED MODULE: ../../shapes/line/dist/browser/index.js
7771
-
7772
- async function loadLineShape(engine, refresh = true) {
7773
- await engine.addShape("line", new LineDrawer(), refresh);
7774
- }
7775
7974
  ;// CONCATENATED MODULE: ../../updaters/rotate/dist/browser/Options/Classes/RotateAnimation.js
7776
7975
 
7777
7976
  class RotateAnimation {
@@ -7827,38 +8026,10 @@ class Rotate extends ValueWithRandom {
7827
8026
  ;// CONCATENATED MODULE: ../../updaters/rotate/dist/browser/RotateUpdater.js
7828
8027
 
7829
8028
 
7830
- function updateRotate(particle, delta) {
7831
- const rotate = particle.rotate,
7832
- rotateOptions = particle.options.rotate;
7833
- if (!rotate || !rotateOptions) {
7834
- return;
7835
- }
7836
- const rotateAnimation = rotateOptions.animation,
7837
- speed = (rotate.velocity ?? 0) * delta.factor,
7838
- max = 2 * Math.PI,
7839
- decay = rotate.decay ?? 1;
7840
- if (!rotateAnimation.enable) {
7841
- return;
7842
- }
7843
- switch (rotate.status) {
7844
- case "increasing":
7845
- rotate.value += speed;
7846
- if (rotate.value > max) {
7847
- rotate.value -= max;
7848
- }
7849
- break;
7850
- case "decreasing":
7851
- default:
7852
- rotate.value -= speed;
7853
- if (rotate.value < 0) {
7854
- rotate.value += max;
7855
- }
7856
- break;
7857
- }
7858
- if (rotate.velocity && decay !== 1) {
7859
- rotate.velocity *= decay;
7860
- }
7861
- }
8029
+ const RotateUpdater_double = 2,
8030
+ RotateUpdater_doublePI = Math.PI * RotateUpdater_double,
8031
+ RotateUpdater_identity = 1,
8032
+ doublePIDeg = 360;
7862
8033
  class RotateUpdater {
7863
8034
  constructor(container) {
7864
8035
  this.container = container;
@@ -7870,13 +8041,16 @@ class RotateUpdater {
7870
8041
  }
7871
8042
  particle.rotate = {
7872
8043
  enable: rotateOptions.animation.enable,
7873
- value: getRangeValue(rotateOptions.value) * Math.PI / 180
8044
+ value: degToRad(getRangeValue(rotateOptions.value)),
8045
+ min: 0,
8046
+ max: RotateUpdater_doublePI
7874
8047
  };
7875
8048
  particle.pathRotation = rotateOptions.path;
7876
8049
  let rotateDirection = rotateOptions.direction;
7877
8050
  if (rotateDirection === "random") {
7878
- const index = Math.floor(getRandom() * 2);
7879
- rotateDirection = index > 0 ? "counter-clockwise" : "clockwise";
8051
+ const index = Math.floor(getRandom() * RotateUpdater_double),
8052
+ minIndex = 0;
8053
+ rotateDirection = index > minIndex ? "counter-clockwise" : "clockwise";
7880
8054
  }
7881
8055
  switch (rotateDirection) {
7882
8056
  case "counter-clockwise":
@@ -7889,8 +8063,8 @@ class RotateUpdater {
7889
8063
  }
7890
8064
  const rotateAnimation = rotateOptions.animation;
7891
8065
  if (rotateAnimation.enable) {
7892
- particle.rotate.decay = 1 - getRangeValue(rotateAnimation.decay);
7893
- particle.rotate.velocity = getRangeValue(rotateAnimation.speed) / 360 * this.container.retina.reduceFactor;
8066
+ particle.rotate.decay = RotateUpdater_identity - getRangeValue(rotateAnimation.decay);
8067
+ particle.rotate.velocity = getRangeValue(rotateAnimation.speed) / doublePIDeg * this.container.retina.reduceFactor;
7894
8068
  if (!rotateAnimation.sync) {
7895
8069
  particle.rotate.velocity *= getRandom();
7896
8070
  }
@@ -7916,8 +8090,11 @@ class RotateUpdater {
7916
8090
  if (!this.isEnabled(particle)) {
7917
8091
  return;
7918
8092
  }
7919
- updateRotate(particle, delta);
7920
- particle.rotation = particle.rotate?.value ?? 0;
8093
+ if (!particle.rotate) {
8094
+ return;
8095
+ }
8096
+ updateAnimation(particle, particle.rotate, false, "none", delta);
8097
+ particle.rotation = particle.rotate.value;
7921
8098
  }
7922
8099
  }
7923
8100
  ;// CONCATENATED MODULE: ../../updaters/rotate/dist/browser/index.js
@@ -8040,10 +8217,11 @@ class SoundsEvent {
8040
8217
  return tmp;
8041
8218
  });
8042
8219
  }
8043
- if (data.filter !== undefined) {
8220
+ if (data.filter) {
8044
8221
  if (isString(data.filter)) {
8045
- if (isFunction(window[data.filter])) {
8046
- this.filter = window[data.filter];
8222
+ const filterFunc = window[data.filter];
8223
+ if (isFunction(filterFunc)) {
8224
+ this.filter = filterFunc;
8047
8225
  }
8048
8226
  } else {
8049
8227
  this.filter = data.filter;
@@ -8056,6 +8234,7 @@ class SoundsIcon {
8056
8234
  constructor() {
8057
8235
  this.width = 24;
8058
8236
  this.height = 24;
8237
+ this.style = "";
8059
8238
  }
8060
8239
  load(data) {
8061
8240
  if (!data) {
@@ -8083,6 +8262,7 @@ class SoundsIcons {
8083
8262
  this.unmute = new SoundsIcon();
8084
8263
  this.volumeDown = new SoundsIcon();
8085
8264
  this.volumeUp = new SoundsIcon();
8265
+ this.enable = false;
8086
8266
  this.mute.svg = `<?xml version="1.0"?>
8087
8267
  <svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"
8088
8268
  xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
@@ -8124,6 +8304,9 @@ class SoundsIcons {
8124
8304
  if (!data) {
8125
8305
  return;
8126
8306
  }
8307
+ if (data.enable !== undefined) {
8308
+ this.enable = data.enable;
8309
+ }
8127
8310
  this.mute.load(data.mute);
8128
8311
  this.unmute.load(data.unmute);
8129
8312
  this.volumeDown.load(data.volumeDown);
@@ -8167,6 +8350,7 @@ class SoundsVolume {
8167
8350
 
8168
8351
  class Sounds {
8169
8352
  constructor() {
8353
+ this.autoPlay = true;
8170
8354
  this.enable = false;
8171
8355
  this.events = [];
8172
8356
  this.icons = new SoundsIcons();
@@ -8176,6 +8360,9 @@ class Sounds {
8176
8360
  if (!data) {
8177
8361
  return;
8178
8362
  }
8363
+ if (data.autoPlay !== undefined) {
8364
+ this.autoPlay = data.autoPlay;
8365
+ }
8179
8366
  if (data.enable !== undefined) {
8180
8367
  this.enable = data.enable;
8181
8368
  }
@@ -8209,20 +8396,33 @@ notes.set("B", [30.87, 61.74, 123.47, 246.94, 493.88, 987.77, 1975.53, 3951.07,
8209
8396
  notes.set("pause", [0]);
8210
8397
  function getNoteFrequency(note) {
8211
8398
  const regex = /(([A-G]b?)(\d))|pause/i,
8212
- result = regex.exec(note);
8213
- if (!result || !result.length) {
8399
+ result = regex.exec(note),
8400
+ groupKey = 2,
8401
+ defaultMatchKey = 0,
8402
+ innerGroupKey = 3;
8403
+ if (!result?.length) {
8214
8404
  return;
8215
8405
  }
8216
- const noteKey = result[2] || result[0],
8406
+ const noteKey = result[groupKey] || result[defaultMatchKey],
8217
8407
  noteItem = notes.get(noteKey);
8218
8408
  if (!noteItem) {
8219
8409
  return;
8220
8410
  }
8221
- return noteItem[parseInt(result[3] || "0")];
8411
+ return noteItem[parseInt(result[innerGroupKey] || "0")];
8222
8412
  }
8413
+ let muted = true;
8414
+ const isWindowMuted = () => {
8415
+ return muted;
8416
+ };
8417
+ const unmuteWindow = () => {
8418
+ muted = false;
8419
+ };
8223
8420
  ;// CONCATENATED MODULE: ../../plugins/sounds/dist/browser/SoundsInstance.js
8224
8421
 
8225
8422
 
8423
+ const zIndexOffset = 1,
8424
+ rightOffset = 1,
8425
+ minVolume = 0;
8226
8426
  function initImage(data) {
8227
8427
  const img = document.createElement("img"),
8228
8428
  {
@@ -8238,13 +8438,17 @@ function initImage(data) {
8238
8438
  {
8239
8439
  width,
8240
8440
  path,
8441
+ style,
8241
8442
  svg
8242
- } = iconOptions;
8243
- setIconStyle(img, pos.top + margin, pos.right - (margin * (rightOffsets.length + 1) + width + rightOffsets.reduce((a, b) => a + b, 0)), display, options.fullScreen.zIndex + 1, width, margin);
8443
+ } = iconOptions,
8444
+ defaultAccumulator = 0;
8445
+ setIconStyle(img, pos.top + margin, pos.right - (margin * (rightOffsets.length + rightOffset) + width + rightOffsets.reduce((a, b) => a + b, defaultAccumulator)), display, options.fullScreen.zIndex + zIndexOffset, width, margin, style);
8244
8446
  img.src = path ?? (svg ? `data:image/svg+xml;base64,${btoa(svg)}` : "");
8245
- const parent = container.canvas.element?.parentNode || document.body;
8447
+ const parent = container.canvas.element?.parentNode ?? document.body;
8246
8448
  parent.append(img);
8247
- img.addEventListener("click", clickCb);
8449
+ img.addEventListener("click", () => {
8450
+ void clickCb();
8451
+ });
8248
8452
  return img;
8249
8453
  }
8250
8454
  function removeImage(image) {
@@ -8253,14 +8457,15 @@ function removeImage(image) {
8253
8457
  }
8254
8458
  image.remove();
8255
8459
  }
8256
- function setIconStyle(icon, top, left, display, zIndex, width, margin) {
8460
+ function setIconStyle(icon, top, left, display, zIndex, width, margin, style) {
8257
8461
  icon.style.userSelect = "none";
8258
8462
  icon.style.webkitUserSelect = "none";
8259
8463
  icon.style.position = "absolute";
8260
8464
  icon.style.top = `${top + margin}px`;
8261
8465
  icon.style.left = `${left - margin - width}px`;
8262
8466
  icon.style.display = display;
8263
- icon.style.zIndex = `${zIndex + 1}`;
8467
+ icon.style.zIndex = `${zIndex + zIndexOffset}`;
8468
+ icon.style.cssText += style;
8264
8469
  }
8265
8470
  class SoundsInstance {
8266
8471
  constructor(container, engine) {
@@ -8282,12 +8487,12 @@ class SoundsInstance {
8282
8487
  }
8283
8488
  for (const event of soundsOptions.events) {
8284
8489
  const cb = args => {
8285
- (async () => {
8490
+ void (async () => {
8286
8491
  const filterNotValid = event.filter && !event.filter(args);
8287
8492
  if (this._container !== args.container) {
8288
8493
  return;
8289
8494
  }
8290
- if (!this._container || this._container.muted || this._container.destroyed) {
8495
+ if (!this._container || !!this._container.muted || this._container.destroyed) {
8291
8496
  executeOnSingleOrMultiple(event.event, item => {
8292
8497
  this._engine.removeEventListener(item, cb);
8293
8498
  });
@@ -8296,18 +8501,19 @@ class SoundsInstance {
8296
8501
  if (filterNotValid) {
8297
8502
  return;
8298
8503
  }
8504
+ const defaultNoteIndex = 0;
8299
8505
  if (event.audio) {
8300
8506
  this._playBuffer(itemFromSingleOrMultiple(event.audio));
8301
8507
  } else if (event.melodies) {
8302
8508
  const melody = itemFromArray(event.melodies);
8303
8509
  if (melody.melodies.length) {
8304
- await Promise.allSettled(melody.melodies.map(m => this._playNote(m.notes, 0, melody.loop)));
8510
+ await Promise.allSettled(melody.melodies.map(m => this._playNote(m.notes, defaultNoteIndex, melody.loop)));
8305
8511
  } else {
8306
- await this._playNote(melody.notes, 0, melody.loop);
8512
+ await this._playNote(melody.notes, defaultNoteIndex, melody.loop);
8307
8513
  }
8308
8514
  } else if (event.notes) {
8309
8515
  const note = itemFromArray(event.notes);
8310
- await this._playNote([note], 0, false);
8516
+ await this._playNote([note], defaultNoteIndex, false);
8311
8517
  }
8312
8518
  })();
8313
8519
  };
@@ -8316,18 +8522,16 @@ class SoundsInstance {
8316
8522
  });
8317
8523
  }
8318
8524
  };
8319
- this._mute = () => {
8320
- const container = this._container;
8321
- if (!container.audioContext) {
8322
- return;
8323
- }
8525
+ this._mute = async () => {
8526
+ const container = this._container,
8527
+ audioContext = this._getAudioContext();
8324
8528
  for (const source of this._audioSources) {
8325
8529
  this._removeAudioSource(source);
8326
8530
  }
8327
8531
  if (this._gain) {
8328
8532
  this._gain.disconnect();
8329
8533
  }
8330
- container.audioContext.close();
8534
+ await audioContext.close();
8331
8535
  container.audioContext = undefined;
8332
8536
  this._engine.dispatchEvent("soundsMuted", {
8333
8537
  container: this._container
@@ -8349,10 +8553,11 @@ class SoundsInstance {
8349
8553
  source.start();
8350
8554
  };
8351
8555
  this._playFrequency = async (frequency, duration) => {
8352
- if (!this._container.audioContext || !this._gain) {
8556
+ if (!this._gain || this._container.muted) {
8353
8557
  return;
8354
8558
  }
8355
- const oscillator = this._addOscillator(this._container.audioContext);
8559
+ const audioContext = this._getAudioContext(),
8560
+ oscillator = this._addOscillator(audioContext);
8356
8561
  oscillator.connect(this._gain);
8357
8562
  oscillator.type = "sine";
8358
8563
  oscillator.frequency.value = frequency;
@@ -8365,14 +8570,14 @@ class SoundsInstance {
8365
8570
  });
8366
8571
  };
8367
8572
  this._playMuteSound = () => {
8368
- const container = this._container;
8369
- if (!container.audioContext) {
8573
+ if (this._container.muted) {
8370
8574
  return;
8371
8575
  }
8372
- const gain = container.audioContext.createGain();
8373
- gain.connect(container.audioContext.destination);
8576
+ const audioContext = this._getAudioContext(),
8577
+ gain = audioContext.createGain();
8578
+ gain.connect(audioContext.destination);
8374
8579
  gain.gain.value = 0;
8375
- const oscillator = container.audioContext.createOscillator();
8580
+ const oscillator = audioContext.createOscillator();
8376
8581
  oscillator.connect(gain);
8377
8582
  oscillator.type = "sine";
8378
8583
  oscillator.frequency.value = 1;
@@ -8396,7 +8601,8 @@ class SoundsInstance {
8396
8601
  return this._playNoteValue(notes, noteIdx, idx);
8397
8602
  });
8398
8603
  await (isArray(promises) ? Promise.allSettled(promises) : promises);
8399
- let nextNoteIdx = noteIdx + 1;
8604
+ const indexOffset = 1;
8605
+ let nextNoteIdx = noteIdx + indexOffset;
8400
8606
  if (loop && nextNoteIdx >= notes.length) {
8401
8607
  nextNoteIdx = nextNoteIdx % notes.length;
8402
8608
  }
@@ -8424,7 +8630,8 @@ class SoundsInstance {
8424
8630
  this._removeAudioSource = source => {
8425
8631
  source.stop();
8426
8632
  source.disconnect();
8427
- this._audioSources.splice(this._audioSources.indexOf(source), 1);
8633
+ const deleteCount = 1;
8634
+ this._audioSources.splice(this._audioSources.indexOf(source), deleteCount);
8428
8635
  };
8429
8636
  this._unmute = () => {
8430
8637
  const container = this._container,
@@ -8433,18 +8640,13 @@ class SoundsInstance {
8433
8640
  if (!soundsOptions) {
8434
8641
  return;
8435
8642
  }
8436
- if (!container.audioContext) {
8437
- container.audioContext = new AudioContext();
8438
- }
8439
- const {
8440
- audioContext
8441
- } = container;
8643
+ const audioContext = this._getAudioContext();
8442
8644
  if (!this._audioSources) {
8443
8645
  this._audioSources = [];
8444
8646
  }
8445
8647
  const gain = audioContext.createGain();
8446
8648
  gain.connect(audioContext.destination);
8447
- gain.gain.value = soundsOptions.volume.value / 100;
8649
+ gain.gain.value = soundsOptions.volume.value / percentDenominator;
8448
8650
  this._gain = gain;
8449
8651
  this._initEvents();
8450
8652
  this._engine.dispatchEvent("soundsUnmuted", {
@@ -8453,7 +8655,11 @@ class SoundsInstance {
8453
8655
  };
8454
8656
  this._updateMuteIcons = () => {
8455
8657
  const container = this._container,
8456
- muteImg = this._muteImg,
8658
+ soundsOptions = container.actualOptions.sounds;
8659
+ if (!soundsOptions?.enable || !soundsOptions.icons.enable) {
8660
+ return;
8661
+ }
8662
+ const muteImg = this._muteImg,
8457
8663
  unmuteImg = this._unmuteImg;
8458
8664
  if (muteImg) {
8459
8665
  muteImg.style.display = container.muted ? "block" : "none";
@@ -8463,12 +8669,13 @@ class SoundsInstance {
8463
8669
  }
8464
8670
  };
8465
8671
  this._updateMuteStatus = async () => {
8466
- const container = this._container;
8672
+ const container = this._container,
8673
+ audioContext = this._getAudioContext();
8467
8674
  if (container.muted) {
8468
- await container.audioContext?.suspend();
8469
- this._mute();
8675
+ await audioContext?.suspend();
8676
+ await this._mute();
8470
8677
  } else {
8471
- await container.audioContext?.resume();
8678
+ await audioContext?.resume();
8472
8679
  this._unmute();
8473
8680
  this._playMuteSound();
8474
8681
  }
@@ -8481,11 +8688,11 @@ class SoundsInstance {
8481
8688
  }
8482
8689
  clamp(this._volume, soundsOptions.volume.min, soundsOptions.volume.max);
8483
8690
  let stateChanged = false;
8484
- if (this._volume <= 0 && !container.muted) {
8691
+ if (this._volume <= minVolume && !container.muted) {
8485
8692
  this._volume = 0;
8486
8693
  container.muted = true;
8487
8694
  stateChanged = true;
8488
- } else if (this._volume > 0 && container.muted) {
8695
+ } else if (this._volume > minVolume && container.muted) {
8489
8696
  container.muted = false;
8490
8697
  stateChanged = true;
8491
8698
  }
@@ -8494,7 +8701,7 @@ class SoundsInstance {
8494
8701
  await this._updateMuteStatus();
8495
8702
  }
8496
8703
  if (this._gain?.gain) {
8497
- this._gain.gain.value = this._volume / 100;
8704
+ this._gain.gain.value = this._volume / percentDenominator;
8498
8705
  }
8499
8706
  };
8500
8707
  this._container = container;
@@ -8510,6 +8717,20 @@ class SoundsInstance {
8510
8717
  if (!soundsOptions?.enable) {
8511
8718
  return;
8512
8719
  }
8720
+ if (soundsOptions.autoPlay && isWindowMuted()) {
8721
+ const firstClickHandler = () => {
8722
+ removeEventListener(mouseDownEvent, firstClickHandler);
8723
+ removeEventListener(touchStartEvent, firstClickHandler);
8724
+ unmuteWindow();
8725
+ void this.unmute();
8726
+ };
8727
+ const listenerOptions = {
8728
+ capture: true,
8729
+ once: true
8730
+ };
8731
+ addEventListener(mouseDownEvent, firstClickHandler, listenerOptions);
8732
+ addEventListener(touchStartEvent, firstClickHandler, listenerOptions);
8733
+ }
8513
8734
  this._volume = soundsOptions.volume.value;
8514
8735
  const events = soundsOptions.events;
8515
8736
  this._audioMap = new Map();
@@ -8517,16 +8738,26 @@ class SoundsInstance {
8517
8738
  if (!event.audio) {
8518
8739
  continue;
8519
8740
  }
8520
- executeOnSingleOrMultiple(event.audio, async audio => {
8741
+ const promises = executeOnSingleOrMultiple(event.audio, async audio => {
8521
8742
  const response = await fetch(audio.source);
8522
8743
  if (!response.ok) {
8523
8744
  return;
8524
8745
  }
8525
- const arrayBuffer = await response.arrayBuffer();
8526
- container.audioContext = new AudioContext();
8527
- const audioBuffer = await container.audioContext.decodeAudioData(arrayBuffer);
8746
+ const arrayBuffer = await response.arrayBuffer(),
8747
+ audioContext = this._getAudioContext(),
8748
+ audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
8528
8749
  this._audioMap.set(audio.source, audioBuffer);
8529
8750
  });
8751
+ if (promises instanceof Promise) {
8752
+ await promises;
8753
+ } else {
8754
+ await Promise.allSettled(promises);
8755
+ }
8756
+ }
8757
+ }
8758
+ async mute() {
8759
+ if (!this._container.muted) {
8760
+ await this.toggleMute();
8530
8761
  }
8531
8762
  }
8532
8763
  async start() {
@@ -8548,17 +8779,17 @@ class SoundsInstance {
8548
8779
  volumeDown,
8549
8780
  volumeUp
8550
8781
  } = soundsOptions.icons,
8551
- margin = 10;
8552
- const toggleMute = async () => {
8553
- container.muted = !container.muted;
8554
- this._updateMuteIcons();
8555
- await this._updateMuteStatus();
8556
- };
8782
+ margin = 10,
8783
+ toggleMute = async () => {
8784
+ await this.toggleMute();
8785
+ },
8786
+ enableIcons = soundsOptions.icons.enable,
8787
+ display = enableIcons ? "block" : "none";
8557
8788
  this._muteImg = initImage({
8558
8789
  container,
8559
8790
  options,
8560
8791
  pos,
8561
- display: "block",
8792
+ display,
8562
8793
  iconOptions: mute,
8563
8794
  margin,
8564
8795
  rightOffsets: [volumeDown.width, volumeUp.width],
@@ -8578,51 +8809,100 @@ class SoundsInstance {
8578
8809
  container,
8579
8810
  options,
8580
8811
  pos,
8581
- display: "block",
8812
+ display,
8582
8813
  iconOptions: volumeDown,
8583
8814
  margin,
8584
8815
  rightOffsets: [volumeUp.width],
8585
8816
  clickCb: async () => {
8586
- if (container.muted) {
8587
- this._volume = 0;
8588
- }
8589
- this._volume -= soundsOptions.volume.step;
8590
- await this._updateVolume();
8817
+ await this.volumeDown();
8591
8818
  }
8592
8819
  });
8593
8820
  this._volumeUpImg = initImage({
8594
8821
  container,
8595
8822
  options,
8596
8823
  pos,
8597
- display: "block",
8824
+ display,
8598
8825
  iconOptions: volumeUp,
8599
8826
  margin,
8600
8827
  rightOffsets: [],
8601
8828
  clickCb: async () => {
8602
- if (container.muted) {
8603
- this._volume = 0;
8604
- }
8605
- this._volume += soundsOptions.volume.step;
8606
- await this._updateVolume();
8829
+ await this.volumeUp();
8607
8830
  }
8608
8831
  });
8832
+ if (!isWindowMuted() && soundsOptions.autoPlay) {
8833
+ await this.unmute();
8834
+ }
8609
8835
  }
8610
8836
  stop() {
8611
8837
  this._container.muted = true;
8612
- this._mute();
8613
- removeImage(this._muteImg);
8614
- removeImage(this._unmuteImg);
8615
- removeImage(this._volumeDownImg);
8616
- removeImage(this._volumeUpImg);
8838
+ void (async () => {
8839
+ await this._mute();
8840
+ removeImage(this._muteImg);
8841
+ removeImage(this._unmuteImg);
8842
+ removeImage(this._volumeDownImg);
8843
+ removeImage(this._volumeUpImg);
8844
+ })();
8845
+ }
8846
+ async toggleMute() {
8847
+ const container = this._container;
8848
+ container.muted = !container.muted;
8849
+ this._updateMuteIcons();
8850
+ await this._updateMuteStatus();
8851
+ }
8852
+ async unmute() {
8853
+ if (this._container.muted) {
8854
+ await this.toggleMute();
8855
+ }
8856
+ }
8857
+ async volumeDown() {
8858
+ const container = this._container,
8859
+ soundsOptions = container.actualOptions.sounds;
8860
+ if (!soundsOptions?.enable) {
8861
+ return;
8862
+ }
8863
+ if (container.muted) {
8864
+ this._volume = 0;
8865
+ }
8866
+ this._volume -= soundsOptions.volume.step;
8867
+ await this._updateVolume();
8868
+ }
8869
+ async volumeUp() {
8870
+ const container = this._container,
8871
+ soundsOptions = container.actualOptions.sounds;
8872
+ if (!soundsOptions?.enable) {
8873
+ return;
8874
+ }
8875
+ this._volume += soundsOptions.volume.step;
8876
+ await this._updateVolume();
8877
+ }
8878
+ _getAudioContext() {
8879
+ const container = this._container;
8880
+ if (!container.audioContext) {
8881
+ container.audioContext = new AudioContext();
8882
+ }
8883
+ return container.audioContext;
8617
8884
  }
8618
8885
  }
8619
8886
  ;// CONCATENATED MODULE: ../../plugins/sounds/dist/browser/index.js
8620
8887
 
8621
8888
 
8889
+
8890
+
8891
+ const generalFirstClickHandler = () => {
8892
+ removeEventListener(mouseDownEvent, generalFirstClickHandler);
8893
+ removeEventListener(touchStartEvent, generalFirstClickHandler);
8894
+ unmuteWindow();
8895
+ };
8622
8896
  class SoundsPlugin {
8623
8897
  constructor(engine) {
8624
8898
  this.id = "sounds";
8625
8899
  this._engine = engine;
8900
+ const listenerOptions = {
8901
+ capture: true,
8902
+ once: true
8903
+ };
8904
+ addEventListener(mouseDownEvent, generalFirstClickHandler, listenerOptions);
8905
+ addEventListener(touchStartEvent, generalFirstClickHandler, listenerOptions);
8626
8906
  }
8627
8907
  getPlugin(container) {
8628
8908
  return new SoundsInstance(container, this._engine);
@@ -8644,118 +8924,16 @@ class SoundsPlugin {
8644
8924
  async function loadSoundsPlugin(engine, refresh = true) {
8645
8925
  await engine.addPlugin(new SoundsPlugin(engine), refresh);
8646
8926
  }
8647
- ;// CONCATENATED MODULE: ../../updaters/strokeColor/dist/browser/Utils.js
8648
-
8649
- function Utils_updateColorValue(delta, colorValue, valueAnimation, max, decrease) {
8650
- if (!colorValue || !valueAnimation.enable || (colorValue.maxLoops ?? 0) > 0 && (colorValue.loops ?? 0) > (colorValue.maxLoops ?? 0)) {
8651
- return;
8652
- }
8653
- if (!colorValue.time) {
8654
- colorValue.time = 0;
8655
- }
8656
- if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
8657
- colorValue.time += delta.value;
8658
- }
8659
- if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
8660
- return;
8661
- }
8662
- const offset = randomInRange(valueAnimation.offset),
8663
- velocity = (colorValue.velocity ?? 0) * delta.factor + offset * 3.6,
8664
- decay = colorValue.decay ?? 1;
8665
- if (!decrease || colorValue.status === "increasing") {
8666
- colorValue.value += velocity;
8667
- if (colorValue.value > max) {
8668
- if (!colorValue.loops) {
8669
- colorValue.loops = 0;
8670
- }
8671
- colorValue.loops++;
8672
- if (decrease) {
8673
- colorValue.status = "decreasing";
8674
- colorValue.value -= colorValue.value % max;
8675
- }
8676
- }
8677
- } else {
8678
- colorValue.value -= velocity;
8679
- if (colorValue.value < 0) {
8680
- if (!colorValue.loops) {
8681
- colorValue.loops = 0;
8682
- }
8683
- colorValue.loops++;
8684
- colorValue.status = "increasing";
8685
- colorValue.value += colorValue.value;
8686
- }
8687
- }
8688
- if (colorValue.velocity && decay !== 1) {
8689
- colorValue.velocity *= decay;
8690
- }
8691
- if (colorValue.value > max) {
8692
- colorValue.value %= max;
8693
- }
8694
- }
8695
- function updateStrokeColor(particle, delta) {
8696
- if (!particle.strokeColor || !particle.strokeAnimation) {
8697
- return;
8698
- }
8699
- const {
8700
- h,
8701
- s,
8702
- l
8703
- } = particle.strokeColor,
8704
- {
8705
- h: hAnimation,
8706
- s: sAnimation,
8707
- l: lAnimation
8708
- } = particle.strokeAnimation;
8709
- if (h) {
8710
- Utils_updateColorValue(delta, h, hAnimation, 360, false);
8711
- }
8712
- if (s) {
8713
- Utils_updateColorValue(delta, s, sAnimation, 100, true);
8714
- }
8715
- if (l) {
8716
- Utils_updateColorValue(delta, l, lAnimation, 100, true);
8717
- }
8718
- }
8719
- ;// CONCATENATED MODULE: ../../updaters/strokeColor/dist/browser/StrokeColorUpdater.js
8720
-
8721
-
8722
- class StrokeColorUpdater {
8723
- constructor(container) {
8724
- this.container = container;
8725
- }
8726
- init(particle) {
8727
- const container = this.container,
8728
- options = particle.options;
8729
- const stroke = itemFromSingleOrMultiple(options.stroke, particle.id, options.reduceDuplicates);
8730
- particle.strokeWidth = getRangeValue(stroke.width) * container.retina.pixelRatio;
8731
- particle.strokeOpacity = getRangeValue(stroke.opacity ?? 1);
8732
- particle.strokeAnimation = stroke.color?.animation;
8733
- const strokeHslColor = rangeColorToHsl(stroke.color) ?? particle.getFillColor();
8734
- if (strokeHslColor) {
8735
- particle.strokeColor = getHslAnimationFromHsl(strokeHslColor, particle.strokeAnimation, container.retina.reduceFactor);
8736
- }
8737
- }
8738
- isEnabled(particle) {
8739
- const color = particle.strokeAnimation,
8740
- {
8741
- strokeColor
8742
- } = particle;
8743
- return !particle.destroyed && !particle.spawning && !!color && (strokeColor?.h.value !== undefined && strokeColor.h.enable || strokeColor?.s.value !== undefined && strokeColor.s.enable || strokeColor?.l.value !== undefined && strokeColor.l.enable);
8744
- }
8745
- update(particle, delta) {
8746
- if (!this.isEnabled(particle)) {
8747
- return;
8748
- }
8749
- updateStrokeColor(particle, delta);
8750
- }
8751
- }
8752
- ;// CONCATENATED MODULE: ../../updaters/strokeColor/dist/browser/index.js
8753
-
8754
- async function loadStrokeColorUpdater(engine, refresh = true) {
8755
- await engine.addParticleUpdater("strokeColor", container => new StrokeColorUpdater(container), refresh);
8756
- }
8757
8927
  ;// CONCATENATED MODULE: ../../effects/trail/dist/browser/TrailDrawer.js
8758
8928
 
8929
+ const TrailDrawer_double = 2,
8930
+ minTrailLength = 2,
8931
+ trailLengthOffset = 1,
8932
+ noItems = 0,
8933
+ TrailDrawer_half = 0.5,
8934
+ minWidth = -1,
8935
+ defaultLength = 10,
8936
+ defaultAlpha = 1;
8759
8937
  class TrailDrawer {
8760
8938
  draw(data) {
8761
8939
  const {
@@ -8763,7 +8941,7 @@ class TrailDrawer {
8763
8941
  radius,
8764
8942
  particle
8765
8943
  } = data,
8766
- diameter = radius * 2,
8944
+ diameter = radius * TrailDrawer_double,
8767
8945
  pxRatio = particle.container.retina.pixelRatio,
8768
8946
  currentPos = particle.getPosition();
8769
8947
  if (!particle.trail || !particle.trailLength) {
@@ -8777,7 +8955,7 @@ class TrailDrawer {
8777
8955
  y: currentPos.y
8778
8956
  }
8779
8957
  });
8780
- if (particle.trail.length < 2) {
8958
+ if (particle.trail.length < minTrailLength) {
8781
8959
  return;
8782
8960
  }
8783
8961
  while (particle.trail.length > pathLength) {
@@ -8792,10 +8970,16 @@ class TrailDrawer {
8792
8970
  width: particle.container.canvas.size.width + diameter,
8793
8971
  height: particle.container.canvas.size.height + diameter
8794
8972
  };
8795
- let lastPos = particle.trail[trailLength - 1].position;
8796
- context.setTransform(1, 0, 0, 1, currentPos.x, currentPos.y);
8797
- for (let i = trailLength; i > 0; i--) {
8798
- const step = particle.trail[i - 1],
8973
+ let lastPos = particle.trail[trailLength - trailLengthOffset].position;
8974
+ const defaultTransform = {
8975
+ a: 1,
8976
+ b: 0,
8977
+ c: 0,
8978
+ d: 1
8979
+ };
8980
+ context.setTransform(defaultTransform.a, defaultTransform.b, defaultTransform.c, defaultTransform.d, currentPos.x, currentPos.y);
8981
+ for (let i = trailLength; i > noItems; i--) {
8982
+ const step = particle.trail[i - trailLengthOffset],
8799
8983
  position = step.position;
8800
8984
  context.beginPath();
8801
8985
  context.moveTo(lastPos.x - offsetPos.x, lastPos.y - offsetPos.y);
@@ -8803,14 +8987,14 @@ class TrailDrawer {
8803
8987
  x: (lastPos.x + canvasSize.width) % canvasSize.width,
8804
8988
  y: (lastPos.y + canvasSize.height) % canvasSize.height
8805
8989
  };
8806
- if (Math.abs(lastPos.x - position.x) > canvasSize.width / 2 || Math.abs(lastPos.y - position.y) > canvasSize.height / 2) {
8990
+ if (Math.abs(lastPos.x - position.x) > canvasSize.width * TrailDrawer_half || Math.abs(lastPos.y - position.y) > canvasSize.height * TrailDrawer_half) {
8807
8991
  lastPos = position;
8808
8992
  continue;
8809
8993
  }
8810
- context.lineTo((Math.abs(lastPos.x - position.x) > canvasSize.width / 2 ? warp.x : position.x) - offsetPos.x, (Math.abs(lastPos.y - position.y) > canvasSize.height / 2 ? warp.y : position.y) - offsetPos.y);
8811
- const width = Math.max(i / trailLength * diameter, pxRatio, particle.trailMinWidth ?? -1);
8812
- const oldAlpha = context.globalAlpha;
8813
- context.globalAlpha = particle.trailFade ? i / trailLength : 1;
8994
+ context.lineTo((Math.abs(lastPos.x - position.x) > canvasSize.width * TrailDrawer_half ? warp.x : position.x) - offsetPos.x, (Math.abs(lastPos.y - position.y) > canvasSize.height * TrailDrawer_half ? warp.y : position.y) - offsetPos.y);
8995
+ const width = Math.max(i / trailLength * diameter, pxRatio, particle.trailMinWidth ?? minWidth),
8996
+ oldAlpha = context.globalAlpha;
8997
+ context.globalAlpha = particle.trailFade ? i / trailLength : defaultAlpha;
8814
8998
  context.lineWidth = particle.trailMaxWidth ? Math.min(width, particle.trailMaxWidth) : width;
8815
8999
  context.strokeStyle = step.color;
8816
9000
  context.stroke();
@@ -8826,7 +9010,7 @@ class TrailDrawer {
8826
9010
  particle.trail = [];
8827
9011
  const effectData = particle.effectData;
8828
9012
  particle.trailFade = effectData?.fade ?? true;
8829
- particle.trailLength = getRangeValue(effectData?.length ?? 10) * container.retina.pixelRatio;
9013
+ particle.trailLength = getRangeValue(effectData?.length ?? defaultLength) * container.retina.pixelRatio;
8830
9014
  particle.trailMaxWidth = effectData?.maxWidth ? getRangeValue(effectData.maxWidth) * container.retina.pixelRatio : undefined;
8831
9015
  particle.trailMinWidth = effectData?.minWidth ? getRangeValue(effectData.minWidth) * container.retina.pixelRatio : undefined;
8832
9016
  }
@@ -8847,13 +9031,12 @@ async function loadTrailEffect(engine, refresh = true) {
8847
9031
 
8848
9032
 
8849
9033
 
8850
-
8851
-
9034
+ const fireworks_minSplitCount = 2;
8852
9035
  let initialized = false;
8853
9036
  let initializing = false;
8854
9037
  const explodeSoundCheck = args => {
8855
9038
  const data = args.data;
8856
- return data.particle.shape === "circle" && !!data.particle.splitCount && data.particle.splitCount < 2;
9039
+ return data.particle.shape === "circle" && !!data.particle.splitCount && data.particle.splitCount < fireworks_minSplitCount;
8857
9040
  };
8858
9041
  class FireworksInstance {
8859
9042
  constructor(container) {
@@ -8875,24 +9058,23 @@ async function initPlugins() {
8875
9058
  }
8876
9059
  if (initializing) {
8877
9060
  return new Promise(resolve => {
8878
- const interval = setInterval(() => {
8879
- if (!initialized) {
8880
- return;
8881
- }
8882
- clearInterval(interval);
8883
- resolve();
8884
- }, 100);
9061
+ const timeout = 100,
9062
+ interval = setInterval(() => {
9063
+ if (!initialized) {
9064
+ return;
9065
+ }
9066
+ clearInterval(interval);
9067
+ resolve();
9068
+ }, timeout);
8885
9069
  });
8886
9070
  }
8887
9071
  initializing = true;
8888
9072
  await loadEmittersPlugin(tsParticles, false);
8889
9073
  await loadEmittersShapeSquare(tsParticles, false);
8890
9074
  await loadSoundsPlugin(tsParticles, false);
8891
- await loadLineShape(tsParticles, false);
8892
9075
  await loadRotateUpdater(tsParticles, false);
8893
9076
  await loadDestroyUpdater(tsParticles, false);
8894
9077
  await loadLifeUpdater(tsParticles, false);
8895
- await loadStrokeColorUpdater(tsParticles, false);
8896
9078
  await loadTrailEffect(tsParticles, false);
8897
9079
  await loadBasic(tsParticles, false);
8898
9080
  initializing = false;
@@ -8909,191 +9091,192 @@ async function fireworks(idOrOptions, sourceOptions) {
8909
9091
  id = "fireworks";
8910
9092
  options.load(idOrOptions);
8911
9093
  }
8912
- const particlesOptions = {
8913
- detectRetina: true,
8914
- background: {
8915
- color: options.background
8916
- },
8917
- fpsLimit: 60,
8918
- emitters: {
8919
- direction: "top",
8920
- life: {
8921
- count: 0,
8922
- duration: 0.1,
8923
- delay: 0.1
9094
+ const identity = 1,
9095
+ particlesOptions = {
9096
+ detectRetina: true,
9097
+ background: {
9098
+ color: options.background
8924
9099
  },
8925
- rate: {
8926
- delay: isNumber(options.rate) ? 1 / options.rate : {
8927
- min: 1 / getRangeMin(options.rate),
8928
- max: 1 / getRangeMax(options.rate)
9100
+ fpsLimit: 60,
9101
+ emitters: {
9102
+ direction: "top",
9103
+ life: {
9104
+ count: 0,
9105
+ duration: 0.1,
9106
+ delay: 0.1
8929
9107
  },
8930
- quantity: 1
8931
- },
8932
- size: {
8933
- width: 100,
8934
- height: 0
8935
- },
8936
- position: {
8937
- y: 100,
8938
- x: 50
8939
- }
8940
- },
8941
- particles: {
8942
- number: {
8943
- value: 0
8944
- },
8945
- color: {
8946
- value: "#fff"
9108
+ rate: {
9109
+ delay: isNumber(options.rate) ? identity / options.rate : {
9110
+ min: identity / getRangeMin(options.rate),
9111
+ max: identity / getRangeMax(options.rate)
9112
+ },
9113
+ quantity: 1
9114
+ },
9115
+ size: {
9116
+ width: 100,
9117
+ height: 0
9118
+ },
9119
+ position: {
9120
+ y: 100,
9121
+ x: 50
9122
+ }
8947
9123
  },
8948
- destroy: {
8949
- mode: "split",
8950
- bounds: {
8951
- top: setRangeValue(options.minHeight)
9124
+ particles: {
9125
+ number: {
9126
+ value: 0
8952
9127
  },
8953
- split: {
8954
- sizeOffset: false,
8955
- count: 1,
8956
- factor: {
8957
- value: 0.333333
8958
- },
8959
- rate: {
8960
- value: options.splitCount
8961
- },
8962
- colorOffset: {
8963
- s: options.saturation,
8964
- l: options.brightness
9128
+ color: {
9129
+ value: "#fff"
9130
+ },
9131
+ destroy: {
9132
+ mode: "split",
9133
+ bounds: {
9134
+ top: setRangeValue(options.minHeight)
8965
9135
  },
8966
- particles: {
8967
- color: {
8968
- value: options.colors
9136
+ split: {
9137
+ sizeOffset: false,
9138
+ count: 1,
9139
+ factor: {
9140
+ value: 0.333333
8969
9141
  },
8970
- number: {
8971
- value: 0
9142
+ rate: {
9143
+ value: options.splitCount
8972
9144
  },
8973
- opacity: {
8974
- value: {
8975
- min: 0.1,
8976
- max: 1
8977
- },
8978
- animation: {
8979
- enable: true,
8980
- speed: 1,
8981
- sync: false,
8982
- startValue: "max",
8983
- destroy: "min"
8984
- }
9145
+ colorOffset: {
9146
+ s: options.saturation,
9147
+ l: options.brightness
8985
9148
  },
8986
- effect: {
8987
- type: "trail",
8988
- options: {
8989
- trail: {
8990
- length: {
8991
- min: 5,
8992
- max: 10
9149
+ particles: {
9150
+ color: {
9151
+ value: options.colors
9152
+ },
9153
+ number: {
9154
+ value: 0
9155
+ },
9156
+ opacity: {
9157
+ value: {
9158
+ min: 0.1,
9159
+ max: 1
9160
+ },
9161
+ animation: {
9162
+ enable: true,
9163
+ speed: 1,
9164
+ sync: false,
9165
+ startValue: "max",
9166
+ destroy: "min"
9167
+ }
9168
+ },
9169
+ effect: {
9170
+ type: "trail",
9171
+ options: {
9172
+ trail: {
9173
+ length: {
9174
+ min: 5,
9175
+ max: 10
9176
+ }
8993
9177
  }
8994
9178
  }
8995
- }
8996
- },
8997
- shape: {
8998
- type: "circle"
8999
- },
9000
- size: {
9001
- value: {
9002
- min: 1,
9003
- max: 2
9004
9179
  },
9005
- animation: {
9006
- enable: true,
9007
- speed: 5,
9008
- count: 1,
9009
- sync: false,
9010
- startValue: "min",
9011
- destroy: "none"
9012
- }
9013
- },
9014
- life: {
9015
- count: 1,
9016
- duration: {
9180
+ shape: {
9181
+ type: "circle"
9182
+ },
9183
+ size: {
9017
9184
  value: {
9018
- min: 0.25,
9019
- max: 0.5
9185
+ min: 1,
9186
+ max: 2
9187
+ },
9188
+ animation: {
9189
+ enable: true,
9190
+ speed: 5,
9191
+ count: 1,
9192
+ sync: false,
9193
+ startValue: "min",
9194
+ destroy: "none"
9020
9195
  }
9021
- }
9022
- },
9023
- move: {
9024
- decay: {
9025
- min: 0.05,
9026
- max: 0.1
9027
9196
  },
9028
- enable: true,
9029
- gravity: {
9030
- enable: true,
9031
- inverse: false,
9032
- acceleration: setRangeValue(options.gravity)
9197
+ life: {
9198
+ count: 1,
9199
+ duration: {
9200
+ value: {
9201
+ min: 0.25,
9202
+ max: 0.5
9203
+ }
9204
+ }
9033
9205
  },
9034
- speed: setRangeValue(options.speed),
9035
- direction: "none",
9036
- outModes: "destroy"
9206
+ move: {
9207
+ decay: {
9208
+ min: 0.05,
9209
+ max: 0.1
9210
+ },
9211
+ enable: true,
9212
+ gravity: {
9213
+ enable: true,
9214
+ inverse: false,
9215
+ acceleration: setRangeValue(options.gravity)
9216
+ },
9217
+ speed: setRangeValue(options.speed),
9218
+ direction: "none",
9219
+ outModes: "destroy"
9220
+ }
9037
9221
  }
9038
9222
  }
9039
- }
9040
- },
9041
- life: {
9042
- count: 1
9043
- },
9044
- effect: {
9045
- type: "trail",
9046
- options: {
9047
- trail: {
9048
- length: {
9049
- min: 10,
9050
- max: 30
9051
- },
9052
- minWidth: 1,
9053
- maxWidth: 1
9223
+ },
9224
+ life: {
9225
+ count: 1
9226
+ },
9227
+ effect: {
9228
+ type: "trail",
9229
+ options: {
9230
+ trail: {
9231
+ length: {
9232
+ min: 10,
9233
+ max: 30
9234
+ },
9235
+ minWidth: 1,
9236
+ maxWidth: 1
9237
+ }
9054
9238
  }
9055
- }
9056
- },
9057
- shape: {
9058
- type: "circle"
9059
- },
9060
- size: {
9061
- value: 1
9062
- },
9063
- opacity: {
9064
- value: 0.5
9065
- },
9066
- rotate: {
9067
- path: true
9068
- },
9069
- move: {
9070
- enable: true,
9071
- gravity: {
9072
- acceleration: 15,
9073
- enable: true,
9074
- inverse: true,
9075
- maxSpeed: 100
9076
9239
  },
9077
- speed: {
9078
- min: 10,
9079
- max: 20
9240
+ shape: {
9241
+ type: "circle"
9242
+ },
9243
+ size: {
9244
+ value: 1
9245
+ },
9246
+ opacity: {
9247
+ value: 0.5
9080
9248
  },
9081
- outModes: {
9082
- default: "destroy",
9083
- top: "none"
9249
+ rotate: {
9250
+ path: true
9251
+ },
9252
+ move: {
9253
+ enable: true,
9254
+ gravity: {
9255
+ acceleration: 15,
9256
+ enable: true,
9257
+ inverse: true,
9258
+ maxSpeed: 100
9259
+ },
9260
+ speed: {
9261
+ min: 10,
9262
+ max: 20
9263
+ },
9264
+ outModes: {
9265
+ default: "destroy",
9266
+ top: "none"
9267
+ }
9084
9268
  }
9269
+ },
9270
+ sounds: {
9271
+ enable: options.sounds,
9272
+ events: [{
9273
+ event: "particleRemoved",
9274
+ filter: explodeSoundCheck,
9275
+ audio: ["https://particles.js.org/audio/explosion0.mp3", "https://particles.js.org/audio/explosion1.mp3", "https://particles.js.org/audio/explosion2.mp3"]
9276
+ }],
9277
+ volume: 50
9085
9278
  }
9086
- },
9087
- sounds: {
9088
- enable: options.sounds,
9089
- events: [{
9090
- event: "particleDestroyed",
9091
- filter: explodeSoundCheck,
9092
- audio: ["https://particles.js.org/audio/explosion0.mp3", "https://particles.js.org/audio/explosion1.mp3", "https://particles.js.org/audio/explosion2.mp3"]
9093
- }],
9094
- volume: 50
9095
- }
9096
- };
9279
+ };
9097
9280
  const container = await tsParticles.load({
9098
9281
  id,
9099
9282
  options: particlesOptions