cursor-fx 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- var CursorFX=(function(exports){'use strict';function d(t){return t[Math.floor(Math.random()*t.length)]}function M(t){let e=document.createElement("canvas");return e.style.position="fixed",e.style.top="0",e.style.left="0",e.style.pointerEvents="none",e.style.zIndex="9999",e.width=window.innerWidth,e.height=window.innerHeight,t.appendChild(e),e}function g(t){t.width=window.innerWidth,t.height=window.innerHeight;}function w(t,e,i,a,r=5){let o=a,n=a*.4;t.beginPath();for(let s=0;s<r*2;s++){let m=s*Math.PI/r,l=s%2===0?o:n,h=Math.cos(m)*l,u=Math.sin(m)*l;s===0?t.moveTo(e+h,i+u):t.lineTo(e+h,i+u);}t.closePath(),t.fill();}function y(t,e,i,a,r){t.fillRect(e-a/2,i-r/2,a,r);}function E(t,e,i,a,r=0){t.save(),t.translate(e,i),t.rotate(r),t.shadowBlur=4,t.shadowColor="#FFFFFF",t.lineWidth=1.8,t.beginPath();for(let o=0;o<6;o++){let n=o*Math.PI/3;t.moveTo(0,0),t.lineTo(Math.cos(n)*a,Math.sin(n)*a);}t.stroke(),t.restore();}function C(t,e,i,a){let r=t.fillStyle,o=t.createRadialGradient(e-a*.25,i-a*.25,0,e,i,a);o.addColorStop(0,"rgba(255, 255, 255, 0.3)"),o.addColorStop(.3,r),o.addColorStop(.7,r),o.addColorStop(1,"rgba(255, 255, 255, 0.1)"),t.beginPath(),t.arc(e,i,a,0,Math.PI*2),t.fillStyle=o,t.fill(),t.strokeStyle="rgba(255, 255, 255, 0.3)",t.lineWidth=1,t.stroke(),t.fillStyle="rgba(255, 255, 255, 0.6)",t.beginPath(),t.arc(e-a*.3,i-a*.3,a*.35,0,Math.PI*2),t.fill(),t.fillStyle="rgba(255, 255, 255, 0.9)",t.beginPath(),t.arc(e-a*.4,i-a*.4,a*.15,0,Math.PI*2),t.fill(),t.fillStyle="rgba(255, 255, 255, 0.2)",t.beginPath(),t.arc(e+a*.4,i+a*.4,a*.2,0,Math.PI*2),t.fill();}function P(t,e,i,a){let r=a/2,o=a*.3;t.fillRect(e-o/2,i-r,o,a),t.fillRect(e-r,i-o/2,a,o);}function F(t,e,i,a,r){t.save(),t.translate(e,i),t.scale(a/r,1),t.beginPath(),t.arc(0,0,r,0,Math.PI*2),t.fill(),t.restore();}var p=class{constructor(e={}){this.particles=[];this.animationId=null;this.effect=null;this.maxParticles=500;this.lastParticleTime=0;this.particleThrottle=16;this.lastMouseX=0;this.lastMouseY=0;this.minMoveDistance=0;if(e.canvas)this.canvas=e.canvas;else {let a=e.container||document.body;this.canvas=M(a);}let i=this.canvas.getContext("2d");if(!i)throw new Error("Failed to get 2D context");this.ctx=i,this.handleResize=this.handleResize.bind(this),this.handleMouseMove=this.handleMouseMove.bind(this),this.handleTouchMove=this.handleTouchMove.bind(this),this.animate=this.animate.bind(this),window.addEventListener("resize",this.handleResize);}handleResize(){g(this.canvas);}handleMouseMove(e){if(!this.effect)return;let i=Date.now(),a=e.clientX-this.lastMouseX,r=e.clientY-this.lastMouseY,o=Math.sqrt(a*a+r*r),n=this.effect.throttle??this.particleThrottle,s=this.effect.minMoveDistance??this.minMoveDistance;if(i-this.lastParticleTime>=n&&o>=s){this.lastParticleTime=i,this.lastMouseX=e.clientX,this.lastMouseY=e.clientY;let m=this.effect.onMouseMove(e.clientX,e.clientY);this.addParticles(m);}}handleTouchMove(e){if(!this.effect||e.touches.length===0)return;let i=Date.now(),a=e.touches[0],r=a.clientX-this.lastMouseX,o=a.clientY-this.lastMouseY,n=Math.sqrt(r*r+o*o),s=this.effect.throttle??this.particleThrottle,m=this.effect.minMoveDistance??this.minMoveDistance;if(i-this.lastParticleTime>=s&&n>=m){this.lastParticleTime=i,this.lastMouseX=a.clientX,this.lastMouseY=a.clientY;let l=this.effect.onMouseMove(a.clientX,a.clientY);this.addParticles(l);}}addParticle(e){this.particles.length<this.maxParticles&&this.particles.push(e);}addParticles(e){let i=this.maxParticles-this.particles.length;i>0&&this.particles.push(...e.slice(0,i));}update(){this.particles.forEach(e=>e.update()),this.particles=this.particles.filter(e=>!e.isDead());}draw(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.particles.forEach(e=>e.draw(this.ctx));}animate(){this.update(),this.draw(),this.animationId=requestAnimationFrame(this.animate);}start(e){this.animationId===null&&(this.effect=e,this.animationId=requestAnimationFrame(this.animate),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("touchmove",this.handleTouchMove,{passive:true}));}stop(){this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null,document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("touchmove",this.handleTouchMove));}clear(){this.particles=[],this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);}destroy(){this.stop(),this.clear(),window.removeEventListener("resize",this.handleResize),this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas);}};var c=class{constructor(e){this.x=e.x,this.y=e.y,this.vx=e.vx??(Math.random()-.5)*4,this.vy=e.vy??(Math.random()-.5)*4,this.size=e.size??3,this.color=e.color??"#ffffff",this.maxLife=e.maxLife??40,this.life=0,this.gravity=e.gravity??.1,this.opacity=1,this.rotation=e.rotation??0,this.rotationSpeed=e.rotationSpeed??0,this.shape=e.shape??"star",this.wobbleAmplitude=e.wobbleAmplitude??0,this.wobbleSpeed=e.wobbleSpeed??0,this.wobblePhase=Math.random()*Math.PI*2,this.windDrift=e.windDrift??0,this.image=e.image,this.initialScale=e.initialScale??1,this.scaleUpDuration=e.scaleUpDuration??0,this.scale=this.initialScale;}update(){if(this.life++,this.vy+=this.gravity,this.scaleUpDuration>0&&this.life<this.scaleUpDuration){let e=this.life/this.scaleUpDuration,i=1-Math.pow(1-e,3);this.scale=this.initialScale+(1-this.initialScale)*i;}else this.scale=1;if(this.wobbleAmplitude>0?(this.wobblePhase+=this.wobbleSpeed,this.x+=this.vx+Math.sin(this.wobblePhase)*this.wobbleAmplitude):this.x+=this.vx,this.windDrift>0){let e=Math.sin(this.life*.05)*this.windDrift*.3+Math.sin(this.life*.02)*this.windDrift*.7;this.x+=e;}this.y+=this.vy,this.rotation+=this.rotationSpeed,this.opacity=1-this.life/this.maxLife;}isDead(){return this.life>=this.maxLife}draw(e){if(e.save(),e.globalAlpha=this.opacity,e.translate(this.x,this.y),e.scale(this.scale,this.scale),e.translate(-this.x,-this.y),this.image&&this.image.complete){e.imageSmoothingEnabled=true,e.imageSmoothingQuality="high";let i=this.size*2.5;e.translate(this.x,this.y),this.rotation!==0&&e.rotate(this.rotation),e.drawImage(this.image,-i/2,-i/2,i,i),e.restore();return}switch(e.fillStyle=this.color,this.shape){case "rectangle":this.rotation!==0&&(e.translate(this.x,this.y),e.rotate(this.rotation),e.translate(-this.x,-this.y)),y(e,this.x,this.y,this.size,this.size*1.5);break;case "circle":e.shadowBlur=15,e.shadowColor=this.color,e.beginPath(),e.arc(this.x,this.y,this.size,0,Math.PI*2),e.fill();break;case "snowflake":e.strokeStyle=this.color,e.lineWidth=1.5,E(e,this.x,this.y,this.size,this.rotation);break;case "bubble":C(e,this.x,this.y,this.size);break;case "cross":e.shadowBlur=18,e.shadowColor=this.color,P(e,this.x,this.y,this.size);break;case "oval":e.shadowBlur=12,e.shadowColor=this.color,F(e,this.x,this.y,this.size*2,this.size);break;default:w(e,this.x,this.y,this.size,5);break}e.restore();}};var f=class{static async loadImage(e){if(this.images.has(e))return this.images.get(e);if(this.loading.has(e))return this.loading.get(e);let i=new Promise((a,r)=>{let o=new Image;o.onload=()=>{this.images.set(e,o),this.loading.delete(e),a(o);},o.onerror=()=>{this.loading.delete(e),r(new Error(`Failed to load image: ${e}`));},o.src=e;});return this.loading.set(e,i),i}static async loadBubbles(e="/bubbles"){let i=[`${e}/soap_bubbles_1.png`,`${e}/soap_bubble_2.png`,`${e}/soap_bubble_3.png`];try{return await Promise.all(i.map(a=>this.loadImage(a)))}catch(a){return console.warn("Failed to load some bubble images, falling back to canvas rendering",a),[]}}static async loadSnowflakes(e="/snowflakes"){let i=[`${e}/snow_flake_1.png`,`${e}/snow_flake_2.png`];try{return await Promise.all(i.map(a=>this.loadImage(a)))}catch(a){return console.warn("Failed to load some snowflake images, falling back to canvas rendering",a),[]}}static getRandomBubble(){let e=Array.from(this.images.entries()).filter(([i])=>i.includes("bubble")).map(([,i])=>i);return e.length===0?null:e[Math.floor(Math.random()*e.length)]}static getRandomSnowflake(){let e=Array.from(this.images.entries()).filter(([i])=>i.includes("snow")).map(([,i])=>i);return e.length===0?null:e[Math.floor(Math.random()*e.length)]}static isLoaded(){return this.images.size>0}static clear(){this.images.clear(),this.loading.clear();}};f.images=new Map,f.loading=new Map;var O=["#FFD700","#FFC700","#FFB700","#FFED4E","#F4E04D"];function S(t={}){let{colors:e=O,particleCount:i=2,particleSize:a=6,gravity:r=-0.05,maxLife:o=40,velocity:n=3}=t;return {onMouseMove(s,m){let l=[];for(let h=0;h<i;h++)l.push(new c({x:s+(Math.random()-.5)*15,y:m+(Math.random()-.5)*15,vx:(Math.random()-.5)*n,vy:(Math.random()-.5)*n-1,size:Math.random()*a+3,color:d(e),maxLife:o+Math.random()*20,gravity:r,shape:"cross"}));return l}}}var k=["#FFD700","#FF69B4","#00CED1","#9370DB"];function D(t={}){let{colors:e=k,particleCount:i=1,particleSize:a=6,gravity:r=.1,maxLife:o=20,velocity:n=4}=t;return {onMouseMove(s,m){let l=[];for(let h=0;h<i;h++)l.push(new c({x:s+(Math.random()-.5)*10,y:m+(Math.random()-.5)*10,vx:(Math.random()-.5)*n,vy:(Math.random()-.5)*n,size:Math.random()*a+3,color:d(e),maxLife:o+Math.random()*10,gravity:r}));return l}}}var x=["#FF6B6B","#4ECDC4","#FFE66D","#95E1D3","#F38181","#AA96DA","#FCBAD3","#A8D8EA"];function L(t={}){let{colors:e=x,particleCount:i=3,particleSize:a=4,gravity:r=.3,maxLife:o=60,velocity:n=6}=t;return {onMouseMove(s,m){let l=[];for(let h=0;h<i;h++)l.push(new c({x:s+(Math.random()-.5)*20,y:m+(Math.random()-.5)*20,vx:(Math.random()-.5)*n,vy:(Math.random()-1)*n*.5,size:Math.random()*a+3,color:d(e),maxLife:o+Math.random()*20,gravity:r,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.2,shape:"rectangle"}));return l}}}var A=["#00FF00","#33FF33","#00CC00","#00DD00"];function T(t={}){let{colors:e=A,particleCount:i=3,particleSize:a=4,gravity:r=0,maxLife:o=60,velocity:n=1}=t;return {onMouseMove(s,m){let l=[];for(let h=0;h<i;h++)l.push(new c({x:s+(Math.random()-.5)*8,y:m+(Math.random()-.5)*8,vx:(Math.random()-.5)*n,vy:(Math.random()-.5)*n,size:Math.random()*a+2,color:d(e),maxLife:o+Math.random()*15,gravity:r,shape:"circle"}));return l}}}var z=["#FFFFFF","#F0F8FF","#E6F3FF","#F5F5F5"];function I(t={}){let{colors:e=z,particleCount:i=1,particleSize:a=7,gravity:r=.12,maxLife:o=150,velocity:n=.4,throttle:s=120,minMoveDistance:m=12}=t;return {throttle:s,minMoveDistance:m,onMouseMove(l,h){let u=[];for(let b=0;b<i;b++){let v=f.getRandomSnowflake();u.push(new c({x:l+(Math.random()-.5)*30,y:h+(Math.random()-.5)*15,vx:(Math.random()-.5)*n,vy:Math.random()*.2+.1,size:Math.random()*a+3,color:d(e),maxLife:o+Math.random()*60,gravity:r,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,shape:"snowflake",windDrift:.8,image:v||void 0}));}return u}}}var B=["rgba(173, 216, 230, 0.4)","rgba(135, 206, 235, 0.4)","rgba(176, 224, 230, 0.4)","rgba(175, 238, 238, 0.4)","rgba(224, 255, 255, 0.4)"];function R(t={}){let{colors:e=B,particleCount:i=1,gravity:a=-0.02,maxLife:r=180,velocity:o=.2,throttle:n=150,minMoveDistance:s=15}=t;return {throttle:n,minMoveDistance:s,onMouseMove(m,l){let h=[];for(let u=0;u<i;u++){let b=f.getRandomBubble(),v=15+Math.random()*30;h.push(new c({x:m+(Math.random()-.5)*10,y:l+(Math.random()-.5)*10,vx:(Math.random()-.5)*o,vy:-Math.random()*.15-.1,size:v,color:d(e),maxLife:r+Math.random()*60,gravity:a,shape:"bubble",wobbleAmplitude:.3,wobbleSpeed:.05,image:b||void 0,initialScale:.3,scaleUpDuration:15}));}return h}}}function Pe(t={}){if(typeof window<"u"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches)return {destroy:()=>{}};let e=new p,{effect:i="fairyDust",...a}=t,r={particleCount:2,...a},o=i==="confetti"?L(r):i==="sparkle"?D(r):i==="retroCRT"?T(r):i==="snow"?I(r):i==="bubble"?R(r):S(r);return e.start(o),{destroy:()=>e.destroy()}}exports.initCursorFX=Pe;return exports;})({});//# sourceMappingURL=cursor-fx.min.js.map
1
+ var CursorFX=(function(exports){'use strict';function d(t){return t[Math.floor(Math.random()*t.length)]}function M(t){let e=document.createElement("canvas");return e.style.position="fixed",e.style.top="0",e.style.left="0",e.style.pointerEvents="none",e.style.zIndex="9999",e.width=window.innerWidth,e.height=window.innerHeight,t.appendChild(e),e}function g(t){t.width=window.innerWidth,t.height=window.innerHeight;}function w(t,e,i,a,o=5){let r=a,n=a*.4;t.beginPath();for(let s=0;s<o*2;s++){let m=s*Math.PI/o,l=s%2===0?r:n,h=Math.cos(m)*l,u=Math.sin(m)*l;s===0?t.moveTo(e+h,i+u):t.lineTo(e+h,i+u);}t.closePath(),t.fill();}function y(t,e,i,a,o){t.fillRect(e-a/2,i-o/2,a,o);}function E(t,e,i,a,o=0){t.save(),t.translate(e,i),t.rotate(o),t.shadowBlur=4,t.shadowColor="#FFFFFF",t.lineWidth=1.8,t.beginPath();for(let r=0;r<6;r++){let n=r*Math.PI/3;t.moveTo(0,0),t.lineTo(Math.cos(n)*a,Math.sin(n)*a);}t.stroke(),t.restore();}function C(t,e,i,a){let o=t.fillStyle,r=t.createRadialGradient(e-a*.25,i-a*.25,0,e,i,a);r.addColorStop(0,"rgba(255, 255, 255, 0.3)"),r.addColorStop(.3,o),r.addColorStop(.7,o),r.addColorStop(1,"rgba(255, 255, 255, 0.1)"),t.beginPath(),t.arc(e,i,a,0,Math.PI*2),t.fillStyle=r,t.fill(),t.strokeStyle="rgba(255, 255, 255, 0.3)",t.lineWidth=1,t.stroke(),t.fillStyle="rgba(255, 255, 255, 0.6)",t.beginPath(),t.arc(e-a*.3,i-a*.3,a*.35,0,Math.PI*2),t.fill(),t.fillStyle="rgba(255, 255, 255, 0.9)",t.beginPath(),t.arc(e-a*.4,i-a*.4,a*.15,0,Math.PI*2),t.fill(),t.fillStyle="rgba(255, 255, 255, 0.2)",t.beginPath(),t.arc(e+a*.4,i+a*.4,a*.2,0,Math.PI*2),t.fill();}function P(t,e,i,a){let o=a/2,r=a*.3;t.fillRect(e-r/2,i-o,r,a),t.fillRect(e-o,i-r/2,a,r);}function F(t,e,i,a,o){t.save(),t.translate(e,i),t.scale(a/o,1),t.beginPath(),t.arc(0,0,o,0,Math.PI*2),t.fill(),t.restore();}var p=class{constructor(e={}){this.particles=[];this.animationId=null;this.effect=null;this.maxParticles=500;this.lastParticleTime=0;this.particleThrottle=16;this.lastMouseX=0;this.lastMouseY=0;this.minMoveDistance=0;if(e.canvas)this.canvas=e.canvas;else {let a=e.container||document.body;this.canvas=M(a);}let i=this.canvas.getContext("2d");if(!i)throw new Error("Failed to get 2D context");this.ctx=i,this.handleResize=this.handleResize.bind(this),this.handleMouseMove=this.handleMouseMove.bind(this),this.handleTouchMove=this.handleTouchMove.bind(this),this.animate=this.animate.bind(this),window.addEventListener("resize",this.handleResize);}handleResize(){g(this.canvas);}handleMouseMove(e){if(!this.effect)return;let i=Date.now(),a=e.clientX-this.lastMouseX,o=e.clientY-this.lastMouseY,r=Math.sqrt(a*a+o*o),n=this.effect.throttle??this.particleThrottle,s=this.effect.minMoveDistance??this.minMoveDistance;if(i-this.lastParticleTime>=n&&r>=s){this.lastParticleTime=i,this.lastMouseX=e.clientX,this.lastMouseY=e.clientY;let m=this.effect.onMouseMove(e.clientX,e.clientY);this.addParticles(m);}}handleTouchMove(e){if(!this.effect||e.touches.length===0)return;let i=Date.now(),a=e.touches[0],o=a.clientX-this.lastMouseX,r=a.clientY-this.lastMouseY,n=Math.sqrt(o*o+r*r),s=this.effect.throttle??this.particleThrottle,m=this.effect.minMoveDistance??this.minMoveDistance;if(i-this.lastParticleTime>=s&&n>=m){this.lastParticleTime=i,this.lastMouseX=a.clientX,this.lastMouseY=a.clientY;let l=this.effect.onMouseMove(a.clientX,a.clientY);this.addParticles(l);}}addParticle(e){this.particles.length<this.maxParticles&&this.particles.push(e);}addParticles(e){let i=this.maxParticles-this.particles.length;i>0&&this.particles.push(...e.slice(0,i));}update(){this.particles.forEach(e=>e.update()),this.particles=this.particles.filter(e=>!e.isDead());}draw(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.particles.forEach(e=>e.draw(this.ctx));}animate(){this.update(),this.draw(),this.animationId=requestAnimationFrame(this.animate);}start(e){this.animationId===null&&(this.effect=e,this.animationId=requestAnimationFrame(this.animate),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("touchmove",this.handleTouchMove,{passive:true}));}stop(){this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null,document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("touchmove",this.handleTouchMove));}clear(){this.particles=[],this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);}destroy(){this.stop(),this.clear(),window.removeEventListener("resize",this.handleResize),this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas);}};var c=class{constructor(e){this.x=e.x,this.y=e.y,this.vx=e.vx??(Math.random()-.5)*4,this.vy=e.vy??(Math.random()-.5)*4,this.size=e.size??3,this.color=e.color??"#ffffff",this.maxLife=e.maxLife??40,this.life=0,this.gravity=e.gravity??.1,this.opacity=1,this.rotation=e.rotation??0,this.rotationSpeed=e.rotationSpeed??0,this.shape=e.shape??"star",this.wobbleAmplitude=e.wobbleAmplitude??0,this.wobbleSpeed=e.wobbleSpeed??0,this.wobblePhase=Math.random()*Math.PI*2,this.windDrift=e.windDrift??0,this.image=e.image,this.initialScale=e.initialScale??1,this.scaleUpDuration=e.scaleUpDuration??0,this.scale=this.initialScale;}update(){if(this.life++,this.vy+=this.gravity,this.scaleUpDuration>0&&this.life<this.scaleUpDuration){let e=this.life/this.scaleUpDuration,i=1-Math.pow(1-e,3);this.scale=this.initialScale+(1-this.initialScale)*i;}else this.scale=1;if(this.wobbleAmplitude>0?(this.wobblePhase+=this.wobbleSpeed,this.x+=this.vx+Math.sin(this.wobblePhase)*this.wobbleAmplitude):this.x+=this.vx,this.windDrift>0){let e=Math.sin(this.life*.05)*this.windDrift*.3+Math.sin(this.life*.02)*this.windDrift*.7;this.x+=e;}this.y+=this.vy,this.rotation+=this.rotationSpeed,this.opacity=1-this.life/this.maxLife;}isDead(){return this.life>=this.maxLife}draw(e){if(e.save(),e.globalAlpha=this.opacity,e.translate(this.x,this.y),e.scale(this.scale,this.scale),e.translate(-this.x,-this.y),this.image&&this.image.complete){e.imageSmoothingEnabled=true,e.imageSmoothingQuality="high";let i=this.size*2.5;e.translate(this.x,this.y),this.rotation!==0&&e.rotate(this.rotation),e.drawImage(this.image,-i/2,-i/2,i,i),e.restore();return}switch(e.fillStyle=this.color,this.shape){case "rectangle":this.rotation!==0&&(e.translate(this.x,this.y),e.rotate(this.rotation),e.translate(-this.x,-this.y)),y(e,this.x,this.y,this.size,this.size*1.5);break;case "circle":e.shadowBlur=15,e.shadowColor=this.color,e.beginPath(),e.arc(this.x,this.y,this.size,0,Math.PI*2),e.fill();break;case "snowflake":e.strokeStyle=this.color,e.lineWidth=1.5,E(e,this.x,this.y,this.size,this.rotation);break;case "bubble":C(e,this.x,this.y,this.size);break;case "cross":e.shadowBlur=18,e.shadowColor=this.color,P(e,this.x,this.y,this.size);break;case "oval":e.shadowBlur=12,e.shadowColor=this.color,F(e,this.x,this.y,this.size*2,this.size);break;default:w(e,this.x,this.y,this.size,5);break}e.restore();}};var f=class{static async loadImage(e){if(this.images.has(e))return this.images.get(e);if(this.loading.has(e))return this.loading.get(e);let i=new Promise((a,o)=>{let r=new Image;r.onload=()=>{this.images.set(e,r),this.loading.delete(e),a(r);},r.onerror=()=>{this.loading.delete(e),o(new Error(`Failed to load image: ${e}`));},r.src=e;});return this.loading.set(e,i),i}static async loadBubbles(e="/bubbles"){let i=[`${e}/soap_bubbles_1.png`,`${e}/soap_bubble_2.png`,`${e}/soap_bubble_3.png`];try{return await Promise.all(i.map(a=>this.loadImage(a)))}catch(a){return console.warn("Failed to load some bubble images, falling back to canvas rendering",a),[]}}static async loadSnowflakes(e="/snowflakes"){let i=[`${e}/snow_flake_1.png`,`${e}/snow_flake_2.png`];try{return await Promise.all(i.map(a=>this.loadImage(a)))}catch(a){return console.warn("Failed to load some snowflake images, falling back to canvas rendering",a),[]}}static getRandomBubble(){let e=Array.from(this.images.entries()).filter(([i])=>i.includes("bubble")).map(([,i])=>i);return e.length===0?null:e[Math.floor(Math.random()*e.length)]}static getRandomSnowflake(){let e=Array.from(this.images.entries()).filter(([i])=>i.includes("snow")).map(([,i])=>i);return e.length===0?null:e[Math.floor(Math.random()*e.length)]}static isLoaded(){return this.images.size>0}static clear(){this.images.clear(),this.loading.clear();}};f.images=new Map,f.loading=new Map;var x=["#FFD700","#FFC700","#FFB700","#FFED4E","#F4E04D"];function S(t={}){let{colors:e=x,particleCount:i=2,particleSize:a=6,gravity:o=-0.05,maxLife:r=40,velocity:n=3}=t;return {onMouseMove(s,m){let l=[];for(let h=0;h<i;h++)l.push(new c({x:s+(Math.random()-.5)*15,y:m+(Math.random()-.5)*15,vx:(Math.random()-.5)*n,vy:(Math.random()-.5)*n-1,size:Math.random()*a+3,color:d(e),maxLife:r+Math.random()*20,gravity:o,shape:"cross"}));return l}}}var O=["#FFD700","#FF69B4","#00CED1","#9370DB"];function D(t={}){let{colors:e=O,particleCount:i=1,particleSize:a=6,gravity:o=.1,maxLife:r=20,velocity:n=4}=t;return {onMouseMove(s,m){let l=[];for(let h=0;h<i;h++)l.push(new c({x:s+(Math.random()-.5)*10,y:m+(Math.random()-.5)*10,vx:(Math.random()-.5)*n,vy:(Math.random()-.5)*n,size:Math.random()*a+3,color:d(e),maxLife:r+Math.random()*10,gravity:o}));return l}}}var k=["#FF6B6B","#4ECDC4","#FFE66D","#95E1D3","#F38181","#AA96DA","#FCBAD3","#A8D8EA"];function L(t={}){let{colors:e=k,particleCount:i=3,particleSize:a=4,gravity:o=.3,maxLife:r=60,velocity:n=6}=t;return {onMouseMove(s,m){let l=[];for(let h=0;h<i;h++)l.push(new c({x:s+(Math.random()-.5)*20,y:m+(Math.random()-.5)*20,vx:(Math.random()-.5)*n,vy:(Math.random()-1)*n*.5,size:Math.random()*a+3,color:d(e),maxLife:r+Math.random()*20,gravity:o,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.2,shape:"rectangle"}));return l}}}var A=["#00FF00","#33FF33","#00CC00","#00DD00"];function I(t={}){let{colors:e=A,particleCount:i=3,particleSize:a=4,gravity:o=0,maxLife:r=60,velocity:n=1}=t;return {onMouseMove(s,m){let l=[];for(let h=0;h<i;h++)l.push(new c({x:s+(Math.random()-.5)*8,y:m+(Math.random()-.5)*8,vx:(Math.random()-.5)*n,vy:(Math.random()-.5)*n,size:Math.random()*a+2,color:d(e),maxLife:r+Math.random()*15,gravity:o,shape:"circle"}));return l}}}var z=["#FFFFFF","#F0F8FF","#E6F3FF","#F5F5F5"];function T(t={}){let{colors:e=z,particleCount:i=1,particleSize:a=7,gravity:o=.12,maxLife:r=150,velocity:n=.4,throttle:s=120,minMoveDistance:m=12}=t;return {throttle:s,minMoveDistance:m,onMouseMove(l,h){let u=[];for(let b=0;b<i;b++){let v=f.getRandomSnowflake();u.push(new c({x:l+(Math.random()-.5)*30,y:h+(Math.random()-.5)*15,vx:(Math.random()-.5)*n,vy:Math.random()*.2+.1,size:Math.random()*a+3,color:d(e),maxLife:r+Math.random()*60,gravity:o,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,shape:"snowflake",windDrift:.8,image:v||void 0}));}return u}}}var B=["rgba(173, 216, 230, 0.4)","rgba(135, 206, 235, 0.4)","rgba(176, 224, 230, 0.4)","rgba(175, 238, 238, 0.4)","rgba(224, 255, 255, 0.4)"];function R(t={}){let{colors:e=B,particleCount:i=1,gravity:a=-0.02,maxLife:o=180,velocity:r=.2,throttle:n=150,minMoveDistance:s=15}=t;return {throttle:n,minMoveDistance:s,onMouseMove(m,l){let h=[];for(let u=0;u<i;u++){let b=f.getRandomBubble(),v=15+Math.random()*30;h.push(new c({x:m+(Math.random()-.5)*10,y:l+(Math.random()-.5)*10,vx:(Math.random()-.5)*r,vy:-Math.random()*.15-.1,size:v,color:d(e),maxLife:o+Math.random()*60,gravity:a,shape:"bubble",wobbleAmplitude:.3,wobbleSpeed:.05,image:b||void 0,initialScale:.3,scaleUpDuration:15}));}return h}}}function Pe(t={}){if(typeof window<"u"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches)return {destroy:()=>{}};let e=new p,{effect:i="fairyDust",...a}=t,o=i==="confetti"?L(a):i==="sparkle"?D(a):i==="retroCRT"?I(a):i==="snow"?T(a):i==="bubble"?R(a):S(a);return e.start(o),{destroy:()=>e.destroy()}}exports.ImageLoader=f;exports.initCursorFX=Pe;return exports;})({});//# sourceMappingURL=cursor-fx.min.js.map
2
2
  //# sourceMappingURL=cursor-fx.min.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/utils.ts","../../src/core/engine.ts","../../src/core/particle.ts","../../src/core/imageLoader.ts","../../src/core/effects/fairyDust.ts","../../src/core/effects/sparkle.ts","../../src/core/effects/confetti.ts","../../src/core/effects/retroCRT.ts","../../src/core/effects/snow.ts","../../src/core/effects/bubble.ts","../../src/vanilla/index.ts"],"names":["randomColor","colors","createCanvas","container","canvas","resizeCanvas","drawStar","ctx","x","y","size","spikes","outerRadius","innerRadius","i","angle","radius","dx","dy","drawRectangle","width","height","drawSnowflake","rotation","drawBubble","baseColor","mainGradient","drawCross","halfSize","thickness","drawOval","CursorFXEngine","options","now","distance","throttle","minDist","particles","touch","particle","availableSlots","effect","Particle","config","progress","easedProgress","drift","imgSize","ImageLoader","src","loadPromise","resolve","reject","img","basePath","bubblePaths","path","error","snowflakePaths","bubbleImages","key","snowflakeImages","DEFAULT_COLORS","createFairyDustEffect","particleCount","particleSize","gravity","maxLife","velocity","createSparkleEffect","createConfettiEffect","createRetroCRTEffect","createSnowEffect","minMoveDistance","snowflakeImage","createBubbleEffect","bubbleImage","baseSize","initCursorFX","engine","effectOptions","optimizedOptions","selectedEffect"],"mappings":"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","file":"cursor-fx.min.js","sourcesContent":["export function randomColor(colors: string[]): string {\n return colors[Math.floor(Math.random() * colors.length)];\n}\n\nexport function randomRange(min: number, max: number): number {\n return Math.random() * (max - min) + min;\n}\n\nexport function createCanvas(container: HTMLElement): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n canvas.style.position = 'fixed';\n canvas.style.top = '0';\n canvas.style.left = '0';\n canvas.style.pointerEvents = 'none';\n canvas.style.zIndex = '9999';\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n container.appendChild(canvas);\n return canvas;\n}\n\nexport function resizeCanvas(canvas: HTMLCanvasElement): void {\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n}\n\nexport function drawStar(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n spikes: number = 5\n): void {\n const outerRadius = size;\n const innerRadius = size * 0.4;\n\n ctx.beginPath();\n for (let i = 0; i < spikes * 2; i++) {\n const angle = (i * Math.PI) / spikes;\n const radius = i % 2 === 0 ? outerRadius : innerRadius;\n const dx = Math.cos(angle) * radius;\n const dy = Math.sin(angle) * radius;\n\n if (i === 0) {\n ctx.moveTo(x + dx, y + dy);\n } else {\n ctx.lineTo(x + dx, y + dy);\n }\n }\n ctx.closePath();\n ctx.fill();\n}\n\nexport function drawRectangle(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.fillRect(x - width / 2, y - height / 2, width, height);\n}\n\nexport function drawSnowflake(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n rotation: number = 0\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Optimized glow - reduced blur for better performance\n ctx.shadowBlur = 4;\n ctx.shadowColor = '#FFFFFF';\n ctx.lineWidth = 1.8; // Slightly thicker for better visibility\n\n // Draw all 6 arms in a single path for better performance\n ctx.beginPath();\n for (let i = 0; i < 6; i++) {\n const angle = (i * Math.PI) / 3;\n ctx.moveTo(0, 0);\n ctx.lineTo(Math.cos(angle) * size, Math.sin(angle) * size);\n }\n ctx.stroke();\n\n ctx.restore();\n}\n\nexport function drawBubble(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Save the original fill color\n const baseColor = ctx.fillStyle as string;\n\n // Main bubble with multi-layer gradient for depth\n const mainGradient = ctx.createRadialGradient(x - size * 0.25, y - size * 0.25, 0, x, y, size);\n mainGradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');\n mainGradient.addColorStop(0.3, baseColor);\n mainGradient.addColorStop(0.7, baseColor);\n mainGradient.addColorStop(1, 'rgba(255, 255, 255, 0.1)');\n\n ctx.beginPath();\n ctx.arc(x, y, size, 0, Math.PI * 2);\n ctx.fillStyle = mainGradient;\n ctx.fill();\n\n // Subtle border/rim for definition\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';\n ctx.lineWidth = 1;\n ctx.stroke();\n\n // Primary highlight (large, soft)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';\n ctx.beginPath();\n ctx.arc(x - size * 0.3, y - size * 0.3, size * 0.35, 0, Math.PI * 2);\n ctx.fill();\n\n // Secondary highlight (small, bright)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';\n ctx.beginPath();\n ctx.arc(x - size * 0.4, y - size * 0.4, size * 0.15, 0, Math.PI * 2);\n ctx.fill();\n\n // Reflected light on opposite side\n ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';\n ctx.beginPath();\n ctx.arc(x + size * 0.4, y + size * 0.4, size * 0.2, 0, Math.PI * 2);\n ctx.fill();\n}\n\nexport function drawCross(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Draw simple 4-pointed cross/plus shape\n const halfSize = size / 2;\n const thickness = size * 0.3;\n\n // Vertical bar\n ctx.fillRect(x - thickness / 2, y - halfSize, thickness, size);\n // Horizontal bar\n ctx.fillRect(x - halfSize, y - thickness / 2, size, thickness);\n}\n\nexport function drawOval(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.scale(width / height, 1);\n ctx.beginPath();\n ctx.arc(0, 0, height, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\n}\n","import { Particle } from './particle';\nimport { createCanvas, resizeCanvas } from './utils';\nimport type { EngineOptions, Effect } from './types';\n\nexport class CursorFXEngine {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private particles: Particle[] = [];\n private animationId: number | null = null;\n private effect: Effect | null = null;\n private maxParticles: number = 500; // Cap to prevent performance issues\n private lastParticleTime: number = 0;\n private particleThrottle: number = 16; // Create particles every 16ms (~60fps)\n private lastMouseX: number = 0;\n private lastMouseY: number = 0;\n private minMoveDistance: number = 0; // Create particles on every valid move\n\n constructor(options: EngineOptions = {}) {\n if (options.canvas) {\n this.canvas = options.canvas;\n } else {\n const container = options.container || document.body;\n this.canvas = createCanvas(container);\n }\n\n const ctx = this.canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context');\n }\n this.ctx = ctx;\n\n // Bind methods once to prevent memory leaks\n this.handleResize = this.handleResize.bind(this);\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleTouchMove = this.handleTouchMove.bind(this);\n this.animate = this.animate.bind(this);\n\n window.addEventListener('resize', this.handleResize);\n }\n\n private handleResize(): void {\n resizeCanvas(this.canvas);\n }\n\n private handleMouseMove(e: MouseEvent): void {\n if (!this.effect) return;\n\n const now = Date.now();\n const dx = e.clientX - this.lastMouseX;\n const dy = e.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND mouse moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = e.clientX;\n this.lastMouseY = e.clientY;\n const particles = this.effect.onMouseMove(e.clientX, e.clientY);\n this.addParticles(particles);\n }\n }\n\n private handleTouchMove(e: TouchEvent): void {\n if (!this.effect || e.touches.length === 0) return;\n\n const now = Date.now();\n const touch = e.touches[0];\n const dx = touch.clientX - this.lastMouseX;\n const dy = touch.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND touch moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = touch.clientX;\n this.lastMouseY = touch.clientY;\n const particles = this.effect.onMouseMove(touch.clientX, touch.clientY);\n this.addParticles(particles);\n }\n }\n\n addParticle(particle: Particle): void {\n if (this.particles.length < this.maxParticles) {\n this.particles.push(particle);\n }\n }\n\n addParticles(particles: Particle[]): void {\n const availableSlots = this.maxParticles - this.particles.length;\n if (availableSlots > 0) {\n this.particles.push(...particles.slice(0, availableSlots));\n }\n }\n\n private update(): void {\n // Update all particles\n this.particles.forEach(particle => particle.update());\n // Remove dead particles\n this.particles = this.particles.filter(particle => !particle.isDead());\n }\n\n private draw(): void {\n // Clear canvas\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n // Render all particles with shadow/glow effects\n this.particles.forEach(particle => particle.draw(this.ctx));\n }\n\n private animate(): void {\n this.update();\n this.draw();\n this.animationId = requestAnimationFrame(this.animate);\n }\n\n start(effect: Effect): void {\n if (this.animationId === null) {\n this.effect = effect;\n this.animationId = requestAnimationFrame(this.animate);\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('touchmove', this.handleTouchMove, { passive: true });\n }\n }\n\n stop(): void {\n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n this.animationId = null;\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('touchmove', this.handleTouchMove);\n }\n }\n\n clear(): void {\n this.particles = [];\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n destroy(): void {\n this.stop();\n this.clear();\n window.removeEventListener('resize', this.handleResize);\n if (this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n}\n","import type { ParticleConfig } from './types';\nimport { drawStar, drawRectangle, drawSnowflake, drawBubble, drawCross, drawOval } from './utils';\n\nexport class Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size: number;\n color: string;\n life: number;\n maxLife: number;\n gravity: number;\n opacity: number;\n rotation: number;\n rotationSpeed: number;\n shape: 'star' | 'rectangle' | 'circle' | 'snowflake' | 'bubble' | 'cross' | 'oval';\n wobbleAmplitude: number;\n wobbleSpeed: number;\n wobblePhase: number;\n windDrift: number;\n image?: HTMLImageElement;\n scale: number;\n initialScale: number;\n scaleUpDuration: number;\n\n constructor(config: ParticleConfig) {\n this.x = config.x;\n this.y = config.y;\n this.vx = config.vx ?? (Math.random() - 0.5) * 4;\n this.vy = config.vy ?? (Math.random() - 0.5) * 4;\n this.size = config.size ?? 3;\n this.color = config.color ?? '#ffffff';\n this.maxLife = config.maxLife ?? 40; // Reduced for better performance\n this.life = 0;\n this.gravity = config.gravity ?? 0.1;\n this.opacity = 1;\n this.rotation = config.rotation ?? 0;\n this.rotationSpeed = config.rotationSpeed ?? 0;\n this.shape = config.shape ?? 'star';\n this.wobbleAmplitude = config.wobbleAmplitude ?? 0;\n this.wobbleSpeed = config.wobbleSpeed ?? 0;\n this.wobblePhase = Math.random() * Math.PI * 2; // Random starting phase\n this.windDrift = config.windDrift ?? 0;\n this.image = config.image;\n this.initialScale = config.initialScale ?? 1; // Default to full scale\n this.scaleUpDuration = config.scaleUpDuration ?? 0; // Default no animation\n this.scale = this.initialScale; // Start at initial scale\n }\n\n update(): void {\n this.life++;\n this.vy += this.gravity;\n\n // Animate scale from initialScale to 1.0 over scaleUpDuration frames\n if (this.scaleUpDuration > 0 && this.life < this.scaleUpDuration) {\n const progress = this.life / this.scaleUpDuration;\n // Ease-out cubic for smooth pop-up effect\n const easedProgress = 1 - Math.pow(1 - progress, 3);\n this.scale = this.initialScale + (1 - this.initialScale) * easedProgress;\n } else {\n this.scale = 1;\n }\n\n // Apply wobble (for bubbles)\n if (this.wobbleAmplitude > 0) {\n this.wobblePhase += this.wobbleSpeed;\n this.x += this.vx + Math.sin(this.wobblePhase) * this.wobbleAmplitude;\n } else {\n this.x += this.vx;\n }\n\n // Apply wind drift (for snowflakes)\n if (this.windDrift > 0) {\n // Smooth Perlin-like drift using sine waves at different frequencies\n const drift = Math.sin(this.life * 0.05) * this.windDrift * 0.3 +\n Math.sin(this.life * 0.02) * this.windDrift * 0.7;\n this.x += drift;\n }\n\n this.y += this.vy;\n this.rotation += this.rotationSpeed;\n this.opacity = 1 - this.life / this.maxLife;\n }\n\n isDead(): boolean {\n return this.life >= this.maxLife;\n }\n\n draw(ctx: CanvasRenderingContext2D): void {\n ctx.save();\n ctx.globalAlpha = this.opacity;\n\n // Apply scale transform (for pop-up animation)\n ctx.translate(this.x, this.y);\n ctx.scale(this.scale, this.scale);\n ctx.translate(-this.x, -this.y);\n\n // If image is available, render image instead of shape\n if (this.image && this.image.complete) {\n // Enable high-quality image smoothing for better rendering\n ctx.imageSmoothingEnabled = true;\n ctx.imageSmoothingQuality = 'high';\n\n const imgSize = this.size * 2.5; // Larger multiplier for bigger images\n ctx.translate(this.x, this.y);\n if (this.rotation !== 0) {\n ctx.rotate(this.rotation);\n }\n\n // Add simple glow for snowflake images (single pass)\n // if (this.shape === 'snowflake') {\n // ctx.shadowBlur = 8;\n // ctx.shadowColor = '#FFFFFF';\n // }\n\n ctx.drawImage(\n this.image,\n -imgSize / 2,\n -imgSize / 2,\n imgSize,\n imgSize\n );\n ctx.restore();\n return;\n }\n\n // Fallback to shape rendering\n ctx.fillStyle = this.color;\n\n // Draw based on shape\n switch (this.shape) {\n case 'rectangle':\n if (this.rotation !== 0) {\n ctx.translate(this.x, this.y);\n ctx.rotate(this.rotation);\n ctx.translate(-this.x, -this.y);\n }\n drawRectangle(ctx, this.x, this.y, this.size, this.size * 1.5);\n break;\n\n case 'circle':\n ctx.shadowBlur = 15; // Strong glow for circles\n ctx.shadowColor = this.color;\n ctx.beginPath();\n ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\n ctx.fill();\n break;\n\n case 'snowflake':\n ctx.strokeStyle = this.color;\n ctx.lineWidth = 1.5;\n drawSnowflake(ctx, this.x, this.y, this.size, this.rotation);\n break;\n\n case 'bubble':\n drawBubble(ctx, this.x, this.y, this.size);\n break;\n\n case 'cross':\n ctx.shadowBlur = 18; // Strong glow for fairy dust\n ctx.shadowColor = this.color;\n drawCross(ctx, this.x, this.y, this.size);\n break;\n\n case 'oval':\n ctx.shadowBlur = 12; // Moderate glow for CRT phosphor\n ctx.shadowColor = this.color;\n drawOval(ctx, this.x, this.y, this.size * 2, this.size);\n break;\n\n default: // star\n drawStar(ctx, this.x, this.y, this.size, 5);\n break;\n }\n\n ctx.restore();\n }\n}\n","// Image loader for bubble assets\nexport class ImageLoader {\n private static images: Map<string, HTMLImageElement> = new Map();\n private static loading: Map<string, Promise<HTMLImageElement>> = new Map();\n\n static async loadImage(src: string): Promise<HTMLImageElement> {\n // Return cached image if already loaded\n if (this.images.has(src)) {\n return this.images.get(src)!;\n }\n\n // Return existing promise if currently loading\n if (this.loading.has(src)) {\n return this.loading.get(src)!;\n }\n\n // Create new loading promise\n const loadPromise = new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n this.images.set(src, img);\n this.loading.delete(src);\n resolve(img);\n };\n img.onerror = () => {\n this.loading.delete(src);\n reject(new Error(`Failed to load image: ${src}`));\n };\n img.src = src;\n });\n\n this.loading.set(src, loadPromise);\n return loadPromise;\n }\n\n static async loadBubbles(basePath: string = '/bubbles'): Promise<HTMLImageElement[]> {\n const bubblePaths = [\n `${basePath}/soap_bubbles_1.png`,\n `${basePath}/soap_bubble_2.png`,\n `${basePath}/soap_bubble_3.png`,\n ];\n\n try {\n return await Promise.all(bubblePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some bubble images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static async loadSnowflakes(basePath: string = '/snowflakes'): Promise<HTMLImageElement[]> {\n const snowflakePaths = [\n // `${basePath}/snowflake.png`,\n `${basePath}/snow_flake_1.png`,\n `${basePath}/snow_flake_2.png`,\n ];\n\n try {\n return await Promise.all(snowflakePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some snowflake images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static getRandomBubble(): HTMLImageElement | null {\n const bubbleImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('bubble'))\n .map(([, img]) => img);\n if (bubbleImages.length === 0) return null;\n return bubbleImages[Math.floor(Math.random() * bubbleImages.length)];\n }\n\n static getRandomSnowflake(): HTMLImageElement | null {\n const snowflakeImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('snow'))\n .map(([, img]) => img);\n if (snowflakeImages.length === 0) return null;\n return snowflakeImages[Math.floor(Math.random() * snowflakeImages.length)];\n }\n\n static isLoaded(): boolean {\n return this.images.size > 0;\n }\n\n static clear(): void {\n this.images.clear();\n this.loading.clear();\n }\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FFC700', // Golden Yellow\n '#FFB700', // Amber\n '#FFED4E', // Light Gold\n '#F4E04D', // Pale Gold\n];\n\nexport function createFairyDustEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 2,\n particleSize = 6, // Increased from 4 for better visibility\n gravity = -0.05, // Slight upward float for magical feel\n maxLife = 40,\n velocity = 3,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 15,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity - 1, // Slight upward bias\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n shape: 'cross',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FF69B4', // Hot Pink\n '#00CED1', // Dark Turquoise\n '#9370DB', // Medium Purple\n];\n\nexport function createSparkleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Reduced for better performance\n particleSize = 6, // Increased from 3 for better visibility\n gravity = 0.1,\n maxLife = 20, // Further reduced for faster cleanup\n velocity = 4,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10,\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 10, // Reduced random variation\n gravity,\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FF6B6B', // Red\n '#4ECDC4', // Turquoise\n '#FFE66D', // Yellow\n '#95E1D3', // Mint\n '#F38181', // Pink\n '#AA96DA', // Purple\n '#FCBAD3', // Light Pink\n '#A8D8EA', // Sky Blue\n];\n\nexport function createConfettiEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4,\n gravity = 0.3, // Stronger gravity for falling effect\n maxLife = 60, // Longer lifetime for confetti\n velocity = 6,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 20,\n y: y + (Math.random() - 0.5) * 20,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 1) * velocity * 0.5, // Bias upward initially\n size: Math.random() * particleSize + 3,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.2, // Rotation speed\n shape: 'rectangle',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#00FF00', // Classic phosphor green\n '#33FF33', // Bright phosphor green\n '#00CC00', // Medium phosphor green\n '#00DD00', // Light phosphor green\n];\n\nexport function createRetroCRTEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4, // Slightly larger for better visibility\n gravity = 0, // No gravity - phosphor glows in place\n maxLife = 60, // Longer persistence like real phosphor\n velocity = 1, // Very slow movement for authentic glow\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 8,\n y: y + (Math.random() - 0.5) * 8,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 2,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 15,\n gravity,\n shape: 'circle', // Back to circles with strong glow\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFFFFF', // Pure white\n '#F0F8FF', // Alice blue\n '#E6F3FF', // Light blue white\n '#F5F5F5', // White smoke\n];\n\n// ⚙️ CONFIGURATION FLAG: Switch between image-based and canvas-drawn snowflakes\nconst USE_SNOWFLAKE_IMAGES = true; // Set to true to use PNG images, false for canvas drawing\n\nexport function createSnowEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // One snowflake at a time\n particleSize = 7, // Bigger for better visibility\n gravity = 0.12, // Faster falling\n maxLife = 150, // Shorter lifetime for faster fall\n velocity = 0.4, // Slightly more drift\n throttle = 120, // Spawn every 120ms - less frequent\n minMoveDistance = 12, // Only spawn when cursor moves 12px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n // Conditionally get snowflake image based on flag\n const snowflakeImage = USE_SNOWFLAKE_IMAGES ? ImageLoader.getRandomSnowflake() : null;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 30,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: Math.random() * 0.2 + 0.1, // Slightly faster downward initial velocity\n size: Math.random() * particleSize + 3, // Variable sizes (3-10px for canvas, base for images)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.03, // More visible rotation\n shape: 'snowflake',\n windDrift: 0.8, // Gentle wind drift/sway\n image: snowflakeImage || undefined, // Use image if flag is true and images loaded\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n 'rgba(173, 216, 230, 0.4)', // Light blue - transparent\n 'rgba(135, 206, 235, 0.4)', // Sky blue - transparent\n 'rgba(176, 224, 230, 0.4)', // Powder blue - transparent\n 'rgba(175, 238, 238, 0.4)', // Pale turquoise - transparent\n 'rgba(224, 255, 255, 0.4)', // Light cyan - transparent\n];\n\nexport function createBubbleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Spawn one bubble at a time\n gravity = -0.02, // Gentle upward buoyancy\n maxLife = 180, // Longer lifetime for slow rise\n velocity = 0.2, // Minimal base horizontal drift\n throttle = 150, // Spawn every 150ms - much less frequent\n minMoveDistance = 15, // Only spawn when cursor moves 15px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n const bubbleImage = ImageLoader.getRandomBubble();\n\n // Create more dramatic size variation (15-45 range for 2.5x multiplier = 37-112px actual)\n const baseSize = 15 + Math.random() * 30;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10, // Spawn closer to pointer\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: -Math.random() * 0.15 - 0.1, // Very slow, consistent upward\n size: baseSize, // Wide size variation (15-45)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n shape: 'bubble',\n wobbleAmplitude: 0.3, // Gentle horizontal wobble\n wobbleSpeed: 0.05, // Slow wobble oscillation\n image: bubbleImage || undefined, // Use image if loaded, fallback to canvas\n initialScale: 0.3, // Start at 30% size for pop-up effect\n scaleUpDuration: 15, // Grow to full size over 15 frames (~250ms)\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { CursorFXEngine, createFairyDustEffect, createSparkleEffect, createConfettiEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect } from '../core';\n\nexport type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';\n\nexport interface InitCursorFXOptions {\n effect?: CursorEffectType;\n colors?: string[];\n particleCount?: number;\n particleSize?: number;\n gravity?: number;\n maxLife?: number;\n velocity?: number;\n}\n\nexport interface CursorFXInstance {\n destroy: () => void;\n}\n\n/**\n * Initialize cursor effects with a single function call.\n * Creates canvas, appends to body, and starts the fairy dust effect.\n *\n * @param options - Configuration options for the effect\n * @returns Instance with destroy() method for cleanup\n *\n * @example\n * ```ts\n * const fx = initCursorFX({\n * colors: ['#FFD700', '#FF69B4'],\n * particleCount: 5\n * });\n *\n * // Later, to cleanup:\n * fx.destroy();\n * ```\n */\nexport function initCursorFX(options: InitCursorFXOptions = {}): CursorFXInstance {\n // Check for prefers-reduced-motion\n if (typeof window !== 'undefined') {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n // Return no-op instance if user prefers reduced motion\n return { destroy: () => {} };\n }\n }\n\n // Create engine (automatically creates and appends canvas with fixed positioning)\n const engine = new CursorFXEngine();\n\n // Extract effect type from options\n const { effect = 'fairyDust', ...effectOptions } = options;\n\n // Reduce particle count for better performance\n const optimizedOptions = {\n particleCount: 2, // Reduced from default 3\n ...effectOptions,\n };\n\n // Select effect based on type\n const selectedEffect =\n effect === 'confetti'\n ? createConfettiEffect(optimizedOptions)\n : effect === 'sparkle'\n ? createSparkleEffect(optimizedOptions)\n : effect === 'retroCRT'\n ? createRetroCRTEffect(optimizedOptions)\n : effect === 'snow'\n ? createSnowEffect(optimizedOptions)\n : effect === 'bubble'\n ? createBubbleEffect(optimizedOptions)\n : createFairyDustEffect(optimizedOptions);\n\n // Start the engine with the effect\n engine.start(selectedEffect);\n\n return {\n destroy: () => engine.destroy(),\n };\n}\n\n// Export types for TypeScript users\nexport type { EffectOptions } from '../core/types';\n"]}
1
+ {"version":3,"sources":["../../src/core/utils.ts","../../src/core/engine.ts","../../src/core/particle.ts","../../src/core/imageLoader.ts","../../src/core/effects/fairyDust.ts","../../src/core/effects/sparkle.ts","../../src/core/effects/confetti.ts","../../src/core/effects/retroCRT.ts","../../src/core/effects/snow.ts","../../src/core/effects/bubble.ts","../../src/vanilla/index.ts"],"names":["randomColor","colors","createCanvas","container","canvas","resizeCanvas","drawStar","ctx","x","y","size","spikes","outerRadius","innerRadius","i","angle","radius","dx","dy","drawRectangle","width","height","drawSnowflake","rotation","drawBubble","baseColor","mainGradient","drawCross","halfSize","thickness","drawOval","CursorFXEngine","options","now","distance","throttle","minDist","particles","touch","particle","availableSlots","effect","Particle","config","progress","easedProgress","drift","imgSize","ImageLoader","src","loadPromise","resolve","reject","img","basePath","bubblePaths","path","error","snowflakePaths","bubbleImages","key","snowflakeImages","DEFAULT_COLORS","createFairyDustEffect","particleCount","particleSize","gravity","maxLife","velocity","createSparkleEffect","createConfettiEffect","createRetroCRTEffect","createSnowEffect","minMoveDistance","snowflakeImage","createBubbleEffect","bubbleImage","baseSize","initCursorFX","engine","effectOptions","selectedEffect"],"mappings":"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","file":"cursor-fx.min.js","sourcesContent":["export function randomColor(colors: string[]): string {\n return colors[Math.floor(Math.random() * colors.length)];\n}\n\nexport function randomRange(min: number, max: number): number {\n return Math.random() * (max - min) + min;\n}\n\nexport function createCanvas(container: HTMLElement): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n canvas.style.position = 'fixed';\n canvas.style.top = '0';\n canvas.style.left = '0';\n canvas.style.pointerEvents = 'none';\n canvas.style.zIndex = '9999';\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n container.appendChild(canvas);\n return canvas;\n}\n\nexport function resizeCanvas(canvas: HTMLCanvasElement): void {\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n}\n\nexport function drawStar(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n spikes: number = 5\n): void {\n const outerRadius = size;\n const innerRadius = size * 0.4;\n\n ctx.beginPath();\n for (let i = 0; i < spikes * 2; i++) {\n const angle = (i * Math.PI) / spikes;\n const radius = i % 2 === 0 ? outerRadius : innerRadius;\n const dx = Math.cos(angle) * radius;\n const dy = Math.sin(angle) * radius;\n\n if (i === 0) {\n ctx.moveTo(x + dx, y + dy);\n } else {\n ctx.lineTo(x + dx, y + dy);\n }\n }\n ctx.closePath();\n ctx.fill();\n}\n\nexport function drawRectangle(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.fillRect(x - width / 2, y - height / 2, width, height);\n}\n\nexport function drawSnowflake(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n rotation: number = 0\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Optimized glow - reduced blur for better performance\n ctx.shadowBlur = 4;\n ctx.shadowColor = '#FFFFFF';\n ctx.lineWidth = 1.8; // Slightly thicker for better visibility\n\n // Draw all 6 arms in a single path for better performance\n ctx.beginPath();\n for (let i = 0; i < 6; i++) {\n const angle = (i * Math.PI) / 3;\n ctx.moveTo(0, 0);\n ctx.lineTo(Math.cos(angle) * size, Math.sin(angle) * size);\n }\n ctx.stroke();\n\n ctx.restore();\n}\n\nexport function drawBubble(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Save the original fill color\n const baseColor = ctx.fillStyle as string;\n\n // Main bubble with multi-layer gradient for depth\n const mainGradient = ctx.createRadialGradient(x - size * 0.25, y - size * 0.25, 0, x, y, size);\n mainGradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');\n mainGradient.addColorStop(0.3, baseColor);\n mainGradient.addColorStop(0.7, baseColor);\n mainGradient.addColorStop(1, 'rgba(255, 255, 255, 0.1)');\n\n ctx.beginPath();\n ctx.arc(x, y, size, 0, Math.PI * 2);\n ctx.fillStyle = mainGradient;\n ctx.fill();\n\n // Subtle border/rim for definition\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';\n ctx.lineWidth = 1;\n ctx.stroke();\n\n // Primary highlight (large, soft)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';\n ctx.beginPath();\n ctx.arc(x - size * 0.3, y - size * 0.3, size * 0.35, 0, Math.PI * 2);\n ctx.fill();\n\n // Secondary highlight (small, bright)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';\n ctx.beginPath();\n ctx.arc(x - size * 0.4, y - size * 0.4, size * 0.15, 0, Math.PI * 2);\n ctx.fill();\n\n // Reflected light on opposite side\n ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';\n ctx.beginPath();\n ctx.arc(x + size * 0.4, y + size * 0.4, size * 0.2, 0, Math.PI * 2);\n ctx.fill();\n}\n\nexport function drawCross(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Draw simple 4-pointed cross/plus shape\n const halfSize = size / 2;\n const thickness = size * 0.3;\n\n // Vertical bar\n ctx.fillRect(x - thickness / 2, y - halfSize, thickness, size);\n // Horizontal bar\n ctx.fillRect(x - halfSize, y - thickness / 2, size, thickness);\n}\n\nexport function drawOval(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.scale(width / height, 1);\n ctx.beginPath();\n ctx.arc(0, 0, height, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\n}\n","import { Particle } from './particle';\nimport { createCanvas, resizeCanvas } from './utils';\nimport type { EngineOptions, Effect } from './types';\n\nexport class CursorFXEngine {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private particles: Particle[] = [];\n private animationId: number | null = null;\n private effect: Effect | null = null;\n private maxParticles: number = 500; // Cap to prevent performance issues\n private lastParticleTime: number = 0;\n private particleThrottle: number = 16; // Create particles every 16ms (~60fps)\n private lastMouseX: number = 0;\n private lastMouseY: number = 0;\n private minMoveDistance: number = 0; // Create particles on every valid move\n\n constructor(options: EngineOptions = {}) {\n if (options.canvas) {\n this.canvas = options.canvas;\n } else {\n const container = options.container || document.body;\n this.canvas = createCanvas(container);\n }\n\n const ctx = this.canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context');\n }\n this.ctx = ctx;\n\n // Bind methods once to prevent memory leaks\n this.handleResize = this.handleResize.bind(this);\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleTouchMove = this.handleTouchMove.bind(this);\n this.animate = this.animate.bind(this);\n\n window.addEventListener('resize', this.handleResize);\n }\n\n private handleResize(): void {\n resizeCanvas(this.canvas);\n }\n\n private handleMouseMove(e: MouseEvent): void {\n if (!this.effect) return;\n\n const now = Date.now();\n const dx = e.clientX - this.lastMouseX;\n const dy = e.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND mouse moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = e.clientX;\n this.lastMouseY = e.clientY;\n const particles = this.effect.onMouseMove(e.clientX, e.clientY);\n this.addParticles(particles);\n }\n }\n\n private handleTouchMove(e: TouchEvent): void {\n if (!this.effect || e.touches.length === 0) return;\n\n const now = Date.now();\n const touch = e.touches[0];\n const dx = touch.clientX - this.lastMouseX;\n const dy = touch.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND touch moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = touch.clientX;\n this.lastMouseY = touch.clientY;\n const particles = this.effect.onMouseMove(touch.clientX, touch.clientY);\n this.addParticles(particles);\n }\n }\n\n addParticle(particle: Particle): void {\n if (this.particles.length < this.maxParticles) {\n this.particles.push(particle);\n }\n }\n\n addParticles(particles: Particle[]): void {\n const availableSlots = this.maxParticles - this.particles.length;\n if (availableSlots > 0) {\n this.particles.push(...particles.slice(0, availableSlots));\n }\n }\n\n private update(): void {\n // Update all particles\n this.particles.forEach(particle => particle.update());\n // Remove dead particles\n this.particles = this.particles.filter(particle => !particle.isDead());\n }\n\n private draw(): void {\n // Clear canvas\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n // Render all particles with shadow/glow effects\n this.particles.forEach(particle => particle.draw(this.ctx));\n }\n\n private animate(): void {\n this.update();\n this.draw();\n this.animationId = requestAnimationFrame(this.animate);\n }\n\n start(effect: Effect): void {\n if (this.animationId === null) {\n this.effect = effect;\n this.animationId = requestAnimationFrame(this.animate);\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('touchmove', this.handleTouchMove, { passive: true });\n }\n }\n\n stop(): void {\n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n this.animationId = null;\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('touchmove', this.handleTouchMove);\n }\n }\n\n clear(): void {\n this.particles = [];\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n destroy(): void {\n this.stop();\n this.clear();\n window.removeEventListener('resize', this.handleResize);\n if (this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n}\n","import type { ParticleConfig } from './types';\nimport { drawStar, drawRectangle, drawSnowflake, drawBubble, drawCross, drawOval } from './utils';\n\nexport class Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size: number;\n color: string;\n life: number;\n maxLife: number;\n gravity: number;\n opacity: number;\n rotation: number;\n rotationSpeed: number;\n shape: 'star' | 'rectangle' | 'circle' | 'snowflake' | 'bubble' | 'cross' | 'oval';\n wobbleAmplitude: number;\n wobbleSpeed: number;\n wobblePhase: number;\n windDrift: number;\n image?: HTMLImageElement;\n scale: number;\n initialScale: number;\n scaleUpDuration: number;\n\n constructor(config: ParticleConfig) {\n this.x = config.x;\n this.y = config.y;\n this.vx = config.vx ?? (Math.random() - 0.5) * 4;\n this.vy = config.vy ?? (Math.random() - 0.5) * 4;\n this.size = config.size ?? 3;\n this.color = config.color ?? '#ffffff';\n this.maxLife = config.maxLife ?? 40; // Reduced for better performance\n this.life = 0;\n this.gravity = config.gravity ?? 0.1;\n this.opacity = 1;\n this.rotation = config.rotation ?? 0;\n this.rotationSpeed = config.rotationSpeed ?? 0;\n this.shape = config.shape ?? 'star';\n this.wobbleAmplitude = config.wobbleAmplitude ?? 0;\n this.wobbleSpeed = config.wobbleSpeed ?? 0;\n this.wobblePhase = Math.random() * Math.PI * 2; // Random starting phase\n this.windDrift = config.windDrift ?? 0;\n this.image = config.image;\n this.initialScale = config.initialScale ?? 1; // Default to full scale\n this.scaleUpDuration = config.scaleUpDuration ?? 0; // Default no animation\n this.scale = this.initialScale; // Start at initial scale\n }\n\n update(): void {\n this.life++;\n this.vy += this.gravity;\n\n // Animate scale from initialScale to 1.0 over scaleUpDuration frames\n if (this.scaleUpDuration > 0 && this.life < this.scaleUpDuration) {\n const progress = this.life / this.scaleUpDuration;\n // Ease-out cubic for smooth pop-up effect\n const easedProgress = 1 - Math.pow(1 - progress, 3);\n this.scale = this.initialScale + (1 - this.initialScale) * easedProgress;\n } else {\n this.scale = 1;\n }\n\n // Apply wobble (for bubbles)\n if (this.wobbleAmplitude > 0) {\n this.wobblePhase += this.wobbleSpeed;\n this.x += this.vx + Math.sin(this.wobblePhase) * this.wobbleAmplitude;\n } else {\n this.x += this.vx;\n }\n\n // Apply wind drift (for snowflakes)\n if (this.windDrift > 0) {\n // Smooth Perlin-like drift using sine waves at different frequencies\n const drift = Math.sin(this.life * 0.05) * this.windDrift * 0.3 +\n Math.sin(this.life * 0.02) * this.windDrift * 0.7;\n this.x += drift;\n }\n\n this.y += this.vy;\n this.rotation += this.rotationSpeed;\n this.opacity = 1 - this.life / this.maxLife;\n }\n\n isDead(): boolean {\n return this.life >= this.maxLife;\n }\n\n draw(ctx: CanvasRenderingContext2D): void {\n ctx.save();\n ctx.globalAlpha = this.opacity;\n\n // Apply scale transform (for pop-up animation)\n ctx.translate(this.x, this.y);\n ctx.scale(this.scale, this.scale);\n ctx.translate(-this.x, -this.y);\n\n // If image is available, render image instead of shape\n if (this.image && this.image.complete) {\n // Enable high-quality image smoothing for better rendering\n ctx.imageSmoothingEnabled = true;\n ctx.imageSmoothingQuality = 'high';\n\n const imgSize = this.size * 2.5; // Larger multiplier for bigger images\n ctx.translate(this.x, this.y);\n if (this.rotation !== 0) {\n ctx.rotate(this.rotation);\n }\n\n // Add simple glow for snowflake images (single pass)\n // if (this.shape === 'snowflake') {\n // ctx.shadowBlur = 8;\n // ctx.shadowColor = '#FFFFFF';\n // }\n\n ctx.drawImage(\n this.image,\n -imgSize / 2,\n -imgSize / 2,\n imgSize,\n imgSize\n );\n ctx.restore();\n return;\n }\n\n // Fallback to shape rendering\n ctx.fillStyle = this.color;\n\n // Draw based on shape\n switch (this.shape) {\n case 'rectangle':\n if (this.rotation !== 0) {\n ctx.translate(this.x, this.y);\n ctx.rotate(this.rotation);\n ctx.translate(-this.x, -this.y);\n }\n drawRectangle(ctx, this.x, this.y, this.size, this.size * 1.5);\n break;\n\n case 'circle':\n ctx.shadowBlur = 15; // Strong glow for circles\n ctx.shadowColor = this.color;\n ctx.beginPath();\n ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\n ctx.fill();\n break;\n\n case 'snowflake':\n ctx.strokeStyle = this.color;\n ctx.lineWidth = 1.5;\n drawSnowflake(ctx, this.x, this.y, this.size, this.rotation);\n break;\n\n case 'bubble':\n drawBubble(ctx, this.x, this.y, this.size);\n break;\n\n case 'cross':\n ctx.shadowBlur = 18; // Strong glow for fairy dust\n ctx.shadowColor = this.color;\n drawCross(ctx, this.x, this.y, this.size);\n break;\n\n case 'oval':\n ctx.shadowBlur = 12; // Moderate glow for CRT phosphor\n ctx.shadowColor = this.color;\n drawOval(ctx, this.x, this.y, this.size * 2, this.size);\n break;\n\n default: // star\n drawStar(ctx, this.x, this.y, this.size, 5);\n break;\n }\n\n ctx.restore();\n }\n}\n","// Image loader for bubble assets\nexport class ImageLoader {\n private static images: Map<string, HTMLImageElement> = new Map();\n private static loading: Map<string, Promise<HTMLImageElement>> = new Map();\n\n static async loadImage(src: string): Promise<HTMLImageElement> {\n // Return cached image if already loaded\n if (this.images.has(src)) {\n return this.images.get(src)!;\n }\n\n // Return existing promise if currently loading\n if (this.loading.has(src)) {\n return this.loading.get(src)!;\n }\n\n // Create new loading promise\n const loadPromise = new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n this.images.set(src, img);\n this.loading.delete(src);\n resolve(img);\n };\n img.onerror = () => {\n this.loading.delete(src);\n reject(new Error(`Failed to load image: ${src}`));\n };\n img.src = src;\n });\n\n this.loading.set(src, loadPromise);\n return loadPromise;\n }\n\n static async loadBubbles(basePath: string = '/bubbles'): Promise<HTMLImageElement[]> {\n const bubblePaths = [\n `${basePath}/soap_bubbles_1.png`,\n `${basePath}/soap_bubble_2.png`,\n `${basePath}/soap_bubble_3.png`,\n ];\n\n try {\n return await Promise.all(bubblePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some bubble images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static async loadSnowflakes(basePath: string = '/snowflakes'): Promise<HTMLImageElement[]> {\n const snowflakePaths = [\n // `${basePath}/snowflake.png`,\n `${basePath}/snow_flake_1.png`,\n `${basePath}/snow_flake_2.png`,\n ];\n\n try {\n return await Promise.all(snowflakePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some snowflake images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static getRandomBubble(): HTMLImageElement | null {\n const bubbleImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('bubble'))\n .map(([, img]) => img);\n if (bubbleImages.length === 0) return null;\n return bubbleImages[Math.floor(Math.random() * bubbleImages.length)];\n }\n\n static getRandomSnowflake(): HTMLImageElement | null {\n const snowflakeImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('snow'))\n .map(([, img]) => img);\n if (snowflakeImages.length === 0) return null;\n return snowflakeImages[Math.floor(Math.random() * snowflakeImages.length)];\n }\n\n static isLoaded(): boolean {\n return this.images.size > 0;\n }\n\n static clear(): void {\n this.images.clear();\n this.loading.clear();\n }\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FFC700', // Golden Yellow\n '#FFB700', // Amber\n '#FFED4E', // Light Gold\n '#F4E04D', // Pale Gold\n];\n\nexport function createFairyDustEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 2,\n particleSize = 6, // Increased from 4 for better visibility\n gravity = -0.05, // Slight upward float for magical feel\n maxLife = 40,\n velocity = 3,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 15,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity - 1, // Slight upward bias\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n shape: 'cross',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FF69B4', // Hot Pink\n '#00CED1', // Dark Turquoise\n '#9370DB', // Medium Purple\n];\n\nexport function createSparkleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Reduced for better performance\n particleSize = 6, // Increased from 3 for better visibility\n gravity = 0.1,\n maxLife = 20, // Further reduced for faster cleanup\n velocity = 4,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10,\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 10, // Reduced random variation\n gravity,\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FF6B6B', // Red\n '#4ECDC4', // Turquoise\n '#FFE66D', // Yellow\n '#95E1D3', // Mint\n '#F38181', // Pink\n '#AA96DA', // Purple\n '#FCBAD3', // Light Pink\n '#A8D8EA', // Sky Blue\n];\n\nexport function createConfettiEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4,\n gravity = 0.3, // Stronger gravity for falling effect\n maxLife = 60, // Longer lifetime for confetti\n velocity = 6,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 20,\n y: y + (Math.random() - 0.5) * 20,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 1) * velocity * 0.5, // Bias upward initially\n size: Math.random() * particleSize + 3,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.2, // Rotation speed\n shape: 'rectangle',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#00FF00', // Classic phosphor green\n '#33FF33', // Bright phosphor green\n '#00CC00', // Medium phosphor green\n '#00DD00', // Light phosphor green\n];\n\nexport function createRetroCRTEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4, // Slightly larger for better visibility\n gravity = 0, // No gravity - phosphor glows in place\n maxLife = 60, // Longer persistence like real phosphor\n velocity = 1, // Very slow movement for authentic glow\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 8,\n y: y + (Math.random() - 0.5) * 8,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 2,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 15,\n gravity,\n shape: 'circle', // Back to circles with strong glow\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFFFFF', // Pure white\n '#F0F8FF', // Alice blue\n '#E6F3FF', // Light blue white\n '#F5F5F5', // White smoke\n];\n\n// ⚙️ CONFIGURATION FLAG: Switch between image-based and canvas-drawn snowflakes\nconst USE_SNOWFLAKE_IMAGES = true; // Set to true to use PNG images, false for canvas drawing\n\nexport function createSnowEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // One snowflake at a time\n particleSize = 7, // Bigger for better visibility\n gravity = 0.12, // Faster falling\n maxLife = 150, // Shorter lifetime for faster fall\n velocity = 0.4, // Slightly more drift\n throttle = 120, // Spawn every 120ms - less frequent\n minMoveDistance = 12, // Only spawn when cursor moves 12px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n // Conditionally get snowflake image based on flag\n const snowflakeImage = USE_SNOWFLAKE_IMAGES ? ImageLoader.getRandomSnowflake() : null;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 30,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: Math.random() * 0.2 + 0.1, // Slightly faster downward initial velocity\n size: Math.random() * particleSize + 3, // Variable sizes (3-10px for canvas, base for images)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.03, // More visible rotation\n shape: 'snowflake',\n windDrift: 0.8, // Gentle wind drift/sway\n image: snowflakeImage || undefined, // Use image if flag is true and images loaded\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n 'rgba(173, 216, 230, 0.4)', // Light blue - transparent\n 'rgba(135, 206, 235, 0.4)', // Sky blue - transparent\n 'rgba(176, 224, 230, 0.4)', // Powder blue - transparent\n 'rgba(175, 238, 238, 0.4)', // Pale turquoise - transparent\n 'rgba(224, 255, 255, 0.4)', // Light cyan - transparent\n];\n\nexport function createBubbleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Spawn one bubble at a time\n gravity = -0.02, // Gentle upward buoyancy\n maxLife = 180, // Longer lifetime for slow rise\n velocity = 0.2, // Minimal base horizontal drift\n throttle = 150, // Spawn every 150ms - much less frequent\n minMoveDistance = 15, // Only spawn when cursor moves 15px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n const bubbleImage = ImageLoader.getRandomBubble();\n\n // Create more dramatic size variation (15-45 range for 2.5x multiplier = 37-112px actual)\n const baseSize = 15 + Math.random() * 30;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10, // Spawn closer to pointer\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: -Math.random() * 0.15 - 0.1, // Very slow, consistent upward\n size: baseSize, // Wide size variation (15-45)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n shape: 'bubble',\n wobbleAmplitude: 0.3, // Gentle horizontal wobble\n wobbleSpeed: 0.05, // Slow wobble oscillation\n image: bubbleImage || undefined, // Use image if loaded, fallback to canvas\n initialScale: 0.3, // Start at 30% size for pop-up effect\n scaleUpDuration: 15, // Grow to full size over 15 frames (~250ms)\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { CursorFXEngine, createFairyDustEffect, createSparkleEffect, createConfettiEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect, ImageLoader } from '../core';\n\n// Re-export ImageLoader for CDN and vanilla users\nexport { ImageLoader };\n\nexport type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';\n\nexport interface InitCursorFXOptions {\n effect?: CursorEffectType;\n colors?: string[];\n particleCount?: number;\n particleSize?: number;\n gravity?: number;\n maxLife?: number;\n velocity?: number;\n}\n\nexport interface CursorFXInstance {\n destroy: () => void;\n}\n\n/**\n * Initialize cursor effects with a single function call.\n * Creates canvas, appends to body, and starts the fairy dust effect.\n *\n * @param options - Configuration options for the effect\n * @returns Instance with destroy() method for cleanup\n *\n * @example\n * ```ts\n * const fx = initCursorFX({\n * colors: ['#FFD700', '#FF69B4'],\n * particleCount: 5\n * });\n *\n * // Later, to cleanup:\n * fx.destroy();\n * ```\n */\nexport function initCursorFX(options: InitCursorFXOptions = {}): CursorFXInstance {\n // Check for prefers-reduced-motion\n if (typeof window !== 'undefined') {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n // Return no-op instance if user prefers reduced motion\n return { destroy: () => {} };\n }\n }\n\n // Create engine (automatically creates and appends canvas with fixed positioning)\n const engine = new CursorFXEngine();\n\n // Extract effect type from options\n const { effect = 'fairyDust', ...effectOptions } = options;\n\n // Select effect based on type\n // Each effect will use its own defaults unless overridden in effectOptions\n const selectedEffect =\n effect === 'confetti'\n ? createConfettiEffect(effectOptions)\n : effect === 'sparkle'\n ? createSparkleEffect(effectOptions)\n : effect === 'retroCRT'\n ? createRetroCRTEffect(effectOptions)\n : effect === 'snow'\n ? createSnowEffect(effectOptions)\n : effect === 'bubble'\n ? createBubbleEffect(effectOptions)\n : createFairyDustEffect(effectOptions);\n\n // Start the engine with the effect\n engine.start(selectedEffect);\n\n return {\n destroy: () => engine.destroy(),\n };\n}\n\n// Export types for TypeScript users\nexport type { EffectOptions } from '../core/types';\n"]}
@@ -1,18 +1,7 @@
1
1
  export { C as CursorFXEngine } from '../engine-DtYS3_cn.mjs';
2
2
  import { E as EffectOptions, a as Effect } from '../particle-CimoPApW.mjs';
3
3
  export { d as EffectFunction, c as EngineOptions, P as Particle, b as ParticleConfig } from '../particle-CimoPApW.mjs';
4
-
5
- declare class ImageLoader {
6
- private static images;
7
- private static loading;
8
- static loadImage(src: string): Promise<HTMLImageElement>;
9
- static loadBubbles(basePath?: string): Promise<HTMLImageElement[]>;
10
- static loadSnowflakes(basePath?: string): Promise<HTMLImageElement[]>;
11
- static getRandomBubble(): HTMLImageElement | null;
12
- static getRandomSnowflake(): HTMLImageElement | null;
13
- static isLoaded(): boolean;
14
- static clear(): void;
15
- }
4
+ export { I as ImageLoader } from '../imageLoader-Bgr5GJIX.mjs';
16
5
 
17
6
  declare function randomColor(colors: string[]): string;
18
7
  declare function randomRange(min: number, max: number): number;
@@ -37,4 +26,4 @@ declare function createSnowEffect(options?: EffectOptions): Effect;
37
26
 
38
27
  declare function createBubbleEffect(options?: EffectOptions): Effect;
39
28
 
40
- export { Effect, EffectOptions, ImageLoader, createBubbleEffect, createCanvas, createConfettiEffect, createFairyDustEffect, createRetroCRTEffect, createSnowEffect, createSparkleEffect, drawBubble, drawCross, drawOval, drawRectangle, drawSnowflake, drawStar, randomColor, randomRange, resizeCanvas };
29
+ export { Effect, EffectOptions, createBubbleEffect, createCanvas, createConfettiEffect, createFairyDustEffect, createRetroCRTEffect, createSnowEffect, createSparkleEffect, drawBubble, drawCross, drawOval, drawRectangle, drawSnowflake, drawStar, randomColor, randomRange, resizeCanvas };
@@ -1,18 +1,7 @@
1
1
  export { C as CursorFXEngine } from '../engine-BiVjsHvN.js';
2
2
  import { E as EffectOptions, a as Effect } from '../particle-CimoPApW.js';
3
3
  export { d as EffectFunction, c as EngineOptions, P as Particle, b as ParticleConfig } from '../particle-CimoPApW.js';
4
-
5
- declare class ImageLoader {
6
- private static images;
7
- private static loading;
8
- static loadImage(src: string): Promise<HTMLImageElement>;
9
- static loadBubbles(basePath?: string): Promise<HTMLImageElement[]>;
10
- static loadSnowflakes(basePath?: string): Promise<HTMLImageElement[]>;
11
- static getRandomBubble(): HTMLImageElement | null;
12
- static getRandomSnowflake(): HTMLImageElement | null;
13
- static isLoaded(): boolean;
14
- static clear(): void;
15
- }
4
+ export { I as ImageLoader } from '../imageLoader-Bgr5GJIX.js';
16
5
 
17
6
  declare function randomColor(colors: string[]): string;
18
7
  declare function randomRange(min: number, max: number): number;
@@ -37,4 +26,4 @@ declare function createSnowEffect(options?: EffectOptions): Effect;
37
26
 
38
27
  declare function createBubbleEffect(options?: EffectOptions): Effect;
39
28
 
40
- export { Effect, EffectOptions, ImageLoader, createBubbleEffect, createCanvas, createConfettiEffect, createFairyDustEffect, createRetroCRTEffect, createSnowEffect, createSparkleEffect, drawBubble, drawCross, drawOval, drawRectangle, drawSnowflake, drawStar, randomColor, randomRange, resizeCanvas };
29
+ export { Effect, EffectOptions, createBubbleEffect, createCanvas, createConfettiEffect, createFairyDustEffect, createRetroCRTEffect, createSnowEffect, createSparkleEffect, drawBubble, drawCross, drawOval, drawRectangle, drawSnowflake, drawStar, randomColor, randomRange, resizeCanvas };
@@ -0,0 +1,13 @@
1
+ declare class ImageLoader {
2
+ private static images;
3
+ private static loading;
4
+ static loadImage(src: string): Promise<HTMLImageElement>;
5
+ static loadBubbles(basePath?: string): Promise<HTMLImageElement[]>;
6
+ static loadSnowflakes(basePath?: string): Promise<HTMLImageElement[]>;
7
+ static getRandomBubble(): HTMLImageElement | null;
8
+ static getRandomSnowflake(): HTMLImageElement | null;
9
+ static isLoaded(): boolean;
10
+ static clear(): void;
11
+ }
12
+
13
+ export { ImageLoader as I };
@@ -0,0 +1,13 @@
1
+ declare class ImageLoader {
2
+ private static images;
3
+ private static loading;
4
+ static loadImage(src: string): Promise<HTMLImageElement>;
5
+ static loadBubbles(basePath?: string): Promise<HTMLImageElement[]>;
6
+ static loadSnowflakes(basePath?: string): Promise<HTMLImageElement[]>;
7
+ static getRandomBubble(): HTMLImageElement | null;
8
+ static getRandomSnowflake(): HTMLImageElement | null;
9
+ static isLoaded(): boolean;
10
+ static clear(): void;
11
+ }
12
+
13
+ export { ImageLoader as I };
@@ -1,4 +1,5 @@
1
1
  export { E as EffectOptions } from '../particle-CimoPApW.mjs';
2
+ export { I as ImageLoader } from '../imageLoader-Bgr5GJIX.mjs';
2
3
 
3
4
  type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';
4
5
  interface InitCursorFXOptions {
@@ -1,4 +1,5 @@
1
1
  export { E as EffectOptions } from '../particle-CimoPApW.js';
2
+ export { I as ImageLoader } from '../imageLoader-Bgr5GJIX.js';
2
3
 
3
4
  type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';
4
5
  interface InitCursorFXOptions {
@@ -760,18 +760,14 @@ function initCursorFX(options = {}) {
760
760
  }
761
761
  const engine = new CursorFXEngine();
762
762
  const { effect = "fairyDust", ...effectOptions } = options;
763
- const optimizedOptions = {
764
- particleCount: 2,
765
- // Reduced from default 3
766
- ...effectOptions
767
- };
768
- const selectedEffect = effect === "confetti" ? createConfettiEffect(optimizedOptions) : effect === "sparkle" ? createSparkleEffect(optimizedOptions) : effect === "retroCRT" ? createRetroCRTEffect(optimizedOptions) : effect === "snow" ? createSnowEffect(optimizedOptions) : effect === "bubble" ? createBubbleEffect(optimizedOptions) : createFairyDustEffect(optimizedOptions);
763
+ const selectedEffect = effect === "confetti" ? createConfettiEffect(effectOptions) : effect === "sparkle" ? createSparkleEffect(effectOptions) : effect === "retroCRT" ? createRetroCRTEffect(effectOptions) : effect === "snow" ? createSnowEffect(effectOptions) : effect === "bubble" ? createBubbleEffect(effectOptions) : createFairyDustEffect(effectOptions);
769
764
  engine.start(selectedEffect);
770
765
  return {
771
766
  destroy: () => engine.destroy()
772
767
  };
773
768
  }
774
769
 
770
+ exports.ImageLoader = ImageLoader;
775
771
  exports.initCursorFX = initCursorFX;
776
772
  //# sourceMappingURL=index.js.map
777
773
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/utils.ts","../../src/core/engine.ts","../../src/core/particle.ts","../../src/core/imageLoader.ts","../../src/core/effects/fairyDust.ts","../../src/core/effects/sparkle.ts","../../src/core/effects/confetti.ts","../../src/core/effects/retroCRT.ts","../../src/core/effects/snow.ts","../../src/core/effects/bubble.ts","../../src/vanilla/index.ts"],"names":["DEFAULT_COLORS"],"mappings":"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","file":"index.js","sourcesContent":["export function randomColor(colors: string[]): string {\n return colors[Math.floor(Math.random() * colors.length)];\n}\n\nexport function randomRange(min: number, max: number): number {\n return Math.random() * (max - min) + min;\n}\n\nexport function createCanvas(container: HTMLElement): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n canvas.style.position = 'fixed';\n canvas.style.top = '0';\n canvas.style.left = '0';\n canvas.style.pointerEvents = 'none';\n canvas.style.zIndex = '9999';\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n container.appendChild(canvas);\n return canvas;\n}\n\nexport function resizeCanvas(canvas: HTMLCanvasElement): void {\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n}\n\nexport function drawStar(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n spikes: number = 5\n): void {\n const outerRadius = size;\n const innerRadius = size * 0.4;\n\n ctx.beginPath();\n for (let i = 0; i < spikes * 2; i++) {\n const angle = (i * Math.PI) / spikes;\n const radius = i % 2 === 0 ? outerRadius : innerRadius;\n const dx = Math.cos(angle) * radius;\n const dy = Math.sin(angle) * radius;\n\n if (i === 0) {\n ctx.moveTo(x + dx, y + dy);\n } else {\n ctx.lineTo(x + dx, y + dy);\n }\n }\n ctx.closePath();\n ctx.fill();\n}\n\nexport function drawRectangle(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.fillRect(x - width / 2, y - height / 2, width, height);\n}\n\nexport function drawSnowflake(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n rotation: number = 0\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Optimized glow - reduced blur for better performance\n ctx.shadowBlur = 4;\n ctx.shadowColor = '#FFFFFF';\n ctx.lineWidth = 1.8; // Slightly thicker for better visibility\n\n // Draw all 6 arms in a single path for better performance\n ctx.beginPath();\n for (let i = 0; i < 6; i++) {\n const angle = (i * Math.PI) / 3;\n ctx.moveTo(0, 0);\n ctx.lineTo(Math.cos(angle) * size, Math.sin(angle) * size);\n }\n ctx.stroke();\n\n ctx.restore();\n}\n\nexport function drawBubble(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Save the original fill color\n const baseColor = ctx.fillStyle as string;\n\n // Main bubble with multi-layer gradient for depth\n const mainGradient = ctx.createRadialGradient(x - size * 0.25, y - size * 0.25, 0, x, y, size);\n mainGradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');\n mainGradient.addColorStop(0.3, baseColor);\n mainGradient.addColorStop(0.7, baseColor);\n mainGradient.addColorStop(1, 'rgba(255, 255, 255, 0.1)');\n\n ctx.beginPath();\n ctx.arc(x, y, size, 0, Math.PI * 2);\n ctx.fillStyle = mainGradient;\n ctx.fill();\n\n // Subtle border/rim for definition\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';\n ctx.lineWidth = 1;\n ctx.stroke();\n\n // Primary highlight (large, soft)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';\n ctx.beginPath();\n ctx.arc(x - size * 0.3, y - size * 0.3, size * 0.35, 0, Math.PI * 2);\n ctx.fill();\n\n // Secondary highlight (small, bright)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';\n ctx.beginPath();\n ctx.arc(x - size * 0.4, y - size * 0.4, size * 0.15, 0, Math.PI * 2);\n ctx.fill();\n\n // Reflected light on opposite side\n ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';\n ctx.beginPath();\n ctx.arc(x + size * 0.4, y + size * 0.4, size * 0.2, 0, Math.PI * 2);\n ctx.fill();\n}\n\nexport function drawCross(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Draw simple 4-pointed cross/plus shape\n const halfSize = size / 2;\n const thickness = size * 0.3;\n\n // Vertical bar\n ctx.fillRect(x - thickness / 2, y - halfSize, thickness, size);\n // Horizontal bar\n ctx.fillRect(x - halfSize, y - thickness / 2, size, thickness);\n}\n\nexport function drawOval(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.scale(width / height, 1);\n ctx.beginPath();\n ctx.arc(0, 0, height, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\n}\n","import { Particle } from './particle';\nimport { createCanvas, resizeCanvas } from './utils';\nimport type { EngineOptions, Effect } from './types';\n\nexport class CursorFXEngine {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private particles: Particle[] = [];\n private animationId: number | null = null;\n private effect: Effect | null = null;\n private maxParticles: number = 500; // Cap to prevent performance issues\n private lastParticleTime: number = 0;\n private particleThrottle: number = 16; // Create particles every 16ms (~60fps)\n private lastMouseX: number = 0;\n private lastMouseY: number = 0;\n private minMoveDistance: number = 0; // Create particles on every valid move\n\n constructor(options: EngineOptions = {}) {\n if (options.canvas) {\n this.canvas = options.canvas;\n } else {\n const container = options.container || document.body;\n this.canvas = createCanvas(container);\n }\n\n const ctx = this.canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context');\n }\n this.ctx = ctx;\n\n // Bind methods once to prevent memory leaks\n this.handleResize = this.handleResize.bind(this);\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleTouchMove = this.handleTouchMove.bind(this);\n this.animate = this.animate.bind(this);\n\n window.addEventListener('resize', this.handleResize);\n }\n\n private handleResize(): void {\n resizeCanvas(this.canvas);\n }\n\n private handleMouseMove(e: MouseEvent): void {\n if (!this.effect) return;\n\n const now = Date.now();\n const dx = e.clientX - this.lastMouseX;\n const dy = e.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND mouse moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = e.clientX;\n this.lastMouseY = e.clientY;\n const particles = this.effect.onMouseMove(e.clientX, e.clientY);\n this.addParticles(particles);\n }\n }\n\n private handleTouchMove(e: TouchEvent): void {\n if (!this.effect || e.touches.length === 0) return;\n\n const now = Date.now();\n const touch = e.touches[0];\n const dx = touch.clientX - this.lastMouseX;\n const dy = touch.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND touch moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = touch.clientX;\n this.lastMouseY = touch.clientY;\n const particles = this.effect.onMouseMove(touch.clientX, touch.clientY);\n this.addParticles(particles);\n }\n }\n\n addParticle(particle: Particle): void {\n if (this.particles.length < this.maxParticles) {\n this.particles.push(particle);\n }\n }\n\n addParticles(particles: Particle[]): void {\n const availableSlots = this.maxParticles - this.particles.length;\n if (availableSlots > 0) {\n this.particles.push(...particles.slice(0, availableSlots));\n }\n }\n\n private update(): void {\n // Update all particles\n this.particles.forEach(particle => particle.update());\n // Remove dead particles\n this.particles = this.particles.filter(particle => !particle.isDead());\n }\n\n private draw(): void {\n // Clear canvas\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n // Render all particles with shadow/glow effects\n this.particles.forEach(particle => particle.draw(this.ctx));\n }\n\n private animate(): void {\n this.update();\n this.draw();\n this.animationId = requestAnimationFrame(this.animate);\n }\n\n start(effect: Effect): void {\n if (this.animationId === null) {\n this.effect = effect;\n this.animationId = requestAnimationFrame(this.animate);\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('touchmove', this.handleTouchMove, { passive: true });\n }\n }\n\n stop(): void {\n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n this.animationId = null;\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('touchmove', this.handleTouchMove);\n }\n }\n\n clear(): void {\n this.particles = [];\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n destroy(): void {\n this.stop();\n this.clear();\n window.removeEventListener('resize', this.handleResize);\n if (this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n}\n","import type { ParticleConfig } from './types';\nimport { drawStar, drawRectangle, drawSnowflake, drawBubble, drawCross, drawOval } from './utils';\n\nexport class Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size: number;\n color: string;\n life: number;\n maxLife: number;\n gravity: number;\n opacity: number;\n rotation: number;\n rotationSpeed: number;\n shape: 'star' | 'rectangle' | 'circle' | 'snowflake' | 'bubble' | 'cross' | 'oval';\n wobbleAmplitude: number;\n wobbleSpeed: number;\n wobblePhase: number;\n windDrift: number;\n image?: HTMLImageElement;\n scale: number;\n initialScale: number;\n scaleUpDuration: number;\n\n constructor(config: ParticleConfig) {\n this.x = config.x;\n this.y = config.y;\n this.vx = config.vx ?? (Math.random() - 0.5) * 4;\n this.vy = config.vy ?? (Math.random() - 0.5) * 4;\n this.size = config.size ?? 3;\n this.color = config.color ?? '#ffffff';\n this.maxLife = config.maxLife ?? 40; // Reduced for better performance\n this.life = 0;\n this.gravity = config.gravity ?? 0.1;\n this.opacity = 1;\n this.rotation = config.rotation ?? 0;\n this.rotationSpeed = config.rotationSpeed ?? 0;\n this.shape = config.shape ?? 'star';\n this.wobbleAmplitude = config.wobbleAmplitude ?? 0;\n this.wobbleSpeed = config.wobbleSpeed ?? 0;\n this.wobblePhase = Math.random() * Math.PI * 2; // Random starting phase\n this.windDrift = config.windDrift ?? 0;\n this.image = config.image;\n this.initialScale = config.initialScale ?? 1; // Default to full scale\n this.scaleUpDuration = config.scaleUpDuration ?? 0; // Default no animation\n this.scale = this.initialScale; // Start at initial scale\n }\n\n update(): void {\n this.life++;\n this.vy += this.gravity;\n\n // Animate scale from initialScale to 1.0 over scaleUpDuration frames\n if (this.scaleUpDuration > 0 && this.life < this.scaleUpDuration) {\n const progress = this.life / this.scaleUpDuration;\n // Ease-out cubic for smooth pop-up effect\n const easedProgress = 1 - Math.pow(1 - progress, 3);\n this.scale = this.initialScale + (1 - this.initialScale) * easedProgress;\n } else {\n this.scale = 1;\n }\n\n // Apply wobble (for bubbles)\n if (this.wobbleAmplitude > 0) {\n this.wobblePhase += this.wobbleSpeed;\n this.x += this.vx + Math.sin(this.wobblePhase) * this.wobbleAmplitude;\n } else {\n this.x += this.vx;\n }\n\n // Apply wind drift (for snowflakes)\n if (this.windDrift > 0) {\n // Smooth Perlin-like drift using sine waves at different frequencies\n const drift = Math.sin(this.life * 0.05) * this.windDrift * 0.3 +\n Math.sin(this.life * 0.02) * this.windDrift * 0.7;\n this.x += drift;\n }\n\n this.y += this.vy;\n this.rotation += this.rotationSpeed;\n this.opacity = 1 - this.life / this.maxLife;\n }\n\n isDead(): boolean {\n return this.life >= this.maxLife;\n }\n\n draw(ctx: CanvasRenderingContext2D): void {\n ctx.save();\n ctx.globalAlpha = this.opacity;\n\n // Apply scale transform (for pop-up animation)\n ctx.translate(this.x, this.y);\n ctx.scale(this.scale, this.scale);\n ctx.translate(-this.x, -this.y);\n\n // If image is available, render image instead of shape\n if (this.image && this.image.complete) {\n // Enable high-quality image smoothing for better rendering\n ctx.imageSmoothingEnabled = true;\n ctx.imageSmoothingQuality = 'high';\n\n const imgSize = this.size * 2.5; // Larger multiplier for bigger images\n ctx.translate(this.x, this.y);\n if (this.rotation !== 0) {\n ctx.rotate(this.rotation);\n }\n\n // Add simple glow for snowflake images (single pass)\n // if (this.shape === 'snowflake') {\n // ctx.shadowBlur = 8;\n // ctx.shadowColor = '#FFFFFF';\n // }\n\n ctx.drawImage(\n this.image,\n -imgSize / 2,\n -imgSize / 2,\n imgSize,\n imgSize\n );\n ctx.restore();\n return;\n }\n\n // Fallback to shape rendering\n ctx.fillStyle = this.color;\n\n // Draw based on shape\n switch (this.shape) {\n case 'rectangle':\n if (this.rotation !== 0) {\n ctx.translate(this.x, this.y);\n ctx.rotate(this.rotation);\n ctx.translate(-this.x, -this.y);\n }\n drawRectangle(ctx, this.x, this.y, this.size, this.size * 1.5);\n break;\n\n case 'circle':\n ctx.shadowBlur = 15; // Strong glow for circles\n ctx.shadowColor = this.color;\n ctx.beginPath();\n ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\n ctx.fill();\n break;\n\n case 'snowflake':\n ctx.strokeStyle = this.color;\n ctx.lineWidth = 1.5;\n drawSnowflake(ctx, this.x, this.y, this.size, this.rotation);\n break;\n\n case 'bubble':\n drawBubble(ctx, this.x, this.y, this.size);\n break;\n\n case 'cross':\n ctx.shadowBlur = 18; // Strong glow for fairy dust\n ctx.shadowColor = this.color;\n drawCross(ctx, this.x, this.y, this.size);\n break;\n\n case 'oval':\n ctx.shadowBlur = 12; // Moderate glow for CRT phosphor\n ctx.shadowColor = this.color;\n drawOval(ctx, this.x, this.y, this.size * 2, this.size);\n break;\n\n default: // star\n drawStar(ctx, this.x, this.y, this.size, 5);\n break;\n }\n\n ctx.restore();\n }\n}\n","// Image loader for bubble assets\nexport class ImageLoader {\n private static images: Map<string, HTMLImageElement> = new Map();\n private static loading: Map<string, Promise<HTMLImageElement>> = new Map();\n\n static async loadImage(src: string): Promise<HTMLImageElement> {\n // Return cached image if already loaded\n if (this.images.has(src)) {\n return this.images.get(src)!;\n }\n\n // Return existing promise if currently loading\n if (this.loading.has(src)) {\n return this.loading.get(src)!;\n }\n\n // Create new loading promise\n const loadPromise = new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n this.images.set(src, img);\n this.loading.delete(src);\n resolve(img);\n };\n img.onerror = () => {\n this.loading.delete(src);\n reject(new Error(`Failed to load image: ${src}`));\n };\n img.src = src;\n });\n\n this.loading.set(src, loadPromise);\n return loadPromise;\n }\n\n static async loadBubbles(basePath: string = '/bubbles'): Promise<HTMLImageElement[]> {\n const bubblePaths = [\n `${basePath}/soap_bubbles_1.png`,\n `${basePath}/soap_bubble_2.png`,\n `${basePath}/soap_bubble_3.png`,\n ];\n\n try {\n return await Promise.all(bubblePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some bubble images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static async loadSnowflakes(basePath: string = '/snowflakes'): Promise<HTMLImageElement[]> {\n const snowflakePaths = [\n // `${basePath}/snowflake.png`,\n `${basePath}/snow_flake_1.png`,\n `${basePath}/snow_flake_2.png`,\n ];\n\n try {\n return await Promise.all(snowflakePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some snowflake images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static getRandomBubble(): HTMLImageElement | null {\n const bubbleImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('bubble'))\n .map(([, img]) => img);\n if (bubbleImages.length === 0) return null;\n return bubbleImages[Math.floor(Math.random() * bubbleImages.length)];\n }\n\n static getRandomSnowflake(): HTMLImageElement | null {\n const snowflakeImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('snow'))\n .map(([, img]) => img);\n if (snowflakeImages.length === 0) return null;\n return snowflakeImages[Math.floor(Math.random() * snowflakeImages.length)];\n }\n\n static isLoaded(): boolean {\n return this.images.size > 0;\n }\n\n static clear(): void {\n this.images.clear();\n this.loading.clear();\n }\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FFC700', // Golden Yellow\n '#FFB700', // Amber\n '#FFED4E', // Light Gold\n '#F4E04D', // Pale Gold\n];\n\nexport function createFairyDustEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 2,\n particleSize = 6, // Increased from 4 for better visibility\n gravity = -0.05, // Slight upward float for magical feel\n maxLife = 40,\n velocity = 3,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 15,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity - 1, // Slight upward bias\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n shape: 'cross',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FF69B4', // Hot Pink\n '#00CED1', // Dark Turquoise\n '#9370DB', // Medium Purple\n];\n\nexport function createSparkleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Reduced for better performance\n particleSize = 6, // Increased from 3 for better visibility\n gravity = 0.1,\n maxLife = 20, // Further reduced for faster cleanup\n velocity = 4,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10,\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 10, // Reduced random variation\n gravity,\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FF6B6B', // Red\n '#4ECDC4', // Turquoise\n '#FFE66D', // Yellow\n '#95E1D3', // Mint\n '#F38181', // Pink\n '#AA96DA', // Purple\n '#FCBAD3', // Light Pink\n '#A8D8EA', // Sky Blue\n];\n\nexport function createConfettiEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4,\n gravity = 0.3, // Stronger gravity for falling effect\n maxLife = 60, // Longer lifetime for confetti\n velocity = 6,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 20,\n y: y + (Math.random() - 0.5) * 20,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 1) * velocity * 0.5, // Bias upward initially\n size: Math.random() * particleSize + 3,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.2, // Rotation speed\n shape: 'rectangle',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#00FF00', // Classic phosphor green\n '#33FF33', // Bright phosphor green\n '#00CC00', // Medium phosphor green\n '#00DD00', // Light phosphor green\n];\n\nexport function createRetroCRTEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4, // Slightly larger for better visibility\n gravity = 0, // No gravity - phosphor glows in place\n maxLife = 60, // Longer persistence like real phosphor\n velocity = 1, // Very slow movement for authentic glow\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 8,\n y: y + (Math.random() - 0.5) * 8,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 2,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 15,\n gravity,\n shape: 'circle', // Back to circles with strong glow\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFFFFF', // Pure white\n '#F0F8FF', // Alice blue\n '#E6F3FF', // Light blue white\n '#F5F5F5', // White smoke\n];\n\n// ⚙️ CONFIGURATION FLAG: Switch between image-based and canvas-drawn snowflakes\nconst USE_SNOWFLAKE_IMAGES = true; // Set to true to use PNG images, false for canvas drawing\n\nexport function createSnowEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // One snowflake at a time\n particleSize = 7, // Bigger for better visibility\n gravity = 0.12, // Faster falling\n maxLife = 150, // Shorter lifetime for faster fall\n velocity = 0.4, // Slightly more drift\n throttle = 120, // Spawn every 120ms - less frequent\n minMoveDistance = 12, // Only spawn when cursor moves 12px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n // Conditionally get snowflake image based on flag\n const snowflakeImage = USE_SNOWFLAKE_IMAGES ? ImageLoader.getRandomSnowflake() : null;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 30,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: Math.random() * 0.2 + 0.1, // Slightly faster downward initial velocity\n size: Math.random() * particleSize + 3, // Variable sizes (3-10px for canvas, base for images)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.03, // More visible rotation\n shape: 'snowflake',\n windDrift: 0.8, // Gentle wind drift/sway\n image: snowflakeImage || undefined, // Use image if flag is true and images loaded\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n 'rgba(173, 216, 230, 0.4)', // Light blue - transparent\n 'rgba(135, 206, 235, 0.4)', // Sky blue - transparent\n 'rgba(176, 224, 230, 0.4)', // Powder blue - transparent\n 'rgba(175, 238, 238, 0.4)', // Pale turquoise - transparent\n 'rgba(224, 255, 255, 0.4)', // Light cyan - transparent\n];\n\nexport function createBubbleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Spawn one bubble at a time\n gravity = -0.02, // Gentle upward buoyancy\n maxLife = 180, // Longer lifetime for slow rise\n velocity = 0.2, // Minimal base horizontal drift\n throttle = 150, // Spawn every 150ms - much less frequent\n minMoveDistance = 15, // Only spawn when cursor moves 15px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n const bubbleImage = ImageLoader.getRandomBubble();\n\n // Create more dramatic size variation (15-45 range for 2.5x multiplier = 37-112px actual)\n const baseSize = 15 + Math.random() * 30;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10, // Spawn closer to pointer\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: -Math.random() * 0.15 - 0.1, // Very slow, consistent upward\n size: baseSize, // Wide size variation (15-45)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n shape: 'bubble',\n wobbleAmplitude: 0.3, // Gentle horizontal wobble\n wobbleSpeed: 0.05, // Slow wobble oscillation\n image: bubbleImage || undefined, // Use image if loaded, fallback to canvas\n initialScale: 0.3, // Start at 30% size for pop-up effect\n scaleUpDuration: 15, // Grow to full size over 15 frames (~250ms)\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { CursorFXEngine, createFairyDustEffect, createSparkleEffect, createConfettiEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect } from '../core';\n\nexport type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';\n\nexport interface InitCursorFXOptions {\n effect?: CursorEffectType;\n colors?: string[];\n particleCount?: number;\n particleSize?: number;\n gravity?: number;\n maxLife?: number;\n velocity?: number;\n}\n\nexport interface CursorFXInstance {\n destroy: () => void;\n}\n\n/**\n * Initialize cursor effects with a single function call.\n * Creates canvas, appends to body, and starts the fairy dust effect.\n *\n * @param options - Configuration options for the effect\n * @returns Instance with destroy() method for cleanup\n *\n * @example\n * ```ts\n * const fx = initCursorFX({\n * colors: ['#FFD700', '#FF69B4'],\n * particleCount: 5\n * });\n *\n * // Later, to cleanup:\n * fx.destroy();\n * ```\n */\nexport function initCursorFX(options: InitCursorFXOptions = {}): CursorFXInstance {\n // Check for prefers-reduced-motion\n if (typeof window !== 'undefined') {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n // Return no-op instance if user prefers reduced motion\n return { destroy: () => {} };\n }\n }\n\n // Create engine (automatically creates and appends canvas with fixed positioning)\n const engine = new CursorFXEngine();\n\n // Extract effect type from options\n const { effect = 'fairyDust', ...effectOptions } = options;\n\n // Reduce particle count for better performance\n const optimizedOptions = {\n particleCount: 2, // Reduced from default 3\n ...effectOptions,\n };\n\n // Select effect based on type\n const selectedEffect =\n effect === 'confetti'\n ? createConfettiEffect(optimizedOptions)\n : effect === 'sparkle'\n ? createSparkleEffect(optimizedOptions)\n : effect === 'retroCRT'\n ? createRetroCRTEffect(optimizedOptions)\n : effect === 'snow'\n ? createSnowEffect(optimizedOptions)\n : effect === 'bubble'\n ? createBubbleEffect(optimizedOptions)\n : createFairyDustEffect(optimizedOptions);\n\n // Start the engine with the effect\n engine.start(selectedEffect);\n\n return {\n destroy: () => engine.destroy(),\n };\n}\n\n// Export types for TypeScript users\nexport type { EffectOptions } from '../core/types';\n"]}
1
+ {"version":3,"sources":["../../src/core/utils.ts","../../src/core/engine.ts","../../src/core/particle.ts","../../src/core/imageLoader.ts","../../src/core/effects/fairyDust.ts","../../src/core/effects/sparkle.ts","../../src/core/effects/confetti.ts","../../src/core/effects/retroCRT.ts","../../src/core/effects/snow.ts","../../src/core/effects/bubble.ts","../../src/vanilla/index.ts"],"names":["DEFAULT_COLORS"],"mappings":";;;AAAO,SAAS,YAAY,MAAA,EAA0B;AACpD,EAAA,OAAO,MAAA,CAAO,KAAK,KAAA,CAAM,IAAA,CAAK,QAAO,GAAI,MAAA,CAAO,MAAM,CAAC,CAAA;AACzD;AAMO,SAAS,aAAa,SAAA,EAA2C;AACtE,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,EAAA,MAAA,CAAO,MAAM,QAAA,GAAW,OAAA;AACxB,EAAA,MAAA,CAAO,MAAM,GAAA,GAAM,GAAA;AACnB,EAAA,MAAA,CAAO,MAAM,IAAA,GAAO,GAAA;AACpB,EAAA,MAAA,CAAO,MAAM,aAAA,GAAgB,MAAA;AAC7B,EAAA,MAAA,CAAO,MAAM,MAAA,GAAS,MAAA;AACtB,EAAA,MAAA,CAAO,QAAQ,MAAA,CAAO,UAAA;AACtB,EAAA,MAAA,CAAO,SAAS,MAAA,CAAO,WAAA;AACvB,EAAA,SAAA,CAAU,YAAY,MAAM,CAAA;AAC5B,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,aAAa,MAAA,EAAiC;AAC5D,EAAA,MAAA,CAAO,QAAQ,MAAA,CAAO,UAAA;AACtB,EAAA,MAAA,CAAO,SAAS,MAAA,CAAO,WAAA;AACzB;AAEO,SAAS,SACd,GAAA,EACA,CAAA,EACA,CAAA,EACA,IAAA,EACA,SAAiB,CAAA,EACX;AACN,EAAA,MAAM,WAAA,GAAc,IAAA;AACpB,EAAA,MAAM,cAAc,IAAA,GAAO,GAAA;AAE3B,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,GAAS,GAAG,CAAA,EAAA,EAAK;AACnC,IAAA,MAAM,KAAA,GAAS,CAAA,GAAI,IAAA,CAAK,EAAA,GAAM,MAAA;AAC9B,IAAA,MAAM,MAAA,GAAS,CAAA,GAAI,CAAA,KAAM,CAAA,GAAI,WAAA,GAAc,WAAA;AAC3C,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,MAAA;AAC7B,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,MAAA;AAE7B,IAAA,IAAI,MAAM,CAAA,EAAG;AACX,MAAA,GAAA,CAAI,MAAA,CAAO,CAAA,GAAI,EAAA,EAAI,CAAA,GAAI,EAAE,CAAA;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,MAAA,CAAO,CAAA,GAAI,EAAA,EAAI,CAAA,GAAI,EAAE,CAAA;AAAA,IAC3B;AAAA,EACF;AACA,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,GAAA,CAAI,IAAA,EAAK;AACX;AAEO,SAAS,aAAA,CACd,GAAA,EACA,CAAA,EACA,CAAA,EACA,OACA,MAAA,EACM;AACN,EAAA,GAAA,CAAI,QAAA,CAAS,IAAI,KAAA,GAAQ,CAAA,EAAG,IAAI,MAAA,GAAS,CAAA,EAAG,OAAO,MAAM,CAAA;AAC3D;AAEO,SAAS,cACd,GAAA,EACA,CAAA,EACA,CAAA,EACA,IAAA,EACA,WAAmB,CAAA,EACb;AACN,EAAA,GAAA,CAAI,IAAA,EAAK;AACT,EAAA,GAAA,CAAI,SAAA,CAAU,GAAG,CAAC,CAAA;AAClB,EAAA,GAAA,CAAI,OAAO,QAAQ,CAAA;AAGnB,EAAA,GAAA,CAAI,UAAA,GAAa,CAAA;AACjB,EAAA,GAAA,CAAI,WAAA,GAAc,SAAA;AAClB,EAAA,GAAA,CAAI,SAAA,GAAY,GAAA;AAGhB,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,KAAA,GAAS,CAAA,GAAI,IAAA,CAAK,EAAA,GAAM,CAAA;AAC9B,IAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAC,CAAA;AACf,IAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,IAAI,CAAA;AAAA,EAC3D;AACA,EAAA,GAAA,CAAI,MAAA,EAAO;AAEX,EAAA,GAAA,CAAI,OAAA,EAAQ;AACd;AAEO,SAAS,UAAA,CACd,GAAA,EACA,CAAA,EACA,CAAA,EACA,IAAA,EACM;AAEN,EAAA,MAAM,YAAY,GAAA,CAAI,SAAA;AAGtB,EAAA,MAAM,YAAA,GAAe,GAAA,CAAI,oBAAA,CAAqB,CAAA,GAAI,IAAA,GAAO,IAAA,EAAM,CAAA,GAAI,IAAA,GAAO,IAAA,EAAM,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,IAAI,CAAA;AAC7F,EAAA,YAAA,CAAa,YAAA,CAAa,GAAG,0BAA0B,CAAA;AACvD,EAAA,YAAA,CAAa,YAAA,CAAa,KAAK,SAAS,CAAA;AACxC,EAAA,YAAA,CAAa,YAAA,CAAa,KAAK,SAAS,CAAA;AACxC,EAAA,YAAA,CAAa,YAAA,CAAa,GAAG,0BAA0B,CAAA;AAEvD,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,GAAA,CAAI,IAAI,CAAA,EAAG,CAAA,EAAG,MAAM,CAAA,EAAG,IAAA,CAAK,KAAK,CAAC,CAAA;AAClC,EAAA,GAAA,CAAI,SAAA,GAAY,YAAA;AAChB,EAAA,GAAA,CAAI,IAAA,EAAK;AAGT,EAAA,GAAA,CAAI,WAAA,GAAc,0BAAA;AAClB,EAAA,GAAA,CAAI,SAAA,GAAY,CAAA;AAChB,EAAA,GAAA,CAAI,MAAA,EAAO;AAGX,EAAA,GAAA,CAAI,SAAA,GAAY,0BAAA;AAChB,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,GAAA,CAAI,GAAA,CAAI,CAAA,GAAI,IAAA,GAAO,GAAA,EAAK,CAAA,GAAI,IAAA,GAAO,GAAA,EAAK,IAAA,GAAO,IAAA,EAAM,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AACnE,EAAA,GAAA,CAAI,IAAA,EAAK;AAGT,EAAA,GAAA,CAAI,SAAA,GAAY,0BAAA;AAChB,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,GAAA,CAAI,GAAA,CAAI,CAAA,GAAI,IAAA,GAAO,GAAA,EAAK,CAAA,GAAI,IAAA,GAAO,GAAA,EAAK,IAAA,GAAO,IAAA,EAAM,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AACnE,EAAA,GAAA,CAAI,IAAA,EAAK;AAGT,EAAA,GAAA,CAAI,SAAA,GAAY,0BAAA;AAChB,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,GAAA,CAAI,GAAA,CAAI,CAAA,GAAI,IAAA,GAAO,GAAA,EAAK,CAAA,GAAI,IAAA,GAAO,GAAA,EAAK,IAAA,GAAO,GAAA,EAAK,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AAClE,EAAA,GAAA,CAAI,IAAA,EAAK;AACX;AAEO,SAAS,SAAA,CACd,GAAA,EACA,CAAA,EACA,CAAA,EACA,IAAA,EACM;AAEN,EAAA,MAAM,WAAW,IAAA,GAAO,CAAA;AACxB,EAAA,MAAM,YAAY,IAAA,GAAO,GAAA;AAGzB,EAAA,GAAA,CAAI,SAAS,CAAA,GAAI,SAAA,GAAY,GAAG,CAAA,GAAI,QAAA,EAAU,WAAW,IAAI,CAAA;AAE7D,EAAA,GAAA,CAAI,SAAS,CAAA,GAAI,QAAA,EAAU,IAAI,SAAA,GAAY,CAAA,EAAG,MAAM,SAAS,CAAA;AAC/D;AAEO,SAAS,QAAA,CACd,GAAA,EACA,CAAA,EACA,CAAA,EACA,OACA,MAAA,EACM;AACN,EAAA,GAAA,CAAI,IAAA,EAAK;AACT,EAAA,GAAA,CAAI,SAAA,CAAU,GAAG,CAAC,CAAA;AAClB,EAAA,GAAA,CAAI,KAAA,CAAM,KAAA,GAAQ,MAAA,EAAQ,CAAC,CAAA;AAC3B,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,GAAA,CAAI,IAAI,CAAA,EAAG,CAAA,EAAG,QAAQ,CAAA,EAAG,IAAA,CAAK,KAAK,CAAC,CAAA;AACpC,EAAA,GAAA,CAAI,IAAA,EAAK;AACT,EAAA,GAAA,CAAI,OAAA,EAAQ;AACd;;;AClKO,IAAM,iBAAN,MAAqB;AAAA;AAAA,EAa1B,WAAA,CAAY,OAAA,GAAyB,EAAC,EAAG;AAVzC,IAAA,IAAA,CAAQ,YAAwB,EAAC;AACjC,IAAA,IAAA,CAAQ,WAAA,GAA6B,IAAA;AACrC,IAAA,IAAA,CAAQ,MAAA,GAAwB,IAAA;AAChC,IAAA,IAAA,CAAQ,YAAA,GAAuB,GAAA;AAC/B;AAAA,IAAA,IAAA,CAAQ,gBAAA,GAA2B,CAAA;AACnC,IAAA,IAAA,CAAQ,gBAAA,GAA2B,EAAA;AACnC;AAAA,IAAA,IAAA,CAAQ,UAAA,GAAqB,CAAA;AAC7B,IAAA,IAAA,CAAQ,UAAA,GAAqB,CAAA;AAC7B,IAAA,IAAA,CAAQ,eAAA,GAA0B,CAAA;AAGhC,IAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,MAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AAAA,IACxB,CAAA,MAAO;AACL,MAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,IAAa,QAAA,CAAS,IAAA;AAChD,MAAA,IAAA,CAAK,MAAA,GAAS,aAAa,SAAS,CAAA;AAAA,IACtC;AAEA,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AACvC,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAM,IAAI,MAAM,0BAA0B,CAAA;AAAA,IAC5C;AACA,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AAGX,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA;AAC/C,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA;AACrD,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA;AACrD,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAErC,IAAA,MAAA,CAAO,gBAAA,CAAiB,QAAA,EAAU,IAAA,CAAK,YAAY,CAAA;AAAA,EACrD;AAAA,EAEQ,YAAA,GAAqB;AAC3B,IAAA,YAAA,CAAa,KAAK,MAAM,CAAA;AAAA,EAC1B;AAAA,EAEQ,gBAAgB,CAAA,EAAqB;AAC3C,IAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAElB,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,EAAA,GAAK,CAAA,CAAE,OAAA,GAAU,IAAA,CAAK,UAAA;AAC5B,IAAA,MAAM,EAAA,GAAK,CAAA,CAAE,OAAA,GAAU,IAAA,CAAK,UAAA;AAC5B,IAAA,MAAM,WAAW,IAAA,CAAK,IAAA,CAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AAG5C,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,QAAA,IAAY,IAAA,CAAK,gBAAA;AAC9C,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,eAAA,IAAmB,IAAA,CAAK,eAAA;AAGpD,IAAA,IAAI,GAAA,GAAM,IAAA,CAAK,gBAAA,IAAoB,QAAA,IAAY,YAAY,OAAA,EAAS;AAClE,MAAA,IAAA,CAAK,gBAAA,GAAmB,GAAA;AACxB,MAAA,IAAA,CAAK,aAAa,CAAA,CAAE,OAAA;AACpB,MAAA,IAAA,CAAK,aAAa,CAAA,CAAE,OAAA;AACpB,MAAA,MAAM,YAAY,IAAA,CAAK,MAAA,CAAO,YAAY,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAC9D,MAAA,IAAA,CAAK,aAAa,SAAS,CAAA;AAAA,IAC7B;AAAA,EACF;AAAA,EAEQ,gBAAgB,CAAA,EAAqB;AAC3C,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,CAAA,CAAE,OAAA,CAAQ,WAAW,CAAA,EAAG;AAE5C,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AACzB,IAAA,MAAM,EAAA,GAAK,KAAA,CAAM,OAAA,GAAU,IAAA,CAAK,UAAA;AAChC,IAAA,MAAM,EAAA,GAAK,KAAA,CAAM,OAAA,GAAU,IAAA,CAAK,UAAA;AAChC,IAAA,MAAM,WAAW,IAAA,CAAK,IAAA,CAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AAG5C,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,QAAA,IAAY,IAAA,CAAK,gBAAA;AAC9C,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,eAAA,IAAmB,IAAA,CAAK,eAAA;AAGpD,IAAA,IAAI,GAAA,GAAM,IAAA,CAAK,gBAAA,IAAoB,QAAA,IAAY,YAAY,OAAA,EAAS;AAClE,MAAA,IAAA,CAAK,gBAAA,GAAmB,GAAA;AACxB,MAAA,IAAA,CAAK,aAAa,KAAA,CAAM,OAAA;AACxB,MAAA,IAAA,CAAK,aAAa,KAAA,CAAM,OAAA;AACxB,MAAA,MAAM,YAAY,IAAA,CAAK,MAAA,CAAO,YAAY,KAAA,CAAM,OAAA,EAAS,MAAM,OAAO,CAAA;AACtE,MAAA,IAAA,CAAK,aAAa,SAAS,CAAA;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,YAAY,QAAA,EAA0B;AACpC,IAAA,IAAI,IAAA,CAAK,SAAA,CAAU,MAAA,GAAS,IAAA,CAAK,YAAA,EAAc;AAC7C,MAAA,IAAA,CAAK,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,aAAa,SAAA,EAA6B;AACxC,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,YAAA,GAAe,IAAA,CAAK,SAAA,CAAU,MAAA;AAC1D,IAAA,IAAI,iBAAiB,CAAA,EAAG;AACtB,MAAA,IAAA,CAAK,UAAU,IAAA,CAAK,GAAG,UAAU,KAAA,CAAM,CAAA,EAAG,cAAc,CAAC,CAAA;AAAA,IAC3D;AAAA,EACF;AAAA,EAEQ,MAAA,GAAe;AAErB,IAAA,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAA,QAAA,KAAY,QAAA,CAAS,QAAQ,CAAA;AAEpD,IAAA,IAAA,CAAK,SAAA,GAAY,KAAK,SAAA,CAAU,MAAA,CAAO,cAAY,CAAC,QAAA,CAAS,QAAQ,CAAA;AAAA,EACvE;AAAA,EAEQ,IAAA,GAAa;AAEnB,IAAA,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA,EAAG,CAAA,EAAG,KAAK,MAAA,CAAO,KAAA,EAAO,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAE9D,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,CAAA,QAAA,KAAY,SAAS,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EAC5D;AAAA,EAEQ,OAAA,GAAgB;AACtB,IAAA,IAAA,CAAK,MAAA,EAAO;AACZ,IAAA,IAAA,CAAK,IAAA,EAAK;AACV,IAAA,IAAA,CAAK,WAAA,GAAc,qBAAA,CAAsB,IAAA,CAAK,OAAO,CAAA;AAAA,EACvD;AAAA,EAEA,MAAM,MAAA,EAAsB;AAC1B,IAAA,IAAI,IAAA,CAAK,gBAAgB,IAAA,EAAM;AAC7B,MAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,MAAA,IAAA,CAAK,WAAA,GAAc,qBAAA,CAAsB,IAAA,CAAK,OAAO,CAAA;AACrD,MAAA,QAAA,CAAS,gBAAA,CAAiB,WAAA,EAAa,IAAA,CAAK,eAAe,CAAA;AAC3D,MAAA,QAAA,CAAS,iBAAiB,WAAA,EAAa,IAAA,CAAK,iBAAiB,EAAE,OAAA,EAAS,MAAM,CAAA;AAAA,IAChF;AAAA,EACF;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAI,IAAA,CAAK,gBAAgB,IAAA,EAAM;AAC7B,MAAA,oBAAA,CAAqB,KAAK,WAAW,CAAA;AACrC,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAA,EAAa,IAAA,CAAK,eAAe,CAAA;AAC9D,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAA,EAAa,IAAA,CAAK,eAAe,CAAA;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,YAAY,EAAC;AAClB,IAAA,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA,EAAG,CAAA,EAAG,KAAK,MAAA,CAAO,KAAA,EAAO,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAAA,EAChE;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,IAAA,EAAK;AACV,IAAA,IAAA,CAAK,KAAA,EAAM;AACX,IAAA,MAAA,CAAO,mBAAA,CAAoB,QAAA,EAAU,IAAA,CAAK,YAAY,CAAA;AACtD,IAAA,IAAI,IAAA,CAAK,OAAO,aAAA,EAAe;AAC7B,MAAA,IAAA,CAAK,MAAA,CAAO,aAAA,CAAc,WAAA,CAAY,IAAA,CAAK,MAAM,CAAA;AAAA,IACnD;AAAA,EACF;AACF,CAAA;;;ACtJO,IAAM,WAAN,MAAe;AAAA,EAuBpB,YAAY,MAAA,EAAwB;AAClC,IAAA,IAAA,CAAK,IAAI,MAAA,CAAO,CAAA;AAChB,IAAA,IAAA,CAAK,IAAI,MAAA,CAAO,CAAA;AAChB,IAAA,IAAA,CAAK,KAAK,MAAA,CAAO,EAAA,IAAA,CAAO,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,CAAA;AAC/C,IAAA,IAAA,CAAK,KAAK,MAAA,CAAO,EAAA,IAAA,CAAO,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,CAAA;AAC/C,IAAA,IAAA,CAAK,IAAA,GAAO,OAAO,IAAA,IAAQ,CAAA;AAC3B,IAAA,IAAA,CAAK,KAAA,GAAQ,OAAO,KAAA,IAAS,SAAA;AAC7B,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,EAAA;AACjC,IAAA,IAAA,CAAK,IAAA,GAAO,CAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,GAAA;AACjC,IAAA,IAAA,CAAK,OAAA,GAAU,CAAA;AACf,IAAA,IAAA,CAAK,QAAA,GAAW,OAAO,QAAA,IAAY,CAAA;AACnC,IAAA,IAAA,CAAK,aAAA,GAAgB,OAAO,aAAA,IAAiB,CAAA;AAC7C,IAAA,IAAA,CAAK,KAAA,GAAQ,OAAO,KAAA,IAAS,MAAA;AAC7B,IAAA,IAAA,CAAK,eAAA,GAAkB,OAAO,eAAA,IAAmB,CAAA;AACjD,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,CAAA;AACzC,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA,CAAK,MAAA,EAAO,GAAI,KAAK,EAAA,GAAK,CAAA;AAC7C,IAAA,IAAA,CAAK,SAAA,GAAY,OAAO,SAAA,IAAa,CAAA;AACrC,IAAA,IAAA,CAAK,QAAQ,MAAA,CAAO,KAAA;AACpB,IAAA,IAAA,CAAK,YAAA,GAAe,OAAO,YAAA,IAAgB,CAAA;AAC3C,IAAA,IAAA,CAAK,eAAA,GAAkB,OAAO,eAAA,IAAmB,CAAA;AACjD,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,YAAA;AAAA,EACpB;AAAA,EAEA,MAAA,GAAe;AACb,IAAA,IAAA,CAAK,IAAA,EAAA;AACL,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,OAAA;AAGhB,IAAA,IAAI,KAAK,eAAA,GAAkB,CAAA,IAAK,IAAA,CAAK,IAAA,GAAO,KAAK,eAAA,EAAiB;AAChE,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,eAAA;AAElC,MAAA,MAAM,gBAAgB,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,UAAU,CAAC,CAAA;AAClD,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,YAAA,GAAA,CAAgB,CAAA,GAAI,KAAK,YAAA,IAAgB,aAAA;AAAA,IAC7D,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,KAAA,GAAQ,CAAA;AAAA,IACf;AAGA,IAAA,IAAI,IAAA,CAAK,kBAAkB,CAAA,EAAG;AAC5B,MAAA,IAAA,CAAK,eAAe,IAAA,CAAK,WAAA;AACzB,MAAA,IAAA,CAAK,CAAA,IAAK,KAAK,EAAA,GAAK,IAAA,CAAK,IAAI,IAAA,CAAK,WAAW,IAAI,IAAA,CAAK,eAAA;AAAA,IACxD,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,KAAK,IAAA,CAAK,EAAA;AAAA,IACjB;AAGA,IAAA,IAAI,IAAA,CAAK,YAAY,CAAA,EAAG;AAEtB,MAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,IAAA,GAAO,IAAI,CAAA,GAAI,IAAA,CAAK,SAAA,GAAY,GAAA,GAC1D,KAAK,GAAA,CAAI,IAAA,CAAK,OAAO,IAAI,CAAA,GAAI,KAAK,SAAA,GAAY,GAAA;AAChD,MAAA,IAAA,CAAK,CAAA,IAAK,KAAA;AAAA,IACZ;AAEA,IAAA,IAAA,CAAK,KAAK,IAAA,CAAK,EAAA;AACf,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,aAAA;AACtB,IAAA,IAAA,CAAK,OAAA,GAAU,CAAA,GAAI,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,OAAA;AAAA,EACtC;AAAA,EAEA,MAAA,GAAkB;AAChB,IAAA,OAAO,IAAA,CAAK,QAAQ,IAAA,CAAK,OAAA;AAAA,EAC3B;AAAA,EAEA,KAAK,GAAA,EAAqC;AACxC,IAAA,GAAA,CAAI,IAAA,EAAK;AACT,IAAA,GAAA,CAAI,cAAc,IAAA,CAAK,OAAA;AAGvB,IAAA,GAAA,CAAI,SAAA,CAAU,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA;AAC5B,IAAA,GAAA,CAAI,KAAA,CAAM,IAAA,CAAK,KAAA,EAAO,IAAA,CAAK,KAAK,CAAA;AAChC,IAAA,GAAA,CAAI,UAAU,CAAC,IAAA,CAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAG9B,IAAA,IAAI,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,KAAA,CAAM,QAAA,EAAU;AAErC,MAAA,GAAA,CAAI,qBAAA,GAAwB,IAAA;AAC5B,MAAA,GAAA,CAAI,qBAAA,GAAwB,MAAA;AAE5B,MAAA,MAAM,OAAA,GAAU,KAAK,IAAA,GAAO,GAAA;AAC5B,MAAA,GAAA,CAAI,SAAA,CAAU,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA;AAC5B,MAAA,IAAI,IAAA,CAAK,aAAa,CAAA,EAAG;AACvB,QAAA,GAAA,CAAI,MAAA,CAAO,KAAK,QAAQ,CAAA;AAAA,MAC1B;AAQA,MAAA,GAAA,CAAI,SAAA;AAAA,QACF,IAAA,CAAK,KAAA;AAAA,QACL,CAAC,OAAA,GAAU,CAAA;AAAA,QACX,CAAC,OAAA,GAAU,CAAA;AAAA,QACX,OAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,GAAA,CAAI,OAAA,EAAQ;AACZ,MAAA;AAAA,IACF;AAGA,IAAA,GAAA,CAAI,YAAY,IAAA,CAAK,KAAA;AAGrB,IAAA,QAAQ,KAAK,KAAA;AAAO,MAClB,KAAK,WAAA;AACH,QAAA,IAAI,IAAA,CAAK,aAAa,CAAA,EAAG;AACvB,UAAA,GAAA,CAAI,SAAA,CAAU,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA;AAC5B,UAAA,GAAA,CAAI,MAAA,CAAO,KAAK,QAAQ,CAAA;AACxB,UAAA,GAAA,CAAI,UAAU,CAAC,IAAA,CAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAAA,QAChC;AACA,QAAA,aAAA,CAAc,GAAA,EAAK,KAAK,CAAA,EAAG,IAAA,CAAK,GAAG,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,IAAA,GAAO,GAAG,CAAA;AAC7D,QAAA;AAAA,MAEF,KAAK,QAAA;AACH,QAAA,GAAA,CAAI,UAAA,GAAa,EAAA;AACjB,QAAA,GAAA,CAAI,cAAc,IAAA,CAAK,KAAA;AACvB,QAAA,GAAA,CAAI,SAAA,EAAU;AACd,QAAA,GAAA,CAAI,GAAA,CAAI,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,CAAA,EAAG,KAAK,IAAA,EAAM,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AACjD,QAAA,GAAA,CAAI,IAAA,EAAK;AACT,QAAA;AAAA,MAEF,KAAK,WAAA;AACH,QAAA,GAAA,CAAI,cAAc,IAAA,CAAK,KAAA;AACvB,QAAA,GAAA,CAAI,SAAA,GAAY,GAAA;AAChB,QAAA,aAAA,CAAc,GAAA,EAAK,KAAK,CAAA,EAAG,IAAA,CAAK,GAAG,IAAA,CAAK,IAAA,EAAM,KAAK,QAAQ,CAAA;AAC3D,QAAA;AAAA,MAEF,KAAK,QAAA;AACH,QAAA,UAAA,CAAW,KAAK,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,CAAA,EAAG,KAAK,IAAI,CAAA;AACzC,QAAA;AAAA,MAEF,KAAK,OAAA;AACH,QAAA,GAAA,CAAI,UAAA,GAAa,EAAA;AACjB,QAAA,GAAA,CAAI,cAAc,IAAA,CAAK,KAAA;AACvB,QAAA,SAAA,CAAU,KAAK,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,CAAA,EAAG,KAAK,IAAI,CAAA;AACxC,QAAA;AAAA,MAEF,KAAK,MAAA;AACH,QAAA,GAAA,CAAI,UAAA,GAAa,EAAA;AACjB,QAAA,GAAA,CAAI,cAAc,IAAA,CAAK,KAAA;AACvB,QAAA,QAAA,CAAS,GAAA,EAAK,KAAK,CAAA,EAAG,IAAA,CAAK,GAAG,IAAA,CAAK,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA;AACtD,QAAA;AAAA,MAEF;AACE,QAAA,QAAA,CAAS,KAAK,IAAA,CAAK,CAAA,EAAG,KAAK,CAAA,EAAG,IAAA,CAAK,MAAM,CAAC,CAAA;AAC1C,QAAA;AAAA;AAGJ,IAAA,GAAA,CAAI,OAAA,EAAQ;AAAA,EACd;AACF,CAAA;;;ACjLO,IAAM,cAAN,MAAkB;AAAA,EAIvB,aAAa,UAAU,GAAA,EAAwC;AAE7D,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,EAAG;AACxB,MAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AAAA,IAC5B;AAGA,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,EAAG;AACzB,MAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAAA,IAC7B;AAGA,IAAA,MAAM,WAAA,GAAc,IAAI,OAAA,CAA0B,CAAC,SAAS,MAAA,KAAW;AACrE,MAAA,MAAM,GAAA,GAAM,IAAI,KAAA,EAAM;AACtB,MAAA,GAAA,CAAI,SAAS,MAAM;AACjB,QAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,GAAA,EAAK,GAAG,CAAA;AACxB,QAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,GAAG,CAAA;AACvB,QAAA,OAAA,CAAQ,GAAG,CAAA;AAAA,MACb,CAAA;AACA,MAAA,GAAA,CAAI,UAAU,MAAM;AAClB,QAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,GAAG,CAAA;AACvB,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,GAAG,EAAE,CAAC,CAAA;AAAA,MAClD,CAAA;AACA,MAAA,GAAA,CAAI,GAAA,GAAM,GAAA;AAAA,IACZ,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,WAAW,CAAA;AACjC,IAAA,OAAO,WAAA;AAAA,EACT;AAAA,EAEA,aAAa,WAAA,CAAY,QAAA,GAAmB,UAAA,EAAyC;AACnF,IAAA,MAAM,WAAA,GAAc;AAAA,MAClB,GAAG,QAAQ,CAAA,mBAAA,CAAA;AAAA,MACX,GAAG,QAAQ,CAAA,kBAAA,CAAA;AAAA,MACX,GAAG,QAAQ,CAAA,kBAAA;AAAA,KACb;AAEA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,OAAA,CAAQ,GAAA,CAAI,WAAA,CAAY,GAAA,CAAI,UAAQ,IAAA,CAAK,SAAA,CAAU,IAAI,CAAC,CAAC,CAAA;AAAA,IACxE,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,uEAAuE,KAAK,CAAA;AACzF,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,aAAa,cAAA,CAAe,QAAA,GAAmB,aAAA,EAA4C;AACzF,IAAA,MAAM,cAAA,GAAiB;AAAA;AAAA,MAErB,GAAG,QAAQ,CAAA,iBAAA,CAAA;AAAA,MACX,GAAG,QAAQ,CAAA,iBAAA;AAAA,KACb;AAEA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,OAAA,CAAQ,GAAA,CAAI,cAAA,CAAe,GAAA,CAAI,UAAQ,IAAA,CAAK,SAAA,CAAU,IAAI,CAAC,CAAC,CAAA;AAAA,IAC3E,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,0EAA0E,KAAK,CAAA;AAC5F,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,OAAO,eAAA,GAA2C;AAChD,IAAA,MAAM,YAAA,GAAe,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,CAClD,MAAA,CAAO,CAAC,CAAC,GAAG,MAAM,GAAA,CAAI,QAAA,CAAS,QAAQ,CAAC,CAAA,CACxC,GAAA,CAAI,CAAC,GAAG,GAAG,CAAA,KAAM,GAAG,CAAA;AACvB,IAAA,IAAI,YAAA,CAAa,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACtC,IAAA,OAAO,YAAA,CAAa,KAAK,KAAA,CAAM,IAAA,CAAK,QAAO,GAAI,YAAA,CAAa,MAAM,CAAC,CAAA;AAAA,EACrE;AAAA,EAEA,OAAO,kBAAA,GAA8C;AACnD,IAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,CACrD,MAAA,CAAO,CAAC,CAAC,GAAG,MAAM,GAAA,CAAI,QAAA,CAAS,MAAM,CAAC,CAAA,CACtC,GAAA,CAAI,CAAC,GAAG,GAAG,CAAA,KAAM,GAAG,CAAA;AACvB,IAAA,IAAI,eAAA,CAAgB,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACzC,IAAA,OAAO,eAAA,CAAgB,KAAK,KAAA,CAAM,IAAA,CAAK,QAAO,GAAI,eAAA,CAAgB,MAAM,CAAC,CAAA;AAAA,EAC3E;AAAA,EAEA,OAAO,QAAA,GAAoB;AACzB,IAAA,OAAO,IAAA,CAAK,OAAO,IAAA,GAAO,CAAA;AAAA,EAC5B;AAAA,EAEA,OAAO,KAAA,GAAc;AACnB,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAClB,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AACF;AAxFa,WAAA,CACI,MAAA,uBAA4C,GAAA,EAAI;AADpD,WAAA,CAEI,OAAA,uBAAsD,GAAA,EAAI;;;ACC3E,IAAM,cAAA,GAAiB;AAAA,EACrB,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAA;AAEO,SAAS,qBAAA,CAAsB,OAAA,GAAyB,EAAC,EAAW;AACzE,EAAA,MAAM;AAAA,IACJ,MAAA,GAAS,cAAA;AAAA,IACT,aAAA,GAAgB,CAAA;AAAA,IAChB,YAAA,GAAe,CAAA;AAAA;AAAA,IACf,OAAA,GAAU,KAAA;AAAA;AAAA,IACV,OAAA,GAAU,EAAA;AAAA,IACV,QAAA,GAAW;AAAA,GACb,GAAI,OAAA;AAEJ,EAAA,OAAO;AAAA,IACL,WAAA,CAAY,GAAW,CAAA,EAAuB;AAC5C,MAAA,MAAM,YAAwB,EAAC;AAE/B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,EAAe,CAAA,EAAA,EAAK;AACtC,QAAA,SAAA,CAAU,IAAA;AAAA,UACR,IAAI,QAAA,CAAS;AAAA,YACX,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,EAAA;AAAA,YAC/B,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,EAAA;AAAA,YAC/B,EAAA,EAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,QAAA;AAAA,YAC5B,EAAA,EAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,OAAO,QAAA,GAAW,CAAA;AAAA;AAAA,YACvC,IAAA,EAAM,IAAA,CAAK,MAAA,EAAO,GAAI,YAAA,GAAe,CAAA;AAAA;AAAA,YACrC,KAAA,EAAO,YAAY,MAAM,CAAA;AAAA,YACzB,OAAA,EAAS,OAAA,GAAU,IAAA,CAAK,MAAA,EAAO,GAAI,EAAA;AAAA,YACnC,OAAA;AAAA,YACA,KAAA,EAAO;AAAA,WACR;AAAA,SACH;AAAA,MACF;AAEA,MAAA,OAAO,SAAA;AAAA,IACT;AAAA,GACF;AACF;;;ACzCA,IAAMA,eAAAA,GAAiB;AAAA,EACrB,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAA;AAEO,SAAS,mBAAA,CAAoB,OAAA,GAAyB,EAAC,EAAW;AACvE,EAAA,MAAM;AAAA,IACJ,MAAA,GAASA,eAAAA;AAAA,IACT,aAAA,GAAgB,CAAA;AAAA;AAAA,IAChB,YAAA,GAAe,CAAA;AAAA;AAAA,IACf,OAAA,GAAU,GAAA;AAAA,IACV,OAAA,GAAU,EAAA;AAAA;AAAA,IACV,QAAA,GAAW;AAAA,GACb,GAAI,OAAA;AAEJ,EAAA,OAAO;AAAA,IACL,WAAA,CAAY,GAAW,CAAA,EAAuB;AAC5C,MAAA,MAAM,YAAwB,EAAC;AAE/B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,EAAe,CAAA,EAAA,EAAK;AACtC,QAAA,SAAA,CAAU,IAAA;AAAA,UACR,IAAI,QAAA,CAAS;AAAA,YACX,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,EAAA;AAAA,YAC/B,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,EAAA;AAAA,YAC/B,EAAA,EAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,QAAA;AAAA,YAC5B,EAAA,EAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,QAAA;AAAA,YAC5B,IAAA,EAAM,IAAA,CAAK,MAAA,EAAO,GAAI,YAAA,GAAe,CAAA;AAAA;AAAA,YACrC,KAAA,EAAO,YAAY,MAAM,CAAA;AAAA,YACzB,OAAA,EAAS,OAAA,GAAU,IAAA,CAAK,MAAA,EAAO,GAAI,EAAA;AAAA;AAAA,YACnC;AAAA,WACD;AAAA,SACH;AAAA,MACF;AAEA,MAAA,OAAO,SAAA;AAAA,IACT;AAAA,GACF;AACF;;;ACvCA,IAAMA,eAAAA,GAAiB;AAAA,EACrB,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAA;AAEO,SAAS,oBAAA,CAAqB,OAAA,GAAyB,EAAC,EAAW;AACxE,EAAA,MAAM;AAAA,IACJ,MAAA,GAASA,eAAAA;AAAA,IACT,aAAA,GAAgB,CAAA;AAAA,IAChB,YAAA,GAAe,CAAA;AAAA,IACf,OAAA,GAAU,GAAA;AAAA;AAAA,IACV,OAAA,GAAU,EAAA;AAAA;AAAA,IACV,QAAA,GAAW;AAAA,GACb,GAAI,OAAA;AAEJ,EAAA,OAAO;AAAA,IACL,WAAA,CAAY,GAAW,CAAA,EAAuB;AAC5C,MAAA,MAAM,YAAwB,EAAC;AAE/B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,EAAe,CAAA,EAAA,EAAK;AACtC,QAAA,SAAA,CAAU,IAAA;AAAA,UACR,IAAI,QAAA,CAAS;AAAA,YACX,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,EAAA;AAAA,YAC/B,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,EAAA;AAAA,YAC/B,EAAA,EAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,QAAA;AAAA,YAC5B,EAAA,EAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,KAAK,QAAA,GAAW,GAAA;AAAA;AAAA,YACrC,IAAA,EAAM,IAAA,CAAK,MAAA,EAAO,GAAI,YAAA,GAAe,CAAA;AAAA,YACrC,KAAA,EAAO,YAAY,MAAM,CAAA;AAAA,YACzB,OAAA,EAAS,OAAA,GAAU,IAAA,CAAK,MAAA,EAAO,GAAI,EAAA;AAAA,YACnC,OAAA;AAAA,YACA,QAAA,EAAU,IAAA,CAAK,MAAA,EAAO,GAAI,KAAK,EAAA,GAAK,CAAA;AAAA;AAAA,YACpC,aAAA,EAAA,CAAgB,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,GAAA;AAAA;AAAA,YACvC,KAAA,EAAO;AAAA,WACR;AAAA,SACH;AAAA,MACF;AAEA,MAAA,OAAO,SAAA;AAAA,IACT;AAAA,GACF;AACF;;;AC9CA,IAAMA,eAAAA,GAAiB;AAAA,EACrB,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAA;AAEO,SAAS,oBAAA,CAAqB,OAAA,GAAyB,EAAC,EAAW;AACxE,EAAA,MAAM;AAAA,IACJ,MAAA,GAASA,eAAAA;AAAA,IACT,aAAA,GAAgB,CAAA;AAAA,IAChB,YAAA,GAAe,CAAA;AAAA;AAAA,IACf,OAAA,GAAU,CAAA;AAAA;AAAA,IACV,OAAA,GAAU,EAAA;AAAA;AAAA,IACV,QAAA,GAAW;AAAA;AAAA,GACb,GAAI,OAAA;AAEJ,EAAA,OAAO;AAAA,IACL,WAAA,CAAY,GAAW,CAAA,EAAuB;AAC5C,MAAA,MAAM,YAAwB,EAAC;AAE/B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,EAAe,CAAA,EAAA,EAAK;AACtC,QAAA,SAAA,CAAU,IAAA;AAAA,UACR,IAAI,QAAA,CAAS;AAAA,YACX,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,CAAA;AAAA,YAC/B,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,CAAA;AAAA,YAC/B,EAAA,EAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,QAAA;AAAA,YAC5B,EAAA,EAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,QAAA;AAAA,YAC5B,IAAA,EAAM,IAAA,CAAK,MAAA,EAAO,GAAI,YAAA,GAAe,CAAA;AAAA,YACrC,KAAA,EAAO,YAAY,MAAM,CAAA;AAAA,YACzB,OAAA,EAAS,OAAA,GAAU,IAAA,CAAK,MAAA,EAAO,GAAI,EAAA;AAAA,YACnC,OAAA;AAAA,YACA,KAAA,EAAO;AAAA;AAAA,WACR;AAAA,SACH;AAAA,MACF;AAEA,MAAA,OAAO,SAAA;AAAA,IACT;AAAA,GACF;AACF;;;ACvCA,IAAMA,eAAAA,GAAiB;AAAA,EACrB,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA,SAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAA;AAKO,SAAS,gBAAA,CAAiB,OAAA,GAAyB,EAAC,EAAW;AACpE,EAAA,MAAM;AAAA,IACJ,MAAA,GAASA,eAAAA;AAAA,IACT,aAAA,GAAgB,CAAA;AAAA;AAAA,IAChB,YAAA,GAAe,CAAA;AAAA;AAAA,IACf,OAAA,GAAU,IAAA;AAAA;AAAA,IACV,OAAA,GAAU,GAAA;AAAA;AAAA,IACV,QAAA,GAAW,GAAA;AAAA;AAAA,IACX,QAAA,GAAW,GAAA;AAAA;AAAA,IACX,eAAA,GAAkB;AAAA;AAAA,GACpB,GAAI,OAAA;AAEJ,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,eAAA;AAAA,IACA,WAAA,CAAY,GAAW,CAAA,EAAuB;AAC5C,MAAA,MAAM,YAAwB,EAAC;AAE/B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,EAAe,CAAA,EAAA,EAAK;AAEtC,QAAA,MAAM,cAAA,GAAwC,WAAA,CAAY,kBAAA,EAAmB,CAAI;AAEjF,QAAA,SAAA,CAAU,IAAA;AAAA,UACR,IAAI,QAAA,CAAS;AAAA,YACX,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,EAAA;AAAA,YAC/B,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,EAAA;AAAA,YAC/B,EAAA,EAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,QAAA;AAAA,YAC5B,EAAA,EAAI,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,GAAM,GAAA;AAAA;AAAA,YAC1B,IAAA,EAAM,IAAA,CAAK,MAAA,EAAO,GAAI,YAAA,GAAe,CAAA;AAAA;AAAA,YACrC,KAAA,EAAO,YAAY,MAAM,CAAA;AAAA,YACzB,OAAA,EAAS,OAAA,GAAU,IAAA,CAAK,MAAA,EAAO,GAAI,EAAA;AAAA,YACnC,OAAA;AAAA,YACA,QAAA,EAAU,IAAA,CAAK,MAAA,EAAO,GAAI,KAAK,EAAA,GAAK,CAAA;AAAA;AAAA,YACpC,aAAA,EAAA,CAAgB,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,IAAA;AAAA;AAAA,YACvC,KAAA,EAAO,WAAA;AAAA,YACP,SAAA,EAAW,GAAA;AAAA;AAAA,YACX,OAAO,cAAA,IAAkB;AAAA;AAAA,WAC1B;AAAA,SACH;AAAA,MACF;AAEA,MAAA,OAAO,SAAA;AAAA,IACT;AAAA,GACF;AACF;;;ACtDA,IAAMA,eAAAA,GAAiB;AAAA,EACrB,0BAAA;AAAA;AAAA,EACA,0BAAA;AAAA;AAAA,EACA,0BAAA;AAAA;AAAA,EACA,0BAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAA;AAEO,SAAS,kBAAA,CAAmB,OAAA,GAAyB,EAAC,EAAW;AACtE,EAAA,MAAM;AAAA,IACJ,MAAA,GAASA,eAAAA;AAAA,IACT,aAAA,GAAgB,CAAA;AAAA;AAAA,IAChB,OAAA,GAAU,KAAA;AAAA;AAAA,IACV,OAAA,GAAU,GAAA;AAAA;AAAA,IACV,QAAA,GAAW,GAAA;AAAA;AAAA,IACX,QAAA,GAAW,GAAA;AAAA;AAAA,IACX,eAAA,GAAkB;AAAA;AAAA,GACpB,GAAI,OAAA;AAEJ,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,eAAA;AAAA,IACA,WAAA,CAAY,GAAW,CAAA,EAAuB;AAC5C,MAAA,MAAM,YAAwB,EAAC;AAE/B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,EAAe,CAAA,EAAA,EAAK;AACtC,QAAA,MAAM,WAAA,GAAc,YAAY,eAAA,EAAgB;AAGhD,QAAA,MAAM,QAAA,GAAW,EAAA,GAAK,IAAA,CAAK,MAAA,EAAO,GAAI,EAAA;AAEtC,QAAA,SAAA,CAAU,IAAA;AAAA,UACR,IAAI,QAAA,CAAS;AAAA,YACX,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,EAAA;AAAA;AAAA,YAC/B,CAAA,EAAG,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,EAAA;AAAA,YAC/B,EAAA,EAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,QAAA;AAAA,YAC5B,EAAA,EAAI,CAAC,IAAA,CAAK,MAAA,KAAW,IAAA,GAAO,GAAA;AAAA;AAAA,YAC5B,IAAA,EAAM,QAAA;AAAA;AAAA,YACN,KAAA,EAAO,YAAY,MAAM,CAAA;AAAA,YACzB,OAAA,EAAS,OAAA,GAAU,IAAA,CAAK,MAAA,EAAO,GAAI,EAAA;AAAA,YACnC,OAAA;AAAA,YACA,KAAA,EAAO,QAAA;AAAA,YACP,eAAA,EAAiB,GAAA;AAAA;AAAA,YACjB,WAAA,EAAa,IAAA;AAAA;AAAA,YACb,OAAO,WAAA,IAAe,MAAA;AAAA;AAAA,YACtB,YAAA,EAAc,GAAA;AAAA;AAAA,YACd,eAAA,EAAiB;AAAA;AAAA,WAClB;AAAA,SACH;AAAA,MACF;AAEA,MAAA,OAAO,SAAA;AAAA,IACT;AAAA,GACF;AACF;;;ACpBO,SAAS,YAAA,CAAa,OAAA,GAA+B,EAAC,EAAqB;AAEhF,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,MAAM,oBAAA,GAAuB,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA;AACnF,IAAA,IAAI,oBAAA,EAAsB;AAExB,MAAA,OAAO,EAAE,SAAS,MAAM;AAAA,MAAC,CAAA,EAAE;AAAA,IAC7B;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAAS,IAAI,cAAA,EAAe;AAGlC,EAAA,MAAM,EAAE,MAAA,GAAS,WAAA,EAAa,GAAG,eAAc,GAAI,OAAA;AAInD,EAAA,MAAM,cAAA,GACJ,MAAA,KAAW,UAAA,GACP,oBAAA,CAAqB,aAAa,CAAA,GAClC,MAAA,KAAW,SAAA,GACX,mBAAA,CAAoB,aAAa,CAAA,GACjC,MAAA,KAAW,UAAA,GACX,oBAAA,CAAqB,aAAa,CAAA,GAClC,MAAA,KAAW,MAAA,GACX,gBAAA,CAAiB,aAAa,CAAA,GAC9B,MAAA,KAAW,QAAA,GACX,kBAAA,CAAmB,aAAa,CAAA,GAChC,qBAAA,CAAsB,aAAa,CAAA;AAGzC,EAAA,MAAA,CAAO,MAAM,cAAc,CAAA;AAE3B,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,MAAM,MAAA,CAAO,OAAA;AAAQ,GAChC;AACF","file":"index.js","sourcesContent":["export function randomColor(colors: string[]): string {\n return colors[Math.floor(Math.random() * colors.length)];\n}\n\nexport function randomRange(min: number, max: number): number {\n return Math.random() * (max - min) + min;\n}\n\nexport function createCanvas(container: HTMLElement): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n canvas.style.position = 'fixed';\n canvas.style.top = '0';\n canvas.style.left = '0';\n canvas.style.pointerEvents = 'none';\n canvas.style.zIndex = '9999';\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n container.appendChild(canvas);\n return canvas;\n}\n\nexport function resizeCanvas(canvas: HTMLCanvasElement): void {\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n}\n\nexport function drawStar(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n spikes: number = 5\n): void {\n const outerRadius = size;\n const innerRadius = size * 0.4;\n\n ctx.beginPath();\n for (let i = 0; i < spikes * 2; i++) {\n const angle = (i * Math.PI) / spikes;\n const radius = i % 2 === 0 ? outerRadius : innerRadius;\n const dx = Math.cos(angle) * radius;\n const dy = Math.sin(angle) * radius;\n\n if (i === 0) {\n ctx.moveTo(x + dx, y + dy);\n } else {\n ctx.lineTo(x + dx, y + dy);\n }\n }\n ctx.closePath();\n ctx.fill();\n}\n\nexport function drawRectangle(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.fillRect(x - width / 2, y - height / 2, width, height);\n}\n\nexport function drawSnowflake(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n rotation: number = 0\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Optimized glow - reduced blur for better performance\n ctx.shadowBlur = 4;\n ctx.shadowColor = '#FFFFFF';\n ctx.lineWidth = 1.8; // Slightly thicker for better visibility\n\n // Draw all 6 arms in a single path for better performance\n ctx.beginPath();\n for (let i = 0; i < 6; i++) {\n const angle = (i * Math.PI) / 3;\n ctx.moveTo(0, 0);\n ctx.lineTo(Math.cos(angle) * size, Math.sin(angle) * size);\n }\n ctx.stroke();\n\n ctx.restore();\n}\n\nexport function drawBubble(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Save the original fill color\n const baseColor = ctx.fillStyle as string;\n\n // Main bubble with multi-layer gradient for depth\n const mainGradient = ctx.createRadialGradient(x - size * 0.25, y - size * 0.25, 0, x, y, size);\n mainGradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');\n mainGradient.addColorStop(0.3, baseColor);\n mainGradient.addColorStop(0.7, baseColor);\n mainGradient.addColorStop(1, 'rgba(255, 255, 255, 0.1)');\n\n ctx.beginPath();\n ctx.arc(x, y, size, 0, Math.PI * 2);\n ctx.fillStyle = mainGradient;\n ctx.fill();\n\n // Subtle border/rim for definition\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';\n ctx.lineWidth = 1;\n ctx.stroke();\n\n // Primary highlight (large, soft)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';\n ctx.beginPath();\n ctx.arc(x - size * 0.3, y - size * 0.3, size * 0.35, 0, Math.PI * 2);\n ctx.fill();\n\n // Secondary highlight (small, bright)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';\n ctx.beginPath();\n ctx.arc(x - size * 0.4, y - size * 0.4, size * 0.15, 0, Math.PI * 2);\n ctx.fill();\n\n // Reflected light on opposite side\n ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';\n ctx.beginPath();\n ctx.arc(x + size * 0.4, y + size * 0.4, size * 0.2, 0, Math.PI * 2);\n ctx.fill();\n}\n\nexport function drawCross(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Draw simple 4-pointed cross/plus shape\n const halfSize = size / 2;\n const thickness = size * 0.3;\n\n // Vertical bar\n ctx.fillRect(x - thickness / 2, y - halfSize, thickness, size);\n // Horizontal bar\n ctx.fillRect(x - halfSize, y - thickness / 2, size, thickness);\n}\n\nexport function drawOval(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.scale(width / height, 1);\n ctx.beginPath();\n ctx.arc(0, 0, height, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\n}\n","import { Particle } from './particle';\nimport { createCanvas, resizeCanvas } from './utils';\nimport type { EngineOptions, Effect } from './types';\n\nexport class CursorFXEngine {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private particles: Particle[] = [];\n private animationId: number | null = null;\n private effect: Effect | null = null;\n private maxParticles: number = 500; // Cap to prevent performance issues\n private lastParticleTime: number = 0;\n private particleThrottle: number = 16; // Create particles every 16ms (~60fps)\n private lastMouseX: number = 0;\n private lastMouseY: number = 0;\n private minMoveDistance: number = 0; // Create particles on every valid move\n\n constructor(options: EngineOptions = {}) {\n if (options.canvas) {\n this.canvas = options.canvas;\n } else {\n const container = options.container || document.body;\n this.canvas = createCanvas(container);\n }\n\n const ctx = this.canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context');\n }\n this.ctx = ctx;\n\n // Bind methods once to prevent memory leaks\n this.handleResize = this.handleResize.bind(this);\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleTouchMove = this.handleTouchMove.bind(this);\n this.animate = this.animate.bind(this);\n\n window.addEventListener('resize', this.handleResize);\n }\n\n private handleResize(): void {\n resizeCanvas(this.canvas);\n }\n\n private handleMouseMove(e: MouseEvent): void {\n if (!this.effect) return;\n\n const now = Date.now();\n const dx = e.clientX - this.lastMouseX;\n const dy = e.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND mouse moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = e.clientX;\n this.lastMouseY = e.clientY;\n const particles = this.effect.onMouseMove(e.clientX, e.clientY);\n this.addParticles(particles);\n }\n }\n\n private handleTouchMove(e: TouchEvent): void {\n if (!this.effect || e.touches.length === 0) return;\n\n const now = Date.now();\n const touch = e.touches[0];\n const dx = touch.clientX - this.lastMouseX;\n const dy = touch.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND touch moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = touch.clientX;\n this.lastMouseY = touch.clientY;\n const particles = this.effect.onMouseMove(touch.clientX, touch.clientY);\n this.addParticles(particles);\n }\n }\n\n addParticle(particle: Particle): void {\n if (this.particles.length < this.maxParticles) {\n this.particles.push(particle);\n }\n }\n\n addParticles(particles: Particle[]): void {\n const availableSlots = this.maxParticles - this.particles.length;\n if (availableSlots > 0) {\n this.particles.push(...particles.slice(0, availableSlots));\n }\n }\n\n private update(): void {\n // Update all particles\n this.particles.forEach(particle => particle.update());\n // Remove dead particles\n this.particles = this.particles.filter(particle => !particle.isDead());\n }\n\n private draw(): void {\n // Clear canvas\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n // Render all particles with shadow/glow effects\n this.particles.forEach(particle => particle.draw(this.ctx));\n }\n\n private animate(): void {\n this.update();\n this.draw();\n this.animationId = requestAnimationFrame(this.animate);\n }\n\n start(effect: Effect): void {\n if (this.animationId === null) {\n this.effect = effect;\n this.animationId = requestAnimationFrame(this.animate);\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('touchmove', this.handleTouchMove, { passive: true });\n }\n }\n\n stop(): void {\n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n this.animationId = null;\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('touchmove', this.handleTouchMove);\n }\n }\n\n clear(): void {\n this.particles = [];\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n destroy(): void {\n this.stop();\n this.clear();\n window.removeEventListener('resize', this.handleResize);\n if (this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n}\n","import type { ParticleConfig } from './types';\nimport { drawStar, drawRectangle, drawSnowflake, drawBubble, drawCross, drawOval } from './utils';\n\nexport class Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size: number;\n color: string;\n life: number;\n maxLife: number;\n gravity: number;\n opacity: number;\n rotation: number;\n rotationSpeed: number;\n shape: 'star' | 'rectangle' | 'circle' | 'snowflake' | 'bubble' | 'cross' | 'oval';\n wobbleAmplitude: number;\n wobbleSpeed: number;\n wobblePhase: number;\n windDrift: number;\n image?: HTMLImageElement;\n scale: number;\n initialScale: number;\n scaleUpDuration: number;\n\n constructor(config: ParticleConfig) {\n this.x = config.x;\n this.y = config.y;\n this.vx = config.vx ?? (Math.random() - 0.5) * 4;\n this.vy = config.vy ?? (Math.random() - 0.5) * 4;\n this.size = config.size ?? 3;\n this.color = config.color ?? '#ffffff';\n this.maxLife = config.maxLife ?? 40; // Reduced for better performance\n this.life = 0;\n this.gravity = config.gravity ?? 0.1;\n this.opacity = 1;\n this.rotation = config.rotation ?? 0;\n this.rotationSpeed = config.rotationSpeed ?? 0;\n this.shape = config.shape ?? 'star';\n this.wobbleAmplitude = config.wobbleAmplitude ?? 0;\n this.wobbleSpeed = config.wobbleSpeed ?? 0;\n this.wobblePhase = Math.random() * Math.PI * 2; // Random starting phase\n this.windDrift = config.windDrift ?? 0;\n this.image = config.image;\n this.initialScale = config.initialScale ?? 1; // Default to full scale\n this.scaleUpDuration = config.scaleUpDuration ?? 0; // Default no animation\n this.scale = this.initialScale; // Start at initial scale\n }\n\n update(): void {\n this.life++;\n this.vy += this.gravity;\n\n // Animate scale from initialScale to 1.0 over scaleUpDuration frames\n if (this.scaleUpDuration > 0 && this.life < this.scaleUpDuration) {\n const progress = this.life / this.scaleUpDuration;\n // Ease-out cubic for smooth pop-up effect\n const easedProgress = 1 - Math.pow(1 - progress, 3);\n this.scale = this.initialScale + (1 - this.initialScale) * easedProgress;\n } else {\n this.scale = 1;\n }\n\n // Apply wobble (for bubbles)\n if (this.wobbleAmplitude > 0) {\n this.wobblePhase += this.wobbleSpeed;\n this.x += this.vx + Math.sin(this.wobblePhase) * this.wobbleAmplitude;\n } else {\n this.x += this.vx;\n }\n\n // Apply wind drift (for snowflakes)\n if (this.windDrift > 0) {\n // Smooth Perlin-like drift using sine waves at different frequencies\n const drift = Math.sin(this.life * 0.05) * this.windDrift * 0.3 +\n Math.sin(this.life * 0.02) * this.windDrift * 0.7;\n this.x += drift;\n }\n\n this.y += this.vy;\n this.rotation += this.rotationSpeed;\n this.opacity = 1 - this.life / this.maxLife;\n }\n\n isDead(): boolean {\n return this.life >= this.maxLife;\n }\n\n draw(ctx: CanvasRenderingContext2D): void {\n ctx.save();\n ctx.globalAlpha = this.opacity;\n\n // Apply scale transform (for pop-up animation)\n ctx.translate(this.x, this.y);\n ctx.scale(this.scale, this.scale);\n ctx.translate(-this.x, -this.y);\n\n // If image is available, render image instead of shape\n if (this.image && this.image.complete) {\n // Enable high-quality image smoothing for better rendering\n ctx.imageSmoothingEnabled = true;\n ctx.imageSmoothingQuality = 'high';\n\n const imgSize = this.size * 2.5; // Larger multiplier for bigger images\n ctx.translate(this.x, this.y);\n if (this.rotation !== 0) {\n ctx.rotate(this.rotation);\n }\n\n // Add simple glow for snowflake images (single pass)\n // if (this.shape === 'snowflake') {\n // ctx.shadowBlur = 8;\n // ctx.shadowColor = '#FFFFFF';\n // }\n\n ctx.drawImage(\n this.image,\n -imgSize / 2,\n -imgSize / 2,\n imgSize,\n imgSize\n );\n ctx.restore();\n return;\n }\n\n // Fallback to shape rendering\n ctx.fillStyle = this.color;\n\n // Draw based on shape\n switch (this.shape) {\n case 'rectangle':\n if (this.rotation !== 0) {\n ctx.translate(this.x, this.y);\n ctx.rotate(this.rotation);\n ctx.translate(-this.x, -this.y);\n }\n drawRectangle(ctx, this.x, this.y, this.size, this.size * 1.5);\n break;\n\n case 'circle':\n ctx.shadowBlur = 15; // Strong glow for circles\n ctx.shadowColor = this.color;\n ctx.beginPath();\n ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\n ctx.fill();\n break;\n\n case 'snowflake':\n ctx.strokeStyle = this.color;\n ctx.lineWidth = 1.5;\n drawSnowflake(ctx, this.x, this.y, this.size, this.rotation);\n break;\n\n case 'bubble':\n drawBubble(ctx, this.x, this.y, this.size);\n break;\n\n case 'cross':\n ctx.shadowBlur = 18; // Strong glow for fairy dust\n ctx.shadowColor = this.color;\n drawCross(ctx, this.x, this.y, this.size);\n break;\n\n case 'oval':\n ctx.shadowBlur = 12; // Moderate glow for CRT phosphor\n ctx.shadowColor = this.color;\n drawOval(ctx, this.x, this.y, this.size * 2, this.size);\n break;\n\n default: // star\n drawStar(ctx, this.x, this.y, this.size, 5);\n break;\n }\n\n ctx.restore();\n }\n}\n","// Image loader for bubble assets\nexport class ImageLoader {\n private static images: Map<string, HTMLImageElement> = new Map();\n private static loading: Map<string, Promise<HTMLImageElement>> = new Map();\n\n static async loadImage(src: string): Promise<HTMLImageElement> {\n // Return cached image if already loaded\n if (this.images.has(src)) {\n return this.images.get(src)!;\n }\n\n // Return existing promise if currently loading\n if (this.loading.has(src)) {\n return this.loading.get(src)!;\n }\n\n // Create new loading promise\n const loadPromise = new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n this.images.set(src, img);\n this.loading.delete(src);\n resolve(img);\n };\n img.onerror = () => {\n this.loading.delete(src);\n reject(new Error(`Failed to load image: ${src}`));\n };\n img.src = src;\n });\n\n this.loading.set(src, loadPromise);\n return loadPromise;\n }\n\n static async loadBubbles(basePath: string = '/bubbles'): Promise<HTMLImageElement[]> {\n const bubblePaths = [\n `${basePath}/soap_bubbles_1.png`,\n `${basePath}/soap_bubble_2.png`,\n `${basePath}/soap_bubble_3.png`,\n ];\n\n try {\n return await Promise.all(bubblePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some bubble images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static async loadSnowflakes(basePath: string = '/snowflakes'): Promise<HTMLImageElement[]> {\n const snowflakePaths = [\n // `${basePath}/snowflake.png`,\n `${basePath}/snow_flake_1.png`,\n `${basePath}/snow_flake_2.png`,\n ];\n\n try {\n return await Promise.all(snowflakePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some snowflake images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static getRandomBubble(): HTMLImageElement | null {\n const bubbleImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('bubble'))\n .map(([, img]) => img);\n if (bubbleImages.length === 0) return null;\n return bubbleImages[Math.floor(Math.random() * bubbleImages.length)];\n }\n\n static getRandomSnowflake(): HTMLImageElement | null {\n const snowflakeImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('snow'))\n .map(([, img]) => img);\n if (snowflakeImages.length === 0) return null;\n return snowflakeImages[Math.floor(Math.random() * snowflakeImages.length)];\n }\n\n static isLoaded(): boolean {\n return this.images.size > 0;\n }\n\n static clear(): void {\n this.images.clear();\n this.loading.clear();\n }\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FFC700', // Golden Yellow\n '#FFB700', // Amber\n '#FFED4E', // Light Gold\n '#F4E04D', // Pale Gold\n];\n\nexport function createFairyDustEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 2,\n particleSize = 6, // Increased from 4 for better visibility\n gravity = -0.05, // Slight upward float for magical feel\n maxLife = 40,\n velocity = 3,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 15,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity - 1, // Slight upward bias\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n shape: 'cross',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FF69B4', // Hot Pink\n '#00CED1', // Dark Turquoise\n '#9370DB', // Medium Purple\n];\n\nexport function createSparkleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Reduced for better performance\n particleSize = 6, // Increased from 3 for better visibility\n gravity = 0.1,\n maxLife = 20, // Further reduced for faster cleanup\n velocity = 4,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10,\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 10, // Reduced random variation\n gravity,\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FF6B6B', // Red\n '#4ECDC4', // Turquoise\n '#FFE66D', // Yellow\n '#95E1D3', // Mint\n '#F38181', // Pink\n '#AA96DA', // Purple\n '#FCBAD3', // Light Pink\n '#A8D8EA', // Sky Blue\n];\n\nexport function createConfettiEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4,\n gravity = 0.3, // Stronger gravity for falling effect\n maxLife = 60, // Longer lifetime for confetti\n velocity = 6,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 20,\n y: y + (Math.random() - 0.5) * 20,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 1) * velocity * 0.5, // Bias upward initially\n size: Math.random() * particleSize + 3,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.2, // Rotation speed\n shape: 'rectangle',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#00FF00', // Classic phosphor green\n '#33FF33', // Bright phosphor green\n '#00CC00', // Medium phosphor green\n '#00DD00', // Light phosphor green\n];\n\nexport function createRetroCRTEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4, // Slightly larger for better visibility\n gravity = 0, // No gravity - phosphor glows in place\n maxLife = 60, // Longer persistence like real phosphor\n velocity = 1, // Very slow movement for authentic glow\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 8,\n y: y + (Math.random() - 0.5) * 8,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 2,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 15,\n gravity,\n shape: 'circle', // Back to circles with strong glow\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFFFFF', // Pure white\n '#F0F8FF', // Alice blue\n '#E6F3FF', // Light blue white\n '#F5F5F5', // White smoke\n];\n\n// ⚙️ CONFIGURATION FLAG: Switch between image-based and canvas-drawn snowflakes\nconst USE_SNOWFLAKE_IMAGES = true; // Set to true to use PNG images, false for canvas drawing\n\nexport function createSnowEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // One snowflake at a time\n particleSize = 7, // Bigger for better visibility\n gravity = 0.12, // Faster falling\n maxLife = 150, // Shorter lifetime for faster fall\n velocity = 0.4, // Slightly more drift\n throttle = 120, // Spawn every 120ms - less frequent\n minMoveDistance = 12, // Only spawn when cursor moves 12px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n // Conditionally get snowflake image based on flag\n const snowflakeImage = USE_SNOWFLAKE_IMAGES ? ImageLoader.getRandomSnowflake() : null;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 30,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: Math.random() * 0.2 + 0.1, // Slightly faster downward initial velocity\n size: Math.random() * particleSize + 3, // Variable sizes (3-10px for canvas, base for images)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.03, // More visible rotation\n shape: 'snowflake',\n windDrift: 0.8, // Gentle wind drift/sway\n image: snowflakeImage || undefined, // Use image if flag is true and images loaded\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n 'rgba(173, 216, 230, 0.4)', // Light blue - transparent\n 'rgba(135, 206, 235, 0.4)', // Sky blue - transparent\n 'rgba(176, 224, 230, 0.4)', // Powder blue - transparent\n 'rgba(175, 238, 238, 0.4)', // Pale turquoise - transparent\n 'rgba(224, 255, 255, 0.4)', // Light cyan - transparent\n];\n\nexport function createBubbleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Spawn one bubble at a time\n gravity = -0.02, // Gentle upward buoyancy\n maxLife = 180, // Longer lifetime for slow rise\n velocity = 0.2, // Minimal base horizontal drift\n throttle = 150, // Spawn every 150ms - much less frequent\n minMoveDistance = 15, // Only spawn when cursor moves 15px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n const bubbleImage = ImageLoader.getRandomBubble();\n\n // Create more dramatic size variation (15-45 range for 2.5x multiplier = 37-112px actual)\n const baseSize = 15 + Math.random() * 30;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10, // Spawn closer to pointer\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: -Math.random() * 0.15 - 0.1, // Very slow, consistent upward\n size: baseSize, // Wide size variation (15-45)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n shape: 'bubble',\n wobbleAmplitude: 0.3, // Gentle horizontal wobble\n wobbleSpeed: 0.05, // Slow wobble oscillation\n image: bubbleImage || undefined, // Use image if loaded, fallback to canvas\n initialScale: 0.3, // Start at 30% size for pop-up effect\n scaleUpDuration: 15, // Grow to full size over 15 frames (~250ms)\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { CursorFXEngine, createFairyDustEffect, createSparkleEffect, createConfettiEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect, ImageLoader } from '../core';\n\n// Re-export ImageLoader for CDN and vanilla users\nexport { ImageLoader };\n\nexport type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';\n\nexport interface InitCursorFXOptions {\n effect?: CursorEffectType;\n colors?: string[];\n particleCount?: number;\n particleSize?: number;\n gravity?: number;\n maxLife?: number;\n velocity?: number;\n}\n\nexport interface CursorFXInstance {\n destroy: () => void;\n}\n\n/**\n * Initialize cursor effects with a single function call.\n * Creates canvas, appends to body, and starts the fairy dust effect.\n *\n * @param options - Configuration options for the effect\n * @returns Instance with destroy() method for cleanup\n *\n * @example\n * ```ts\n * const fx = initCursorFX({\n * colors: ['#FFD700', '#FF69B4'],\n * particleCount: 5\n * });\n *\n * // Later, to cleanup:\n * fx.destroy();\n * ```\n */\nexport function initCursorFX(options: InitCursorFXOptions = {}): CursorFXInstance {\n // Check for prefers-reduced-motion\n if (typeof window !== 'undefined') {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n // Return no-op instance if user prefers reduced motion\n return { destroy: () => {} };\n }\n }\n\n // Create engine (automatically creates and appends canvas with fixed positioning)\n const engine = new CursorFXEngine();\n\n // Extract effect type from options\n const { effect = 'fairyDust', ...effectOptions } = options;\n\n // Select effect based on type\n // Each effect will use its own defaults unless overridden in effectOptions\n const selectedEffect =\n effect === 'confetti'\n ? createConfettiEffect(effectOptions)\n : effect === 'sparkle'\n ? createSparkleEffect(effectOptions)\n : effect === 'retroCRT'\n ? createRetroCRTEffect(effectOptions)\n : effect === 'snow'\n ? createSnowEffect(effectOptions)\n : effect === 'bubble'\n ? createBubbleEffect(effectOptions)\n : createFairyDustEffect(effectOptions);\n\n // Start the engine with the effect\n engine.start(selectedEffect);\n\n return {\n destroy: () => engine.destroy(),\n };\n}\n\n// Export types for TypeScript users\nexport type { EffectOptions } from '../core/types';\n"]}
@@ -1,4 +1,5 @@
1
1
  import { CursorFXEngine, createConfettiEffect, createSparkleEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect, createFairyDustEffect } from '../chunk-5ZV2U5LA.mjs';
2
+ export { ImageLoader } from '../chunk-5ZV2U5LA.mjs';
2
3
 
3
4
  // src/vanilla/index.ts
4
5
  function initCursorFX(options = {}) {
@@ -11,12 +12,7 @@ function initCursorFX(options = {}) {
11
12
  }
12
13
  const engine = new CursorFXEngine();
13
14
  const { effect = "fairyDust", ...effectOptions } = options;
14
- const optimizedOptions = {
15
- particleCount: 2,
16
- // Reduced from default 3
17
- ...effectOptions
18
- };
19
- const selectedEffect = effect === "confetti" ? createConfettiEffect(optimizedOptions) : effect === "sparkle" ? createSparkleEffect(optimizedOptions) : effect === "retroCRT" ? createRetroCRTEffect(optimizedOptions) : effect === "snow" ? createSnowEffect(optimizedOptions) : effect === "bubble" ? createBubbleEffect(optimizedOptions) : createFairyDustEffect(optimizedOptions);
15
+ const selectedEffect = effect === "confetti" ? createConfettiEffect(effectOptions) : effect === "sparkle" ? createSparkleEffect(effectOptions) : effect === "retroCRT" ? createRetroCRTEffect(effectOptions) : effect === "snow" ? createSnowEffect(effectOptions) : effect === "bubble" ? createBubbleEffect(effectOptions) : createFairyDustEffect(effectOptions);
20
16
  engine.start(selectedEffect);
21
17
  return {
22
18
  destroy: () => engine.destroy()
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/vanilla/index.ts"],"names":[],"mappings":";;;AAoCO,SAAS,YAAA,CAAa,OAAA,GAA+B,EAAC,EAAqB;AAEhF,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,MAAM,oBAAA,GAAuB,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA;AACnF,IAAA,IAAI,oBAAA,EAAsB;AAExB,MAAA,OAAO,EAAE,SAAS,MAAM;AAAA,MAAC,CAAA,EAAE;AAAA,IAC7B;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAAS,IAAI,cAAA,EAAe;AAGlC,EAAA,MAAM,EAAE,MAAA,GAAS,WAAA,EAAa,GAAG,eAAc,GAAI,OAAA;AAGnD,EAAA,MAAM,gBAAA,GAAmB;AAAA,IACvB,aAAA,EAAe,CAAA;AAAA;AAAA,IACf,GAAG;AAAA,GACL;AAGA,EAAA,MAAM,cAAA,GACJ,MAAA,KAAW,UAAA,GACP,oBAAA,CAAqB,gBAAgB,CAAA,GACrC,MAAA,KAAW,SAAA,GACX,mBAAA,CAAoB,gBAAgB,CAAA,GACpC,MAAA,KAAW,UAAA,GACX,oBAAA,CAAqB,gBAAgB,CAAA,GACrC,MAAA,KAAW,MAAA,GACX,gBAAA,CAAiB,gBAAgB,CAAA,GACjC,MAAA,KAAW,QAAA,GACX,kBAAA,CAAmB,gBAAgB,CAAA,GACnC,qBAAA,CAAsB,gBAAgB,CAAA;AAG5C,EAAA,MAAA,CAAO,MAAM,cAAc,CAAA;AAE3B,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,MAAM,MAAA,CAAO,OAAA;AAAQ,GAChC;AACF","file":"index.mjs","sourcesContent":["import { CursorFXEngine, createFairyDustEffect, createSparkleEffect, createConfettiEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect } from '../core';\n\nexport type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';\n\nexport interface InitCursorFXOptions {\n effect?: CursorEffectType;\n colors?: string[];\n particleCount?: number;\n particleSize?: number;\n gravity?: number;\n maxLife?: number;\n velocity?: number;\n}\n\nexport interface CursorFXInstance {\n destroy: () => void;\n}\n\n/**\n * Initialize cursor effects with a single function call.\n * Creates canvas, appends to body, and starts the fairy dust effect.\n *\n * @param options - Configuration options for the effect\n * @returns Instance with destroy() method for cleanup\n *\n * @example\n * ```ts\n * const fx = initCursorFX({\n * colors: ['#FFD700', '#FF69B4'],\n * particleCount: 5\n * });\n *\n * // Later, to cleanup:\n * fx.destroy();\n * ```\n */\nexport function initCursorFX(options: InitCursorFXOptions = {}): CursorFXInstance {\n // Check for prefers-reduced-motion\n if (typeof window !== 'undefined') {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n // Return no-op instance if user prefers reduced motion\n return { destroy: () => {} };\n }\n }\n\n // Create engine (automatically creates and appends canvas with fixed positioning)\n const engine = new CursorFXEngine();\n\n // Extract effect type from options\n const { effect = 'fairyDust', ...effectOptions } = options;\n\n // Reduce particle count for better performance\n const optimizedOptions = {\n particleCount: 2, // Reduced from default 3\n ...effectOptions,\n };\n\n // Select effect based on type\n const selectedEffect =\n effect === 'confetti'\n ? createConfettiEffect(optimizedOptions)\n : effect === 'sparkle'\n ? createSparkleEffect(optimizedOptions)\n : effect === 'retroCRT'\n ? createRetroCRTEffect(optimizedOptions)\n : effect === 'snow'\n ? createSnowEffect(optimizedOptions)\n : effect === 'bubble'\n ? createBubbleEffect(optimizedOptions)\n : createFairyDustEffect(optimizedOptions);\n\n // Start the engine with the effect\n engine.start(selectedEffect);\n\n return {\n destroy: () => engine.destroy(),\n };\n}\n\n// Export types for TypeScript users\nexport type { EffectOptions } from '../core/types';\n"]}
1
+ {"version":3,"sources":["../../src/vanilla/index.ts"],"names":[],"mappings":";;;;AAuCO,SAAS,YAAA,CAAa,OAAA,GAA+B,EAAC,EAAqB;AAEhF,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,MAAM,oBAAA,GAAuB,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA;AACnF,IAAA,IAAI,oBAAA,EAAsB;AAExB,MAAA,OAAO,EAAE,SAAS,MAAM;AAAA,MAAC,CAAA,EAAE;AAAA,IAC7B;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAAS,IAAI,cAAA,EAAe;AAGlC,EAAA,MAAM,EAAE,MAAA,GAAS,WAAA,EAAa,GAAG,eAAc,GAAI,OAAA;AAInD,EAAA,MAAM,cAAA,GACJ,MAAA,KAAW,UAAA,GACP,oBAAA,CAAqB,aAAa,CAAA,GAClC,MAAA,KAAW,SAAA,GACX,mBAAA,CAAoB,aAAa,CAAA,GACjC,MAAA,KAAW,UAAA,GACX,oBAAA,CAAqB,aAAa,CAAA,GAClC,MAAA,KAAW,MAAA,GACX,gBAAA,CAAiB,aAAa,CAAA,GAC9B,MAAA,KAAW,QAAA,GACX,kBAAA,CAAmB,aAAa,CAAA,GAChC,qBAAA,CAAsB,aAAa,CAAA;AAGzC,EAAA,MAAA,CAAO,MAAM,cAAc,CAAA;AAE3B,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,MAAM,MAAA,CAAO,OAAA;AAAQ,GAChC;AACF","file":"index.mjs","sourcesContent":["import { CursorFXEngine, createFairyDustEffect, createSparkleEffect, createConfettiEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect, ImageLoader } from '../core';\n\n// Re-export ImageLoader for CDN and vanilla users\nexport { ImageLoader };\n\nexport type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';\n\nexport interface InitCursorFXOptions {\n effect?: CursorEffectType;\n colors?: string[];\n particleCount?: number;\n particleSize?: number;\n gravity?: number;\n maxLife?: number;\n velocity?: number;\n}\n\nexport interface CursorFXInstance {\n destroy: () => void;\n}\n\n/**\n * Initialize cursor effects with a single function call.\n * Creates canvas, appends to body, and starts the fairy dust effect.\n *\n * @param options - Configuration options for the effect\n * @returns Instance with destroy() method for cleanup\n *\n * @example\n * ```ts\n * const fx = initCursorFX({\n * colors: ['#FFD700', '#FF69B4'],\n * particleCount: 5\n * });\n *\n * // Later, to cleanup:\n * fx.destroy();\n * ```\n */\nexport function initCursorFX(options: InitCursorFXOptions = {}): CursorFXInstance {\n // Check for prefers-reduced-motion\n if (typeof window !== 'undefined') {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n // Return no-op instance if user prefers reduced motion\n return { destroy: () => {} };\n }\n }\n\n // Create engine (automatically creates and appends canvas with fixed positioning)\n const engine = new CursorFXEngine();\n\n // Extract effect type from options\n const { effect = 'fairyDust', ...effectOptions } = options;\n\n // Select effect based on type\n // Each effect will use its own defaults unless overridden in effectOptions\n const selectedEffect =\n effect === 'confetti'\n ? createConfettiEffect(effectOptions)\n : effect === 'sparkle'\n ? createSparkleEffect(effectOptions)\n : effect === 'retroCRT'\n ? createRetroCRTEffect(effectOptions)\n : effect === 'snow'\n ? createSnowEffect(effectOptions)\n : effect === 'bubble'\n ? createBubbleEffect(effectOptions)\n : createFairyDustEffect(effectOptions);\n\n // Start the engine with the effect\n engine.start(selectedEffect);\n\n return {\n destroy: () => engine.destroy(),\n };\n}\n\n// Export types for TypeScript users\nexport type { EffectOptions } from '../core/types';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursor-fx",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Beautiful, customizable cursor effects for React and vanilla JavaScript. Add magical fairy dust particles that follow your cursor with minimal setup.",
5
5
  "author": "Anto Pravin C <antopravin.dev@gmail.com>",
6
6
  "license": "MIT",