UNPKG

310 kBJavaScriptView Raw
1(function webpackUniversalModuleDefinition(root, factory) {
2 if (typeof exports === "object" && typeof module === "object") module.exports = factory(); else if (typeof define === "function" && define.amd) define([], factory); else {
3 var a = factory();
4 for (var i in a) (typeof exports === "object" ? exports : root)[i] = a[i];
5 }
6})(this, (function() {
7 return (() => {
8 "use strict";
9 var __webpack_require__ = {};
10 (() => {
11 __webpack_require__.d = (exports, definition) => {
12 for (var key in definition) {
13 if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
14 Object.defineProperty(exports, key, {
15 enumerable: true,
16 get: definition[key]
17 });
18 }
19 }
20 };
21 })();
22 (() => {
23 __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
24 })();
25 (() => {
26 __webpack_require__.r = exports => {
27 if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
28 Object.defineProperty(exports, Symbol.toStringTag, {
29 value: "Module"
30 });
31 }
32 Object.defineProperty(exports, "__esModule", {
33 value: true
34 });
35 };
36 })();
37 var __webpack_exports__ = {};
38 __webpack_require__.r(__webpack_exports__);
39 __webpack_require__.d(__webpack_exports__, {
40 AlterType: () => AlterType,
41 AnimationStatus: () => AnimationStatus,
42 Circle: () => Circle,
43 CircleWarp: () => CircleWarp,
44 ClickMode: () => ClickMode,
45 CollisionMode: () => CollisionMode,
46 Constants: () => Constants,
47 Container: () => Container,
48 DestroyMode: () => DestroyMode,
49 DestroyType: () => DestroyType,
50 DivMode: () => DivMode,
51 DivType: () => DivType,
52 EasingType: () => EasingType,
53 ExternalInteractorBase: () => ExternalInteractorBase,
54 GradientType: () => GradientType,
55 HoverMode: () => HoverMode,
56 InteractivityDetect: () => InteractivityDetect,
57 InteractorType: () => InteractorType,
58 Main: () => Main,
59 MoveDirection: () => MoveDirection,
60 OrbitType: () => OrbitType,
61 OutMode: () => OutMode,
62 OutModeDirection: () => OutModeDirection,
63 Particle: () => Particle,
64 ParticlesInteractorBase: () => ParticlesInteractorBase,
65 Point: () => Point,
66 Rectangle: () => Rectangle,
67 RollMode: () => RollMode,
68 RotateDirection: () => RotateDirection,
69 ShapeType: () => ShapeType,
70 SizeMode: () => SizeMode,
71 StartValueType: () => StartValueType,
72 ThemeMode: () => ThemeMode,
73 TiltDirection: () => TiltDirection,
74 Vector: () => Vector,
75 alterHsl: () => alterHsl,
76 animate: () => animate,
77 areBoundsInside: () => areBoundsInside,
78 arrayRandomIndex: () => arrayRandomIndex,
79 calcEasing: () => calcEasing,
80 calculateBounds: () => calculateBounds,
81 cancelAnimation: () => cancelAnimation,
82 circleBounce: () => circleBounce,
83 circleBounceDataFromParticle: () => circleBounceDataFromParticle,
84 clamp: () => clamp,
85 clear: () => clear,
86 collisionVelocity: () => collisionVelocity,
87 colorMix: () => colorMix,
88 colorToHsl: () => colorToHsl,
89 colorToRgb: () => colorToRgb,
90 deepExtend: () => deepExtend,
91 divMode: () => divMode,
92 divModeExecute: () => divModeExecute,
93 drawConnectLine: () => drawConnectLine,
94 drawEllipse: () => drawEllipse,
95 drawGrabLine: () => drawGrabLine,
96 drawLinkLine: () => drawLinkLine,
97 drawLinkTriangle: () => drawLinkTriangle,
98 drawParticle: () => drawParticle,
99 drawParticlePlugin: () => drawParticlePlugin,
100 drawPlugin: () => drawPlugin,
101 drawShape: () => drawShape,
102 drawShapeAfterEffect: () => drawShapeAfterEffect,
103 getDistance: () => getDistance,
104 getDistances: () => getDistances,
105 getHslAnimationFromHsl: () => getHslAnimationFromHsl,
106 getHslFromAnimation: () => getHslFromAnimation,
107 getLinkColor: () => getLinkColor,
108 getLinkRandomColor: () => getLinkRandomColor,
109 getParticleBaseVelocity: () => getParticleBaseVelocity,
110 getParticleDirectionAngle: () => getParticleDirectionAngle,
111 getRandomRgbColor: () => getRandomRgbColor,
112 getRangeMax: () => getRangeMax,
113 getRangeMin: () => getRangeMin,
114 getRangeValue: () => getRangeValue,
115 getStyleFromHsl: () => getStyleFromHsl,
116 getStyleFromHsv: () => getStyleFromHsv,
117 getStyleFromRgb: () => getStyleFromRgb,
118 getValue: () => getValue,
119 gradient: () => gradient,
120 hslToHsv: () => hslToHsv,
121 hslToRgb: () => hslToRgb,
122 hslaToHsva: () => hslaToHsva,
123 hslaToRgba: () => hslaToRgba,
124 hsvToHsl: () => hsvToHsl,
125 hsvToRgb: () => hsvToRgb,
126 hsvaToHsla: () => hsvaToHsla,
127 hsvaToRgba: () => hsvaToRgba,
128 isDivModeEnabled: () => isDivModeEnabled,
129 isInArray: () => isInArray,
130 isPointInside: () => isPointInside,
131 isSsr: () => isSsr,
132 itemFromArray: () => itemFromArray,
133 loadFont: () => loadFont,
134 mix: () => mix,
135 pJSDom: () => pJSDom,
136 paintBase: () => paintBase,
137 particlesJS: () => particlesJS,
138 randomInRange: () => randomInRange,
139 rectBounce: () => rectBounce,
140 rgbToHsl: () => rgbToHsl,
141 rgbToHsv: () => rgbToHsv,
142 rgbaToHsva: () => rgbaToHsva,
143 setRangeValue: () => setRangeValue,
144 singleDivModeExecute: () => singleDivModeExecute,
145 stringToAlpha: () => stringToAlpha,
146 stringToRgb: () => stringToRgb,
147 tsParticles: () => tsParticles
148 });
149 const initPjs = main => {
150 const particlesJS = (tagId, options) => main.load(tagId, options);
151 particlesJS.load = (tagId, pathConfigJson, callback) => {
152 main.loadJSON(tagId, pathConfigJson).then((container => {
153 if (container) {
154 callback(container);
155 }
156 })).catch((() => {
157 callback(undefined);
158 }));
159 };
160 particlesJS.setOnClickHandler = callback => {
161 main.setOnClickHandler(callback);
162 };
163 const pJSDom = main.dom();
164 return {
165 particlesJS,
166 pJSDom
167 };
168 };
169 var MoveDirection;
170 (function(MoveDirection) {
171 MoveDirection["bottom"] = "bottom";
172 MoveDirection["bottomLeft"] = "bottom-left";
173 MoveDirection["bottomRight"] = "bottom-right";
174 MoveDirection["left"] = "left";
175 MoveDirection["none"] = "none";
176 MoveDirection["right"] = "right";
177 MoveDirection["top"] = "top";
178 MoveDirection["topLeft"] = "top-left";
179 MoveDirection["topRight"] = "top-right";
180 })(MoveDirection || (MoveDirection = {}));
181 var RotateDirection;
182 (function(RotateDirection) {
183 RotateDirection["clockwise"] = "clockwise";
184 RotateDirection["counterClockwise"] = "counter-clockwise";
185 RotateDirection["random"] = "random";
186 })(RotateDirection || (RotateDirection = {}));
187 var OutModeDirection;
188 (function(OutModeDirection) {
189 OutModeDirection["bottom"] = "bottom";
190 OutModeDirection["left"] = "left";
191 OutModeDirection["right"] = "right";
192 OutModeDirection["top"] = "top";
193 })(OutModeDirection || (OutModeDirection = {}));
194 var TiltDirection;
195 (function(TiltDirection) {
196 TiltDirection["clockwise"] = "clockwise";
197 TiltDirection["counterClockwise"] = "counter-clockwise";
198 TiltDirection["random"] = "random";
199 })(TiltDirection || (TiltDirection = {}));
200 var ClickMode;
201 (function(ClickMode) {
202 ClickMode["attract"] = "attract";
203 ClickMode["bubble"] = "bubble";
204 ClickMode["push"] = "push";
205 ClickMode["remove"] = "remove";
206 ClickMode["repulse"] = "repulse";
207 ClickMode["pause"] = "pause";
208 ClickMode["trail"] = "trail";
209 })(ClickMode || (ClickMode = {}));
210 var DestroyMode;
211 (function(DestroyMode) {
212 DestroyMode["none"] = "none";
213 DestroyMode["split"] = "split";
214 })(DestroyMode || (DestroyMode = {}));
215 var DivMode;
216 (function(DivMode) {
217 DivMode["bounce"] = "bounce";
218 DivMode["bubble"] = "bubble";
219 DivMode["repulse"] = "repulse";
220 })(DivMode || (DivMode = {}));
221 var HoverMode;
222 (function(HoverMode) {
223 HoverMode["attract"] = "attract";
224 HoverMode["bounce"] = "bounce";
225 HoverMode["bubble"] = "bubble";
226 HoverMode["connect"] = "connect";
227 HoverMode["grab"] = "grab";
228 HoverMode["light"] = "light";
229 HoverMode["repulse"] = "repulse";
230 HoverMode["slow"] = "slow";
231 HoverMode["trail"] = "trail";
232 })(HoverMode || (HoverMode = {}));
233 var CollisionMode;
234 (function(CollisionMode) {
235 CollisionMode["absorb"] = "absorb";
236 CollisionMode["bounce"] = "bounce";
237 CollisionMode["destroy"] = "destroy";
238 })(CollisionMode || (CollisionMode = {}));
239 var OutMode;
240 (function(OutMode) {
241 OutMode["bounce"] = "bounce";
242 OutMode["bounceHorizontal"] = "bounce-horizontal";
243 OutMode["bounceVertical"] = "bounce-vertical";
244 OutMode["none"] = "none";
245 OutMode["out"] = "out";
246 OutMode["destroy"] = "destroy";
247 OutMode["split"] = "split";
248 })(OutMode || (OutMode = {}));
249 var RollMode;
250 (function(RollMode) {
251 RollMode["both"] = "both";
252 RollMode["horizontal"] = "horizontal";
253 RollMode["vertical"] = "vertical";
254 })(RollMode || (RollMode = {}));
255 var SizeMode;
256 (function(SizeMode) {
257 SizeMode["precise"] = "precise";
258 SizeMode["percent"] = "percent";
259 })(SizeMode || (SizeMode = {}));
260 var ThemeMode;
261 (function(ThemeMode) {
262 ThemeMode["any"] = "any";
263 ThemeMode["dark"] = "dark";
264 ThemeMode["light"] = "light";
265 })(ThemeMode || (ThemeMode = {}));
266 var AnimationStatus;
267 (function(AnimationStatus) {
268 AnimationStatus[AnimationStatus["increasing"] = 0] = "increasing";
269 AnimationStatus[AnimationStatus["decreasing"] = 1] = "decreasing";
270 })(AnimationStatus || (AnimationStatus = {}));
271 var AlterType;
272 (function(AlterType) {
273 AlterType["darken"] = "darken";
274 AlterType["enlighten"] = "enlighten";
275 })(AlterType || (AlterType = {}));
276 var DestroyType;
277 (function(DestroyType) {
278 DestroyType["none"] = "none";
279 DestroyType["max"] = "max";
280 DestroyType["min"] = "min";
281 })(DestroyType || (DestroyType = {}));
282 var GradientType;
283 (function(GradientType) {
284 GradientType["linear"] = "linear";
285 GradientType["radial"] = "radial";
286 GradientType["random"] = "random";
287 })(GradientType || (GradientType = {}));
288 var InteractorType;
289 (function(InteractorType) {
290 InteractorType[InteractorType["External"] = 0] = "External";
291 InteractorType[InteractorType["Particles"] = 1] = "Particles";
292 })(InteractorType || (InteractorType = {}));
293 var ShapeType;
294 (function(ShapeType) {
295 ShapeType["char"] = "char";
296 ShapeType["character"] = "character";
297 ShapeType["circle"] = "circle";
298 ShapeType["edge"] = "edge";
299 ShapeType["image"] = "image";
300 ShapeType["images"] = "images";
301 ShapeType["line"] = "line";
302 ShapeType["polygon"] = "polygon";
303 ShapeType["square"] = "square";
304 ShapeType["star"] = "star";
305 ShapeType["triangle"] = "triangle";
306 })(ShapeType || (ShapeType = {}));
307 var StartValueType;
308 (function(StartValueType) {
309 StartValueType["max"] = "max";
310 StartValueType["min"] = "min";
311 StartValueType["random"] = "random";
312 })(StartValueType || (StartValueType = {}));
313 var DivType;
314 (function(DivType) {
315 DivType["circle"] = "circle";
316 DivType["rectangle"] = "rectangle";
317 })(DivType || (DivType = {}));
318 var EasingType;
319 (function(EasingType) {
320 EasingType["easeOutBack"] = "ease-out-back";
321 EasingType["easeOutCirc"] = "ease-out-circ";
322 EasingType["easeOutCubic"] = "ease-out-cubic";
323 EasingType["easeOutQuad"] = "ease-out-quad";
324 EasingType["easeOutQuart"] = "ease-out-quart";
325 EasingType["easeOutQuint"] = "ease-out-quint";
326 EasingType["easeOutExpo"] = "ease-out-expo";
327 EasingType["easeOutSine"] = "ease-out-sine";
328 })(EasingType || (EasingType = {}));
329 var OrbitType;
330 (function(OrbitType) {
331 OrbitType["front"] = "front";
332 OrbitType["back"] = "back";
333 })(OrbitType || (OrbitType = {}));
334 var InteractivityDetect;
335 (function(InteractivityDetect) {
336 InteractivityDetect["canvas"] = "canvas";
337 InteractivityDetect["parent"] = "parent";
338 InteractivityDetect["window"] = "window";
339 })(InteractivityDetect || (InteractivityDetect = {}));
340 class Vector {
341 constructor(x, y) {
342 let defX, defY;
343 if (y === undefined) {
344 if (typeof x === "number") {
345 throw new Error("tsParticles - Vector not initialized correctly");
346 }
347 const coords = x;
348 [defX, defY] = [ coords.x, coords.y ];
349 } else {
350 [defX, defY] = [ x, y ];
351 }
352 this.x = defX;
353 this.y = defY;
354 }
355 static clone(source) {
356 return Vector.create(source.x, source.y);
357 }
358 static create(x, y) {
359 return new Vector(x, y);
360 }
361 static get origin() {
362 return Vector.create(0, 0);
363 }
364 get angle() {
365 return Math.atan2(this.y, this.x);
366 }
367 set angle(angle) {
368 this.updateFromAngle(angle, this.length);
369 }
370 get length() {
371 return Math.sqrt(this.x ** 2 + this.y ** 2);
372 }
373 set length(length) {
374 this.updateFromAngle(this.angle, length);
375 }
376 add(v) {
377 return Vector.create(this.x + v.x, this.y + v.y);
378 }
379 addTo(v) {
380 this.x += v.x;
381 this.y += v.y;
382 }
383 sub(v) {
384 return Vector.create(this.x - v.x, this.y - v.y);
385 }
386 subFrom(v) {
387 this.x -= v.x;
388 this.y -= v.y;
389 }
390 mult(n) {
391 return Vector.create(this.x * n, this.y * n);
392 }
393 multTo(n) {
394 this.x *= n;
395 this.y *= n;
396 }
397 div(n) {
398 return Vector.create(this.x / n, this.y / n);
399 }
400 divTo(n) {
401 this.x /= n;
402 this.y /= n;
403 }
404 distanceTo(v) {
405 return this.sub(v).length;
406 }
407 getLengthSq() {
408 return this.x ** 2 + this.y ** 2;
409 }
410 distanceToSq(v) {
411 return this.sub(v).getLengthSq();
412 }
413 manhattanDistanceTo(v) {
414 return Math.abs(v.x - this.x) + Math.abs(v.y - this.y);
415 }
416 copy() {
417 return Vector.clone(this);
418 }
419 setTo(velocity) {
420 this.x = velocity.x;
421 this.y = velocity.y;
422 }
423 rotate(angle) {
424 return Vector.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle));
425 }
426 updateFromAngle(angle, length) {
427 this.x = Math.cos(angle) * length;
428 this.y = Math.sin(angle) * length;
429 }
430 }
431 function clamp(num, min, max) {
432 return Math.min(Math.max(num, min), max);
433 }
434 function mix(comp1, comp2, weight1, weight2) {
435 return Math.floor((comp1 * weight1 + comp2 * weight2) / (weight1 + weight2));
436 }
437 function randomInRange(r) {
438 const max = getRangeMax(r);
439 let min = getRangeMin(r);
440 if (max === min) {
441 min = 0;
442 }
443 return Math.random() * (max - min) + min;
444 }
445 function getRangeValue(value) {
446 return typeof value === "number" ? value : randomInRange(value);
447 }
448 function getRangeMin(value) {
449 return typeof value === "number" ? value : value.min;
450 }
451 function getRangeMax(value) {
452 return typeof value === "number" ? value : value.max;
453 }
454 function setRangeValue(source, value) {
455 if (source === value || value === undefined && typeof source === "number") {
456 return source;
457 }
458 const min = getRangeMin(source), max = getRangeMax(source);
459 return value !== undefined ? {
460 min: Math.min(min, value),
461 max: Math.max(max, value)
462 } : setRangeValue(min, max);
463 }
464 function getValue(options) {
465 const random = options.random;
466 const {enable, minimumValue} = typeof random === "boolean" ? {
467 enable: random,
468 minimumValue: 0
469 } : random;
470 return enable ? getRangeValue(setRangeValue(options.value, minimumValue)) : getRangeValue(options.value);
471 }
472 function getDistances(pointA, pointB) {
473 const dx = pointA.x - pointB.x;
474 const dy = pointA.y - pointB.y;
475 return {
476 dx,
477 dy,
478 distance: Math.sqrt(dx * dx + dy * dy)
479 };
480 }
481 function getDistance(pointA, pointB) {
482 return getDistances(pointA, pointB).distance;
483 }
484 function getParticleDirectionAngle(direction) {
485 if (typeof direction === "number") {
486 return direction * Math.PI / 180;
487 } else {
488 switch (direction) {
489 case MoveDirection.top:
490 return -Math.PI / 2;
491
492 case MoveDirection.topRight:
493 return -Math.PI / 4;
494
495 case MoveDirection.right:
496 return 0;
497
498 case MoveDirection.bottomRight:
499 return Math.PI / 4;
500
501 case MoveDirection.bottom:
502 return Math.PI / 2;
503
504 case MoveDirection.bottomLeft:
505 return 3 * Math.PI / 4;
506
507 case MoveDirection.left:
508 return Math.PI;
509
510 case MoveDirection.topLeft:
511 return -3 * Math.PI / 4;
512
513 case MoveDirection.none:
514 default:
515 return Math.random() * Math.PI * 2;
516 }
517 }
518 }
519 function getParticleBaseVelocity(direction) {
520 const baseVelocity = Vector.origin;
521 baseVelocity.length = 1;
522 baseVelocity.angle = direction;
523 return baseVelocity;
524 }
525 function collisionVelocity(v1, v2, m1, m2) {
526 return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * 2 * m2 / (m1 + m2), v1.y);
527 }
528 function calcEasing(value, type) {
529 switch (type) {
530 case EasingType.easeOutQuad:
531 return 1 - (1 - value) ** 2;
532
533 case EasingType.easeOutCubic:
534 return 1 - (1 - value) ** 3;
535
536 case EasingType.easeOutQuart:
537 return 1 - (1 - value) ** 4;
538
539 case EasingType.easeOutQuint:
540 return 1 - (1 - value) ** 5;
541
542 case EasingType.easeOutExpo:
543 return value === 1 ? 1 : 1 - Math.pow(2, -10 * value);
544
545 case EasingType.easeOutSine:
546 return Math.sin(value * Math.PI / 2);
547
548 case EasingType.easeOutBack:
549 {
550 const c1 = 1.70158;
551 const c3 = c1 + 1;
552 return 1 + c3 * Math.pow(value - 1, 3) + c1 * Math.pow(value - 1, 2);
553 }
554
555 case EasingType.easeOutCirc:
556 return Math.sqrt(1 - Math.pow(value - 1, 2));
557
558 default:
559 return value;
560 }
561 }
562 function rectSideBounce(pSide, pOtherSide, rectSide, rectOtherSide, velocity, factor) {
563 const res = {
564 bounced: false
565 };
566 if (pOtherSide.min >= rectOtherSide.min && pOtherSide.min <= rectOtherSide.max && pOtherSide.max >= rectOtherSide.min && pOtherSide.max <= rectOtherSide.max) {
567 if (pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) / 2 && velocity > 0 || pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) / 2 && velocity < 0) {
568 res.velocity = velocity * -factor;
569 res.bounced = true;
570 }
571 }
572 return res;
573 }
574 function checkSelector(element, selectors) {
575 if (selectors instanceof Array) {
576 for (const selector of selectors) {
577 if (element.matches(selector)) {
578 return true;
579 }
580 }
581 return false;
582 } else {
583 return element.matches(selectors);
584 }
585 }
586 function isSsr() {
587 return typeof window === "undefined" || !window || typeof window.document === "undefined" || !window.document;
588 }
589 function animate() {
590 return isSsr() ? callback => setTimeout(callback) : callback => (window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || window.setTimeout)(callback);
591 }
592 function cancelAnimation() {
593 return isSsr() ? handle => clearTimeout(handle) : handle => (window.cancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.mozCancelRequestAnimationFrame || window.oCancelRequestAnimationFrame || window.msCancelRequestAnimationFrame || window.clearTimeout)(handle);
594 }
595 function isInArray(value, array) {
596 return value === array || array instanceof Array && array.indexOf(value) > -1;
597 }
598 async function loadFont(character) {
599 var _a, _b;
600 try {
601 await document.fonts.load(`${(_a = character.weight) !== null && _a !== void 0 ? _a : "400"} 36px '${(_b = character.font) !== null && _b !== void 0 ? _b : "Verdana"}'`);
602 } catch (_c) {}
603 }
604 function arrayRandomIndex(array) {
605 return Math.floor(Math.random() * array.length);
606 }
607 function itemFromArray(array, index, useIndex = true) {
608 const fixedIndex = index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array);
609 return array[fixedIndex];
610 }
611 function isPointInside(point, size, radius, direction) {
612 return areBoundsInside(calculateBounds(point, radius !== null && radius !== void 0 ? radius : 0), size, direction);
613 }
614 function areBoundsInside(bounds, size, direction) {
615 let inside = true;
616 if (!direction || direction === OutModeDirection.bottom) {
617 inside = bounds.top < size.height;
618 }
619 if (inside && (!direction || direction === OutModeDirection.left)) {
620 inside = bounds.right > 0;
621 }
622 if (inside && (!direction || direction === OutModeDirection.right)) {
623 inside = bounds.left < size.width;
624 }
625 if (inside && (!direction || direction === OutModeDirection.top)) {
626 inside = bounds.bottom > 0;
627 }
628 return inside;
629 }
630 function calculateBounds(point, radius) {
631 return {
632 bottom: point.y + radius,
633 left: point.x - radius,
634 right: point.x + radius,
635 top: point.y - radius
636 };
637 }
638 function deepExtend(destination, ...sources) {
639 for (const source of sources) {
640 if (source === undefined || source === null) {
641 continue;
642 }
643 if (typeof source !== "object") {
644 destination = source;
645 continue;
646 }
647 const sourceIsArray = Array.isArray(source);
648 if (sourceIsArray && (typeof destination !== "object" || !destination || !Array.isArray(destination))) {
649 destination = [];
650 } else if (!sourceIsArray && (typeof destination !== "object" || !destination || Array.isArray(destination))) {
651 destination = {};
652 }
653 for (const key in source) {
654 if (key === "__proto__") {
655 continue;
656 }
657 const sourceDict = source;
658 const value = sourceDict[key];
659 const isObject = typeof value === "object";
660 const destDict = destination;
661 destDict[key] = isObject && Array.isArray(value) ? value.map((v => deepExtend(destDict[key], v))) : deepExtend(destDict[key], value);
662 }
663 }
664 return destination;
665 }
666 function isDivModeEnabled(mode, divs) {
667 return divs instanceof Array ? !!divs.find((t => t.enable && isInArray(mode, t.mode))) : isInArray(mode, divs.mode);
668 }
669 function divModeExecute(mode, divs, callback) {
670 if (divs instanceof Array) {
671 for (const div of divs) {
672 const divMode = div.mode;
673 const divEnabled = div.enable;
674 if (divEnabled && isInArray(mode, divMode)) {
675 singleDivModeExecute(div, callback);
676 }
677 }
678 } else {
679 const divMode = divs.mode;
680 const divEnabled = divs.enable;
681 if (divEnabled && isInArray(mode, divMode)) {
682 singleDivModeExecute(divs, callback);
683 }
684 }
685 }
686 function singleDivModeExecute(div, callback) {
687 const selectors = div.selectors;
688 if (selectors instanceof Array) {
689 for (const selector of selectors) {
690 callback(selector, div);
691 }
692 } else {
693 callback(selectors, div);
694 }
695 }
696 function divMode(divs, element) {
697 if (!element || !divs) {
698 return;
699 }
700 if (divs instanceof Array) {
701 return divs.find((d => checkSelector(element, d.selectors)));
702 } else if (checkSelector(element, divs.selectors)) {
703 return divs;
704 }
705 }
706 function circleBounceDataFromParticle(p) {
707 return {
708 position: p.getPosition(),
709 radius: p.getRadius(),
710 mass: p.getMass(),
711 velocity: p.velocity,
712 factor: Vector.create(getValue(p.options.bounce.horizontal), getValue(p.options.bounce.vertical))
713 };
714 }
715 function circleBounce(p1, p2) {
716 const xVelocityDiff = p1.velocity.x;
717 const yVelocityDiff = p1.velocity.y;
718 const pos1 = p1.position;
719 const pos2 = p2.position;
720 const xDist = pos2.x - pos1.x;
721 const yDist = pos2.y - pos1.y;
722 if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0) {
723 const angle = -Math.atan2(pos2.y - pos1.y, pos2.x - pos1.x);
724 const m1 = p1.mass;
725 const m2 = p2.mass;
726 const u1 = p1.velocity.rotate(angle);
727 const u2 = p2.velocity.rotate(angle);
728 const v1 = collisionVelocity(u1, u2, m1, m2);
729 const v2 = collisionVelocity(u2, u1, m1, m2);
730 const vFinal1 = v1.rotate(-angle);
731 const vFinal2 = v2.rotate(-angle);
732 p1.velocity.x = vFinal1.x * p1.factor.x;
733 p1.velocity.y = vFinal1.y * p1.factor.y;
734 p2.velocity.x = vFinal2.x * p2.factor.x;
735 p2.velocity.y = vFinal2.y * p2.factor.y;
736 }
737 }
738 function rectBounce(particle, divBounds) {
739 const pPos = particle.getPosition();
740 const size = particle.getRadius();
741 const bounds = calculateBounds(pPos, size);
742 const resH = rectSideBounce({
743 min: bounds.left,
744 max: bounds.right
745 }, {
746 min: bounds.top,
747 max: bounds.bottom
748 }, {
749 min: divBounds.left,
750 max: divBounds.right
751 }, {
752 min: divBounds.top,
753 max: divBounds.bottom
754 }, particle.velocity.x, getValue(particle.options.bounce.horizontal));
755 if (resH.bounced) {
756 if (resH.velocity !== undefined) {
757 particle.velocity.x = resH.velocity;
758 }
759 if (resH.position !== undefined) {
760 particle.position.x = resH.position;
761 }
762 }
763 const resV = rectSideBounce({
764 min: bounds.top,
765 max: bounds.bottom
766 }, {
767 min: bounds.left,
768 max: bounds.right
769 }, {
770 min: divBounds.top,
771 max: divBounds.bottom
772 }, {
773 min: divBounds.left,
774 max: divBounds.right
775 }, particle.velocity.y, getValue(particle.options.bounce.vertical));
776 if (resV.bounced) {
777 if (resV.velocity !== undefined) {
778 particle.velocity.y = resV.velocity;
779 }
780 if (resV.position !== undefined) {
781 particle.position.y = resV.position;
782 }
783 }
784 }
785 class Constants {}
786 Constants.canvasClass = "tsparticles-canvas-el";
787 Constants.randomColorValue = "random";
788 Constants.midColorValue = "mid";
789 Constants.touchEndEvent = "touchend";
790 Constants.mouseDownEvent = "mousedown";
791 Constants.mouseUpEvent = "mouseup";
792 Constants.mouseMoveEvent = "mousemove";
793 Constants.touchStartEvent = "touchstart";
794 Constants.touchMoveEvent = "touchmove";
795 Constants.mouseLeaveEvent = "mouseleave";
796 Constants.mouseOutEvent = "mouseout";
797 Constants.touchCancelEvent = "touchcancel";
798 Constants.resizeEvent = "resize";
799 Constants.visibilityChangeEvent = "visibilitychange";
800 Constants.noPolygonDataLoaded = "No polygon data loaded.";
801 Constants.noPolygonFound = "No polygon found, you need to specify SVG url in config.";
802 function hue2rgb(p, q, t) {
803 let tCalc = t;
804 if (tCalc < 0) {
805 tCalc += 1;
806 }
807 if (tCalc > 1) {
808 tCalc -= 1;
809 }
810 if (tCalc < 1 / 6) {
811 return p + (q - p) * 6 * tCalc;
812 }
813 if (tCalc < 1 / 2) {
814 return q;
815 }
816 if (tCalc < 2 / 3) {
817 return p + (q - p) * (2 / 3 - tCalc) * 6;
818 }
819 return p;
820 }
821 function stringToRgba(input) {
822 if (input.startsWith("rgb")) {
823 const regex = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.]+)\s*)?\)/i;
824 const result = regex.exec(input);
825 return result ? {
826 a: result.length > 4 ? parseFloat(result[5]) : 1,
827 b: parseInt(result[3], 10),
828 g: parseInt(result[2], 10),
829 r: parseInt(result[1], 10)
830 } : undefined;
831 } else if (input.startsWith("hsl")) {
832 const regex = /hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.]+)\s*)?\)/i;
833 const result = regex.exec(input);
834 return result ? hslaToRgba({
835 a: result.length > 4 ? parseFloat(result[5]) : 1,
836 h: parseInt(result[1], 10),
837 l: parseInt(result[3], 10),
838 s: parseInt(result[2], 10)
839 }) : undefined;
840 } else if (input.startsWith("hsv")) {
841 const regex = /hsva?\(\s*(\d+)°\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.]+)\s*)?\)/i;
842 const result = regex.exec(input);
843 return result ? hsvaToRgba({
844 a: result.length > 4 ? parseFloat(result[5]) : 1,
845 h: parseInt(result[1], 10),
846 s: parseInt(result[2], 10),
847 v: parseInt(result[3], 10)
848 }) : undefined;
849 } else {
850 const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i;
851 const hexFixed = input.replace(shorthandRegex, ((_m, r, g, b, a) => r + r + g + g + b + b + (a !== undefined ? a + a : "")));
852 const regex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i;
853 const result = regex.exec(hexFixed);
854 return result ? {
855 a: result[4] !== undefined ? parseInt(result[4], 16) / 255 : 1,
856 b: parseInt(result[3], 16),
857 g: parseInt(result[2], 16),
858 r: parseInt(result[1], 16)
859 } : undefined;
860 }
861 }
862 function colorToRgb(input, index, useIndex = true) {
863 var _a, _b, _c;
864 if (input === undefined) {
865 return;
866 }
867 const color = typeof input === "string" ? {
868 value: input
869 } : input;
870 let res;
871 if (typeof color.value === "string") {
872 if (color.value === Constants.randomColorValue) {
873 res = getRandomRgbColor();
874 } else {
875 res = stringToRgb(color.value);
876 }
877 } else {
878 if (color.value instanceof Array) {
879 const colorSelected = itemFromArray(color.value, index, useIndex);
880 res = colorToRgb({
881 value: colorSelected
882 });
883 } else {
884 const colorValue = color.value;
885 const rgbColor = (_a = colorValue.rgb) !== null && _a !== void 0 ? _a : color.value;
886 if (rgbColor.r !== undefined) {
887 res = rgbColor;
888 } else {
889 const hslColor = (_b = colorValue.hsl) !== null && _b !== void 0 ? _b : color.value;
890 if (hslColor.h !== undefined && hslColor.l !== undefined) {
891 res = hslToRgb(hslColor);
892 } else {
893 const hsvColor = (_c = colorValue.hsv) !== null && _c !== void 0 ? _c : color.value;
894 if (hsvColor.h !== undefined && hsvColor.v !== undefined) {
895 res = hsvToRgb(hsvColor);
896 }
897 }
898 }
899 }
900 }
901 return res;
902 }
903 function colorToHsl(color, index, useIndex = true) {
904 const rgb = colorToRgb(color, index, useIndex);
905 return rgb !== undefined ? rgbToHsl(rgb) : undefined;
906 }
907 function rgbToHsl(color) {
908 const r1 = color.r / 255;
909 const g1 = color.g / 255;
910 const b1 = color.b / 255;
911 const max = Math.max(r1, g1, b1);
912 const min = Math.min(r1, g1, b1);
913 const res = {
914 h: 0,
915 l: (max + min) / 2,
916 s: 0
917 };
918 if (max != min) {
919 res.s = res.l < .5 ? (max - min) / (max + min) : (max - min) / (2 - max - min);
920 res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? 2 + (b1 - r1) / (max - min) : 4 + (r1 - g1) / (max - min);
921 }
922 res.l *= 100;
923 res.s *= 100;
924 res.h *= 60;
925 if (res.h < 0) {
926 res.h += 360;
927 }
928 return res;
929 }
930 function stringToAlpha(input) {
931 var _a;
932 return (_a = stringToRgba(input)) === null || _a === void 0 ? void 0 : _a.a;
933 }
934 function stringToRgb(input) {
935 return stringToRgba(input);
936 }
937 function hslToRgb(hsl) {
938 const result = {
939 b: 0,
940 g: 0,
941 r: 0
942 };
943 const hslPercent = {
944 h: hsl.h / 360,
945 l: hsl.l / 100,
946 s: hsl.s / 100
947 };
948 if (hslPercent.s === 0) {
949 result.b = hslPercent.l;
950 result.g = hslPercent.l;
951 result.r = hslPercent.l;
952 } else {
953 const q = hslPercent.l < .5 ? hslPercent.l * (1 + hslPercent.s) : hslPercent.l + hslPercent.s - hslPercent.l * hslPercent.s;
954 const p = 2 * hslPercent.l - q;
955 result.r = hue2rgb(p, q, hslPercent.h + 1 / 3);
956 result.g = hue2rgb(p, q, hslPercent.h);
957 result.b = hue2rgb(p, q, hslPercent.h - 1 / 3);
958 }
959 result.r = Math.floor(result.r * 255);
960 result.g = Math.floor(result.g * 255);
961 result.b = Math.floor(result.b * 255);
962 return result;
963 }
964 function hslaToRgba(hsla) {
965 const rgbResult = hslToRgb(hsla);
966 return {
967 a: hsla.a,
968 b: rgbResult.b,
969 g: rgbResult.g,
970 r: rgbResult.r
971 };
972 }
973 function hslToHsv(hsl) {
974 const l = hsl.l / 100, sl = hsl.s / 100;
975 const v = l + sl * Math.min(l, 1 - l), sv = !v ? 0 : 2 * (1 - l / v);
976 return {
977 h: hsl.h,
978 s: sv * 100,
979 v: v * 100
980 };
981 }
982 function hslaToHsva(hsla) {
983 const hsvResult = hslToHsv(hsla);
984 return {
985 a: hsla.a,
986 h: hsvResult.h,
987 s: hsvResult.s,
988 v: hsvResult.v
989 };
990 }
991 function hsvToHsl(hsv) {
992 const v = hsv.v / 100, sv = hsv.s / 100;
993 const l = v * (1 - sv / 2), sl = l === 0 || l === 1 ? 0 : (v - l) / Math.min(l, 1 - l);
994 return {
995 h: hsv.h,
996 l: l * 100,
997 s: sl * 100
998 };
999 }
1000 function hsvaToHsla(hsva) {
1001 const hslResult = hsvToHsl(hsva);
1002 return {
1003 a: hsva.a,
1004 h: hslResult.h,
1005 l: hslResult.l,
1006 s: hslResult.s
1007 };
1008 }
1009 function hsvToRgb(hsv) {
1010 const result = {
1011 b: 0,
1012 g: 0,
1013 r: 0
1014 };
1015 const hsvPercent = {
1016 h: hsv.h / 60,
1017 s: hsv.s / 100,
1018 v: hsv.v / 100
1019 };
1020 const c = hsvPercent.v * hsvPercent.s, x = c * (1 - Math.abs(hsvPercent.h % 2 - 1));
1021 let tempRgb;
1022 if (hsvPercent.h >= 0 && hsvPercent.h <= 1) {
1023 tempRgb = {
1024 r: c,
1025 g: x,
1026 b: 0
1027 };
1028 } else if (hsvPercent.h > 1 && hsvPercent.h <= 2) {
1029 tempRgb = {
1030 r: x,
1031 g: c,
1032 b: 0
1033 };
1034 } else if (hsvPercent.h > 2 && hsvPercent.h <= 3) {
1035 tempRgb = {
1036 r: 0,
1037 g: c,
1038 b: x
1039 };
1040 } else if (hsvPercent.h > 3 && hsvPercent.h <= 4) {
1041 tempRgb = {
1042 r: 0,
1043 g: x,
1044 b: c
1045 };
1046 } else if (hsvPercent.h > 4 && hsvPercent.h <= 5) {
1047 tempRgb = {
1048 r: x,
1049 g: 0,
1050 b: c
1051 };
1052 } else if (hsvPercent.h > 5 && hsvPercent.h <= 6) {
1053 tempRgb = {
1054 r: c,
1055 g: 0,
1056 b: x
1057 };
1058 }
1059 if (tempRgb) {
1060 const m = hsvPercent.v - c;
1061 result.r = Math.floor((tempRgb.r + m) * 255);
1062 result.g = Math.floor((tempRgb.g + m) * 255);
1063 result.b = Math.floor((tempRgb.b + m) * 255);
1064 }
1065 return result;
1066 }
1067 function hsvaToRgba(hsva) {
1068 const rgbResult = hsvToRgb(hsva);
1069 return {
1070 a: hsva.a,
1071 b: rgbResult.b,
1072 g: rgbResult.g,
1073 r: rgbResult.r
1074 };
1075 }
1076 function rgbToHsv(rgb) {
1077 const rgbPercent = {
1078 r: rgb.r / 255,
1079 g: rgb.g / 255,
1080 b: rgb.b / 255
1081 }, xMax = Math.max(rgbPercent.r, rgbPercent.g, rgbPercent.b), xMin = Math.min(rgbPercent.r, rgbPercent.g, rgbPercent.b), v = xMax, c = xMax - xMin;
1082 let h = 0;
1083 if (v === rgbPercent.r) {
1084 h = 60 * ((rgbPercent.g - rgbPercent.b) / c);
1085 } else if (v === rgbPercent.g) {
1086 h = 60 * (2 + (rgbPercent.b - rgbPercent.r) / c);
1087 } else if (v === rgbPercent.b) {
1088 h = 60 * (4 + (rgbPercent.r - rgbPercent.g) / c);
1089 }
1090 const s = !v ? 0 : c / v;
1091 return {
1092 h,
1093 s: s * 100,
1094 v: v * 100
1095 };
1096 }
1097 function rgbaToHsva(rgba) {
1098 const hsvResult = rgbToHsv(rgba);
1099 return {
1100 a: rgba.a,
1101 h: hsvResult.h,
1102 s: hsvResult.s,
1103 v: hsvResult.v
1104 };
1105 }
1106 function getRandomRgbColor(min) {
1107 const fixedMin = min !== null && min !== void 0 ? min : 0;
1108 return {
1109 b: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1110 g: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1111 r: Math.floor(randomInRange(setRangeValue(fixedMin, 256)))
1112 };
1113 }
1114 function getStyleFromRgb(color, opacity) {
1115 return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity !== null && opacity !== void 0 ? opacity : 1})`;
1116 }
1117 function getStyleFromHsl(color, opacity) {
1118 return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity !== null && opacity !== void 0 ? opacity : 1})`;
1119 }
1120 function getStyleFromHsv(color, opacity) {
1121 return getStyleFromHsl(hsvToHsl(color), opacity);
1122 }
1123 function colorMix(color1, color2, size1, size2) {
1124 let rgb1 = color1;
1125 let rgb2 = color2;
1126 if (rgb1.r === undefined) {
1127 rgb1 = hslToRgb(color1);
1128 }
1129 if (rgb2.r === undefined) {
1130 rgb2 = hslToRgb(color2);
1131 }
1132 return {
1133 b: mix(rgb1.b, rgb2.b, size1, size2),
1134 g: mix(rgb1.g, rgb2.g, size1, size2),
1135 r: mix(rgb1.r, rgb2.r, size1, size2)
1136 };
1137 }
1138 function getLinkColor(p1, p2, linkColor) {
1139 var _a, _b;
1140 if (linkColor === Constants.randomColorValue) {
1141 return getRandomRgbColor();
1142 } else if (linkColor === "mid") {
1143 const sourceColor = (_a = p1.getFillColor()) !== null && _a !== void 0 ? _a : p1.getStrokeColor();
1144 const destColor = (_b = p2 === null || p2 === void 0 ? void 0 : p2.getFillColor()) !== null && _b !== void 0 ? _b : p2 === null || p2 === void 0 ? void 0 : p2.getStrokeColor();
1145 if (sourceColor && destColor && p2) {
1146 return colorMix(sourceColor, destColor, p1.getRadius(), p2.getRadius());
1147 } else {
1148 const hslColor = sourceColor !== null && sourceColor !== void 0 ? sourceColor : destColor;
1149 if (hslColor) {
1150 return hslToRgb(hslColor);
1151 }
1152 }
1153 } else {
1154 return linkColor;
1155 }
1156 }
1157 function getLinkRandomColor(optColor, blink, consent) {
1158 const color = typeof optColor === "string" ? optColor : optColor.value;
1159 if (color === Constants.randomColorValue) {
1160 if (consent) {
1161 return colorToRgb({
1162 value: color
1163 });
1164 } else if (blink) {
1165 return Constants.randomColorValue;
1166 } else {
1167 return Constants.midColorValue;
1168 }
1169 } else {
1170 return colorToRgb({
1171 value: color
1172 });
1173 }
1174 }
1175 function getHslFromAnimation(animation) {
1176 return animation !== undefined ? {
1177 h: animation.h.value,
1178 s: animation.s.value,
1179 l: animation.l.value
1180 } : undefined;
1181 }
1182 function getHslAnimationFromHsl(hsl, animationOptions, reduceFactor) {
1183 const resColor = {
1184 h: {
1185 enable: false,
1186 value: hsl.h
1187 },
1188 s: {
1189 enable: false,
1190 value: hsl.s
1191 },
1192 l: {
1193 enable: false,
1194 value: hsl.l
1195 }
1196 };
1197 if (animationOptions) {
1198 setColorAnimation(resColor.h, animationOptions.h, reduceFactor);
1199 setColorAnimation(resColor.s, animationOptions.s, reduceFactor);
1200 setColorAnimation(resColor.l, animationOptions.l, reduceFactor);
1201 }
1202 return resColor;
1203 }
1204 function setColorAnimation(colorValue, colorAnimation, reduceFactor) {
1205 colorValue.enable = colorAnimation.enable;
1206 if (colorValue.enable) {
1207 colorValue.velocity = colorAnimation.speed / 100 * reduceFactor;
1208 if (colorAnimation.sync) {
1209 return;
1210 }
1211 colorValue.status = AnimationStatus.increasing;
1212 colorValue.velocity *= Math.random();
1213 if (colorValue.value) {
1214 colorValue.value *= Math.random();
1215 }
1216 } else {
1217 colorValue.velocity = 0;
1218 }
1219 }
1220 function drawLine(context, begin, end) {
1221 context.beginPath();
1222 context.moveTo(begin.x, begin.y);
1223 context.lineTo(end.x, end.y);
1224 context.closePath();
1225 }
1226 function drawTriangle(context, p1, p2, p3) {
1227 context.beginPath();
1228 context.moveTo(p1.x, p1.y);
1229 context.lineTo(p2.x, p2.y);
1230 context.lineTo(p3.x, p3.y);
1231 context.closePath();
1232 }
1233 function paintBase(context, dimension, baseColor) {
1234 context.save();
1235 context.fillStyle = baseColor !== null && baseColor !== void 0 ? baseColor : "rgba(0,0,0,0)";
1236 context.fillRect(0, 0, dimension.width, dimension.height);
1237 context.restore();
1238 }
1239 function clear(context, dimension) {
1240 context.clearRect(0, 0, dimension.width, dimension.height);
1241 }
1242 function drawLinkLine(context, width, begin, end, maxDistance, canvasSize, warp, backgroundMask, composite, colorLine, opacity, shadow) {
1243 let drawn = false;
1244 if (getDistance(begin, end) <= maxDistance) {
1245 drawLine(context, begin, end);
1246 drawn = true;
1247 } else if (warp) {
1248 let pi1;
1249 let pi2;
1250 const endNE = {
1251 x: end.x - canvasSize.width,
1252 y: end.y
1253 };
1254 const d1 = getDistances(begin, endNE);
1255 if (d1.distance <= maxDistance) {
1256 const yi = begin.y - d1.dy / d1.dx * begin.x;
1257 pi1 = {
1258 x: 0,
1259 y: yi
1260 };
1261 pi2 = {
1262 x: canvasSize.width,
1263 y: yi
1264 };
1265 } else {
1266 const endSW = {
1267 x: end.x,
1268 y: end.y - canvasSize.height
1269 };
1270 const d2 = getDistances(begin, endSW);
1271 if (d2.distance <= maxDistance) {
1272 const yi = begin.y - d2.dy / d2.dx * begin.x;
1273 const xi = -yi / (d2.dy / d2.dx);
1274 pi1 = {
1275 x: xi,
1276 y: 0
1277 };
1278 pi2 = {
1279 x: xi,
1280 y: canvasSize.height
1281 };
1282 } else {
1283 const endSE = {
1284 x: end.x - canvasSize.width,
1285 y: end.y - canvasSize.height
1286 };
1287 const d3 = getDistances(begin, endSE);
1288 if (d3.distance <= maxDistance) {
1289 const yi = begin.y - d3.dy / d3.dx * begin.x;
1290 const xi = -yi / (d3.dy / d3.dx);
1291 pi1 = {
1292 x: xi,
1293 y: yi
1294 };
1295 pi2 = {
1296 x: pi1.x + canvasSize.width,
1297 y: pi1.y + canvasSize.height
1298 };
1299 }
1300 }
1301 }
1302 if (pi1 && pi2) {
1303 drawLine(context, begin, pi1);
1304 drawLine(context, end, pi2);
1305 drawn = true;
1306 }
1307 }
1308 if (!drawn) {
1309 return;
1310 }
1311 context.lineWidth = width;
1312 if (backgroundMask) {
1313 context.globalCompositeOperation = composite;
1314 }
1315 context.strokeStyle = getStyleFromRgb(colorLine, opacity);
1316 if (shadow.enable) {
1317 const shadowColor = colorToRgb(shadow.color);
1318 if (shadowColor) {
1319 context.shadowBlur = shadow.blur;
1320 context.shadowColor = getStyleFromRgb(shadowColor);
1321 }
1322 }
1323 context.stroke();
1324 }
1325 function drawLinkTriangle(context, pos1, pos2, pos3, backgroundMask, composite, colorTriangle, opacityTriangle) {
1326 drawTriangle(context, pos1, pos2, pos3);
1327 if (backgroundMask) {
1328 context.globalCompositeOperation = composite;
1329 }
1330 context.fillStyle = getStyleFromRgb(colorTriangle, opacityTriangle);
1331 context.fill();
1332 }
1333 function drawConnectLine(context, width, lineStyle, begin, end) {
1334 context.save();
1335 drawLine(context, begin, end);
1336 context.lineWidth = width;
1337 context.strokeStyle = lineStyle;
1338 context.stroke();
1339 context.restore();
1340 }
1341 function gradient(context, p1, p2, opacity) {
1342 const gradStop = Math.floor(p2.getRadius() / p1.getRadius());
1343 const color1 = p1.getFillColor();
1344 const color2 = p2.getFillColor();
1345 if (!color1 || !color2) {
1346 return;
1347 }
1348 const sourcePos = p1.getPosition();
1349 const destPos = p2.getPosition();
1350 const midRgb = colorMix(color1, color2, p1.getRadius(), p2.getRadius());
1351 const grad = context.createLinearGradient(sourcePos.x, sourcePos.y, destPos.x, destPos.y);
1352 grad.addColorStop(0, getStyleFromHsl(color1, opacity));
1353 grad.addColorStop(gradStop > 1 ? 1 : gradStop, getStyleFromRgb(midRgb, opacity));
1354 grad.addColorStop(1, getStyleFromHsl(color2, opacity));
1355 return grad;
1356 }
1357 function drawGrabLine(context, width, begin, end, colorLine, opacity) {
1358 context.save();
1359 drawLine(context, begin, end);
1360 context.strokeStyle = getStyleFromRgb(colorLine, opacity);
1361 context.lineWidth = width;
1362 context.stroke();
1363 context.restore();
1364 }
1365 function drawParticle(container, context, particle, delta, fillColorValue, strokeColorValue, backgroundMask, composite, radius, opacity, shadow, gradient) {
1366 var _a, _b, _c, _d, _e, _f;
1367 const pos = particle.getPosition();
1368 const tiltOptions = particle.options.tilt;
1369 const rollOptions = particle.options.roll;
1370 context.save();
1371 if (tiltOptions.enable || rollOptions.enable) {
1372 const roll = rollOptions.enable && particle.roll;
1373 const tilt = tiltOptions.enable && particle.tilt;
1374 const rollHorizontal = roll && (rollOptions.mode === RollMode.horizontal || rollOptions.mode === RollMode.both);
1375 const rollVertical = roll && (rollOptions.mode === RollMode.vertical || rollOptions.mode === RollMode.both);
1376 context.setTransform(rollHorizontal ? Math.cos(particle.roll.angle) : 1, tilt ? Math.cos(particle.tilt.value) * particle.tilt.cosDirection : 0, tilt ? Math.sin(particle.tilt.value) * particle.tilt.sinDirection : 0, rollVertical ? Math.sin(particle.roll.angle) : 1, pos.x, pos.y);
1377 } else {
1378 context.translate(pos.x, pos.y);
1379 }
1380 context.beginPath();
1381 const angle = ((_b = (_a = particle.rotate) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 0) + (particle.options.rotate.path ? particle.velocity.angle : 0);
1382 if (angle !== 0) {
1383 context.rotate(angle);
1384 }
1385 if (backgroundMask) {
1386 context.globalCompositeOperation = composite;
1387 }
1388 const shadowColor = particle.shadowColor;
1389 if (shadow.enable && shadowColor) {
1390 context.shadowBlur = shadow.blur;
1391 context.shadowColor = getStyleFromRgb(shadowColor);
1392 context.shadowOffsetX = shadow.offset.x;
1393 context.shadowOffsetY = shadow.offset.y;
1394 }
1395 if (gradient) {
1396 const gradientAngle = gradient.angle.value;
1397 const fillGradient = gradient.type === GradientType.radial ? context.createRadialGradient(0, 0, 0, 0, 0, radius) : context.createLinearGradient(Math.cos(gradientAngle) * -radius, Math.sin(gradientAngle) * -radius, Math.cos(gradientAngle) * radius, Math.sin(gradientAngle) * radius);
1398 for (const color of gradient.colors) {
1399 fillGradient.addColorStop(color.stop, getStyleFromHsl({
1400 h: color.value.h.value,
1401 s: color.value.s.value,
1402 l: color.value.l.value
1403 }, (_d = (_c = color.opacity) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : opacity));
1404 }
1405 context.fillStyle = fillGradient;
1406 } else {
1407 if (fillColorValue) {
1408 context.fillStyle = fillColorValue;
1409 }
1410 }
1411 const stroke = particle.stroke;
1412 context.lineWidth = (_e = particle.strokeWidth) !== null && _e !== void 0 ? _e : 0;
1413 if (strokeColorValue) {
1414 context.strokeStyle = strokeColorValue;
1415 }
1416 drawShape(container, context, particle, radius, opacity, delta);
1417 if (((_f = stroke === null || stroke === void 0 ? void 0 : stroke.width) !== null && _f !== void 0 ? _f : 0) > 0) {
1418 context.stroke();
1419 }
1420 if (particle.close) {
1421 context.closePath();
1422 }
1423 if (particle.fill) {
1424 context.fill();
1425 }
1426 context.restore();
1427 context.save();
1428 if (tiltOptions.enable && particle.tilt) {
1429 context.setTransform(1, Math.cos(particle.tilt.value) * particle.tilt.cosDirection, Math.sin(particle.tilt.value) * particle.tilt.sinDirection, 1, pos.x, pos.y);
1430 } else {
1431 context.translate(pos.x, pos.y);
1432 }
1433 if (angle !== 0) {
1434 context.rotate(angle);
1435 }
1436 if (backgroundMask) {
1437 context.globalCompositeOperation = composite;
1438 }
1439 drawShapeAfterEffect(container, context, particle, radius, opacity, delta);
1440 context.restore();
1441 }
1442 function drawShape(container, context, particle, radius, opacity, delta) {
1443 if (!particle.shape) {
1444 return;
1445 }
1446 const drawer = container.drawers.get(particle.shape);
1447 if (!drawer) {
1448 return;
1449 }
1450 drawer.draw(context, particle, radius, opacity, delta, container.retina.pixelRatio);
1451 }
1452 function drawShapeAfterEffect(container, context, particle, radius, opacity, delta) {
1453 if (!particle.shape) {
1454 return;
1455 }
1456 const drawer = container.drawers.get(particle.shape);
1457 if (!(drawer === null || drawer === void 0 ? void 0 : drawer.afterEffect)) {
1458 return;
1459 }
1460 drawer.afterEffect(context, particle, radius, opacity, delta, container.retina.pixelRatio);
1461 }
1462 function drawPlugin(context, plugin, delta) {
1463 if (!plugin.draw) {
1464 return;
1465 }
1466 context.save();
1467 plugin.draw(context, delta);
1468 context.restore();
1469 }
1470 function drawParticlePlugin(context, plugin, particle, delta) {
1471 if (plugin.drawParticle !== undefined) {
1472 context.save();
1473 plugin.drawParticle(context, particle, delta);
1474 context.restore();
1475 }
1476 }
1477 function drawEllipse(context, particle, fillColorValue, radius, opacity, width, rotation, start, end) {
1478 const pos = particle.getPosition();
1479 if (fillColorValue) {
1480 context.strokeStyle = getStyleFromHsl(fillColorValue, opacity);
1481 }
1482 if (width === 0) {
1483 return;
1484 }
1485 context.lineWidth = width;
1486 const rotationRadian = rotation * Math.PI / 180;
1487 context.beginPath();
1488 context.ellipse(pos.x, pos.y, radius / 2, radius * 2, rotationRadian, start, end);
1489 context.stroke();
1490 }
1491 function alterHsl(color, type, value) {
1492 return {
1493 h: color.h,
1494 s: color.s,
1495 l: color.l + (type === AlterType.darken ? -1 : 1) * value
1496 };
1497 }
1498 class Range {
1499 constructor(x, y) {
1500 this.position = {
1501 x,
1502 y
1503 };
1504 }
1505 }
1506 class Circle extends Range {
1507 constructor(x, y, radius) {
1508 super(x, y);
1509 this.radius = radius;
1510 }
1511 contains(point) {
1512 return getDistance(point, this.position) <= this.radius;
1513 }
1514 intersects(range) {
1515 const rect = range;
1516 const circle = range;
1517 const pos1 = this.position;
1518 const pos2 = range.position;
1519 const xDist = Math.abs(pos2.x - pos1.x);
1520 const yDist = Math.abs(pos2.y - pos1.y);
1521 const r = this.radius;
1522 if (circle.radius !== undefined) {
1523 const rSum = r + circle.radius;
1524 const dist = Math.sqrt(xDist * xDist + yDist + yDist);
1525 return rSum > dist;
1526 } else if (rect.size !== undefined) {
1527 const w = rect.size.width;
1528 const h = rect.size.height;
1529 const edges = Math.pow(xDist - w, 2) + Math.pow(yDist - h, 2);
1530 if (xDist > r + w || yDist > r + h) {
1531 return false;
1532 }
1533 if (xDist <= w || yDist <= h) {
1534 return true;
1535 }
1536 return edges <= r * r;
1537 }
1538 return false;
1539 }
1540 }
1541 class Rectangle extends Range {
1542 constructor(x, y, width, height) {
1543 super(x, y);
1544 this.size = {
1545 height,
1546 width
1547 };
1548 }
1549 contains(point) {
1550 const w = this.size.width;
1551 const h = this.size.height;
1552 const pos = this.position;
1553 return point.x >= pos.x && point.x <= pos.x + w && point.y >= pos.y && point.y <= pos.y + h;
1554 }
1555 intersects(range) {
1556 const rect = range;
1557 const circle = range;
1558 const w = this.size.width;
1559 const h = this.size.height;
1560 const pos1 = this.position;
1561 const pos2 = range.position;
1562 if (circle.radius !== undefined) {
1563 return circle.intersects(this);
1564 } else if (rect.size !== undefined) {
1565 const size2 = rect.size;
1566 const w2 = size2.width;
1567 const h2 = size2.height;
1568 return pos2.x < pos1.x + w && pos2.x + w2 > pos1.x && pos2.y < pos1.y + h && pos2.y + h2 > pos1.y;
1569 }
1570 return false;
1571 }
1572 }
1573 class CircleWarp extends Circle {
1574 constructor(x, y, radius, canvasSize) {
1575 super(x, y, radius);
1576 this.canvasSize = canvasSize;
1577 this.canvasSize = {
1578 height: canvasSize.height,
1579 width: canvasSize.width
1580 };
1581 }
1582 contains(point) {
1583 if (super.contains(point)) {
1584 return true;
1585 }
1586 const posNE = {
1587 x: point.x - this.canvasSize.width,
1588 y: point.y
1589 };
1590 if (super.contains(posNE)) {
1591 return true;
1592 }
1593 const posSE = {
1594 x: point.x - this.canvasSize.width,
1595 y: point.y - this.canvasSize.height
1596 };
1597 if (super.contains(posSE)) {
1598 return true;
1599 }
1600 const posSW = {
1601 x: point.x,
1602 y: point.y - this.canvasSize.height
1603 };
1604 return super.contains(posSW);
1605 }
1606 intersects(range) {
1607 if (super.intersects(range)) {
1608 return true;
1609 }
1610 const rect = range;
1611 const circle = range;
1612 const newPos = {
1613 x: range.position.x - this.canvasSize.width,
1614 y: range.position.y - this.canvasSize.height
1615 };
1616 if (circle.radius !== undefined) {
1617 const biggerCircle = new Circle(newPos.x, newPos.y, circle.radius * 2);
1618 return super.intersects(biggerCircle);
1619 } else if (rect.size !== undefined) {
1620 const rectSW = new Rectangle(newPos.x, newPos.y, rect.size.width * 2, rect.size.height * 2);
1621 return super.intersects(rectSW);
1622 }
1623 return false;
1624 }
1625 }
1626 function manageListener(element, event, handler, add, options) {
1627 if (add) {
1628 let addOptions = {
1629 passive: true
1630 };
1631 if (typeof options === "boolean") {
1632 addOptions.capture = options;
1633 } else if (options !== undefined) {
1634 addOptions = options;
1635 }
1636 element.addEventListener(event, handler, addOptions);
1637 } else {
1638 const removeOptions = options;
1639 element.removeEventListener(event, handler, removeOptions);
1640 }
1641 }
1642 class EventListeners {
1643 constructor(container) {
1644 this.container = container;
1645 this.canPush = true;
1646 this.mouseMoveHandler = e => this.mouseTouchMove(e);
1647 this.touchStartHandler = e => this.mouseTouchMove(e);
1648 this.touchMoveHandler = e => this.mouseTouchMove(e);
1649 this.touchEndHandler = () => this.mouseTouchFinish();
1650 this.mouseLeaveHandler = () => this.mouseTouchFinish();
1651 this.touchCancelHandler = () => this.mouseTouchFinish();
1652 this.touchEndClickHandler = e => this.mouseTouchClick(e);
1653 this.mouseUpHandler = e => this.mouseTouchClick(e);
1654 this.mouseDownHandler = () => this.mouseDown();
1655 this.visibilityChangeHandler = () => this.handleVisibilityChange();
1656 this.themeChangeHandler = e => this.handleThemeChange(e);
1657 this.resizeHandler = () => this.handleWindowResize();
1658 }
1659 addListeners() {
1660 this.manageListeners(true);
1661 }
1662 removeListeners() {
1663 this.manageListeners(false);
1664 }
1665 manageListeners(add) {
1666 var _a;
1667 const container = this.container;
1668 const options = container.actualOptions;
1669 const detectType = options.interactivity.detectsOn;
1670 let mouseLeaveEvent = Constants.mouseLeaveEvent;
1671 if (detectType === InteractivityDetect.window) {
1672 container.interactivity.element = window;
1673 mouseLeaveEvent = Constants.mouseOutEvent;
1674 } else if (detectType === InteractivityDetect.parent && container.canvas.element) {
1675 const canvasEl = container.canvas.element;
1676 container.interactivity.element = (_a = canvasEl.parentElement) !== null && _a !== void 0 ? _a : canvasEl.parentNode;
1677 } else {
1678 container.interactivity.element = container.canvas.element;
1679 }
1680 const mediaMatch = typeof matchMedia !== "undefined" && matchMedia("(prefers-color-scheme: dark)");
1681 if (mediaMatch) {
1682 manageListener(mediaMatch, "change", this.themeChangeHandler, add);
1683 }
1684 const interactivityEl = container.interactivity.element;
1685 if (!interactivityEl) {
1686 return;
1687 }
1688 const html = interactivityEl;
1689 if (options.interactivity.events.onHover.enable || options.interactivity.events.onClick.enable) {
1690 manageListener(interactivityEl, Constants.mouseMoveEvent, this.mouseMoveHandler, add);
1691 manageListener(interactivityEl, Constants.touchStartEvent, this.touchStartHandler, add);
1692 manageListener(interactivityEl, Constants.touchMoveEvent, this.touchMoveHandler, add);
1693 if (!options.interactivity.events.onClick.enable) {
1694 manageListener(interactivityEl, Constants.touchEndEvent, this.touchEndHandler, add);
1695 } else {
1696 manageListener(interactivityEl, Constants.touchEndEvent, this.touchEndClickHandler, add);
1697 manageListener(interactivityEl, Constants.mouseUpEvent, this.mouseUpHandler, add);
1698 manageListener(interactivityEl, Constants.mouseDownEvent, this.mouseDownHandler, add);
1699 }
1700 manageListener(interactivityEl, mouseLeaveEvent, this.mouseLeaveHandler, add);
1701 manageListener(interactivityEl, Constants.touchCancelEvent, this.touchCancelHandler, add);
1702 }
1703 if (container.canvas.element) {
1704 container.canvas.element.style.pointerEvents = html === container.canvas.element ? "initial" : "none";
1705 }
1706 if (options.interactivity.events.resize) {
1707 if (typeof ResizeObserver !== "undefined") {
1708 if (this.resizeObserver && !add) {
1709 if (container.canvas.element) {
1710 this.resizeObserver.unobserve(container.canvas.element);
1711 }
1712 this.resizeObserver.disconnect();
1713 delete this.resizeObserver;
1714 } else if (!this.resizeObserver && add && container.canvas.element) {
1715 this.resizeObserver = new ResizeObserver((entries => {
1716 const entry = entries.find((e => e.target === container.canvas.element));
1717 if (!entry) {
1718 return;
1719 }
1720 this.handleWindowResize();
1721 }));
1722 this.resizeObserver.observe(container.canvas.element);
1723 }
1724 } else {
1725 manageListener(window, Constants.resizeEvent, this.resizeHandler, add);
1726 }
1727 }
1728 if (document) {
1729 manageListener(document, Constants.visibilityChangeEvent, this.visibilityChangeHandler, add, false);
1730 }
1731 }
1732 handleWindowResize() {
1733 if (this.resizeTimeout) {
1734 clearTimeout(this.resizeTimeout);
1735 delete this.resizeTimeout;
1736 }
1737 this.resizeTimeout = setTimeout((() => {
1738 var _a;
1739 return (_a = this.container.canvas) === null || _a === void 0 ? void 0 : _a.windowResize();
1740 }), 500);
1741 }
1742 handleVisibilityChange() {
1743 const container = this.container;
1744 const options = container.actualOptions;
1745 this.mouseTouchFinish();
1746 if (!options.pauseOnBlur) {
1747 return;
1748 }
1749 if (document === null || document === void 0 ? void 0 : document.hidden) {
1750 container.pageHidden = true;
1751 container.pause();
1752 } else {
1753 container.pageHidden = false;
1754 if (container.getAnimationStatus()) {
1755 container.play(true);
1756 } else {
1757 container.draw(true);
1758 }
1759 }
1760 }
1761 mouseDown() {
1762 const interactivity = this.container.interactivity;
1763 if (interactivity) {
1764 const mouse = interactivity.mouse;
1765 mouse.clicking = true;
1766 mouse.downPosition = mouse.position;
1767 }
1768 }
1769 mouseTouchMove(e) {
1770 var _a, _b, _c, _d, _e, _f, _g;
1771 const container = this.container;
1772 const options = container.actualOptions;
1773 if (((_a = container.interactivity) === null || _a === void 0 ? void 0 : _a.element) === undefined) {
1774 return;
1775 }
1776 container.interactivity.mouse.inside = true;
1777 let pos;
1778 const canvas = container.canvas.element;
1779 if (e.type.startsWith("mouse")) {
1780 this.canPush = true;
1781 const mouseEvent = e;
1782 if (container.interactivity.element === window) {
1783 if (canvas) {
1784 const clientRect = canvas.getBoundingClientRect();
1785 pos = {
1786 x: mouseEvent.clientX - clientRect.left,
1787 y: mouseEvent.clientY - clientRect.top
1788 };
1789 }
1790 } else if (options.interactivity.detectsOn === InteractivityDetect.parent) {
1791 const source = mouseEvent.target;
1792 const target = mouseEvent.currentTarget;
1793 const canvasEl = container.canvas.element;
1794 if (source && target && canvasEl) {
1795 const sourceRect = source.getBoundingClientRect();
1796 const targetRect = target.getBoundingClientRect();
1797 const canvasRect = canvasEl.getBoundingClientRect();
1798 pos = {
1799 x: mouseEvent.offsetX + 2 * sourceRect.left - (targetRect.left + canvasRect.left),
1800 y: mouseEvent.offsetY + 2 * sourceRect.top - (targetRect.top + canvasRect.top)
1801 };
1802 } else {
1803 pos = {
1804 x: (_b = mouseEvent.offsetX) !== null && _b !== void 0 ? _b : mouseEvent.clientX,
1805 y: (_c = mouseEvent.offsetY) !== null && _c !== void 0 ? _c : mouseEvent.clientY
1806 };
1807 }
1808 } else {
1809 if (mouseEvent.target === container.canvas.element) {
1810 pos = {
1811 x: (_d = mouseEvent.offsetX) !== null && _d !== void 0 ? _d : mouseEvent.clientX,
1812 y: (_e = mouseEvent.offsetY) !== null && _e !== void 0 ? _e : mouseEvent.clientY
1813 };
1814 }
1815 }
1816 } else {
1817 this.canPush = e.type !== "touchmove";
1818 const touchEvent = e;
1819 const lastTouch = touchEvent.touches[touchEvent.touches.length - 1];
1820 const canvasRect = canvas === null || canvas === void 0 ? void 0 : canvas.getBoundingClientRect();
1821 pos = {
1822 x: lastTouch.clientX - ((_f = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.left) !== null && _f !== void 0 ? _f : 0),
1823 y: lastTouch.clientY - ((_g = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.top) !== null && _g !== void 0 ? _g : 0)
1824 };
1825 }
1826 const pxRatio = container.retina.pixelRatio;
1827 if (pos) {
1828 pos.x *= pxRatio;
1829 pos.y *= pxRatio;
1830 }
1831 container.interactivity.mouse.position = pos;
1832 container.interactivity.status = Constants.mouseMoveEvent;
1833 }
1834 mouseTouchFinish() {
1835 const interactivity = this.container.interactivity;
1836 if (interactivity === undefined) {
1837 return;
1838 }
1839 const mouse = interactivity.mouse;
1840 delete mouse.position;
1841 delete mouse.clickPosition;
1842 delete mouse.downPosition;
1843 interactivity.status = Constants.mouseLeaveEvent;
1844 mouse.inside = false;
1845 mouse.clicking = false;
1846 }
1847 mouseTouchClick(e) {
1848 const container = this.container;
1849 const options = container.actualOptions;
1850 const mouse = container.interactivity.mouse;
1851 mouse.inside = true;
1852 let handled = false;
1853 const mousePosition = mouse.position;
1854 if (mousePosition === undefined || !options.interactivity.events.onClick.enable) {
1855 return;
1856 }
1857 for (const [, plugin] of container.plugins) {
1858 if (plugin.clickPositionValid !== undefined) {
1859 handled = plugin.clickPositionValid(mousePosition);
1860 if (handled) {
1861 break;
1862 }
1863 }
1864 }
1865 if (!handled) {
1866 this.doMouseTouchClick(e);
1867 }
1868 mouse.clicking = false;
1869 }
1870 doMouseTouchClick(e) {
1871 const container = this.container;
1872 const options = container.actualOptions;
1873 if (this.canPush) {
1874 const mousePos = container.interactivity.mouse.position;
1875 if (mousePos) {
1876 container.interactivity.mouse.clickPosition = {
1877 x: mousePos.x,
1878 y: mousePos.y
1879 };
1880 } else {
1881 return;
1882 }
1883 container.interactivity.mouse.clickTime = (new Date).getTime();
1884 const onClick = options.interactivity.events.onClick;
1885 if (onClick.mode instanceof Array) {
1886 for (const mode of onClick.mode) {
1887 this.handleClickMode(mode);
1888 }
1889 } else {
1890 this.handleClickMode(onClick.mode);
1891 }
1892 }
1893 if (e.type === "touchend") {
1894 setTimeout((() => this.mouseTouchFinish()), 500);
1895 }
1896 }
1897 handleThemeChange(e) {
1898 const mediaEvent = e;
1899 const themeName = mediaEvent.matches ? this.container.options.defaultDarkTheme : this.container.options.defaultLightTheme;
1900 const theme = this.container.options.themes.find((theme => theme.name === themeName));
1901 if (theme && theme.default.auto) {
1902 this.container.loadTheme(themeName);
1903 }
1904 }
1905 handleClickMode(mode) {
1906 const container = this.container;
1907 const options = container.actualOptions;
1908 const pushNb = options.interactivity.modes.push.quantity;
1909 const removeNb = options.interactivity.modes.remove.quantity;
1910 switch (mode) {
1911 case ClickMode.push:
1912 {
1913 if (pushNb > 0) {
1914 const pushOptions = options.interactivity.modes.push;
1915 const group = itemFromArray([ undefined, ...pushOptions.groups ]);
1916 const groupOptions = group !== undefined ? container.actualOptions.particles.groups[group] : undefined;
1917 container.particles.push(pushNb, container.interactivity.mouse, groupOptions, group);
1918 }
1919 break;
1920 }
1921
1922 case ClickMode.remove:
1923 container.particles.removeQuantity(removeNb);
1924 break;
1925
1926 case ClickMode.bubble:
1927 container.bubble.clicking = true;
1928 break;
1929
1930 case ClickMode.repulse:
1931 container.repulse.clicking = true;
1932 container.repulse.count = 0;
1933 for (const particle of container.repulse.particles) {
1934 particle.velocity.setTo(particle.initialVelocity);
1935 }
1936 container.repulse.particles = [];
1937 container.repulse.finish = false;
1938 setTimeout((() => {
1939 if (!container.destroyed) {
1940 container.repulse.clicking = false;
1941 }
1942 }), options.interactivity.modes.repulse.duration * 1e3);
1943 break;
1944
1945 case ClickMode.attract:
1946 container.attract.clicking = true;
1947 container.attract.count = 0;
1948 for (const particle of container.attract.particles) {
1949 particle.velocity.setTo(particle.initialVelocity);
1950 }
1951 container.attract.particles = [];
1952 container.attract.finish = false;
1953 setTimeout((() => {
1954 if (!container.destroyed) {
1955 container.attract.clicking = false;
1956 }
1957 }), options.interactivity.modes.attract.duration * 1e3);
1958 break;
1959
1960 case ClickMode.pause:
1961 if (container.getAnimationStatus()) {
1962 container.pause();
1963 } else {
1964 container.play();
1965 }
1966 break;
1967 }
1968 for (const [, plugin] of container.plugins) {
1969 if (plugin.handleClickMode) {
1970 plugin.handleClickMode(mode);
1971 }
1972 }
1973 }
1974 }
1975 const plugins = [];
1976 const interactorsInitializers = new Map;
1977 const updatersInitializers = new Map;
1978 const interactors = new Map;
1979 const updaters = new Map;
1980 const presets = new Map;
1981 const drawers = new Map;
1982 const pathGenerators = new Map;
1983 class Plugins {
1984 static getPlugin(plugin) {
1985 return plugins.find((t => t.id === plugin));
1986 }
1987 static addPlugin(plugin) {
1988 if (!Plugins.getPlugin(plugin.id)) {
1989 plugins.push(plugin);
1990 }
1991 }
1992 static getAvailablePlugins(container) {
1993 const res = new Map;
1994 for (const plugin of plugins) {
1995 if (!plugin.needsPlugin(container.actualOptions)) {
1996 continue;
1997 }
1998 res.set(plugin.id, plugin.getPlugin(container));
1999 }
2000 return res;
2001 }
2002 static loadOptions(options, sourceOptions) {
2003 for (const plugin of plugins) {
2004 plugin.loadOptions(options, sourceOptions);
2005 }
2006 }
2007 static getPreset(preset) {
2008 return presets.get(preset);
2009 }
2010 static addPreset(presetKey, options, override = false) {
2011 if (override || !Plugins.getPreset(presetKey)) {
2012 presets.set(presetKey, options);
2013 }
2014 }
2015 static addShapeDrawer(type, drawer) {
2016 if (!Plugins.getShapeDrawer(type)) {
2017 drawers.set(type, drawer);
2018 }
2019 }
2020 static getShapeDrawer(type) {
2021 return drawers.get(type);
2022 }
2023 static getSupportedShapes() {
2024 return drawers.keys();
2025 }
2026 static getPathGenerator(type) {
2027 return pathGenerators.get(type);
2028 }
2029 static addPathGenerator(type, pathGenerator) {
2030 if (!Plugins.getPathGenerator(type)) {
2031 pathGenerators.set(type, pathGenerator);
2032 }
2033 }
2034 static getInteractors(container) {
2035 let res = interactors.get(container);
2036 if (!res) {
2037 res = [ ...interactorsInitializers.values() ].map((t => t(container)));
2038 interactors.set(container, res);
2039 }
2040 return res;
2041 }
2042 static addInteractor(name, initInteractor) {
2043 interactorsInitializers.set(name, initInteractor);
2044 }
2045 static getUpdaters(container) {
2046 let res = updaters.get(container);
2047 if (!res) {
2048 res = [ ...updatersInitializers.values() ].map((t => t(container)));
2049 updaters.set(container, res);
2050 }
2051 return res;
2052 }
2053 static addParticleUpdater(name, initUpdater) {
2054 updatersInitializers.set(name, initUpdater);
2055 }
2056 }
2057 class Point {
2058 constructor(position, particle) {
2059 this.position = position;
2060 this.particle = particle;
2061 }
2062 }
2063 class QuadTree {
2064 constructor(rectangle, capacity) {
2065 this.rectangle = rectangle;
2066 this.capacity = capacity;
2067 this.points = [];
2068 this.divided = false;
2069 }
2070 subdivide() {
2071 const x = this.rectangle.position.x;
2072 const y = this.rectangle.position.y;
2073 const w = this.rectangle.size.width;
2074 const h = this.rectangle.size.height;
2075 const capacity = this.capacity;
2076 this.northEast = new QuadTree(new Rectangle(x, y, w / 2, h / 2), capacity);
2077 this.northWest = new QuadTree(new Rectangle(x + w / 2, y, w / 2, h / 2), capacity);
2078 this.southEast = new QuadTree(new Rectangle(x, y + h / 2, w / 2, h / 2), capacity);
2079 this.southWest = new QuadTree(new Rectangle(x + w / 2, y + h / 2, w / 2, h / 2), capacity);
2080 this.divided = true;
2081 }
2082 insert(point) {
2083 var _a, _b, _c, _d, _e;
2084 if (!this.rectangle.contains(point.position)) {
2085 return false;
2086 }
2087 if (this.points.length < this.capacity) {
2088 this.points.push(point);
2089 return true;
2090 }
2091 if (!this.divided) {
2092 this.subdivide();
2093 }
2094 return (_e = ((_a = this.northEast) === null || _a === void 0 ? void 0 : _a.insert(point)) || ((_b = this.northWest) === null || _b === void 0 ? void 0 : _b.insert(point)) || ((_c = this.southEast) === null || _c === void 0 ? void 0 : _c.insert(point)) || ((_d = this.southWest) === null || _d === void 0 ? void 0 : _d.insert(point))) !== null && _e !== void 0 ? _e : false;
2095 }
2096 queryCircle(position, radius) {
2097 return this.query(new Circle(position.x, position.y, radius));
2098 }
2099 queryCircleWarp(position, radius, containerOrSize) {
2100 const container = containerOrSize;
2101 const size = containerOrSize;
2102 return this.query(new CircleWarp(position.x, position.y, radius, container.canvas !== undefined ? container.canvas.size : size));
2103 }
2104 queryRectangle(position, size) {
2105 return this.query(new Rectangle(position.x, position.y, size.width, size.height));
2106 }
2107 query(range, found) {
2108 var _a, _b, _c, _d;
2109 const res = found !== null && found !== void 0 ? found : [];
2110 if (!range.intersects(this.rectangle)) {
2111 return [];
2112 } else {
2113 for (const p of this.points) {
2114 if (!range.contains(p.position) && getDistance(range.position, p.position) > p.particle.getRadius()) {
2115 continue;
2116 }
2117 res.push(p.particle);
2118 }
2119 if (this.divided) {
2120 (_a = this.northEast) === null || _a === void 0 ? void 0 : _a.query(range, res);
2121 (_b = this.northWest) === null || _b === void 0 ? void 0 : _b.query(range, res);
2122 (_c = this.southEast) === null || _c === void 0 ? void 0 : _c.query(range, res);
2123 (_d = this.southWest) === null || _d === void 0 ? void 0 : _d.query(range, res);
2124 }
2125 }
2126 return res;
2127 }
2128 }
2129 class Canvas {
2130 constructor(container) {
2131 this.container = container;
2132 this.size = {
2133 height: 0,
2134 width: 0
2135 };
2136 this.context = null;
2137 this.generatedCanvas = false;
2138 }
2139 init() {
2140 this.resize();
2141 this.initStyle();
2142 this.initCover();
2143 this.initTrail();
2144 this.initBackground();
2145 this.paint();
2146 }
2147 loadCanvas(canvas, generatedCanvas) {
2148 var _a;
2149 if (!canvas.className) {
2150 canvas.className = Constants.canvasClass;
2151 }
2152 if (this.generatedCanvas) {
2153 (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove();
2154 }
2155 this.generatedCanvas = generatedCanvas !== null && generatedCanvas !== void 0 ? generatedCanvas : this.generatedCanvas;
2156 this.element = canvas;
2157 this.originalStyle = deepExtend({}, this.element.style);
2158 this.size.height = canvas.offsetHeight;
2159 this.size.width = canvas.offsetWidth;
2160 this.context = this.element.getContext("2d");
2161 this.container.retina.init();
2162 this.initBackground();
2163 }
2164 destroy() {
2165 var _a;
2166 if (this.generatedCanvas) {
2167 (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove();
2168 }
2169 this.draw((ctx => {
2170 clear(ctx, this.size);
2171 }));
2172 }
2173 paint() {
2174 const options = this.container.actualOptions;
2175 this.draw((ctx => {
2176 if (options.backgroundMask.enable && options.backgroundMask.cover && this.coverColor) {
2177 clear(ctx, this.size);
2178 this.paintBase(getStyleFromRgb(this.coverColor, this.coverColor.a));
2179 } else {
2180 this.paintBase();
2181 }
2182 }));
2183 }
2184 clear() {
2185 const options = this.container.actualOptions;
2186 const trail = options.particles.move.trail;
2187 if (options.backgroundMask.enable) {
2188 this.paint();
2189 } else if (trail.enable && trail.length > 0 && this.trailFillColor) {
2190 this.paintBase(getStyleFromRgb(this.trailFillColor, 1 / trail.length));
2191 } else {
2192 this.draw((ctx => {
2193 clear(ctx, this.size);
2194 }));
2195 }
2196 }
2197 windowResize() {
2198 if (!this.element) {
2199 return;
2200 }
2201 const container = this.container;
2202 this.resize();
2203 const needsRefresh = container.updateActualOptions();
2204 container.particles.setDensity();
2205 for (const [, plugin] of container.plugins) {
2206 if (plugin.resize !== undefined) {
2207 plugin.resize();
2208 }
2209 }
2210 if (needsRefresh) {
2211 container.refresh();
2212 }
2213 }
2214 resize() {
2215 if (!this.element) {
2216 return;
2217 }
2218 const container = this.container;
2219 const pxRatio = container.retina.pixelRatio;
2220 const size = container.canvas.size;
2221 const oldSize = {
2222 width: size.width,
2223 height: size.height
2224 };
2225 size.width = this.element.offsetWidth * pxRatio;
2226 size.height = this.element.offsetHeight * pxRatio;
2227 this.element.width = size.width;
2228 this.element.height = size.height;
2229 if (this.container.started) {
2230 this.resizeFactor = {
2231 width: size.width / oldSize.width,
2232 height: size.height / oldSize.height
2233 };
2234 }
2235 }
2236 drawConnectLine(p1, p2) {
2237 this.draw((ctx => {
2238 var _a;
2239 const lineStyle = this.lineStyle(p1, p2);
2240 if (!lineStyle) {
2241 return;
2242 }
2243 const pos1 = p1.getPosition();
2244 const pos2 = p2.getPosition();
2245 drawConnectLine(ctx, (_a = p1.retina.linksWidth) !== null && _a !== void 0 ? _a : this.container.retina.linksWidth, lineStyle, pos1, pos2);
2246 }));
2247 }
2248 drawGrabLine(particle, lineColor, opacity, mousePos) {
2249 const container = this.container;
2250 this.draw((ctx => {
2251 var _a;
2252 const beginPos = particle.getPosition();
2253 drawGrabLine(ctx, (_a = particle.retina.linksWidth) !== null && _a !== void 0 ? _a : container.retina.linksWidth, beginPos, mousePos, lineColor, opacity);
2254 }));
2255 }
2256 drawParticle(particle, delta) {
2257 var _a, _b, _c, _d, _e, _f;
2258 if (particle.spawning || particle.destroyed) {
2259 return;
2260 }
2261 const pfColor = particle.getFillColor();
2262 const psColor = (_a = particle.getStrokeColor()) !== null && _a !== void 0 ? _a : pfColor;
2263 if (!pfColor && !psColor) {
2264 return;
2265 }
2266 let [fColor, sColor] = this.getPluginParticleColors(particle);
2267 const pOptions = particle.options;
2268 const twinkle = pOptions.twinkle.particles;
2269 const twinkling = twinkle.enable && Math.random() < twinkle.frequency;
2270 if (!fColor || !sColor) {
2271 const twinkleRgb = colorToHsl(twinkle.color);
2272 if (!fColor) {
2273 fColor = twinkling && twinkleRgb !== undefined ? twinkleRgb : pfColor ? pfColor : undefined;
2274 }
2275 if (!sColor) {
2276 sColor = twinkling && twinkleRgb !== undefined ? twinkleRgb : psColor ? psColor : undefined;
2277 }
2278 }
2279 const options = this.container.actualOptions;
2280 const zIndexOptions = particle.options.zIndex;
2281 const zOpacityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.opacityRate;
2282 const radius = particle.getRadius();
2283 const opacity = twinkling ? twinkle.opacity : (_d = (_b = particle.bubble.opacity) !== null && _b !== void 0 ? _b : (_c = particle.opacity) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : 1;
2284 const strokeOpacity = (_f = (_e = particle.stroke) === null || _e === void 0 ? void 0 : _e.opacity) !== null && _f !== void 0 ? _f : opacity;
2285 const zOpacity = opacity * zOpacityFactor;
2286 const fillColorValue = fColor ? getStyleFromHsl(fColor, zOpacity) : undefined;
2287 if (!fillColorValue && !sColor) {
2288 return;
2289 }
2290 this.draw((ctx => {
2291 const zSizeFactor = (1 - particle.zIndexFactor) ** zIndexOptions.sizeRate;
2292 const zStrokeOpacity = strokeOpacity * zOpacityFactor;
2293 const strokeColorValue = sColor ? getStyleFromHsl(sColor, zStrokeOpacity) : fillColorValue;
2294 if (radius <= 0) {
2295 return;
2296 }
2297 const container = this.container;
2298 for (const updater of container.particles.updaters) {
2299 if (updater.beforeDraw) {
2300 updater.beforeDraw(particle);
2301 }
2302 }
2303 drawParticle(this.container, ctx, particle, delta, fillColorValue, strokeColorValue, options.backgroundMask.enable, options.backgroundMask.composite, radius * zSizeFactor, zOpacity, particle.options.shadow, particle.gradient);
2304 for (const updater of container.particles.updaters) {
2305 if (updater.afterDraw) {
2306 updater.afterDraw(particle);
2307 }
2308 }
2309 }));
2310 }
2311 drawPlugin(plugin, delta) {
2312 this.draw((ctx => {
2313 drawPlugin(ctx, plugin, delta);
2314 }));
2315 }
2316 drawParticlePlugin(plugin, particle, delta) {
2317 this.draw((ctx => {
2318 drawParticlePlugin(ctx, plugin, particle, delta);
2319 }));
2320 }
2321 initBackground() {
2322 const options = this.container.actualOptions;
2323 const background = options.background;
2324 const element = this.element;
2325 const elementStyle = element === null || element === void 0 ? void 0 : element.style;
2326 if (!elementStyle) {
2327 return;
2328 }
2329 if (background.color) {
2330 const color = colorToRgb(background.color);
2331 elementStyle.backgroundColor = color ? getStyleFromRgb(color, background.opacity) : "";
2332 } else {
2333 elementStyle.backgroundColor = "";
2334 }
2335 elementStyle.backgroundImage = background.image || "";
2336 elementStyle.backgroundPosition = background.position || "";
2337 elementStyle.backgroundRepeat = background.repeat || "";
2338 elementStyle.backgroundSize = background.size || "";
2339 }
2340 draw(cb) {
2341 if (!this.context) {
2342 return;
2343 }
2344 return cb(this.context);
2345 }
2346 initCover() {
2347 const options = this.container.actualOptions;
2348 const cover = options.backgroundMask.cover;
2349 const color = cover.color;
2350 const coverRgb = colorToRgb(color);
2351 if (coverRgb) {
2352 this.coverColor = {
2353 r: coverRgb.r,
2354 g: coverRgb.g,
2355 b: coverRgb.b,
2356 a: cover.opacity
2357 };
2358 }
2359 }
2360 initTrail() {
2361 const options = this.container.actualOptions;
2362 const trail = options.particles.move.trail;
2363 const fillColor = colorToRgb(trail.fillColor);
2364 if (fillColor) {
2365 const trail = options.particles.move.trail;
2366 this.trailFillColor = {
2367 r: fillColor.r,
2368 g: fillColor.g,
2369 b: fillColor.b,
2370 a: 1 / trail.length
2371 };
2372 }
2373 }
2374 getPluginParticleColors(particle) {
2375 let fColor;
2376 let sColor;
2377 for (const [, plugin] of this.container.plugins) {
2378 if (!fColor && plugin.particleFillColor) {
2379 fColor = colorToHsl(plugin.particleFillColor(particle));
2380 }
2381 if (!sColor && plugin.particleStrokeColor) {
2382 sColor = colorToHsl(plugin.particleStrokeColor(particle));
2383 }
2384 if (fColor && sColor) {
2385 break;
2386 }
2387 }
2388 return [ fColor, sColor ];
2389 }
2390 initStyle() {
2391 const element = this.element, options = this.container.actualOptions;
2392 if (!element) {
2393 return;
2394 }
2395 const originalStyle = this.originalStyle;
2396 if (options.fullScreen.enable) {
2397 this.originalStyle = deepExtend({}, element.style);
2398 element.style.position = "fixed";
2399 element.style.zIndex = options.fullScreen.zIndex.toString(10);
2400 element.style.top = "0";
2401 element.style.left = "0";
2402 element.style.width = "100%";
2403 element.style.height = "100%";
2404 } else if (originalStyle) {
2405 element.style.position = originalStyle.position;
2406 element.style.zIndex = originalStyle.zIndex;
2407 element.style.top = originalStyle.top;
2408 element.style.left = originalStyle.left;
2409 element.style.width = originalStyle.width;
2410 element.style.height = originalStyle.height;
2411 }
2412 }
2413 paintBase(baseColor) {
2414 this.draw((ctx => {
2415 paintBase(ctx, this.size, baseColor);
2416 }));
2417 }
2418 lineStyle(p1, p2) {
2419 return this.draw((ctx => {
2420 const options = this.container.actualOptions;
2421 const connectOptions = options.interactivity.modes.connect;
2422 return gradient(ctx, p1, p2, connectOptions.links.opacity);
2423 }));
2424 }
2425 }
2426 class OptionsColor {
2427 constructor() {
2428 this.value = "#fff";
2429 }
2430 static create(source, data) {
2431 const color = new OptionsColor;
2432 color.load(source);
2433 if (data !== undefined) {
2434 if (typeof data === "string" || data instanceof Array) {
2435 color.load({
2436 value: data
2437 });
2438 } else {
2439 color.load(data);
2440 }
2441 }
2442 return color;
2443 }
2444 load(data) {
2445 if ((data === null || data === void 0 ? void 0 : data.value) === undefined) {
2446 return;
2447 }
2448 this.value = data.value;
2449 }
2450 }
2451 class LinksShadow {
2452 constructor() {
2453 this.blur = 5;
2454 this.color = new OptionsColor;
2455 this.enable = false;
2456 this.color.value = "#00ff00";
2457 }
2458 load(data) {
2459 if (data === undefined) {
2460 return;
2461 }
2462 if (data.blur !== undefined) {
2463 this.blur = data.blur;
2464 }
2465 this.color = OptionsColor.create(this.color, data.color);
2466 if (data.enable !== undefined) {
2467 this.enable = data.enable;
2468 }
2469 }
2470 }
2471 class LinksTriangle {
2472 constructor() {
2473 this.enable = false;
2474 this.frequency = 1;
2475 }
2476 load(data) {
2477 if (data === undefined) {
2478 return;
2479 }
2480 if (data.color !== undefined) {
2481 this.color = OptionsColor.create(this.color, data.color);
2482 }
2483 if (data.enable !== undefined) {
2484 this.enable = data.enable;
2485 }
2486 if (data.frequency !== undefined) {
2487 this.frequency = data.frequency;
2488 }
2489 if (data.opacity !== undefined) {
2490 this.opacity = data.opacity;
2491 }
2492 }
2493 }
2494 class Links {
2495 constructor() {
2496 this.blink = false;
2497 this.color = new OptionsColor;
2498 this.consent = false;
2499 this.distance = 100;
2500 this.enable = false;
2501 this.frequency = 1;
2502 this.opacity = 1;
2503 this.shadow = new LinksShadow;
2504 this.triangles = new LinksTriangle;
2505 this.width = 1;
2506 this.warp = false;
2507 }
2508 load(data) {
2509 if (data === undefined) {
2510 return;
2511 }
2512 if (data.id !== undefined) {
2513 this.id = data.id;
2514 }
2515 if (data.blink !== undefined) {
2516 this.blink = data.blink;
2517 }
2518 this.color = OptionsColor.create(this.color, data.color);
2519 if (data.consent !== undefined) {
2520 this.consent = data.consent;
2521 }
2522 if (data.distance !== undefined) {
2523 this.distance = data.distance;
2524 }
2525 if (data.enable !== undefined) {
2526 this.enable = data.enable;
2527 }
2528 if (data.frequency !== undefined) {
2529 this.frequency = data.frequency;
2530 }
2531 if (data.opacity !== undefined) {
2532 this.opacity = data.opacity;
2533 }
2534 this.shadow.load(data.shadow);
2535 this.triangles.load(data.triangles);
2536 if (data.width !== undefined) {
2537 this.width = data.width;
2538 }
2539 if (data.warp !== undefined) {
2540 this.warp = data.warp;
2541 }
2542 }
2543 }
2544 class Attract {
2545 constructor() {
2546 this.distance = 200;
2547 this.enable = false;
2548 this.rotate = {
2549 x: 3e3,
2550 y: 3e3
2551 };
2552 }
2553 get rotateX() {
2554 return this.rotate.x;
2555 }
2556 set rotateX(value) {
2557 this.rotate.x = value;
2558 }
2559 get rotateY() {
2560 return this.rotate.y;
2561 }
2562 set rotateY(value) {
2563 this.rotate.y = value;
2564 }
2565 load(data) {
2566 var _a, _b, _c, _d;
2567 if (!data) {
2568 return;
2569 }
2570 if (data.distance !== undefined) {
2571 this.distance = data.distance;
2572 }
2573 if (data.enable !== undefined) {
2574 this.enable = data.enable;
2575 }
2576 const rotateX = (_b = (_a = data.rotate) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : data.rotateX;
2577 if (rotateX !== undefined) {
2578 this.rotate.x = rotateX;
2579 }
2580 const rotateY = (_d = (_c = data.rotate) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : data.rotateY;
2581 if (rotateY !== undefined) {
2582 this.rotate.y = rotateY;
2583 }
2584 }
2585 }
2586 class Trail {
2587 constructor() {
2588 this.enable = false;
2589 this.length = 10;
2590 this.fillColor = new OptionsColor;
2591 this.fillColor.value = "#000000";
2592 }
2593 load(data) {
2594 if (data === undefined) {
2595 return;
2596 }
2597 if (data.enable !== undefined) {
2598 this.enable = data.enable;
2599 }
2600 this.fillColor = OptionsColor.create(this.fillColor, data.fillColor);
2601 if (data.length !== undefined) {
2602 this.length = data.length;
2603 }
2604 }
2605 }
2606 class Random {
2607 constructor() {
2608 this.enable = false;
2609 this.minimumValue = 0;
2610 }
2611 load(data) {
2612 if (!data) {
2613 return;
2614 }
2615 if (data.enable !== undefined) {
2616 this.enable = data.enable;
2617 }
2618 if (data.minimumValue !== undefined) {
2619 this.minimumValue = data.minimumValue;
2620 }
2621 }
2622 }
2623 class ValueWithRandom {
2624 constructor() {
2625 this.random = new Random;
2626 this.value = 0;
2627 }
2628 load(data) {
2629 if (!data) {
2630 return;
2631 }
2632 if (typeof data.random === "boolean") {
2633 this.random.enable = data.random;
2634 } else {
2635 this.random.load(data.random);
2636 }
2637 if (data.value !== undefined) {
2638 this.value = setRangeValue(data.value, this.random.enable ? this.random.minimumValue : undefined);
2639 }
2640 }
2641 }
2642 class PathDelay extends ValueWithRandom {
2643 constructor() {
2644 super();
2645 }
2646 }
2647 class Path {
2648 constructor() {
2649 this.clamp = true;
2650 this.delay = new PathDelay;
2651 this.enable = false;
2652 this.options = {};
2653 }
2654 load(data) {
2655 if (data === undefined) {
2656 return;
2657 }
2658 if (data.clamp !== undefined) {
2659 this.clamp = data.clamp;
2660 }
2661 this.delay.load(data.delay);
2662 if (data.enable !== undefined) {
2663 this.enable = data.enable;
2664 }
2665 this.generator = data.generator;
2666 if (data.options) {
2667 this.options = deepExtend(this.options, data.options);
2668 }
2669 }
2670 }
2671 class MoveAngle {
2672 constructor() {
2673 this.offset = 0;
2674 this.value = 90;
2675 }
2676 load(data) {
2677 if (data === undefined) {
2678 return;
2679 }
2680 if (data.offset !== undefined) {
2681 this.offset = data.offset;
2682 }
2683 if (data.value !== undefined) {
2684 this.value = data.value;
2685 }
2686 }
2687 }
2688 class MoveGravity {
2689 constructor() {
2690 this.acceleration = 9.81;
2691 this.enable = false;
2692 this.inverse = false;
2693 this.maxSpeed = 50;
2694 }
2695 load(data) {
2696 if (!data) {
2697 return;
2698 }
2699 if (data.acceleration !== undefined) {
2700 this.acceleration = data.acceleration;
2701 }
2702 if (data.enable !== undefined) {
2703 this.enable = data.enable;
2704 }
2705 if (data.inverse !== undefined) {
2706 this.inverse = data.inverse;
2707 }
2708 if (data.maxSpeed !== undefined) {
2709 this.maxSpeed = data.maxSpeed;
2710 }
2711 }
2712 }
2713 class OutModes {
2714 constructor() {
2715 this.default = OutMode.out;
2716 }
2717 load(data) {
2718 var _a, _b, _c, _d;
2719 if (!data) {
2720 return;
2721 }
2722 if (data.default !== undefined) {
2723 this.default = data.default;
2724 }
2725 this.bottom = (_a = data.bottom) !== null && _a !== void 0 ? _a : data.default;
2726 this.left = (_b = data.left) !== null && _b !== void 0 ? _b : data.default;
2727 this.right = (_c = data.right) !== null && _c !== void 0 ? _c : data.default;
2728 this.top = (_d = data.top) !== null && _d !== void 0 ? _d : data.default;
2729 }
2730 }
2731 class Spin {
2732 constructor() {
2733 this.acceleration = 0;
2734 this.enable = false;
2735 }
2736 load(data) {
2737 if (!data) {
2738 return;
2739 }
2740 if (data.acceleration !== undefined) {
2741 this.acceleration = setRangeValue(data.acceleration);
2742 }
2743 if (data.enable !== undefined) {
2744 this.enable = data.enable;
2745 }
2746 this.position = data.position ? deepExtend({}, data.position) : undefined;
2747 }
2748 }
2749 class Move {
2750 constructor() {
2751 this.angle = new MoveAngle;
2752 this.attract = new Attract;
2753 this.decay = 0;
2754 this.distance = {};
2755 this.direction = MoveDirection.none;
2756 this.drift = 0;
2757 this.enable = false;
2758 this.gravity = new MoveGravity;
2759 this.path = new Path;
2760 this.outModes = new OutModes;
2761 this.random = false;
2762 this.size = false;
2763 this.speed = 2;
2764 this.spin = new Spin;
2765 this.straight = false;
2766 this.trail = new Trail;
2767 this.vibrate = false;
2768 this.warp = false;
2769 }
2770 get collisions() {
2771 return false;
2772 }
2773 set collisions(value) {}
2774 get bounce() {
2775 return this.collisions;
2776 }
2777 set bounce(value) {
2778 this.collisions = value;
2779 }
2780 get out_mode() {
2781 return this.outMode;
2782 }
2783 set out_mode(value) {
2784 this.outMode = value;
2785 }
2786 get outMode() {
2787 return this.outModes.default;
2788 }
2789 set outMode(value) {
2790 this.outModes.default = value;
2791 }
2792 get noise() {
2793 return this.path;
2794 }
2795 set noise(value) {
2796 this.path = value;
2797 }
2798 load(data) {
2799 var _a, _b, _c;
2800 if (data === undefined) {
2801 return;
2802 }
2803 if (data.angle !== undefined) {
2804 if (typeof data.angle === "number") {
2805 this.angle.value = data.angle;
2806 } else {
2807 this.angle.load(data.angle);
2808 }
2809 }
2810 this.attract.load(data.attract);
2811 if (data.decay !== undefined) {
2812 this.decay = data.decay;
2813 }
2814 if (data.direction !== undefined) {
2815 this.direction = data.direction;
2816 }
2817 if (data.distance !== undefined) {
2818 this.distance = typeof data.distance === "number" ? {
2819 horizontal: data.distance,
2820 vertical: data.distance
2821 } : deepExtend({}, data.distance);
2822 }
2823 if (data.drift !== undefined) {
2824 this.drift = setRangeValue(data.drift);
2825 }
2826 if (data.enable !== undefined) {
2827 this.enable = data.enable;
2828 }
2829 this.gravity.load(data.gravity);
2830 const outMode = (_a = data.outMode) !== null && _a !== void 0 ? _a : data.out_mode;
2831 if (data.outModes !== undefined || outMode !== undefined) {
2832 if (typeof data.outModes === "string" || data.outModes === undefined && outMode !== undefined) {
2833 this.outModes.load({
2834 default: (_b = data.outModes) !== null && _b !== void 0 ? _b : outMode
2835 });
2836 } else {
2837 this.outModes.load(data.outModes);
2838 }
2839 }
2840 this.path.load((_c = data.path) !== null && _c !== void 0 ? _c : data.noise);
2841 if (data.random !== undefined) {
2842 this.random = data.random;
2843 }
2844 if (data.size !== undefined) {
2845 this.size = data.size;
2846 }
2847 if (data.speed !== undefined) {
2848 this.speed = setRangeValue(data.speed);
2849 }
2850 this.spin.load(data.spin);
2851 if (data.straight !== undefined) {
2852 this.straight = data.straight;
2853 }
2854 this.trail.load(data.trail);
2855 if (data.vibrate !== undefined) {
2856 this.vibrate = data.vibrate;
2857 }
2858 if (data.warp !== undefined) {
2859 this.warp = data.warp;
2860 }
2861 }
2862 }
2863 class Density {
2864 constructor() {
2865 this.enable = false;
2866 this.area = 800;
2867 this.factor = 1e3;
2868 }
2869 get value_area() {
2870 return this.area;
2871 }
2872 set value_area(value) {
2873 this.area = value;
2874 }
2875 load(data) {
2876 var _a;
2877 if (data === undefined) {
2878 return;
2879 }
2880 if (data.enable !== undefined) {
2881 this.enable = data.enable;
2882 }
2883 const area = (_a = data.area) !== null && _a !== void 0 ? _a : data.value_area;
2884 if (area !== undefined) {
2885 this.area = area;
2886 }
2887 if (data.factor !== undefined) {
2888 this.factor = data.factor;
2889 }
2890 }
2891 }
2892 class ParticlesNumber {
2893 constructor() {
2894 this.density = new Density;
2895 this.limit = 0;
2896 this.value = 100;
2897 }
2898 get max() {
2899 return this.limit;
2900 }
2901 set max(value) {
2902 this.limit = value;
2903 }
2904 load(data) {
2905 var _a;
2906 if (data === undefined) {
2907 return;
2908 }
2909 this.density.load(data.density);
2910 const limit = (_a = data.limit) !== null && _a !== void 0 ? _a : data.max;
2911 if (limit !== undefined) {
2912 this.limit = limit;
2913 }
2914 if (data.value !== undefined) {
2915 this.value = data.value;
2916 }
2917 }
2918 }
2919 class AnimationOptions {
2920 constructor() {
2921 this.count = 0;
2922 this.enable = false;
2923 this.speed = 1;
2924 this.sync = false;
2925 }
2926 load(data) {
2927 if (!data) {
2928 return;
2929 }
2930 if (data.count !== undefined) {
2931 this.count = data.count;
2932 }
2933 if (data.enable !== undefined) {
2934 this.enable = data.enable;
2935 }
2936 if (data.speed !== undefined) {
2937 this.speed = data.speed;
2938 }
2939 if (data.sync !== undefined) {
2940 this.sync = data.sync;
2941 }
2942 }
2943 }
2944 class OpacityAnimation extends AnimationOptions {
2945 constructor() {
2946 super();
2947 this.destroy = DestroyType.none;
2948 this.enable = false;
2949 this.speed = 2;
2950 this.startValue = StartValueType.random;
2951 this.sync = false;
2952 }
2953 get opacity_min() {
2954 return this.minimumValue;
2955 }
2956 set opacity_min(value) {
2957 this.minimumValue = value;
2958 }
2959 load(data) {
2960 var _a;
2961 if (data === undefined) {
2962 return;
2963 }
2964 super.load(data);
2965 if (data.destroy !== undefined) {
2966 this.destroy = data.destroy;
2967 }
2968 if (data.enable !== undefined) {
2969 this.enable = data.enable;
2970 }
2971 this.minimumValue = (_a = data.minimumValue) !== null && _a !== void 0 ? _a : data.opacity_min;
2972 if (data.speed !== undefined) {
2973 this.speed = data.speed;
2974 }
2975 if (data.startValue !== undefined) {
2976 this.startValue = data.startValue;
2977 }
2978 if (data.sync !== undefined) {
2979 this.sync = data.sync;
2980 }
2981 }
2982 }
2983 class Opacity extends ValueWithRandom {
2984 constructor() {
2985 super();
2986 this.animation = new OpacityAnimation;
2987 this.random.minimumValue = .1;
2988 this.value = 1;
2989 }
2990 get anim() {
2991 return this.animation;
2992 }
2993 set anim(value) {
2994 this.animation = value;
2995 }
2996 load(data) {
2997 var _a;
2998 if (!data) {
2999 return;
3000 }
3001 super.load(data);
3002 const animation = (_a = data.animation) !== null && _a !== void 0 ? _a : data.anim;
3003 if (animation !== undefined) {
3004 this.animation.load(animation);
3005 this.value = setRangeValue(this.value, this.animation.enable ? this.animation.minimumValue : undefined);
3006 }
3007 }
3008 }
3009 class Shape {
3010 constructor() {
3011 this.options = {};
3012 this.type = ShapeType.circle;
3013 }
3014 get image() {
3015 var _a;
3016 return (_a = this.options[ShapeType.image]) !== null && _a !== void 0 ? _a : this.options[ShapeType.images];
3017 }
3018 set image(value) {
3019 this.options[ShapeType.image] = value;
3020 this.options[ShapeType.images] = value;
3021 }
3022 get custom() {
3023 return this.options;
3024 }
3025 set custom(value) {
3026 this.options = value;
3027 }
3028 get images() {
3029 return this.image;
3030 }
3031 set images(value) {
3032 this.image = value;
3033 }
3034 get stroke() {
3035 return [];
3036 }
3037 set stroke(_value) {}
3038 get character() {
3039 var _a;
3040 return (_a = this.options[ShapeType.character]) !== null && _a !== void 0 ? _a : this.options[ShapeType.char];
3041 }
3042 set character(value) {
3043 this.options[ShapeType.character] = value;
3044 this.options[ShapeType.char] = value;
3045 }
3046 get polygon() {
3047 var _a;
3048 return (_a = this.options[ShapeType.polygon]) !== null && _a !== void 0 ? _a : this.options[ShapeType.star];
3049 }
3050 set polygon(value) {
3051 this.options[ShapeType.polygon] = value;
3052 this.options[ShapeType.star] = value;
3053 }
3054 load(data) {
3055 var _a, _b, _c;
3056 if (data === undefined) {
3057 return;
3058 }
3059 const options = (_a = data.options) !== null && _a !== void 0 ? _a : data.custom;
3060 if (options !== undefined) {
3061 for (const shape in options) {
3062 const item = options[shape];
3063 if (item !== undefined) {
3064 this.options[shape] = deepExtend((_b = this.options[shape]) !== null && _b !== void 0 ? _b : {}, item);
3065 }
3066 }
3067 }
3068 this.loadShape(data.character, ShapeType.character, ShapeType.char, true);
3069 this.loadShape(data.polygon, ShapeType.polygon, ShapeType.star, false);
3070 this.loadShape((_c = data.image) !== null && _c !== void 0 ? _c : data.images, ShapeType.image, ShapeType.images, true);
3071 if (data.type !== undefined) {
3072 this.type = data.type;
3073 }
3074 }
3075 loadShape(item, mainKey, altKey, altOverride) {
3076 var _a, _b, _c, _d;
3077 if (item === undefined) {
3078 return;
3079 }
3080 if (item instanceof Array) {
3081 if (!(this.options[mainKey] instanceof Array)) {
3082 this.options[mainKey] = [];
3083 if (!this.options[altKey] || altOverride) {
3084 this.options[altKey] = [];
3085 }
3086 }
3087 this.options[mainKey] = deepExtend((_a = this.options[mainKey]) !== null && _a !== void 0 ? _a : [], item);
3088 if (!this.options[altKey] || altOverride) {
3089 this.options[altKey] = deepExtend((_b = this.options[altKey]) !== null && _b !== void 0 ? _b : [], item);
3090 }
3091 } else {
3092 if (this.options[mainKey] instanceof Array) {
3093 this.options[mainKey] = {};
3094 if (!this.options[altKey] || altOverride) {
3095 this.options[altKey] = {};
3096 }
3097 }
3098 this.options[mainKey] = deepExtend((_c = this.options[mainKey]) !== null && _c !== void 0 ? _c : {}, item);
3099 if (!this.options[altKey] || altOverride) {
3100 this.options[altKey] = deepExtend((_d = this.options[altKey]) !== null && _d !== void 0 ? _d : {}, item);
3101 }
3102 }
3103 }
3104 }
3105 class SizeAnimation extends AnimationOptions {
3106 constructor() {
3107 super();
3108 this.destroy = DestroyType.none;
3109 this.enable = false;
3110 this.speed = 5;
3111 this.startValue = StartValueType.random;
3112 this.sync = false;
3113 }
3114 get size_min() {
3115 return this.minimumValue;
3116 }
3117 set size_min(value) {
3118 this.minimumValue = value;
3119 }
3120 load(data) {
3121 var _a;
3122 if (data === undefined) {
3123 return;
3124 }
3125 super.load(data);
3126 if (data.destroy !== undefined) {
3127 this.destroy = data.destroy;
3128 }
3129 if (data.enable !== undefined) {
3130 this.enable = data.enable;
3131 }
3132 this.minimumValue = (_a = data.minimumValue) !== null && _a !== void 0 ? _a : data.size_min;
3133 if (data.speed !== undefined) {
3134 this.speed = data.speed;
3135 }
3136 if (data.startValue !== undefined) {
3137 this.startValue = data.startValue;
3138 }
3139 if (data.sync !== undefined) {
3140 this.sync = data.sync;
3141 }
3142 }
3143 }
3144 class Size extends ValueWithRandom {
3145 constructor() {
3146 super();
3147 this.animation = new SizeAnimation;
3148 this.random.minimumValue = 1;
3149 this.value = 3;
3150 }
3151 get anim() {
3152 return this.animation;
3153 }
3154 set anim(value) {
3155 this.animation = value;
3156 }
3157 load(data) {
3158 var _a;
3159 if (!data) {
3160 return;
3161 }
3162 super.load(data);
3163 const animation = (_a = data.animation) !== null && _a !== void 0 ? _a : data.anim;
3164 if (animation !== undefined) {
3165 this.animation.load(animation);
3166 this.value = setRangeValue(this.value, this.animation.enable ? this.animation.minimumValue : undefined);
3167 }
3168 }
3169 }
3170 class RotateAnimation {
3171 constructor() {
3172 this.enable = false;
3173 this.speed = 0;
3174 this.sync = false;
3175 }
3176 load(data) {
3177 if (data === undefined) {
3178 return;
3179 }
3180 if (data.enable !== undefined) {
3181 this.enable = data.enable;
3182 }
3183 if (data.speed !== undefined) {
3184 this.speed = data.speed;
3185 }
3186 if (data.sync !== undefined) {
3187 this.sync = data.sync;
3188 }
3189 }
3190 }
3191 class Rotate extends ValueWithRandom {
3192 constructor() {
3193 super();
3194 this.animation = new RotateAnimation;
3195 this.direction = RotateDirection.clockwise;
3196 this.path = false;
3197 this.value = 0;
3198 }
3199 load(data) {
3200 if (!data) {
3201 return;
3202 }
3203 super.load(data);
3204 if (data.direction !== undefined) {
3205 this.direction = data.direction;
3206 }
3207 this.animation.load(data.animation);
3208 if (data.path !== undefined) {
3209 this.path = data.path;
3210 }
3211 }
3212 }
3213 class Shadow {
3214 constructor() {
3215 this.blur = 0;
3216 this.color = new OptionsColor;
3217 this.enable = false;
3218 this.offset = {
3219 x: 0,
3220 y: 0
3221 };
3222 this.color.value = "#000000";
3223 }
3224 load(data) {
3225 if (data === undefined) {
3226 return;
3227 }
3228 if (data.blur !== undefined) {
3229 this.blur = data.blur;
3230 }
3231 this.color = OptionsColor.create(this.color, data.color);
3232 if (data.enable !== undefined) {
3233 this.enable = data.enable;
3234 }
3235 if (data.offset === undefined) {
3236 return;
3237 }
3238 if (data.offset.x !== undefined) {
3239 this.offset.x = data.offset.x;
3240 }
3241 if (data.offset.y !== undefined) {
3242 this.offset.y = data.offset.y;
3243 }
3244 }
3245 }
3246 class ColorAnimation {
3247 constructor() {
3248 this.count = 0;
3249 this.enable = false;
3250 this.offset = 0;
3251 this.speed = 1;
3252 this.sync = true;
3253 }
3254 load(data) {
3255 if (data === undefined) {
3256 return;
3257 }
3258 if (data.count !== undefined) {
3259 this.count = data.count;
3260 }
3261 if (data.enable !== undefined) {
3262 this.enable = data.enable;
3263 }
3264 if (data.offset !== undefined) {
3265 this.offset = setRangeValue(data.offset);
3266 }
3267 if (data.speed !== undefined) {
3268 this.speed = data.speed;
3269 }
3270 if (data.sync !== undefined) {
3271 this.sync = data.sync;
3272 }
3273 }
3274 }
3275 class HslAnimation {
3276 constructor() {
3277 this.h = new ColorAnimation;
3278 this.s = new ColorAnimation;
3279 this.l = new ColorAnimation;
3280 }
3281 load(data) {
3282 if (!data) {
3283 return;
3284 }
3285 this.h.load(data.h);
3286 this.s.load(data.s);
3287 this.l.load(data.l);
3288 }
3289 }
3290 class AnimatableColor extends OptionsColor {
3291 constructor() {
3292 super();
3293 this.animation = new HslAnimation;
3294 }
3295 static create(source, data) {
3296 const color = new AnimatableColor;
3297 color.load(source);
3298 if (data !== undefined) {
3299 if (typeof data === "string" || data instanceof Array) {
3300 color.load({
3301 value: data
3302 });
3303 } else {
3304 color.load(data);
3305 }
3306 }
3307 return color;
3308 }
3309 load(data) {
3310 super.load(data);
3311 if (!data) {
3312 return;
3313 }
3314 const colorAnimation = data.animation;
3315 if (colorAnimation !== undefined) {
3316 if (colorAnimation.enable !== undefined) {
3317 this.animation.h.load(colorAnimation);
3318 } else {
3319 this.animation.load(data.animation);
3320 }
3321 }
3322 }
3323 }
3324 class Stroke {
3325 constructor() {
3326 this.width = 0;
3327 }
3328 load(data) {
3329 if (data === undefined) {
3330 return;
3331 }
3332 if (data.color !== undefined) {
3333 this.color = AnimatableColor.create(this.color, data.color);
3334 }
3335 if (data.width !== undefined) {
3336 this.width = data.width;
3337 }
3338 if (data.opacity !== undefined) {
3339 this.opacity = data.opacity;
3340 }
3341 }
3342 }
3343 class BounceFactor extends ValueWithRandom {
3344 constructor() {
3345 super();
3346 this.random.minimumValue = .1;
3347 this.value = 1;
3348 }
3349 }
3350 class Bounce {
3351 constructor() {
3352 this.horizontal = new BounceFactor;
3353 this.vertical = new BounceFactor;
3354 }
3355 load(data) {
3356 if (!data) {
3357 return;
3358 }
3359 this.horizontal.load(data.horizontal);
3360 this.vertical.load(data.vertical);
3361 }
3362 }
3363 class CollisionsOverlap {
3364 constructor() {
3365 this.enable = true;
3366 this.retries = 0;
3367 }
3368 load(data) {
3369 if (!data) {
3370 return;
3371 }
3372 if (data.enable !== undefined) {
3373 this.enable = data.enable;
3374 }
3375 if (data.retries !== undefined) {
3376 this.retries = data.retries;
3377 }
3378 }
3379 }
3380 class Collisions {
3381 constructor() {
3382 this.bounce = new Bounce;
3383 this.enable = false;
3384 this.mode = CollisionMode.bounce;
3385 this.overlap = new CollisionsOverlap;
3386 }
3387 load(data) {
3388 if (data === undefined) {
3389 return;
3390 }
3391 this.bounce.load(data.bounce);
3392 if (data.enable !== undefined) {
3393 this.enable = data.enable;
3394 }
3395 if (data.mode !== undefined) {
3396 this.mode = data.mode;
3397 }
3398 this.overlap.load(data.overlap);
3399 }
3400 }
3401 class TwinkleValues {
3402 constructor() {
3403 this.enable = false;
3404 this.frequency = .05;
3405 this.opacity = 1;
3406 }
3407 load(data) {
3408 if (data === undefined) {
3409 return;
3410 }
3411 if (data.color !== undefined) {
3412 this.color = OptionsColor.create(this.color, data.color);
3413 }
3414 if (data.enable !== undefined) {
3415 this.enable = data.enable;
3416 }
3417 if (data.frequency !== undefined) {
3418 this.frequency = data.frequency;
3419 }
3420 if (data.opacity !== undefined) {
3421 this.opacity = data.opacity;
3422 }
3423 }
3424 }
3425 class Twinkle {
3426 constructor() {
3427 this.lines = new TwinkleValues;
3428 this.particles = new TwinkleValues;
3429 }
3430 load(data) {
3431 if (data === undefined) {
3432 return;
3433 }
3434 this.lines.load(data.lines);
3435 this.particles.load(data.particles);
3436 }
3437 }
3438 class LifeDelay extends ValueWithRandom {
3439 constructor() {
3440 super();
3441 this.sync = false;
3442 }
3443 load(data) {
3444 if (!data) {
3445 return;
3446 }
3447 super.load(data);
3448 if (data.sync !== undefined) {
3449 this.sync = data.sync;
3450 }
3451 }
3452 }
3453 class LifeDuration extends ValueWithRandom {
3454 constructor() {
3455 super();
3456 this.random.minimumValue = 1e-4;
3457 this.sync = false;
3458 }
3459 load(data) {
3460 if (data === undefined) {
3461 return;
3462 }
3463 super.load(data);
3464 if (data.sync !== undefined) {
3465 this.sync = data.sync;
3466 }
3467 }
3468 }
3469 class Life {
3470 constructor() {
3471 this.count = 0;
3472 this.delay = new LifeDelay;
3473 this.duration = new LifeDuration;
3474 }
3475 load(data) {
3476 if (data === undefined) {
3477 return;
3478 }
3479 if (data.count !== undefined) {
3480 this.count = data.count;
3481 }
3482 this.delay.load(data.delay);
3483 this.duration.load(data.duration);
3484 }
3485 }
3486 class SplitFactor extends ValueWithRandom {
3487 constructor() {
3488 super();
3489 this.value = 3;
3490 }
3491 }
3492 class SplitRate extends ValueWithRandom {
3493 constructor() {
3494 super();
3495 this.value = {
3496 min: 4,
3497 max: 9
3498 };
3499 }
3500 }
3501 class Split {
3502 constructor() {
3503 this.count = 1;
3504 this.factor = new SplitFactor;
3505 this.rate = new SplitRate;
3506 this.sizeOffset = true;
3507 }
3508 load(data) {
3509 if (!data) {
3510 return;
3511 }
3512 if (data.count !== undefined) {
3513 this.count = data.count;
3514 }
3515 this.factor.load(data.factor);
3516 this.rate.load(data.rate);
3517 if (data.particles !== undefined) {
3518 this.particles = deepExtend({}, data.particles);
3519 }
3520 if (data.sizeOffset !== undefined) {
3521 this.sizeOffset = data.sizeOffset;
3522 }
3523 }
3524 }
3525 class Destroy {
3526 constructor() {
3527 this.mode = DestroyMode.none;
3528 this.split = new Split;
3529 }
3530 load(data) {
3531 if (!data) {
3532 return;
3533 }
3534 if (data.mode !== undefined) {
3535 this.mode = data.mode;
3536 }
3537 this.split.load(data.split);
3538 }
3539 }
3540 class Wobble {
3541 constructor() {
3542 this.distance = 5;
3543 this.enable = false;
3544 this.speed = 50;
3545 }
3546 load(data) {
3547 if (!data) {
3548 return;
3549 }
3550 if (data.distance !== undefined) {
3551 this.distance = setRangeValue(data.distance);
3552 }
3553 if (data.enable !== undefined) {
3554 this.enable = data.enable;
3555 }
3556 if (data.speed !== undefined) {
3557 this.speed = setRangeValue(data.speed);
3558 }
3559 }
3560 }
3561 class TiltAnimation {
3562 constructor() {
3563 this.enable = false;
3564 this.speed = 0;
3565 this.sync = false;
3566 }
3567 load(data) {
3568 if (data === undefined) {
3569 return;
3570 }
3571 if (data.enable !== undefined) {
3572 this.enable = data.enable;
3573 }
3574 if (data.speed !== undefined) {
3575 this.speed = data.speed;
3576 }
3577 if (data.sync !== undefined) {
3578 this.sync = data.sync;
3579 }
3580 }
3581 }
3582 class Tilt extends ValueWithRandom {
3583 constructor() {
3584 super();
3585 this.animation = new TiltAnimation;
3586 this.direction = TiltDirection.clockwise;
3587 this.enable = false;
3588 this.value = 0;
3589 }
3590 load(data) {
3591 if (!data) {
3592 return;
3593 }
3594 super.load(data);
3595 this.animation.load(data.animation);
3596 if (data.direction !== undefined) {
3597 this.direction = data.direction;
3598 }
3599 if (data.enable !== undefined) {
3600 this.enable = data.enable;
3601 }
3602 }
3603 }
3604 class RollLight {
3605 constructor() {
3606 this.enable = false;
3607 this.value = 0;
3608 }
3609 load(data) {
3610 if (!data) {
3611 return;
3612 }
3613 if (data.enable !== undefined) {
3614 this.enable = data.enable;
3615 }
3616 if (data.value !== undefined) {
3617 this.value = data.value;
3618 }
3619 }
3620 }
3621 class Roll {
3622 constructor() {
3623 this.darken = new RollLight;
3624 this.enable = false;
3625 this.enlighten = new RollLight;
3626 this.mode = RollMode.vertical;
3627 this.speed = 25;
3628 }
3629 load(data) {
3630 if (!data) {
3631 return;
3632 }
3633 if (data.backColor !== undefined) {
3634 this.backColor = OptionsColor.create(this.backColor, data.backColor);
3635 }
3636 this.darken.load(data.darken);
3637 if (data.enable !== undefined) {
3638 this.enable = data.enable;
3639 }
3640 this.enlighten.load(data.enlighten);
3641 if (data.mode !== undefined) {
3642 this.mode = data.mode;
3643 }
3644 if (data.speed !== undefined) {
3645 this.speed = setRangeValue(data.speed);
3646 }
3647 }
3648 }
3649 class ZIndex extends ValueWithRandom {
3650 constructor() {
3651 super();
3652 this.opacityRate = 1;
3653 this.sizeRate = 1;
3654 this.velocityRate = 1;
3655 }
3656 load(data) {
3657 super.load(data);
3658 if (!data) {
3659 return;
3660 }
3661 if (data.opacityRate !== undefined) {
3662 this.opacityRate = data.opacityRate;
3663 }
3664 if (data.sizeRate !== undefined) {
3665 this.sizeRate = data.sizeRate;
3666 }
3667 if (data.velocityRate !== undefined) {
3668 this.velocityRate = data.velocityRate;
3669 }
3670 }
3671 }
3672 class OrbitRotation extends ValueWithRandom {
3673 constructor() {
3674 super();
3675 this.value = 45;
3676 this.random.enable = false;
3677 this.random.minimumValue = 0;
3678 }
3679 load(data) {
3680 if (data === undefined) {
3681 return;
3682 }
3683 super.load(data);
3684 }
3685 }
3686 class Orbit {
3687 constructor() {
3688 this.animation = new AnimationOptions;
3689 this.enable = false;
3690 this.opacity = 1;
3691 this.rotation = new OrbitRotation;
3692 this.width = 1;
3693 }
3694 load(data) {
3695 if (data === undefined) {
3696 return;
3697 }
3698 this.animation.load(data.animation);
3699 this.rotation.load(data.rotation);
3700 if (data.enable !== undefined) {
3701 this.enable = data.enable;
3702 }
3703 if (data.opacity !== undefined) {
3704 this.opacity = data.opacity;
3705 }
3706 if (data.width !== undefined) {
3707 this.width = data.width;
3708 }
3709 if (data.radius !== undefined) {
3710 this.radius = data.radius;
3711 }
3712 if (data.color !== undefined) {
3713 this.color = OptionsColor.create(this.color, data.color);
3714 }
3715 }
3716 }
3717 class Repulse extends ValueWithRandom {
3718 constructor() {
3719 super();
3720 this.enabled = false;
3721 this.distance = 1;
3722 this.duration = 1;
3723 this.factor = 1;
3724 this.speed = 1;
3725 }
3726 load(data) {
3727 super.load(data);
3728 if (!data) {
3729 return;
3730 }
3731 if (data.enabled !== undefined) {
3732 this.enabled = data.enabled;
3733 }
3734 if (data.distance !== undefined) {
3735 this.distance = data.distance;
3736 }
3737 if (data.duration !== undefined) {
3738 this.duration = data.duration;
3739 }
3740 if (data.factor !== undefined) {
3741 this.factor = data.factor;
3742 }
3743 if (data.speed !== undefined) {
3744 this.speed = data.speed;
3745 }
3746 }
3747 }
3748 class AnimatableGradient {
3749 constructor() {
3750 this.angle = new GradientAngle;
3751 this.colors = [];
3752 this.type = GradientType.random;
3753 }
3754 load(data) {
3755 if (!data) {
3756 return;
3757 }
3758 this.angle.load(data.angle);
3759 if (data.colors !== undefined) {
3760 this.colors = data.colors.map((s => {
3761 const tmp = new AnimatableGradientColor;
3762 tmp.load(s);
3763 return tmp;
3764 }));
3765 }
3766 if (data.type !== undefined) {
3767 this.type = data.type;
3768 }
3769 }
3770 }
3771 class GradientAngle {
3772 constructor() {
3773 this.value = 0;
3774 this.animation = new GradientAngleAnimation;
3775 this.direction = RotateDirection.clockwise;
3776 }
3777 load(data) {
3778 if (!data) {
3779 return;
3780 }
3781 this.animation.load(data.animation);
3782 if (data.value !== undefined) {
3783 this.value = data.value;
3784 }
3785 if (data.direction !== undefined) {
3786 this.direction = data.direction;
3787 }
3788 }
3789 }
3790 class GradientColorOpacity {
3791 constructor() {
3792 this.value = 0;
3793 this.animation = new GradientColorOpacityAnimation;
3794 }
3795 load(data) {
3796 if (!data) {
3797 return;
3798 }
3799 this.animation.load(data.animation);
3800 if (data.value !== undefined) {
3801 this.value = setRangeValue(data.value);
3802 }
3803 }
3804 }
3805 class AnimatableGradientColor {
3806 constructor() {
3807 this.stop = 0;
3808 this.value = new AnimatableColor;
3809 }
3810 load(data) {
3811 if (!data) {
3812 return;
3813 }
3814 if (data.stop !== undefined) {
3815 this.stop = data.stop;
3816 }
3817 this.value = AnimatableColor.create(this.value, data.value);
3818 if (data.opacity !== undefined) {
3819 this.opacity = new GradientColorOpacity;
3820 if (typeof data.opacity === "number") {
3821 this.opacity.value = data.opacity;
3822 } else {
3823 this.opacity.load(data.opacity);
3824 }
3825 }
3826 }
3827 }
3828 class GradientAngleAnimation {
3829 constructor() {
3830 this.count = 0;
3831 this.enable = false;
3832 this.speed = 0;
3833 this.sync = false;
3834 }
3835 load(data) {
3836 if (!data) {
3837 return;
3838 }
3839 if (data.count !== undefined) {
3840 this.count = data.count;
3841 }
3842 if (data.enable !== undefined) {
3843 this.enable = data.enable;
3844 }
3845 if (data.speed !== undefined) {
3846 this.speed = data.speed;
3847 }
3848 if (data.sync !== undefined) {
3849 this.sync = data.sync;
3850 }
3851 }
3852 }
3853 class GradientColorOpacityAnimation {
3854 constructor() {
3855 this.count = 0;
3856 this.enable = false;
3857 this.speed = 0;
3858 this.sync = false;
3859 this.startValue = StartValueType.random;
3860 }
3861 load(data) {
3862 if (!data) {
3863 return;
3864 }
3865 if (data.count !== undefined) {
3866 this.count = data.count;
3867 }
3868 if (data.enable !== undefined) {
3869 this.enable = data.enable;
3870 }
3871 if (data.speed !== undefined) {
3872 this.speed = data.speed;
3873 }
3874 if (data.sync !== undefined) {
3875 this.sync = data.sync;
3876 }
3877 if (data.startValue !== undefined) {
3878 this.startValue = data.startValue;
3879 }
3880 }
3881 }
3882 class ParticlesOptions {
3883 constructor() {
3884 this.bounce = new Bounce;
3885 this.collisions = new Collisions;
3886 this.color = new AnimatableColor;
3887 this.destroy = new Destroy;
3888 this.gradient = [];
3889 this.groups = {};
3890 this.life = new Life;
3891 this.links = new Links;
3892 this.move = new Move;
3893 this.number = new ParticlesNumber;
3894 this.opacity = new Opacity;
3895 this.orbit = new Orbit;
3896 this.reduceDuplicates = false;
3897 this.repulse = new Repulse;
3898 this.roll = new Roll;
3899 this.rotate = new Rotate;
3900 this.shadow = new Shadow;
3901 this.shape = new Shape;
3902 this.size = new Size;
3903 this.stroke = new Stroke;
3904 this.tilt = new Tilt;
3905 this.twinkle = new Twinkle;
3906 this.wobble = new Wobble;
3907 this.zIndex = new ZIndex;
3908 }
3909 get line_linked() {
3910 return this.links;
3911 }
3912 set line_linked(value) {
3913 this.links = value;
3914 }
3915 get lineLinked() {
3916 return this.links;
3917 }
3918 set lineLinked(value) {
3919 this.links = value;
3920 }
3921 load(data) {
3922 var _a, _b, _c, _d, _e, _f, _g, _h;
3923 if (data === undefined) {
3924 return;
3925 }
3926 this.bounce.load(data.bounce);
3927 this.color.load(AnimatableColor.create(this.color, data.color));
3928 this.destroy.load(data.destroy);
3929 this.life.load(data.life);
3930 const links = (_b = (_a = data.links) !== null && _a !== void 0 ? _a : data.lineLinked) !== null && _b !== void 0 ? _b : data.line_linked;
3931 if (links !== undefined) {
3932 this.links.load(links);
3933 }
3934 if (data.groups !== undefined) {
3935 for (const group in data.groups) {
3936 const item = data.groups[group];
3937 if (item !== undefined) {
3938 this.groups[group] = deepExtend((_c = this.groups[group]) !== null && _c !== void 0 ? _c : {}, item);
3939 }
3940 }
3941 }
3942 this.move.load(data.move);
3943 this.number.load(data.number);
3944 this.opacity.load(data.opacity);
3945 this.orbit.load(data.orbit);
3946 if (data.reduceDuplicates !== undefined) {
3947 this.reduceDuplicates = data.reduceDuplicates;
3948 }
3949 this.repulse.load(data.repulse);
3950 this.roll.load(data.roll);
3951 this.rotate.load(data.rotate);
3952 this.shape.load(data.shape);
3953 this.size.load(data.size);
3954 this.shadow.load(data.shadow);
3955 this.tilt.load(data.tilt);
3956 this.twinkle.load(data.twinkle);
3957 this.wobble.load(data.wobble);
3958 this.zIndex.load(data.zIndex);
3959 const collisions = (_e = (_d = data.move) === null || _d === void 0 ? void 0 : _d.collisions) !== null && _e !== void 0 ? _e : (_f = data.move) === null || _f === void 0 ? void 0 : _f.bounce;
3960 if (collisions !== undefined) {
3961 this.collisions.enable = collisions;
3962 }
3963 this.collisions.load(data.collisions);
3964 const strokeToLoad = (_g = data.stroke) !== null && _g !== void 0 ? _g : (_h = data.shape) === null || _h === void 0 ? void 0 : _h.stroke;
3965 if (strokeToLoad) {
3966 if (strokeToLoad instanceof Array) {
3967 this.stroke = strokeToLoad.map((s => {
3968 const tmp = new Stroke;
3969 tmp.load(s);
3970 return tmp;
3971 }));
3972 } else {
3973 if (this.stroke instanceof Array) {
3974 this.stroke = new Stroke;
3975 }
3976 this.stroke.load(strokeToLoad);
3977 }
3978 }
3979 const gradientToLoad = data.gradient;
3980 if (gradientToLoad) {
3981 if (gradientToLoad instanceof Array) {
3982 this.gradient = gradientToLoad.map((s => {
3983 const tmp = new AnimatableGradient;
3984 tmp.load(s);
3985 return tmp;
3986 }));
3987 } else {
3988 if (this.gradient instanceof Array) {
3989 this.gradient = new AnimatableGradient;
3990 }
3991 this.gradient.load(gradientToLoad);
3992 }
3993 }
3994 }
3995 }
3996 class Vector3d extends Vector {
3997 constructor(x, y, z) {
3998 super(x, y);
3999 this.z = z === undefined ? x.z : z;
4000 }
4001 static clone(source) {
4002 return Vector3d.create(source.x, source.y, source.z);
4003 }
4004 static create(x, y, z) {
4005 return new Vector3d(x, y, z);
4006 }
4007 add(v) {
4008 return v instanceof Vector3d ? Vector3d.create(this.x + v.x, this.y + v.y, this.z + v.z) : super.add(v);
4009 }
4010 addTo(v) {
4011 super.addTo(v);
4012 if (v instanceof Vector3d) {
4013 this.z += v.z;
4014 }
4015 }
4016 sub(v) {
4017 return v instanceof Vector3d ? Vector3d.create(this.x - v.x, this.y - v.y, this.z - v.z) : super.sub(v);
4018 }
4019 subFrom(v) {
4020 super.subFrom(v);
4021 if (v instanceof Vector3d) {
4022 this.z -= v.z;
4023 }
4024 }
4025 mult(n) {
4026 return Vector3d.create(this.x * n, this.y * n, this.z * n);
4027 }
4028 multTo(n) {
4029 super.multTo(n);
4030 this.z *= n;
4031 }
4032 div(n) {
4033 return Vector3d.create(this.x / n, this.y / n, this.z / n);
4034 }
4035 divTo(n) {
4036 super.divTo(n);
4037 this.z /= n;
4038 }
4039 copy() {
4040 return Vector3d.clone(this);
4041 }
4042 setTo(v) {
4043 super.setTo(v);
4044 if (v instanceof Vector3d) {
4045 this.z = v.z;
4046 }
4047 }
4048 }
4049 const fixOutMode = data => {
4050 if (isInArray(data.outMode, data.checkModes) || isInArray(data.outMode, data.checkModes)) {
4051 if (data.coord > data.maxCoord - data.radius * 2) {
4052 data.setCb(-data.radius);
4053 } else if (data.coord < data.radius * 2) {
4054 data.setCb(data.radius);
4055 }
4056 }
4057 };
4058 class Particle {
4059 constructor(id, container, position, overrideOptions, group) {
4060 var _a, _b, _c, _d, _e, _f, _g, _h, _j;
4061 this.id = id;
4062 this.container = container;
4063 this.group = group;
4064 this.fill = true;
4065 this.close = true;
4066 this.lastPathTime = 0;
4067 this.destroyed = false;
4068 this.unbreakable = false;
4069 this.splitCount = 0;
4070 this.misplaced = false;
4071 this.retina = {
4072 maxDistance: {}
4073 };
4074 const pxRatio = container.retina.pixelRatio;
4075 const mainOptions = container.actualOptions;
4076 const particlesOptions = new ParticlesOptions;
4077 particlesOptions.load(mainOptions.particles);
4078 const shapeType = particlesOptions.shape.type;
4079 const reduceDuplicates = particlesOptions.reduceDuplicates;
4080 this.shape = shapeType instanceof Array ? itemFromArray(shapeType, this.id, reduceDuplicates) : shapeType;
4081 if (overrideOptions === null || overrideOptions === void 0 ? void 0 : overrideOptions.shape) {
4082 if (overrideOptions.shape.type) {
4083 const overrideShapeType = overrideOptions.shape.type;
4084 this.shape = overrideShapeType instanceof Array ? itemFromArray(overrideShapeType, this.id, reduceDuplicates) : overrideShapeType;
4085 }
4086 const shapeOptions = new Shape;
4087 shapeOptions.load(overrideOptions.shape);
4088 if (this.shape) {
4089 this.shapeData = this.loadShapeData(shapeOptions, reduceDuplicates);
4090 }
4091 } else {
4092 this.shapeData = this.loadShapeData(particlesOptions.shape, reduceDuplicates);
4093 }
4094 if (overrideOptions !== undefined) {
4095 particlesOptions.load(overrideOptions);
4096 }
4097 if (((_a = this.shapeData) === null || _a === void 0 ? void 0 : _a.particles) !== undefined) {
4098 particlesOptions.load((_b = this.shapeData) === null || _b === void 0 ? void 0 : _b.particles);
4099 }
4100 this.fill = (_d = (_c = this.shapeData) === null || _c === void 0 ? void 0 : _c.fill) !== null && _d !== void 0 ? _d : this.fill;
4101 this.close = (_f = (_e = this.shapeData) === null || _e === void 0 ? void 0 : _e.close) !== null && _f !== void 0 ? _f : this.close;
4102 this.options = particlesOptions;
4103 this.pathDelay = getValue(this.options.move.path.delay) * 1e3;
4104 const zIndexValue = getRangeValue(this.options.zIndex.value);
4105 container.retina.initParticle(this);
4106 const sizeOptions = this.options.size, sizeRange = sizeOptions.value;
4107 this.size = {
4108 enable: sizeOptions.animation.enable,
4109 value: getValue(sizeOptions) * container.retina.pixelRatio,
4110 max: getRangeMax(sizeRange) * pxRatio,
4111 min: getRangeMin(sizeRange) * pxRatio,
4112 loops: 0,
4113 maxLoops: sizeOptions.animation.count
4114 };
4115 const sizeAnimation = sizeOptions.animation;
4116 if (sizeAnimation.enable) {
4117 this.size.status = AnimationStatus.increasing;
4118 switch (sizeAnimation.startValue) {
4119 case StartValueType.min:
4120 this.size.value = this.size.min;
4121 this.size.status = AnimationStatus.increasing;
4122 break;
4123
4124 case StartValueType.random:
4125 this.size.value = randomInRange(this.size) * pxRatio;
4126 this.size.status = Math.random() >= .5 ? AnimationStatus.increasing : AnimationStatus.decreasing;
4127 break;
4128
4129 case StartValueType.max:
4130 default:
4131 this.size.value = this.size.max;
4132 this.size.status = AnimationStatus.decreasing;
4133 break;
4134 }
4135 this.size.velocity = ((_g = this.retina.sizeAnimationSpeed) !== null && _g !== void 0 ? _g : container.retina.sizeAnimationSpeed) / 100 * container.retina.reduceFactor;
4136 if (!sizeAnimation.sync) {
4137 this.size.velocity *= Math.random();
4138 }
4139 }
4140 this.direction = getParticleDirectionAngle(this.options.move.direction);
4141 this.bubble = {
4142 inRange: false
4143 };
4144 this.initialVelocity = this.calculateVelocity();
4145 this.velocity = this.initialVelocity.copy();
4146 this.moveDecay = 1 - getRangeValue(this.options.move.decay);
4147 this.position = this.calcPosition(container, position, clamp(zIndexValue, 0, container.zLayers));
4148 this.initialPosition = this.position.copy();
4149 this.offset = Vector.origin;
4150 const particles = container.particles;
4151 particles.needsSort = particles.needsSort || particles.lastZIndex < this.position.z;
4152 particles.lastZIndex = this.position.z;
4153 this.zIndexFactor = this.position.z / container.zLayers;
4154 this.sides = 24;
4155 let drawer = container.drawers.get(this.shape);
4156 if (!drawer) {
4157 drawer = Plugins.getShapeDrawer(this.shape);
4158 if (drawer) {
4159 container.drawers.set(this.shape, drawer);
4160 }
4161 }
4162 if (drawer === null || drawer === void 0 ? void 0 : drawer.loadShape) {
4163 drawer === null || drawer === void 0 ? void 0 : drawer.loadShape(this);
4164 }
4165 const sideCountFunc = drawer === null || drawer === void 0 ? void 0 : drawer.getSidesCount;
4166 if (sideCountFunc) {
4167 this.sides = sideCountFunc(this);
4168 }
4169 this.life = this.loadLife();
4170 this.spawning = this.life.delay > 0;
4171 if (this.options.move.spin.enable) {
4172 const spinPos = (_h = this.options.move.spin.position) !== null && _h !== void 0 ? _h : {
4173 x: 50,
4174 y: 50
4175 };
4176 const spinCenter = {
4177 x: spinPos.x / 100 * container.canvas.size.width,
4178 y: spinPos.y / 100 * container.canvas.size.height
4179 };
4180 const pos = this.getPosition();
4181 const distance = getDistance(pos, spinCenter);
4182 this.spin = {
4183 center: spinCenter,
4184 direction: this.velocity.x >= 0 ? RotateDirection.clockwise : RotateDirection.counterClockwise,
4185 angle: this.velocity.angle,
4186 radius: distance,
4187 acceleration: (_j = this.retina.spinAcceleration) !== null && _j !== void 0 ? _j : getRangeValue(this.options.move.spin.acceleration)
4188 };
4189 }
4190 this.shadowColor = colorToRgb(this.options.shadow.color);
4191 for (const updater of container.particles.updaters) {
4192 if (updater.init) {
4193 updater.init(this);
4194 }
4195 }
4196 if (drawer && drawer.particleInit) {
4197 drawer.particleInit(container, this);
4198 }
4199 for (const [, plugin] of container.plugins) {
4200 if (plugin.particleCreated) {
4201 plugin.particleCreated(this);
4202 }
4203 }
4204 }
4205 isVisible() {
4206 return !this.destroyed && !this.spawning && this.isInsideCanvas();
4207 }
4208 isInsideCanvas() {
4209 const radius = this.getRadius();
4210 const canvasSize = this.container.canvas.size;
4211 return this.position.x >= -radius && this.position.y >= -radius && this.position.y <= canvasSize.height + radius && this.position.x <= canvasSize.width + radius;
4212 }
4213 draw(delta) {
4214 const container = this.container;
4215 for (const [, plugin] of container.plugins) {
4216 container.canvas.drawParticlePlugin(plugin, this, delta);
4217 }
4218 container.canvas.drawParticle(this, delta);
4219 }
4220 getPosition() {
4221 return {
4222 x: this.position.x + this.offset.x,
4223 y: this.position.y + this.offset.y,
4224 z: this.position.z
4225 };
4226 }
4227 getRadius() {
4228 var _a;
4229 return (_a = this.bubble.radius) !== null && _a !== void 0 ? _a : this.size.value;
4230 }
4231 getMass() {
4232 return this.getRadius() ** 2 * Math.PI / 2;
4233 }
4234 getFillColor() {
4235 var _a, _b, _c;
4236 const color = (_a = this.bubble.color) !== null && _a !== void 0 ? _a : getHslFromAnimation(this.color);
4237 if (color && this.roll && (this.backColor || this.roll.alter)) {
4238 const rolled = Math.floor(((_c = (_b = this.roll) === null || _b === void 0 ? void 0 : _b.angle) !== null && _c !== void 0 ? _c : 0) / (Math.PI / 2)) % 2;
4239 if (rolled) {
4240 if (this.backColor) {
4241 return this.backColor;
4242 }
4243 if (this.roll.alter) {
4244 return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
4245 }
4246 }
4247 }
4248 return color;
4249 }
4250 getStrokeColor() {
4251 var _a, _b;
4252 return (_b = (_a = this.bubble.color) !== null && _a !== void 0 ? _a : getHslFromAnimation(this.strokeColor)) !== null && _b !== void 0 ? _b : this.getFillColor();
4253 }
4254 destroy(override) {
4255 this.destroyed = true;
4256 this.bubble.inRange = false;
4257 if (this.unbreakable) {
4258 return;
4259 }
4260 this.destroyed = true;
4261 this.bubble.inRange = false;
4262 for (const [, plugin] of this.container.plugins) {
4263 if (plugin.particleDestroyed) {
4264 plugin.particleDestroyed(this, override);
4265 }
4266 }
4267 if (override) {
4268 return;
4269 }
4270 const destroyOptions = this.options.destroy;
4271 if (destroyOptions.mode === DestroyMode.split) {
4272 this.split();
4273 }
4274 }
4275 reset() {
4276 if (this.opacity) {
4277 this.opacity.loops = 0;
4278 }
4279 this.size.loops = 0;
4280 }
4281 split() {
4282 const splitOptions = this.options.destroy.split;
4283 if (splitOptions.count >= 0 && this.splitCount++ > splitOptions.count) {
4284 return;
4285 }
4286 const rate = getRangeValue(splitOptions.rate.value);
4287 for (let i = 0; i < rate; i++) {
4288 this.container.particles.addSplitParticle(this);
4289 }
4290 }
4291 calcPosition(container, position, zIndex, tryCount = 0) {
4292 var _a, _b, _c, _d, _e, _f;
4293 for (const [, plugin] of container.plugins) {
4294 const pluginPos = plugin.particlePosition !== undefined ? plugin.particlePosition(position, this) : undefined;
4295 if (pluginPos !== undefined) {
4296 return Vector3d.create(pluginPos.x, pluginPos.y, zIndex);
4297 }
4298 }
4299 const canvasSize = container.canvas.size;
4300 const pos = Vector3d.create((_a = position === null || position === void 0 ? void 0 : position.x) !== null && _a !== void 0 ? _a : Math.random() * canvasSize.width, (_b = position === null || position === void 0 ? void 0 : position.y) !== null && _b !== void 0 ? _b : Math.random() * canvasSize.height, zIndex);
4301 const radius = this.getRadius();
4302 const outModes = this.options.move.outModes, fixHorizontal = outMode => {
4303 fixOutMode({
4304 outMode,
4305 checkModes: [ OutMode.bounce, OutMode.bounceHorizontal ],
4306 coord: pos.x,
4307 maxCoord: container.canvas.size.width,
4308 setCb: value => pos.x += value,
4309 radius
4310 });
4311 }, fixVertical = outMode => {
4312 fixOutMode({
4313 outMode,
4314 checkModes: [ OutMode.bounce, OutMode.bounceVertical ],
4315 coord: pos.y,
4316 maxCoord: container.canvas.size.height,
4317 setCb: value => pos.y += value,
4318 radius
4319 });
4320 };
4321 fixHorizontal((_c = outModes.left) !== null && _c !== void 0 ? _c : outModes.default);
4322 fixHorizontal((_d = outModes.right) !== null && _d !== void 0 ? _d : outModes.default);
4323 fixVertical((_e = outModes.top) !== null && _e !== void 0 ? _e : outModes.default);
4324 fixVertical((_f = outModes.bottom) !== null && _f !== void 0 ? _f : outModes.default);
4325 if (this.checkOverlap(pos, tryCount)) {
4326 return this.calcPosition(container, undefined, zIndex, tryCount + 1);
4327 }
4328 return pos;
4329 }
4330 checkOverlap(pos, tryCount = 0) {
4331 const collisionsOptions = this.options.collisions;
4332 const radius = this.getRadius();
4333 if (!collisionsOptions.enable) {
4334 return false;
4335 }
4336 const overlapOptions = collisionsOptions.overlap;
4337 if (overlapOptions.enable) {
4338 return false;
4339 }
4340 const retries = overlapOptions.retries;
4341 if (retries >= 0 && tryCount > retries) {
4342 throw new Error("Particle is overlapping and can't be placed");
4343 }
4344 let overlaps = false;
4345 for (const particle of this.container.particles.array) {
4346 if (getDistance(pos, particle.position) < radius + particle.getRadius()) {
4347 overlaps = true;
4348 break;
4349 }
4350 }
4351 return overlaps;
4352 }
4353 calculateVelocity() {
4354 const baseVelocity = getParticleBaseVelocity(this.direction);
4355 const res = baseVelocity.copy();
4356 const moveOptions = this.options.move;
4357 const rad = Math.PI / 180 * moveOptions.angle.value;
4358 const radOffset = Math.PI / 180 * moveOptions.angle.offset;
4359 const range = {
4360 left: radOffset - rad / 2,
4361 right: radOffset + rad / 2
4362 };
4363 if (!moveOptions.straight) {
4364 res.angle += randomInRange(setRangeValue(range.left, range.right));
4365 }
4366 if (moveOptions.random && typeof moveOptions.speed === "number") {
4367 res.length *= Math.random();
4368 }
4369 return res;
4370 }
4371 loadShapeData(shapeOptions, reduceDuplicates) {
4372 const shapeData = shapeOptions.options[this.shape];
4373 if (shapeData) {
4374 return deepExtend({}, shapeData instanceof Array ? itemFromArray(shapeData, this.id, reduceDuplicates) : shapeData);
4375 }
4376 }
4377 loadLife() {
4378 const container = this.container;
4379 const particlesOptions = this.options;
4380 const lifeOptions = particlesOptions.life;
4381 const life = {
4382 delay: container.retina.reduceFactor ? getRangeValue(lifeOptions.delay.value) * (lifeOptions.delay.sync ? 1 : Math.random()) / container.retina.reduceFactor * 1e3 : 0,
4383 delayTime: 0,
4384 duration: container.retina.reduceFactor ? getRangeValue(lifeOptions.duration.value) * (lifeOptions.duration.sync ? 1 : Math.random()) / container.retina.reduceFactor * 1e3 : 0,
4385 time: 0,
4386 count: particlesOptions.life.count
4387 };
4388 if (life.duration <= 0) {
4389 life.duration = -1;
4390 }
4391 if (life.count <= 0) {
4392 life.count = -1;
4393 }
4394 return life;
4395 }
4396 }
4397 class InteractionManager {
4398 constructor(container) {
4399 this.container = container;
4400 const interactors = Plugins.getInteractors(container);
4401 this.externalInteractors = [];
4402 this.particleInteractors = [];
4403 for (const interactor of interactors) {
4404 switch (interactor.type) {
4405 case InteractorType.External:
4406 this.externalInteractors.push(interactor);
4407 break;
4408
4409 case InteractorType.Particles:
4410 this.particleInteractors.push(interactor);
4411 break;
4412 }
4413 }
4414 }
4415 externalInteract(delta) {
4416 for (const interactor of this.externalInteractors) {
4417 if (interactor.isEnabled()) {
4418 interactor.interact(delta);
4419 }
4420 }
4421 }
4422 particlesInteract(particle, delta) {
4423 for (const interactor of this.externalInteractors) {
4424 interactor.reset(particle);
4425 }
4426 for (const interactor of this.particleInteractors) {
4427 if (interactor.isEnabled(particle)) {
4428 interactor.interact(particle, delta);
4429 }
4430 }
4431 }
4432 }
4433 function applyDistance(particle) {
4434 const initialPosition = particle.initialPosition;
4435 const {dx, dy} = getDistances(initialPosition, particle.position);
4436 const dxFixed = Math.abs(dx), dyFixed = Math.abs(dy);
4437 const hDistance = particle.retina.maxDistance.horizontal;
4438 const vDistance = particle.retina.maxDistance.vertical;
4439 if (!hDistance && !vDistance) {
4440 return;
4441 }
4442 if ((hDistance && dxFixed >= hDistance || vDistance && dyFixed >= vDistance) && !particle.misplaced) {
4443 particle.misplaced = !!hDistance && dxFixed > hDistance || !!vDistance && dyFixed > vDistance;
4444 if (hDistance) {
4445 particle.velocity.x = particle.velocity.y / 2 - particle.velocity.x;
4446 }
4447 if (vDistance) {
4448 particle.velocity.y = particle.velocity.x / 2 - particle.velocity.y;
4449 }
4450 } else if ((!hDistance || dxFixed < hDistance) && (!vDistance || dyFixed < vDistance) && particle.misplaced) {
4451 particle.misplaced = false;
4452 } else if (particle.misplaced) {
4453 const pos = particle.position, vel = particle.velocity;
4454 if (hDistance && (pos.x < initialPosition.x && vel.x < 0 || pos.x > initialPosition.x && vel.x > 0)) {
4455 vel.x *= -Math.random();
4456 }
4457 if (vDistance && (pos.y < initialPosition.y && vel.y < 0 || pos.y > initialPosition.y && vel.y > 0)) {
4458 vel.y *= -Math.random();
4459 }
4460 }
4461 }
4462 class Mover {
4463 constructor(container) {
4464 this.container = container;
4465 }
4466 move(particle, delta) {
4467 if (particle.destroyed) {
4468 return;
4469 }
4470 this.moveParticle(particle, delta);
4471 this.moveParallax(particle);
4472 }
4473 moveParticle(particle, delta) {
4474 var _a, _b, _c;
4475 var _d, _e;
4476 const particleOptions = particle.options;
4477 const moveOptions = particleOptions.move;
4478 if (!moveOptions.enable) {
4479 return;
4480 }
4481 const container = this.container, slowFactor = this.getProximitySpeedFactor(particle), baseSpeed = ((_a = (_d = particle.retina).moveSpeed) !== null && _a !== void 0 ? _a : _d.moveSpeed = getRangeValue(moveOptions.speed) * container.retina.pixelRatio) * container.retina.reduceFactor, moveDrift = (_b = (_e = particle.retina).moveDrift) !== null && _b !== void 0 ? _b : _e.moveDrift = getRangeValue(particle.options.move.drift) * container.retina.pixelRatio, maxSize = getRangeMax(particleOptions.size.value) * container.retina.pixelRatio, sizeFactor = moveOptions.size ? particle.getRadius() / maxSize : 1, diffFactor = 2, speedFactor = sizeFactor * slowFactor * (delta.factor || 1) / diffFactor, moveSpeed = baseSpeed * speedFactor;
4482 this.applyPath(particle, delta);
4483 const gravityOptions = moveOptions.gravity;
4484 const gravityFactor = gravityOptions.enable && gravityOptions.inverse ? -1 : 1;
4485 if (gravityOptions.enable && moveSpeed) {
4486 particle.velocity.y += gravityFactor * (gravityOptions.acceleration * delta.factor) / (60 * moveSpeed);
4487 }
4488 if (moveDrift && moveSpeed) {
4489 particle.velocity.x += moveDrift * delta.factor / (60 * moveSpeed);
4490 }
4491 const decay = particle.moveDecay;
4492 if (decay != 1) {
4493 particle.velocity.multTo(decay);
4494 }
4495 const velocity = particle.velocity.mult(moveSpeed);
4496 const maxSpeed = (_c = particle.retina.maxSpeed) !== null && _c !== void 0 ? _c : container.retina.maxSpeed;
4497 if (gravityOptions.enable && gravityOptions.maxSpeed > 0 && (!gravityOptions.inverse && velocity.y >= 0 && velocity.y >= maxSpeed || gravityOptions.inverse && velocity.y <= 0 && velocity.y <= -maxSpeed)) {
4498 velocity.y = gravityFactor * maxSpeed;
4499 if (moveSpeed) {
4500 particle.velocity.y = velocity.y / moveSpeed;
4501 }
4502 }
4503 const zIndexOptions = particle.options.zIndex, zVelocityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
4504 if (moveOptions.spin.enable) {
4505 this.spin(particle, moveSpeed);
4506 } else {
4507 if (zVelocityFactor != 1) {
4508 velocity.multTo(zVelocityFactor);
4509 }
4510 particle.position.addTo(velocity);
4511 if (moveOptions.vibrate) {
4512 particle.position.x += Math.sin(particle.position.x * Math.cos(particle.position.y));
4513 particle.position.y += Math.cos(particle.position.y * Math.sin(particle.position.x));
4514 }
4515 }
4516 applyDistance(particle);
4517 }
4518 spin(particle, moveSpeed) {
4519 const container = this.container;
4520 if (!particle.spin) {
4521 return;
4522 }
4523 const updateFunc = {
4524 x: particle.spin.direction === RotateDirection.clockwise ? Math.cos : Math.sin,
4525 y: particle.spin.direction === RotateDirection.clockwise ? Math.sin : Math.cos
4526 };
4527 particle.position.x = particle.spin.center.x + particle.spin.radius * updateFunc.x(particle.spin.angle);
4528 particle.position.y = particle.spin.center.y + particle.spin.radius * updateFunc.y(particle.spin.angle);
4529 particle.spin.radius += particle.spin.acceleration;
4530 const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height);
4531 if (particle.spin.radius > maxCanvasSize / 2) {
4532 particle.spin.radius = maxCanvasSize / 2;
4533 particle.spin.acceleration *= -1;
4534 } else if (particle.spin.radius < 0) {
4535 particle.spin.radius = 0;
4536 particle.spin.acceleration *= -1;
4537 }
4538 particle.spin.angle += moveSpeed / 100 * (1 - particle.spin.radius / maxCanvasSize);
4539 }
4540 applyPath(particle, delta) {
4541 const particlesOptions = particle.options;
4542 const pathOptions = particlesOptions.move.path;
4543 const pathEnabled = pathOptions.enable;
4544 if (!pathEnabled) {
4545 return;
4546 }
4547 const container = this.container;
4548 if (particle.lastPathTime <= particle.pathDelay) {
4549 particle.lastPathTime += delta.value;
4550 return;
4551 }
4552 const path = container.pathGenerator.generate(particle);
4553 particle.velocity.addTo(path);
4554 if (pathOptions.clamp) {
4555 particle.velocity.x = clamp(particle.velocity.x, -1, 1);
4556 particle.velocity.y = clamp(particle.velocity.y, -1, 1);
4557 }
4558 particle.lastPathTime -= particle.pathDelay;
4559 }
4560 moveParallax(particle) {
4561 const container = this.container;
4562 const options = container.actualOptions;
4563 if (isSsr() || !options.interactivity.events.onHover.parallax.enable) {
4564 return;
4565 }
4566 const parallaxForce = options.interactivity.events.onHover.parallax.force;
4567 const mousePos = container.interactivity.mouse.position;
4568 if (!mousePos) {
4569 return;
4570 }
4571 const canvasCenter = {
4572 x: container.canvas.size.width / 2,
4573 y: container.canvas.size.height / 2
4574 };
4575 const parallaxSmooth = options.interactivity.events.onHover.parallax.smooth;
4576 const factor = particle.getRadius() / parallaxForce;
4577 const tmp = {
4578 x: (mousePos.x - canvasCenter.x) * factor,
4579 y: (mousePos.y - canvasCenter.y) * factor
4580 };
4581 particle.offset.x += (tmp.x - particle.offset.x) / parallaxSmooth;
4582 particle.offset.y += (tmp.y - particle.offset.y) / parallaxSmooth;
4583 }
4584 getProximitySpeedFactor(particle) {
4585 const container = this.container;
4586 const options = container.actualOptions;
4587 const active = isInArray(HoverMode.slow, options.interactivity.events.onHover.mode);
4588 if (!active) {
4589 return 1;
4590 }
4591 const mousePos = this.container.interactivity.mouse.position;
4592 if (!mousePos) {
4593 return 1;
4594 }
4595 const particlePos = particle.getPosition();
4596 const dist = getDistance(mousePos, particlePos);
4597 const radius = container.retina.slowModeRadius;
4598 if (dist > radius) {
4599 return 1;
4600 }
4601 const proximityFactor = dist / radius || 0;
4602 const slowFactor = options.interactivity.modes.slow.factor;
4603 return proximityFactor / slowFactor;
4604 }
4605 }
4606 class Particles {
4607 constructor(container) {
4608 this.container = container;
4609 this.nextId = 0;
4610 this.array = [];
4611 this.zArray = [];
4612 this.mover = new Mover(container);
4613 this.limit = 0;
4614 this.needsSort = false;
4615 this.lastZIndex = 0;
4616 this.freqs = {
4617 links: new Map,
4618 triangles: new Map
4619 };
4620 this.interactionManager = new InteractionManager(container);
4621 const canvasSize = this.container.canvas.size;
4622 this.linksColors = new Map;
4623 this.quadTree = new QuadTree(new Rectangle(-canvasSize.width / 4, -canvasSize.height / 4, canvasSize.width * 3 / 2, canvasSize.height * 3 / 2), 4);
4624 this.updaters = Plugins.getUpdaters(container);
4625 }
4626 get count() {
4627 return this.array.length;
4628 }
4629 init() {
4630 var _a;
4631 const container = this.container;
4632 const options = container.actualOptions;
4633 this.lastZIndex = 0;
4634 this.needsSort = false;
4635 this.freqs.links = new Map;
4636 this.freqs.triangles = new Map;
4637 let handled = false;
4638 for (const [, plugin] of container.plugins) {
4639 if (plugin.particlesInitialization !== undefined) {
4640 handled = plugin.particlesInitialization();
4641 }
4642 if (handled) {
4643 break;
4644 }
4645 }
4646 this.addManualParticles();
4647 if (!handled) {
4648 for (const group in options.particles.groups) {
4649 const groupOptions = options.particles.groups[group];
4650 for (let i = this.count, j = 0; j < ((_a = groupOptions.number) === null || _a === void 0 ? void 0 : _a.value) && i < options.particles.number.value; i++,
4651 j++) {
4652 this.addParticle(undefined, groupOptions, group);
4653 }
4654 }
4655 for (let i = this.count; i < options.particles.number.value; i++) {
4656 this.addParticle();
4657 }
4658 }
4659 container.pathGenerator.init(container);
4660 }
4661 redraw() {
4662 this.clear();
4663 this.init();
4664 this.draw({
4665 value: 0,
4666 factor: 0
4667 });
4668 }
4669 removeAt(index, quantity = 1, group, override) {
4670 if (!(index >= 0 && index <= this.count)) {
4671 return;
4672 }
4673 let deleted = 0;
4674 for (let i = index; deleted < quantity && i < this.count; i++) {
4675 const particle = this.array[i];
4676 if (!particle || particle.group !== group) {
4677 continue;
4678 }
4679 particle.destroy(override);
4680 this.array.splice(i--, 1);
4681 const zIdx = this.zArray.indexOf(particle);
4682 this.zArray.splice(zIdx, 1);
4683 deleted++;
4684 }
4685 }
4686 remove(particle, group, override) {
4687 this.removeAt(this.array.indexOf(particle), undefined, group, override);
4688 }
4689 update(delta) {
4690 const container = this.container;
4691 const particlesToDelete = [];
4692 container.pathGenerator.update();
4693 for (const [, plugin] of container.plugins) {
4694 if (plugin.update !== undefined) {
4695 plugin.update(delta);
4696 }
4697 }
4698 for (const particle of this.array) {
4699 const resizeFactor = container.canvas.resizeFactor;
4700 if (resizeFactor) {
4701 particle.position.x *= resizeFactor.width;
4702 particle.position.y *= resizeFactor.height;
4703 }
4704 particle.bubble.inRange = false;
4705 for (const [, plugin] of this.container.plugins) {
4706 if (particle.destroyed) {
4707 break;
4708 }
4709 if (plugin.particleUpdate) {
4710 plugin.particleUpdate(particle, delta);
4711 }
4712 }
4713 this.mover.move(particle, delta);
4714 if (particle.destroyed) {
4715 particlesToDelete.push(particle);
4716 continue;
4717 }
4718 this.quadTree.insert(new Point(particle.getPosition(), particle));
4719 }
4720 for (const particle of particlesToDelete) {
4721 this.remove(particle);
4722 }
4723 this.interactionManager.externalInteract(delta);
4724 for (const particle of container.particles.array) {
4725 for (const updater of this.updaters) {
4726 updater.update(particle, delta);
4727 }
4728 if (!particle.destroyed && !particle.spawning) {
4729 this.interactionManager.particlesInteract(particle, delta);
4730 }
4731 }
4732 delete container.canvas.resizeFactor;
4733 }
4734 draw(delta) {
4735 const container = this.container;
4736 container.canvas.clear();
4737 const canvasSize = this.container.canvas.size;
4738 this.quadTree = new QuadTree(new Rectangle(-canvasSize.width / 4, -canvasSize.height / 4, canvasSize.width * 3 / 2, canvasSize.height * 3 / 2), 4);
4739 this.update(delta);
4740 if (this.needsSort) {
4741 this.zArray.sort(((a, b) => b.position.z - a.position.z || a.id - b.id));
4742 this.lastZIndex = this.zArray[this.zArray.length - 1].position.z;
4743 this.needsSort = false;
4744 }
4745 for (const [, plugin] of container.plugins) {
4746 container.canvas.drawPlugin(plugin, delta);
4747 }
4748 for (const p of this.zArray) {
4749 p.draw(delta);
4750 }
4751 }
4752 clear() {
4753 this.array = [];
4754 this.zArray = [];
4755 }
4756 push(nb, mouse, overrideOptions, group) {
4757 this.pushing = true;
4758 for (let i = 0; i < nb; i++) {
4759 this.addParticle(mouse === null || mouse === void 0 ? void 0 : mouse.position, overrideOptions, group);
4760 }
4761 this.pushing = false;
4762 }
4763 addParticle(position, overrideOptions, group) {
4764 const container = this.container;
4765 const options = container.actualOptions;
4766 const limit = options.particles.number.limit * container.density;
4767 if (limit > 0) {
4768 const countToRemove = this.count + 1 - limit;
4769 if (countToRemove > 0) {
4770 this.removeQuantity(countToRemove);
4771 }
4772 }
4773 return this.pushParticle(position, overrideOptions, group);
4774 }
4775 addSplitParticle(parent) {
4776 const splitOptions = parent.options.destroy.split;
4777 const options = new ParticlesOptions;
4778 options.load(parent.options);
4779 const factor = getRangeValue(splitOptions.factor.value);
4780 options.color.load({
4781 value: {
4782 hsl: parent.getFillColor()
4783 }
4784 });
4785 if (typeof options.size.value === "number") {
4786 options.size.value /= factor;
4787 } else {
4788 options.size.value.min /= factor;
4789 options.size.value.max /= factor;
4790 }
4791 options.load(splitOptions.particles);
4792 const offset = splitOptions.sizeOffset ? setRangeValue(-parent.size.value, parent.size.value) : 0;
4793 const position = {
4794 x: parent.position.x + randomInRange(offset),
4795 y: parent.position.y + randomInRange(offset)
4796 };
4797 return this.pushParticle(position, options, parent.group, (particle => {
4798 if (particle.size.value < .5) {
4799 return false;
4800 }
4801 particle.velocity.length = randomInRange(setRangeValue(parent.velocity.length, particle.velocity.length));
4802 particle.splitCount = parent.splitCount + 1;
4803 particle.unbreakable = true;
4804 setTimeout((() => {
4805 particle.unbreakable = false;
4806 }), 500);
4807 return true;
4808 }));
4809 }
4810 removeQuantity(quantity, group) {
4811 this.removeAt(0, quantity, group);
4812 }
4813 getLinkFrequency(p1, p2) {
4814 const key = `${Math.min(p1.id, p2.id)}_${Math.max(p1.id, p2.id)}`;
4815 let res = this.freqs.links.get(key);
4816 if (res === undefined) {
4817 res = Math.random();
4818 this.freqs.links.set(key, res);
4819 }
4820 return res;
4821 }
4822 getTriangleFrequency(p1, p2, p3) {
4823 let [id1, id2, id3] = [ p1.id, p2.id, p3.id ];
4824 if (id1 > id2) {
4825 [id2, id1] = [ id1, id2 ];
4826 }
4827 if (id2 > id3) {
4828 [id3, id2] = [ id2, id3 ];
4829 }
4830 if (id1 > id3) {
4831 [id3, id1] = [ id1, id3 ];
4832 }
4833 const key = `${id1}_${id2}_${id3}`;
4834 let res = this.freqs.triangles.get(key);
4835 if (res === undefined) {
4836 res = Math.random();
4837 this.freqs.triangles.set(key, res);
4838 }
4839 return res;
4840 }
4841 addManualParticles() {
4842 const container = this.container;
4843 const options = container.actualOptions;
4844 for (const particle of options.manualParticles) {
4845 const pos = particle.position ? {
4846 x: particle.position.x * container.canvas.size.width / 100,
4847 y: particle.position.y * container.canvas.size.height / 100
4848 } : undefined;
4849 this.addParticle(pos, particle.options);
4850 }
4851 }
4852 setDensity() {
4853 const options = this.container.actualOptions;
4854 for (const group in options.particles.groups) {
4855 this.applyDensity(options.particles.groups[group], 0, group);
4856 }
4857 this.applyDensity(options.particles, options.manualParticles.length);
4858 }
4859 applyDensity(options, manualCount, group) {
4860 var _a;
4861 if (!((_a = options.number.density) === null || _a === void 0 ? void 0 : _a.enable)) {
4862 return;
4863 }
4864 const numberOptions = options.number;
4865 const densityFactor = this.initDensityFactor(numberOptions.density);
4866 const optParticlesNumber = numberOptions.value;
4867 const optParticlesLimit = numberOptions.limit > 0 ? numberOptions.limit : optParticlesNumber;
4868 const particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + manualCount;
4869 const particlesCount = Math.min(this.count, this.array.filter((t => t.group === group)).length);
4870 this.limit = numberOptions.limit * densityFactor;
4871 if (particlesCount < particlesNumber) {
4872 this.push(Math.abs(particlesNumber - particlesCount), undefined, options, group);
4873 } else if (particlesCount > particlesNumber) {
4874 this.removeQuantity(particlesCount - particlesNumber, group);
4875 }
4876 }
4877 initDensityFactor(densityOptions) {
4878 const container = this.container;
4879 if (!container.canvas.element || !densityOptions.enable) {
4880 return 1;
4881 }
4882 const canvas = container.canvas.element;
4883 const pxRatio = container.retina.pixelRatio;
4884 return canvas.width * canvas.height / (densityOptions.factor * pxRatio ** 2 * densityOptions.area);
4885 }
4886 pushParticle(position, overrideOptions, group, initializer) {
4887 try {
4888 const particle = new Particle(this.nextId, this.container, position, overrideOptions, group);
4889 let canAdd = true;
4890 if (initializer) {
4891 canAdd = initializer(particle);
4892 }
4893 if (!canAdd) {
4894 return;
4895 }
4896 this.array.push(particle);
4897 this.zArray.push(particle);
4898 this.nextId++;
4899 return particle;
4900 } catch (e) {
4901 console.warn(`error adding particle: ${e}`);
4902 return;
4903 }
4904 }
4905 }
4906 class Retina {
4907 constructor(container) {
4908 this.container = container;
4909 }
4910 init() {
4911 const container = this.container;
4912 const options = container.actualOptions;
4913 this.pixelRatio = !options.detectRetina || isSsr() ? 1 : window.devicePixelRatio;
4914 const motionOptions = this.container.actualOptions.motion;
4915 if (motionOptions && (motionOptions.disable || motionOptions.reduce.value)) {
4916 if (isSsr() || typeof matchMedia === "undefined" || !matchMedia) {
4917 this.reduceFactor = 1;
4918 } else {
4919 const mediaQuery = matchMedia("(prefers-reduced-motion: reduce)");
4920 if (mediaQuery) {
4921 this.handleMotionChange(mediaQuery);
4922 const handleChange = () => {
4923 this.handleMotionChange(mediaQuery);
4924 container.refresh().catch((() => {}));
4925 };
4926 if (mediaQuery.addEventListener !== undefined) {
4927 mediaQuery.addEventListener("change", handleChange);
4928 } else if (mediaQuery.addListener !== undefined) {
4929 mediaQuery.addListener(handleChange);
4930 }
4931 }
4932 }
4933 } else {
4934 this.reduceFactor = 1;
4935 }
4936 const ratio = this.pixelRatio;
4937 if (container.canvas.element) {
4938 const element = container.canvas.element;
4939 container.canvas.size.width = element.offsetWidth * ratio;
4940 container.canvas.size.height = element.offsetHeight * ratio;
4941 }
4942 const particles = options.particles;
4943 this.attractDistance = particles.move.attract.distance * ratio;
4944 this.linksDistance = particles.links.distance * ratio;
4945 this.linksWidth = particles.links.width * ratio;
4946 this.sizeAnimationSpeed = particles.size.animation.speed * ratio;
4947 this.maxSpeed = particles.move.gravity.maxSpeed * ratio;
4948 if (particles.orbit.radius !== undefined) {
4949 this.orbitRadius = particles.orbit.radius * this.container.retina.pixelRatio;
4950 }
4951 const modes = options.interactivity.modes;
4952 this.connectModeDistance = modes.connect.distance * ratio;
4953 this.connectModeRadius = modes.connect.radius * ratio;
4954 this.grabModeDistance = modes.grab.distance * ratio;
4955 this.repulseModeDistance = modes.repulse.distance * ratio;
4956 this.bounceModeDistance = modes.bounce.distance * ratio;
4957 this.attractModeDistance = modes.attract.distance * ratio;
4958 this.slowModeRadius = modes.slow.radius * ratio;
4959 this.bubbleModeDistance = modes.bubble.distance * ratio;
4960 if (modes.bubble.size) {
4961 this.bubbleModeSize = modes.bubble.size * ratio;
4962 }
4963 }
4964 initParticle(particle) {
4965 const options = particle.options;
4966 const ratio = this.pixelRatio;
4967 const moveDistance = options.move.distance;
4968 const props = particle.retina;
4969 props.attractDistance = options.move.attract.distance * ratio;
4970 props.linksDistance = options.links.distance * ratio;
4971 props.linksWidth = options.links.width * ratio;
4972 props.moveDrift = getRangeValue(options.move.drift) * ratio;
4973 props.moveSpeed = getRangeValue(options.move.speed) * ratio;
4974 props.sizeAnimationSpeed = options.size.animation.speed * ratio;
4975 if (particle.spin) {
4976 props.spinAcceleration = getRangeValue(options.move.spin.acceleration) * ratio;
4977 }
4978 const maxDistance = props.maxDistance;
4979 maxDistance.horizontal = moveDistance.horizontal !== undefined ? moveDistance.horizontal * ratio : undefined;
4980 maxDistance.vertical = moveDistance.vertical !== undefined ? moveDistance.vertical * ratio : undefined;
4981 props.maxSpeed = options.move.gravity.maxSpeed * ratio;
4982 }
4983 handleMotionChange(mediaQuery) {
4984 const options = this.container.actualOptions;
4985 if (mediaQuery.matches) {
4986 const motion = options.motion;
4987 this.reduceFactor = motion.disable ? 0 : motion.reduce.value ? 1 / motion.reduce.factor : 1;
4988 } else {
4989 this.reduceFactor = 1;
4990 }
4991 }
4992 }
4993 class FrameManager {
4994 constructor(container) {
4995 this.container = container;
4996 }
4997 nextFrame(timestamp) {
4998 var _a;
4999 try {
5000 const container = this.container;
5001 if (container.lastFrameTime !== undefined && timestamp < container.lastFrameTime + 1e3 / container.fpsLimit) {
5002 container.draw(false);
5003 return;
5004 }
5005 (_a = container.lastFrameTime) !== null && _a !== void 0 ? _a : container.lastFrameTime = timestamp;
5006 const deltaValue = timestamp - container.lastFrameTime;
5007 const delta = {
5008 value: deltaValue,
5009 factor: 60 * deltaValue / 1e3
5010 };
5011 container.lifeTime += delta.value;
5012 container.lastFrameTime = timestamp;
5013 if (deltaValue > 1e3) {
5014 container.draw(false);
5015 return;
5016 }
5017 container.particles.draw(delta);
5018 if (container.duration > 0 && container.lifeTime > container.duration) {
5019 container.destroy();
5020 return;
5021 }
5022 if (container.getAnimationStatus()) {
5023 container.draw(false);
5024 }
5025 } catch (e) {
5026 console.error("tsParticles error in animation loop", e);
5027 }
5028 }
5029 }
5030 class ClickEvent {
5031 constructor() {
5032 this.enable = false;
5033 this.mode = [];
5034 }
5035 load(data) {
5036 if (data === undefined) {
5037 return;
5038 }
5039 if (data.enable !== undefined) {
5040 this.enable = data.enable;
5041 }
5042 if (data.mode !== undefined) {
5043 this.mode = data.mode;
5044 }
5045 }
5046 }
5047 class DivEvent {
5048 constructor() {
5049 this.selectors = [];
5050 this.enable = false;
5051 this.mode = [];
5052 this.type = DivType.circle;
5053 }
5054 get elementId() {
5055 return this.ids;
5056 }
5057 set elementId(value) {
5058 this.ids = value;
5059 }
5060 get el() {
5061 return this.elementId;
5062 }
5063 set el(value) {
5064 this.elementId = value;
5065 }
5066 get ids() {
5067 return this.selectors instanceof Array ? this.selectors.map((t => t.replace("#", ""))) : this.selectors.replace("#", "");
5068 }
5069 set ids(value) {
5070 this.selectors = value instanceof Array ? value.map((t => `#${t}`)) : `#${value}`;
5071 }
5072 load(data) {
5073 var _a, _b;
5074 if (data === undefined) {
5075 return;
5076 }
5077 const ids = (_b = (_a = data.ids) !== null && _a !== void 0 ? _a : data.elementId) !== null && _b !== void 0 ? _b : data.el;
5078 if (ids !== undefined) {
5079 this.ids = ids;
5080 }
5081 if (data.selectors !== undefined) {
5082 this.selectors = data.selectors;
5083 }
5084 if (data.enable !== undefined) {
5085 this.enable = data.enable;
5086 }
5087 if (data.mode !== undefined) {
5088 this.mode = data.mode;
5089 }
5090 if (data.type !== undefined) {
5091 this.type = data.type;
5092 }
5093 }
5094 }
5095 class Parallax {
5096 constructor() {
5097 this.enable = false;
5098 this.force = 2;
5099 this.smooth = 10;
5100 }
5101 load(data) {
5102 if (data === undefined) {
5103 return;
5104 }
5105 if (data.enable !== undefined) {
5106 this.enable = data.enable;
5107 }
5108 if (data.force !== undefined) {
5109 this.force = data.force;
5110 }
5111 if (data.smooth !== undefined) {
5112 this.smooth = data.smooth;
5113 }
5114 }
5115 }
5116 class HoverEvent {
5117 constructor() {
5118 this.enable = false;
5119 this.mode = [];
5120 this.parallax = new Parallax;
5121 }
5122 load(data) {
5123 if (data === undefined) {
5124 return;
5125 }
5126 if (data.enable !== undefined) {
5127 this.enable = data.enable;
5128 }
5129 if (data.mode !== undefined) {
5130 this.mode = data.mode;
5131 }
5132 this.parallax.load(data.parallax);
5133 }
5134 }
5135 class Events {
5136 constructor() {
5137 this.onClick = new ClickEvent;
5138 this.onDiv = new DivEvent;
5139 this.onHover = new HoverEvent;
5140 this.resize = true;
5141 }
5142 get onclick() {
5143 return this.onClick;
5144 }
5145 set onclick(value) {
5146 this.onClick = value;
5147 }
5148 get ondiv() {
5149 return this.onDiv;
5150 }
5151 set ondiv(value) {
5152 this.onDiv = value;
5153 }
5154 get onhover() {
5155 return this.onHover;
5156 }
5157 set onhover(value) {
5158 this.onHover = value;
5159 }
5160 load(data) {
5161 var _a, _b, _c;
5162 if (data === undefined) {
5163 return;
5164 }
5165 this.onClick.load((_a = data.onClick) !== null && _a !== void 0 ? _a : data.onclick);
5166 const onDiv = (_b = data.onDiv) !== null && _b !== void 0 ? _b : data.ondiv;
5167 if (onDiv !== undefined) {
5168 if (onDiv instanceof Array) {
5169 this.onDiv = onDiv.map((div => {
5170 const tmp = new DivEvent;
5171 tmp.load(div);
5172 return tmp;
5173 }));
5174 } else {
5175 this.onDiv = new DivEvent;
5176 this.onDiv.load(onDiv);
5177 }
5178 }
5179 this.onHover.load((_c = data.onHover) !== null && _c !== void 0 ? _c : data.onhover);
5180 if (data.resize !== undefined) {
5181 this.resize = data.resize;
5182 }
5183 }
5184 }
5185 class BubbleBase {
5186 constructor() {
5187 this.distance = 200;
5188 this.duration = .4;
5189 this.mix = false;
5190 }
5191 load(data) {
5192 if (data === undefined) {
5193 return;
5194 }
5195 if (data.distance !== undefined) {
5196 this.distance = data.distance;
5197 }
5198 if (data.duration !== undefined) {
5199 this.duration = data.duration;
5200 }
5201 if (data.mix !== undefined) {
5202 this.mix = data.mix;
5203 }
5204 if (data.opacity !== undefined) {
5205 this.opacity = data.opacity;
5206 }
5207 if (data.color !== undefined) {
5208 if (data.color instanceof Array) {
5209 this.color = data.color.map((s => OptionsColor.create(undefined, s)));
5210 } else {
5211 if (this.color instanceof Array) {
5212 this.color = new OptionsColor;
5213 }
5214 this.color = OptionsColor.create(this.color, data.color);
5215 }
5216 }
5217 if (data.size !== undefined) {
5218 this.size = data.size;
5219 }
5220 }
5221 }
5222 class BubbleDiv extends BubbleBase {
5223 constructor() {
5224 super();
5225 this.selectors = [];
5226 }
5227 get ids() {
5228 return this.selectors instanceof Array ? this.selectors.map((t => t.replace("#", ""))) : this.selectors.replace("#", "");
5229 }
5230 set ids(value) {
5231 this.selectors = value instanceof Array ? value.map((t => `#${t}`)) : `#${value}`;
5232 }
5233 load(data) {
5234 super.load(data);
5235 if (data === undefined) {
5236 return;
5237 }
5238 if (data.ids !== undefined) {
5239 this.ids = data.ids;
5240 }
5241 if (data.selectors !== undefined) {
5242 this.selectors = data.selectors;
5243 }
5244 }
5245 }
5246 class Bubble extends BubbleBase {
5247 load(data) {
5248 super.load(data);
5249 if (!(data !== undefined && data.divs !== undefined)) {
5250 return;
5251 }
5252 if (data.divs instanceof Array) {
5253 this.divs = data.divs.map((s => {
5254 const tmp = new BubbleDiv;
5255 tmp.load(s);
5256 return tmp;
5257 }));
5258 } else {
5259 if (this.divs instanceof Array || !this.divs) {
5260 this.divs = new BubbleDiv;
5261 }
5262 this.divs.load(data.divs);
5263 }
5264 }
5265 }
5266 class ConnectLinks {
5267 constructor() {
5268 this.opacity = .5;
5269 }
5270 load(data) {
5271 if (!(data !== undefined && data.opacity !== undefined)) {
5272 return;
5273 }
5274 this.opacity = data.opacity;
5275 }
5276 }
5277 class Connect {
5278 constructor() {
5279 this.distance = 80;
5280 this.links = new ConnectLinks;
5281 this.radius = 60;
5282 }
5283 get line_linked() {
5284 return this.links;
5285 }
5286 set line_linked(value) {
5287 this.links = value;
5288 }
5289 get lineLinked() {
5290 return this.links;
5291 }
5292 set lineLinked(value) {
5293 this.links = value;
5294 }
5295 load(data) {
5296 var _a, _b;
5297 if (data === undefined) {
5298 return;
5299 }
5300 if (data.distance !== undefined) {
5301 this.distance = data.distance;
5302 }
5303 this.links.load((_b = (_a = data.links) !== null && _a !== void 0 ? _a : data.lineLinked) !== null && _b !== void 0 ? _b : data.line_linked);
5304 if (data.radius !== undefined) {
5305 this.radius = data.radius;
5306 }
5307 }
5308 }
5309 class GrabLinks {
5310 constructor() {
5311 this.blink = false;
5312 this.consent = false;
5313 this.opacity = 1;
5314 }
5315 load(data) {
5316 if (data === undefined) {
5317 return;
5318 }
5319 if (data.blink !== undefined) {
5320 this.blink = data.blink;
5321 }
5322 if (data.color !== undefined) {
5323 this.color = OptionsColor.create(this.color, data.color);
5324 }
5325 if (data.consent !== undefined) {
5326 this.consent = data.consent;
5327 }
5328 if (data.opacity !== undefined) {
5329 this.opacity = data.opacity;
5330 }
5331 }
5332 }
5333 class Grab {
5334 constructor() {
5335 this.distance = 100;
5336 this.links = new GrabLinks;
5337 }
5338 get line_linked() {
5339 return this.links;
5340 }
5341 set line_linked(value) {
5342 this.links = value;
5343 }
5344 get lineLinked() {
5345 return this.links;
5346 }
5347 set lineLinked(value) {
5348 this.links = value;
5349 }
5350 load(data) {
5351 var _a, _b;
5352 if (data === undefined) {
5353 return;
5354 }
5355 if (data.distance !== undefined) {
5356 this.distance = data.distance;
5357 }
5358 this.links.load((_b = (_a = data.links) !== null && _a !== void 0 ? _a : data.lineLinked) !== null && _b !== void 0 ? _b : data.line_linked);
5359 }
5360 }
5361 class Remove {
5362 constructor() {
5363 this.quantity = 2;
5364 }
5365 get particles_nb() {
5366 return this.quantity;
5367 }
5368 set particles_nb(value) {
5369 this.quantity = value;
5370 }
5371 load(data) {
5372 var _a;
5373 if (data === undefined) {
5374 return;
5375 }
5376 const quantity = (_a = data.quantity) !== null && _a !== void 0 ? _a : data.particles_nb;
5377 if (quantity !== undefined) {
5378 this.quantity = quantity;
5379 }
5380 }
5381 }
5382 class Push {
5383 constructor() {
5384 this.default = true;
5385 this.groups = [];
5386 this.quantity = 4;
5387 }
5388 get particles_nb() {
5389 return this.quantity;
5390 }
5391 set particles_nb(value) {
5392 this.quantity = value;
5393 }
5394 load(data) {
5395 var _a;
5396 if (data === undefined) {
5397 return;
5398 }
5399 if (data.default !== undefined) {
5400 this.default = data.default;
5401 }
5402 if (data.groups !== undefined) {
5403 this.groups = data.groups.map((t => t));
5404 }
5405 if (!this.groups.length) {
5406 this.default = true;
5407 }
5408 const quantity = (_a = data.quantity) !== null && _a !== void 0 ? _a : data.particles_nb;
5409 if (quantity !== undefined) {
5410 this.quantity = quantity;
5411 }
5412 }
5413 }
5414 class RepulseBase {
5415 constructor() {
5416 this.distance = 200;
5417 this.duration = .4;
5418 this.factor = 100;
5419 this.speed = 1;
5420 this.maxSpeed = 50;
5421 this.easing = EasingType.easeOutQuad;
5422 }
5423 load(data) {
5424 if (!data) {
5425 return;
5426 }
5427 if (data.distance !== undefined) {
5428 this.distance = data.distance;
5429 }
5430 if (data.duration !== undefined) {
5431 this.duration = data.duration;
5432 }
5433 if (data.easing !== undefined) {
5434 this.easing = data.easing;
5435 }
5436 if (data.factor !== undefined) {
5437 this.factor = data.factor;
5438 }
5439 if (data.speed !== undefined) {
5440 this.speed = data.speed;
5441 }
5442 if (data.maxSpeed !== undefined) {
5443 this.maxSpeed = data.maxSpeed;
5444 }
5445 }
5446 }
5447 class RepulseDiv extends RepulseBase {
5448 constructor() {
5449 super();
5450 this.selectors = [];
5451 }
5452 get ids() {
5453 if (this.selectors instanceof Array) {
5454 return this.selectors.map((t => t.replace("#", "")));
5455 } else {
5456 return this.selectors.replace("#", "");
5457 }
5458 }
5459 set ids(value) {
5460 if (value instanceof Array) {
5461 this.selectors = value.map((() => `#${value}`));
5462 } else {
5463 this.selectors = `#${value}`;
5464 }
5465 }
5466 load(data) {
5467 super.load(data);
5468 if (data === undefined) {
5469 return;
5470 }
5471 if (data.ids !== undefined) {
5472 this.ids = data.ids;
5473 }
5474 if (data.selectors !== undefined) {
5475 this.selectors = data.selectors;
5476 }
5477 }
5478 }
5479 class Repulse_Repulse extends RepulseBase {
5480 load(data) {
5481 super.load(data);
5482 if ((data === null || data === void 0 ? void 0 : data.divs) === undefined) {
5483 return;
5484 }
5485 if (data.divs instanceof Array) {
5486 this.divs = data.divs.map((s => {
5487 const tmp = new RepulseDiv;
5488 tmp.load(s);
5489 return tmp;
5490 }));
5491 } else {
5492 if (this.divs instanceof Array || !this.divs) {
5493 this.divs = new RepulseDiv;
5494 }
5495 this.divs.load(data.divs);
5496 }
5497 }
5498 }
5499 class Slow {
5500 constructor() {
5501 this.factor = 3;
5502 this.radius = 200;
5503 }
5504 get active() {
5505 return false;
5506 }
5507 set active(_value) {}
5508 load(data) {
5509 if (data === undefined) {
5510 return;
5511 }
5512 if (data.factor !== undefined) {
5513 this.factor = data.factor;
5514 }
5515 if (data.radius !== undefined) {
5516 this.radius = data.radius;
5517 }
5518 }
5519 }
5520 class Trail_Trail {
5521 constructor() {
5522 this.delay = 1;
5523 this.pauseOnStop = false;
5524 this.quantity = 1;
5525 }
5526 load(data) {
5527 if (data === undefined) {
5528 return;
5529 }
5530 if (data.delay !== undefined) {
5531 this.delay = data.delay;
5532 }
5533 if (data.quantity !== undefined) {
5534 this.quantity = data.quantity;
5535 }
5536 if (data.particles !== undefined) {
5537 this.particles = deepExtend({}, data.particles);
5538 }
5539 if (data.pauseOnStop !== undefined) {
5540 this.pauseOnStop = data.pauseOnStop;
5541 }
5542 }
5543 }
5544 class Attract_Attract {
5545 constructor() {
5546 this.distance = 200;
5547 this.duration = .4;
5548 this.easing = EasingType.easeOutQuad;
5549 this.factor = 1;
5550 this.maxSpeed = 50;
5551 this.speed = 1;
5552 }
5553 load(data) {
5554 if (!data) {
5555 return;
5556 }
5557 if (data.distance !== undefined) {
5558 this.distance = data.distance;
5559 }
5560 if (data.duration !== undefined) {
5561 this.duration = data.duration;
5562 }
5563 if (data.easing !== undefined) {
5564 this.easing = data.easing;
5565 }
5566 if (data.factor !== undefined) {
5567 this.factor = data.factor;
5568 }
5569 if (data.maxSpeed !== undefined) {
5570 this.maxSpeed = data.maxSpeed;
5571 }
5572 if (data.speed !== undefined) {
5573 this.speed = data.speed;
5574 }
5575 }
5576 }
5577 class LightGradient {
5578 constructor() {
5579 this.start = new OptionsColor;
5580 this.stop = new OptionsColor;
5581 this.start.value = "#ffffff";
5582 this.stop.value = "#000000";
5583 }
5584 load(data) {
5585 if (data === undefined) {
5586 return;
5587 }
5588 this.start = OptionsColor.create(this.start, data.start);
5589 this.stop = OptionsColor.create(this.stop, data.stop);
5590 }
5591 }
5592 class LightArea {
5593 constructor() {
5594 this.gradient = new LightGradient;
5595 this.radius = 1e3;
5596 }
5597 load(data) {
5598 if (data === undefined) {
5599 return;
5600 }
5601 this.gradient.load(data.gradient);
5602 if (data.radius !== undefined) {
5603 this.radius = data.radius;
5604 }
5605 }
5606 }
5607 class LightShadow {
5608 constructor() {
5609 this.color = new OptionsColor;
5610 this.color.value = "#000000";
5611 this.length = 2e3;
5612 }
5613 load(data) {
5614 if (data === undefined) {
5615 return;
5616 }
5617 this.color = OptionsColor.create(this.color, data.color);
5618 if (data.length !== undefined) {
5619 this.length = data.length;
5620 }
5621 }
5622 }
5623 class Light {
5624 constructor() {
5625 this.area = new LightArea;
5626 this.shadow = new LightShadow;
5627 }
5628 load(data) {
5629 if (data === undefined) {
5630 return;
5631 }
5632 this.area.load(data.area);
5633 this.shadow.load(data.shadow);
5634 }
5635 }
5636 class Bounce_Bounce {
5637 constructor() {
5638 this.distance = 200;
5639 }
5640 load(data) {
5641 if (!data) {
5642 return;
5643 }
5644 if (data.distance !== undefined) {
5645 this.distance = data.distance;
5646 }
5647 }
5648 }
5649 class Modes {
5650 constructor() {
5651 this.attract = new Attract_Attract;
5652 this.bounce = new Bounce_Bounce;
5653 this.bubble = new Bubble;
5654 this.connect = new Connect;
5655 this.grab = new Grab;
5656 this.light = new Light;
5657 this.push = new Push;
5658 this.remove = new Remove;
5659 this.repulse = new Repulse_Repulse;
5660 this.slow = new Slow;
5661 this.trail = new Trail_Trail;
5662 }
5663 load(data) {
5664 if (data === undefined) {
5665 return;
5666 }
5667 this.attract.load(data.attract);
5668 this.bubble.load(data.bubble);
5669 this.connect.load(data.connect);
5670 this.grab.load(data.grab);
5671 this.light.load(data.light);
5672 this.push.load(data.push);
5673 this.remove.load(data.remove);
5674 this.repulse.load(data.repulse);
5675 this.slow.load(data.slow);
5676 this.trail.load(data.trail);
5677 }
5678 }
5679 class Interactivity {
5680 constructor() {
5681 this.detectsOn = InteractivityDetect.canvas;
5682 this.events = new Events;
5683 this.modes = new Modes;
5684 }
5685 get detect_on() {
5686 return this.detectsOn;
5687 }
5688 set detect_on(value) {
5689 this.detectsOn = value;
5690 }
5691 load(data) {
5692 var _a, _b, _c;
5693 if (data === undefined) {
5694 return;
5695 }
5696 const detectsOn = (_a = data.detectsOn) !== null && _a !== void 0 ? _a : data.detect_on;
5697 if (detectsOn !== undefined) {
5698 this.detectsOn = detectsOn;
5699 }
5700 this.events.load(data.events);
5701 this.modes.load(data.modes);
5702 if (((_c = (_b = data.modes) === null || _b === void 0 ? void 0 : _b.slow) === null || _c === void 0 ? void 0 : _c.active) === true) {
5703 if (this.events.onHover.mode instanceof Array) {
5704 if (this.events.onHover.mode.indexOf(HoverMode.slow) < 0) {
5705 this.events.onHover.mode.push(HoverMode.slow);
5706 }
5707 } else if (this.events.onHover.mode !== HoverMode.slow) {
5708 this.events.onHover.mode = [ this.events.onHover.mode, HoverMode.slow ];
5709 }
5710 }
5711 }
5712 }
5713 class BackgroundMaskCover {
5714 constructor() {
5715 this.color = new OptionsColor;
5716 this.opacity = 1;
5717 }
5718 load(data) {
5719 if (data === undefined) {
5720 return;
5721 }
5722 if (data.color !== undefined) {
5723 this.color = OptionsColor.create(this.color, data.color);
5724 }
5725 if (data.opacity !== undefined) {
5726 this.opacity = data.opacity;
5727 }
5728 }
5729 }
5730 class BackgroundMask {
5731 constructor() {
5732 this.composite = "destination-out";
5733 this.cover = new BackgroundMaskCover;
5734 this.enable = false;
5735 }
5736 load(data) {
5737 if (data === undefined) {
5738 return;
5739 }
5740 if (data.composite !== undefined) {
5741 this.composite = data.composite;
5742 }
5743 if (data.cover !== undefined) {
5744 const cover = data.cover;
5745 const color = typeof data.cover === "string" ? {
5746 color: data.cover
5747 } : data.cover;
5748 this.cover.load(cover.color !== undefined ? cover : {
5749 color
5750 });
5751 }
5752 if (data.enable !== undefined) {
5753 this.enable = data.enable;
5754 }
5755 }
5756 }
5757 class Background {
5758 constructor() {
5759 this.color = new OptionsColor;
5760 this.color.value = "";
5761 this.image = "";
5762 this.position = "";
5763 this.repeat = "";
5764 this.size = "";
5765 this.opacity = 1;
5766 }
5767 load(data) {
5768 if (data === undefined) {
5769 return;
5770 }
5771 if (data.color !== undefined) {
5772 this.color = OptionsColor.create(this.color, data.color);
5773 }
5774 if (data.image !== undefined) {
5775 this.image = data.image;
5776 }
5777 if (data.position !== undefined) {
5778 this.position = data.position;
5779 }
5780 if (data.repeat !== undefined) {
5781 this.repeat = data.repeat;
5782 }
5783 if (data.size !== undefined) {
5784 this.size = data.size;
5785 }
5786 if (data.opacity !== undefined) {
5787 this.opacity = data.opacity;
5788 }
5789 }
5790 }
5791 class ThemeDefault {
5792 constructor() {
5793 this.auto = false;
5794 this.mode = ThemeMode.any;
5795 this.value = false;
5796 }
5797 load(data) {
5798 if (!data) {
5799 return;
5800 }
5801 if (data.auto !== undefined) {
5802 this.auto = data.auto;
5803 }
5804 if (data.mode !== undefined) {
5805 this.mode = data.mode;
5806 }
5807 if (data.value !== undefined) {
5808 this.value = data.value;
5809 }
5810 }
5811 }
5812 class Theme {
5813 constructor() {
5814 this.name = "";
5815 this.default = new ThemeDefault;
5816 }
5817 load(data) {
5818 if (data === undefined) {
5819 return;
5820 }
5821 if (data.name !== undefined) {
5822 this.name = data.name;
5823 }
5824 this.default.load(data.default);
5825 if (data.options !== undefined) {
5826 this.options = deepExtend({}, data.options);
5827 }
5828 }
5829 }
5830 class FullScreen {
5831 constructor() {
5832 this.enable = false;
5833 this.zIndex = -1;
5834 }
5835 load(data) {
5836 if (!data) {
5837 return;
5838 }
5839 if (data.enable !== undefined) {
5840 this.enable = data.enable;
5841 }
5842 if (data.zIndex !== undefined) {
5843 this.zIndex = data.zIndex;
5844 }
5845 }
5846 }
5847 class MotionReduce {
5848 constructor() {
5849 this.factor = 4;
5850 this.value = true;
5851 }
5852 load(data) {
5853 if (!data) {
5854 return;
5855 }
5856 if (data.factor !== undefined) {
5857 this.factor = data.factor;
5858 }
5859 if (data.value !== undefined) {
5860 this.value = data.value;
5861 }
5862 }
5863 }
5864 class Motion {
5865 constructor() {
5866 this.disable = false;
5867 this.reduce = new MotionReduce;
5868 }
5869 load(data) {
5870 if (!data) {
5871 return;
5872 }
5873 if (data.disable !== undefined) {
5874 this.disable = data.disable;
5875 }
5876 this.reduce.load(data.reduce);
5877 }
5878 }
5879 class ManualParticle {
5880 load(data) {
5881 var _a, _b;
5882 if (!data) {
5883 return;
5884 }
5885 if (data.position !== undefined) {
5886 this.position = {
5887 x: (_a = data.position.x) !== null && _a !== void 0 ? _a : 50,
5888 y: (_b = data.position.y) !== null && _b !== void 0 ? _b : 50
5889 };
5890 }
5891 if (data.options !== undefined) {
5892 this.options = deepExtend({}, data.options);
5893 }
5894 }
5895 }
5896 class Responsive {
5897 constructor() {
5898 this.maxWidth = Infinity;
5899 this.options = {};
5900 }
5901 load(data) {
5902 if (!data) {
5903 return;
5904 }
5905 if (data.maxWidth !== undefined) {
5906 this.maxWidth = data.maxWidth;
5907 }
5908 if (data.options !== undefined) {
5909 this.options = deepExtend({}, data.options);
5910 }
5911 }
5912 }
5913 var __classPrivateFieldGet = undefined && undefined.__classPrivateFieldGet || function(receiver, state, kind, f) {
5914 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
5915 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5916 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5917 };
5918 var _Options_instances, _Options_findDefaultTheme;
5919 class Options {
5920 constructor() {
5921 _Options_instances.add(this);
5922 this.autoPlay = true;
5923 this.background = new Background;
5924 this.backgroundMask = new BackgroundMask;
5925 this.fullScreen = new FullScreen;
5926 this.detectRetina = true;
5927 this.duration = 0;
5928 this.fpsLimit = 60;
5929 this.interactivity = new Interactivity;
5930 this.manualParticles = [];
5931 this.motion = new Motion;
5932 this.particles = new ParticlesOptions;
5933 this.pauseOnBlur = true;
5934 this.pauseOnOutsideViewport = true;
5935 this.responsive = [];
5936 this.themes = [];
5937 this.zLayers = 100;
5938 }
5939 get fps_limit() {
5940 return this.fpsLimit;
5941 }
5942 set fps_limit(value) {
5943 this.fpsLimit = value;
5944 }
5945 get retina_detect() {
5946 return this.detectRetina;
5947 }
5948 set retina_detect(value) {
5949 this.detectRetina = value;
5950 }
5951 get backgroundMode() {
5952 return this.fullScreen;
5953 }
5954 set backgroundMode(value) {
5955 this.fullScreen.load(value);
5956 }
5957 load(data) {
5958 var _a, _b, _c, _d, _e;
5959 if (data === undefined) {
5960 return;
5961 }
5962 if (data.preset !== undefined) {
5963 if (data.preset instanceof Array) {
5964 for (const preset of data.preset) {
5965 this.importPreset(preset);
5966 }
5967 } else {
5968 this.importPreset(data.preset);
5969 }
5970 }
5971 if (data.autoPlay !== undefined) {
5972 this.autoPlay = data.autoPlay;
5973 }
5974 const detectRetina = (_a = data.detectRetina) !== null && _a !== void 0 ? _a : data.retina_detect;
5975 if (detectRetina !== undefined) {
5976 this.detectRetina = detectRetina;
5977 }
5978 if (data.duration !== undefined) {
5979 this.duration = data.duration;
5980 }
5981 const fpsLimit = (_b = data.fpsLimit) !== null && _b !== void 0 ? _b : data.fps_limit;
5982 if (fpsLimit !== undefined) {
5983 this.fpsLimit = fpsLimit;
5984 }
5985 if (data.pauseOnBlur !== undefined) {
5986 this.pauseOnBlur = data.pauseOnBlur;
5987 }
5988 if (data.pauseOnOutsideViewport !== undefined) {
5989 this.pauseOnOutsideViewport = data.pauseOnOutsideViewport;
5990 }
5991 if (data.zLayers !== undefined) {
5992 this.zLayers = data.zLayers;
5993 }
5994 this.background.load(data.background);
5995 const fullScreen = (_c = data.fullScreen) !== null && _c !== void 0 ? _c : data.backgroundMode;
5996 if (typeof fullScreen === "boolean") {
5997 this.fullScreen.enable = fullScreen;
5998 } else {
5999 this.fullScreen.load(fullScreen);
6000 }
6001 this.backgroundMask.load(data.backgroundMask);
6002 this.interactivity.load(data.interactivity);
6003 if (data.manualParticles !== undefined) {
6004 this.manualParticles = data.manualParticles.map((t => {
6005 const tmp = new ManualParticle;
6006 tmp.load(t);
6007 return tmp;
6008 }));
6009 }
6010 this.motion.load(data.motion);
6011 this.particles.load(data.particles);
6012 Plugins.loadOptions(this, data);
6013 if (data.responsive !== undefined) {
6014 for (const responsive of data.responsive) {
6015 const optResponsive = new Responsive;
6016 optResponsive.load(responsive);
6017 this.responsive.push(optResponsive);
6018 }
6019 }
6020 this.responsive.sort(((a, b) => a.maxWidth - b.maxWidth));
6021 if (data.themes !== undefined) {
6022 for (const theme of data.themes) {
6023 const optTheme = new Theme;
6024 optTheme.load(theme);
6025 this.themes.push(optTheme);
6026 }
6027 }
6028 this.defaultDarkTheme = (_d = __classPrivateFieldGet(this, _Options_instances, "m", _Options_findDefaultTheme).call(this, ThemeMode.dark)) === null || _d === void 0 ? void 0 : _d.name;
6029 this.defaultLightTheme = (_e = __classPrivateFieldGet(this, _Options_instances, "m", _Options_findDefaultTheme).call(this, ThemeMode.light)) === null || _e === void 0 ? void 0 : _e.name;
6030 }
6031 setTheme(name) {
6032 if (name) {
6033 const chosenTheme = this.themes.find((theme => theme.name === name));
6034 if (chosenTheme) {
6035 this.load(chosenTheme.options);
6036 }
6037 } else {
6038 const mediaMatch = typeof matchMedia !== "undefined" && matchMedia("(prefers-color-scheme: dark)"), clientDarkMode = mediaMatch && mediaMatch.matches, defaultTheme = __classPrivateFieldGet(this, _Options_instances, "m", _Options_findDefaultTheme).call(this, clientDarkMode ? ThemeMode.dark : ThemeMode.light);
6039 if (defaultTheme) {
6040 this.load(defaultTheme.options);
6041 }
6042 }
6043 }
6044 setResponsive(width, pxRatio, defaultOptions) {
6045 this.load(defaultOptions);
6046 const responsiveOptions = this.responsive.find((t => t.maxWidth * pxRatio > width));
6047 this.load(responsiveOptions === null || responsiveOptions === void 0 ? void 0 : responsiveOptions.options);
6048 return responsiveOptions === null || responsiveOptions === void 0 ? void 0 : responsiveOptions.maxWidth;
6049 }
6050 importPreset(preset) {
6051 this.load(Plugins.getPreset(preset));
6052 }
6053 }
6054 _Options_instances = new WeakSet, _Options_findDefaultTheme = function _Options_findDefaultTheme(mode) {
6055 var _a;
6056 return (_a = this.themes.find((theme => theme.default.value && theme.default.mode === mode))) !== null && _a !== void 0 ? _a : this.themes.find((theme => theme.default.value && theme.default.mode === ThemeMode.any));
6057 };
6058 class Container {
6059 constructor(id, sourceOptions, ...presets) {
6060 this.id = id;
6061 this.fpsLimit = 60;
6062 this.duration = 0;
6063 this.lifeTime = 0;
6064 this.firstStart = true;
6065 this.started = false;
6066 this.destroyed = false;
6067 this.paused = true;
6068 this.lastFrameTime = 0;
6069 this.zLayers = 100;
6070 this.pageHidden = false;
6071 this._sourceOptions = sourceOptions;
6072 this.retina = new Retina(this);
6073 this.canvas = new Canvas(this);
6074 this.particles = new Particles(this);
6075 this.drawer = new FrameManager(this);
6076 this.pathGenerator = {
6077 generate: () => {
6078 const v = Vector.create(0, 0);
6079 v.length = Math.random();
6080 v.angle = Math.random() * Math.PI * 2;
6081 return v;
6082 },
6083 init: () => {},
6084 update: () => {}
6085 };
6086 this.interactivity = {
6087 mouse: {
6088 clicking: false,
6089 inside: false
6090 }
6091 };
6092 this.bubble = {};
6093 this.repulse = {
6094 particles: []
6095 };
6096 this.attract = {
6097 particles: []
6098 };
6099 this.plugins = new Map;
6100 this.drawers = new Map;
6101 this.density = 1;
6102 this._options = new Options;
6103 this.actualOptions = new Options;
6104 for (const preset of presets) {
6105 this._options.load(Plugins.getPreset(preset));
6106 }
6107 const shapes = Plugins.getSupportedShapes();
6108 for (const type of shapes) {
6109 const drawer = Plugins.getShapeDrawer(type);
6110 if (drawer) {
6111 this.drawers.set(type, drawer);
6112 }
6113 }
6114 this._options.load(this._sourceOptions);
6115 this.eventListeners = new EventListeners(this);
6116 if (typeof IntersectionObserver !== "undefined" && IntersectionObserver) {
6117 this.intersectionObserver = new IntersectionObserver((entries => this.intersectionManager(entries)));
6118 }
6119 }
6120 get options() {
6121 return this._options;
6122 }
6123 get sourceOptions() {
6124 return this._sourceOptions;
6125 }
6126 play(force) {
6127 const needsUpdate = this.paused || force;
6128 if (this.firstStart && !this.actualOptions.autoPlay) {
6129 this.firstStart = false;
6130 return;
6131 }
6132 if (this.paused) {
6133 this.paused = false;
6134 }
6135 if (needsUpdate) {
6136 for (const [, plugin] of this.plugins) {
6137 if (plugin.play) {
6138 plugin.play();
6139 }
6140 }
6141 }
6142 this.draw(needsUpdate || false);
6143 }
6144 pause() {
6145 if (this.drawAnimationFrame !== undefined) {
6146 cancelAnimation()(this.drawAnimationFrame);
6147 delete this.drawAnimationFrame;
6148 }
6149 if (this.paused) {
6150 return;
6151 }
6152 for (const [, plugin] of this.plugins) {
6153 if (plugin.pause) {
6154 plugin.pause();
6155 }
6156 }
6157 if (!this.pageHidden) {
6158 this.paused = true;
6159 }
6160 }
6161 draw(force) {
6162 let refreshTime = force;
6163 this.drawAnimationFrame = animate()((timestamp => {
6164 if (refreshTime) {
6165 this.lastFrameTime = undefined;
6166 refreshTime = false;
6167 }
6168 this.drawer.nextFrame(timestamp);
6169 }));
6170 }
6171 getAnimationStatus() {
6172 return !this.paused && !this.pageHidden;
6173 }
6174 setNoise(noiseOrGenerator, init, update) {
6175 this.setPath(noiseOrGenerator, init, update);
6176 }
6177 setPath(pathOrGenerator, init, update) {
6178 if (!pathOrGenerator) {
6179 return;
6180 }
6181 if (typeof pathOrGenerator === "function") {
6182 this.pathGenerator.generate = pathOrGenerator;
6183 if (init) {
6184 this.pathGenerator.init = init;
6185 }
6186 if (update) {
6187 this.pathGenerator.update = update;
6188 }
6189 } else {
6190 if (pathOrGenerator.generate) {
6191 this.pathGenerator.generate = pathOrGenerator.generate;
6192 }
6193 if (pathOrGenerator.init) {
6194 this.pathGenerator.init = pathOrGenerator.init;
6195 }
6196 if (pathOrGenerator.update) {
6197 this.pathGenerator.update = pathOrGenerator.update;
6198 }
6199 }
6200 }
6201 destroy() {
6202 this.stop();
6203 this.canvas.destroy();
6204 for (const [, drawer] of this.drawers) {
6205 if (drawer.destroy) {
6206 drawer.destroy(this);
6207 }
6208 }
6209 for (const key of this.drawers.keys()) {
6210 this.drawers.delete(key);
6211 }
6212 this.destroyed = true;
6213 }
6214 exportImg(callback) {
6215 this.exportImage(callback);
6216 }
6217 exportImage(callback, type, quality) {
6218 var _a;
6219 return (_a = this.canvas.element) === null || _a === void 0 ? void 0 : _a.toBlob(callback, type !== null && type !== void 0 ? type : "image/png", quality);
6220 }
6221 exportConfiguration() {
6222 return JSON.stringify(this.actualOptions, undefined, 2);
6223 }
6224 refresh() {
6225 this.stop();
6226 return this.start();
6227 }
6228 reset() {
6229 this._options = new Options;
6230 return this.refresh();
6231 }
6232 stop() {
6233 if (!this.started) {
6234 return;
6235 }
6236 this.firstStart = true;
6237 this.started = false;
6238 this.eventListeners.removeListeners();
6239 this.pause();
6240 this.particles.clear();
6241 this.canvas.clear();
6242 if (this.interactivity.element instanceof HTMLElement && this.intersectionObserver) {
6243 this.intersectionObserver.observe(this.interactivity.element);
6244 }
6245 for (const [, plugin] of this.plugins) {
6246 if (plugin.stop) {
6247 plugin.stop();
6248 }
6249 }
6250 for (const key of this.plugins.keys()) {
6251 this.plugins.delete(key);
6252 }
6253 this.particles.linksColors = new Map;
6254 delete this.particles.grabLineColor;
6255 delete this.particles.linksColor;
6256 }
6257 async loadTheme(name) {
6258 this.currentTheme = name;
6259 await this.refresh();
6260 }
6261 async start() {
6262 if (this.started) {
6263 return;
6264 }
6265 await this.init();
6266 this.started = true;
6267 this.eventListeners.addListeners();
6268 if (this.interactivity.element instanceof HTMLElement && this.intersectionObserver) {
6269 this.intersectionObserver.observe(this.interactivity.element);
6270 }
6271 for (const [, plugin] of this.plugins) {
6272 if (plugin.startAsync !== undefined) {
6273 await plugin.startAsync();
6274 } else if (plugin.start !== undefined) {
6275 plugin.start();
6276 }
6277 }
6278 this.play();
6279 }
6280 addClickHandler(callback) {
6281 const el = this.interactivity.element;
6282 if (!el) {
6283 return;
6284 }
6285 const clickOrTouchHandler = (e, pos, radius) => {
6286 if (this.destroyed) {
6287 return;
6288 }
6289 const pxRatio = this.retina.pixelRatio, posRetina = {
6290 x: pos.x * pxRatio,
6291 y: pos.y * pxRatio
6292 }, particles = this.particles.quadTree.queryCircle(posRetina, radius * pxRatio);
6293 callback(e, particles);
6294 };
6295 const clickHandler = e => {
6296 if (this.destroyed) {
6297 return;
6298 }
6299 const mouseEvent = e;
6300 const pos = {
6301 x: mouseEvent.offsetX || mouseEvent.clientX,
6302 y: mouseEvent.offsetY || mouseEvent.clientY
6303 };
6304 clickOrTouchHandler(e, pos, 1);
6305 };
6306 const touchStartHandler = () => {
6307 if (this.destroyed) {
6308 return;
6309 }
6310 touched = true;
6311 touchMoved = false;
6312 };
6313 const touchMoveHandler = () => {
6314 if (this.destroyed) {
6315 return;
6316 }
6317 touchMoved = true;
6318 };
6319 const touchEndHandler = e => {
6320 var _a, _b, _c;
6321 if (this.destroyed) {
6322 return;
6323 }
6324 if (touched && !touchMoved) {
6325 const touchEvent = e;
6326 let lastTouch = touchEvent.touches[touchEvent.touches.length - 1];
6327 if (!lastTouch) {
6328 lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - 1];
6329 if (!lastTouch) {
6330 return;
6331 }
6332 }
6333 const canvasRect = (_a = this.canvas.element) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
6334 const pos = {
6335 x: lastTouch.clientX - ((_b = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.left) !== null && _b !== void 0 ? _b : 0),
6336 y: lastTouch.clientY - ((_c = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.top) !== null && _c !== void 0 ? _c : 0)
6337 };
6338 clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
6339 }
6340 touched = false;
6341 touchMoved = false;
6342 };
6343 const touchCancelHandler = () => {
6344 if (this.destroyed) {
6345 return;
6346 }
6347 touched = false;
6348 touchMoved = false;
6349 };
6350 let touched = false;
6351 let touchMoved = false;
6352 el.addEventListener("click", clickHandler);
6353 el.addEventListener("touchstart", touchStartHandler);
6354 el.addEventListener("touchmove", touchMoveHandler);
6355 el.addEventListener("touchend", touchEndHandler);
6356 el.addEventListener("touchcancel", touchCancelHandler);
6357 }
6358 updateActualOptions() {
6359 this.actualOptions.responsive = [];
6360 const newMaxWidth = this.actualOptions.setResponsive(this.canvas.size.width, this.retina.pixelRatio, this._options);
6361 this.actualOptions.setTheme(this.currentTheme);
6362 if (this.responsiveMaxWidth != newMaxWidth) {
6363 this.responsiveMaxWidth = newMaxWidth;
6364 return true;
6365 }
6366 return false;
6367 }
6368 async init() {
6369 this.actualOptions = new Options;
6370 this.actualOptions.load(this._options);
6371 this.retina.init();
6372 this.canvas.init();
6373 this.updateActualOptions();
6374 this.canvas.initBackground();
6375 this.canvas.resize();
6376 this.zLayers = this.actualOptions.zLayers;
6377 this.duration = getRangeValue(this.actualOptions.duration);
6378 this.lifeTime = 0;
6379 this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 60;
6380 const availablePlugins = Plugins.getAvailablePlugins(this);
6381 for (const [id, plugin] of availablePlugins) {
6382 this.plugins.set(id, plugin);
6383 }
6384 for (const [, drawer] of this.drawers) {
6385 if (drawer.init) {
6386 await drawer.init(this);
6387 }
6388 }
6389 for (const [, plugin] of this.plugins) {
6390 if (plugin.init) {
6391 plugin.init(this.actualOptions);
6392 } else if (plugin.initAsync !== undefined) {
6393 await plugin.initAsync(this.actualOptions);
6394 }
6395 }
6396 const pathOptions = this.actualOptions.particles.move.path;
6397 if (pathOptions.generator) {
6398 const customGenerator = Plugins.getPathGenerator(pathOptions.generator);
6399 if (customGenerator) {
6400 if (customGenerator.init) {
6401 this.pathGenerator.init = customGenerator.init;
6402 }
6403 if (customGenerator.generate) {
6404 this.pathGenerator.generate = customGenerator.generate;
6405 }
6406 if (customGenerator.update) {
6407 this.pathGenerator.update = customGenerator.update;
6408 }
6409 }
6410 }
6411 this.particles.init();
6412 this.particles.setDensity();
6413 for (const [, plugin] of this.plugins) {
6414 if (plugin.particlesSetup !== undefined) {
6415 plugin.particlesSetup();
6416 }
6417 }
6418 }
6419 intersectionManager(entries) {
6420 if (!this.actualOptions.pauseOnOutsideViewport) {
6421 return;
6422 }
6423 for (const entry of entries) {
6424 if (entry.target !== this.interactivity.element) {
6425 continue;
6426 }
6427 if (entry.isIntersecting) {
6428 this.play();
6429 } else {
6430 this.pause();
6431 }
6432 }
6433 }
6434 }
6435 const tsParticlesDom = [];
6436 function fetchError(statusCode) {
6437 console.error(`Error tsParticles - fetch status: ${statusCode}`);
6438 console.error("Error tsParticles - File config not found");
6439 }
6440 class Loader {
6441 static dom() {
6442 return tsParticlesDom;
6443 }
6444 static domItem(index) {
6445 const dom = Loader.dom();
6446 const item = dom[index];
6447 if (item && !item.destroyed) {
6448 return item;
6449 }
6450 dom.splice(index, 1);
6451 }
6452 static async loadOptions(params) {
6453 var _a, _b, _c;
6454 const tagId = (_a = params.tagId) !== null && _a !== void 0 ? _a : `tsparticles${Math.floor(Math.random() * 1e4)}`;
6455 const {options, index} = params;
6456 let domContainer = (_b = params.element) !== null && _b !== void 0 ? _b : document.getElementById(tagId);
6457 if (!domContainer) {
6458 domContainer = document.createElement("div");
6459 domContainer.id = tagId;
6460 (_c = document.querySelector("body")) === null || _c === void 0 ? void 0 : _c.append(domContainer);
6461 }
6462 const currentOptions = options instanceof Array ? itemFromArray(options, index) : options;
6463 const dom = Loader.dom();
6464 const oldIndex = dom.findIndex((v => v.id === tagId));
6465 if (oldIndex >= 0) {
6466 const old = Loader.domItem(oldIndex);
6467 if (old && !old.destroyed) {
6468 old.destroy();
6469 dom.splice(oldIndex, 1);
6470 }
6471 }
6472 let canvasEl;
6473 let generatedCanvas;
6474 if (domContainer.tagName.toLowerCase() === "canvas") {
6475 canvasEl = domContainer;
6476 generatedCanvas = false;
6477 } else {
6478 const existingCanvases = domContainer.getElementsByTagName("canvas");
6479 if (existingCanvases.length) {
6480 canvasEl = existingCanvases[0];
6481 if (!canvasEl.className) {
6482 canvasEl.className = Constants.canvasClass;
6483 }
6484 generatedCanvas = false;
6485 } else {
6486 generatedCanvas = true;
6487 canvasEl = document.createElement("canvas");
6488 canvasEl.className = Constants.canvasClass;
6489 canvasEl.style.width = "100%";
6490 canvasEl.style.height = "100%";
6491 domContainer.appendChild(canvasEl);
6492 }
6493 }
6494 const newItem = new Container(tagId, currentOptions);
6495 if (oldIndex >= 0) {
6496 dom.splice(oldIndex, 0, newItem);
6497 } else {
6498 dom.push(newItem);
6499 }
6500 newItem.canvas.loadCanvas(canvasEl, generatedCanvas);
6501 await newItem.start();
6502 return newItem;
6503 }
6504 static async loadRemoteOptions(params) {
6505 const {url: jsonUrl, index} = params;
6506 const url = jsonUrl instanceof Array ? itemFromArray(jsonUrl, index) : jsonUrl;
6507 if (!url) {
6508 return;
6509 }
6510 const response = await fetch(url);
6511 if (!response.ok) {
6512 fetchError(response.status);
6513 return;
6514 }
6515 const data = await response.json();
6516 return await Loader.loadOptions({
6517 tagId: params.tagId,
6518 element: params.element,
6519 index,
6520 options: data
6521 });
6522 }
6523 static load(tagId, options, index) {
6524 const params = {
6525 index
6526 };
6527 if (typeof tagId === "string") {
6528 params.tagId = tagId;
6529 } else {
6530 params.options = tagId;
6531 }
6532 if (typeof options === "number") {
6533 params.index = options !== null && options !== void 0 ? options : params.index;
6534 } else {
6535 params.options = options !== null && options !== void 0 ? options : params.options;
6536 }
6537 return this.loadOptions(params);
6538 }
6539 static async set(id, domContainer, options, index) {
6540 const params = {
6541 index
6542 };
6543 if (typeof id === "string") {
6544 params.tagId = id;
6545 } else {
6546 params.element = id;
6547 }
6548 if (domContainer instanceof HTMLElement) {
6549 params.element = domContainer;
6550 } else {
6551 params.options = domContainer;
6552 }
6553 if (typeof options === "number") {
6554 params.index = options;
6555 } else {
6556 params.options = options !== null && options !== void 0 ? options : params.options;
6557 }
6558 return this.loadOptions(params);
6559 }
6560 static async loadJSON(tagId, jsonUrl, index) {
6561 let url, id;
6562 if (typeof jsonUrl === "number" || jsonUrl === undefined) {
6563 url = tagId;
6564 } else {
6565 id = tagId;
6566 url = jsonUrl;
6567 }
6568 return await Loader.loadRemoteOptions({
6569 tagId: id,
6570 url,
6571 index
6572 });
6573 }
6574 static async setJSON(id, domContainer, jsonUrl, index) {
6575 let url, newId, newIndex, element;
6576 if (id instanceof HTMLElement) {
6577 element = id;
6578 url = domContainer;
6579 newIndex = jsonUrl;
6580 } else {
6581 newId = id;
6582 element = domContainer;
6583 url = jsonUrl;
6584 newIndex = index;
6585 }
6586 return await Loader.loadRemoteOptions({
6587 tagId: newId,
6588 url,
6589 index: newIndex,
6590 element
6591 });
6592 }
6593 static setOnClickHandler(callback) {
6594 const dom = Loader.dom();
6595 if (dom.length === 0) {
6596 throw new Error("Can only set click handlers after calling tsParticles.load() or tsParticles.loadJSON()");
6597 }
6598 for (const domItem of dom) {
6599 domItem.addClickHandler(callback);
6600 }
6601 }
6602 }
6603 var __classPrivateFieldSet = undefined && undefined.__classPrivateFieldSet || function(receiver, state, value, kind, f) {
6604 if (kind === "m") throw new TypeError("Private method is not writable");
6605 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
6606 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6607 return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value),
6608 value;
6609 };
6610 var main_classPrivateFieldGet = undefined && undefined.__classPrivateFieldGet || function(receiver, state, kind, f) {
6611 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
6612 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
6613 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6614 };
6615 var _Main_initialized;
6616 class Main {
6617 constructor() {
6618 _Main_initialized.set(this, void 0);
6619 __classPrivateFieldSet(this, _Main_initialized, false, "f");
6620 }
6621 init() {
6622 if (!main_classPrivateFieldGet(this, _Main_initialized, "f")) {
6623 __classPrivateFieldSet(this, _Main_initialized, true, "f");
6624 }
6625 }
6626 async loadFromArray(tagId, options, index) {
6627 return Loader.load(tagId, options, index);
6628 }
6629 async load(tagId, options) {
6630 return Loader.load(tagId, options);
6631 }
6632 async set(id, element, options) {
6633 return Loader.set(id, element, options);
6634 }
6635 async loadJSON(tagId, pathConfigJson, index) {
6636 return Loader.loadJSON(tagId, pathConfigJson, index);
6637 }
6638 async setJSON(id, element, pathConfigJson, index) {
6639 return Loader.setJSON(id, element, pathConfigJson, index);
6640 }
6641 setOnClickHandler(callback) {
6642 Loader.setOnClickHandler(callback);
6643 }
6644 dom() {
6645 return Loader.dom();
6646 }
6647 domItem(index) {
6648 return Loader.domItem(index);
6649 }
6650 addShape(shape, drawer, init, afterEffect, destroy) {
6651 let customDrawer;
6652 if (typeof drawer === "function") {
6653 customDrawer = {
6654 afterEffect,
6655 destroy,
6656 draw: drawer,
6657 init
6658 };
6659 } else {
6660 customDrawer = drawer;
6661 }
6662 Plugins.addShapeDrawer(shape, customDrawer);
6663 }
6664 addPreset(preset, options, override = false) {
6665 Plugins.addPreset(preset, options, override);
6666 }
6667 addPlugin(plugin) {
6668 Plugins.addPlugin(plugin);
6669 }
6670 addPathGenerator(name, generator) {
6671 Plugins.addPathGenerator(name, generator);
6672 }
6673 addInteractor(name, interactorInitializer) {
6674 Plugins.addInteractor(name, interactorInitializer);
6675 }
6676 addParticleUpdater(name, updaterInitializer) {
6677 Plugins.addParticleUpdater(name, updaterInitializer);
6678 }
6679 }
6680 _Main_initialized = new WeakMap;
6681 class CircleDrawer {
6682 getSidesCount() {
6683 return 12;
6684 }
6685 draw(context, particle, radius) {
6686 context.arc(0, 0, radius, 0, Math.PI * 2, false);
6687 }
6688 }
6689 function loadCircleShape(tsParticles) {
6690 tsParticles.addShape("circle", new CircleDrawer);
6691 }
6692 class LifeUpdater {
6693 constructor(container) {
6694 this.container = container;
6695 }
6696 init() {}
6697 isEnabled(particle) {
6698 return !particle.destroyed;
6699 }
6700 update(particle, delta) {
6701 if (!this.isEnabled(particle)) {
6702 return;
6703 }
6704 const life = particle.life;
6705 let justSpawned = false;
6706 if (particle.spawning) {
6707 life.delayTime += delta.value;
6708 if (life.delayTime >= particle.life.delay) {
6709 justSpawned = true;
6710 particle.spawning = false;
6711 life.delayTime = 0;
6712 life.time = 0;
6713 } else {
6714 return;
6715 }
6716 }
6717 if (life.duration === -1) {
6718 return;
6719 }
6720 if (particle.spawning) {
6721 return;
6722 }
6723 if (justSpawned) {
6724 life.time = 0;
6725 } else {
6726 life.time += delta.value;
6727 }
6728 if (life.time < life.duration) {
6729 return;
6730 }
6731 life.time = 0;
6732 if (particle.life.count > 0) {
6733 particle.life.count--;
6734 }
6735 if (particle.life.count === 0) {
6736 particle.destroy();
6737 return;
6738 }
6739 const canvasSize = this.container.canvas.size, widthRange = setRangeValue(0, canvasSize.width), heightRange = setRangeValue(0, canvasSize.width);
6740 particle.position.x = randomInRange(widthRange);
6741 particle.position.y = randomInRange(heightRange);
6742 particle.spawning = true;
6743 life.delayTime = 0;
6744 life.time = 0;
6745 particle.reset();
6746 const lifeOptions = particle.options.life;
6747 life.delay = getRangeValue(lifeOptions.delay.value) * 1e3;
6748 life.duration = getRangeValue(lifeOptions.duration.value) * 1e3;
6749 }
6750 }
6751 function loadLifeUpdater(tsParticles) {
6752 tsParticles.addParticleUpdater("life", (container => new LifeUpdater(container)));
6753 }
6754 class ExternalInteractorBase {
6755 constructor(container) {
6756 this.container = container;
6757 this.type = InteractorType.External;
6758 }
6759 }
6760 class Connector extends ExternalInteractorBase {
6761 constructor(container) {
6762 super(container);
6763 }
6764 isEnabled() {
6765 const container = this.container, mouse = container.interactivity.mouse, events = container.actualOptions.interactivity.events;
6766 if (!(events.onHover.enable && mouse.position)) {
6767 return false;
6768 }
6769 return isInArray(HoverMode.connect, events.onHover.mode);
6770 }
6771 reset() {}
6772 interact() {
6773 const container = this.container, options = container.actualOptions;
6774 if (options.interactivity.events.onHover.enable && container.interactivity.status === "mousemove") {
6775 const mousePos = container.interactivity.mouse.position;
6776 if (!mousePos) {
6777 return;
6778 }
6779 const distance = Math.abs(container.retina.connectModeRadius), query = container.particles.quadTree.queryCircle(mousePos, distance);
6780 let i = 0;
6781 for (const p1 of query) {
6782 const pos1 = p1.getPosition();
6783 for (const p2 of query.slice(i + 1)) {
6784 const pos2 = p2.getPosition(), distMax = Math.abs(container.retina.connectModeDistance), xDiff = Math.abs(pos1.x - pos2.x), yDiff = Math.abs(pos1.y - pos2.y);
6785 if (xDiff < distMax && yDiff < distMax) {
6786 container.canvas.drawConnectLine(p1, p2);
6787 }
6788 }
6789 ++i;
6790 }
6791 }
6792 }
6793 }
6794 function loadExternalConnectInteraction(tsParticles) {
6795 tsParticles.addInteractor("externalConnect", (container => new Connector(container)));
6796 }
6797 function checkDestroy(particle, value, minValue, maxValue) {
6798 switch (particle.options.opacity.animation.destroy) {
6799 case DestroyType.max:
6800 if (value >= maxValue) {
6801 particle.destroy();
6802 }
6803 break;
6804
6805 case DestroyType.min:
6806 if (value <= minValue) {
6807 particle.destroy();
6808 }
6809 break;
6810 }
6811 }
6812 function updateOpacity(particle, delta) {
6813 var _a, _b, _c, _d, _e;
6814 if (!particle.opacity) {
6815 return;
6816 }
6817 const minValue = particle.opacity.min;
6818 const maxValue = particle.opacity.max;
6819 if (!(!particle.destroyed && particle.opacity.enable && (((_a = particle.opacity.maxLoops) !== null && _a !== void 0 ? _a : 0) <= 0 || ((_b = particle.opacity.loops) !== null && _b !== void 0 ? _b : 0) < ((_c = particle.opacity.maxLoops) !== null && _c !== void 0 ? _c : 0)))) {
6820 return;
6821 }
6822 switch (particle.opacity.status) {
6823 case AnimationStatus.increasing:
6824 if (particle.opacity.value >= maxValue) {
6825 particle.opacity.status = AnimationStatus.decreasing;
6826 if (!particle.opacity.loops) {
6827 particle.opacity.loops = 0;
6828 }
6829 particle.opacity.loops++;
6830 } else {
6831 particle.opacity.value += ((_d = particle.opacity.velocity) !== null && _d !== void 0 ? _d : 0) * delta.factor;
6832 }
6833 break;
6834
6835 case AnimationStatus.decreasing:
6836 if (particle.opacity.value <= minValue) {
6837 particle.opacity.status = AnimationStatus.increasing;
6838 if (!particle.opacity.loops) {
6839 particle.opacity.loops = 0;
6840 }
6841 particle.opacity.loops++;
6842 } else {
6843 particle.opacity.value -= ((_e = particle.opacity.velocity) !== null && _e !== void 0 ? _e : 0) * delta.factor;
6844 }
6845 break;
6846 }
6847 checkDestroy(particle, particle.opacity.value, minValue, maxValue);
6848 if (!particle.destroyed) {
6849 particle.opacity.value = clamp(particle.opacity.value, minValue, maxValue);
6850 }
6851 }
6852 class OpacityUpdater {
6853 constructor(container) {
6854 this.container = container;
6855 }
6856 init(particle) {
6857 const opacityOptions = particle.options.opacity;
6858 particle.opacity = {
6859 enable: opacityOptions.animation.enable,
6860 max: getRangeMax(opacityOptions.value),
6861 min: getRangeMin(opacityOptions.value),
6862 value: getRangeValue(opacityOptions.value),
6863 loops: 0,
6864 maxLoops: opacityOptions.animation.count
6865 };
6866 const opacityAnimation = opacityOptions.animation;
6867 if (opacityAnimation.enable) {
6868 particle.opacity.status = AnimationStatus.increasing;
6869 const opacityRange = opacityOptions.value;
6870 particle.opacity.min = getRangeMin(opacityRange);
6871 particle.opacity.max = getRangeMax(opacityRange);
6872 switch (opacityAnimation.startValue) {
6873 case StartValueType.min:
6874 particle.opacity.value = particle.opacity.min;
6875 particle.opacity.status = AnimationStatus.increasing;
6876 break;
6877
6878 case StartValueType.random:
6879 particle.opacity.value = randomInRange(particle.opacity);
6880 particle.opacity.status = Math.random() >= .5 ? AnimationStatus.increasing : AnimationStatus.decreasing;
6881 break;
6882
6883 case StartValueType.max:
6884 default:
6885 particle.opacity.value = particle.opacity.max;
6886 particle.opacity.status = AnimationStatus.decreasing;
6887 break;
6888 }
6889 particle.opacity.velocity = opacityAnimation.speed / 100 * this.container.retina.reduceFactor;
6890 if (!opacityAnimation.sync) {
6891 particle.opacity.velocity *= Math.random();
6892 }
6893 }
6894 }
6895 isEnabled(particle) {
6896 var _a, _b, _c;
6897 return !particle.destroyed && !particle.spawning && !!particle.opacity && particle.opacity.enable && (((_a = particle.opacity.maxLoops) !== null && _a !== void 0 ? _a : 0) <= 0 || ((_b = particle.opacity.loops) !== null && _b !== void 0 ? _b : 0) < ((_c = particle.opacity.maxLoops) !== null && _c !== void 0 ? _c : 0));
6898 }
6899 update(particle, delta) {
6900 if (!this.isEnabled(particle)) {
6901 return;
6902 }
6903 updateOpacity(particle, delta);
6904 }
6905 }
6906 function loadOpacityUpdater(tsParticles) {
6907 tsParticles.addParticleUpdater("opacity", (container => new OpacityUpdater(container)));
6908 }
6909 function loadImage(source) {
6910 return new Promise(((resolve, reject) => {
6911 if (!source) {
6912 reject("Error tsParticles - No image.src");
6913 return;
6914 }
6915 const image = {
6916 source,
6917 type: source.substr(source.length - 3)
6918 };
6919 const img = new Image;
6920 img.addEventListener("load", (() => {
6921 image.element = img;
6922 resolve(image);
6923 }));
6924 img.addEventListener("error", (() => {
6925 reject(`Error tsParticles - loading image: ${source}`);
6926 }));
6927 img.src = source;
6928 }));
6929 }
6930 async function downloadSvgImage(source) {
6931 if (!source) {
6932 throw new Error("Error tsParticles - No image.src");
6933 }
6934 const image = {
6935 source,
6936 type: source.substr(source.length - 3)
6937 };
6938 if (image.type !== "svg") {
6939 return loadImage(source);
6940 }
6941 const response = await fetch(image.source);
6942 if (!response.ok) {
6943 throw new Error("Error tsParticles - Image not found");
6944 }
6945 image.svgData = await response.text();
6946 return image;
6947 }
6948 function replaceColorSvg(imageShape, color, opacity) {
6949 const {svgData} = imageShape;
6950 if (!svgData) {
6951 return "";
6952 }
6953 if (svgData.includes("fill")) {
6954 const currentColor = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
6955 return svgData.replace(currentColor, (() => getStyleFromHsl(color, opacity)));
6956 }
6957 const preFillIndex = svgData.indexOf(">");
6958 return `${svgData.substring(0, preFillIndex)} fill="${getStyleFromHsl(color, opacity)}"${svgData.substring(preFillIndex)}`;
6959 }
6960 var ImageDrawer_classPrivateFieldSet = undefined && undefined.__classPrivateFieldSet || function(receiver, state, value, kind, f) {
6961 if (kind === "m") throw new TypeError("Private method is not writable");
6962 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
6963 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6964 return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value),
6965 value;
6966 };
6967 var ImageDrawer_classPrivateFieldGet = undefined && undefined.__classPrivateFieldGet || function(receiver, state, kind, f) {
6968 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
6969 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
6970 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6971 };
6972 var _ImageDrawer_images;
6973 class ImageDrawer {
6974 constructor() {
6975 _ImageDrawer_images.set(this, void 0);
6976 ImageDrawer_classPrivateFieldSet(this, _ImageDrawer_images, [], "f");
6977 }
6978 getSidesCount() {
6979 return 12;
6980 }
6981 getImages(container) {
6982 const containerImages = ImageDrawer_classPrivateFieldGet(this, _ImageDrawer_images, "f").find((t => t.id === container.id));
6983 if (!containerImages) {
6984 ImageDrawer_classPrivateFieldGet(this, _ImageDrawer_images, "f").push({
6985 id: container.id,
6986 images: []
6987 });
6988 return this.getImages(container);
6989 } else {
6990 return containerImages;
6991 }
6992 }
6993 addImage(container, image) {
6994 const containerImages = this.getImages(container);
6995 containerImages === null || containerImages === void 0 ? void 0 : containerImages.images.push(image);
6996 }
6997 async init(container) {
6998 await this.loadImagesFromParticlesOptions(container, container.actualOptions.particles);
6999 await this.loadImagesFromParticlesOptions(container, container.actualOptions.interactivity.modes.trail.particles);
7000 for (const manualParticle of container.actualOptions.manualParticles) {
7001 await this.loadImagesFromParticlesOptions(container, manualParticle.options);
7002 }
7003 const emitterOptions = container.actualOptions;
7004 if (emitterOptions.emitters) {
7005 if (emitterOptions.emitters instanceof Array) {
7006 for (const emitter of emitterOptions.emitters) {
7007 await this.loadImagesFromParticlesOptions(container, emitter.particles);
7008 }
7009 } else {
7010 await this.loadImagesFromParticlesOptions(container, emitterOptions.emitters.particles);
7011 }
7012 }
7013 const interactiveEmitters = emitterOptions.interactivity.modes.emitters;
7014 if (interactiveEmitters) {
7015 if (interactiveEmitters instanceof Array) {
7016 for (const emitter of interactiveEmitters) {
7017 await this.loadImagesFromParticlesOptions(container, emitter.particles);
7018 }
7019 } else {
7020 await this.loadImagesFromParticlesOptions(container, interactiveEmitters.particles);
7021 }
7022 }
7023 }
7024 destroy() {
7025 ImageDrawer_classPrivateFieldSet(this, _ImageDrawer_images, [], "f");
7026 }
7027 async loadImagesFromParticlesOptions(container, options) {
7028 var _a, _b, _c;
7029 const shapeOptions = options === null || options === void 0 ? void 0 : options.shape;
7030 if (!(shapeOptions === null || shapeOptions === void 0 ? void 0 : shapeOptions.type) || !shapeOptions.options || !isInArray(ShapeType.image, shapeOptions.type) && !isInArray(ShapeType.images, shapeOptions.type)) {
7031 return;
7032 }
7033 const idx = ImageDrawer_classPrivateFieldGet(this, _ImageDrawer_images, "f").findIndex((t => t.id === container.id));
7034 if (idx >= 0) {
7035 ImageDrawer_classPrivateFieldGet(this, _ImageDrawer_images, "f").splice(idx, 1);
7036 }
7037 const imageOptions = (_a = shapeOptions.options[ShapeType.images]) !== null && _a !== void 0 ? _a : shapeOptions.options[ShapeType.image];
7038 if (imageOptions instanceof Array) {
7039 for (const optionsImage of imageOptions) {
7040 await this.loadImageShape(container, optionsImage);
7041 }
7042 } else {
7043 await this.loadImageShape(container, imageOptions);
7044 }
7045 if (options === null || options === void 0 ? void 0 : options.groups) {
7046 for (const groupName in options.groups) {
7047 const group = options.groups[groupName];
7048 await this.loadImagesFromParticlesOptions(container, group);
7049 }
7050 }
7051 if ((_c = (_b = options === null || options === void 0 ? void 0 : options.destroy) === null || _b === void 0 ? void 0 : _b.split) === null || _c === void 0 ? void 0 : _c.particles) {
7052 await this.loadImagesFromParticlesOptions(container, options === null || options === void 0 ? void 0 : options.destroy.split.particles);
7053 }
7054 }
7055 async loadImageShape(container, imageShape) {
7056 try {
7057 const imageFunc = imageShape.replaceColor ? downloadSvgImage : loadImage;
7058 const image = await imageFunc(imageShape.src);
7059 if (image) {
7060 this.addImage(container, image);
7061 }
7062 } catch (_a) {
7063 console.warn(`tsParticles error - ${imageShape.src} not found`);
7064 }
7065 }
7066 draw(context, particle, radius, opacity) {
7067 var _a, _b;
7068 if (!context) {
7069 return;
7070 }
7071 const image = particle.image;
7072 const element = (_a = image === null || image === void 0 ? void 0 : image.data) === null || _a === void 0 ? void 0 : _a.element;
7073 if (!element) {
7074 return;
7075 }
7076 const ratio = (_b = image === null || image === void 0 ? void 0 : image.ratio) !== null && _b !== void 0 ? _b : 1;
7077 const pos = {
7078 x: -radius,
7079 y: -radius
7080 };
7081 if (!(image === null || image === void 0 ? void 0 : image.data.svgData) || !(image === null || image === void 0 ? void 0 : image.replaceColor)) {
7082 context.globalAlpha = opacity;
7083 }
7084 context.drawImage(element, pos.x, pos.y, radius * 2, radius * 2 / ratio);
7085 if (!(image === null || image === void 0 ? void 0 : image.data.svgData) || !(image === null || image === void 0 ? void 0 : image.replaceColor)) {
7086 context.globalAlpha = 1;
7087 }
7088 }
7089 loadShape(particle) {
7090 var _a, _b, _c, _d, _e, _f, _g;
7091 if (particle.shape !== "image" && particle.shape !== "images") {
7092 return;
7093 }
7094 const images = this.getImages(particle.container).images;
7095 const imageData = particle.shapeData;
7096 const image = (_a = images.find((t => t.source === imageData.src))) !== null && _a !== void 0 ? _a : images[0];
7097 const color = particle.getFillColor();
7098 let imageRes;
7099 if (!image) {
7100 return;
7101 }
7102 if (image.svgData !== undefined && imageData.replaceColor && color) {
7103 const svgColoredData = replaceColorSvg(image, color, (_c = (_b = particle.opacity) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : 1);
7104 const svg = new Blob([ svgColoredData ], {
7105 type: "image/svg+xml"
7106 });
7107 const domUrl = URL || window.URL || window.webkitURL || window;
7108 const url = domUrl.createObjectURL(svg);
7109 const img = new Image;
7110 imageRes = {
7111 data: Object.assign(Object.assign({}, image), {
7112 svgData: svgColoredData
7113 }),
7114 ratio: imageData.width / imageData.height,
7115 replaceColor: (_d = imageData.replaceColor) !== null && _d !== void 0 ? _d : imageData.replace_color,
7116 source: imageData.src
7117 };
7118 img.addEventListener("load", (() => {
7119 const pImage = particle.image;
7120 if (pImage) {
7121 pImage.loaded = true;
7122 image.element = img;
7123 }
7124 domUrl.revokeObjectURL(url);
7125 }));
7126 img.addEventListener("error", (() => {
7127 domUrl.revokeObjectURL(url);
7128 loadImage(imageData.src).then((img2 => {
7129 const pImage = particle.image;
7130 if (pImage) {
7131 image.element = img2 === null || img2 === void 0 ? void 0 : img2.element;
7132 pImage.loaded = true;
7133 }
7134 }));
7135 }));
7136 img.src = url;
7137 } else {
7138 imageRes = {
7139 data: image,
7140 loaded: true,
7141 ratio: imageData.width / imageData.height,
7142 replaceColor: (_e = imageData.replaceColor) !== null && _e !== void 0 ? _e : imageData.replace_color,
7143 source: imageData.src
7144 };
7145 }
7146 if (!imageRes.ratio) {
7147 imageRes.ratio = 1;
7148 }
7149 const fill = (_f = imageData.fill) !== null && _f !== void 0 ? _f : particle.fill;
7150 const close = (_g = imageData.close) !== null && _g !== void 0 ? _g : particle.close;
7151 const imageShape = {
7152 image: imageRes,
7153 fill,
7154 close
7155 };
7156 particle.image = imageShape.image;
7157 particle.fill = imageShape.fill;
7158 particle.close = imageShape.close;
7159 }
7160 }
7161 _ImageDrawer_images = new WeakMap;
7162 function loadImageShape(tsParticles) {
7163 const imageDrawer = new ImageDrawer;
7164 tsParticles.addShape("image", imageDrawer);
7165 tsParticles.addShape("images", imageDrawer);
7166 }
7167 class PolygonDrawerBase {
7168 getSidesCount(particle) {
7169 var _a, _b;
7170 const polygon = particle.shapeData;
7171 return (_b = (_a = polygon === null || polygon === void 0 ? void 0 : polygon.sides) !== null && _a !== void 0 ? _a : polygon === null || polygon === void 0 ? void 0 : polygon.nb_sides) !== null && _b !== void 0 ? _b : 5;
7172 }
7173 draw(context, particle, radius) {
7174 const start = this.getCenter(particle, radius);
7175 const side = this.getSidesData(particle, radius);
7176 const sideCount = side.count.numerator * side.count.denominator;
7177 const decimalSides = side.count.numerator / side.count.denominator;
7178 const interiorAngleDegrees = 180 * (decimalSides - 2) / decimalSides;
7179 const interiorAngle = Math.PI - Math.PI * interiorAngleDegrees / 180;
7180 if (!context) {
7181 return;
7182 }
7183 context.beginPath();
7184 context.translate(start.x, start.y);
7185 context.moveTo(0, 0);
7186 for (let i = 0; i < sideCount; i++) {
7187 context.lineTo(side.length, 0);
7188 context.translate(side.length, 0);
7189 context.rotate(interiorAngle);
7190 }
7191 }
7192 }
7193 class PolygonDrawer extends PolygonDrawerBase {
7194 getSidesData(particle, radius) {
7195 var _a, _b;
7196 const polygon = particle.shapeData;
7197 const sides = (_b = (_a = polygon === null || polygon === void 0 ? void 0 : polygon.sides) !== null && _a !== void 0 ? _a : polygon === null || polygon === void 0 ? void 0 : polygon.nb_sides) !== null && _b !== void 0 ? _b : 5;
7198 return {
7199 count: {
7200 denominator: 1,
7201 numerator: sides
7202 },
7203 length: radius * 2.66 / (sides / 3)
7204 };
7205 }
7206 getCenter(particle, radius) {
7207 const sides = this.getSidesCount(particle);
7208 return {
7209 x: -radius / (sides / 3.5),
7210 y: -radius / (2.66 / 3.5)
7211 };
7212 }
7213 }
7214 class TriangleDrawer extends PolygonDrawerBase {
7215 getSidesCount() {
7216 return 3;
7217 }
7218 getSidesData(particle, radius) {
7219 return {
7220 count: {
7221 denominator: 2,
7222 numerator: 3
7223 },
7224 length: radius * 2
7225 };
7226 }
7227 getCenter(particle, radius) {
7228 return {
7229 x: -radius,
7230 y: radius / 1.66
7231 };
7232 }
7233 }
7234 function loadGenericPolygonShape(tsParticles) {
7235 tsParticles.addShape("polygon", new PolygonDrawer);
7236 }
7237 function loadTriangleShape(tsParticles) {
7238 tsParticles.addShape("triangle", new TriangleDrawer);
7239 }
7240 function loadPolygonShape(tsParticles) {
7241 loadGenericPolygonShape(tsParticles);
7242 loadTriangleShape(tsParticles);
7243 }
7244 var ProcessBubbleType;
7245 (function(ProcessBubbleType) {
7246 ProcessBubbleType["color"] = "color";
7247 ProcessBubbleType["opacity"] = "opacity";
7248 ProcessBubbleType["size"] = "size";
7249 })(ProcessBubbleType || (ProcessBubbleType = {}));
7250 function calculateBubbleValue(particleValue, modeValue, optionsValue, ratio) {
7251 if (modeValue >= optionsValue) {
7252 const value = particleValue + (modeValue - optionsValue) * ratio;
7253 return clamp(value, particleValue, modeValue);
7254 } else if (modeValue < optionsValue) {
7255 const value = particleValue - (optionsValue - modeValue) * ratio;
7256 return clamp(value, modeValue, particleValue);
7257 }
7258 }
7259 class Bubbler extends ExternalInteractorBase {
7260 constructor(container) {
7261 super(container);
7262 }
7263 isEnabled() {
7264 const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = options.interactivity.events, divs = events.onDiv, divBubble = isDivModeEnabled(DivMode.bubble, divs);
7265 if (!(divBubble || events.onHover.enable && mouse.position || events.onClick.enable && mouse.clickPosition)) {
7266 return false;
7267 }
7268 const hoverMode = events.onHover.mode;
7269 const clickMode = events.onClick.mode;
7270 return isInArray(HoverMode.bubble, hoverMode) || isInArray(ClickMode.bubble, clickMode) || divBubble;
7271 }
7272 reset(particle, force) {
7273 if (!(!particle.bubble.inRange || force)) {
7274 return;
7275 }
7276 delete particle.bubble.div;
7277 delete particle.bubble.opacity;
7278 delete particle.bubble.radius;
7279 delete particle.bubble.color;
7280 }
7281 interact() {
7282 const options = this.container.actualOptions, events = options.interactivity.events, onHover = events.onHover, onClick = events.onClick, hoverEnabled = onHover.enable, hoverMode = onHover.mode, clickEnabled = onClick.enable, clickMode = onClick.mode, divs = events.onDiv;
7283 if (hoverEnabled && isInArray(HoverMode.bubble, hoverMode)) {
7284 this.hoverBubble();
7285 } else if (clickEnabled && isInArray(ClickMode.bubble, clickMode)) {
7286 this.clickBubble();
7287 } else {
7288 divModeExecute(DivMode.bubble, divs, ((selector, div) => this.singleSelectorHover(selector, div)));
7289 }
7290 }
7291 singleSelectorHover(selector, div) {
7292 const container = this.container, selectors = document.querySelectorAll(selector);
7293 if (!selectors.length) {
7294 return;
7295 }
7296 selectors.forEach((item => {
7297 const elem = item, pxRatio = container.retina.pixelRatio, pos = {
7298 x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
7299 y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
7300 }, repulseRadius = elem.offsetWidth / 2 * pxRatio, area = div.type === DivType.circle ? new Circle(pos.x, pos.y, repulseRadius) : new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area);
7301 for (const particle of query) {
7302 if (!area.contains(particle.getPosition())) {
7303 continue;
7304 }
7305 particle.bubble.inRange = true;
7306 const divs = container.actualOptions.interactivity.modes.bubble.divs;
7307 const divBubble = divMode(divs, elem);
7308 if (!particle.bubble.div || particle.bubble.div !== elem) {
7309 this.reset(particle, true);
7310 particle.bubble.div = elem;
7311 }
7312 this.hoverBubbleSize(particle, 1, divBubble);
7313 this.hoverBubbleOpacity(particle, 1, divBubble);
7314 this.hoverBubbleColor(particle, 1, divBubble);
7315 }
7316 }));
7317 }
7318 process(particle, distMouse, timeSpent, data) {
7319 const container = this.container, bubbleParam = data.bubbleObj.optValue;
7320 if (bubbleParam === undefined) {
7321 return;
7322 }
7323 const options = container.actualOptions, bubbleDuration = options.interactivity.modes.bubble.duration, bubbleDistance = container.retina.bubbleModeDistance, particlesParam = data.particlesObj.optValue, pObjBubble = data.bubbleObj.value, pObj = data.particlesObj.value || 0, type = data.type;
7324 if (bubbleParam === particlesParam) {
7325 return;
7326 }
7327 if (!container.bubble.durationEnd) {
7328 if (distMouse <= bubbleDistance) {
7329 const obj = pObjBubble !== null && pObjBubble !== void 0 ? pObjBubble : pObj;
7330 if (obj !== bubbleParam) {
7331 const value = pObj - timeSpent * (pObj - bubbleParam) / bubbleDuration;
7332 if (type === ProcessBubbleType.size) {
7333 particle.bubble.radius = value;
7334 }
7335 if (type === ProcessBubbleType.opacity) {
7336 particle.bubble.opacity = value;
7337 }
7338 }
7339 } else {
7340 if (type === ProcessBubbleType.size) {
7341 delete particle.bubble.radius;
7342 }
7343 if (type === ProcessBubbleType.opacity) {
7344 delete particle.bubble.opacity;
7345 }
7346 }
7347 } else if (pObjBubble) {
7348 if (type === ProcessBubbleType.size) {
7349 delete particle.bubble.radius;
7350 }
7351 if (type === ProcessBubbleType.opacity) {
7352 delete particle.bubble.opacity;
7353 }
7354 }
7355 }
7356 clickBubble() {
7357 var _a, _b;
7358 const container = this.container, options = container.actualOptions, mouseClickPos = container.interactivity.mouse.clickPosition;
7359 if (!mouseClickPos) {
7360 return;
7361 }
7362 const distance = container.retina.bubbleModeDistance, query = container.particles.quadTree.queryCircle(mouseClickPos, distance);
7363 for (const particle of query) {
7364 if (!container.bubble.clicking) {
7365 continue;
7366 }
7367 particle.bubble.inRange = !container.bubble.durationEnd;
7368 const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = ((new Date).getTime() - (container.interactivity.mouse.clickTime || 0)) / 1e3;
7369 if (timeSpent > options.interactivity.modes.bubble.duration) {
7370 container.bubble.durationEnd = true;
7371 }
7372 if (timeSpent > options.interactivity.modes.bubble.duration * 2) {
7373 container.bubble.clicking = false;
7374 container.bubble.durationEnd = false;
7375 }
7376 const sizeData = {
7377 bubbleObj: {
7378 optValue: container.retina.bubbleModeSize,
7379 value: particle.bubble.radius
7380 },
7381 particlesObj: {
7382 optValue: getRangeMax(particle.options.size.value) * container.retina.pixelRatio,
7383 value: particle.size.value
7384 },
7385 type: ProcessBubbleType.size
7386 };
7387 this.process(particle, distMouse, timeSpent, sizeData);
7388 const opacityData = {
7389 bubbleObj: {
7390 optValue: options.interactivity.modes.bubble.opacity,
7391 value: particle.bubble.opacity
7392 },
7393 particlesObj: {
7394 optValue: getRangeMax(particle.options.opacity.value),
7395 value: (_b = (_a = particle.opacity) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 1
7396 },
7397 type: ProcessBubbleType.opacity
7398 };
7399 this.process(particle, distMouse, timeSpent, opacityData);
7400 if (!container.bubble.durationEnd) {
7401 if (distMouse <= container.retina.bubbleModeDistance) {
7402 this.hoverBubbleColor(particle, distMouse);
7403 } else {
7404 delete particle.bubble.color;
7405 }
7406 } else {
7407 delete particle.bubble.color;
7408 }
7409 }
7410 }
7411 hoverBubble() {
7412 const container = this.container, mousePos = container.interactivity.mouse.position;
7413 if (mousePos === undefined) {
7414 return;
7415 }
7416 const distance = container.retina.bubbleModeDistance, query = container.particles.quadTree.queryCircle(mousePos, distance);
7417 for (const particle of query) {
7418 particle.bubble.inRange = true;
7419 const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos), ratio = 1 - pointDistance / distance;
7420 if (pointDistance <= distance) {
7421 if (ratio >= 0 && container.interactivity.status === Constants.mouseMoveEvent) {
7422 this.hoverBubbleSize(particle, ratio);
7423 this.hoverBubbleOpacity(particle, ratio);
7424 this.hoverBubbleColor(particle, ratio);
7425 }
7426 } else {
7427 this.reset(particle);
7428 }
7429 if (container.interactivity.status === Constants.mouseLeaveEvent) {
7430 this.reset(particle);
7431 }
7432 }
7433 }
7434 hoverBubbleSize(particle, ratio, divBubble) {
7435 const container = this.container, modeSize = (divBubble === null || divBubble === void 0 ? void 0 : divBubble.size) ? divBubble.size * container.retina.pixelRatio : container.retina.bubbleModeSize;
7436 if (modeSize === undefined) {
7437 return;
7438 }
7439 const optSize = getRangeMax(particle.options.size.value) * container.retina.pixelRatio;
7440 const pSize = particle.size.value;
7441 const size = calculateBubbleValue(pSize, modeSize, optSize, ratio);
7442 if (size !== undefined) {
7443 particle.bubble.radius = size;
7444 }
7445 }
7446 hoverBubbleOpacity(particle, ratio, divBubble) {
7447 var _a, _b, _c;
7448 const container = this.container, options = container.actualOptions, modeOpacity = (_a = divBubble === null || divBubble === void 0 ? void 0 : divBubble.opacity) !== null && _a !== void 0 ? _a : options.interactivity.modes.bubble.opacity;
7449 if (!modeOpacity) {
7450 return;
7451 }
7452 const optOpacity = particle.options.opacity.value;
7453 const pOpacity = (_c = (_b = particle.opacity) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : 1;
7454 const opacity = calculateBubbleValue(pOpacity, modeOpacity, getRangeMax(optOpacity), ratio);
7455 if (opacity !== undefined) {
7456 particle.bubble.opacity = opacity;
7457 }
7458 }
7459 hoverBubbleColor(particle, ratio, divBubble) {
7460 const options = this.container.actualOptions;
7461 const bubbleOptions = divBubble !== null && divBubble !== void 0 ? divBubble : options.interactivity.modes.bubble;
7462 if (!particle.bubble.finalColor) {
7463 const modeColor = bubbleOptions.color;
7464 if (!modeColor) {
7465 return;
7466 }
7467 const bubbleColor = modeColor instanceof Array ? itemFromArray(modeColor) : modeColor;
7468 particle.bubble.finalColor = colorToHsl(bubbleColor);
7469 }
7470 if (!particle.bubble.finalColor) {
7471 return;
7472 }
7473 if (bubbleOptions.mix) {
7474 particle.bubble.color = undefined;
7475 const pColor = particle.getFillColor();
7476 particle.bubble.color = pColor ? rgbToHsl(colorMix(pColor, particle.bubble.finalColor, 1 - ratio, ratio)) : particle.bubble.finalColor;
7477 } else {
7478 particle.bubble.color = particle.bubble.finalColor;
7479 }
7480 }
7481 }
7482 function loadExternalBubbleInteraction(tsParticles) {
7483 tsParticles.addInteractor("externalBubble", (container => new Bubbler(container)));
7484 }
7485 class Attractor extends ExternalInteractorBase {
7486 constructor(container) {
7487 super(container);
7488 }
7489 isEnabled() {
7490 const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = options.interactivity.events;
7491 if ((!mouse.position || !events.onHover.enable) && (!mouse.clickPosition || !events.onClick.enable)) {
7492 return false;
7493 }
7494 const hoverMode = events.onHover.mode, clickMode = events.onClick.mode;
7495 return isInArray(HoverMode.attract, hoverMode) || isInArray(ClickMode.attract, clickMode);
7496 }
7497 reset() {}
7498 interact() {
7499 const container = this.container, options = container.actualOptions, mouseMoveStatus = container.interactivity.status === Constants.mouseMoveEvent, events = options.interactivity.events, hoverEnabled = events.onHover.enable, hoverMode = events.onHover.mode, clickEnabled = events.onClick.enable, clickMode = events.onClick.mode;
7500 if (mouseMoveStatus && hoverEnabled && isInArray(HoverMode.attract, hoverMode)) {
7501 this.hoverAttract();
7502 } else if (clickEnabled && isInArray(ClickMode.attract, clickMode)) {
7503 this.clickAttract();
7504 }
7505 }
7506 hoverAttract() {
7507 const container = this.container;
7508 const mousePos = container.interactivity.mouse.position;
7509 if (!mousePos) {
7510 return;
7511 }
7512 const attractRadius = container.retina.attractModeDistance;
7513 this.processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius));
7514 }
7515 processAttract(position, attractRadius, area) {
7516 const container = this.container;
7517 const attractOptions = container.actualOptions.interactivity.modes.attract;
7518 const query = container.particles.quadTree.query(area);
7519 for (const particle of query) {
7520 const {dx, dy, distance} = getDistances(particle.position, position);
7521 const velocity = attractOptions.speed * attractOptions.factor;
7522 const attractFactor = clamp(calcEasing(1 - distance / attractRadius, attractOptions.easing) * velocity, 0, attractOptions.maxSpeed);
7523 const normVec = Vector.create(distance === 0 ? velocity : dx / distance * attractFactor, distance === 0 ? velocity : dy / distance * attractFactor);
7524 particle.position.subFrom(normVec);
7525 }
7526 }
7527 clickAttract() {
7528 const container = this.container;
7529 if (!container.attract.finish) {
7530 if (!container.attract.count) {
7531 container.attract.count = 0;
7532 }
7533 container.attract.count++;
7534 if (container.attract.count === container.particles.count) {
7535 container.attract.finish = true;
7536 }
7537 }
7538 if (container.attract.clicking) {
7539 const mousePos = container.interactivity.mouse.clickPosition;
7540 if (!mousePos) {
7541 return;
7542 }
7543 const attractRadius = container.retina.attractModeDistance;
7544 this.processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius));
7545 } else if (container.attract.clicking === false) {
7546 container.attract.particles = [];
7547 }
7548 return;
7549 }
7550 }
7551 function loadExternalAttractInteraction(tsParticles) {
7552 tsParticles.addInteractor("externalAttract", (container => new Attractor(container)));
7553 }
7554 class Grabber extends ExternalInteractorBase {
7555 constructor(container) {
7556 super(container);
7557 }
7558 isEnabled() {
7559 const container = this.container, mouse = container.interactivity.mouse, events = container.actualOptions.interactivity.events;
7560 return events.onHover.enable && !!mouse.position && isInArray(HoverMode.grab, events.onHover.mode);
7561 }
7562 reset() {}
7563 interact() {
7564 var _a;
7565 const container = this.container, options = container.actualOptions, interactivity = options.interactivity;
7566 if (interactivity.events.onHover.enable && container.interactivity.status === Constants.mouseMoveEvent) {
7567 const mousePos = container.interactivity.mouse.position;
7568 if (!mousePos) {
7569 return;
7570 }
7571 const distance = container.retina.grabModeDistance, query = container.particles.quadTree.queryCircle(mousePos, distance);
7572 for (const particle of query) {
7573 const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos);
7574 if (pointDistance <= distance) {
7575 const grabLineOptions = interactivity.modes.grab.links, lineOpacity = grabLineOptions.opacity, opacityLine = lineOpacity - pointDistance * lineOpacity / distance;
7576 if (opacityLine <= 0) {
7577 continue;
7578 }
7579 const optColor = (_a = grabLineOptions.color) !== null && _a !== void 0 ? _a : particle.options.links.color;
7580 if (!container.particles.grabLineColor) {
7581 const linksOptions = options.interactivity.modes.grab.links;
7582 container.particles.grabLineColor = getLinkRandomColor(optColor, linksOptions.blink, linksOptions.consent);
7583 }
7584 const colorLine = getLinkColor(particle, undefined, container.particles.grabLineColor);
7585 if (!colorLine) {
7586 return;
7587 }
7588 container.canvas.drawGrabLine(particle, colorLine, opacityLine, mousePos);
7589 }
7590 }
7591 }
7592 }
7593 }
7594 function loadExternalGrabInteraction(tsParticles) {
7595 tsParticles.addInteractor("externalGrab", (container => new Grabber(container)));
7596 }
7597 class StarDrawer {
7598 getSidesCount(particle) {
7599 var _a, _b;
7600 const star = particle.shapeData;
7601 return (_b = (_a = star === null || star === void 0 ? void 0 : star.sides) !== null && _a !== void 0 ? _a : star === null || star === void 0 ? void 0 : star.nb_sides) !== null && _b !== void 0 ? _b : 5;
7602 }
7603 draw(context, particle, radius) {
7604 var _a;
7605 const star = particle.shapeData;
7606 const sides = this.getSidesCount(particle);
7607 const inset = (_a = star === null || star === void 0 ? void 0 : star.inset) !== null && _a !== void 0 ? _a : 2;
7608 context.moveTo(0, 0 - radius);
7609 for (let i = 0; i < sides; i++) {
7610 context.rotate(Math.PI / sides);
7611 context.lineTo(0, 0 - radius * inset);
7612 context.rotate(Math.PI / sides);
7613 context.lineTo(0, 0 - radius);
7614 }
7615 }
7616 }
7617 function loadStarShape(tsParticles) {
7618 tsParticles.addShape("star", new StarDrawer);
7619 }
7620 class ParticlesInteractorBase {
7621 constructor(container) {
7622 this.container = container;
7623 this.type = InteractorType.Particles;
7624 }
7625 }
7626 class Attractor_Attractor extends ParticlesInteractorBase {
7627 constructor(container) {
7628 super(container);
7629 }
7630 interact(p1) {
7631 var _a;
7632 const container = this.container, distance = (_a = p1.retina.attractDistance) !== null && _a !== void 0 ? _a : container.retina.attractDistance, pos1 = p1.getPosition(), query = container.particles.quadTree.queryCircle(pos1, distance);
7633 for (const p2 of query) {
7634 if (p1 === p2 || !p2.options.move.attract.enable || p2.destroyed || p2.spawning) {
7635 continue;
7636 }
7637 const pos2 = p2.getPosition(), {dx, dy} = getDistances(pos1, pos2), rotate = p1.options.move.attract.rotate, ax = dx / (rotate.x * 1e3), ay = dy / (rotate.y * 1e3), p1Factor = p2.size.value / p1.size.value, p2Factor = 1 / p1Factor;
7638 p1.velocity.x -= ax * p1Factor;
7639 p1.velocity.y -= ay * p1Factor;
7640 p2.velocity.x += ax * p2Factor;
7641 p2.velocity.y += ay * p2Factor;
7642 }
7643 }
7644 isEnabled(particle) {
7645 return particle.options.move.attract.enable;
7646 }
7647 reset() {}
7648 }
7649 function loadParticlesAttractInteraction(tsParticles) {
7650 tsParticles.addInteractor("particlesAttract", (container => new Attractor_Attractor(container)));
7651 }
7652 const fixFactor = Math.sqrt(2);
7653 class SquareDrawer {
7654 getSidesCount() {
7655 return 4;
7656 }
7657 draw(context, particle, radius) {
7658 context.rect(-radius / fixFactor, -radius / fixFactor, radius * 2 / fixFactor, radius * 2 / fixFactor);
7659 }
7660 }
7661 function loadSquareShape(tsParticles) {
7662 const drawer = new SquareDrawer;
7663 tsParticles.addShape("edge", drawer);
7664 tsParticles.addShape("square", drawer);
7665 }
7666 function updateColorValue(delta, value, valueAnimation, max, decrease) {
7667 var _a;
7668 const colorValue = value;
7669 if (!colorValue || !colorValue.enable) {
7670 return;
7671 }
7672 const offset = randomInRange(valueAnimation.offset);
7673 const velocity = ((_a = value.velocity) !== null && _a !== void 0 ? _a : 0) * delta.factor + offset * 3.6;
7674 if (!decrease || colorValue.status === AnimationStatus.increasing) {
7675 colorValue.value += velocity;
7676 if (decrease && colorValue.value > max) {
7677 colorValue.status = AnimationStatus.decreasing;
7678 colorValue.value -= colorValue.value % max;
7679 }
7680 } else {
7681 colorValue.value -= velocity;
7682 if (colorValue.value < 0) {
7683 colorValue.status = AnimationStatus.increasing;
7684 colorValue.value += colorValue.value;
7685 }
7686 }
7687 if (colorValue.value > max) {
7688 colorValue.value %= max;
7689 }
7690 }
7691 function updateStrokeColor(particle, delta) {
7692 var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
7693 if (!((_a = particle.stroke) === null || _a === void 0 ? void 0 : _a.color)) {
7694 return;
7695 }
7696 const animationOptions = particle.stroke.color.animation;
7697 const h = (_c = (_b = particle.strokeColor) === null || _b === void 0 ? void 0 : _b.h) !== null && _c !== void 0 ? _c : (_d = particle.color) === null || _d === void 0 ? void 0 : _d.h;
7698 if (h) {
7699 updateColorValue(delta, h, animationOptions.h, 360, false);
7700 }
7701 const s = (_f = (_e = particle.strokeColor) === null || _e === void 0 ? void 0 : _e.s) !== null && _f !== void 0 ? _f : (_g = particle.color) === null || _g === void 0 ? void 0 : _g.s;
7702 if (s) {
7703 updateColorValue(delta, s, animationOptions.s, 100, true);
7704 }
7705 const l = (_j = (_h = particle.strokeColor) === null || _h === void 0 ? void 0 : _h.l) !== null && _j !== void 0 ? _j : (_k = particle.color) === null || _k === void 0 ? void 0 : _k.l;
7706 if (l) {
7707 updateColorValue(delta, l, animationOptions.l, 100, true);
7708 }
7709 }
7710 class StrokeColorUpdater {
7711 constructor(container) {
7712 this.container = container;
7713 }
7714 init(particle) {
7715 var _a, _b;
7716 const container = this.container;
7717 particle.stroke = particle.options.stroke instanceof Array ? itemFromArray(particle.options.stroke, particle.id, particle.options.reduceDuplicates) : particle.options.stroke;
7718 particle.strokeWidth = particle.stroke.width * container.retina.pixelRatio;
7719 const strokeHslColor = (_a = colorToHsl(particle.stroke.color)) !== null && _a !== void 0 ? _a : particle.getFillColor();
7720 if (strokeHslColor) {
7721 particle.strokeColor = getHslAnimationFromHsl(strokeHslColor, (_b = particle.stroke.color) === null || _b === void 0 ? void 0 : _b.animation, container.retina.reduceFactor);
7722 }
7723 }
7724 isEnabled(particle) {
7725 var _a, _b, _c, _d;
7726 const color = (_a = particle.stroke) === null || _a === void 0 ? void 0 : _a.color;
7727 return !particle.destroyed && !particle.spawning && !!color && (((_b = particle.strokeColor) === null || _b === void 0 ? void 0 : _b.h.value) !== undefined && color.animation.h.enable || ((_c = particle.strokeColor) === null || _c === void 0 ? void 0 : _c.s.value) !== undefined && color.animation.s.enable || ((_d = particle.strokeColor) === null || _d === void 0 ? void 0 : _d.l.value) !== undefined && color.animation.l.enable);
7728 }
7729 update(particle, delta) {
7730 if (!this.isEnabled(particle)) {
7731 return;
7732 }
7733 updateStrokeColor(particle, delta);
7734 }
7735 }
7736 function loadStrokeColorUpdater(tsParticles) {
7737 tsParticles.addParticleUpdater("strokeColor", (container => new StrokeColorUpdater(container)));
7738 }
7739 function ColorUpdater_updateColorValue(delta, value, valueAnimation, max, decrease) {
7740 var _a;
7741 const colorValue = value;
7742 if (!colorValue || !valueAnimation.enable) {
7743 return;
7744 }
7745 const offset = randomInRange(valueAnimation.offset);
7746 const velocity = ((_a = value.velocity) !== null && _a !== void 0 ? _a : 0) * delta.factor + offset * 3.6;
7747 if (!decrease || colorValue.status === AnimationStatus.increasing) {
7748 colorValue.value += velocity;
7749 if (decrease && colorValue.value > max) {
7750 colorValue.status = AnimationStatus.decreasing;
7751 colorValue.value -= colorValue.value % max;
7752 }
7753 } else {
7754 colorValue.value -= velocity;
7755 if (colorValue.value < 0) {
7756 colorValue.status = AnimationStatus.increasing;
7757 colorValue.value += colorValue.value;
7758 }
7759 }
7760 if (colorValue.value > max) {
7761 colorValue.value %= max;
7762 }
7763 }
7764 function updateColor(particle, delta) {
7765 var _a, _b, _c;
7766 const animationOptions = particle.options.color.animation;
7767 if (((_a = particle.color) === null || _a === void 0 ? void 0 : _a.h) !== undefined) {
7768 ColorUpdater_updateColorValue(delta, particle.color.h, animationOptions.h, 360, false);
7769 }
7770 if (((_b = particle.color) === null || _b === void 0 ? void 0 : _b.s) !== undefined) {
7771 ColorUpdater_updateColorValue(delta, particle.color.s, animationOptions.s, 100, true);
7772 }
7773 if (((_c = particle.color) === null || _c === void 0 ? void 0 : _c.l) !== undefined) {
7774 ColorUpdater_updateColorValue(delta, particle.color.l, animationOptions.l, 100, true);
7775 }
7776 }
7777 class ColorUpdater {
7778 constructor(container) {
7779 this.container = container;
7780 }
7781 init(particle) {
7782 const hslColor = colorToHsl(particle.options.color, particle.id, particle.options.reduceDuplicates);
7783 if (hslColor) {
7784 particle.color = getHslAnimationFromHsl(hslColor, particle.options.color.animation, this.container.retina.reduceFactor);
7785 }
7786 }
7787 isEnabled(particle) {
7788 var _a, _b, _c;
7789 const animationOptions = particle.options.color.animation;
7790 return !particle.destroyed && !particle.spawning && (((_a = particle.color) === null || _a === void 0 ? void 0 : _a.h.value) !== undefined && animationOptions.h.enable || ((_b = particle.color) === null || _b === void 0 ? void 0 : _b.s.value) !== undefined && animationOptions.s.enable || ((_c = particle.color) === null || _c === void 0 ? void 0 : _c.l.value) !== undefined && animationOptions.l.enable);
7791 }
7792 update(particle, delta) {
7793 updateColor(particle, delta);
7794 }
7795 }
7796 function loadColorUpdater(tsParticles) {
7797 tsParticles.addParticleUpdater("color", (container => new ColorUpdater(container)));
7798 }
7799 function bounce(p1, p2) {
7800 circleBounce(circleBounceDataFromParticle(p1), circleBounceDataFromParticle(p2));
7801 }
7802 function destroy(p1, p2) {
7803 if (!p1.unbreakable && !p2.unbreakable) {
7804 bounce(p1, p2);
7805 }
7806 if (p1.getRadius() === undefined && p2.getRadius() !== undefined) {
7807 p1.destroy();
7808 } else if (p1.getRadius() !== undefined && p2.getRadius() === undefined) {
7809 p2.destroy();
7810 } else if (p1.getRadius() !== undefined && p2.getRadius() !== undefined) {
7811 if (p1.getRadius() >= p2.getRadius()) {
7812 p2.destroy();
7813 } else {
7814 p1.destroy();
7815 }
7816 }
7817 }
7818 class Collider extends ParticlesInteractorBase {
7819 constructor(container) {
7820 super(container);
7821 }
7822 isEnabled(particle) {
7823 return particle.options.collisions.enable;
7824 }
7825 reset() {}
7826 interact(p1) {
7827 const container = this.container;
7828 const pos1 = p1.getPosition();
7829 const radius1 = p1.getRadius();
7830 const query = container.particles.quadTree.queryCircle(pos1, radius1 * 2);
7831 for (const p2 of query) {
7832 if (p1 === p2 || !p2.options.collisions.enable || p1.options.collisions.mode !== p2.options.collisions.mode || p2.destroyed || p2.spawning) {
7833 continue;
7834 }
7835 const pos2 = p2.getPosition();
7836 if (Math.round(pos1.z) !== Math.round(pos2.z)) {
7837 continue;
7838 }
7839 const dist = getDistance(pos1, pos2);
7840 const radius2 = p2.getRadius();
7841 const distP = radius1 + radius2;
7842 if (dist <= distP) {
7843 this.resolveCollision(p1, p2);
7844 }
7845 }
7846 }
7847 resolveCollision(p1, p2) {
7848 switch (p1.options.collisions.mode) {
7849 case CollisionMode.absorb:
7850 {
7851 this.absorb(p1, p2);
7852 break;
7853 }
7854
7855 case CollisionMode.bounce:
7856 {
7857 bounce(p1, p2);
7858 break;
7859 }
7860
7861 case CollisionMode.destroy:
7862 {
7863 destroy(p1, p2);
7864 break;
7865 }
7866 }
7867 }
7868 absorb(p1, p2) {
7869 const container = this.container;
7870 const fps = container.fpsLimit / 1e3;
7871 if (p1.getRadius() === undefined && p2.getRadius() !== undefined) {
7872 p1.destroy();
7873 } else if (p1.getRadius() !== undefined && p2.getRadius() === undefined) {
7874 p2.destroy();
7875 } else if (p1.getRadius() !== undefined && p2.getRadius() !== undefined) {
7876 if (p1.getRadius() >= p2.getRadius()) {
7877 const factor = clamp(p1.getRadius() / p2.getRadius(), 0, p2.getRadius()) * fps;
7878 p1.size.value += factor;
7879 p2.size.value -= factor;
7880 if (p2.getRadius() <= container.retina.pixelRatio) {
7881 p2.size.value = 0;
7882 p2.destroy();
7883 }
7884 } else {
7885 const factor = clamp(p2.getRadius() / p1.getRadius(), 0, p1.getRadius()) * fps;
7886 p1.size.value -= factor;
7887 p2.size.value += factor;
7888 if (p1.getRadius() <= container.retina.pixelRatio) {
7889 p1.size.value = 0;
7890 p1.destroy();
7891 }
7892 }
7893 }
7894 }
7895 }
7896 function loadParticlesCollisionsInteraction(tsParticles) {
7897 tsParticles.addInteractor("particlesCollisions", (container => new Collider(container)));
7898 }
7899 function updateAngle(particle, delta) {
7900 var _a;
7901 const rotate = particle.rotate;
7902 if (!rotate) {
7903 return;
7904 }
7905 const rotateOptions = particle.options.rotate;
7906 const rotateAnimation = rotateOptions.animation;
7907 const speed = ((_a = rotate.velocity) !== null && _a !== void 0 ? _a : 0) * delta.factor;
7908 const max = 2 * Math.PI;
7909 if (!rotateAnimation.enable) {
7910 return;
7911 }
7912 switch (rotate.status) {
7913 case AnimationStatus.increasing:
7914 rotate.value += speed;
7915 if (rotate.value > max) {
7916 rotate.value -= max;
7917 }
7918 break;
7919
7920 case AnimationStatus.decreasing:
7921 default:
7922 rotate.value -= speed;
7923 if (rotate.value < 0) {
7924 rotate.value += max;
7925 }
7926 break;
7927 }
7928 }
7929 class AngleUpdater {
7930 constructor(container) {
7931 this.container = container;
7932 }
7933 init(particle) {
7934 const rotateOptions = particle.options.rotate;
7935 particle.rotate = {
7936 enable: rotateOptions.animation.enable,
7937 value: getRangeValue(rotateOptions.value) * Math.PI / 180
7938 };
7939 let rotateDirection = rotateOptions.direction;
7940 if (rotateDirection === RotateDirection.random) {
7941 const index = Math.floor(Math.random() * 2);
7942 rotateDirection = index > 0 ? RotateDirection.counterClockwise : RotateDirection.clockwise;
7943 }
7944 switch (rotateDirection) {
7945 case RotateDirection.counterClockwise:
7946 case "counterClockwise":
7947 particle.rotate.status = AnimationStatus.decreasing;
7948 break;
7949
7950 case RotateDirection.clockwise:
7951 particle.rotate.status = AnimationStatus.increasing;
7952 break;
7953 }
7954 const rotateAnimation = particle.options.rotate.animation;
7955 if (rotateAnimation.enable) {
7956 particle.rotate.velocity = rotateAnimation.speed / 360 * this.container.retina.reduceFactor;
7957 if (!rotateAnimation.sync) {
7958 particle.rotate.velocity *= Math.random();
7959 }
7960 }
7961 }
7962 isEnabled(particle) {
7963 const rotate = particle.options.rotate;
7964 const rotateAnimation = rotate.animation;
7965 return !particle.destroyed && !particle.spawning && !rotate.path && rotateAnimation.enable;
7966 }
7967 update(particle, delta) {
7968 if (!this.isEnabled(particle)) {
7969 return;
7970 }
7971 updateAngle(particle, delta);
7972 }
7973 }
7974 function loadAngleUpdater(tsParticles) {
7975 tsParticles.addParticleUpdater("angle", (container => new AngleUpdater(container)));
7976 }
7977 function bounceHorizontal(data) {
7978 if (!(data.outMode === OutMode.bounce || data.outMode === OutMode.bounceHorizontal || data.outMode === "bounceHorizontal" || data.outMode === OutMode.split)) {
7979 return;
7980 }
7981 const velocity = data.particle.velocity.x;
7982 let bounced = false;
7983 if (data.direction === OutModeDirection.right && data.bounds.right >= data.canvasSize.width && velocity > 0 || data.direction === OutModeDirection.left && data.bounds.left <= 0 && velocity < 0) {
7984 const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
7985 data.particle.velocity.x *= -newVelocity;
7986 bounced = true;
7987 }
7988 if (!bounced) {
7989 return;
7990 }
7991 const minPos = data.offset.x + data.size;
7992 if (data.bounds.right >= data.canvasSize.width) {
7993 data.particle.position.x = data.canvasSize.width - minPos;
7994 } else if (data.bounds.left <= 0) {
7995 data.particle.position.x = minPos;
7996 }
7997 if (data.outMode === OutMode.split) {
7998 data.particle.destroy();
7999 }
8000 }
8001 function bounceVertical(data) {
8002 if (data.outMode === OutMode.bounce || data.outMode === OutMode.bounceVertical || data.outMode === "bounceVertical" || data.outMode === OutMode.split) {
8003 const velocity = data.particle.velocity.y;
8004 let bounced = false;
8005 if (data.direction === OutModeDirection.bottom && data.bounds.bottom >= data.canvasSize.height && velocity > 0 || data.direction === OutModeDirection.top && data.bounds.top <= 0 && velocity < 0) {
8006 const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
8007 data.particle.velocity.y *= -newVelocity;
8008 bounced = true;
8009 }
8010 if (!bounced) {
8011 return;
8012 }
8013 const minPos = data.offset.y + data.size;
8014 if (data.bounds.bottom >= data.canvasSize.height) {
8015 data.particle.position.y = data.canvasSize.height - minPos;
8016 } else if (data.bounds.top <= 0) {
8017 data.particle.position.y = minPos;
8018 }
8019 if (data.outMode === OutMode.split) {
8020 data.particle.destroy();
8021 }
8022 }
8023 }
8024 class OutOfCanvasUpdater {
8025 constructor(container) {
8026 this.container = container;
8027 }
8028 init() {}
8029 isEnabled(particle) {
8030 return !particle.destroyed && !particle.spawning;
8031 }
8032 update(particle, delta) {
8033 var _a, _b, _c, _d;
8034 const outModes = particle.options.move.outModes;
8035 this.updateOutMode(particle, delta, (_a = outModes.bottom) !== null && _a !== void 0 ? _a : outModes.default, OutModeDirection.bottom);
8036 this.updateOutMode(particle, delta, (_b = outModes.left) !== null && _b !== void 0 ? _b : outModes.default, OutModeDirection.left);
8037 this.updateOutMode(particle, delta, (_c = outModes.right) !== null && _c !== void 0 ? _c : outModes.default, OutModeDirection.right);
8038 this.updateOutMode(particle, delta, (_d = outModes.top) !== null && _d !== void 0 ? _d : outModes.default, OutModeDirection.top);
8039 }
8040 updateOutMode(particle, delta, outMode, direction) {
8041 switch (outMode) {
8042 case OutMode.bounce:
8043 case OutMode.bounceVertical:
8044 case OutMode.bounceHorizontal:
8045 case "bounceVertical":
8046 case "bounceHorizontal":
8047 case OutMode.split:
8048 this.bounce(particle, delta, direction, outMode);
8049 break;
8050
8051 case OutMode.destroy:
8052 this.destroy(particle, direction);
8053 break;
8054
8055 case OutMode.out:
8056 this.out(particle, direction);
8057 break;
8058
8059 case OutMode.none:
8060 default:
8061 this.none(particle, direction);
8062 break;
8063 }
8064 }
8065 destroy(particle, direction) {
8066 const container = this.container;
8067 if (isPointInside(particle.position, container.canvas.size, particle.getRadius(), direction)) {
8068 return;
8069 }
8070 container.particles.remove(particle, undefined, true);
8071 }
8072 out(particle, direction) {
8073 const container = this.container;
8074 if (isPointInside(particle.position, container.canvas.size, particle.getRadius(), direction)) {
8075 return;
8076 }
8077 const wrap = particle.options.move.warp, canvasSize = container.canvas.size, newPos = {
8078 bottom: canvasSize.height + particle.getRadius() + particle.offset.y,
8079 left: -particle.getRadius() - particle.offset.x,
8080 right: canvasSize.width + particle.getRadius() + particle.offset.x,
8081 top: -particle.getRadius() - particle.offset.y
8082 }, sizeValue = particle.getRadius(), nextBounds = calculateBounds(particle.position, sizeValue);
8083 if (direction === OutModeDirection.right && nextBounds.left > canvasSize.width + particle.offset.x) {
8084 particle.position.x = newPos.left;
8085 particle.initialPosition.x = particle.position.x;
8086 if (!wrap) {
8087 particle.position.y = Math.random() * canvasSize.height;
8088 particle.initialPosition.y = particle.position.y;
8089 }
8090 } else if (direction === OutModeDirection.left && nextBounds.right < -particle.offset.x) {
8091 particle.position.x = newPos.right;
8092 particle.initialPosition.x = particle.position.x;
8093 if (!wrap) {
8094 particle.position.y = Math.random() * canvasSize.height;
8095 particle.initialPosition.y = particle.position.y;
8096 }
8097 }
8098 if (direction === OutModeDirection.bottom && nextBounds.top > canvasSize.height + particle.offset.y) {
8099 if (!wrap) {
8100 particle.position.x = Math.random() * canvasSize.width;
8101 particle.initialPosition.x = particle.position.x;
8102 }
8103 particle.position.y = newPos.top;
8104 particle.initialPosition.y = particle.position.y;
8105 } else if (direction === OutModeDirection.top && nextBounds.bottom < -particle.offset.y) {
8106 if (!wrap) {
8107 particle.position.x = Math.random() * canvasSize.width;
8108 particle.initialPosition.x = particle.position.x;
8109 }
8110 particle.position.y = newPos.bottom;
8111 particle.initialPosition.y = particle.position.y;
8112 }
8113 }
8114 bounce(particle, delta, direction, outMode) {
8115 const container = this.container;
8116 let handled = false;
8117 for (const [, plugin] of container.plugins) {
8118 if (plugin.particleBounce !== undefined) {
8119 handled = plugin.particleBounce(particle, delta, direction);
8120 }
8121 if (handled) {
8122 break;
8123 }
8124 }
8125 if (handled) {
8126 return;
8127 }
8128 const pos = particle.getPosition(), offset = particle.offset, size = particle.getRadius(), bounds = calculateBounds(pos, size), canvasSize = container.canvas.size;
8129 bounceHorizontal({
8130 particle,
8131 outMode,
8132 direction,
8133 bounds,
8134 canvasSize,
8135 offset,
8136 size
8137 });
8138 bounceVertical({
8139 particle,
8140 outMode,
8141 direction,
8142 bounds,
8143 canvasSize,
8144 offset,
8145 size
8146 });
8147 }
8148 none(particle, direction) {
8149 if (particle.options.move.distance.horizontal && (direction === OutModeDirection.left || direction === OutModeDirection.right) || particle.options.move.distance.vertical && (direction === OutModeDirection.top || direction === OutModeDirection.bottom)) {
8150 return;
8151 }
8152 const gravityOptions = particle.options.move.gravity, container = this.container;
8153 const canvasSize = container.canvas.size;
8154 const pRadius = particle.getRadius();
8155 if (!gravityOptions.enable) {
8156 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) {
8157 return;
8158 }
8159 if (!isPointInside(particle.position, container.canvas.size, pRadius, direction)) {
8160 container.particles.remove(particle);
8161 }
8162 } else {
8163 const position = particle.position;
8164 if (!gravityOptions.inverse && position.y > canvasSize.height + pRadius && direction === OutModeDirection.bottom || gravityOptions.inverse && position.y < -pRadius && direction === OutModeDirection.top) {
8165 container.particles.remove(particle);
8166 }
8167 }
8168 }
8169 }
8170 function loadOutModesUpdater(tsParticles) {
8171 tsParticles.addParticleUpdater("outModes", (container => new OutOfCanvasUpdater(container)));
8172 }
8173 class Repulser extends ExternalInteractorBase {
8174 constructor(container) {
8175 super(container);
8176 }
8177 isEnabled() {
8178 const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = options.interactivity.events, divs = events.onDiv, divRepulse = isDivModeEnabled(DivMode.repulse, divs);
8179 if (!(divRepulse || events.onHover.enable && mouse.position || events.onClick.enable && mouse.clickPosition)) {
8180 return false;
8181 }
8182 const hoverMode = events.onHover.mode, clickMode = events.onClick.mode;
8183 return isInArray(HoverMode.repulse, hoverMode) || isInArray(ClickMode.repulse, clickMode) || divRepulse;
8184 }
8185 reset() {}
8186 interact() {
8187 const container = this.container, options = container.actualOptions, mouseMoveStatus = container.interactivity.status === Constants.mouseMoveEvent, events = options.interactivity.events, hoverEnabled = events.onHover.enable, hoverMode = events.onHover.mode, clickEnabled = events.onClick.enable, clickMode = events.onClick.mode, divs = events.onDiv;
8188 if (mouseMoveStatus && hoverEnabled && isInArray(HoverMode.repulse, hoverMode)) {
8189 this.hoverRepulse();
8190 } else if (clickEnabled && isInArray(ClickMode.repulse, clickMode)) {
8191 this.clickRepulse();
8192 } else {
8193 divModeExecute(DivMode.repulse, divs, ((selector, div) => this.singleSelectorRepulse(selector, div)));
8194 }
8195 }
8196 singleSelectorRepulse(selector, div) {
8197 const container = this.container, query = document.querySelectorAll(selector);
8198 if (!query.length) {
8199 return;
8200 }
8201 query.forEach((item => {
8202 const elem = item, pxRatio = container.retina.pixelRatio, pos = {
8203 x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
8204 y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
8205 }, repulseRadius = elem.offsetWidth / 2 * pxRatio, area = div.type === DivType.circle ? new Circle(pos.x, pos.y, repulseRadius) : new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), divs = container.actualOptions.interactivity.modes.repulse.divs, divRepulse = divMode(divs, elem);
8206 this.processRepulse(pos, repulseRadius, area, divRepulse);
8207 }));
8208 }
8209 hoverRepulse() {
8210 const container = this.container, mousePos = container.interactivity.mouse.position;
8211 if (!mousePos) {
8212 return;
8213 }
8214 const repulseRadius = container.retina.repulseModeDistance;
8215 this.processRepulse(mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
8216 }
8217 processRepulse(position, repulseRadius, area, divRepulse) {
8218 var _a;
8219 const container = this.container, query = container.particles.quadTree.query(area), repulseOptions = container.actualOptions.interactivity.modes.repulse;
8220 for (const particle of query) {
8221 const {dx, dy, distance} = getDistances(particle.position, position), velocity = ((_a = divRepulse === null || divRepulse === void 0 ? void 0 : divRepulse.speed) !== null && _a !== void 0 ? _a : repulseOptions.speed) * repulseOptions.factor, repulseFactor = clamp(calcEasing(1 - distance / repulseRadius, repulseOptions.easing) * velocity, 0, repulseOptions.maxSpeed), normVec = Vector.create(distance === 0 ? velocity : dx / distance * repulseFactor, distance === 0 ? velocity : dy / distance * repulseFactor);
8222 particle.position.addTo(normVec);
8223 }
8224 }
8225 clickRepulse() {
8226 const container = this.container;
8227 if (!container.repulse.finish) {
8228 if (!container.repulse.count) {
8229 container.repulse.count = 0;
8230 }
8231 container.repulse.count++;
8232 if (container.repulse.count === container.particles.count) {
8233 container.repulse.finish = true;
8234 }
8235 }
8236 if (container.repulse.clicking) {
8237 const repulseDistance = container.retina.repulseModeDistance, repulseRadius = Math.pow(repulseDistance / 6, 3), mouseClickPos = container.interactivity.mouse.clickPosition;
8238 if (mouseClickPos === undefined) {
8239 return;
8240 }
8241 const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range);
8242 for (const particle of query) {
8243 const {dx, dy, distance} = getDistances(mouseClickPos, particle.position), d = distance ** 2, velocity = container.actualOptions.interactivity.modes.repulse.speed, force = -repulseRadius * velocity / d;
8244 if (d <= repulseRadius) {
8245 container.repulse.particles.push(particle);
8246 const vect = Vector.create(dx, dy);
8247 vect.length = force;
8248 particle.velocity.setTo(vect);
8249 }
8250 }
8251 } else if (container.repulse.clicking === false) {
8252 for (const particle of container.repulse.particles) {
8253 particle.velocity.setTo(particle.initialVelocity);
8254 }
8255 container.repulse.particles = [];
8256 }
8257 }
8258 }
8259 function loadExternalRepulseInteraction(tsParticles) {
8260 tsParticles.addInteractor("externalRepulse", (container => new Repulser(container)));
8261 }
8262 class LineDrawer {
8263 getSidesCount() {
8264 return 1;
8265 }
8266 draw(context, particle, radius) {
8267 context.moveTo(-radius / 2, 0);
8268 context.lineTo(radius / 2, 0);
8269 }
8270 }
8271 function loadLineShape(tsParticles) {
8272 tsParticles.addShape("line", new LineDrawer);
8273 }
8274 class Bouncer extends ExternalInteractorBase {
8275 constructor(container) {
8276 super(container);
8277 }
8278 isEnabled() {
8279 const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = options.interactivity.events, divs = events.onDiv;
8280 return mouse.position && events.onHover.enable && isInArray(HoverMode.bounce, events.onHover.mode) || isDivModeEnabled(DivMode.bounce, divs);
8281 }
8282 interact() {
8283 const container = this.container, options = container.actualOptions, events = options.interactivity.events, mouseMoveStatus = container.interactivity.status === Constants.mouseMoveEvent, hoverEnabled = events.onHover.enable, hoverMode = events.onHover.mode, divs = events.onDiv;
8284 if (mouseMoveStatus && hoverEnabled && isInArray(HoverMode.bounce, hoverMode)) {
8285 this.processMouseBounce();
8286 } else {
8287 divModeExecute(DivMode.bounce, divs, ((selector, div) => this.singleSelectorBounce(selector, div)));
8288 }
8289 }
8290 reset() {}
8291 processMouseBounce() {
8292 const container = this.container, pxRatio = container.retina.pixelRatio, tolerance = 10 * pxRatio, mousePos = container.interactivity.mouse.position, radius = container.retina.bounceModeDistance;
8293 if (mousePos) {
8294 this.processBounce(mousePos, radius, new Circle(mousePos.x, mousePos.y, radius + tolerance));
8295 }
8296 }
8297 singleSelectorBounce(selector, div) {
8298 const container = this.container;
8299 const query = document.querySelectorAll(selector);
8300 if (!query.length) {
8301 return;
8302 }
8303 query.forEach((item => {
8304 const elem = item, pxRatio = container.retina.pixelRatio, pos = {
8305 x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
8306 y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
8307 }, radius = elem.offsetWidth / 2 * pxRatio, tolerance = 10 * pxRatio;
8308 const area = div.type === DivType.circle ? new Circle(pos.x, pos.y, radius + tolerance) : new Rectangle(elem.offsetLeft * pxRatio - tolerance, elem.offsetTop * pxRatio - tolerance, elem.offsetWidth * pxRatio + tolerance * 2, elem.offsetHeight * pxRatio + tolerance * 2);
8309 this.processBounce(pos, radius, area);
8310 }));
8311 }
8312 processBounce(position, radius, area) {
8313 const query = this.container.particles.quadTree.query(area);
8314 for (const particle of query) {
8315 if (area instanceof Circle) {
8316 circleBounce(circleBounceDataFromParticle(particle), {
8317 position,
8318 radius,
8319 mass: radius ** 2 * Math.PI / 2,
8320 velocity: Vector.origin,
8321 factor: Vector.origin
8322 });
8323 } else if (area instanceof Rectangle) {
8324 rectBounce(particle, calculateBounds(position, radius));
8325 }
8326 }
8327 }
8328 }
8329 function loadExternalBounceInteraction(tsParticles) {
8330 tsParticles.addInteractor("externalBounce", (container => new Bouncer(container)));
8331 }
8332 const validTypes = [ "text", "character", "char" ];
8333 class TextDrawer {
8334 getSidesCount() {
8335 return 12;
8336 }
8337 async init(container) {
8338 const options = container.actualOptions;
8339 if (validTypes.find((t => isInArray(t, options.particles.shape.type)))) {
8340 const shapeOptions = validTypes.map((t => options.particles.shape.options[t])).find((t => !!t));
8341 if (shapeOptions instanceof Array) {
8342 const promises = [];
8343 for (const character of shapeOptions) {
8344 promises.push(loadFont(character));
8345 }
8346 await Promise.allSettled(promises);
8347 } else {
8348 if (shapeOptions !== undefined) {
8349 await loadFont(shapeOptions);
8350 }
8351 }
8352 }
8353 }
8354 draw(context, particle, radius, opacity) {
8355 var _a, _b, _c;
8356 const character = particle.shapeData;
8357 if (character === undefined) {
8358 return;
8359 }
8360 const textData = character.value;
8361 if (textData === undefined) {
8362 return;
8363 }
8364 const textParticle = particle;
8365 if (textParticle.text === undefined) {
8366 textParticle.text = textData instanceof Array ? itemFromArray(textData, particle.randomIndexData) : textData;
8367 }
8368 const text = textParticle.text;
8369 const style = (_a = character.style) !== null && _a !== void 0 ? _a : "";
8370 const weight = (_b = character.weight) !== null && _b !== void 0 ? _b : "400";
8371 const size = Math.round(radius) * 2;
8372 const font = (_c = character.font) !== null && _c !== void 0 ? _c : "Verdana";
8373 const fill = particle.fill;
8374 const offsetX = text.length * radius / 2;
8375 context.font = `${style} ${weight} ${size}px "${font}"`;
8376 const pos = {
8377 x: -offsetX,
8378 y: radius / 2
8379 };
8380 context.globalAlpha = opacity;
8381 if (fill) {
8382 context.fillText(text, pos.x, pos.y);
8383 } else {
8384 context.strokeText(text, pos.x, pos.y);
8385 }
8386 context.globalAlpha = 1;
8387 }
8388 }
8389 function loadTextShape(tsParticles) {
8390 const drawer = new TextDrawer;
8391 for (const type of validTypes) {
8392 tsParticles.addShape(type, drawer);
8393 }
8394 }
8395 function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
8396 let distance = getDistance(pos1, pos2);
8397 if (!warp || distance <= optDistance) {
8398 return distance;
8399 }
8400 const pos2NE = {
8401 x: pos2.x - canvasSize.width,
8402 y: pos2.y
8403 };
8404 distance = getDistance(pos1, pos2NE);
8405 if (distance <= optDistance) {
8406 return distance;
8407 }
8408 const pos2SE = {
8409 x: pos2.x - canvasSize.width,
8410 y: pos2.y - canvasSize.height
8411 };
8412 distance = getDistance(pos1, pos2SE);
8413 if (distance <= optDistance) {
8414 return distance;
8415 }
8416 const pos2SW = {
8417 x: pos2.x,
8418 y: pos2.y - canvasSize.height
8419 };
8420 distance = getDistance(pos1, pos2SW);
8421 return distance;
8422 }
8423 class Linker extends ParticlesInteractorBase {
8424 constructor(container) {
8425 super(container);
8426 }
8427 isEnabled(particle) {
8428 return particle.options.links.enable;
8429 }
8430 reset() {}
8431 interact(p1) {
8432 var _a;
8433 p1.links = [];
8434 const pos1 = p1.getPosition();
8435 const container = this.container;
8436 const canvasSize = container.canvas.size;
8437 if (pos1.x < 0 || pos1.y < 0 || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
8438 return;
8439 }
8440 const linkOpt1 = p1.options.links;
8441 const optOpacity = linkOpt1.opacity;
8442 const optDistance = (_a = p1.retina.linksDistance) !== null && _a !== void 0 ? _a : container.retina.linksDistance;
8443 const warp = linkOpt1.warp;
8444 const range = warp ? new CircleWarp(pos1.x, pos1.y, optDistance, canvasSize) : new Circle(pos1.x, pos1.y, optDistance);
8445 const query = container.particles.quadTree.query(range);
8446 for (const p2 of query) {
8447 const linkOpt2 = p2.options.links;
8448 if (p1 === p2 || !linkOpt2.enable || linkOpt1.id !== linkOpt2.id || p2.spawning || p2.destroyed || p1.links.map((t => t.destination)).indexOf(p2) !== -1 || p2.links.map((t => t.destination)).indexOf(p1) !== -1) {
8449 continue;
8450 }
8451 const pos2 = p2.getPosition();
8452 if (pos2.x < 0 || pos2.y < 0 || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
8453 continue;
8454 }
8455 const distance = getLinkDistance(pos1, pos2, optDistance, canvasSize, warp && linkOpt2.warp);
8456 if (distance > optDistance) {
8457 return;
8458 }
8459 const opacityLine = (1 - distance / optDistance) * optOpacity;
8460 this.setColor(p1);
8461 p1.links.push({
8462 destination: p2,
8463 opacity: opacityLine
8464 });
8465 }
8466 }
8467 setColor(p1) {
8468 const container = this.container;
8469 const linksOptions = p1.options.links;
8470 let linkColor = linksOptions.id === undefined ? container.particles.linksColor : container.particles.linksColors.get(linksOptions.id);
8471 if (!linkColor) {
8472 const optColor = linksOptions.color;
8473 linkColor = getLinkRandomColor(optColor, linksOptions.blink, linksOptions.consent);
8474 if (linksOptions.id === undefined) {
8475 container.particles.linksColor = linkColor;
8476 } else {
8477 container.particles.linksColors.set(linksOptions.id, linkColor);
8478 }
8479 }
8480 }
8481 }
8482 class LinkInstance {
8483 constructor(container) {
8484 this.container = container;
8485 }
8486 particleCreated(particle) {
8487 const linkParticle = particle;
8488 linkParticle.links = [];
8489 }
8490 particleDestroyed(particle) {
8491 const linkParticle = particle;
8492 linkParticle.links = [];
8493 }
8494 drawParticle(context, particle) {
8495 const linkParticle = particle;
8496 const container = this.container;
8497 const particles = container.particles;
8498 const pOptions = particle.options;
8499 if (linkParticle.links.length > 0) {
8500 context.save();
8501 const p1Links = linkParticle.links.filter((l => {
8502 const linkFreq = container.particles.getLinkFrequency(linkParticle, l.destination);
8503 return linkFreq <= pOptions.links.frequency;
8504 }));
8505 for (const link of p1Links) {
8506 const p2 = link.destination;
8507 if (pOptions.links.triangles.enable) {
8508 const links = p1Links.map((l => l.destination));
8509 const vertices = p2.links.filter((t => {
8510 const linkFreq = container.particles.getLinkFrequency(p2, t.destination);
8511 return linkFreq <= p2.options.links.frequency && links.indexOf(t.destination) >= 0;
8512 }));
8513 if (vertices.length) {
8514 for (const vertex of vertices) {
8515 const p3 = vertex.destination;
8516 const triangleFreq = particles.getTriangleFrequency(linkParticle, p2, p3);
8517 if (triangleFreq > pOptions.links.triangles.frequency) {
8518 continue;
8519 }
8520 this.drawLinkTriangle(linkParticle, link, vertex);
8521 }
8522 }
8523 }
8524 if (link.opacity > 0 && container.retina.linksWidth > 0) {
8525 this.drawLinkLine(linkParticle, link);
8526 }
8527 }
8528 context.restore();
8529 }
8530 }
8531 drawLinkTriangle(p1, link1, link2) {
8532 var _a;
8533 const container = this.container;
8534 const options = container.actualOptions;
8535 const p2 = link1.destination;
8536 const p3 = link2.destination;
8537 const triangleOptions = p1.options.links.triangles;
8538 const opacityTriangle = (_a = triangleOptions.opacity) !== null && _a !== void 0 ? _a : (link1.opacity + link2.opacity) / 2;
8539 if (opacityTriangle <= 0) {
8540 return;
8541 }
8542 const pos1 = p1.getPosition();
8543 const pos2 = p2.getPosition();
8544 const pos3 = p3.getPosition();
8545 container.canvas.draw((ctx => {
8546 if (getDistance(pos1, pos2) > container.retina.linksDistance || getDistance(pos3, pos2) > container.retina.linksDistance || getDistance(pos3, pos1) > container.retina.linksDistance) {
8547 return;
8548 }
8549 let colorTriangle = colorToRgb(triangleOptions.color);
8550 if (!colorTriangle) {
8551 const linksOptions = p1.options.links;
8552 const linkColor = linksOptions.id !== undefined ? container.particles.linksColors.get(linksOptions.id) : container.particles.linksColor;
8553 colorTriangle = getLinkColor(p1, p2, linkColor);
8554 }
8555 if (!colorTriangle) {
8556 return;
8557 }
8558 drawLinkTriangle(ctx, pos1, pos2, pos3, options.backgroundMask.enable, options.backgroundMask.composite, colorTriangle, opacityTriangle);
8559 }));
8560 }
8561 drawLinkLine(p1, link) {
8562 const container = this.container;
8563 const options = container.actualOptions;
8564 const p2 = link.destination;
8565 let opacity = link.opacity;
8566 const pos1 = p1.getPosition();
8567 const pos2 = p2.getPosition();
8568 container.canvas.draw((ctx => {
8569 var _a, _b;
8570 let colorLine;
8571 const twinkle = p1.options.twinkle.lines;
8572 if (twinkle.enable) {
8573 const twinkleFreq = twinkle.frequency;
8574 const twinkleRgb = colorToRgb(twinkle.color);
8575 const twinkling = Math.random() < twinkleFreq;
8576 if (twinkling && twinkleRgb !== undefined) {
8577 colorLine = twinkleRgb;
8578 opacity = twinkle.opacity;
8579 }
8580 }
8581 if (!colorLine) {
8582 const linksOptions = p1.options.links;
8583 const linkColor = linksOptions.id !== undefined ? container.particles.linksColors.get(linksOptions.id) : container.particles.linksColor;
8584 colorLine = getLinkColor(p1, p2, linkColor);
8585 }
8586 if (!colorLine) {
8587 return;
8588 }
8589 const width = (_a = p1.retina.linksWidth) !== null && _a !== void 0 ? _a : container.retina.linksWidth;
8590 const maxDistance = (_b = p1.retina.linksDistance) !== null && _b !== void 0 ? _b : container.retina.linksDistance;
8591 drawLinkLine(ctx, width, pos1, pos2, maxDistance, container.canvas.size, p1.options.links.warp, options.backgroundMask.enable, options.backgroundMask.composite, colorLine, opacity, p1.options.links.shadow);
8592 }));
8593 }
8594 }
8595 class Plugin {
8596 constructor() {
8597 this.id = "links";
8598 }
8599 getPlugin(container) {
8600 return new LinkInstance(container);
8601 }
8602 needsPlugin() {
8603 return true;
8604 }
8605 loadOptions() {}
8606 }
8607 function loadPlugin(tsParticles) {
8608 const plugin = new Plugin;
8609 tsParticles.addPlugin(plugin);
8610 }
8611 function loadInteraction(tsParticles) {
8612 tsParticles.addInteractor("particlesLinks", (container => new Linker(container)));
8613 }
8614 function loadParticlesLinksInteraction(tsParticles) {
8615 loadInteraction(tsParticles);
8616 loadPlugin(tsParticles);
8617 }
8618 function SizeUpdater_checkDestroy(particle, value, minValue, maxValue) {
8619 switch (particle.options.size.animation.destroy) {
8620 case DestroyType.max:
8621 if (value >= maxValue) {
8622 particle.destroy();
8623 }
8624 break;
8625
8626 case DestroyType.min:
8627 if (value <= minValue) {
8628 particle.destroy();
8629 }
8630 break;
8631 }
8632 }
8633 function updateSize(particle, delta) {
8634 var _a, _b, _c, _d;
8635 const sizeVelocity = ((_a = particle.size.velocity) !== null && _a !== void 0 ? _a : 0) * delta.factor;
8636 const minValue = particle.size.min;
8637 const maxValue = particle.size.max;
8638 if (!(!particle.destroyed && particle.size.enable && (((_b = particle.size.loops) !== null && _b !== void 0 ? _b : 0) <= 0 || ((_c = particle.size.loops) !== null && _c !== void 0 ? _c : 0) < ((_d = particle.size.maxLoops) !== null && _d !== void 0 ? _d : 0)))) {
8639 return;
8640 }
8641 switch (particle.size.status) {
8642 case AnimationStatus.increasing:
8643 if (particle.size.value >= maxValue) {
8644 particle.size.status = AnimationStatus.decreasing;
8645 if (!particle.size.loops) {
8646 particle.size.loops = 0;
8647 }
8648 particle.size.loops++;
8649 } else {
8650 particle.size.value += sizeVelocity;
8651 }
8652 break;
8653
8654 case AnimationStatus.decreasing:
8655 if (particle.size.value <= minValue) {
8656 particle.size.status = AnimationStatus.increasing;
8657 if (!particle.size.loops) {
8658 particle.size.loops = 0;
8659 }
8660 particle.size.loops++;
8661 } else {
8662 particle.size.value -= sizeVelocity;
8663 }
8664 }
8665 SizeUpdater_checkDestroy(particle, particle.size.value, minValue, maxValue);
8666 if (!particle.destroyed) {
8667 particle.size.value = clamp(particle.size.value, minValue, maxValue);
8668 }
8669 }
8670 class SizeUpdater {
8671 init() {}
8672 isEnabled(particle) {
8673 var _a, _b, _c;
8674 return !particle.destroyed && !particle.spawning && particle.size.enable && (((_a = particle.size.loops) !== null && _a !== void 0 ? _a : 0) <= 0 || ((_b = particle.size.loops) !== null && _b !== void 0 ? _b : 0) < ((_c = particle.size.maxLoops) !== null && _c !== void 0 ? _c : 0));
8675 }
8676 update(particle, delta) {
8677 if (!this.isEnabled(particle)) {
8678 return;
8679 }
8680 updateSize(particle, delta);
8681 }
8682 }
8683 function loadSizeUpdater(tsParticles) {
8684 tsParticles.addParticleUpdater("size", (() => new SizeUpdater));
8685 }
8686 function loadSlim(tsParticles) {
8687 loadExternalAttractInteraction(tsParticles);
8688 loadExternalBounceInteraction(tsParticles);
8689 loadExternalBubbleInteraction(tsParticles);
8690 loadExternalConnectInteraction(tsParticles);
8691 loadExternalGrabInteraction(tsParticles);
8692 loadExternalRepulseInteraction(tsParticles);
8693 loadParticlesAttractInteraction(tsParticles);
8694 loadParticlesCollisionsInteraction(tsParticles);
8695 loadParticlesLinksInteraction(tsParticles);
8696 loadCircleShape(tsParticles);
8697 loadImageShape(tsParticles);
8698 loadLineShape(tsParticles);
8699 loadPolygonShape(tsParticles);
8700 loadSquareShape(tsParticles);
8701 loadStarShape(tsParticles);
8702 loadTextShape(tsParticles);
8703 loadLifeUpdater(tsParticles);
8704 loadOpacityUpdater(tsParticles);
8705 loadSizeUpdater(tsParticles);
8706 loadAngleUpdater(tsParticles);
8707 loadColorUpdater(tsParticles);
8708 loadStrokeColorUpdater(tsParticles);
8709 loadOutModesUpdater(tsParticles);
8710 }
8711 const tsParticles = new Main;
8712 tsParticles.init();
8713 loadSlim(tsParticles);
8714 const {particlesJS, pJSDom} = initPjs(tsParticles);
8715 return __webpack_exports__;
8716 })();
8717}));
\No newline at end of file