jetcode-scrubjs
Version:
HTML5 Game Library with a Focus on Ease of Learning
13 lines • 87.5 kB
JavaScript
(()=>{var At=Object.defineProperty;var It=(u,t)=>{for(var e in t)At(u,e,{get:t[e],enumerable:!0})};var kt={};It(kt,{BVH:()=>nt,BVHBranch:()=>Z,Camera:()=>ut,CameraChanges:()=>dt,CircleCollider:()=>F,Collider:()=>K,CollisionResult:()=>k,CollisionSystem:()=>ot,Costume:()=>z,ErrorMessages:()=>y,EventEmitter:()=>Y,Game:()=>R,JetcodeSocket:()=>g,JetcodeSocketConnection:()=>st,Keyboard:()=>at,KeyboardMap:()=>A,Mouse:()=>lt,MultiplayerControl:()=>mt,MultiplayerGame:()=>Ot,MultiplayerSprite:()=>pt,OrphanSharedData:()=>X,Player:()=>_t,PointCollider:()=>N,PolygonCollider:()=>w,Registry:()=>O,SAT:()=>rt,ScheduledCallbackExecutor:()=>V,ScheduledCallbackItem:()=>U,ScheduledState:()=>H,SharedData:()=>Tt,Sprite:()=>$,Stage:()=>wt,Styles:()=>ht,ValidatorFactory:()=>ct,aabbAABB:()=>Mt,circleCircle:()=>Nt,polygonCircle:()=>xt,polygonPolygon:()=>Dt,separatingAxis:()=>Et});var st=class{constructor(t,e,i=0){this.connectActions=[g.JOINED,g.RECEIVE_DATA,g.MEMBER_JOINED,g.MEMBER_LEFT,g.GAME_STARTED,g.GAME_STOPPED,g.ERROR];this.socket=t,this.lobbyId=i,this.memberId=null,this.connects={},this._listenSocket()}_listenSocket(){this.socket.onmessage=t=>{let[e,i,s]=this._parse(t.data);e===g.RECEIVE_DATA?this.emit(g.RECEIVE_DATA,[s,i,i?.MemberId===this.memberId]):e===g.MEMBER_JOINED?this.emit(g.MEMBER_JOINED,[i,i?.MemberId===this.memberId]):e===g.MEMBER_LEFT?this.emit(g.MEMBER_LEFT,[i,i?.MemberId===this.memberId]):this.connects[e]&&this.emit(e,[i])}}emit(t,e){this.connects[t]&&this.connects[t].forEach(i=>{i(...e)})}connect(t,e){if(!this.connectActions.includes(t))throw new Error("This actions is not defined.");return this.connects[t]||(this.connects[t]=[]),this.connects[t].push(e),e}disconnect(t,e){if(!this.connectActions.includes(t))throw new Error("This action is not defined.");this.connects[t]&&(this.connects[t]=this.connects[t].filter(i=>i!==e))}sendData(t,e={}){if(!this.lobbyId)throw new Error("You are not in the lobby!");let i=`${g.SEND_DATA}
`;for(let[s,n]of Object.entries(e))i+=s+"="+n+`
`;i+=`SendTime=${Date.now()}
`,i+=`
`+t,this.socket.send(i)}joinLobby(t,e,i={}){return new Promise((s,n)=>{e||(e=0);let r=`${g.JOIN_LOBBY}
`;r+=`GameToken=${t}
`,r+=`LobbyId=${e}
`;for(let[o,a]of Object.entries(i))r+=`${o}=${a}
`;this.socket.send(r),this.connect(g.JOINED,o=>{if(o.LobbyId&&o.MemberId&&o.CurrentTime){this.lobbyId=o.LobbyId,this.memberId=o.MemberId;let a=Date.now();this.deltaTime=a-Number(o.CurrentTime),s(this.lobbyId)}else n(new Error("Couldn't join the lobby"))})})}leaveLobby(){if(!this.lobbyId)return;let t=`${g.LEAVE_LOBBY}
LobbyId=${this.lobbyId}
`;this.socket.send(t),this.lobbyId=null}_parse(t){let e=t.split(`
`),i=e[0],s="",n=[],r="parameters";for(let o=1;o<e.length;o++){let a=e[o];if(a===""&&r==="parameters")r="value";else if(r==="parameters"){let l=a.split("="),h=l[0];n[h]=l.length>1?l[1]:null}else r==="value"&&(s=s+a+`
`)}return s&&(s=s.slice(0,-1)),[i,n,s]}};var g=class{constructor(t="ws://localhost:17500"){this.socketUrl=t,this.socket=null,this.defaultParameters={LobbyAutoCreate:!0,MaxMembers:2,MinMembers:2,StartGameWithMembers:2}}connect(t,e=null,i={}){let s={...this.defaultParameters,...i};return new Promise((n,r)=>{this.socket=new WebSocket(this.socketUrl),this.socket.onopen=()=>{let o=new st(this.socket,t,e);o.joinLobby(t,e,s).then(()=>{n(o)}).catch(r)},this.socket.onerror=o=>{r(o)}})}};g.JOIN_LOBBY="JOIN_LOBBY",g.LEAVE_LOBBY="LEAVE_LOBBY",g.SEND_DATA="SEND_DATA",g.JOINED="JOINED",g.RECEIVE_DATA="RECEIVE_DATA",g.MEMBER_JOINED="MEMBER_JOINED",g.MEMBER_LEFT="MEMBER_LEFT",g.GAME_STARTED="GAME_STARTED",g.GAME_STOPPED="GAME_STOPPED",g.ERROR="ERROR";var Ct=[],Z=class u{constructor(){this._bvh_parent=null;this._bvh_branch=!0;this._bvh_left=null;this._bvh_right=null;this._bvh_sort=0;this._bvh_min_x=0;this._bvh_min_y=0;this._bvh_max_x=0;this._bvh_max_y=0}static getBranch(){return Ct.length?Ct.pop():new u}static releaseBranch(t){Ct.push(t)}static sortBranches(t,e){return t.sort>e.sort?-1:1}};var tt=class tt{constructor(){this._hierarchy=null;this._bodies=[];this._dirty_branches=[]}insert(t,e=!1){if(!e){let p=t._bvh;if(p&&p!==this)throw new Error("Body belongs to another collision system");t._bvh=this,this._bodies.push(t)}let i=t._polygon,s=t.x,n=t.y;i&&(t._dirty_coords||t.x!==t._x||t.y!==t._y||t.angle!==t._angle||t.scale_x!==t._scale_x||t.scale_y!==t._scale_y)&&t._calculateCoords();let r=t._bvh_padding,o=i?0:t.radius*t.scale,a=(i?t._min_x:s-o)-r,l=(i?t._min_y:n-o)-r,h=(i?t._max_x:s+o)+r,d=(i?t._max_y:n+o)+r;t._bvh_min_x=a,t._bvh_min_y=l,t._bvh_max_x=h,t._bvh_max_y=d;let c=this._hierarchy,_=0;if(!c)this._hierarchy=t;else{let p=0;for(;p++<tt.MAX_DEPTH;)if(c._bvh_branch){let m=c._bvh_left,f=m._bvh_min_y,b=m._bvh_max_x,v=m._bvh_max_y,C=a<m._bvh_min_x?a:m._bvh_min_x,S=l<f?l:f,E=h>b?h:b,I=d>v?d:v,G=(b-m._bvh_min_x)*(v-f),et=(E-C)*(I-S)-G,L=c._bvh_right,P=L._bvh_min_x,j=L._bvh_min_y,W=L._bvh_max_x,M=L._bvh_max_y,D=a<P?a:P,T=l<j?l:j,B=h>W?h:W,Q=d>M?d:M,it=(W-P)*(M-j),gt=(B-D)*(Q-T)-it;c._bvh_sort=_++,c._bvh_min_x=C<D?C:D,c._bvh_min_y=S<T?S:T,c._bvh_max_x=E>B?E:B,c._bvh_max_y=I>Q?I:Q,c=et<=gt?m:L}else{let m=c._bvh_parent,f=c._bvh_min_x,b=c._bvh_min_y,v=c._bvh_max_x,C=c._bvh_max_y,S=c._bvh_parent=t._bvh_parent=Z.getBranch();S._bvh_parent=m,S._bvh_left=c,S._bvh_right=t,S._bvh_sort=_++,S._bvh_min_x=a<f?a:f,S._bvh_min_y=l<b?l:b,S._bvh_max_x=h>v?h:v,S._bvh_max_y=d>C?d:C,m?m._bvh_left===c?m._bvh_left=S:m._bvh_right=S:this._hierarchy=S;break}}}remove(t,e=!1){if(!e){let o=t._bvh;if(o&&o!==this)throw new Error("Body belongs to another collision system");t._bvh=null,this._bodies.splice(this._bodies.indexOf(t),1)}if(this._hierarchy===t){this._hierarchy=null;return}let i=t._bvh_parent;if(!i){console.error("The parent is not defined in the collision system.");return}let s=i._bvh_parent,n=i._bvh_left,r=n===t?i._bvh_right:n;if(r._bvh_parent=s,r._bvh_branch&&(r._bvh_sort=i._bvh_sort),s){s._bvh_left===i?s._bvh_left=r:s._bvh_right=r;let o=s,a=0;for(;o&&a++<tt.MAX_DEPTH;){let l=o._bvh_left,h=l._bvh_min_x,d=l._bvh_min_y,c=l._bvh_max_x,_=l._bvh_max_y,p=o._bvh_right,m=p._bvh_min_x,f=p._bvh_min_y,b=p._bvh_max_x,v=p._bvh_max_y;o._bvh_min_x=h<m?h:m,o._bvh_min_y=d<f?d:f,o._bvh_max_x=c>b?c:b,o._bvh_max_y=_>v?_:v,o=o._bvh_parent}}else this._hierarchy=r;Z.releaseBranch(i)}update(){let t=this._bodies,e=t.length;for(let i=0;i<e;++i){let s=t[i],n=!1;if(!n&&s.padding!==s._bvh_padding&&(s._bvh_padding=s.padding,n=!0),!n){let r=s._polygon;r&&(s._dirty_coords||s.x!==s._x||s.y!==s._y||s.angle!==s._angle||s.scale_x!==s._scale_x||s.scale_y!==s._scale_y)&&s._calculateCoords();let o=s.x,a=s.y,l=r?0:s.radius*s.scale,h=r?s._min_x:o-l,d=r?s._min_y:a-l,c=r?s._max_x:o+l,_=r?s._max_y:a+l;n=h<s._bvh_min_x||d<s._bvh_min_y||c>s._bvh_max_x||_>s._bvh_max_y}n&&(this.remove(s,!0),this.insert(s,!0))}}potentials(t){let e=[],i=t._bvh_min_x,s=t._bvh_min_y,n=t._bvh_max_x,r=t._bvh_max_y,o=this._hierarchy,a=!0;if(!o||!o._bvh_branch)return e;let l=0;for(;o&&l++<tt.MAX_DEPTH;){if(a){a=!1;let c=o._bvh_branch?o._bvh_left:null;for(;c&&c._bvh_max_x>=i&&c._bvh_max_y>=s&&c._bvh_min_x<=n&&c._bvh_min_y<=r;)o=c,c=o._bvh_branch?o._bvh_left:null}let h=o._bvh_branch,d=h?o._bvh_right:null;if(d&&d._bvh_max_x>i&&d._bvh_max_y>s&&d._bvh_min_x<n&&d._bvh_min_y<r)o=d,a=!0;else{!h&&o!==t&&e.push(o);let c=o._bvh_parent;if(c){for(;c&&c._bvh_right===o;)o=c,c=o._bvh_parent;o=c}else break}}return e}draw(t){let e=this._bodies,i=e.length;for(let s=0;s<i;++s)e[s].draw(t)}drawBVH(t){let e=this._hierarchy,i=!0;for(;e;){if(i){i=!1;let h=e._bvh_branch?e._bvh_left:null;for(;h;)e=h,h=e._bvh_branch?e._bvh_left:null}let s=e._bvh_branch,n=e._bvh_min_x,r=e._bvh_min_y,o=e._bvh_max_x,a=e._bvh_max_y,l=s?e._bvh_right:null;if(t.moveTo(n,r),t.lineTo(o,r),t.lineTo(o,a),t.lineTo(n,a),t.lineTo(n,r),l)e=l,i=!0;else{let h=e._bvh_parent;if(h){for(;h&&h._bvh_right===e;)e=h,h=e._bvh_parent;e=h}else break}}}};tt.MAX_DEPTH=1e4;var nt=tt;function rt(u,t,e=null,i=!0){let s=u._polygon,n=t._polygon,r=!1;return e&&(e.a=u,e.b=t,e.a_in_b=!0,e.b_in_a=!0,e.overlap=null,e.overlap_x=0,e.overlap_y=0,e.collidedSprite=null),s&&(u._dirty_coords||u.x!==u._x||u.y!==u._y||u.angle!==u._angle||u.scale_x!==u._scale_x||u.scale_y!==u._scale_y)&&u._calculateCoords(),n&&(t._dirty_coords||t.x!==t._x||t.y!==t._y||t.angle!==t._angle||t.scale_x!==t._scale_x||t.scale_y!==t._scale_y)&&t._calculateCoords(),(!i||Mt(u,t))&&(s&&u._dirty_normals&&u._calculateNormals(),n&&t._dirty_normals&&t._calculateNormals(),r=s&&n?Dt(u,t,e):s?xt(u,t,e,!1):n?xt(t,u,e,!0):Nt(u,t,e)),e&&(e.collision=r),r}function Mt(u,t){let e=u._polygon,i=e?0:u.x,s=e?0:u.y,n=e?0:u.radius*u.scale,r=e?u._min_x:i-n,o=e?u._min_y:s-n,a=e?u._max_x:i+n,l=e?u._max_y:s+n,h=t._polygon,d=h?0:t.x,c=h?0:t.y,_=h?0:t.radius*t.scale,p=h?t._min_x:d-_,m=h?t._min_y:c-_,f=h?t._max_x:d+_,b=h?t._max_y:c+_;return r<f&&o<b&&a>p&&l>m}function Dt(u,t,e=null){let i=u._coords.length,s=t._coords.length;if(i===2&&s===2){let l=u._coords,h=t._coords;return e&&(e.overlap=0),l[0]===h[0]&&l[1]===h[1]}let n=u._coords,r=t._coords,o=u._normals,a=t._normals;if(i>2){for(let l=0,h=1;l<i;l+=2,h+=2)if(Et(n,r,o[l],o[h],e))return!1}if(s>2){for(let l=0,h=1;l<s;l+=2,h+=2)if(Et(n,r,a[l],a[h],e))return!1}return!0}function xt(u,t,e=null,i=!1){let s=u._coords,n=u._edges,r=u._normals,o=t.x,a=t.y,l=t.radius*t.scale,h=l*2,d=l*l,c=s.length,_=!0,p=!0,m=null,f=0,b=0;if(c===2){let v=o-s[0],C=a-s[1],S=v*v+C*C;if(S>d)return!1;if(e){let E=Math.sqrt(S);m=l-E,f=v/E,b=C/E,p=!1}}else for(let v=0,C=1;v<c;v+=2,C+=2){let S=o-s[v],E=a-s[C],I=n[v],G=n[C],q=S*I+E*G,et=q<0?-1:q>I*I+G*G?1:0,L=!1,P=0,j=0,W=0;if(e&&_&&S*S+E*E>d&&(_=!1),et){let M=et===-1,D=M?v===0?c-2:v-2:v===c-2?0:v+2,T=D+1,B=o-s[D],Q=a-s[T],it=n[D],ft=n[T],gt=B*it+Q*ft;if((gt<0?-1:gt>it*it+ft*ft?1:0)===-et){let yt=M?S:B,vt=M?E:Q,Rt=yt*yt+vt*vt;if(Rt>d)return!1;if(e){let St=Math.sqrt(Rt);L=!0,P=l-St,j=yt/St,W=vt/St,p=!1}}}else{let M=r[v],D=r[C],T=S*M+E*D,B=T<0?-T:T;if(T>0&&B>l)return!1;e&&(L=!0,P=l-T,j=M,W=D,(p&&T>=0||P<h)&&(p=!1))}L&&(m===null||m>P)&&(m=P,f=j,b=W)}return e&&(e.a_in_b=i?p:_,e.b_in_a=i?_:p,e.overlap=m,e.overlap_x=i?-f:f,e.overlap_y=i?-b:b),!0}function Nt(u,t,e=null){let i=u.radius*u.scale,s=t.radius*t.scale,n=t.x-u.x,r=t.y-u.y,o=i+s,a=n*n+r*r;if(a>o*o)return!1;if(e){let l=Math.sqrt(a);e.a_in_b=i<=s&&l<=s-i,e.b_in_a=s<=i&&l<=i-s,e.overlap=o-l,e.overlap_x=n/l,e.overlap_y=r/l}return!0}function Et(u,t,e,i,s=null){let n=u.length,r=t.length;if(!n||!r)return!0;let o=null,a=null,l=null,h=null;for(let d=0,c=1;d<n;d+=2,c+=2){let _=u[d]*e+u[c]*i;(o===null||o>_)&&(o=_),(a===null||a<_)&&(a=_)}for(let d=0,c=1;d<r;d+=2,c+=2){let _=t[d]*e+t[c]*i;(l===null||l>_)&&(l=_),(h===null||h<_)&&(h=_)}if(o>h||a<l)return!0;if(s){let d=0;if(o<l)if(s.a_in_b=!1,a<h)d=a-l,s.b_in_a=!1;else{let p=a-l,m=h-o;d=p<m?p:-m}else if(s.b_in_a=!1,a>h)d=o-h,s.a_in_b=!1;else{let p=a-l,m=h-o;d=p<m?p:-m}let c=s.overlap,_=d<0?-d:d;if(c===null||c>_){let p=d<0?-1:1;s.overlap=_,s.overlap_x=e*p,s.overlap_y=i*p}}return!1}var k=class{constructor(){this.collision=!1;this.a=null;this.b=null;this.a_in_b=!1;this.b_in_a=!1;this.overlap=0;this.overlap_x=0;this.overlap_y=0}};var K=class{constructor(t=0,e=0,i=5){this._offset_x=0;this._offset_y=0;this._circle=!1;this._polygon=!1;this._point=!1;this._bvh=null;this._bvh_parent=null;this._bvh_branch=!1;this._bvh_min_x=0;this._bvh_min_y=0;this._bvh_max_x=0;this._bvh_max_y=0;this._parent_sprite=null;this._center_distance=0;this._center_angle=0;this.x=t,this.y=e,this.padding=i,this._bvh_padding=i}collides(t,e=null,i=!0){return rt(this,t,e,i)}potentials(){let t=this._bvh;if(t===null)throw new Error("Body does not belong to a collision system");return t.potentials(this)}remove(){let t=this._bvh;t&&t.remove(this,!1)}set parentSprite(t){this._parent_sprite=t}get parentSprite(){return this._parent_sprite}set offset_x(t){this._offset_x=-t,this.updateCenterParams()}get offset_x(){return-this._offset_x}set offset_y(t){this._offset_y=-t,this.updateCenterParams()}get offset_y(){return-this._offset_y}get center_offset_x(){if(this._parent_sprite.rotateStyle==="leftRight"||this._parent_sprite.rotateStyle==="none"){let t=this._parent_sprite._direction>180&&this._parent_sprite.rotateStyle==="leftRight"?-1:1;return this._offset_x*t}return this._center_distance*Math.cos(this._center_angle-this._parent_sprite.globalAngleRadians)}get center_offset_y(){return this._parent_sprite.rotateStyle==="leftRight"||this._parent_sprite.rotateStyle==="none"?-this._offset_y:-this._center_distance*Math.sin(this._center_angle-this._parent_sprite.globalAngleRadians)}createResult(){return new k}updateCenterParams(){this._center_distance=Math.hypot(this._offset_x,this._offset_y),this._center_angle=-Math.atan2(-this._offset_y,-this._offset_x)}static createResult(){return new k}};var F=class extends K{constructor(t=0,e=0,i=0,s=1,n=5){super(t,e,n),this.radius=i,this.scale=s}draw(t){let e=this.x,i=this.y,s=this.radius*this.scale;t.moveTo(e+s,i),t.arc(e,i,s,0,Math.PI*2)}};var w=class u extends K{constructor(e=0,i=0,s=[],n=0,r=1,o=1,a=5){super(e,i,a);this._min_x=0;this._min_y=0;this._max_x=0;this._max_y=0;this._points=null;this._coords=null;this._edges=null;this._normals=null;this._dirty_coords=!0;this._dirty_normals=!0;this._origin_points=null;this.angle=n,this.scale_x=r,this.scale_y=o,this._polygon=!0,this._x=e,this._y=i,this._angle=n,this._scale_x=r,this._scale_y=o,this._origin_points=s,u.prototype.setPoints.call(this,s)}draw(e){(this._dirty_coords||this.x!==this._x||this.y!==this._y||this.angle!==this._angle||this.scale_x!==this._scale_x||this.scale_y!==this._scale_y)&&this._calculateCoords();let i=this._coords;if(i.length===2)e.moveTo(i[0],i[1]),e.arc(i[0],i[1],1,0,Math.PI*2);else{e.moveTo(i[0],i[1]);for(let s=2;s<i.length;s+=2)e.lineTo(i[s],i[s+1]);i.length>4&&e.lineTo(i[0],i[1])}}setPoints(e){let i=e.length;this._points=new Float64Array(i*2),this._coords=new Float64Array(i*2),this._edges=new Float64Array(i*2),this._normals=new Float64Array(i*2);let s=this._points;for(let n=0,r=0,o=1;n<i;++n,r+=2,o+=2){let a=e[n];s[r]=a[0],s[o]=a[1]}this._dirty_coords=!0}_calculateCoords(){let e=this.x,i=this.y,s=this.angle,n=this.scale_x,r=this.scale_y,o=this._points,a=this._coords,l=o.length,h,d,c,_;for(let p=0,m=1;p<l;p+=2,m+=2){let f=o[p]*n,b=o[m]*r;if(s){let v=Math.cos(s),C=Math.sin(s),S=f,E=b;f=S*v-E*C,b=S*C+E*v}f+=e,b+=i,a[p]=f,a[m]=b,p===0?(h=d=f,c=_=b):(f<h?h=f:f>d&&(d=f),b<c?c=b:b>_&&(_=b))}this._x=e,this._y=i,this._angle=s,this._scale_x=n,this._scale_y=r,this._min_x=h,this._min_y=c,this._max_x=d,this._max_y=_,this._dirty_coords=!1,this._dirty_normals=!0}_calculateNormals(){let e=this._coords,i=this._edges,s=this._normals,n=e.length;for(let r=0,o=1;r<n;r+=2,o+=2){let a=r+2<n?r+2:0,l=e[a]-e[r],h=e[a+1]-e[o],d=l||h?Math.sqrt(l*l+h*h):0;i[r]=l,i[o]=h,s[r]=d?h/d:0,s[o]=d?-l/d:0}this._dirty_normals=!1}get points(){return this._origin_points}};var N=class extends w{constructor(t=0,e=0,i=5){super(t,e,[[0,0]],0,1,1,i),this._point=!0}};N.prototype.setPoints=void 0;var ot=class{constructor(){this._bvh=new nt}createCircle(t=0,e=0,i=0,s=1,n=0){let r=new F(t,e,i,s,n);return this._bvh.insert(r),r}createPolygon(t=0,e=0,i=[[0,0]],s=0,n=1,r=1,o=0){let a=new w(t,e,i,s,n,r,o);return this._bvh.insert(a),a}createPoint(t=0,e=0,i=0){let s=new N(t,e,i);return this._bvh.insert(s),s}createResult(){return new k}static createResult(){return new k}insert(...t){for(let e of t)this._bvh.insert(e,!1);return this}remove(...t){for(let e of t)this._bvh.remove(e,!1);return this}update(){return this._bvh.update(),this}draw(t){return this._bvh.draw(t)}drawBVH(t){return this._bvh.drawBVH(t)}potentials(t){return this._bvh.potentials(t)}collides(t,e,i=null,s=!0){return rt(t,e,i,s)}};var x=class x{static getMessage(t,e,i=null){if(!x.messages[t])throw new Error("Message is not defined.");if(!x.messages[t][e])throw new Error("Message for this locale is not defined.");let s=x.messages[t][e];return i&&(s=x.replaceVariables(s,i)),s}static replaceVariables(t,e){return t.replace(/\${([^}]+)}/g,(i,s)=>e[s]!==void 0?e[s]:"")}};x.SCRIPT_ERROR="script_error",x.MISTAKE_METHOD="mistake_method",x.MISTAKE_METHOD_WITH_CLOSEST="mistake_method_with_closest",x.NEED_STAGE_BEFORE_RUN_GAME="need_stage_before_run_game",x.NEED_CREATE_STAGE_BEFORE_SPRITE="need_create_stage_before_sprite",x.COSTUME_NOT_LOADED="costume_not_loaded",x.BACKGROUND_NOT_LOADED="background_not_loaded",x.CLONED_NOT_READY="cloned_not_ready",x.SOUND_INDEX_NOT_FOUND="sound_index_not_found",x.SOUND_NAME_NOT_FOUND="sound_name_not_found",x.SOUND_NAME_ALREADY_EXISTS="sound_name_already_exists",x.SOUND_NOT_ALLOWED_ERROR="sound_not_allowed_error",x.SOUND_USE_NOT_READY="sound_use_not_ready",x.COSTUME_INDEX_NOT_FOUND="costume_index_not_found",x.COSTUME_NAME_NOT_FOUND="costume_name_not_found",x.COSTUME_SWITCH_NOT_READY="costume_switch_not_ready",x.STAMP_NOT_READY="stamp_not_ready",x.STAMP_COSTUME_NOT_FOUND="stamp_costume_not_found",x.COLLIDER_NAME_NOT_FOUND="collider_name_not_found",x.STAGE_SET_BEFORE_GAME_READY="stage_set_before_game_ready",x.messages={script_error:{ru:"\u041F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430, \u043E\u0437\u043D\u0430\u043A\u043E\u043C\u044C\u0442\u0435\u0441\u044C \u0441 \u043F\u043E\u0434\u0440\u043E\u0431\u043D\u043E\u0439 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0435\u0439 \u0432 \u043A\u043E\u043D\u0441\u043E\u043B\u0438.",en:"An error has occurred, take a look at the details in the console."},mistake_method:{ru:'${className}: \u041C\u0435\u0442\u043E\u0434 \u0438\u043B\u0438 \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u043E "${prop}" \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E',en:'${className}: Method "${prop}" not found'},mistake_method_with_closest:{ru:'${className}: \u041C\u0435\u0442\u043E\u0434 \u0438\u043B\u0438 \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u043E "${prop}" \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E. \u0412\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0432\u044B \u0438\u043C\u0435\u043B\u0438 \u0432\u0432\u0438\u0434\u0443: ${closestString}?',en:'${className}: Method "${prop}" not found. Did you mean: ${closestString}?'},need_stage_before_run_game:{ru:"\u0412\u0430\u043C \u043D\u0443\u0436\u043D\u043E \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440 Stage \u043F\u0435\u0440\u0435\u0434 \u0437\u0430\u043F\u0443\u0441\u043A\u043E\u043C \u0438\u0433\u0440\u044B.",en:"You need create Stage instance before run game."},need_create_stage_before_sprite:{ru:"\u0412\u0430\u043C \u043D\u0443\u0436\u043D\u043E \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440 \u043A\u043B\u0430\u0441\u0441\u0430 Stage \u043F\u0435\u0440\u0435\u0434 \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440\u043E\u043C \u043A\u043B\u0430\u0441\u0441\u0430 Sprite.",en:"You need create Stage instance before Sprite instance."},costume_not_loaded:{ru:'\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u0434\u043B\u044F \u043A\u043E\u0441\u0442\u044E\u043C\u0430 "${costumePath}" \u043D\u0435 \u0431\u044B\u043B\u043E \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E. \u041F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E\u0441\u0442\u044C \u043F\u0443\u0442\u0438.',en:'Costume image "${costumePath}" was not loaded. Check that the path is correct.'},background_not_loaded:{ru:'\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u0434\u043B\u044F \u0444\u043E\u043D\u0430 "${backgroundPath}" \u043D\u0435 \u0431\u044B\u043B\u043E \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E. \u041F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E\u0441\u0442\u044C \u043F\u0443\u0442\u0438.',en:'Background image "${backgroundPath}" was not loaded. Check that the path is correct.'},cloned_not_ready:{ru:"\u0421\u043F\u0440\u0430\u0439\u0442 \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043A\u043B\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u043D, \u043F\u043E\u0442\u043E\u043C\u0443 \u0447\u0442\u043E \u043E\u043D \u0435\u0449\u0435 \u043D\u0435 \u0433\u043E\u0442\u043E\u0432. \u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u043C\u0435\u0442\u043E\u0434 sprite.onReady()",en:"Sprite cannot be cloned because one is not ready. Try using the sprite.onReady() method."},sound_index_not_found:{ru:'\u0417\u0432\u0443\u043A \u0441 \u0438\u043D\u0434\u0435\u043A\u0441\u043E\u043C "${soundIndex}" \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.',en:'Sound with index "${soundIndex}" not found.'},sound_name_not_found:{ru:'\u0417\u0432\u0443\u043A \u0441 \u0438\u043C\u0435\u043D\u0435\u043C "${soundName}" \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.',en:'Sound with name "${soundName}" not found.'},sound_name_already_exists:{ru:'\u0417\u0432\u0443\u043A \u0441 \u0438\u043C\u0435\u043D\u0435\u043C "${soundName}" \u0443\u0436\u0435 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D.',en:'Sound with name "${soundName}" already exists.'},sound_use_not_ready:{ru:"\u0421\u043F\u0440\u0430\u0439\u0442 \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0437\u0432\u0443\u043A\u0438, \u043F\u043E\u0442\u043E\u043C\u0443 \u0447\u0442\u043E \u0441\u043F\u0440\u0430\u0439\u0442 \u0435\u0449\u0435 \u043D\u0435 \u0433\u043E\u0442\u043E\u0432. \u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u043C\u0435\u0442\u043E\u0434 sprite.onReady().",en:"Sprite cannot use sounds because sprite is not ready. Try using the sprite.onReady() method."},sound_not_allowed_error:{ru:"\u0412\u043E\u0441\u043F\u0440\u043E\u0438\u0437\u0432\u0435\u0434\u0435\u043D\u0438\u0435 \u0437\u0432\u0443\u043A\u0430 \u0437\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043E. \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u0434\u043E\u043B\u0436\u0435\u043D \u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u0432\u0437\u0430\u0438\u043C\u043E\u0434\u0435\u0439\u0441\u0442\u0432\u043E\u0432\u0430\u0442\u044C \u0441 \u0438\u0433\u0440\u043E\u0439. \u0412\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043C\u0435\u0442\u043E\u0434\u043E\u043C Game.onUserInteracted()",en:"Audio playback is blocked. The user must first interact with the game. Use the Game.onUserInteracted() method."},costume_index_not_found:{ru:'\u041A\u043E\u0441\u0442\u044E\u043C \u0441 \u0438\u043D\u0434\u0435\u043A\u0441\u043E\u043C "${costumeIndex}" \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.',en:'Costume with index "${costumeIndex}" not found.'},costume_name_not_found:{ru:'\u041A\u043E\u0441\u0442\u044E\u043C \u0441 \u0438\u043C\u0435\u043D\u0435\u043C "${costumeName}" \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.',en:'Costume with name "${costumeName}" not found.'},costume_switch_not_ready:{ru:"\u0421\u043F\u0440\u0430\u0439\u0442 \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0438\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u043A\u043E\u0441\u0442\u044E\u043C, \u043F\u043E\u0442\u043E\u043C\u0443 \u0447\u0442\u043E \u0441\u043F\u0440\u0430\u0439\u0442 \u0435\u0449\u0435 \u043D\u0435 \u0433\u043E\u0442\u043E\u0432. \u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u043C\u0435\u0442\u043E\u0434 sprite.onReady().",en:"Sprite cannot change a costume because sprite is not ready. Try using the sprite.onReady() method."},stamp_not_ready:{ru:"\u0421\u043F\u0440\u0430\u0439\u0442 \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u0448\u0442\u0430\u043C\u043F, \u043F\u043E\u0442\u043E\u043C\u0443 \u0447\u0442\u043E \u043E\u043D \u0435\u0449\u0435 \u043D\u0435 \u0433\u043E\u0442\u043E\u0432. \u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u043C\u0435\u0442\u043E\u0434 sprite.onReady()",en:"Sprite cannot create a stamp because sprite is not ready. Try using the sprite.onReady() method."},stamp_costume_not_found:{ru:'\u0428\u0442\u0430\u043C \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u0441\u043E\u0437\u0434\u0430\u043D, \u0442\u0430\u043A \u043A\u0430\u043A \u043A\u043E\u0441\u0442\u044E\u043C \u0441 \u0438\u043D\u0434\u0435\u043A\u0441\u043E\u043C "${costumeIndex}" \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.',en:'The stamp cannot be created because the costume with the index "${costumeIndex}" has not been found.'},collider_name_not_found:{ru:'\u041A\u043E\u043B\u043B\u0430\u0439\u0434\u0435\u0440 \u0441 \u0438\u043C\u0435\u043D\u0435\u043C "${colliderName}" \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.',en:'Collider with name "${colliderName}" not found.'},stage_set_before_game_ready:{ru:"\u0421\u043F\u0440\u0430\u0439\u0442 \u043C\u0435\u043D\u044F\u0435\u0442 \u0441\u0446\u0435\u043D\u0443 \u0434\u043E \u0433\u043E\u0442\u043E\u0432\u043D\u043E\u0441\u0442\u0438 \u0438\u0433\u0440\u044B.",en:"Sprite changed stage before game is ready."}};var y=x;var bt=class bt{static getChar(t){return bt.map[t]}};bt.map=["","","","CANCEL","","","HELP","","BACK_SPACE","TAB","","","CLEAR","ENTER","ENTER_SPECIAL","","SHIFT","CONTROL","ALT","PAUSE","CAPS_LOCK","KANA","EISU","JUNJA","FINAL","HANJA","","ESCAPE","CONVERT","NONCONVERT","ACCEPT","MODECHANGE","SPACE","PAGE_UP","PAGE_DOWN","END","HOME","LEFT","UP","RIGHT","DOWN","SELECT","PRINT","EXECUTE","PRINTSCREEN","INSERT","DELETE","","0","1","2","3","4","5","6","7","8","9","COLON","SEMICOLON","LESS_THAN","EQUALS","GREATER_THAN","QUESTION_MARK","AT","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","OS_KEY","","CONTEXT_MENU","","SLEEP","NUMPAD0","NUMPAD1","NUMPAD2","NUMPAD3","NUMPAD4","NUMPAD5","NUMPAD6","NUMPAD7","NUMPAD8","NUMPAD9","MULTIPLY","ADD","SEPARATOR","SUBTRACT","DECIMAL","DIVIDE","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12","F13","F14","F15","F16","F17","F18","F19","F20","F21","F22","F23","F24","","","","","","","","","NUM_LOCK","SCROLL_LOCK","WIN_OEM_FJ_JISHO","WIN_OEM_FJ_MASSHOU","WIN_OEM_FJ_TOUROKU","WIN_OEM_FJ_LOYA","WIN_OEM_FJ_ROYA","","","","","","","","","","CIRCUMFLEX","EXCLAMATION","DOUBLE_QUOTE","HASH","DOLLAR","PERCENT","AMPERSAND","UNDERSCORE","OPEN_PAREN","CLOSE_PAREN","ASTERISK","PLUS","PIPE","HYPHEN_MINUS","OPEN_CURLY_BRACKET","CLOSE_CURLY_BRACKET","TILDE","","","","","VOLUME_MUTE","VOLUME_DOWN","VOLUME_UP","","","SEMICOLON","EQUALS","COMMA","MINUS","PERIOD","SLASH","BACK_QUOTE","","","","","","","","","","","","","","","","","","","","","","","","","","","OPEN_BRACKET","BACK_SLASH","CLOSE_BRACKET","QUOTE","","META","ALTGR","","WIN_ICO_HELP","WIN_ICO_00","","WIN_ICO_CLEAR","","","WIN_OEM_RESET","WIN_OEM_JUMP","WIN_OEM_PA1","WIN_OEM_PA2","WIN_OEM_PA3","WIN_OEM_WSCTRL","WIN_OEM_CUSEL","WIN_OEM_ATTN","WIN_OEM_FINISH","WIN_OEM_COPY","WIN_OEM_AUTO","WIN_OEM_ENLW","WIN_OEM_BACKTAB","ATTN","CRSEL","EXSEL","EREOF","PLAY","ZOOM","","PA1","WIN_OEM_CLEAR",""];var A=bt;var at=class{constructor(){this.keys={};document.addEventListener("keydown",t=>{let e=A.getChar(t.keyCode);this.keys[e]=!0}),document.addEventListener("keyup",t=>{let e=A.getChar(t.keyCode);delete this.keys[e]})}keyPressed(t){return this.keys[t.toUpperCase()]!==void 0}keyDown(t,e){document.addEventListener("keydown",i=>{let s=A.getChar(i.keyCode);t.toUpperCase()==s&&e(i)})}keyUp(t,e){document.addEventListener("keyup",i=>{let s=A.getChar(i.keyCode);t.toUpperCase()==s&&e(i)})}};var lt=class{constructor(t){this.x=0;this.y=0;this.isDown=!1;document.addEventListener("mousedown",()=>{this.isDown=!0,this.lastStage=t.getActiveStage()}),document.addEventListener("mouseup",()=>{this.isDown=!1}),document.addEventListener("mousemove",e=>{this.x=t.correctMouseX(e.clientX),this.y=t.correctMouseY(e.clientY)}),this.point=new N(this.x,this.y)}getPoint(){return this.point.x=this.x,this.point.y=this.y,this.point}isMouseDown(t){return this.isDown&&t===this.lastStage}clearMouseDown(){this.isDown=!1}};var O=class u{constructor(){this.data={}}static getInstance(){return this.instance||(this.instance=new u),this.instance}set(t,e){this.data[t]=e}has(t){return this.data[t]!==void 0}get(t){return this.data[t]}};var ht=class{constructor(t,e,i){this.canvas=t,this.setEnvironmentStyles(),this.setCanvasSize(e,i),this.canvasRect=t.getBoundingClientRect(),window.addEventListener("resize",()=>{this.setCanvasSize(e,i),this.canvasRect=t.getBoundingClientRect()})}setEnvironmentStyles(){document.body.style.margin="0",document.body.style.height="100vh",document.body.style.padding="0",document.body.style.overflow="hidden",document.body.style.display="flex",document.body.style.alignItems="center",document.body.style.justifyContent="center"}setCanvasSize(t,e){this.canvas.width=t||document.body.clientWidth,this.canvas.height=e||document.body.clientHeight}};var ct=class u{constructor(t){this.game=t}createValidator(t,e){let i=this.game;return new Proxy(t,{get(s,n){if(n in s)return s[n];if(typeof n=="symbol"||n.startsWith("_"))return;let r=Object.getOwnPropertyNames(Object.getPrototypeOf(s)).filter(a=>a!=="constructor"),o=u.findClosestMethods(n.toString(),r);if(o.length){let a=o.join(", ");i.throwError(y.MISTAKE_METHOD_WITH_CLOSEST,{className:e,prop:n,closestString:a})}else i.throwError(y.MISTAKE_METHOD,{className:e,prop:n})}})}static findClosestMethods(t,e,i=2){return e.map(s=>({name:s,distance:u.levenshteinDistance(t.toLowerCase(),s.toLowerCase())})).filter(({distance:s})=>s<=i).sort((s,n)=>s.distance-n.distance).map(({name:s})=>s).slice(0,3)}static levenshteinDistance(t,e){let i=Array(t.length+1).fill(null).map(()=>Array(e.length+1).fill(0));for(let s=0;s<=t.length;s++)i[s][0]=s;for(let s=0;s<=e.length;s++)i[0][s]=s;for(let s=1;s<=t.length;s++)for(let n=1;n<=e.length;n++){let r=t[s-1]===e[n-1]?0:1;i[s][n]=Math.min(i[s-1][n]+1,i[s][n-1]+1,i[s-1][n-1]+r)}return i[t.length][e.length]}};var z=class{constructor(){this.ready=!1}get width(){return this.image instanceof HTMLCanvasElement?this.image.width:0}get height(){return this.image instanceof HTMLCanvasElement?this.image.height:0}};var Y=class{constructor(){this.callbacksMap=new Map;this.eventTarget=new EventTarget}once(t,e,i){if(this.callbacksMap.get(t))return!1;let s=n=>{typeof i=="function"?i(n):i.handleEvent(n),this.eventTarget.removeEventListener(e,s),this.remove(t)};return this.eventTarget.addEventListener(e,s),this.callbacksMap.set(t,{type:e,callback:s}),!0}on(t,e,i){return this.callbacksMap.get(t)?!1:(this.eventTarget.addEventListener(e,i),this.callbacksMap.set(t,{type:e,callback:i}),!0)}emit(t,e){this.eventTarget.dispatchEvent(new CustomEvent(t,{detail:e}))}remove(t){let e=this.callbacksMap.get(t);return e?(this.eventTarget.removeEventListener(e.type,e.callback),this.callbacksMap.delete(t),!0):!1}removeByType(t){this.callbacksMap.forEach((e,i)=>{t===e.type&&(this.eventTarget.removeEventListener(e.type,e.callback),this.callbacksMap.delete(i))})}clearAll(){this.callbacksMap.forEach(t=>{this.eventTarget.removeEventListener(t.type,t.callback)}),this.callbacksMap.clear()}};var J=class J{constructor(t=null,e=null,i=null,s=!0,n="ru",r=!1){this.debugMode="none";this.debugCollider=!1;this.debugColor="red";this.stages=[];this.activeStage=null;this.styles=null;this.loadedStages=0;this.onReadyCallbacks=[];this.onUserInteractedCallbacks=[];this.onReadyPending=!0;this.running=!1;this.pendingRun=!1;this.reportedError=!1;this._displayErrors=!0;this._locale="ru";this._userInteracted=!1;this._displayErrors=s,this._locale=n,this.validatorFactory=new ct(this);let o=this;if(this.displayErrors&&(o=this.validatorFactory.createValidator(this,"Game")),window.onerror=()=>{o.reportError(y.getMessage(y.SCRIPT_ERROR,o._locale))},o.id=Symbol(),o.eventEmitter=new Y,o.keyboard=new at,i){let a=document.getElementById(i);a instanceof HTMLCanvasElement&&(o.canvas=a)}else o.canvas=document.createElement("canvas"),document.body.appendChild(o.canvas);return o.canvas.width=t,o.canvas.height=e,o.styles=new ht(o.canvas,t,e),o.mouse=new lt(o),o.context=o.canvas.getContext("2d"),o.context.imageSmoothingEnabled=r,O.getInstance().set("game",o),o.addListeners(),o}addStage(t){return this.stages.push(t),this}getLastStage(){return this.stages.length?this.stages[this.stages.length-1]:null}getActiveStage(){return this.activeStage?this.activeStage:null}run(t=null){if(!(this.activeStage&&this.activeStage==t)){if(!t&&this.stages.length&&(t=this.stages[0]),t||this.throwError(y.NEED_STAGE_BEFORE_RUN_GAME),!this.running)for(let e of this.stages)e.ready();this.activeStage&&this.activeStage.running&&this.activeStage.stop(),this.running=!1,this.pendingRun=!0,this.activeStage=t,this.tryDoRun()}}isReady(){return this.loadedStages==this.stages.length}onReady(t){this.onReadyCallbacks.push(t)}onUserInteracted(t){this.onUserInteractedCallbacks.push(t)}stop(){this.activeStage&&this.activeStage.running&&this.activeStage.stop(),this.running=!1}get displayErrors(){return this._displayErrors}get locale(){return this._locale}get width(){return this.canvas.width}get height(){return this.canvas.height}get userInteracted(){return this._userInteracted}isInsideGame(t,e){return t>=0&&t<=this.width&&e>=0&&e<=this.height}correctMouseX(t){let e=this.activeStage?this.activeStage.camera.startCornerX:0;return t-this.styles.canvasRect.left+e}correctMouseY(t){let e=this.activeStage?this.activeStage.camera.startCornerY:0;return t-this.styles.canvasRect.top+e}keyPressed(t){if(Array.isArray(t)){for(let e of t)if(this.keyboard.keyPressed(e))return!0;return!1}return this.keyboard.keyPressed(t)}keyDown(t,e){this.keyboard.keyDown(t,e)}keyUp(t,e){this.keyboard.keyUp(t,e)}mouseDown(){return this.mouse.isMouseDown(this.activeStage)}mouseDownOnce(){let t=this.mouse.isMouseDown(this.activeStage);return this.mouse.clearMouseDown(),t}getMousePoint(){return this.mouse.getPoint()}getRandom(t,e){return Math.floor(Math.random()*(e-t+1))+t}throwError(t,e=null,i=!0){let s=y.getMessage(t,this.locale,e);this.throwErrorRaw(s,i)}throwErrorRaw(t,e=!0){throw e&&this.reportError(t),new Error(t)}reportError(t){this._displayErrors&&!this.reportedError&&(alert(t),this.reportedError=!0)}addListeners(){this.eventEmitter.on(J.STAGE_READY_EVENT,J.STAGE_READY_EVENT,t=>{this.loadedStages++,this.tryDoOnReady()}),document.addEventListener("visibilitychange",()=>{document.hidden?this.activeStage&&this.activeStage.running&&this.activeStage.stop():this.activeStage&&this.activeStage.stopped&&this.activeStage.run()}),this.userInteractionPromise=new Promise(t=>{document.addEventListener("click",t,{once:!0}),document.addEventListener("keydown",e=>{["Control","Shift","CapsLock","NumLock","Alt","Meta"].includes(e.key)||t(!0)},{once:!0})})}tryDoOnReady(){if(this.isReady()&&this.onReadyPending){if(this.onReadyPending=!1,this.onReadyCallbacks.length){for(let t of this.onReadyCallbacks)t();this.onReadyCallbacks=[]}this.userInteractionPromise.then(()=>{this._userInteracted=!0,this.onUserInteractedCallbacks.filter(t=>(t(this),!1))}),this.tryDoRun()}}tryDoRun(){this.pendingRun&&!this.running&&this.isReady()&&(this.running=!0,this.pendingRun=!1,this.activeStage.run())}};J.STAGE_READY_EVENT="scrubjs.stage.ready",J.STAGE_BACKGROUND_READY_EVENT="scrubjs.stage.background_ready",J.SPRITE_READY_EVENT="scrubjs.sprite.ready";var R=J;var U=class{constructor(t,e,i,s){this.callback=t,this.state=e,this.timeout=i,this.finishCallback=s}};var H=class{constructor(t,e,i){this.interval=t,this.maxIterations=e,this.currentIteration=i}};var $=class{constructor(t,e=0,i=[],s=null){this.name="No name";this.game=null;this.stage=null;this._parentSprite=null;this._collidedSprite=null;this._original=null;this.costumeIndex=null;this.costume=null;this.costumes=[];this.costumeNames=[];this.sounds=[];this.soundNames=[];this.currentColliderName=null;this.colliders=new Map;this.phrase=null;this.phraseLiveTime=null;this._x=0;this._y=0;this._pivotOffsetX=0;this._pivotOffsetY=0;this._width=0;this._height=0;this._defaultColliderNone=!1;this._direction=0;this._size=100;this._centerDistance=0;this._centerAngle=0;this._rotateStyle="normal";this._hidden=!1;this._opacity=null;this._filter=null;this._deleted=!1;this._stopped=!0;this.pendingCostumeGrids=0;this.pendingCostumes=0;this.pendingSounds=0;this._children=[];this.onReadyCallbacks=[];this.onReadyPending=!0;this.scheduledCallbacks=[];this.tempScheduledCallbacks=[];this._drawings=[];this._tags=[];this.stoppedTime=null;this.diffTime=null;if(!O.getInstance().has("game"))throw new Error("You need create Game instance before Stage instance.");this.game=O.getInstance().get("game");let n=this;this.game.displayErrors&&(n=this.game.validatorFactory.createValidator(this,"Sprite")),n.id=Symbol(),n.eventEmitter=new Y,n.collisionResult=new k,n.stage=t,this.stage||(n.stage=this.game.getLastStage()),n.stage||n.game.throwError(y.STAGE_SET_BEFORE_GAME_READY),n._layer=e,n._x=n.game.width/2,n._y=n.game.height/2;for(let r of i)n.addCostume(r);return n.scheduledCallbackExecutor=new V(n),n.stage.addSprite(n),s?this.setOriginal(s):n.init(),n.stoppedTime=Date.now(),n}init(){}onReady(t){this.onReadyCallbacks.push(t)}isReady(){return this.pendingCostumes===0&&this.pendingCostumeGrids===0&&this.pendingSounds===0||this.game.isReady()}get deleted(){return this._deleted}get stopped(){return this._stopped}setParent(t){return t.addChild(this),this}addChild(t){if(!this._children.includes(t)){this._children.push(t),t.parent=this,t.layer=this.layer,t.x=0,t.y=0,t.direction=0;for(let e of this.tags)t.addTag(e)}return t.parent=this,this}removeChild(t){let e=this._children.indexOf(t);if(e>-1){let i=this._children[e];i.parent=null;for(let s of this.tags)i.removeTag(s);this._children.splice(e,1)}return this}getChildren(){return this._children}set parent(t){this._parentSprite=t}get parent(){return this._parentSprite}getMainSprite(){return this._parentSprite?this._parentSprite.getMainSprite():this}switchCollider(t){if(this.colliders.has(t)||this.game.throwError(y.COLLIDER_NAME_NOT_FOUND,{colliderName:t}),this.currentColliderName===t)return this;let e=this.collider;e&&this.stage.collisionSystem.remove(e),this.currentColliderName=t;let i=this.collider;return this.stage.collisionSystem.insert(i),this._width=i.width,this._height=i.height,this}get launched(){return!this.onReadyPending}setCollider(t,e,i=0,s=0){if(e.parentSprite=this,e.offset_x=i,e.offset_y=s,this.currentColliderName===t&&this.colliders.has(t)){let n=this.colliders.get(t);this.stage.collisionSystem.remove(n),this.currentColliderName=null}return this.colliders.set(t,e),this.updateColliderPosition(e),this.isReady()&&!this.collider&&this.switchCollider(t),this}setRectCollider(t,e,i,s=0,n=0){let r=0;this._rotateStyle!="leftRight"&&(r=this.globalAngleRadians);let o=new w(this.x,this.y,[[e/2*-1,i/2*-1],[e/2,i/2*-1],[e/2,i/2],[e/2*-1,i/2]],r,this.size/100,this.size/100);return o.width=e,o.height=i,this.setCollider(t,o,s,n),this}setPolygonCollider(t,e,i=0,s=0){let n=0;this._rotateStyle!="leftRight"&&(n=this.globalAngleRadians);let r=this.calculateCentroid(e),o=e.map(d=>[d[0]-r.x,d[1]-r.y]),a=new w(this.x,this.y,o,n,this.size/100,this.size/100),{width:l,height:h}=this.calculatePolygonSize(o);return a.width=l,a.height=h,this.setCollider(t,a,i,s),this}setCircleCollider(t,e,i=0,s=0){let n=new F(this.x,this.y,e,this.size/100);return n.width=e*2,n.height=e*2,this.setCollider(t,n,i,s),this}setCostumeCollider(t,e=0,i=0,s=0){this.costumes[e]===void 0&&this.game.throwError(y.COSTUME_INDEX_NOT_FOUND,{costumeIndex:e});let n=this.costumes[e];return this.setRectCollider(t,n.width,n.height,i,s),this}removeCollider(t){if(t)this.removeColliderByName(t);else{let e=this.collider;e&&this.stage.collisionSystem.remove(e),this.colliders.clear(),this.currentColliderName=null,this.defaultColliderNone=!0}return this}removeColliderByName(t){let e=this.getCollider(t);if(this.colliders.delete(t),this.colliders.size===0&&(this.defaultColliderNone=!0),t===this.currentColliderName&&(this.stage.collisionSystem.remove(e),this.colliders.size)){let i=this.colliders.keys().next().value;this.switchCollider(i)}return this}getCollider(t){return this.colliders.has(t)||this.game.throwError(y.COLLIDER_NAME_NOT_FOUND,{colliderName:t}),this.colliders.get(t)}hasCollider(t){return this.colliders.has(t)}get collider(){return this.currentColliderName&&this.colliders.has(this.currentColliderName)?this.colliders.get(this.currentColliderName):null}get collidedSprite(){return this._collidedSprite}set defaultColliderNone(t){this._defaultColliderNone=t}get defaultColliderNone(){return this._defaultColliderNone}getColliders(){return this.colliders.entries()}cloneCollider(t){let e=t.getColliders();for(let[i,s]of e)s instanceof F&&this.setCircleCollider(i,s.radius,s.offset_x,s.offset_y),s instanceof w&&this.setPolygonCollider(i,s.points,s.offset_x,s.offset_y)}calculateCentroid(t){let e=0,i=0;for(let r of t)e+=r[0],i+=r[1];let s=e/t.length,n=i/t.length;return{x:s,y:n}}calculatePolygonSize(t){let e=t[0][0],i=t[0][1],s=t[0][0],n=t[0][1];for(let a of t)a[0]<e&&(e=a[0]),a[0]>s&&(s=a[0]),a[1]<i&&(i=a[1]),a[1]>n&&(n=a[1]);let r=s-e,o=n-i;return{width:r,height:o}}updateColliderPosition(t){t.x=this.imageCenterX+t.center_offset_x*this.size/100,t.y=this.imageCenterY+t.center_offset_y*this.size/100}updateColliderAngle(){let t=this.collider;t instanceof w&&(this._rotateStyle=="leftRight"?t.angle=0:t.angle=this.globalAngleRadians),t&&this.updateColliderPosition(t)}updateColliderSize(t){t instanceof w?(t.scale_x=this.size/100,t.scale_y=this.size/100):t instanceof F&&(t.scale=this.size/100)}addTag(t){this.hasTag(t)||this._tags.push(t);for(let e of this._children)e.addTag(t);return this}removeTag(t){let e=this._tags.indexOf(t);e>-1&&this._tags.splice(e,1);for(let i of this._children)i.addTag(t);return this}hasTag(t){return this._tags.includes(t)}get tags(){return this._tags}addCostume(t,e){let i=new z,s=this.costumes.length,n=(e?.name??"Costume")+"-"+s;this.costumes.push(i),this.costumeNames.push(n),this.pendingCostumes++;let r=new Image;r.src=t,e?.alphaColor&&(r.crossOrigin="anonymous");let o=()=>{if(this.deleted)return;let a=this.transformImage(r,e?.rotate??0,e?.flipX??!1,e?.flipY??!1,e?.x??0,e?.y??0,e?.width??r.naturalWidth,e?.height??r.naturalHeight,e?.alphaColor??null,e?.alphaTolerance??0,e?.crop??0,e?.cropTop??null,e?.cropRight??null,e?.cropBottom??null,e?.cropLeft??null);i.image=a,i.ready=!0,this.pendingCostumes--,this.tryDoOnReady(),r.removeEventListener("load",o)};return r.addEventListener("load",o),r.addEventListener("error",()=>{this.game.throwError(y.COSTUME_NOT_LOADED,{costumePath:t})}),this}addCostumeGrid(t,e){let i=new Image;i.src=t;let s=e?.name??"Costume";this.pendingCostumeGrids++;let n=()=>{i.naturalWidth,i.naturalHeight;let r=e.cols,o=e.rows,a=e.limit,l=e.offset,h=i.naturalWidth/r,d=i.naturalHeight/o,c=!1,_=0,p=0,m=0;for(let f=0;f<o;f++){for(let b=0;b<r;b++){if(c=!1,l!==null&&l>0&&(l--,c=!0),!c){if(a!==null){if(a==0)break;a>0&&a--}let v=new z;this.costumes.push(v),this.costumeNames.push(s+"-"+_);let C=this.transformImage(i,e?.rotate??0,e?.flipX??!1,e?.flipY??!1,p+(e?.x??0),m+(e?.y??0),e?.width??h,e?.height??d,e?.alphaColor??null,e?.alphaTolerance??0,e?.crop??0,e?.cropTop??null,e?.cropRight??null,e?.cropBottom??null,e?.cropLeft??null);v.image=C,v.ready=!0,_++}p+=h}p=0,m+=d}this.pendingCostumeGrids--,this.tryDoOnReady(),i.removeEventListener("load",n)};return i.addEventListener("load",n),this}drawCostume(t,e){let i=document.createElement("canvas"),s=i.getContext("2d");i.width=e?.width??100,i.height=e?.height??100,this.pendingCostumes++,t(s,this);let n=this.costumes.length,r=(e?.name??"Costume")+"-"+n;Object.values(e||{}).some(l=>!!l)&&(i=this.transformImage(i,e?.rotate??0,e?.flipX??!1,e?.flipY??!1,e?.x??0,e?.y??0,e?.width??i.width,e?.height??i.height,e?.alphaColor??null,e?.alphaTolerance??0,e?.crop??0,e?.cropTop??null,e?.cropRight??null,e?.cropBottom??null,e?.cropLeft??null));let a=new z;return a.image=i,a.ready=!0,this.costumes.push(a),this.costumeNames.push(r+"-"+n),this.pendingCostumes--,this}removeCostume(t){return this.costumes[t]===void 0&&this.game.throwError(y.COSTUME_INDEX_NOT_FOUND,{costumeIndex:t}),this.costumes.splice(t,1),this.costumeNames.splice(t,1),this.costumeIndex===t&&(this.costumeIndex=null,this.costumes.length>0?this.nextCostume():this.costume=null),this}switchCostume(t){if(this.deleted)return;this.isReady()||this.game.throwError(y.COSTUME_SWITCH_NOT_READY);let e=this.costumes[t];return e instanceof z&&e.ready&&(this.costumeIndex=t,this.costume=e),this}switchCostumeByName(t){this.isReady()||this.game.throwError(y.COSTUME_SWITCH_NOT_READY);let e=this.costumeNames.indexOf(t);return e>-1?this.switchCostume(e):this.game.throwError(y.COSTUME_NAME_NOT_FOUND,{costumeName:t}),this}nextCostume(t=0,e){if(this.deleted)return;this.isReady()||this.game.throwError(y.COSTUME_SWITCH_NOT_READY);let i=this.costumes.length-1;t=Math.min(i,Math.max(0,t)),e=Math.min(i,Math.max(0,e??i));let s=this.costumeIndex+1;return(s>e||s<t)&&(s=t),s!==this.costumeIndex&&this.switchCostume(s),s}prevCostume(t=0,e){if(this.deleted)return;this.isReady()||this.game.throwError(y.COSTUME_SWITCH_NOT_READY);let i=this.costumes.length-1;t=Math.min(i,Math.max(0,t)),e=Math.min(i,Math.max(0,e??i));let s=this.costumeIndex-1;return(s<t||s>e)&&(s=e),s!==this.costumeIndex&&this.switchCostume(s),s}getCostume(){return this.costume}getCostumeName(){return this.costumeIndex===null?"No costume":this.costumeNames[this.costumeIndex]}getCostumeIndex(){return this.costumeIndex}transformImage(t,e,i=!1,s=!1,n=0,r=0,o=null,a=null,l=null,h=0,d=0,c=null,_=null,p=null,m=null){c=c??d,_=_??d,p=p??d,m=m??d,n+=_,o-=_,o-=m,r+=c,a-=c,a-=p;let f=document.createElement("canvas"),b=f.getContext("2d"),v=e*Math.PI/180,C=o??(t instanceof HTMLImageElement?t.naturalWidth:t.width),S=a??(t instanceof HTMLImageElement?t.naturalHeight:t.height);if(e){let G=Math.abs(Math.cos(v)),q=Math.abs(Math.sin(v));C=C*G+S*q,S=C*q+S*G}f.width=Math.ceil(C),f.height=Math.ceil(S),b.translate(f.width/2,f.height/2),e&&b.rotate(v),(i||s)&&b.scale(i?-1:1,s?-1:1);let E=-o/2,I=-a/2;return b.drawImage(t,n,r,o,a,E,I,o,a),l&&(f=this.setAlpha(f,l,h??0)),f}setAlpha(t,e,i=0){let s=document.createElement("canvas"),n=s.getContext("2d");if(!n)throw new Error("Canvas context is not available");s.width=t.width,s.height=t.height;let r=t.getContext("2d").getImageData(0,0,t.width,t.height),o=r.data,a;if(typeof e=="string"){if(a=this.hexToRgb(e),!a)throw new Error(`Invalid HEX color: ${e}`)}else a=e;for(let l=0;l<o.length;l+=4){let h=o[l],d=o[l+1],c=o[l+2];Math.abs(h-a.r)<=i&&Math.abs(d-a.g)<=i&&Math.abs(c-a.b)<=i&&(o[l+3]=0)}return n.putImageData(r,0,0),s}hexToRgb(t){if(t=t.replace(/^#/,""),t.length===3&&(t=t.split("").map(i=>i+i).join("")),t.length!==6)return null;let e=parseInt(t,16);return{r:e>>16&255,g:e>>8&255,b:e&255}}cloneCostume(t,e){this.costumes.push(t),this.costumeNames.push(e)}addSound(t,e){this.soundNames.includes(e)&&this.game.throwError(y.SOUND_NAME_ALREADY_EXISTS,{soundName:e});let i=new Audio;i.src=t,this.sounds.push(i),this.soundNames.push(e),this.pendingSounds++,i.load();let s=()=>{this.pendingSounds--,this.tryDoOnReady(),i.removeEventListener("loadedmetadata",s)};return i.addEventListener("loadedmetadata",s),this}removeSound(t){let e=this.soundNames.indexOf(t);return e<0&&this.game.throwError(y.SOUND_NAME_NOT_FOUND,{soundName:t}),this.sounds.splice(e,1),this}playSound(t,e={}){let i=this.getSound(t);this.doPlaySound(i,e)}startSound(t,e={}){let i=this.cloneSound(t);return this.doPlaySound(i,e),i}pauseSound(t){this.getSound(t).pause()}getSound(t){this.isReady()||this.game.throwError(y.SOUND_USE_NOT_READY);let e=this.soundNames.indexOf(t);e<0&&this.game.throwError(y.SOUND_NAME_NOT_FOUND,{soundName:t});let i=this.sounds[e];return i instanceof Audio||this.game.throwError(y.SOUND_INDEX_NOT_FOUND,{soundIndex:e}),i}cloneSound(t){let e=this.getSound(t);return new Audio(e.src)}doPlaySound(t,e={}){e.volume!==void 0&&(t.volume=e.volume),e.currentTime!==void 0&&(t.currentTime=e.currentTime),e.loop!==void 0&&(t.loop=e.loop);let i=t.play();i!==void 0&&i.catch(s=>{s.name==="NotAllowedError"?this.game.throwError(y.SOUND_NOT_ALLOWED_ERROR,{},!1):console.error("Audio playback error:",s)})}stamp(t,e=!0){this.isReady()||this.game.throwError(y.STAMP_NOT_READY),t=t??this.costumeIndex,this.costumes[t]||this.game.throwError(y.STAMP_COSTUME_NOT_FOUND,{costumeIndex:t});let i=this.costumes[t];i.image instanceof HTMLCanvasElement||this.game.throwErrorRaw("The image inside the costume was not found.");let s=0;e&&this._rotateStyle==="normal"&&(s=this.direction),this.stage.stampImage(i.image,this.x,this.y,s)}pen(t){this._drawings.push(t)}get drawings(){return this._drawings}set opacity(t){t===null?this._opacity=null:this._opacity=Math.min(1,Math.max(0,t))}get opacity(){return this._opacity}set filter(t){this._filter=t}get filter(){return this._filter}set rotateStyle(t){this._rotateStyle=t;for(let e of this._children)e.rotateStyle=t}get rotateStyle(){return this._rotateStyle}set layer(t){let e=this._parentSprite?this._parentSprite.globalLayer+t:t;this.stage.changeSpriteLayer(this,this._layer,e),this._layer=t;for(let i of this._children)i.globalLayer=i.layer+this._layer}get layer(){return this._layer}set globalLayer(t){this.layer=this._parentSprite?t-this._parentSprite.globalLayer:t}get globalLayer(){return this._parentSprite?this._parentSprite.globalLayer+this._layer:this._layer}set hidden(t){this._hidden=t;for(let e of this._children)e.hidden=t}get hidden(){return this._hidden}say(t,e){if(this.phrase=this.name+": "+t,this.phraseLiveTime=null,e){let i=new Date().getTime();this.phraseLiveTime=i+e}}getPhrase(){if(this.phrase){if(this.phraseLiveTime===null)return this.phrase;let t=new Date().getTime();if(this.phraseLiveTime>t)return this.phrase;this.phrase=null,this.phraseLiveTime=null}retu