mudlet-map-renderer 0.26.0-konva → 0.27.0-konva

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.
@@ -3,6 +3,7 @@ import { default as Area } from './reader/Area';
3
3
  import { SvgExportOptions } from './SvgExporter';
4
4
  import { MapRenderer } from './MapRenderer';
5
5
  export declare function colorLightness(color: string): number;
6
+ export declare function darkenColor(color: string, factor: number): string;
6
7
  export type PerfSnapshot = {
7
8
  /** Total updateRoomCulling time in ms */
8
9
  cullingMs: number;
@@ -97,6 +98,11 @@ export type PlayerMarkerStyle = {
97
98
  * When false, the stroke is solid regardless of the dash property.
98
99
  */
99
100
  dashEnabled: boolean;
101
+ /**
102
+ * When true, the marker shape matches the current roomShape setting
103
+ * (rectangle, circle, or roundedRectangle) instead of always being a circle.
104
+ */
105
+ matchRoomShape: boolean;
100
106
  };
101
107
  /**
102
108
  * Settings for map rendering.
@@ -150,6 +156,8 @@ export type Settings = {
150
156
  borders: boolean;
151
157
  /** When true, rooms use frame rendering: fill=backgroundColor, stroke=envColor. Default: false */
152
158
  frameMode: boolean;
159
+ /** When true, rooms use colored rendering: fill=envColor darkened 30%, stroke=envColor. Default: false */
160
+ coloredMode: boolean;
153
161
  /** When true, rooms display a 3D emboss effect (rectangle/roundedRectangle only). Default: false */
154
162
  emboss: boolean;
155
163
  /** When true, displays the area name as a header text on the map. Default: false */
@@ -294,6 +302,7 @@ export declare class Renderer implements MapRenderer {
294
302
  */
295
303
  updatePositionMarker(roomId: number): void;
296
304
  setPosition(roomId: number, center?: boolean): void;
305
+ private applyPositionMarker;
297
306
  clearPosition(): void;
298
307
  centerOn(roomId: number, instant?: boolean): void;
299
308
  renderPath(locations: number[], color?: string): import('konva/lib/Group').Group | import('konva/lib/Shape').Shape<import('konva/lib/Shape').ShapeConfig> | undefined;
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("konva"),Z=["north","south","east","west","northeast","northwest","southeast","southwest"],At={n:"north",s:"south",e:"east",w:"west",ne:"northeast",nw:"northwest",se:"southeast",sw:"southwest"},N={north:"n",south:"s",east:"e",west:"w",northeast:"ne",northwest:"nw",southeast:"se",southwest:"sw",up:"u",down:"d",in:"i",out:"o"},st={north:{x:0,y:-1},south:{x:0,y:1},east:{x:1,y:0},west:{x:-1,y:0},northeast:{x:1,y:-1},northwest:{x:-1,y:-1},southeast:{x:1,y:1},southwest:{x:-1,y:1}},ut=["north","south","east","west","northeast","northwest","southeast","southwest"],Lt={north:"south",south:"north",east:"west",west:"east",northeast:"southwest",northwest:"southeast",southeast:"northwest",southwest:"northeast"};function ft(m){return m?Object.prototype.hasOwnProperty.call(st,m):!1}function L(m,t,s,e=1){if(!ft(s))return{x:m,y:t};const i=st[s];return{x:m+i.x*e,y:t+i.y*e}}function it(m,t,s,e=1,i=0){if(!ft(s))return{x:m,y:t};const o=st[s];if(!(o.x!==0&&o.y!==0)||i<=0)return L(m,t,s,e);const r=e-i+i/Math.SQRT2;return{x:m+o.x*r,y:t+o.y*r}}function ot(m,t,s,e=1){if(!ft(s))return{x:m,y:t};const i=st[s],o=Math.atan2(i.y,i.x);return{x:m+Math.cos(o)*e,y:t+Math.sin(o)*e}}const H={OPEN_DOOR:"rgb(10, 155, 10)",CLOSED_DOOR:"rgb(226, 205, 59)",LOCKED_DOOR:"rgb(155, 10, 10)",ONE_WAY_FILL:"rgb(155, 10, 10)"},Xt={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},Wt=["up","down","in","out"];function xt(m){switch(m){case 1:return H.OPEN_DOOR;case 2:return H.CLOSED_DOOR;default:return H.LOCKED_DOOR}}class mt{constructor(t,s,e){this.mapReader=t,this.mapRenderer=s,this.settings=e}getRoomEdgePoint(t,s,e,i){return this.settings.roomShape==="circle"?ot(t,s,e,i):this.settings.roomShape==="roundedRectangle"?it(t,s,e,i,this.settings.roomSize*.2):L(t,s,e,i)}renderData(t,s){return this.renderDataWithColor(t,this.settings.lineColor,s)}renderDataWithColor(t,s,e){const i=t.aDir&&Z.includes(t.aDir),o=t.bDir&&Z.includes(t.bDir);if(i&&o)return this.renderTwoWayExitData(t,s,e);if(i||o){const n=i?"a":"b";return this.renderOneWayExitData(t,s,n)}}renderTwoWayExitData(t,s,e){const i=this.mapReader.getRoom(t.a),o=this.mapReader.getRoom(t.b);if(!i||!o||!t.aDir||!t.bDir||i.customLines[N[t.aDir]]&&o.customLines[N[t.bDir]]||i.z!==o.z&&(e!==o.z&&i.customLines[N[t.aDir]]||e!==i.z&&o.customLines[N[t.bDir]]))return;const n=this.getRoomEdgePoint(i.x,i.y,t.aDir,this.settings.roomSize/2),r=this.getRoomEdgePoint(o.x,o.y,t.bDir,this.settings.roomSize/2),h=[n.x,n.y,r.x,r.y],a=[{points:h,stroke:s,strokeWidth:this.settings.lineWidth}],c=[],l=i.doors[N[t.aDir]]??o.doors[N[t.bDir]];if(l){const p=h[0]+(h[2]-h[0])/2,x=h[1]+(h[3]-h[1])/2;c.push({x:p-this.settings.roomSize/4,y:x-this.settings.roomSize/4,width:this.settings.roomSize/2,height:this.settings.roomSize/2,stroke:xt(l),strokeWidth:this.settings.lineWidth})}const d=Math.min(h[0],h[2]),g=Math.max(h[0],h[2]),u=Math.min(h[1],h[3]),f=Math.max(h[1],h[3]),y=i.z!==o.z?i.z===e?o.id:i.id:void 0;return{lines:a,arrows:[],doors:c,bounds:{x:d,y:u,width:g-d,height:f-u},targetRoomId:y}}renderOneWayExitData(t,s,e){const i=e==="a"||!e&&t.aDir,o=i?this.mapReader.getRoom(t.a):this.mapReader.getRoom(t.b),n=i?this.mapReader.getRoom(t.b):this.mapReader.getRoom(t.a),r=i?t.aDir:t.bDir;if(!r||!o||!n||!Z.includes(r)||o.customLines[N[r]||r])return;if(o.area!=n.area&&r){const $=this.mapReader.getColorValue(n.env),X=this.getRoomEdgePoint(o.x,o.y,r,this.settings.roomSize/2),w=L(o.x,o.y,r,this.settings.roomSize*1.5),R=$;return{lines:[],arrows:[{points:[X.x,X.y,w.x,w.y],pointerLength:.3,pointerWidth:.3,strokeWidth:this.settings.lineWidth*1.4,stroke:R,fill:R}],doors:[],bounds:{x:Math.min(X.x,w.x),y:Math.min(X.y,w.y),width:Math.abs(w.x-X.x),height:Math.abs(w.y-X.y)},targetRoomId:n.id}}const h=n.area!==o.area||n.z!==o.z;let a={x:n.x,y:n.y};h&&(a=L(o.x,o.y,r,this.settings.roomSize/2));const c=L(o.x,o.y,r,.3),l=c.x-(c.x-a.x)/2,d=c.y-(c.y-a.y)/2,g=this.getRoomEdgePoint(o.x,o.y,r,this.settings.roomSize/2),u=[g.x,g.y,a.x,a.y],f=[g.x,a.x,l],y=[g.y,a.y,d],p=Math.min(...f),x=Math.max(...f),k=Math.min(...y),D=Math.max(...y);return{lines:[{points:u,stroke:s,strokeWidth:this.settings.lineWidth,dash:[.1,.05]}],arrows:[{points:[u[0],u[1],l,d],pointerLength:.5,pointerWidth:.35,strokeWidth:this.settings.lineWidth*1.4,stroke:s,fill:H.ONE_WAY_FILL,dash:[.1,.05]}],doors:[],bounds:{x:p,y:k,width:x-p,height:D-k},...h?{targetRoomId:n.id}:{}}}render(t,s){return this.renderWithColor(t,this.settings.lineColor,s)}renderWithColor(t,s,e){const i=t.aDir&&Z.includes(t.aDir),o=t.bDir&&Z.includes(t.bDir);if(i&&o)return this.renderTwoWayExit(t,s,e);if(i||o){const n=i?"a":"b";return this.renderOneWayExit(t,s,n)}}renderTwoWayExit(t,s,e){const i=this.mapReader.getRoom(t.a),o=this.mapReader.getRoom(t.b);if(!i||!o||!t.aDir||!t.bDir||i.customLines[N[t.aDir]]&&o.customLines[N[t.bDir]]||i.z!==o.z&&(e!==o.z&&i.customLines[N[t.aDir]]||e!==i.z&&o.customLines[N[t.bDir]]))return;const n=new b.Group({listening:!1}),r=[];if(r.push(...Object.values(this.getRoomEdgePoint(i.x,i.y,t.aDir,this.settings.roomSize/2))),r.push(...Object.values(this.getRoomEdgePoint(o.x,o.y,t.bDir,this.settings.roomSize/2))),i.doors[N[t.aDir]]||o.doors[N[t.bDir]]){const a=this.renderDoor(r,i.doors[N[t.aDir]]??o.doors[N[t.bDir]]);n.add(a)}const h=new b.Line({points:r,stroke:s,strokeWidth:this.settings.lineWidth,perfectDrawEnabled:!1,listening:!1});return n.add(h),n}renderOneWayExit(t,s,e){const i=e==="a"||!e&&t.aDir,o=i?this.mapReader.getRoom(t.a):this.mapReader.getRoom(t.b),n=i?this.mapReader.getRoom(t.b):this.mapReader.getRoom(t.a),r=i?t.aDir:t.bDir;if(!r||!o||!n||!Z.includes(r)||o.customLines[N[r]||r])return;if(o.area!=n.area&&r){const y=this.mapReader.getColorValue(n.env);return this.renderAreaExit(o,r,y)}let h={x:n.x,y:n.y};(n.area!==o.area||n.z!==o.z)&&(h=L(o.x,o.y,r,this.settings.roomSize/2));const a=L(o.x,o.y,r,.3),c=a.x-(a.x-h.x)/2,l=a.y-(a.y-h.y)/2,d=new b.Group({listening:!1}),g=[];g.push(...Object.values(this.getRoomEdgePoint(o.x,o.y,r,this.settings.roomSize/2))),g.push(h.x,h.y);const u=new b.Line({points:g,stroke:s,strokeWidth:this.settings.lineWidth,dashEnabled:!0,dash:[.1,.05],perfectDrawEnabled:!1,listening:!1});d.add(u);const f=new b.Arrow({points:[g[0],g[1],c,l],pointerLength:.5,pointerWidth:.35,strokeWidth:this.settings.lineWidth*1.4,stroke:s,fill:H.ONE_WAY_FILL,dashEnabled:!0,dash:[.1,.05],perfectDrawEnabled:!1,listening:!1});return d.add(f),d}renderAreaExit(t,s,e){const i=this.getRoomEdgePoint(t.x,t.y,s,this.settings.roomSize/2),o=L(t.x,t.y,s,this.settings.roomSize*1.5),n=e??this.mapReader.getColorValue(t.env);return new b.Arrow({points:[i.x,i.y,o.x,o.y],pointerLength:.3,pointerWidth:.3,strokeWidth:this.settings.lineWidth*1.4,stroke:n,fill:n,perfectDrawEnabled:!1,listening:!1})}renderSpecialExits(t,s){return Object.entries(t.customLines).flatMap(([e,i])=>{const o=[t.x,t.y];i.points.reduce((d,g)=>(d.push(g.x,-g.y),d),o);const n=i.attributes.arrow?b.Arrow:b.Line,r=s??`rgb(${i.attributes.color.r}, ${i.attributes.color.g}, ${i.attributes.color.b})`,h=new n({points:o,strokeWidth:this.settings.lineWidth,stroke:r,fill:s??`rgb(${i.attributes.color.r}, ${i.attributes.color.g} , ${i.attributes.color.b})`,pointerLength:.3,pointerWidth:.2,perfectDrawEnabled:!1,listening:!1});let a=i.attributes.style;a==="dot line"?(h.dash([.05,.05]),h.dashOffset(.1)):a==="dash line"?h.dash([.4,.2]):a==="solid line"||a!==void 0&&console.log("Brak opisu stylu: "+a);const c=[h],l=t.doors[e];return l&&o.length>=4&&c.push(this.renderDoor(o,l)),c})}getSpecialExitAreaTargets(t){const s=[];for(const[e,i]of Object.entries(t.customLines)){let o=t.specialExits[e];if(o===void 0){const d=At[e];d&&(o=t.exits[d]??t.specialExits[d])}if(o===void 0)continue;const n=this.mapReader.getRoom(o);if(!n||n.area===t.area&&n.z===t.z)continue;const r=[t.x,t.y];i.points.reduce((d,g)=>(d.push(g.x,-g.y),d),r);let h=1/0,a=1/0,c=-1/0,l=-1/0;for(let d=0;d<r.length;d+=2)h=Math.min(h,r[d]),c=Math.max(c,r[d]),a=Math.min(a,r[d+1]),l=Math.max(l,r[d+1]);s.push({bounds:{x:h,y:a,width:c-h,height:l-a},targetRoomId:o})}return s}renderStubs(t,s=this.settings.lineColor){return t.stubs.map(e=>{const i=Xt[e],o=this.getRoomEdgePoint(t.x,t.y,i,this.settings.roomSize/2),n=L(t.x,t.y,i,this.settings.roomSize/2+.5),r=[o.x,o.y,n.x,n.y];return new b.Line({points:r,stroke:s,strokeWidth:this.settings.lineWidth,perfectDrawEnabled:!1,listening:!1})})}getSymbolColor(t,s){return this.settings.frameMode?this.mapReader.getColorValue(t):this.mapReader.getSymbolColor(t,s)}renderInnerExits(t){return Wt.map(s=>{if(t.exits[s]){const e=new b.Group({listening:!1}),i=new b.RegularPolygon({x:t.x,y:t.y,sides:3,fill:this.getSymbolColor(t.env,.6),stroke:this.getSymbolColor(t.env),strokeWidth:this.settings.lineWidth,radius:this.settings.roomSize/5,scaleX:1.4,scaleY:.8,perfectDrawEnabled:!1,listening:!1});e.add(i);let o=t.doors[s];if(o!==void 0)switch(o){case 1:i.stroke(H.OPEN_DOOR);break;case 2:i.stroke(H.CLOSED_DOOR);break;default:i.stroke(H.LOCKED_DOOR)}const n=i.stroke();switch(s){case"up":i.position(L(t.x,t.y,"south",this.settings.roomSize/4));break;case"down":i.rotation(180),i.position(L(t.x,t.y,"north",this.settings.roomSize/4));break;case"in":{i.rotation(90),i.position(L(t.x,t.y,"west",this.settings.roomSize/4));const r=L(t.x,t.y,"east",this.settings.roomSize/4);e.add(new b.RegularPolygon({x:r.x,y:r.y,sides:3,fill:i.fill(),stroke:n,strokeWidth:this.settings.lineWidth,radius:this.settings.roomSize/5,scaleX:1.4,scaleY:.8,rotation:-90,perfectDrawEnabled:!1,listening:!1}));break}case"out":{i.rotation(-90),i.position(L(t.x,t.y,"west",this.settings.roomSize/4));const r=L(t.x,t.y,"east",this.settings.roomSize/4);e.add(new b.RegularPolygon({x:r.x,y:r.y,sides:3,fill:i.fill(),stroke:n,strokeWidth:this.settings.lineWidth,radius:this.settings.roomSize/5,scaleX:1.4,scaleY:.8,rotation:90,perfectDrawEnabled:!1,listening:!1}));break}}return e}}).filter(s=>s!==void 0)}renderDoor(t,s){const e={x:t[0]+(t[2]-t[0])/2,y:t[1]+(t[3]-t[1])/2};return new b.Rect({x:e.x-this.settings.roomSize/4,y:e.y-this.settings.roomSize/4,width:this.settings.roomSize/2,height:this.settings.roomSize/2,stroke:xt(s),strokeWidth:this.settings.lineWidth,perfectDrawEnabled:!1,listening:!1})}}class zt{constructor(t,s){this.rooms=[],this.labels=[],this.rooms=t,this.labels=s,this.bounds=this.createBounds()}getRooms(){return this.rooms}getLabels(){return this.labels}getBounds(){return this.bounds}createBounds(){const t=this.rooms.reduce((s,e)=>({minX:Math.min(s.minX,e.x),maxX:Math.max(s.maxX,e.x),minY:Math.min(s.minY,e.y),maxY:Math.max(s.maxY,e.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY});for(const s of this.labels){const e=s.X,i=-s.Y;t.minX=Math.min(t.minX,e),t.maxX=Math.max(t.maxX,e+s.Width),t.minY=Math.min(t.minY,i),t.maxY=Math.max(t.maxY,i+s.Height)}return t}}const et=class et{constructor(t){this.planes={},this.exits=new Map,this.version=0,this.area=t,this.planes=this.createPlanes(),this.createExits()}getAreaName(){return this.area.areaName}getAreaId(){return parseInt(this.area.areaId)}getVersion(){return this.version}markDirty(){this.version++}getPlane(t){return this.planes[t]}getPlanes(){return Object.values(this.planes)}getZLevels(){return Object.keys(this.planes).map(Number).sort((t,s)=>t-s)}getRooms(){return this.area.rooms}getFullBounds(){return this.getPlanes().reduce((t,s)=>{const e=s.getBounds();return{minX:Math.min(t.minX,e.minX),maxX:Math.max(t.maxX,e.maxX),minY:Math.min(t.minY,e.minY),maxY:Math.max(t.maxY,e.maxY)}},{minX:1/0,maxX:-1/0,minY:1/0,maxY:-1/0})}getLinkExits(t){return Array.from(this.exits.values()).filter(s=>s.zIndex.includes(t))}createPlanes(){const t=this.area.rooms.reduce((s,e)=>(s[e.z]||(s[e.z]=[]),s[e.z].push(e),s),{});return Object.entries(t).reduce((s,[e,i])=>(s[+e]=new zt(i,this.area.labels.filter(o=>o.Z===+e)),s),{})}createExits(){const t=new Map;this.area.rooms.forEach(s=>{Object.entries(s.exits).forEach(([e,i])=>{if(s.id===i)return;const o=Math.min(s.id,i),n=Math.max(s.id,i),r=`${o}-${n}`;t.has(r)||t.set(r,[]),t.get(r).push({origin:s.id,target:i,z:s.z,dir:e})})});for(const[s,e]of t){const[i,o]=s.split("-"),n=parseInt(i),r=parseInt(o),h=e.filter(l=>l.origin===n),a=e.filter(l=>l.origin===r),c=new Set;for(const l of h){let d=-1;for(let g=0;g<a.length;g++)if(!c.has(g)){if(a[g].dir===et.oppositeDir[l.dir]){d=g;break}d===-1&&(d=g)}if(d!==-1){c.add(d);const g=a[d];this.exits.set(`${s}-${l.dir}`,{a:n,b:r,aDir:l.dir,bDir:g.dir,zIndex:[l.z,g.z]})}else this.exits.set(`${s}-a:${l.dir}`,{a:n,b:r,aDir:l.dir,zIndex:[l.z]})}for(let l=0;l<a.length;l++)if(!c.has(l)){const d=a[l];this.exits.set(`${s}-b:${d.dir}`,{a:n,b:r,bDir:d.dir,zIndex:[d.z]})}}}};et.oppositeDir={north:"south",south:"north",east:"west",west:"east",northeast:"southwest",southwest:"northeast",northwest:"southeast",southeast:"northwest",up:"down",down:"up",in:"out",out:"in"};let _=et;class bt extends zt{constructor(t,s){super(t.getRooms(),t.getLabels()),this.basePlane=t,this.visitedRooms=s}getRooms(){return this.basePlane.getRooms().filter(t=>this.visitedRooms.has(t.id))}getLabels(){return this.basePlane.getLabels()}getBounds(){const t=this.getRooms();return t.length?t.reduce((s,e)=>({minX:Math.min(s.minX,e.x),maxX:Math.max(s.maxX,e.x),minY:Math.min(s.minY,e.y),maxY:Math.max(s.maxY,e.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY}):this.basePlane.getBounds()}}class J extends _{constructor(t,s){super(t),this.planeCache=new WeakMap,this.visitedRooms=s instanceof Set?s:new Set(s??[]),this.areaRoomIds=new Set(t.rooms.map(e=>e.id))}getPlane(t){const s=super.getPlane(t);if(!s)return s;let e=this.planeCache.get(s);return e||(e=new bt(s,this.visitedRooms),this.planeCache.set(s,e)),e}getPlanes(){return super.getPlanes().map(t=>{let s=this.planeCache.get(t);return s||(s=new bt(t,this.visitedRooms),this.planeCache.set(t,s)),s})}getLinkExits(t){return super.getLinkExits(t).filter(s=>this.visitedRooms.has(s.a)||this.visitedRooms.has(s.b))}getVisitedRoomCount(){return super.getRooms().reduce((t,s)=>t+(this.visitedRooms.has(s.id)?1:0),0)}getTotalRoomCount(){return this.areaRoomIds.size}hasVisitedRoom(t){return this.areaRoomIds.has(t)&&this.visitedRooms.has(t)}getVisitedRoomIds(){return super.getRooms().filter(t=>this.visitedRooms.has(t.id)).map(t=>t.id)}addVisitedRoom(t){const s=this.visitedRooms.has(t);this.visitedRooms.add(t);const e=!s&&this.areaRoomIds.has(t);return e&&this.markDirty(),e}addVisitedRooms(t){let s=0;for(const e of t){const i=this.visitedRooms.has(e);this.visitedRooms.add(e),!i&&this.areaRoomIds.has(e)&&s++}return s>0&&this.markDirty(),s}}const G=["up","down","in","out"];function tt(m,t,s,e,i){return m.roomShape==="circle"?ot(t,s,e,i):m.roomShape==="roundedRectangle"?it(t,s,e,i,m.roomSize*.2):L(t,s,e,i)}function Yt(m,t,s){for(const[e,i]of Object.entries(t.exits))if(i===s.id){const o=e;if(G.includes(o)){const h=N[o],a=t.customLines[h]?h:t.customLines[o]?o:void 0;return{type:"inner",fromDir:o,customLineKey:a,fromRoom:t,toRoom:s}}const n=N[o];if(t.customLines[n])return{type:"special",fromDir:o,customLineKey:n,fromRoom:t,toRoom:s};if(t.customLines[o])return{type:"special",fromDir:o,customLineKey:o,fromRoom:t,toRoom:s};const r=Nt(s,t.id);return{type:"regular",fromDir:o,toDir:r,fromRoom:t,toRoom:s}}for(const[e,i]of Object.entries(t.specialExits))if(i===s.id)return t.customLines[e]?{type:"special",customLineKey:e,fromRoom:t,toRoom:s}:{type:"inner",fromRoom:t,toRoom:s};for(const[e,i]of Object.entries(s.exits))if(i===t.id){const o=e;if(G.includes(o)){const r=N[o],h=s.customLines[r]?r:s.customLines[o]?o:void 0;return{type:"inner",toDir:o,customLineKey:h,fromRoom:t,toRoom:s}}const n=N[o];return s.customLines[n]?{type:"special",toDir:o,customLineKey:n,fromRoom:t,toRoom:s}:s.customLines[o]?{type:"special",toDir:o,customLineKey:o,fromRoom:t,toRoom:s}:{type:"regular",toDir:o,fromRoom:t,toRoom:s}}for(const[e,i]of Object.entries(s.specialExits))if(i===t.id)return s.customLines[e]?{type:"special",customLineKey:e,fromRoom:t,toRoom:s}:{type:"inner",fromRoom:t,toRoom:s};return{type:"none",fromRoom:t,toRoom:s}}function Nt(m,t){for(const[s,e]of Object.entries(m.exits))if(e===t)return s}function wt(m,t,s){return m?m.area===t&&m.z===s:!1}function Tt(m,t){for(const[s,e]of Object.entries(m.exits))if(e===t.id)return{direction:s};for(const[s,e]of Object.entries(m.specialExits))if(e===t.id)return}function Ot(m,t){for(const s of ut)if(m.exits[s]===t.id)return s;for(const s of ut)if(t.exits[s]===m.id)return Lt[s]}function Bt(m,t,s){const{fromRoom:e,toRoom:i,fromDir:o,toDir:n}=t;if(s.length===0&&s.push(e.x,e.y),o&&Z.includes(o)){const r=tt(m,e.x,e.y,o,m.roomSize/2);s.push(r.x,r.y)}if(n&&Z.includes(n)){const r=tt(m,i.x,i.y,n,m.roomSize/2);s.push(r.x,r.y)}s.push(i.x,i.y)}function Ft(m,t){const{fromRoom:s,toRoom:e,customLineKey:i}=m;let o=s,n;i&&(n=s.customLines[i],n||(n=e.customLines[i],o=e)),t.length===0&&t.push(o.x,o.y),n&&n.points.forEach(r=>{t.push(r.x,-r.y)}),t.push(e.x,e.y)}function nt(m,t,s,e,i){const o=[],n=[],r=[],h=s.map(d=>m.getRoom(d)).filter(d=>d!==void 0);let a=[];const c=()=>{a.length>=4&&o.push({points:[...a]}),a=[]},l=d=>{const{fromRoom:g,toRoom:u,fromDir:f,toDir:y,customLineKey:p}=d;if(p){let x=g,k=g.customLines[p];if(k||(k=u.customLines[p],x=u),k){const D=[x.x,x.y];k.points.forEach($=>{D.push($.x,-$.y)}),r.push({points:D})}}f&&G.includes(f)&&n.push({room:g,direction:f}),y&&G.includes(y)&&n.push({room:u,direction:y})};for(let d=0;d<h.length-1;d++){const g=h[d],u=h[d+1],f=wt(g,e,i),y=wt(u,e,i);if(!f&&!y){c();continue}if(f&&y){const p=Yt(m,g,u);switch(p.type){case"regular":Bt(t,p,a);break;case"special":Ft(p,a);break;case"inner":c(),l(p);break;case"none":a.length===0&&a.push(g.x,g.y),a.push(u.x,u.y);break}}else{const p=f?g:u,x=f?u:g,k=Tt(p,x);if(k){if(G.includes(k.direction))c(),n.push({room:p,direction:k.direction});else if(Z.includes(k.direction)){a.length===0&&a.push(p.x,p.y);const D=tt(t,p.x,p.y,k.direction,t.roomSize/2),$=L(p.x,p.y,k.direction,t.roomSize);a.push(D.x,D.y,$.x,$.y),c()}}else{const D=Ot(p,x);if(D){a.length===0&&a.push(p.x,p.y);const $=tt(t,p.x,p.y,D,t.roomSize/2),X=L(p.x,p.y,D,t.roomSize);a.push($.x,$.y,X.x,X.y),c()}}}}return c(),{segments:o,innerMarkers:n,customLines:r}}class Vt{constructor(t,s,e){this.paths=[],this.mapReader=t,this.overlayLayer=s,this.settings=e}createStrokedLine(t,s){const e=new b.Group;return e.opacity(.8),e.add(new b.Line({points:t,stroke:"black",strokeWidth:this.settings.lineWidth*8,lineCap:"round",lineJoin:"round"})),e.add(new b.Line({points:t,stroke:s,strokeWidth:this.settings.lineWidth*4,lineCap:"round",lineJoin:"round"})),e}renderInnerExitMarker(t,s,e){const i=new b.Group;i.opacity(.8);const o=new b.RegularPolygon({x:t.x,y:t.y,sides:3,fill:e,stroke:"black",strokeWidth:this.settings.lineWidth*2,radius:this.settings.roomSize/5,scaleX:1.4,scaleY:.8});switch(s){case"up":o.position(L(t.x,t.y,"south",this.settings.roomSize/4));break;case"down":o.rotation(180),o.position(L(t.x,t.y,"north",this.settings.roomSize/4));break;case"in":{const n=o.clone();n.rotation(-90),n.position(L(t.x,t.y,"east",this.settings.roomSize/4)),i.add(n),o.rotation(90),o.position(L(t.x,t.y,"west",this.settings.roomSize/4));break}case"out":{const n=o.clone();n.rotation(90),n.position(L(t.x,t.y,"east",this.settings.roomSize/4)),i.add(n),o.rotation(-90),o.position(L(t.x,t.y,"west",this.settings.roomSize/4));break}}return i.add(o),i}renderPath(t,s,e,i="#66E64D"){if(s===void 0||e===void 0)return;const o=nt(this.mapReader,this.settings,t,s,e);for(const n of o.segments){const r=this.createStrokedLine(n.points,i);this.overlayLayer.add(r),this.paths.push(r)}for(const n of o.customLines){const r=this.createStrokedLine(n.points,i);this.overlayLayer.add(r),this.paths.push(r)}for(const n of o.innerMarkers){const r=this.renderInnerExitMarker(n.room,n.direction,i);this.overlayLayer.add(r),this.paths.push(r)}return this.paths[0]}clearPaths(){this.paths.forEach(t=>{t.destroy()}),this.paths=[]}}const Zt={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},jt=["up","down","in","out"],at={OPEN:"rgb(10, 155, 10)",CLOSED:"rgb(226, 205, 59)",LOCKED:"rgb(155, 10, 10)"};function vt(m){switch(m){case 1:return at.OPEN;case 2:return at.CLOSED;default:return at.LOCKED}}function A(m){return m.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}class pt{constructor(t,s){this.mapReader=t,this.settings=s,this.exitRenderer=new mt(t,null,s)}getSymbolColor(t,s){return this.settings.frameMode?this.mapReader.getColorValue(t):this.mapReader.getSymbolColor(t,s)}export(t,s,e){const i=this.mapReader.getArea(t);if(!i)throw new Error(`Area ${t} not found`);const o=i.getPlane(s);if(!o)throw new Error(`Plane z=${s} not found in area ${t}`);const n=e?.padding??3,r=this.computeBounds(i,o,e?.roomId,n),h=[];h.push(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${r.x} ${r.y} ${r.w} ${r.h}">`),h.push(`<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" fill="${A(this.settings.backgroundColor)}"/>`),this.settings.gridEnabled&&this.renderGrid(h,r),this.renderLabels(h,o.getLabels()),this.renderLinkExits(h,i,s);const a=o.getRooms();this.renderSpecialExits(h,a),this.renderStubs(h,a),this.renderRooms(h,a),this.renderInnerExits(h,a);const c=e?.overlays;if(c){if(c.paths)for(const l of c.paths)this.renderPathOverlay(h,l.locations,l.color,t,s);if(c.highlights)for(const l of c.highlights)this.renderHighlightOverlay(h,l.roomId,l.color);c.position&&this.renderPositionMarker(h,c.position.roomId)}if(this.settings.areaName){const l=i.getAreaName();if(l){const d=this.getEffectiveBounds(i,o);h.push(`<text x="${d.minX-3.5}" y="${d.minY-2}" font-size="2.5" font-family="${A(this.settings.fontFamily)}" fill="white">${A(l)}</text>`)}}return h.push("</svg>"),h.join(`
2
- `)}computeBounds(t,s,e,i){if(e!==void 0){const g=this.mapReader.getRoom(e);if(!g)throw new Error(`Room ${e} not found`);return{x:g.x-i,y:g.y-i,w:i*2,h:i*2}}const o=this.getEffectiveBounds(t,s),n=this.settings.areaName?t.getAreaName():void 0,r=n?7:0,h=n?3.5:0,a=o.minX-h,c=o.minY-r,l=n?o.minX-3.5+n.length*2.5*.6:-1/0,d=Math.max(o.maxX,l);return{x:a-i,y:c-i,w:d-a+i*2,h:o.maxY-c+i*2}}getEffectiveBounds(t,s){return this.settings.uniformLevelSize?t.getFullBounds():s.getBounds()}getRoomEdgePoint(t,s,e,i){return this.settings.roomShape==="circle"?ot(t,s,e,i):this.settings.roomShape==="roundedRectangle"?it(t,s,e,i,this.settings.roomSize*.2):L(t,s,e,i)}renderGrid(t,s){const e=this.settings.gridSize,i=Math.floor(s.x/e)*e,o=Math.ceil((s.x+s.w)/e)*e,n=Math.floor(s.y/e)*e,r=Math.ceil((s.y+s.h)/e)*e,h=A(this.settings.gridColor),a=this.settings.gridLineWidth;for(let c=i;c<=o;c+=e)t.push(`<line x1="${c}" y1="${n}" x2="${c}" y2="${r}" stroke="${h}" stroke-width="${a}"/>`);for(let c=n;c<=r;c+=e)t.push(`<line x1="${i}" y1="${c}" x2="${o}" y2="${c}" stroke="${h}" stroke-width="${a}"/>`)}renderLabels(t,s){for(const e of s){const i=e.X,o=-e.Y;if(this.settings.labelRenderMode==="image"&&e.pixMap){t.push(`<image x="${i}" y="${o}" width="${e.Width}" height="${e.Height}" href="data:image/png;base64,${e.pixMap}"/>`);continue}if((e.BgColor?.alpha??0)>0&&!this.settings.transparentLabels){const n=this.labelColor(e.BgColor);t.push(`<rect x="${i}" y="${o}" width="${e.Width}" height="${e.Height}" fill="${n}"/>`)}if(e.Text){const n=this.labelColor(e.FgColor),r=Math.min(.75,e.Width/Math.max(e.Text.length/2,1)),h=Math.max(.1,Math.min(r,Math.max(e.Height*.9,.1)));t.push(`<text x="${i+e.Width/2}" y="${o+e.Height/2}" font-size="${h}" font-family="${A(this.settings.fontFamily)}" fill="${n}" text-anchor="middle" dominant-baseline="central">${A(e.Text)}</text>`)}}}labelColor(t){const s=(t?.alpha??255)/255,e=i=>Math.min(255,Math.max(0,i??0));return`rgba(${e(t?.r)}, ${e(t?.g)}, ${e(t?.b)}, ${s})`}renderLinkExits(t,s,e){const i=s.getLinkExits(e);for(const o of i){const n=this.exitRenderer.renderData(o,e);n&&this.renderExitData(t,n)}}renderExitData(t,s){for(const e of s.lines)this.renderSvgLine(t,e);for(const e of s.arrows)this.renderSvgArrow(t,e);for(const e of s.doors)this.renderSvgDoor(t,e)}renderSvgLine(t,s){if(s.points.length<4)return;const e=s.points.map(o=>o.toString()).join(" "),i=s.dash?` stroke-dasharray="${s.dash.join(" ")}"`:"";t.push(`<polyline points="${e}" stroke="${A(s.stroke)}" stroke-width="${s.strokeWidth}" fill="none"${i}/>`)}renderSvgArrow(t,s){if(s.points.length<4)return;const e=s.points.map(p=>p.toString()).join(" "),i=s.dash?` stroke-dasharray="${s.dash.join(" ")}"`:"";t.push(`<polyline points="${e}" stroke="${A(s.stroke)}" stroke-width="${s.strokeWidth}" fill="none"${i}/>`);const o=s.points.length-2,n=s.points[o],r=s.points[o+1],h=s.points[o-2],a=s.points[o-1],c=Math.atan2(r-a,n-h),l=s.pointerLength,d=s.pointerWidth/2,g=n-l*Math.cos(c-Math.atan2(d,l)),u=r-l*Math.sin(c-Math.atan2(d,l)),f=n-l*Math.cos(c+Math.atan2(d,l)),y=r-l*Math.sin(c+Math.atan2(d,l));t.push(`<polygon points="${n},${r} ${g},${u} ${f},${y}" fill="${A(s.fill)}" stroke="${A(s.stroke)}" stroke-width="${s.strokeWidth}"/>`)}renderSvgDoor(t,s){t.push(`<rect x="${s.x}" y="${s.y}" width="${s.width}" height="${s.height}" stroke="${A(s.stroke)}" stroke-width="${s.strokeWidth}" fill="none"/>`)}renderStubs(t,s){const e=this.settings.lineColor;for(const i of s)for(const o of i.stubs){const n=Zt[o];if(!n)continue;const r=this.getRoomEdgePoint(i.x,i.y,n,this.settings.roomSize/2),h=L(i.x,i.y,n,this.settings.roomSize/2+.5);t.push(`<line x1="${r.x}" y1="${r.y}" x2="${h.x}" y2="${h.y}" stroke="${A(e)}" stroke-width="${this.settings.lineWidth}"/>`)}}renderSpecialExits(t,s){for(const e of s)for(const[i,o]of Object.entries(e.customLines)){const n=[e.x,e.y];for(const l of o.points)n.push(l.x,-l.y);const r=`rgb(${o.attributes.color.r}, ${o.attributes.color.g}, ${o.attributes.color.b})`;let h="";o.attributes.style==="dot line"?h=' stroke-dasharray="0.05 0.05"':o.attributes.style==="dash line"&&(h=' stroke-dasharray="0.4 0.2"');const a=n.map(l=>l.toString()).join(" ");if(o.attributes.arrow&&n.length>=4){t.push(`<polyline points="${a}" stroke="${A(r)}" stroke-width="${this.settings.lineWidth}" fill="none"${h}/>`);const l=n.length-2,d=n[l],g=n[l+1],u=n[l-2],f=n[l-1],y=Math.atan2(g-f,d-u),p=.3,x=.1,k=d-p*Math.cos(y-Math.atan2(x,p)),D=g-p*Math.sin(y-Math.atan2(x,p)),$=d-p*Math.cos(y+Math.atan2(x,p)),X=g-p*Math.sin(y+Math.atan2(x,p));t.push(`<polygon points="${d},${g} ${k},${D} ${$},${X}" fill="${A(r)}" stroke="${A(r)}" stroke-width="${this.settings.lineWidth}"/>`)}else t.push(`<polyline points="${a}" stroke="${A(r)}" stroke-width="${this.settings.lineWidth}" fill="none"${h}/>`);const c=e.doors[i];if(c&&n.length>=4){const l=n[0]+(n[2]-n[0])/2,d=n[1]+(n[3]-n[1])/2,g=this.settings.roomSize/2;t.push(`<rect x="${l-g/2}" y="${d-g/2}" width="${g}" height="${g}" stroke="${vt(c)}" stroke-width="${this.settings.lineWidth}" fill="none"/>`)}}}renderRooms(t,s){const e=this.settings.roomSize,i=e/2;for(const o of s){const n=this.mapReader.getColorValue(o.env),r=this.settings.frameMode?this.settings.backgroundColor:n,h=this.settings.frameMode?n:this.settings.lineColor;if(this.settings.roomShape==="circle")t.push(`<circle cx="${o.x}" cy="${o.y}" r="${i}" fill="${A(r)}" stroke="${A(h)}" stroke-width="${this.settings.lineWidth}"/>`);else{const a=o.x-i,c=o.y-i,l=this.settings.roomShape==="roundedRectangle"?e*.2:0,d=l>0?` rx="${l}" ry="${l}"`:"";if(t.push(`<rect x="${a}" y="${c}" width="${e}" height="${e}" fill="${A(r)}" stroke="${A(h)}" stroke-width="${this.settings.lineWidth}"${d}/>`),this.settings.emboss){const g=q(this.settings.lineColor)>.41,u=g?"#000000":"#ffffff",f=g?`${a},${c} ${a+e},${c} ${a+e},${c+e}`:`${a},${c} ${a},${c+e} ${a+e},${c+e}`;t.push(`<polyline points="${f}" stroke="${u}" stroke-width="${this.settings.lineWidth}" fill="none"/>`)}}if(o.roomChar){const a=this.getSymbolColor(o.env),c=e*.75;t.push(`<text x="${o.x}" y="${o.y}" dy="0.35em" font-size="${c}" font-weight="bold" font-family="${A(this.settings.fontFamily)}" fill="${A(a)}" text-anchor="middle">${A(o.roomChar)}</text>`)}}}renderInnerExits(t,s){const e=this.settings.roomSize,i=e/5;for(const o of s)for(const n of jt){if(!o.exits[n])continue;const r=this.getSymbolColor(o.env),h=this.getSymbolColor(o.env,.6);let a;const c=o.doors[n];c!==void 0&&(a=vt(c));const l=a??r;switch(n){case"up":{const d=L(o.x,o.y,"south",e/4);t.push(this.svgTriangle(d.x,d.y,i,0,h,l));break}case"down":{const d=L(o.x,o.y,"north",e/4);t.push(this.svgTriangle(d.x,d.y,i,180,h,l));break}case"in":{const d=L(o.x,o.y,"west",e/4),g=L(o.x,o.y,"east",e/4);t.push(this.svgTriangle(d.x,d.y,i,90,h,l)),t.push(this.svgTriangle(g.x,g.y,i,-90,h,l));break}case"out":{const d=L(o.x,o.y,"west",e/4),g=L(o.x,o.y,"east",e/4);t.push(this.svgTriangle(d.x,d.y,i,-90,h,l)),t.push(this.svgTriangle(g.x,g.y,i,90,h,l));break}}}}svgTriangle(t,s,e,i,o,n){const a=i*Math.PI/180,c=[];for(let l=0;l<3;l++){const d=2*Math.PI*l/3-Math.PI/2;let g=Math.cos(d)*e*1.4,u=Math.sin(d)*e*.8;const f=g*Math.cos(a)-u*Math.sin(a),y=g*Math.sin(a)+u*Math.cos(a);c.push(`${t+f},${s+y}`)}return`<polygon points="${c.join(" ")}" fill="${A(o)}" stroke="${A(n)}" stroke-width="${this.settings.lineWidth}"/>`}renderPathOverlay(t,s,e,i,o){const n=nt(this.mapReader,this.settings,s,i,o),r=this.settings.lineWidth;for(const a of n.segments){const c=a.points.map(l=>l.toString()).join(" ");t.push(`<polyline points="${c}" stroke="black" stroke-width="${r*8}" stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.8"/>`),t.push(`<polyline points="${c}" stroke="${A(e)}" stroke-width="${r*4}" stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.8"/>`)}for(const a of n.customLines){const c=a.points.map(l=>l.toString()).join(" ");t.push(`<polyline points="${c}" stroke="black" stroke-width="${r*8}" stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.8"/>`),t.push(`<polyline points="${c}" stroke="${A(e)}" stroke-width="${r*4}" stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.8"/>`)}const h=this.settings.roomSize/5;for(const a of n.innerMarkers)t.push(this.svgTriangle(a.room.x,a.room.y,h,this.innerExitRotation(a.direction),e,"black"))}innerExitRotation(t){switch(t){case"up":return 0;case"down":return 180;case"in":return 90;case"out":return-90;default:return 0}}renderHighlightOverlay(t,s,e){const i=this.mapReader.getRoom(s);if(!i)return;const o=1.5,n=this.settings.roomSize,r="0.05 0.05";if(this.settings.roomShape==="circle")t.push(`<circle cx="${i.x}" cy="${i.y}" r="${n/2*o}" stroke="${A(e)}" stroke-width="0.1" stroke-dasharray="${r}" fill="none"/>`);else{const h=n*o;t.push(`<rect x="${i.x-h/2}" y="${i.y-h/2}" width="${h}" height="${h}" stroke="${A(e)}" stroke-width="0.1" stroke-dasharray="${r}" fill="none"/>`)}}renderPositionMarker(t,s){const e=this.mapReader.getRoom(s);if(!e)return;const i=this.settings.playerMarker,n=this.settings.roomSize*i.sizeFactor,r=i.dashEnabled&&i.dash?` stroke-dasharray="${i.dash.join(" ")}"`:"",h=i.fillAlpha>0?` fill="${i.fillColor}" fill-opacity="${i.fillAlpha}"`:' fill="none"';t.push(`<circle cx="${e.x}" cy="${e.y}" r="${n/2}" stroke="${i.strokeColor}" stroke-width="${i.strokeWidth}" stroke-opacity="${i.strokeAlpha}"${r}${h}/>`)}}const Ht=.6,j=75,Gt=.025,_t="rgb(225, 255, 225)",K="rgb(120, 72, 0)";function q(m){let t,s,e;const i=m.match(/(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);if(i)t=parseInt(i[1])/255,s=parseInt(i[2])/255,e=parseInt(i[3])/255;else if(m.startsWith("#")&&m.length>=7)t=parseInt(m.slice(1,3),16)/255,s=parseInt(m.slice(3,5),16)/255,e=parseInt(m.slice(5,7),16)/255;else return .5;return(Math.max(t,s,e)+Math.min(t,s,e))/2}class qt{constructor(t=60){this.samples=[],this.lastCullingTime=0,this.callback=null,this.windowSize=t}setCallback(t){t!==this.callback&&(this.callback=t,this.samples=[])}record(t){this.callback&&(this.samples.push(t),this.samples.length>=this.windowSize&&this.flush())}computeFps(){const t=performance.now(),s=t-this.lastCullingTime;return this.lastCullingTime=t,s>0?1e3/s:0}flush(){const t=this.samples.length;if(t===0)return;const s={cullingMs:0,gridMs:0,visibleRooms:0,totalRooms:0,visibleExits:0,fps:0};for(const e of this.samples)s.cullingMs+=e.cullingMs,s.gridMs+=e.gridMs,s.visibleRooms+=e.visibleRooms,s.totalRooms+=e.totalRooms,s.visibleExits+=e.visibleExits,s.fps+=e.fps;s.cullingMs/=t,s.gridMs/=t,s.visibleRooms=Math.round(s.visibleRooms/t),s.totalRooms=Math.round(s.totalRooms/t),s.visibleExits=Math.round(s.visibleExits/t),s.fps=Math.round(s.fps),this.callback(s),this.samples=[]}}function Q(m,t){const s=parseInt(m.slice(1,3),16),e=parseInt(m.slice(3,5),16),i=parseInt(m.slice(5,7),16);return`rgba(${s}, ${e}, ${i}, ${t})`}function yt(){return{roomSize:Ht,lineWidth:Gt,lineColor:_t,backgroundColor:"#000000",instantMapMove:!1,highlightCurrentRoom:!0,cullingEnabled:!0,cullingMode:"indexed",cullingBounds:null,labelRenderMode:"image",transparentLabels:!1,roomShape:"rectangle",playerMarker:{strokeColor:"#00e5b2",strokeAlpha:1,fillColor:"#00e5b2",fillAlpha:0,strokeWidth:.1,sizeFactor:1.7,dash:[.05,.05],dashEnabled:!0},gridEnabled:!1,gridSize:1,gridColor:"rgba(200, 200, 200, 0.15)",gridLineWidth:.03,perfCallback:null,borders:!0,frameMode:!1,emboss:!1,areaName:!0,fontFamily:"sans-serif",uniformLevelSize:!1}}class Kt{constructor(t,s,e){this.highlights=new Map,this.currentZoom=1,this.currentRoomOverlay=[],this.roomNodes=new Map,this.centerOnResize=!0,this.minZoom=.05,this.standaloneExitNodes=[],this.spatialBucketSize=5,this.roomSpatialIndex=new Map,this.exitSpatialIndex=new Map,this.visibleRooms=new Set,this.visibleStandaloneExitNodes=new Set,this.bufferRoomSet=new Set,this.bufferExitSet=new Set,this.bufferRoomCandidates=new Set,this.bufferExitCandidates=new Set,this.cullingScheduled=!1,this.perfMonitor=new qt,this.areaExitHitZones=[],this.visibleExitDrawData=[],this.cachedGridBounds=null,this.settings=e??yt(),this.stage=new b.Stage({container:t,width:t.clientWidth,height:t.clientHeight,draggable:!0}),t.style.backgroundColor=this.settings.backgroundColor,window.addEventListener("resize",()=>{this.onResize(t)}),t.addEventListener("resize",()=>{this.onResize(t)}),this.gridLayer=new b.Layer({listening:!1,hitGraphEnabled:!1}),this.stage.add(this.gridLayer),this.linkLayer=new b.Layer({listening:!1,hitGraphEnabled:!1}),this.stage.add(this.linkLayer),this.roomLayer=new b.Layer({hitGraphEnabled:!1}),this.stage.add(this.roomLayer),this.positionLayer=new b.Layer({listening:!1,hitGraphEnabled:!1}),this.stage.add(this.positionLayer),this.overlayLayer=new b.Layer({listening:!1,hitGraphEnabled:!1}),this.stage.add(this.overlayLayer),this.mapReader=s,this.exitRenderer=new mt(s,this,this.settings),this.pathRenderer=new Vt(s,this.overlayLayer,this.settings),this.initScaling(1.1),this.stage.on("dragmove",()=>{this.scheduleRoomCulling(),this.emitPanEvent()}),this.stage.on("dragend",()=>{this.scheduleRoomCulling(),this.emitPanEvent()}),this.initRoomHitDetection()}clientToMapPoint(t,s){const i=this.stage.container().getBoundingClientRect(),o=t-i.left,n=s-i.top,r=this.stage.scaleX();if(!r)return null;const h=this.stage.position();return{x:(o-h.x)/r,y:(n-h.y)/r}}findRoomAtClientPoint(t,s){const e=this.clientToMapPoint(t,s);if(!e)return null;const i=this.settings.roomSize/2,o=this.getBucketKey(Math.floor(e.x/this.spatialBucketSize),Math.floor(e.y/this.spatialBucketSize)),n=this.roomSpatialIndex.get(o);if(!n)return null;for(const r of n){const h=e.x-r.room.x,a=e.y-r.room.y;if(h>=-i&&h<=i&&a>=-i&&a<=i)return r.room}return null}initRoomHitDetection(){const t=this.stage.container();let s=null;t.addEventListener("mousemove",a=>{const c=this.findRoomAtClientPoint(a.clientX,a.clientY);if(c!==s&&(s=c,c)){t.style.cursor="pointer";return}if(!s){const d=this.findAreaExitAtClientPoint(a.clientX,a.clientY)!==null;t.style.cursor=d?"pointer":"auto"}}),t.addEventListener("mouseleave",()=>{s=null,t.style.cursor="auto"});let e=null;t.addEventListener("mousedown",a=>{a.button===0&&(e={x:a.clientX,y:a.clientY})}),t.addEventListener("mouseup",a=>{if(a.button!==0||!e)return;const c=a.clientX-e.x,l=a.clientY-e.y;if(e=null,c*c+l*l>25)return;const d=this.findRoomAtClientPoint(a.clientX,a.clientY);if(d){this.emitRoomClickEvent(d.id,a.clientX,a.clientY);return}const g=this.findAreaExitAtClientPoint(a.clientX,a.clientY);if(g){this.emitAreaExitClickEvent(g.targetRoomId,a.clientX,a.clientY);return}this.emitMapClickEvent()}),t.addEventListener("contextmenu",a=>{const c=this.findRoomAtClientPoint(a.clientX,a.clientY);c&&(a.preventDefault(),this.emitRoomContextEvent(c.id,a.clientX,a.clientY))});let i,o,n;const r=()=>{n!==void 0&&(this.stage.draggable(n),n=void 0)},h=()=>{i!==void 0&&(window.clearTimeout(i),i=void 0),o=void 0,r()};t.addEventListener("touchstart",a=>{if(h(),a.touches.length>1)return;const c=a.touches[0];!c||!this.findRoomAtClientPoint(c.clientX,c.clientY)||(o={clientX:c.clientX,clientY:c.clientY},n=this.stage.draggable(),this.stage.draggable(!1),i=window.setTimeout(()=>{if(o){const d=this.findRoomAtClientPoint(o.clientX,o.clientY);d&&this.emitRoomContextEvent(d.id,o.clientX,o.clientY)}h()},500))},{passive:!0}),t.addEventListener("touchend",()=>h(),{passive:!0}),t.addEventListener("touchcancel",()=>h(),{passive:!0}),t.addEventListener("touchmove",a=>{if(!o)return;const c=a.touches[0];if(!c){h();return}const l=c.clientX-o.clientX,d=c.clientY-o.clientY;if(l*l+d*d>100){const g=n;h(),g&&this.stage.startDrag()}},{passive:!0})}onResize(t){this.stage.width(t.clientWidth),this.stage.height(t.clientHeight),this.centerOnResize&&this.currentRoomId&&this.centerOnRoom(this.mapReader.getRoom(this.currentRoomId),!1),this.stage.batchDraw(),this.scheduleRoomCulling()}initScaling(t){let s,e=!1,i=!1;this.stage.on("touchstart",o=>{const n=o.evt.touches;n&&n.length>1?(i=!0,this.stage.isDragging()&&(this.stage.stopDrag(),e=!0),this.stage.draggable(!1)):(i=!1,this.stage.draggable(!0))}),this.stage.on("touchend touchcancel",o=>{s=void 0;const n=o.evt.touches;(!n||n.length<=1)&&(i=!1,this.stage.draggable(!0))}),this.stage.on("wheel",o=>{o.evt.preventDefault();const n=this.stage.scaleX(),r=this.stage.getPointerPosition();if(!r)return;const h={x:(r.x-this.stage.x())/n,y:(r.y-this.stage.y())/n};let a=o.evt.deltaY>0?-1:1;o.evt.ctrlKey&&(a=-a);const c=a>0?this.currentZoom*t:this.currentZoom/t;if(this.setZoom(c)){const d=this.stage.scaleX(),g={x:r.x-h.x*d,y:r.y-h.y*d};this.stage.position(g),this.scheduleRoomCulling(),this.emitZoomChangeEvent()}}),this.stage.on("touchmove",o=>{const n=o.evt.touches,r=n?.[0],h=n?.[1];if(h||i&&(i=!1,this.stage.draggable(!0)),r&&!h&&e&&!this.stage.isDragging()&&(this.stage.startDrag(),e=!1),!r||!h){s=void 0;return}o.evt.preventDefault(),this.stage.isDragging()&&(this.stage.stopDrag(),e=!0),i||(i=!0,this.stage.draggable(!1));const a=this.stage.container().getBoundingClientRect(),c={x:r.clientX-a.left,y:r.clientY-a.top},l={x:h.clientX-a.left,y:h.clientY-a.top},d=Math.hypot(c.x-l.x,c.y-l.y);if(s===void 0){s=d;return}if(s===0||d===0){s=d;return}const g=this.stage.scaleX(),u=this.stage.x(),f=this.stage.y(),y={x:this.stage.width()/2,y:this.stage.height()/2},p={x:(y.x-u)/g,y:(y.y-f)/g},x=this.currentZoom*(d/s);if(this.setZoom(x)){const D=this.stage.scaleX(),$={x:y.x-p.x*D,y:y.y-p.y*D};this.stage.position($),this.stage.batchDraw(),this.scheduleRoomCulling(),this.emitZoomChangeEvent()}s=d})}drawArea(t,s){const e=this.mapReader.getArea(t);if(!e)return;const i=e.getPlane(s);i&&(this.currentArea=t,this.currentAreaInstance=e,this.currentZIndex=s,this.currentAreaVersion=e.getVersion(),this.clearCurrentRoomOverlay(),this.positionRender&&(this.positionRender.destroy(),this.positionRender=void 0),this.positionLayer.destroyChildren(),this.gridLayer.destroyChildren(),this.invalidateGridCache(),this.roomLayer.destroyChildren(),this.linkLayer.destroyChildren(),this.roomNodes.clear(),this.standaloneExitNodes=[],this.areaExitHitZones=[],this.standaloneExitBoundsRoomSize=void 0,this.roomSpatialIndex.clear(),this.exitSpatialIndex.clear(),this.visibleRooms.clear(),this.visibleStandaloneExitNodes.clear(),this.visibleExitDrawData.length=0,this.exitBatchShape=void 0,this.spatialBucketSize=this.computeSpatialBucketSize(),this.stage.scale({x:j*this.currentZoom,y:j*this.currentZoom}),this.renderGrid(),this.renderLabels(i.getLabels()),this.renderExits(e.getLinkExits(s)),this.renderRooms(i.getRooms()??[]),this.renderAreaName(e,i),this.refreshHighlights(),this.updateRoomCulling(),this.stage.batchDraw())}exportSvg(t){return this.currentArea===void 0||this.currentZIndex===void 0?void 0:new pt(this.mapReader,this.settings).export(this.currentArea,this.currentZIndex,t)}exportPng(t){if(this.currentArea===void 0||this.currentZIndex===void 0)return;const s=t?.pixelRatio??1,e=this.stage.toCanvas({pixelRatio:s}),i=document.createElement("canvas");i.width=e.width,i.height=e.height;const o=i.getContext("2d");return o.fillStyle=this.settings.backgroundColor,o.fillRect(0,0,i.width,i.height),o.drawImage(e,0,0),i.toDataURL("image/png")}exportPngBlob(t){if(this.currentArea===void 0||this.currentZIndex===void 0)return;const s=t?.pixelRatio??1,e=this.stage.toCanvas({pixelRatio:s}),i=document.createElement("canvas");i.width=e.width,i.height=e.height;const o=i.getContext("2d");return o.fillStyle=this.settings.backgroundColor,o.fillRect(0,0,i.width,i.height),o.drawImage(e,0,0),new Promise(n=>{i.toBlob(r=>{r&&n(r)},"image/png")})}computeSpatialBucketSize(){return Math.max(this.settings.roomSize*10,5)}getBucketKey(t,s){return t*1000003+s}forEachBucket(t,s,e,i,o){const n=this.spatialBucketSize,r=Math.min(t,e),h=Math.max(t,e),a=Math.min(s,i),c=Math.max(s,i),l=Math.floor(r/n),d=Math.floor(h/n),g=Math.floor(a/n),u=Math.floor(c/n);for(let f=l;f<=d;f++)for(let y=g;y<=u;y++)o(this.getBucketKey(f,y))}addRoomToSpatialIndex(t){const s=this.settings.roomSize/2,e=t.room.x-s,i=t.room.x+s,o=t.room.y-s,n=t.room.y+s;this.forEachBucket(e,o,i,n,r=>{let h=this.roomSpatialIndex.get(r);h||(h=new Set,this.roomSpatialIndex.set(r,h)),h.add(t)})}addStandaloneExitToSpatialIndex(t){const{bounds:s}=t,e=s.x,i=s.x+s.width,o=s.y,n=s.y+s.height;this.forEachBucket(e,o,i,n,r=>{let h=this.exitSpatialIndex.get(r);h||(h=new Set,this.exitSpatialIndex.set(r,h)),h.add(t)})}collectRoomCandidates(t,s,e,i){const o=this.bufferRoomCandidates;return o.clear(),this.forEachBucket(t,s,e,i,n=>{this.roomSpatialIndex.get(n)?.forEach(h=>o.add(h))}),o}collectStandaloneExitCandidates(t,s,e,i){const o=this.bufferExitCandidates;return o.clear(),this.forEachBucket(t,s,e,i,n=>{this.exitSpatialIndex.get(n)?.forEach(h=>o.add(h))}),o}refreshStandaloneExitBoundsIfNeeded(){this.standaloneExitBoundsRoomSize!==this.settings.roomSize&&(this.exitSpatialIndex.clear(),this.standaloneExitNodes.forEach(t=>{this.addStandaloneExitToSpatialIndex(t)}),this.standaloneExitBoundsRoomSize=this.settings.roomSize)}emitRoomContextEvent(t,s,e){const i=this.stage.container(),o=i.getBoundingClientRect(),n={roomId:t,position:{x:s-o.left,y:e-o.top}},r=new CustomEvent("roomcontextmenu",{detail:n});i.dispatchEvent(r)}emitRoomClickEvent(t,s,e){const i=this.stage.container(),o=i.getBoundingClientRect(),n={roomId:t,position:{x:s-o.left,y:e-o.top}},r=new CustomEvent("roomclick",{detail:n});i.dispatchEvent(r)}findAreaExitAtClientPoint(t,s){const e=this.clientToMapPoint(t,s);if(!e)return null;for(const i of this.areaExitHitZones){const o=i.bounds,n=this.settings.roomSize*.5;if(e.x>=o.x-n&&e.x<=o.x+o.width+n&&e.y>=o.y-n&&e.y<=o.y+o.height+n)return i}return null}emitAreaExitClickEvent(t,s,e){const i=this.stage.container(),o=i.getBoundingClientRect(),n={targetRoomId:t,position:{x:s-o.left,y:e-o.top}},r=new CustomEvent("areaexitclick",{detail:n});i.dispatchEvent(r)}emitZoomChangeEvent(){const t=new CustomEvent("zoom",{detail:{zoom:this.currentZoom}});this.stage.container().dispatchEvent(t)}emitPanEvent(){const t=new CustomEvent("pan",{detail:this.getViewportBounds()});this.stage.container().dispatchEvent(t)}emitMapClickEvent(){const t=new CustomEvent("mapclick");this.stage.container().dispatchEvent(t)}setZoom(t){const s=Math.max(this.minZoom,Math.min(5,t));return this.currentZoom===s?!1:(this.currentZoom=s,this.stage.scale({x:j*this.currentZoom,y:j*this.currentZoom}),this.scheduleRoomCulling(),this.emitPanEvent(),!0)}zoomToCenter(t){const s=Math.max(this.minZoom,Math.min(5,t));if(this.currentZoom===s)return!1;const e=this.stage.scaleX(),i=this.stage.width(),o=this.stage.height(),n=i/2,r=o/2,h={x:(n-this.stage.x())/e,y:(r-this.stage.y())/e};this.currentZoom=s;const a=j*s;this.stage.scale({x:a,y:a});const c={x:n-h.x*a,y:r-h.y*a};return this.stage.position(c),this.stage.batchDraw(),this.scheduleRoomCulling(),!0}getZoom(){return this.currentZoom}getViewportBounds(){const t=this.stage.scaleX(),s=this.stage.position();return{minX:(0-s.x)/t,maxX:(this.stage.width()-s.x)/t,minY:(0-s.y)/t,maxY:(this.stage.height()-s.y)/t}}getAreaBounds(){if(!this.currentAreaInstance||this.currentZIndex===void 0)return null;const t=this.currentAreaInstance.getPlane(this.currentZIndex);if(!t)return null;const s=this.getEffectiveBounds(this.currentAreaInstance,t),e=this.settings.areaName&&this.currentAreaInstance.getAreaName();return{minX:e?s.minX-4:s.minX,maxX:s.maxX,minY:e?s.minY-7:s.minY,maxY:s.maxY}}fitArea(){if(this.currentArea===void 0||this.currentZIndex===void 0||!this.currentAreaInstance)return;const t=this.currentAreaInstance.getPlane(this.currentZIndex);if(!t)return;const s=this.getEffectiveBounds(this.currentAreaInstance,t),e=this.settings.areaName&&this.currentAreaInstance.getAreaName(),i=e?s.minY-7:s.minY,o=e?s.minX-4:s.minX,n=s.maxX-o,r=s.maxY-i;if(n<=0||r<=0)return;const h=this.stage.width(),a=this.stage.height(),c=2,l=h/((n+c*2)*j),d=a/((r+c*2)*j),g=Math.min(l,d);this.currentZoom=Math.max(.05,Math.min(5,g)),this.minZoom=this.currentZoom;const u=j*this.currentZoom;this.stage.scale({x:u,y:u});const f=(o+s.maxX)/2,y=(i+s.maxY)/2;this.stage.position({x:h/2-f*u,y:a/2-y*u}),this.stage.batchDraw(),this.scheduleRoomCulling()}setCullingMode(t){this.settings.cullingMode=t,this.settings.cullingEnabled=t!=="none",this.scheduleRoomCulling()}getCullingMode(){return this.settings.cullingMode}getCurrentArea(){return this.currentArea?this.mapReader.getArea(this.currentArea):void 0}refreshCurrentRoomOverlay(){if(this.currentRoomId!==void 0){const t=this.mapReader.getRoom(this.currentRoomId);t&&this.updateCurrentRoomOverlay(t)}}updateBackground(){this.stage.container().style.backgroundColor=this.settings.backgroundColor}refresh(){this.updateBackground(),this.currentArea!==void 0&&this.currentZIndex!==void 0&&(this.drawArea(this.currentArea,this.currentZIndex),this.currentRoomId!==void 0&&this.setPosition(this.currentRoomId))}updatePositionMarker(t){const s=this.mapReader.getRoom(t);if(!s)return;if(s.area!==this.currentArea||s.z!==this.currentZIndex){this.positionRender&&(this.positionRender.hide(),this.positionLayer.batchDraw());return}this.currentRoomId=t,this.updateCurrentRoomOverlay(s);const e=Q(this.settings.playerMarker.strokeColor,this.settings.playerMarker.strokeAlpha),i=Q(this.settings.playerMarker.fillColor,this.settings.playerMarker.fillAlpha),o=this.settings.roomSize/2*this.settings.playerMarker.sizeFactor;this.positionRender?(this.positionRender.position({x:s.x,y:s.y}),this.positionRender.radius(o),this.positionRender.stroke(e),this.positionRender.fill(i),this.positionRender.strokeWidth(this.settings.playerMarker.strokeWidth),this.positionRender.dash(this.settings.playerMarker.dash??[]),this.positionRender.dashEnabled(this.settings.playerMarker.dashEnabled),this.positionRender.show()):(this.positionRender=new b.Circle({x:s.x,y:s.y,radius:o,stroke:e,fill:i,strokeWidth:this.settings.playerMarker.strokeWidth,dash:this.settings.playerMarker.dash,dashEnabled:this.settings.playerMarker.dashEnabled}),this.positionLayer.add(this.positionRender)),this.positionLayer.batchDraw()}setPosition(t,s=!0){const e=this.mapReader.getRoom(t);if(!e)return;const i=this.mapReader.getArea(e.area),o=i?.getVersion();let n=this.currentArea!==e.area||this.currentZIndex!==e.z;(this.currentArea!==e.area||this.currentZIndex!==e.z||o!==void 0&&this.currentAreaVersion!==o||i!==void 0&&this.currentAreaInstance!==i)&&this.drawArea(e.area,e.z),s?this.centerOnRoom(e,n):this.currentRoomId=t,this.updateCurrentRoomOverlay(e);const r=Q(this.settings.playerMarker.strokeColor,this.settings.playerMarker.strokeAlpha),h=Q(this.settings.playerMarker.fillColor,this.settings.playerMarker.fillAlpha),a=this.settings.roomSize/2*this.settings.playerMarker.sizeFactor;this.positionRender?(this.positionRender.radius(a),this.positionRender.stroke(r),this.positionRender.fill(h),this.positionRender.strokeWidth(this.settings.playerMarker.strokeWidth),this.positionRender.dash(this.settings.playerMarker.dash??[]),this.positionRender.dashEnabled(this.settings.playerMarker.dashEnabled)):(this.positionRender=new b.Circle({x:e.x,y:e.y,radius:a,stroke:r,fill:h,strokeWidth:this.settings.playerMarker.strokeWidth,dash:this.settings.playerMarker.dash,dashEnabled:this.settings.playerMarker.dashEnabled}),this.positionLayer.add(this.positionRender))}clearPosition(){this.currentRoomId=void 0,this.positionRender&&(this.positionRender.destroy(),this.positionRender=void 0),this.positionLayer.batchDraw(),this.currentRoomOverlay.forEach(t=>t.destroy()),this.currentRoomOverlay=[],this.overlayLayer.batchDraw()}centerOn(t,s){const e=this.mapReader.getRoom(t);if(!e)return;const i=this.mapReader.getArea(e.area),o=i?.getVersion(),n=this.currentArea!==e.area||this.currentZIndex!==e.z;(n||o!==void 0&&this.currentAreaVersion!==o||i!==void 0&&this.currentAreaInstance!==i)&&this.drawArea(e.area,e.z),this.centerOnRoomView(e,s??n)}renderPath(t,s){return this.pathRenderer.renderPath(t,this.currentArea,this.currentZIndex,s)}clearPaths(){this.pathRenderer.clearPaths()}renderHighlight(t,s){const e=this.mapReader.getRoom(t);if(!e)return;const i=this.highlights.get(t);i?.shape&&(i.shape.destroy(),delete i.shape);const o={color:s,area:e.area,z:e.z};if(this.highlights.set(t,o),e.area===this.currentArea&&e.z===this.currentZIndex){const n=this.createHighlightShape(e,s);return this.overlayLayer.add(n),o.shape=n,this.overlayLayer.batchDraw(),n}return o.shape}removeHighlight(t){const s=this.highlights.get(t);s&&(s.shape?.destroy(),this.highlights.delete(t),this.overlayLayer.batchDraw())}hasHighlight(t){return this.highlights.has(t)}clearHighlights(){this.highlights.forEach(({shape:t})=>t?.destroy()),this.highlights.clear(),this.overlayLayer.batchDraw()}refreshHighlights(){this.highlights.forEach((t,s)=>{if(t.shape?.destroy(),delete t.shape,t.area!==this.currentArea||t.z!==this.currentZIndex)return;const e=this.mapReader.getRoom(s);if(!e)return;const i=this.createHighlightShape(e,t.color);this.overlayLayer.add(i),t.shape=i}),this.overlayLayer.batchDraw()}createHighlightShape(t,s){return this.settings.roomShape==="circle"?new b.Circle({x:t.x,y:t.y,radius:this.settings.roomSize/2*1.5,stroke:s,strokeWidth:.1,dash:[.05,.05],dashEnabled:!0,listening:!1}):new b.Rect({x:t.x-this.settings.roomSize/2*1.5,y:t.y-this.settings.roomSize/2*1.5,width:this.settings.roomSize*1.5,height:this.settings.roomSize*1.5,stroke:s,strokeWidth:.1,dash:[.05,.05],dashEnabled:!0,cornerRadius:this.settings.roomShape==="roundedRectangle"?this.settings.roomSize*1.5*.2:0,listening:!1})}centerOnRoom(t,s=!1){this.currentRoomId=t.id;const e={x:t.x,y:t.y};this.positionRender?.position(t);const o=this.stage.getAbsoluteTransform().point(e),n={x:this.stage.width()/2,y:this.stage.height()/2},r=n.x-o.x,h=n.y-o.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),s||this.settings.instantMapMove?(this.stage.position({x:this.stage.x()+r,y:this.stage.y()+h}),this.scheduleRoomCulling()):(this.currentTransition=new b.Tween({node:this.stage,x:this.stage.x()+r,y:this.stage.y()+h,duration:.2,easing:b.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>this.scheduleRoomCulling()}),this.currentTransition.play())}centerOnRoomView(t,s=!1){const e={x:t.x,y:t.y},o=this.stage.getAbsoluteTransform().point(e),n={x:this.stage.width()/2,y:this.stage.height()/2},r=n.x-o.x,h=n.y-o.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),s||this.settings.instantMapMove?(this.stage.position({x:this.stage.x()+r,y:this.stage.y()+h}),this.scheduleRoomCulling(),this.emitPanEvent()):(this.currentTransition=new b.Tween({node:this.stage,x:this.stage.x()+r,y:this.stage.y()+h,duration:.2,easing:b.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>{this.scheduleRoomCulling(),this.emitPanEvent()}}),this.currentTransition.play())}getEffectiveBounds(t,s){return this.settings.uniformLevelSize?t.getFullBounds():s.getBounds()}renderAreaName(t,s){if(!this.settings.areaName)return;const e=t.getAreaName();if(!e)return;const i=this.getEffectiveBounds(t,s);this.roomLayer.add(new b.Text({x:i.minX-3.5,y:i.minY-4.5,text:e,fontSize:2.5,fontFamily:this.settings.fontFamily,fill:"white",listening:!1,perfectDrawEnabled:!1}))}renderRooms(t){t.forEach(s=>{const e=new b.Group({x:s.x-this.settings.roomSize/2,y:s.y-this.settings.roomSize/2,listening:!1}),i=this.mapReader.getColorValue(s.env),o=this.settings.frameMode?this.settings.backgroundColor:i,n=this.settings.frameMode?i:this.settings.lineColor,r=this.settings.borders?this.settings.lineWidth:0,h=this.settings.roomShape==="circle"?new b.Circle({x:this.settings.roomSize/2,y:this.settings.roomSize/2,radius:this.settings.roomSize/2,fill:o,strokeWidth:r,stroke:n,perfectDrawEnabled:!1,listening:!1}):new b.Rect({x:0,y:0,width:this.settings.roomSize,height:this.settings.roomSize,fill:o,strokeWidth:r,stroke:n,cornerRadius:this.settings.roomShape==="roundedRectangle"?this.settings.roomSize*.2:0,perfectDrawEnabled:!1,listening:!1});if(e.add(h),this.settings.emboss&&this.settings.roomShape!=="circle"){const d=this.settings.roomSize,g=q(this.settings.lineColor)>.41;e.add(new b.Line({points:g?[0,0,d,0,d,d]:[0,0,0,d,d,d],stroke:g?"#000000":"#ffffff",strokeWidth:this.settings.lineWidth,perfectDrawEnabled:!1,listening:!1}))}this.renderSymbol(s,e),this.roomLayer.add(e),this.exitRenderer.renderSpecialExits(s).forEach(d=>{this.linkLayer.add(d)}),this.exitRenderer.getSpecialExitAreaTargets(s).forEach(d=>{this.areaExitHitZones.push(d)});const a=s.x-this.settings.roomSize/2,c=s.y-this.settings.roomSize/2;this.exitRenderer.renderStubs(s).forEach(d=>{const g=d.points();for(let u=0;u<g.length;u+=2)g[u]-=a,g[u+1]-=c;d.points(g),e.add(d)}),this.exitRenderer.renderInnerExits(s).forEach(d=>{d.position({x:-a,y:-c}),e.add(d)});const l={room:s,group:e};this.roomNodes.set(s.id,l),this.addRoomToSpatialIndex(l)})}scheduleRoomCulling(){this.cullingScheduled||(this.cullingScheduled=!0,window.requestAnimationFrame(()=>{this.cullingScheduled=!1,this.updateRoomCulling()}))}updateRoomCulling(){if(this.roomNodes.size===0&&this.standaloneExitNodes.length===0)return;const t=this.stage.scaleX();if(!t)return;this.syncPerfMonitor();const s=this.settings.perfCallback?performance.now():0,e=this.stage.position(),i=this.settings.roomSize/2,o=this.settings.cullingBounds,n=o?o.x:0,r=o?o.x+o.width:this.stage.width(),h=o?o.y:0,a=o?o.y+o.height:this.stage.height(),c=Math.min(n,r),l=Math.max(n,r),d=Math.min(h,a),g=Math.max(h,a),u=(c-e.x)/t,f=(l-e.x)/t,y=(d-e.y)/t,p=(g-e.y)/t;let x=!1,k=!1;const D=this.settings.cullingEnabled?this.settings.cullingMode??"indexed":"none",$=u-i,X=f+i,w=y-i,R=p+i;if(this.refreshStandaloneExitBoundsIfNeeded(),D==="none"){if(this.roomNodes.forEach(v=>{v.group.visible()||(v.group.visible(!0),x=!0)}),this.visibleExitDrawData.length!==this.standaloneExitNodes.length){this.visibleExitDrawData.length=0;for(const v of this.standaloneExitNodes)this.visibleExitDrawData.push(v.data);k=!0}x&&this.roomLayer.batchDraw(),k&&this.linkLayer.batchDraw(),this.visibleRooms.clear(),this.roomNodes.forEach(v=>this.visibleRooms.add(v)),this.visibleStandaloneExitNodes.clear(),this.standaloneExitNodes.forEach(v=>this.visibleStandaloneExitNodes.add(v));return}if(D==="basic"){const v=this.bufferRoomSet;v.clear(),this.roomNodes.forEach(P=>{const O=P.room.x-i,T=P.room.x+i,F=P.room.y-i,V=P.room.y+i,B=T>=u&&O<=f&&V>=y&&F<=p;P.group.visible()!==B&&(P.group.visible(B),x=!0),B&&v.add(P)});const z=this.bufferExitSet;z.clear();let Y=!1;this.standaloneExitNodes.forEach(P=>{const{bounds:O}=P,T=O.x,F=O.x+O.width,V=O.y,B=O.y+O.height;F>=u&&T<=f&&B>=y&&V<=p&&(z.add(P),this.visibleStandaloneExitNodes.has(P)||(Y=!0))}),!Y&&z.size!==this.visibleStandaloneExitNodes.size&&(Y=!0),this.bufferRoomSet=this.visibleRooms,this.visibleRooms=v,this.bufferExitSet=this.visibleStandaloneExitNodes,this.visibleStandaloneExitNodes=z,Y&&(this.visibleExitDrawData.length=0,this.visibleStandaloneExitNodes.forEach(P=>this.visibleExitDrawData.push(P.data)),k=!0),x&&this.roomLayer.batchDraw(),k&&this.linkLayer.batchDraw();return}const E=this.collectRoomCandidates($,w,X,R),C=this.bufferRoomSet;C.clear(),E.forEach(v=>{const z=v.room.x-i,Y=v.room.x+i,P=v.room.y-i,O=v.room.y+i,T=Y>=u&&z<=f&&O>=y&&P<=p;v.group.visible()!==T&&(v.group.visible(T),x=!0),T&&C.add(v)}),this.visibleRooms.forEach(v=>{E.has(v)||v.group.visible()&&(v.group.visible(!1),x=!0)}),this.bufferRoomSet=this.visibleRooms,this.visibleRooms=C;const S=this.collectStandaloneExitCandidates($,w,X,R),M=this.bufferExitSet;M.clear();let I=!1;S.forEach(v=>{const{bounds:z}=v,Y=z.x,P=z.x+z.width,O=z.y,T=z.y+z.height;P>=u&&Y<=f&&T>=y&&O<=p&&(M.add(v),this.visibleStandaloneExitNodes.has(v)||(I=!0))}),!I&&M.size!==this.visibleStandaloneExitNodes.size&&(I=!0),this.bufferExitSet=this.visibleStandaloneExitNodes,this.visibleStandaloneExitNodes=M,I&&(this.visibleExitDrawData.length=0,this.visibleStandaloneExitNodes.forEach(v=>this.visibleExitDrawData.push(v.data)),k=!0),x&&this.roomLayer.batchDraw(),k&&this.linkLayer.batchDraw();const W=this.settings.perfCallback?performance.now():0;if(this.renderGrid(),this.settings.perfCallback){const v=performance.now()-W,z=performance.now()-s;this.perfMonitor.record({cullingMs:z,gridMs:v,visibleRooms:this.visibleRooms.size,totalRooms:this.roomNodes.size,visibleExits:this.visibleStandaloneExitNodes.size,fps:this.perfMonitor.computeFps()})}}syncPerfMonitor(){this.perfMonitor.setCallback(this.settings.perfCallback)}invalidateGridCache(){this.cachedGridBounds=null}renderGrid(){if(!this.settings.gridEnabled){this.cachedGridBounds!==null&&(this.gridLayer.destroyChildren(),this.gridLayer.batchDraw(),this.cachedGridBounds=null);return}const t=this.stage.scaleX();if(!t)return;const s=this.stage.position(),e=this.stage.width(),i=this.stage.height(),o=(0-s.x)/t,n=(e-s.x)/t,r=(0-s.y)/t,h=(i-s.y)/t,a=this.settings.gridSize*2,c=Math.floor((Math.min(o,n)-a)/this.settings.gridSize)*this.settings.gridSize,l=Math.ceil((Math.max(o,n)+a)/this.settings.gridSize)*this.settings.gridSize,d=Math.floor((Math.min(r,h)-a)/this.settings.gridSize)*this.settings.gridSize,g=Math.ceil((Math.max(r,h)+a)/this.settings.gridSize)*this.settings.gridSize,u=this.cachedGridBounds;if(!(u&&u.left===c&&u.right===l&&u.top===d&&u.bottom===g)){this.gridLayer.destroyChildren();for(let f=c;f<=l;f+=this.settings.gridSize)this.gridLayer.add(new b.Line({points:[f,d,f,g],stroke:this.settings.gridColor,strokeWidth:this.settings.gridLineWidth,listening:!1,perfectDrawEnabled:!1}));for(let f=d;f<=g;f+=this.settings.gridSize)this.gridLayer.add(new b.Line({points:[c,f,l,f],stroke:this.settings.gridColor,strokeWidth:this.settings.gridLineWidth,listening:!1,perfectDrawEnabled:!1}));this.cachedGridBounds={left:c,right:l,top:d,bottom:g},this.gridLayer.batchDraw()}}clearCurrentRoomOverlay(){this.currentRoomOverlay.forEach(t=>t.destroy()),this.currentRoomOverlay=[],this.positionLayer.batchDraw()}updateCurrentRoomOverlay(t){if(this.clearCurrentRoomOverlay(),t.area!==this.currentArea||t.z!==this.currentZIndex){this.positionLayer.batchDraw();return}const s=new Map;s.set(t.id,t);const e=[],i=this.currentAreaInstance instanceof J?this.currentAreaInstance:void 0;this.currentAreaInstance&&this.currentZIndex!==void 0&&this.currentAreaInstance.getLinkExits(this.currentZIndex).filter(h=>h.a===t.id||h.b===t.id).forEach(h=>{const a=this.settings.highlightCurrentRoom?this.exitRenderer.renderWithColor(h,K,this.currentZIndex):this.exitRenderer.render(h,this.currentZIndex);a&&e.push(a)});const o=this.settings.highlightCurrentRoom?K:void 0;this.exitRenderer.renderSpecialExits(t,o).forEach(r=>{e.push(r)}),(this.settings.highlightCurrentRoom?this.exitRenderer.renderStubs(t,K):this.exitRenderer.renderStubs(t)).forEach(r=>{e.push(r)}),[...Object.values(t.exits),...Object.values(t.specialExits)].forEach(r=>{const h=this.mapReader.getRoom(r),a=!i||i.hasVisitedRoom(r);h&&h.area===this.currentArea&&h.z===this.currentZIndex&&a&&s.set(r,h)}),e.forEach(r=>{this.positionLayer.add(r),this.currentRoomOverlay.push(r)}),s.forEach((r,h)=>{const a=h===t.id,c=this.createOverlayRoomGroup(r,{stroke:a&&this.settings.highlightCurrentRoom?K:this.settings.lineColor});this.positionLayer.add(c),this.currentRoomOverlay.push(c),this.exitRenderer.renderInnerExits(r).forEach(l=>{this.positionLayer.add(l),this.currentRoomOverlay.push(l)})}),this.positionRender&&this.positionRender.moveToTop(),this.positionLayer.batchDraw()}createOverlayRoomGroup(t,s){const e=new b.Group({x:t.x-this.settings.roomSize/2,y:t.y-this.settings.roomSize/2,listening:!1}),i=this.mapReader.getColorValue(t.env),o=this.settings.frameMode?this.settings.backgroundColor:i,n=this.settings.frameMode?i:s.stroke,r=this.settings.borders?this.settings.lineWidth:0,h=this.settings.roomShape==="circle"?new b.Circle({x:this.settings.roomSize/2,y:this.settings.roomSize/2,radius:this.settings.roomSize/2,fill:o,stroke:n,strokeWidth:r}):new b.Rect({x:0,y:0,width:this.settings.roomSize,height:this.settings.roomSize,fill:o,stroke:n,strokeWidth:r,cornerRadius:this.settings.roomShape==="roundedRectangle"?this.settings.roomSize*.2:0});if(e.add(h),this.settings.emboss&&this.settings.roomShape!=="circle"){const a=this.settings.roomSize,c=q(this.settings.lineColor)>.41;e.add(new b.Line({points:c?[0,0,a,0,a,a]:[0,0,0,a,a,a],stroke:c?"#000000":"#ffffff",strokeWidth:this.settings.lineWidth,perfectDrawEnabled:!1,listening:!1}))}return this.renderSymbol(t,e),e}getSymbolColor(t,s){return this.settings.frameMode?this.mapReader.getColorValue(t):this.mapReader.getSymbolColor(t,s)}renderSymbol(t,s){if(t.roomChar!==void 0){const e=this.settings.roomSize*.75,i=new b.Text({x:0,y:0,text:t.roomChar,fontSize:e,fontStyle:"bold",fill:this.getSymbolColor(t.env),align:"center",verticalAlign:"middle",width:this.settings.roomSize,height:this.settings.roomSize,perfectDrawEnabled:!1,listening:!1});s.add(i)}}renderExits(t){t.forEach(s=>{const e=this.exitRenderer.renderData(s,this.currentZIndex);if(!e)return;const i={data:e,bounds:e.bounds,targetRoomId:e.targetRoomId};this.standaloneExitNodes.push(i),this.addStandaloneExitToSpatialIndex(i),e.targetRoomId!==void 0&&this.areaExitHitZones.push({bounds:e.bounds,targetRoomId:e.targetRoomId})}),this.standaloneExitBoundsRoomSize=this.settings.roomSize,this.exitBatchShape=new b.Shape({listening:!1,perfectDrawEnabled:!1,sceneFunc:s=>{const e=s._context;for(const i of this.visibleExitDrawData)this.drawExitData(e,i)}}),this.linkLayer.add(this.exitBatchShape)}drawExitData(t,s){for(const e of s.lines){t.beginPath(),t.moveTo(e.points[0],e.points[1]);for(let i=2;i<e.points.length;i+=2)t.lineTo(e.points[i],e.points[i+1]);t.strokeStyle=e.stroke,t.lineWidth=e.strokeWidth,e.dash?t.setLineDash(e.dash):t.setLineDash([]),t.stroke()}for(const e of s.arrows){t.beginPath(),t.moveTo(e.points[0],e.points[1]);for(let d=2;d<e.points.length;d+=2)t.lineTo(e.points[d],e.points[d+1]);t.strokeStyle=e.stroke,t.lineWidth=e.strokeWidth,e.dash?t.setLineDash(e.dash):t.setLineDash([]),t.stroke();const i=e.points.length-2,o=e.points[i],n=e.points[i+1],r=e.points[i-2],h=e.points[i-1],a=Math.atan2(n-h,o-r),c=e.pointerLength,l=e.pointerWidth/2;t.beginPath(),t.setLineDash([]),t.moveTo(o,n),t.lineTo(o-c*Math.cos(a-Math.atan2(l,c)),n-c*Math.sin(a-Math.atan2(l,c))),t.lineTo(o-c*Math.cos(a+Math.atan2(l,c)),n-c*Math.sin(a+Math.atan2(l,c))),t.closePath(),t.fillStyle=e.fill,t.fill(),t.strokeStyle=e.stroke,t.lineWidth=e.strokeWidth,t.stroke()}for(const e of s.doors)t.beginPath(),t.rect(e.x,e.y,e.width,e.height),t.strokeStyle=e.stroke,t.lineWidth=e.strokeWidth,t.setLineDash([]),t.stroke()}renderLabels(t){this.settings.labelRenderMode!=="none"&&t.forEach(s=>{if(this.settings.labelRenderMode==="image"){if(!s.pixMap)return;const e=new Image;e.src=`data:image/png;base64,${s.pixMap}`;const i=new b.Image({x:s.X,y:-s.Y,width:s.Width,height:s.Height,image:e,listening:!1});this.linkLayer.add(i);return}this.renderLabelAsData(s)})}renderLabelAsData(t){const s=new b.Group({listening:!1}),e=new b.Rect({x:t.X,y:-t.Y,width:t.Width,height:t.Height,listening:!1});(t.BgColor?.alpha??0)>0&&!this.settings.transparentLabels?e.fill(this.getLabelColor(t.BgColor)):e.fillEnabled(!1),s.add(e);const i=Math.min(.75,t.Width/Math.max(t.Text.length/2,1)),o=Math.max(.1,Math.min(i,Math.max(t.Height*.9,.1))),n=new b.Text({x:t.X,y:-t.Y,width:t.Width,height:t.Height,text:t.Text,fontSize:o,fillEnabled:!0,fill:this.getLabelColor(t.FgColor),align:"center",verticalAlign:"middle",listening:!1});s.add(n),this.linkLayer.add(s)}getLabelColor(t){const s=(t?.alpha??255)/255,e=i=>Math.min(255,Math.max(0,i??0));return`rgba(${e(t?.r)}, ${e(t?.g)}, ${e(t?.b)}, ${s})`}}const kt={rgbValue:"rgb(114, 1, 0)",symbolColor:[225,225,225]};function Rt(m){const t=m[0]/255,s=m[1]/255,e=m[2]/255,i=Math.max(t,s,e),o=Math.min(t,s,e);return(i+o)/2}class Qt{constructor(t,s){this.rooms={},this.areas={},this.areaSources={},this.explorationEnabled=!1,this.colors={},t.forEach(e=>{e.rooms.forEach(o=>{o.y=-o.y,this.rooms[o.id]=o});const i=parseInt(e.areaId);this.areas[i]=new _(e),this.areaSources[i]=e}),this.colors=s.reduce((e,i)=>({...e,[i.envId]:{rgb:i.colors,rgbValue:`rgb(${i.colors.join(",")})`,symbolColor:Rt(i.colors)>.41?[25,25,25]:[225,255,255],symbolColorValue:Rt(i.colors)>.41?"rgb(25,25,25)":"rgb(225,255,255)"}}),{})}getArea(t){return this.areas[t]}getExplorationArea(t){const s=this.areas[t];if(s instanceof J)return s}getAreas(){return Object.values(this.areas)}getRooms(){return Object.values(this.rooms)}getRoom(t){return this.rooms[t]}ensureVisitedRooms(){return this.visitedRooms||(this.visitedRooms=new Set),this.visitedRooms}applyExplorationDecoration(){this.visitedRooms&&Object.entries(this.areaSources).forEach(([t,s])=>{const e=parseInt(t,10);this.areas[e]=new J(s,this.visitedRooms)})}decorateWithExploration(t){return t!==void 0?this.setVisitedRooms(t):this.ensureVisitedRooms(),this.applyExplorationDecoration(),this.explorationEnabled=!0,this.visitedRooms}getVisitedRooms(){return this.visitedRooms}clearExplorationDecoration(){Object.entries(this.areaSources).forEach(([t,s])=>{const e=parseInt(t,10);this.areas[e]=new _(s)}),this.explorationEnabled=!1}isExplorationEnabled(){return this.explorationEnabled}setVisitedRooms(t){return this.visitedRooms=t instanceof Set?t:new Set(t),this.explorationEnabled&&this.applyExplorationDecoration(),this.visitedRooms}addVisitedRoom(t){if(this.explorationEnabled){const i=this.getRoom(t);if(i){const o=this.getExplorationArea(i.area);if(o)return o.addVisitedRoom(t)}}const s=this.ensureVisitedRooms(),e=s.has(t);return s.add(t),!e}addVisitedRooms(t){const s=this.ensureVisitedRooms();let e=0;for(const i of t){if(this.explorationEnabled){const n=this.getRoom(i);if(n){const r=this.getExplorationArea(n.area);if(r){r.addVisitedRoom(i)&&e++;continue}}}const o=s.has(i);s.add(i),o||e++}return e}hasVisitedRoom(t){return this.visitedRooms?.has(t)??!1}getColorValue(t){return this.colors[t]?.rgbValue??kt.rgbValue}getSymbolColor(t,s){const e=this.colors[t]?.symbolColor??kt.symbolColor,i=Math.min(Math.max(s??1,0),1),o=e.join(",");return i!=1?`rgba(${o}, ${i})`:`rgba(${o})`}}function Ut(m){return m&&m.__esModule&&Object.prototype.hasOwnProperty.call(m,"default")?m.default:m}var ht,St;function Jt(){if(St)return ht;St=1;class m{constructor(){this.keys=new Set,this.queue=[]}sort(){this.queue.sort((s,e)=>s.priority-e.priority)}set(s,e){const i=Number(e);if(isNaN(i))throw new TypeError('"priority" must be a number');return this.keys.has(s)?this.queue.map(o=>(o.key===s&&Object.assign(o,{priority:i}),o)):(this.keys.add(s),this.queue.push({key:s,priority:i})),this.sort(),this.queue.length}next(){const s=this.queue.shift();return this.keys.delete(s.key),s}isEmpty(){return this.queue.length===0}has(s){return this.keys.has(s)}get(s){return this.queue.find(e=>e.key===s)}}return ht=m,ht}var ct,Et;function te(){if(Et)return ct;Et=1;function m(t,s){const e=new Map;for(const[i,o]of t)i!==s&&o instanceof Map?e.set(i,m(o,s)):i!==s&&e.set(i,o);return e}return ct=m,ct}var lt,Mt;function ee(){if(Mt)return lt;Mt=1;function m(s){const e=Number(s);return!(isNaN(e)||e<=0)}function t(s){const e=new Map;return Object.keys(s).forEach(o=>{const n=s[o];if(n!==null&&typeof n=="object"&&!Array.isArray(n))return e.set(o,t(n));if(!m(n))throw new Error(`Could not add node at key "${o}", make sure it's a valid node`,n);return e.set(o,Number(n))}),e}return lt=t,lt}var dt,Ct;function se(){if(Ct)return dt;Ct=1;function m(t){if(!(t instanceof Map))throw new Error(`Invalid graph: Expected Map instead found ${typeof t}`);t.forEach((s,e)=>{if(typeof s=="object"&&s instanceof Map){m(s);return}if(typeof s!="number"||s<=0)throw new Error(`Values must be numbers greater than 0. Found value ${s} at ${e}`)})}return dt=m,dt}var gt,Dt;function ie(){if(Dt)return gt;Dt=1;const m=Jt(),t=te(),s=ee(),e=se();class i{constructor(n){n instanceof Map?(e(n),this.graph=n):n?this.graph=s(n):this.graph=new Map}addNode(n,r){let h;return r instanceof Map?(e(r),h=r):h=s(r),this.graph.set(n,h),this}addVertex(n,r){return this.addNode(n,r)}removeNode(n){return this.graph=t(this.graph,n),this}path(n,r,h={}){if(!this.graph.size)return h.cost?{path:null,cost:0}:null;const a=new Set,c=new m,l=new Map;let d=[],g=0,u=[];if(h.avoid&&(u=[].concat(h.avoid)),u.includes(n))throw new Error(`Starting node (${n}) cannot be avoided`);if(u.includes(r))throw new Error(`Ending node (${r}) cannot be avoided`);for(c.set(n,0);!c.isEmpty();){const f=c.next();if(f.key===r){g=f.priority;let p=f.key;for(;l.has(p);)d.push(p),p=l.get(p);break}a.add(f.key),(this.graph.get(f.key)||new Map).forEach((p,x)=>{if(a.has(x)||u.includes(x))return null;if(!c.has(x))return l.set(x,f.key),c.set(x,f.priority+p);const k=c.get(x).priority,D=f.priority+p;return D<k?(l.set(x,f.key),c.set(x,D)):null})}return d.length?(h.trim?d.shift():d=d.concat([n]),h.reverse||(d=d.reverse()),h.cost?{path:d,cost:g}:d):h.cost?{path:null,cost:0}:null}shortestPath(...n){return this.path(...n)}}return gt=i,gt}var oe=ie();const ne=Ut(oe),re={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},ae={north:"n",northeast:"ne",northwest:"nw",east:"e",west:"w",south:"s",southeast:"se",southwest:"sw",up:"up",down:"down",in:"in",out:"out"};function It(m,t){m.push(t);let s=m.length-1;for(;s>0;){const e=s-1>>1;if(m[e].priority<=m[s].priority)break;[m[e],m[s]]=[m[s],m[e]],s=e}}function he(m){if(m.length===0)return;const t=m[0],s=m.pop();if(m.length>0){m[0]=s;let e=0;const i=m.length;for(;;){let o=e;const n=2*e+1,r=2*e+2;if(n<i&&m[n].priority<m[o].priority&&(o=n),r<i&&m[r].priority<m[o].priority&&(o=r),o===e)break;[m[e],m[o]]=[m[o],m[e]],e=o}}return t}function ce(m,t,s){const e=[s];let i=s;for(;i!==t;)i=m.get(i),e.push(i);return e.reverse(),e}function le(m,t,s){const e=m.path(t.toString(),s.toString()),i=Array.isArray(e)?e:e?.path;return i?i.map(o=>Number(o)):null}function de(m,t,s,e,i,o){const n=e.getRoom(s);if(!n)return null;const r=n.x,h=n.y,a=n.z,c=u=>{const f=e.getRoom(u);if(!f)return 0;const y=f.x-r,p=f.y-h,x=f.z-a;return Math.sqrt(y*y+p*p+x*x)/i*o},l=new Map,d=new Map,g=[];for(l.set(t,0),It(g,{id:t,priority:c(t)});g.length>0;){const{id:u}=he(g);if(u===s)return ce(d,t,s);const f=l.get(u)??1/0,y=m.get(u);if(y)for(const p of y){const x=f+p.weight;x<(l.get(p.id)??1/0)&&(l.set(p.id,x),d.set(p.id,u),It(g,{id:p.id,priority:x+c(p.id)}))}}return null}class ge{constructor(t,s="dijkstra"){this.cache=new Map,this.mapReader=t,this._algorithm=s;const{adj:e,maxEdgeDistance:i,minEdgeWeight:o,graphDefinition:n}=this.buildGraph();this.adj=e,this.graph=new ne(n),this.maxEdgeDistance=i,this.minEdgeWeight=o}get algorithm(){return this._algorithm}setAlgorithm(t){t!==this._algorithm&&(this._algorithm=t,this.cache.clear())}findPath(t,s){const e=`${t}->${s}`;if(this.cache.has(e))return this.cache.get(e);if(t===s){const o=this.mapReader.getRoom(t)?[t]:null;return this.cache.set(e,o),o}if(!this.mapReader.getRoom(t)||!this.mapReader.getRoom(s))return this.cache.set(e,null),null;let i;switch(this._algorithm){case"dijkstra":i=le(this.graph,t,s);break;case"astar":i=de(this.adj,t,s,this.mapReader,this.maxEdgeDistance,this.minEdgeWeight);break}return this.cache.set(e,i),i}resolveEdgeWeight(t,s,e){const i=t.exitWeights?.[s];return i!==void 0&&i>0?i:Math.max(e.weight,1)}buildGraph(){const t=new Map,s={};let e=1,i=1/0;return this.mapReader.getRooms().forEach(o=>{const n=[],r={},h=new Set((o.exitLocks??[]).map(c=>re[c]).filter(c=>!!c)),a=new Set(o.mSpecialExitLocks??[]);Object.entries(o.exits??{}).forEach(([c,l])=>{if(h.has(c))return;const d=this.mapReader.getRoom(l);if(d){const g=ae[c]??c,u=this.resolveEdgeWeight(o,g,d);n.push({id:l,weight:u}),r[l.toString()]=u,u<i&&(i=u);const f=d.x-o.x,y=d.y-o.y,p=d.z-o.z,x=Math.sqrt(f*f+y*y+p*p);x>e&&(e=x)}}),Object.entries(o.specialExits??{}).forEach(([c,l])=>{if(a.has(l))return;const d=this.mapReader.getRoom(l);if(d){const g=this.resolveEdgeWeight(o,c,d);n.push({id:l,weight:g}),r[l.toString()]=g,g<i&&(i=g);const u=d.x-o.x,f=d.y-o.y,y=d.z-o.z,p=Math.sqrt(u*u+f*f+y*y);p>e&&(e=p)}}),t.set(o.id,n),s[o.id.toString()]=r}),isFinite(i)||(i=1),{adj:t,maxEdgeDistance:e,minEdgeWeight:i,graphDefinition:s}}}const ue={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"};function $t(){return{areaWidth:150,areaHeight:80,areaSpacing:50,fontSize:14,connectionLineWidth:2,areaFillColor:"#2a2a3e",areaStrokeColor:"#4a4a6e",textColor:"#e0e0e0",connectionColor:"#6a6a8e",highlightColor:"#ff9900"}}class fe{constructor(t,s,e){this.areaNodes=new Map,this.connectionGroups=[],this.currentZoom=1,this.domainInfo=new Map,this.domainFilter="all",this.dotsMode=!1,this.settings=e??$t(),this.stage=new b.Stage({container:t,width:t.clientWidth,height:t.clientHeight,draggable:!0}),this.backgroundLayer=new b.Layer({listening:!1}),this.stage.add(this.backgroundLayer),this.connectionLayer=new b.Layer({listening:!1}),this.stage.add(this.connectionLayer),this.areaLayer=new b.Layer,this.stage.add(this.areaLayer),this.mapReader=s,this.initScaling(),this.initResize(t)}initResize(t){new ResizeObserver(()=>{this.stage.width(t.clientWidth),this.stage.height(t.clientHeight),this.stage.batchDraw()}).observe(t)}initScaling(){this.stage.on("wheel",s=>{s.evt.preventDefault();const e=this.stage.scaleX(),i=this.stage.getPointerPosition();if(!i)return;const o={x:(i.x-this.stage.x())/e,y:(i.y-this.stage.y())/e},r=(s.evt.deltaY>0?-1:1)>0?this.currentZoom*1.1:this.currentZoom/1.1;if(this.setZoom(r)){const h=this.stage.scaleX(),a={x:i.x-o.x*h,y:i.y-o.y*h};this.stage.position(a),this.stage.batchDraw()}})}setZoom(t){const s=Math.max(.1,Math.min(5,t));return this.currentZoom===s?!1:(this.currentZoom=s,this.stage.scale({x:this.currentZoom,y:this.currentZoom}),!0)}getZoom(){return this.currentZoom}setDomainInfo(t){this.domainInfo.clear();for(const[s,e]of Object.entries(t))this.domainInfo.set(Number(s),e)}setDomainFilter(t){this.domainFilter=t}getDomainFilter(){return this.domainFilter}setBackgroundImage(t){this.backgroundConfig={url:t.url,x:t.x,y:t.y,width:t.width,height:t.height,opacity:t.opacity??.3}}clearBackgroundImage(){this.backgroundConfig=void 0,this.backgroundImage=void 0,this.backgroundLayer.destroyChildren(),this.backgroundLayer.batchDraw()}redrawBackground(){this.drawBackground()}setDotsMode(t){this.dotsMode=t}getDotsMode(){return this.dotsMode}redraw(){this.drawBackground(),this.drawConnections(),this.drawAreas(),this.stage.batchDraw()}isAreaInDomain(t){const s=this.domainInfo.get(t);if(!s)return this.domainFilter==="interdomain"||this.domainFilter==="all";switch(this.domainFilter){case"ishtar":return s.isIshtar;case"empire":return s.isEmpire;case"interdomain":return!s.isIshtar&&!s.isEmpire;case"all":return!0}}areAreasInSameDomain(t,s){const e=this.domainInfo.get(t),i=this.domainInfo.get(s);return!e||!i?!1:e.isIshtar&&i.isIshtar||e.isEmpire&&i.isEmpire?!0:!e.isIshtar&&!e.isEmpire&&!i.isIshtar&&!i.isEmpire}render(){this.analyzeConnections(),this.layoutAreas(),this.drawBackground(),this.drawConnections(),this.drawAreas(),this.centerView(),this.stage.batchDraw()}drawBackground(){if(this.backgroundLayer.destroyChildren(),!this.backgroundConfig)return;const t=new Image;t.crossOrigin="anonymous",t.onload=()=>{this.backgroundImage=new b.Image({x:this.backgroundConfig.x,y:this.backgroundConfig.y,image:t,width:this.backgroundConfig.width,height:this.backgroundConfig.height,opacity:this.backgroundConfig.opacity,listening:!1}),this.backgroundLayer.add(this.backgroundImage),this.backgroundLayer.batchDraw()},t.onerror=()=>{console.error("Failed to load background image:",this.backgroundConfig?.url)},t.src=this.backgroundConfig.url}analyzeConnections(){this.areaNodes.clear(),this.connectionGroups=[];const t=this.mapReader.getRooms(),s=this.mapReader.getAreas(),e=new Map;for(const a of s){const c=a.getAreaId(),l=a.getRooms();if(l.length===0)continue;let d=1/0,g=-1/0,u=1/0,f=-1/0,y=0;for(const k of l)k.z===0&&(y++,d=Math.min(d,k.x),g=Math.max(g,k.x),u=Math.min(u,k.y),f=Math.max(f,k.y));if(y===0)for(const k of l)d=Math.min(d,k.x),g=Math.max(g,k.x),u=Math.min(u,k.y),f=Math.max(f,k.y);const p=(d+g)/2,x=(u+f)/2;e.set(c,{minX:d,maxX:g,minY:u,maxY:f,centerX:p,centerY:x,roomCount:l.length})}let i=1;for(const a of e.values()){const c=a.maxX-a.minX,l=a.maxY-a.minY;i=Math.max(i,c,l)}const o=200,n=100,r=o/i;for(const a of s){const c=a.getAreaId(),l=e.get(c);if(!l||!this.isAreaInDomain(c))continue;const d=l.maxX-l.minX,g=l.maxY-l.minY;let u=Math.max(n,d*r),f=Math.max(n,g*r);const y=u/f;y>3?f=u/3:y<1/3&&(u=f/3),this.areaNodes.set(c,{areaId:c,name:a.getAreaName(),x:0,y:0,width:u,height:f,connections:[],roomCount:l.roomCount,realCenterX:l.centerX,realCenterY:l.centerY})}const h=new Map;for(const a of t){const c=a.area;if(!this.areaNodes.has(c))continue;const l=this.getLockedDirections(a),d=new Set(a.mSpecialExitLocks??[]);for(const[g,u]of Object.entries(a.exits??{})){if(l.has(g))continue;const f=this.mapReader.getRoom(u);if(!f||f.area===c||!this.areaNodes.has(f.area)||!this.areAreasInSameDomain(c,f.area))continue;const y=this.createConnection(a,f,g);y&&this.addConnection(h,y)}for(const[g,u]of Object.entries(a.specialExits??{})){if(d.has(u))continue;const f=this.mapReader.getRoom(u);if(!f||f.area===c||!this.areaNodes.has(f.area)||!this.areAreasInSameDomain(c,f.area))continue;const y=this.parseDirection(g),p=this.createConnection(a,f,y);p&&this.addConnection(h,p)}}for(const[a,c]of h){const[l,d]=a.split("-").map(Number),g=this.createConnectionGroup(l,d,c);this.connectionGroups.push(g);const u=this.areaNodes.get(l),f=this.areaNodes.get(d);if(u&&u.connections.push(...c),f)for(const y of c)f.connections.push({...y,fromAreaId:y.toAreaId,toAreaId:y.fromAreaId,fromRoomId:y.toRoomId,toRoomId:y.fromRoomId,direction:y.direction?Lt[y.direction]:null,fromRoomPosition:y.toRoomPosition,toRoomPosition:y.fromRoomPosition})}}getLockedDirections(t){return new Set((t.exitLocks??[]).map(s=>ue[s]).filter(s=>!!s))}createConnection(t,s,e){const i=this.toPlanarDirection(e);return{fromAreaId:t.area,toAreaId:s.area,fromRoomId:t.id,toRoomId:s.id,direction:i,fromRoomPosition:{x:t.x,y:t.y},toRoomPosition:{x:s.x,y:s.y}}}addConnection(t,s){const e=s.fromAreaId<s.toAreaId?`${s.fromAreaId}-${s.toAreaId}`:`${s.toAreaId}-${s.fromAreaId}`;t.has(e)||t.set(e,[]),t.get(e).push(s)}createConnectionGroup(t,s,e){const i=new Map;let o=0,n=0;for(const a of e)a.direction&&i.set(a.direction,(i.get(a.direction)??0)+1),o+=a.toRoomPosition.x-a.fromRoomPosition.x,n+=a.toRoomPosition.y-a.fromRoomPosition.y;let r=null,h=0;for(const[a,c]of i)c>h&&(h=c,r=a);return{fromAreaId:t,toAreaId:s,connections:e,primaryDirection:r,averageOffset:{x:o/e.length,y:n/e.length}}}parseDirection(t){const s=t.toLowerCase().trim();return{n:"north",north:"north",s:"south",south:"south",e:"east",east:"east",w:"west",west:"west",ne:"northeast",northeast:"northeast",nw:"northwest",northwest:"northwest",se:"southeast",southeast:"southeast",sw:"southwest",southwest:"southwest",u:"up",up:"up",d:"down",down:"down",i:"in",in:"in",o:"out",out:"out"}[s]??null}toPlanarDirection(t){return t&&ut.includes(t)?t:null}layoutAreas(){if(Array.from(this.areaNodes.values()).length===0)return;const s=this.findConnectedComponents();let e=0;const i=this.settings.areaWidth*3;for(const o of s)if(o.length===1){const n=this.areaNodes.get(o[0]);n&&(n.x=e,n.y=0),e+=this.settings.areaWidth+i}else{const n=this.forceDirectedLayout(o);for(const h of o){const a=this.areaNodes.get(h);a&&isFinite(n.minX)&&isFinite(n.minY)&&(a.x-=n.minX,a.x+=e,a.y-=n.minY)}const r=isFinite(n.maxX-n.minX)?n.maxX-n.minX:this.settings.areaWidth;e+=r+i}}findConnectedComponents(){const t=new Set,s=[];for(const[e]of this.areaNodes){if(t.has(e))continue;const i=[],o=[e];for(;o.length>0;){const n=o.shift();if(t.has(n))continue;t.add(n),i.push(n);const r=this.areaNodes.get(n);if(r)for(const h of r.connections)t.has(h.toAreaId)||o.push(h.toAreaId)}s.push(i)}return s}forceDirectedLayout(t){const s=new Map;for(const w of t){const R=this.areaNodes.get(w);if(!R)continue;const E=new Set(R.connections.map(C=>C.toAreaId));s.set(w,E)}const e=new Set,i=new Set;for(const[w,R]of s)R.size>=3&&e.add(w);for(const[w,R]of s){if(e.has(w)||i.has(w)||R.size>2)continue;const E=[w];i.add(w);const C=Array.from(R);for(const M of C){let I=M,W=w;for(;I&&!i.has(I)&&!e.has(I);){const v=s.get(I);if(!v)break;if(v.size>=3){e.add(I);break}E.push(I),i.add(I);let z=!1;for(const Y of v)if(Y!==W&&!i.has(Y)){W=I,I=Y,z=!0;break}if(!z)break}}let S=!1;for(const M of E){const I=s.get(M);if(I){for(const W of I)if(e.has(W)){S=!0;break}}if(S)break}if(!S&&E.length>0){let M=E[0],I=s.get(E[0])?.size??0;for(const W of E){const v=s.get(W)?.size??0;v>I&&(I=v,M=W)}e.add(M),i.delete(M)}}for(const w of t){const R=s.get(w);(!R||R.size===0)&&e.add(w)}const o=new Map,n=new Map;for(const w of e)o.set(w,w),n.set(w,[]);const r=new Set(e);for(const w of e){const R=s.get(w)??new Set;for(const E of R){if(r.has(E))continue;const C=[];let S=E,M=w;for(;S&&!r.has(S);){C.push(S),o.set(S,w),r.add(S);const I=s.get(S)??new Set;let W;for(const v of I)if(v!==M&&!r.has(v)){W=v;break}M=S,S=W}C.length>0&&n.get(w).push(C)}}const h=new Set,a=[],c=e.values().next().value,l=c!==void 0?c:t[0];if(l!==void 0){const w=this.areaNodes.get(l);w&&(w.x=0,w.y=0,h.add(l),a.push(l))}for(;a.length>0;){const w=a.shift(),R=this.areaNodes.get(w),E=new Map;for(const C of R.connections){const S=C.toAreaId;if(h.has(S)||!e.has(S))continue;const M=this.areaNodes.get(S);if(!M)continue;const I=C.direction??"none";E.has(I)||E.set(I,[]),E.get(I).push({id:S,node:M,conn:C})}for(const[C,S]of E){const M=this.getDirectionOffset(C==="none"?null:C);S.sort((v,z)=>Math.abs(M.x)>Math.abs(M.y)?z.node.realCenterY-v.node.realCenterY:v.node.realCenterX-z.node.realCenterX);const I=this.settings.areaWidth+this.settings.areaSpacing,W=this.settings.areaHeight+this.settings.areaSpacing;S.forEach((v,z)=>{if(v.node.x=R.x+M.x*I,v.node.y=R.y+M.y*W,S.length>1){const Y=(z-(S.length-1)/2)*.5;Math.abs(M.x)>Math.abs(M.y)?v.node.y+=Y*W:v.node.x+=Y*I}h.add(v.id),a.push(v.id)})}}const d=Array.from(e);d.length>1&&this.applyForces(d,80);const g=this.settings.areaWidth+this.settings.areaSpacing+30,u=this.settings.areaHeight+this.settings.areaSpacing+30,f=new Map,y=["east","west","north","south","northeast","northwest","southeast","southwest"];for(const[w,R]of n){const E=this.areaNodes.get(w);if(!E)continue;let C=0;const S=new Map;for(const M of R){let I=w,W=E.x,v=E.y,z=null;for(const Y of M){const P=this.areaNodes.get(Y);if(!P)continue;const O=this.areaNodes.get(I);let T=null;if(O){for(const B of O.connections)if(B.toAreaId===Y){T=B.direction;break}}!T&&I===w?(z=y[C%y.length],C++,T=z):!T&&z&&(T=z);const F=this.getDirectionOffset(T);let V=0;if(I===w&&T){const B=T,rt=S.get(B)??0;S.set(B,rt+1),V=rt}P.x=W+F.x*g,P.y=v+F.y*u,V>0&&(F.x!==0&&F.y===0?P.y+=V*u*1.2:F.y!==0&&F.x===0?P.x+=V*g*1.2:(P.x+=V*g*1.2,P.y-=V*u*1.2)),f.set(Y,{dx:P.x-E.x,dy:P.y-E.y,hubId:w}),I=Y,W=P.x,v=P.y}}}const p=new Map,x=new Map;for(const w of e){const R=this.areaNodes.get(w);if(!R)continue;let E=R.x,C=R.y,S=R.x+R.width,M=R.y+R.height;const I=n.get(w)??[];for(const W of I)for(const v of W){const z=this.areaNodes.get(v);z&&(E=Math.min(E,z.x),C=Math.min(C,z.y),S=Math.max(S,z.x+z.width),M=Math.max(M,z.y+z.height))}p.set(w,{minX:E,minY:C,maxX:S,maxY:M}),x.set(w,{dx:E-R.x,dy:C-R.y})}this.applyClusterForces(d,p,x,60);for(const[w,R]of f){const E=this.areaNodes.get(w),C=this.areaNodes.get(R.hubId);!E||!C||(E.x=C.x+R.dx,E.y=C.y+R.dy)}let k=1/0,D=1/0,$=-1/0,X=-1/0;for(const w of t){const R=this.areaNodes.get(w);k=Math.min(k,R.x),D=Math.min(D,R.y),$=Math.max($,R.x+R.width),X=Math.max(X,R.y+R.height)}return{minX:k,minY:D,maxX:$,maxY:X}}getDirectionOffset(t){const s={north:{x:0,y:-1},south:{x:0,y:1},east:{x:1,y:0},west:{x:-1,y:0},northeast:{x:.75,y:-.75},northwest:{x:-.75,y:-.75},southeast:{x:.75,y:.75},southwest:{x:-.75,y:.75}};return t&&s[t]?s[t]:{x:1,y:0}}applyClusterForces(t,s,e,i){const r=new Map;for(const h of t)r.set(h,{vx:0,vy:0});for(let h=0;h<i;h++){for(const a of t){const c=this.areaNodes.get(a),l=s.get(a),d=e.get(a);if(!c||!l||!d)continue;const g=l.maxX-l.minX,u=l.maxY-l.minY;l.minX=c.x+d.dx,l.minY=c.y+d.dy,l.maxX=l.minX+g,l.maxY=l.minY+u}for(const a of t){const c=this.areaNodes.get(a),l=r.get(a),d=s.get(a);if(!(!c||!l||!d)){for(const g of t){if(a===g)continue;const u=s.get(g);if(!u)continue;const f=(d.minX+d.maxX)/2,y=(d.minY+d.maxY)/2,p=(u.minX+u.maxX)/2,x=(u.minY+u.maxY)/2,k=f-p,D=y-x,$=(d.maxX-d.minX)/2,X=(d.maxY-d.minY)/2,w=(u.maxX-u.minX)/2,R=(u.maxY-u.minY)/2,E=$+w+50,C=X+R+50,S=E-Math.abs(k),M=C-Math.abs(D);if(S>0&&M>0)if(S<M){const I=S*(k>=0?1:-1)*.5;l.vx+=I}else{const I=M*(D>=0?1:-1)*.5;l.vy+=I}}for(const g of c.connections){const u=this.areaNodes.get(g.toAreaId);if(!u||!t.includes(g.toAreaId))continue;const f=u.x-c.x,y=u.y-c.y,p=Math.sqrt(f*f+y*y)||1,x=this.settings.areaWidth+this.settings.areaSpacing+50,D=(p-x)*.015;l.vx+=f/p*D,l.vy+=y/p*D}}}for(const a of t){const c=this.areaNodes.get(a),l=r.get(a);!c||!l||(c.x+=l.vx,c.y+=l.vy,l.vx*=.8,l.vy*=.8)}}}applyForces(t,s){const o=this.settings.areaWidth+this.settings.areaSpacing,n=this.settings.areaWidth/2+60,r=new Set(t),h=[],a=new Set;for(const l of t){const d=this.areaNodes.get(l);if(d)for(const g of d.connections){if(!r.has(g.toAreaId))continue;const u=Math.min(l,g.toAreaId)+"-"+Math.max(l,g.toAreaId);a.has(u)||(a.add(u),h.push({from:l,to:g.toAreaId}))}}const c=new Map;for(const l of t)c.set(l,{vx:0,vy:0});for(let l=0;l<s;l++){for(const d of t){const g=this.areaNodes.get(d),u=c.get(d);if(!g||!u)continue;const f=g.x+g.width/2,y=g.y+g.height/2;for(const p of t){if(d===p)continue;const x=this.areaNodes.get(p);if(!x)continue;const k=(g.width+x.width)/2+20,D=(g.height+x.height)/2+20,$=g.x+g.width/2,X=g.y+g.height/2,w=x.x+x.width/2,R=x.y+x.height/2,E=$-w,C=X-R,S=k-Math.abs(E),M=D-Math.abs(C);S>0&&M>0&&(S<M?u.vx+=(E>=0?1:-1)*S*.5:u.vy+=(C>=0?1:-1)*M*.5)}for(const p of h){if(p.from===d||p.to===d)continue;const x=this.areaNodes.get(p.from),k=this.areaNodes.get(p.to);if(!x||!k)continue;const D=x.x+x.width/2,$=x.y+x.height/2,X=k.x+k.width/2,w=k.y+k.height/2,R=this.closestPointOnSegment(f,y,D,$,X,w),E=f-R.x,C=y-R.y,S=Math.sqrt(E*E+C*C)||1;if(S<n){const M=(n-S)*.6;u.vx+=E/S*M,u.vy+=C/S*M}}for(const p of g.connections){if(!r.has(p.toAreaId))continue;const x=this.areaNodes.get(p.toAreaId);if(!x)continue;const k=x.x-g.x,D=x.y-g.y,$=Math.sqrt(k*k+D*D)||1,w=($-o)*.03;u.vx+=k/$*w,u.vy+=D/$*w;const R=this.getDirectionOffset(p.direction),E=g.x+R.x*o,C=g.y+R.y*o,S=c.get(p.toAreaId);S&&(S.vx+=(E-x.x)*.01,S.vy+=(C-x.y)*.01)}}for(const d of t){const g=this.areaNodes.get(d),u=c.get(d);!g||!u||(g.x+=u.vx,g.y+=u.vy,u.vx*=.8,u.vy*=.8)}}}closestPointOnSegment(t,s,e,i,o,n){const r=o-e,h=n-i,a=t-e,c=s-i,l=r*r+h*h;if(l===0)return{x:e,y:i};let d=(a*r+c*h)/l;return d=Math.max(0,Math.min(1,d)),{x:e+d*r,y:i+d*h}}edgesIntersect(t,s,e,i,o,n,r,h){const a=(c,l,d,g,u,f)=>(f-l)*(d-c)>(g-l)*(u-c);return a(t,s,o,n,r,h)!==a(e,i,o,n,r,h)&&a(t,s,e,i,o,n)!==a(t,s,e,i,r,h)}drawConnections(){this.connectionLayer.destroyChildren();for(const t of this.connectionGroups){const s=this.areaNodes.get(t.fromAreaId),e=this.areaNodes.get(t.toAreaId);if(!s||!e||!isFinite(s.x)||!isFinite(s.y)||!isFinite(e.x)||!isFinite(e.y))continue;const i={x:s.x+s.width/2,y:s.y+s.height/2},o={x:e.x+e.width/2,y:e.y+e.height/2};let n,r;if(this.dotsMode?(n=i,r=o):(n=this.getEdgePoint(s,o),r=this.getEdgePoint(e,i)),!isFinite(n.x)||!isFinite(n.y)||!isFinite(r.x)||!isFinite(r.y))continue;const h=this.dotsMode?"#ffffff":this.settings.connectionColor,a=this.dotsMode?1:Math.min(this.settings.connectionLineWidth,1+t.connections.length*.5),c=new b.Line({points:[n.x,n.y,r.x,r.y],stroke:h,strokeWidth:a,lineCap:"round",listening:!1});this.connectionLayer.add(c)}}getEdgePoint(t,s){const e=t.x+t.width/2,i=t.y+t.height/2,o=s.x-e,n=s.y-i,r=t.width/2,h=t.height/2;if(o===0&&n===0)return{x:e,y:i};const a=Math.abs(o),c=Math.abs(n);let l;return a/r>c/h?l=r/a:l=h/c,{x:e+o*l,y:i+n*l}}drawAreas(){this.areaLayer.destroyChildren();for(const[,t]of this.areaNodes){if(!isFinite(t.x)||!isFinite(t.y))continue;const s=t.areaId===this.highlightedArea;if(this.dotsMode){const i=t.x+t.width/2,o=t.y+t.height/2,n=new b.Group({x:i,y:o,draggable:!0}),r=new b.Circle({radius:6,fill:s?this.settings.highlightColor:"#ffffff",stroke:s?this.settings.highlightColor:"#ffffff",strokeWidth:1}),h=new b.Text({text:t.name,fontSize:10,fill:"#ffffff",x:10,y:-5});n.add(r),n.add(h),n.on("click tap",()=>{this.emitAreaClickEvent(t.areaId)}),n.on("mouseenter",()=>{this.stage.container().style.cursor="pointer",r.fill(this.settings.highlightColor),r.stroke(this.settings.highlightColor),this.areaLayer.batchDraw()}),n.on("mouseleave",()=>{this.stage.container().style.cursor="auto",r.fill(s?this.settings.highlightColor:"#ffffff"),r.stroke(s?this.settings.highlightColor:"#ffffff"),this.areaLayer.batchDraw()}),n.on("dragmove",()=>{t.x=n.x()-t.width/2,t.y=n.y()-t.height/2,this.drawConnections(),this.connectionLayer.batchDraw()}),n.on("dragstart",()=>{this.stage.container().style.cursor="grabbing"}),n.on("dragend",()=>{this.stage.container().style.cursor="pointer"}),this.areaLayer.add(n)}else{const e=new b.Group({x:t.x,y:t.y,draggable:!0}),i=new b.Rect({width:t.width,height:t.height,fill:this.settings.areaFillColor,stroke:s?this.settings.highlightColor:this.settings.areaStrokeColor,strokeWidth:s?3:2,cornerRadius:8}),o=new b.Text({text:t.name,fontSize:this.settings.fontSize,fill:this.settings.textColor,width:t.width-10,height:t.height-20,x:5,y:10,align:"center",verticalAlign:"middle",ellipsis:!0,wrap:"word"}),n=new b.Text({text:`${t.roomCount} rooms`,fontSize:10,fill:this.settings.connectionColor,width:t.width-10,x:5,y:t.height-18,align:"center"});e.add(i),e.add(o),e.add(n),e.on("click tap",()=>{this.emitAreaClickEvent(t.areaId)}),e.on("mouseenter",()=>{this.stage.container().style.cursor="pointer",i.stroke(this.settings.highlightColor),this.areaLayer.batchDraw()}),e.on("mouseleave",()=>{this.stage.container().style.cursor="auto",i.stroke(s?this.settings.highlightColor:this.settings.areaStrokeColor),this.areaLayer.batchDraw()}),e.on("dragmove",()=>{t.x=e.x(),t.y=e.y(),this.drawConnections(),this.connectionLayer.batchDraw()}),e.on("dragstart",()=>{this.stage.container().style.cursor="grabbing"}),e.on("dragend",()=>{this.stage.container().style.cursor="pointer"}),this.areaLayer.add(e)}}}centerView(){let t=1/0,s=1/0,e=-1/0,i=-1/0;for(const[,u]of this.areaNodes)t=Math.min(t,u.x),s=Math.min(s,u.y),e=Math.max(e,u.x+u.width),i=Math.max(i,u.y+u.height);if(!isFinite(t))return;const o=e-t,n=i-s,r=t+o/2,h=s+n/2,a=50,c=(this.stage.width()-a*2)/o,l=(this.stage.height()-a*2)/n,d=Math.min(c,l,1.5);this.setZoom(d);const g=this.stage.scaleX();this.stage.position({x:this.stage.width()/2-r*g,y:this.stage.height()/2-h*g})}highlightArea(t){this.highlightedArea=t,this.drawAreas(),this.stage.batchDraw()}centerOnArea(t){const s=this.areaNodes.get(t);if(!s)return;const e=this.stage.scaleX(),i=s.x+s.width/2,o=s.y+s.height/2;this.stage.position({x:this.stage.width()/2-i*e,y:this.stage.height()/2-o*e}),this.stage.batchDraw()}emitAreaClickEvent(t){const s=new CustomEvent("areaclick",{detail:{areaId:t}});this.stage.container().dispatchEvent(s)}getAreaNode(t){return this.areaNodes.get(t)}getConnectionGroups(){return this.connectionGroups}destroy(){this.stage.destroy()}}const me={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},pe=["up","down","in","out"],U={1:"rgb(10, 155, 10)",2:"rgb(226, 205, 59)",3:"rgb(155, 10, 10)"};class Pt{constructor(t,s){this.mapReader=t,this.settings=s,this.exitRenderer=new mt(t,null,s)}getSymbolColor(t,s){return this.settings.frameMode?this.mapReader.getColorValue(t):this.mapReader.getSymbolColor(t,s)}render(t,s,e,i){const o=this.mapReader.getArea(s);if(!o)throw new Error(`Area ${s} not found`);const n=o.getPlane(e);if(!n)throw new Error(`Plane z=${e} not found in area ${s}`);const r=i.padding??3,h=this.computeBounds(o,n,i.roomId,r),a=i.width/h.w,c=i.height/h.h,l=Math.min(a,c);t.save(),t.fillStyle=this.settings.backgroundColor,t.fillRect(0,0,i.width,i.height);const d=h.w*l,g=h.h*l;if(t.translate((i.width-d)/2,(i.height-g)/2),t.scale(l,l),t.translate(-h.x,-h.y),this.settings.gridEnabled){const f=(i.width-d)/2,y=(i.height-g)/2,p={x:h.x-f/l,y:h.y-y/l,w:i.width/l,h:i.height/l};this.renderGrid(t,p)}this.renderLabels(t,n.getLabels()),this.renderLinkExits(t,o,e),this.renderSpecialExits(t,n.getRooms()),this.renderStubs(t,n.getRooms()),this.renderRooms(t,n.getRooms()),this.renderInnerExits(t,n.getRooms());const u=i.overlays;if(u){if(u.paths)for(const f of u.paths)this.renderPathOverlay(t,f.locations,f.color,s,e);if(u.highlights)for(const f of u.highlights)this.renderHighlightOverlay(t,f.roomId,f.color);u.position&&this.renderPositionMarker(t,u.position.roomId)}if(this.settings.areaName){const f=o.getAreaName();if(f){const y=this.getEffectiveBounds(o,n);t.fillStyle="white",t.font=`2.5px ${this.settings.fontFamily}`,t.textAlign="left",t.textBaseline="bottom",t.fillText(f,y.minX-3.5,y.minY-2)}}t.restore()}computeBounds(t,s,e,i){if(e!==void 0){const g=this.mapReader.getRoom(e);if(!g)throw new Error(`Room ${e} not found`);return{x:g.x-i,y:g.y-i,w:i*2,h:i*2}}const o=this.getEffectiveBounds(t,s),n=this.settings.areaName?t.getAreaName():void 0,r=n?7:0,h=n?3.5:0,a=o.minX-h,c=o.minY-r,l=n?o.minX-3.5+n.length*2.5*.6:-1/0,d=Math.max(o.maxX,l);return{x:a-i,y:c-i,w:d-a+i*2,h:o.maxY-c+i*2}}getEffectiveBounds(t,s){return this.settings.uniformLevelSize?t.getFullBounds():s.getBounds()}getRoomEdgePoint(t,s,e,i){return this.settings.roomShape==="circle"?ot(t,s,e,i):this.settings.roomShape==="roundedRectangle"?it(t,s,e,i,this.settings.roomSize*.2):L(t,s,e,i)}renderGrid(t,s){const e=this.settings.gridSize,i=Math.floor(s.x/e)*e,o=Math.ceil((s.x+s.w)/e)*e,n=Math.floor(s.y/e)*e,r=Math.ceil((s.y+s.h)/e)*e;t.strokeStyle=this.settings.gridColor,t.lineWidth=this.settings.gridLineWidth,t.setLineDash([]);for(let h=i;h<=o;h+=e)t.beginPath(),t.moveTo(h,n),t.lineTo(h,r),t.stroke();for(let h=n;h<=r;h+=e)t.beginPath(),t.moveTo(i,h),t.lineTo(o,h),t.stroke()}renderLabels(t,s){for(const e of s){const i=e.X,o=-e.Y;if((e.BgColor?.alpha??0)>0&&!this.settings.transparentLabels){const n=(e.BgColor.alpha??255)/255;t.fillStyle=`rgba(${e.BgColor.r},${e.BgColor.g},${e.BgColor.b},${n})`,t.fillRect(i,o,e.Width,e.Height)}if(e.Text){const n=(e.FgColor?.alpha??255)/255;t.fillStyle=`rgba(${e.FgColor?.r??0},${e.FgColor?.g??0},${e.FgColor?.b??0},${n})`;const r=Math.min(.75,e.Width/Math.max(e.Text.length/2,1)),h=Math.max(.1,Math.min(r,Math.max(e.Height*.9,.1)));t.font=`${h}px ${this.settings.fontFamily}`,t.textAlign="center",t.textBaseline="middle",t.fillText(e.Text,i+e.Width/2,o+e.Height/2)}}}renderLinkExits(t,s,e){const i=s.getLinkExits(e);for(const o of i){const n=this.exitRenderer.renderData(o,e);n&&this.drawExitData(t,n)}}drawExitData(t,s){for(const e of s.lines){t.beginPath(),t.moveTo(e.points[0],e.points[1]);for(let i=2;i<e.points.length;i+=2)t.lineTo(e.points[i],e.points[i+1]);t.strokeStyle=e.stroke,t.lineWidth=e.strokeWidth,t.setLineDash(e.dash??[]),t.stroke()}for(const e of s.arrows){t.beginPath(),t.moveTo(e.points[0],e.points[1]);for(let d=2;d<e.points.length;d+=2)t.lineTo(e.points[d],e.points[d+1]);t.strokeStyle=e.stroke,t.lineWidth=e.strokeWidth,t.setLineDash(e.dash??[]),t.stroke();const i=e.points.length-2,o=e.points[i],n=e.points[i+1],r=e.points[i-2],h=e.points[i-1],a=Math.atan2(n-h,o-r),c=e.pointerLength,l=e.pointerWidth/2;t.beginPath(),t.setLineDash([]),t.moveTo(o,n),t.lineTo(o-c*Math.cos(a-Math.atan2(l,c)),n-c*Math.sin(a-Math.atan2(l,c))),t.lineTo(o-c*Math.cos(a+Math.atan2(l,c)),n-c*Math.sin(a+Math.atan2(l,c))),t.closePath(),t.fillStyle=e.fill,t.fill(),t.strokeStyle=e.stroke,t.lineWidth=e.strokeWidth,t.stroke()}for(const e of s.doors)t.beginPath(),t.rect(e.x,e.y,e.width,e.height),t.strokeStyle=e.stroke,t.lineWidth=e.strokeWidth,t.setLineDash([]),t.stroke()}renderStubs(t,s){t.strokeStyle=this.settings.lineColor,t.lineWidth=this.settings.lineWidth,t.setLineDash([]);for(const e of s)for(const i of e.stubs){const o=me[i];if(!o)continue;const n=this.getRoomEdgePoint(e.x,e.y,o,this.settings.roomSize/2),r=L(e.x,e.y,o,this.settings.roomSize/2+.5);t.beginPath(),t.moveTo(n.x,n.y),t.lineTo(r.x,r.y),t.stroke()}}renderSpecialExits(t,s){for(const e of s)for(const[i,o]of Object.entries(e.customLines)){const n=[e.x,e.y];for(const a of o.points)n.push(a.x,-a.y);const r=`rgb(${o.attributes.color.r}, ${o.attributes.color.g}, ${o.attributes.color.b})`;t.strokeStyle=r,t.lineWidth=this.settings.lineWidth,o.attributes.style==="dot line"?t.setLineDash([.05,.05]):o.attributes.style==="dash line"?t.setLineDash([.4,.2]):t.setLineDash([]),t.beginPath(),t.moveTo(n[0],n[1]);for(let a=2;a<n.length;a+=2)t.lineTo(n[a],n[a+1]);if(t.stroke(),o.attributes.arrow&&n.length>=4){const a=n.length-2,c=n[a],l=n[a+1],d=n[a-2],g=n[a-1],u=Math.atan2(l-g,c-d),f=.3,y=.1;t.beginPath(),t.setLineDash([]),t.moveTo(c,l),t.lineTo(c-f*Math.cos(u-Math.atan2(y,f)),l-f*Math.sin(u-Math.atan2(y,f))),t.lineTo(c-f*Math.cos(u+Math.atan2(y,f)),l-f*Math.sin(u+Math.atan2(y,f))),t.closePath(),t.fillStyle=r,t.fill()}const h=e.doors[i];if(h&&n.length>=4){const a=n[0]+(n[2]-n[0])/2,c=n[1]+(n[3]-n[1])/2,l=this.settings.roomSize/2;t.beginPath(),t.rect(a-l/2,c-l/2,l,l),t.strokeStyle=U[h]??U[3],t.lineWidth=this.settings.lineWidth,t.setLineDash([]),t.stroke()}}}renderRooms(t,s){const e=this.settings.roomSize,i=e/2;for(const o of s){const n=this.mapReader.getColorValue(o.env),r=this.settings.frameMode?this.settings.backgroundColor:n,h=this.settings.frameMode?n:this.settings.lineColor;if(t.fillStyle=r,t.strokeStyle=h,t.lineWidth=this.settings.lineWidth,t.setLineDash([]),this.settings.roomShape==="circle")t.beginPath(),t.arc(o.x,o.y,i,0,Math.PI*2),t.fill(),t.stroke();else{const a=o.x-i,c=o.y-i,l=this.settings.roomShape==="roundedRectangle"?e*.2:0;if(l>0?(this.roundRect(t,a,c,e,e,l),t.fill(),t.stroke()):(t.fillRect(a,c,e,e),t.strokeRect(a,c,e,e)),this.settings.emboss){const d=q(this.settings.lineColor)>.41;t.beginPath(),d?(t.moveTo(a,c),t.lineTo(a+e,c),t.lineTo(a+e,c+e)):(t.moveTo(a,c),t.lineTo(a,c+e),t.lineTo(a+e,c+e)),t.strokeStyle=d?"#000000":"#ffffff",t.lineWidth=this.settings.lineWidth,t.stroke()}}if(o.roomChar){const a=this.getSymbolColor(o.env),c=e*.75;t.fillStyle=a,t.font=`bold ${c}px ${this.settings.fontFamily}`,t.textAlign="left",t.textBaseline="alphabetic";const l=t.measureText(o.roomChar);t.fillText(o.roomChar,o.x-l.width/2,o.y+c*.35)}}}roundRect(t,s,e,i,o,n){t.beginPath(),t.moveTo(s+n,e),t.lineTo(s+i-n,e),t.arcTo(s+i,e,s+i,e+n,n),t.lineTo(s+i,e+o-n),t.arcTo(s+i,e+o,s+i-n,e+o,n),t.lineTo(s+n,e+o),t.arcTo(s,e+o,s,e+o-n,n),t.lineTo(s,e+n),t.arcTo(s,e,s+n,e,n),t.closePath()}renderInnerExits(t,s){const e=this.settings.roomSize,i=e/5;for(const o of s)for(const n of pe){if(!o.exits[n])continue;const r=this.getSymbolColor(o.env),h=this.getSymbolColor(o.env,.6),a=o.doors[n],c=a!==void 0?U[a]??U[3]:r;switch(n){case"up":{const l=L(o.x,o.y,"south",e/4);this.drawTriangle(t,l.x,l.y,i,0,h,c);break}case"down":{const l=L(o.x,o.y,"north",e/4);this.drawTriangle(t,l.x,l.y,i,180,h,c);break}case"in":{const l=L(o.x,o.y,"west",e/4),d=L(o.x,o.y,"east",e/4);this.drawTriangle(t,l.x,l.y,i,90,h,c),this.drawTriangle(t,d.x,d.y,i,-90,h,c);break}case"out":{const l=L(o.x,o.y,"west",e/4),d=L(o.x,o.y,"east",e/4);this.drawTriangle(t,l.x,l.y,i,-90,h,c),this.drawTriangle(t,d.x,d.y,i,90,h,c);break}}}}drawTriangle(t,s,e,i,o,n,r){const c=o*Math.PI/180;t.beginPath();for(let l=0;l<3;l++){const d=2*Math.PI*l/3-Math.PI/2;let g=Math.cos(d)*i*1.4,u=Math.sin(d)*i*.8;const f=g*Math.cos(c)-u*Math.sin(c),y=g*Math.sin(c)+u*Math.cos(c);l===0?t.moveTo(s+f,e+y):t.lineTo(s+f,e+y)}t.closePath(),t.fillStyle=n,t.fill(),t.strokeStyle=r,t.lineWidth=this.settings.lineWidth,t.stroke()}renderPathOverlay(t,s,e,i,o){const n=nt(this.mapReader,this.settings,s,i,o),r=this.settings.lineWidth;t.save(),t.globalAlpha=.8,t.lineCap="round",t.lineJoin="round",t.setLineDash([]);const h=c=>{if(!(c.length<4)){t.beginPath(),t.moveTo(c[0],c[1]);for(let l=2;l<c.length;l+=2)t.lineTo(c[l],c[l+1]);t.strokeStyle="black",t.lineWidth=r*8,t.stroke(),t.beginPath(),t.moveTo(c[0],c[1]);for(let l=2;l<c.length;l+=2)t.lineTo(c[l],c[l+1]);t.strokeStyle=e,t.lineWidth=r*4,t.stroke()}};for(const c of n.segments)h(c.points);for(const c of n.customLines)h(c.points);const a=this.settings.roomSize/5;for(const c of n.innerMarkers){const l=c.direction==="up"?0:c.direction==="down"?180:c.direction==="in"?90:-90;this.drawTriangle(t,c.room.x,c.room.y,a,l,e,"black")}t.restore()}renderHighlightOverlay(t,s,e){const i=this.mapReader.getRoom(s);if(!i)return;const o=1.5,n=this.settings.roomSize;if(t.strokeStyle=e,t.lineWidth=.1,t.setLineDash([.05,.05]),this.settings.roomShape==="circle")t.beginPath(),t.arc(i.x,i.y,n/2*o,0,Math.PI*2),t.stroke();else{const r=n*o;t.strokeRect(i.x-r/2,i.y-r/2,r,r)}t.setLineDash([])}renderPositionMarker(t,s){const e=this.mapReader.getRoom(s);if(!e)return;const i=this.settings.playerMarker,o=this.settings.roomSize*i.sizeFactor;t.save(),t.globalAlpha=i.strokeAlpha,t.strokeStyle=i.strokeColor,t.lineWidth=i.strokeWidth,t.setLineDash(i.dashEnabled&&i.dash?i.dash:[]),t.beginPath(),t.arc(e.x,e.y,o/2,0,Math.PI*2),t.stroke(),i.fillAlpha>0&&(t.globalAlpha=i.fillAlpha,t.fillStyle=i.fillColor,t.fill()),t.restore()}}class ye{constructor(t,s){this.highlights=new Map,this.paths=[],this.mapReader=t,this.settings=s??yt()}drawArea(t,s){const e=this.mapReader.getArea(t);!e||!e.getPlane(s)||(this.currentArea=t,this.currentAreaInstance=e,this.currentZIndex=s)}getCurrentArea(){return this.currentAreaInstance}setPosition(t){this.positionRoomId=t}clearPosition(){this.positionRoomId=void 0}renderPath(t,s="#66E64D"){this.paths.push({locations:t,color:s})}clearPaths(){this.paths=[]}renderHighlight(t,s){const e=this.mapReader.getRoom(t);e&&this.highlights.set(t,{color:s,area:e.area,z:e.z})}removeHighlight(t){this.highlights.delete(t)}hasHighlight(t){return this.highlights.has(t)}clearHighlights(){this.highlights.clear()}exportSvg(t){if(this.currentArea===void 0||this.currentZIndex===void 0)return;const s={...t,overlays:this.buildOverlays(t?.overlays)};return new pt(this.mapReader,this.settings).export(this.currentArea,this.currentZIndex,s)}renderToCanvas(t,s){if(this.currentArea===void 0||this.currentZIndex===void 0)return;const e={...s,overlays:this.buildOverlays(s?.overlays)};new Pt(this.mapReader,this.settings).render(t,this.currentArea,this.currentZIndex,e)}buildOverlays(t){const s={...t};if(this.positionRoomId!==void 0){const o=this.mapReader.getRoom(this.positionRoomId);o&&o.area===this.currentArea&&o.z===this.currentZIndex&&(s.position={roomId:this.positionRoomId})}const e=[...t?.highlights??[]];for(const[o,n]of this.highlights)n.area===this.currentArea&&n.z===this.currentZIndex&&e.push({roomId:o,color:n.color});e.length>0&&(s.highlights=e);const i=[...t?.paths??[]];return i.push(...this.paths),i.length>0&&(s.paths=i),s}}exports.AreaMapRenderer=fe;exports.CanvasExporter=Pt;exports.ExplorationArea=J;exports.HeadlessRenderer=ye;exports.MapReader=Qt;exports.PathFinder=ge;exports.Renderer=Kt;exports.SvgExporter=pt;exports.colorLightness=q;exports.computePathData=nt;exports.createAreaMapSettings=$t;exports.createSettings=yt;
3
- //# sourceMappingURL=index.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let l=require(`konva`);l=c(l,1);var u=[`north`,`south`,`east`,`west`,`northeast`,`northwest`,`southeast`,`southwest`],d={n:`north`,s:`south`,e:`east`,w:`west`,ne:`northeast`,nw:`northwest`,se:`southeast`,sw:`southwest`},f={north:`n`,south:`s`,east:`e`,west:`w`,northeast:`ne`,northwest:`nw`,southeast:`se`,southwest:`sw`,up:`u`,down:`d`,in:`i`,out:`o`},p={north:{x:0,y:-1},south:{x:0,y:1},east:{x:1,y:0},west:{x:-1,y:0},northeast:{x:1,y:-1},northwest:{x:-1,y:-1},southeast:{x:1,y:1},southwest:{x:-1,y:1}},m=[`north`,`south`,`east`,`west`,`northeast`,`northwest`,`southeast`,`southwest`],h={north:`south`,south:`north`,east:`west`,west:`east`,northeast:`southwest`,northwest:`southeast`,southeast:`northwest`,southwest:`northeast`};function g(e){return e?Object.prototype.hasOwnProperty.call(p,e):!1}function _(e,t,n,r=1){if(!g(n))return{x:e,y:t};let i=p[n];return{x:e+i.x*r,y:t+i.y*r}}function v(e,t,n,r=1,i=0){if(!g(n))return{x:e,y:t};let a=p[n];if(!(a.x!==0&&a.y!==0)||i<=0)return _(e,t,n,r);let o=r-i+i/Math.SQRT2;return{x:e+a.x*o,y:t+a.y*o}}function y(e,t,n,r=1){if(!g(n))return{x:e,y:t};let i=p[n],a=Math.atan2(i.y,i.x);return{x:e+Math.cos(a)*r,y:t+Math.sin(a)*r}}var b={OPEN_DOOR:`rgb(10, 155, 10)`,CLOSED_DOOR:`rgb(226, 205, 59)`,LOCKED_DOOR:`rgb(155, 10, 10)`,ONE_WAY_FILL:`rgb(155, 10, 10)`},x={1:`north`,2:`northeast`,3:`northwest`,4:`east`,5:`west`,6:`south`,7:`southeast`,8:`southwest`,9:`up`,10:`down`,11:`in`,12:`out`},S=[`up`,`down`,`in`,`out`];function C(e){switch(e){case 1:return b.OPEN_DOOR;case 2:return b.CLOSED_DOOR;default:return b.LOCKED_DOOR}}var w=class{constructor(e,t,n){this.mapReader=e,this.mapRenderer=t,this.settings=n}getRoomEdgePoint(e,t,n,r){return this.settings.roomShape===`circle`?y(e,t,n,r):this.settings.roomShape===`roundedRectangle`?v(e,t,n,r,this.settings.roomSize*.2):_(e,t,n,r)}renderData(e,t){return this.renderDataWithColor(e,this.settings.lineColor,t)}renderDataWithColor(e,t,n){let r=e.aDir&&u.includes(e.aDir),i=e.bDir&&u.includes(e.bDir);if(r&&i)return this.renderTwoWayExitData(e,t,n);if(r||i){let n=r?`a`:`b`;return this.renderOneWayExitData(e,t,n)}}renderTwoWayExitData(e,t,n){let r=this.mapReader.getRoom(e.a),i=this.mapReader.getRoom(e.b);if(!r||!i||!e.aDir||!e.bDir||r.customLines[f[e.aDir]]&&i.customLines[f[e.bDir]]||r.z!==i.z&&(n!==i.z&&r.customLines[f[e.aDir]]||n!==r.z&&i.customLines[f[e.bDir]]))return;let a=this.getRoomEdgePoint(r.x,r.y,e.aDir,this.settings.roomSize/2),o=this.getRoomEdgePoint(i.x,i.y,e.bDir,this.settings.roomSize/2),s=[a.x,a.y,o.x,o.y],c=[{points:s,stroke:t,strokeWidth:this.settings.lineWidth}],l=[],u=r.doors[f[e.aDir]]??i.doors[f[e.bDir]];if(u){let e=s[0]+(s[2]-s[0])/2,t=s[1]+(s[3]-s[1])/2;l.push({x:e-this.settings.roomSize/4,y:t-this.settings.roomSize/4,width:this.settings.roomSize/2,height:this.settings.roomSize/2,stroke:C(u),strokeWidth:this.settings.lineWidth})}let d=Math.min(s[0],s[2]),p=Math.max(s[0],s[2]),m=Math.min(s[1],s[3]),h=Math.max(s[1],s[3]),g=r.z===i.z?void 0:r.z===n?i.id:r.id;return{lines:c,arrows:[],doors:l,bounds:{x:d,y:m,width:p-d,height:h-m},targetRoomId:g}}renderOneWayExitData(e,t,n){let r=n===`a`||!n&&e.aDir,i=r?this.mapReader.getRoom(e.a):this.mapReader.getRoom(e.b),a=r?this.mapReader.getRoom(e.b):this.mapReader.getRoom(e.a),o=r?e.aDir:e.bDir;if(!o||!i||!a||!u.includes(o)||i.customLines[f[o]||o])return;if(i.area!=a.area&&o){let e=this.mapReader.getColorValue(a.env),t=this.getRoomEdgePoint(i.x,i.y,o,this.settings.roomSize/2),n=_(i.x,i.y,o,this.settings.roomSize*1.5),r=e;return{lines:[],arrows:[{points:[t.x,t.y,n.x,n.y],pointerLength:.3,pointerWidth:.3,strokeWidth:this.settings.lineWidth*1.4,stroke:r,fill:r}],doors:[],bounds:{x:Math.min(t.x,n.x),y:Math.min(t.y,n.y),width:Math.abs(n.x-t.x),height:Math.abs(n.y-t.y)},targetRoomId:a.id}}let s=a.area!==i.area||a.z!==i.z,c={x:a.x,y:a.y};s&&(c=_(i.x,i.y,o,this.settings.roomSize/2));let l=_(i.x,i.y,o,.3),d=l.x-(l.x-c.x)/2,p=l.y-(l.y-c.y)/2,m=this.getRoomEdgePoint(i.x,i.y,o,this.settings.roomSize/2),h=[m.x,m.y,c.x,c.y],g=[m.x,c.x,d],v=[m.y,c.y,p],y=Math.min(...g),x=Math.max(...g),S=Math.min(...v),C=Math.max(...v);return{lines:[{points:h,stroke:t,strokeWidth:this.settings.lineWidth,dash:[.1,.05]}],arrows:[{points:[h[0],h[1],d,p],pointerLength:.5,pointerWidth:.35,strokeWidth:this.settings.lineWidth*1.4,stroke:t,fill:b.ONE_WAY_FILL,dash:[.1,.05]}],doors:[],bounds:{x:y,y:S,width:x-y,height:C-S},...s?{targetRoomId:a.id}:{}}}render(e,t){return this.renderWithColor(e,this.settings.lineColor,t)}renderWithColor(e,t,n){let r=e.aDir&&u.includes(e.aDir),i=e.bDir&&u.includes(e.bDir);if(r&&i)return this.renderTwoWayExit(e,t,n);if(r||i){let n=r?`a`:`b`;return this.renderOneWayExit(e,t,n)}}renderTwoWayExit(e,t,n){let r=this.mapReader.getRoom(e.a),i=this.mapReader.getRoom(e.b);if(!r||!i||!e.aDir||!e.bDir||r.customLines[f[e.aDir]]&&i.customLines[f[e.bDir]]||r.z!==i.z&&(n!==i.z&&r.customLines[f[e.aDir]]||n!==r.z&&i.customLines[f[e.bDir]]))return;let a=new l.default.Group({listening:!1}),o=[];if(o.push(...Object.values(this.getRoomEdgePoint(r.x,r.y,e.aDir,this.settings.roomSize/2))),o.push(...Object.values(this.getRoomEdgePoint(i.x,i.y,e.bDir,this.settings.roomSize/2))),r.doors[f[e.aDir]]||i.doors[f[e.bDir]]){let t=this.renderDoor(o,r.doors[f[e.aDir]]??i.doors[f[e.bDir]]);a.add(t)}let s=new l.default.Line({points:o,stroke:t,strokeWidth:this.settings.lineWidth,perfectDrawEnabled:!1,listening:!1});return a.add(s),a}renderOneWayExit(e,t,n){let r=n===`a`||!n&&e.aDir,i=r?this.mapReader.getRoom(e.a):this.mapReader.getRoom(e.b),a=r?this.mapReader.getRoom(e.b):this.mapReader.getRoom(e.a),o=r?e.aDir:e.bDir;if(!o||!i||!a||!u.includes(o)||i.customLines[f[o]||o])return;if(i.area!=a.area&&o){let e=this.mapReader.getColorValue(a.env);return this.renderAreaExit(i,o,e)}let s={x:a.x,y:a.y};(a.area!==i.area||a.z!==i.z)&&(s=_(i.x,i.y,o,this.settings.roomSize/2));let c=_(i.x,i.y,o,.3),d=c.x-(c.x-s.x)/2,p=c.y-(c.y-s.y)/2,m=new l.default.Group({listening:!1}),h=[];h.push(...Object.values(this.getRoomEdgePoint(i.x,i.y,o,this.settings.roomSize/2))),h.push(s.x,s.y);let g=new l.default.Line({points:h,stroke:t,strokeWidth:this.settings.lineWidth,dashEnabled:!0,dash:[.1,.05],perfectDrawEnabled:!1,listening:!1});m.add(g);let v=new l.default.Arrow({points:[h[0],h[1],d,p],pointerLength:.5,pointerWidth:.35,strokeWidth:this.settings.lineWidth*1.4,stroke:t,fill:b.ONE_WAY_FILL,dashEnabled:!0,dash:[.1,.05],perfectDrawEnabled:!1,listening:!1});return m.add(v),m}renderAreaExit(e,t,n){let r=this.getRoomEdgePoint(e.x,e.y,t,this.settings.roomSize/2),i=_(e.x,e.y,t,this.settings.roomSize*1.5),a=n??this.mapReader.getColorValue(e.env);return new l.default.Arrow({points:[r.x,r.y,i.x,i.y],pointerLength:.3,pointerWidth:.3,strokeWidth:this.settings.lineWidth*1.4,stroke:a,fill:a,perfectDrawEnabled:!1,listening:!1})}renderSpecialExits(e,t){return Object.entries(e.customLines).flatMap(([n,r])=>{let i=[e.x,e.y];r.points.reduce((e,t)=>(e.push(t.x,-t.y),e),i);let a=r.attributes.arrow?l.default.Arrow:l.default.Line,o=t??`rgb(${r.attributes.color.r}, ${r.attributes.color.g}, ${r.attributes.color.b})`,s=new a({points:i,strokeWidth:this.settings.lineWidth,stroke:o,fill:t??`rgb(${r.attributes.color.r}, ${r.attributes.color.g} , ${r.attributes.color.b})`,pointerLength:.3,pointerWidth:.2,perfectDrawEnabled:!1,listening:!1}),c=r.attributes.style;c===`dot line`?(s.dash([.05,.05]),s.dashOffset(.1)):c===`dash line`?s.dash([.4,.2]):c===`solid line`||c!==void 0&&console.log(`Brak opisu stylu: `+c);let u=[s],d=e.doors[n];return d&&i.length>=4&&u.push(this.renderDoor(i,d)),u})}getSpecialExitAreaTargets(e){let t=[];for(let[n,r]of Object.entries(e.customLines)){let i=e.specialExits[n];if(i===void 0){let t=d[n];t&&(i=e.exits[t]??e.specialExits[t])}if(i===void 0)continue;let a=this.mapReader.getRoom(i);if(!a||a.area===e.area&&a.z===e.z)continue;let o=[e.x,e.y];r.points.reduce((e,t)=>(e.push(t.x,-t.y),e),o);let s=1/0,c=1/0,l=-1/0,u=-1/0;for(let e=0;e<o.length;e+=2)s=Math.min(s,o[e]),l=Math.max(l,o[e]),c=Math.min(c,o[e+1]),u=Math.max(u,o[e+1]);t.push({bounds:{x:s,y:c,width:l-s,height:u-c},targetRoomId:i})}return t}renderStubs(e,t=this.settings.lineColor){return e.stubs.map(n=>{let r=x[n],i=this.getRoomEdgePoint(e.x,e.y,r,this.settings.roomSize/2),a=_(e.x,e.y,r,this.settings.roomSize/2+.5),o=[i.x,i.y,a.x,a.y];return new l.default.Line({points:o,stroke:t,strokeWidth:this.settings.lineWidth,perfectDrawEnabled:!1,listening:!1})})}getSymbolColor(e,t){return this.settings.frameMode?this.mapReader.getColorValue(e):this.mapReader.getSymbolColor(e,t)}renderInnerExits(e){return S.map(t=>{if(e.exits[t]){let n=new l.default.Group({listening:!1}),r=new l.default.RegularPolygon({x:e.x,y:e.y,sides:3,fill:this.getSymbolColor(e.env,.6),stroke:this.getSymbolColor(e.env),strokeWidth:this.settings.lineWidth,radius:this.settings.roomSize/5,scaleX:1.4,scaleY:.8,perfectDrawEnabled:!1,listening:!1});n.add(r);let i=e.doors[t];if(i!==void 0)switch(i){case 1:r.stroke(b.OPEN_DOOR);break;case 2:r.stroke(b.CLOSED_DOOR);break;default:r.stroke(b.LOCKED_DOOR)}let a=r.stroke();switch(t){case`up`:r.position(_(e.x,e.y,`south`,this.settings.roomSize/4));break;case`down`:r.rotation(180),r.position(_(e.x,e.y,`north`,this.settings.roomSize/4));break;case`in`:{r.rotation(90),r.position(_(e.x,e.y,`west`,this.settings.roomSize/4));let t=_(e.x,e.y,`east`,this.settings.roomSize/4);n.add(new l.default.RegularPolygon({x:t.x,y:t.y,sides:3,fill:r.fill(),stroke:a,strokeWidth:this.settings.lineWidth,radius:this.settings.roomSize/5,scaleX:1.4,scaleY:.8,rotation:-90,perfectDrawEnabled:!1,listening:!1}));break}case`out`:{r.rotation(-90),r.position(_(e.x,e.y,`west`,this.settings.roomSize/4));let t=_(e.x,e.y,`east`,this.settings.roomSize/4);n.add(new l.default.RegularPolygon({x:t.x,y:t.y,sides:3,fill:r.fill(),stroke:a,strokeWidth:this.settings.lineWidth,radius:this.settings.roomSize/5,scaleX:1.4,scaleY:.8,rotation:90,perfectDrawEnabled:!1,listening:!1}));break}}return n}}).filter(e=>e!==void 0)}renderDoor(e,t){let n={x:e[0]+(e[2]-e[0])/2,y:e[1]+(e[3]-e[1])/2};return new l.default.Rect({x:n.x-this.settings.roomSize/4,y:n.y-this.settings.roomSize/4,width:this.settings.roomSize/2,height:this.settings.roomSize/2,stroke:C(t),strokeWidth:this.settings.lineWidth,perfectDrawEnabled:!1,listening:!1})}},T=class{constructor(e,t){this.rooms=[],this.labels=[],this.rooms=e,this.labels=t,this.bounds=this.createBounds()}getRooms(){return this.rooms}getLabels(){return this.labels}getBounds(){return this.bounds}createBounds(){let e=this.rooms.reduce((e,t)=>({minX:Math.min(e.minX,t.x),maxX:Math.max(e.maxX,t.x),minY:Math.min(e.minY,t.y),maxY:Math.max(e.maxY,t.y)}),{minX:1/0,maxX:-1/0,minY:1/0,maxY:-1/0});for(let t of this.labels){let n=t.X,r=-t.Y;e.minX=Math.min(e.minX,n),e.maxX=Math.max(e.maxX,n+t.Width),e.minY=Math.min(e.minY,r),e.maxY=Math.max(e.maxY,r+t.Height)}return e}},E=class e{constructor(e){this.planes={},this.exits=new Map,this.version=0,this.area=e,this.planes=this.createPlanes(),this.createExits()}getAreaName(){return this.area.areaName}getAreaId(){return parseInt(this.area.areaId)}getVersion(){return this.version}markDirty(){this.version++}getPlane(e){return this.planes[e]}getPlanes(){return Object.values(this.planes)}getZLevels(){return Object.keys(this.planes).map(Number).sort((e,t)=>e-t)}getRooms(){return this.area.rooms}getFullBounds(){return this.getPlanes().reduce((e,t)=>{let n=t.getBounds();return{minX:Math.min(e.minX,n.minX),maxX:Math.max(e.maxX,n.maxX),minY:Math.min(e.minY,n.minY),maxY:Math.max(e.maxY,n.maxY)}},{minX:1/0,maxX:-1/0,minY:1/0,maxY:-1/0})}getLinkExits(e){return Array.from(this.exits.values()).filter(t=>t.zIndex.includes(e))}createPlanes(){let e=this.area.rooms.reduce((e,t)=>(e[t.z]||(e[t.z]=[]),e[t.z].push(t),e),{});return Object.entries(e).reduce((e,[t,n])=>(e[+t]=new T(n,this.area.labels.filter(e=>e.Z===+t)),e),{})}static{this.oppositeDir={north:`south`,south:`north`,east:`west`,west:`east`,northeast:`southwest`,southwest:`northeast`,northwest:`southeast`,southeast:`northwest`,up:`down`,down:`up`,in:`out`,out:`in`}}createExits(){let t=new Map;this.area.rooms.forEach(e=>{Object.entries(e.exits).forEach(([n,r])=>{if(e.id===r)return;let i=`${Math.min(e.id,r)}-${Math.max(e.id,r)}`;t.has(i)||t.set(i,[]),t.get(i).push({origin:e.id,target:r,z:e.z,dir:n})})});for(let[n,r]of t){let[t,i]=n.split(`-`),a=parseInt(t),o=parseInt(i),s=r.filter(e=>e.origin===a),c=r.filter(e=>e.origin===o),l=new Set;for(let t of s){let r=-1;for(let n=0;n<c.length;n++)if(!l.has(n)){if(c[n].dir===e.oppositeDir[t.dir]){r=n;break}r===-1&&(r=n)}if(r!==-1){l.add(r);let e=c[r];this.exits.set(`${n}-${t.dir}`,{a,b:o,aDir:t.dir,bDir:e.dir,zIndex:[t.z,e.z]})}else this.exits.set(`${n}-a:${t.dir}`,{a,b:o,aDir:t.dir,zIndex:[t.z]})}for(let e=0;e<c.length;e++)if(!l.has(e)){let t=c[e];this.exits.set(`${n}-b:${t.dir}`,{a,b:o,bDir:t.dir,zIndex:[t.z]})}}}},D=class extends T{constructor(e,t){super(e.getRooms(),e.getLabels()),this.basePlane=e,this.visitedRooms=t}getRooms(){return this.basePlane.getRooms().filter(e=>this.visitedRooms.has(e.id))}getLabels(){return this.basePlane.getLabels()}getBounds(){let e=this.getRooms();return e.length?e.reduce((e,t)=>({minX:Math.min(e.minX,t.x),maxX:Math.max(e.maxX,t.x),minY:Math.min(e.minY,t.y),maxY:Math.max(e.maxY,t.y)}),{minX:1/0,maxX:-1/0,minY:1/0,maxY:-1/0}):this.basePlane.getBounds()}},O=class extends E{constructor(e,t){super(e),this.planeCache=new WeakMap,this.visitedRooms=t instanceof Set?t:new Set(t??[]),this.areaRoomIds=new Set(e.rooms.map(e=>e.id))}getPlane(e){let t=super.getPlane(e);if(!t)return t;let n=this.planeCache.get(t);return n||(n=new D(t,this.visitedRooms),this.planeCache.set(t,n)),n}getPlanes(){return super.getPlanes().map(e=>{let t=this.planeCache.get(e);return t||(t=new D(e,this.visitedRooms),this.planeCache.set(e,t)),t})}getLinkExits(e){return super.getLinkExits(e).filter(e=>this.visitedRooms.has(e.a)||this.visitedRooms.has(e.b))}getVisitedRoomCount(){return super.getRooms().reduce((e,t)=>e+ +!!this.visitedRooms.has(t.id),0)}getTotalRoomCount(){return this.areaRoomIds.size}hasVisitedRoom(e){return this.areaRoomIds.has(e)&&this.visitedRooms.has(e)}getVisitedRoomIds(){return super.getRooms().filter(e=>this.visitedRooms.has(e.id)).map(e=>e.id)}addVisitedRoom(e){let t=this.visitedRooms.has(e);this.visitedRooms.add(e);let n=!t&&this.areaRoomIds.has(e);return n&&this.markDirty(),n}addVisitedRooms(e){let t=0;for(let n of e){let e=this.visitedRooms.has(n);this.visitedRooms.add(n),!e&&this.areaRoomIds.has(n)&&t++}return t>0&&this.markDirty(),t}},k=[`up`,`down`,`in`,`out`];function A(e,t,n,r,i){return e.roomShape===`circle`?y(t,n,r,i):e.roomShape===`roundedRectangle`?v(t,n,r,i,e.roomSize*.2):_(t,n,r,i)}function ee(e,t,n){for(let[e,r]of Object.entries(t.exits))if(r===n.id){let r=e;if(k.includes(r)){let e=f[r];return{type:`inner`,fromDir:r,customLineKey:t.customLines[e]?e:t.customLines[r]?r:void 0,fromRoom:t,toRoom:n}}let i=f[r];return t.customLines[i]?{type:`special`,fromDir:r,customLineKey:i,fromRoom:t,toRoom:n}:t.customLines[r]?{type:`special`,fromDir:r,customLineKey:r,fromRoom:t,toRoom:n}:{type:`regular`,fromDir:r,toDir:te(n,t.id),fromRoom:t,toRoom:n}}for(let[e,r]of Object.entries(t.specialExits))if(r===n.id)return t.customLines[e]?{type:`special`,customLineKey:e,fromRoom:t,toRoom:n}:{type:`inner`,fromRoom:t,toRoom:n};for(let[e,r]of Object.entries(n.exits))if(r===t.id){let r=e;if(k.includes(r)){let e=f[r];return{type:`inner`,toDir:r,customLineKey:n.customLines[e]?e:n.customLines[r]?r:void 0,fromRoom:t,toRoom:n}}let i=f[r];return n.customLines[i]?{type:`special`,toDir:r,customLineKey:i,fromRoom:t,toRoom:n}:n.customLines[r]?{type:`special`,toDir:r,customLineKey:r,fromRoom:t,toRoom:n}:{type:`regular`,toDir:r,fromRoom:t,toRoom:n}}for(let[e,r]of Object.entries(n.specialExits))if(r===t.id)return n.customLines[e]?{type:`special`,customLineKey:e,fromRoom:t,toRoom:n}:{type:`inner`,fromRoom:t,toRoom:n};return{type:`none`,fromRoom:t,toRoom:n}}function te(e,t){for(let[n,r]of Object.entries(e.exits))if(r===t)return n}function j(e,t,n){return e?e.area===t&&e.z===n:!1}function ne(e,t){for(let[n,r]of Object.entries(e.exits))if(r===t.id)return{direction:n};for(let[n,r]of Object.entries(e.specialExits))if(r===t.id)return}function re(e,t){for(let n of m)if(e.exits[n]===t.id)return n;for(let n of m)if(t.exits[n]===e.id)return h[n]}function ie(e,t,n){let{fromRoom:r,toRoom:i,fromDir:a,toDir:o}=t;if(n.length===0&&n.push(r.x,r.y),a&&u.includes(a)){let t=A(e,r.x,r.y,a,e.roomSize/2);n.push(t.x,t.y)}if(o&&u.includes(o)){let t=A(e,i.x,i.y,o,e.roomSize/2);n.push(t.x,t.y)}n.push(i.x,i.y)}function ae(e,t){let{fromRoom:n,toRoom:r,customLineKey:i}=e,a=n,o;i&&(o=n.customLines[i],o||(o=r.customLines[i],a=r)),t.length===0&&t.push(a.x,a.y),o&&o.points.forEach(e=>{t.push(e.x,-e.y)}),t.push(r.x,r.y)}function M(e,t,n,r,i){let a=[],o=[],s=[],c=n.map(t=>e.getRoom(t)).filter(e=>e!==void 0),l=[],d=()=>{l.length>=4&&a.push({points:[...l]}),l=[]},f=e=>{let{fromRoom:t,toRoom:n,fromDir:r,toDir:i,customLineKey:a}=e;if(a){let e=t,r=t.customLines[a];if(r||(r=n.customLines[a],e=n),r){let t=[e.x,e.y];r.points.forEach(e=>{t.push(e.x,-e.y)}),s.push({points:t})}}r&&k.includes(r)&&o.push({room:t,direction:r}),i&&k.includes(i)&&o.push({room:n,direction:i})};for(let n=0;n<c.length-1;n++){let a=c[n],s=c[n+1],p=j(a,r,i),m=j(s,r,i);if(!p&&!m){d();continue}if(p&&m){let n=ee(e,a,s);switch(n.type){case`regular`:ie(t,n,l);break;case`special`:ae(n,l);break;case`inner`:d(),f(n);break;case`none`:l.length===0&&l.push(a.x,a.y),l.push(s.x,s.y);break}}else{let e=p?a:s,n=p?s:a,r=ne(e,n);if(r){if(k.includes(r.direction))d(),o.push({room:e,direction:r.direction});else if(u.includes(r.direction)){l.length===0&&l.push(e.x,e.y);let n=A(t,e.x,e.y,r.direction,t.roomSize/2),i=_(e.x,e.y,r.direction,t.roomSize);l.push(n.x,n.y,i.x,i.y),d()}}else{let r=re(e,n);if(r){l.length===0&&l.push(e.x,e.y);let n=A(t,e.x,e.y,r,t.roomSize/2),i=_(e.x,e.y,r,t.roomSize);l.push(n.x,n.y,i.x,i.y),d()}}}}return d(),{segments:a,innerMarkers:o,customLines:s}}var oe=class{constructor(e,t,n){this.paths=[],this.mapReader=e,this.overlayLayer=t,this.settings=n}createStrokedLine(e,t){let n=new l.default.Group;return n.opacity(.8),n.add(new l.default.Line({points:e,stroke:`black`,strokeWidth:this.settings.lineWidth*8,lineCap:`round`,lineJoin:`round`})),n.add(new l.default.Line({points:e,stroke:t,strokeWidth:this.settings.lineWidth*4,lineCap:`round`,lineJoin:`round`})),n}renderInnerExitMarker(e,t,n){let r=new l.default.Group;r.opacity(.8);let i=new l.default.RegularPolygon({x:e.x,y:e.y,sides:3,fill:n,stroke:`black`,strokeWidth:this.settings.lineWidth*2,radius:this.settings.roomSize/5,scaleX:1.4,scaleY:.8});switch(t){case`up`:i.position(_(e.x,e.y,`south`,this.settings.roomSize/4));break;case`down`:i.rotation(180),i.position(_(e.x,e.y,`north`,this.settings.roomSize/4));break;case`in`:{let t=i.clone();t.rotation(-90),t.position(_(e.x,e.y,`east`,this.settings.roomSize/4)),r.add(t),i.rotation(90),i.position(_(e.x,e.y,`west`,this.settings.roomSize/4));break}case`out`:{let t=i.clone();t.rotation(90),t.position(_(e.x,e.y,`east`,this.settings.roomSize/4)),r.add(t),i.rotation(-90),i.position(_(e.x,e.y,`west`,this.settings.roomSize/4));break}}return r.add(i),r}renderPath(e,t,n,r=`#66E64D`){if(t===void 0||n===void 0)return;let i=M(this.mapReader,this.settings,e,t,n);for(let e of i.segments){let t=this.createStrokedLine(e.points,r);this.overlayLayer.add(t),this.paths.push(t)}for(let e of i.customLines){let t=this.createStrokedLine(e.points,r);this.overlayLayer.add(t),this.paths.push(t)}for(let e of i.innerMarkers){let t=this.renderInnerExitMarker(e.room,e.direction,r);this.overlayLayer.add(t),this.paths.push(t)}return this.paths[0]}clearPaths(){this.paths.forEach(e=>{e.destroy()}),this.paths=[]}},N=72,P=200,F=120,I=new Map,L=null;function se(){return L||(L=document.createElement(`canvas`),L.width=P,L.height=P),L}function R(e,t){let n=`${e}::${t}`,r=I.get(n);if(r!==void 0)return r;let i=se().getContext(`2d`);i.clearRect(0,0,P,P),i.font=`bold ${N}px ${t}`,i.textBaseline=`alphabetic`,i.textAlign=`center`,i.fillStyle=`#ffffff`,i.fillText(e,P/2,F);let{data:a}=i.getImageData(0,0,P,P),o=P,s=-1;for(let e=0;e<P;e++)for(let t=0;t<P;t++)a[(e*P+t)*4+3]>16&&(e<o&&(o=e),e>s&&(s=e));if(s===-1)return I.set(n,.35),.35;let c=(F-o-Math.max(0,s-F))/2/N;return I.set(n,c),c}var ce={1:`north`,2:`northeast`,3:`northwest`,4:`east`,5:`west`,6:`south`,7:`southeast`,8:`southwest`,9:`up`,10:`down`,11:`in`,12:`out`},le=[`up`,`down`,`in`,`out`],z={OPEN:`rgb(10, 155, 10)`,CLOSED:`rgb(226, 205, 59)`,LOCKED:`rgb(155, 10, 10)`};function B(e){switch(e){case 1:return z.OPEN;case 2:return z.CLOSED;default:return z.LOCKED}}function V(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`)}var H=class{constructor(e,t){this.mapReader=e,this.settings=t,this.exitRenderer=new w(e,null,t)}getSymbolColor(e,t){return this.settings.frameMode?this.mapReader.getColorValue(e):this.mapReader.getSymbolColor(e,t)}export(e,t,n){let r=this.mapReader.getArea(e);if(!r)throw Error(`Area ${e} not found`);let i=r.getPlane(t);if(!i)throw Error(`Plane z=${t} not found in area ${e}`);let a=n?.padding??3,o=this.computeBounds(r,i,n?.roomId,a),s=[];s.push(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${o.x} ${o.y} ${o.w} ${o.h}">`),s.push(`<rect x="${o.x}" y="${o.y}" width="${o.w}" height="${o.h}" fill="${V(this.settings.backgroundColor)}"/>`),this.settings.gridEnabled&&this.renderGrid(s,o),this.renderLabels(s,i.getLabels()),this.renderLinkExits(s,r,t);let c=i.getRooms();this.renderSpecialExits(s,c),this.renderStubs(s,c),this.renderRooms(s,c),this.renderInnerExits(s,c);let l=n?.overlays;if(l){if(l.paths)for(let n of l.paths)this.renderPathOverlay(s,n.locations,n.color,e,t);if(l.highlights)for(let e of l.highlights)this.renderHighlightOverlay(s,e.roomId,e.color);l.position&&this.renderPositionMarker(s,l.position.roomId)}if(this.settings.areaName){let e=r.getAreaName();if(e){let t=this.getEffectiveBounds(r,i);s.push(`<text x="${t.minX-3.5}" y="${t.minY-2}" font-size="2.5" font-family="${V(this.settings.fontFamily)}" fill="white">${V(e)}</text>`)}}return s.push(`</svg>`),s.join(`
2
+ `)}computeBounds(e,t,n,r){if(n!==void 0){let e=this.mapReader.getRoom(n);if(!e)throw Error(`Room ${n} not found`);return{x:e.x-r,y:e.y-r,w:r*2,h:r*2}}let i=this.getEffectiveBounds(e,t),a=this.settings.areaName?e.getAreaName():void 0,o=a?7:0,s=a?3.5:0,c=i.minX-s,l=i.minY-o,u=a?i.minX-3.5+a.length*2.5*.6:-1/0,d=Math.max(i.maxX,u);return{x:c-r,y:l-r,w:d-c+r*2,h:i.maxY-l+r*2}}getEffectiveBounds(e,t){return this.settings.uniformLevelSize?e.getFullBounds():t.getBounds()}getRoomEdgePoint(e,t,n,r){return this.settings.roomShape===`circle`?y(e,t,n,r):this.settings.roomShape===`roundedRectangle`?v(e,t,n,r,this.settings.roomSize*.2):_(e,t,n,r)}renderGrid(e,t){let n=this.settings.gridSize,r=Math.floor(t.x/n)*n,i=Math.ceil((t.x+t.w)/n)*n,a=Math.floor(t.y/n)*n,o=Math.ceil((t.y+t.h)/n)*n,s=V(this.settings.gridColor),c=this.settings.gridLineWidth;for(let t=r;t<=i;t+=n)e.push(`<line x1="${t}" y1="${a}" x2="${t}" y2="${o}" stroke="${s}" stroke-width="${c}"/>`);for(let t=a;t<=o;t+=n)e.push(`<line x1="${r}" y1="${t}" x2="${i}" y2="${t}" stroke="${s}" stroke-width="${c}"/>`)}renderLabels(e,t){for(let n of t){let t=n.X,r=-n.Y;if(this.settings.labelRenderMode===`image`&&n.pixMap){e.push(`<image x="${t}" y="${r}" width="${n.Width}" height="${n.Height}" href="data:image/png;base64,${n.pixMap}"/>`);continue}if((n.BgColor?.alpha??0)>0&&!this.settings.transparentLabels){let i=this.labelColor(n.BgColor);e.push(`<rect x="${t}" y="${r}" width="${n.Width}" height="${n.Height}" fill="${i}"/>`)}if(n.Text){let i=this.labelColor(n.FgColor),a=Math.min(.75,n.Width/Math.max(n.Text.length/2,1)),o=Math.max(.1,Math.min(a,Math.max(n.Height*.9,.1)));e.push(`<text x="${t+n.Width/2}" y="${r+n.Height/2}" font-size="${o}" font-family="${V(this.settings.fontFamily)}" fill="${i}" text-anchor="middle" dominant-baseline="central">${V(n.Text)}</text>`)}}}labelColor(e){let t=(e?.alpha??255)/255,n=e=>Math.min(255,Math.max(0,e??0));return`rgba(${n(e?.r)}, ${n(e?.g)}, ${n(e?.b)}, ${t})`}renderLinkExits(e,t,n){let r=t.getLinkExits(n);for(let t of r){let r=this.exitRenderer.renderData(t,n);r&&this.renderExitData(e,r)}}renderExitData(e,t){for(let n of t.lines)this.renderSvgLine(e,n);for(let n of t.arrows)this.renderSvgArrow(e,n);for(let n of t.doors)this.renderSvgDoor(e,n)}renderSvgLine(e,t){if(t.points.length<4)return;let n=t.points.map(e=>e.toString()).join(` `),r=t.dash?` stroke-dasharray="${t.dash.join(` `)}"`:``;e.push(`<polyline points="${n}" stroke="${V(t.stroke)}" stroke-width="${t.strokeWidth}" fill="none"${r}/>`)}renderSvgArrow(e,t){if(t.points.length<4)return;let n=t.points.map(e=>e.toString()).join(` `),r=t.dash?` stroke-dasharray="${t.dash.join(` `)}"`:``;e.push(`<polyline points="${n}" stroke="${V(t.stroke)}" stroke-width="${t.strokeWidth}" fill="none"${r}/>`);let i=t.points.length-2,a=t.points[i],o=t.points[i+1],s=t.points[i-2],c=t.points[i-1],l=Math.atan2(o-c,a-s),u=t.pointerLength,d=t.pointerWidth/2,f=a-u*Math.cos(l-Math.atan2(d,u)),p=o-u*Math.sin(l-Math.atan2(d,u)),m=a-u*Math.cos(l+Math.atan2(d,u)),h=o-u*Math.sin(l+Math.atan2(d,u));e.push(`<polygon points="${a},${o} ${f},${p} ${m},${h}" fill="${V(t.fill)}" stroke="${V(t.stroke)}" stroke-width="${t.strokeWidth}"/>`)}renderSvgDoor(e,t){e.push(`<rect x="${t.x}" y="${t.y}" width="${t.width}" height="${t.height}" stroke="${V(t.stroke)}" stroke-width="${t.strokeWidth}" fill="none"/>`)}renderStubs(e,t){let n=this.settings.lineColor;for(let r of t)for(let t of r.stubs){let i=ce[t];if(!i)continue;let a=this.getRoomEdgePoint(r.x,r.y,i,this.settings.roomSize/2),o=_(r.x,r.y,i,this.settings.roomSize/2+.5);e.push(`<line x1="${a.x}" y1="${a.y}" x2="${o.x}" y2="${o.y}" stroke="${V(n)}" stroke-width="${this.settings.lineWidth}"/>`)}}renderSpecialExits(e,t){for(let n of t)for(let[t,r]of Object.entries(n.customLines)){let i=[n.x,n.y];for(let e of r.points)i.push(e.x,-e.y);let a=`rgb(${r.attributes.color.r}, ${r.attributes.color.g}, ${r.attributes.color.b})`,o=``;r.attributes.style===`dot line`?o=` stroke-dasharray="0.05 0.05"`:r.attributes.style===`dash line`&&(o=` stroke-dasharray="0.4 0.2"`);let s=i.map(e=>e.toString()).join(` `);if(r.attributes.arrow&&i.length>=4){e.push(`<polyline points="${s}" stroke="${V(a)}" stroke-width="${this.settings.lineWidth}" fill="none"${o}/>`);let t=i.length-2,n=i[t],r=i[t+1],c=i[t-2],l=i[t-1],u=Math.atan2(r-l,n-c),d=.3,f=.1,p=n-d*Math.cos(u-Math.atan2(f,d)),m=r-d*Math.sin(u-Math.atan2(f,d)),h=n-d*Math.cos(u+Math.atan2(f,d)),g=r-d*Math.sin(u+Math.atan2(f,d));e.push(`<polygon points="${n},${r} ${p},${m} ${h},${g}" fill="${V(a)}" stroke="${V(a)}" stroke-width="${this.settings.lineWidth}"/>`)}else e.push(`<polyline points="${s}" stroke="${V(a)}" stroke-width="${this.settings.lineWidth}" fill="none"${o}/>`);let c=n.doors[t];if(c&&i.length>=4){let t=i[0]+(i[2]-i[0])/2,n=i[1]+(i[3]-i[1])/2,r=this.settings.roomSize/2;e.push(`<rect x="${t-r/2}" y="${n-r/2}" width="${r}" height="${r}" stroke="${B(c)}" stroke-width="${this.settings.lineWidth}" fill="none"/>`)}}}renderRooms(e,t){let n=this.settings.roomSize,r=n/2;for(let i of t){let t=this.mapReader.getColorValue(i.env),a=this.settings.coloredMode?K(t,.5):this.settings.frameMode?this.settings.backgroundColor:t,o=this.settings.frameMode||this.settings.coloredMode?t:this.settings.lineColor;if(this.settings.roomShape===`circle`)e.push(`<circle cx="${i.x}" cy="${i.y}" r="${r}" fill="${V(a)}" stroke="${V(o)}" stroke-width="${this.settings.lineWidth}"/>`);else{let t=i.x-r,s=i.y-r,c=this.settings.roomShape===`roundedRectangle`?n*.2:0,l=c>0?` rx="${c}" ry="${c}"`:``;if(e.push(`<rect x="${t}" y="${s}" width="${n}" height="${n}" fill="${V(a)}" stroke="${V(o)}" stroke-width="${this.settings.lineWidth}"${l}/>`),this.settings.emboss){let r=G(this.settings.lineColor)>.41,i=r?`#000000`:`#ffffff`,a=r?`${t},${s} ${t+n},${s} ${t+n},${s+n}`:`${t},${s} ${t},${s+n} ${t+n},${s+n}`;e.push(`<polyline points="${a}" stroke="${i}" stroke-width="${this.settings.lineWidth}" fill="none"/>`)}}if(i.roomChar){let t=this.getSymbolColor(i.env),r=n*.75,a=i.y+R(i.roomChar,this.settings.fontFamily)*r;e.push(`<text x="${i.x}" y="${a}" font-size="${r}" font-weight="bold" font-family="${V(this.settings.fontFamily)}" fill="${V(t)}" text-anchor="middle">${V(i.roomChar)}</text>`)}}}renderInnerExits(e,t){let n=this.settings.roomSize,r=n/5;for(let i of t)for(let t of le){if(!i.exits[t])continue;let a=this.getSymbolColor(i.env),o=this.getSymbolColor(i.env,.6),s,c=i.doors[t];c!==void 0&&(s=B(c));let l=s??a;switch(t){case`up`:{let t=_(i.x,i.y,`south`,n/4);e.push(this.svgTriangle(t.x,t.y,r,0,o,l));break}case`down`:{let t=_(i.x,i.y,`north`,n/4);e.push(this.svgTriangle(t.x,t.y,r,180,o,l));break}case`in`:{let t=_(i.x,i.y,`west`,n/4),a=_(i.x,i.y,`east`,n/4);e.push(this.svgTriangle(t.x,t.y,r,90,o,l)),e.push(this.svgTriangle(a.x,a.y,r,-90,o,l));break}case`out`:{let t=_(i.x,i.y,`west`,n/4),a=_(i.x,i.y,`east`,n/4);e.push(this.svgTriangle(t.x,t.y,r,-90,o,l)),e.push(this.svgTriangle(a.x,a.y,r,90,o,l));break}}}}svgTriangle(e,t,n,r,i,a){let o=r*Math.PI/180,s=[];for(let r=0;r<3;r++){let i=2*Math.PI*r/3-Math.PI/2,a=Math.cos(i)*n*1.4,c=Math.sin(i)*n*.8,l=a*Math.cos(o)-c*Math.sin(o),u=a*Math.sin(o)+c*Math.cos(o);s.push(`${e+l},${t+u}`)}return`<polygon points="${s.join(` `)}" fill="${V(i)}" stroke="${V(a)}" stroke-width="${this.settings.lineWidth}"/>`}renderPathOverlay(e,t,n,r,i){let a=M(this.mapReader,this.settings,t,r,i),o=this.settings.lineWidth;for(let t of a.segments){let r=t.points.map(e=>e.toString()).join(` `);e.push(`<polyline points="${r}" stroke="black" stroke-width="${o*8}" stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.8"/>`),e.push(`<polyline points="${r}" stroke="${V(n)}" stroke-width="${o*4}" stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.8"/>`)}for(let t of a.customLines){let r=t.points.map(e=>e.toString()).join(` `);e.push(`<polyline points="${r}" stroke="black" stroke-width="${o*8}" stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.8"/>`),e.push(`<polyline points="${r}" stroke="${V(n)}" stroke-width="${o*4}" stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.8"/>`)}let s=this.settings.roomSize/5;for(let t of a.innerMarkers)e.push(this.svgTriangle(t.room.x,t.room.y,s,this.innerExitRotation(t.direction),n,`black`))}innerExitRotation(e){switch(e){case`up`:return 0;case`down`:return 180;case`in`:return 90;case`out`:return-90;default:return 0}}renderHighlightOverlay(e,t,n){let r=this.mapReader.getRoom(t);if(!r)return;let i=1.5,a=this.settings.roomSize,o=`0.05 0.05`;if(this.settings.roomShape===`circle`)e.push(`<circle cx="${r.x}" cy="${r.y}" r="${a/2*i}" stroke="${V(n)}" stroke-width="0.1" stroke-dasharray="${o}" fill="none"/>`);else{let t=a*i;e.push(`<rect x="${r.x-t/2}" y="${r.y-t/2}" width="${t}" height="${t}" stroke="${V(n)}" stroke-width="0.1" stroke-dasharray="${o}" fill="none"/>`)}}renderPositionMarker(e,t){let n=this.mapReader.getRoom(t);if(!n)return;let r=this.settings.playerMarker,i=this.settings.roomSize*r.sizeFactor,a=r.dashEnabled&&r.dash?` stroke-dasharray="${r.dash.join(` `)}"`:``,o=r.fillAlpha>0?` fill="${r.fillColor}" fill-opacity="${r.fillAlpha}"`:` fill="none"`,s=`stroke="${r.strokeColor}" stroke-width="${r.strokeWidth}" stroke-opacity="${r.strokeAlpha}"${a}${o}`;if(r.matchRoomShape&&this.settings.roomShape!==`circle`){let t=i/2,r=this.settings.roomShape===`roundedRectangle`?i*.2:0,a=r>0?` rx="${r}" ry="${r}"`:``;e.push(`<rect x="${n.x-t}" y="${n.y-t}" width="${i}" height="${i}" ${s}${a}/>`)}else e.push(`<circle cx="${n.x}" cy="${n.y}" r="${i/2}" ${s}/>`)}},ue=.6,U=75,de=.025,fe=`rgb(225, 255, 225)`,W=`rgb(120, 72, 0)`;function G(e){let t,n,r,i=e.match(/(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);if(i)t=parseInt(i[1])/255,n=parseInt(i[2])/255,r=parseInt(i[3])/255;else if(e.startsWith(`#`)&&e.length>=7)t=parseInt(e.slice(1,3),16)/255,n=parseInt(e.slice(3,5),16)/255,r=parseInt(e.slice(5,7),16)/255;else return .5;return(Math.max(t,n,r)+Math.min(t,n,r))/2}function K(e,t){let n,r,i,a=e.match(/(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);if(a)n=parseInt(a[1]),r=parseInt(a[2]),i=parseInt(a[3]);else if(e.startsWith(`#`)&&e.length>=7)n=parseInt(e.slice(1,3),16),r=parseInt(e.slice(3,5),16),i=parseInt(e.slice(5,7),16);else return e;return n=Math.round(n*(1-t)),r=Math.round(r*(1-t)),i=Math.round(i*(1-t)),`rgb(${n}, ${r}, ${i})`}var pe=class{constructor(e=60){this.samples=[],this.lastCullingTime=0,this.callback=null,this.windowSize=e}setCallback(e){e!==this.callback&&(this.callback=e,this.samples=[])}record(e){this.callback&&(this.samples.push(e),this.samples.length>=this.windowSize&&this.flush())}computeFps(){let e=performance.now(),t=e-this.lastCullingTime;return this.lastCullingTime=e,t>0?1e3/t:0}flush(){let e=this.samples.length;if(e===0)return;let t={cullingMs:0,gridMs:0,visibleRooms:0,totalRooms:0,visibleExits:0,fps:0};for(let e of this.samples)t.cullingMs+=e.cullingMs,t.gridMs+=e.gridMs,t.visibleRooms+=e.visibleRooms,t.totalRooms+=e.totalRooms,t.visibleExits+=e.visibleExits,t.fps+=e.fps;t.cullingMs/=e,t.gridMs/=e,t.visibleRooms=Math.round(t.visibleRooms/e),t.totalRooms=Math.round(t.totalRooms/e),t.visibleExits=Math.round(t.visibleExits/e),t.fps=Math.round(t.fps),this.callback(t),this.samples=[]}};function q(e,t){return`rgba(${parseInt(e.slice(1,3),16)}, ${parseInt(e.slice(3,5),16)}, ${parseInt(e.slice(5,7),16)}, ${t})`}function J(){return{roomSize:ue,lineWidth:de,lineColor:fe,backgroundColor:`#000000`,instantMapMove:!1,highlightCurrentRoom:!0,cullingEnabled:!0,cullingMode:`indexed`,cullingBounds:null,labelRenderMode:`image`,transparentLabels:!1,roomShape:`rectangle`,playerMarker:{strokeColor:`#00e5b2`,strokeAlpha:1,fillColor:`#00e5b2`,fillAlpha:0,strokeWidth:.1,sizeFactor:1.7,dash:[.05,.05],dashEnabled:!0,matchRoomShape:!1},gridEnabled:!1,gridSize:1,gridColor:`rgba(200, 200, 200, 0.15)`,gridLineWidth:.03,perfCallback:null,borders:!0,frameMode:!1,coloredMode:!1,emboss:!1,areaName:!0,fontFamily:`sans-serif`,uniformLevelSize:!1}}var me=class{constructor(e,t,n){this.highlights=new Map,this.currentZoom=1,this.currentRoomOverlay=[],this.roomNodes=new Map,this.centerOnResize=!0,this.minZoom=.05,this.standaloneExitNodes=[],this.spatialBucketSize=5,this.roomSpatialIndex=new Map,this.exitSpatialIndex=new Map,this.visibleRooms=new Set,this.visibleStandaloneExitNodes=new Set,this.bufferRoomSet=new Set,this.bufferExitSet=new Set,this.bufferRoomCandidates=new Set,this.bufferExitCandidates=new Set,this.cullingScheduled=!1,this.perfMonitor=new pe,this.areaExitHitZones=[],this.visibleExitDrawData=[],this.cachedGridBounds=null,this.settings=n??J(),this.stage=new l.default.Stage({container:e,width:e.clientWidth,height:e.clientHeight,draggable:!0}),e.style.backgroundColor=this.settings.backgroundColor,window.addEventListener(`resize`,()=>{this.onResize(e)}),e.addEventListener(`resize`,()=>{this.onResize(e)}),this.gridLayer=new l.default.Layer({listening:!1}),this.stage.add(this.gridLayer),this.linkLayer=new l.default.Layer({listening:!1}),this.stage.add(this.linkLayer),this.roomLayer=new l.default.Layer,this.stage.add(this.roomLayer),this.positionLayer=new l.default.Layer({listening:!1}),this.stage.add(this.positionLayer),this.overlayLayer=new l.default.Layer({listening:!1}),this.stage.add(this.overlayLayer),this.mapReader=t,this.exitRenderer=new w(t,this,this.settings),this.pathRenderer=new oe(t,this.overlayLayer,this.settings),this.initScaling(1.1),this.stage.on(`dragmove`,()=>{this.scheduleRoomCulling(),this.emitPanEvent()}),this.stage.on(`dragend`,()=>{this.scheduleRoomCulling(),this.emitPanEvent()}),this.initRoomHitDetection()}clientToMapPoint(e,t){let n=this.stage.container().getBoundingClientRect(),r=e-n.left,i=t-n.top,a=this.stage.scaleX();if(!a)return null;let o=this.stage.position();return{x:(r-o.x)/a,y:(i-o.y)/a}}findRoomAtClientPoint(e,t){let n=this.clientToMapPoint(e,t);if(!n)return null;let r=this.settings.roomSize/2,i=this.getBucketKey(Math.floor(n.x/this.spatialBucketSize),Math.floor(n.y/this.spatialBucketSize)),a=this.roomSpatialIndex.get(i);if(!a)return null;for(let e of a){let t=n.x-e.room.x,i=n.y-e.room.y;if(t>=-r&&t<=r&&i>=-r&&i<=r)return e.room}return null}initRoomHitDetection(){let e=this.stage.container(),t=null;e.addEventListener(`mousemove`,n=>{let r=this.findRoomAtClientPoint(n.clientX,n.clientY);if(r!==t&&(t=r,r)){e.style.cursor=`pointer`;return}if(!t){let t=this.findAreaExitAtClientPoint(n.clientX,n.clientY)!==null;e.style.cursor=t?`pointer`:`auto`}}),e.addEventListener(`mouseleave`,()=>{t=null,e.style.cursor=`auto`});let n=null;e.addEventListener(`mousedown`,e=>{e.button===0&&(n={x:e.clientX,y:e.clientY})}),e.addEventListener(`mouseup`,e=>{if(e.button!==0||!n)return;let t=e.clientX-n.x,r=e.clientY-n.y;if(n=null,t*t+r*r>25)return;let i=this.findRoomAtClientPoint(e.clientX,e.clientY);if(i){this.emitRoomClickEvent(i.id,e.clientX,e.clientY);return}let a=this.findAreaExitAtClientPoint(e.clientX,e.clientY);if(a){this.emitAreaExitClickEvent(a.targetRoomId,e.clientX,e.clientY);return}this.emitMapClickEvent()}),e.addEventListener(`contextmenu`,e=>{let t=this.findRoomAtClientPoint(e.clientX,e.clientY);t&&(e.preventDefault(),this.emitRoomContextEvent(t.id,e.clientX,e.clientY))});let r,i,a,o=()=>{a!==void 0&&(this.stage.draggable(a),a=void 0)},s=()=>{r!==void 0&&(window.clearTimeout(r),r=void 0),i=void 0,o()};e.addEventListener(`touchstart`,e=>{if(s(),e.touches.length>1)return;let t=e.touches[0];t&&this.findRoomAtClientPoint(t.clientX,t.clientY)&&(i={clientX:t.clientX,clientY:t.clientY},a=this.stage.draggable(),this.stage.draggable(!1),r=window.setTimeout(()=>{if(i){let e=this.findRoomAtClientPoint(i.clientX,i.clientY);e&&this.emitRoomContextEvent(e.id,i.clientX,i.clientY)}s()},500))},{passive:!0}),e.addEventListener(`touchend`,()=>s(),{passive:!0}),e.addEventListener(`touchcancel`,()=>s(),{passive:!0}),e.addEventListener(`touchmove`,e=>{if(!i)return;let t=e.touches[0];if(!t){s();return}let n=t.clientX-i.clientX,r=t.clientY-i.clientY;if(n*n+r*r>100){let e=a;s(),e&&this.stage.startDrag()}},{passive:!0})}onResize(e){this.stage.width(e.clientWidth),this.stage.height(e.clientHeight),this.centerOnResize&&this.currentRoomId&&this.centerOnRoom(this.mapReader.getRoom(this.currentRoomId),!1),this.stage.batchDraw(),this.scheduleRoomCulling()}initScaling(e){let t,n=!1,r=!1;this.stage.on(`touchstart`,e=>{let t=e.evt.touches;t&&t.length>1?(r=!0,this.stage.isDragging()&&(this.stage.stopDrag(),n=!0),this.stage.draggable(!1)):(r=!1,this.stage.draggable(!0))}),this.stage.on(`touchend touchcancel`,e=>{t=void 0;let n=e.evt.touches;(!n||n.length<=1)&&(r=!1,this.stage.draggable(!0))}),this.stage.on(`wheel`,t=>{t.evt.preventDefault();let n=this.stage.scaleX(),r=this.stage.getPointerPosition();if(!r)return;let i={x:(r.x-this.stage.x())/n,y:(r.y-this.stage.y())/n},a=t.evt.deltaY>0?-1:1;t.evt.ctrlKey&&(a=-a);let o=a>0?this.currentZoom*e:this.currentZoom/e;if(this.setZoom(o)){let e=this.stage.scaleX(),t={x:r.x-i.x*e,y:r.y-i.y*e};this.stage.position(t),this.scheduleRoomCulling(),this.emitZoomChangeEvent()}}),this.stage.on(`touchmove`,e=>{let i=e.evt.touches,a=i?.[0],o=i?.[1];if(o||r&&(r=!1,this.stage.draggable(!0)),a&&!o&&n&&!this.stage.isDragging()&&(this.stage.startDrag(),n=!1),!a||!o){t=void 0;return}e.evt.preventDefault(),this.stage.isDragging()&&(this.stage.stopDrag(),n=!0),r||(r=!0,this.stage.draggable(!1));let s=this.stage.container().getBoundingClientRect(),c={x:a.clientX-s.left,y:a.clientY-s.top},l={x:o.clientX-s.left,y:o.clientY-s.top},u=Math.hypot(c.x-l.x,c.y-l.y);if(t===void 0){t=u;return}if(t===0||u===0){t=u;return}let d=this.stage.scaleX(),f=this.stage.x(),p=this.stage.y(),m={x:this.stage.width()/2,y:this.stage.height()/2},h={x:(m.x-f)/d,y:(m.y-p)/d},g=this.currentZoom*(u/t);if(this.setZoom(g)){let e=this.stage.scaleX(),t={x:m.x-h.x*e,y:m.y-h.y*e};this.stage.position(t),this.stage.batchDraw(),this.scheduleRoomCulling(),this.emitZoomChangeEvent()}t=u})}drawArea(e,t){let n=this.mapReader.getArea(e);if(!n)return;let r=n.getPlane(t);r&&(this.currentArea=e,this.currentAreaInstance=n,this.currentZIndex=t,this.currentAreaVersion=n.getVersion(),this.clearCurrentRoomOverlay(),this.positionRender&&=(this.positionRender.destroy(),void 0),this.positionLayer.destroyChildren(),this.gridLayer.destroyChildren(),this.invalidateGridCache(),this.roomLayer.destroyChildren(),this.linkLayer.destroyChildren(),this.roomNodes.clear(),this.standaloneExitNodes=[],this.areaExitHitZones=[],this.standaloneExitBoundsRoomSize=void 0,this.roomSpatialIndex.clear(),this.exitSpatialIndex.clear(),this.visibleRooms.clear(),this.visibleStandaloneExitNodes.clear(),this.visibleExitDrawData.length=0,this.exitBatchShape=void 0,this.spatialBucketSize=this.computeSpatialBucketSize(),this.stage.scale({x:U*this.currentZoom,y:U*this.currentZoom}),this.renderGrid(),this.renderLabels(r.getLabels()),this.renderExits(n.getLinkExits(t)),this.renderRooms(r.getRooms()??[]),this.renderAreaName(n,r),this.refreshHighlights(),this.updateRoomCulling(),this.stage.batchDraw())}exportSvg(e){if(!(this.currentArea===void 0||this.currentZIndex===void 0))return new H(this.mapReader,this.settings).export(this.currentArea,this.currentZIndex,e)}exportPng(e){if(this.currentArea===void 0||this.currentZIndex===void 0)return;let t=e?.pixelRatio??1,n=this.stage.toCanvas({pixelRatio:t}),r=document.createElement(`canvas`);r.width=n.width,r.height=n.height;let i=r.getContext(`2d`);return i.fillStyle=this.settings.backgroundColor,i.fillRect(0,0,r.width,r.height),i.drawImage(n,0,0),r.toDataURL(`image/png`)}exportPngBlob(e){if(this.currentArea===void 0||this.currentZIndex===void 0)return;let t=e?.pixelRatio??1,n=this.stage.toCanvas({pixelRatio:t}),r=document.createElement(`canvas`);r.width=n.width,r.height=n.height;let i=r.getContext(`2d`);return i.fillStyle=this.settings.backgroundColor,i.fillRect(0,0,r.width,r.height),i.drawImage(n,0,0),new Promise(e=>{r.toBlob(t=>{t&&e(t)},`image/png`)})}computeSpatialBucketSize(){return Math.max(this.settings.roomSize*10,5)}getBucketKey(e,t){return e*1000003+t}forEachBucket(e,t,n,r,i){let a=this.spatialBucketSize,o=Math.min(e,n),s=Math.max(e,n),c=Math.min(t,r),l=Math.max(t,r),u=Math.floor(o/a),d=Math.floor(s/a),f=Math.floor(c/a),p=Math.floor(l/a);for(let e=u;e<=d;e++)for(let t=f;t<=p;t++)i(this.getBucketKey(e,t))}addRoomToSpatialIndex(e){let t=this.settings.roomSize/2,n=e.room.x-t,r=e.room.x+t,i=e.room.y-t,a=e.room.y+t;this.forEachBucket(n,i,r,a,t=>{let n=this.roomSpatialIndex.get(t);n||(n=new Set,this.roomSpatialIndex.set(t,n)),n.add(e)})}addStandaloneExitToSpatialIndex(e){let{bounds:t}=e,n=t.x,r=t.x+t.width,i=t.y,a=t.y+t.height;this.forEachBucket(n,i,r,a,t=>{let n=this.exitSpatialIndex.get(t);n||(n=new Set,this.exitSpatialIndex.set(t,n)),n.add(e)})}collectRoomCandidates(e,t,n,r){let i=this.bufferRoomCandidates;return i.clear(),this.forEachBucket(e,t,n,r,e=>{this.roomSpatialIndex.get(e)?.forEach(e=>i.add(e))}),i}collectStandaloneExitCandidates(e,t,n,r){let i=this.bufferExitCandidates;return i.clear(),this.forEachBucket(e,t,n,r,e=>{this.exitSpatialIndex.get(e)?.forEach(e=>i.add(e))}),i}refreshStandaloneExitBoundsIfNeeded(){this.standaloneExitBoundsRoomSize!==this.settings.roomSize&&(this.exitSpatialIndex.clear(),this.standaloneExitNodes.forEach(e=>{this.addStandaloneExitToSpatialIndex(e)}),this.standaloneExitBoundsRoomSize=this.settings.roomSize)}emitRoomContextEvent(e,t,n){let r=this.stage.container(),i=r.getBoundingClientRect(),a={roomId:e,position:{x:t-i.left,y:n-i.top}},o=new CustomEvent(`roomcontextmenu`,{detail:a});r.dispatchEvent(o)}emitRoomClickEvent(e,t,n){let r=this.stage.container(),i=r.getBoundingClientRect(),a={roomId:e,position:{x:t-i.left,y:n-i.top}},o=new CustomEvent(`roomclick`,{detail:a});r.dispatchEvent(o)}findAreaExitAtClientPoint(e,t){let n=this.clientToMapPoint(e,t);if(!n)return null;for(let e of this.areaExitHitZones){let t=e.bounds,r=this.settings.roomSize*.5;if(n.x>=t.x-r&&n.x<=t.x+t.width+r&&n.y>=t.y-r&&n.y<=t.y+t.height+r)return e}return null}emitAreaExitClickEvent(e,t,n){let r=this.stage.container(),i=r.getBoundingClientRect(),a={targetRoomId:e,position:{x:t-i.left,y:n-i.top}},o=new CustomEvent(`areaexitclick`,{detail:a});r.dispatchEvent(o)}emitZoomChangeEvent(){let e=new CustomEvent(`zoom`,{detail:{zoom:this.currentZoom}});this.stage.container().dispatchEvent(e)}emitPanEvent(){let e=new CustomEvent(`pan`,{detail:this.getViewportBounds()});this.stage.container().dispatchEvent(e)}emitMapClickEvent(){let e=new CustomEvent(`mapclick`);this.stage.container().dispatchEvent(e)}setZoom(e){let t=Math.max(this.minZoom,Math.min(5,e));return this.currentZoom===t?!1:(this.currentZoom=t,this.stage.scale({x:U*this.currentZoom,y:U*this.currentZoom}),this.scheduleRoomCulling(),this.emitPanEvent(),!0)}zoomToCenter(e){let t=Math.max(this.minZoom,Math.min(5,e));if(this.currentZoom===t)return!1;let n=this.stage.scaleX(),r=this.stage.width(),i=this.stage.height(),a=r/2,o=i/2,s={x:(a-this.stage.x())/n,y:(o-this.stage.y())/n};this.currentZoom=t;let c=U*t;this.stage.scale({x:c,y:c});let l={x:a-s.x*c,y:o-s.y*c};return this.stage.position(l),this.stage.batchDraw(),this.scheduleRoomCulling(),this.emitZoomChangeEvent(),this.emitPanEvent(),!0}getZoom(){return this.currentZoom}getViewportBounds(){let e=this.stage.scaleX(),t=this.stage.position();return{minX:(0-t.x)/e,maxX:(this.stage.width()-t.x)/e,minY:(0-t.y)/e,maxY:(this.stage.height()-t.y)/e}}getAreaBounds(){if(!this.currentAreaInstance||this.currentZIndex===void 0)return null;let e=this.currentAreaInstance.getPlane(this.currentZIndex);if(!e)return null;let t=this.getEffectiveBounds(this.currentAreaInstance,e),n=this.settings.areaName&&this.currentAreaInstance.getAreaName();return{minX:n?t.minX-4:t.minX,maxX:t.maxX,minY:n?t.minY-7:t.minY,maxY:t.maxY}}fitArea(){if(this.currentArea===void 0||this.currentZIndex===void 0||!this.currentAreaInstance)return;let e=this.currentAreaInstance.getPlane(this.currentZIndex);if(!e)return;let t=this.getEffectiveBounds(this.currentAreaInstance,e),n=this.settings.areaName&&this.currentAreaInstance.getAreaName(),r=n?t.minY-7:t.minY,i=n?t.minX-4:t.minX,a=t.maxX-i,o=t.maxY-r;if(a<=0||o<=0)return;let s=this.stage.width(),c=this.stage.height(),l=s/((a+4)*U),u=c/((o+4)*U);this.currentZoom=Math.max(.05,Math.min(5,Math.min(l,u))),this.minZoom=this.currentZoom;let d=U*this.currentZoom;this.stage.scale({x:d,y:d});let f=(i+t.maxX)/2,p=(r+t.maxY)/2;this.stage.position({x:s/2-f*d,y:c/2-p*d}),this.stage.batchDraw(),this.scheduleRoomCulling()}setCullingMode(e){this.settings.cullingMode=e,this.settings.cullingEnabled=e!==`none`,this.scheduleRoomCulling()}getCullingMode(){return this.settings.cullingMode}getCurrentArea(){return this.currentArea?this.mapReader.getArea(this.currentArea):void 0}refreshCurrentRoomOverlay(){if(this.currentRoomId!==void 0){let e=this.mapReader.getRoom(this.currentRoomId);e&&this.updateCurrentRoomOverlay(e)}}updateBackground(){this.stage.container().style.backgroundColor=this.settings.backgroundColor}refresh(){this.updateBackground(),this.currentArea!==void 0&&this.currentZIndex!==void 0&&(this.drawArea(this.currentArea,this.currentZIndex),this.currentRoomId!==void 0&&this.setPosition(this.currentRoomId))}updatePositionMarker(e){let t=this.mapReader.getRoom(e);if(t){if(t.area!==this.currentArea||t.z!==this.currentZIndex){this.positionRender&&(this.positionRender.hide(),this.positionLayer.batchDraw());return}this.currentRoomId=e,this.updateCurrentRoomOverlay(t),this.applyPositionMarker(t),this.positionLayer.batchDraw()}}setPosition(e,t=!0){let n=this.mapReader.getRoom(e);if(!n)return;let r=this.mapReader.getArea(n.area),i=r?.getVersion(),a=this.currentArea!==n.area||this.currentZIndex!==n.z;(this.currentArea!==n.area||this.currentZIndex!==n.z||i!==void 0&&this.currentAreaVersion!==i||r!==void 0&&this.currentAreaInstance!==r)&&this.drawArea(n.area,n.z),t?this.centerOnRoom(n,a):this.currentRoomId=e,this.updateCurrentRoomOverlay(n),this.applyPositionMarker(n)}applyPositionMarker(e){let t=this.settings.playerMarker,n=q(t.strokeColor,t.strokeAlpha),r=q(t.fillColor,t.fillAlpha),i=this.settings.roomSize*t.sizeFactor,a=i/2;if(this.positionRender&&this.positionRender.destroy(),t.matchRoomShape&&this.settings.roomShape!==`circle`){let o=this.settings.roomShape===`roundedRectangle`?i*.2:0;this.positionRender=new l.default.Rect({x:e.x-a,y:e.y-a,width:i,height:i,stroke:n,fill:r,strokeWidth:t.strokeWidth,dash:t.dash,dashEnabled:t.dashEnabled,cornerRadius:o})}else this.positionRender=new l.default.Circle({x:e.x,y:e.y,radius:a,stroke:n,fill:r,strokeWidth:t.strokeWidth,dash:t.dash,dashEnabled:t.dashEnabled});this.positionLayer.add(this.positionRender)}clearPosition(){this.currentRoomId=void 0,this.positionRender&&=(this.positionRender.destroy(),void 0),this.positionLayer.batchDraw(),this.currentRoomOverlay.forEach(e=>e.destroy()),this.currentRoomOverlay=[],this.overlayLayer.batchDraw()}centerOn(e,t){let n=this.mapReader.getRoom(e);if(!n)return;let r=this.mapReader.getArea(n.area),i=r?.getVersion(),a=this.currentArea!==n.area||this.currentZIndex!==n.z;(a||i!==void 0&&this.currentAreaVersion!==i||r!==void 0&&this.currentAreaInstance!==r)&&this.drawArea(n.area,n.z),this.centerOnRoomView(n,t??a)}renderPath(e,t){return this.pathRenderer.renderPath(e,this.currentArea,this.currentZIndex,t)}clearPaths(){this.pathRenderer.clearPaths()}renderHighlight(e,t){let n=this.mapReader.getRoom(e);if(!n)return;let r=this.highlights.get(e);r?.shape&&(r.shape.destroy(),delete r.shape);let i={color:t,area:n.area,z:n.z};if(this.highlights.set(e,i),n.area===this.currentArea&&n.z===this.currentZIndex){let e=this.createHighlightShape(n,t);return this.overlayLayer.add(e),i.shape=e,this.overlayLayer.batchDraw(),e}return i.shape}removeHighlight(e){let t=this.highlights.get(e);t&&(t.shape?.destroy(),this.highlights.delete(e),this.overlayLayer.batchDraw())}hasHighlight(e){return this.highlights.has(e)}clearHighlights(){this.highlights.forEach(({shape:e})=>e?.destroy()),this.highlights.clear(),this.overlayLayer.batchDraw()}refreshHighlights(){this.highlights.forEach((e,t)=>{if(e.shape?.destroy(),delete e.shape,e.area!==this.currentArea||e.z!==this.currentZIndex)return;let n=this.mapReader.getRoom(t);if(!n)return;let r=this.createHighlightShape(n,e.color);this.overlayLayer.add(r),e.shape=r}),this.overlayLayer.batchDraw()}createHighlightShape(e,t){let n=1.5;return this.settings.roomShape===`circle`?new l.default.Circle({x:e.x,y:e.y,radius:this.settings.roomSize/2*n,stroke:t,strokeWidth:.1,dash:[.05,.05],dashEnabled:!0,listening:!1}):new l.default.Rect({x:e.x-this.settings.roomSize/2*n,y:e.y-this.settings.roomSize/2*n,width:this.settings.roomSize*n,height:this.settings.roomSize*n,stroke:t,strokeWidth:.1,dash:[.05,.05],dashEnabled:!0,cornerRadius:this.settings.roomShape===`roundedRectangle`?this.settings.roomSize*n*.2:0,listening:!1})}centerOnRoom(e,t=!1){this.currentRoomId=e.id;let n={x:e.x,y:e.y};if(this.positionRender)if(this.positionRender instanceof l.default.Rect){let t=this.positionRender.width()/2;this.positionRender.position({x:e.x-t,y:e.y-t})}else this.positionRender.position(e);let r=this.stage.getAbsoluteTransform().point(n),i={x:this.stage.width()/2,y:this.stage.height()/2},a=i.x-r.x,o=i.y-r.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),t||this.settings.instantMapMove?(this.stage.position({x:this.stage.x()+a,y:this.stage.y()+o}),this.scheduleRoomCulling()):(this.currentTransition=new l.default.Tween({node:this.stage,x:this.stage.x()+a,y:this.stage.y()+o,duration:.2,easing:l.default.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>this.scheduleRoomCulling()}),this.currentTransition.play())}centerOnRoomView(e,t=!1){let n={x:e.x,y:e.y},r=this.stage.getAbsoluteTransform().point(n),i={x:this.stage.width()/2,y:this.stage.height()/2},a=i.x-r.x,o=i.y-r.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),t||this.settings.instantMapMove?(this.stage.position({x:this.stage.x()+a,y:this.stage.y()+o}),this.scheduleRoomCulling(),this.emitPanEvent()):(this.currentTransition=new l.default.Tween({node:this.stage,x:this.stage.x()+a,y:this.stage.y()+o,duration:.2,easing:l.default.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>{this.scheduleRoomCulling(),this.emitPanEvent()}}),this.currentTransition.play())}getEffectiveBounds(e,t){return this.settings.uniformLevelSize?e.getFullBounds():t.getBounds()}renderAreaName(e,t){if(!this.settings.areaName)return;let n=e.getAreaName();if(!n)return;let r=this.getEffectiveBounds(e,t);this.roomLayer.add(new l.default.Text({x:r.minX-3.5,y:r.minY-4.5,text:n,fontSize:2.5,fontFamily:this.settings.fontFamily,fill:`white`,listening:!1,perfectDrawEnabled:!1}))}renderRooms(e){e.forEach(e=>{let t=new l.default.Group({x:e.x-this.settings.roomSize/2,y:e.y-this.settings.roomSize/2,listening:!1}),n=this.mapReader.getColorValue(e.env),r=this.settings.coloredMode?K(n,.7):this.settings.frameMode?this.settings.backgroundColor:n,i=this.settings.frameMode||this.settings.coloredMode?n:this.settings.lineColor,a=this.settings.borders?this.settings.lineWidth:0,o=this.settings.roomShape===`circle`?new l.default.Circle({x:this.settings.roomSize/2,y:this.settings.roomSize/2,radius:this.settings.roomSize/2,fill:r,strokeWidth:a,stroke:i,perfectDrawEnabled:!1,listening:!1}):new l.default.Rect({x:0,y:0,width:this.settings.roomSize,height:this.settings.roomSize,fill:r,strokeWidth:a,stroke:i,cornerRadius:this.settings.roomShape===`roundedRectangle`?this.settings.roomSize*.2:0,perfectDrawEnabled:!1,listening:!1});if(t.add(o),this.settings.emboss&&this.settings.roomShape!==`circle`){let e=this.settings.roomSize,n=G(this.settings.lineColor)>.41;t.add(new l.default.Line({points:n?[0,0,e,0,e,e]:[0,0,0,e,e,e],stroke:n?`#000000`:`#ffffff`,strokeWidth:this.settings.lineWidth,perfectDrawEnabled:!1,listening:!1}))}this.renderSymbol(e,t),this.roomLayer.add(t),this.exitRenderer.renderSpecialExits(e).forEach(e=>{this.linkLayer.add(e)}),this.exitRenderer.getSpecialExitAreaTargets(e).forEach(e=>{this.areaExitHitZones.push(e)});let s=e.x-this.settings.roomSize/2,c=e.y-this.settings.roomSize/2;this.exitRenderer.renderStubs(e).forEach(e=>{let n=e.points();for(let e=0;e<n.length;e+=2)n[e]-=s,n[e+1]-=c;e.points(n),t.add(e)}),this.exitRenderer.renderInnerExits(e).forEach(e=>{e.position({x:-s,y:-c}),t.add(e)});let u={room:e,group:t};this.roomNodes.set(e.id,u),this.addRoomToSpatialIndex(u)})}scheduleRoomCulling(){this.cullingScheduled||(this.cullingScheduled=!0,window.requestAnimationFrame(()=>{this.cullingScheduled=!1,this.updateRoomCulling()}))}updateRoomCulling(){if(this.roomNodes.size===0&&this.standaloneExitNodes.length===0)return;let e=this.stage.scaleX();if(!e)return;this.syncPerfMonitor();let t=this.settings.perfCallback?performance.now():0,n=this.stage.position(),r=this.settings.roomSize/2,i=this.settings.cullingBounds,a=i?i.x:0,o=i?i.x+i.width:this.stage.width(),s=i?i.y:0,c=i?i.y+i.height:this.stage.height(),l=Math.min(a,o),u=Math.max(a,o),d=Math.min(s,c),f=Math.max(s,c),p=(l-n.x)/e,m=(u-n.x)/e,h=(d-n.y)/e,g=(f-n.y)/e,_=!1,v=!1,y=this.settings.cullingEnabled?this.settings.cullingMode??`indexed`:`none`,b=p-r,x=m+r,S=h-r,C=g+r;if(this.refreshStandaloneExitBoundsIfNeeded(),y===`none`){if(this.roomNodes.forEach(e=>{e.group.visible()||(e.group.visible(!0),_=!0)}),this.visibleExitDrawData.length!==this.standaloneExitNodes.length){this.visibleExitDrawData.length=0;for(let e of this.standaloneExitNodes)this.visibleExitDrawData.push(e.data);v=!0}_&&this.roomLayer.batchDraw(),v&&this.linkLayer.batchDraw(),this.visibleRooms.clear(),this.roomNodes.forEach(e=>this.visibleRooms.add(e)),this.visibleStandaloneExitNodes.clear(),this.standaloneExitNodes.forEach(e=>this.visibleStandaloneExitNodes.add(e));return}if(y===`basic`){let e=this.bufferRoomSet;e.clear(),this.roomNodes.forEach(t=>{let n=t.room.x-r,i=t.room.x+r,a=t.room.y-r,o=t.room.y+r,s=i>=p&&n<=m&&o>=h&&a<=g;t.group.visible()!==s&&(t.group.visible(s),_=!0),s&&e.add(t)});let t=this.bufferExitSet;t.clear();let n=!1;this.standaloneExitNodes.forEach(e=>{let{bounds:r}=e,i=r.x,a=r.x+r.width,o=r.y,s=r.y+r.height;a>=p&&i<=m&&s>=h&&o<=g&&(t.add(e),this.visibleStandaloneExitNodes.has(e)||(n=!0))}),!n&&t.size!==this.visibleStandaloneExitNodes.size&&(n=!0),this.bufferRoomSet=this.visibleRooms,this.visibleRooms=e,this.bufferExitSet=this.visibleStandaloneExitNodes,this.visibleStandaloneExitNodes=t,n&&(this.visibleExitDrawData.length=0,this.visibleStandaloneExitNodes.forEach(e=>this.visibleExitDrawData.push(e.data)),v=!0),_&&this.roomLayer.batchDraw(),v&&this.linkLayer.batchDraw();return}let w=this.collectRoomCandidates(b,S,x,C),T=this.bufferRoomSet;T.clear(),w.forEach(e=>{let t=e.room.x-r,n=e.room.x+r,i=e.room.y-r,a=e.room.y+r,o=n>=p&&t<=m&&a>=h&&i<=g;e.group.visible()!==o&&(e.group.visible(o),_=!0),o&&T.add(e)}),this.visibleRooms.forEach(e=>{w.has(e)||e.group.visible()&&(e.group.visible(!1),_=!0)}),this.bufferRoomSet=this.visibleRooms,this.visibleRooms=T;let E=this.collectStandaloneExitCandidates(b,S,x,C),D=this.bufferExitSet;D.clear();let O=!1;E.forEach(e=>{let{bounds:t}=e,n=t.x,r=t.x+t.width,i=t.y,a=t.y+t.height;r>=p&&n<=m&&a>=h&&i<=g&&(D.add(e),this.visibleStandaloneExitNodes.has(e)||(O=!0))}),!O&&D.size!==this.visibleStandaloneExitNodes.size&&(O=!0),this.bufferExitSet=this.visibleStandaloneExitNodes,this.visibleStandaloneExitNodes=D,O&&(this.visibleExitDrawData.length=0,this.visibleStandaloneExitNodes.forEach(e=>this.visibleExitDrawData.push(e.data)),v=!0),_&&this.roomLayer.batchDraw(),v&&this.linkLayer.batchDraw();let k=this.settings.perfCallback?performance.now():0;if(this.renderGrid(),this.settings.perfCallback){let e=performance.now()-k,n=performance.now()-t;this.perfMonitor.record({cullingMs:n,gridMs:e,visibleRooms:this.visibleRooms.size,totalRooms:this.roomNodes.size,visibleExits:this.visibleStandaloneExitNodes.size,fps:this.perfMonitor.computeFps()})}}syncPerfMonitor(){this.perfMonitor.setCallback(this.settings.perfCallback)}invalidateGridCache(){this.cachedGridBounds=null}renderGrid(){if(!this.settings.gridEnabled){this.cachedGridBounds!==null&&(this.gridLayer.destroyChildren(),this.gridLayer.batchDraw(),this.cachedGridBounds=null);return}let e=this.stage.scaleX();if(!e)return;let t=this.stage.position(),n=this.stage.width(),r=this.stage.height(),i=(0-t.x)/e,a=(n-t.x)/e,o=(0-t.y)/e,s=(r-t.y)/e,c=this.settings.gridSize*2,u=Math.floor((Math.min(i,a)-c)/this.settings.gridSize)*this.settings.gridSize,d=Math.ceil((Math.max(i,a)+c)/this.settings.gridSize)*this.settings.gridSize,f=Math.floor((Math.min(o,s)-c)/this.settings.gridSize)*this.settings.gridSize,p=Math.ceil((Math.max(o,s)+c)/this.settings.gridSize)*this.settings.gridSize,m=this.cachedGridBounds;if(!(m&&m.left===u&&m.right===d&&m.top===f&&m.bottom===p)){this.gridLayer.destroyChildren();for(let e=u;e<=d;e+=this.settings.gridSize)this.gridLayer.add(new l.default.Line({points:[e,f,e,p],stroke:this.settings.gridColor,strokeWidth:this.settings.gridLineWidth,listening:!1,perfectDrawEnabled:!1}));for(let e=f;e<=p;e+=this.settings.gridSize)this.gridLayer.add(new l.default.Line({points:[u,e,d,e],stroke:this.settings.gridColor,strokeWidth:this.settings.gridLineWidth,listening:!1,perfectDrawEnabled:!1}));this.cachedGridBounds={left:u,right:d,top:f,bottom:p},this.gridLayer.batchDraw()}}clearCurrentRoomOverlay(){this.currentRoomOverlay.forEach(e=>e.destroy()),this.currentRoomOverlay=[],this.positionLayer.batchDraw()}updateCurrentRoomOverlay(e){if(this.clearCurrentRoomOverlay(),e.area!==this.currentArea||e.z!==this.currentZIndex){this.positionLayer.batchDraw();return}let t=new Map;t.set(e.id,e);let n=[],r=this.currentAreaInstance instanceof O?this.currentAreaInstance:void 0;this.currentAreaInstance&&this.currentZIndex!==void 0&&this.currentAreaInstance.getLinkExits(this.currentZIndex).filter(t=>t.a===e.id||t.b===e.id).forEach(e=>{let t=this.settings.highlightCurrentRoom?this.exitRenderer.renderWithColor(e,W,this.currentZIndex):this.exitRenderer.render(e,this.currentZIndex);t&&n.push(t)});let i=this.settings.highlightCurrentRoom?W:void 0;this.exitRenderer.renderSpecialExits(e,i).forEach(e=>{n.push(e)}),(this.settings.highlightCurrentRoom?this.exitRenderer.renderStubs(e,W):this.exitRenderer.renderStubs(e)).forEach(e=>{n.push(e)}),[...Object.values(e.exits),...Object.values(e.specialExits)].forEach(e=>{let n=this.mapReader.getRoom(e),i=!r||r.hasVisitedRoom(e);n&&n.area===this.currentArea&&n.z===this.currentZIndex&&i&&t.set(e,n)}),n.forEach(e=>{this.positionLayer.add(e),this.currentRoomOverlay.push(e)}),t.forEach((t,n)=>{let r=n===e.id,i=this.createOverlayRoomGroup(t,{stroke:r&&this.settings.highlightCurrentRoom?W:this.settings.lineColor});this.positionLayer.add(i),this.currentRoomOverlay.push(i),this.exitRenderer.renderInnerExits(t).forEach(e=>{this.positionLayer.add(e),this.currentRoomOverlay.push(e)})}),this.positionRender&&this.positionRender.moveToTop(),this.positionLayer.batchDraw()}createOverlayRoomGroup(e,t){let n=new l.default.Group({x:e.x-this.settings.roomSize/2,y:e.y-this.settings.roomSize/2,listening:!1}),r=this.mapReader.getColorValue(e.env),i=this.settings.coloredMode?K(r,.5):this.settings.frameMode?this.settings.backgroundColor:r,a=this.settings.frameMode||this.settings.coloredMode?r:t.stroke,o=this.settings.borders?this.settings.lineWidth:0,s=this.settings.roomShape===`circle`?new l.default.Circle({x:this.settings.roomSize/2,y:this.settings.roomSize/2,radius:this.settings.roomSize/2,fill:i,stroke:a,strokeWidth:o}):new l.default.Rect({x:0,y:0,width:this.settings.roomSize,height:this.settings.roomSize,fill:i,stroke:a,strokeWidth:o,cornerRadius:this.settings.roomShape===`roundedRectangle`?this.settings.roomSize*.2:0});if(n.add(s),this.settings.emboss&&this.settings.roomShape!==`circle`){let e=this.settings.roomSize,t=G(this.settings.lineColor)>.41;n.add(new l.default.Line({points:t?[0,0,e,0,e,e]:[0,0,0,e,e,e],stroke:t?`#000000`:`#ffffff`,strokeWidth:this.settings.lineWidth,perfectDrawEnabled:!1,listening:!1}))}return this.renderSymbol(e,n),n}getSymbolColor(e,t){return this.settings.frameMode?this.mapReader.getColorValue(e):this.mapReader.getSymbolColor(e,t)}renderSymbol(e,t){if(e.roomChar!==void 0){let n=this.settings.roomSize*.75,r=R(e.roomChar,this.settings.fontFamily),i=R(`M`,this.settings.fontFamily),a=new l.default.Text({x:0,y:0,text:e.roomChar,fontSize:n,fontStyle:`bold`,fill:this.getSymbolColor(e.env),align:`center`,verticalAlign:`middle`,width:this.settings.roomSize,height:this.settings.roomSize,offsetY:(i-r)*n,perfectDrawEnabled:!1,listening:!1});t.add(a)}}renderExits(e){e.forEach(e=>{let t=this.exitRenderer.renderData(e,this.currentZIndex);if(!t)return;let n={data:t,bounds:t.bounds,targetRoomId:t.targetRoomId};this.standaloneExitNodes.push(n),this.addStandaloneExitToSpatialIndex(n),t.targetRoomId!==void 0&&this.areaExitHitZones.push({bounds:t.bounds,targetRoomId:t.targetRoomId})}),this.standaloneExitBoundsRoomSize=this.settings.roomSize,this.exitBatchShape=new l.default.Shape({listening:!1,perfectDrawEnabled:!1,sceneFunc:e=>{let t=e._context;for(let e of this.visibleExitDrawData)this.drawExitData(t,e)}}),this.linkLayer.add(this.exitBatchShape)}drawExitData(e,t){for(let n of t.lines){e.beginPath(),e.moveTo(n.points[0],n.points[1]);for(let t=2;t<n.points.length;t+=2)e.lineTo(n.points[t],n.points[t+1]);e.strokeStyle=n.stroke,e.lineWidth=n.strokeWidth,n.dash?e.setLineDash(n.dash):e.setLineDash([]),e.stroke()}for(let n of t.arrows){e.beginPath(),e.moveTo(n.points[0],n.points[1]);for(let t=2;t<n.points.length;t+=2)e.lineTo(n.points[t],n.points[t+1]);e.strokeStyle=n.stroke,e.lineWidth=n.strokeWidth,n.dash?e.setLineDash(n.dash):e.setLineDash([]),e.stroke();let t=n.points.length-2,r=n.points[t],i=n.points[t+1],a=n.points[t-2],o=n.points[t-1],s=Math.atan2(i-o,r-a),c=n.pointerLength,l=n.pointerWidth/2;e.beginPath(),e.setLineDash([]),e.moveTo(r,i),e.lineTo(r-c*Math.cos(s-Math.atan2(l,c)),i-c*Math.sin(s-Math.atan2(l,c))),e.lineTo(r-c*Math.cos(s+Math.atan2(l,c)),i-c*Math.sin(s+Math.atan2(l,c))),e.closePath(),e.fillStyle=n.fill,e.fill(),e.strokeStyle=n.stroke,e.lineWidth=n.strokeWidth,e.stroke()}for(let n of t.doors)e.beginPath(),e.rect(n.x,n.y,n.width,n.height),e.strokeStyle=n.stroke,e.lineWidth=n.strokeWidth,e.setLineDash([]),e.stroke()}renderLabels(e){this.settings.labelRenderMode!==`none`&&e.forEach(e=>{if(this.settings.labelRenderMode===`image`){if(!e.pixMap)return;let t=new Image;t.src=`data:image/png;base64,${e.pixMap}`;let n=new l.default.Image({x:e.X,y:-e.Y,width:e.Width,height:e.Height,image:t,listening:!1});this.linkLayer.add(n);return}this.renderLabelAsData(e)})}renderLabelAsData(e){let t=new l.default.Group({listening:!1}),n=new l.default.Rect({x:e.X,y:-e.Y,width:e.Width,height:e.Height,listening:!1});(e.BgColor?.alpha??0)>0&&!this.settings.transparentLabels?n.fill(this.getLabelColor(e.BgColor)):n.fillEnabled(!1),t.add(n);let r=Math.min(.75,e.Width/Math.max(e.Text.length/2,1)),i=Math.max(.1,Math.min(r,Math.max(e.Height*.9,.1))),a=new l.default.Text({x:e.X,y:-e.Y,width:e.Width,height:e.Height,text:e.Text,fontSize:i,fillEnabled:!0,fill:this.getLabelColor(e.FgColor),align:`center`,verticalAlign:`middle`,listening:!1});t.add(a),this.linkLayer.add(t)}getLabelColor(e){let t=(e?.alpha??255)/255,n=e=>Math.min(255,Math.max(0,e??0));return`rgba(${n(e?.r)}, ${n(e?.g)}, ${n(e?.b)}, ${t})`}},Y={rgb:[114,1,0],rgbValue:`rgb(114, 1, 0)`,symbolColor:[225,225,225],symbolColorValue:`rgb(225,225,225)`};function X(e){let t=e[0]/255,n=e[1]/255,r=e[2]/255;return(Math.max(t,n,r)+Math.min(t,n,r))/2}var he=class{constructor(e,t){this.rooms={},this.areas={},this.areaSources={},this.explorationEnabled=!1,this.colors={},e.forEach(e=>{e.rooms.forEach(e=>{e.y=-e.y,this.rooms[e.id]=e});let t=parseInt(e.areaId);this.areas[t]=new E(e),this.areaSources[t]=e}),this.colors=t.reduce((e,t)=>({...e,[t.envId]:{rgb:t.colors,rgbValue:`rgb(${t.colors.join(`,`)})`,symbolColor:X(t.colors)>.41?[25,25,25]:[225,255,255],symbolColorValue:X(t.colors)>.41?`rgb(25,25,25)`:`rgb(225,255,255)`}}),{})}getArea(e){return this.areas[e]}getExplorationArea(e){let t=this.areas[e];if(t instanceof O)return t}getAreas(){return Object.values(this.areas)}getRooms(){return Object.values(this.rooms)}getRoom(e){return this.rooms[e]}ensureVisitedRooms(){return this.visitedRooms||=new Set,this.visitedRooms}applyExplorationDecoration(){this.visitedRooms&&Object.entries(this.areaSources).forEach(([e,t])=>{let n=parseInt(e,10);this.areas[n]=new O(t,this.visitedRooms)})}decorateWithExploration(e){return e===void 0?this.ensureVisitedRooms():this.setVisitedRooms(e),this.applyExplorationDecoration(),this.explorationEnabled=!0,this.visitedRooms}getVisitedRooms(){return this.visitedRooms}clearExplorationDecoration(){Object.entries(this.areaSources).forEach(([e,t])=>{let n=parseInt(e,10);this.areas[n]=new E(t)}),this.explorationEnabled=!1}isExplorationEnabled(){return this.explorationEnabled}setVisitedRooms(e){return this.visitedRooms=e instanceof Set?e:new Set(e),this.explorationEnabled&&this.applyExplorationDecoration(),this.visitedRooms}addVisitedRoom(e){if(this.explorationEnabled){let t=this.getRoom(e);if(t){let n=this.getExplorationArea(t.area);if(n)return n.addVisitedRoom(e)}}let t=this.ensureVisitedRooms(),n=t.has(e);return t.add(e),!n}addVisitedRooms(e){let t=this.ensureVisitedRooms(),n=0;for(let r of e){if(this.explorationEnabled){let e=this.getRoom(r);if(e){let t=this.getExplorationArea(e.area);if(t){t.addVisitedRoom(r)&&n++;continue}}}let e=t.has(r);t.add(r),e||n++}return n}hasVisitedRoom(e){return this.visitedRooms?.has(e)??!1}getColorValue(e){return this.colors[e]?.rgbValue??Y.rgbValue}getSymbolColor(e,t){let n=this.colors[e]?.symbolColor??Y.symbolColor,r=Math.min(Math.max(t??1,0),1),i=n.join(`,`);return r==1?`rgba(${i})`:`rgba(${i}, ${r})`}},ge=o(((e,t)=>{t.exports=class{constructor(){this.keys=new Set,this.queue=[]}sort(){this.queue.sort((e,t)=>e.priority-t.priority)}set(e,t){let n=Number(t);if(isNaN(n))throw TypeError(`"priority" must be a number`);return this.keys.has(e)?this.queue.map(t=>(t.key===e&&Object.assign(t,{priority:n}),t)):(this.keys.add(e),this.queue.push({key:e,priority:n})),this.sort(),this.queue.length}next(){let e=this.queue.shift();return this.keys.delete(e.key),e}isEmpty(){return this.queue.length===0}has(e){return this.keys.has(e)}get(e){return this.queue.find(t=>t.key===e)}}})),_e=o(((e,t)=>{function n(e,t){let r=new Map;for(let[i,a]of e)i!==t&&a instanceof Map?r.set(i,n(a,t)):i!==t&&r.set(i,a);return r}t.exports=n})),ve=o(((e,t)=>{function n(e){let t=Number(e);return!(isNaN(t)||t<=0)}function r(e){let t=new Map;return Object.keys(e).forEach(i=>{let a=e[i];if(typeof a==`object`&&a&&!Array.isArray(a))return t.set(i,r(a));if(!n(a))throw Error(`Could not add node at key "${i}", make sure it's a valid node`,a);return t.set(i,Number(a))}),t}t.exports=r})),ye=o(((e,t)=>{function n(e){if(!(e instanceof Map))throw Error(`Invalid graph: Expected Map instead found ${typeof e}`);e.forEach((e,t)=>{if(typeof e==`object`&&e instanceof Map){n(e);return}if(typeof e!=`number`||e<=0)throw Error(`Values must be numbers greater than 0. Found value ${e} at ${t}`)})}t.exports=n})),be=c(o(((e,t)=>{var n=ge(),r=_e(),i=ve(),a=ye();t.exports=class{constructor(e){e instanceof Map?(a(e),this.graph=e):e?this.graph=i(e):this.graph=new Map}addNode(e,t){let n;return t instanceof Map?(a(t),n=t):n=i(t),this.graph.set(e,n),this}addVertex(e,t){return this.addNode(e,t)}removeNode(e){return this.graph=r(this.graph,e),this}path(e,t,r={}){if(!this.graph.size)return r.cost?{path:null,cost:0}:null;let i=new Set,a=new n,o=new Map,s=[],c=0,l=[];if(r.avoid&&(l=[].concat(r.avoid)),l.includes(e))throw Error(`Starting node (${e}) cannot be avoided`);if(l.includes(t))throw Error(`Ending node (${t}) cannot be avoided`);for(a.set(e,0);!a.isEmpty();){let e=a.next();if(e.key===t){c=e.priority;let t=e.key;for(;o.has(t);)s.push(t),t=o.get(t);break}i.add(e.key),(this.graph.get(e.key)||new Map).forEach((t,n)=>{if(i.has(n)||l.includes(n))return null;if(!a.has(n))return o.set(n,e.key),a.set(n,e.priority+t);let r=a.get(n).priority,s=e.priority+t;return s<r?(o.set(n,e.key),a.set(n,s)):null})}return s.length?(r.trim?s.shift():s=s.concat([e]),r.reverse||(s=s.reverse()),r.cost?{path:s,cost:c}:s):r.cost?{path:null,cost:0}:null}shortestPath(...e){return this.path(...e)}}}))(),1),xe={1:`north`,2:`northeast`,3:`northwest`,4:`east`,5:`west`,6:`south`,7:`southeast`,8:`southwest`,9:`up`,10:`down`,11:`in`,12:`out`},Se={north:`n`,northeast:`ne`,northwest:`nw`,east:`e`,west:`w`,south:`s`,southeast:`se`,southwest:`sw`,up:`up`,down:`down`,in:`in`,out:`out`};function Z(e,t){e.push(t);let n=e.length-1;for(;n>0;){let t=n-1>>1;if(e[t].priority<=e[n].priority)break;[e[t],e[n]]=[e[n],e[t]],n=t}}function Ce(e){if(e.length===0)return;let t=e[0],n=e.pop();if(e.length>0){e[0]=n;let t=0,r=e.length;for(;;){let n=t,i=2*t+1,a=2*t+2;if(i<r&&e[i].priority<e[n].priority&&(n=i),a<r&&e[a].priority<e[n].priority&&(n=a),n===t)break;[e[t],e[n]]=[e[n],e[t]],t=n}}return t}function we(e,t,n){let r=[n],i=n;for(;i!==t;)i=e.get(i),r.push(i);return r.reverse(),r}function Te(e,t,n){let r=e.path(t.toString(),n.toString()),i=Array.isArray(r)?r:r?.path;return i?i.map(e=>Number(e)):null}function Ee(e,t,n,r,i,a){let o=r.getRoom(n);if(!o)return null;let s=o.x,c=o.y,l=o.z,u=e=>{let t=r.getRoom(e);if(!t)return 0;let n=t.x-s,o=t.y-c,u=t.z-l;return Math.sqrt(n*n+o*o+u*u)/i*a},d=new Map,f=new Map,p=[];for(d.set(t,0),Z(p,{id:t,priority:u(t)});p.length>0;){let{id:r}=Ce(p);if(r===n)return we(f,t,n);let i=d.get(r)??1/0,a=e.get(r);if(a)for(let e of a){let t=i+e.weight;t<(d.get(e.id)??1/0)&&(d.set(e.id,t),f.set(e.id,r),Z(p,{id:e.id,priority:t+u(e.id)}))}}return null}var De=class{constructor(e,t=`dijkstra`){this.cache=new Map,this.mapReader=e,this._algorithm=t;let{adj:n,maxEdgeDistance:r,minEdgeWeight:i,graphDefinition:a}=this.buildGraph();this.adj=n,this.graph=new be.default(a),this.maxEdgeDistance=r,this.minEdgeWeight=i}get algorithm(){return this._algorithm}setAlgorithm(e){e!==this._algorithm&&(this._algorithm=e,this.cache.clear())}findPath(e,t){let n=`${e}->${t}`;if(this.cache.has(n))return this.cache.get(n);if(e===t){let t=this.mapReader.getRoom(e)?[e]:null;return this.cache.set(n,t),t}if(!this.mapReader.getRoom(e)||!this.mapReader.getRoom(t))return this.cache.set(n,null),null;let r;switch(this._algorithm){case`dijkstra`:r=Te(this.graph,e,t);break;case`astar`:r=Ee(this.adj,e,t,this.mapReader,this.maxEdgeDistance,this.minEdgeWeight);break}return this.cache.set(n,r),r}resolveEdgeWeight(e,t,n){let r=e.exitWeights?.[t];return r!==void 0&&r>0?r:Math.max(n.weight,1)}buildGraph(){let e=new Map,t={},n=1,r=1/0;return this.mapReader.getRooms().forEach(i=>{let a=[],o={},s=new Set((i.exitLocks??[]).map(e=>xe[e]).filter(e=>!!e)),c=new Set(i.mSpecialExitLocks??[]);Object.entries(i.exits??{}).forEach(([e,t])=>{if(s.has(e))return;let c=this.mapReader.getRoom(t);if(c){let s=Se[e]??e,l=this.resolveEdgeWeight(i,s,c);a.push({id:t,weight:l}),o[t.toString()]=l,l<r&&(r=l);let u=c.x-i.x,d=c.y-i.y,f=c.z-i.z,p=Math.sqrt(u*u+d*d+f*f);p>n&&(n=p)}}),Object.entries(i.specialExits??{}).forEach(([e,t])=>{if(c.has(t))return;let s=this.mapReader.getRoom(t);if(s){let c=this.resolveEdgeWeight(i,e,s);a.push({id:t,weight:c}),o[t.toString()]=c,c<r&&(r=c);let l=s.x-i.x,u=s.y-i.y,d=s.z-i.z,f=Math.sqrt(l*l+u*u+d*d);f>n&&(n=f)}}),e.set(i.id,a),t[i.id.toString()]=o}),isFinite(r)||(r=1),{adj:e,maxEdgeDistance:n,minEdgeWeight:r,graphDefinition:t}}},Oe={1:`north`,2:`northeast`,3:`northwest`,4:`east`,5:`west`,6:`south`,7:`southeast`,8:`southwest`,9:`up`,10:`down`,11:`in`,12:`out`};function ke(){return{areaWidth:150,areaHeight:80,areaSpacing:50,fontSize:14,connectionLineWidth:2,areaFillColor:`#2a2a3e`,areaStrokeColor:`#4a4a6e`,textColor:`#e0e0e0`,connectionColor:`#6a6a8e`,highlightColor:`#ff9900`}}var Ae=class{constructor(e,t,n){this.areaNodes=new Map,this.connectionGroups=[],this.currentZoom=1,this.domainInfo=new Map,this.domainFilter=`all`,this.dotsMode=!1,this.settings=n??ke(),this.stage=new l.default.Stage({container:e,width:e.clientWidth,height:e.clientHeight,draggable:!0}),this.backgroundLayer=new l.default.Layer({listening:!1}),this.stage.add(this.backgroundLayer),this.connectionLayer=new l.default.Layer({listening:!1}),this.stage.add(this.connectionLayer),this.areaLayer=new l.default.Layer,this.stage.add(this.areaLayer),this.mapReader=t,this.initScaling(),this.initResize(e)}initResize(e){new ResizeObserver(()=>{this.stage.width(e.clientWidth),this.stage.height(e.clientHeight),this.stage.batchDraw()}).observe(e)}initScaling(){let e=1.1;this.stage.on(`wheel`,t=>{t.evt.preventDefault();let n=this.stage.scaleX(),r=this.stage.getPointerPosition();if(!r)return;let i={x:(r.x-this.stage.x())/n,y:(r.y-this.stage.y())/n},a=(t.evt.deltaY>0?-1:1)>0?this.currentZoom*e:this.currentZoom/e;if(this.setZoom(a)){let e=this.stage.scaleX(),t={x:r.x-i.x*e,y:r.y-i.y*e};this.stage.position(t),this.stage.batchDraw()}})}setZoom(e){let t=Math.max(.1,Math.min(5,e));return this.currentZoom===t?!1:(this.currentZoom=t,this.stage.scale({x:this.currentZoom,y:this.currentZoom}),!0)}getZoom(){return this.currentZoom}setDomainInfo(e){this.domainInfo.clear();for(let[t,n]of Object.entries(e))this.domainInfo.set(Number(t),n)}setDomainFilter(e){this.domainFilter=e}getDomainFilter(){return this.domainFilter}setBackgroundImage(e){this.backgroundConfig={url:e.url,x:e.x,y:e.y,width:e.width,height:e.height,opacity:e.opacity??.3}}clearBackgroundImage(){this.backgroundConfig=void 0,this.backgroundImage=void 0,this.backgroundLayer.destroyChildren(),this.backgroundLayer.batchDraw()}redrawBackground(){this.drawBackground()}setDotsMode(e){this.dotsMode=e}getDotsMode(){return this.dotsMode}redraw(){this.drawBackground(),this.drawConnections(),this.drawAreas(),this.stage.batchDraw()}isAreaInDomain(e){let t=this.domainInfo.get(e);if(!t)return this.domainFilter===`interdomain`||this.domainFilter===`all`;switch(this.domainFilter){case`ishtar`:return t.isIshtar;case`empire`:return t.isEmpire;case`interdomain`:return!t.isIshtar&&!t.isEmpire;case`all`:return!0}}areAreasInSameDomain(e,t){let n=this.domainInfo.get(e),r=this.domainInfo.get(t);return!n||!r?!1:n.isIshtar&&r.isIshtar||n.isEmpire&&r.isEmpire?!0:!n.isIshtar&&!n.isEmpire&&!r.isIshtar&&!r.isEmpire}render(){this.analyzeConnections(),this.layoutAreas(),this.drawBackground(),this.drawConnections(),this.drawAreas(),this.centerView(),this.stage.batchDraw()}drawBackground(){if(this.backgroundLayer.destroyChildren(),!this.backgroundConfig)return;let e=new Image;e.crossOrigin=`anonymous`,e.onload=()=>{this.backgroundImage=new l.default.Image({x:this.backgroundConfig.x,y:this.backgroundConfig.y,image:e,width:this.backgroundConfig.width,height:this.backgroundConfig.height,opacity:this.backgroundConfig.opacity,listening:!1}),this.backgroundLayer.add(this.backgroundImage),this.backgroundLayer.batchDraw()},e.onerror=()=>{console.error(`Failed to load background image:`,this.backgroundConfig?.url)},e.src=this.backgroundConfig.url}analyzeConnections(){this.areaNodes.clear(),this.connectionGroups=[];let e=this.mapReader.getRooms(),t=this.mapReader.getAreas(),n=new Map;for(let e of t){let t=e.getAreaId(),r=e.getRooms();if(r.length===0)continue;let i=1/0,a=-1/0,o=1/0,s=-1/0,c=0;for(let e of r)e.z===0&&(c++,i=Math.min(i,e.x),a=Math.max(a,e.x),o=Math.min(o,e.y),s=Math.max(s,e.y));if(c===0)for(let e of r)i=Math.min(i,e.x),a=Math.max(a,e.x),o=Math.min(o,e.y),s=Math.max(s,e.y);let l=(i+a)/2,u=(o+s)/2;n.set(t,{minX:i,maxX:a,minY:o,maxY:s,centerX:l,centerY:u,roomCount:r.length})}let r=1;for(let e of n.values()){let t=e.maxX-e.minX,n=e.maxY-e.minY;r=Math.max(r,t,n)}let i=200/r;for(let e of t){let t=e.getAreaId(),r=n.get(t);if(!r||!this.isAreaInDomain(t))continue;let a=r.maxX-r.minX,o=r.maxY-r.minY,s=Math.max(100,a*i),c=Math.max(100,o*i),l=s/c;l>3?c=s/3:l<1/3&&(s=c/3),this.areaNodes.set(t,{areaId:t,name:e.getAreaName(),x:0,y:0,width:s,height:c,connections:[],roomCount:r.roomCount,realCenterX:r.centerX,realCenterY:r.centerY})}let a=new Map;for(let t of e){let e=t.area;if(!this.areaNodes.has(e))continue;let n=this.getLockedDirections(t),r=new Set(t.mSpecialExitLocks??[]);for(let[r,i]of Object.entries(t.exits??{})){if(n.has(r))continue;let o=this.mapReader.getRoom(i);if(!o||o.area===e||!this.areaNodes.has(o.area)||!this.areAreasInSameDomain(e,o.area))continue;let s=this.createConnection(t,o,r);s&&this.addConnection(a,s)}for(let[n,i]of Object.entries(t.specialExits??{})){if(r.has(i))continue;let o=this.mapReader.getRoom(i);if(!o||o.area===e||!this.areaNodes.has(o.area)||!this.areAreasInSameDomain(e,o.area))continue;let s=this.parseDirection(n),c=this.createConnection(t,o,s);c&&this.addConnection(a,c)}}for(let[e,t]of a){let[n,r]=e.split(`-`).map(Number),i=this.createConnectionGroup(n,r,t);this.connectionGroups.push(i);let a=this.areaNodes.get(n),o=this.areaNodes.get(r);if(a&&a.connections.push(...t),o)for(let e of t)o.connections.push({...e,fromAreaId:e.toAreaId,toAreaId:e.fromAreaId,fromRoomId:e.toRoomId,toRoomId:e.fromRoomId,direction:e.direction?h[e.direction]:null,fromRoomPosition:e.toRoomPosition,toRoomPosition:e.fromRoomPosition})}}getLockedDirections(e){return new Set((e.exitLocks??[]).map(e=>Oe[e]).filter(e=>!!e))}createConnection(e,t,n){let r=this.toPlanarDirection(n);return{fromAreaId:e.area,toAreaId:t.area,fromRoomId:e.id,toRoomId:t.id,direction:r,fromRoomPosition:{x:e.x,y:e.y},toRoomPosition:{x:t.x,y:t.y}}}addConnection(e,t){let n=t.fromAreaId<t.toAreaId?`${t.fromAreaId}-${t.toAreaId}`:`${t.toAreaId}-${t.fromAreaId}`;e.has(n)||e.set(n,[]),e.get(n).push(t)}createConnectionGroup(e,t,n){let r=new Map,i=0,a=0;for(let e of n)e.direction&&r.set(e.direction,(r.get(e.direction)??0)+1),i+=e.toRoomPosition.x-e.fromRoomPosition.x,a+=e.toRoomPosition.y-e.fromRoomPosition.y;let o=null,s=0;for(let[e,t]of r)t>s&&(s=t,o=e);return{fromAreaId:e,toAreaId:t,connections:n,primaryDirection:o,averageOffset:{x:i/n.length,y:a/n.length}}}parseDirection(e){return{n:`north`,north:`north`,s:`south`,south:`south`,e:`east`,east:`east`,w:`west`,west:`west`,ne:`northeast`,northeast:`northeast`,nw:`northwest`,northwest:`northwest`,se:`southeast`,southeast:`southeast`,sw:`southwest`,southwest:`southwest`,u:`up`,up:`up`,d:`down`,down:`down`,i:`in`,in:`in`,o:`out`,out:`out`}[e.toLowerCase().trim()]??null}toPlanarDirection(e){return e&&m.includes(e)?e:null}layoutAreas(){if(Array.from(this.areaNodes.values()).length===0)return;let e=this.findConnectedComponents(),t=0,n=this.settings.areaWidth*3;for(let r of e)if(r.length===1){let e=this.areaNodes.get(r[0]);e&&(e.x=t,e.y=0),t+=this.settings.areaWidth+n}else{let e=this.forceDirectedLayout(r);for(let n of r){let r=this.areaNodes.get(n);r&&isFinite(e.minX)&&isFinite(e.minY)&&(r.x-=e.minX,r.x+=t,r.y-=e.minY)}let i=isFinite(e.maxX-e.minX)?e.maxX-e.minX:this.settings.areaWidth;t+=i+n}}findConnectedComponents(){let e=new Set,t=[];for(let[n]of this.areaNodes){if(e.has(n))continue;let r=[],i=[n];for(;i.length>0;){let t=i.shift();if(e.has(t))continue;e.add(t),r.push(t);let n=this.areaNodes.get(t);if(n)for(let t of n.connections)e.has(t.toAreaId)||i.push(t.toAreaId)}t.push(r)}return t}forceDirectedLayout(e){let t=new Map;for(let n of e){let e=this.areaNodes.get(n);if(!e)continue;let r=new Set(e.connections.map(e=>e.toAreaId));t.set(n,r)}let n=new Set,r=new Set;for(let[e,r]of t)r.size>=3&&n.add(e);for(let[e,i]of t){if(n.has(e)||r.has(e)||i.size>2)continue;let a=[e];r.add(e);let o=Array.from(i);for(let i of o){let o=i,s=e;for(;o&&!r.has(o)&&!n.has(o);){let e=t.get(o);if(!e)break;if(e.size>=3){n.add(o);break}a.push(o),r.add(o);let i=!1;for(let t of e)if(t!==s&&!r.has(t)){s=o,o=t,i=!0;break}if(!i)break}}let s=!1;for(let e of a){let r=t.get(e);if(r){for(let e of r)if(n.has(e)){s=!0;break}}if(s)break}if(!s&&a.length>0){let e=a[0],i=t.get(a[0])?.size??0;for(let n of a){let r=t.get(n)?.size??0;r>i&&(i=r,e=n)}n.add(e),r.delete(e)}}for(let r of e){let e=t.get(r);(!e||e.size===0)&&n.add(r)}let i=new Map,a=new Map;for(let e of n)i.set(e,e),a.set(e,[]);let o=new Set(n);for(let e of n){let n=t.get(e)??new Set;for(let r of n){if(o.has(r))continue;let n=[],s=r,c=e;for(;s&&!o.has(s);){n.push(s),i.set(s,e),o.add(s);let r=t.get(s)??new Set,a;for(let e of r)if(e!==c&&!o.has(e)){a=e;break}c=s,s=a}n.length>0&&a.get(e).push(n)}}let s=new Set,c=[],l=n.values().next().value,u=l===void 0?e[0]:l;if(u!==void 0){let e=this.areaNodes.get(u);e&&(e.x=0,e.y=0,s.add(u),c.push(u))}for(;c.length>0;){let e=c.shift(),t=this.areaNodes.get(e),r=new Map;for(let e of t.connections){let t=e.toAreaId;if(s.has(t)||!n.has(t))continue;let i=this.areaNodes.get(t);if(!i)continue;let a=e.direction??`none`;r.has(a)||r.set(a,[]),r.get(a).push({id:t,node:i,conn:e})}for(let[e,n]of r){let r=this.getDirectionOffset(e===`none`?null:e);n.sort((e,t)=>Math.abs(r.x)>Math.abs(r.y)?t.node.realCenterY-e.node.realCenterY:e.node.realCenterX-t.node.realCenterX);let i=this.settings.areaWidth+this.settings.areaSpacing,a=this.settings.areaHeight+this.settings.areaSpacing;n.forEach((e,o)=>{if(e.node.x=t.x+r.x*i,e.node.y=t.y+r.y*a,n.length>1){let t=(o-(n.length-1)/2)*.5;Math.abs(r.x)>Math.abs(r.y)?e.node.y+=t*a:e.node.x+=t*i}s.add(e.id),c.push(e.id)})}}let d=Array.from(n);d.length>1&&this.applyForces(d,80);let f=this.settings.areaWidth+this.settings.areaSpacing+30,p=this.settings.areaHeight+this.settings.areaSpacing+30,m=new Map,h=[`east`,`west`,`north`,`south`,`northeast`,`northwest`,`southeast`,`southwest`];for(let[e,t]of a){let n=this.areaNodes.get(e);if(!n)continue;let r=0,i=new Map;for(let a of t){let t=e,o=n.x,s=n.y,c=null;for(let l of a){let a=this.areaNodes.get(l);if(!a)continue;let u=this.areaNodes.get(t),d=null;if(u){for(let e of u.connections)if(e.toAreaId===l){d=e.direction;break}}!d&&t===e?(c=h[r%h.length],r++,d=c):!d&&c&&(d=c);let g=this.getDirectionOffset(d),_=0;if(t===e&&d){let e=d,t=i.get(e)??0;i.set(e,t+1),_=t}if(a.x=o+g.x*f,a.y=s+g.y*p,_>0){let e=1.2;g.x!==0&&g.y===0?a.y+=_*p*e:g.y!==0&&g.x===0?a.x+=_*f*e:(a.x+=_*f*e,a.y-=_*p*e)}m.set(l,{dx:a.x-n.x,dy:a.y-n.y,hubId:e}),t=l,o=a.x,s=a.y}}}let g=new Map,_=new Map;for(let e of n){let t=this.areaNodes.get(e);if(!t)continue;let n=t.x,r=t.y,i=t.x+t.width,o=t.y+t.height,s=a.get(e)??[];for(let e of s)for(let t of e){let e=this.areaNodes.get(t);e&&(n=Math.min(n,e.x),r=Math.min(r,e.y),i=Math.max(i,e.x+e.width),o=Math.max(o,e.y+e.height))}g.set(e,{minX:n,minY:r,maxX:i,maxY:o}),_.set(e,{dx:n-t.x,dy:r-t.y})}this.applyClusterForces(d,g,_,60);for(let[e,t]of m){let n=this.areaNodes.get(e),r=this.areaNodes.get(t.hubId);!n||!r||(n.x=r.x+t.dx,n.y=r.y+t.dy)}let v=1/0,y=1/0,b=-1/0,x=-1/0;for(let t of e){let e=this.areaNodes.get(t);v=Math.min(v,e.x),y=Math.min(y,e.y),b=Math.max(b,e.x+e.width),x=Math.max(x,e.y+e.height)}return{minX:v,minY:y,maxX:b,maxY:x}}getDirectionOffset(e){let t={north:{x:0,y:-1},south:{x:0,y:1},east:{x:1,y:0},west:{x:-1,y:0},northeast:{x:.75,y:-.75},northwest:{x:-.75,y:-.75},southeast:{x:.75,y:.75},southwest:{x:-.75,y:.75}};return e&&t[e]?t[e]:{x:1,y:0}}applyClusterForces(e,t,n,r){let i=.8,a=new Map;for(let t of e)a.set(t,{vx:0,vy:0});for(let o=0;o<r;o++){for(let r of e){let e=this.areaNodes.get(r),i=t.get(r),a=n.get(r);if(!e||!i||!a)continue;let o=i.maxX-i.minX,s=i.maxY-i.minY;i.minX=e.x+a.dx,i.minY=e.y+a.dy,i.maxX=i.minX+o,i.maxY=i.minY+s}for(let n of e){let r=this.areaNodes.get(n),i=a.get(n),o=t.get(n);if(!(!r||!i||!o)){for(let r of e){if(n===r)continue;let e=t.get(r);if(!e)continue;let a=(o.minX+o.maxX)/2,s=(o.minY+o.maxY)/2,c=(e.minX+e.maxX)/2,l=(e.minY+e.maxY)/2,u=a-c,d=s-l,f=(o.maxX-o.minX)/2,p=(o.maxY-o.minY)/2,m=(e.maxX-e.minX)/2,h=(e.maxY-e.minY)/2,g=f+m+50,_=p+h+50,v=g-Math.abs(u),y=_-Math.abs(d);if(v>0&&y>0)if(v<y){let e=v*(u>=0?1:-1)*.5;i.vx+=e}else{let e=y*(d>=0?1:-1)*.5;i.vy+=e}}for(let t of r.connections){let n=this.areaNodes.get(t.toAreaId);if(!n||!e.includes(t.toAreaId))continue;let a=n.x-r.x,o=n.y-r.y,s=Math.sqrt(a*a+o*o)||1,c=(s-(this.settings.areaWidth+this.settings.areaSpacing+50))*.015;i.vx+=a/s*c,i.vy+=o/s*c}}}for(let t of e){let e=this.areaNodes.get(t),n=a.get(t);!e||!n||(e.x+=n.vx,e.y+=n.vy,n.vx*=i,n.vy*=i)}}}applyForces(e,t){let n=.8,r=this.settings.areaWidth+this.settings.areaSpacing,i=this.settings.areaWidth/2+60,a=new Set(e),o=[],s=new Set;for(let t of e){let e=this.areaNodes.get(t);if(e)for(let n of e.connections){if(!a.has(n.toAreaId))continue;let e=Math.min(t,n.toAreaId)+`-`+Math.max(t,n.toAreaId);s.has(e)||(s.add(e),o.push({from:t,to:n.toAreaId}))}}let c=new Map;for(let t of e)c.set(t,{vx:0,vy:0});for(let s=0;s<t;s++){for(let t of e){let n=this.areaNodes.get(t),s=c.get(t);if(!n||!s)continue;let l=n.x+n.width/2,u=n.y+n.height/2;for(let r of e){if(t===r)continue;let e=this.areaNodes.get(r);if(!e)continue;let i=(n.width+e.width)/2+20,a=(n.height+e.height)/2+20,o=n.x+n.width/2,c=n.y+n.height/2,l=e.x+e.width/2,u=e.y+e.height/2,d=o-l,f=c-u,p=i-Math.abs(d),m=a-Math.abs(f);p>0&&m>0&&(p<m?s.vx+=(d>=0?1:-1)*p*.5:s.vy+=(f>=0?1:-1)*m*.5)}for(let e of o){if(e.from===t||e.to===t)continue;let n=this.areaNodes.get(e.from),r=this.areaNodes.get(e.to);if(!n||!r)continue;let a=n.x+n.width/2,o=n.y+n.height/2,c=r.x+r.width/2,d=r.y+r.height/2,f=this.closestPointOnSegment(l,u,a,o,c,d),p=l-f.x,m=u-f.y,h=Math.sqrt(p*p+m*m)||1;if(h<i){let e=(i-h)*.6;s.vx+=p/h*e,s.vy+=m/h*e}}for(let e of n.connections){if(!a.has(e.toAreaId))continue;let t=this.areaNodes.get(e.toAreaId);if(!t)continue;let i=t.x-n.x,o=t.y-n.y,l=Math.sqrt(i*i+o*o)||1,u=(l-r)*.03;s.vx+=i/l*u,s.vy+=o/l*u;let d=this.getDirectionOffset(e.direction),f=n.x+d.x*r,p=n.y+d.y*r,m=c.get(e.toAreaId);m&&(m.vx+=(f-t.x)*.01,m.vy+=(p-t.y)*.01)}}for(let t of e){let e=this.areaNodes.get(t),r=c.get(t);!e||!r||(e.x+=r.vx,e.y+=r.vy,r.vx*=n,r.vy*=n)}}}closestPointOnSegment(e,t,n,r,i,a){let o=i-n,s=a-r,c=e-n,l=t-r,u=o*o+s*s;if(u===0)return{x:n,y:r};let d=(c*o+l*s)/u;return d=Math.max(0,Math.min(1,d)),{x:n+d*o,y:r+d*s}}edgesIntersect(e,t,n,r,i,a,o,s){let c=(e,t,n,r,i,a)=>(a-t)*(n-e)>(r-t)*(i-e);return c(e,t,i,a,o,s)!==c(n,r,i,a,o,s)&&c(e,t,n,r,i,a)!==c(e,t,n,r,o,s)}drawConnections(){this.connectionLayer.destroyChildren();for(let e of this.connectionGroups){let t=this.areaNodes.get(e.fromAreaId),n=this.areaNodes.get(e.toAreaId);if(!t||!n||!isFinite(t.x)||!isFinite(t.y)||!isFinite(n.x)||!isFinite(n.y))continue;let r={x:t.x+t.width/2,y:t.y+t.height/2},i={x:n.x+n.width/2,y:n.y+n.height/2},a,o;if(this.dotsMode?(a=r,o=i):(a=this.getEdgePoint(t,i),o=this.getEdgePoint(n,r)),!isFinite(a.x)||!isFinite(a.y)||!isFinite(o.x)||!isFinite(o.y))continue;let s=this.dotsMode?`#ffffff`:this.settings.connectionColor,c=this.dotsMode?1:Math.min(this.settings.connectionLineWidth,1+e.connections.length*.5),u=new l.default.Line({points:[a.x,a.y,o.x,o.y],stroke:s,strokeWidth:c,lineCap:`round`,listening:!1});this.connectionLayer.add(u)}}getEdgePoint(e,t){let n=e.x+e.width/2,r=e.y+e.height/2,i=t.x-n,a=t.y-r,o=e.width/2,s=e.height/2;if(i===0&&a===0)return{x:n,y:r};let c=Math.abs(i),l=Math.abs(a),u;return u=c/o>l/s?o/c:s/l,{x:n+i*u,y:r+a*u}}drawAreas(){this.areaLayer.destroyChildren();for(let[,e]of this.areaNodes){if(!isFinite(e.x)||!isFinite(e.y))continue;let t=e.areaId===this.highlightedArea;if(this.dotsMode){let n=e.x+e.width/2,r=e.y+e.height/2,i=new l.default.Group({x:n,y:r,draggable:!0}),a=new l.default.Circle({radius:6,fill:t?this.settings.highlightColor:`#ffffff`,stroke:t?this.settings.highlightColor:`#ffffff`,strokeWidth:1}),o=new l.default.Text({text:e.name,fontSize:10,fill:`#ffffff`,x:10,y:-5});i.add(a),i.add(o),i.on(`click tap`,()=>{this.emitAreaClickEvent(e.areaId)}),i.on(`mouseenter`,()=>{this.stage.container().style.cursor=`pointer`,a.fill(this.settings.highlightColor),a.stroke(this.settings.highlightColor),this.areaLayer.batchDraw()}),i.on(`mouseleave`,()=>{this.stage.container().style.cursor=`auto`,a.fill(t?this.settings.highlightColor:`#ffffff`),a.stroke(t?this.settings.highlightColor:`#ffffff`),this.areaLayer.batchDraw()}),i.on(`dragmove`,()=>{e.x=i.x()-e.width/2,e.y=i.y()-e.height/2,this.drawConnections(),this.connectionLayer.batchDraw()}),i.on(`dragstart`,()=>{this.stage.container().style.cursor=`grabbing`}),i.on(`dragend`,()=>{this.stage.container().style.cursor=`pointer`}),this.areaLayer.add(i)}else{let n=new l.default.Group({x:e.x,y:e.y,draggable:!0}),r=new l.default.Rect({width:e.width,height:e.height,fill:this.settings.areaFillColor,stroke:t?this.settings.highlightColor:this.settings.areaStrokeColor,strokeWidth:t?3:2,cornerRadius:8}),i=new l.default.Text({text:e.name,fontSize:this.settings.fontSize,fill:this.settings.textColor,width:e.width-10,height:e.height-20,x:5,y:10,align:`center`,verticalAlign:`middle`,ellipsis:!0,wrap:`word`}),a=new l.default.Text({text:`${e.roomCount} rooms`,fontSize:10,fill:this.settings.connectionColor,width:e.width-10,x:5,y:e.height-18,align:`center`});n.add(r),n.add(i),n.add(a),n.on(`click tap`,()=>{this.emitAreaClickEvent(e.areaId)}),n.on(`mouseenter`,()=>{this.stage.container().style.cursor=`pointer`,r.stroke(this.settings.highlightColor),this.areaLayer.batchDraw()}),n.on(`mouseleave`,()=>{this.stage.container().style.cursor=`auto`,r.stroke(t?this.settings.highlightColor:this.settings.areaStrokeColor),this.areaLayer.batchDraw()}),n.on(`dragmove`,()=>{e.x=n.x(),e.y=n.y(),this.drawConnections(),this.connectionLayer.batchDraw()}),n.on(`dragstart`,()=>{this.stage.container().style.cursor=`grabbing`}),n.on(`dragend`,()=>{this.stage.container().style.cursor=`pointer`}),this.areaLayer.add(n)}}}centerView(){let e=1/0,t=1/0,n=-1/0,r=-1/0;for(let[,i]of this.areaNodes)e=Math.min(e,i.x),t=Math.min(t,i.y),n=Math.max(n,i.x+i.width),r=Math.max(r,i.y+i.height);if(!isFinite(e))return;let i=n-e,a=r-t,o=e+i/2,s=t+a/2,c=(this.stage.width()-100)/i,l=(this.stage.height()-100)/a,u=Math.min(c,l,1.5);this.setZoom(u);let d=this.stage.scaleX();this.stage.position({x:this.stage.width()/2-o*d,y:this.stage.height()/2-s*d})}highlightArea(e){this.highlightedArea=e,this.drawAreas(),this.stage.batchDraw()}centerOnArea(e){let t=this.areaNodes.get(e);if(!t)return;let n=this.stage.scaleX(),r=t.x+t.width/2,i=t.y+t.height/2;this.stage.position({x:this.stage.width()/2-r*n,y:this.stage.height()/2-i*n}),this.stage.batchDraw()}emitAreaClickEvent(e){let t=new CustomEvent(`areaclick`,{detail:{areaId:e}});this.stage.container().dispatchEvent(t)}getAreaNode(e){return this.areaNodes.get(e)}getConnectionGroups(){return this.connectionGroups}destroy(){this.stage.destroy()}},je={1:`north`,2:`northeast`,3:`northwest`,4:`east`,5:`west`,6:`south`,7:`southeast`,8:`southwest`,9:`up`,10:`down`,11:`in`,12:`out`},Me=[`up`,`down`,`in`,`out`],Q={1:`rgb(10, 155, 10)`,2:`rgb(226, 205, 59)`,3:`rgb(155, 10, 10)`},$=class{constructor(e,t){this.mapReader=e,this.settings=t,this.exitRenderer=new w(e,null,t)}getSymbolColor(e,t){return this.settings.frameMode?this.mapReader.getColorValue(e):this.mapReader.getSymbolColor(e,t)}render(e,t,n,r){let i=this.mapReader.getArea(t);if(!i)throw Error(`Area ${t} not found`);let a=i.getPlane(n);if(!a)throw Error(`Plane z=${n} not found in area ${t}`);let o=r.padding??3,s=this.computeBounds(i,a,r.roomId,o),c=r.width/s.w,l=r.height/s.h,u=Math.min(c,l);e.save(),e.fillStyle=this.settings.backgroundColor,e.fillRect(0,0,r.width,r.height);let d=s.w*u,f=s.h*u;if(e.translate((r.width-d)/2,(r.height-f)/2),e.scale(u,u),e.translate(-s.x,-s.y),this.settings.gridEnabled){let t=(r.width-d)/2,n=(r.height-f)/2,i={x:s.x-t/u,y:s.y-n/u,w:r.width/u,h:r.height/u};this.renderGrid(e,i)}this.renderLabels(e,a.getLabels()),this.renderLinkExits(e,i,n),this.renderSpecialExits(e,a.getRooms()),this.renderStubs(e,a.getRooms()),this.renderRooms(e,a.getRooms()),this.renderInnerExits(e,a.getRooms());let p=r.overlays;if(p){if(p.paths)for(let r of p.paths)this.renderPathOverlay(e,r.locations,r.color,t,n);if(p.highlights)for(let t of p.highlights)this.renderHighlightOverlay(e,t.roomId,t.color);p.position&&this.renderPositionMarker(e,p.position.roomId)}if(this.settings.areaName){let t=i.getAreaName();if(t){let n=this.getEffectiveBounds(i,a);e.fillStyle=`white`,e.font=`2.5px ${this.settings.fontFamily}`,e.textAlign=`left`,e.textBaseline=`bottom`,e.fillText(t,n.minX-3.5,n.minY-2)}}e.restore()}computeBounds(e,t,n,r){if(n!==void 0){let e=this.mapReader.getRoom(n);if(!e)throw Error(`Room ${n} not found`);return{x:e.x-r,y:e.y-r,w:r*2,h:r*2}}let i=this.getEffectiveBounds(e,t),a=this.settings.areaName?e.getAreaName():void 0,o=a?7:0,s=a?3.5:0,c=i.minX-s,l=i.minY-o,u=a?i.minX-3.5+a.length*2.5*.6:-1/0,d=Math.max(i.maxX,u);return{x:c-r,y:l-r,w:d-c+r*2,h:i.maxY-l+r*2}}getEffectiveBounds(e,t){return this.settings.uniformLevelSize?e.getFullBounds():t.getBounds()}getRoomEdgePoint(e,t,n,r){return this.settings.roomShape===`circle`?y(e,t,n,r):this.settings.roomShape===`roundedRectangle`?v(e,t,n,r,this.settings.roomSize*.2):_(e,t,n,r)}renderGrid(e,t){let n=this.settings.gridSize,r=Math.floor(t.x/n)*n,i=Math.ceil((t.x+t.w)/n)*n,a=Math.floor(t.y/n)*n,o=Math.ceil((t.y+t.h)/n)*n;e.strokeStyle=this.settings.gridColor,e.lineWidth=this.settings.gridLineWidth,e.setLineDash([]);for(let t=r;t<=i;t+=n)e.beginPath(),e.moveTo(t,a),e.lineTo(t,o),e.stroke();for(let t=a;t<=o;t+=n)e.beginPath(),e.moveTo(r,t),e.lineTo(i,t),e.stroke()}renderLabels(e,t){for(let n of t){let t=n.X,r=-n.Y;if((n.BgColor?.alpha??0)>0&&!this.settings.transparentLabels){let i=(n.BgColor.alpha??255)/255;e.fillStyle=`rgba(${n.BgColor.r},${n.BgColor.g},${n.BgColor.b},${i})`,e.fillRect(t,r,n.Width,n.Height)}if(n.Text){let i=(n.FgColor?.alpha??255)/255;e.fillStyle=`rgba(${n.FgColor?.r??0},${n.FgColor?.g??0},${n.FgColor?.b??0},${i})`;let a=Math.min(.75,n.Width/Math.max(n.Text.length/2,1));e.font=`${Math.max(.1,Math.min(a,Math.max(n.Height*.9,.1)))}px ${this.settings.fontFamily}`,e.textAlign=`center`,e.textBaseline=`middle`,e.fillText(n.Text,t+n.Width/2,r+n.Height/2)}}}renderLinkExits(e,t,n){let r=t.getLinkExits(n);for(let t of r){let r=this.exitRenderer.renderData(t,n);r&&this.drawExitData(e,r)}}drawExitData(e,t){for(let n of t.lines){e.beginPath(),e.moveTo(n.points[0],n.points[1]);for(let t=2;t<n.points.length;t+=2)e.lineTo(n.points[t],n.points[t+1]);e.strokeStyle=n.stroke,e.lineWidth=n.strokeWidth,e.setLineDash(n.dash??[]),e.stroke()}for(let n of t.arrows){e.beginPath(),e.moveTo(n.points[0],n.points[1]);for(let t=2;t<n.points.length;t+=2)e.lineTo(n.points[t],n.points[t+1]);e.strokeStyle=n.stroke,e.lineWidth=n.strokeWidth,e.setLineDash(n.dash??[]),e.stroke();let t=n.points.length-2,r=n.points[t],i=n.points[t+1],a=n.points[t-2],o=n.points[t-1],s=Math.atan2(i-o,r-a),c=n.pointerLength,l=n.pointerWidth/2;e.beginPath(),e.setLineDash([]),e.moveTo(r,i),e.lineTo(r-c*Math.cos(s-Math.atan2(l,c)),i-c*Math.sin(s-Math.atan2(l,c))),e.lineTo(r-c*Math.cos(s+Math.atan2(l,c)),i-c*Math.sin(s+Math.atan2(l,c))),e.closePath(),e.fillStyle=n.fill,e.fill(),e.strokeStyle=n.stroke,e.lineWidth=n.strokeWidth,e.stroke()}for(let n of t.doors)e.beginPath(),e.rect(n.x,n.y,n.width,n.height),e.strokeStyle=n.stroke,e.lineWidth=n.strokeWidth,e.setLineDash([]),e.stroke()}renderStubs(e,t){e.strokeStyle=this.settings.lineColor,e.lineWidth=this.settings.lineWidth,e.setLineDash([]);for(let n of t)for(let t of n.stubs){let r=je[t];if(!r)continue;let i=this.getRoomEdgePoint(n.x,n.y,r,this.settings.roomSize/2),a=_(n.x,n.y,r,this.settings.roomSize/2+.5);e.beginPath(),e.moveTo(i.x,i.y),e.lineTo(a.x,a.y),e.stroke()}}renderSpecialExits(e,t){for(let n of t)for(let[t,r]of Object.entries(n.customLines)){let i=[n.x,n.y];for(let e of r.points)i.push(e.x,-e.y);let a=`rgb(${r.attributes.color.r}, ${r.attributes.color.g}, ${r.attributes.color.b})`;e.strokeStyle=a,e.lineWidth=this.settings.lineWidth,r.attributes.style===`dot line`?e.setLineDash([.05,.05]):r.attributes.style===`dash line`?e.setLineDash([.4,.2]):e.setLineDash([]),e.beginPath(),e.moveTo(i[0],i[1]);for(let t=2;t<i.length;t+=2)e.lineTo(i[t],i[t+1]);if(e.stroke(),r.attributes.arrow&&i.length>=4){let t=i.length-2,n=i[t],r=i[t+1],o=i[t-2],s=i[t-1],c=Math.atan2(r-s,n-o),l=.3,u=.1;e.beginPath(),e.setLineDash([]),e.moveTo(n,r),e.lineTo(n-l*Math.cos(c-Math.atan2(u,l)),r-l*Math.sin(c-Math.atan2(u,l))),e.lineTo(n-l*Math.cos(c+Math.atan2(u,l)),r-l*Math.sin(c+Math.atan2(u,l))),e.closePath(),e.fillStyle=a,e.fill()}let o=n.doors[t];if(o&&i.length>=4){let t=i[0]+(i[2]-i[0])/2,n=i[1]+(i[3]-i[1])/2,r=this.settings.roomSize/2;e.beginPath(),e.rect(t-r/2,n-r/2,r,r),e.strokeStyle=Q[o]??Q[3],e.lineWidth=this.settings.lineWidth,e.setLineDash([]),e.stroke()}}}renderRooms(e,t){let n=this.settings.roomSize,r=n/2;for(let i of t){let t=this.mapReader.getColorValue(i.env),a=this.settings.coloredMode?K(t,.5):this.settings.frameMode?this.settings.backgroundColor:t,o=this.settings.frameMode||this.settings.coloredMode?t:this.settings.lineColor;if(e.fillStyle=a,e.strokeStyle=o,e.lineWidth=this.settings.lineWidth,e.setLineDash([]),this.settings.roomShape===`circle`)e.beginPath(),e.arc(i.x,i.y,r,0,Math.PI*2),e.fill(),e.stroke();else{let t=i.x-r,a=i.y-r,o=this.settings.roomShape===`roundedRectangle`?n*.2:0;if(o>0?(this.roundRect(e,t,a,n,n,o),e.fill(),e.stroke()):(e.fillRect(t,a,n,n),e.strokeRect(t,a,n,n)),this.settings.emboss){let r=G(this.settings.lineColor)>.41;e.beginPath(),r?(e.moveTo(t,a),e.lineTo(t+n,a),e.lineTo(t+n,a+n)):(e.moveTo(t,a),e.lineTo(t,a+n),e.lineTo(t+n,a+n)),e.strokeStyle=r?`#000000`:`#ffffff`,e.lineWidth=this.settings.lineWidth,e.stroke()}}if(i.roomChar){let t=this.getSymbolColor(i.env),r=n*.75;e.fillStyle=t,e.font=`bold ${r}px ${this.settings.fontFamily}`,e.textAlign=`center`,e.textBaseline=`alphabetic`;let a=R(i.roomChar,this.settings.fontFamily);e.fillText(i.roomChar,i.x,i.y+a*r)}}}roundRect(e,t,n,r,i,a){e.beginPath(),e.moveTo(t+a,n),e.lineTo(t+r-a,n),e.arcTo(t+r,n,t+r,n+a,a),e.lineTo(t+r,n+i-a),e.arcTo(t+r,n+i,t+r-a,n+i,a),e.lineTo(t+a,n+i),e.arcTo(t,n+i,t,n+i-a,a),e.lineTo(t,n+a),e.arcTo(t,n,t+a,n,a),e.closePath()}renderInnerExits(e,t){let n=this.settings.roomSize,r=n/5;for(let i of t)for(let t of Me){if(!i.exits[t])continue;let a=this.getSymbolColor(i.env),o=this.getSymbolColor(i.env,.6),s=i.doors[t],c=s===void 0?a:Q[s]??Q[3];switch(t){case`up`:{let t=_(i.x,i.y,`south`,n/4);this.drawTriangle(e,t.x,t.y,r,0,o,c);break}case`down`:{let t=_(i.x,i.y,`north`,n/4);this.drawTriangle(e,t.x,t.y,r,180,o,c);break}case`in`:{let t=_(i.x,i.y,`west`,n/4),a=_(i.x,i.y,`east`,n/4);this.drawTriangle(e,t.x,t.y,r,90,o,c),this.drawTriangle(e,a.x,a.y,r,-90,o,c);break}case`out`:{let t=_(i.x,i.y,`west`,n/4),a=_(i.x,i.y,`east`,n/4);this.drawTriangle(e,t.x,t.y,r,-90,o,c),this.drawTriangle(e,a.x,a.y,r,90,o,c);break}}}}drawTriangle(e,t,n,r,i,a,o){let s=i*Math.PI/180;e.beginPath();for(let i=0;i<3;i++){let a=2*Math.PI*i/3-Math.PI/2,o=Math.cos(a)*r*1.4,c=Math.sin(a)*r*.8,l=o*Math.cos(s)-c*Math.sin(s),u=o*Math.sin(s)+c*Math.cos(s);i===0?e.moveTo(t+l,n+u):e.lineTo(t+l,n+u)}e.closePath(),e.fillStyle=a,e.fill(),e.strokeStyle=o,e.lineWidth=this.settings.lineWidth,e.stroke()}renderPathOverlay(e,t,n,r,i){let a=M(this.mapReader,this.settings,t,r,i),o=this.settings.lineWidth;e.save(),e.globalAlpha=.8,e.lineCap=`round`,e.lineJoin=`round`,e.setLineDash([]);let s=t=>{if(!(t.length<4)){e.beginPath(),e.moveTo(t[0],t[1]);for(let n=2;n<t.length;n+=2)e.lineTo(t[n],t[n+1]);e.strokeStyle=`black`,e.lineWidth=o*8,e.stroke(),e.beginPath(),e.moveTo(t[0],t[1]);for(let n=2;n<t.length;n+=2)e.lineTo(t[n],t[n+1]);e.strokeStyle=n,e.lineWidth=o*4,e.stroke()}};for(let e of a.segments)s(e.points);for(let e of a.customLines)s(e.points);let c=this.settings.roomSize/5;for(let t of a.innerMarkers){let r=t.direction===`up`?0:t.direction===`down`?180:t.direction===`in`?90:-90;this.drawTriangle(e,t.room.x,t.room.y,c,r,n,`black`)}e.restore()}renderHighlightOverlay(e,t,n){let r=this.mapReader.getRoom(t);if(!r)return;let i=1.5,a=this.settings.roomSize;if(e.strokeStyle=n,e.lineWidth=.1,e.setLineDash([.05,.05]),this.settings.roomShape===`circle`)e.beginPath(),e.arc(r.x,r.y,a/2*i,0,Math.PI*2),e.stroke();else{let t=a*i;e.strokeRect(r.x-t/2,r.y-t/2,t,t)}e.setLineDash([])}renderPositionMarker(e,t){let n=this.mapReader.getRoom(t);if(!n)return;let r=this.settings.playerMarker,i=this.settings.roomSize*r.sizeFactor;if(e.save(),e.globalAlpha=r.strokeAlpha,e.strokeStyle=r.strokeColor,e.lineWidth=r.strokeWidth,e.setLineDash(r.dashEnabled&&r.dash?r.dash:[]),r.matchRoomShape&&this.settings.roomShape!==`circle`){let t=i/2,r=this.settings.roomShape===`roundedRectangle`?i*.2:0;r>0?this.roundRect(e,n.x-t,n.y-t,i,i,r):(e.beginPath(),e.rect(n.x-t,n.y-t,i,i))}else e.beginPath(),e.arc(n.x,n.y,i/2,0,Math.PI*2);e.stroke(),r.fillAlpha>0&&(e.globalAlpha=r.fillAlpha,e.fillStyle=r.fillColor,e.fill()),e.restore()}},Ne=class{constructor(e,t){this.highlights=new Map,this.paths=[],this.mapReader=e,this.settings=t??J()}drawArea(e,t){let n=this.mapReader.getArea(e);n&&n.getPlane(t)&&(this.currentArea=e,this.currentAreaInstance=n,this.currentZIndex=t)}getCurrentArea(){return this.currentAreaInstance}setPosition(e){this.positionRoomId=e}clearPosition(){this.positionRoomId=void 0}renderPath(e,t=`#66E64D`){this.paths.push({locations:e,color:t})}clearPaths(){this.paths=[]}renderHighlight(e,t){let n=this.mapReader.getRoom(e);n&&this.highlights.set(e,{color:t,area:n.area,z:n.z})}removeHighlight(e){this.highlights.delete(e)}hasHighlight(e){return this.highlights.has(e)}clearHighlights(){this.highlights.clear()}exportSvg(e){if(this.currentArea===void 0||this.currentZIndex===void 0)return;let t={...e,overlays:this.buildOverlays(e?.overlays)};return new H(this.mapReader,this.settings).export(this.currentArea,this.currentZIndex,t)}renderToCanvas(e,t){if(this.currentArea===void 0||this.currentZIndex===void 0)return;let n={...t,overlays:this.buildOverlays(t?.overlays)};new $(this.mapReader,this.settings).render(e,this.currentArea,this.currentZIndex,n)}buildOverlays(e){let t={...e};if(this.positionRoomId!==void 0){let e=this.mapReader.getRoom(this.positionRoomId);e&&e.area===this.currentArea&&e.z===this.currentZIndex&&(t.position={roomId:this.positionRoomId})}let n=[...e?.highlights??[]];for(let[e,t]of this.highlights)t.area===this.currentArea&&t.z===this.currentZIndex&&n.push({roomId:e,color:t.color});n.length>0&&(t.highlights=n);let r=[...e?.paths??[]];return r.push(...this.paths),r.length>0&&(t.paths=r),t}};exports.AreaMapRenderer=Ae,exports.CanvasExporter=$,exports.ExplorationArea=O,exports.HeadlessRenderer=Ne,exports.MapReader=he,exports.PathFinder=De,exports.Renderer=me,exports.SvgExporter=H,exports.colorLightness=G,exports.computePathData=M,exports.createAreaMapSettings=ke,exports.createSettings=J,exports.darkenColor=K;
3
+ //# sourceMappingURL=index.cjs.map