import{e as S,f as k,h as E,H as R,o as D,c as I,u as U,a as P,R as G,i as N,b as B,A as W,d as H,j as q,k as Z,l as z}from"./sprite-view-Br3916N3.js";import{A as L,d as $,s as T}from"./schema-B1NKxfZc.js";import{G as j}from"./Graphics-D2W9cmNd.js";class K{constructor(t,e,s){this.world=t,this.viewW=e,this.viewH=s}x=0;y=0;zoom=1;minZoom=.25;maxZoom=4;resize(t,e){this.viewW=t,this.viewH=e,this.apply()}setCenter(t,e){this.x=t,this.y=e,this.apply()}setZoom(t){this.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,t)),this.apply()}setZoomRange(t,e){this.minZoom=t,this.maxZoom=e,this.setZoom(this.zoom)}apply(){this.world.scale.set(this.zoom),this.world.position.set(Math.round(this.viewW/2-this.x*this.zoom),Math.round(this.viewH/2-this.y*this.zoom))}bounds(t=0){const e=this.viewW/2/this.zoom+t,s=this.viewH/2/this.zoom+t;return{x0:this.x-e,y0:this.y-s,x1:this.x+e,y1:this.y+s}}screenToWorld(t,e){return{x:(t-this.world.position.x)/this.zoom,y:(e-this.world.position.y)/this.zoom}}worldToScreen(t,e){return{x:t*this.zoom+this.world.position.x,y:e*this.zoom+this.world.position.y}}}function V(f){return f>=17&&f<=19?{mode:"rain",level:f-16}:f>=1&&f<=3?{mode:"snow",level:f}:{mode:"none",level:0}}class J{container=new S;g=new j;flash=new j;parts=[];mode="none";level=0;w=0;h=0;flashLevel=0;nextBolt=0;constructor(){this.container.addChild(this.g,this.flash),this.container.eventMode="none"}resize(t,e){this.w=t,this.h=e,this.mode!=="none"&&this.build()}setWeather(t){const{mode:e,level:s}=V(t);e===this.mode&&s===this.level||(this.mode=e,this.level=s,this.build())}build(){if(this.parts=[],this.mode==="none"||!this.w||!this.h){this.g.clear(),this.flash.clear();return}const t=this.mode==="rain"?[0,130,230,360][this.level]:[0,90,170,280][this.level];for(let e=0;e<t;e++)this.parts.push(this.spawn(!0));this.nextBolt=1500+Math.random()*3e3}spawn(t){const e=t?Math.random()*this.h:-10;if(this.mode==="rain"){const i=900+this.level*260+Math.random()*300;return{x:Math.random()*(this.w+200)-100,y:e,vx:-120-this.level*40,vy:i,s:8+this.level*4+Math.random()*6,ph:0}}const s=40+this.level*20+Math.random()*40;return{x:Math.random()*this.w,y:e,vx:0,vy:s,s:1.1+Math.random()*(1+this.level*.6),ph:Math.random()*Math.PI*2}}update(t){if(this.mode==="none"){this.flashLevel>0&&this.drawFlash();return}const e=t/1e3,s=this.g;if(s.clear(),this.mode==="rain"){for(const i of this.parts){if(i.x+=i.vx*e,i.y+=i.vy*e,i.y>this.h+10||i.x<-110){Object.assign(i,this.spawn(!1));continue}s.moveTo(i.x,i.y).lineTo(i.x-i.vx*.018,i.y-i.s)}s.stroke({width:1.1+this.level*.15,color:12374783,alpha:.34+this.level*.06}),this.storm(t)}else{for(const i of this.parts){if(i.ph+=e*1.6,i.x+=Math.sin(i.ph)*(10+this.level*6)*e,i.y+=i.vy*e,i.y>this.h+6){Object.assign(i,this.spawn(!1));continue}i.x<-6?i.x=this.w+6:i.x>this.w+6&&(i.x=-6),s.circle(i.x,i.y,i.s)}s.fill({color:16777215,alpha:.72})}this.flashLevel>0&&this.drawFlash()}storm(t){this.level<3||(this.nextBolt-=t,this.nextBolt<=0&&(this.flashLevel=.55+Math.random()*.3,this.nextBolt=2500+Math.random()*5e3))}drawFlash(){this.flashLevel=Math.max(0,this.flashLevel-.05),this.flash.clear(),this.flashLevel>.01&&this.w&&this.flash.rect(0,0,this.w,this.h).fill({color:14673663,alpha:this.flashLevel*.5})}destroy(){this.container.destroy({children:!0})}}const Q=[0,1,1,1,0,-1,-1,-1],tt=[-1,-1,0,1,1,1,0,-1];function b(f,t,e,s){if(f.solid(t+Q[s],e+tt[s]))return!1;switch(s){case 0:return f.northOpen(t,e);case 2:return f.eastOpen(t,e);case 4:return f.northOpen(t,e+1);default:return f.eastOpen(t-1,e)}}function F(f,t,e,s){switch(s&7){case 0:case 2:case 4:case 6:return b(f,t,e,s&7);case 1:return b(f,t,e,0)&&b(f,t,e-1,2)||b(f,t,e,2)&&b(f,t+1,e,0);case 3:return b(f,t,e,4)&&b(f,t,e+1,2)||b(f,t,e,2)&&b(f,t+1,e,4);case 5:return b(f,t,e,4)&&b(f,t,e+1,6)||b(f,t,e,6)&&b(f,t-1,e,4);default:return b(f,t,e,0)&&b(f,t,e-1,6)||b(f,t,e,6)&&b(f,t-1,e,0)}}class et{startX;startY;w;h;grid;constructor(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength);this.startX=e.getUint32(0,!0),this.startY=e.getUint32(4,!0),this.w=e.getUint32(8,!0),this.h=e.getUint32(12,!0),this.grid=t.subarray(16)}tile(t,e){const s=t-this.startX,i=e-this.startY;return s<0||i<0||s>=this.w||i>=this.h?0:this.grid[i*this.w+s]}solid(t,e){const s=this.tile(t,e);return(s&128)!==0||(s&3)===0}northOpen(t,e){return(this.tile(t,e)&2)!==0}eastOpen(t,e){return(this.tile(t,e)&1)!==0}blocked(t,e){return this.solid(t,e)}passable(t,e,s){return F(this,t,e,s)}zone(t,e){return this.tile(t,e)&48}}const A=k().chunkCells,st=18;function it(f,t,e,s=0){return(4*(t-e)+(f-18)+(1<<20))*65536+f*256+(s&255)}function ot(f,t,e=st,s=0){return(4*(t-f)+(e-18)+(1<<20))*65536+e*256+128+s}function nt(f){const t=new Map,e=s=>{if(!s)return;const i=s>>>8;let r=t.get(i);r||(r=new Set,t.set(i,r)),r.add(s&255)};for(let s=0;s<f.ground.length;s++)e(f.ground[s]);for(const s of f.extra)e(s.tile);for(const s of f.objectTiles)e(s.tile);return t}class C{constructor(t,e){this.tilesets=t,this.sectorLoader=e,this.depth.sortableChildren=!0}ground=new S;depth=new S;sectors=new Map;pending=new Map;originX=0;originY=0;mapId=0;index=null;collision=null;seq=0;async setMap(t){this.clear(),this.mapId=t;{const s=this.doorEdges.get(t);this.shutDoors=s&&s.size?s:null}this.collision=null,this.index=null;const e=await this.sectorLoader.map(t);this.index=e.index,this.originX=e.index.bounds.minX,this.originY=e.index.bounds.minY,this.seq++,this.sectorLoader.collision(t).then(s=>{this.mapId===t&&(this.collision=s)})}clear(){for(const t of[...this.sectors.keys()])this.unload(t);this.pending.clear(),this.repairs.clear()}sectorNameAt(t,e){const s=32768+Math.floor((t-32768)/64),i=32768+Math.floor((e-32768)/64);return s.toString(16).padStart(4,"0")+i.toString(16).padStart(4,"0")}async sync(t,e,s,i){for(const l of[...this.sectors.keys()])!t.has(l)&&!e.has(l)&&this.unload(l);const r=[];for(const l of t)!this.sectors.has(l)&&!this.pending.has(l)&&r.push(l);i&&r.sort((l,o)=>l===i?-1:o===i?1:0);let d=0;s?.(0,r.length);const c=r.map(l=>this.load(l).then(()=>s?.(++d,r.length)));await Promise.all(c)}isLoaded(t){return this.sectors.has(t)}whenLoaded(t){return this.sectors.has(t)?Promise.resolve():this.pending.get(t)??Promise.resolve()}load(t){const e=this.seq,s=this.mapId,i=(async()=>{let r;try{r=await this.sectorLoader.sector(s,t)}catch{return}const d=nt(r),c=r.tilesets.filter(n=>d.has(n));for(const n of c)this.tilesets.hold(n);const l=new Map,o=[];try{const n=await Promise.all(c.map(w=>this.tilesets.load(w,d.get(w)).catch(()=>null)));if(e!==this.seq)return;n.forEach((w,x)=>{w&&(l.set(c[x],w),this.tilesets.retain(c[x]),o.push(c[x]))})}finally{for(const n of c)this.tilesets.unhold(n)}const a=parseInt(t.slice(0,4),16),p=parseInt(t.slice(4,8),16),u=(a-32768)*64+32768-this.originX,h=(p-32768)*64+32768-this.originY,m={name:t,sx:a,sy:p,bx:u,by:h,chunks:[],objects:[],objChunks:[],fadeObjects:[],tilesets:o,data:r};if(await this.buildGround(m,l,e),e!==this.seq){for(const n of m.chunks)n.destroy({children:!0});for(const n of o)this.tilesets.release(n);return}this.buildObjects(m,l),this.sectors.set(t,m),this.checkComplete(t,m,d,l,e)})().finally(()=>this.pending.delete(t));return this.pending.set(t,i),i}repairs=new Map;static REPAIR_DELAYS_MS=[2e3,5e3,1e4,2e4,3e4,6e4];checkComplete(t,e,s,i,r){let d=0;const c=[];for(const[a,p]of s){const u=i.get(a);let h=0;if(!u)h=p.size;else for(const m of p)u.atlas.tiles[m]&&!u.tiles.has(m)&&h++;h&&(d+=h,c.push(a))}if(!d){this.repairs.delete(t);return}const l=this.repairs.get(t)??0,o=C.REPAIR_DELAYS_MS[Math.min(l,C.REPAIR_DELAYS_MS.length-1)];this.repairs.set(t,l+1),console.warn(`sector ${t}: ${d} tiles missing (tilesets ${c.join(",")}), rebuilding in ${o/1e3}s`),setTimeout(()=>{r!==this.seq||this.sectors.get(t)!==e||(this.unload(t),this.load(t))},o)}tex(t,e){const i=t.get(e>>>8)?.tiles.get(e&255);return i?{tex:i.tex,ox:i.meta.ox??0,oy:i.meta.oy??0,alpha50:!!i.meta.a,multiply:!!i.meta.m,kind:i.meta.k}:null}style(t,e){e.alpha50&&(t.alpha=.5),e.multiply&&(t.blendMode="multiply")}static nextFrame(){return new Promise(t=>{let e=!1;const s=()=>{e||(e=!0,t())};typeof requestAnimationFrame=="function"&&requestAnimationFrame(s),setTimeout(s,32)})}async buildGround(t,e,s){const{data:i,bx:r,by:d}=t,c=64/A,l=[];for(let o=0;o<c;o++)for(let a=0;a<c;a++){const p=new S;p.cullable=!0;for(let u=o*A;u<(o+1)*A;u++)for(let h=a*A;h<(a+1)*A;h++){const m=I(r+h,d+u);for(let n=0;n<2;n++){const w=i.ground[u*128+2*h+n];if(!w)continue;const x=this.tex(e,w);if(!x)continue;const g=new E(x.tex),y=x.kind==="D"?n*R:0;g.position.set(m.X-R+y+x.ox,m.Y+x.oy),this.style(g,x),p.addChild(g)}}if(l.push(p),this.ground.addChild(p),a===c-1&&(await C.nextFrame(),s!==this.seq)){t.chunks=l;return}}for(const o of i.objectTiles){const a=this.tex(e,o.tile);if(!a||a.kind!=="L"&&a.kind!=="R")continue;const p=new E(a.tex),u=D(r,d,o.a,o.b);p.position.set(u.X+a.ox-(a.kind==="R"?R:0),u.Y+a.oy),this.style(p,a);const h=Math.min(c-1,Math.floor(o.b/A))*c+Math.min(c-1,Math.floor((o.a>>1)/A));l[h].addChild(p)}for(const o of i.extra){const a=this.tex(e,o.tile);if(!a)continue;const p=new E(a.tex);if(a.kind==="L"||a.kind==="R"){const h=I(r+(o.a>>1),d+o.b);p.position.set(h.X-R+a.ox,h.Y+a.oy)}else{const h=D(r,d,o.a,o.b);p.position.set(h.X+a.ox,h.Y+a.oy)}this.style(p,a);const u=Math.min(c-1,Math.floor(o.b/A))*c+Math.min(c-1,Math.floor((o.a>>1)/A));l[u].addChild(p)}for(const o of l){let a=1/0,p=1/0,u=-1/0,h=-1/0;for(const m of o.children){const n=m,w=n.width,x=n.height;n.x<a&&(a=n.x),n.y<p&&(p=n.y),n.x+w>u&&(u=n.x+w),n.y+x>h&&(h=n.y+x)}o.__b=o.children.length?{x0:a,y0:p,x1:u,y1:h}:void 0}t.chunks=l}buildObjects(t,e){const{data:s,bx:i,by:r}=t,d=64/A,c=new Map,l=new Map;for(const o of s.objectTiles){const a=this.tex(e,o.tile);if(!a||a.kind==="L"||a.kind==="R")continue;const p=new E(a.tex),u=D(i,r,o.a,o.b),h=u.X+a.ox,m=u.Y+a.oy;p.position.set(h,m),this.style(p,a),p.zIndex=it(o.layer,r+o.b,i+(o.a>>1),o.a),t.objects.push(p);const n=a.tex.width,w=a.tex.height,x=Math.min(d-1,Math.max(0,Math.floor((o.a>>1)/A))),y=Math.min(d-1,Math.max(0,Math.floor(o.b/A)))*d+x;let M=c.get(y);M||(M={x0:1/0,y0:1/0,x1:-1/0,y1:-1/0,sprites:[],attached:!1,rects:[]},c.set(y,M)),M.sprites.push(p),M.rects.push(h,m,h+n,m+w),h<M.x0&&(M.x0=h),m<M.y0&&(M.y0=m),h+n>M.x1&&(M.x1=h+n),m+w>M.y1&&(M.y1=m+w);let v=l.get(o.objectId);v||(v={x0:1/0,y0:1/0,x1:-1/0,y1:-1/0,tiles:[],cur:1},l.set(o.objectId,v)),v.tiles.push({s:p,x0:h,y0:m,x1:h+n,y1:m+w,depth:p.zIndex,a0:p.alpha}),h<v.x0&&(v.x0=h),m<v.y0&&(v.y0=m),h+n>v.x1&&(v.x1=h+n),m+w>v.y1&&(v.y1=m+w)}t.objChunks=[...c.values()],t.fadeObjects=[...l.values()].filter(o=>o.tiles.length<=800&&o.x1-o.x0<=2400&&o.y1-o.y0<=2e3)}cull(t,e=t){const{x0:s,y0:i,x1:r,y1:d}=t,c=e.x0,l=e.y0,o=e.x1,a=e.y1;for(const p of this.sectors.values())for(const u of p.objChunks){const h=u.x1>=s&&u.x0<=r&&u.y1>=i&&u.y0<=d;if(h!==u.attached)if(u.attached=h,h)for(const w of u.sprites)this.depth.addChild(w);else for(const w of u.sprites)this.depth.removeChild(w);if(!u.attached)continue;const{sprites:m,rects:n}=u;for(let w=0,x=0;w<m.length;w++,x+=4){const g=n[x]<=o&&n[x+2]>=c&&n[x+1]<=a&&n[x+3]>=l;m[w].visible!==g&&(m[w].visible=g)}}this.syncGroundCache(t)}syncGroundCache(t){const{x0:e,y0:s,x1:i,y1:r}=t,d=(e+i)/2,c=(s+r)/2,l=n=>n.__l15cached===!0,o=(n,w)=>{const x=C.CACHE_RESOLUTION;n.cacheAsTexture?.(w&&x?{resolution:x,scaleMode:"nearest"}:w),n.__l15cached=w},a=[],p=[],u=C.CULL_MARGIN;for(const n of this.sectors.values())for(const w of n.chunks){const x=w.__b;if(!x)continue;const g=x.x1>=e-u&&x.x0<=i+u&&x.y1>=s-u&&x.y0<=r+u;w.visible!==g&&(w.visible=g);const y=l(w);if(!this.cacheGround){y&&p.push(w);continue}const M=y?C.CACHE_DROP_MARGIN:C.CACHE_MARGIN;if(x.x1>=e-M&&x.x0<=i+M&&x.y1>=s-M&&x.y0<=r+M){const v=Math.max(0,Math.max(x.x0-d,d-x.x1)),Y=Math.max(0,Math.max(x.y0-c,c-x.y1));a.push({c:w,d:v*v+Y*Y})}else y&&p.push(w)}const h=this.maxCachedChunks;if(a.length>h){a.sort((n,w)=>n.d-w.d);for(let n=h;n<a.length;n++)l(a[n].c)&&p.push(a[n].c);a.length=h}for(const n of p)o(n,!1);let m=0;for(const{c:n}of a)if(!l(n)){if(m>=C.CACHE_BUILDS_PER_FRAME)break;m++,o(n,!0)}}cacheGround=k().cacheGround;maxCachedChunks=k().maxCachedChunks;static CACHE_MARGIN=k().groundCacheMargin;static CACHE_DROP_MARGIN=k().groundCacheMargin*2;static CULL_MARGIN=96;static CACHE_BUILDS_PER_FRAME=2;static CACHE_RESOLUTION=k().groundCacheResolution;static FADE_ALPHA=.4;roofFade(t,e,s){const i=t-this.originX,r=e-this.originY,d=I(i,r),c=ot(i,r),l=d.X,o=[d.Y-52,d.Y-26,d.Y-2],a=C.FADE_ALPHA,p=Math.min(1,s/140);for(const u of this.sectors.values())for(const h of u.fadeObjects){let m=1;if(l>=h.x0&&l<=h.x1&&o[0]<=h.y1&&o[2]>=h.y0){for(const n of h.tiles)if(!(n.depth<=c||l<n.x0||l>n.x1)&&(o[0]>=n.y0&&o[0]<=n.y1||o[1]>=n.y0&&o[1]<=n.y1||o[2]>=n.y0&&o[2]<=n.y1)){m=a;break}}if(h.cur!==m){h.cur=h.cur<m?Math.min(m,h.cur+p):Math.max(m,h.cur-p);for(const n of h.tiles)n.s.alpha=n.a0*h.cur}}}unload(t){const e=this.sectors.get(t);if(e){for(const s of e.chunks)s.cacheAsTexture?.(!1),this.ground.removeChild(s);for(const s of e.objChunks)if(s.attached)for(const i of s.sprites)this.depth.removeChild(i);for(const s of e.tilesets)this.tilesets.release(s);this.attrCache===e&&(this.attrCache=null),this.sectors.delete(t),this.sectorLoader.forget(this.mapId,t),this.queueDestroy(e.chunks,e.objects)}}dyingChunks=[];dyingSprites=[];draining=!1;queueDestroy(t,e){this.dyingChunks.push(...t),this.dyingSprites.push(...e),this.draining||this.drainDestroy()}async drainDestroy(){this.draining=!0;try{for(;this.dyingChunks.length||this.dyingSprites.length;){for(let t=0;t<2&&this.dyingChunks.length;t++)this.dyingChunks.pop().destroy({children:!0});for(let t=0;t<400&&this.dyingSprites.length;t++)this.dyingSprites.pop().destroy();await C.nextFrame()}}finally{this.draining=!1}}doorEdges=new Map;shutDoors=null;static doorKey(t,e){return e*65536+t}setDoorEdge(t,e,s,i,r){let d=this.doorEdges.get(t);d||(d=new Set,this.doorEdges.set(t,d));const c=i&1?C.doorKey(e+1,s):C.doorKey(e,s-1);r?d.add(c):d.delete(c),t===this.mapId&&(this.shutDoors=d.size?d:null)}cells={solid:(t,e)=>{if(this.shutDoors?.has(C.doorKey(t,e)))return!0;const s=this.attrSectorAt(t,e);if(!s)return this.collision?.solid(t,e)??!0;const i=this.attrIndex(s,t,e),r=s.data.attrs;return(r[i]&1)!==0&&(r[i+1]&1)!==0},northOpen:(t,e)=>{const s=this.attrSectorAt(t,e);return s?(s.data.attrs[this.attrIndex(s,t,e)]&1)===0:this.collision?.northOpen(t,e)??!1},eastOpen:(t,e)=>{const s=this.attrSectorAt(t,e);return s?(s.data.attrs[this.attrIndex(s,t,e)+1]&1)===0:this.collision?.eastOpen(t,e)??!1}};blocked(t,e){return this.cells.solid(t,e)}passable(t,e,s){return F(this.cells,t,e,s)}zoneAt(t,e){return this.collision?this.collision.zone(t,e):0}attrIndex(t,e,s){return(s-(t.by+this.originY))*128+(e-(t.bx+this.originX))*2}attrCache=null;attrSectorAt(t,e){const s=this.attrCache;if(s){const r=t-(s.bx+this.originX),d=e-(s.by+this.originY);if(r>=0&&r<64&&d>=0&&d<64)return s}const i=this.sectors.get(this.sectorNameAt(t,e));return!i||(i.hasAttrs??=i.data.attrs.some(r=>(r&1)!==0),!i.hasAttrs)?null:(this.attrCache=i,i)}attrAt(t,e){const s=this.attrSectorAt(t,e);if(!s)return 0;const i=this.attrIndex(s,t,e);return s.data.attrs[i]|s.data.attrs[i+1]}loadedSectorCount(){return this.sectors.size}}function rt(f,t,e){const s=[];let i=[],r=0,d=0,c=0;const l=()=>{i.length&&s.push({height:d+c,items:i}),i=[],r=0,d=0,c=0};for(let o=0;o<f.length;o++){const a=f[o];r+a.w>t&&(d+=c,r=0,c=0),d+a.h>e&&l(),i.push({i:o,x:r,y:d}),r+=a.w,a.h>c&&(c=a.h)}return l(),s}function at(f,t){let e=0,s=1;for(const i of f)e+=i.w*i.h,i.w>s&&(s=i.w);return Math.min(t,Math.max(s,Math.min(t,Math.ceil(Math.sqrt(e)))))}const X=1,_=2048,ht=k().tilesetConcurrency;class ct{constructor(t){this.src=t}loaded=new Map;atlases=new Map;packed=new Map;wanted=new Map;wantAll=new Set;jobs=new Map;active=0;queue=[];get(t){return this.loaded.get(t)}async gate(t){this.active>=ht&&await new Promise(e=>this.queue.push(e)),this.active++;try{return await t()}finally{this.active--,this.queue.shift()?.()}}atlas(t){let e=this.atlases.get(t);return e||(e=this.src.json(L.tileset(t)),this.atlases.set(t,e),e.catch(()=>this.atlases.delete(t)),e)}load(t,e){let s=this.wanted.get(t);if(s||(s=new Set,this.wanted.set(t,s)),e)for(const r of e)s.add(r);else this.wantAll.add(t);const i=this.jobs.get(t);return i?i.then(()=>this.run(t),()=>this.run(t)):this.run(t)}run(t){const e=this.jobs.get(t);if(e)return e;const s=(async()=>{const i=await this.atlas(t);let r=this.loaded.get(t);for(r||(r={id:t,atlas:i,pages:[],tiles:new Map,refs:0},this.loaded.set(t,r),this.packed.set(t,new Set));;){const d=this.packed.get(t)??new Set,c=this.wantAll.delete(t),l=this.wanted.get(t),o=c?Object.keys(i.tiles).map(Number):[...l??[]];l?.clear();const a=o.filter(p=>!d.has(p)&&i.tiles[p]);if(!a.length)return r;await this.pack(r,a)}})();return this.jobs.set(t,s),s.catch(()=>{}).finally(()=>{this.jobs.get(t)===s&&this.jobs.delete(t)}),s}async pack(t,e){const s=e.map(d=>({s:d,m:t.atlas.tiles[d]})).filter(d=>d.m);if(!s.length)return;const i=this.packed.get(t.id)??new Set,r=new Map;for(const d of s){const c=d.m.p??0;let l=r.get(c);l||(l=[],r.set(c,l)),l.push(d)}for(const[d,c]of r){c.sort((u,h)=>h.m.h-u.m.h||h.m.w-u.m.w);const l=c.map(u=>({w:u.m.w+X,h:u.m.h+X})),o=at(l,_),a=rt(l,o,_),p=await this.gate(()=>this.src.image(`tiles/${t.atlas.pages[d]}`));try{for(const u of a){const h=lt(o,u.height),m=h.getContext("2d");if(!m)throw new Error("no 2d context");for(const g of u.items){const y=c[g.i];m.drawImage(p,y.m.x,y.m.y,y.m.w,y.m.h,g.x,g.y,y.m.w,y.m.h)}const{tex:n,bitmap:w}=await dt(h);n.source.scaleMode="nearest",U(n,w);const x=t.pages.length;t.pages.push(n);for(const g of u.items){const y=c[g.i];t.tiles.set(y.s,{tex:new P({source:t.pages[x].source,frame:new G(g.x,g.y,y.m.w,y.m.h)}),meta:y.m}),i.add(y.s)}}}finally{p.close?.()}}this.packed.set(t.id,i)}held=new Map;hold(t){this.held.set(t,(this.held.get(t)??0)+1)}unhold(t){const e=(this.held.get(t)??0)-1;e>0?this.held.set(t,e):this.held.delete(t),this.freeIfUnused(t)}retain(t){const e=this.loaded.get(t);e&&e.refs++}release(t){const e=this.loaded.get(t);e&&(e.refs--,this.freeIfUnused(t))}freeIfUnused(t){const e=this.loaded.get(t);if(!(!e||e.refs>0||this.held.has(t))){for(const s of e.pages)s.source.destroy();this.loaded.delete(t),this.packed.delete(t),this.wanted.delete(t),this.wantAll.delete(t)}}}function lt(f,t){if(typeof OffscreenCanvas=="function")return new OffscreenCanvas(f,t);const e=document.createElement("canvas");return e.width=f,e.height=t,e}async function dt(f){const t=f,e=typeof t.transferToImageBitmap=="function"?t.transferToImageBitmap():await createImageBitmap(f);return{tex:P.from(e),bitmap:e}}class ft{constructor(t){this.index=t;for(const e of t.sectors)this.sectorsByName.set(e.name,e)}sectorsByName=new Map;has(t){return this.sectorsByName.has(t)}}class ut{constructor(t){this.src=t}maps=new Map;sectors=new Map;collisions=new Map;collision(t){let e=this.collisions.get(t);return e||(e=(async()=>{for(let s=0;;s++)try{return new et(await this.src.bytes(L.collision(t)))}catch(i){if(N(i))return null;await new Promise(r=>setTimeout(r,Math.min(3e4,2e3*2**s)))}})(),this.collisions.set(t,e)),e}map(t){let e=this.maps.get(t);return e||(e=this.src.json(L.mapIndex(t)).then(s=>new ft(s)),this.maps.set(t,e),e.catch(()=>this.maps.delete(t))),e}sector(t,e){const s=`${t}/${e}`;let i=this.sectors.get(s);return i||(i=this.src.bytes(L.sector(t,e)).then($),this.sectors.set(s,i),i.catch(()=>this.sectors.delete(s))),i}forget(t,e){this.sectors.delete(`${t}/${e}`)}}class O{app=new B;world=new S;overhead=new S;weather=new J;light=new j;camera;assets;tilesets;sectors;sprites;map;tickers=[];lastFrame=0;watchdog=null;constructor(t){this.assets=new W(t),this.tilesets=new ct(this.assets),this.sectors=new ut(this.assets),this.sprites=new H(this.assets),this.map=new C(this.tilesets,this.sectors)}async init(t){const e=q()||await Z(),s=new URLSearchParams(location.search).get("gpu"),r=(s==="webgl"||s==="webgpu"?s:T.renderer==="auto"?null:T.renderer)??(k().lowMemory||pt()?"webgl":"webgpu");this.perfMode=T.performance,this.cheapEffects=k().cheapEffects,await this.app.init({canvas:t,resizeTo:window,background:0,antialias:!1,preference:r,resolution:this.frameResolution(e),roundPixels:!0});const d=new URLSearchParams(location.search).get("cache");this.map.cacheGround=d==="0"?!1:d==="1"?!0:k().cacheGround,this.world.addChild(this.map.ground,this.map.depth,this.overhead),this.app.stage.addChild(this.world,this.weather.container,this.light),this.camera=new K(this.world,this.app.screen.width,this.app.screen.height),k().lowMemory&&this.camera.setZoomRange(.7,2.5),this.weather.resize(this.app.screen.width,this.app.screen.height),this.app.renderer.on("resize",(c,l)=>{this.camera.resize(c,l),this.weather.resize(c,l),this.drawLight()}),this.applyFrameRate(T.frameRate),this.app.ticker.add(c=>{this.lastFrame=performance.now();const l=Math.min(1e3,c.deltaMS);this.performanceMode||this.weather.update(l),this.runTickers(l)}),this.app.ticker.remove(this.app.render,this.app),this.app.ticker.add(()=>{try{this.app.render()}catch(c){console.error("render error — auto-healing destroyed textures",c);try{this.sweepDestroyedTextures(this.app.stage)}catch{}}}),this.lastFrame=performance.now(),this.watchdog=window.setInterval(()=>{const c=performance.now();if(c-this.lastFrame<200)return;const l=Math.min(1e3,c-this.lastFrame);this.lastFrame=c,this.runTickers(l)},100),this.limitBatchTextures(),z(this.app.renderer.texture),this.drawLight(),this.watchContextLoss(t)}watchContextLoss(t){t.addEventListener("webglcontextlost",e=>{e.preventDefault(),console.error("WebGL context lost");let s=0;try{s=Number(sessionStorage.getItem("l15.ctxlost")??0)}catch{}const i=Date.now();if(i-s<6e4){this.onContextLost?.();return}try{sessionStorage.setItem("l15.ctxlost",String(i))}catch{}setTimeout(()=>location.reload(),300)})}onContextLost=null;destroy(){z(null),this.sprites.destroy(),this.watchdog!==null&&clearInterval(this.watchdog),this.app.destroy()}sweepDestroyedTextures(t){const e=t,s=e.texture;s&&s!==P.EMPTY&&(!s.source||s.source.destroyed)&&(e.texture=P.EMPTY,t.visible=!1);for(const i of t.children)this.sweepDestroyedTextures(i)}runTickers(t){for(const e of this.tickers)try{e(t)}catch(s){console.error("ticker error",s)}}static WEBGL_BATCH_TEXTURES=1;limitBatchTextures(){const t=this.app.renderer.limits;if(!t)return;const e=Number(new URLSearchParams(location.search).get("batch")),s=e>0?e:this.app.renderer.name==="webgl"?O.WEBGL_BATCH_TEXTURES:t.maxBatchableTextures;s<t.maxBatchableTextures&&(t.maxBatchableTextures=Math.max(1,Math.floor(s)))}static PERF_RESOLUTION=.75;perfMode=!1;cheapEffects=!1;accelerated=!0;get performanceMode(){return this.perfMode||this.cheapEffects}frameResolution(t=this.accelerated){if(this.accelerated=t,!t)return .6;const e=Math.min(typeof devicePixelRatio=="number"&&devicePixelRatio>0?devicePixelRatio:1,k().renderScale);return this.perfMode?Math.min(e,O.PERF_RESOLUTION):e}applyFrameRate(t){this.app.ticker.maxFPS=t}applyPerformanceMode(t){if(this.perfMode===t)return;this.perfMode=t;const e=this.app.renderer;e.resolution=this.frameResolution(),this.app.renderer.resize(this.app.screen.width,this.app.screen.height),t&&this.weather.setWeather(0)}onTick(t){return this.tickers.push(t),()=>{this.tickers=this.tickers.filter(e=>e!==t)}}setDarkness(t){this.timeDark=Math.max(0,Math.min(1,t)),this.drawLight()}setWeather(t){this.weather.setWeather(t),this.weatherDark=t>=17?(t-16)*.12:t>=1&&t<=3?t*.05:0,this.drawLight()}timeDark=0;weatherDark=0;drawLight(){if(!this.app.renderer)return;this.light.clear();const t=Math.min(1,this.timeDark+this.weatherDark);t<=0||this.light.rect(0,0,this.app.screen.width,this.app.screen.height).fill({color:1052720,alpha:t*.6})}visibleCells(t=2){const e=this.camera.bounds(96),s=[[e.x0,e.y0],[e.x1,e.y0],[e.x0,e.y1],[e.x1,e.y1]].map(([i,r])=>({lx:(i/48-(r-24)/24)/2,ly:(i/48+(r-24)/24)/2}));return{minX:Math.floor(Math.min(...s.map(i=>i.lx)))-t,maxX:Math.ceil(Math.max(...s.map(i=>i.lx)))+t,minY:Math.floor(Math.min(...s.map(i=>i.ly)))-t,maxY:Math.ceil(Math.max(...s.map(i=>i.ly)))+t}}wantedSectors(t=0){const e=this.visibleCells(k().sectorMargin),s=new Set,i=new Set,r=this.map.originX,d=this.map.originY,c=Math.floor((e.minX+r-32768)/64),l=Math.floor((e.maxX+r-32768)/64),o=Math.floor((e.minY+d-32768)/64),a=Math.floor((e.maxY+d-32768)/64),p=this.map.index;if(!p)return{want:s,keep:i};for(let u=o-t;u<=a+t;u++)for(let h=c-t;h<=l+t;h++){const m=(32768+h).toString(16).padStart(4,"0")+(32768+u).toString(16).padStart(4,"0");if(!p.sectors.some(w=>w.name===m))continue;(h>=c&&h<=l&&u>=o&&u<=a?s:i).add(m)}return{want:s,keep:i}}lookAt(t,e){const s=I(t-this.map.originX,e-this.map.originY);this.camera.setCenter(s.X,s.Y+24)}}function pt(){const f=navigator.userAgent;return/AppleWebKit/.test(f)&&!/Chrome|Chromium|CriOS|Edg|OPR|Android/.test(f)}export{O as R,ot as e};
