@kayelaa/canvas 0.1.14 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -868,11 +868,18 @@ declare class Vector2 {
868
868
  * @returns {Vector2}
869
869
  */
870
870
  static from(rad: number): Vector2;
871
+ isEmpty(): boolean;
871
872
  /**
872
873
  * Returns the angle of the vector relative to the positive X-axis in radians
873
874
  * @returns {number}
874
875
  */
875
876
  get angle(): number;
877
+ /**
878
+ * Returns angle from this vector to vec in radians
879
+ * @param {Vector2} vec
880
+ * @returns {number}
881
+ */
882
+ angleTo(vec: Vector2): number;
876
883
  /**
877
884
  * Returns the length (magnitude) of the vector
878
885
  * @returns {number}
@@ -888,6 +895,7 @@ declare class Vector2 {
888
895
  * @returns {Vector2}
889
896
  */
890
897
  normalized(): Vector2;
898
+ consume(size: number): void;
891
899
  project(other: Vector2): Vector2;
892
900
  /**
893
901
  * Reflects a normalized vector (length = 1)
@@ -1479,4 +1487,4 @@ declare namespace LEA {
1479
1487
  export { type LEA_DefaultWSE as DefaultWSE, LEA_DeltaTweenII as DeltaTweenII, LEA_ENVIRONMENT as ENVIRONMENT, LEA_GEmitterMemory as GEmitterMemory, LEA_LeaEntityII as LeaEntityII, type LEA_LeaEntitySerializer as LeaEntitySerializer, type LEA_LeaEntitySerializerArray as LeaEntitySerializerArray, type LEA_LeaEntitySerializerEach as LeaEntitySerializerEach, LEA_LeaEventEmitter as LeaEventEmitter, LEA_LeaGameII as LeaGameII, LEA_LeaRendererII as LeaRendererII, LEA_LeaSceneII as LeaSceneII, LEA_LeaSerializers as LeaSerializers, LEA_LeaTickerII as LeaTickerII, LEA_LeaTimeout as LeaTimeout, LEA_LeaUtilsII as LeaUtilsII, LEA_LiaAudio as LiaAudio, LEA_LiaAudioSrc as LiaAudioSrc, LEA_LiaOscSFX as LiaOscSFX, LEA_LiaSFXMap as LiaSFXMap, type LEA_Listener as Listener, type LEA_NOTE_NAME as NOTE_NAME, LEA_NOTE_NAMES as NOTE_NAMES, type LEA_OrderedLeaEntitySerializer as OrderedLeaEntitySerializer, type LEA_RayHit as RayHit, type LEA_RaycastResult as RaycastResult, LEA_RectLeaEntity as RectLeaEntity, type LEA_SFXConfig as SFXConfig, type LEA_Side as Side, LEA_Vector2 as Vector2, LEA_colToRGBA as colToRGBA, LEA_defaultSFXConfig as defaultSFXConfig, LEA_editRGBA as editRGBA, LEA_generateUUID as generateUUID, LEA_getAvoidAngle as getAvoidAngle, LEA_getEnvironment as getEnvironment, LEA_getNormalizedColor as getNormalizedColor, LEA_getRayHit as getRayHit, LEA_isInitiallyMobile as isInitiallyMobile, LEA_isMobile as isMobile, LEA_isNode as isNode, LEA_isNote as isNote, LEA_isWeb as isWeb, LEA_parseFillStyle as parseFillStyle, LEA_raycastAvoid as raycastAvoid, LEA_scaleCoord as scaleCoord, LEA_setAnimInterval as setAnimInterval, LEA_sfxHit as sfxHit, LEA_sfxJump as sfxJump, LEA_sfxLaser as sfxLaser, LEA_sfxUIClick as sfxUIClick, LEA_sfxUIHover as sfxUIHover, LEA_shortUID as shortUID, LEA_tinyUID as tinyUID };
1480
1488
  }
1481
1489
 
1482
- export { shortUID as $, getAvoidAngle as A, getEnvironment as B, getNormalizedColor as C, type DefaultWSE as D, ENVIRONMENT as E, getRayHit as F, GEmitterMemory as G, isInitiallyMobile as H, isMobile as I, isNode as J, isNote as K, LEA as L, isWeb as M, type NOTE_NAME as N, type OrderedLeaEntitySerializer as O, parseFillStyle as P, raycastAvoid as Q, RectLeaEntity as R, type SFXConfig as S, scaleCoord as T, setAnimInterval as U, Vector2 as V, sfxHit as W, sfxJump as X, sfxLaser as Y, sfxUIClick as Z, sfxUIHover as _, LeaGameII as a, tinyUID as a0, LeaRendererII as b, LeaSceneII as c, DeltaTweenII as d, LeaEntityII as e, type LeaEntitySerializer as f, type LeaEntitySerializerArray as g, type LeaEntitySerializerEach as h, LeaEventEmitter as i, LeaSerializers as j, LeaTickerII as k, LeaTimeout as l, LeaUtilsII as m, LiaAudio as n, LiaAudioSrc as o, LiaOscSFX as p, LiaSFXMap as q, type Listener as r, NOTE_NAMES as s, type RayHit as t, type RaycastResult as u, type Side as v, colToRGBA as w, defaultSFXConfig as x, editRGBA as y, generateUUID as z };
1490
+ export { shortUID as $, getAvoidAngle as A, getEnvironment as B, getNormalizedColor as C, type DefaultWSE as D, ENVIRONMENT as E, getRayHit as F, GEmitterMemory as G, isInitiallyMobile as H, isMobile as I, isNode as J, isNote as K, LEA as L, isWeb as M, type NOTE_NAME as N, type OrderedLeaEntitySerializer as O, parseFillStyle as P, raycastAvoid as Q, RectLeaEntity as R, type SFXConfig as S, scaleCoord as T, setAnimInterval as U, Vector2 as V, sfxHit as W, sfxJump as X, sfxLaser as Y, sfxUIClick as Z, sfxUIHover as _, LeaGameII as a, tinyUID as a0, LeaTimeout as b, LeaRendererII as c, LeaEventEmitter as d, LeaTickerII as e, LeaSceneII as f, DeltaTweenII as g, LeaEntityII as h, type LeaEntitySerializer as i, type LeaEntitySerializerArray as j, type LeaEntitySerializerEach as k, LeaSerializers as l, LeaUtilsII as m, LiaAudio as n, LiaAudioSrc as o, LiaOscSFX as p, LiaSFXMap as q, type Listener as r, NOTE_NAMES as s, type RayHit as t, type RaycastResult as u, type Side as v, colToRGBA as w, defaultSFXConfig as x, editRGBA as y, generateUUID as z };
@@ -868,11 +868,18 @@ declare class Vector2 {
868
868
  * @returns {Vector2}
869
869
  */
870
870
  static from(rad: number): Vector2;
871
+ isEmpty(): boolean;
871
872
  /**
872
873
  * Returns the angle of the vector relative to the positive X-axis in radians
873
874
  * @returns {number}
874
875
  */
875
876
  get angle(): number;
877
+ /**
878
+ * Returns angle from this vector to vec in radians
879
+ * @param {Vector2} vec
880
+ * @returns {number}
881
+ */
882
+ angleTo(vec: Vector2): number;
876
883
  /**
877
884
  * Returns the length (magnitude) of the vector
878
885
  * @returns {number}
@@ -888,6 +895,7 @@ declare class Vector2 {
888
895
  * @returns {Vector2}
889
896
  */
890
897
  normalized(): Vector2;
898
+ consume(size: number): void;
891
899
  project(other: Vector2): Vector2;
892
900
  /**
893
901
  * Reflects a normalized vector (length = 1)
@@ -1479,4 +1487,4 @@ declare namespace LEA {
1479
1487
  export { type LEA_DefaultWSE as DefaultWSE, LEA_DeltaTweenII as DeltaTweenII, LEA_ENVIRONMENT as ENVIRONMENT, LEA_GEmitterMemory as GEmitterMemory, LEA_LeaEntityII as LeaEntityII, type LEA_LeaEntitySerializer as LeaEntitySerializer, type LEA_LeaEntitySerializerArray as LeaEntitySerializerArray, type LEA_LeaEntitySerializerEach as LeaEntitySerializerEach, LEA_LeaEventEmitter as LeaEventEmitter, LEA_LeaGameII as LeaGameII, LEA_LeaRendererII as LeaRendererII, LEA_LeaSceneII as LeaSceneII, LEA_LeaSerializers as LeaSerializers, LEA_LeaTickerII as LeaTickerII, LEA_LeaTimeout as LeaTimeout, LEA_LeaUtilsII as LeaUtilsII, LEA_LiaAudio as LiaAudio, LEA_LiaAudioSrc as LiaAudioSrc, LEA_LiaOscSFX as LiaOscSFX, LEA_LiaSFXMap as LiaSFXMap, type LEA_Listener as Listener, type LEA_NOTE_NAME as NOTE_NAME, LEA_NOTE_NAMES as NOTE_NAMES, type LEA_OrderedLeaEntitySerializer as OrderedLeaEntitySerializer, type LEA_RayHit as RayHit, type LEA_RaycastResult as RaycastResult, LEA_RectLeaEntity as RectLeaEntity, type LEA_SFXConfig as SFXConfig, type LEA_Side as Side, LEA_Vector2 as Vector2, LEA_colToRGBA as colToRGBA, LEA_defaultSFXConfig as defaultSFXConfig, LEA_editRGBA as editRGBA, LEA_generateUUID as generateUUID, LEA_getAvoidAngle as getAvoidAngle, LEA_getEnvironment as getEnvironment, LEA_getNormalizedColor as getNormalizedColor, LEA_getRayHit as getRayHit, LEA_isInitiallyMobile as isInitiallyMobile, LEA_isMobile as isMobile, LEA_isNode as isNode, LEA_isNote as isNote, LEA_isWeb as isWeb, LEA_parseFillStyle as parseFillStyle, LEA_raycastAvoid as raycastAvoid, LEA_scaleCoord as scaleCoord, LEA_setAnimInterval as setAnimInterval, LEA_sfxHit as sfxHit, LEA_sfxJump as sfxJump, LEA_sfxLaser as sfxLaser, LEA_sfxUIClick as sfxUIClick, LEA_sfxUIHover as sfxUIHover, LEA_shortUID as shortUID, LEA_tinyUID as tinyUID };
1480
1488
  }
1481
1489
 
1482
- export { shortUID as $, getAvoidAngle as A, getEnvironment as B, getNormalizedColor as C, type DefaultWSE as D, ENVIRONMENT as E, getRayHit as F, GEmitterMemory as G, isInitiallyMobile as H, isMobile as I, isNode as J, isNote as K, LEA as L, isWeb as M, type NOTE_NAME as N, type OrderedLeaEntitySerializer as O, parseFillStyle as P, raycastAvoid as Q, RectLeaEntity as R, type SFXConfig as S, scaleCoord as T, setAnimInterval as U, Vector2 as V, sfxHit as W, sfxJump as X, sfxLaser as Y, sfxUIClick as Z, sfxUIHover as _, LeaGameII as a, tinyUID as a0, LeaRendererII as b, LeaSceneII as c, DeltaTweenII as d, LeaEntityII as e, type LeaEntitySerializer as f, type LeaEntitySerializerArray as g, type LeaEntitySerializerEach as h, LeaEventEmitter as i, LeaSerializers as j, LeaTickerII as k, LeaTimeout as l, LeaUtilsII as m, LiaAudio as n, LiaAudioSrc as o, LiaOscSFX as p, LiaSFXMap as q, type Listener as r, NOTE_NAMES as s, type RayHit as t, type RaycastResult as u, type Side as v, colToRGBA as w, defaultSFXConfig as x, editRGBA as y, generateUUID as z };
1490
+ export { shortUID as $, getAvoidAngle as A, getEnvironment as B, getNormalizedColor as C, type DefaultWSE as D, ENVIRONMENT as E, getRayHit as F, GEmitterMemory as G, isInitiallyMobile as H, isMobile as I, isNode as J, isNote as K, LEA as L, isWeb as M, type NOTE_NAME as N, type OrderedLeaEntitySerializer as O, parseFillStyle as P, raycastAvoid as Q, RectLeaEntity as R, type SFXConfig as S, scaleCoord as T, setAnimInterval as U, Vector2 as V, sfxHit as W, sfxJump as X, sfxLaser as Y, sfxUIClick as Z, sfxUIHover as _, LeaGameII as a, tinyUID as a0, LeaTimeout as b, LeaRendererII as c, LeaEventEmitter as d, LeaTickerII as e, LeaSceneII as f, DeltaTweenII as g, LeaEntityII as h, type LeaEntitySerializer as i, type LeaEntitySerializerArray as j, type LeaEntitySerializerEach as k, LeaSerializers as l, LeaUtilsII as m, LiaAudio as n, LiaAudioSrc as o, LiaOscSFX as p, LiaSFXMap as q, type Listener as r, NOTE_NAMES as s, type RayHit as t, type RaycastResult as u, type Side as v, colToRGBA as w, defaultSFXConfig as x, editRGBA as y, generateUUID as z };
package/dist/lea.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var R=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var ne=Object.prototype.hasOwnProperty;var re=(n,e)=>{for(var t in e)R(n,t,{get:e[t],enumerable:!0})},ie=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of te(e))!ne.call(n,i)&&i!==t&&R(n,i,{get:()=>e[i],enumerable:!(r=ee(e,i))||r.enumerable});return n};var se=n=>ie(R({},"__esModule",{value:!0}),n);var be={};re(be,{DeltaTweenII:()=>_,ENVIRONMENT:()=>N,GEmitterMemory:()=>L,LeaEntityII:()=>E,LeaEventEmitter:()=>y,LeaGameII:()=>V,LeaRendererII:()=>F,LeaSceneII:()=>P,LeaSerializers:()=>G,LeaTickerII:()=>I,LeaTimeout:()=>A,LeaUtilsII:()=>f,LiaAudio:()=>T,LiaAudioSrc:()=>w,LiaOscSFX:()=>x,LiaSFXMap:()=>le,NOTE_NAMES:()=>D,RectLeaEntity:()=>K,Vector2:()=>C,colToRGBA:()=>oe,defaultSFXConfig:()=>X,editRGBA:()=>ue,generateUUID:()=>j,getAvoidAngle:()=>Y,getEnvironment:()=>q,getNormalizedColor:()=>ae,getRayHit:()=>J,isInitiallyMobile:()=>fe,isMobile:()=>Z,isNode:()=>k,isNote:()=>he,isWeb:()=>b,parseFillStyle:()=>O,raycastAvoid:()=>pe,scaleCoord:()=>ce,setAnimInterval:()=>Q,sfxHit:()=>W,sfxJump:()=>H,sfxLaser:()=>$,sfxUIClick:()=>B,sfxUIHover:()=>U,shortUID:()=>me,tinyUID:()=>de});module.exports=se(be);var y=class{#e=new Map;constructor(){this.#e=new Map}on(e,t){let r=this.#e.get(e)||[];return r.push(t),this.#e.set(e,r),this}once(e,t){let r=(...i)=>{this.off(e,r),t(...i)};return this.on(e,r),this}off(e,t){let r=this.#e.get(e);if(!r)return this;let i=r.indexOf(t);return i>=0&&r.splice(i,1),this}emit(e,...t){let r=this.#e.get(e);if(!r||r.length===0){if(e==="error")throw t[0];return!1}return r.slice().forEach(i=>i(...t)),!0}removeAllListeners(e){return e?this.#e.delete(e):this.#e.clear(),this}listenerCount(e){return this.#e.get(e)?.length??0}},F=class extends y{canvas;ctx;running;_rafId;_fps;_frameCount;_fpsTimer;_lastFrameTime;constructor(e,{viewportWidth:t,viewportHeight:r,cameraWidth:i,cameraHeight:a}={}){if(!b)throw new Error("Web-Only");super(),this.canvas=e,this.ctx=e.getContext("2d"),this.automatic=!0,this.#e=t??e.width,this.#t=r??e.height,this.#n=i??e.width,this.#r=a??e.height,this.running=!1,this._rafId=null,this._loop=this._loop.bind(this),this.updateCanvasResolution(),this._fps=60,this._frameCount=0,this._fpsTimer=0}automatic;retransform(){this.ctx.setTransform(1,0,0,1,0,0);let e=this.#n/this.#e,t=this.#r/this.#t;this.ctx.translate(this.#n/2,this.#r/2),this.ctx.scale(e,t),this.ctx.translate(-this.#e/2,-this.#t/2)}#e=0;#t=0;#n=0;#r=0;get viewportWidth(){return this.#e}set viewportWidth(e){this.#e=e,this.retransform()}get width(){return this.#e}get height(){return this.#t}get centerX(){return this.#e/2}get centerY(){return this.#t/2}get left(){return 0}get top(){return 0}get right(){return this.#e}get bottom(){return this.#t}get viewportHeight(){return this.#t}set viewportHeight(e){this.#t=e,this.retransform()}get cameraWidth(){return this.#n}set cameraWidth(e){this.#n=e,this.updateCanvasResolution(),this.retransform()}get cameraHeight(){return this.#r}set cameraHeight(e){this.#r=e,this.updateCanvasResolution(),this.retransform()}updateCanvasResolution(){this.canvas.width=this.#n,this.canvas.height=this.#r}applyTransform(){this.retransform()}get FPS(){return this._fps}_loop(){this.automatic&&this.update(),this._rafId=requestAnimationFrame(this._loop)}update(){if(!this.running||!b)return;let e=performance.now(),t=(e-(this._lastFrameTime??e))/1e3;this._lastFrameTime=e,this._frameCount++,this._fpsTimer+=t,this._fpsTimer>=1&&(this._fps=Math.round(this._frameCount/this._fpsTimer),this._frameCount=0,this._fpsTimer=0),this.ctx.clearRect(0,0,this.#n,this.#r),this.emit("draw",this.ctx)}start(){if(!this.running){if(!b||typeof globalThis.requestAnimationFrame>"u")throw new Error("Raf is not supported");this.running=!0,this._rafId=requestAnimationFrame(this._loop)}}stop(){if(!b||typeof globalThis.requestAnimationFrame>"u")throw new Error("Raf is not supported");this.running=!1,this._rafId!==null&&(cancelAnimationFrame(this._rafId),this._rafId=null)}},I=class extends y{setNow(e){this.#e=e}#e=0;__intervalId=null;__lastTime=0;constructor(e=16){super(),this.#t=e,this.speedHackDT=1}speedHackDT;get isRaf(){return this.tickInterval===1/0}#t=15;get tickInterval(){return this.#t}set tickInterval(e){this.#t=e,this.__intervalId&&(this.stop(),this.start())}now(){return this.#e}__tick(){let e=performance.now(),t=(e-this.__lastTime)/1e3*this.speedHackDT;this.__lastTime=e,this.#e+=t*1e3,this.emit("tick",t)}createTimeout(e){return new A(e,this)}createTween(e,t=()=>{}){let r=new _(e),i=(a=0)=>{if(r.finished){this.off("tick",i);return}r.update(a)};return r.on("finish",()=>{this.off("tick",i)}),r.on("delta",a=>{t(a)}),this.on("tick",i),r}start(){this.__intervalId===null&&(this.__lastTime=performance.now(),this.__intervalId=b&&!isFinite(this.tickInterval)?Q(()=>this.__tick()).clear:setInterval(()=>this.__tick(),this.tickInterval))}stop(){this.__intervalId!==null&&(typeof this.__intervalId=="function"?this.__intervalId():clearInterval(this.__intervalId)),this.__intervalId=null}getSineMod(e,t=0){return .5+.5*Math.sin((this.now()%e/e+t)*2*Math.PI)}},G;(M=>{function n(h){return h===!0?1:0}M.booleanExport=n;function e(h){return h===0?!1:h===1}M.booleanImport=e;function t(h){return`${h.x}|${h.y}`}M.vec2Export=t;function r(h){let[d,g]=h.split("|"),v=parseFloat(d),S=parseFloat(g);if(isNaN(v)||isNaN(S))throw new Error(`Invalid Vector2 string: ${h}`);return new C(v,S)}M.vec2Import=r,M.booleanMap={mapExport:n,mapImport:e};function a(h){return d=>Number(d.toFixed(h))}M.createRounder=a;function u(h=10){return{mapExport(d){return Math.round(d/h)},mapImport(d){return d*h}}}M.createLowPrecision=u;function c(h){return Math.round(h)}M.lightWeightRounder=c;function s(h=100){return{mapExport(d){return Math.round(d*h)},mapImport(d){return d/h}}}M.createPercent=s;function o(h){let d=new Map(Object.entries(h));return{mapExport:g=>d.get(g)??null,mapImport:g=>Array.from(d.entries()).find(([v,S])=>S===g)?.[0]??null}}M.createLookup=o;function l(h){let d=h*(180/Math.PI);return Math.round((d%360+360)%360)}M.radToDeg=l;function m(h){return h*(Math.PI/180)}M.degToRad=m,M.angleRadToDeg={mapExport:l,mapImport:m};function z(h=10){let d=u(h);return{mapExport(g){return d.mapExport(l(g))},mapImport(g){return d.mapImport(m(g))}}}M.createLowPrecisionRadToDeg=z})(G||={});var E=class n extends y{name="";scaleRotate=0;scale=1;constructor(e,t=0,r=0){super(),this.autoTranslate=!1,this.name=e,this.z=0,this.___pos=new C(t,r),this.nonSerializableProperties=[],this.nonSerializableProperties.push("___pos","autoTranslate","arraySerializeMap"),this.forceSerializableProperties=[],this.forceSerializableProperties.push("x","y")}arraySerializeMap;autoTranslate;z;___pos;nonSerializableProperties;forceSerializableProperties;get pos(){return this.___pos}get x(){return this.pos.x}get y(){return this.pos.y}set x(e){this.pos.x=e}set y(e){this.pos.y=e}handleUpdate(e){if(this.update)try{this.emit("update",e),this.update(e)}catch(t){this.emit("error",t)}}handleDraw(e){if(!(k||!this.draw)){e.save(),this.autoTranslate&&e.translate(this.x,this.y);try{this.emit("draw",e),this.draw(e)}catch(t){this.emit("error",t)}e.restore()}}serialize(){if(Array.isArray(this.arraySerializeMap))return this.arraySerializeMap.map(([i,{mapExport:a}])=>{let u=Reflect.get(this,i);return a?a(u):u});let e=["_events","_eventsCount","_maxListeners","nonSerializableProperties","forceSerializableProperties"],t=[...Reflect.ownKeys(this),...this.forceSerializableProperties].filter(i=>!this.nonSerializableProperties.includes(i)&&!e.includes(i.toString())),r=Object.fromEntries(t.map(i=>{let a=Reflect.get(this,i);if(k&&typeof a=="number"){let u=a.toString().split("."),s=(u[1]?u[1].length:0)>2?Number(a.toFixed(2)):a;return[i,s]}return[i,a]}));return JSON.parse(JSON.stringify(r))}toLocal(e){return e.subtract(this.pos)}toWorld(e){return e.add(this.pos)}deserializeArray(e){return n.deserializeArray(this.arraySerializeMap,e)}static deserializeArray(e,t){if(!e||!Array.isArray(t))return t;let r={};for(let i=0;i<t.length;i++){let a=e[i];if(!a)break;let[u,{mapImport:c}]=a,s=t[i];if(c&&(s=c(s)),typeof u!="string")break;try{Reflect.set(r,u,s)}catch(o){console.error(o)}}return r}},P=class extends y{name="";entities=new Map;paused=!0;constructor(e){super(),this.name=e}handleUpdate(e){if(!this.paused){this.emit("update",e);for(let t of this.entities.values())t.handleUpdate(e)}}handleDraw(e){if(!k&&!this.paused){this.emit("draw",e);for(let t of[...this.entities.values()].sort((r,i)=>r.z-i.z))t.handleDraw(e)}}addEntity(e){if(!(e instanceof E))throw new Error("invalid entity");if(!e.name)throw new Error("Entity must have a name.");this.entities.set(e.name,e)}removeEntity(e){if(!(e instanceof E))throw new Error("invalid entity");this.entities.delete(e.name)}getEntity(e){return this.entities.get(e)}},V=class{scenes;ticker;get centerX(){return this.width/2}get centerY(){return this.height/2}get left(){return 0}get top(){return 0}get right(){return this.width}get bottom(){return this.height}width;height;constructor(e,t,r=16){this.ticker=new I(r),this.scenes=new Map,this.width=e,this.height=t,this.ticker.on("tick",i=>{for(let a of this.scenes.values())a.paused||a.handleUpdate(i)})}addScene(e){if(!e.name)throw new Error("Scene must have a name.");e.paused=!1,this.scenes.set(e.name,e)}removeScene(e){e&&(e.paused=!0),this.scenes.delete(e.name)}now(){return this.ticker.now()}start(){this.ticker.start()}stop(){this.ticker.stop()}},f={lerp(n,e,t){return n+(e-n)*t},clamp(n,e,t){return Math.min(t,Math.max(e,n))},clamp01(n){return Math.min(1,Math.max(0,n))},easeLinear(n){return n},easeInQuad(n){return n*n},easeOutQuad(n){return 1-(1-n)*(1-n)},easeInOutQuad(n){return n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2},easeInSine(n){return 1-Math.cos(n*Math.PI/2)},easeOutSine(n){return Math.sin(n*Math.PI/2)},easeInOutSine(n){return-(Math.cos(Math.PI*n)-1)/2},easeInExpo(n){return n===0?0:Math.pow(2,10*n-10)},easeOutExpo(n){return n===1?1:1-Math.pow(2,-10*n)},easeInOutExpo(n){return n===0?0:n===1?1:n<.5?Math.pow(2,20*n-10)/2:(2-Math.pow(2,-20*n+10))/2},smoothstep(n){return n=f.clamp(n,0,1),n*n*(3-2*n)},randomLerp(n,e){return f.lerp(n,e,Math.random())},randomInt(n,e){return Math.floor(Math.random()*(e-n+1))+n},randomArrayValue(n){return n[f.randomInt(0,n.length-1)]},createBezier(n,e,t,r){function i(c,s,o,l,m){let p=1-c;return p*p*p*s+3*p*p*c*o+3*p*c*c*l+c*c*c*m}function a(c,s,o,l,m){let p=1-c;return 3*p*p*(o-s)+6*p*c*(l-o)+3*c*c*(m-l)}function u(c){let s=c;for(let o=0;o<6;o++){let l=i(s,0,n,t,1),m=a(s,0,n,t,1);if(m===0)break;s-=(l-c)/m}return f.clamp(s,0,1)}return function(s){s=f.clamp(s,0,1);let o=u(s);return i(o,0,e,r,1)}},lengthSquared(...n){return n.reduce((e,t)=>e+t*t,0)},normalizeRad(n){let e=2*Math.PI;return n=n%e,n<0&&(n+=e),n},angleInvertY(n){return f.normalizeRad(-n)},degToRadFlipY(n){return f.angleInvertY(n*Math.PI/180)},minimalAngularDirection(n,e){n=f.normalizeRad(n),e=f.normalizeRad(e);let t=f.normalizeRad(e-n),r=f.normalizeRad(n-e);return t<=r?1:-1}},_=class extends y{constructor({delta:e,ms:t,easing:r}){super(),this.delta=e,this.duration=t,this.elapsed=0,this.easing=r??(i=>i),this.lastValue=0,this.finished=!1}delta;duration;elapsed;lastValue;finished;easing;update(e){this.elapsed+=e*1e3;let t=f.clamp(this.elapsed/this.duration,0,1),r=this.easing(t),i=this.delta*r,a=i-this.lastValue;this.lastValue=i,this.emit("delta",a),t>=1&&(this.finished=!0,this.emit("finish",void 0))}},K=class extends E{constructor(e,t=0,r=0,i=50,a=50){super(e,t,r),this.width=i,this.height=a}width;height;get left(){return this.x-this.width/2}set left(e){this.x=e+this.width/2}get right(){return this.x+this.width/2}set right(e){this.x=e-this.width/2}get top(){return this.y-this.height/2}set top(e){this.y=e+this.height/2}get bottom(){return this.y+this.height/2}set bottom(e){this.y=e-this.height/2}get lx(){return 0}get ly(){return 0}get lleft(){return-this.width/2}get lright(){return this.width/2}get ltop(){return-this.height/2}get lbottom(){return this.height/2}isCollidingWith(e){return!(this.right<e.left||this.left>e.right||this.bottom<e.top||this.top>e.bottom)}color="rgba(0, 0, 255, 0.3)";draw(e){e.translate(this.x,this.y),e.rotate(this.scaleRotate),e.fillStyle=this.color,e.fillRect(-this.width/2,-this.height/2,this.width,this.height)}},A=class extends y{duration;ticker;elapsed;finished;_resolve;promise;_timeoutId;constructor(e,t=null){super(),this.duration=e,this.ticker=t,this.elapsed=0,this.finished=!1,this._resolve=null,this.promise=new Promise(r=>this._resolve=r),this.update=this.update.bind(this),this.ticker&&this.ticker.on("tick",this.update)}update(e=0){this.finished||(this.elapsed+=e*1e3,this.elapsed>=this.duration&&this.finish())}finish(){this.finished||(this.finished=!0,this.emit("finish",void 0),this._resolve&&this._resolve(),this.ticker&&this.ticker.off("tick",this.update))}start(){return this.ticker||(this._timeoutId=setTimeout(()=>this.finish(),this.duration)),this}cancel(){this.finished||(this.finished=!0,!this.ticker&&this._timeoutId!=null&&clearTimeout(this._timeoutId),this.ticker&&this.ticker.off("tick",this.update))}then(e,t){return this.promise.then(e,t)}after(e,t){return this.promise.then(e,t)}},C=class n{constructor(e=0,t=0){this.x=e,this.y=t}x;y;toJSON(){return{x:this.x,y:this.y,vec2:!0}}static isVec2(e){return e&&typeof e=="object"&&"x"in e&&"y"in e&&e.vec2===!0}static fromSerialized(e){return this.isVec2(e)?new this(e.x,e.y):null}rotate(e){let t=Math.cos(e),r=Math.sin(e);return new n(this.x*t-this.y*r,this.x*r+this.y*t)}static from(e){return new n(Math.cos(e),Math.sin(e))}get angle(){return Math.atan2(this.y,this.x)}get length(){return Math.hypot(this.x,this.y)}get lengthSquared(){return this.x*this.x+this.y*this.y}normalized(){let e=this.length;return e===0?new n(0,0):new n(this.x/e,this.y/e)}project(e){return e.scale(this.dotNormalized(e))}reflect(e){let t=this.dot(e);return this.subtract(e.scale(2*t))}dotNormalized(e){let t=this.normalized(),r=e.normalized();return t.x*r.x+t.y*r.y}lengthSquaredTo(e){let t=this.x-e.x,r=this.y-e.y;return t*t+r*r}dot(e){return this.x*e.x+this.y*e.y}distanceTo(e){return Math.hypot(this.x-e.x,this.y-e.y)}distanceToCheap(e){let t=this.x-e.x,r=this.y-e.y;return t*t+r*r}directionTo(e){return new n(e.x-this.x,e.y-this.y).normalized()}add(e){return new n(this.x+e.x,this.y+e.y)}addRaw(e){return new n(this.x+e,this.y+e)}overwite(e){this.x=e.x,this.y=e.y}subtract(e){return new n(this.x-e.x,this.y-e.y)}scale(e){return new n(this.x*e,this.y*e)}toString(){return`Vector2(${this.x}, ${this.y})`}clone(){return new n(this.x,this.y)}};function ae(n){let e=/^rgba?\(([^)]+)\)$/,t=n.match(e);if(t){let[r,i,a,u=1]=t[1].split(",").map(c=>parseFloat(c));return{r:Math.max(0,Math.min(255,Math.floor(r))),g:Math.max(0,Math.min(255,Math.floor(i))),b:Math.max(0,Math.min(255,Math.floor(a))),a:Math.max(0,Math.min(1,Math.floor(u*255)/255))}}return O(n)}function oe(n){return`rgba(${n.r}, ${n.g}, ${n.b}, ${n.a})`}function O(n){if(n=n.trim().toLowerCase(),n[0]==="#"){let t,r,i;if(n.length===7)t=parseInt(n.slice(1,3),16),r=parseInt(n.slice(3,5),16),i=parseInt(n.slice(5,7),16);else if(n.length===4)t=parseInt(n[1]+n[1],16),r=parseInt(n[2]+n[2],16),i=parseInt(n[3]+n[3],16);else throw new Error("Invalid hex color");return{r:t,g:r,b:i,a:1}}let e=n.match(/^rgba?\s*\(\s*(\d+)[, ]\s*(\d+)[, ]\s*(\d+)(?:[, ]\s*([\d.]+))?\s*\)$/);if(e)return{r:parseInt(e[1]),g:parseInt(e[2]),b:parseInt(e[3]),a:e[4]!==void 0?parseFloat(e[4]):1};throw new Error("Unsupported fillStyle format")}function ue(n,{r:e,g:t,b:r,a:i}={}){let[a,u,c,s,o]=n.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]*)\)?/)||[];return`rgba(${e??u}, ${t??c}, ${r??s}, ${i??(o||1)})`}function ce(n,e,t){return t+(n-t)*e}function q(){return typeof process<"u"&&process.release?.name==="node"?"node":typeof window<"u"||typeof self<"u"?"web":"unknown"}var N=q(),k=N==="node",b=N==="web",T=class n{static unlock(){b&&this.audioCtx.state!=="running"&&this.audioCtx.resume()}static audioCtx=b?new AudioContext:null;static masterGain=b?this.audioCtx.createGain():null;static musicGain=b?this.audioCtx.createGain():null;static sfxGain=b?this.audioCtx.createGain():null;static{b&&(this.masterGain.gain.value=1,this.musicGain.gain.value=1,this.sfxGain.gain.value=1,this.sfxGain.connect(this.masterGain),this.musicGain.connect(this.masterGain),this.masterGain.connect(this.audioCtx.destination))}static get SFX_VOLUME(){return this.sfxGain.gain.value}static get MUSIC_VOLUME(){return this.musicGain.gain.value}static get VOLUME(){return this.masterGain.gain.value}static set SFX_VOLUME(e){this.sfxGain.gain.value=e}static set MUSIC_VOLUME(e){this.musicGain.gain.value=e}static set VOLUME(e){this.masterGain.gain.value=e}static noteToHz(e){return this.tuningFreq*Math.pow(2,(e-9)/12)}static tuningFreq=440;static audioBufferCache=new Map;static loops=new Map;static sfsx=new Map;static loopIdCounter=0;static CACHE_NAME="lia-audio-cache-v1";static async preLoad(e){if(this.audioBufferCache.has(e))return this.audioBufferCache.get(e);let t=n.CACHE_NAME,r,i;if(typeof caches<"u"&&(i=await caches.open(t),r=await i.match(e)),!r){if(r=await fetch(e),!r.ok)throw new Error(`Failed to fetch ${e}`);i&&await i.put(e,r.clone())}let a=await r.arrayBuffer(),u=await this.audioCtx.decodeAudioData(a);return this.audioBufferCache.set(e,u),u}static async getOnlyDownloadedCache(e){let t=n.CACHE_NAME;return await(await caches.open(t)).match(e)}static getCached(e){return this.audioBufferCache.get(e)||null}static async playSound(e,t=.2,r=1,i=!0){try{this.sfsx.has(e)&&this.sfsx.get(e).source.stop(),this.audioBufferCache.has(e)||await this.preLoad(e);let a=this.getCached(e);if(!a)return;let u=new w(a);u.buffer=a;let c=1-.12,s=1+.12;u.playbackRate=r??c+Math.random()*(s-c);let o=this.audioCtx.createGain();o.gain.value=t,u.tempGain=o,u.connect(o),o.connect(this.sfxGain),u.onended=()=>{u.disconnect(),o.disconnect()},u.start(),i&&this.sfsx.set(e,{source:u,gain:o})}catch(a){console.error(a)}}static async playLoop(e,t=1,{loopStart:r=0,loopEnd:i=null,exclusive:a=!0,skipMS:u=0}={}){if(a)for(let m of this.loops.keys())this.stopLoop(m);this.audioBufferCache.has(e)||await this.preLoad(e);let c=this.getCached(e);if(!c)return;let s=new w(c);s.buffer=c,s.loop=!0,typeof r=="number"&&(s.loopStart=r),typeof i=="number"&&(s.loopEnd=i);let o=this.audioCtx.createGain();o.gain.value=t,s.tempGain=o,s.playbackRate=1,s.onended=()=>{s.disconnect(),o.disconnect()},s.connect(o),o.connect(this.musicGain),s.start(0,u/1e3);let l=++this.loopIdCounter;return this.loops.set(l,{source:s,gain:o}),l}static stopLoop(e){let t=this.loops.get(e);t&&(t.source.stop(),t.source.notIndependent||(t.source.disconnect(),t.gain.disconnect()),this.loops.delete(e))}static async createLiaSource(e,{volume:t=1,speed:r=1,loop:i=!1,loopStart:a=0,loopEnd:u=null,isMusic:c=!1,gain:s=null}={}){try{this.audioBufferCache.has(e)||await this.preLoad(e);let o=this.getCached(e);if(!o)return null;let l=new w(o);l.loop=i,l.loopStart=a,l.loopEnd=typeof u=="number"?u:o.duration,l.playbackRate=r;let m=this.audioCtx.createGain();return m.gain.value=t,l.connect(m),l.tempGain=m,m.connect(s||(c?this.musicGain:this.sfxGain)),l.onended=()=>{l.disconnect(),m.disconnect()},l}catch(o){return console.error("Failed to create LiaAudioSrc:",o),null}}},D=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];function he(n){return D.includes(n)}var w=class{numberOfInputs;numberOfOutputs;constructor(e,t=T.audioCtx){this.context=t,this.buffer=e,this.source=null,this.startTime=0,this.pauseTime=0,this.playbackRate=1,this.isPlaying=!1,this.loop=!1,this.output=b?t.createGain():null,this.output.gain.value=1,this.channelCount=2,this.channelCountMode="max",this.channelInterpretation="speakers",this.numberOfInputs=0,this.numberOfOutputs=1,this.onended=null}channelCount;channelCountMode;channelInterpretation;onended;source;buffer;context;_createSource(){this.source&&(this.source.onended=null);let e=this.context.createBufferSource();return e.buffer=this.buffer,e.playbackRate.value=this.playbackRate,e.loop=this.loop,e.loopStart=this.loopStart,e.loopEnd=this.loopEnd>0?this.loopEnd:this.buffer.duration,e.connect(this.output),this.source=e,e.onended=()=>{this.source===e&&(this.isPlaying&&!this.loop&&(this.isPlaying=!1,this.pauseTime=0),typeof this.onended=="function"&&this.onended())},e}play({fadeIn:e=0,offset:t=null}={}){let r=t!==null?t:this.pauseTime;if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.source=this._createSource(),this.startTime=this.context.currentTime-r/this.playbackRate,this.source.start(0,r),e>0?(this.output.gain.setValueAtTime(0,this.context.currentTime),this.output.gain.linearRampToValueAtTime(1,this.context.currentTime+e)):this.output.gain.setValueAtTime(1,this.context.currentTime),this.isPlaying=!0}start(e=0,t=0,r){this.isPlaying||(this.source=this._createSource(),this.startTime=this.context.currentTime+e-t/this.playbackRate,r!==void 0?this.source.start(this.context.currentTime+e,t,r):this.source.start(this.context.currentTime+e,t),this.pauseTime=t,this.isPlaying=!0)}pause({fadeOut:e=0}={}){if(!this.isPlaying)return;let t=this.getElapsed()/1e3;if(this.loop&&this.loopEnd>this.loopStart){let r=this.loopEnd-this.loopStart;t=this.loopStart+(t-this.loopStart)%r}if(this.isPlaying=!1,e>0){let r=this.context.currentTime;this.output.gain.setValueAtTime(this.output.gain.value,r),this.output.gain.linearRampToValueAtTime(0,r+e),setTimeout(()=>{if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.pauseTime=t,this.output.gain.setValueAtTime(1,this.context.currentTime)},e*1e3)}else{if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.pauseTime=t}}getElapsed(){return this.isPlaying?(this.context.currentTime-this.startTime)*this.playbackRate*1e3:this.pauseTime*1e3}setSpeed(e){if(e<=0)throw new Error("Playback rate must be positive");let t=this.getElapsed()/1e3;this.playbackRate=e,this.isPlaying&&(this.pause(),this.pauseTime=t,this.play())}setLoop(e=!0){this.loop=e,this.source&&(this.source.loop=e)}loop;playbackRate;startTime;tempGain=null;connect(e,t=0,r=0){if("value"in e)this.output.connect(e,t);else return this.output.connect(e,t,r),e}disconnect(e,t,r){e===void 0?this.output.disconnect():this.output.disconnect(e,t,r)}output;stop(e=0){if(this.notIndependent)return this.pause();if(!this.source)return;let t=this.context.currentTime+e;this.source.stop(t),this.isPlaying=!1,this.notIndependent||(this.pauseTime=0)}pauseTime;isPlaying;notIndependent=!1;loopStart=0;loopEnd=0},X={osc:{enabled:!0,type:"sine",freq:440,detune:0},noise:{enabled:!1,level:.5},ampEnv:{attack:.005,decay:.1,sustain:0,release:.1,volume:.3},pitchEnv:{amount:0,decay:.2},filter:{enabled:!1,type:"lowpass",freq:1200,Q:1,envAmount:0,decay:.2},lfo:{enabled:!1,target:"freq",rate:8,depth:20},duration:.4},x=class n{constructor(e={}){this.ctx=T.audioCtx,this.cfg=structuredClone(X),Object.assign(this.cfg,e)}ctx;cfg;play(e=T.sfxGain){let t=this.ctx,r=t.currentTime,i=this.cfg,a=t.createGain();a.gain.setValueAtTime(1e-4,r);let u=i.ampEnv;a.gain.exponentialRampToValueAtTime(u.volume,r+u.attack),a.gain.exponentialRampToValueAtTime(Math.max(1e-4,u.sustain*u.volume),r+u.attack+u.decay),a.gain.exponentialRampToValueAtTime(1e-4,r+i.duration+u.release);let c=a,s;i.filter.enabled&&(s=t.createBiquadFilter(),s.type=i.filter.type,s.frequency.value=i.filter.freq,s.Q.value=i.filter.Q,s.connect(a),c=s);let o;if(i.osc.enabled){if(o=t.createOscillator(),o.type=i.osc.type,o.frequency.value=i.osc.freq,o.detune.value=i.osc.detune,i.pitchEnv.amount!==0){let h=Math.pow(2,i.pitchEnv.amount/12);o.frequency.exponentialRampToValueAtTime(i.osc.freq*h,r+i.pitchEnv.decay)}o.connect(c),o.start(r),o.stop(r+i.duration+u.release)}let l;if(i.noise.enabled){let h=t.sampleRate*i.duration,d=t.createBuffer(1,h,t.sampleRate),g=d.getChannelData(0);for(let v=0;v<h;v++)g[v]=(Math.random()*2-1)*i.noise.level;l=t.createBufferSource(),l.buffer=d,l.connect(c),l.start(r),l.stop(r+i.duration+u.release)}let m,p;i.lfo.enabled&&o&&(m=t.createOscillator(),m.frequency.value=i.lfo.rate,p=t.createGain(),p.gain.value=i.lfo.depth,m.connect(p),i.lfo.target==="freq"?p.connect(o.frequency):i.lfo.target==="gain"?p.connect(a.gain):i.lfo.target==="filter"&&s&&p.connect(s.frequency),m.start(r),m.stop(r+i.duration)),a.connect(e);let z=[o,l,m,p,s,a],M=r+i.duration+u.release;setTimeout(()=>{z.forEach(h=>h?.disconnect())},(M-t.currentTime)*1e3)}getConfig(){return structuredClone(this.cfg)}setConfig(e){return Object.assign(this.cfg,e),this}getKey(e){return this.cfg[e]}setKey(e,t){return Object.assign(this.cfg[e],t),this}setFreq(e){return this.cfg.osc.freq=e,this}setWave(e){return this.cfg.osc.type=e,this}setVolume(e){return this.cfg.ampEnv.volume=e,this}setAmpEnv(e,t,r,i){return Object.assign(this.cfg.ampEnv,{attack:e,decay:t,sustain:r,release:i}),this}setPitchEnv(e,t){return Object.assign(this.cfg.pitchEnv,{amount:e,decay:t}),this}setNoiseEnabled(e){return this.cfg.noise.enabled=e,this}setNoiseLevel(e){return this.cfg.noise.level=e,this}setFilterEnabled(e){return this.cfg.filter.enabled=e,this}setFilter(e,t,r){return Object.assign(this.cfg.filter,{type:e,freq:t,Q:r,enabled:!0}),this}setLFOEnabled(e){return this.cfg.lfo.enabled=e,this}setLFO(e,t,r){return Object.assign(this.cfg.lfo,{target:e,rate:t,depth:r,enabled:!0}),this}setDuration(e){return this.cfg.duration=e,this}clone(){return new n(structuredClone(this.cfg))}},B=new x({osc:{enabled:!0,type:"square",freq:900,detune:0},ampEnv:{attack:.002,decay:.04,sustain:0,release:.02,volume:.15},duration:.05}),U=new x({osc:{enabled:!0,type:"sine",freq:600,detune:0},ampEnv:{attack:.01,decay:.08,sustain:0,release:.04,volume:.12},duration:.1}),H=new x({osc:{enabled:!0,type:"triangle",freq:500,detune:0},pitchEnv:{amount:12,decay:.15},ampEnv:{attack:.01,decay:.12,sustain:0,release:.05,volume:.25},duration:.18}),$=new x({osc:{enabled:!0,type:"sawtooth",freq:1200,detune:0},pitchEnv:{amount:-24,decay:.3},ampEnv:{attack:.005,decay:.25,sustain:0,release:.05,volume:.3},duration:.35}),W=new x({osc:{enabled:!0,type:"square",freq:180,detune:0},noise:{enabled:!0,level:.4},ampEnv:{attack:.002,decay:.15,sustain:0,release:.05,volume:.35},duration:.2}),le=new Map([["ui_click",B],["ui_hover",U],["jump",H],["laser",$],["hit",W]]);function me(n=12){let e=Date.now().toString(36),t=crypto.getRandomValues(new Uint8Array(n)),r=Array.from(t).map(i=>i.toString(36).padStart(2,"0")).join("");return(e+r).slice(0,n)}function de(n=12){let e=Date.now().toString(36),t=crypto.getRandomValues(new Uint8Array(4)),r=Array.from(t).map(i=>i.toString(36).padStart(2,"0")).join("");return(e+r).slice(0,n)}var L=class{peer=null;key;events={};mbAcc=0;connected=!1;constructor(){this.key=`${j()}_${Date.now()}`}connect(e){e&&(this.peer=e,e.peer=this,this.connected=!0,e.connected=!0),this._emit("open")}isConnected(){return this.connected&&!!this.peer}on(e,t){this.events[e]||(this.events[e]=[]),this.events[e].push(t)}off(e,t){this.events[e]&&(this.events[e]=this.events[e].filter(r=>r!==t))}_emit(e,t){this.events[e]?.forEach(r=>r(t))}send(e,t){if(!this.peer)throw new Error("No peer connected");this.peer._receive(e,t)}_receive(e,t){e?this._emit(e,t):this._emit("message",t)}close(){if(this.connected=!1,this.peer){let e=this.peer;this.peer=null,e.peer=null,e.connected=!1,e._emit("close")}this._emit("close")}getKey(){return this.key}};function j(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let n=new Uint8Array(16);return crypto.getRandomValues(n),n[6]=n[6]&15|64,n[8]=n[8]&63|128,[...n].map(e=>e.toString(16).padStart(2,"0")).join("").replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/,"$1-$2-$3-$4-$5")}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let e=Math.random()*16|0;return(n==="x"?e:e&3|8).toString(16)})}function Q(n){let e=!0;function t(){e&&(n(),requestAnimationFrame(t))}return requestAnimationFrame(t),{clear:()=>e=!1}}function J(n,e,t,r,i){let a=Math.cos(i),u=Math.sin(i),c=[];if(a!==0){let s=(0-n)/a,o=e+s*u;s>0&&o>=0&&o<=r&&c.push({side:"left",t:s})}if(a!==0){let s=(t-n)/a,o=e+s*u;s>0&&o>=0&&o<=r&&c.push({side:"right",t:s})}if(u!==0){let s=(0-e)/u,o=n+s*a;s>0&&o>=0&&o<=t&&c.push({side:"top",t:s})}if(u!==0){let s=(r-e)/u,o=n+s*a;s>0&&o>=0&&o<=t&&c.push({side:"bottom",t:s})}return c.length===0?null:(c.sort((s,o)=>s.t-o.t),c[0])}function Y(n,e){let t;switch(e){case"left":case"right":t=Math.PI-n;break;case"top":case"bottom":t=2*Math.PI-n;break}return(t%(2*Math.PI)+2*Math.PI)%(2*Math.PI)}function pe(n,e,t,r,i){let a=J(n,e,t,r,i);return a?{...a,avoidAngle:Y(i,a.side)}:null}function Z(){return k?!1:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}var fe=Z();0&&(module.exports={DeltaTweenII,ENVIRONMENT,GEmitterMemory,LeaEntityII,LeaEventEmitter,LeaGameII,LeaRendererII,LeaSceneII,LeaSerializers,LeaTickerII,LeaTimeout,LeaUtilsII,LiaAudio,LiaAudioSrc,LiaOscSFX,LiaSFXMap,NOTE_NAMES,RectLeaEntity,Vector2,colToRGBA,defaultSFXConfig,editRGBA,generateUUID,getAvoidAngle,getEnvironment,getNormalizedColor,getRayHit,isInitiallyMobile,isMobile,isNode,isNote,isWeb,parseFillStyle,raycastAvoid,scaleCoord,setAnimInterval,sfxHit,sfxJump,sfxLaser,sfxUIClick,sfxUIHover,shortUID,tinyUID});
1
+ "use strict";var R=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var ne=Object.prototype.hasOwnProperty;var re=(n,e)=>{for(var t in e)R(n,t,{get:e[t],enumerable:!0})},ie=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of te(e))!ne.call(n,i)&&i!==t&&R(n,i,{get:()=>e[i],enumerable:!(r=ee(e,i))||r.enumerable});return n};var se=n=>ie(R({},"__esModule",{value:!0}),n);var be={};re(be,{DeltaTweenII:()=>_,ENVIRONMENT:()=>N,GEmitterMemory:()=>L,LeaEntityII:()=>E,LeaEventEmitter:()=>y,LeaGameII:()=>V,LeaRendererII:()=>F,LeaSceneII:()=>P,LeaSerializers:()=>G,LeaTickerII:()=>I,LeaTimeout:()=>A,LeaUtilsII:()=>b,LiaAudio:()=>T,LiaAudioSrc:()=>w,LiaOscSFX:()=>x,LiaSFXMap:()=>le,NOTE_NAMES:()=>D,RectLeaEntity:()=>K,Vector2:()=>C,colToRGBA:()=>oe,defaultSFXConfig:()=>X,editRGBA:()=>ue,generateUUID:()=>j,getAvoidAngle:()=>Y,getEnvironment:()=>q,getNormalizedColor:()=>ae,getRayHit:()=>J,isInitiallyMobile:()=>fe,isMobile:()=>Z,isNode:()=>k,isNote:()=>he,isWeb:()=>f,parseFillStyle:()=>O,raycastAvoid:()=>pe,scaleCoord:()=>ce,setAnimInterval:()=>Q,sfxHit:()=>W,sfxJump:()=>H,sfxLaser:()=>$,sfxUIClick:()=>B,sfxUIHover:()=>U,shortUID:()=>me,tinyUID:()=>de});module.exports=se(be);var y=class{#e=new Map;constructor(){this.#e=new Map}on(e,t){let r=this.#e.get(e)||[];return r.push(t),this.#e.set(e,r),this}once(e,t){let r=(...i)=>{this.off(e,r),t(...i)};return this.on(e,r),this}off(e,t){let r=this.#e.get(e);if(!r)return this;let i=r.indexOf(t);return i>=0&&r.splice(i,1),this}emit(e,...t){let r=this.#e.get(e);if(!r||r.length===0){if(e==="error")throw t[0];return!1}return r.slice().forEach(i=>i(...t)),!0}removeAllListeners(e){return e?this.#e.delete(e):this.#e.clear(),this}listenerCount(e){return this.#e.get(e)?.length??0}},F=class extends y{canvas;ctx;running;_rafId;_fps;_frameCount;_fpsTimer;_lastFrameTime;constructor(e,{viewportWidth:t,viewportHeight:r,cameraWidth:i,cameraHeight:a}={}){if(!f)throw new Error("Web-Only");super(),this.canvas=e,this.ctx=e.getContext("2d"),this.automatic=!0,this.#e=t??e.width,this.#t=r??e.height,this.#n=i??e.width,this.#r=a??e.height,this.running=!1,this._rafId=null,this._loop=this._loop.bind(this),this.updateCanvasResolution(),this._fps=60,this._frameCount=0,this._fpsTimer=0}automatic;retransform(){this.ctx.setTransform(1,0,0,1,0,0);let e=this.#n/this.#e,t=this.#r/this.#t;this.ctx.translate(this.#n/2,this.#r/2),this.ctx.scale(e,t),this.ctx.translate(-this.#e/2,-this.#t/2)}#e=0;#t=0;#n=0;#r=0;get viewportWidth(){return this.#e}set viewportWidth(e){this.#e=e,this.retransform()}get width(){return this.#e}get height(){return this.#t}get centerX(){return this.#e/2}get centerY(){return this.#t/2}get left(){return 0}get top(){return 0}get right(){return this.#e}get bottom(){return this.#t}get viewportHeight(){return this.#t}set viewportHeight(e){this.#t=e,this.retransform()}get cameraWidth(){return this.#n}set cameraWidth(e){this.#n=e,this.updateCanvasResolution(),this.retransform()}get cameraHeight(){return this.#r}set cameraHeight(e){this.#r=e,this.updateCanvasResolution(),this.retransform()}updateCanvasResolution(){this.canvas.width=this.#n,this.canvas.height=this.#r}applyTransform(){this.retransform()}get FPS(){return this._fps}_loop(){this.automatic&&this.update(),this._rafId=requestAnimationFrame(this._loop)}update(){if(!this.running||!f)return;let e=performance.now(),t=(e-(this._lastFrameTime??e))/1e3;this._lastFrameTime=e,this._frameCount++,this._fpsTimer+=t,this._fpsTimer>=1&&(this._fps=Math.round(this._frameCount/this._fpsTimer),this._frameCount=0,this._fpsTimer=0),this.ctx.clearRect(0,0,this.#n,this.#r),this.emit("draw",this.ctx)}start(){if(!this.running){if(!f||typeof globalThis.requestAnimationFrame>"u")throw new Error("Raf is not supported");this.running=!0,this._rafId=requestAnimationFrame(this._loop)}}stop(){if(!f||typeof globalThis.requestAnimationFrame>"u")throw new Error("Raf is not supported");this.running=!1,this._rafId!==null&&(cancelAnimationFrame(this._rafId),this._rafId=null)}},I=class extends y{setNow(e){this.#e=e}#e=0;__intervalId=null;__lastTime=0;constructor(e=16){super(),this.#t=e,this.speedHackDT=1}speedHackDT;get isRaf(){return this.tickInterval===1/0}#t=15;get tickInterval(){return this.#t}set tickInterval(e){this.#t=e,this.__intervalId&&(this.stop(),this.start())}now(){return this.#e}__tick(){let e=performance.now(),t=(e-this.__lastTime)/1e3*this.speedHackDT;this.__lastTime=e,!(f&&typeof this.__intervalId=="function"&&document.hidden)&&(this.#e+=t*1e3,this.emit("tick",t))}createTimeout(e){return new A(e,this)}createTween(e,t=()=>{}){let r=new _(e),i=(a=0)=>{if(r.finished){this.off("tick",i);return}r.update(a)};return r.on("finish",()=>{this.off("tick",i)}),r.on("delta",a=>{t(a)}),this.on("tick",i),r}start(){this.__intervalId===null&&(this.__lastTime=performance.now(),this.__intervalId=f&&!isFinite(this.tickInterval)?Q(()=>this.__tick()).clear:setInterval(()=>this.__tick(),this.tickInterval))}stop(){this.__intervalId!==null&&(typeof this.__intervalId=="function"?this.__intervalId():clearInterval(this.__intervalId)),this.__intervalId=null}getSineMod(e,t=0){return .5+.5*Math.sin((this.now()%e/e+t)*2*Math.PI)}},G;(M=>{function n(h){return h===!0?1:0}M.booleanExport=n;function e(h){return h===0?!1:h===1}M.booleanImport=e;function t(h){return`${h.x}|${h.y}`}M.vec2Export=t;function r(h){let[d,g]=h.split("|"),v=parseFloat(d),S=parseFloat(g);if(isNaN(v)||isNaN(S))throw new Error(`Invalid Vector2 string: ${h}`);return new C(v,S)}M.vec2Import=r,M.booleanMap={mapExport:n,mapImport:e};function a(h){return d=>Number(d.toFixed(h))}M.createRounder=a;function u(h=10){return{mapExport(d){return Math.round(d/h)},mapImport(d){return d*h}}}M.createLowPrecision=u;function c(h){return Math.round(h)}M.lightWeightRounder=c;function s(h=100){return{mapExport(d){return Math.round(d*h)},mapImport(d){return d/h}}}M.createPercent=s;function o(h){let d=new Map(Object.entries(h));return{mapExport:g=>d.get(g)??null,mapImport:g=>Array.from(d.entries()).find(([v,S])=>S===g)?.[0]??null}}M.createLookup=o;function l(h){let d=h*(180/Math.PI);return Math.round((d%360+360)%360)}M.radToDeg=l;function m(h){return h*(Math.PI/180)}M.degToRad=m,M.angleRadToDeg={mapExport:l,mapImport:m};function z(h=10){let d=u(h);return{mapExport(g){return d.mapExport(l(g))},mapImport(g){return d.mapImport(m(g))}}}M.createLowPrecisionRadToDeg=z})(G||={});var E=class n extends y{name="";scaleRotate=0;scale=1;constructor(e,t=0,r=0){super(),this.autoTranslate=!1,this.name=e,this.z=0,this.___pos=new C(t,r),this.nonSerializableProperties=[],this.nonSerializableProperties.push("___pos","autoTranslate","arraySerializeMap"),this.forceSerializableProperties=[],this.forceSerializableProperties.push("x","y")}arraySerializeMap;autoTranslate;z;___pos;nonSerializableProperties;forceSerializableProperties;get pos(){return this.___pos}get x(){return this.pos.x}get y(){return this.pos.y}set x(e){this.pos.x=e}set y(e){this.pos.y=e}handleUpdate(e){if(this.update)try{this.emit("update",e),this.update(e)}catch(t){this.emit("error",t)}}handleDraw(e){if(!(k||!this.draw)){e.save(),this.autoTranslate&&e.translate(this.x,this.y);try{this.emit("draw",e),this.draw(e)}catch(t){this.emit("error",t)}e.restore()}}serialize(){if(Array.isArray(this.arraySerializeMap))return this.arraySerializeMap.map(([i,{mapExport:a}])=>{let u=Reflect.get(this,i);return a?a(u):u});let e=["_events","_eventsCount","_maxListeners","nonSerializableProperties","forceSerializableProperties"],t=[...Reflect.ownKeys(this),...this.forceSerializableProperties].filter(i=>!this.nonSerializableProperties.includes(i)&&!e.includes(i.toString())),r=Object.fromEntries(t.map(i=>{let a=Reflect.get(this,i);if(k&&typeof a=="number"){let u=a.toString().split("."),s=(u[1]?u[1].length:0)>2?Number(a.toFixed(2)):a;return[i,s]}return[i,a]}));return JSON.parse(JSON.stringify(r))}toLocal(e){return e.subtract(this.pos)}toWorld(e){return e.add(this.pos)}deserializeArray(e){return n.deserializeArray(this.arraySerializeMap,e)}static deserializeArray(e,t){if(!e||!Array.isArray(t))return t;let r={};for(let i=0;i<t.length;i++){let a=e[i];if(!a)break;let[u,{mapImport:c}]=a,s=t[i];if(c&&(s=c(s)),typeof u!="string")break;try{Reflect.set(r,u,s)}catch(o){console.error(o)}}return r}},P=class extends y{name="";entities=new Map;paused=!0;constructor(e){super(),this.name=e}handleUpdate(e){if(!this.paused){this.emit("update",e);for(let t of this.entities.values())t.handleUpdate(e)}}handleDraw(e){if(!k&&!this.paused){this.emit("draw",e);for(let t of[...this.entities.values()].sort((r,i)=>r.z-i.z))t.handleDraw(e)}}addEntity(e){if(!(e instanceof E))throw new Error("invalid entity");if(!e.name)throw new Error("Entity must have a name.");this.entities.set(e.name,e)}removeEntity(e){if(!(e instanceof E))throw new Error("invalid entity");this.entities.delete(e.name)}getEntity(e){return this.entities.get(e)}},V=class{scenes;ticker;get centerX(){return this.width/2}get centerY(){return this.height/2}get left(){return 0}get top(){return 0}get right(){return this.width}get bottom(){return this.height}width;height;constructor(e,t,r=16){this.ticker=new I(r),this.scenes=new Map,this.width=e,this.height=t,this.ticker.on("tick",i=>{for(let a of this.scenes.values())a.paused||a.handleUpdate(i)})}addScene(e){if(!e.name)throw new Error("Scene must have a name.");e.paused=!1,this.scenes.set(e.name,e)}removeScene(e){e&&(e.paused=!0),this.scenes.delete(e.name)}now(){return this.ticker.now()}start(){this.ticker.start()}stop(){this.ticker.stop()}},b={lerp(n,e,t){return n+(e-n)*t},clamp(n,e,t){return Math.min(t,Math.max(e,n))},clamp01(n){return Math.min(1,Math.max(0,n))},easeLinear(n){return n},easeInQuad(n){return n*n},easeOutQuad(n){return 1-(1-n)*(1-n)},easeInOutQuad(n){return n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2},easeInSine(n){return 1-Math.cos(n*Math.PI/2)},easeOutSine(n){return Math.sin(n*Math.PI/2)},easeInOutSine(n){return-(Math.cos(Math.PI*n)-1)/2},easeInExpo(n){return n===0?0:Math.pow(2,10*n-10)},easeOutExpo(n){return n===1?1:1-Math.pow(2,-10*n)},easeInOutExpo(n){return n===0?0:n===1?1:n<.5?Math.pow(2,20*n-10)/2:(2-Math.pow(2,-20*n+10))/2},smoothstep(n){return n=b.clamp(n,0,1),n*n*(3-2*n)},randomLerp(n,e){return b.lerp(n,e,Math.random())},randomInt(n,e){return Math.floor(Math.random()*(e-n+1))+n},randomArrayValue(n){return n[b.randomInt(0,n.length-1)]},createBezier(n,e,t,r){function i(c,s,o,l,m){let p=1-c;return p*p*p*s+3*p*p*c*o+3*p*c*c*l+c*c*c*m}function a(c,s,o,l,m){let p=1-c;return 3*p*p*(o-s)+6*p*c*(l-o)+3*c*c*(m-l)}function u(c){let s=c;for(let o=0;o<6;o++){let l=i(s,0,n,t,1),m=a(s,0,n,t,1);if(m===0)break;s-=(l-c)/m}return b.clamp(s,0,1)}return function(s){s=b.clamp(s,0,1);let o=u(s);return i(o,0,e,r,1)}},lengthSquared(...n){return n.reduce((e,t)=>e+t*t,0)},normalizeRad(n){let e=2*Math.PI;return n=n%e,n<0&&(n+=e),n},angleInvertY(n){return b.normalizeRad(-n)},degToRadFlipY(n){return b.angleInvertY(n*Math.PI/180)},minimalAngularDirection(n,e){n=b.normalizeRad(n),e=b.normalizeRad(e);let t=b.normalizeRad(e-n),r=b.normalizeRad(n-e);return t<=r?1:-1}},_=class extends y{constructor({delta:e,ms:t,easing:r}){super(),this.delta=e,this.duration=t,this.elapsed=0,this.easing=r??(i=>i),this.lastValue=0,this.finished=!1}delta;duration;elapsed;lastValue;finished;easing;update(e){this.elapsed+=e*1e3;let t=b.clamp(this.elapsed/this.duration,0,1),r=this.easing(t),i=this.delta*r,a=i-this.lastValue;this.lastValue=i,this.emit("delta",a),t>=1&&(this.finished=!0,this.emit("finish",void 0))}},K=class extends E{constructor(e,t=0,r=0,i=50,a=50){super(e,t,r),this.width=i,this.height=a}width;height;get left(){return this.x-this.width/2}set left(e){this.x=e+this.width/2}get right(){return this.x+this.width/2}set right(e){this.x=e-this.width/2}get top(){return this.y-this.height/2}set top(e){this.y=e+this.height/2}get bottom(){return this.y+this.height/2}set bottom(e){this.y=e-this.height/2}get lx(){return 0}get ly(){return 0}get lleft(){return-this.width/2}get lright(){return this.width/2}get ltop(){return-this.height/2}get lbottom(){return this.height/2}isCollidingWith(e){return!(this.right<e.left||this.left>e.right||this.bottom<e.top||this.top>e.bottom)}color="rgba(0, 0, 255, 0.3)";draw(e){e.translate(this.x,this.y),e.rotate(this.scaleRotate),e.fillStyle=this.color,e.fillRect(-this.width/2,-this.height/2,this.width,this.height)}},A=class extends y{duration;ticker;elapsed;finished;_resolve;promise;_timeoutId;constructor(e,t=null){super(),this.duration=e,this.ticker=t,this.elapsed=0,this.finished=!1,this._resolve=null,this.promise=new Promise(r=>this._resolve=r),this.update=this.update.bind(this),this.ticker&&this.ticker.on("tick",this.update)}update(e=0){this.finished||(this.elapsed+=e*1e3,this.elapsed>=this.duration&&this.finish())}finish(){this.finished||(this.finished=!0,this.emit("finish",void 0),this._resolve&&this._resolve(),this.ticker&&this.ticker.off("tick",this.update))}start(){return this.ticker||(this._timeoutId=setTimeout(()=>this.finish(),this.duration)),this}cancel(){this.finished||(this.finished=!0,!this.ticker&&this._timeoutId!=null&&clearTimeout(this._timeoutId),this.ticker&&this.ticker.off("tick",this.update))}then(e,t){return this.promise.then(e,t)}after(e,t){return this.promise.then(e,t)}},C=class n{constructor(e=0,t=0){this.x=e,this.y=t}x;y;toJSON(){return{x:this.x,y:this.y,vec2:!0}}static isVec2(e){return e&&typeof e=="object"&&"x"in e&&"y"in e&&e.vec2===!0}static fromSerialized(e){return this.isVec2(e)?new this(e.x,e.y):null}rotate(e){let t=Math.cos(e),r=Math.sin(e);return new n(this.x*t-this.y*r,this.x*r+this.y*t)}static from(e){return new n(Math.cos(e),Math.sin(e))}isEmpty(){return Math.abs(this.x)<.01&&Math.abs(this.y)<.01}get angle(){return Math.atan2(this.y,this.x)}angleTo(e){return Math.atan2(e.y-this.y,e.x-this.x)}get length(){return Math.hypot(this.x,this.y)}get lengthSquared(){return this.x*this.x+this.y*this.y}normalized(){let e=this.length;return e===0?new n(0,0):new n(this.x/e,this.y/e)}consume(e){let t=this.length;t<=e?(this.x=0,this.y=0):this.overwite(this.scale((t-e)/t))}project(e){return e.scale(this.dotNormalized(e))}reflect(e){let t=this.dot(e);return this.subtract(e.scale(2*t))}dotNormalized(e){let t=this.normalized(),r=e.normalized();return t.x*r.x+t.y*r.y}lengthSquaredTo(e){let t=this.x-e.x,r=this.y-e.y;return t*t+r*r}dot(e){return this.x*e.x+this.y*e.y}distanceTo(e){return Math.hypot(this.x-e.x,this.y-e.y)}distanceToCheap(e){let t=this.x-e.x,r=this.y-e.y;return t*t+r*r}directionTo(e){return new n(e.x-this.x,e.y-this.y).normalized()}add(e){return new n(this.x+e.x,this.y+e.y)}addRaw(e){return new n(this.x+e,this.y+e)}overwite(e){this.x=e.x,this.y=e.y}subtract(e){return new n(this.x-e.x,this.y-e.y)}scale(e){return new n(this.x*e,this.y*e)}toString(){return`Vector2(${this.x}, ${this.y})`}clone(){return new n(this.x,this.y)}};function ae(n){let e=/^rgba?\(([^)]+)\)$/,t=n.match(e);if(t){let[r,i,a,u=1]=t[1].split(",").map(c=>parseFloat(c));return{r:Math.max(0,Math.min(255,Math.floor(r))),g:Math.max(0,Math.min(255,Math.floor(i))),b:Math.max(0,Math.min(255,Math.floor(a))),a:Math.max(0,Math.min(1,Math.floor(u*255)/255))}}return O(n)}function oe(n){return`rgba(${n.r}, ${n.g}, ${n.b}, ${n.a})`}function O(n){if(n=n.trim().toLowerCase(),n[0]==="#"){let t,r,i;if(n.length===7)t=parseInt(n.slice(1,3),16),r=parseInt(n.slice(3,5),16),i=parseInt(n.slice(5,7),16);else if(n.length===4)t=parseInt(n[1]+n[1],16),r=parseInt(n[2]+n[2],16),i=parseInt(n[3]+n[3],16);else throw new Error("Invalid hex color");return{r:t,g:r,b:i,a:1}}let e=n.match(/^rgba?\s*\(\s*(\d+)[, ]\s*(\d+)[, ]\s*(\d+)(?:[, ]\s*([\d.]+))?\s*\)$/);if(e)return{r:parseInt(e[1]),g:parseInt(e[2]),b:parseInt(e[3]),a:e[4]!==void 0?parseFloat(e[4]):1};throw new Error("Unsupported fillStyle format")}function ue(n,{r:e,g:t,b:r,a:i}={}){let[a,u,c,s,o]=n.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]*)\)?/)||[];return`rgba(${e??u}, ${t??c}, ${r??s}, ${i??(o||1)})`}function ce(n,e,t){return t+(n-t)*e}function q(){return typeof process<"u"&&process.release?.name==="node"?"node":typeof window<"u"||typeof self<"u"?"web":"unknown"}var N=q(),k=N==="node",f=N==="web",T=class n{static unlock(){f&&this.audioCtx.state!=="running"&&this.audioCtx.resume()}static audioCtx=f?new AudioContext:null;static masterGain=f?this.audioCtx.createGain():null;static musicGain=f?this.audioCtx.createGain():null;static sfxGain=f?this.audioCtx.createGain():null;static{f&&(this.masterGain.gain.value=1,this.musicGain.gain.value=1,this.sfxGain.gain.value=1,this.sfxGain.connect(this.masterGain),this.musicGain.connect(this.masterGain),this.masterGain.connect(this.audioCtx.destination))}static get SFX_VOLUME(){return this.sfxGain.gain.value}static get MUSIC_VOLUME(){return this.musicGain.gain.value}static get VOLUME(){return this.masterGain.gain.value}static set SFX_VOLUME(e){this.sfxGain.gain.value=e}static set MUSIC_VOLUME(e){this.musicGain.gain.value=e}static set VOLUME(e){this.masterGain.gain.value=e}static noteToHz(e){return this.tuningFreq*Math.pow(2,(e-9)/12)}static tuningFreq=440;static audioBufferCache=new Map;static loops=new Map;static sfsx=new Map;static loopIdCounter=0;static CACHE_NAME="lia-audio-cache-v1";static async preLoad(e){if(this.audioBufferCache.has(e))return this.audioBufferCache.get(e);let t=n.CACHE_NAME,r,i;if(typeof caches<"u"&&(i=await caches.open(t),r=await i.match(e)),!r){if(r=await fetch(e),!r.ok)throw new Error(`Failed to fetch ${e}`);i&&await i.put(e,r.clone())}let a=await r.arrayBuffer(),u=await this.audioCtx.decodeAudioData(a);return this.audioBufferCache.set(e,u),u}static async getOnlyDownloadedCache(e){let t=n.CACHE_NAME;return await(await caches.open(t)).match(e)}static getCached(e){return this.audioBufferCache.get(e)||null}static async playSound(e,t=.2,r=1,i=!0){try{this.sfsx.has(e)&&this.sfsx.get(e).source.stop(),this.audioBufferCache.has(e)||await this.preLoad(e);let a=this.getCached(e);if(!a)return;let u=new w(a);u.buffer=a;let c=1-.12,s=1+.12;u.playbackRate=r??c+Math.random()*(s-c);let o=this.audioCtx.createGain();o.gain.value=t,u.tempGain=o,u.connect(o),o.connect(this.sfxGain),u.onended=()=>{u.disconnect(),o.disconnect()},u.start(),i&&this.sfsx.set(e,{source:u,gain:o})}catch(a){console.error(a)}}static async playLoop(e,t=1,{loopStart:r=0,loopEnd:i=null,exclusive:a=!0,skipMS:u=0}={}){if(a)for(let m of this.loops.keys())this.stopLoop(m);this.audioBufferCache.has(e)||await this.preLoad(e);let c=this.getCached(e);if(!c)return;let s=new w(c);s.buffer=c,s.loop=!0,typeof r=="number"&&(s.loopStart=r),typeof i=="number"&&(s.loopEnd=i);let o=this.audioCtx.createGain();o.gain.value=t,s.tempGain=o,s.playbackRate=1,s.onended=()=>{s.disconnect(),o.disconnect()},s.connect(o),o.connect(this.musicGain),s.start(0,u/1e3);let l=++this.loopIdCounter;return this.loops.set(l,{source:s,gain:o}),l}static stopLoop(e){let t=this.loops.get(e);t&&(t.source.stop(),t.source.notIndependent||(t.source.disconnect(),t.gain.disconnect()),this.loops.delete(e))}static async createLiaSource(e,{volume:t=1,speed:r=1,loop:i=!1,loopStart:a=0,loopEnd:u=null,isMusic:c=!1,gain:s=null}={}){try{this.audioBufferCache.has(e)||await this.preLoad(e);let o=this.getCached(e);if(!o)return null;let l=new w(o);l.loop=i,l.loopStart=a,l.loopEnd=typeof u=="number"?u:o.duration,l.playbackRate=r;let m=this.audioCtx.createGain();return m.gain.value=t,l.connect(m),l.tempGain=m,m.connect(s||(c?this.musicGain:this.sfxGain)),l.onended=()=>{l.disconnect(),m.disconnect()},l}catch(o){return console.error("Failed to create LiaAudioSrc:",o),null}}},D=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];function he(n){return D.includes(n)}var w=class{numberOfInputs;numberOfOutputs;constructor(e,t=T.audioCtx){this.context=t,this.buffer=e,this.source=null,this.startTime=0,this.pauseTime=0,this.playbackRate=1,this.isPlaying=!1,this.loop=!1,this.output=f?t.createGain():null,this.output.gain.value=1,this.channelCount=2,this.channelCountMode="max",this.channelInterpretation="speakers",this.numberOfInputs=0,this.numberOfOutputs=1,this.onended=null}channelCount;channelCountMode;channelInterpretation;onended;source;buffer;context;_createSource(){this.source&&(this.source.onended=null);let e=this.context.createBufferSource();return e.buffer=this.buffer,e.playbackRate.value=this.playbackRate,e.loop=this.loop,e.loopStart=this.loopStart,e.loopEnd=this.loopEnd>0?this.loopEnd:this.buffer.duration,e.connect(this.output),this.source=e,e.onended=()=>{this.source===e&&(this.isPlaying&&!this.loop&&(this.isPlaying=!1,this.pauseTime=0),typeof this.onended=="function"&&this.onended())},e}play({fadeIn:e=0,offset:t=null}={}){let r=t!==null?t:this.pauseTime;if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.source=this._createSource(),this.startTime=this.context.currentTime-r/this.playbackRate,this.source.start(0,r),e>0?(this.output.gain.setValueAtTime(0,this.context.currentTime),this.output.gain.linearRampToValueAtTime(1,this.context.currentTime+e)):this.output.gain.setValueAtTime(1,this.context.currentTime),this.isPlaying=!0}start(e=0,t=0,r){this.isPlaying||(this.source=this._createSource(),this.startTime=this.context.currentTime+e-t/this.playbackRate,r!==void 0?this.source.start(this.context.currentTime+e,t,r):this.source.start(this.context.currentTime+e,t),this.pauseTime=t,this.isPlaying=!0)}pause({fadeOut:e=0}={}){if(!this.isPlaying)return;let t=this.getElapsed()/1e3;if(this.loop&&this.loopEnd>this.loopStart){let r=this.loopEnd-this.loopStart;t=this.loopStart+(t-this.loopStart)%r}if(this.isPlaying=!1,e>0){let r=this.context.currentTime;this.output.gain.setValueAtTime(this.output.gain.value,r),this.output.gain.linearRampToValueAtTime(0,r+e),setTimeout(()=>{if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.pauseTime=t,this.output.gain.setValueAtTime(1,this.context.currentTime)},e*1e3)}else{if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.pauseTime=t}}getElapsed(){return this.isPlaying?(this.context.currentTime-this.startTime)*this.playbackRate*1e3:this.pauseTime*1e3}setSpeed(e){if(e<=0)throw new Error("Playback rate must be positive");let t=this.getElapsed()/1e3;this.playbackRate=e,this.isPlaying&&(this.pause(),this.pauseTime=t,this.play())}setLoop(e=!0){this.loop=e,this.source&&(this.source.loop=e)}loop;playbackRate;startTime;tempGain=null;connect(e,t=0,r=0){if("value"in e)this.output.connect(e,t);else return this.output.connect(e,t,r),e}disconnect(e,t,r){e===void 0?this.output.disconnect():this.output.disconnect(e,t,r)}output;stop(e=0){if(this.notIndependent)return this.pause();if(!this.source)return;let t=this.context.currentTime+e;this.source.stop(t),this.isPlaying=!1,this.notIndependent||(this.pauseTime=0)}pauseTime;isPlaying;notIndependent=!1;loopStart=0;loopEnd=0},X={osc:{enabled:!0,type:"sine",freq:440,detune:0},noise:{enabled:!1,level:.5},ampEnv:{attack:.005,decay:.1,sustain:0,release:.1,volume:.3},pitchEnv:{amount:0,decay:.2},filter:{enabled:!1,type:"lowpass",freq:1200,Q:1,envAmount:0,decay:.2},lfo:{enabled:!1,target:"freq",rate:8,depth:20},duration:.4},x=class n{constructor(e={}){this.ctx=T.audioCtx,this.cfg=structuredClone(X),Object.assign(this.cfg,e)}ctx;cfg;play(e=T.sfxGain){let t=this.ctx,r=t.currentTime,i=this.cfg,a=t.createGain();a.gain.setValueAtTime(1e-4,r);let u=i.ampEnv;a.gain.exponentialRampToValueAtTime(u.volume,r+u.attack),a.gain.exponentialRampToValueAtTime(Math.max(1e-4,u.sustain*u.volume),r+u.attack+u.decay),a.gain.exponentialRampToValueAtTime(1e-4,r+i.duration+u.release);let c=a,s;i.filter.enabled&&(s=t.createBiquadFilter(),s.type=i.filter.type,s.frequency.value=i.filter.freq,s.Q.value=i.filter.Q,s.connect(a),c=s);let o;if(i.osc.enabled){if(o=t.createOscillator(),o.type=i.osc.type,o.frequency.value=i.osc.freq,o.detune.value=i.osc.detune,i.pitchEnv.amount!==0){let h=Math.pow(2,i.pitchEnv.amount/12);o.frequency.exponentialRampToValueAtTime(i.osc.freq*h,r+i.pitchEnv.decay)}o.connect(c),o.start(r),o.stop(r+i.duration+u.release)}let l;if(i.noise.enabled){let h=t.sampleRate*i.duration,d=t.createBuffer(1,h,t.sampleRate),g=d.getChannelData(0);for(let v=0;v<h;v++)g[v]=(Math.random()*2-1)*i.noise.level;l=t.createBufferSource(),l.buffer=d,l.connect(c),l.start(r),l.stop(r+i.duration+u.release)}let m,p;i.lfo.enabled&&o&&(m=t.createOscillator(),m.frequency.value=i.lfo.rate,p=t.createGain(),p.gain.value=i.lfo.depth,m.connect(p),i.lfo.target==="freq"?p.connect(o.frequency):i.lfo.target==="gain"?p.connect(a.gain):i.lfo.target==="filter"&&s&&p.connect(s.frequency),m.start(r),m.stop(r+i.duration)),a.connect(e);let z=[o,l,m,p,s,a],M=r+i.duration+u.release;setTimeout(()=>{z.forEach(h=>h?.disconnect())},(M-t.currentTime)*1e3)}getConfig(){return structuredClone(this.cfg)}setConfig(e){return Object.assign(this.cfg,e),this}getKey(e){return this.cfg[e]}setKey(e,t){return Object.assign(this.cfg[e],t),this}setFreq(e){return this.cfg.osc.freq=e,this}setWave(e){return this.cfg.osc.type=e,this}setVolume(e){return this.cfg.ampEnv.volume=e,this}setAmpEnv(e,t,r,i){return Object.assign(this.cfg.ampEnv,{attack:e,decay:t,sustain:r,release:i}),this}setPitchEnv(e,t){return Object.assign(this.cfg.pitchEnv,{amount:e,decay:t}),this}setNoiseEnabled(e){return this.cfg.noise.enabled=e,this}setNoiseLevel(e){return this.cfg.noise.level=e,this}setFilterEnabled(e){return this.cfg.filter.enabled=e,this}setFilter(e,t,r){return Object.assign(this.cfg.filter,{type:e,freq:t,Q:r,enabled:!0}),this}setLFOEnabled(e){return this.cfg.lfo.enabled=e,this}setLFO(e,t,r){return Object.assign(this.cfg.lfo,{target:e,rate:t,depth:r,enabled:!0}),this}setDuration(e){return this.cfg.duration=e,this}clone(){return new n(structuredClone(this.cfg))}},B=new x({osc:{enabled:!0,type:"square",freq:900,detune:0},ampEnv:{attack:.002,decay:.04,sustain:0,release:.02,volume:.15},duration:.05}),U=new x({osc:{enabled:!0,type:"sine",freq:600,detune:0},ampEnv:{attack:.01,decay:.08,sustain:0,release:.04,volume:.12},duration:.1}),H=new x({osc:{enabled:!0,type:"triangle",freq:500,detune:0},pitchEnv:{amount:12,decay:.15},ampEnv:{attack:.01,decay:.12,sustain:0,release:.05,volume:.25},duration:.18}),$=new x({osc:{enabled:!0,type:"sawtooth",freq:1200,detune:0},pitchEnv:{amount:-24,decay:.3},ampEnv:{attack:.005,decay:.25,sustain:0,release:.05,volume:.3},duration:.35}),W=new x({osc:{enabled:!0,type:"square",freq:180,detune:0},noise:{enabled:!0,level:.4},ampEnv:{attack:.002,decay:.15,sustain:0,release:.05,volume:.35},duration:.2}),le=new Map([["ui_click",B],["ui_hover",U],["jump",H],["laser",$],["hit",W]]);function me(n=12){let e=Date.now().toString(36),t=crypto.getRandomValues(new Uint8Array(n)),r=Array.from(t).map(i=>i.toString(36).padStart(2,"0")).join("");return(e+r).slice(0,n)}function de(n=12){let e=Date.now().toString(36),t=crypto.getRandomValues(new Uint8Array(4)),r=Array.from(t).map(i=>i.toString(36).padStart(2,"0")).join("");return(e+r).slice(0,n)}var L=class{peer=null;key;events={};mbAcc=0;connected=!1;constructor(){this.key=`${j()}_${Date.now()}`}connect(e){e&&(this.peer=e,e.peer=this,this.connected=!0,e.connected=!0),this._emit("open")}isConnected(){return this.connected&&!!this.peer}on(e,t){this.events[e]||(this.events[e]=[]),this.events[e].push(t)}off(e,t){this.events[e]&&(this.events[e]=this.events[e].filter(r=>r!==t))}_emit(e,t){this.events[e]?.forEach(r=>r(t))}send(e,t){if(!this.peer)throw new Error("No peer connected");this.peer._receive(e,t)}_receive(e,t){e?this._emit(e,t):this._emit("message",t)}close(){if(this.connected=!1,this.peer){let e=this.peer;this.peer=null,e.peer=null,e.connected=!1,e._emit("close")}this._emit("close")}getKey(){return this.key}};function j(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let n=new Uint8Array(16);return crypto.getRandomValues(n),n[6]=n[6]&15|64,n[8]=n[8]&63|128,[...n].map(e=>e.toString(16).padStart(2,"0")).join("").replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/,"$1-$2-$3-$4-$5")}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let e=Math.random()*16|0;return(n==="x"?e:e&3|8).toString(16)})}function Q(n){let e=!0;function t(){e&&(n(),requestAnimationFrame(t))}return requestAnimationFrame(t),{clear:()=>e=!1}}function J(n,e,t,r,i){let a=Math.cos(i),u=Math.sin(i),c=[];if(a!==0){let s=(0-n)/a,o=e+s*u;s>0&&o>=0&&o<=r&&c.push({side:"left",t:s})}if(a!==0){let s=(t-n)/a,o=e+s*u;s>0&&o>=0&&o<=r&&c.push({side:"right",t:s})}if(u!==0){let s=(0-e)/u,o=n+s*a;s>0&&o>=0&&o<=t&&c.push({side:"top",t:s})}if(u!==0){let s=(r-e)/u,o=n+s*a;s>0&&o>=0&&o<=t&&c.push({side:"bottom",t:s})}return c.length===0?null:(c.sort((s,o)=>s.t-o.t),c[0])}function Y(n,e){let t;switch(e){case"left":case"right":t=Math.PI-n;break;case"top":case"bottom":t=2*Math.PI-n;break}return(t%(2*Math.PI)+2*Math.PI)%(2*Math.PI)}function pe(n,e,t,r,i){let a=J(n,e,t,r,i);return a?{...a,avoidAngle:Y(i,a.side)}:null}function Z(){return k?!1:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}var fe=Z();0&&(module.exports={DeltaTweenII,ENVIRONMENT,GEmitterMemory,LeaEntityII,LeaEventEmitter,LeaGameII,LeaRendererII,LeaSceneII,LeaSerializers,LeaTickerII,LeaTimeout,LeaUtilsII,LiaAudio,LiaAudioSrc,LiaOscSFX,LiaSFXMap,NOTE_NAMES,RectLeaEntity,Vector2,colToRGBA,defaultSFXConfig,editRGBA,generateUUID,getAvoidAngle,getEnvironment,getNormalizedColor,getRayHit,isInitiallyMobile,isMobile,isNode,isNote,isWeb,parseFillStyle,raycastAvoid,scaleCoord,setAnimInterval,sfxHit,sfxJump,sfxLaser,sfxUIClick,sfxUIHover,shortUID,tinyUID});
package/dist/lea.d.cts CHANGED
@@ -1 +1 @@
1
- export { D as DefaultWSE, d as DeltaTweenII, E as ENVIRONMENT, G as GEmitterMemory, e as LeaEntityII, f as LeaEntitySerializer, g as LeaEntitySerializerArray, h as LeaEntitySerializerEach, i as LeaEventEmitter, a as LeaGameII, b as LeaRendererII, c as LeaSceneII, j as LeaSerializers, k as LeaTickerII, l as LeaTimeout, m as LeaUtilsII, n as LiaAudio, o as LiaAudioSrc, p as LiaOscSFX, q as LiaSFXMap, r as Listener, N as NOTE_NAME, s as NOTE_NAMES, O as OrderedLeaEntitySerializer, t as RayHit, u as RaycastResult, R as RectLeaEntity, S as SFXConfig, v as Side, V as Vector2, w as colToRGBA, x as defaultSFXConfig, y as editRGBA, z as generateUUID, A as getAvoidAngle, B as getEnvironment, C as getNormalizedColor, F as getRayHit, H as isInitiallyMobile, I as isMobile, J as isNode, K as isNote, M as isWeb, P as parseFillStyle, Q as raycastAvoid, T as scaleCoord, U as setAnimInterval, W as sfxHit, X as sfxJump, Y as sfxLaser, Z as sfxUIClick, _ as sfxUIHover, $ as shortUID, a0 as tinyUID } from './lea-DvxsutSf.cjs';
1
+ export { D as DefaultWSE, g as DeltaTweenII, E as ENVIRONMENT, G as GEmitterMemory, h as LeaEntityII, i as LeaEntitySerializer, j as LeaEntitySerializerArray, k as LeaEntitySerializerEach, d as LeaEventEmitter, a as LeaGameII, c as LeaRendererII, f as LeaSceneII, l as LeaSerializers, e as LeaTickerII, b as LeaTimeout, m as LeaUtilsII, n as LiaAudio, o as LiaAudioSrc, p as LiaOscSFX, q as LiaSFXMap, r as Listener, N as NOTE_NAME, s as NOTE_NAMES, O as OrderedLeaEntitySerializer, t as RayHit, u as RaycastResult, R as RectLeaEntity, S as SFXConfig, v as Side, V as Vector2, w as colToRGBA, x as defaultSFXConfig, y as editRGBA, z as generateUUID, A as getAvoidAngle, B as getEnvironment, C as getNormalizedColor, F as getRayHit, H as isInitiallyMobile, I as isMobile, J as isNode, K as isNote, M as isWeb, P as parseFillStyle, Q as raycastAvoid, T as scaleCoord, U as setAnimInterval, W as sfxHit, X as sfxJump, Y as sfxLaser, Z as sfxUIClick, _ as sfxUIHover, $ as shortUID, a0 as tinyUID } from './lea-k7IGP_-W.cjs';
package/dist/lea.d.ts CHANGED
@@ -1 +1 @@
1
- export { D as DefaultWSE, d as DeltaTweenII, E as ENVIRONMENT, G as GEmitterMemory, e as LeaEntityII, f as LeaEntitySerializer, g as LeaEntitySerializerArray, h as LeaEntitySerializerEach, i as LeaEventEmitter, a as LeaGameII, b as LeaRendererII, c as LeaSceneII, j as LeaSerializers, k as LeaTickerII, l as LeaTimeout, m as LeaUtilsII, n as LiaAudio, o as LiaAudioSrc, p as LiaOscSFX, q as LiaSFXMap, r as Listener, N as NOTE_NAME, s as NOTE_NAMES, O as OrderedLeaEntitySerializer, t as RayHit, u as RaycastResult, R as RectLeaEntity, S as SFXConfig, v as Side, V as Vector2, w as colToRGBA, x as defaultSFXConfig, y as editRGBA, z as generateUUID, A as getAvoidAngle, B as getEnvironment, C as getNormalizedColor, F as getRayHit, H as isInitiallyMobile, I as isMobile, J as isNode, K as isNote, M as isWeb, P as parseFillStyle, Q as raycastAvoid, T as scaleCoord, U as setAnimInterval, W as sfxHit, X as sfxJump, Y as sfxLaser, Z as sfxUIClick, _ as sfxUIHover, $ as shortUID, a0 as tinyUID } from './lea-DvxsutSf.js';
1
+ export { D as DefaultWSE, g as DeltaTweenII, E as ENVIRONMENT, G as GEmitterMemory, h as LeaEntityII, i as LeaEntitySerializer, j as LeaEntitySerializerArray, k as LeaEntitySerializerEach, d as LeaEventEmitter, a as LeaGameII, c as LeaRendererII, f as LeaSceneII, l as LeaSerializers, e as LeaTickerII, b as LeaTimeout, m as LeaUtilsII, n as LiaAudio, o as LiaAudioSrc, p as LiaOscSFX, q as LiaSFXMap, r as Listener, N as NOTE_NAME, s as NOTE_NAMES, O as OrderedLeaEntitySerializer, t as RayHit, u as RaycastResult, R as RectLeaEntity, S as SFXConfig, v as Side, V as Vector2, w as colToRGBA, x as defaultSFXConfig, y as editRGBA, z as generateUUID, A as getAvoidAngle, B as getEnvironment, C as getNormalizedColor, F as getRayHit, H as isInitiallyMobile, I as isMobile, J as isNode, K as isNote, M as isWeb, P as parseFillStyle, Q as raycastAvoid, T as scaleCoord, U as setAnimInterval, W as sfxHit, X as sfxJump, Y as sfxLaser, Z as sfxUIClick, _ as sfxUIHover, $ as shortUID, a0 as tinyUID } from './lea-k7IGP_-W.js';
package/dist/lea.js CHANGED
@@ -1 +1 @@
1
- var y=class{#e=new Map;constructor(){this.#e=new Map}on(e,t){let r=this.#e.get(e)||[];return r.push(t),this.#e.set(e,r),this}once(e,t){let r=(...i)=>{this.off(e,r),t(...i)};return this.on(e,r),this}off(e,t){let r=this.#e.get(e);if(!r)return this;let i=r.indexOf(t);return i>=0&&r.splice(i,1),this}emit(e,...t){let r=this.#e.get(e);if(!r||r.length===0){if(e==="error")throw t[0];return!1}return r.slice().forEach(i=>i(...t)),!0}removeAllListeners(e){return e?this.#e.delete(e):this.#e.clear(),this}listenerCount(e){return this.#e.get(e)?.length??0}},F=class extends y{canvas;ctx;running;_rafId;_fps;_frameCount;_fpsTimer;_lastFrameTime;constructor(e,{viewportWidth:t,viewportHeight:r,cameraWidth:i,cameraHeight:a}={}){if(!b)throw new Error("Web-Only");super(),this.canvas=e,this.ctx=e.getContext("2d"),this.automatic=!0,this.#e=t??e.width,this.#t=r??e.height,this.#n=i??e.width,this.#r=a??e.height,this.running=!1,this._rafId=null,this._loop=this._loop.bind(this),this.updateCanvasResolution(),this._fps=60,this._frameCount=0,this._fpsTimer=0}automatic;retransform(){this.ctx.setTransform(1,0,0,1,0,0);let e=this.#n/this.#e,t=this.#r/this.#t;this.ctx.translate(this.#n/2,this.#r/2),this.ctx.scale(e,t),this.ctx.translate(-this.#e/2,-this.#t/2)}#e=0;#t=0;#n=0;#r=0;get viewportWidth(){return this.#e}set viewportWidth(e){this.#e=e,this.retransform()}get width(){return this.#e}get height(){return this.#t}get centerX(){return this.#e/2}get centerY(){return this.#t/2}get left(){return 0}get top(){return 0}get right(){return this.#e}get bottom(){return this.#t}get viewportHeight(){return this.#t}set viewportHeight(e){this.#t=e,this.retransform()}get cameraWidth(){return this.#n}set cameraWidth(e){this.#n=e,this.updateCanvasResolution(),this.retransform()}get cameraHeight(){return this.#r}set cameraHeight(e){this.#r=e,this.updateCanvasResolution(),this.retransform()}updateCanvasResolution(){this.canvas.width=this.#n,this.canvas.height=this.#r}applyTransform(){this.retransform()}get FPS(){return this._fps}_loop(){this.automatic&&this.update(),this._rafId=requestAnimationFrame(this._loop)}update(){if(!this.running||!b)return;let e=performance.now(),t=(e-(this._lastFrameTime??e))/1e3;this._lastFrameTime=e,this._frameCount++,this._fpsTimer+=t,this._fpsTimer>=1&&(this._fps=Math.round(this._frameCount/this._fpsTimer),this._frameCount=0,this._fpsTimer=0),this.ctx.clearRect(0,0,this.#n,this.#r),this.emit("draw",this.ctx)}start(){if(!this.running){if(!b||typeof globalThis.requestAnimationFrame>"u")throw new Error("Raf is not supported");this.running=!0,this._rafId=requestAnimationFrame(this._loop)}}stop(){if(!b||typeof globalThis.requestAnimationFrame>"u")throw new Error("Raf is not supported");this.running=!1,this._rafId!==null&&(cancelAnimationFrame(this._rafId),this._rafId=null)}},I=class extends y{setNow(e){this.#e=e}#e=0;__intervalId=null;__lastTime=0;constructor(e=16){super(),this.#t=e,this.speedHackDT=1}speedHackDT;get isRaf(){return this.tickInterval===1/0}#t=15;get tickInterval(){return this.#t}set tickInterval(e){this.#t=e,this.__intervalId&&(this.stop(),this.start())}now(){return this.#e}__tick(){let e=performance.now(),t=(e-this.__lastTime)/1e3*this.speedHackDT;this.__lastTime=e,this.#e+=t*1e3,this.emit("tick",t)}createTimeout(e){return new A(e,this)}createTween(e,t=()=>{}){let r=new _(e),i=(a=0)=>{if(r.finished){this.off("tick",i);return}r.update(a)};return r.on("finish",()=>{this.off("tick",i)}),r.on("delta",a=>{t(a)}),this.on("tick",i),r}start(){this.__intervalId===null&&(this.__lastTime=performance.now(),this.__intervalId=b&&!isFinite(this.tickInterval)?j(()=>this.__tick()).clear:setInterval(()=>this.__tick(),this.tickInterval))}stop(){this.__intervalId!==null&&(typeof this.__intervalId=="function"?this.__intervalId():clearInterval(this.__intervalId)),this.__intervalId=null}getSineMod(e,t=0){return .5+.5*Math.sin((this.now()%e/e+t)*2*Math.PI)}},z;(C=>{function n(h){return h===!0?1:0}C.booleanExport=n;function e(h){return h===0?!1:h===1}C.booleanImport=e;function t(h){return`${h.x}|${h.y}`}C.vec2Export=t;function r(h){let[d,g]=h.split("|"),x=parseFloat(d),k=parseFloat(g);if(isNaN(x)||isNaN(k))throw new Error(`Invalid Vector2 string: ${h}`);return new M(x,k)}C.vec2Import=r,C.booleanMap={mapExport:n,mapImport:e};function a(h){return d=>Number(d.toFixed(h))}C.createRounder=a;function u(h=10){return{mapExport(d){return Math.round(d/h)},mapImport(d){return d*h}}}C.createLowPrecision=u;function c(h){return Math.round(h)}C.lightWeightRounder=c;function s(h=100){return{mapExport(d){return Math.round(d*h)},mapImport(d){return d/h}}}C.createPercent=s;function o(h){let d=new Map(Object.entries(h));return{mapExport:g=>d.get(g)??null,mapImport:g=>Array.from(d.entries()).find(([x,k])=>k===g)?.[0]??null}}C.createLookup=o;function l(h){let d=h*(180/Math.PI);return Math.round((d%360+360)%360)}C.radToDeg=l;function m(h){return h*(Math.PI/180)}C.degToRad=m,C.angleRadToDeg={mapExport:l,mapImport:m};function R(h=10){let d=u(h);return{mapExport(g){return d.mapExport(l(g))},mapImport(g){return d.mapImport(m(g))}}}C.createLowPrecisionRadToDeg=R})(z||={});var E=class n extends y{name="";scaleRotate=0;scale=1;constructor(e,t=0,r=0){super(),this.autoTranslate=!1,this.name=e,this.z=0,this.___pos=new M(t,r),this.nonSerializableProperties=[],this.nonSerializableProperties.push("___pos","autoTranslate","arraySerializeMap"),this.forceSerializableProperties=[],this.forceSerializableProperties.push("x","y")}arraySerializeMap;autoTranslate;z;___pos;nonSerializableProperties;forceSerializableProperties;get pos(){return this.___pos}get x(){return this.pos.x}get y(){return this.pos.y}set x(e){this.pos.x=e}set y(e){this.pos.y=e}handleUpdate(e){if(this.update)try{this.emit("update",e),this.update(e)}catch(t){this.emit("error",t)}}handleDraw(e){if(!(S||!this.draw)){e.save(),this.autoTranslate&&e.translate(this.x,this.y);try{this.emit("draw",e),this.draw(e)}catch(t){this.emit("error",t)}e.restore()}}serialize(){if(Array.isArray(this.arraySerializeMap))return this.arraySerializeMap.map(([i,{mapExport:a}])=>{let u=Reflect.get(this,i);return a?a(u):u});let e=["_events","_eventsCount","_maxListeners","nonSerializableProperties","forceSerializableProperties"],t=[...Reflect.ownKeys(this),...this.forceSerializableProperties].filter(i=>!this.nonSerializableProperties.includes(i)&&!e.includes(i.toString())),r=Object.fromEntries(t.map(i=>{let a=Reflect.get(this,i);if(S&&typeof a=="number"){let u=a.toString().split("."),s=(u[1]?u[1].length:0)>2?Number(a.toFixed(2)):a;return[i,s]}return[i,a]}));return JSON.parse(JSON.stringify(r))}toLocal(e){return e.subtract(this.pos)}toWorld(e){return e.add(this.pos)}deserializeArray(e){return n.deserializeArray(this.arraySerializeMap,e)}static deserializeArray(e,t){if(!e||!Array.isArray(t))return t;let r={};for(let i=0;i<t.length;i++){let a=e[i];if(!a)break;let[u,{mapImport:c}]=a,s=t[i];if(c&&(s=c(s)),typeof u!="string")break;try{Reflect.set(r,u,s)}catch(o){console.error(o)}}return r}},P=class extends y{name="";entities=new Map;paused=!0;constructor(e){super(),this.name=e}handleUpdate(e){if(!this.paused){this.emit("update",e);for(let t of this.entities.values())t.handleUpdate(e)}}handleDraw(e){if(!S&&!this.paused){this.emit("draw",e);for(let t of[...this.entities.values()].sort((r,i)=>r.z-i.z))t.handleDraw(e)}}addEntity(e){if(!(e instanceof E))throw new Error("invalid entity");if(!e.name)throw new Error("Entity must have a name.");this.entities.set(e.name,e)}removeEntity(e){if(!(e instanceof E))throw new Error("invalid entity");this.entities.delete(e.name)}getEntity(e){return this.entities.get(e)}},V=class{scenes;ticker;get centerX(){return this.width/2}get centerY(){return this.height/2}get left(){return 0}get top(){return 0}get right(){return this.width}get bottom(){return this.height}width;height;constructor(e,t,r=16){this.ticker=new I(r),this.scenes=new Map,this.width=e,this.height=t,this.ticker.on("tick",i=>{for(let a of this.scenes.values())a.paused||a.handleUpdate(i)})}addScene(e){if(!e.name)throw new Error("Scene must have a name.");e.paused=!1,this.scenes.set(e.name,e)}removeScene(e){e&&(e.paused=!0),this.scenes.delete(e.name)}now(){return this.ticker.now()}start(){this.ticker.start()}stop(){this.ticker.stop()}},f={lerp(n,e,t){return n+(e-n)*t},clamp(n,e,t){return Math.min(t,Math.max(e,n))},clamp01(n){return Math.min(1,Math.max(0,n))},easeLinear(n){return n},easeInQuad(n){return n*n},easeOutQuad(n){return 1-(1-n)*(1-n)},easeInOutQuad(n){return n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2},easeInSine(n){return 1-Math.cos(n*Math.PI/2)},easeOutSine(n){return Math.sin(n*Math.PI/2)},easeInOutSine(n){return-(Math.cos(Math.PI*n)-1)/2},easeInExpo(n){return n===0?0:Math.pow(2,10*n-10)},easeOutExpo(n){return n===1?1:1-Math.pow(2,-10*n)},easeInOutExpo(n){return n===0?0:n===1?1:n<.5?Math.pow(2,20*n-10)/2:(2-Math.pow(2,-20*n+10))/2},smoothstep(n){return n=f.clamp(n,0,1),n*n*(3-2*n)},randomLerp(n,e){return f.lerp(n,e,Math.random())},randomInt(n,e){return Math.floor(Math.random()*(e-n+1))+n},randomArrayValue(n){return n[f.randomInt(0,n.length-1)]},createBezier(n,e,t,r){function i(c,s,o,l,m){let p=1-c;return p*p*p*s+3*p*p*c*o+3*p*c*c*l+c*c*c*m}function a(c,s,o,l,m){let p=1-c;return 3*p*p*(o-s)+6*p*c*(l-o)+3*c*c*(m-l)}function u(c){let s=c;for(let o=0;o<6;o++){let l=i(s,0,n,t,1),m=a(s,0,n,t,1);if(m===0)break;s-=(l-c)/m}return f.clamp(s,0,1)}return function(s){s=f.clamp(s,0,1);let o=u(s);return i(o,0,e,r,1)}},lengthSquared(...n){return n.reduce((e,t)=>e+t*t,0)},normalizeRad(n){let e=2*Math.PI;return n=n%e,n<0&&(n+=e),n},angleInvertY(n){return f.normalizeRad(-n)},degToRadFlipY(n){return f.angleInvertY(n*Math.PI/180)},minimalAngularDirection(n,e){n=f.normalizeRad(n),e=f.normalizeRad(e);let t=f.normalizeRad(e-n),r=f.normalizeRad(n-e);return t<=r?1:-1}},_=class extends y{constructor({delta:e,ms:t,easing:r}){super(),this.delta=e,this.duration=t,this.elapsed=0,this.easing=r??(i=>i),this.lastValue=0,this.finished=!1}delta;duration;elapsed;lastValue;finished;easing;update(e){this.elapsed+=e*1e3;let t=f.clamp(this.elapsed/this.duration,0,1),r=this.easing(t),i=this.delta*r,a=i-this.lastValue;this.lastValue=i,this.emit("delta",a),t>=1&&(this.finished=!0,this.emit("finish",void 0))}},K=class extends E{constructor(e,t=0,r=0,i=50,a=50){super(e,t,r),this.width=i,this.height=a}width;height;get left(){return this.x-this.width/2}set left(e){this.x=e+this.width/2}get right(){return this.x+this.width/2}set right(e){this.x=e-this.width/2}get top(){return this.y-this.height/2}set top(e){this.y=e+this.height/2}get bottom(){return this.y+this.height/2}set bottom(e){this.y=e-this.height/2}get lx(){return 0}get ly(){return 0}get lleft(){return-this.width/2}get lright(){return this.width/2}get ltop(){return-this.height/2}get lbottom(){return this.height/2}isCollidingWith(e){return!(this.right<e.left||this.left>e.right||this.bottom<e.top||this.top>e.bottom)}color="rgba(0, 0, 255, 0.3)";draw(e){e.translate(this.x,this.y),e.rotate(this.scaleRotate),e.fillStyle=this.color,e.fillRect(-this.width/2,-this.height/2,this.width,this.height)}},A=class extends y{duration;ticker;elapsed;finished;_resolve;promise;_timeoutId;constructor(e,t=null){super(),this.duration=e,this.ticker=t,this.elapsed=0,this.finished=!1,this._resolve=null,this.promise=new Promise(r=>this._resolve=r),this.update=this.update.bind(this),this.ticker&&this.ticker.on("tick",this.update)}update(e=0){this.finished||(this.elapsed+=e*1e3,this.elapsed>=this.duration&&this.finish())}finish(){this.finished||(this.finished=!0,this.emit("finish",void 0),this._resolve&&this._resolve(),this.ticker&&this.ticker.off("tick",this.update))}start(){return this.ticker||(this._timeoutId=setTimeout(()=>this.finish(),this.duration)),this}cancel(){this.finished||(this.finished=!0,!this.ticker&&this._timeoutId!=null&&clearTimeout(this._timeoutId),this.ticker&&this.ticker.off("tick",this.update))}then(e,t){return this.promise.then(e,t)}after(e,t){return this.promise.then(e,t)}},M=class n{constructor(e=0,t=0){this.x=e,this.y=t}x;y;toJSON(){return{x:this.x,y:this.y,vec2:!0}}static isVec2(e){return e&&typeof e=="object"&&"x"in e&&"y"in e&&e.vec2===!0}static fromSerialized(e){return this.isVec2(e)?new this(e.x,e.y):null}rotate(e){let t=Math.cos(e),r=Math.sin(e);return new n(this.x*t-this.y*r,this.x*r+this.y*t)}static from(e){return new n(Math.cos(e),Math.sin(e))}get angle(){return Math.atan2(this.y,this.x)}get length(){return Math.hypot(this.x,this.y)}get lengthSquared(){return this.x*this.x+this.y*this.y}normalized(){let e=this.length;return e===0?new n(0,0):new n(this.x/e,this.y/e)}project(e){return e.scale(this.dotNormalized(e))}reflect(e){let t=this.dot(e);return this.subtract(e.scale(2*t))}dotNormalized(e){let t=this.normalized(),r=e.normalized();return t.x*r.x+t.y*r.y}lengthSquaredTo(e){let t=this.x-e.x,r=this.y-e.y;return t*t+r*r}dot(e){return this.x*e.x+this.y*e.y}distanceTo(e){return Math.hypot(this.x-e.x,this.y-e.y)}distanceToCheap(e){let t=this.x-e.x,r=this.y-e.y;return t*t+r*r}directionTo(e){return new n(e.x-this.x,e.y-this.y).normalized()}add(e){return new n(this.x+e.x,this.y+e.y)}addRaw(e){return new n(this.x+e,this.y+e)}overwite(e){this.x=e.x,this.y=e.y}subtract(e){return new n(this.x-e.x,this.y-e.y)}scale(e){return new n(this.x*e,this.y*e)}toString(){return`Vector2(${this.x}, ${this.y})`}clone(){return new n(this.x,this.y)}};function Z(n){let e=/^rgba?\(([^)]+)\)$/,t=n.match(e);if(t){let[r,i,a,u=1]=t[1].split(",").map(c=>parseFloat(c));return{r:Math.max(0,Math.min(255,Math.floor(r))),g:Math.max(0,Math.min(255,Math.floor(i))),b:Math.max(0,Math.min(255,Math.floor(a))),a:Math.max(0,Math.min(1,Math.floor(u*255)/255))}}return G(n)}function ee(n){return`rgba(${n.r}, ${n.g}, ${n.b}, ${n.a})`}function G(n){if(n=n.trim().toLowerCase(),n[0]==="#"){let t,r,i;if(n.length===7)t=parseInt(n.slice(1,3),16),r=parseInt(n.slice(3,5),16),i=parseInt(n.slice(5,7),16);else if(n.length===4)t=parseInt(n[1]+n[1],16),r=parseInt(n[2]+n[2],16),i=parseInt(n[3]+n[3],16);else throw new Error("Invalid hex color");return{r:t,g:r,b:i,a:1}}let e=n.match(/^rgba?\s*\(\s*(\d+)[, ]\s*(\d+)[, ]\s*(\d+)(?:[, ]\s*([\d.]+))?\s*\)$/);if(e)return{r:parseInt(e[1]),g:parseInt(e[2]),b:parseInt(e[3]),a:e[4]!==void 0?parseFloat(e[4]):1};throw new Error("Unsupported fillStyle format")}function te(n,{r:e,g:t,b:r,a:i}={}){let[a,u,c,s,o]=n.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]*)\)?/)||[];return`rgba(${e??u}, ${t??c}, ${r??s}, ${i??(o||1)})`}function ne(n,e,t){return t+(n-t)*e}function O(){return typeof process<"u"&&process.release?.name==="node"?"node":typeof window<"u"||typeof self<"u"?"web":"unknown"}var N=O(),S=N==="node",b=N==="web",T=class n{static unlock(){b&&this.audioCtx.state!=="running"&&this.audioCtx.resume()}static audioCtx=b?new AudioContext:null;static masterGain=b?this.audioCtx.createGain():null;static musicGain=b?this.audioCtx.createGain():null;static sfxGain=b?this.audioCtx.createGain():null;static{b&&(this.masterGain.gain.value=1,this.musicGain.gain.value=1,this.sfxGain.gain.value=1,this.sfxGain.connect(this.masterGain),this.musicGain.connect(this.masterGain),this.masterGain.connect(this.audioCtx.destination))}static get SFX_VOLUME(){return this.sfxGain.gain.value}static get MUSIC_VOLUME(){return this.musicGain.gain.value}static get VOLUME(){return this.masterGain.gain.value}static set SFX_VOLUME(e){this.sfxGain.gain.value=e}static set MUSIC_VOLUME(e){this.musicGain.gain.value=e}static set VOLUME(e){this.masterGain.gain.value=e}static noteToHz(e){return this.tuningFreq*Math.pow(2,(e-9)/12)}static tuningFreq=440;static audioBufferCache=new Map;static loops=new Map;static sfsx=new Map;static loopIdCounter=0;static CACHE_NAME="lia-audio-cache-v1";static async preLoad(e){if(this.audioBufferCache.has(e))return this.audioBufferCache.get(e);let t=n.CACHE_NAME,r,i;if(typeof caches<"u"&&(i=await caches.open(t),r=await i.match(e)),!r){if(r=await fetch(e),!r.ok)throw new Error(`Failed to fetch ${e}`);i&&await i.put(e,r.clone())}let a=await r.arrayBuffer(),u=await this.audioCtx.decodeAudioData(a);return this.audioBufferCache.set(e,u),u}static async getOnlyDownloadedCache(e){let t=n.CACHE_NAME;return await(await caches.open(t)).match(e)}static getCached(e){return this.audioBufferCache.get(e)||null}static async playSound(e,t=.2,r=1,i=!0){try{this.sfsx.has(e)&&this.sfsx.get(e).source.stop(),this.audioBufferCache.has(e)||await this.preLoad(e);let a=this.getCached(e);if(!a)return;let u=new w(a);u.buffer=a;let c=1-.12,s=1+.12;u.playbackRate=r??c+Math.random()*(s-c);let o=this.audioCtx.createGain();o.gain.value=t,u.tempGain=o,u.connect(o),o.connect(this.sfxGain),u.onended=()=>{u.disconnect(),o.disconnect()},u.start(),i&&this.sfsx.set(e,{source:u,gain:o})}catch(a){console.error(a)}}static async playLoop(e,t=1,{loopStart:r=0,loopEnd:i=null,exclusive:a=!0,skipMS:u=0}={}){if(a)for(let m of this.loops.keys())this.stopLoop(m);this.audioBufferCache.has(e)||await this.preLoad(e);let c=this.getCached(e);if(!c)return;let s=new w(c);s.buffer=c,s.loop=!0,typeof r=="number"&&(s.loopStart=r),typeof i=="number"&&(s.loopEnd=i);let o=this.audioCtx.createGain();o.gain.value=t,s.tempGain=o,s.playbackRate=1,s.onended=()=>{s.disconnect(),o.disconnect()},s.connect(o),o.connect(this.musicGain),s.start(0,u/1e3);let l=++this.loopIdCounter;return this.loops.set(l,{source:s,gain:o}),l}static stopLoop(e){let t=this.loops.get(e);t&&(t.source.stop(),t.source.notIndependent||(t.source.disconnect(),t.gain.disconnect()),this.loops.delete(e))}static async createLiaSource(e,{volume:t=1,speed:r=1,loop:i=!1,loopStart:a=0,loopEnd:u=null,isMusic:c=!1,gain:s=null}={}){try{this.audioBufferCache.has(e)||await this.preLoad(e);let o=this.getCached(e);if(!o)return null;let l=new w(o);l.loop=i,l.loopStart=a,l.loopEnd=typeof u=="number"?u:o.duration,l.playbackRate=r;let m=this.audioCtx.createGain();return m.gain.value=t,l.connect(m),l.tempGain=m,m.connect(s||(c?this.musicGain:this.sfxGain)),l.onended=()=>{l.disconnect(),m.disconnect()},l}catch(o){return console.error("Failed to create LiaAudioSrc:",o),null}}},q=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];function re(n){return q.includes(n)}var w=class{numberOfInputs;numberOfOutputs;constructor(e,t=T.audioCtx){this.context=t,this.buffer=e,this.source=null,this.startTime=0,this.pauseTime=0,this.playbackRate=1,this.isPlaying=!1,this.loop=!1,this.output=b?t.createGain():null,this.output.gain.value=1,this.channelCount=2,this.channelCountMode="max",this.channelInterpretation="speakers",this.numberOfInputs=0,this.numberOfOutputs=1,this.onended=null}channelCount;channelCountMode;channelInterpretation;onended;source;buffer;context;_createSource(){this.source&&(this.source.onended=null);let e=this.context.createBufferSource();return e.buffer=this.buffer,e.playbackRate.value=this.playbackRate,e.loop=this.loop,e.loopStart=this.loopStart,e.loopEnd=this.loopEnd>0?this.loopEnd:this.buffer.duration,e.connect(this.output),this.source=e,e.onended=()=>{this.source===e&&(this.isPlaying&&!this.loop&&(this.isPlaying=!1,this.pauseTime=0),typeof this.onended=="function"&&this.onended())},e}play({fadeIn:e=0,offset:t=null}={}){let r=t!==null?t:this.pauseTime;if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.source=this._createSource(),this.startTime=this.context.currentTime-r/this.playbackRate,this.source.start(0,r),e>0?(this.output.gain.setValueAtTime(0,this.context.currentTime),this.output.gain.linearRampToValueAtTime(1,this.context.currentTime+e)):this.output.gain.setValueAtTime(1,this.context.currentTime),this.isPlaying=!0}start(e=0,t=0,r){this.isPlaying||(this.source=this._createSource(),this.startTime=this.context.currentTime+e-t/this.playbackRate,r!==void 0?this.source.start(this.context.currentTime+e,t,r):this.source.start(this.context.currentTime+e,t),this.pauseTime=t,this.isPlaying=!0)}pause({fadeOut:e=0}={}){if(!this.isPlaying)return;let t=this.getElapsed()/1e3;if(this.loop&&this.loopEnd>this.loopStart){let r=this.loopEnd-this.loopStart;t=this.loopStart+(t-this.loopStart)%r}if(this.isPlaying=!1,e>0){let r=this.context.currentTime;this.output.gain.setValueAtTime(this.output.gain.value,r),this.output.gain.linearRampToValueAtTime(0,r+e),setTimeout(()=>{if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.pauseTime=t,this.output.gain.setValueAtTime(1,this.context.currentTime)},e*1e3)}else{if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.pauseTime=t}}getElapsed(){return this.isPlaying?(this.context.currentTime-this.startTime)*this.playbackRate*1e3:this.pauseTime*1e3}setSpeed(e){if(e<=0)throw new Error("Playback rate must be positive");let t=this.getElapsed()/1e3;this.playbackRate=e,this.isPlaying&&(this.pause(),this.pauseTime=t,this.play())}setLoop(e=!0){this.loop=e,this.source&&(this.source.loop=e)}loop;playbackRate;startTime;tempGain=null;connect(e,t=0,r=0){if("value"in e)this.output.connect(e,t);else return this.output.connect(e,t,r),e}disconnect(e,t,r){e===void 0?this.output.disconnect():this.output.disconnect(e,t,r)}output;stop(e=0){if(this.notIndependent)return this.pause();if(!this.source)return;let t=this.context.currentTime+e;this.source.stop(t),this.isPlaying=!1,this.notIndependent||(this.pauseTime=0)}pauseTime;isPlaying;notIndependent=!1;loopStart=0;loopEnd=0},D={osc:{enabled:!0,type:"sine",freq:440,detune:0},noise:{enabled:!1,level:.5},ampEnv:{attack:.005,decay:.1,sustain:0,release:.1,volume:.3},pitchEnv:{amount:0,decay:.2},filter:{enabled:!1,type:"lowpass",freq:1200,Q:1,envAmount:0,decay:.2},lfo:{enabled:!1,target:"freq",rate:8,depth:20},duration:.4},v=class n{constructor(e={}){this.ctx=T.audioCtx,this.cfg=structuredClone(D),Object.assign(this.cfg,e)}ctx;cfg;play(e=T.sfxGain){let t=this.ctx,r=t.currentTime,i=this.cfg,a=t.createGain();a.gain.setValueAtTime(1e-4,r);let u=i.ampEnv;a.gain.exponentialRampToValueAtTime(u.volume,r+u.attack),a.gain.exponentialRampToValueAtTime(Math.max(1e-4,u.sustain*u.volume),r+u.attack+u.decay),a.gain.exponentialRampToValueAtTime(1e-4,r+i.duration+u.release);let c=a,s;i.filter.enabled&&(s=t.createBiquadFilter(),s.type=i.filter.type,s.frequency.value=i.filter.freq,s.Q.value=i.filter.Q,s.connect(a),c=s);let o;if(i.osc.enabled){if(o=t.createOscillator(),o.type=i.osc.type,o.frequency.value=i.osc.freq,o.detune.value=i.osc.detune,i.pitchEnv.amount!==0){let h=Math.pow(2,i.pitchEnv.amount/12);o.frequency.exponentialRampToValueAtTime(i.osc.freq*h,r+i.pitchEnv.decay)}o.connect(c),o.start(r),o.stop(r+i.duration+u.release)}let l;if(i.noise.enabled){let h=t.sampleRate*i.duration,d=t.createBuffer(1,h,t.sampleRate),g=d.getChannelData(0);for(let x=0;x<h;x++)g[x]=(Math.random()*2-1)*i.noise.level;l=t.createBufferSource(),l.buffer=d,l.connect(c),l.start(r),l.stop(r+i.duration+u.release)}let m,p;i.lfo.enabled&&o&&(m=t.createOscillator(),m.frequency.value=i.lfo.rate,p=t.createGain(),p.gain.value=i.lfo.depth,m.connect(p),i.lfo.target==="freq"?p.connect(o.frequency):i.lfo.target==="gain"?p.connect(a.gain):i.lfo.target==="filter"&&s&&p.connect(s.frequency),m.start(r),m.stop(r+i.duration)),a.connect(e);let R=[o,l,m,p,s,a],C=r+i.duration+u.release;setTimeout(()=>{R.forEach(h=>h?.disconnect())},(C-t.currentTime)*1e3)}getConfig(){return structuredClone(this.cfg)}setConfig(e){return Object.assign(this.cfg,e),this}getKey(e){return this.cfg[e]}setKey(e,t){return Object.assign(this.cfg[e],t),this}setFreq(e){return this.cfg.osc.freq=e,this}setWave(e){return this.cfg.osc.type=e,this}setVolume(e){return this.cfg.ampEnv.volume=e,this}setAmpEnv(e,t,r,i){return Object.assign(this.cfg.ampEnv,{attack:e,decay:t,sustain:r,release:i}),this}setPitchEnv(e,t){return Object.assign(this.cfg.pitchEnv,{amount:e,decay:t}),this}setNoiseEnabled(e){return this.cfg.noise.enabled=e,this}setNoiseLevel(e){return this.cfg.noise.level=e,this}setFilterEnabled(e){return this.cfg.filter.enabled=e,this}setFilter(e,t,r){return Object.assign(this.cfg.filter,{type:e,freq:t,Q:r,enabled:!0}),this}setLFOEnabled(e){return this.cfg.lfo.enabled=e,this}setLFO(e,t,r){return Object.assign(this.cfg.lfo,{target:e,rate:t,depth:r,enabled:!0}),this}setDuration(e){return this.cfg.duration=e,this}clone(){return new n(structuredClone(this.cfg))}},X=new v({osc:{enabled:!0,type:"square",freq:900,detune:0},ampEnv:{attack:.002,decay:.04,sustain:0,release:.02,volume:.15},duration:.05}),B=new v({osc:{enabled:!0,type:"sine",freq:600,detune:0},ampEnv:{attack:.01,decay:.08,sustain:0,release:.04,volume:.12},duration:.1}),U=new v({osc:{enabled:!0,type:"triangle",freq:500,detune:0},pitchEnv:{amount:12,decay:.15},ampEnv:{attack:.01,decay:.12,sustain:0,release:.05,volume:.25},duration:.18}),H=new v({osc:{enabled:!0,type:"sawtooth",freq:1200,detune:0},pitchEnv:{amount:-24,decay:.3},ampEnv:{attack:.005,decay:.25,sustain:0,release:.05,volume:.3},duration:.35}),$=new v({osc:{enabled:!0,type:"square",freq:180,detune:0},noise:{enabled:!0,level:.4},ampEnv:{attack:.002,decay:.15,sustain:0,release:.05,volume:.35},duration:.2}),ie=new Map([["ui_click",X],["ui_hover",B],["jump",U],["laser",H],["hit",$]]);function se(n=12){let e=Date.now().toString(36),t=crypto.getRandomValues(new Uint8Array(n)),r=Array.from(t).map(i=>i.toString(36).padStart(2,"0")).join("");return(e+r).slice(0,n)}function ae(n=12){let e=Date.now().toString(36),t=crypto.getRandomValues(new Uint8Array(4)),r=Array.from(t).map(i=>i.toString(36).padStart(2,"0")).join("");return(e+r).slice(0,n)}var L=class{peer=null;key;events={};mbAcc=0;connected=!1;constructor(){this.key=`${W()}_${Date.now()}`}connect(e){e&&(this.peer=e,e.peer=this,this.connected=!0,e.connected=!0),this._emit("open")}isConnected(){return this.connected&&!!this.peer}on(e,t){this.events[e]||(this.events[e]=[]),this.events[e].push(t)}off(e,t){this.events[e]&&(this.events[e]=this.events[e].filter(r=>r!==t))}_emit(e,t){this.events[e]?.forEach(r=>r(t))}send(e,t){if(!this.peer)throw new Error("No peer connected");this.peer._receive(e,t)}_receive(e,t){e?this._emit(e,t):this._emit("message",t)}close(){if(this.connected=!1,this.peer){let e=this.peer;this.peer=null,e.peer=null,e.connected=!1,e._emit("close")}this._emit("close")}getKey(){return this.key}};function W(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let n=new Uint8Array(16);return crypto.getRandomValues(n),n[6]=n[6]&15|64,n[8]=n[8]&63|128,[...n].map(e=>e.toString(16).padStart(2,"0")).join("").replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/,"$1-$2-$3-$4-$5")}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let e=Math.random()*16|0;return(n==="x"?e:e&3|8).toString(16)})}function j(n){let e=!0;function t(){e&&(n(),requestAnimationFrame(t))}return requestAnimationFrame(t),{clear:()=>e=!1}}function Q(n,e,t,r,i){let a=Math.cos(i),u=Math.sin(i),c=[];if(a!==0){let s=(0-n)/a,o=e+s*u;s>0&&o>=0&&o<=r&&c.push({side:"left",t:s})}if(a!==0){let s=(t-n)/a,o=e+s*u;s>0&&o>=0&&o<=r&&c.push({side:"right",t:s})}if(u!==0){let s=(0-e)/u,o=n+s*a;s>0&&o>=0&&o<=t&&c.push({side:"top",t:s})}if(u!==0){let s=(r-e)/u,o=n+s*a;s>0&&o>=0&&o<=t&&c.push({side:"bottom",t:s})}return c.length===0?null:(c.sort((s,o)=>s.t-o.t),c[0])}function J(n,e){let t;switch(e){case"left":case"right":t=Math.PI-n;break;case"top":case"bottom":t=2*Math.PI-n;break}return(t%(2*Math.PI)+2*Math.PI)%(2*Math.PI)}function oe(n,e,t,r,i){let a=Q(n,e,t,r,i);return a?{...a,avoidAngle:J(i,a.side)}:null}function Y(){return S?!1:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}var ue=Y();export{_ as DeltaTweenII,N as ENVIRONMENT,L as GEmitterMemory,E as LeaEntityII,y as LeaEventEmitter,V as LeaGameII,F as LeaRendererII,P as LeaSceneII,z as LeaSerializers,I as LeaTickerII,A as LeaTimeout,f as LeaUtilsII,T as LiaAudio,w as LiaAudioSrc,v as LiaOscSFX,ie as LiaSFXMap,q as NOTE_NAMES,K as RectLeaEntity,M as Vector2,ee as colToRGBA,D as defaultSFXConfig,te as editRGBA,W as generateUUID,J as getAvoidAngle,O as getEnvironment,Z as getNormalizedColor,Q as getRayHit,ue as isInitiallyMobile,Y as isMobile,S as isNode,re as isNote,b as isWeb,G as parseFillStyle,oe as raycastAvoid,ne as scaleCoord,j as setAnimInterval,$ as sfxHit,U as sfxJump,H as sfxLaser,X as sfxUIClick,B as sfxUIHover,se as shortUID,ae as tinyUID};
1
+ var y=class{#e=new Map;constructor(){this.#e=new Map}on(e,t){let r=this.#e.get(e)||[];return r.push(t),this.#e.set(e,r),this}once(e,t){let r=(...i)=>{this.off(e,r),t(...i)};return this.on(e,r),this}off(e,t){let r=this.#e.get(e);if(!r)return this;let i=r.indexOf(t);return i>=0&&r.splice(i,1),this}emit(e,...t){let r=this.#e.get(e);if(!r||r.length===0){if(e==="error")throw t[0];return!1}return r.slice().forEach(i=>i(...t)),!0}removeAllListeners(e){return e?this.#e.delete(e):this.#e.clear(),this}listenerCount(e){return this.#e.get(e)?.length??0}},F=class extends y{canvas;ctx;running;_rafId;_fps;_frameCount;_fpsTimer;_lastFrameTime;constructor(e,{viewportWidth:t,viewportHeight:r,cameraWidth:i,cameraHeight:a}={}){if(!f)throw new Error("Web-Only");super(),this.canvas=e,this.ctx=e.getContext("2d"),this.automatic=!0,this.#e=t??e.width,this.#t=r??e.height,this.#n=i??e.width,this.#r=a??e.height,this.running=!1,this._rafId=null,this._loop=this._loop.bind(this),this.updateCanvasResolution(),this._fps=60,this._frameCount=0,this._fpsTimer=0}automatic;retransform(){this.ctx.setTransform(1,0,0,1,0,0);let e=this.#n/this.#e,t=this.#r/this.#t;this.ctx.translate(this.#n/2,this.#r/2),this.ctx.scale(e,t),this.ctx.translate(-this.#e/2,-this.#t/2)}#e=0;#t=0;#n=0;#r=0;get viewportWidth(){return this.#e}set viewportWidth(e){this.#e=e,this.retransform()}get width(){return this.#e}get height(){return this.#t}get centerX(){return this.#e/2}get centerY(){return this.#t/2}get left(){return 0}get top(){return 0}get right(){return this.#e}get bottom(){return this.#t}get viewportHeight(){return this.#t}set viewportHeight(e){this.#t=e,this.retransform()}get cameraWidth(){return this.#n}set cameraWidth(e){this.#n=e,this.updateCanvasResolution(),this.retransform()}get cameraHeight(){return this.#r}set cameraHeight(e){this.#r=e,this.updateCanvasResolution(),this.retransform()}updateCanvasResolution(){this.canvas.width=this.#n,this.canvas.height=this.#r}applyTransform(){this.retransform()}get FPS(){return this._fps}_loop(){this.automatic&&this.update(),this._rafId=requestAnimationFrame(this._loop)}update(){if(!this.running||!f)return;let e=performance.now(),t=(e-(this._lastFrameTime??e))/1e3;this._lastFrameTime=e,this._frameCount++,this._fpsTimer+=t,this._fpsTimer>=1&&(this._fps=Math.round(this._frameCount/this._fpsTimer),this._frameCount=0,this._fpsTimer=0),this.ctx.clearRect(0,0,this.#n,this.#r),this.emit("draw",this.ctx)}start(){if(!this.running){if(!f||typeof globalThis.requestAnimationFrame>"u")throw new Error("Raf is not supported");this.running=!0,this._rafId=requestAnimationFrame(this._loop)}}stop(){if(!f||typeof globalThis.requestAnimationFrame>"u")throw new Error("Raf is not supported");this.running=!1,this._rafId!==null&&(cancelAnimationFrame(this._rafId),this._rafId=null)}},I=class extends y{setNow(e){this.#e=e}#e=0;__intervalId=null;__lastTime=0;constructor(e=16){super(),this.#t=e,this.speedHackDT=1}speedHackDT;get isRaf(){return this.tickInterval===1/0}#t=15;get tickInterval(){return this.#t}set tickInterval(e){this.#t=e,this.__intervalId&&(this.stop(),this.start())}now(){return this.#e}__tick(){let e=performance.now(),t=(e-this.__lastTime)/1e3*this.speedHackDT;this.__lastTime=e,!(f&&typeof this.__intervalId=="function"&&document.hidden)&&(this.#e+=t*1e3,this.emit("tick",t))}createTimeout(e){return new A(e,this)}createTween(e,t=()=>{}){let r=new _(e),i=(a=0)=>{if(r.finished){this.off("tick",i);return}r.update(a)};return r.on("finish",()=>{this.off("tick",i)}),r.on("delta",a=>{t(a)}),this.on("tick",i),r}start(){this.__intervalId===null&&(this.__lastTime=performance.now(),this.__intervalId=f&&!isFinite(this.tickInterval)?j(()=>this.__tick()).clear:setInterval(()=>this.__tick(),this.tickInterval))}stop(){this.__intervalId!==null&&(typeof this.__intervalId=="function"?this.__intervalId():clearInterval(this.__intervalId)),this.__intervalId=null}getSineMod(e,t=0){return .5+.5*Math.sin((this.now()%e/e+t)*2*Math.PI)}},z;(C=>{function n(h){return h===!0?1:0}C.booleanExport=n;function e(h){return h===0?!1:h===1}C.booleanImport=e;function t(h){return`${h.x}|${h.y}`}C.vec2Export=t;function r(h){let[d,g]=h.split("|"),x=parseFloat(d),k=parseFloat(g);if(isNaN(x)||isNaN(k))throw new Error(`Invalid Vector2 string: ${h}`);return new M(x,k)}C.vec2Import=r,C.booleanMap={mapExport:n,mapImport:e};function a(h){return d=>Number(d.toFixed(h))}C.createRounder=a;function u(h=10){return{mapExport(d){return Math.round(d/h)},mapImport(d){return d*h}}}C.createLowPrecision=u;function c(h){return Math.round(h)}C.lightWeightRounder=c;function s(h=100){return{mapExport(d){return Math.round(d*h)},mapImport(d){return d/h}}}C.createPercent=s;function o(h){let d=new Map(Object.entries(h));return{mapExport:g=>d.get(g)??null,mapImport:g=>Array.from(d.entries()).find(([x,k])=>k===g)?.[0]??null}}C.createLookup=o;function l(h){let d=h*(180/Math.PI);return Math.round((d%360+360)%360)}C.radToDeg=l;function m(h){return h*(Math.PI/180)}C.degToRad=m,C.angleRadToDeg={mapExport:l,mapImport:m};function R(h=10){let d=u(h);return{mapExport(g){return d.mapExport(l(g))},mapImport(g){return d.mapImport(m(g))}}}C.createLowPrecisionRadToDeg=R})(z||={});var E=class n extends y{name="";scaleRotate=0;scale=1;constructor(e,t=0,r=0){super(),this.autoTranslate=!1,this.name=e,this.z=0,this.___pos=new M(t,r),this.nonSerializableProperties=[],this.nonSerializableProperties.push("___pos","autoTranslate","arraySerializeMap"),this.forceSerializableProperties=[],this.forceSerializableProperties.push("x","y")}arraySerializeMap;autoTranslate;z;___pos;nonSerializableProperties;forceSerializableProperties;get pos(){return this.___pos}get x(){return this.pos.x}get y(){return this.pos.y}set x(e){this.pos.x=e}set y(e){this.pos.y=e}handleUpdate(e){if(this.update)try{this.emit("update",e),this.update(e)}catch(t){this.emit("error",t)}}handleDraw(e){if(!(S||!this.draw)){e.save(),this.autoTranslate&&e.translate(this.x,this.y);try{this.emit("draw",e),this.draw(e)}catch(t){this.emit("error",t)}e.restore()}}serialize(){if(Array.isArray(this.arraySerializeMap))return this.arraySerializeMap.map(([i,{mapExport:a}])=>{let u=Reflect.get(this,i);return a?a(u):u});let e=["_events","_eventsCount","_maxListeners","nonSerializableProperties","forceSerializableProperties"],t=[...Reflect.ownKeys(this),...this.forceSerializableProperties].filter(i=>!this.nonSerializableProperties.includes(i)&&!e.includes(i.toString())),r=Object.fromEntries(t.map(i=>{let a=Reflect.get(this,i);if(S&&typeof a=="number"){let u=a.toString().split("."),s=(u[1]?u[1].length:0)>2?Number(a.toFixed(2)):a;return[i,s]}return[i,a]}));return JSON.parse(JSON.stringify(r))}toLocal(e){return e.subtract(this.pos)}toWorld(e){return e.add(this.pos)}deserializeArray(e){return n.deserializeArray(this.arraySerializeMap,e)}static deserializeArray(e,t){if(!e||!Array.isArray(t))return t;let r={};for(let i=0;i<t.length;i++){let a=e[i];if(!a)break;let[u,{mapImport:c}]=a,s=t[i];if(c&&(s=c(s)),typeof u!="string")break;try{Reflect.set(r,u,s)}catch(o){console.error(o)}}return r}},P=class extends y{name="";entities=new Map;paused=!0;constructor(e){super(),this.name=e}handleUpdate(e){if(!this.paused){this.emit("update",e);for(let t of this.entities.values())t.handleUpdate(e)}}handleDraw(e){if(!S&&!this.paused){this.emit("draw",e);for(let t of[...this.entities.values()].sort((r,i)=>r.z-i.z))t.handleDraw(e)}}addEntity(e){if(!(e instanceof E))throw new Error("invalid entity");if(!e.name)throw new Error("Entity must have a name.");this.entities.set(e.name,e)}removeEntity(e){if(!(e instanceof E))throw new Error("invalid entity");this.entities.delete(e.name)}getEntity(e){return this.entities.get(e)}},V=class{scenes;ticker;get centerX(){return this.width/2}get centerY(){return this.height/2}get left(){return 0}get top(){return 0}get right(){return this.width}get bottom(){return this.height}width;height;constructor(e,t,r=16){this.ticker=new I(r),this.scenes=new Map,this.width=e,this.height=t,this.ticker.on("tick",i=>{for(let a of this.scenes.values())a.paused||a.handleUpdate(i)})}addScene(e){if(!e.name)throw new Error("Scene must have a name.");e.paused=!1,this.scenes.set(e.name,e)}removeScene(e){e&&(e.paused=!0),this.scenes.delete(e.name)}now(){return this.ticker.now()}start(){this.ticker.start()}stop(){this.ticker.stop()}},b={lerp(n,e,t){return n+(e-n)*t},clamp(n,e,t){return Math.min(t,Math.max(e,n))},clamp01(n){return Math.min(1,Math.max(0,n))},easeLinear(n){return n},easeInQuad(n){return n*n},easeOutQuad(n){return 1-(1-n)*(1-n)},easeInOutQuad(n){return n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2},easeInSine(n){return 1-Math.cos(n*Math.PI/2)},easeOutSine(n){return Math.sin(n*Math.PI/2)},easeInOutSine(n){return-(Math.cos(Math.PI*n)-1)/2},easeInExpo(n){return n===0?0:Math.pow(2,10*n-10)},easeOutExpo(n){return n===1?1:1-Math.pow(2,-10*n)},easeInOutExpo(n){return n===0?0:n===1?1:n<.5?Math.pow(2,20*n-10)/2:(2-Math.pow(2,-20*n+10))/2},smoothstep(n){return n=b.clamp(n,0,1),n*n*(3-2*n)},randomLerp(n,e){return b.lerp(n,e,Math.random())},randomInt(n,e){return Math.floor(Math.random()*(e-n+1))+n},randomArrayValue(n){return n[b.randomInt(0,n.length-1)]},createBezier(n,e,t,r){function i(c,s,o,l,m){let p=1-c;return p*p*p*s+3*p*p*c*o+3*p*c*c*l+c*c*c*m}function a(c,s,o,l,m){let p=1-c;return 3*p*p*(o-s)+6*p*c*(l-o)+3*c*c*(m-l)}function u(c){let s=c;for(let o=0;o<6;o++){let l=i(s,0,n,t,1),m=a(s,0,n,t,1);if(m===0)break;s-=(l-c)/m}return b.clamp(s,0,1)}return function(s){s=b.clamp(s,0,1);let o=u(s);return i(o,0,e,r,1)}},lengthSquared(...n){return n.reduce((e,t)=>e+t*t,0)},normalizeRad(n){let e=2*Math.PI;return n=n%e,n<0&&(n+=e),n},angleInvertY(n){return b.normalizeRad(-n)},degToRadFlipY(n){return b.angleInvertY(n*Math.PI/180)},minimalAngularDirection(n,e){n=b.normalizeRad(n),e=b.normalizeRad(e);let t=b.normalizeRad(e-n),r=b.normalizeRad(n-e);return t<=r?1:-1}},_=class extends y{constructor({delta:e,ms:t,easing:r}){super(),this.delta=e,this.duration=t,this.elapsed=0,this.easing=r??(i=>i),this.lastValue=0,this.finished=!1}delta;duration;elapsed;lastValue;finished;easing;update(e){this.elapsed+=e*1e3;let t=b.clamp(this.elapsed/this.duration,0,1),r=this.easing(t),i=this.delta*r,a=i-this.lastValue;this.lastValue=i,this.emit("delta",a),t>=1&&(this.finished=!0,this.emit("finish",void 0))}},K=class extends E{constructor(e,t=0,r=0,i=50,a=50){super(e,t,r),this.width=i,this.height=a}width;height;get left(){return this.x-this.width/2}set left(e){this.x=e+this.width/2}get right(){return this.x+this.width/2}set right(e){this.x=e-this.width/2}get top(){return this.y-this.height/2}set top(e){this.y=e+this.height/2}get bottom(){return this.y+this.height/2}set bottom(e){this.y=e-this.height/2}get lx(){return 0}get ly(){return 0}get lleft(){return-this.width/2}get lright(){return this.width/2}get ltop(){return-this.height/2}get lbottom(){return this.height/2}isCollidingWith(e){return!(this.right<e.left||this.left>e.right||this.bottom<e.top||this.top>e.bottom)}color="rgba(0, 0, 255, 0.3)";draw(e){e.translate(this.x,this.y),e.rotate(this.scaleRotate),e.fillStyle=this.color,e.fillRect(-this.width/2,-this.height/2,this.width,this.height)}},A=class extends y{duration;ticker;elapsed;finished;_resolve;promise;_timeoutId;constructor(e,t=null){super(),this.duration=e,this.ticker=t,this.elapsed=0,this.finished=!1,this._resolve=null,this.promise=new Promise(r=>this._resolve=r),this.update=this.update.bind(this),this.ticker&&this.ticker.on("tick",this.update)}update(e=0){this.finished||(this.elapsed+=e*1e3,this.elapsed>=this.duration&&this.finish())}finish(){this.finished||(this.finished=!0,this.emit("finish",void 0),this._resolve&&this._resolve(),this.ticker&&this.ticker.off("tick",this.update))}start(){return this.ticker||(this._timeoutId=setTimeout(()=>this.finish(),this.duration)),this}cancel(){this.finished||(this.finished=!0,!this.ticker&&this._timeoutId!=null&&clearTimeout(this._timeoutId),this.ticker&&this.ticker.off("tick",this.update))}then(e,t){return this.promise.then(e,t)}after(e,t){return this.promise.then(e,t)}},M=class n{constructor(e=0,t=0){this.x=e,this.y=t}x;y;toJSON(){return{x:this.x,y:this.y,vec2:!0}}static isVec2(e){return e&&typeof e=="object"&&"x"in e&&"y"in e&&e.vec2===!0}static fromSerialized(e){return this.isVec2(e)?new this(e.x,e.y):null}rotate(e){let t=Math.cos(e),r=Math.sin(e);return new n(this.x*t-this.y*r,this.x*r+this.y*t)}static from(e){return new n(Math.cos(e),Math.sin(e))}isEmpty(){return Math.abs(this.x)<.01&&Math.abs(this.y)<.01}get angle(){return Math.atan2(this.y,this.x)}angleTo(e){return Math.atan2(e.y-this.y,e.x-this.x)}get length(){return Math.hypot(this.x,this.y)}get lengthSquared(){return this.x*this.x+this.y*this.y}normalized(){let e=this.length;return e===0?new n(0,0):new n(this.x/e,this.y/e)}consume(e){let t=this.length;t<=e?(this.x=0,this.y=0):this.overwite(this.scale((t-e)/t))}project(e){return e.scale(this.dotNormalized(e))}reflect(e){let t=this.dot(e);return this.subtract(e.scale(2*t))}dotNormalized(e){let t=this.normalized(),r=e.normalized();return t.x*r.x+t.y*r.y}lengthSquaredTo(e){let t=this.x-e.x,r=this.y-e.y;return t*t+r*r}dot(e){return this.x*e.x+this.y*e.y}distanceTo(e){return Math.hypot(this.x-e.x,this.y-e.y)}distanceToCheap(e){let t=this.x-e.x,r=this.y-e.y;return t*t+r*r}directionTo(e){return new n(e.x-this.x,e.y-this.y).normalized()}add(e){return new n(this.x+e.x,this.y+e.y)}addRaw(e){return new n(this.x+e,this.y+e)}overwite(e){this.x=e.x,this.y=e.y}subtract(e){return new n(this.x-e.x,this.y-e.y)}scale(e){return new n(this.x*e,this.y*e)}toString(){return`Vector2(${this.x}, ${this.y})`}clone(){return new n(this.x,this.y)}};function Z(n){let e=/^rgba?\(([^)]+)\)$/,t=n.match(e);if(t){let[r,i,a,u=1]=t[1].split(",").map(c=>parseFloat(c));return{r:Math.max(0,Math.min(255,Math.floor(r))),g:Math.max(0,Math.min(255,Math.floor(i))),b:Math.max(0,Math.min(255,Math.floor(a))),a:Math.max(0,Math.min(1,Math.floor(u*255)/255))}}return G(n)}function ee(n){return`rgba(${n.r}, ${n.g}, ${n.b}, ${n.a})`}function G(n){if(n=n.trim().toLowerCase(),n[0]==="#"){let t,r,i;if(n.length===7)t=parseInt(n.slice(1,3),16),r=parseInt(n.slice(3,5),16),i=parseInt(n.slice(5,7),16);else if(n.length===4)t=parseInt(n[1]+n[1],16),r=parseInt(n[2]+n[2],16),i=parseInt(n[3]+n[3],16);else throw new Error("Invalid hex color");return{r:t,g:r,b:i,a:1}}let e=n.match(/^rgba?\s*\(\s*(\d+)[, ]\s*(\d+)[, ]\s*(\d+)(?:[, ]\s*([\d.]+))?\s*\)$/);if(e)return{r:parseInt(e[1]),g:parseInt(e[2]),b:parseInt(e[3]),a:e[4]!==void 0?parseFloat(e[4]):1};throw new Error("Unsupported fillStyle format")}function te(n,{r:e,g:t,b:r,a:i}={}){let[a,u,c,s,o]=n.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]*)\)?/)||[];return`rgba(${e??u}, ${t??c}, ${r??s}, ${i??(o||1)})`}function ne(n,e,t){return t+(n-t)*e}function O(){return typeof process<"u"&&process.release?.name==="node"?"node":typeof window<"u"||typeof self<"u"?"web":"unknown"}var N=O(),S=N==="node",f=N==="web",T=class n{static unlock(){f&&this.audioCtx.state!=="running"&&this.audioCtx.resume()}static audioCtx=f?new AudioContext:null;static masterGain=f?this.audioCtx.createGain():null;static musicGain=f?this.audioCtx.createGain():null;static sfxGain=f?this.audioCtx.createGain():null;static{f&&(this.masterGain.gain.value=1,this.musicGain.gain.value=1,this.sfxGain.gain.value=1,this.sfxGain.connect(this.masterGain),this.musicGain.connect(this.masterGain),this.masterGain.connect(this.audioCtx.destination))}static get SFX_VOLUME(){return this.sfxGain.gain.value}static get MUSIC_VOLUME(){return this.musicGain.gain.value}static get VOLUME(){return this.masterGain.gain.value}static set SFX_VOLUME(e){this.sfxGain.gain.value=e}static set MUSIC_VOLUME(e){this.musicGain.gain.value=e}static set VOLUME(e){this.masterGain.gain.value=e}static noteToHz(e){return this.tuningFreq*Math.pow(2,(e-9)/12)}static tuningFreq=440;static audioBufferCache=new Map;static loops=new Map;static sfsx=new Map;static loopIdCounter=0;static CACHE_NAME="lia-audio-cache-v1";static async preLoad(e){if(this.audioBufferCache.has(e))return this.audioBufferCache.get(e);let t=n.CACHE_NAME,r,i;if(typeof caches<"u"&&(i=await caches.open(t),r=await i.match(e)),!r){if(r=await fetch(e),!r.ok)throw new Error(`Failed to fetch ${e}`);i&&await i.put(e,r.clone())}let a=await r.arrayBuffer(),u=await this.audioCtx.decodeAudioData(a);return this.audioBufferCache.set(e,u),u}static async getOnlyDownloadedCache(e){let t=n.CACHE_NAME;return await(await caches.open(t)).match(e)}static getCached(e){return this.audioBufferCache.get(e)||null}static async playSound(e,t=.2,r=1,i=!0){try{this.sfsx.has(e)&&this.sfsx.get(e).source.stop(),this.audioBufferCache.has(e)||await this.preLoad(e);let a=this.getCached(e);if(!a)return;let u=new w(a);u.buffer=a;let c=1-.12,s=1+.12;u.playbackRate=r??c+Math.random()*(s-c);let o=this.audioCtx.createGain();o.gain.value=t,u.tempGain=o,u.connect(o),o.connect(this.sfxGain),u.onended=()=>{u.disconnect(),o.disconnect()},u.start(),i&&this.sfsx.set(e,{source:u,gain:o})}catch(a){console.error(a)}}static async playLoop(e,t=1,{loopStart:r=0,loopEnd:i=null,exclusive:a=!0,skipMS:u=0}={}){if(a)for(let m of this.loops.keys())this.stopLoop(m);this.audioBufferCache.has(e)||await this.preLoad(e);let c=this.getCached(e);if(!c)return;let s=new w(c);s.buffer=c,s.loop=!0,typeof r=="number"&&(s.loopStart=r),typeof i=="number"&&(s.loopEnd=i);let o=this.audioCtx.createGain();o.gain.value=t,s.tempGain=o,s.playbackRate=1,s.onended=()=>{s.disconnect(),o.disconnect()},s.connect(o),o.connect(this.musicGain),s.start(0,u/1e3);let l=++this.loopIdCounter;return this.loops.set(l,{source:s,gain:o}),l}static stopLoop(e){let t=this.loops.get(e);t&&(t.source.stop(),t.source.notIndependent||(t.source.disconnect(),t.gain.disconnect()),this.loops.delete(e))}static async createLiaSource(e,{volume:t=1,speed:r=1,loop:i=!1,loopStart:a=0,loopEnd:u=null,isMusic:c=!1,gain:s=null}={}){try{this.audioBufferCache.has(e)||await this.preLoad(e);let o=this.getCached(e);if(!o)return null;let l=new w(o);l.loop=i,l.loopStart=a,l.loopEnd=typeof u=="number"?u:o.duration,l.playbackRate=r;let m=this.audioCtx.createGain();return m.gain.value=t,l.connect(m),l.tempGain=m,m.connect(s||(c?this.musicGain:this.sfxGain)),l.onended=()=>{l.disconnect(),m.disconnect()},l}catch(o){return console.error("Failed to create LiaAudioSrc:",o),null}}},q=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];function re(n){return q.includes(n)}var w=class{numberOfInputs;numberOfOutputs;constructor(e,t=T.audioCtx){this.context=t,this.buffer=e,this.source=null,this.startTime=0,this.pauseTime=0,this.playbackRate=1,this.isPlaying=!1,this.loop=!1,this.output=f?t.createGain():null,this.output.gain.value=1,this.channelCount=2,this.channelCountMode="max",this.channelInterpretation="speakers",this.numberOfInputs=0,this.numberOfOutputs=1,this.onended=null}channelCount;channelCountMode;channelInterpretation;onended;source;buffer;context;_createSource(){this.source&&(this.source.onended=null);let e=this.context.createBufferSource();return e.buffer=this.buffer,e.playbackRate.value=this.playbackRate,e.loop=this.loop,e.loopStart=this.loopStart,e.loopEnd=this.loopEnd>0?this.loopEnd:this.buffer.duration,e.connect(this.output),this.source=e,e.onended=()=>{this.source===e&&(this.isPlaying&&!this.loop&&(this.isPlaying=!1,this.pauseTime=0),typeof this.onended=="function"&&this.onended())},e}play({fadeIn:e=0,offset:t=null}={}){let r=t!==null?t:this.pauseTime;if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.source=this._createSource(),this.startTime=this.context.currentTime-r/this.playbackRate,this.source.start(0,r),e>0?(this.output.gain.setValueAtTime(0,this.context.currentTime),this.output.gain.linearRampToValueAtTime(1,this.context.currentTime+e)):this.output.gain.setValueAtTime(1,this.context.currentTime),this.isPlaying=!0}start(e=0,t=0,r){this.isPlaying||(this.source=this._createSource(),this.startTime=this.context.currentTime+e-t/this.playbackRate,r!==void 0?this.source.start(this.context.currentTime+e,t,r):this.source.start(this.context.currentTime+e,t),this.pauseTime=t,this.isPlaying=!0)}pause({fadeOut:e=0}={}){if(!this.isPlaying)return;let t=this.getElapsed()/1e3;if(this.loop&&this.loopEnd>this.loopStart){let r=this.loopEnd-this.loopStart;t=this.loopStart+(t-this.loopStart)%r}if(this.isPlaying=!1,e>0){let r=this.context.currentTime;this.output.gain.setValueAtTime(this.output.gain.value,r),this.output.gain.linearRampToValueAtTime(0,r+e),setTimeout(()=>{if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.pauseTime=t,this.output.gain.setValueAtTime(1,this.context.currentTime)},e*1e3)}else{if(this.source){this.source.onended=null;try{this.source.stop()}catch{}}this.pauseTime=t}}getElapsed(){return this.isPlaying?(this.context.currentTime-this.startTime)*this.playbackRate*1e3:this.pauseTime*1e3}setSpeed(e){if(e<=0)throw new Error("Playback rate must be positive");let t=this.getElapsed()/1e3;this.playbackRate=e,this.isPlaying&&(this.pause(),this.pauseTime=t,this.play())}setLoop(e=!0){this.loop=e,this.source&&(this.source.loop=e)}loop;playbackRate;startTime;tempGain=null;connect(e,t=0,r=0){if("value"in e)this.output.connect(e,t);else return this.output.connect(e,t,r),e}disconnect(e,t,r){e===void 0?this.output.disconnect():this.output.disconnect(e,t,r)}output;stop(e=0){if(this.notIndependent)return this.pause();if(!this.source)return;let t=this.context.currentTime+e;this.source.stop(t),this.isPlaying=!1,this.notIndependent||(this.pauseTime=0)}pauseTime;isPlaying;notIndependent=!1;loopStart=0;loopEnd=0},D={osc:{enabled:!0,type:"sine",freq:440,detune:0},noise:{enabled:!1,level:.5},ampEnv:{attack:.005,decay:.1,sustain:0,release:.1,volume:.3},pitchEnv:{amount:0,decay:.2},filter:{enabled:!1,type:"lowpass",freq:1200,Q:1,envAmount:0,decay:.2},lfo:{enabled:!1,target:"freq",rate:8,depth:20},duration:.4},v=class n{constructor(e={}){this.ctx=T.audioCtx,this.cfg=structuredClone(D),Object.assign(this.cfg,e)}ctx;cfg;play(e=T.sfxGain){let t=this.ctx,r=t.currentTime,i=this.cfg,a=t.createGain();a.gain.setValueAtTime(1e-4,r);let u=i.ampEnv;a.gain.exponentialRampToValueAtTime(u.volume,r+u.attack),a.gain.exponentialRampToValueAtTime(Math.max(1e-4,u.sustain*u.volume),r+u.attack+u.decay),a.gain.exponentialRampToValueAtTime(1e-4,r+i.duration+u.release);let c=a,s;i.filter.enabled&&(s=t.createBiquadFilter(),s.type=i.filter.type,s.frequency.value=i.filter.freq,s.Q.value=i.filter.Q,s.connect(a),c=s);let o;if(i.osc.enabled){if(o=t.createOscillator(),o.type=i.osc.type,o.frequency.value=i.osc.freq,o.detune.value=i.osc.detune,i.pitchEnv.amount!==0){let h=Math.pow(2,i.pitchEnv.amount/12);o.frequency.exponentialRampToValueAtTime(i.osc.freq*h,r+i.pitchEnv.decay)}o.connect(c),o.start(r),o.stop(r+i.duration+u.release)}let l;if(i.noise.enabled){let h=t.sampleRate*i.duration,d=t.createBuffer(1,h,t.sampleRate),g=d.getChannelData(0);for(let x=0;x<h;x++)g[x]=(Math.random()*2-1)*i.noise.level;l=t.createBufferSource(),l.buffer=d,l.connect(c),l.start(r),l.stop(r+i.duration+u.release)}let m,p;i.lfo.enabled&&o&&(m=t.createOscillator(),m.frequency.value=i.lfo.rate,p=t.createGain(),p.gain.value=i.lfo.depth,m.connect(p),i.lfo.target==="freq"?p.connect(o.frequency):i.lfo.target==="gain"?p.connect(a.gain):i.lfo.target==="filter"&&s&&p.connect(s.frequency),m.start(r),m.stop(r+i.duration)),a.connect(e);let R=[o,l,m,p,s,a],C=r+i.duration+u.release;setTimeout(()=>{R.forEach(h=>h?.disconnect())},(C-t.currentTime)*1e3)}getConfig(){return structuredClone(this.cfg)}setConfig(e){return Object.assign(this.cfg,e),this}getKey(e){return this.cfg[e]}setKey(e,t){return Object.assign(this.cfg[e],t),this}setFreq(e){return this.cfg.osc.freq=e,this}setWave(e){return this.cfg.osc.type=e,this}setVolume(e){return this.cfg.ampEnv.volume=e,this}setAmpEnv(e,t,r,i){return Object.assign(this.cfg.ampEnv,{attack:e,decay:t,sustain:r,release:i}),this}setPitchEnv(e,t){return Object.assign(this.cfg.pitchEnv,{amount:e,decay:t}),this}setNoiseEnabled(e){return this.cfg.noise.enabled=e,this}setNoiseLevel(e){return this.cfg.noise.level=e,this}setFilterEnabled(e){return this.cfg.filter.enabled=e,this}setFilter(e,t,r){return Object.assign(this.cfg.filter,{type:e,freq:t,Q:r,enabled:!0}),this}setLFOEnabled(e){return this.cfg.lfo.enabled=e,this}setLFO(e,t,r){return Object.assign(this.cfg.lfo,{target:e,rate:t,depth:r,enabled:!0}),this}setDuration(e){return this.cfg.duration=e,this}clone(){return new n(structuredClone(this.cfg))}},X=new v({osc:{enabled:!0,type:"square",freq:900,detune:0},ampEnv:{attack:.002,decay:.04,sustain:0,release:.02,volume:.15},duration:.05}),B=new v({osc:{enabled:!0,type:"sine",freq:600,detune:0},ampEnv:{attack:.01,decay:.08,sustain:0,release:.04,volume:.12},duration:.1}),U=new v({osc:{enabled:!0,type:"triangle",freq:500,detune:0},pitchEnv:{amount:12,decay:.15},ampEnv:{attack:.01,decay:.12,sustain:0,release:.05,volume:.25},duration:.18}),H=new v({osc:{enabled:!0,type:"sawtooth",freq:1200,detune:0},pitchEnv:{amount:-24,decay:.3},ampEnv:{attack:.005,decay:.25,sustain:0,release:.05,volume:.3},duration:.35}),$=new v({osc:{enabled:!0,type:"square",freq:180,detune:0},noise:{enabled:!0,level:.4},ampEnv:{attack:.002,decay:.15,sustain:0,release:.05,volume:.35},duration:.2}),ie=new Map([["ui_click",X],["ui_hover",B],["jump",U],["laser",H],["hit",$]]);function se(n=12){let e=Date.now().toString(36),t=crypto.getRandomValues(new Uint8Array(n)),r=Array.from(t).map(i=>i.toString(36).padStart(2,"0")).join("");return(e+r).slice(0,n)}function ae(n=12){let e=Date.now().toString(36),t=crypto.getRandomValues(new Uint8Array(4)),r=Array.from(t).map(i=>i.toString(36).padStart(2,"0")).join("");return(e+r).slice(0,n)}var L=class{peer=null;key;events={};mbAcc=0;connected=!1;constructor(){this.key=`${W()}_${Date.now()}`}connect(e){e&&(this.peer=e,e.peer=this,this.connected=!0,e.connected=!0),this._emit("open")}isConnected(){return this.connected&&!!this.peer}on(e,t){this.events[e]||(this.events[e]=[]),this.events[e].push(t)}off(e,t){this.events[e]&&(this.events[e]=this.events[e].filter(r=>r!==t))}_emit(e,t){this.events[e]?.forEach(r=>r(t))}send(e,t){if(!this.peer)throw new Error("No peer connected");this.peer._receive(e,t)}_receive(e,t){e?this._emit(e,t):this._emit("message",t)}close(){if(this.connected=!1,this.peer){let e=this.peer;this.peer=null,e.peer=null,e.connected=!1,e._emit("close")}this._emit("close")}getKey(){return this.key}};function W(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let n=new Uint8Array(16);return crypto.getRandomValues(n),n[6]=n[6]&15|64,n[8]=n[8]&63|128,[...n].map(e=>e.toString(16).padStart(2,"0")).join("").replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/,"$1-$2-$3-$4-$5")}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let e=Math.random()*16|0;return(n==="x"?e:e&3|8).toString(16)})}function j(n){let e=!0;function t(){e&&(n(),requestAnimationFrame(t))}return requestAnimationFrame(t),{clear:()=>e=!1}}function Q(n,e,t,r,i){let a=Math.cos(i),u=Math.sin(i),c=[];if(a!==0){let s=(0-n)/a,o=e+s*u;s>0&&o>=0&&o<=r&&c.push({side:"left",t:s})}if(a!==0){let s=(t-n)/a,o=e+s*u;s>0&&o>=0&&o<=r&&c.push({side:"right",t:s})}if(u!==0){let s=(0-e)/u,o=n+s*a;s>0&&o>=0&&o<=t&&c.push({side:"top",t:s})}if(u!==0){let s=(r-e)/u,o=n+s*a;s>0&&o>=0&&o<=t&&c.push({side:"bottom",t:s})}return c.length===0?null:(c.sort((s,o)=>s.t-o.t),c[0])}function J(n,e){let t;switch(e){case"left":case"right":t=Math.PI-n;break;case"top":case"bottom":t=2*Math.PI-n;break}return(t%(2*Math.PI)+2*Math.PI)%(2*Math.PI)}function oe(n,e,t,r,i){let a=Q(n,e,t,r,i);return a?{...a,avoidAngle:J(i,a.side)}:null}function Y(){return S?!1:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}var ue=Y();export{_ as DeltaTweenII,N as ENVIRONMENT,L as GEmitterMemory,E as LeaEntityII,y as LeaEventEmitter,V as LeaGameII,F as LeaRendererII,P as LeaSceneII,z as LeaSerializers,I as LeaTickerII,A as LeaTimeout,b as LeaUtilsII,T as LiaAudio,w as LiaAudioSrc,v as LiaOscSFX,ie as LiaSFXMap,q as NOTE_NAMES,K as RectLeaEntity,M as Vector2,ee as colToRGBA,D as defaultSFXConfig,te as editRGBA,W as generateUUID,J as getAvoidAngle,O as getEnvironment,Z as getNormalizedColor,Q as getRayHit,ue as isInitiallyMobile,Y as isMobile,S as isNode,re as isNote,f as isWeb,G as parseFillStyle,oe as raycastAvoid,ne as scaleCoord,j as setAnimInterval,$ as sfxHit,U as sfxJump,H as sfxLaser,X as sfxUIClick,B as sfxUIHover,se as shortUID,ae as tinyUID};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kayelaa/canvas",
3
- "version": "0.1.14",
3
+ "version": "0.2.0",
4
4
  "description": "Declarative entity composition hooks + canvas utilities for LEA-based 2D games",
5
5
  "license": "MIT",
6
6
  "author": "Kayelaa Cagara",