@tsparticles/stencil 4.3.1 → 4.4.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.
@@ -1,4 +1,4 @@
1
- import { R as RangeType, c as checkDistance, s as squareExp, a as isNull, b as setRangeValue, h as hMin, d as hMax, l as lMin, e as lMax, f as sMin, g as sMax, j as isString, k as isArray, m as deepExtend, P as PixelMode, O as OutMode, M as MoveDirection, n as isNumber, o as isObject, L as LimitMode, p as executeOnSingleOrMultiple, q as isBoolean, r as itemFromArray, u as defaultOpacity, v as randomColorValue, A as AlterType, w as lFactor, x as half, y as double, z as hPhase, B as rgbMax, C as getRandomInRange, D as identity, E as defaultRgbMin, F as maxNits, G as sextuple, H as triple, I as phaseNumerator, J as sNormalizedOffset, K as originPoint, N as DrawLayer, Q as minimumSize, S as defaultCompositeValue, T as minStrokeWidth, U as defaultZoom, V as getLogger, W as zIndexFactorOffset, X as defaultTransformValue, Y as safeMutationObserver, Z as generatedAttribute, _ as cloneStyle, $ as safeMatchMedia, a0 as getFullScreenStyle, a1 as safeDocument, a2 as millisecondsToSeconds, a3 as manageListener, a4 as visibilityChangeEvent, a5 as resizeEvent, a6 as Vector3d, a7 as EventType, a8 as defaultAngle, a9 as defaultTransform, aa as defaultRetryCount, ab as tryCountIncrement, ac as getParticleBaseVelocity, ad as randomInRangeValue, ae as getRandom, af as OutModeDirection, ag as clamp, ah as minZ, ai as getPosition, aj as getParticleDirectionAngle, ak as ParticleOutType, al as Vector, am as calcExactPositionOrRandomFromSize, an as getRangeValue, ao as itemFromSingleOrMultiple, ap as isInArray, aq as doublePI, ar as degToRad, as as spatialHashGridCellSize, at as minLimit, au as minCount, av as minIndex, aw as defaultRemoveQuantity, ax as defaultDensityFactor, ay as deleteCount, az as countOffset, aA as one, aB as defaultRatio, aC as defaultReduceFactor, aD as animate, aE as defaultFpsLimit, aF as minFpsLimit, aG as cancelAnimation, aH as defaultFps } from './index-uBrXcY8m.js';
1
+ import { R as RangeType, c as checkDistance, s as squareExp, a as isNull, b as setRangeValue, h as hMin, d as hMax, l as lMin, e as lMax, f as sMin, g as sMax, j as isString, k as isArray, H as HdrMode, m as isBoolean, n as isNumber, o as deepExtend, P as PixelMode, O as OutMode, M as MoveDirection, p as isObject, L as LimitMode, q as executeOnSingleOrMultiple, r as itemFromArray, u as defaultOpacity, v as maxNits, w as randomColorValue, A as AlterType, x as lFactor, y as half, z as double, B as hPhase, C as rgbMax, D as getRandomInRange, E as identity, F as defaultRgbMin, G as clamp, I as none, J as one, K as sextuple, N as triple, Q as phaseNumerator, S as sNormalizedOffset, T as originPoint, U as DrawLayer, V as minimumSize, W as defaultCompositeValue, X as minStrokeWidth, Y as defaultZoom, Z as getLogger, _ as zIndexFactorOffset, $ as defaultTransformValue, a0 as safeMutationObserver, a1 as generatedAttribute, a2 as cloneStyle, a3 as safeMatchMedia, a4 as getFullScreenStyle, a5 as safeDocument, a6 as millisecondsToSeconds, a7 as manageListener, a8 as visibilityChangeEvent, a9 as resizeEvent, aa as Vector3d, ab as EventType, ac as defaultAngle, ad as defaultTransform, ae as defaultRetryCount, af as tryCountIncrement, ag as getParticleBaseVelocity, ah as randomInRangeValue, ai as getRandom, aj as OutModeDirection, ak as minZ, al as getPosition, am as getParticleDirectionAngle, an as ParticleOutType, ao as Vector, ap as calcExactPositionOrRandomFromSize, aq as getRangeValue, ar as itemFromSingleOrMultiple, as as isInArray, at as doublePI, au as degToRad, av as spatialHashGridCellSize, aw as minLimit, ax as minCount, ay as minIndex, az as defaultRemoveQuantity, aA as defaultDensityFactor, aB as deleteCount, aC as countOffset, aD as defaultRatio, aE as defaultReduceFactor, aF as animate, aG as defaultFpsLimit, aH as minFpsLimit, aI as cancelAnimation, aJ as defaultFps } from './index-D6pTafK8.js';
2
2
 
3
3
  class BaseRange {
4
4
  position;
@@ -239,6 +239,29 @@ class FullScreen extends OptionLoader {
239
239
  }
240
240
  }
241
241
 
242
+ const defaultPeakNits = 400, minPeakNits = 0, toStringValue = (value) => String(value);
243
+ class HDROptions extends OptionLoader {
244
+ enable = true;
245
+ mode = HdrMode.standard;
246
+ peakNits = defaultPeakNits;
247
+ doLoad(data) {
248
+ if (data.enable !== undefined && !isBoolean(data.enable)) {
249
+ throw new Error(`Invalid HDR "enable" value: expected a boolean, got "${String(data.enable)}"`);
250
+ }
251
+ if (data.mode !== undefined &&
252
+ (typeof data.mode !== "string" || !Object.values(HdrMode).includes(data.mode))) {
253
+ throw new Error(`Invalid HDR "mode" value: expected one of ${Object.values(HdrMode).join(", ")}, got "${toStringValue(data.mode)}"`);
254
+ }
255
+ if (data.peakNits !== undefined &&
256
+ (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
257
+ throw new Error(`Invalid HDR "peakNits" value: expected a positive number, got "${String(data.peakNits)}"`);
258
+ }
259
+ loadProperty(this, "enable", data.enable);
260
+ loadProperty(this, "mode", data.mode);
261
+ loadProperty(this, "peakNits", data.peakNits);
262
+ }
263
+ }
264
+
242
265
  class ResizeEvent extends OptionLoader {
243
266
  delay = 0.5;
244
267
  enable = true;
@@ -672,7 +695,7 @@ class Options extends OptionLoader {
672
695
  duration = 0;
673
696
  fpsLimit = 120;
674
697
  fullScreen;
675
- hdr = true;
698
+ hdr;
676
699
  key;
677
700
  name;
678
701
  palette;
@@ -692,6 +715,7 @@ class Options extends OptionLoader {
692
715
  this.#container = container;
693
716
  this.background = new Background();
694
717
  this.fullScreen = new FullScreen();
718
+ this.hdr = new HDROptions();
695
719
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
696
720
  this.resize = new ResizeEvent();
697
721
  }
@@ -714,7 +738,15 @@ class Options extends OptionLoader {
714
738
  loadProperty(this, "detectRetina", data.detectRetina);
715
739
  loadRangeProperty(this, "duration", data.duration);
716
740
  loadProperty(this, "fpsLimit", data.fpsLimit);
717
- loadProperty(this, "hdr", data.hdr);
741
+ const hdrData = data.hdr;
742
+ if (isBoolean(hdrData)) {
743
+ this.hdr.enable = hdrData;
744
+ this.hdr.mode = HdrMode.standard;
745
+ this.hdr.peakNits = 400;
746
+ }
747
+ else {
748
+ this.hdr.load(hdrData);
749
+ }
718
750
  loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
719
751
  loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
720
752
  loadProperty(this, "zLayers", data.zLayers);
@@ -757,7 +789,7 @@ class Options extends OptionLoader {
757
789
  }
758
790
  }
759
791
 
760
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203;
792
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, acesA = 2.51, acesB = 0.03, acesC = 2.43, acesD = 0.59, acesE = 0.14, saturationBoost = 1.15, lightnessBoost = 1.05, temperatureR = 1.05, temperatureB = 0.95, contrastFactor = 1.1, luminanceR = 0.2126, luminanceG = 0.7152, luminanceB = 0.0722, dynamicLuminanceFactor = 2, channelCount = 3;
761
793
  function getCachedStyle(key, generator) {
762
794
  let cached = styleCache.get(key);
763
795
  if (!cached) {
@@ -769,6 +801,42 @@ function getCachedStyle(key, generator) {
769
801
  }
770
802
  return cached;
771
803
  }
804
+ function acesFilmic(x) {
805
+ return clamp((x * (acesA * x + acesB)) / (x * (acesC * x + acesD) + acesE), none, one);
806
+ }
807
+ function applyHdrModeAdjustments(r, g, b, mode, maxChannel) {
808
+ switch (mode) {
809
+ case HdrMode.vivid: {
810
+ const avg = (r + g + b) / channelCount;
811
+ return {
812
+ b: clamp(clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
813
+ g: clamp(clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
814
+ r: clamp(clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
815
+ };
816
+ }
817
+ case HdrMode.cinematic: {
818
+ const tempR = r * temperatureR, tempB = b * temperatureB, avg = (tempR + g + tempB) / channelCount;
819
+ return {
820
+ b: clamp(avg + (tempB - avg) * contrastFactor, none, maxChannel),
821
+ g: clamp(avg + (g - avg) * contrastFactor, none, maxChannel),
822
+ r: clamp(avg + (tempR - avg) * contrastFactor, none, maxChannel),
823
+ };
824
+ }
825
+ case HdrMode.dynamic: {
826
+ const luminance = luminanceR * r + luminanceG * g + luminanceB * b, vividWeight = Math.min(one, luminance * dynamicLuminanceFactor), naturalWeight = one - vividWeight, avg = (r + g + b) / channelCount, vividR = clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, vividG = clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, vividB = clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost;
827
+ return {
828
+ b: clamp(b * naturalWeight + vividB * vividWeight, none, maxChannel),
829
+ g: clamp(g * naturalWeight + vividG * vividWeight, none, maxChannel),
830
+ r: clamp(r * naturalWeight + vividR * vividWeight, none, maxChannel),
831
+ };
832
+ }
833
+ case HdrMode.standard:
834
+ return { b, g, r };
835
+ case HdrMode.natural:
836
+ default:
837
+ return { b, g, r };
838
+ }
839
+ }
772
840
  function stringToRgba(pluginManager, input) {
773
841
  if (!input) {
774
842
  return;
@@ -906,21 +974,40 @@ function getRandomRgbColor(min, hdr) {
906
974
  r: getRgbInRangeValue(),
907
975
  };
908
976
  }
909
- function getStyleFromRgb(color, hdr, opacity) {
910
- const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity, key = `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
911
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
977
+ function getStyleFromRgb(color, hdr, opacity, peakNits, mode) {
978
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity, key = hdr
979
+ ? `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
980
+ : `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-sdr-${op.toString()}`;
981
+ return getCachedStyle(key, () => hdr ? getHdrStyleFromRgb(color, opacity, peakNits, mode) : getSdrStyleFromRgb(color, opacity));
912
982
  }
913
- function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
914
- const headroom = peakNits / sdrReferenceWhiteNits;
915
- return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity).toString()})`;
983
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits, mode = HdrMode.standard) {
984
+ const headroom = peakNits / sdrReferenceWhiteNits, middleGray = 0.18, mapped = hdrToneMapColor(color, headroom, middleGray, mode);
985
+ return `color(display-p3 ${mapped.r.toString()} ${mapped.g.toString()} ${mapped.b.toString()} / ${(opacity ?? defaultOpacity).toString()})`;
986
+ }
987
+ function hdrToneMapColor(color, headroom, middleGray, mode) {
988
+ const rNorm = color.r / rgbMax, gNorm = color.g / rgbMax, bNorm = color.b / rgbMax;
989
+ if (mode !== HdrMode.natural && mode !== HdrMode.vivid && mode !== HdrMode.cinematic && mode !== HdrMode.dynamic) {
990
+ return { b: bNorm, g: gNorm, r: rNorm };
991
+ }
992
+ const maxChannel = Math.max(one, headroom), luminance = luminanceR * rNorm + luminanceG * gNorm + luminanceB * bNorm, mappedLuminance = hdrToneMap(luminance, headroom, middleGray), scale = luminance > none ? mappedLuminance / luminance : one;
993
+ return applyHdrModeAdjustments(clamp(rNorm * scale, none, maxChannel), clamp(gNorm * scale, none, maxChannel), clamp(bNorm * scale, none, maxChannel), mode, maxChannel);
994
+ }
995
+ function hdrToneMap(normalized, headroom, middleGray) {
996
+ if (normalized <= middleGray) {
997
+ return acesFilmic(normalized);
998
+ }
999
+ const expanded = normalized + (normalized - middleGray) * (headroom - one);
1000
+ return acesFilmic(expanded);
916
1001
  }
917
1002
  function getSdrStyleFromRgb(color, opacity) {
918
1003
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity).toString()})`;
919
1004
  }
920
- function getStyleFromHsl(color, hdr, opacity) {
921
- const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity, key = `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
1005
+ function getStyleFromHsl(color, hdr, opacity, peakNits, mode) {
1006
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity, key = hdr
1007
+ ? `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
1008
+ : `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-sdr-${op.toString()}`;
922
1009
  return getCachedStyle(key, () => hdr
923
- ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
1010
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity, peakNits, mode)
924
1011
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
925
1012
  }
926
1013
  function getHslFromAnimation(animation) {
@@ -1058,7 +1145,11 @@ class RenderManager {
1058
1145
  if (!fColor && !sColor) {
1059
1146
  return;
1060
1147
  }
1061
- const container = this.#container, zIndexOptions = particle.options.zIndex, zIndexFactor = zIndexFactorOffset - particle.zIndexFactor, { fillOpacity, opacity, strokeOpacity } = particle.getOpacity(), transform = this.#reusableTransform, colorStyles = this.#reusableColorStyles, fill = fColor ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity) : undefined, stroke = sColor ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity) : fill;
1148
+ const container = this.#container, zIndexOptions = particle.options.zIndex, zIndexFactor = zIndexFactorOffset - particle.zIndexFactor, { fillOpacity, opacity, strokeOpacity } = particle.getOpacity(), transform = this.#reusableTransform, colorStyles = this.#reusableColorStyles, fill = fColor
1149
+ ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity, container.peakNits, container.hdrMode)
1150
+ : undefined, stroke = sColor
1151
+ ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity, container.peakNits, container.hdrMode)
1152
+ : fill;
1062
1153
  transform.a = transform.b = transform.c = transform.d = undefined;
1063
1154
  colorStyles.fill = fill;
1064
1155
  colorStyles.stroke = stroke;
@@ -1392,7 +1483,9 @@ class RenderManager {
1392
1483
  if (typeof background.element === "string") {
1393
1484
  if (typeof document !== "undefined") {
1394
1485
  const node = document.querySelector(background.element);
1395
- if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
1486
+ if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
1487
+ (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
1488
+ (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
1396
1489
  this.#backgroundElement = node;
1397
1490
  }
1398
1491
  else if (node) {
@@ -1403,10 +1496,10 @@ class RenderManager {
1403
1496
  }
1404
1497
  }
1405
1498
  }
1406
- else if (background.element instanceof HTMLCanvasElement ||
1407
- background.element instanceof OffscreenCanvas ||
1408
- background.element instanceof HTMLVideoElement ||
1409
- background.element instanceof HTMLImageElement) {
1499
+ else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
1500
+ (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
1501
+ (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
1502
+ (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
1410
1503
  this.#backgroundElement = background.element;
1411
1504
  }
1412
1505
  }
@@ -1474,6 +1567,7 @@ class CanvasManager {
1474
1567
  zoom = defaultZoom;
1475
1568
  #container;
1476
1569
  #generated;
1570
+ #hdrMediaListeners;
1477
1571
  #mutationObserver;
1478
1572
  #originalStyle;
1479
1573
  #pluginManager;
@@ -1538,7 +1632,6 @@ class CanvasManager {
1538
1632
  });
1539
1633
  this.resize();
1540
1634
  this.#initStyle();
1541
- this.initBackground();
1542
1635
  this.#safeMutationObserver(obs => {
1543
1636
  const element = this.domElement;
1544
1637
  if (!element || !(element instanceof Node)) {
@@ -1548,6 +1641,8 @@ class CanvasManager {
1548
1641
  });
1549
1642
  this.initPlugins();
1550
1643
  this.#initContext();
1644
+ this.initBackground();
1645
+ this.#initHdrListeners();
1551
1646
  this.render.init();
1552
1647
  }
1553
1648
  initBackground() {
@@ -1557,7 +1652,8 @@ class CanvasManager {
1557
1652
  }
1558
1653
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
1559
1654
  if (color) {
1560
- elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
1655
+ const hdrOptions = container.actualOptions.hdr;
1656
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
1561
1657
  }
1562
1658
  else {
1563
1659
  elementStyle.backgroundColor = "";
@@ -1654,6 +1750,7 @@ class CanvasManager {
1654
1750
  obs.disconnect();
1655
1751
  });
1656
1752
  this.#mutationObserver = undefined;
1753
+ this.#removeHdrListeners();
1657
1754
  this.render.stop();
1658
1755
  }
1659
1756
  async windowResize() {
@@ -1673,9 +1770,16 @@ class CanvasManager {
1673
1770
  }
1674
1771
  }
1675
1772
  #initContext() {
1676
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
1773
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
1677
1774
  safeMatchMedia("(color-gamut: p3)")?.matches &&
1678
1775
  safeMatchMedia("(dynamic-range: high)")?.matches;
1776
+ container.hdr = canSupportHdr ?? false;
1777
+ container.hdrMode = container.actualOptions.hdr.mode;
1778
+ container.peakNits = container.actualOptions.hdr.peakNits;
1779
+ const renderCanvas = this.renderCanvas;
1780
+ if (!renderCanvas) {
1781
+ return;
1782
+ }
1679
1783
  this.render.setContextSettings({
1680
1784
  alpha: true,
1681
1785
  desynchronized: true,
@@ -1684,11 +1788,47 @@ class CanvasManager {
1684
1788
  ? { colorSpace: "display-p3", colorType: "float16" }
1685
1789
  : { colorSpace: "srgb" }),
1686
1790
  });
1687
- const renderCanvas = this.renderCanvas;
1688
- if (!renderCanvas) {
1689
- return;
1791
+ let context;
1792
+ try {
1793
+ context = renderCanvas.getContext("2d", this.render.settings);
1794
+ }
1795
+ catch {
1796
+ context = null;
1797
+ }
1798
+ if (canSupportHdr && !context) {
1799
+ container.hdr = false;
1800
+ const sdrSettings = {
1801
+ alpha: true,
1802
+ desynchronized: true,
1803
+ willReadFrequently: false,
1804
+ colorSpace: "srgb",
1805
+ };
1806
+ this.render.setContextSettings(sdrSettings);
1807
+ try {
1808
+ context = renderCanvas.getContext("2d", sdrSettings);
1809
+ }
1810
+ catch {
1811
+ context = null;
1812
+ }
1690
1813
  }
1691
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
1814
+ this.render.setContext(context);
1815
+ }
1816
+ #initHdrListeners() {
1817
+ this.#removeHdrListeners();
1818
+ const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
1819
+ this.#recreateRenderCanvas();
1820
+ this.#initContext();
1821
+ this.initBackground();
1822
+ }, listeners = [];
1823
+ if (p3Query) {
1824
+ p3Query.addEventListener("change", handleChange);
1825
+ listeners.push({ handler: handleChange, mql: p3Query });
1826
+ }
1827
+ if (hdrQuery) {
1828
+ hdrQuery.addEventListener("change", handleChange);
1829
+ listeners.push({ handler: handleChange, mql: hdrQuery });
1830
+ }
1831
+ this.#hdrMediaListeners = listeners;
1692
1832
  }
1693
1833
  #initStyle() {
1694
1834
  const element = this.domElement, options = this.#container.actualOptions;
@@ -1712,6 +1852,25 @@ class CanvasManager {
1712
1852
  element.style.setProperty(key, value, "important");
1713
1853
  }
1714
1854
  }
1855
+ #recreateRenderCanvas() {
1856
+ const renderCanvas = this.renderCanvas;
1857
+ if (!renderCanvas) {
1858
+ return;
1859
+ }
1860
+ if (this.domElement) {
1861
+ return;
1862
+ }
1863
+ this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
1864
+ }
1865
+ #removeHdrListeners() {
1866
+ if (!this.#hdrMediaListeners) {
1867
+ return;
1868
+ }
1869
+ for (const { handler, mql } of this.#hdrMediaListeners) {
1870
+ mql.removeEventListener("change", handler);
1871
+ }
1872
+ this.#hdrMediaListeners = undefined;
1873
+ }
1715
1874
  #repairStyle() {
1716
1875
  const element = this.domElement;
1717
1876
  if (!element) {
@@ -2096,9 +2255,9 @@ class Particle {
2096
2255
  }
2097
2256
  getOpacity() {
2098
2257
  const zIndexOptions = this.options.zIndex, zIndexFactor = zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, baseOpacity = getRangeValue(this.opacity?.value ?? defaultOpacity), modifierOpacity = this.#applyModifiers(undefined, m => m.opacity), opacity = modifierOpacity ?? baseOpacity, fillOpacity = this.fillOpacity ?? defaultOpacity, strokeOpacity = this.strokeOpacity ?? defaultOpacity;
2099
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
2258
+ this.#cachedOpacityData.fillOpacity = fillOpacity;
2100
2259
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
2101
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
2260
+ this.#cachedOpacityData.strokeOpacity = strokeOpacity;
2102
2261
  return this.#cachedOpacityData;
2103
2262
  }
2104
2263
  getPosition() {
@@ -2953,6 +3112,7 @@ class Container {
2953
3112
  effectDrawers;
2954
3113
  fpsLimit;
2955
3114
  hdr;
3115
+ hdrMode;
2956
3116
  id;
2957
3117
  pageHidden;
2958
3118
  particleCreatedPlugins;
@@ -2960,6 +3120,7 @@ class Container {
2960
3120
  particlePositionPlugins;
2961
3121
  particleUpdaters;
2962
3122
  particles;
3123
+ peakNits;
2963
3124
  plugins;
2964
3125
  retina;
2965
3126
  shapeDrawers;
@@ -2990,6 +3151,8 @@ class Container {
2990
3151
  this.id = Symbol(id);
2991
3152
  this.fpsLimit = 120;
2992
3153
  this.hdr = false;
3154
+ this.hdrMode = HdrMode.standard;
3155
+ this.peakNits = 400;
2993
3156
  this.#smooth = false;
2994
3157
  this.#delay = 0;
2995
3158
  this.#duration = 0;
@@ -3129,8 +3292,9 @@ class Container {
3129
3292
  this.updateActualOptions();
3130
3293
  this.canvas.initBackground();
3131
3294
  this.canvas.resize();
3132
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
3133
- this.hdr = hdr;
3295
+ const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
3296
+ this.hdrMode = hdrOptions.mode;
3297
+ this.peakNits = hdrOptions.peakNits;
3134
3298
  this.zLayers = zLayers;
3135
3299
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
3136
3300
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;
@@ -269,6 +269,9 @@ var PixelMode;
269
269
  PixelMode["percent"] = "percent";
270
270
  })(PixelMode || (PixelMode = {}));
271
271
 
272
+ function isForbiddenKey(key) {
273
+ return key === "__proto__" || key === "constructor" || key === "prototype";
274
+ }
272
275
  function hasMatchMedia() {
273
276
  return typeof matchMedia !== "undefined";
274
277
  }
@@ -317,7 +320,7 @@ function deepExtend(destination, ...sources) {
317
320
  if (!hasNested) {
318
321
  const sourceDict = source, destDict = destination;
319
322
  for (const key of sourceKeys) {
320
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
323
+ if (isForbiddenKey(key)) {
321
324
  continue;
322
325
  }
323
326
  const v = sourceDict[key];
@@ -328,7 +331,7 @@ function deepExtend(destination, ...sources) {
328
331
  continue;
329
332
  }
330
333
  for (const key of sourceKeys) {
331
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
334
+ if (isForbiddenKey(key)) {
332
335
  continue;
333
336
  }
334
337
  const sourceDict = source, destDict = destination, value = sourceDict[key];
@@ -744,7 +747,7 @@ class Engine {
744
747
  return this.#domArray;
745
748
  }
746
749
  get version() {
747
- return "4.3.1";
750
+ return "4.4.0";
748
751
  }
749
752
  addEventListener(type, listener) {
750
753
  this.#eventDispatcher.addEventListener(type, listener);
@@ -779,7 +782,7 @@ class Engine {
779
782
  if (typeof HTMLElement !== "undefined" && params.element instanceof HTMLElement) {
780
783
  domSourceElement = params.element;
781
784
  }
782
- const { Container } = await import('./Container-COqetWkt.js'), id = params.id ?? domSourceElement?.id ?? `tsparticles${Math.floor(getRandom() * loadRandomFactor).toString()}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options, currentOptions = itemFromSingleOrMultiple(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), newItem = new Container({
785
+ const { Container } = await import('./Container-DJBmSrgJ.js'), id = params.id ?? domSourceElement?.id ?? `tsparticles${Math.floor(getRandom() * loadRandomFactor).toString()}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options, currentOptions = itemFromSingleOrMultiple(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), newItem = new Container({
783
786
  dispatchCallback: (eventType, args) => {
784
787
  this.dispatchEvent(eventType, args);
785
788
  },
@@ -825,6 +828,10 @@ class Engine {
825
828
  }
826
829
 
827
830
  function initEngine() {
831
+ const existing = globalThis.tsParticles;
832
+ if (existing?.pluginManager) {
833
+ return existing;
834
+ }
828
835
  return new Engine();
829
836
  }
830
837
 
@@ -849,6 +856,15 @@ var AnimationMode;
849
856
  AnimationMode["random"] = "random";
850
857
  })(AnimationMode || (AnimationMode = {}));
851
858
 
859
+ var HdrMode;
860
+ (function (HdrMode) {
861
+ HdrMode["standard"] = "standard";
862
+ HdrMode["natural"] = "natural";
863
+ HdrMode["vivid"] = "vivid";
864
+ HdrMode["cinematic"] = "cinematic";
865
+ HdrMode["dynamic"] = "dynamic";
866
+ })(HdrMode || (HdrMode = {}));
867
+
852
868
  var LimitMode;
853
869
  (function (LimitMode) {
854
870
  LimitMode["delete"] = "delete";
@@ -956,4 +972,4 @@ async function waitForParticlesEngineInitialization() {
956
972
  await (initPromise !== null && initPromise !== void 0 ? initPromise : Promise.resolve());
957
973
  }
958
974
 
959
- export { safeMatchMedia as $, AlterType as A, rgbMax as B, getRandomInRange as C, identity as D, defaultRgbMin as E, maxNits as F, sextuple as G, triple as H, phaseNumerator as I, sNormalizedOffset as J, originPoint as K, LimitMode as L, MoveDirection as M, DrawLayer as N, OutMode as O, PixelMode as P, minimumSize as Q, RangeType as R, defaultCompositeValue as S, minStrokeWidth as T, defaultZoom as U, getLogger as V, zIndexFactorOffset as W, defaultTransformValue as X, safeMutationObserver as Y, generatedAttribute as Z, cloneStyle as _, isNull as a, getFullScreenStyle as a0, safeDocument as a1, millisecondsToSeconds as a2, manageListener as a3, visibilityChangeEvent as a4, resizeEvent as a5, Vector3d as a6, EventType as a7, defaultAngle as a8, defaultTransform as a9, one as aA, defaultRatio as aB, defaultReduceFactor as aC, animate as aD, defaultFpsLimit as aE, minFpsLimit as aF, cancelAnimation as aG, defaultFps as aH, isParticlesEngineInitialized as aI, waitForParticlesEngineInitialization as aJ, defaultRetryCount as aa, tryCountIncrement as ab, getParticleBaseVelocity as ac, randomInRangeValue as ad, getRandom as ae, OutModeDirection as af, clamp as ag, minZ as ah, getPosition as ai, getParticleDirectionAngle as aj, ParticleOutType as ak, Vector as al, calcExactPositionOrRandomFromSize as am, getRangeValue as an, itemFromSingleOrMultiple as ao, isInArray as ap, doublePI as aq, degToRad as ar, spatialHashGridCellSize as as, minLimit as at, minCount as au, minIndex as av, defaultRemoveQuantity as aw, defaultDensityFactor as ax, deleteCount as ay, countOffset as az, setRangeValue as b, checkDistance as c, hMax as d, lMax as e, sMin as f, sMax as g, hMin as h, initParticlesEngine as i, isString as j, isArray as k, lMin as l, deepExtend as m, isNumber as n, isObject as o, executeOnSingleOrMultiple as p, isBoolean as q, itemFromArray as r, squareExp as s, tsParticles as t, defaultOpacity as u, randomColorValue as v, lFactor as w, half as x, double as y, hPhase as z };
975
+ export { defaultTransformValue as $, AlterType as A, hPhase as B, rgbMax as C, getRandomInRange as D, identity as E, defaultRgbMin as F, clamp as G, HdrMode as H, none as I, one as J, sextuple as K, LimitMode as L, MoveDirection as M, triple as N, OutMode as O, PixelMode as P, phaseNumerator as Q, RangeType as R, sNormalizedOffset as S, originPoint as T, DrawLayer as U, minimumSize as V, defaultCompositeValue as W, minStrokeWidth as X, defaultZoom as Y, getLogger as Z, zIndexFactorOffset as _, isNull as a, safeMutationObserver as a0, generatedAttribute as a1, cloneStyle as a2, safeMatchMedia as a3, getFullScreenStyle as a4, safeDocument as a5, millisecondsToSeconds as a6, manageListener as a7, visibilityChangeEvent as a8, resizeEvent as a9, defaultDensityFactor as aA, deleteCount as aB, countOffset as aC, defaultRatio as aD, defaultReduceFactor as aE, animate as aF, defaultFpsLimit as aG, minFpsLimit as aH, cancelAnimation as aI, defaultFps as aJ, isParticlesEngineInitialized as aK, waitForParticlesEngineInitialization as aL, Vector3d as aa, EventType as ab, defaultAngle as ac, defaultTransform as ad, defaultRetryCount as ae, tryCountIncrement as af, getParticleBaseVelocity as ag, randomInRangeValue as ah, getRandom as ai, OutModeDirection as aj, minZ as ak, getPosition as al, getParticleDirectionAngle as am, ParticleOutType as an, Vector as ao, calcExactPositionOrRandomFromSize as ap, getRangeValue as aq, itemFromSingleOrMultiple as ar, isInArray as as, doublePI as at, degToRad as au, spatialHashGridCellSize as av, minLimit as aw, minCount as ax, minIndex as ay, defaultRemoveQuantity as az, setRangeValue as b, checkDistance as c, hMax as d, lMax as e, sMin as f, sMax as g, hMin as h, initParticlesEngine as i, isString as j, isArray as k, lMin as l, isBoolean as m, isNumber as n, deepExtend as o, isObject as p, executeOnSingleOrMultiple as q, itemFromArray as r, squareExp as s, tsParticles as t, defaultOpacity as u, maxNits as v, randomColorValue as w, lFactor as x, half as y, double as z };
package/dist/esm/index.js CHANGED
@@ -1 +1 @@
1
- export { i as initParticlesEngine, aI as isParticlesEngineInitialized, aJ as waitForParticlesEngineInitialization } from './index-uBrXcY8m.js';
1
+ export { i as initParticlesEngine, aK as isParticlesEngineInitialized, aL as waitForParticlesEngineInitialization } from './index-D6pTafK8.js';
@@ -1,5 +1,5 @@
1
1
  import { r as registerInstance, c as createEvent, h } from './index-PhwiK2_P.js';
2
- import { i as initParticlesEngine, t as tsParticles } from './index-uBrXcY8m.js';
2
+ import { i as initParticlesEngine, t as tsParticles } from './index-D6pTafK8.js';
3
3
 
4
4
  const StencilParticles = class {
5
5
  constructor(hostRef) {
@@ -46,7 +46,7 @@ const StencilParticles = class {
46
46
  }
47
47
  // Load particles directly onto the DOM element.
48
48
  // If a container-id is provided, use it so consumers can retrieve the container later.
49
- const loadParams = Object.assign(Object.assign({ element: this.containerElement }, (this.containerId ? { id: this.containerId } : {})), (this.options ? { options: this.options } : { url: this.url }));
49
+ const loadParams = Object.assign(Object.assign(Object.assign({ element: this.containerElement }, (this.containerId ? { id: this.containerId } : {})), (this.options ? { options: this.options } : {})), (this.url ? { url: this.url } : {}));
50
50
  container = await tsParticles.load(loadParams);
51
51
  }
52
52
  catch (error) {
@@ -65,7 +65,7 @@ const StencilParticles = class {
65
65
  }
66
66
  }
67
67
  render() {
68
- return (h("div", { key: 'f5fe33d147a1a606a75fe0d1ee385bacaf0e0b7d', id: this.containerId, ref: el => {
68
+ return (h("div", { key: 'a2468083e697bd937120a4e800456a12d80a6935', id: this.containerId, ref: el => {
69
69
  this.containerElement = el;
70
70
  }, style: { width: "100%", height: "100%" } }));
71
71
  }
@@ -1 +1 @@
1
- export{i as initParticlesEngine,aI as isParticlesEngineInitialized,aJ as waitForParticlesEngineInitialization}from"./p-Buaac_o7.js";
1
+ export{i as initParticlesEngine,aK as isParticlesEngineInitialized,aL as waitForParticlesEngineInitialization}from"./p-BayVYJDL.js";
@@ -0,0 +1 @@
1
+ const t="generated",n="source-over",e="resize",s="visibilitychange",a=100,i=.5,r=1e3,o={x:0,y:0,z:0},c={a:1,b:0,c:0,d:1},u="random",h=2,f=2*Math.PI,l=60,d="true",p="false",g="canvas",w=0,m=2,v=100,M=1,y=1,b=1,E=255,P=360,x=100,A=100,L=0,S=0,C=60,k=1,z=0,D=1,T=1,O=120,F=0,j=1,B=0,$=1,H=0,_=0,q=1,I=0,R=0,U=1,V=1,W=0,G=1,J=0,K=1,N=0,Z=400,Q=3,X=6,Y=1,tt=1,nt=0,et=1;var st;function at(t){return"z"in t?t.z:o.z}!function(t){t.bottom="bottom",t.bottomLeft="bottom-left",t.bottomRight="bottom-right",t.left="left",t.none="none",t.right="right",t.top="top",t.topLeft="top-left",t.topRight="top-right",t.outside="outside",t.inside="inside"}(st||(st={}));class it{x;y;z;constructor(t=o.x,n=o.y,e=o.z){this.x=t,this.y=n,this.z=e}static get origin(){return it.create(o.x,o.y,o.z)}get angle(){return Math.atan2(this.y,this.x)}set angle(t){this.#t(t,this.length)}get length(){return Math.sqrt(this.getLengthSq())}set length(t){this.#t(this.angle,t)}static clone(t){return it.create(t.x,t.y,at(t))}static create(t,n,e){return"number"==typeof t?new it(t,n??o.y,e??o.z):new it(t.x,t.y,at(t))}add(t){return it.create(this.x+t.x,this.y+t.y,this.z+at(t))}addTo(t){this.x+=t.x,this.y+=t.y,this.z+=at(t)}copy(){return it.clone(this)}div(t){return it.create(this.x/t,this.y/t,this.z/t)}getLengthSq(){return this.x**2+this.y**2}mult(t){return it.create(this.x*t,this.y*t,this.z*t)}multTo(t){this.x*=t,this.y*=t,this.z*=t}normalize(){const t=this.length;0!=t&&this.multTo(1/t)}rotate(t){return it.create(this.x*Math.cos(t)-this.y*Math.sin(t),this.x*Math.sin(t)+this.y*Math.cos(t),o.z)}setTo(t){this.x=t.x,this.y=t.y,this.z=at(t)}sub(t){return it.create(this.x-t.x,this.y-t.y,this.z-at(t))}subFrom(t){this.x-=t.x,this.y-=t.y,this.z-=at(t)}#t(t,n){this.x=Math.cos(t)*n,this.y=Math.sin(t)*n}}class rt extends it{constructor(t=o.x,n=o.y){super(t,n,o.z)}static get origin(){return rt.create(o.x,o.y)}static clone(t){return rt.create(t.x,t.y)}static create(t,n){return"number"==typeof t?new rt(t,n??o.y):new rt(t.x,t.y)}}function ot(t){return"boolean"==typeof t}function ct(t){return"string"==typeof t}function ut(t){return"number"==typeof t}function ht(t){return"object"==typeof t&&null!==t}function ft(t){return Array.isArray(t)}function lt(t){return null==t}const dt=Math.PI/180;let pt=Math.random;function gt(){return Mt(pt(),0,1-Number.EPSILON)}function wt(t,n){return gt()*(n-t)+t}function mt(t){return requestAnimationFrame(t)}function vt(t){cancelAnimationFrame(t)}function Mt(t,n,e){return Math.min(Math.max(t,n),e)}function yt(t){const n=Pt(t);let e=Et(t);return n===e&&(e=0),wt(e,n)}function bt(t){return ut(t)?t:yt(t)}function Et(t){return ut(t)?t:t.min}function Pt(t){return ut(t)?t:t.max}function xt(t,n){if(t===n||void 0===n&&ut(t))return t;const e=Et(t),s=Pt(t);return void 0!==n?{min:Math.min(e,n),max:Math.max(s,n)}:xt(e,s)}function At(t,n,e){return function(t,n){const e=t.x-n.x,s=t.y-n.y;return e*e+s*s}(t,n)<=e*e}function Lt(t){return t*dt}function St(t,n,e){if(ut(t))return Lt(t);switch(t){case st.top:return.5*-Math.PI;case st.topRight:return.25*-Math.PI;case st.right:return 0;case st.bottomRight:return.25*Math.PI;case st.bottom:return.5*Math.PI;case st.bottomLeft:return.75*Math.PI;case st.left:return Math.PI;case st.topLeft:return.75*-Math.PI;case st.inside:return Math.atan2(e.y-n.y,e.x-n.x);case st.outside:return Math.atan2(n.y-e.y,n.x-e.x);default:return gt()*f}}function Ct(t){const n=rt.origin;return n.length=1,n.angle=t,n}function kt(t){const{position:n,size:e}=t;return{x:n?.x??gt()*e.width,y:n?.y??gt()*e.height}}var zt,Dt;function Tt(t){return"__proto__"===t||"constructor"===t||"prototype"===t}function Ot(){return globalThis.document}function Ft(t){if("undefined"!=typeof matchMedia)return matchMedia(t)}function jt(t){if("undefined"!=typeof MutationObserver)return new MutationObserver(t)}function Bt(t,n){return t===n||ft(n)&&n.includes(t)}function $t(t,n,e=!0){return t[void 0!==n&&e?n%t.length:Math.floor(gt()*t.length)]}function Ht(t,...n){for(const e of n){if(lt(e))continue;if(!ht(e)){t=e;continue}Array.isArray(e)?Array.isArray(t)||(t=[]):ht(t)&&!Array.isArray(t)||(t=Object.create(null));const n=Object.keys(e);if(n.some((t=>{const n=e[t];return ht(n)||Array.isArray(n)})))for(const s of n){if(Tt(s))continue;const n=t,a=e[s];n[s]=Array.isArray(a)?a.map((t=>Ht(void 0,t))):Ht(n[s],a)}else{const s=e,a=t;for(const t of n){if(Tt(t))continue;const n=s[t];void 0!==n&&(a[t]=n)}}}return t}function _t(t,n){return ft(t)?t.map(((t,e)=>n(t,e))):n(t,0)}function qt(t,n,e){return ft(t)?$t(t,n,e):t}function It(t,n){return function(t,n){if(t.mode!==Dt.percent){const{mode:n,...e}=t;return e}return"x"in t?{x:t.x/a*n.width,y:t.y/a*n.height}:{width:t.width/a*n.width,height:t.height/a*n.height}}(t,n)}function Rt(t){const n=Ot().createElement("div").style;for(const e in t){const s=t[e];if(!(e in t)||lt(s))continue;const a=t.getPropertyValue?.(s);if(!a)continue;const i=t.getPropertyPriority?.(s);i?n.setProperty(s,a,i):n.setProperty(s,a)}return n}let Ut,Vt;function Wt(t){if(Ut!==t||!Vt){Ut=t;const n=Ot().createElement("div").style,e=10,s={width:"100%",height:"100%",margin:"0",padding:"0",borderWidth:"0",position:"fixed",zIndex:t.toString(e),"z-index":t.toString(e),top:"0",left:"0","pointer-events":"none"};for(const t in s){const e=s[t];void 0!==e&&n.setProperty(t,e)}Vt=n}return Vt}function Gt(t,n,e,s,a){if(s){let s={passive:!0};ot(a)?s.capture=a:void 0!==a&&(s=a),t.addEventListener(n,e,s)}else t.removeEventListener(n,e,a)}async function Jt(t,n,e,s=!1){let a=n.get(t);if(!a||s){const s=await Promise.all([...e.entries()].map((([n,e])=>e(t).then((t=>[n,t])))));a=new Map(s),n.set(t,a)}return a}!function(t){t.bottom="bottom",t.left="left",t.right="right",t.top="top"}(zt||(zt={})),function(t){t.precise="precise",t.percent="percent"}(Dt||(Dt={}));class Kt{#n;constructor(){this.#n=new Map}addEventListener(t,n){this.removeEventListener(t,n);let e=this.#n.get(t);e||(e=[],this.#n.set(t,e)),e.push(n)}dispatchEvent(t,n){const e=this.#n.get(t);e?.forEach((t=>{t(n)}))}hasEventListener(t){return!!this.#n.get(t)}removeAllEventListeners(t){t?this.#n.delete(t):this.#n=new Map}removeEventListener(t,n){const e=this.#n.get(t);if(!e)return;const s=e.length,a=e.indexOf(n);a<0||(1===s?this.#n.delete(t):e.splice(a,1))}}var Nt;!function(t){t.configAdded="configAdded",t.containerInit="containerInit",t.particlesSetup="particlesSetup",t.containerStarted="containerStarted",t.containerStopped="containerStopped",t.containerDestroyed="containerDestroyed",t.containerPaused="containerPaused",t.containerPlay="containerPlay",t.containerBuilt="containerBuilt",t.particleAdded="particleAdded",t.particleDestroyed="particleDestroyed",t.particleRemoved="particleRemoved"}(Nt||(Nt={}));class Zt{colorManagers=new Map;easingFunctions=new Map;effectDrawers=new Map;initializers={effects:new Map,shapes:new Map,updaters:new Map};palettes=new Map;plugins=[];presets=new Map;shapeDrawers=new Map;updaters=new Map;#e=new Set;#s=new Map;#a;#i=new Set;#r=!1;#o=!1;#c=new Set;constructor(t){this.#a=t}get configs(){const t={};for(const[n,e]of this.#s)t[n]=e;return t}addColorManager(t,n){this.colorManagers.set(t,n)}addConfig(t){const n=t.key??t.name??"default";this.#s.set(n,t),this.#a.dispatchEvent(Nt.configAdded,{data:{name:n,config:t}})}addEasing(t,n){this.easingFunctions.get(t)||this.easingFunctions.set(t,n)}addEffect(t,n){this.initializers.effects.set(t,n)}addPalette(t,n){this.palettes.set(t,n)}addParticleUpdater(t,n){this.initializers.updaters.set(t,n)}addPlugin(t){this.getPlugin(t.id)||this.plugins.push(t)}addPreset(t,n,e=!1){!e&&this.getPreset(t)||this.presets.set(t,n)}addShape(t,n){for(const e of t)this.initializers.shapes.set(e,n)}clearPlugins(t){this.effectDrawers.delete(t),this.shapeDrawers.delete(t),this.updaters.delete(t)}getEasing(t){return this.easingFunctions.get(t)??(t=>t)}getEffectDrawers(t,n=!1){return Jt(t,this.effectDrawers,this.initializers.effects,n)}getPalette(t){return this.palettes.get(t)}getPlugin(t){return this.plugins.find((n=>n.id===t))}getPreset(t){return this.presets.get(t)}async getShapeDrawers(t,n=!1){return Jt(t,this.shapeDrawers,this.initializers.shapes,n)}async getUpdaters(t,n=!1){return async function(t,n,e,s=!1){let a=n.get(t);return a&&!s||(a=await Promise.all([...e.values()].map((n=>n(t)))),n.set(t,a)),a}(t,this.updaters,this.initializers.updaters,n)}async init(){if(!this.#r&&!this.#o){this.#o=!0,this.#i=new Set,this.#e=new Set(this.#c);try{for(const t of this.#e)await this.#u(t,this.#i,this.#e)}finally{this.#c.clear(),this.#o=!1,this.#r=!0}}}loadParticlesOptions(t,n,...e){const s=this.updaters.get(t);s&&s.forEach((t=>t.loadOptions?.(n,...e)))}async register(...t){if(this.#r)throw new Error("Register plugins can only be done before calling tsParticles.load()");for(const n of t)this.#o?await this.#u(n,this.#i,this.#e):this.#c.add(n)}async#u(t,n,e){n.has(t)||(n.add(t),e.add(t),await t(this.#a))}}const Qt=t=>(...n)=>{t(...n)},Xt={debug:Qt(console.debug),error:(t,...n)=>{console.error(`tsParticles - Error - ${t}`,...n)},info:Qt(console.info),log:Qt(console.log),trace:Qt(console.trace),verbose:Qt(console.log),warning:Qt(console.warn)};function Yt(){return Xt}const tn="100%";class nn{pluginManager=new Zt(this);#h=[];#f=new Kt;#r=!1;get items(){return this.#h}get version(){return"4.4.0"}addEventListener(t,n){this.#f.addEventListener(t,n)}checkVersion(t){if(this.version!==t)throw new Error(`The tsParticles version is different from the loaded plugins version. Engine version: ${this.version}. Plugin version: ${t}`)}dispatchEvent(t,n){this.#f.dispatchEvent(t,n)}async init(){this.#r||(await this.pluginManager.init(),this.#r=!0)}item(t){const n=this.items,e=n[t];if(!e?.destroyed)return e;n.splice(t,1)}async load(n){let e;await this.init(),"undefined"!=typeof HTMLElement&&n.element instanceof HTMLElement&&(e=n.element);const{Container:s}=await import("./p-CU7ZW8VD.js"),a=n.id??e?.id??`tsparticles${Math.floor(1e4*gt()).toString()}`,{index:i,url:r}=n,o=r?await async function(t){const n=qt(t.url,t.index);if(!n)return t.fallback;const e=await fetch(n);return e.ok?await e.json():(Yt().error(`${e.status.toString()} while retrieving config file`),t.fallback)}({fallback:n.options,url:r,index:i}):n.options,c=qt(o,i),{items:u}=this,h=u.findIndex((t=>t.id.description===a)),f=new s({dispatchCallback:(t,n)=>{this.dispatchEvent(t,n)},id:a,onDestroy:t=>{if(!t)return;const n=this.items,e=n.indexOf(f);e>=0&&n.splice(e,1)},pluginManager:this.pluginManager,sourceOptions:c});if(h>=0){const t=this.item(h),n=t?1:0;t&&!t.destroyed&&t.destroy(!1),u.splice(h,n,f)}else u.push(f);const l="undefined"!=typeof OffscreenCanvas&&n.element instanceof OffscreenCanvas?n.element:(n=>{const e=Ot();let s;if(n instanceof HTMLCanvasElement||n.tagName.toLowerCase()===g)s=n,s.dataset[t]??=p,s.dataset[t]===d&&(s.style.width||=tn,s.style.height||=tn,s.style.pointerEvents="none",s.style.setProperty("pointer-events","none"));else{const a=n.getElementsByTagName(g).item(0);a?(s=a,s.dataset[t]=p):(s=e.createElement(g),s.dataset[t]=d,n.appendChild(s)),s.style.width||=tn,s.style.height||=tn,s.style.pointerEvents="none",s.style.setProperty("pointer-events","none")}return s})(((n,e)=>{const s=Ot();let a=e??s.getElementById(n);return a||(a=s.createElement("canvas"),a.id=n,a.dataset[t]=d,s.body.append(a),a)})(a,e));return f.canvas.loadCanvas(l),await f.start(),f}async refresh(t=!0){t&&await Promise.all(this.items.map((t=>t.refresh())))}removeEventListener(t,n){this.#f.removeEventListener(t,n)}}var en,sn,an,rn,on,cn,un,hn,fn,ln,dn,pn,gn;!function(t){t.circle="circle",t.rectangle="rectangle"}(en||(en={})),function(t){t.clockwise="clockwise",t.counterClockwise="counter-clockwise",t.random="random"}(sn||(sn={})),function(t){t.auto="auto",t.increase="increase",t.decrease="decrease",t.random="random"}(an||(an={})),function(t){t.standard="standard",t.natural="natural",t.vivid="vivid",t.cinematic="cinematic",t.dynamic="dynamic"}(rn||(rn={})),function(t){t.delete="delete",t.wait="wait"}(on||(on={})),function(t){t.bounce="bounce",t.none="none",t.out="out",t.destroy="destroy",t.split="split"}(cn||(cn={})),function(t){t.darken="darken",t.enlighten="enlighten"}(un||(un={})),function(t){t.none="none",t.max="max",t.min="min"}(hn||(hn={})),function(t){t.linear="linear",t.radial="radial",t.random="random"}(fn||(fn={})),function(t){t.normal="normal",t.inside="inside",t.outside="outside"}(ln||(ln={})),function(t){t.max="max",t.min="min",t.random="random"}(dn||(dn={})),function(t){t.increasing="increasing",t.decreasing="decreasing"}(pn||(pn={})),function(t){t[t.BackgroundElement=0]="BackgroundElement",t[t.BackgroundDraw=1]="BackgroundDraw",t[t.BackgroundMask=2]="BackgroundMask",t[t.CanvasSetup=3]="CanvasSetup",t[t.PluginContent=4]="PluginContent",t[t.Particles=5]="Particles",t[t.CanvasCleanup=6]="CanvasCleanup",t[t.Foreground=7]="Foreground"}(gn||(gn={}));const wn=function(){const t=globalThis.tsParticles;return t?.pluginManager?t:new nn}();let mn,vn,Mn=!1;async function yn(t){if(!Mn)if(mn){if(vn!==t)throw new Error("initParticlesEngine callback must be stable across the app lifecycle.");await mn}else vn=t,mn=(async()=>{t&&await t(wn),"function"==typeof wn.init&&await wn.init(),Mn=!0})().catch((t=>{throw mn=void 0,vn=void 0,Mn=!1,t})),await mn}function bn(){return Mn}async function En(){await(null!=mn?mn:Promise.resolve())}export{k as $,un as A,C as B,E as C,wt as D,G as E,nt as F,Mt as G,rn as H,B as I,j as J,X as K,on as L,st as M,Q as N,cn as O,Dt as P,tt as Q,en as R,Y as S,o as T,gn as U,z as V,n as W,J as X,et as Y,Yt as Z,D as _,lt as a,jt as a0,t as a1,Rt as a2,Ft as a3,Wt as a4,Ot as a5,r as a6,Gt as a7,s as a8,e as a9,U as aA,V as aB,q as aC,y as aD,b as aE,mt as aF,O as aG,F as aH,vt as aI,l as aJ,bn as aK,En as aL,it as aa,Nt as ab,W as ac,c as ad,w as ae,$ as af,Ct as ag,yt as ah,gt as ai,zt as aj,H as ak,It as al,St as am,ln as an,rt as ao,kt as ap,bt as aq,qt as ar,Bt as as,f as at,Lt as au,v as av,_ as aw,I as ax,R as ay,M as az,xt as b,At as c,P as d,A as e,S as f,x as g,L as h,yn as i,ct as j,ft as k,N as l,ot as m,ut as n,Ht as o,ht as p,_t as q,$t as r,m as s,wn as t,T as u,Z as v,u as w,K as x,i as y,h as z}