open-plant 1.2.20 → 1.2.21
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.
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +483 -488
- package/dist/index.js.map +1 -1
- package/dist/types/react/overview-map.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -29,7 +29,7 @@ out vec4 outColor;
|
|
|
29
29
|
void main() {
|
|
30
30
|
outColor = texture(uTexture, vUv);
|
|
31
31
|
}
|
|
32
|
-
`;class Tr{constructor(t){y(this,"canvas");y(this,"gl");y(this,"camera",new hi);y(this,"imageWidth");y(this,"imageHeight");y(this,"clearColor");y(this,"program");y(this,"vao");y(this,"quadBuffer");y(this,"uCameraLocation");y(this,"uBoundsLocation");y(this,"uTextureLocation");y(this,"resizeObserver");y(this,"tiles",[]);y(this,"frameId",null);y(this,"loadVersion",0);y(this,"destroyed",!1);y(this,"fitted",!1);y(this,"controlledViewState",!1);this.canvas=t.canvas,this.imageWidth=Math.max(1,t.imageWidth),this.imageHeight=Math.max(1,t.imageHeight),this.clearColor=t.clearColor??[.03,.05,.08,1],this.gl=fi(this.canvas),this.program=li(this.gl,di,mi);const n=this.gl.createVertexArray(),r=this.gl.createBuffer();if(!n||!r)throw new Error("Failed to create WebGL buffers.");this.vao=n,this.quadBuffer=r,this.gl.bindVertexArray(this.vao),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.quadBuffer);const i=new Float32Array([0,0,0,0,1,0,1,0,0,1,0,1,1,1,1,1]);this.gl.bufferData(this.gl.ARRAY_BUFFER,i,this.gl.STATIC_DRAW);const o=this.gl.getAttribLocation(this.program,"aUnit"),s=this.gl.getAttribLocation(this.program,"aUv");if(o<0||s<0)throw new Error("Failed to get attribute locations.");const a=4*Float32Array.BYTES_PER_ELEMENT;this.gl.enableVertexAttribArray(o),this.gl.vertexAttribPointer(o,2,this.gl.FLOAT,!1,a,0),this.gl.enableVertexAttribArray(s),this.gl.vertexAttribPointer(s,2,this.gl.FLOAT,!1,a,2*Float32Array.BYTES_PER_ELEMENT),this.gl.bindVertexArray(null),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null),this.uCameraLocation=fn(this.gl,this.program,"uCamera"),this.uBoundsLocation=fn(this.gl,this.program,"uBounds"),this.uTextureLocation=fn(this.gl,this.program,"uTexture"),t.initialViewState&&(this.controlledViewState=!0,this.camera.setViewState(t.initialViewState)),this.resizeObserver=new ResizeObserver(()=>{this.resize()}),this.resizeObserver.observe(this.canvas),this.resize()}async setTiles(t){if(this.destroyed)return;const n=++this.loadVersion,r=await Promise.all(t.map(async i=>await this.loadTile(i,n)));if(this.destroyed||n!==this.loadVersion){for(const i of r)i&&this.gl.deleteTexture(i.texture);return}this.disposeTiles(this.tiles),this.tiles=r.filter(i=>i!==null),this.requestRender()}setViewState(t){this.controlledViewState=!0,this.camera.setViewState(t),this.requestRender()}getViewState(){return this.camera.getViewState()}destroy(){this.destroyed||(this.destroyed=!0,this.loadVersion+=1,this.frameId!==null&&(cancelAnimationFrame(this.frameId),this.frameId=null),this.resizeObserver.disconnect(),this.disposeTiles(this.tiles),this.tiles=[],this.gl.deleteBuffer(this.quadBuffer),this.gl.deleteVertexArray(this.vao),this.gl.deleteProgram(this.program))}async loadTile(t,n){try{const r=await fetch(t.url);if(!r.ok)throw new Error(`Tile fetch failed: ${r.status} ${r.statusText}`);const i=await r.blob(),o=await createImageBitmap(i);if(this.destroyed||n!==this.loadVersion)return o.close(),null;const s=this.gl.createTexture();if(!s)throw o.close(),new Error("Failed to create tile texture.");return this.gl.bindTexture(this.gl.TEXTURE_2D,s),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,1),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,o),this.gl.bindTexture(this.gl.TEXTURE_2D,null),o.close(),{id:t.id,bounds:t.bounds,texture:s}}catch(r){return console.error(`[M1TileRenderer] tile load failed: ${t.id}`,r),null}}resize(){if(this.destroyed)return;const t=this.canvas.getBoundingClientRect(),n=Math.max(1,t.width||this.canvas.clientWidth||1),r=Math.max(1,t.height||this.canvas.clientHeight||1),i=Math.max(1,window.devicePixelRatio||1),o=Math.max(1,Math.round(n*i)),s=Math.max(1,Math.round(r*i));(this.canvas.width!==o||this.canvas.height!==s)&&(this.canvas.width=o,this.canvas.height=s),this.camera.setViewport(n,r),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),!this.fitted&&!this.controlledViewState&&(this.fitToImage(),this.fitted=!0),this.requestRender()}fitToImage(){const t=this.camera.getViewportSize(),n=Math.min(t.width/this.imageWidth,t.height/this.imageHeight),r=Number.isFinite(n)&&n>0?n:1,i=t.width/r,o=t.height/r,s=(this.imageWidth-i)*.5,a=(this.imageHeight-o)*.5;this.camera.setViewState({zoom:r,offsetX:s,offsetY:a})}requestRender(){this.frameId!==null||this.destroyed||(this.frameId=requestAnimationFrame(()=>{this.frameId=null,this.render()}))}render(){if(!this.destroyed){this.gl.clearColor(this.clearColor[0],this.clearColor[1],this.clearColor[2],this.clearColor[3]),this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.useProgram(this.program),this.gl.bindVertexArray(this.vao),this.gl.uniformMatrix3fv(this.uCameraLocation,!1,this.camera.getMatrix()),this.gl.uniform1i(this.uTextureLocation,0);for(const t of this.tiles)this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,t.texture),this.gl.uniform4f(this.uBoundsLocation,t.bounds[0],t.bounds[1],t.bounds[2],t.bounds[3]),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4);this.gl.bindTexture(this.gl.TEXTURE_2D,null),this.gl.bindVertexArray(null)}}disposeTiles(t){for(const n of t)this.gl.deleteTexture(n.texture)}}const gi=.1,pi=4e6,bi=4096,wi=64,yi=1,Mi=4,Er=1e-6,Si=24;function en(e,t,n){return Math.max(t,Math.min(n,e))}function Gt(e){if(!Array.isArray(e)||e.length<3)return[];const t=e.map(([i,o])=>[i,o]),n=t[0],r=t[t.length-1];return!n||!r?[]:((n[0]!==r[0]||n[1]!==r[1])&&t.push([n[0],n[1]]),t)}function Ai(e){if(!Array.isArray(e)||e.length===0)return[];const t=[];for(const n of e){if(!Array.isArray(n)||n.length<2)continue;const r=Number(n[0]),i=Number(n[1]);if(!Number.isFinite(r)||!Number.isFinite(i))continue;const o=t[t.length-1];o&&Math.abs(o[0]-r)<1e-9&&Math.abs(o[1]-i)<1e-9||t.push([r,i])}return t}function xi(e,t,n){if(t<=Er||n<8)return[];const r=[];for(let i=0;i<=n;i+=1){const o=i/n*Math.PI*2;r.push([e[0]+Math.cos(o)*t,e[1]+Math.sin(o)*t])}return Gt(r)}function hn(e,t){if(!e.length)return[];let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[a,c]of e)a<n&&(n=a),a>i&&(i=a),c<r&&(r=c),c>o&&(o=c);if(!Number.isFinite(n)||!Number.isFinite(r))return[];const s=Math.max(t,1);return Gt([[n-s,r-s],[i+s,r-s],[i+s,o+s],[n-s,o+s]])}function Ti(e,t){let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[a,c]of e)a<n&&(n=a),a>i&&(i=a),c<r&&(r=c),c>o&&(o=c);const s=Math.max(t,1);return[n-s,r-s,i+s,o+s]}function Ei(e,t,n){const r=Math.max(gi,Number(n.minRasterStep)||0),i=Math.max(32768,Math.floor(n.maxRasterPixels||pi)),o=Math.max(256,Math.floor(n.maxRasterSize||bi)),s=Math.max(.001,e[2]-e[0]),a=Math.max(.001,e[3]-e[1]);let c=Math.max(r,Number.EPSILON),l=3,f=Math.ceil(s/c)+l*2+1,b=Math.ceil(a/c)+l*2+1;for(;(f>o||b>o||f*b>i)&&(c*=1.15,f=Math.ceil(s/c)+l*2+1,b=Math.ceil(a/c)+l*2+1,!(c>Math.max(s,a))););return f=Math.max(8,f),b=Math.max(8,b),{minX:e[0],minY:e[1],step:c,padding:l,width:f,height:b}}function Ri(e,t){if(typeof OffscreenCanvas<"u"){const r=new OffscreenCanvas(e,t).getContext("2d",{willReadFrequently:!0});if(r)return r}if(typeof document<"u"){const n=document.createElement("canvas");return n.width=e,n.height=t,n.getContext("2d",{willReadFrequently:!0})}return null}function Ci(e,t){return[(e[0]-t.minX)/t.step+t.padding,(e[1]-t.minY)/t.step+t.padding]}function Pi(e,t,n){const r=Ri(n.width,n.height);if(!r)return new Uint8Array(0);r.clearRect(0,0,n.width,n.height),r.fillStyle="#ffffff",r.strokeStyle="#ffffff",r.lineCap="round",r.lineJoin="round",r.lineWidth=t*2/n.step;const i=e.map(a=>Ci(a,n));if(i.length<=1){const a=i[0];if(!a)return new Uint8Array(0);r.beginPath(),r.arc(a[0],a[1],t/n.step,0,Math.PI*2),r.fill()}else{r.beginPath(),r.moveTo(i[0][0],i[0][1]);for(let a=1;a<i.length;a+=1)r.lineTo(i[a][0],i[a][1]);r.stroke()}const o=r.getImageData(0,0,n.width,n.height),s=new Uint8Array(n.width*n.height);for(let a=0;a<s.length;a+=1)s[a]=o.data[a*4+3]>=Si?1:0;return s}function Ii(e,t,n){const r=[],i=t+1,o=(a,c)=>c*i+a,s=(a,c)=>a>=0&&c>=0&&a<t&&c<n&&e[c*t+a]>0;for(let a=0;a<n;a+=1)for(let c=0;c<t;c+=1)s(c,a)&&(s(c,a-1)||r.push({start:o(c,a),end:o(c+1,a),dir:0}),s(c+1,a)||r.push({start:o(c+1,a),end:o(c+1,a+1),dir:1}),s(c,a+1)||r.push({start:o(c+1,a+1),end:o(c,a+1),dir:2}),s(c-1,a)||r.push({start:o(c,a+1),end:o(c,a),dir:3}));return r}function vi(e,t){const n=(t-e+4)%4;return n===1?0:n===0?1:n===3?2:3}function _i(e){if(!e.length)return[];const t=new Map;for(let i=0;i<e.length;i+=1){const o=t.get(e[i].start);o?o.push(i):t.set(e[i].start,[i])}const n=new Uint8Array(e.length),r=[];for(let i=0;i<e.length;i+=1){if(n[i])continue;const o=e[i],s=o.start;let a=o.end,c=o.dir;const l=[o.start,o.end];n[i]=1;let f=0;const b=e.length*3;for(;a!==s&&f<b;){const m=t.get(a);if(!m||m.length===0)break;let w=-1,g=1/0;for(const T of m){if(n[T])continue;const _=e[T],B=vi(c,_.dir);B<g&&(g=B,w=T)}if(w<0)break;n[w]=1;const S=e[w];a=S.end,c=S.dir,l.push(a),f+=1}l.length>=4&&l[0]===l[l.length-1]&&r.push(l)}return r}function Fi(e,t,n){const r=t+1,i=[];for(const o of e){const s=o%r,a=Math.floor(o/r);i.push([n.minX+(s-n.padding)*n.step,n.minY+(a-n.padding)*n.step])}return Gt(i)}function Ui(e){if(e.length<4)return 0;let t=0;for(let n=0;n<e.length-1;n+=1){const r=e[n],i=e[n+1];t+=r[0]*i[1]-i[0]*r[1]}return t*.5}function Bi(e,t=1e-9){const n=Gt(e);if(n.length<5)return n;const r=[n[0]];for(let i=1;i<n.length-1;i+=1){const o=r[r.length-1],s=n[i],a=n[i+1],c=(s[0]-o[0])*(a[1]-s[1])-(s[1]-o[1])*(a[0]-s[0]);Math.abs(c)<=t||r.push(s)}return r.push(r[0]),Gt(r)}function Li(e,t,n){const r=n[0]-t[0],i=n[1]-t[1],o=r*r+i*i;if(o<=1e-12){const b=e[0]-t[0],m=e[1]-t[1];return b*b+m*m}const s=en(((e[0]-t[0])*r+(e[1]-t[1])*i)/o,0,1),a=t[0]+r*s,c=t[1]+i*s,l=e[0]-a,f=e[1]-c;return l*l+f*f}function Ni(e,t){if(e.length<=2||t<=0)return e.slice();const n=new Uint8Array(e.length);n[0]=1,n[e.length-1]=1;const r=t*t,i=[[0,e.length-1]];for(;i.length>0;){const s=i.pop();if(!s)break;const[a,c]=s;if(c-a<=1)continue;let l=0,f=-1;for(let b=a+1;b<c;b+=1){const m=Li(e[b],e[a],e[c]);m>l&&(l=m,f=b)}f>=0&&l>r&&(n[f]=1,i.push([a,f],[f,c]))}const o=[];for(let s=0;s<e.length;s+=1)n[s]&&o.push(e[s]);return o}function zi(e,t){const n=Gt(e);if(n.length<5||t<=0)return n;const r=n.slice(0,-1),i=Ni(r,t);return i.length<3?n:Gt(i)}function Di(e,t){let n=Gt(e);if(t<=0||n.length<5)return n;for(let r=0;r<t;r+=1){const i=n.slice(0,-1);if(i.length<3)break;const o=[];for(let s=0;s<i.length;s+=1){const a=i[s],c=i[(s+1)%i.length];o.push([a[0]*.75+c[0]*.25,a[1]*.75+c[1]*.25],[a[0]*.25+c[0]*.75,a[1]*.25+c[1]*.75])}n=Gt(o)}return n}function xe(e,t){return t?Gt(e.map(([n,r])=>[en(n,t[0],t[2]),en(r,t[1],t[3])])):e}function ki(e,t){const n=Ai(e),r=Math.max(Er,Number(t.radius)||0);if(n.length===0||!Number.isFinite(r))return[];const i=Math.max(12,Math.floor(t.circleSides||wi));if(n.length===1)return xe(xi(n[0],r,i),t.clipBounds);const o=Ti(n,r),s=Ei(o,r,t),a=Pi(n,r,s);if(!a.length)return xe(hn(n,r),t.clipBounds);const c=Ii(a,s.width,s.height),l=_i(c);if(!l.length)return xe(hn(n,r),t.clipBounds);let f=[],b=0;for(const S of l){const T=Fi(S,s.width,s),_=Math.abs(Ui(T));_<=b||(b=_,f=T)}if(!f.length)return xe(hn(n,r),t.clipBounds);const m=typeof t.simplifyTolerance=="number"&&Number.isFinite(t.simplifyTolerance)?Math.max(0,t.simplifyTolerance):s.step*.2,w=typeof t.smoothingPasses=="number"&&Number.isFinite(t.smoothingPasses)?Math.round(en(t.smoothingPasses,0,Mi)):yi,g=zi(Di(Bi(f,s.step*.001),w),m);return xe(g,t.clipBounds)}function Qn(e){return typeof e=="number"&&Number.isFinite(e)}function Oi(e){return Array.isArray(e)&&e.length>=2&&Qn(e[0])&&Qn(e[1])}function Rr(e){return Array.isArray(e)&&e.length>0&&e.every(t=>Oi(t))}function Cr(e){return Array.isArray(e)&&e.length>0&&e.every(t=>Rr(t))}function Xi(e){return Array.isArray(e)&&e.length>0&&e.every(t=>Cr(t))}function Yi(e){if(!Array.isArray(e)||e.length<3)return[];const t=[];for(const i of e){if(!Array.isArray(i)||i.length<2)continue;const o=Number(i[0]),s=Number(i[1]);if(!Number.isFinite(o)||!Number.isFinite(s))continue;const a=t[t.length-1];a&&a[0]===o&&a[1]===s||t.push([o,s])}if(t.length<3)return[];const n=t[0],r=t[t.length-1];return(n[0]!==r[0]||n[1]!==r[1])&&t.push([n[0],n[1]]),t.length>=4?t:[]}function yn(e){if(!Array.isArray(e)||e.length<4)return 0;let t=0;for(let n=0;n<e.length-1;n+=1){const r=e[n],i=e[n+1];t+=r[0]*i[1]-i[0]*r[1]}return t*.5}function dn(e){if(!Array.isArray(e)||e.length===0)return[];const t=[];for(const o of e){const s=Yi(o);s.length>=4&&t.push(s)}if(t.length===0)return[];if(t.length===1)return[t[0]];let n=0,r=0;for(let o=0;o<t.length;o+=1){const s=Math.abs(yn(t[o]));s<=r||(r=s,n=o)}const i=[t[n]];for(let o=0;o<t.length;o+=1)o!==n&&i.push(t[o]);return i}function Pr(e){if(!e)return[];if(Rr(e)){const t=dn([e]);return t.length>0?[t]:[]}if(Cr(e)){const t=dn(e);return t.length>0?[t]:[]}if(Xi(e)){const t=[];for(const n of e){const r=dn(n);r.length>0&&t.push(r)}return t}return[]}function tr(e,t,n){let r=!1;for(let i=0,o=n.length-1;i<n.length;o=i,i+=1){const s=n[i][0],a=n[i][1],c=n[o][0],l=n[o][1];a>t!=l>t&&e<(c-s)*(t-a)/(l-a||Number.EPSILON)+s&&(r=!r)}return r}function Ie(e){const t=[];for(const n of e??[]){const r=Pr(n);for(const i of r){const o=i[0];if(!o||o.length<4)continue;let s=1/0,a=1/0,c=-1/0,l=-1/0;for(const[b,m]of o)b<s&&(s=b),b>c&&(c=b),m<a&&(a=m),m>l&&(l=m);if(!Number.isFinite(s)||!Number.isFinite(a)||!Number.isFinite(c)||!Number.isFinite(l))continue;let f=Math.abs(yn(o));for(let b=1;b<i.length;b+=1)f-=Math.abs(yn(i[b]));t.push({outer:o,holes:i.slice(1),minX:s,minY:a,maxX:c,maxY:l,area:Math.max(1e-6,f)})}}return t}function Ir(e,t,n){if(e<n.minX||e>n.maxX||t<n.minY||t>n.maxY||!tr(e,t,n.outer))return!1;for(const r of n.holes)if(tr(e,t,r))return!1;return!0}function nn(e,t,n){for(const r of n)if(Ir(e,t,r))return!0;return!1}const In=[160,160,160,255];function tt(e,t,n){return Math.max(t,Math.min(n,e))}function vn(e,t,n){const r=Number(e),i=Number(t),o=Number(n);return!Number.isFinite(r)||r<=0?1:!Number.isFinite(i)||!Number.isFinite(o)?r:Math.pow(2,i-o)*r}function Wi(e,t,n){let i=100*vn(e,t,n);if(Number(e)){let o="μm";return i>1e3&&(i/=1e3,o="mm"),`${i.toPrecision(3)} ${o}`}return`${Math.round(i*1e3)/1e3} pixels`}function Vi(e,t){return!e&&!t?!0:!e||!t?!1:Math.abs((e.zoom??0)-(t.zoom??0))<1e-6&&Math.abs((e.offsetX??0)-(t.offsetX??0))<1e-6&&Math.abs((e.offsetY??0)-(t.offsetY??0))<1e-6&&Math.abs((e.rotationDeg??0)-(t.rotationDeg??0))<1e-6}function Gi(e){const t=String(e??"").trim();if(!t)return"";if(/^bearer\s+/i.test(t)){const n=t.replace(/^bearer\s+/i,"").trim();return n?`Bearer ${n}`:""}return`Bearer ${t}`}function vr(e){const n=String(e??"").trim().match(/^#?([0-9a-fA-F]{6})$/);if(!n)return[...In];const r=Number.parseInt(n[1],16);return[r>>16&255,r>>8&255,r&255,255]}function qi(e){const t=[[...In]],n=new Map;for(const i of e??[]){const o=String(i?.termId??"");!o||n.has(o)||(n.set(o,t.length),t.push(vr(i?.termColor)))}const r=new Uint8Array(t.length*4);for(let i=0;i<t.length;i+=1)r[i*4]=t[i][0],r[i*4+1]=t[i][1],r[i*4+2]=t[i][2],r[i*4+3]=t[i][3];return{colors:r,termToPaletteIndex:n}}function er(e,t,n){const r=e.createShader(e.VERTEX_SHADER),i=e.createShader(e.FRAGMENT_SHADER);if(!r||!i)throw new Error("Shader allocation failed");if(e.shaderSource(r,t),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(r)||"vertex compile failed");if(e.shaderSource(i,n),e.compileShader(i),!e.getShaderParameter(i,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(i)||"fragment compile failed");const o=e.createProgram();if(!o)throw new Error("Program allocation failed");if(e.attachShader(o,r),e.attachShader(o,i),e.linkProgram(o),e.deleteShader(r),e.deleteShader(i),!e.getProgramParameter(o,e.LINK_STATUS))throw new Error(e.getProgramInfoLog(o)||"program link failed");return o}const Hi="rgba(255, 77, 79, 0.16)",nr="transparent",$i=3,Zi=2,_r=96,Ki=1,rr=[],Ce=[],rn=1e3,Fr=2,Ur=2,ji=4096,Ji=.2,Qi=1.12,to=.89,eo=32,no="#000000",ro=.1,io="#FFCF00",oo="#FF0000",so=1.5,ir=[2,2],ao=1,co=.25,uo=4,lo=1,fo=0,ho=4,mo=.05,go=256,or=1.5,re={color:"#ff4d4f",width:2,lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},po={color:"#4cc9f0",width:2,lineDash:[10,8],lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},bo="rgba(23, 23, 25, 0.1)",wo=6,zt={fontFamily:"Pretendard, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",fontSize:11,fontWeight:600,textColor:"#171719",backgroundColor:"#FFCC00",borderColor:"rgba(0, 0, 0, 0)",borderWidth:0,paddingX:8,paddingY:4,offsetY:10,borderRadius:4},ie={fontFamily:"Pretendard, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",fontSize:13,fontWeight:500,textColor:"#FFFFFF",backgroundColor:"rgba(23, 23, 25, 0.5)",borderRadius:4,paddingX:6,paddingY:3},sr={x:16,y:-24},yo=20,ar=1e-6;function Ot(e,t,n){return Math.max(t,Math.min(n,e))}function Br(e,t,n){if(!e||!n)return 0;const r=Number(n.minZoom),i=Number(n.maxZoom);return!Number.isFinite(r)||!Number.isFinite(i)||i-r<=ar||!Number.isFinite(t)?0:t>=i-ar?yo:0}function Xe(e){return e==="stamp-rectangle"||e==="stamp-circle"||e==="stamp-rectangle-4096px"||e==="stamp-rectangle-2mm2"||e==="stamp-circle-2mm2"||e==="stamp-circle-hpf-0.2mm2"}function Ee(e,t){return typeof e!="number"||!Number.isFinite(e)||e<=0?t:e}function Mo(e){return{rectangleAreaMm2:Ee(e?.rectangleAreaMm2,Fr),circleAreaMm2:Ee(e?.circleAreaMm2,Ur),rectanglePixelSize:Ee(e?.rectanglePixelSize,ji)}}function So(e,t){return typeof e!="number"||!Number.isFinite(e)?t:Ot(e,0,1)}function Ao(e){if(!Array.isArray(e))return ir;const t=e.filter(n=>Number.isFinite(n)&&n>=0);return t.length>0?t:ir}function xo(e){return typeof e!="number"||!Number.isFinite(e)?ao:Ot(e,co,uo)}function To(e){return typeof e!="number"||!Number.isFinite(e)?lo:Math.round(Ot(e,fo,ho))}function Eo(e){const t=Ee(e?.radius,eo),n=Ee(e?.cursorLineWidth,so),r=xo(e?.edgeDetail),i=To(e?.edgeSmoothing);return{radius:t,edgeDetail:r,edgeSmoothing:i,clickSelectRoi:e?.clickSelectRoi===!0,fillColor:e?.fillColor||no,fillOpacity:So(e?.fillOpacity,ro),cursorColor:e?.cursorColor||io,cursorActiveColor:e?.cursorActiveColor||oo,cursorLineWidth:n,cursorLineDash:Ao(e?.cursorLineDash)}}function Ro(e){return e*rn*rn}function cr(e,t,n){if(!e||!Number.isFinite(t)||t<=0)return[];if(n){const r=n.worldToScreen(e[0],e[1]),i=n.worldToScreen(e[0]+t,e[1]);if(r&&i){const o=Math.hypot(i[0]-r[0],i[1]-r[1]),s=[[r[0]-o,r[1]-o],[r[0]+o,r[1]-o],[r[0]+o,r[1]+o],[r[0]-o,r[1]+o]],a=[];for(const c of s){const l=n.screenToWorld(c);if(!l)throw new Error("Failed to create rectangle");a.push(l)}return vt(a)}}return vt([[e[0]-t,e[1]-t],[e[0]+t,e[1]-t],[e[0]+t,e[1]+t],[e[0]-t,e[1]+t]])}function Co(e,t,n=_r){if(!e||!Number.isFinite(t)||t<=0)return[];const r=[];for(let i=0;i<=n;i+=1){const o=i/n*Math.PI*2;r.push([e[0]+Math.cos(o)*t,e[1]+Math.sin(o)*t])}return vt(r)}function vt(e){if(!Array.isArray(e)||e.length<3)return[];const t=e.map(([i,o])=>[i,o]),n=t[0],r=t[t.length-1];return!n||!r?[]:((n[0]!==r[0]||n[1]!==r[1])&&t.push([n[0],n[1]]),t)}function on(e,t,n){if(!e||!t)return[];if(n){const r=n.worldToScreen(e[0],e[1]),i=n.worldToScreen(t[0],t[1]);if(r&&i){const o=[[r[0],r[1]],[i[0],r[1]],[i[0],i[1]],[r[0],i[1]]],s=[];for(const a of o){const c=n.screenToWorld(a);if(!c)return on(e,t);s.push(c)}return vt(s)}}return vt([[e[0],e[1]],[t[0],e[1]],[t[0],t[1]],[e[0],t[1]]])}function Mn(e,t,n=_r){if(!e||!t)return[];const r=(e[0]+t[0])*.5,i=(e[1]+t[1])*.5,o=Math.hypot(t[0]-e[0],t[1]-e[1])*.5;if(o<1)return[];const s=[];for(let a=0;a<=n;a+=1){const c=a/n*Math.PI*2;s.push([r+Math.cos(c)*o,i+Math.sin(c)*o])}return vt(s)}function tn(e){if(!Array.isArray(e)||e.length<4)return 0;let t=0;for(let n=0;n<e.length-1;n+=1){const r=e[n],i=e[n+1];t+=r[0]*i[1]-i[0]*r[1]}return Math.abs(t*.5)}function ur(e){if(!Array.isArray(e)||e.length===0)return[0,0,0,0];let t=1/0,n=1/0,r=-1/0,i=-1/0;for(const[o,s]of e)o<t&&(t=o),o>r&&(r=o),s<n&&(n=s),s>i&&(i=s);return[t,n,r,i]}function lr(e){return Array.isArray(e)&&e.length>=4&&tn(e)>Ki}function Sn(e,t,n=!1){if(t.length!==0){e.moveTo(t[0][0],t[0][1]);for(let r=1;r<t.length;r+=1)e.lineTo(t[r][0],t[r][1]);n&&e.closePath()}}function Vt(e,t,n,r=!1,i=!1,o=Hi){t.length!==0&&(e.beginPath(),Sn(e,t,r),i&&r&&(e.fillStyle=o,e.fill()),e.strokeStyle=n.color,e.lineWidth=n.width,e.lineJoin=n.lineJoin,e.lineCap=n.lineCap,e.shadowColor=n.shadowColor,e.shadowBlur=n.shadowBlur,e.shadowOffsetX=n.shadowOffsetX,e.shadowOffsetY=n.shadowOffsetY,e.setLineDash(n.lineDash),e.stroke(),e.setLineDash(Ce),e.shadowColor="rgba(0, 0, 0, 0)",e.shadowBlur=0,e.shadowOffsetX=0,e.shadowOffsetY=0)}function Po(e){if(typeof e!="string")return nr;const t=e.trim();return t.length>0?t:nr}function Lr(e){const t=Array.isArray(e?.lineDash)?e.lineDash.filter(s=>Number.isFinite(s)&&s>=0):Ce,n=typeof e?.width=="number"&&Number.isFinite(e.width)?Math.max(0,e.width):re.width,r=typeof e?.shadowBlur=="number"&&Number.isFinite(e.shadowBlur)?Math.max(0,e.shadowBlur):re.shadowBlur,i=typeof e?.shadowOffsetX=="number"&&Number.isFinite(e.shadowOffsetX)?e.shadowOffsetX:re.shadowOffsetX,o=typeof e?.shadowOffsetY=="number"&&Number.isFinite(e.shadowOffsetY)?e.shadowOffsetY:re.shadowOffsetY;return{color:e?.color||re.color,width:n,lineDash:t.length?t:Ce,lineJoin:e?.lineJoin||re.lineJoin,lineCap:e?.lineCap||re.lineCap,shadowColor:e?.shadowColor||re.shadowColor,shadowBlur:r,shadowOffsetX:i,shadowOffsetY:o}}function Te(e,t){return t?Lr({color:t.color??e.color,width:t.width??e.width,lineDash:t.lineDash??e.lineDash,lineJoin:t.lineJoin??e.lineJoin,lineCap:t.lineCap??e.lineCap,shadowColor:t.shadowColor??e.shadowColor,shadowBlur:t.shadowBlur??e.shadowBlur,shadowOffsetX:t.shadowOffsetX??e.shadowOffsetX,shadowOffsetY:t.shadowOffsetY??e.shadowOffsetY}):e}function fr(e,t){return e==null||t===null||t===void 0?!1:String(e)===String(t)}function Io(e){const t=e[0];return Array.isArray(t)&&Array.isArray(t[0])}function hr(e){return typeof e=="number"&&Number.isFinite(e)}function vo(e){return Array.isArray(e)&&e.length>=2&&hr(e[0])&&hr(e[1])}function _o(e){return Array.isArray(e)&&e.length>=2&&e.every(t=>vo(t))}function Nr(e,t){if(!(!Array.isArray(e)||e.length===0)){if(_o(e)){t.push(e.map(([n,r])=>[n,r]));return}for(const n of e)Nr(n,t)}}function dr(e,t){const n=[];Nr(e,n);const r=[];for(const i of n){if(i.length<2)continue;const o=t?vt(i):i;o.length>=(t?4:2)&&r.push(o)}return r}function Fo(e,t,n,r){if(!(t.length<4||n.length===0)){e.save(),e.beginPath(),Sn(e,t,!0);for(const i of n)i.length<4||Sn(e,i,!0);e.fillStyle=r,e.fill("evenodd"),e.restore()}}function _n(e){const t=typeof e?.paddingX=="number"&&Number.isFinite(e.paddingX)?Math.max(0,e.paddingX):zt.paddingX,n=typeof e?.paddingY=="number"&&Number.isFinite(e.paddingY)?Math.max(0,e.paddingY):zt.paddingY,r=typeof e?.fontSize=="number"&&Number.isFinite(e.fontSize)?Math.max(8,e.fontSize):zt.fontSize,i=typeof e?.borderWidth=="number"&&Number.isFinite(e.borderWidth)?Math.max(0,e.borderWidth):zt.borderWidth,o=typeof e?.offsetY=="number"&&Number.isFinite(e.offsetY)?e.offsetY:zt.offsetY,s=typeof e?.borderRadius=="number"&&Number.isFinite(e.borderRadius)?Math.max(0,e.borderRadius):zt.borderRadius;return{fontFamily:e?.fontFamily||zt.fontFamily,fontSize:r,fontWeight:e?.fontWeight||zt.fontWeight,textColor:e?.textColor||zt.textColor,backgroundColor:e?.backgroundColor||zt.backgroundColor,borderColor:e?.borderColor||zt.borderColor,borderWidth:i,paddingX:t,paddingY:n,offsetY:o,borderRadius:s}}function zr(e,t){return t?_n({fontFamily:t.fontFamily??e.fontFamily,fontSize:t.fontSize??e.fontSize,fontWeight:t.fontWeight??e.fontWeight,textColor:t.textColor??e.textColor,backgroundColor:t.backgroundColor??e.backgroundColor,borderColor:t.borderColor??e.borderColor,borderWidth:t.borderWidth??e.borderWidth,paddingX:t.paddingX??e.paddingX,paddingY:t.paddingY??e.paddingY,offsetY:t.offsetY??e.offsetY,borderRadius:t.borderRadius??e.borderRadius}):e}function Uo(e){const t=typeof e?.fontSize=="number"&&Number.isFinite(e.fontSize)?Math.max(8,e.fontSize):ie.fontSize,n=typeof e?.borderRadius=="number"&&Number.isFinite(e.borderRadius)?Math.max(0,e.borderRadius):ie.borderRadius,r=typeof e?.paddingX=="number"&&Number.isFinite(e.paddingX)?Math.max(0,e.paddingX):ie.paddingX,i=typeof e?.paddingY=="number"&&Number.isFinite(e.paddingY)?Math.max(0,e.paddingY):ie.paddingY;return{fontFamily:e?.fontFamily||ie.fontFamily,fontSize:t,fontWeight:e?.fontWeight||ie.fontWeight,textColor:e?.textColor||ie.textColor,backgroundColor:e?.backgroundColor||ie.backgroundColor,borderRadius:n,paddingX:r,paddingY:i}}function Bo(e){const t=typeof e?.x=="number"&&Number.isFinite(e.x)?e.x:sr.x,n=typeof e?.y=="number"&&Number.isFinite(e.y)?e.y:sr.y;return{x:t,y:n}}function An(e){return Number.isFinite(e)?`${Math.max(0,e).toFixed(3)} mm²`:"0.000 mm²"}function Lo(e){const t=typeof e?.format=="function"?e.format:An,n=Bo(e?.cursorOffset);return{enabled:e?.enabled===!0,format:t,style:Uo(e?.style),cursorOffsetX:n.x,cursorOffsetY:n.y}}function No(e){return{color:bo,width:wo,lineDash:Ce,lineJoin:e.lineJoin,lineCap:e.lineCap,shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0}}function Dr(e,t,n,r,i,o){const s=Math.max(0,Math.min(o,r*.5,i*.5));e.beginPath(),e.moveTo(t+s,n),e.lineTo(t+r-s,n),e.quadraticCurveTo(t+r,n,t+r,n+s),e.lineTo(t+r,n+i-s),e.quadraticCurveTo(t+r,n+i,t+r-s,n+i),e.lineTo(t+s,n+i),e.quadraticCurveTo(t,n+i,t,n+i-s),e.lineTo(t,n+s),e.quadraticCurveTo(t,n,t+s,n),e.closePath()}function zo(e){if(!e.length)return null;let t=1/0;for(const i of e)i[1]<t&&(t=i[1]);if(!Number.isFinite(t))return null;let n=1/0,r=-1/0;for(const i of e)Math.abs(i[1]-t)>.5||(i[0]<n&&(n=i[0]),i[0]>r&&(r=i[0]));return!Number.isFinite(n)||!Number.isFinite(r)?null:[(n+r)*.5,t]}function Do(e){let t=null;for(const n of e){const r=zo(n.outer);r&&(!t||r[1]<t[1]||r[1]===t[1]&&r[0]<t[0])&&(t=r)}return t}function mr(e){const t=Pr(e);if(t.length===0)return[];const n=[];for(const r of t){const i=r[0];if(!i||i.length<4)continue;const o=i.map(([a,c])=>[a,c]),s=[];for(let a=1;a<r.length;a+=1){const c=r[a];!c||c.length<4||s.push(c.map(([l,f])=>[l,f]))}n.push({outer:o,holes:s})}return n}function ko(e,t,n,r,i,o){const s=t.trim();if(!s)return;e.save(),e.font=`${o.fontWeight} ${o.fontSize}px ${o.fontFamily}`,e.textAlign="center",e.textBaseline="middle";const c=e.measureText(s).width+o.paddingX*2,l=o.fontSize+o.paddingY*2,f=Ot(n[0],c*.5+1,r-c*.5-1),b=Ot(n[1]-o.offsetY,l*.5+1,i-l*.5-1),m=f-c*.5,w=b-l*.5;e.fillStyle=o.backgroundColor,e.strokeStyle=o.borderColor,e.lineWidth=o.borderWidth,Dr(e,m,w,c,l,o.borderRadius),e.fill(),o.borderWidth>0&&e.stroke(),e.fillStyle=o.textColor,e.fillText(s,f,b+.5),e.restore()}function Oo(e,t,n,r,i,o,s,a){const c=t.trim();if(!c)return;e.save(),e.font=`${o.fontWeight} ${o.fontSize}px ${o.fontFamily}`,e.textAlign="center",e.textBaseline="middle";const f=e.measureText(c).width+o.paddingX*2,b=o.fontSize+o.paddingY*2,m=Ot(n[0]+s,f*.5+1,r-f*.5-1),w=Ot(n[1]+a,b*.5+1,i-b*.5-1),g=m-f*.5,S=w-b*.5;e.fillStyle=o.backgroundColor,Dr(e,g,S,f,b,o.borderRadius),e.fill(),e.fillStyle=o.textColor,e.fillText(c,m,w+.5),e.restore()}function Ye(e,t,n){return[Ot(e[0],0,t),Ot(e[1],0,n)]}function de(e){if(!Array.isArray(e)||e.length<2)return null;const t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:[t,n]}function kr({tool:e,imageWidth:t,imageHeight:n,imageMpp:r,imageZoom:i,stampOptions:o,brushOptions:s,projectorRef:a,onBrushTap:c,onDrawComplete:l,onPatchComplete:f,enabled:b,viewStateSignal:m,persistedRegions:w,patchRegions:g,persistedPolygons:S,drawFillColor:T,regionStrokeStyle:_,regionStrokeHoverStyle:B,regionStrokeActiveStyle:N,patchStrokeStyle:V,resolveRegionStrokeStyle:F,resolveRegionLabelStyle:X,overlayShapes:K,hoveredRegionId:ft=null,activeRegionId:mt=null,regionLabelStyle:Tt,drawAreaTooltip:It,autoLiftRegionLabelAtMaxZoom:Ft=!1,regionLabelAutoLiftOffsetPx:rt,invalidateRef:Xt,className:ae,style:ce}){const J=d.useRef(null),Yt=d.useRef(!1),qt=d.useRef(new Map),ge=d.useRef(e),St=d.useRef({isDrawing:!1,pointerId:null,start:null,current:null,cursor:null,cursorScreen:null,points:[],screenPoints:[],stampCenter:null}),ot=b??e!=="cursor",R=d.useMemo(()=>w&&w.length>0?w:!S||S.length===0?rr:S.map((u,h)=>({id:h,coordinates:u})),[w,S]),P=d.useMemo(()=>g??rr,[g]),U=d.useMemo(()=>{const u=[];for(let h=0;h<R.length;h+=1){const M=R[h],A=mr(M.coordinates);A.length!==0&&u.push({region:M,regionIndex:h,regionKey:M.id??h,polygons:A})}return u},[R]),Q=d.useMemo(()=>{const u=[];for(let h=0;h<P.length;h+=1){const M=P[h],A=mr(M.coordinates);A.length!==0&&u.push({region:M,regionIndex:h,regionKey:M.id??h,polygons:A})}return u},[P]),Y=d.useMemo(()=>Lr(_),[_]),st=d.useMemo(()=>Te(Y,B),[Y,B]),gt=d.useMemo(()=>Te(Y,N),[Y,N]),H=d.useMemo(()=>Te(po,V),[V]),W=d.useMemo(()=>Po(T),[T]),et=d.useMemo(()=>_n(Tt),[Tt]),at=d.useMemo(()=>Lo(It),[It]),j=d.useMemo(()=>Mo(o),[o]),k=d.useMemo(()=>Eo(s),[s]),ht=d.useMemo(()=>({position:"absolute",inset:0,zIndex:2,width:"100%",height:"100%",display:"block",touchAction:"none",pointerEvents:ot?"auto":"none",cursor:ot?e==="brush"?"none":"crosshair":"default",...ce}),[ot,e,ce]),ct=d.useCallback(()=>{const u=J.current;if(!u)return;const h=u.getBoundingClientRect(),M=Math.max(1,window.devicePixelRatio||1),A=Math.max(1,Math.round(h.width*M)),E=Math.max(1,Math.round(h.height*M));(u.width!==A||u.height!==E)&&(u.width=A,u.height=E)},[]),G=d.useCallback(u=>{const h=a.current;if(!h||u.length===0)return[];const M=new Array(u.length);for(let A=0;A<u.length;A+=1){const E=de(h.worldToScreen(u[A][0],u[A][1]));if(!E)return[];M[A]=E}return M},[a]),pt=d.useCallback(u=>{const h=a.current,M=J.current;if(!h||!M)return null;const A=M.getBoundingClientRect(),E=de(h.screenToWorld(A.left+u[0],A.top+u[1]));return E?Ye(E,t,n):null},[a,t,n]),At=d.useCallback(()=>{const u=a.current,h=u?.getViewState?.().rotationDeg??0;if(!(Math.abs(h%360)<.01||!u))return{worldToScreen:(M,A)=>de(u.worldToScreen(M,A)),screenToWorld:pt}},[a,pt]),Ut=d.useCallback(u=>{if(!Number.isFinite(u)||u<=0)return 0;const h=typeof r=="number"&&Number.isFinite(r)&&r>0?r:1,M=typeof i=="number"&&Number.isFinite(i)?i:0,A=a.current?.getViewState?.().zoom,E=typeof A=="number"&&Number.isFinite(A)&&A>0?A:1,D=M+Math.log2(E),L=Math.max(1e-9,vn(h,M,D));return u/L/E},[r,i,a]),Nt=d.useCallback((u,h)=>{if(!h)return[];let M=0;if(u==="stamp-rectangle-4096px"){const D=j.rectanglePixelSize*.5;return cr(h,D,At()).map(L=>Ye(L,t,n))}if(u==="stamp-rectangle"||u==="stamp-rectangle-2mm2"?M=u==="stamp-rectangle-2mm2"?Fr:j.rectangleAreaMm2:(u==="stamp-circle"||u==="stamp-circle-2mm2"||u==="stamp-circle-hpf-0.2mm2")&&(M=u==="stamp-circle-hpf-0.2mm2"?Ji:u==="stamp-circle-2mm2"?Ur:j.circleAreaMm2),!Number.isFinite(M)||M<=0)return[];const A=Ro(M);let E=[];if(u==="stamp-rectangle"||u==="stamp-rectangle-2mm2"){const D=Ut(Math.sqrt(A)*.5);E=cr(h,D,At())}else if(u==="stamp-circle"||u==="stamp-circle-2mm2"||u==="stamp-circle-hpf-0.2mm2"){const D=Ut(Math.sqrt(A/Math.PI));E=Co(h,D)}return E.length?E.map(D=>Ye(D,t,n)):[]},[Ut,t,n,j,At]),Et=d.useCallback(()=>{const u=St.current;return Xe(e)?Nt(e,u.stampCenter):e==="brush"?[]:u.isDrawing?e==="freehand"?u.points:e==="rectangle"?on(u.start,u.current,At()):e==="circular"?Mn(u.start,u.current):[]:[]},[e,Nt,At]),bt=d.useCallback(u=>{const h=St.current;if(!h.isDrawing||h.screenPoints.length===0)return;const M=h.screenPoints;if(M.length===0)return;const A=k.radius;if(!(!Number.isFinite(A)||A<=0)){if(u.save(),u.globalAlpha=k.fillOpacity,u.fillStyle=k.fillColor,u.strokeStyle=k.fillColor,u.lineCap="round",u.lineJoin="round",u.lineWidth=A*2,M.length===1)u.beginPath(),u.arc(M[0][0],M[0][1],A,0,Math.PI*2),u.fill();else{u.beginPath(),u.moveTo(M[0][0],M[0][1]);for(let E=1;E<M.length;E+=1)u.lineTo(M[E][0],M[E][1]);u.stroke()}u.restore()}},[k]),$=d.useCallback(u=>{const h=St.current,M=h.cursor;if(!M)return;const A=h.cursorScreen??de(a.current?.worldToScreen(M[0],M[1])??[]);if(!A)return;const E=k.radius;!Number.isFinite(E)||E<=0||(u.save(),u.beginPath(),u.arc(A[0],A[1],E,0,Math.PI*2),u.strokeStyle=h.isDrawing?k.cursorActiveColor:k.cursorColor,u.lineWidth=k.cursorLineWidth,u.setLineDash(k.cursorLineDash),u.stroke(),u.setLineDash(Ce),u.restore())},[a,k]),Ht=d.useCallback(()=>{ct();const u=J.current;if(!u)return;const h=u.getContext("2d");if(!h)return;const M=Math.max(1,window.devicePixelRatio||1),A=u.width/M,E=u.height/M;if(h.setTransform(1,0,0,1,0,0),h.clearRect(0,0,u.width,u.height),h.setTransform(M,0,0,M,0,0),U.length>0)for(const L of U){const{region:nt,polygons:Z,regionIndex:O,regionKey:ut}=L,dt=fr(mt,ut)?"active":fr(ft,ut)?"hover":"default";let Bt=dt==="active"?gt:dt==="hover"?st:Y;if(F){const Mt=F({region:nt,regionId:ut,regionIndex:O,state:dt});Bt=Te(Bt,Mt||void 0)}const xt=dt==="default"?null:No(Bt);for(const Mt of Z){const Wt=G(Mt.outer);Wt.length>=4&&(xt&&Vt(h,Wt,xt,!0,!1),Vt(h,Wt,Bt,!0,!1));for(const $t of Mt.holes){const Rt=G($t);Rt.length>=4&&(xt&&Vt(h,Rt,xt,!0,!1),Vt(h,Rt,Bt,!0,!1))}}}if(Q.length>0)for(const L of Q)for(const nt of L.polygons){const Z=G(nt.outer);Z.length>=4&&Vt(h,Z,H,!0,!1);for(const O of nt.holes){const ut=G(O);ut.length>=4&&Vt(h,ut,H,!0,!1)}}if(Array.isArray(K)&&K.length>0){const L=!!globalThis.__OPEN_PLANT_DEBUG_OVERLAY__,nt=G(vt([[0,0],[t,0],[t,n],[0,n]]));for(let Z=0;Z<K.length;Z+=1){const O=K[Z];if(!O?.coordinates?.length||O.visible===!1)continue;const ut=O.closed??Io(O.coordinates),dt=dr(O.coordinates,ut);if(O.invertedFill?.fillColor){const xt=[],Mt=dr(O.coordinates,!0);for(const Wt of Mt){const $t=G(Wt);$t.length>=4&&xt.push($t)}if(L){const Wt=String(O.id??Z),$t=`${nt.length}|${Mt.length}|${xt.length}|${O.invertedFill.fillColor}`;qt.current.get(Wt)!==$t&&(qt.current.set(Wt,$t),console.debug("[open-plant] invertedFill",{id:O.id??Z,outerRingPoints:nt.length,sourceRingCount:Mt.length,holeRingCount:xt.length,fillColor:O.invertedFill.fillColor}))}Fo(h,nt,xt,O.invertedFill.fillColor)}if(dt.length===0)continue;const Bt=Te(Y,O.stroke??O.strokeStyle);for(const xt of dt){const Mt=G(xt);Mt.length<2||Vt(h,Mt,Bt,ut,O.fill??!1)}}}const D=Et();if(ot){if(e==="brush")bt(h),$(h);else if(D.length>0)if(e==="freehand"){const L=G(D);L.length>=2&&Vt(h,L,Y,!1,!1),L.length>=3&&Vt(h,G(vt(D)),Y,!0,!0,W)}else{const L=G(D);L.length>=4&&Vt(h,L,Y,!0,!0,W)}}if(U.length>0){const L=Math.max(1e-6,a.current?.getViewState?.().zoom??1),nt=typeof rt=="number"&&Number.isFinite(rt)?Math.max(0,rt):Br(Ft,L,a.current?.getZoomRange?.());for(const Z of U){if(!Z.region.label)continue;const O=Do(Z.polygons);if(!O)continue;const ut=de(a.current?.worldToScreen(O[0],O[1])??[]);if(!ut)continue;let dt=zr(et,X?.({region:Z.region,regionId:Z.regionKey,regionIndex:Z.regionIndex,zoom:L}));nt>0&&(dt={...dt,offsetY:dt.offsetY+nt}),ko(h,Z.region.label,ut,A,E,dt)}}if(at.enabled&&ot&&(e==="freehand"||e==="rectangle"||e==="circular")){const L=St.current;if(L.isDrawing){const nt=e==="freehand"?vt(D):D;if(nt.length>=4){const Z=tn(nt),O=typeof r=="number"&&Number.isFinite(r)&&r>0?r:0,ut=O>0?Z*O*O/(rn*rn):0;let dt=An(ut);try{dt=at.format(ut)}catch{dt=An(ut)}const Bt=L.cursorScreen??(L.current?de(a.current?.worldToScreen(L.current[0],L.current[1])??[]):null);Bt&&Oo(h,dt,Bt,A,E,at.style,at.cursorOffsetX,at.cursorOffsetY)}}}},[ot,e,Et,bt,$,ct,G,t,n,a,U,K,ft,mt,Y,st,gt,W,Q,H,F,X,et,at,Ft,rt,r]),z=d.useCallback(()=>{Yt.current||(Yt.current=!0,requestAnimationFrame(()=>{Yt.current=!1,Ht()}))},[Ht]),wt=d.useCallback((u=!1)=>{const h=St.current,M=J.current;if(M&&h.pointerId!==null&&M.hasPointerCapture(h.pointerId))try{M.releasePointerCapture(h.pointerId)}catch{}h.isDrawing=!1,h.pointerId=null,h.start=null,h.current=null,h.points=[],h.screenPoints=[],h.stampCenter=null,u||(h.cursor=null,h.cursorScreen=null)},[]),it=d.useCallback(u=>{const h=a.current;if(!h||t<=0||n<=0)return null;const M=de(h.screenToWorld(u.clientX,u.clientY));return M?Ye(M,t,n):null},[a,t,n]),lt=d.useCallback(u=>{const h=J.current;if(!h)return null;const M=h.getBoundingClientRect(),A=Ot(u.clientX-M.left,0,M.width),E=Ot(u.clientY-M.top,0,M.height);return!Number.isFinite(A)||!Number.isFinite(E)?null:[A,E]},[]),jt=d.useCallback(()=>{const u=St.current;if(!u.isDrawing){wt(!0),z();return}let h=[];if(e==="freehand")u.points.length>=$i&&(h=vt(u.points));else if(e==="rectangle")h=on(u.start,u.current,At());else if(e==="circular")h=Mn(u.start,u.current);else if(e==="brush"){const M=u.points[u.points.length-1]??u.current??u.start;if(k.clickSelectRoi&&M&&u.points.length<=1&&c?.(M)){wt(!0),z();return}const A=k.edgeDetail,E=Math.max(mo,k.radius*2/(go*A)),D=u.screenPoints.length>0?u.screenPoints:G(u.points),L=ki(D,{radius:k.radius,minRasterStep:E,circleSides:Math.max(24,Math.round(64*A)),simplifyTolerance:E*.25,smoothingPasses:k.edgeSmoothing}),nt=[];for(const Z of L){const O=pt(Z);O&&nt.push(O)}h=vt(nt)}(e==="freehand"||e==="rectangle"||e==="circular"||e==="brush")&&lr(h)&&l&&l({tool:e,intent:e==="brush"?"brush":"roi",coordinates:h,bbox:ur(h),areaPx:tn(h)}),wt(!0),z()},[e,l,wt,z,G,pt,At,k.radius,k.edgeDetail,k.edgeSmoothing,k.clickSelectRoi,c]),Jt=d.useCallback((u,h)=>{const M=Nt(u,h);if(!lr(M))return;const A=u==="stamp-rectangle-4096px"?"patch":"roi",E={tool:u,intent:A,coordinates:M,bbox:ur(M),areaPx:tn(M)};l?.(E),A==="patch"&&f&&f(E)},[Nt,l,f]),pe=d.useCallback((u,h,M)=>{const A=or*or,E=u.screenPoints[u.screenPoints.length-1];if(!E){u.points.push(h),u.screenPoints.push(M),u.current=h;return}const D=M[0]-E[0],L=M[1]-E[1];D*D+L*L>=A?(u.points.push(h),u.screenPoints.push(M)):(u.points[u.points.length-1]=h,u.screenPoints[u.screenPoints.length-1]=M),u.current=h},[]),ve=d.useCallback(u=>{if(!ot||e==="cursor"||u.button!==0)return;const h=it(u);if(!h)return;const M=lt(u);if(!M)return;if(u.preventDefault(),u.stopPropagation(),Xe(e)){const D=St.current;D.stampCenter=h,Jt(e,h),z();return}const A=J.current;A&&A.setPointerCapture(u.pointerId);const E=St.current;E.isDrawing=!0,E.pointerId=u.pointerId,E.start=h,E.current=h,E.cursor=h,E.cursorScreen=M,E.points=e==="freehand"||e==="brush"?[h]:[],E.screenPoints=e==="brush"?[M]:[],z()},[ot,e,it,lt,Jt,z]),ue=d.useCallback(u=>{if(!ot||e==="cursor")return;const h=it(u);if(!h)return;const M=lt(u);if(!M)return;const A=St.current;if(A.cursor=h,A.cursorScreen=M,Xe(e)){A.stampCenter=h,u.preventDefault(),u.stopPropagation(),z();return}if(e==="brush"){if(!A.isDrawing||A.pointerId!==u.pointerId){z();return}u.preventDefault(),u.stopPropagation(),pe(A,h,M),z();return}if(!(!A.isDrawing||A.pointerId!==u.pointerId)){if(u.preventDefault(),u.stopPropagation(),e==="freehand"){const E=a.current,D=Math.max(1e-6,E?.getViewState?.().zoom??1),L=Zi/D,nt=L*L,Z=A.points[A.points.length-1];if(!Z)A.points.push(h);else{const O=h[0]-Z[0],ut=h[1]-Z[1];O*O+ut*ut>=nt&&A.points.push(h)}}else A.current=h;z()}},[ot,e,it,lt,z,a,pe]),yt=d.useCallback(u=>{const h=St.current;if(!h.isDrawing||h.pointerId!==u.pointerId)return;u.preventDefault(),u.stopPropagation();const M=it(u),A=lt(u);M&&(h.cursor=M,A&&(h.cursorScreen=A),e==="brush"?A&&pe(h,M,A):h.current=M);const E=J.current;if(E&&E.hasPointerCapture(u.pointerId))try{E.releasePointerCapture(u.pointerId)}catch{}jt()},[jt,it,lt,e,pe]),_e=d.useCallback(()=>{const u=St.current;let h=!1;e==="brush"&&!u.isDrawing&&u.cursor&&(u.cursor=null,u.cursorScreen=null,h=!0),Xe(e)&&u.stampCenter&&(u.stampCenter=null,h=!0),h&&z()},[e,z]);return d.useEffect(()=>{ct(),z();const u=J.current;if(!u)return;const h=new ResizeObserver(()=>{ct(),z()});return h.observe(u),()=>{h.disconnect()}},[ct,z]),d.useEffect(()=>{ot||wt(),z()},[ot,z,wt]),d.useEffect(()=>{ge.current!==e&&(ge.current=e,wt(),z())},[e,wt,z]),d.useEffect(()=>{z()},[m,R,K,z]),d.useEffect(()=>{if(Xt)return Xt.current=z,()=>{Xt.current===z&&(Xt.current=null)}},[Xt,z]),d.useEffect(()=>{if(!ot)return;const u=h=>{h.key==="Escape"&&(wt(),z())};return window.addEventListener("keydown",u),()=>{window.removeEventListener("keydown",u)}},[ot,wt,z]),kt.jsx("canvas",{ref:J,className:ae,style:ht,onPointerDown:ve,onPointerMove:ue,onPointerUp:yt,onPointerCancel:yt,onPointerLeave:_e,onContextMenu:u=>{ot&&u.preventDefault()},onWheel:u=>{if(!ot)return;const h=J.current,M=a.current;if(!h||typeof M?.zoomBy!="function")return;u.preventDefault(),u.stopPropagation();const A=h.getBoundingClientRect(),E=u.clientX-A.left,D=u.clientY-A.top;M.zoomBy(u.deltaY<0?Qi:to,E,D),z()}})}function gr(e){return String(e??"").replace(/\/+$/,"")}function Or(e){const t=String(e??"");return t.startsWith("/")?t:`/${t}`}function Xo(e){const t=gr(e);if(!t)return"";if(/\/TileGroup\d+$/i.test(t))return t;let n=null;try{n=new URL(t)}catch{n=null}if(n){const r=`${n.protocol}//${n.host}`,i=gr(n.pathname||"");return/\/ims$/i.test(i)?`${r}${i}`:/\/tiles$/i.test(i)?`${r}${i}`:`${r}${i}/tiles`}return/\/ims$/i.test(t)?"/ims":/\/tiles$/i.test(t)?`${t}`:`${t}/tiles`}function Yo(e,t){const n=e?.imsInfo||{},r=!!e?.imsInfo,i=Number(n.width??e?.width??0),o=Number(n.height??e?.height??0),s=Number(n.tileSize??e?.tileSize??0),a=Number(n.zoom??e?.zoom??0),c=String(n.path??e?.path??""),l=Number(n.mpp??e?.mpp??0);if(!i||!o||!s||!c)throw new Error("이미지 메타데이터가 불완전합니다. width/height/tileSize/path 확인 필요");const f=Array.isArray(e?.terms)?e.terms.map(g=>({termId:String(g?.termId??""),termName:String(g?.termName??""),termColor:String(g?.termColor??"")})):[],b=Or(c),m=Xo(t),w=r?(g,S,T)=>`${m}${b}/${g}/${T}_${S}.webp`:void 0;return{id:e?._id||"unknown",name:e?.name||"unknown",width:i,height:o,mpp:Number.isFinite(l)&&l>0?l:void 0,tileSize:s,maxTierZoom:Number.isFinite(a)?Math.max(0,Math.floor(a)):0,tilePath:c,tileBaseUrl:t,terms:f,tileUrlBuilder:w}}function Fn(e,t,n,r){if(e.tileUrlBuilder)return e.tileUrlBuilder(t,n,r);const i=Or(e.tilePath);return`${e.tileBaseUrl}${i}/${t}/${r}_${n}.webp`}const Pt={width:200,height:125,margin:16,position:"bottom-right",borderRadius:6,borderWidth:0,backgroundColor:"rgba(4, 10, 18, 0.88)",borderColor:"rgba(230, 244, 255, 0.35)",viewportBorderColor:"#171719",viewportBorderStyle:"dash",viewportFillColor:"transparent",interactive:!0,showThumbnail:!0,maxThumbnailTiles:16};function pr(e,t,n,r){const i=t.length;if(i===4){for(let o=0;o<i;o+=1){const s=t[o],a=t[(o+1)%i],c=Math.hypot(a[0]-s[0],a[1]-s[1]);if(c<1e-6)continue;const l=Math.max(1,Math.round((c+r)/(n+r))),f=l*n+(l-1)*r,b=c/Math.max(1e-6,f),m=n*b,w=r*b;e.beginPath(),e.moveTo(s[0],s[1]),e.lineTo(a[0],a[1]),e.setLineDash([m,w]),e.lineDashOffset=0,e.stroke()}e.setLineDash([]),e.lineDashOffset=0}}function Ae(e,t,n=1){return typeof e!="number"||!Number.isFinite(e)?t:Math.max(n,e)}function We(e){return Array.isArray(e)&&e.length===4&&Number.isFinite(e[0])&&Number.isFinite(e[1])&&Number.isFinite(e[2])&&Number.isFinite(e[3])}const Wo={position:"absolute",top:4,right:4,zIndex:1,width:18,height:18,borderRadius:999,border:"1px solid rgba(255,255,255,0.4)",background:"rgba(16, 17, 19, 0.85)",color:"#fff",fontSize:12,lineHeight:1,cursor:"pointer",padding:0,display:"flex",alignItems:"center",justifyContent:"center"};function Xr({source:e,projectorRef:t,authToken:n="",options:r,invalidateRef:i,className:o,style:s}){const a=d.useRef(null),c=d.useRef(null),l=d.useRef(null),f=d.useRef({active:!1,pointerId:null}),b=d.useRef(null),m=d.useRef(!1),w=Ae(r?.width,Pt.width,64),g=Ae(r?.height,Pt.height,48),S=d.useMemo(()=>{const R=Math.max(1,e.width),P=Math.max(1,e.height),U=R/P,Q=w/g;let Y,st;return U>Q?(Y=w,st=w/U):(st=g,Y=g*U),{x:(w-Y)/2,y:(g-st)/2,w:Y,h:st}},[e.width,e.height,w,g]),T=Ae(r?.margin,Pt.margin,0),_=Ae(r?.borderRadius,Pt.borderRadius,0),B=Ae(r?.borderWidth,Pt.borderWidth,0),N=Math.max(1,Math.round(Ae(r?.maxThumbnailTiles,Pt.maxThumbnailTiles,1))),V=r?.backgroundColor||Pt.backgroundColor,F=r?.borderColor||Pt.borderColor,X=r?.viewportBorderColor||Pt.viewportBorderColor,K=r?.viewportBorderStyle==="stroke"||r?.viewportBorderStyle==="dash"?r.viewportBorderStyle:Pt.viewportBorderStyle,ft=r?.viewportFillColor??Pt.viewportFillColor,mt=r?.interactive??Pt.interactive,Tt=r?.showThumbnail??Pt.showThumbnail,It=r?.position||Pt.position,Ft=r?.onClose,rt=r?.closeIcon,Xt=r?.closeButtonStyle,ae=d.useMemo(()=>{const R={};return It==="top-left"||It==="bottom-left"?R.left=T:R.right=T,It==="top-left"||It==="top-right"?R.top=T:R.bottom=T,{position:"absolute",...R,width:w,height:g,borderRadius:_,overflow:"hidden",zIndex:4,pointerEvents:mt?"auto":"none",touchAction:"none",boxShadow:"0 10px 22px rgba(0, 0, 0, 0.3)",...s}},[T,It,w,g,_,mt,s]),ce=d.useCallback(()=>{const R=a.current;if(!R)return;const P=R.getContext("2d");if(!P)return;const U=w,Q=g,Y=Math.max(1,window.devicePixelRatio||1),st=Math.max(1,Math.round(U*Y)),gt=Math.max(1,Math.round(Q*Y));(R.width!==st||R.height!==gt)&&(R.width=st,R.height=gt),P.setTransform(1,0,0,1,0,0),P.clearRect(0,0,R.width,R.height),P.setTransform(Y,0,0,Y,0,0),P.fillStyle=V,P.fillRect(0,0,U,Q);const{x:H,y:W,w:et,h:at}=S,j=c.current;j&&P.drawImage(j,H,W,et,at),P.strokeStyle=F,P.lineWidth=B,P.strokeRect(B*.5,B*.5,U-B,Q-B);const k=t.current,ht=k?.getViewBounds?.(),ct=k?.getViewCorners?.(),G=We(ht)?ht:We(l.current)?l.current:null;if(!G)return;l.current=G;const pt=et/Math.max(1,e.width),At=at/Math.max(1,e.height),Ut=Array.isArray(ct)&&ct.length>=4&&ct.every(it=>Array.isArray(it)&&it.length>=2&&Number.isFinite(it[0])&&Number.isFinite(it[1]))?ct:null,Nt=K==="dash";if(Ut){const it=[];for(let lt=0;lt<Ut.length;lt+=1){const jt=Ut[lt];it.push([tt(H+jt[0]*pt,H,H+et),tt(W+jt[1]*At,W,W+at)])}P.beginPath();for(let lt=0;lt<it.length;lt+=1)lt===0?P.moveTo(it[lt][0],it[lt][1]):P.lineTo(it[lt][0],it[lt][1]);P.closePath(),P.fillStyle=ft,P.fill(),P.strokeStyle=X,P.lineWidth=2.25,Nt?pr(P,it,4,3):P.stroke();return}const Et=tt(H+G[0]*pt,H,H+et),bt=tt(W+G[1]*At,W,W+at),$=tt(H+G[2]*pt,H,H+et),Ht=tt(W+G[3]*At,W,W+at),z=Math.max(1,$-Et),wt=Math.max(1,Ht-bt);if(P.fillStyle=ft,P.fillRect(Et,bt,z,wt),P.strokeStyle=X,P.lineWidth=2.25,Nt){const it=[[Et+.5,bt+.5],[Et+.5+Math.max(1,z-1),bt+.5],[Et+.5+Math.max(1,z-1),bt+.5+Math.max(1,wt-1)],[Et+.5,bt+.5+Math.max(1,wt-1)]];pr(P,it,4,3)}else P.strokeRect(Et+.5,bt+.5,Math.max(1,z-1),Math.max(1,wt-1))},[w,g,S,V,F,B,t,e.width,e.height,ft,X,K]),J=d.useCallback(()=>{m.current||(m.current=!0,b.current=requestAnimationFrame(()=>{m.current=!1,b.current=null,ce()}))},[ce]),Yt=d.useCallback((R,P)=>{const U=a.current;if(!U)return null;const Q=U.getBoundingClientRect();if(!Q.width||!Q.height)return null;const Y=Q.width/w,st=Q.height/g,gt=S.x*Y,H=S.y*st,W=S.w*Y,et=S.h*st,at=tt((R-Q.left-gt)/W,0,1),j=tt((P-Q.top-H)/et,0,1);return[at*e.width,j*e.height]},[e.width,e.height,w,g,S]),qt=d.useCallback((R,P)=>{const U=t.current;if(!U)return;if(U.setViewCenter){U.setViewCenter(R,P),J();return}const Q=U.getViewBounds?.(),Y=We(Q)?Q:We(l.current)?l.current:null;if(!Y)return;const st=Math.max(1e-6,Y[2]-Y[0]),gt=Math.max(1e-6,Y[3]-Y[1]);U.setViewState({offsetX:R-st*.5,offsetY:P-gt*.5}),J()},[t,J]),ge=d.useCallback(R=>{if(!mt||R.button!==0)return;const P=a.current;if(!P)return;const U=Yt(R.clientX,R.clientY);U&&(R.preventDefault(),R.stopPropagation(),P.setPointerCapture(R.pointerId),f.current={active:!0,pointerId:R.pointerId},qt(U[0],U[1]))},[mt,Yt,qt]),St=d.useCallback(R=>{const P=f.current;if(!P.active||P.pointerId!==R.pointerId)return;const U=Yt(R.clientX,R.clientY);U&&(R.preventDefault(),R.stopPropagation(),qt(U[0],U[1]))},[Yt,qt]),ot=d.useCallback(R=>{const P=f.current;if(!P.active||P.pointerId!==R.pointerId)return;const U=a.current;if(U&&U.hasPointerCapture(R.pointerId))try{U.releasePointerCapture(R.pointerId)}catch{}f.current={active:!1,pointerId:null},J()},[J]);return d.useEffect(()=>{let R=!1;c.current=null,J();const P=0,U=2**(e.maxTierZoom-P),Q=Math.ceil(e.width/U),Y=Math.ceil(e.height/U),st=Math.max(1,Math.ceil(Q/e.tileSize)),gt=Math.max(1,Math.ceil(Y/e.tileSize)),H=st*gt;if(!Tt||H>N)return;const W=document.createElement("canvas");W.width=Math.max(1,Math.round(S.w)),W.height=Math.max(1,Math.round(S.h));const et=W.getContext("2d");if(!et)return;et.fillStyle=V,et.fillRect(0,0,W.width,W.height);const at=[];for(let j=0;j<gt;j+=1)for(let k=0;k<st;k+=1){const ht=k*e.tileSize*U,ct=j*e.tileSize*U,G=Math.min((k+1)*e.tileSize,Q)*U,pt=Math.min((j+1)*e.tileSize,Y)*U;at.push({url:Fn(e,P,k,j),bounds:[ht,ct,G,pt]})}return Promise.allSettled(at.map(async j=>{const k=!!n,ht=await fetch(j.url,{headers:k?{Authorization:n}:void 0});if(!ht.ok)throw new Error(`HTTP ${ht.status}`);const ct=await createImageBitmap(await ht.blob());return{tile:j,bitmap:ct}})).then(j=>{if(R){for(const ct of j)ct.status==="fulfilled"&&ct.value.bitmap.close();return}const k=W.width/Math.max(1,e.width),ht=W.height/Math.max(1,e.height);for(const ct of j){if(ct.status!=="fulfilled")continue;const{tile:{bounds:G},bitmap:pt}=ct.value,At=G[0]*k,Ut=G[1]*ht,Nt=Math.max(1,(G[2]-G[0])*k),Et=Math.max(1,(G[3]-G[1])*ht);et.drawImage(pt,At,Ut,Nt,Et),pt.close()}c.current=W,J()}),()=>{R=!0}},[e,n,S,V,Tt,N,J]),d.useEffect(()=>{J()},[J]),d.useEffect(()=>{if(i)return i.current=J,()=>{i.current===J&&(i.current=null)}},[i,J]),d.useEffect(()=>()=>{f.current={active:!1,pointerId:null},b.current!==null&&(cancelAnimationFrame(b.current),b.current=null),m.current=!1},[]),kt.jsxs("div",{className:o,style:ae,children:[kt.jsx("canvas",{ref:a,style:{width:"100%",height:"100%",display:"block",borderRadius:"inherit"},onPointerDown:ge,onPointerMove:St,onPointerUp:ot,onPointerCancel:ot,onContextMenu:R=>{R.preventDefault()},onWheel:R=>{R.preventDefault(),R.stopPropagation()}}),Ft&&kt.jsx("button",{type:"button","aria-label":"Hide overview map",onClick:R=>{R.stopPropagation(),Ft()},style:Xt?{...Xt}:{...Wo},children:rt??"×"})]})}function Vo({imageWidth:e,imageHeight:t,tiles:n,viewState:r,className:i,style:o}){const s=d.useRef(null),a=d.useRef(null),c=d.useMemo(()=>({width:"100%",height:"100%",display:"block",...o}),[o]);return d.useEffect(()=>{const l=s.current;if(!l)return;const f=new Tr({canvas:l,imageWidth:e,imageHeight:t,initialViewState:r});return a.current=f,f.setTiles(n),()=>{f.destroy(),a.current=null}},[e,t]),d.useEffect(()=>{const l=a.current;l&&l.setTiles(n)},[n]),d.useEffect(()=>{const l=a.current;!l||!r||l.setViewState(r)},[r]),kt.jsx("canvas",{ref:s,className:i,style:c})}function Yr(e){const t=e.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER;return Math.max(0,Math.min(Math.floor(e.count??0),Math.floor((e.positions?.length??0)/2),e.paletteIndices?.length??0,t))}function Pe(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return null;const n=Ie(t??[]);if(n.length===0){const g={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return e.fillModes instanceof Uint8Array&&(g.fillModes=new Uint8Array(0)),e.ids instanceof Uint32Array&&(g.ids=new Uint32Array(0)),g}const r=Yr(e),i=e.positions,o=e.paletteIndices,s=e.fillModes instanceof Uint8Array&&e.fillModes.length>=r?e.fillModes:null,a=e.ids instanceof Uint32Array&&e.ids.length>=r?e.ids:null,c=new Float32Array(r*2),l=new Uint16Array(r),f=s?new Uint8Array(r):null,b=a?new Uint32Array(r):null;let m=0;for(let g=0;g<r;g+=1){const S=i[g*2],T=i[g*2+1];nn(S,T,n)&&(c[m*2]=S,c[m*2+1]=T,l[m]=o[g],f&&(f[m]=s[g]),b&&(b[m]=a[g]),m+=1)}const w={count:m,positions:c.subarray(0,m*2),paletteIndices:l.subarray(0,m)};return f&&(w.fillModes=f.subarray(0,m)),b&&(w.ids=b.subarray(0,m)),w}function Wr(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return new Uint32Array(0);const n=Ie(t??[]);if(n.length===0)return new Uint32Array(0);const r=Yr(e);if(r===0)return new Uint32Array(0);const i=e.positions,o=new Uint32Array(r);let s=0;for(let a=0;a<r;a+=1){const c=i[a*2],l=i[a*2+1];nn(c,l,n)&&(o[s]=a,s+=1)}return o.subarray(0,s)}let Ve=null;const Go=`
|
|
32
|
+
`;class Tr{constructor(t){y(this,"canvas");y(this,"gl");y(this,"camera",new hi);y(this,"imageWidth");y(this,"imageHeight");y(this,"clearColor");y(this,"program");y(this,"vao");y(this,"quadBuffer");y(this,"uCameraLocation");y(this,"uBoundsLocation");y(this,"uTextureLocation");y(this,"resizeObserver");y(this,"tiles",[]);y(this,"frameId",null);y(this,"loadVersion",0);y(this,"destroyed",!1);y(this,"fitted",!1);y(this,"controlledViewState",!1);this.canvas=t.canvas,this.imageWidth=Math.max(1,t.imageWidth),this.imageHeight=Math.max(1,t.imageHeight),this.clearColor=t.clearColor??[.03,.05,.08,1],this.gl=fi(this.canvas),this.program=li(this.gl,di,mi);const n=this.gl.createVertexArray(),r=this.gl.createBuffer();if(!n||!r)throw new Error("Failed to create WebGL buffers.");this.vao=n,this.quadBuffer=r,this.gl.bindVertexArray(this.vao),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.quadBuffer);const i=new Float32Array([0,0,0,0,1,0,1,0,0,1,0,1,1,1,1,1]);this.gl.bufferData(this.gl.ARRAY_BUFFER,i,this.gl.STATIC_DRAW);const o=this.gl.getAttribLocation(this.program,"aUnit"),s=this.gl.getAttribLocation(this.program,"aUv");if(o<0||s<0)throw new Error("Failed to get attribute locations.");const a=4*Float32Array.BYTES_PER_ELEMENT;this.gl.enableVertexAttribArray(o),this.gl.vertexAttribPointer(o,2,this.gl.FLOAT,!1,a,0),this.gl.enableVertexAttribArray(s),this.gl.vertexAttribPointer(s,2,this.gl.FLOAT,!1,a,2*Float32Array.BYTES_PER_ELEMENT),this.gl.bindVertexArray(null),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null),this.uCameraLocation=fn(this.gl,this.program,"uCamera"),this.uBoundsLocation=fn(this.gl,this.program,"uBounds"),this.uTextureLocation=fn(this.gl,this.program,"uTexture"),t.initialViewState&&(this.controlledViewState=!0,this.camera.setViewState(t.initialViewState)),this.resizeObserver=new ResizeObserver(()=>{this.resize()}),this.resizeObserver.observe(this.canvas),this.resize()}async setTiles(t){if(this.destroyed)return;const n=++this.loadVersion,r=await Promise.all(t.map(async i=>await this.loadTile(i,n)));if(this.destroyed||n!==this.loadVersion){for(const i of r)i&&this.gl.deleteTexture(i.texture);return}this.disposeTiles(this.tiles),this.tiles=r.filter(i=>i!==null),this.requestRender()}setViewState(t){this.controlledViewState=!0,this.camera.setViewState(t),this.requestRender()}getViewState(){return this.camera.getViewState()}destroy(){this.destroyed||(this.destroyed=!0,this.loadVersion+=1,this.frameId!==null&&(cancelAnimationFrame(this.frameId),this.frameId=null),this.resizeObserver.disconnect(),this.disposeTiles(this.tiles),this.tiles=[],this.gl.deleteBuffer(this.quadBuffer),this.gl.deleteVertexArray(this.vao),this.gl.deleteProgram(this.program))}async loadTile(t,n){try{const r=await fetch(t.url);if(!r.ok)throw new Error(`Tile fetch failed: ${r.status} ${r.statusText}`);const i=await r.blob(),o=await createImageBitmap(i);if(this.destroyed||n!==this.loadVersion)return o.close(),null;const s=this.gl.createTexture();if(!s)throw o.close(),new Error("Failed to create tile texture.");return this.gl.bindTexture(this.gl.TEXTURE_2D,s),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,1),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,o),this.gl.bindTexture(this.gl.TEXTURE_2D,null),o.close(),{id:t.id,bounds:t.bounds,texture:s}}catch(r){return console.error(`[M1TileRenderer] tile load failed: ${t.id}`,r),null}}resize(){if(this.destroyed)return;const t=this.canvas.getBoundingClientRect(),n=Math.max(1,t.width||this.canvas.clientWidth||1),r=Math.max(1,t.height||this.canvas.clientHeight||1),i=Math.max(1,window.devicePixelRatio||1),o=Math.max(1,Math.round(n*i)),s=Math.max(1,Math.round(r*i));(this.canvas.width!==o||this.canvas.height!==s)&&(this.canvas.width=o,this.canvas.height=s),this.camera.setViewport(n,r),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),!this.fitted&&!this.controlledViewState&&(this.fitToImage(),this.fitted=!0),this.requestRender()}fitToImage(){const t=this.camera.getViewportSize(),n=Math.min(t.width/this.imageWidth,t.height/this.imageHeight),r=Number.isFinite(n)&&n>0?n:1,i=t.width/r,o=t.height/r,s=(this.imageWidth-i)*.5,a=(this.imageHeight-o)*.5;this.camera.setViewState({zoom:r,offsetX:s,offsetY:a})}requestRender(){this.frameId!==null||this.destroyed||(this.frameId=requestAnimationFrame(()=>{this.frameId=null,this.render()}))}render(){if(!this.destroyed){this.gl.clearColor(this.clearColor[0],this.clearColor[1],this.clearColor[2],this.clearColor[3]),this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.useProgram(this.program),this.gl.bindVertexArray(this.vao),this.gl.uniformMatrix3fv(this.uCameraLocation,!1,this.camera.getMatrix()),this.gl.uniform1i(this.uTextureLocation,0);for(const t of this.tiles)this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,t.texture),this.gl.uniform4f(this.uBoundsLocation,t.bounds[0],t.bounds[1],t.bounds[2],t.bounds[3]),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4);this.gl.bindTexture(this.gl.TEXTURE_2D,null),this.gl.bindVertexArray(null)}}disposeTiles(t){for(const n of t)this.gl.deleteTexture(n.texture)}}const gi=.1,pi=4e6,bi=4096,wi=64,yi=1,Mi=4,Er=1e-6,Si=24;function en(e,t,n){return Math.max(t,Math.min(n,e))}function Gt(e){if(!Array.isArray(e)||e.length<3)return[];const t=e.map(([i,o])=>[i,o]),n=t[0],r=t[t.length-1];return!n||!r?[]:((n[0]!==r[0]||n[1]!==r[1])&&t.push([n[0],n[1]]),t)}function Ai(e){if(!Array.isArray(e)||e.length===0)return[];const t=[];for(const n of e){if(!Array.isArray(n)||n.length<2)continue;const r=Number(n[0]),i=Number(n[1]);if(!Number.isFinite(r)||!Number.isFinite(i))continue;const o=t[t.length-1];o&&Math.abs(o[0]-r)<1e-9&&Math.abs(o[1]-i)<1e-9||t.push([r,i])}return t}function xi(e,t,n){if(t<=Er||n<8)return[];const r=[];for(let i=0;i<=n;i+=1){const o=i/n*Math.PI*2;r.push([e[0]+Math.cos(o)*t,e[1]+Math.sin(o)*t])}return Gt(r)}function hn(e,t){if(!e.length)return[];let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[a,c]of e)a<n&&(n=a),a>i&&(i=a),c<r&&(r=c),c>o&&(o=c);if(!Number.isFinite(n)||!Number.isFinite(r))return[];const s=Math.max(t,1);return Gt([[n-s,r-s],[i+s,r-s],[i+s,o+s],[n-s,o+s]])}function Ti(e,t){let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[a,c]of e)a<n&&(n=a),a>i&&(i=a),c<r&&(r=c),c>o&&(o=c);const s=Math.max(t,1);return[n-s,r-s,i+s,o+s]}function Ei(e,t,n){const r=Math.max(gi,Number(n.minRasterStep)||0),i=Math.max(32768,Math.floor(n.maxRasterPixels||pi)),o=Math.max(256,Math.floor(n.maxRasterSize||bi)),s=Math.max(.001,e[2]-e[0]),a=Math.max(.001,e[3]-e[1]);let c=Math.max(r,Number.EPSILON),l=3,f=Math.ceil(s/c)+l*2+1,b=Math.ceil(a/c)+l*2+1;for(;(f>o||b>o||f*b>i)&&(c*=1.15,f=Math.ceil(s/c)+l*2+1,b=Math.ceil(a/c)+l*2+1,!(c>Math.max(s,a))););return f=Math.max(8,f),b=Math.max(8,b),{minX:e[0],minY:e[1],step:c,padding:l,width:f,height:b}}function Ri(e,t){if(typeof OffscreenCanvas<"u"){const r=new OffscreenCanvas(e,t).getContext("2d",{willReadFrequently:!0});if(r)return r}if(typeof document<"u"){const n=document.createElement("canvas");return n.width=e,n.height=t,n.getContext("2d",{willReadFrequently:!0})}return null}function Ci(e,t){return[(e[0]-t.minX)/t.step+t.padding,(e[1]-t.minY)/t.step+t.padding]}function Pi(e,t,n){const r=Ri(n.width,n.height);if(!r)return new Uint8Array(0);r.clearRect(0,0,n.width,n.height),r.fillStyle="#ffffff",r.strokeStyle="#ffffff",r.lineCap="round",r.lineJoin="round",r.lineWidth=t*2/n.step;const i=e.map(a=>Ci(a,n));if(i.length<=1){const a=i[0];if(!a)return new Uint8Array(0);r.beginPath(),r.arc(a[0],a[1],t/n.step,0,Math.PI*2),r.fill()}else{r.beginPath(),r.moveTo(i[0][0],i[0][1]);for(let a=1;a<i.length;a+=1)r.lineTo(i[a][0],i[a][1]);r.stroke()}const o=r.getImageData(0,0,n.width,n.height),s=new Uint8Array(n.width*n.height);for(let a=0;a<s.length;a+=1)s[a]=o.data[a*4+3]>=Si?1:0;return s}function Ii(e,t,n){const r=[],i=t+1,o=(a,c)=>c*i+a,s=(a,c)=>a>=0&&c>=0&&a<t&&c<n&&e[c*t+a]>0;for(let a=0;a<n;a+=1)for(let c=0;c<t;c+=1)s(c,a)&&(s(c,a-1)||r.push({start:o(c,a),end:o(c+1,a),dir:0}),s(c+1,a)||r.push({start:o(c+1,a),end:o(c+1,a+1),dir:1}),s(c,a+1)||r.push({start:o(c+1,a+1),end:o(c,a+1),dir:2}),s(c-1,a)||r.push({start:o(c,a+1),end:o(c,a),dir:3}));return r}function vi(e,t){const n=(t-e+4)%4;return n===1?0:n===0?1:n===3?2:3}function _i(e){if(!e.length)return[];const t=new Map;for(let i=0;i<e.length;i+=1){const o=t.get(e[i].start);o?o.push(i):t.set(e[i].start,[i])}const n=new Uint8Array(e.length),r=[];for(let i=0;i<e.length;i+=1){if(n[i])continue;const o=e[i],s=o.start;let a=o.end,c=o.dir;const l=[o.start,o.end];n[i]=1;let f=0;const b=e.length*3;for(;a!==s&&f<b;){const m=t.get(a);if(!m||m.length===0)break;let w=-1,g=1/0;for(const T of m){if(n[T])continue;const _=e[T],B=vi(c,_.dir);B<g&&(g=B,w=T)}if(w<0)break;n[w]=1;const S=e[w];a=S.end,c=S.dir,l.push(a),f+=1}l.length>=4&&l[0]===l[l.length-1]&&r.push(l)}return r}function Fi(e,t,n){const r=t+1,i=[];for(const o of e){const s=o%r,a=Math.floor(o/r);i.push([n.minX+(s-n.padding)*n.step,n.minY+(a-n.padding)*n.step])}return Gt(i)}function Ui(e){if(e.length<4)return 0;let t=0;for(let n=0;n<e.length-1;n+=1){const r=e[n],i=e[n+1];t+=r[0]*i[1]-i[0]*r[1]}return t*.5}function Bi(e,t=1e-9){const n=Gt(e);if(n.length<5)return n;const r=[n[0]];for(let i=1;i<n.length-1;i+=1){const o=r[r.length-1],s=n[i],a=n[i+1],c=(s[0]-o[0])*(a[1]-s[1])-(s[1]-o[1])*(a[0]-s[0]);Math.abs(c)<=t||r.push(s)}return r.push(r[0]),Gt(r)}function Li(e,t,n){const r=n[0]-t[0],i=n[1]-t[1],o=r*r+i*i;if(o<=1e-12){const b=e[0]-t[0],m=e[1]-t[1];return b*b+m*m}const s=en(((e[0]-t[0])*r+(e[1]-t[1])*i)/o,0,1),a=t[0]+r*s,c=t[1]+i*s,l=e[0]-a,f=e[1]-c;return l*l+f*f}function Ni(e,t){if(e.length<=2||t<=0)return e.slice();const n=new Uint8Array(e.length);n[0]=1,n[e.length-1]=1;const r=t*t,i=[[0,e.length-1]];for(;i.length>0;){const s=i.pop();if(!s)break;const[a,c]=s;if(c-a<=1)continue;let l=0,f=-1;for(let b=a+1;b<c;b+=1){const m=Li(e[b],e[a],e[c]);m>l&&(l=m,f=b)}f>=0&&l>r&&(n[f]=1,i.push([a,f],[f,c]))}const o=[];for(let s=0;s<e.length;s+=1)n[s]&&o.push(e[s]);return o}function zi(e,t){const n=Gt(e);if(n.length<5||t<=0)return n;const r=n.slice(0,-1),i=Ni(r,t);return i.length<3?n:Gt(i)}function Di(e,t){let n=Gt(e);if(t<=0||n.length<5)return n;for(let r=0;r<t;r+=1){const i=n.slice(0,-1);if(i.length<3)break;const o=[];for(let s=0;s<i.length;s+=1){const a=i[s],c=i[(s+1)%i.length];o.push([a[0]*.75+c[0]*.25,a[1]*.75+c[1]*.25],[a[0]*.25+c[0]*.75,a[1]*.25+c[1]*.75])}n=Gt(o)}return n}function xe(e,t){return t?Gt(e.map(([n,r])=>[en(n,t[0],t[2]),en(r,t[1],t[3])])):e}function ki(e,t){const n=Ai(e),r=Math.max(Er,Number(t.radius)||0);if(n.length===0||!Number.isFinite(r))return[];const i=Math.max(12,Math.floor(t.circleSides||wi));if(n.length===1)return xe(xi(n[0],r,i),t.clipBounds);const o=Ti(n,r),s=Ei(o,r,t),a=Pi(n,r,s);if(!a.length)return xe(hn(n,r),t.clipBounds);const c=Ii(a,s.width,s.height),l=_i(c);if(!l.length)return xe(hn(n,r),t.clipBounds);let f=[],b=0;for(const S of l){const T=Fi(S,s.width,s),_=Math.abs(Ui(T));_<=b||(b=_,f=T)}if(!f.length)return xe(hn(n,r),t.clipBounds);const m=typeof t.simplifyTolerance=="number"&&Number.isFinite(t.simplifyTolerance)?Math.max(0,t.simplifyTolerance):s.step*.2,w=typeof t.smoothingPasses=="number"&&Number.isFinite(t.smoothingPasses)?Math.round(en(t.smoothingPasses,0,Mi)):yi,g=zi(Di(Bi(f,s.step*.001),w),m);return xe(g,t.clipBounds)}function Qn(e){return typeof e=="number"&&Number.isFinite(e)}function Oi(e){return Array.isArray(e)&&e.length>=2&&Qn(e[0])&&Qn(e[1])}function Rr(e){return Array.isArray(e)&&e.length>0&&e.every(t=>Oi(t))}function Cr(e){return Array.isArray(e)&&e.length>0&&e.every(t=>Rr(t))}function Xi(e){return Array.isArray(e)&&e.length>0&&e.every(t=>Cr(t))}function Yi(e){if(!Array.isArray(e)||e.length<3)return[];const t=[];for(const i of e){if(!Array.isArray(i)||i.length<2)continue;const o=Number(i[0]),s=Number(i[1]);if(!Number.isFinite(o)||!Number.isFinite(s))continue;const a=t[t.length-1];a&&a[0]===o&&a[1]===s||t.push([o,s])}if(t.length<3)return[];const n=t[0],r=t[t.length-1];return(n[0]!==r[0]||n[1]!==r[1])&&t.push([n[0],n[1]]),t.length>=4?t:[]}function yn(e){if(!Array.isArray(e)||e.length<4)return 0;let t=0;for(let n=0;n<e.length-1;n+=1){const r=e[n],i=e[n+1];t+=r[0]*i[1]-i[0]*r[1]}return t*.5}function dn(e){if(!Array.isArray(e)||e.length===0)return[];const t=[];for(const o of e){const s=Yi(o);s.length>=4&&t.push(s)}if(t.length===0)return[];if(t.length===1)return[t[0]];let n=0,r=0;for(let o=0;o<t.length;o+=1){const s=Math.abs(yn(t[o]));s<=r||(r=s,n=o)}const i=[t[n]];for(let o=0;o<t.length;o+=1)o!==n&&i.push(t[o]);return i}function Pr(e){if(!e)return[];if(Rr(e)){const t=dn([e]);return t.length>0?[t]:[]}if(Cr(e)){const t=dn(e);return t.length>0?[t]:[]}if(Xi(e)){const t=[];for(const n of e){const r=dn(n);r.length>0&&t.push(r)}return t}return[]}function tr(e,t,n){let r=!1;for(let i=0,o=n.length-1;i<n.length;o=i,i+=1){const s=n[i][0],a=n[i][1],c=n[o][0],l=n[o][1];a>t!=l>t&&e<(c-s)*(t-a)/(l-a||Number.EPSILON)+s&&(r=!r)}return r}function Ie(e){const t=[];for(const n of e??[]){const r=Pr(n);for(const i of r){const o=i[0];if(!o||o.length<4)continue;let s=1/0,a=1/0,c=-1/0,l=-1/0;for(const[b,m]of o)b<s&&(s=b),b>c&&(c=b),m<a&&(a=m),m>l&&(l=m);if(!Number.isFinite(s)||!Number.isFinite(a)||!Number.isFinite(c)||!Number.isFinite(l))continue;let f=Math.abs(yn(o));for(let b=1;b<i.length;b+=1)f-=Math.abs(yn(i[b]));t.push({outer:o,holes:i.slice(1),minX:s,minY:a,maxX:c,maxY:l,area:Math.max(1e-6,f)})}}return t}function Ir(e,t,n){if(e<n.minX||e>n.maxX||t<n.minY||t>n.maxY||!tr(e,t,n.outer))return!1;for(const r of n.holes)if(tr(e,t,r))return!1;return!0}function nn(e,t,n){for(const r of n)if(Ir(e,t,r))return!0;return!1}const In=[160,160,160,255];function rt(e,t,n){return Math.max(t,Math.min(n,e))}function vn(e,t,n){const r=Number(e),i=Number(t),o=Number(n);return!Number.isFinite(r)||r<=0?1:!Number.isFinite(i)||!Number.isFinite(o)?r:Math.pow(2,i-o)*r}function Wi(e,t,n){let i=100*vn(e,t,n);if(Number(e)){let o="μm";return i>1e3&&(i/=1e3,o="mm"),`${i.toPrecision(3)} ${o}`}return`${Math.round(i*1e3)/1e3} pixels`}function Vi(e,t){return!e&&!t?!0:!e||!t?!1:Math.abs((e.zoom??0)-(t.zoom??0))<1e-6&&Math.abs((e.offsetX??0)-(t.offsetX??0))<1e-6&&Math.abs((e.offsetY??0)-(t.offsetY??0))<1e-6&&Math.abs((e.rotationDeg??0)-(t.rotationDeg??0))<1e-6}function Gi(e){const t=String(e??"").trim();if(!t)return"";if(/^bearer\s+/i.test(t)){const n=t.replace(/^bearer\s+/i,"").trim();return n?`Bearer ${n}`:""}return`Bearer ${t}`}function vr(e){const n=String(e??"").trim().match(/^#?([0-9a-fA-F]{6})$/);if(!n)return[...In];const r=Number.parseInt(n[1],16);return[r>>16&255,r>>8&255,r&255,255]}function qi(e){const t=[[...In]],n=new Map;for(const i of e??[]){const o=String(i?.termId??"");!o||n.has(o)||(n.set(o,t.length),t.push(vr(i?.termColor)))}const r=new Uint8Array(t.length*4);for(let i=0;i<t.length;i+=1)r[i*4]=t[i][0],r[i*4+1]=t[i][1],r[i*4+2]=t[i][2],r[i*4+3]=t[i][3];return{colors:r,termToPaletteIndex:n}}function er(e,t,n){const r=e.createShader(e.VERTEX_SHADER),i=e.createShader(e.FRAGMENT_SHADER);if(!r||!i)throw new Error("Shader allocation failed");if(e.shaderSource(r,t),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(r)||"vertex compile failed");if(e.shaderSource(i,n),e.compileShader(i),!e.getShaderParameter(i,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(i)||"fragment compile failed");const o=e.createProgram();if(!o)throw new Error("Program allocation failed");if(e.attachShader(o,r),e.attachShader(o,i),e.linkProgram(o),e.deleteShader(r),e.deleteShader(i),!e.getProgramParameter(o,e.LINK_STATUS))throw new Error(e.getProgramInfoLog(o)||"program link failed");return o}const Hi="rgba(255, 77, 79, 0.16)",nr="transparent",$i=3,Zi=2,_r=96,Ki=1,rr=[],Ce=[],rn=1e3,Fr=2,Ur=2,ji=4096,Ji=.2,Qi=1.12,to=.89,eo=32,no="#000000",ro=.1,io="#FFCF00",oo="#FF0000",so=1.5,ir=[2,2],ao=1,co=.25,uo=4,lo=1,fo=0,ho=4,mo=.05,go=256,or=1.5,ne={color:"#ff4d4f",width:2,lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},po={color:"#4cc9f0",width:2,lineDash:[10,8],lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},bo="rgba(23, 23, 25, 0.1)",wo=6,zt={fontFamily:"Pretendard, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",fontSize:11,fontWeight:600,textColor:"#171719",backgroundColor:"#FFCC00",borderColor:"rgba(0, 0, 0, 0)",borderWidth:0,paddingX:8,paddingY:4,offsetY:10,borderRadius:4},re={fontFamily:"Pretendard, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",fontSize:13,fontWeight:500,textColor:"#FFFFFF",backgroundColor:"rgba(23, 23, 25, 0.5)",borderRadius:4,paddingX:6,paddingY:3},sr={x:16,y:-24},yo=20,ar=1e-6;function Ot(e,t,n){return Math.max(t,Math.min(n,e))}function Br(e,t,n){if(!e||!n)return 0;const r=Number(n.minZoom),i=Number(n.maxZoom);return!Number.isFinite(r)||!Number.isFinite(i)||i-r<=ar||!Number.isFinite(t)?0:t>=i-ar?yo:0}function Xe(e){return e==="stamp-rectangle"||e==="stamp-circle"||e==="stamp-rectangle-4096px"||e==="stamp-rectangle-2mm2"||e==="stamp-circle-2mm2"||e==="stamp-circle-hpf-0.2mm2"}function Ee(e,t){return typeof e!="number"||!Number.isFinite(e)||e<=0?t:e}function Mo(e){return{rectangleAreaMm2:Ee(e?.rectangleAreaMm2,Fr),circleAreaMm2:Ee(e?.circleAreaMm2,Ur),rectanglePixelSize:Ee(e?.rectanglePixelSize,ji)}}function So(e,t){return typeof e!="number"||!Number.isFinite(e)?t:Ot(e,0,1)}function Ao(e){if(!Array.isArray(e))return ir;const t=e.filter(n=>Number.isFinite(n)&&n>=0);return t.length>0?t:ir}function xo(e){return typeof e!="number"||!Number.isFinite(e)?ao:Ot(e,co,uo)}function To(e){return typeof e!="number"||!Number.isFinite(e)?lo:Math.round(Ot(e,fo,ho))}function Eo(e){const t=Ee(e?.radius,eo),n=Ee(e?.cursorLineWidth,so),r=xo(e?.edgeDetail),i=To(e?.edgeSmoothing);return{radius:t,edgeDetail:r,edgeSmoothing:i,clickSelectRoi:e?.clickSelectRoi===!0,fillColor:e?.fillColor||no,fillOpacity:So(e?.fillOpacity,ro),cursorColor:e?.cursorColor||io,cursorActiveColor:e?.cursorActiveColor||oo,cursorLineWidth:n,cursorLineDash:Ao(e?.cursorLineDash)}}function Ro(e){return e*rn*rn}function cr(e,t,n){if(!e||!Number.isFinite(t)||t<=0)return[];if(n){const r=n.worldToScreen(e[0],e[1]),i=n.worldToScreen(e[0]+t,e[1]);if(r&&i){const o=Math.hypot(i[0]-r[0],i[1]-r[1]),s=[[r[0]-o,r[1]-o],[r[0]+o,r[1]-o],[r[0]+o,r[1]+o],[r[0]-o,r[1]+o]],a=[];for(const c of s){const l=n.screenToWorld(c);if(!l)throw new Error("Failed to create rectangle");a.push(l)}return vt(a)}}return vt([[e[0]-t,e[1]-t],[e[0]+t,e[1]-t],[e[0]+t,e[1]+t],[e[0]-t,e[1]+t]])}function Co(e,t,n=_r){if(!e||!Number.isFinite(t)||t<=0)return[];const r=[];for(let i=0;i<=n;i+=1){const o=i/n*Math.PI*2;r.push([e[0]+Math.cos(o)*t,e[1]+Math.sin(o)*t])}return vt(r)}function vt(e){if(!Array.isArray(e)||e.length<3)return[];const t=e.map(([i,o])=>[i,o]),n=t[0],r=t[t.length-1];return!n||!r?[]:((n[0]!==r[0]||n[1]!==r[1])&&t.push([n[0],n[1]]),t)}function on(e,t,n){if(!e||!t)return[];if(n){const r=n.worldToScreen(e[0],e[1]),i=n.worldToScreen(t[0],t[1]);if(r&&i){const o=[[r[0],r[1]],[i[0],r[1]],[i[0],i[1]],[r[0],i[1]]],s=[];for(const a of o){const c=n.screenToWorld(a);if(!c)return on(e,t);s.push(c)}return vt(s)}}return vt([[e[0],e[1]],[t[0],e[1]],[t[0],t[1]],[e[0],t[1]]])}function Mn(e,t,n=_r){if(!e||!t)return[];const r=(e[0]+t[0])*.5,i=(e[1]+t[1])*.5,o=Math.hypot(t[0]-e[0],t[1]-e[1])*.5;if(o<1)return[];const s=[];for(let a=0;a<=n;a+=1){const c=a/n*Math.PI*2;s.push([r+Math.cos(c)*o,i+Math.sin(c)*o])}return vt(s)}function tn(e){if(!Array.isArray(e)||e.length<4)return 0;let t=0;for(let n=0;n<e.length-1;n+=1){const r=e[n],i=e[n+1];t+=r[0]*i[1]-i[0]*r[1]}return Math.abs(t*.5)}function ur(e){if(!Array.isArray(e)||e.length===0)return[0,0,0,0];let t=1/0,n=1/0,r=-1/0,i=-1/0;for(const[o,s]of e)o<t&&(t=o),o>r&&(r=o),s<n&&(n=s),s>i&&(i=s);return[t,n,r,i]}function lr(e){return Array.isArray(e)&&e.length>=4&&tn(e)>Ki}function Sn(e,t,n=!1){if(t.length!==0){e.moveTo(t[0][0],t[0][1]);for(let r=1;r<t.length;r+=1)e.lineTo(t[r][0],t[r][1]);n&&e.closePath()}}function Vt(e,t,n,r=!1,i=!1,o=Hi){t.length!==0&&(e.beginPath(),Sn(e,t,r),i&&r&&(e.fillStyle=o,e.fill()),e.strokeStyle=n.color,e.lineWidth=n.width,e.lineJoin=n.lineJoin,e.lineCap=n.lineCap,e.shadowColor=n.shadowColor,e.shadowBlur=n.shadowBlur,e.shadowOffsetX=n.shadowOffsetX,e.shadowOffsetY=n.shadowOffsetY,e.setLineDash(n.lineDash),e.stroke(),e.setLineDash(Ce),e.shadowColor="rgba(0, 0, 0, 0)",e.shadowBlur=0,e.shadowOffsetX=0,e.shadowOffsetY=0)}function Po(e){if(typeof e!="string")return nr;const t=e.trim();return t.length>0?t:nr}function Lr(e){const t=Array.isArray(e?.lineDash)?e.lineDash.filter(s=>Number.isFinite(s)&&s>=0):Ce,n=typeof e?.width=="number"&&Number.isFinite(e.width)?Math.max(0,e.width):ne.width,r=typeof e?.shadowBlur=="number"&&Number.isFinite(e.shadowBlur)?Math.max(0,e.shadowBlur):ne.shadowBlur,i=typeof e?.shadowOffsetX=="number"&&Number.isFinite(e.shadowOffsetX)?e.shadowOffsetX:ne.shadowOffsetX,o=typeof e?.shadowOffsetY=="number"&&Number.isFinite(e.shadowOffsetY)?e.shadowOffsetY:ne.shadowOffsetY;return{color:e?.color||ne.color,width:n,lineDash:t.length?t:Ce,lineJoin:e?.lineJoin||ne.lineJoin,lineCap:e?.lineCap||ne.lineCap,shadowColor:e?.shadowColor||ne.shadowColor,shadowBlur:r,shadowOffsetX:i,shadowOffsetY:o}}function Te(e,t){return t?Lr({color:t.color??e.color,width:t.width??e.width,lineDash:t.lineDash??e.lineDash,lineJoin:t.lineJoin??e.lineJoin,lineCap:t.lineCap??e.lineCap,shadowColor:t.shadowColor??e.shadowColor,shadowBlur:t.shadowBlur??e.shadowBlur,shadowOffsetX:t.shadowOffsetX??e.shadowOffsetX,shadowOffsetY:t.shadowOffsetY??e.shadowOffsetY}):e}function fr(e,t){return e==null||t===null||t===void 0?!1:String(e)===String(t)}function Io(e){const t=e[0];return Array.isArray(t)&&Array.isArray(t[0])}function hr(e){return typeof e=="number"&&Number.isFinite(e)}function vo(e){return Array.isArray(e)&&e.length>=2&&hr(e[0])&&hr(e[1])}function _o(e){return Array.isArray(e)&&e.length>=2&&e.every(t=>vo(t))}function Nr(e,t){if(!(!Array.isArray(e)||e.length===0)){if(_o(e)){t.push(e.map(([n,r])=>[n,r]));return}for(const n of e)Nr(n,t)}}function dr(e,t){const n=[];Nr(e,n);const r=[];for(const i of n){if(i.length<2)continue;const o=t?vt(i):i;o.length>=(t?4:2)&&r.push(o)}return r}function Fo(e,t,n,r){if(!(t.length<4||n.length===0)){e.save(),e.beginPath(),Sn(e,t,!0);for(const i of n)i.length<4||Sn(e,i,!0);e.fillStyle=r,e.fill("evenodd"),e.restore()}}function _n(e){const t=typeof e?.paddingX=="number"&&Number.isFinite(e.paddingX)?Math.max(0,e.paddingX):zt.paddingX,n=typeof e?.paddingY=="number"&&Number.isFinite(e.paddingY)?Math.max(0,e.paddingY):zt.paddingY,r=typeof e?.fontSize=="number"&&Number.isFinite(e.fontSize)?Math.max(8,e.fontSize):zt.fontSize,i=typeof e?.borderWidth=="number"&&Number.isFinite(e.borderWidth)?Math.max(0,e.borderWidth):zt.borderWidth,o=typeof e?.offsetY=="number"&&Number.isFinite(e.offsetY)?e.offsetY:zt.offsetY,s=typeof e?.borderRadius=="number"&&Number.isFinite(e.borderRadius)?Math.max(0,e.borderRadius):zt.borderRadius;return{fontFamily:e?.fontFamily||zt.fontFamily,fontSize:r,fontWeight:e?.fontWeight||zt.fontWeight,textColor:e?.textColor||zt.textColor,backgroundColor:e?.backgroundColor||zt.backgroundColor,borderColor:e?.borderColor||zt.borderColor,borderWidth:i,paddingX:t,paddingY:n,offsetY:o,borderRadius:s}}function zr(e,t){return t?_n({fontFamily:t.fontFamily??e.fontFamily,fontSize:t.fontSize??e.fontSize,fontWeight:t.fontWeight??e.fontWeight,textColor:t.textColor??e.textColor,backgroundColor:t.backgroundColor??e.backgroundColor,borderColor:t.borderColor??e.borderColor,borderWidth:t.borderWidth??e.borderWidth,paddingX:t.paddingX??e.paddingX,paddingY:t.paddingY??e.paddingY,offsetY:t.offsetY??e.offsetY,borderRadius:t.borderRadius??e.borderRadius}):e}function Uo(e){const t=typeof e?.fontSize=="number"&&Number.isFinite(e.fontSize)?Math.max(8,e.fontSize):re.fontSize,n=typeof e?.borderRadius=="number"&&Number.isFinite(e.borderRadius)?Math.max(0,e.borderRadius):re.borderRadius,r=typeof e?.paddingX=="number"&&Number.isFinite(e.paddingX)?Math.max(0,e.paddingX):re.paddingX,i=typeof e?.paddingY=="number"&&Number.isFinite(e.paddingY)?Math.max(0,e.paddingY):re.paddingY;return{fontFamily:e?.fontFamily||re.fontFamily,fontSize:t,fontWeight:e?.fontWeight||re.fontWeight,textColor:e?.textColor||re.textColor,backgroundColor:e?.backgroundColor||re.backgroundColor,borderRadius:n,paddingX:r,paddingY:i}}function Bo(e){const t=typeof e?.x=="number"&&Number.isFinite(e.x)?e.x:sr.x,n=typeof e?.y=="number"&&Number.isFinite(e.y)?e.y:sr.y;return{x:t,y:n}}function An(e){return Number.isFinite(e)?`${Math.max(0,e).toFixed(3)} mm²`:"0.000 mm²"}function Lo(e){const t=typeof e?.format=="function"?e.format:An,n=Bo(e?.cursorOffset);return{enabled:e?.enabled===!0,format:t,style:Uo(e?.style),cursorOffsetX:n.x,cursorOffsetY:n.y}}function No(e){return{color:bo,width:wo,lineDash:Ce,lineJoin:e.lineJoin,lineCap:e.lineCap,shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0}}function Dr(e,t,n,r,i,o){const s=Math.max(0,Math.min(o,r*.5,i*.5));e.beginPath(),e.moveTo(t+s,n),e.lineTo(t+r-s,n),e.quadraticCurveTo(t+r,n,t+r,n+s),e.lineTo(t+r,n+i-s),e.quadraticCurveTo(t+r,n+i,t+r-s,n+i),e.lineTo(t+s,n+i),e.quadraticCurveTo(t,n+i,t,n+i-s),e.lineTo(t,n+s),e.quadraticCurveTo(t,n,t+s,n),e.closePath()}function zo(e){if(!e.length)return null;let t=1/0;for(const i of e)i[1]<t&&(t=i[1]);if(!Number.isFinite(t))return null;let n=1/0,r=-1/0;for(const i of e)Math.abs(i[1]-t)>.5||(i[0]<n&&(n=i[0]),i[0]>r&&(r=i[0]));return!Number.isFinite(n)||!Number.isFinite(r)?null:[(n+r)*.5,t]}function Do(e){let t=null;for(const n of e){const r=zo(n.outer);r&&(!t||r[1]<t[1]||r[1]===t[1]&&r[0]<t[0])&&(t=r)}return t}function mr(e){const t=Pr(e);if(t.length===0)return[];const n=[];for(const r of t){const i=r[0];if(!i||i.length<4)continue;const o=i.map(([a,c])=>[a,c]),s=[];for(let a=1;a<r.length;a+=1){const c=r[a];!c||c.length<4||s.push(c.map(([l,f])=>[l,f]))}n.push({outer:o,holes:s})}return n}function ko(e,t,n,r,i,o){const s=t.trim();if(!s)return;e.save(),e.font=`${o.fontWeight} ${o.fontSize}px ${o.fontFamily}`,e.textAlign="center",e.textBaseline="middle";const c=e.measureText(s).width+o.paddingX*2,l=o.fontSize+o.paddingY*2,f=Ot(n[0],c*.5+1,r-c*.5-1),b=Ot(n[1]-o.offsetY,l*.5+1,i-l*.5-1),m=f-c*.5,w=b-l*.5;e.fillStyle=o.backgroundColor,e.strokeStyle=o.borderColor,e.lineWidth=o.borderWidth,Dr(e,m,w,c,l,o.borderRadius),e.fill(),o.borderWidth>0&&e.stroke(),e.fillStyle=o.textColor,e.fillText(s,f,b+.5),e.restore()}function Oo(e,t,n,r,i,o,s,a){const c=t.trim();if(!c)return;e.save(),e.font=`${o.fontWeight} ${o.fontSize}px ${o.fontFamily}`,e.textAlign="center",e.textBaseline="middle";const f=e.measureText(c).width+o.paddingX*2,b=o.fontSize+o.paddingY*2,m=Ot(n[0]+s,f*.5+1,r-f*.5-1),w=Ot(n[1]+a,b*.5+1,i-b*.5-1),g=m-f*.5,S=w-b*.5;e.fillStyle=o.backgroundColor,Dr(e,g,S,f,b,o.borderRadius),e.fill(),e.fillStyle=o.textColor,e.fillText(c,m,w+.5),e.restore()}function Ye(e,t,n){return[Ot(e[0],0,t),Ot(e[1],0,n)]}function he(e){if(!Array.isArray(e)||e.length<2)return null;const t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:[t,n]}function kr({tool:e,imageWidth:t,imageHeight:n,imageMpp:r,imageZoom:i,stampOptions:o,brushOptions:s,projectorRef:a,onBrushTap:c,onDrawComplete:l,onPatchComplete:f,enabled:b,viewStateSignal:m,persistedRegions:w,patchRegions:g,persistedPolygons:S,drawFillColor:T,regionStrokeStyle:_,regionStrokeHoverStyle:B,regionStrokeActiveStyle:N,patchStrokeStyle:W,resolveRegionStrokeStyle:F,resolveRegionLabelStyle:X,overlayShapes:Z,hoveredRegionId:lt=null,activeRegionId:mt=null,regionLabelStyle:Tt,drawAreaTooltip:It,autoLiftRegionLabelAtMaxZoom:Ft=!1,regionLabelAutoLiftOffsetPx:nt,invalidateRef:Xt,className:se,style:ae}){const J=d.useRef(null),Yt=d.useRef(!1),qt=d.useRef(new Map),me=d.useRef(e),St=d.useRef({isDrawing:!1,pointerId:null,start:null,current:null,cursor:null,cursorScreen:null,points:[],screenPoints:[],stampCenter:null}),it=b??e!=="cursor",C=d.useMemo(()=>w&&w.length>0?w:!S||S.length===0?rr:S.map((u,h)=>({id:h,coordinates:u})),[w,S]),R=d.useMemo(()=>g??rr,[g]),U=d.useMemo(()=>{const u=[];for(let h=0;h<C.length;h+=1){const M=C[h],A=mr(M.coordinates);A.length!==0&&u.push({region:M,regionIndex:h,regionKey:M.id??h,polygons:A})}return u},[C]),Q=d.useMemo(()=>{const u=[];for(let h=0;h<R.length;h+=1){const M=R[h],A=mr(M.coordinates);A.length!==0&&u.push({region:M,regionIndex:h,regionKey:M.id??h,polygons:A})}return u},[R]),Y=d.useMemo(()=>Lr(_),[_]),st=d.useMemo(()=>Te(Y,B),[Y,B]),gt=d.useMemo(()=>Te(Y,N),[Y,N]),K=d.useMemo(()=>Te(po,W),[W]),V=d.useMemo(()=>Po(T),[T]),tt=d.useMemo(()=>_n(Tt),[Tt]),at=d.useMemo(()=>Lo(It),[It]),j=d.useMemo(()=>Mo(o),[o]),k=d.useMemo(()=>Eo(s),[s]),ft=d.useMemo(()=>({position:"absolute",inset:0,zIndex:2,width:"100%",height:"100%",display:"block",touchAction:"none",pointerEvents:it?"auto":"none",cursor:it?e==="brush"?"none":"crosshair":"default",...ae}),[it,e,ae]),ct=d.useCallback(()=>{const u=J.current;if(!u)return;const h=u.getBoundingClientRect(),M=Math.max(1,window.devicePixelRatio||1),A=Math.max(1,Math.round(h.width*M)),E=Math.max(1,Math.round(h.height*M));(u.width!==A||u.height!==E)&&(u.width=A,u.height=E)},[]),G=d.useCallback(u=>{const h=a.current;if(!h||u.length===0)return[];const M=new Array(u.length);for(let A=0;A<u.length;A+=1){const E=he(h.worldToScreen(u[A][0],u[A][1]));if(!E)return[];M[A]=E}return M},[a]),pt=d.useCallback(u=>{const h=a.current,M=J.current;if(!h||!M)return null;const A=M.getBoundingClientRect(),E=he(h.screenToWorld(A.left+u[0],A.top+u[1]));return E?Ye(E,t,n):null},[a,t,n]),At=d.useCallback(()=>{const u=a.current,h=u?.getViewState?.().rotationDeg??0;if(!(Math.abs(h%360)<.01||!u))return{worldToScreen:(M,A)=>he(u.worldToScreen(M,A)),screenToWorld:pt}},[a,pt]),Lt=d.useCallback(u=>{if(!Number.isFinite(u)||u<=0)return 0;const h=typeof r=="number"&&Number.isFinite(r)&&r>0?r:1,M=typeof i=="number"&&Number.isFinite(i)?i:0,A=a.current?.getViewState?.().zoom,E=typeof A=="number"&&Number.isFinite(A)&&A>0?A:1,D=M+Math.log2(E),L=Math.max(1e-9,vn(h,M,D));return u/L/E},[r,i,a]),Nt=d.useCallback((u,h)=>{if(!h)return[];let M=0;if(u==="stamp-rectangle-4096px"){const D=j.rectanglePixelSize*.5;return cr(h,D,At()).map(L=>Ye(L,t,n))}if(u==="stamp-rectangle"||u==="stamp-rectangle-2mm2"?M=u==="stamp-rectangle-2mm2"?Fr:j.rectangleAreaMm2:(u==="stamp-circle"||u==="stamp-circle-2mm2"||u==="stamp-circle-hpf-0.2mm2")&&(M=u==="stamp-circle-hpf-0.2mm2"?Ji:u==="stamp-circle-2mm2"?Ur:j.circleAreaMm2),!Number.isFinite(M)||M<=0)return[];const A=Ro(M);let E=[];if(u==="stamp-rectangle"||u==="stamp-rectangle-2mm2"){const D=Lt(Math.sqrt(A)*.5);E=cr(h,D,At())}else if(u==="stamp-circle"||u==="stamp-circle-2mm2"||u==="stamp-circle-hpf-0.2mm2"){const D=Lt(Math.sqrt(A/Math.PI));E=Co(h,D)}return E.length?E.map(D=>Ye(D,t,n)):[]},[Lt,t,n,j,At]),Et=d.useCallback(()=>{const u=St.current;return Xe(e)?Nt(e,u.stampCenter):e==="brush"?[]:u.isDrawing?e==="freehand"?u.points:e==="rectangle"?on(u.start,u.current,At()):e==="circular"?Mn(u.start,u.current):[]:[]},[e,Nt,At]),bt=d.useCallback(u=>{const h=St.current;if(!h.isDrawing||h.screenPoints.length===0)return;const M=h.screenPoints;if(M.length===0)return;const A=k.radius;if(!(!Number.isFinite(A)||A<=0)){if(u.save(),u.globalAlpha=k.fillOpacity,u.fillStyle=k.fillColor,u.strokeStyle=k.fillColor,u.lineCap="round",u.lineJoin="round",u.lineWidth=A*2,M.length===1)u.beginPath(),u.arc(M[0][0],M[0][1],A,0,Math.PI*2),u.fill();else{u.beginPath(),u.moveTo(M[0][0],M[0][1]);for(let E=1;E<M.length;E+=1)u.lineTo(M[E][0],M[E][1]);u.stroke()}u.restore()}},[k]),H=d.useCallback(u=>{const h=St.current,M=h.cursor;if(!M)return;const A=h.cursorScreen??he(a.current?.worldToScreen(M[0],M[1])??[]);if(!A)return;const E=k.radius;!Number.isFinite(E)||E<=0||(u.save(),u.beginPath(),u.arc(A[0],A[1],E,0,Math.PI*2),u.strokeStyle=h.isDrawing?k.cursorActiveColor:k.cursorColor,u.lineWidth=k.cursorLineWidth,u.setLineDash(k.cursorLineDash),u.stroke(),u.setLineDash(Ce),u.restore())},[a,k]),Ht=d.useCallback(()=>{ct();const u=J.current;if(!u)return;const h=u.getContext("2d");if(!h)return;const M=Math.max(1,window.devicePixelRatio||1),A=u.width/M,E=u.height/M;if(h.setTransform(1,0,0,1,0,0),h.clearRect(0,0,u.width,u.height),h.setTransform(M,0,0,M,0,0),U.length>0)for(const L of U){const{region:et,polygons:$,regionIndex:O,regionKey:ut}=L,dt=fr(mt,ut)?"active":fr(lt,ut)?"hover":"default";let Ut=dt==="active"?gt:dt==="hover"?st:Y;if(F){const Mt=F({region:et,regionId:ut,regionIndex:O,state:dt});Ut=Te(Ut,Mt||void 0)}const xt=dt==="default"?null:No(Ut);for(const Mt of $){const Wt=G(Mt.outer);Wt.length>=4&&(xt&&Vt(h,Wt,xt,!0,!1),Vt(h,Wt,Ut,!0,!1));for(const $t of Mt.holes){const Rt=G($t);Rt.length>=4&&(xt&&Vt(h,Rt,xt,!0,!1),Vt(h,Rt,Ut,!0,!1))}}}if(Q.length>0)for(const L of Q)for(const et of L.polygons){const $=G(et.outer);$.length>=4&&Vt(h,$,K,!0,!1);for(const O of et.holes){const ut=G(O);ut.length>=4&&Vt(h,ut,K,!0,!1)}}if(Array.isArray(Z)&&Z.length>0){const L=!!globalThis.__OPEN_PLANT_DEBUG_OVERLAY__,et=G(vt([[0,0],[t,0],[t,n],[0,n]]));for(let $=0;$<Z.length;$+=1){const O=Z[$];if(!O?.coordinates?.length||O.visible===!1)continue;const ut=O.closed??Io(O.coordinates),dt=dr(O.coordinates,ut);if(O.invertedFill?.fillColor){const xt=[],Mt=dr(O.coordinates,!0);for(const Wt of Mt){const $t=G(Wt);$t.length>=4&&xt.push($t)}if(L){const Wt=String(O.id??$),$t=`${et.length}|${Mt.length}|${xt.length}|${O.invertedFill.fillColor}`;qt.current.get(Wt)!==$t&&(qt.current.set(Wt,$t),console.debug("[open-plant] invertedFill",{id:O.id??$,outerRingPoints:et.length,sourceRingCount:Mt.length,holeRingCount:xt.length,fillColor:O.invertedFill.fillColor}))}Fo(h,et,xt,O.invertedFill.fillColor)}if(dt.length===0)continue;const Ut=Te(Y,O.stroke??O.strokeStyle);for(const xt of dt){const Mt=G(xt);Mt.length<2||Vt(h,Mt,Ut,ut,O.fill??!1)}}}const D=Et();if(it){if(e==="brush")bt(h),H(h);else if(D.length>0)if(e==="freehand"){const L=G(D);L.length>=2&&Vt(h,L,Y,!1,!1),L.length>=3&&Vt(h,G(vt(D)),Y,!0,!0,V)}else{const L=G(D);L.length>=4&&Vt(h,L,Y,!0,!0,V)}}if(U.length>0){const L=Math.max(1e-6,a.current?.getViewState?.().zoom??1),et=typeof nt=="number"&&Number.isFinite(nt)?Math.max(0,nt):Br(Ft,L,a.current?.getZoomRange?.());for(const $ of U){if(!$.region.label)continue;const O=Do($.polygons);if(!O)continue;const ut=he(a.current?.worldToScreen(O[0],O[1])??[]);if(!ut)continue;let dt=zr(tt,X?.({region:$.region,regionId:$.regionKey,regionIndex:$.regionIndex,zoom:L}));et>0&&(dt={...dt,offsetY:dt.offsetY+et}),ko(h,$.region.label,ut,A,E,dt)}}if(at.enabled&&it&&(e==="freehand"||e==="rectangle"||e==="circular")){const L=St.current;if(L.isDrawing){const et=e==="freehand"?vt(D):D;if(et.length>=4){const $=tn(et),O=typeof r=="number"&&Number.isFinite(r)&&r>0?r:0,ut=O>0?$*O*O/(rn*rn):0;let dt=An(ut);try{dt=at.format(ut)}catch{dt=An(ut)}const Ut=L.cursorScreen??(L.current?he(a.current?.worldToScreen(L.current[0],L.current[1])??[]):null);Ut&&Oo(h,dt,Ut,A,E,at.style,at.cursorOffsetX,at.cursorOffsetY)}}}},[it,e,Et,bt,H,ct,G,t,n,a,U,Z,lt,mt,Y,st,gt,V,Q,K,F,X,tt,at,Ft,nt,r]),z=d.useCallback(()=>{Yt.current||(Yt.current=!0,requestAnimationFrame(()=>{Yt.current=!1,Ht()}))},[Ht]),wt=d.useCallback((u=!1)=>{const h=St.current,M=J.current;if(M&&h.pointerId!==null&&M.hasPointerCapture(h.pointerId))try{M.releasePointerCapture(h.pointerId)}catch{}h.isDrawing=!1,h.pointerId=null,h.start=null,h.current=null,h.points=[],h.screenPoints=[],h.stampCenter=null,u||(h.cursor=null,h.cursorScreen=null)},[]),ot=d.useCallback(u=>{const h=a.current;if(!h||t<=0||n<=0)return null;const M=he(h.screenToWorld(u.clientX,u.clientY));return M?Ye(M,t,n):null},[a,t,n]),ht=d.useCallback(u=>{const h=J.current;if(!h)return null;const M=h.getBoundingClientRect(),A=Ot(u.clientX-M.left,0,M.width),E=Ot(u.clientY-M.top,0,M.height);return!Number.isFinite(A)||!Number.isFinite(E)?null:[A,E]},[]),Ae=d.useCallback(()=>{const u=St.current;if(!u.isDrawing){wt(!0),z();return}let h=[];if(e==="freehand")u.points.length>=$i&&(h=vt(u.points));else if(e==="rectangle")h=on(u.start,u.current,At());else if(e==="circular")h=Mn(u.start,u.current);else if(e==="brush"){const M=u.points[u.points.length-1]??u.current??u.start;if(k.clickSelectRoi&&M&&u.points.length<=1&&c?.(M)){wt(!0),z();return}const A=k.edgeDetail,E=Math.max(mo,k.radius*2/(go*A)),D=u.screenPoints.length>0?u.screenPoints:G(u.points),L=ki(D,{radius:k.radius,minRasterStep:E,circleSides:Math.max(24,Math.round(64*A)),simplifyTolerance:E*.25,smoothingPasses:k.edgeSmoothing}),et=[];for(const $ of L){const O=pt($);O&&et.push(O)}h=vt(et)}(e==="freehand"||e==="rectangle"||e==="circular"||e==="brush")&&lr(h)&&l&&l({tool:e,intent:e==="brush"?"brush":"roi",coordinates:h,bbox:ur(h),areaPx:tn(h)}),wt(!0),z()},[e,l,wt,z,G,pt,At,k.radius,k.edgeDetail,k.edgeSmoothing,k.clickSelectRoi,c]),jt=d.useCallback((u,h)=>{const M=Nt(u,h);if(!lr(M))return;const A=u==="stamp-rectangle-4096px"?"patch":"roi",E={tool:u,intent:A,coordinates:M,bbox:ur(M),areaPx:tn(M)};l?.(E),A==="patch"&&f&&f(E)},[Nt,l,f]),ge=d.useCallback((u,h,M)=>{const A=or*or,E=u.screenPoints[u.screenPoints.length-1];if(!E){u.points.push(h),u.screenPoints.push(M),u.current=h;return}const D=M[0]-E[0],L=M[1]-E[1];D*D+L*L>=A?(u.points.push(h),u.screenPoints.push(M)):(u.points[u.points.length-1]=h,u.screenPoints[u.screenPoints.length-1]=M),u.current=h},[]),ve=d.useCallback(u=>{if(!it||e==="cursor"||u.button!==0)return;const h=ot(u);if(!h)return;const M=ht(u);if(!M)return;if(u.preventDefault(),u.stopPropagation(),Xe(e)){const D=St.current;D.stampCenter=h,jt(e,h),z();return}const A=J.current;A&&A.setPointerCapture(u.pointerId);const E=St.current;E.isDrawing=!0,E.pointerId=u.pointerId,E.start=h,E.current=h,E.cursor=h,E.cursorScreen=M,E.points=e==="freehand"||e==="brush"?[h]:[],E.screenPoints=e==="brush"?[M]:[],z()},[it,e,ot,ht,jt,z]),ce=d.useCallback(u=>{if(!it||e==="cursor")return;const h=ot(u);if(!h)return;const M=ht(u);if(!M)return;const A=St.current;if(A.cursor=h,A.cursorScreen=M,Xe(e)){A.stampCenter=h,u.preventDefault(),u.stopPropagation(),z();return}if(e==="brush"){if(!A.isDrawing||A.pointerId!==u.pointerId){z();return}u.preventDefault(),u.stopPropagation(),ge(A,h,M),z();return}if(!(!A.isDrawing||A.pointerId!==u.pointerId)){if(u.preventDefault(),u.stopPropagation(),e==="freehand"){const E=a.current,D=Math.max(1e-6,E?.getViewState?.().zoom??1),L=Zi/D,et=L*L,$=A.points[A.points.length-1];if(!$)A.points.push(h);else{const O=h[0]-$[0],ut=h[1]-$[1];O*O+ut*ut>=et&&A.points.push(h)}}else A.current=h;z()}},[it,e,ot,ht,z,a,ge]),yt=d.useCallback(u=>{const h=St.current;if(!h.isDrawing||h.pointerId!==u.pointerId)return;u.preventDefault(),u.stopPropagation();const M=ot(u),A=ht(u);M&&(h.cursor=M,A&&(h.cursorScreen=A),e==="brush"?A&&ge(h,M,A):h.current=M);const E=J.current;if(E&&E.hasPointerCapture(u.pointerId))try{E.releasePointerCapture(u.pointerId)}catch{}Ae()},[Ae,ot,ht,e,ge]),_e=d.useCallback(()=>{const u=St.current;let h=!1;e==="brush"&&!u.isDrawing&&u.cursor&&(u.cursor=null,u.cursorScreen=null,h=!0),Xe(e)&&u.stampCenter&&(u.stampCenter=null,h=!0),h&&z()},[e,z]);return d.useEffect(()=>{ct(),z();const u=J.current;if(!u)return;const h=new ResizeObserver(()=>{ct(),z()});return h.observe(u),()=>{h.disconnect()}},[ct,z]),d.useEffect(()=>{it||wt(),z()},[it,z,wt]),d.useEffect(()=>{me.current!==e&&(me.current=e,wt(),z())},[e,wt,z]),d.useEffect(()=>{z()},[m,C,Z,z]),d.useEffect(()=>{if(Xt)return Xt.current=z,()=>{Xt.current===z&&(Xt.current=null)}},[Xt,z]),d.useEffect(()=>{if(!it)return;const u=h=>{h.key==="Escape"&&(wt(),z())};return window.addEventListener("keydown",u),()=>{window.removeEventListener("keydown",u)}},[it,wt,z]),kt.jsx("canvas",{ref:J,className:se,style:ft,onPointerDown:ve,onPointerMove:ce,onPointerUp:yt,onPointerCancel:yt,onPointerLeave:_e,onContextMenu:u=>{it&&u.preventDefault()},onWheel:u=>{if(!it)return;const h=J.current,M=a.current;if(!h||typeof M?.zoomBy!="function")return;u.preventDefault(),u.stopPropagation();const A=h.getBoundingClientRect(),E=u.clientX-A.left,D=u.clientY-A.top;M.zoomBy(u.deltaY<0?Qi:to,E,D),z()}})}function gr(e){return String(e??"").replace(/\/+$/,"")}function Or(e){const t=String(e??"");return t.startsWith("/")?t:`/${t}`}function Xo(e){const t=gr(e);if(!t)return"";if(/\/TileGroup\d+$/i.test(t))return t;let n=null;try{n=new URL(t)}catch{n=null}if(n){const r=`${n.protocol}//${n.host}`,i=gr(n.pathname||"");return/\/ims$/i.test(i)?`${r}${i}`:/\/tiles$/i.test(i)?`${r}${i}`:`${r}${i}/tiles`}return/\/ims$/i.test(t)?"/ims":/\/tiles$/i.test(t)?`${t}`:`${t}/tiles`}function Yo(e,t){const n=e?.imsInfo||{},r=!!e?.imsInfo,i=Number(n.width??e?.width??0),o=Number(n.height??e?.height??0),s=Number(n.tileSize??e?.tileSize??0),a=Number(n.zoom??e?.zoom??0),c=String(n.path??e?.path??""),l=Number(n.mpp??e?.mpp??0);if(!i||!o||!s||!c)throw new Error("이미지 메타데이터가 불완전합니다. width/height/tileSize/path 확인 필요");const f=Array.isArray(e?.terms)?e.terms.map(g=>({termId:String(g?.termId??""),termName:String(g?.termName??""),termColor:String(g?.termColor??"")})):[],b=Or(c),m=Xo(t),w=r?(g,S,T)=>`${m}${b}/${g}/${T}_${S}.webp`:void 0;return{id:e?._id||"unknown",name:e?.name||"unknown",width:i,height:o,mpp:Number.isFinite(l)&&l>0?l:void 0,tileSize:s,maxTierZoom:Number.isFinite(a)?Math.max(0,Math.floor(a)):0,tilePath:c,tileBaseUrl:t,terms:f,tileUrlBuilder:w}}function Fn(e,t,n,r){if(e.tileUrlBuilder)return e.tileUrlBuilder(t,n,r);const i=Or(e.tilePath);return`${e.tileBaseUrl}${i}/${t}/${r}_${n}.webp`}const Pt={width:200,height:125,margin:16,position:"bottom-right",borderRadius:6,borderWidth:0,backgroundColor:"rgba(4, 10, 18, 0.88)",borderColor:"rgba(230, 244, 255, 0.35)",viewportBorderColor:"#171719",viewportBorderStyle:"dash",viewportFillColor:"transparent",interactive:!0,showThumbnail:!0,maxThumbnailTiles:16};function pr(e,t,n,r){const i=t.length;if(i===4){for(let o=0;o<i;o+=1){const s=t[o],a=t[(o+1)%i],c=Math.hypot(a[0]-s[0],a[1]-s[1]);if(c<1e-6)continue;const l=Math.max(1,Math.round((c+r)/(n+r))),f=l*n+(l-1)*r,b=c/Math.max(1e-6,f),m=n*b,w=r*b;e.beginPath(),e.moveTo(s[0],s[1]),e.lineTo(a[0],a[1]),e.setLineDash([m,w]),e.lineDashOffset=0,e.stroke()}e.setLineDash([]),e.lineDashOffset=0}}function Se(e,t,n=1){return typeof e!="number"||!Number.isFinite(e)?t:Math.max(n,e)}function We(e){return Array.isArray(e)&&e.length===4&&Number.isFinite(e[0])&&Number.isFinite(e[1])&&Number.isFinite(e[2])&&Number.isFinite(e[3])}const Wo={position:"absolute",top:4,right:4,zIndex:1,width:18,height:18,borderRadius:999,border:"1px solid rgba(255,255,255,0.4)",background:"rgba(16, 17, 19, 0.85)",color:"#fff",fontSize:12,lineHeight:1,cursor:"pointer",padding:0,display:"flex",alignItems:"center",justifyContent:"center"};function Xr({source:e,projectorRef:t,authToken:n="",options:r,invalidateRef:i,className:o,style:s}){const a=d.useRef(null),c=d.useRef(null),l=d.useRef(null),f=d.useRef({active:!1,pointerId:null}),b=d.useRef(null),m=d.useRef(!1),w=Se(r?.width,Pt.width,64),g=Se(r?.height,Pt.height,48),S=d.useMemo(()=>{const C=Math.max(1,e.width),R=Math.max(1,e.height),U=C/R,Q=w/g;let Y,st;return U>Q?(Y=w,st=w/U):(st=g,Y=g*U),{x:(w-Y)/2,y:(g-st)/2,w:Y,h:st}},[e.width,e.height,w,g]),T=Se(r?.margin,Pt.margin,0),_=Se(r?.borderRadius,Pt.borderRadius,0),B=Se(r?.borderWidth,Pt.borderWidth,0),N=Math.max(1,Math.round(Se(r?.maxThumbnailTiles,Pt.maxThumbnailTiles,1))),W=r?.backgroundColor||Pt.backgroundColor,F=r?.borderColor||Pt.borderColor,X=r?.viewportBorderColor||Pt.viewportBorderColor,Z=r?.viewportBorderStyle==="stroke"||r?.viewportBorderStyle==="dash"?r.viewportBorderStyle:Pt.viewportBorderStyle,lt=r?.viewportFillColor??Pt.viewportFillColor,mt=r?.interactive??Pt.interactive,Tt=r?.showThumbnail??Pt.showThumbnail,It=r?.position||Pt.position,Ft=r?.onClose,nt=r?.closeIcon,Xt=r?.closeButtonStyle,se=d.useMemo(()=>{const C={};return It==="top-left"||It==="bottom-left"?C.left=T:C.right=T,It==="top-left"||It==="top-right"?C.top=T:C.bottom=T,{position:"absolute",...C,width:w,height:g,borderRadius:_,overflow:"hidden",zIndex:4,pointerEvents:mt?"auto":"none",touchAction:"none",boxShadow:"0 10px 22px rgba(0, 0, 0, 0.3)",...s}},[T,It,w,g,_,mt,s]),ae=d.useCallback(()=>{const C=a.current;if(!C)return;const R=C.getContext("2d");if(!R)return;const U=w,Q=g,Y=Math.max(1,window.devicePixelRatio||1),st=Math.max(1,Math.round(U*Y)),gt=Math.max(1,Math.round(Q*Y));(C.width!==st||C.height!==gt)&&(C.width=st,C.height=gt),R.setTransform(1,0,0,1,0,0),R.clearRect(0,0,C.width,C.height),R.setTransform(Y,0,0,Y,0,0),R.fillStyle=W,R.fillRect(0,0,U,Q);const{x:K,y:V,w:tt,h:at}=S,j=c.current;j&&R.drawImage(j,K,V,tt,at),R.strokeStyle=F,R.lineWidth=B,R.strokeRect(B*.5,B*.5,U-B,Q-B);const k=t.current,ft=k?.getViewBounds?.(),ct=k?.getViewCorners?.(),G=We(ft)?ft:We(l.current)?l.current:null;if(!G)return;l.current=G;const pt=tt/Math.max(1,e.width),At=at/Math.max(1,e.height),Lt=Array.isArray(ct)&&ct.length>=4&&ct.every(ot=>Array.isArray(ot)&&ot.length>=2&&Number.isFinite(ot[0])&&Number.isFinite(ot[1]))?ct:null,Nt=Z==="dash";if(Lt){const ot=Lt.map(ht=>[K+ht[0]*pt,V+ht[1]*At]);R.save(),R.beginPath(),R.rect(K,V,tt,at),R.clip(),R.beginPath();for(let ht=0;ht<ot.length;ht+=1)ht===0?R.moveTo(ot[ht][0],ot[ht][1]):R.lineTo(ot[ht][0],ot[ht][1]);R.closePath(),R.fillStyle=lt,R.fill(),R.strokeStyle=X,R.lineWidth=2.25,Nt?pr(R,ot,4,3):R.stroke(),R.restore();return}const Et=rt(K+G[0]*pt,K,K+tt),bt=rt(V+G[1]*At,V,V+at),H=rt(K+G[2]*pt,K,K+tt),Ht=rt(V+G[3]*At,V,V+at),z=Math.max(1,H-Et),wt=Math.max(1,Ht-bt);if(R.fillStyle=lt,R.fillRect(Et,bt,z,wt),R.strokeStyle=X,R.lineWidth=2.25,Nt){const ot=[[Et+.5,bt+.5],[Et+.5+Math.max(1,z-1),bt+.5],[Et+.5+Math.max(1,z-1),bt+.5+Math.max(1,wt-1)],[Et+.5,bt+.5+Math.max(1,wt-1)]];pr(R,ot,4,3)}else R.strokeRect(Et+.5,bt+.5,Math.max(1,z-1),Math.max(1,wt-1))},[w,g,S,W,F,B,t,e.width,e.height,lt,X,Z]),J=d.useCallback(()=>{m.current||(m.current=!0,b.current=requestAnimationFrame(()=>{m.current=!1,b.current=null,ae()}))},[ae]),Yt=d.useCallback((C,R)=>{const U=a.current;if(!U)return null;const Q=U.getBoundingClientRect();if(!Q.width||!Q.height)return null;const Y=Q.width/w,st=Q.height/g,gt=S.x*Y,K=S.y*st,V=S.w*Y,tt=S.h*st,at=rt((C-Q.left-gt)/V,0,1),j=rt((R-Q.top-K)/tt,0,1);return[at*e.width,j*e.height]},[e.width,e.height,w,g,S]),qt=d.useCallback((C,R)=>{const U=t.current;if(!U)return;if(U.setViewCenter){U.setViewCenter(C,R),J();return}const Q=U.getViewBounds?.(),Y=We(Q)?Q:We(l.current)?l.current:null;if(!Y)return;const st=Math.max(1e-6,Y[2]-Y[0]),gt=Math.max(1e-6,Y[3]-Y[1]);U.setViewState({offsetX:C-st*.5,offsetY:R-gt*.5}),J()},[t,J]),me=d.useCallback(C=>{if(!mt||C.button!==0)return;const R=a.current;if(!R)return;const U=Yt(C.clientX,C.clientY);U&&(C.preventDefault(),C.stopPropagation(),R.setPointerCapture(C.pointerId),f.current={active:!0,pointerId:C.pointerId},qt(U[0],U[1]))},[mt,Yt,qt]),St=d.useCallback(C=>{const R=f.current;if(!R.active||R.pointerId!==C.pointerId)return;const U=Yt(C.clientX,C.clientY);U&&(C.preventDefault(),C.stopPropagation(),qt(U[0],U[1]))},[Yt,qt]),it=d.useCallback(C=>{const R=f.current;if(!R.active||R.pointerId!==C.pointerId)return;const U=a.current;if(U&&U.hasPointerCapture(C.pointerId))try{U.releasePointerCapture(C.pointerId)}catch{}f.current={active:!1,pointerId:null},J()},[J]);return d.useEffect(()=>{let C=!1;c.current=null,J();const R=0,U=2**(e.maxTierZoom-R),Q=Math.ceil(e.width/U),Y=Math.ceil(e.height/U),st=Math.max(1,Math.ceil(Q/e.tileSize)),gt=Math.max(1,Math.ceil(Y/e.tileSize)),K=st*gt;if(!Tt||K>N)return;const V=document.createElement("canvas");V.width=Math.max(1,Math.round(S.w)),V.height=Math.max(1,Math.round(S.h));const tt=V.getContext("2d");if(!tt)return;tt.fillStyle=W,tt.fillRect(0,0,V.width,V.height);const at=[];for(let j=0;j<gt;j+=1)for(let k=0;k<st;k+=1){const ft=k*e.tileSize*U,ct=j*e.tileSize*U,G=Math.min((k+1)*e.tileSize,Q)*U,pt=Math.min((j+1)*e.tileSize,Y)*U;at.push({url:Fn(e,R,k,j),bounds:[ft,ct,G,pt]})}return Promise.allSettled(at.map(async j=>{const k=!!n,ft=await fetch(j.url,{headers:k?{Authorization:n}:void 0});if(!ft.ok)throw new Error(`HTTP ${ft.status}`);const ct=await createImageBitmap(await ft.blob());return{tile:j,bitmap:ct}})).then(j=>{if(C){for(const ct of j)ct.status==="fulfilled"&&ct.value.bitmap.close();return}const k=V.width/Math.max(1,e.width),ft=V.height/Math.max(1,e.height);for(const ct of j){if(ct.status!=="fulfilled")continue;const{tile:{bounds:G},bitmap:pt}=ct.value,At=G[0]*k,Lt=G[1]*ft,Nt=Math.max(1,(G[2]-G[0])*k),Et=Math.max(1,(G[3]-G[1])*ft);tt.drawImage(pt,At,Lt,Nt,Et),pt.close()}c.current=V,J()}),()=>{C=!0}},[e,n,S,W,Tt,N,J]),d.useEffect(()=>{J()},[J]),d.useEffect(()=>{if(i)return i.current=J,()=>{i.current===J&&(i.current=null)}},[i,J]),d.useEffect(()=>()=>{f.current={active:!1,pointerId:null},b.current!==null&&(cancelAnimationFrame(b.current),b.current=null),m.current=!1},[]),kt.jsxs("div",{className:o,style:se,children:[kt.jsx("canvas",{ref:a,style:{width:"100%",height:"100%",display:"block",borderRadius:"inherit"},onPointerDown:me,onPointerMove:St,onPointerUp:it,onPointerCancel:it,onContextMenu:C=>{C.preventDefault()},onWheel:C=>{C.preventDefault(),C.stopPropagation()}}),Ft&&kt.jsx("button",{type:"button","aria-label":"Hide overview map",onClick:C=>{C.stopPropagation(),Ft()},style:Xt?{...Xt}:{...Wo},children:nt??"×"})]})}function Vo({imageWidth:e,imageHeight:t,tiles:n,viewState:r,className:i,style:o}){const s=d.useRef(null),a=d.useRef(null),c=d.useMemo(()=>({width:"100%",height:"100%",display:"block",...o}),[o]);return d.useEffect(()=>{const l=s.current;if(!l)return;const f=new Tr({canvas:l,imageWidth:e,imageHeight:t,initialViewState:r});return a.current=f,f.setTiles(n),()=>{f.destroy(),a.current=null}},[e,t]),d.useEffect(()=>{const l=a.current;l&&l.setTiles(n)},[n]),d.useEffect(()=>{const l=a.current;!l||!r||l.setViewState(r)},[r]),kt.jsx("canvas",{ref:s,className:i,style:c})}function Yr(e){const t=e.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER;return Math.max(0,Math.min(Math.floor(e.count??0),Math.floor((e.positions?.length??0)/2),e.paletteIndices?.length??0,t))}function Pe(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return null;const n=Ie(t??[]);if(n.length===0){const g={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return e.fillModes instanceof Uint8Array&&(g.fillModes=new Uint8Array(0)),e.ids instanceof Uint32Array&&(g.ids=new Uint32Array(0)),g}const r=Yr(e),i=e.positions,o=e.paletteIndices,s=e.fillModes instanceof Uint8Array&&e.fillModes.length>=r?e.fillModes:null,a=e.ids instanceof Uint32Array&&e.ids.length>=r?e.ids:null,c=new Float32Array(r*2),l=new Uint16Array(r),f=s?new Uint8Array(r):null,b=a?new Uint32Array(r):null;let m=0;for(let g=0;g<r;g+=1){const S=i[g*2],T=i[g*2+1];nn(S,T,n)&&(c[m*2]=S,c[m*2+1]=T,l[m]=o[g],f&&(f[m]=s[g]),b&&(b[m]=a[g]),m+=1)}const w={count:m,positions:c.subarray(0,m*2),paletteIndices:l.subarray(0,m)};return f&&(w.fillModes=f.subarray(0,m)),b&&(w.ids=b.subarray(0,m)),w}function Wr(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return new Uint32Array(0);const n=Ie(t??[]);if(n.length===0)return new Uint32Array(0);const r=Yr(e);if(r===0)return new Uint32Array(0);const i=e.positions,o=new Uint32Array(r);let s=0;for(let a=0;a<r;a+=1){const c=i[a*2],l=i[a*2+1];nn(c,l,n)&&(o[s]=a,s+=1)}return o.subarray(0,s)}let Ve=null;const Go=`
|
|
33
33
|
struct Params {
|
|
34
34
|
pointCount: u32,
|
|
35
35
|
boundsCount: u32,
|
|
@@ -60,7 +60,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
60
60
|
}
|
|
61
61
|
outputMask[i] = inside;
|
|
62
62
|
}
|
|
63
|
-
`;function qo(){if(typeof navigator>"u")return!1;const e=navigator;return typeof e.gpu=="object"&&e.gpu!==null}function Vr(){if(!qo())return null;const t=navigator.gpu;if(!t||typeof t!="object")return null;const n=t;return typeof n.requestAdapter!="function"?null:n}const Ge=globalThis.GPUShaderStage?.COMPUTE??4,mn=globalThis.GPUBufferUsage?.STORAGE??128,qe=globalThis.GPUBufferUsage?.COPY_DST??8,Ho=globalThis.GPUBufferUsage?.COPY_SRC??4,$o=globalThis.GPUBufferUsage?.UNIFORM??64,Zo=globalThis.GPUBufferUsage?.MAP_READ??1,Ko=globalThis.GPUMapMode?.READ??1;async function jo(){const e=Vr();if(!e)return{supported:!1,features:[]};const t=await e.requestAdapter();return t?{supported:!0,adapterName:t.info?.description??t.info?.vendor??"unknown",features:Array.from(t.features),limits:{maxStorageBufferBindingSize:Number(t.limits.maxStorageBufferBindingSize),maxComputeInvocationsPerWorkgroup:Number(t.limits.maxComputeInvocationsPerWorkgroup),maxComputeWorkgroupSizeX:Number(t.limits.maxComputeWorkgroupSizeX)}}:{supported:!1,features:[]}}async function Jo(){return Ve||(Ve=(async()=>{const e=Vr();if(!e)return null;const t=await e.requestAdapter();if(!t)return null;const n=await t.requestDevice(),r=n.createBindGroupLayout({entries:[{binding:0,visibility:Ge,buffer:{type:"read-only-storage"}},{binding:1,visibility:Ge,buffer:{type:"read-only-storage"}},{binding:2,visibility:Ge,buffer:{type:"storage"}},{binding:3,visibility:Ge,buffer:{type:"uniform"}}]}),i=n.createComputePipeline({layout:n.createPipelineLayout({bindGroupLayouts:[r]}),compute:{module:n.createShaderModule({code:Go}),entryPoint:"main"}});return{device:n,pipeline:i,bindGroupLayout:r}})(),Ve)}function He(e,t){return Math.ceil(e/t)*t}async function Gr(e,t,n){const r=await Jo();if(!r)return null;const i=Math.max(0,Math.floor(t)),o=Math.max(0,Math.floor(n.length/4));if(i===0||o===0)return new Uint32Array(0);const s=Math.min(i,Math.floor(e.length/2));if(s===0)return new Uint32Array(0);const a=s*2*Float32Array.BYTES_PER_ELEMENT,c=o*4*Float32Array.BYTES_PER_ELEMENT,l=s*Uint32Array.BYTES_PER_ELEMENT,f=Number(r.device.limits.maxStorageBufferBindingSize);if(a>f||c>f||l>f)return null;const b=r.device.createBuffer({size:He(a,4),usage:mn|qe}),m=r.device.createBuffer({size:He(c,4),usage:mn|qe}),w=r.device.createBuffer({size:He(l,4),usage:mn|Ho}),g=r.device.createBuffer({size:16,usage:$o|qe}),S=r.device.createBuffer({size:He(l,4),usage:qe|Zo});r.device.queue.writeBuffer(b,0,e.buffer,e.byteOffset,a),r.device.queue.writeBuffer(m,0,n.buffer,n.byteOffset,c),r.device.queue.writeBuffer(g,0,new Uint32Array([s,o,0,0]));const T=r.device.createBindGroup({layout:r.bindGroupLayout,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:{buffer:m}},{binding:2,resource:{buffer:w}},{binding:3,resource:{buffer:g}}]}),_=r.device.createCommandEncoder(),B=_.beginComputePass();B.setPipeline(r.pipeline),B.setBindGroup(0,T),B.dispatchWorkgroups(Math.ceil(s/256)),B.end(),_.copyBufferToBuffer(w,0,S,0,l),r.device.queue.submit([_.finish()]),await S.mapAsync(Ko);const N=S.getMappedRange(),V=new Uint32Array(N.slice(0));return S.unmap(),b.destroy(),m.destroy(),w.destroy(),g.destroy(),S.destroy(),V}function Kt(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}async function qr(e,t,n={}){const r=Kt(),i=n.bridgeToDraw===!0;if(!e||!e.count||!e.positions||!e.paletteIndices)return{data:null,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}};const o=Ie(t??[]);if(o.length===0){const F={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return e.fillModes instanceof Uint8Array&&(F.fillModes=new Uint8Array(0)),e.ids instanceof Uint32Array&&(F.ids=new Uint32Array(0)),{data:F,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}}}const s=e.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER,a=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length,s)),c=e.fillModes instanceof Uint8Array&&e.fillModes.length>=a?e.fillModes:null,l=e.ids instanceof Uint32Array&&e.ids.length>=a?e.ids:null;if(a===0){const F={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return c&&(F.fillModes=new Uint8Array(0)),l&&(F.ids=new Uint32Array(0)),{data:F,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}}}const f=new Float32Array(o.length*4);for(let F=0;F<o.length;F+=1){const X=F*4,K=o[F];f[X]=K.minX,f[X+1]=K.minY,f[X+2]=K.maxX,f[X+3]=K.maxY}let b=null,m=!1;try{b=await Gr(e.positions,a,f),m=!!b}catch{b=null,m=!1}if(!b)return{data:Pe(e,t),meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!1,candidateCount:a,bridgedToDraw:!1}};let w=0;for(let F=0;F<a;F+=1)b[F]===1&&(w+=1);const g=new Uint32Array(w);if(w>0){let F=0;for(let X=0;X<a;X+=1)b[X]===1&&(g[F]=X,F+=1)}if(w===0){if(i){const X={count:a,positions:e.positions.subarray(0,a*2),paletteIndices:e.paletteIndices.subarray(0,a),drawIndices:new Uint32Array(0)};return c&&(X.fillModes=c.subarray(0,a)),l&&(X.ids=l.subarray(0,a)),{data:X,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!0}}}const F={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return c&&(F.fillModes=new Uint8Array(0)),l&&(F.ids=new Uint32Array(0)),{data:F,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!1}}}if(i){const F=new Uint32Array(w);let X=0;for(let ft=0;ft<w;ft+=1){const mt=g[ft]??0,Tt=e.positions[mt*2],It=e.positions[mt*2+1];nn(Tt,It,o)&&(F[X]=mt,X+=1)}const K={count:a,positions:e.positions.subarray(0,a*2),paletteIndices:e.paletteIndices.subarray(0,a),drawIndices:F.subarray(0,X)};return c&&(K.fillModes=c.subarray(0,a)),l&&(K.ids=l.subarray(0,a)),{data:K,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!0,candidateCount:w,bridgedToDraw:!0}}}const S=new Float32Array(w*2),T=new Uint16Array(w),_=c?new Uint8Array(w):null,B=l?new Uint32Array(w):null;let N=0;for(let F=0;F<w;F+=1){const X=g[F]??0,K=e.positions[X*2],ft=e.positions[X*2+1];nn(K,ft,o)&&(S[N*2]=K,S[N*2+1]=ft,T[N]=e.paletteIndices[X],_&&(_[N]=c[X]),B&&(B[N]=l[X]),N+=1)}const V={count:N,positions:S.subarray(0,N*2),paletteIndices:T.subarray(0,N)};return _&&(V.fillModes=_.subarray(0,N)),B&&(V.ids=B.subarray(0,N)),{data:V,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!0,candidateCount:w,bridgedToDraw:!1}}}let _t=null,xn=!0,Hr=1;const se=new Map;function oe(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function $r(){if(!xn)return null;if(_t)return _t;try{const e=new Worker(new URL(""+(typeof document>"u"?require("url").pathToFileURL(__dirname+"/assets/roi-clip-worker-BDVQwN2T.js").href:new URL("assets/roi-clip-worker-BDVQwN2T.js",document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),typeof document>"u"?require("url").pathToFileURL(__filename).href:ln&&ln.tagName.toUpperCase()==="SCRIPT"&&ln.src||new URL("index.cjs",document.baseURI).href),{type:"module"});return e.addEventListener("message",Un),e.addEventListener("error",Bn),_t=e,e}catch{return xn=!1,null}}function Un(e){const t=e.data;if(!t)return;const n=se.get(t.id);if(!n)return;if(se.delete(t.id),t.type==="roi-clip-failure"){n.reject(new Error(t.error||"worker clip failed"));return}if(t.type==="roi-clip-index-success"){if(n.kind!=="index"){n.reject(new Error("worker response mismatch: expected point data result"));return}const l=Math.max(0,Math.floor(t.count)),f=new Uint32Array(t.indices).subarray(0,l);n.resolve({indices:f,meta:{mode:"worker",durationMs:Number.isFinite(t.durationMs)?t.durationMs:oe()-n.startMs}});return}if(n.kind!=="data"){n.reject(new Error("worker response mismatch: expected index result"));return}const r=Math.max(0,Math.floor(t.count)),i=new Float32Array(t.positions),o=new Uint16Array(t.paletteIndices),s=t.fillModes?new Uint8Array(t.fillModes):null,a=t.ids?new Uint32Array(t.ids):null,c={count:r,positions:i.subarray(0,r*2),paletteIndices:o.subarray(0,r)};s&&(c.fillModes=s.subarray(0,r)),a&&(c.ids=a.subarray(0,r)),n.resolve({data:c,meta:{mode:"worker",durationMs:Number.isFinite(t.durationMs)?t.durationMs:oe()-n.startMs}})}function Bn(){xn=!1,_t&&(_t.removeEventListener("message",Un),_t.removeEventListener("error",Bn),_t.terminate(),_t=null);for(const[,e]of se)e.reject(new Error("worker crashed"));se.clear()}function Qo(){if(_t){_t.removeEventListener("message",Un),_t.removeEventListener("error",Bn),_t.terminate(),_t=null;for(const[,e]of se)e.reject(new Error("worker terminated"));se.clear()}}async function Zr(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return{data:null,meta:{mode:"worker",durationMs:0}};const n=$r();if(!n){const b=oe();return{data:Pe(e,t),meta:{mode:"sync",durationMs:oe()-b}}}const r=e.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER,i=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length,r)),o=e.positions.slice(0,i*2),s=e.paletteIndices.slice(0,i),a=e.fillModes instanceof Uint8Array&&e.fillModes.length>=i?e.fillModes.slice(0,i):null,c=e.ids instanceof Uint32Array&&e.ids.length>=i?e.ids.slice(0,i):null,l=Hr++,f=oe();return new Promise((b,m)=>{se.set(l,{kind:"data",resolve:b,reject:m,startMs:f});const w={type:"roi-clip-request",id:l,count:i,positions:o.buffer,paletteIndices:s.buffer,fillModes:a?.buffer,ids:c?.buffer,polygons:t??[]},g=[o.buffer,s.buffer];a&&g.push(a.buffer),c&&g.push(c.buffer),n.postMessage(w,g)})}async function ts(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return{indices:new Uint32Array(0),meta:{mode:"worker",durationMs:0}};const n=$r();if(!n){const c=oe();return{indices:Wr(e,t),meta:{mode:"sync",durationMs:oe()-c}}}const r=e.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER,i=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length,r)),o=e.positions.slice(0,i*2),s=Hr++,a=oe();return new Promise((c,l)=>{se.set(s,{kind:"index",resolve:c,reject:l,startMs:a});const f={type:"roi-clip-index-request",id:s,count:i,positions:o.buffer,polygons:t??[]};n.postMessage(f,[o.buffer])})}function es(e){const t=[];for(let n=0;n<e.length;n+=1){const r=e[n],i=Ie([r?.coordinates]);if(i.length===0)continue;let o=0;for(const s of i)o+=s.area;t.push({regionId:r.id??n,regionIndex:n,polygons:i,area:Math.max(1e-6,o)})}return t}function ns(e,t){if(Array.isArray(t)){const n=t[e];if(typeof n=="string"&&n.length>0)return n}if(t instanceof Map){const n=t.get(e);if(typeof n=="string"&&n.length>0)return n}return String(e)}function Kr(e,t,n={}){const r=Math.max(0,Math.min(Math.floor(e?.count??0),Math.floor((e?.positions?.length??0)/2),e?.paletteIndices?.length??0,e?.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER));let i=null;if(e?.drawIndices instanceof Uint32Array){const m=e.drawIndices;let w=m.length;for(let g=0;g<m.length;g+=1)m[g]<r||(w-=1);if(w===m.length)i=m;else if(w>0){const g=new Uint32Array(w);let S=0;for(let T=0;T<m.length;T+=1){const _=m[T];_>=r||(g[S]=_,S+=1)}i=g}else i=new Uint32Array(0)}const o=i?i.length:r,s=es(t??[]);if(!e||o===0||s.length===0)return{groups:[],inputPointCount:o,pointsInsideAnyRegion:0,unmatchedPointCount:o};const a=new Map,c=new Map;let l=0;for(let m=0;m<o;m+=1){const w=i?i[m]:m,g=e.positions[w*2],S=e.positions[w*2+1];let T=null;for(const N of s){let V=!1;for(const F of N.polygons)if(Ir(g,S,F)){V=!0;break}V&&(!T||N.area<T.area)&&(T=N)}if(!T)continue;l+=1;const _=e.paletteIndices[w]??0,B=a.get(T.regionIndex)??new Map;B.set(_,(B.get(_)??0)+1),a.set(T.regionIndex,B),c.set(T.regionIndex,(c.get(T.regionIndex)??0)+1)}const f=n.includeEmptyRegions??!1,b=[];for(const m of s){const w=c.get(m.regionIndex)??0;if(!f&&w<=0)continue;const g=a.get(m.regionIndex)??new Map,S=Array.from(g.entries()).map(([T,_])=>({termId:ns(T,n.paletteIndexToTermId),paletteIndex:T,count:_})).sort((T,_)=>_.count-T.count||T.paletteIndex-_.paletteIndex);b.push({regionId:m.regionId,regionIndex:m.regionIndex,totalCount:w,termCounts:S})}return{groups:b,inputPointCount:o,pointsInsideAnyRegion:l,unmatchedPointCount:Math.max(0,o-l)}}function $e(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function rs(e,t){if(!t)return!1;try{const r=new URL(e,typeof window<"u"?window.location.href:void 0).hostname.toLowerCase();if(r.includes("amazonaws.com")||r.startsWith("s3.")||r.includes(".s3."))return!1}catch{}return!0}class jr{constructor(t){y(this,"maxConcurrency");y(this,"maxRetries");y(this,"retryBaseDelayMs");y(this,"retryMaxDelayMs");y(this,"onTileLoad");y(this,"onTileError");y(this,"onStateChange");y(this,"authToken");y(this,"destroyed",!1);y(this,"queue",[]);y(this,"queuedByKey",new Map);y(this,"inflight",new Map);y(this,"visibleKeys",new Set);y(this,"timerId",null);y(this,"abortedCount",0);y(this,"retryCount",0);y(this,"failedCount",0);this.maxConcurrency=Math.max(1,Math.floor(t.maxConcurrency??12)),this.maxRetries=Math.max(0,Math.floor(t.maxRetries??2)),this.retryBaseDelayMs=Math.max(10,Math.floor(t.retryBaseDelayMs??120)),this.retryMaxDelayMs=Math.max(this.retryBaseDelayMs,Math.floor(t.retryMaxDelayMs??1200)),this.authToken=t.authToken??"",this.onTileLoad=t.onTileLoad,this.onTileError=t.onTileError,this.onStateChange=t.onStateChange}setAuthToken(t){this.authToken=String(t??"")}schedule(t){if(this.destroyed)return;const n=new Set;for(const r of t)n.add(r.key);this.visibleKeys=n,this.dropInvisibleQueued(n),this.abortInvisibleInflight(n);for(const r of t){if(this.inflight.has(r.key)){const s=this.inflight.get(r.key);s&&(s.tile=r);continue}const i=this.queuedByKey.get(r.key);if(i){i.tile=r;continue}const o={tile:r,attempt:0,readyAt:$e()};this.queue.push(o),this.queuedByKey.set(r.key,o)}this.sortQueue(),this.pump(),this.emitStateChange()}clear(){this.clearPumpTimer(),this.visibleKeys.clear(),this.queue=[],this.queuedByKey.clear();for(const[,t]of this.inflight)t.controller.abort();this.inflight.clear(),this.emitStateChange()}destroy(){this.destroyed||(this.destroyed=!0,this.clear())}getInflightCount(){return this.inflight.size}getSnapshot(){return{inflight:this.inflight.size,queued:this.queue.length,aborted:this.abortedCount,retries:this.retryCount,failed:this.failedCount}}dropInvisibleQueued(t){if(this.queue.length===0)return;const n=[];for(const r of this.queue){if(!t.has(r.tile.key)){this.queuedByKey.delete(r.tile.key);continue}n.push(r)}this.queue=n}abortInvisibleInflight(t){for(const[n,r]of this.inflight)t.has(n)||(this.inflight.delete(n),this.abortedCount+=1,r.controller.abort())}sortQueue(){this.queue.sort((t,n)=>t.readyAt!==n.readyAt?t.readyAt-n.readyAt:t.tile.distance2!==n.tile.distance2?t.tile.distance2-n.tile.distance2:t.tile.tier!==n.tile.tier?n.tile.tier-t.tile.tier:t.tile.key.localeCompare(n.tile.key))}pump(){if(this.destroyed)return;for(this.clearPumpTimer();this.inflight.size<this.maxConcurrency;){const r=this.takeNextReadyQueueItem();if(!r)break;this.startFetch(r)}if(this.inflight.size>=this.maxConcurrency||this.queue.length===0)return;const t=this.queue[0]?.readyAt;if(typeof t!="number")return;const n=Math.max(0,t-$e());this.timerId=window.setTimeout(()=>{this.timerId=null,this.pump()},n)}takeNextReadyQueueItem(){if(this.queue.length===0)return null;const t=$e(),n=this.queue[0];return!n||n.readyAt>t?null:(this.queue.shift(),this.queuedByKey.delete(n.tile.key),n)}startFetch(t){const n=new AbortController,r={tile:t.tile,attempt:t.attempt,controller:n};this.inflight.set(t.tile.key,r),this.emitStateChange();const i=rs(t.tile.url,this.authToken);fetch(t.tile.url,{signal:n.signal,headers:i?{Authorization:this.authToken}:void 0}).then(o=>{if(!o.ok)throw new Error(`HTTP ${o.status}`);return o.blob()}).then(o=>createImageBitmap(o)).then(o=>{if(this.destroyed||n.signal.aborted){o.close();return}if(!this.visibleKeys.has(t.tile.key)){o.close();return}this.onTileLoad(t.tile,o)}).catch(o=>{if(n.signal.aborted||this.destroyed)return;if(t.attempt<this.maxRetries&&this.visibleKeys.has(t.tile.key)){this.retryCount+=1;const a=t.attempt+1,c=this.getRetryDelay(a),l={tile:t.tile,attempt:a,readyAt:$e()+c},f=this.queuedByKey.get(t.tile.key);f?(f.tile=l.tile,f.readyAt=Math.min(f.readyAt,l.readyAt),f.attempt=Math.max(f.attempt,l.attempt)):(this.queue.push(l),this.queuedByKey.set(l.tile.key,l)),this.sortQueue();return}this.failedCount+=1,this.onTileError?.(t.tile,o,t.attempt+1)}).finally(()=>{this.inflight.delete(t.tile.key),this.pump(),this.emitStateChange()})}getRetryDelay(t){const n=Math.max(0,t-1),r=Math.min(this.retryMaxDelayMs,this.retryBaseDelayMs*2**n),i=.85+Math.random()*.3;return Math.round(r*i)}clearPumpTimer(){this.timerId!==null&&(window.clearTimeout(this.timerId),this.timerId=null)}emitStateChange(){this.onStateChange?.(this.getSnapshot())}}const br=.35,Tn=.5,is=256,En=[{zoom:1,size:2.8},{zoom:2,size:3.4},{zoom:3,size:4.2},{zoom:4,size:5.3},{zoom:5,size:6.8},{zoom:6,size:8.4},{zoom:7,size:9.8},{zoom:8,size:11.2},{zoom:9,size:14},{zoom:10,size:17.5},{zoom:11,size:22},{zoom:12,size:28}];class os{constructor(){y(this,"viewportWidth",1);y(this,"viewportHeight",1);y(this,"viewState",{zoom:1,offsetX:0,offsetY:0,rotationDeg:0})}setViewport(t,n){this.viewportWidth=Math.max(1,t),this.viewportHeight=Math.max(1,n)}getViewport(){return{width:this.viewportWidth,height:this.viewportHeight}}setViewState(t){typeof t.zoom=="number"&&(this.viewState.zoom=Math.max(1e-4,t.zoom)),typeof t.offsetX=="number"&&(this.viewState.offsetX=t.offsetX),typeof t.offsetY=="number"&&(this.viewState.offsetY=t.offsetY),typeof t.rotationDeg=="number"&&Number.isFinite(t.rotationDeg)&&(this.viewState.rotationDeg=t.rotationDeg)}getViewState(){return{...this.viewState}}getCenter(){const t=Math.max(1e-6,this.viewState.zoom);return[this.viewState.offsetX+this.viewportWidth/(2*t),this.viewState.offsetY+this.viewportHeight/(2*t)]}setCenter(t,n){const r=Math.max(1e-6,this.viewState.zoom);this.viewState.offsetX=t-this.viewportWidth/(2*r),this.viewState.offsetY=n-this.viewportHeight/(2*r)}screenToWorld(t,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,s]=this.getCenter(),a=(t-this.viewportWidth*.5)/i,c=(n-this.viewportHeight*.5)/i,l=Re(r.rotationDeg),f=Math.cos(l),b=Math.sin(l);return[o+a*f-c*b,s+a*b+c*f]}worldToScreen(t,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,s]=this.getCenter(),a=t-o,c=n-s,l=Re(r.rotationDeg),f=Math.cos(l),b=Math.sin(l),m=a*f+c*b,w=-a*b+c*f;return[this.viewportWidth*.5+m*i,this.viewportHeight*.5+w*i]}getViewCorners(){const t=this.viewportWidth,n=this.viewportHeight;return[this.screenToWorld(0,0),this.screenToWorld(t,0),this.screenToWorld(t,n),this.screenToWorld(0,n)]}getMatrix(){const t=Math.max(1e-6,this.viewState.zoom),[n,r]=this.getCenter(),i=Re(this.viewState.rotationDeg),o=Math.cos(i),s=Math.sin(i),a=2*t*o/this.viewportWidth,c=2*t*s/this.viewportWidth,l=2*t*s/this.viewportHeight,f=-2*t*o/this.viewportHeight,b=-(a*n+c*r),m=-(l*n+f*r);return new Float32Array([a,l,0,c,f,0,b,m,1])}}function Re(e){return e*Math.PI/180}function Ze(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function Dt(e,t,n){const r=e.getUniformLocation(t,n);if(!r)throw new Error(`uniform location lookup failed: ${n}`);return r}function Ke(e,t){return!e||!t?e===t:e.buffer===t.buffer&&e.byteOffset===t.byteOffset&&e.byteLength===t.byteLength}function Rn(e){return e.map(t=>({zoom:t.zoom,size:t.size}))}function wr(e){if(!e)return Rn(En);const t=new Map;for(const[n,r]of Object.entries(e)){const i=Number(n),o=Number(r);!Number.isFinite(i)||!Number.isFinite(o)||o<=0||t.set(i,o)}return t.size===0?Rn(En):Array.from(t.entries()).sort((n,r)=>n[0]-r[0]).map(([n,r])=>({zoom:n,size:r}))}function ss(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n].zoom!==t[n].zoom||e[n].size!==t[n].size)return!1;return!0}function as(e,t){if(!Number.isFinite(e))return t[0]?.size??Tn;if(t.length===0)return Tn;if(t.length===1||e<=t[0].zoom)return t[0].size;for(let s=1;s<t.length;s+=1){const a=t[s-1],c=t[s];if(e>c.zoom)continue;const l=Math.max(1e-6,c.zoom-a.zoom),f=tt((e-a.zoom)/l,0,1);return a.size+(c.size-a.size)*f}const n=t[t.length-1],r=t[t.length-2],i=Math.max(1e-6,n.zoom-r.zoom),o=(n.size-r.size)/i;return n.size+(e-n.zoom)*o}const cs=.1,us=5;function yr(e){return typeof e!="number"||!Number.isFinite(e)?1:tt(e,cs,us)}const ls=-100,fs=100;function gn(e){return typeof e!="number"||!Number.isFinite(e)?0:tt(e,ls,fs)}function Mr(e){const t=gn(e?.brightness),n=gn(e?.contrast),r=gn(e?.saturation);return{brightness:t/200,contrast:n/100,saturation:r/100}}const hs=2e3;function Jr(e){return e}function pn(e){return typeof e!="number"||!Number.isFinite(e)?0:tt(e,0,hs)}function je(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?null:Math.max(1e-6,e)}function bn(e){return typeof e=="function"?e:Jr}function Sr(e,t){return Math.abs(e.zoom-t.zoom)<=1e-6&&Math.abs(e.offsetX-t.offsetX)<=1e-6&&Math.abs(e.offsetY-t.offsetY)<=1e-6&&Math.abs(e.rotationDeg-t.rotationDeg)<=1e-6}class Qr{constructor(t,n,r={}){y(this,"canvas");y(this,"source");y(this,"gl");y(this,"camera",new os);y(this,"onViewStateChange");y(this,"onStats");y(this,"onTileError");y(this,"onContextLost");y(this,"onContextRestored");y(this,"resizeObserver");y(this,"tileProgram");y(this,"pointProgram");y(this,"tileScheduler");y(this,"authToken");y(this,"destroyed",!1);y(this,"contextLost",!1);y(this,"frame",null);y(this,"frameSerial",0);y(this,"dragging",!1);y(this,"interactionMode","none");y(this,"rotateLastAngleRad",null);y(this,"pointerId",null);y(this,"lastPointerX",0);y(this,"lastPointerY",0);y(this,"interactionLocked",!1);y(this,"ctrlDragRotate",!0);y(this,"rotationDragSensitivityDegPerPixel",.35);y(this,"maxCacheTiles");y(this,"fitZoom",1);y(this,"minZoom",1e-6);y(this,"maxZoom",1);y(this,"minZoomOverride",null);y(this,"maxZoomOverride",null);y(this,"viewTransitionDurationMs",0);y(this,"viewTransitionEasing",Jr);y(this,"viewAnimation",null);y(this,"viewAnimationFrame",null);y(this,"currentTier",0);y(this,"pointCount",0);y(this,"usePointIndices",!1);y(this,"pointBuffersDirty",!0);y(this,"pointPaletteSize",1);y(this,"pointSizeStops",Rn(En));y(this,"pointStrokeScale",1);y(this,"imageColorSettings",{brightness:0,contrast:0,saturation:0});y(this,"lastPointData",null);y(this,"lastPointPalette",null);y(this,"zeroFillModes",new Uint8Array(0));y(this,"cache",new Map);y(this,"boundPointerDown");y(this,"boundPointerMove");y(this,"boundPointerUp");y(this,"boundWheel");y(this,"boundDoubleClick");y(this,"boundContextMenu");y(this,"boundContextLost");y(this,"boundContextRestored");this.canvas=t,this.source=n,this.onViewStateChange=r.onViewStateChange,this.onStats=r.onStats,this.onTileError=r.onTileError,this.onContextLost=r.onContextLost,this.onContextRestored=r.onContextRestored,this.authToken=r.authToken??"",this.maxCacheTiles=Math.max(32,Math.floor(r.maxCacheTiles??320)),this.ctrlDragRotate=r.ctrlDragRotate??!0,this.rotationDragSensitivityDegPerPixel=typeof r.rotationDragSensitivityDegPerPixel=="number"&&Number.isFinite(r.rotationDragSensitivityDegPerPixel)?Math.max(0,r.rotationDragSensitivityDegPerPixel):br,this.pointSizeStops=wr(r.pointSizeByZoom),this.pointStrokeScale=yr(r.pointStrokeScale),this.imageColorSettings=Mr(r.imageColorSettings),this.minZoomOverride=je(r.minZoom),this.maxZoomOverride=je(r.maxZoom),this.viewTransitionDurationMs=pn(r.viewTransition?.duration),this.viewTransitionEasing=bn(r.viewTransition?.easing);const i=t.getContext("webgl2",{alpha:!1,antialias:!1,depth:!1,stencil:!1,powerPreference:"high-performance"});if(!i)throw new Error("WebGL2 not supported");this.gl=i,this.tileProgram=this.initTileProgram(),this.pointProgram=this.initPointProgram(),this.tileScheduler=new jr({authToken:this.authToken,maxConcurrency:r.tileScheduler?.maxConcurrency??12,maxRetries:r.tileScheduler?.maxRetries??2,retryBaseDelayMs:r.tileScheduler?.retryBaseDelayMs??120,retryMaxDelayMs:r.tileScheduler?.retryMaxDelayMs??1200,onTileLoad:(o,s)=>this.handleTileLoaded(o,s),onTileError:(o,s,a)=>{this.onTileError?.({tile:o,error:s,attemptCount:a}),console.warn("tile load failed",o.url,s)}}),this.resizeObserver=new ResizeObserver(()=>this.resize()),this.resizeObserver.observe(t),this.boundPointerDown=o=>this.onPointerDown(o),this.boundPointerMove=o=>this.onPointerMove(o),this.boundPointerUp=o=>this.onPointerUp(o),this.boundWheel=o=>this.onWheel(o),this.boundDoubleClick=o=>this.onDoubleClick(o),this.boundContextMenu=o=>this.onContextMenu(o),this.boundContextLost=o=>this.onWebGlContextLost(o),this.boundContextRestored=o=>this.onWebGlContextRestored(o),t.addEventListener("pointerdown",this.boundPointerDown),t.addEventListener("pointermove",this.boundPointerMove),t.addEventListener("pointerup",this.boundPointerUp),t.addEventListener("pointercancel",this.boundPointerUp),t.addEventListener("wheel",this.boundWheel,{passive:!1}),t.addEventListener("dblclick",this.boundDoubleClick),t.addEventListener("contextmenu",this.boundContextMenu),t.addEventListener("webglcontextlost",this.boundContextLost),t.addEventListener("webglcontextrestored",this.boundContextRestored),this.fitToImage({duration:0}),this.resize()}resolveDefaultZoomBounds(){const t=Math.max(this.fitZoom*.5,1e-6),n=Math.max(1,this.fitZoom*8);return{minZoom:t,maxZoom:Math.max(t,n)}}applyZoomBounds(){const t=this.resolveDefaultZoomBounds();let n=this.minZoomOverride??t.minZoom,r=this.maxZoomOverride??t.maxZoom;n=Math.max(1e-6,n),r=Math.max(1e-6,r),n>r&&(n=r),this.minZoom=n,this.maxZoom=r}resolveTargetViewState(t){const n=this.camera.getViewState(),r={zoom:typeof t.zoom=="number"&&Number.isFinite(t.zoom)?tt(t.zoom,this.minZoom,this.maxZoom):n.zoom,offsetX:typeof t.offsetX=="number"&&Number.isFinite(t.offsetX)?t.offsetX:n.offsetX,offsetY:typeof t.offsetY=="number"&&Number.isFinite(t.offsetY)?t.offsetY:n.offsetY,rotationDeg:typeof t.rotationDeg=="number"&&Number.isFinite(t.rotationDeg)?t.rotationDeg:n.rotationDeg};this.camera.setViewState(r),this.clampViewState();const i=this.camera.getViewState();return this.camera.setViewState(n),i}cancelViewAnimation(){this.viewAnimation=null,this.viewAnimationFrame!==null&&(cancelAnimationFrame(this.viewAnimationFrame),this.viewAnimationFrame=null)}startViewAnimation(t,n,r){const i=this.camera.getViewState();this.cancelViewAnimation(),this.viewAnimation={startMs:Ze(),durationMs:Math.max(0,n),from:i,to:t,easing:r};const o=()=>{const s=this.viewAnimation;if(!s)return;const a=Math.max(0,Ze()-s.startMs),c=s.durationMs<=0?1:tt(a/s.durationMs,0,1);let l=c;try{l=s.easing(c)}catch{l=c}Number.isFinite(l)||(l=c),l=tt(l,0,1);const f={zoom:s.from.zoom+(s.to.zoom-s.from.zoom)*l,offsetX:s.from.offsetX+(s.to.offsetX-s.from.offsetX)*l,offsetY:s.from.offsetY+(s.to.offsetY-s.from.offsetY)*l,rotationDeg:s.from.rotationDeg+(s.to.rotationDeg-s.from.rotationDeg)*l};if(this.camera.setViewState(f),this.clampViewState(),this.emitViewState(),this.requestRender(),c>=1){this.viewAnimation=null,this.viewAnimationFrame=null;return}this.viewAnimationFrame=requestAnimationFrame(o)};this.viewAnimationFrame=requestAnimationFrame(o)}setAuthToken(t){this.authToken=String(t??""),this.tileScheduler.setAuthToken(this.authToken)}setZoomRange(t,n){const r=je(t),i=je(n);if(this.minZoomOverride===r&&this.maxZoomOverride===i)return;this.minZoomOverride=r,this.maxZoomOverride=i,this.applyZoomBounds();const o=this.resolveTargetViewState({}),s=this.camera.getViewState();Sr(s,o)||(this.cancelViewAnimation(),this.camera.setViewState(o),this.emitViewState(),this.requestRender())}setViewTransition(t){this.viewTransitionDurationMs=pn(t?.duration),this.viewTransitionEasing=bn(t?.easing)}setViewState(t,n){const r=this.resolveTargetViewState(t),i=this.camera.getViewState();if(Sr(i,r))return;const o=pn(n?.duration??this.viewTransitionDurationMs),s=bn(n?.easing??this.viewTransitionEasing);if(o<=0){this.cancelViewAnimation(),this.camera.setViewState(r),this.emitViewState(),this.requestRender();return}this.startViewAnimation(r,o,s)}getViewState(){return this.camera.getViewState()}getZoomRange(){return{minZoom:this.minZoom,maxZoom:this.maxZoom}}setPointPalette(t){if(!t||t.length===0){this.lastPointPalette=null;return}if(this.lastPointPalette=new Uint8Array(t),this.contextLost||this.gl.isContextLost())return;const n=this.gl,r=Math.max(1,Math.floor(this.lastPointPalette.length/4));this.pointPaletteSize=r,n.bindTexture(n.TEXTURE_2D,this.pointProgram.paletteTexture),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,r,1,0,n.RGBA,n.UNSIGNED_BYTE,this.lastPointPalette),n.bindTexture(n.TEXTURE_2D,null),this.requestRender()}setPointData(t){if(!t||!t.count||!t.positions||!t.paletteIndices){this.lastPointData=null,this.pointCount=0,this.usePointIndices=!1,this.requestRender();return}const n=t.fillModes instanceof Uint8Array?t.fillModes:null,r=n!==null,i=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length,r?n.length:Number.MAX_SAFE_INTEGER)),o=t.positions.subarray(0,i*2),s=t.paletteIndices.subarray(0,i),a=r?n.subarray(0,i):void 0,c=t.drawIndices instanceof Uint32Array,l=c?this.sanitizeDrawIndices(t.drawIndices,i):null,f=this.lastPointData,b=f?.fillModes instanceof Uint8Array;let m=this.pointBuffersDirty||!f||f.count!==i||!Ke(f.positions,o)||!Ke(f.paletteIndices,s)||b!==r||r&&(!f?.fillModes||!Ke(f.fillModes,a)),w=this.pointBuffersDirty||c&&(!f?.drawIndices||!Ke(f.drawIndices,l))||!c&&!!f?.drawIndices;if(this.lastPointData={count:i,positions:o,paletteIndices:s,fillModes:a,drawIndices:c?l??void 0:void 0},this.contextLost||this.gl.isContextLost())return;const g=this.gl;m&&(g.bindBuffer(g.ARRAY_BUFFER,this.pointProgram.posBuffer),g.bufferData(g.ARRAY_BUFFER,this.lastPointData.positions,g.STATIC_DRAW),g.bindBuffer(g.ARRAY_BUFFER,this.pointProgram.termBuffer),g.bufferData(g.ARRAY_BUFFER,this.lastPointData.paletteIndices,g.STATIC_DRAW),g.bindBuffer(g.ARRAY_BUFFER,this.pointProgram.fillModeBuffer),g.bufferData(g.ARRAY_BUFFER,this.lastPointData.fillModes??this.getZeroFillModes(i),g.STATIC_DRAW),g.bindBuffer(g.ARRAY_BUFFER,null)),c&&w&&(g.bindBuffer(g.ELEMENT_ARRAY_BUFFER,this.pointProgram.indexBuffer),g.bufferData(g.ELEMENT_ARRAY_BUFFER,l??new Uint32Array(0),g.DYNAMIC_DRAW),g.bindBuffer(g.ELEMENT_ARRAY_BUFFER,null)),this.usePointIndices=c,this.pointCount=c?l?.length??0:this.lastPointData.count,(m||w)&&(this.pointBuffersDirty=!1),this.requestRender()}sanitizeDrawIndices(t,n){if(n<=0||t.length===0)return new Uint32Array(0);let r=t.length;for(let s=0;s<t.length;s+=1)t[s]<n||(r-=1);if(r===t.length)return t;if(r<=0)return new Uint32Array(0);const i=new Uint32Array(r);let o=0;for(let s=0;s<t.length;s+=1){const a=t[s];a>=n||(i[o]=a,o+=1)}return i}getZeroFillModes(t){return t<=0?new Uint8Array(0):(this.zeroFillModes.length<t&&(this.zeroFillModes=new Uint8Array(t)),this.zeroFillModes.subarray(0,t))}setInteractionLock(t){const n=!!t;this.interactionLocked!==n&&(this.interactionLocked=n,n&&this.cancelDrag())}setPointSizeByZoom(t){const n=wr(t);ss(this.pointSizeStops,n)||(this.pointSizeStops=n,this.requestRender())}setPointStrokeScale(t){const n=yr(t);this.pointStrokeScale!==n&&(this.pointStrokeScale=n,this.requestRender())}setImageColorSettings(t){const n=Mr(t),r=this.imageColorSettings;r.brightness===n.brightness&&r.contrast===n.contrast&&r.saturation===n.saturation||(this.imageColorSettings=n,this.requestRender())}cancelDrag(){if(this.pointerId!==null&&this.canvas.hasPointerCapture(this.pointerId))try{this.canvas.releasePointerCapture(this.pointerId)}catch{}this.dragging=!1,this.interactionMode="none",this.rotateLastAngleRad=null,this.pointerId=null,this.canvas.classList.remove("dragging")}getPointerAngleRad(t,n){const r=this.canvas.getBoundingClientRect(),i=t-r.left-r.width*.5,o=n-r.top-r.height*.5;return Math.atan2(o,i)}screenToWorld(t,n){const r=this.canvas.getBoundingClientRect(),i=t-r.left,o=n-r.top;return this.camera.screenToWorld(i,o)}worldToScreen(t,n){return this.camera.worldToScreen(t,n)}setViewCenter(t,n,r){if(!Number.isFinite(t)||!Number.isFinite(n))return;const i=this.camera.getViewState(),o=Math.max(1e-6,i.zoom),s=this.camera.getViewport();this.setViewState({offsetX:t-s.width/(2*o),offsetY:n-s.height/(2*o)},r)}getViewCorners(){return this.camera.getViewCorners()}resetRotation(t){const n=this.camera.getViewState();Math.abs(n.rotationDeg)<1e-6||this.setViewState({rotationDeg:0},t)}getPointSizeByZoom(){const t=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(t),r=as(n,this.pointSizeStops);return tt(r,Tn,is)}fitToImage(t){const n=this.canvas.getBoundingClientRect(),r=Math.max(1,n.width||1),i=Math.max(1,n.height||1),o=Math.min(r/this.source.width,i/this.source.height),s=Number.isFinite(o)&&o>0?o:1;this.fitZoom=s,this.applyZoomBounds();const a=tt(s,this.minZoom,this.maxZoom),c=r/a,l=i/a;this.setViewState({zoom:a,offsetX:(this.source.width-c)*.5,offsetY:(this.source.height-l)*.5,rotationDeg:0},t)}zoomBy(t,n,r,i){const o=this.camera.getViewState(),s=tt(o.zoom*t,this.minZoom,this.maxZoom);if(s===o.zoom)return;const[a,c]=this.camera.screenToWorld(n,r),l=this.camera.getViewport(),f=n-l.width*.5,b=r-l.height*.5,m=Re(o.rotationDeg),w=Math.cos(m),g=Math.sin(m),S=f/s*w-b/s*g,T=f/s*g+b/s*w,_=a-S,B=c-T;this.setViewState({zoom:s,offsetX:_-l.width/(2*s),offsetY:B-l.height/(2*s)},i)}clampViewState(){const t=this.getViewBounds(),n=Math.max(1e-6,t[2]-t[0]),r=Math.max(1e-6,t[3]-t[1]),i=n*.2,o=r*.2,[s,a]=this.camera.getCenter(),c=n*.5,l=r*.5,f=c-i,b=this.source.width-c+i,m=l-o,w=this.source.height-l+o,g=f<=b?tt(s,f,b):this.source.width*.5,S=m<=w?tt(a,m,w):this.source.height*.5;this.camera.setCenter(g,S)}emitViewState(){this.onViewStateChange?.(this.camera.getViewState())}selectTier(){const t=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(t);return tt(Math.floor(n),0,this.source.maxTierZoom)}getViewBounds(){const t=this.camera.getViewCorners();let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[s,a]of t)s<n&&(n=s),s>i&&(i=s),a<r&&(r=a),a>o&&(o=a);return[n,r,i,o]}intersectsBounds(t,n){return!(t[2]<=n[0]||t[0]>=n[2]||t[3]<=n[1]||t[1]>=n[3])}getVisibleTiles(){const t=this.selectTier();this.currentTier=t;const n=this.getViewBounds(),r=Math.pow(2,this.source.maxTierZoom-t),i=Math.ceil(this.source.width/r),o=Math.ceil(this.source.height/r),s=Math.max(1,Math.ceil(i/this.source.tileSize)),a=Math.max(1,Math.ceil(o/this.source.tileSize)),c=n[0],l=n[1],f=n[2],b=n[3],m=tt(Math.floor(c/r/this.source.tileSize),0,s-1),w=tt(Math.floor((f-1)/r/this.source.tileSize),0,s-1),g=tt(Math.floor(l/r/this.source.tileSize),0,a-1),S=tt(Math.floor((b-1)/r/this.source.tileSize),0,a-1);if(m>w||g>S)return[];const T=(c+f)*.5/r/this.source.tileSize,_=(l+b)*.5/r/this.source.tileSize,B=[];for(let N=g;N<=S;N+=1)for(let V=m;V<=w;V+=1){const F=V*this.source.tileSize*r,X=N*this.source.tileSize*r,K=Math.min((V+1)*this.source.tileSize,i)*r,ft=Math.min((N+1)*this.source.tileSize,o)*r,mt=V-T,Tt=N-_;B.push({key:`${t}/${V}/${N}`,tier:t,x:V,y:N,bounds:[F,X,K,ft],distance2:mt*mt+Tt*Tt,url:Fn(this.source,t,V,N)})}return B.sort((N,V)=>N.distance2-V.distance2),B}trimCache(){if(this.cache.size<=this.maxCacheTiles)return;const t=Array.from(this.cache.entries());t.sort((r,i)=>r[1].lastUsed-i[1].lastUsed);const n=this.cache.size-this.maxCacheTiles;for(let r=0;r<n;r+=1){const[i,o]=t[r];this.gl.deleteTexture(o.texture),this.cache.delete(i)}}render(){if(this.destroyed||this.contextLost||this.gl.isContextLost())return;const t=Ze();this.frameSerial+=1;const n=this.gl,r=this.tileProgram,i=this.pointProgram;n.clearColor(.03,.06,.1,1),n.clear(n.COLOR_BUFFER_BIT);const o=this.getVisibleTiles(),s=this.getViewBounds(),a=new Set(o.map(m=>m.key));n.useProgram(r.program),n.bindVertexArray(r.vao),n.uniformMatrix3fv(r.uCamera,!1,this.camera.getMatrix()),n.uniform1i(r.uTexture,0),n.uniform1f(r.uBrightness,this.imageColorSettings.brightness),n.uniform1f(r.uContrast,this.imageColorSettings.contrast),n.uniform1f(r.uSaturation,this.imageColorSettings.saturation);const c=[];for(const[,m]of this.cache)a.has(m.key)||this.intersectsBounds(m.bounds,s)&&c.push(m);c.sort((m,w)=>m.tier-w.tier);for(const m of c)m.lastUsed=this.frameSerial,n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,m.texture),n.uniform4f(r.uBounds,m.bounds[0],m.bounds[1],m.bounds[2],m.bounds[3]),n.drawArrays(n.TRIANGLE_STRIP,0,4);let l=0;const f=[];for(const m of o){const w=this.cache.get(m.key);if(!w){f.push(m);continue}w.lastUsed=this.frameSerial,n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,w.texture),n.uniform4f(r.uBounds,w.bounds[0],w.bounds[1],w.bounds[2],w.bounds[3]),n.drawArrays(n.TRIANGLE_STRIP,0,4),l+=1}this.tileScheduler.schedule(f),n.bindTexture(n.TEXTURE_2D,null),n.bindVertexArray(null);let b=0;if(this.pointCount>0&&(n.enable(n.BLEND),n.blendFunc(n.ONE,n.ONE_MINUS_SRC_ALPHA),n.useProgram(i.program),n.bindVertexArray(i.vao),n.uniformMatrix3fv(i.uCamera,!1,this.camera.getMatrix()),n.uniform1f(i.uPointSize,this.getPointSizeByZoom()),n.uniform1f(i.uPointStrokeScale,this.pointStrokeScale),n.uniform1f(i.uPaletteSize,this.pointPaletteSize),n.uniform1i(i.uPalette,1),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,i.paletteTexture),this.usePointIndices?n.drawElements(n.POINTS,this.pointCount,n.UNSIGNED_INT,0):n.drawArrays(n.POINTS,0,this.pointCount),n.bindTexture(n.TEXTURE_2D,null),n.bindVertexArray(null),b=this.pointCount),this.onStats){const m=this.tileScheduler.getSnapshot(),w=l,g=f.length,S=c.length+l+(b>0?1:0);this.onStats({tier:this.currentTier,visible:o.length,rendered:l,points:b,fallback:c.length,cache:this.cache.size,inflight:m.inflight,queued:m.queued,retries:m.retries,failed:m.failed,aborted:m.aborted,cacheHits:w,cacheMisses:g,drawCalls:S,frameMs:Ze()-t})}}requestRender(){this.frame!==null||this.destroyed||this.contextLost||this.gl.isContextLost()||(this.frame=requestAnimationFrame(()=>{this.frame=null,this.render()}))}resize(){const t=this.canvas.getBoundingClientRect(),n=Math.max(1,t.width||this.canvas.clientWidth||1),r=Math.max(1,t.height||this.canvas.clientHeight||1),i=Math.max(1,window.devicePixelRatio||1),o=Math.max(1,Math.round(n*i)),s=Math.max(1,Math.round(r*i));(this.canvas.width!==o||this.canvas.height!==s)&&(this.canvas.width=o,this.canvas.height=s),this.camera.setViewport(n,r),this.gl.viewport(0,0,o,s),this.requestRender()}onPointerDown(t){if(this.interactionLocked)return;const n=this.ctrlDragRotate&&(t.ctrlKey||t.metaKey);(t.button===0||n&&t.button===2)&&(this.cancelViewAnimation(),n&&t.preventDefault(),this.dragging=!0,this.interactionMode=n?"rotate":"pan",this.pointerId=t.pointerId,this.lastPointerX=t.clientX,this.lastPointerY=t.clientY,this.rotateLastAngleRad=this.interactionMode==="rotate"?this.getPointerAngleRad(t.clientX,t.clientY):null,this.canvas.classList.add("dragging"),this.canvas.setPointerCapture(t.pointerId))}onPointerMove(t){if(this.interactionLocked||!this.dragging||t.pointerId!==this.pointerId)return;const n=t.clientX-this.lastPointerX,r=t.clientY-this.lastPointerY;if(this.lastPointerX=t.clientX,this.lastPointerY=t.clientY,this.interactionMode==="rotate"){const i=this.getPointerAngleRad(t.clientX,t.clientY),o=this.rotateLastAngleRad;if(this.rotateLastAngleRad=i,o!==null){const s=i-o,a=Math.atan2(Math.sin(s),Math.cos(s)),c=this.rotationDragSensitivityDegPerPixel/br,l=this.camera.getViewState();this.camera.setViewState({rotationDeg:l.rotationDeg-a*180/Math.PI*c})}}else{const i=this.camera.getViewState(),o=Math.max(1e-6,i.zoom),s=Re(i.rotationDeg),a=Math.cos(s),c=Math.sin(s),l=(n*a-r*c)/o,f=(n*c+r*a)/o;this.camera.setViewState({offsetX:i.offsetX-l,offsetY:i.offsetY-f})}this.clampViewState(),this.emitViewState(),this.requestRender()}onPointerUp(t){this.interactionLocked||t.pointerId===this.pointerId&&this.cancelDrag()}onWheel(t){if(this.interactionLocked){t.preventDefault();return}t.preventDefault();const n=this.canvas.getBoundingClientRect(),r=t.clientX-n.left,i=t.clientY-n.top,o=t.deltaY<0?1.12:.89;this.zoomBy(o,r,i)}onDoubleClick(t){if(this.interactionLocked)return;const n=this.canvas.getBoundingClientRect(),r=t.clientX-n.left,i=t.clientY-n.top;this.zoomBy(t.shiftKey?.8:1.25,r,i)}onContextMenu(t){(this.dragging||t.ctrlKey||t.metaKey)&&t.preventDefault()}onWebGlContextLost(t){t.preventDefault(),!(this.destroyed||this.contextLost)&&(this.contextLost=!0,this.pointBuffersDirty=!0,this.frame!==null&&(cancelAnimationFrame(this.frame),this.frame=null),this.cancelViewAnimation(),this.cancelDrag(),this.tileScheduler.clear(),this.cache.clear(),this.onContextLost?.())}onWebGlContextRestored(t){this.destroyed||(this.contextLost=!1,this.cache.clear(),this.tileProgram=this.initTileProgram(),this.pointProgram=this.initPointProgram(),this.pointBuffersDirty=!0,this.lastPointPalette&&this.lastPointPalette.length>0&&this.setPointPalette(this.lastPointPalette),this.lastPointData?this.setPointData(this.lastPointData):this.pointCount=0,this.resize(),this.requestRender(),this.onContextRestored?.())}destroy(){if(!this.destroyed){if(this.destroyed=!0,this.frame!==null&&(cancelAnimationFrame(this.frame),this.frame=null),this.cancelViewAnimation(),this.resizeObserver.disconnect(),this.canvas.removeEventListener("pointerdown",this.boundPointerDown),this.canvas.removeEventListener("pointermove",this.boundPointerMove),this.canvas.removeEventListener("pointerup",this.boundPointerUp),this.canvas.removeEventListener("pointercancel",this.boundPointerUp),this.canvas.removeEventListener("wheel",this.boundWheel),this.canvas.removeEventListener("dblclick",this.boundDoubleClick),this.canvas.removeEventListener("contextmenu",this.boundContextMenu),this.canvas.removeEventListener("webglcontextlost",this.boundContextLost),this.canvas.removeEventListener("webglcontextrestored",this.boundContextRestored),this.cancelDrag(),this.tileScheduler.destroy(),!this.contextLost&&!this.gl.isContextLost()){for(const[,t]of this.cache)this.gl.deleteTexture(t.texture);this.gl.deleteBuffer(this.tileProgram.vbo),this.gl.deleteVertexArray(this.tileProgram.vao),this.gl.deleteProgram(this.tileProgram.program),this.gl.deleteBuffer(this.pointProgram.posBuffer),this.gl.deleteBuffer(this.pointProgram.termBuffer),this.gl.deleteBuffer(this.pointProgram.fillModeBuffer),this.gl.deleteBuffer(this.pointProgram.indexBuffer),this.gl.deleteTexture(this.pointProgram.paletteTexture),this.gl.deleteVertexArray(this.pointProgram.vao),this.gl.deleteProgram(this.pointProgram.program)}this.cache.clear()}}initTileProgram(){const t=this.gl,i=er(t,`#version 300 es
|
|
63
|
+
`;function qo(){if(typeof navigator>"u")return!1;const e=navigator;return typeof e.gpu=="object"&&e.gpu!==null}function Vr(){if(!qo())return null;const t=navigator.gpu;if(!t||typeof t!="object")return null;const n=t;return typeof n.requestAdapter!="function"?null:n}const Ge=globalThis.GPUShaderStage?.COMPUTE??4,mn=globalThis.GPUBufferUsage?.STORAGE??128,qe=globalThis.GPUBufferUsage?.COPY_DST??8,Ho=globalThis.GPUBufferUsage?.COPY_SRC??4,$o=globalThis.GPUBufferUsage?.UNIFORM??64,Zo=globalThis.GPUBufferUsage?.MAP_READ??1,Ko=globalThis.GPUMapMode?.READ??1;async function jo(){const e=Vr();if(!e)return{supported:!1,features:[]};const t=await e.requestAdapter();return t?{supported:!0,adapterName:t.info?.description??t.info?.vendor??"unknown",features:Array.from(t.features),limits:{maxStorageBufferBindingSize:Number(t.limits.maxStorageBufferBindingSize),maxComputeInvocationsPerWorkgroup:Number(t.limits.maxComputeInvocationsPerWorkgroup),maxComputeWorkgroupSizeX:Number(t.limits.maxComputeWorkgroupSizeX)}}:{supported:!1,features:[]}}async function Jo(){return Ve||(Ve=(async()=>{const e=Vr();if(!e)return null;const t=await e.requestAdapter();if(!t)return null;const n=await t.requestDevice(),r=n.createBindGroupLayout({entries:[{binding:0,visibility:Ge,buffer:{type:"read-only-storage"}},{binding:1,visibility:Ge,buffer:{type:"read-only-storage"}},{binding:2,visibility:Ge,buffer:{type:"storage"}},{binding:3,visibility:Ge,buffer:{type:"uniform"}}]}),i=n.createComputePipeline({layout:n.createPipelineLayout({bindGroupLayouts:[r]}),compute:{module:n.createShaderModule({code:Go}),entryPoint:"main"}});return{device:n,pipeline:i,bindGroupLayout:r}})(),Ve)}function He(e,t){return Math.ceil(e/t)*t}async function Gr(e,t,n){const r=await Jo();if(!r)return null;const i=Math.max(0,Math.floor(t)),o=Math.max(0,Math.floor(n.length/4));if(i===0||o===0)return new Uint32Array(0);const s=Math.min(i,Math.floor(e.length/2));if(s===0)return new Uint32Array(0);const a=s*2*Float32Array.BYTES_PER_ELEMENT,c=o*4*Float32Array.BYTES_PER_ELEMENT,l=s*Uint32Array.BYTES_PER_ELEMENT,f=Number(r.device.limits.maxStorageBufferBindingSize);if(a>f||c>f||l>f)return null;const b=r.device.createBuffer({size:He(a,4),usage:mn|qe}),m=r.device.createBuffer({size:He(c,4),usage:mn|qe}),w=r.device.createBuffer({size:He(l,4),usage:mn|Ho}),g=r.device.createBuffer({size:16,usage:$o|qe}),S=r.device.createBuffer({size:He(l,4),usage:qe|Zo});r.device.queue.writeBuffer(b,0,e.buffer,e.byteOffset,a),r.device.queue.writeBuffer(m,0,n.buffer,n.byteOffset,c),r.device.queue.writeBuffer(g,0,new Uint32Array([s,o,0,0]));const T=r.device.createBindGroup({layout:r.bindGroupLayout,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:{buffer:m}},{binding:2,resource:{buffer:w}},{binding:3,resource:{buffer:g}}]}),_=r.device.createCommandEncoder(),B=_.beginComputePass();B.setPipeline(r.pipeline),B.setBindGroup(0,T),B.dispatchWorkgroups(Math.ceil(s/256)),B.end(),_.copyBufferToBuffer(w,0,S,0,l),r.device.queue.submit([_.finish()]),await S.mapAsync(Ko);const N=S.getMappedRange(),W=new Uint32Array(N.slice(0));return S.unmap(),b.destroy(),m.destroy(),w.destroy(),g.destroy(),S.destroy(),W}function Kt(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}async function qr(e,t,n={}){const r=Kt(),i=n.bridgeToDraw===!0;if(!e||!e.count||!e.positions||!e.paletteIndices)return{data:null,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}};const o=Ie(t??[]);if(o.length===0){const F={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return e.fillModes instanceof Uint8Array&&(F.fillModes=new Uint8Array(0)),e.ids instanceof Uint32Array&&(F.ids=new Uint32Array(0)),{data:F,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}}}const s=e.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER,a=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length,s)),c=e.fillModes instanceof Uint8Array&&e.fillModes.length>=a?e.fillModes:null,l=e.ids instanceof Uint32Array&&e.ids.length>=a?e.ids:null;if(a===0){const F={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return c&&(F.fillModes=new Uint8Array(0)),l&&(F.ids=new Uint32Array(0)),{data:F,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}}}const f=new Float32Array(o.length*4);for(let F=0;F<o.length;F+=1){const X=F*4,Z=o[F];f[X]=Z.minX,f[X+1]=Z.minY,f[X+2]=Z.maxX,f[X+3]=Z.maxY}let b=null,m=!1;try{b=await Gr(e.positions,a,f),m=!!b}catch{b=null,m=!1}if(!b)return{data:Pe(e,t),meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!1,candidateCount:a,bridgedToDraw:!1}};let w=0;for(let F=0;F<a;F+=1)b[F]===1&&(w+=1);const g=new Uint32Array(w);if(w>0){let F=0;for(let X=0;X<a;X+=1)b[X]===1&&(g[F]=X,F+=1)}if(w===0){if(i){const X={count:a,positions:e.positions.subarray(0,a*2),paletteIndices:e.paletteIndices.subarray(0,a),drawIndices:new Uint32Array(0)};return c&&(X.fillModes=c.subarray(0,a)),l&&(X.ids=l.subarray(0,a)),{data:X,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!0}}}const F={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return c&&(F.fillModes=new Uint8Array(0)),l&&(F.ids=new Uint32Array(0)),{data:F,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!1}}}if(i){const F=new Uint32Array(w);let X=0;for(let lt=0;lt<w;lt+=1){const mt=g[lt]??0,Tt=e.positions[mt*2],It=e.positions[mt*2+1];nn(Tt,It,o)&&(F[X]=mt,X+=1)}const Z={count:a,positions:e.positions.subarray(0,a*2),paletteIndices:e.paletteIndices.subarray(0,a),drawIndices:F.subarray(0,X)};return c&&(Z.fillModes=c.subarray(0,a)),l&&(Z.ids=l.subarray(0,a)),{data:Z,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!0,candidateCount:w,bridgedToDraw:!0}}}const S=new Float32Array(w*2),T=new Uint16Array(w),_=c?new Uint8Array(w):null,B=l?new Uint32Array(w):null;let N=0;for(let F=0;F<w;F+=1){const X=g[F]??0,Z=e.positions[X*2],lt=e.positions[X*2+1];nn(Z,lt,o)&&(S[N*2]=Z,S[N*2+1]=lt,T[N]=e.paletteIndices[X],_&&(_[N]=c[X]),B&&(B[N]=l[X]),N+=1)}const W={count:N,positions:S.subarray(0,N*2),paletteIndices:T.subarray(0,N)};return _&&(W.fillModes=_.subarray(0,N)),B&&(W.ids=B.subarray(0,N)),{data:W,meta:{mode:"hybrid-webgpu",durationMs:Kt()-r,usedWebGpu:!0,candidateCount:w,bridgedToDraw:!1}}}let _t=null,xn=!0,Hr=1;const oe=new Map;function ie(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function $r(){if(!xn)return null;if(_t)return _t;try{const e=new Worker(new URL(""+(typeof document>"u"?require("url").pathToFileURL(__dirname+"/assets/roi-clip-worker-BDVQwN2T.js").href:new URL("assets/roi-clip-worker-BDVQwN2T.js",document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),typeof document>"u"?require("url").pathToFileURL(__filename).href:ln&&ln.tagName.toUpperCase()==="SCRIPT"&&ln.src||new URL("index.cjs",document.baseURI).href),{type:"module"});return e.addEventListener("message",Un),e.addEventListener("error",Bn),_t=e,e}catch{return xn=!1,null}}function Un(e){const t=e.data;if(!t)return;const n=oe.get(t.id);if(!n)return;if(oe.delete(t.id),t.type==="roi-clip-failure"){n.reject(new Error(t.error||"worker clip failed"));return}if(t.type==="roi-clip-index-success"){if(n.kind!=="index"){n.reject(new Error("worker response mismatch: expected point data result"));return}const l=Math.max(0,Math.floor(t.count)),f=new Uint32Array(t.indices).subarray(0,l);n.resolve({indices:f,meta:{mode:"worker",durationMs:Number.isFinite(t.durationMs)?t.durationMs:ie()-n.startMs}});return}if(n.kind!=="data"){n.reject(new Error("worker response mismatch: expected index result"));return}const r=Math.max(0,Math.floor(t.count)),i=new Float32Array(t.positions),o=new Uint16Array(t.paletteIndices),s=t.fillModes?new Uint8Array(t.fillModes):null,a=t.ids?new Uint32Array(t.ids):null,c={count:r,positions:i.subarray(0,r*2),paletteIndices:o.subarray(0,r)};s&&(c.fillModes=s.subarray(0,r)),a&&(c.ids=a.subarray(0,r)),n.resolve({data:c,meta:{mode:"worker",durationMs:Number.isFinite(t.durationMs)?t.durationMs:ie()-n.startMs}})}function Bn(){xn=!1,_t&&(_t.removeEventListener("message",Un),_t.removeEventListener("error",Bn),_t.terminate(),_t=null);for(const[,e]of oe)e.reject(new Error("worker crashed"));oe.clear()}function Qo(){if(_t){_t.removeEventListener("message",Un),_t.removeEventListener("error",Bn),_t.terminate(),_t=null;for(const[,e]of oe)e.reject(new Error("worker terminated"));oe.clear()}}async function Zr(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return{data:null,meta:{mode:"worker",durationMs:0}};const n=$r();if(!n){const b=ie();return{data:Pe(e,t),meta:{mode:"sync",durationMs:ie()-b}}}const r=e.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER,i=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length,r)),o=e.positions.slice(0,i*2),s=e.paletteIndices.slice(0,i),a=e.fillModes instanceof Uint8Array&&e.fillModes.length>=i?e.fillModes.slice(0,i):null,c=e.ids instanceof Uint32Array&&e.ids.length>=i?e.ids.slice(0,i):null,l=Hr++,f=ie();return new Promise((b,m)=>{oe.set(l,{kind:"data",resolve:b,reject:m,startMs:f});const w={type:"roi-clip-request",id:l,count:i,positions:o.buffer,paletteIndices:s.buffer,fillModes:a?.buffer,ids:c?.buffer,polygons:t??[]},g=[o.buffer,s.buffer];a&&g.push(a.buffer),c&&g.push(c.buffer),n.postMessage(w,g)})}async function ts(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return{indices:new Uint32Array(0),meta:{mode:"worker",durationMs:0}};const n=$r();if(!n){const c=ie();return{indices:Wr(e,t),meta:{mode:"sync",durationMs:ie()-c}}}const r=e.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER,i=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length,r)),o=e.positions.slice(0,i*2),s=Hr++,a=ie();return new Promise((c,l)=>{oe.set(s,{kind:"index",resolve:c,reject:l,startMs:a});const f={type:"roi-clip-index-request",id:s,count:i,positions:o.buffer,polygons:t??[]};n.postMessage(f,[o.buffer])})}function es(e){const t=[];for(let n=0;n<e.length;n+=1){const r=e[n],i=Ie([r?.coordinates]);if(i.length===0)continue;let o=0;for(const s of i)o+=s.area;t.push({regionId:r.id??n,regionIndex:n,polygons:i,area:Math.max(1e-6,o)})}return t}function ns(e,t){if(Array.isArray(t)){const n=t[e];if(typeof n=="string"&&n.length>0)return n}if(t instanceof Map){const n=t.get(e);if(typeof n=="string"&&n.length>0)return n}return String(e)}function Kr(e,t,n={}){const r=Math.max(0,Math.min(Math.floor(e?.count??0),Math.floor((e?.positions?.length??0)/2),e?.paletteIndices?.length??0,e?.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER));let i=null;if(e?.drawIndices instanceof Uint32Array){const m=e.drawIndices;let w=m.length;for(let g=0;g<m.length;g+=1)m[g]<r||(w-=1);if(w===m.length)i=m;else if(w>0){const g=new Uint32Array(w);let S=0;for(let T=0;T<m.length;T+=1){const _=m[T];_>=r||(g[S]=_,S+=1)}i=g}else i=new Uint32Array(0)}const o=i?i.length:r,s=es(t??[]);if(!e||o===0||s.length===0)return{groups:[],inputPointCount:o,pointsInsideAnyRegion:0,unmatchedPointCount:o};const a=new Map,c=new Map;let l=0;for(let m=0;m<o;m+=1){const w=i?i[m]:m,g=e.positions[w*2],S=e.positions[w*2+1];let T=null;for(const N of s){let W=!1;for(const F of N.polygons)if(Ir(g,S,F)){W=!0;break}W&&(!T||N.area<T.area)&&(T=N)}if(!T)continue;l+=1;const _=e.paletteIndices[w]??0,B=a.get(T.regionIndex)??new Map;B.set(_,(B.get(_)??0)+1),a.set(T.regionIndex,B),c.set(T.regionIndex,(c.get(T.regionIndex)??0)+1)}const f=n.includeEmptyRegions??!1,b=[];for(const m of s){const w=c.get(m.regionIndex)??0;if(!f&&w<=0)continue;const g=a.get(m.regionIndex)??new Map,S=Array.from(g.entries()).map(([T,_])=>({termId:ns(T,n.paletteIndexToTermId),paletteIndex:T,count:_})).sort((T,_)=>_.count-T.count||T.paletteIndex-_.paletteIndex);b.push({regionId:m.regionId,regionIndex:m.regionIndex,totalCount:w,termCounts:S})}return{groups:b,inputPointCount:o,pointsInsideAnyRegion:l,unmatchedPointCount:Math.max(0,o-l)}}function $e(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function rs(e,t){if(!t)return!1;try{const r=new URL(e,typeof window<"u"?window.location.href:void 0).hostname.toLowerCase();if(r.includes("amazonaws.com")||r.startsWith("s3.")||r.includes(".s3."))return!1}catch{}return!0}class jr{constructor(t){y(this,"maxConcurrency");y(this,"maxRetries");y(this,"retryBaseDelayMs");y(this,"retryMaxDelayMs");y(this,"onTileLoad");y(this,"onTileError");y(this,"onStateChange");y(this,"authToken");y(this,"destroyed",!1);y(this,"queue",[]);y(this,"queuedByKey",new Map);y(this,"inflight",new Map);y(this,"visibleKeys",new Set);y(this,"timerId",null);y(this,"abortedCount",0);y(this,"retryCount",0);y(this,"failedCount",0);this.maxConcurrency=Math.max(1,Math.floor(t.maxConcurrency??12)),this.maxRetries=Math.max(0,Math.floor(t.maxRetries??2)),this.retryBaseDelayMs=Math.max(10,Math.floor(t.retryBaseDelayMs??120)),this.retryMaxDelayMs=Math.max(this.retryBaseDelayMs,Math.floor(t.retryMaxDelayMs??1200)),this.authToken=t.authToken??"",this.onTileLoad=t.onTileLoad,this.onTileError=t.onTileError,this.onStateChange=t.onStateChange}setAuthToken(t){this.authToken=String(t??"")}schedule(t){if(this.destroyed)return;const n=new Set;for(const r of t)n.add(r.key);this.visibleKeys=n,this.dropInvisibleQueued(n),this.abortInvisibleInflight(n);for(const r of t){if(this.inflight.has(r.key)){const s=this.inflight.get(r.key);s&&(s.tile=r);continue}const i=this.queuedByKey.get(r.key);if(i){i.tile=r;continue}const o={tile:r,attempt:0,readyAt:$e()};this.queue.push(o),this.queuedByKey.set(r.key,o)}this.sortQueue(),this.pump(),this.emitStateChange()}clear(){this.clearPumpTimer(),this.visibleKeys.clear(),this.queue=[],this.queuedByKey.clear();for(const[,t]of this.inflight)t.controller.abort();this.inflight.clear(),this.emitStateChange()}destroy(){this.destroyed||(this.destroyed=!0,this.clear())}getInflightCount(){return this.inflight.size}getSnapshot(){return{inflight:this.inflight.size,queued:this.queue.length,aborted:this.abortedCount,retries:this.retryCount,failed:this.failedCount}}dropInvisibleQueued(t){if(this.queue.length===0)return;const n=[];for(const r of this.queue){if(!t.has(r.tile.key)){this.queuedByKey.delete(r.tile.key);continue}n.push(r)}this.queue=n}abortInvisibleInflight(t){for(const[n,r]of this.inflight)t.has(n)||(this.inflight.delete(n),this.abortedCount+=1,r.controller.abort())}sortQueue(){this.queue.sort((t,n)=>t.readyAt!==n.readyAt?t.readyAt-n.readyAt:t.tile.distance2!==n.tile.distance2?t.tile.distance2-n.tile.distance2:t.tile.tier!==n.tile.tier?n.tile.tier-t.tile.tier:t.tile.key.localeCompare(n.tile.key))}pump(){if(this.destroyed)return;for(this.clearPumpTimer();this.inflight.size<this.maxConcurrency;){const r=this.takeNextReadyQueueItem();if(!r)break;this.startFetch(r)}if(this.inflight.size>=this.maxConcurrency||this.queue.length===0)return;const t=this.queue[0]?.readyAt;if(typeof t!="number")return;const n=Math.max(0,t-$e());this.timerId=window.setTimeout(()=>{this.timerId=null,this.pump()},n)}takeNextReadyQueueItem(){if(this.queue.length===0)return null;const t=$e(),n=this.queue[0];return!n||n.readyAt>t?null:(this.queue.shift(),this.queuedByKey.delete(n.tile.key),n)}startFetch(t){const n=new AbortController,r={tile:t.tile,attempt:t.attempt,controller:n};this.inflight.set(t.tile.key,r),this.emitStateChange();const i=rs(t.tile.url,this.authToken);fetch(t.tile.url,{signal:n.signal,headers:i?{Authorization:this.authToken}:void 0}).then(o=>{if(!o.ok)throw new Error(`HTTP ${o.status}`);return o.blob()}).then(o=>createImageBitmap(o)).then(o=>{if(this.destroyed||n.signal.aborted){o.close();return}if(!this.visibleKeys.has(t.tile.key)){o.close();return}this.onTileLoad(t.tile,o)}).catch(o=>{if(n.signal.aborted||this.destroyed)return;if(t.attempt<this.maxRetries&&this.visibleKeys.has(t.tile.key)){this.retryCount+=1;const a=t.attempt+1,c=this.getRetryDelay(a),l={tile:t.tile,attempt:a,readyAt:$e()+c},f=this.queuedByKey.get(t.tile.key);f?(f.tile=l.tile,f.readyAt=Math.min(f.readyAt,l.readyAt),f.attempt=Math.max(f.attempt,l.attempt)):(this.queue.push(l),this.queuedByKey.set(l.tile.key,l)),this.sortQueue();return}this.failedCount+=1,this.onTileError?.(t.tile,o,t.attempt+1)}).finally(()=>{this.inflight.delete(t.tile.key),this.pump(),this.emitStateChange()})}getRetryDelay(t){const n=Math.max(0,t-1),r=Math.min(this.retryMaxDelayMs,this.retryBaseDelayMs*2**n),i=.85+Math.random()*.3;return Math.round(r*i)}clearPumpTimer(){this.timerId!==null&&(window.clearTimeout(this.timerId),this.timerId=null)}emitStateChange(){this.onStateChange?.(this.getSnapshot())}}const br=.35,Tn=.5,is=256,En=[{zoom:1,size:2.8},{zoom:2,size:3.4},{zoom:3,size:4.2},{zoom:4,size:5.3},{zoom:5,size:6.8},{zoom:6,size:8.4},{zoom:7,size:9.8},{zoom:8,size:11.2},{zoom:9,size:14},{zoom:10,size:17.5},{zoom:11,size:22},{zoom:12,size:28}];class os{constructor(){y(this,"viewportWidth",1);y(this,"viewportHeight",1);y(this,"viewState",{zoom:1,offsetX:0,offsetY:0,rotationDeg:0})}setViewport(t,n){this.viewportWidth=Math.max(1,t),this.viewportHeight=Math.max(1,n)}getViewport(){return{width:this.viewportWidth,height:this.viewportHeight}}setViewState(t){typeof t.zoom=="number"&&(this.viewState.zoom=Math.max(1e-4,t.zoom)),typeof t.offsetX=="number"&&(this.viewState.offsetX=t.offsetX),typeof t.offsetY=="number"&&(this.viewState.offsetY=t.offsetY),typeof t.rotationDeg=="number"&&Number.isFinite(t.rotationDeg)&&(this.viewState.rotationDeg=t.rotationDeg)}getViewState(){return{...this.viewState}}getCenter(){const t=Math.max(1e-6,this.viewState.zoom);return[this.viewState.offsetX+this.viewportWidth/(2*t),this.viewState.offsetY+this.viewportHeight/(2*t)]}setCenter(t,n){const r=Math.max(1e-6,this.viewState.zoom);this.viewState.offsetX=t-this.viewportWidth/(2*r),this.viewState.offsetY=n-this.viewportHeight/(2*r)}screenToWorld(t,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,s]=this.getCenter(),a=(t-this.viewportWidth*.5)/i,c=(n-this.viewportHeight*.5)/i,l=Re(r.rotationDeg),f=Math.cos(l),b=Math.sin(l);return[o+a*f-c*b,s+a*b+c*f]}worldToScreen(t,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,s]=this.getCenter(),a=t-o,c=n-s,l=Re(r.rotationDeg),f=Math.cos(l),b=Math.sin(l),m=a*f+c*b,w=-a*b+c*f;return[this.viewportWidth*.5+m*i,this.viewportHeight*.5+w*i]}getViewCorners(){const t=this.viewportWidth,n=this.viewportHeight;return[this.screenToWorld(0,0),this.screenToWorld(t,0),this.screenToWorld(t,n),this.screenToWorld(0,n)]}getMatrix(){const t=Math.max(1e-6,this.viewState.zoom),[n,r]=this.getCenter(),i=Re(this.viewState.rotationDeg),o=Math.cos(i),s=Math.sin(i),a=2*t*o/this.viewportWidth,c=2*t*s/this.viewportWidth,l=2*t*s/this.viewportHeight,f=-2*t*o/this.viewportHeight,b=-(a*n+c*r),m=-(l*n+f*r);return new Float32Array([a,l,0,c,f,0,b,m,1])}}function Re(e){return e*Math.PI/180}function Ze(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function Dt(e,t,n){const r=e.getUniformLocation(t,n);if(!r)throw new Error(`uniform location lookup failed: ${n}`);return r}function Ke(e,t){return!e||!t?e===t:e.buffer===t.buffer&&e.byteOffset===t.byteOffset&&e.byteLength===t.byteLength}function Rn(e){return e.map(t=>({zoom:t.zoom,size:t.size}))}function wr(e){if(!e)return Rn(En);const t=new Map;for(const[n,r]of Object.entries(e)){const i=Number(n),o=Number(r);!Number.isFinite(i)||!Number.isFinite(o)||o<=0||t.set(i,o)}return t.size===0?Rn(En):Array.from(t.entries()).sort((n,r)=>n[0]-r[0]).map(([n,r])=>({zoom:n,size:r}))}function ss(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n].zoom!==t[n].zoom||e[n].size!==t[n].size)return!1;return!0}function as(e,t){if(!Number.isFinite(e))return t[0]?.size??Tn;if(t.length===0)return Tn;if(t.length===1||e<=t[0].zoom)return t[0].size;for(let s=1;s<t.length;s+=1){const a=t[s-1],c=t[s];if(e>c.zoom)continue;const l=Math.max(1e-6,c.zoom-a.zoom),f=rt((e-a.zoom)/l,0,1);return a.size+(c.size-a.size)*f}const n=t[t.length-1],r=t[t.length-2],i=Math.max(1e-6,n.zoom-r.zoom),o=(n.size-r.size)/i;return n.size+(e-n.zoom)*o}const cs=.1,us=5;function yr(e){return typeof e!="number"||!Number.isFinite(e)?1:rt(e,cs,us)}const ls=-100,fs=100;function gn(e){return typeof e!="number"||!Number.isFinite(e)?0:rt(e,ls,fs)}function Mr(e){const t=gn(e?.brightness),n=gn(e?.contrast),r=gn(e?.saturation);return{brightness:t/200,contrast:n/100,saturation:r/100}}const hs=2e3;function Jr(e){return e}function pn(e){return typeof e!="number"||!Number.isFinite(e)?0:rt(e,0,hs)}function je(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?null:Math.max(1e-6,e)}function bn(e){return typeof e=="function"?e:Jr}function Sr(e,t){return Math.abs(e.zoom-t.zoom)<=1e-6&&Math.abs(e.offsetX-t.offsetX)<=1e-6&&Math.abs(e.offsetY-t.offsetY)<=1e-6&&Math.abs(e.rotationDeg-t.rotationDeg)<=1e-6}class Qr{constructor(t,n,r={}){y(this,"canvas");y(this,"source");y(this,"gl");y(this,"camera",new os);y(this,"onViewStateChange");y(this,"onStats");y(this,"onTileError");y(this,"onContextLost");y(this,"onContextRestored");y(this,"resizeObserver");y(this,"tileProgram");y(this,"pointProgram");y(this,"tileScheduler");y(this,"authToken");y(this,"destroyed",!1);y(this,"contextLost",!1);y(this,"frame",null);y(this,"frameSerial",0);y(this,"dragging",!1);y(this,"interactionMode","none");y(this,"rotateLastAngleRad",null);y(this,"pointerId",null);y(this,"lastPointerX",0);y(this,"lastPointerY",0);y(this,"interactionLocked",!1);y(this,"ctrlDragRotate",!0);y(this,"rotationDragSensitivityDegPerPixel",.35);y(this,"maxCacheTiles");y(this,"fitZoom",1);y(this,"minZoom",1e-6);y(this,"maxZoom",1);y(this,"minZoomOverride",null);y(this,"maxZoomOverride",null);y(this,"viewTransitionDurationMs",0);y(this,"viewTransitionEasing",Jr);y(this,"viewAnimation",null);y(this,"viewAnimationFrame",null);y(this,"currentTier",0);y(this,"pointCount",0);y(this,"usePointIndices",!1);y(this,"pointBuffersDirty",!0);y(this,"pointPaletteSize",1);y(this,"pointSizeStops",Rn(En));y(this,"pointStrokeScale",1);y(this,"imageColorSettings",{brightness:0,contrast:0,saturation:0});y(this,"lastPointData",null);y(this,"lastPointPalette",null);y(this,"zeroFillModes",new Uint8Array(0));y(this,"cache",new Map);y(this,"boundPointerDown");y(this,"boundPointerMove");y(this,"boundPointerUp");y(this,"boundWheel");y(this,"boundDoubleClick");y(this,"boundContextMenu");y(this,"boundContextLost");y(this,"boundContextRestored");this.canvas=t,this.source=n,this.onViewStateChange=r.onViewStateChange,this.onStats=r.onStats,this.onTileError=r.onTileError,this.onContextLost=r.onContextLost,this.onContextRestored=r.onContextRestored,this.authToken=r.authToken??"",this.maxCacheTiles=Math.max(32,Math.floor(r.maxCacheTiles??320)),this.ctrlDragRotate=r.ctrlDragRotate??!0,this.rotationDragSensitivityDegPerPixel=typeof r.rotationDragSensitivityDegPerPixel=="number"&&Number.isFinite(r.rotationDragSensitivityDegPerPixel)?Math.max(0,r.rotationDragSensitivityDegPerPixel):br,this.pointSizeStops=wr(r.pointSizeByZoom),this.pointStrokeScale=yr(r.pointStrokeScale),this.imageColorSettings=Mr(r.imageColorSettings),this.minZoomOverride=je(r.minZoom),this.maxZoomOverride=je(r.maxZoom),this.viewTransitionDurationMs=pn(r.viewTransition?.duration),this.viewTransitionEasing=bn(r.viewTransition?.easing);const i=t.getContext("webgl2",{alpha:!1,antialias:!1,depth:!1,stencil:!1,powerPreference:"high-performance"});if(!i)throw new Error("WebGL2 not supported");this.gl=i,this.tileProgram=this.initTileProgram(),this.pointProgram=this.initPointProgram(),this.tileScheduler=new jr({authToken:this.authToken,maxConcurrency:r.tileScheduler?.maxConcurrency??12,maxRetries:r.tileScheduler?.maxRetries??2,retryBaseDelayMs:r.tileScheduler?.retryBaseDelayMs??120,retryMaxDelayMs:r.tileScheduler?.retryMaxDelayMs??1200,onTileLoad:(o,s)=>this.handleTileLoaded(o,s),onTileError:(o,s,a)=>{this.onTileError?.({tile:o,error:s,attemptCount:a}),console.warn("tile load failed",o.url,s)}}),this.resizeObserver=new ResizeObserver(()=>this.resize()),this.resizeObserver.observe(t),this.boundPointerDown=o=>this.onPointerDown(o),this.boundPointerMove=o=>this.onPointerMove(o),this.boundPointerUp=o=>this.onPointerUp(o),this.boundWheel=o=>this.onWheel(o),this.boundDoubleClick=o=>this.onDoubleClick(o),this.boundContextMenu=o=>this.onContextMenu(o),this.boundContextLost=o=>this.onWebGlContextLost(o),this.boundContextRestored=o=>this.onWebGlContextRestored(o),t.addEventListener("pointerdown",this.boundPointerDown),t.addEventListener("pointermove",this.boundPointerMove),t.addEventListener("pointerup",this.boundPointerUp),t.addEventListener("pointercancel",this.boundPointerUp),t.addEventListener("wheel",this.boundWheel,{passive:!1}),t.addEventListener("dblclick",this.boundDoubleClick),t.addEventListener("contextmenu",this.boundContextMenu),t.addEventListener("webglcontextlost",this.boundContextLost),t.addEventListener("webglcontextrestored",this.boundContextRestored),this.fitToImage({duration:0}),this.resize()}resolveDefaultZoomBounds(){const t=Math.max(this.fitZoom*.5,1e-6),n=Math.max(1,this.fitZoom*8);return{minZoom:t,maxZoom:Math.max(t,n)}}applyZoomBounds(){const t=this.resolveDefaultZoomBounds();let n=this.minZoomOverride??t.minZoom,r=this.maxZoomOverride??t.maxZoom;n=Math.max(1e-6,n),r=Math.max(1e-6,r),n>r&&(n=r),this.minZoom=n,this.maxZoom=r}resolveTargetViewState(t){const n=this.camera.getViewState(),r={zoom:typeof t.zoom=="number"&&Number.isFinite(t.zoom)?rt(t.zoom,this.minZoom,this.maxZoom):n.zoom,offsetX:typeof t.offsetX=="number"&&Number.isFinite(t.offsetX)?t.offsetX:n.offsetX,offsetY:typeof t.offsetY=="number"&&Number.isFinite(t.offsetY)?t.offsetY:n.offsetY,rotationDeg:typeof t.rotationDeg=="number"&&Number.isFinite(t.rotationDeg)?t.rotationDeg:n.rotationDeg};this.camera.setViewState(r),this.clampViewState();const i=this.camera.getViewState();return this.camera.setViewState(n),i}cancelViewAnimation(){this.viewAnimation=null,this.viewAnimationFrame!==null&&(cancelAnimationFrame(this.viewAnimationFrame),this.viewAnimationFrame=null)}startViewAnimation(t,n,r){const i=this.camera.getViewState();this.cancelViewAnimation(),this.viewAnimation={startMs:Ze(),durationMs:Math.max(0,n),from:i,to:t,easing:r};const o=()=>{const s=this.viewAnimation;if(!s)return;const a=Math.max(0,Ze()-s.startMs),c=s.durationMs<=0?1:rt(a/s.durationMs,0,1);let l=c;try{l=s.easing(c)}catch{l=c}Number.isFinite(l)||(l=c),l=rt(l,0,1);const f={zoom:s.from.zoom+(s.to.zoom-s.from.zoom)*l,offsetX:s.from.offsetX+(s.to.offsetX-s.from.offsetX)*l,offsetY:s.from.offsetY+(s.to.offsetY-s.from.offsetY)*l,rotationDeg:s.from.rotationDeg+(s.to.rotationDeg-s.from.rotationDeg)*l};if(this.camera.setViewState(f),this.clampViewState(),this.emitViewState(),this.requestRender(),c>=1){this.viewAnimation=null,this.viewAnimationFrame=null;return}this.viewAnimationFrame=requestAnimationFrame(o)};this.viewAnimationFrame=requestAnimationFrame(o)}setAuthToken(t){this.authToken=String(t??""),this.tileScheduler.setAuthToken(this.authToken)}setZoomRange(t,n){const r=je(t),i=je(n);if(this.minZoomOverride===r&&this.maxZoomOverride===i)return;this.minZoomOverride=r,this.maxZoomOverride=i,this.applyZoomBounds();const o=this.resolveTargetViewState({}),s=this.camera.getViewState();Sr(s,o)||(this.cancelViewAnimation(),this.camera.setViewState(o),this.emitViewState(),this.requestRender())}setViewTransition(t){this.viewTransitionDurationMs=pn(t?.duration),this.viewTransitionEasing=bn(t?.easing)}setViewState(t,n){const r=this.resolveTargetViewState(t),i=this.camera.getViewState();if(Sr(i,r))return;const o=pn(n?.duration??this.viewTransitionDurationMs),s=bn(n?.easing??this.viewTransitionEasing);if(o<=0){this.cancelViewAnimation(),this.camera.setViewState(r),this.emitViewState(),this.requestRender();return}this.startViewAnimation(r,o,s)}getViewState(){return this.camera.getViewState()}getZoomRange(){return{minZoom:this.minZoom,maxZoom:this.maxZoom}}setPointPalette(t){if(!t||t.length===0){this.lastPointPalette=null;return}if(this.lastPointPalette=new Uint8Array(t),this.contextLost||this.gl.isContextLost())return;const n=this.gl,r=Math.max(1,Math.floor(this.lastPointPalette.length/4));this.pointPaletteSize=r,n.bindTexture(n.TEXTURE_2D,this.pointProgram.paletteTexture),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,r,1,0,n.RGBA,n.UNSIGNED_BYTE,this.lastPointPalette),n.bindTexture(n.TEXTURE_2D,null),this.requestRender()}setPointData(t){if(!t||!t.count||!t.positions||!t.paletteIndices){this.lastPointData=null,this.pointCount=0,this.usePointIndices=!1,this.requestRender();return}const n=t.fillModes instanceof Uint8Array?t.fillModes:null,r=n!==null,i=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length,r?n.length:Number.MAX_SAFE_INTEGER)),o=t.positions.subarray(0,i*2),s=t.paletteIndices.subarray(0,i),a=r?n.subarray(0,i):void 0,c=t.drawIndices instanceof Uint32Array,l=c?this.sanitizeDrawIndices(t.drawIndices,i):null,f=this.lastPointData,b=f?.fillModes instanceof Uint8Array;let m=this.pointBuffersDirty||!f||f.count!==i||!Ke(f.positions,o)||!Ke(f.paletteIndices,s)||b!==r||r&&(!f?.fillModes||!Ke(f.fillModes,a)),w=this.pointBuffersDirty||c&&(!f?.drawIndices||!Ke(f.drawIndices,l))||!c&&!!f?.drawIndices;if(this.lastPointData={count:i,positions:o,paletteIndices:s,fillModes:a,drawIndices:c?l??void 0:void 0},this.contextLost||this.gl.isContextLost())return;const g=this.gl;m&&(g.bindBuffer(g.ARRAY_BUFFER,this.pointProgram.posBuffer),g.bufferData(g.ARRAY_BUFFER,this.lastPointData.positions,g.STATIC_DRAW),g.bindBuffer(g.ARRAY_BUFFER,this.pointProgram.termBuffer),g.bufferData(g.ARRAY_BUFFER,this.lastPointData.paletteIndices,g.STATIC_DRAW),g.bindBuffer(g.ARRAY_BUFFER,this.pointProgram.fillModeBuffer),g.bufferData(g.ARRAY_BUFFER,this.lastPointData.fillModes??this.getZeroFillModes(i),g.STATIC_DRAW),g.bindBuffer(g.ARRAY_BUFFER,null)),c&&w&&(g.bindBuffer(g.ELEMENT_ARRAY_BUFFER,this.pointProgram.indexBuffer),g.bufferData(g.ELEMENT_ARRAY_BUFFER,l??new Uint32Array(0),g.DYNAMIC_DRAW),g.bindBuffer(g.ELEMENT_ARRAY_BUFFER,null)),this.usePointIndices=c,this.pointCount=c?l?.length??0:this.lastPointData.count,(m||w)&&(this.pointBuffersDirty=!1),this.requestRender()}sanitizeDrawIndices(t,n){if(n<=0||t.length===0)return new Uint32Array(0);let r=t.length;for(let s=0;s<t.length;s+=1)t[s]<n||(r-=1);if(r===t.length)return t;if(r<=0)return new Uint32Array(0);const i=new Uint32Array(r);let o=0;for(let s=0;s<t.length;s+=1){const a=t[s];a>=n||(i[o]=a,o+=1)}return i}getZeroFillModes(t){return t<=0?new Uint8Array(0):(this.zeroFillModes.length<t&&(this.zeroFillModes=new Uint8Array(t)),this.zeroFillModes.subarray(0,t))}setInteractionLock(t){const n=!!t;this.interactionLocked!==n&&(this.interactionLocked=n,n&&this.cancelDrag())}setPointSizeByZoom(t){const n=wr(t);ss(this.pointSizeStops,n)||(this.pointSizeStops=n,this.requestRender())}setPointStrokeScale(t){const n=yr(t);this.pointStrokeScale!==n&&(this.pointStrokeScale=n,this.requestRender())}setImageColorSettings(t){const n=Mr(t),r=this.imageColorSettings;r.brightness===n.brightness&&r.contrast===n.contrast&&r.saturation===n.saturation||(this.imageColorSettings=n,this.requestRender())}cancelDrag(){if(this.pointerId!==null&&this.canvas.hasPointerCapture(this.pointerId))try{this.canvas.releasePointerCapture(this.pointerId)}catch{}this.dragging=!1,this.interactionMode="none",this.rotateLastAngleRad=null,this.pointerId=null,this.canvas.classList.remove("dragging")}getPointerAngleRad(t,n){const r=this.canvas.getBoundingClientRect(),i=t-r.left-r.width*.5,o=n-r.top-r.height*.5;return Math.atan2(o,i)}screenToWorld(t,n){const r=this.canvas.getBoundingClientRect(),i=t-r.left,o=n-r.top;return this.camera.screenToWorld(i,o)}worldToScreen(t,n){return this.camera.worldToScreen(t,n)}setViewCenter(t,n,r){if(!Number.isFinite(t)||!Number.isFinite(n))return;const i=this.camera.getViewState(),o=Math.max(1e-6,i.zoom),s=this.camera.getViewport();this.setViewState({offsetX:t-s.width/(2*o),offsetY:n-s.height/(2*o)},r)}getViewCorners(){return this.camera.getViewCorners()}resetRotation(t){const n=this.camera.getViewState();Math.abs(n.rotationDeg)<1e-6||this.setViewState({rotationDeg:0},t)}getPointSizeByZoom(){const t=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(t),r=as(n,this.pointSizeStops);return rt(r,Tn,is)}fitToImage(t){const n=this.canvas.getBoundingClientRect(),r=Math.max(1,n.width||1),i=Math.max(1,n.height||1),o=Math.min(r/this.source.width,i/this.source.height),s=Number.isFinite(o)&&o>0?o:1;this.fitZoom=s,this.applyZoomBounds();const a=rt(s,this.minZoom,this.maxZoom),c=r/a,l=i/a;this.setViewState({zoom:a,offsetX:(this.source.width-c)*.5,offsetY:(this.source.height-l)*.5,rotationDeg:0},t)}zoomBy(t,n,r,i){const o=this.camera.getViewState(),s=rt(o.zoom*t,this.minZoom,this.maxZoom);if(s===o.zoom)return;const[a,c]=this.camera.screenToWorld(n,r),l=this.camera.getViewport(),f=n-l.width*.5,b=r-l.height*.5,m=Re(o.rotationDeg),w=Math.cos(m),g=Math.sin(m),S=f/s*w-b/s*g,T=f/s*g+b/s*w,_=a-S,B=c-T;this.setViewState({zoom:s,offsetX:_-l.width/(2*s),offsetY:B-l.height/(2*s)},i)}clampViewState(){const t=this.getViewBounds(),n=Math.max(1e-6,t[2]-t[0]),r=Math.max(1e-6,t[3]-t[1]),i=n*.2,o=r*.2,[s,a]=this.camera.getCenter(),c=n*.5,l=r*.5,f=c-i,b=this.source.width-c+i,m=l-o,w=this.source.height-l+o,g=f<=b?rt(s,f,b):this.source.width*.5,S=m<=w?rt(a,m,w):this.source.height*.5;this.camera.setCenter(g,S)}emitViewState(){this.onViewStateChange?.(this.camera.getViewState())}selectTier(){const t=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(t);return rt(Math.floor(n),0,this.source.maxTierZoom)}getViewBounds(){const t=this.camera.getViewCorners();let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[s,a]of t)s<n&&(n=s),s>i&&(i=s),a<r&&(r=a),a>o&&(o=a);return[n,r,i,o]}intersectsBounds(t,n){return!(t[2]<=n[0]||t[0]>=n[2]||t[3]<=n[1]||t[1]>=n[3])}getVisibleTiles(){const t=this.selectTier();this.currentTier=t;const n=this.getViewBounds(),r=Math.pow(2,this.source.maxTierZoom-t),i=Math.ceil(this.source.width/r),o=Math.ceil(this.source.height/r),s=Math.max(1,Math.ceil(i/this.source.tileSize)),a=Math.max(1,Math.ceil(o/this.source.tileSize)),c=n[0],l=n[1],f=n[2],b=n[3],m=rt(Math.floor(c/r/this.source.tileSize),0,s-1),w=rt(Math.floor((f-1)/r/this.source.tileSize),0,s-1),g=rt(Math.floor(l/r/this.source.tileSize),0,a-1),S=rt(Math.floor((b-1)/r/this.source.tileSize),0,a-1);if(m>w||g>S)return[];const T=(c+f)*.5/r/this.source.tileSize,_=(l+b)*.5/r/this.source.tileSize,B=[];for(let N=g;N<=S;N+=1)for(let W=m;W<=w;W+=1){const F=W*this.source.tileSize*r,X=N*this.source.tileSize*r,Z=Math.min((W+1)*this.source.tileSize,i)*r,lt=Math.min((N+1)*this.source.tileSize,o)*r,mt=W-T,Tt=N-_;B.push({key:`${t}/${W}/${N}`,tier:t,x:W,y:N,bounds:[F,X,Z,lt],distance2:mt*mt+Tt*Tt,url:Fn(this.source,t,W,N)})}return B.sort((N,W)=>N.distance2-W.distance2),B}trimCache(){if(this.cache.size<=this.maxCacheTiles)return;const t=Array.from(this.cache.entries());t.sort((r,i)=>r[1].lastUsed-i[1].lastUsed);const n=this.cache.size-this.maxCacheTiles;for(let r=0;r<n;r+=1){const[i,o]=t[r];this.gl.deleteTexture(o.texture),this.cache.delete(i)}}render(){if(this.destroyed||this.contextLost||this.gl.isContextLost())return;const t=Ze();this.frameSerial+=1;const n=this.gl,r=this.tileProgram,i=this.pointProgram;n.clearColor(.03,.06,.1,1),n.clear(n.COLOR_BUFFER_BIT);const o=this.getVisibleTiles(),s=this.getViewBounds(),a=new Set(o.map(m=>m.key));n.useProgram(r.program),n.bindVertexArray(r.vao),n.uniformMatrix3fv(r.uCamera,!1,this.camera.getMatrix()),n.uniform1i(r.uTexture,0),n.uniform1f(r.uBrightness,this.imageColorSettings.brightness),n.uniform1f(r.uContrast,this.imageColorSettings.contrast),n.uniform1f(r.uSaturation,this.imageColorSettings.saturation);const c=[];for(const[,m]of this.cache)a.has(m.key)||this.intersectsBounds(m.bounds,s)&&c.push(m);c.sort((m,w)=>m.tier-w.tier);for(const m of c)m.lastUsed=this.frameSerial,n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,m.texture),n.uniform4f(r.uBounds,m.bounds[0],m.bounds[1],m.bounds[2],m.bounds[3]),n.drawArrays(n.TRIANGLE_STRIP,0,4);let l=0;const f=[];for(const m of o){const w=this.cache.get(m.key);if(!w){f.push(m);continue}w.lastUsed=this.frameSerial,n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,w.texture),n.uniform4f(r.uBounds,w.bounds[0],w.bounds[1],w.bounds[2],w.bounds[3]),n.drawArrays(n.TRIANGLE_STRIP,0,4),l+=1}this.tileScheduler.schedule(f),n.bindTexture(n.TEXTURE_2D,null),n.bindVertexArray(null);let b=0;if(this.pointCount>0&&(n.enable(n.BLEND),n.blendFunc(n.ONE,n.ONE_MINUS_SRC_ALPHA),n.useProgram(i.program),n.bindVertexArray(i.vao),n.uniformMatrix3fv(i.uCamera,!1,this.camera.getMatrix()),n.uniform1f(i.uPointSize,this.getPointSizeByZoom()),n.uniform1f(i.uPointStrokeScale,this.pointStrokeScale),n.uniform1f(i.uPaletteSize,this.pointPaletteSize),n.uniform1i(i.uPalette,1),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,i.paletteTexture),this.usePointIndices?n.drawElements(n.POINTS,this.pointCount,n.UNSIGNED_INT,0):n.drawArrays(n.POINTS,0,this.pointCount),n.bindTexture(n.TEXTURE_2D,null),n.bindVertexArray(null),b=this.pointCount),this.onStats){const m=this.tileScheduler.getSnapshot(),w=l,g=f.length,S=c.length+l+(b>0?1:0);this.onStats({tier:this.currentTier,visible:o.length,rendered:l,points:b,fallback:c.length,cache:this.cache.size,inflight:m.inflight,queued:m.queued,retries:m.retries,failed:m.failed,aborted:m.aborted,cacheHits:w,cacheMisses:g,drawCalls:S,frameMs:Ze()-t})}}requestRender(){this.frame!==null||this.destroyed||this.contextLost||this.gl.isContextLost()||(this.frame=requestAnimationFrame(()=>{this.frame=null,this.render()}))}resize(){const t=this.canvas.getBoundingClientRect(),n=Math.max(1,t.width||this.canvas.clientWidth||1),r=Math.max(1,t.height||this.canvas.clientHeight||1),i=Math.max(1,window.devicePixelRatio||1),o=Math.max(1,Math.round(n*i)),s=Math.max(1,Math.round(r*i));(this.canvas.width!==o||this.canvas.height!==s)&&(this.canvas.width=o,this.canvas.height=s),this.camera.setViewport(n,r),this.gl.viewport(0,0,o,s),this.requestRender()}onPointerDown(t){if(this.interactionLocked)return;const n=this.ctrlDragRotate&&(t.ctrlKey||t.metaKey);(t.button===0||n&&t.button===2)&&(this.cancelViewAnimation(),n&&t.preventDefault(),this.dragging=!0,this.interactionMode=n?"rotate":"pan",this.pointerId=t.pointerId,this.lastPointerX=t.clientX,this.lastPointerY=t.clientY,this.rotateLastAngleRad=this.interactionMode==="rotate"?this.getPointerAngleRad(t.clientX,t.clientY):null,this.canvas.classList.add("dragging"),this.canvas.setPointerCapture(t.pointerId))}onPointerMove(t){if(this.interactionLocked||!this.dragging||t.pointerId!==this.pointerId)return;const n=t.clientX-this.lastPointerX,r=t.clientY-this.lastPointerY;if(this.lastPointerX=t.clientX,this.lastPointerY=t.clientY,this.interactionMode==="rotate"){const i=this.getPointerAngleRad(t.clientX,t.clientY),o=this.rotateLastAngleRad;if(this.rotateLastAngleRad=i,o!==null){const s=i-o,a=Math.atan2(Math.sin(s),Math.cos(s)),c=this.rotationDragSensitivityDegPerPixel/br,l=this.camera.getViewState();this.camera.setViewState({rotationDeg:l.rotationDeg-a*180/Math.PI*c})}}else{const i=this.camera.getViewState(),o=Math.max(1e-6,i.zoom),s=Re(i.rotationDeg),a=Math.cos(s),c=Math.sin(s),l=(n*a-r*c)/o,f=(n*c+r*a)/o;this.camera.setViewState({offsetX:i.offsetX-l,offsetY:i.offsetY-f})}this.clampViewState(),this.emitViewState(),this.requestRender()}onPointerUp(t){this.interactionLocked||t.pointerId===this.pointerId&&this.cancelDrag()}onWheel(t){if(this.interactionLocked){t.preventDefault();return}t.preventDefault();const n=this.canvas.getBoundingClientRect(),r=t.clientX-n.left,i=t.clientY-n.top,o=t.deltaY<0?1.12:.89;this.zoomBy(o,r,i)}onDoubleClick(t){if(this.interactionLocked)return;const n=this.canvas.getBoundingClientRect(),r=t.clientX-n.left,i=t.clientY-n.top;this.zoomBy(t.shiftKey?.8:1.25,r,i)}onContextMenu(t){(this.dragging||t.ctrlKey||t.metaKey)&&t.preventDefault()}onWebGlContextLost(t){t.preventDefault(),!(this.destroyed||this.contextLost)&&(this.contextLost=!0,this.pointBuffersDirty=!0,this.frame!==null&&(cancelAnimationFrame(this.frame),this.frame=null),this.cancelViewAnimation(),this.cancelDrag(),this.tileScheduler.clear(),this.cache.clear(),this.onContextLost?.())}onWebGlContextRestored(t){this.destroyed||(this.contextLost=!1,this.cache.clear(),this.tileProgram=this.initTileProgram(),this.pointProgram=this.initPointProgram(),this.pointBuffersDirty=!0,this.lastPointPalette&&this.lastPointPalette.length>0&&this.setPointPalette(this.lastPointPalette),this.lastPointData?this.setPointData(this.lastPointData):this.pointCount=0,this.resize(),this.requestRender(),this.onContextRestored?.())}destroy(){if(!this.destroyed){if(this.destroyed=!0,this.frame!==null&&(cancelAnimationFrame(this.frame),this.frame=null),this.cancelViewAnimation(),this.resizeObserver.disconnect(),this.canvas.removeEventListener("pointerdown",this.boundPointerDown),this.canvas.removeEventListener("pointermove",this.boundPointerMove),this.canvas.removeEventListener("pointerup",this.boundPointerUp),this.canvas.removeEventListener("pointercancel",this.boundPointerUp),this.canvas.removeEventListener("wheel",this.boundWheel),this.canvas.removeEventListener("dblclick",this.boundDoubleClick),this.canvas.removeEventListener("contextmenu",this.boundContextMenu),this.canvas.removeEventListener("webglcontextlost",this.boundContextLost),this.canvas.removeEventListener("webglcontextrestored",this.boundContextRestored),this.cancelDrag(),this.tileScheduler.destroy(),!this.contextLost&&!this.gl.isContextLost()){for(const[,t]of this.cache)this.gl.deleteTexture(t.texture);this.gl.deleteBuffer(this.tileProgram.vbo),this.gl.deleteVertexArray(this.tileProgram.vao),this.gl.deleteProgram(this.tileProgram.program),this.gl.deleteBuffer(this.pointProgram.posBuffer),this.gl.deleteBuffer(this.pointProgram.termBuffer),this.gl.deleteBuffer(this.pointProgram.fillModeBuffer),this.gl.deleteBuffer(this.pointProgram.indexBuffer),this.gl.deleteTexture(this.pointProgram.paletteTexture),this.gl.deleteVertexArray(this.pointProgram.vao),this.gl.deleteProgram(this.pointProgram.program)}this.cache.clear()}}initTileProgram(){const t=this.gl,i=er(t,`#version 300 es
|
|
64
64
|
precision highp float;
|
|
65
65
|
in vec2 aUnit;
|
|
66
66
|
in vec2 aUv;
|
|
@@ -154,6 +154,6 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
154
154
|
if (alpha <= 0.001) discard;
|
|
155
155
|
|
|
156
156
|
outColor = vec4(color.rgb * alpha, alpha);
|
|
157
|
-
}`),o=Dt(t,i,"uCamera"),s=Dt(t,i,"uPointSize"),a=Dt(t,i,"uPointStrokeScale"),c=Dt(t,i,"uPalette"),l=Dt(t,i,"uPaletteSize"),f=t.createVertexArray(),b=t.createBuffer(),m=t.createBuffer(),w=t.createBuffer(),g=t.createBuffer(),S=t.createTexture();if(!f||!b||!m||!w||!g||!S)throw new Error("point buffer allocation failed");t.bindVertexArray(f),t.bindBuffer(t.ARRAY_BUFFER,b),t.bufferData(t.ARRAY_BUFFER,0,t.DYNAMIC_DRAW);const T=t.getAttribLocation(i,"aPosition");if(T<0)throw new Error("point position attribute not found");t.enableVertexAttribArray(T),t.vertexAttribPointer(T,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,m),t.bufferData(t.ARRAY_BUFFER,0,t.DYNAMIC_DRAW);const _=t.getAttribLocation(i,"aTerm");if(_<0)throw new Error("point term attribute not found");t.enableVertexAttribArray(_),t.vertexAttribIPointer(_,1,t.UNSIGNED_SHORT,0,0),t.bindBuffer(t.ARRAY_BUFFER,w),t.bufferData(t.ARRAY_BUFFER,0,t.DYNAMIC_DRAW);const B=t.getAttribLocation(i,"aFillMode");if(B<0)throw new Error("point fill mode attribute not found");return t.enableVertexAttribArray(B),t.vertexAttribIPointer(B,1,t.UNSIGNED_BYTE,0,0),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,g),t.bufferData(t.ELEMENT_ARRAY_BUFFER,0,t.DYNAMIC_DRAW),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null),t.bindTexture(t.TEXTURE_2D,S),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,1,1,0,t.RGBA,t.UNSIGNED_BYTE,new Uint8Array([160,160,160,255])),t.bindTexture(t.TEXTURE_2D,null),{program:i,vao:f,posBuffer:b,termBuffer:m,fillModeBuffer:w,indexBuffer:g,paletteTexture:S,uCamera:o,uPointSize:s,uPointStrokeScale:a,uPalette:c,uPaletteSize:l}}handleTileLoaded(t,n){if(this.destroyed||this.contextLost||this.gl.isContextLost()){n.close();return}if(this.cache.has(t.key)){n.close();return}const r=this.createTextureFromBitmap(n);n.close(),r&&(this.cache.set(t.key,{key:t.key,texture:r,bounds:t.bounds,tier:t.tier,lastUsed:this.frameSerial}),this.trimCache(),this.requestRender())}createTextureFromBitmap(t){if(this.contextLost||this.gl.isContextLost())return null;const n=this.gl,r=n.createTexture();return r?(n.bindTexture(n.TEXTURE_2D,r),n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL,1),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.LINEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,n.RGBA,n.UNSIGNED_BYTE,t),n.bindTexture(n.TEXTURE_2D,null),r):null}}const wn=[],ds=[],ms={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)},gs=.65,ps=4,bs=24,ws=1024,ys=4,Ms=6,Ss=.5,As=.58,xs=4096,Ts=180,Ar=20;let Je=null;const Qe=new Map;function Es(e){const t=e.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER;return Math.max(0,Math.min(Math.floor(e.count??0),Math.floor((e.positions?.length??0)/2),e.paletteIndices?.length??0,t))}function Rs(e,t){if(!(e instanceof Uint32Array)||t<=0||e.length===0)return null;let n=!1;for(let o=0;o<e.length;o+=1)if(!(e[o]<t)){n=!0;break}if(!n)return e;const r=new Uint32Array(e.length);let i=0;for(let o=0;o<e.length;o+=1){const s=e[o];s>=t||(r[i]=s,i+=1)}return r.subarray(0,i)}function Cs(e,t){if(!e||t<=0)return 256;const n=Math.max(1,e.width*e.height),i=Math.sqrt(n/Math.max(1,t))*ys;return Math.max(bs,Math.min(ws,i))}function Ps(e,t){if(!e||!e.positions||!e.paletteIndices)return null;const n=Es(e);if(n<=0)return null;const r=e.positions.subarray(0,n*2),i=e.ids instanceof Uint32Array&&e.ids.length>=n?e.ids.subarray(0,n):null,o=Rs(e.drawIndices,n),s=o?o.length:n;if(s===0)return null;const a=Cs(t,s),c=new Map,l=f=>{const b=r[f*2],m=r[f*2+1];if(!Number.isFinite(b)||!Number.isFinite(m))return;const w=Math.floor(b/a),g=Math.floor(m/a);let S=c.get(w);S||(S=new Map,c.set(w,S));const T=S.get(g);T?T.push(f):S.set(g,[f])};if(o)for(let f=0;f<o.length;f+=1)l(o[f]??0);else for(let f=0;f<n;f+=1)l(f);return c.size===0?null:{cellSize:a,safeCount:n,positions:r,ids:i,buckets:c}}function Cn(e,t){return e.id??t}function me(e,t,n){return Math.max(t,Math.min(n,e))}function Is(e){const t=me(e,0,1);return t*t*(3-2*t)}function Pn(e){if(!Array.isArray(e)||e.length<2)return null;const t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:[t,n]}function vs(e){if(e.length===0)return null;let t=1/0;for(const i of e)i[1]<t&&(t=i[1]);if(!Number.isFinite(t))return null;let n=1/0,r=-1/0;for(const i of e)Math.abs(i[1]-t)>Ss||(i[0]<n&&(n=i[0]),i[0]>r&&(r=i[0]));return!Number.isFinite(n)||!Number.isFinite(r)?null:[(n+r)*.5,t]}function _s(e){let t=null;for(const n of e){const r=vs(n.outer);r&&(!t||r[1]<t[1]||r[1]===t[1]&&r[0]<t[0])&&(t=r)}return t}function Fs(e,t,n,r,i,o){const s=i-n,a=o-r,c=s*s+a*a;if(c<=1e-12){const g=e-n,S=t-r;return g*g+S*S}const l=me(((e-n)*s+(t-r)*a)/c,0,1),f=n+s*l,b=r+a*l,m=e-f,w=t-b;return m*m+w*w}function xr(e,t,n,r){for(let i=1;i<n.length;i+=1){const o=n[i-1],s=n[i];if(Fs(e,t,o[0],o[1],s[0],s[1])<=r)return!0}return!1}function Us(e,t,n,r){if(e<n.minX-r||e>n.maxX+r||t<n.minY-r||t>n.maxY+r)return!1;const i=r*r;if(xr(e,t,n.outer,i))return!0;for(const o of n.holes)if(xr(e,t,o,i))return!0;return!1}function Bs(){if(Je)return Je;if(typeof document>"u")return null;const t=document.createElement("canvas").getContext("2d");return t?(Je=t,Je):null}function Ls(e,t){const n=`${t.fontWeight}|${t.fontSize}|${t.fontFamily}|${e}`,r=Qe.get(n);if(r!==void 0)return r;const i=e.length*t.fontSize*As,o=Bs();let s=i;if(o){o.font=`${t.fontWeight} ${t.fontSize}px ${t.fontFamily}`;const a=o.measureText(e).width;Number.isFinite(a)&&a>=0&&(s=a)}return Qe.size>xs&&Qe.clear(),Qe.set(n,s),s}function Ns(e,t,n,r,i,o){if(!e.label||!e.labelAnchor)return!1;const s=Pn(n.worldToScreen(e.labelAnchor[0],e.labelAnchor[1]));if(!s)return!1;const c=Ls(e.label,r)+r.paddingX*2,l=r.fontSize+r.paddingY*2,f=me(s[0],c*.5+1,i-c*.5-1),b=me(s[1]-r.offsetY,l*.5+1,o-l*.5-1),m=f-c*.5,w=f+c*.5,g=b-l*.5,S=b+l*.5;return t[0]>=m&&t[0]<=w&&t[1]>=g&&t[1]<=S}function zs(e){const t=[];for(let n=0;n<e.length;n+=1){const r=e[n],i=Ie([r?.coordinates]);if(i.length===0)continue;const o=typeof r?.label=="string"?r.label.trim():"";t.push({region:r,regionIndex:n,regionId:Cn(r,n),polygons:i,label:o,labelAnchor:o?_s(i):null})}return t}function Ds(e,t,n,r,i,o,s,a,c){const l=e[0],f=e[1],b=Math.max(1e-6,r.getViewState().zoom),m=Math.max(0,s),w=Ms/b;for(let g=n.length-1;g>=0;g-=1){const S=n[g];for(const _ of S.polygons)if(Us(l,f,_,w))return{region:S.region,regionIndex:S.regionIndex,regionId:S.regionId};let T=zr(i,o?.({region:S.region,regionId:S.regionId,regionIndex:S.regionIndex,zoom:b}));if(m>0&&(T={...T,offsetY:T.offsetY+m}),!!Ns(S,t,r,T,a,c))return{region:S.region,regionIndex:S.regionIndex,regionId:S.regionId}}return null}function ks({source:e,viewState:t,imageColorSettings:n=null,onViewStateChange:r,onStats:i,onTileError:o,onContextLost:s,onContextRestored:a,debugOverlay:c=!1,debugOverlayStyle:l,fitNonce:f=0,rotationResetNonce:b=0,authToken:m="",ctrlDragRotate:w=!0,pointData:g=null,pointPalette:S=null,pointSizeByZoom:T,pointStrokeScale:_,minZoom:B,maxZoom:N,viewTransition:V,roiRegions:F,roiPolygons:X,clipPointsToRois:K=!1,clipMode:ft="worker",onClipStats:mt,onRoiPointGroups:Tt,roiPaletteIndexToTermId:It,interactionLock:Ft=!1,drawTool:rt="cursor",stampOptions:Xt,brushOptions:ae,drawFillColor:ce,regionStrokeStyle:J,regionStrokeHoverStyle:Yt,regionStrokeActiveStyle:qt,patchStrokeStyle:ge,resolveRegionStrokeStyle:St,resolveRegionLabelStyle:ot,overlayShapes:R,customLayers:P,patchRegions:U,regionLabelStyle:Q,drawAreaTooltip:Y,autoLiftRegionLabelAtMaxZoom:st=!1,onPointerWorldMove:gt,onPointHover:H,onPointClick:W,onRegionHover:et,onRegionClick:at,activeRegionId:j,onActiveRegionChange:k,getCellByCoordinatesRef:ht,onDrawComplete:ct,onPatchComplete:G,overviewMapConfig:pt,className:At,style:Ut}){const Nt=pt?.show??!1,Et=pt?.options,bt=d.useRef(null),$=d.useRef(null),Ht=d.useRef(null),z=d.useRef(null),wt=d.useRef(r),it=d.useRef(i),lt=d.useRef(c),[jt,Jt]=d.useState(null),[pe,ve]=d.useState(()=>j??null),ue=j!==void 0,yt=ue?j??null:pe,[_e,u]=d.useState(null),[h,M]=d.useState(null),[A,E]=d.useState(0),D=d.useRef(null),L=d.useRef(null),nt=d.useRef(null),Z=d.useRef(0),O=d.useRef({rafId:null,startMs:0,from:0,to:0}),ut=d.useRef(0),dt=F??wn,Bt=U??wn,xt=X??ds,Mt=(P?.length??0)>0,Wt=d.useMemo(()=>({position:"relative",width:"100%",height:"100%",...Ut}),[Ut]),$t=d.useMemo(()=>({position:"absolute",top:8,left:8,zIndex:7,margin:0,padding:"8px 10px",maxWidth:"min(420px, 80%)",pointerEvents:"none",whiteSpace:"pre-wrap",lineHeight:1.35,fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontSize:11,color:"#cde6ff",background:"rgba(6, 12, 20, 0.82)",border:"1px solid rgba(173, 216, 255, 0.28)",borderRadius:8,boxShadow:"0 8px 22px rgba(0,0,0,0.35)",...l}),[l]),Rt=d.useMemo(()=>dt.length>0?dt:xt.length===0?wn:xt.map((p,x)=>({id:x,coordinates:p})),[dt,xt]),Qt=d.useMemo(()=>zs(Rt),[Rt]),Ln=d.useMemo(()=>_n(Q),[Q]),be=d.useCallback(p=>{const x=me(p,0,Ar);Math.abs(Z.current-x)<1e-4||(Z.current=x,E(x))},[]),le=d.useCallback(()=>{const p=O.current;p.rafId!==null&&(cancelAnimationFrame(p.rafId),p.rafId=null)},[]),sn=d.useCallback(p=>{const x=me(p,0,Ar),C=O.current,I=Z.current;if(Math.abs(I-x)<1e-4){le(),C.to=x,be(x);return}le(),C.startMs=performance.now(),C.from=I,C.to=x;const v=q=>{const Ct=O.current,Zt=Math.max(0,q-Ct.startMs),Se=me(Zt/Ts,0,1),Le=Is(Se),Ne=Ct.from+(Ct.to-Ct.from)*Le;if(be(Ne),Ht.current?.(),Se>=1){Ct.rafId=null,be(Ct.to);return}Ct.rafId=requestAnimationFrame(v)};C.rafId=requestAnimationFrame(v)},[be,le]),te=d.useCallback(p=>{const x=$.current;if(!x||typeof p!="number"||!Number.isFinite(p)){sn(0);return}const C=Br(st,p,x.getZoomRange());sn(C)},[st,sn]),fe=d.useMemo(()=>Rt.map(p=>p.coordinates),[Rt]),[we,Fe]=d.useState(g);d.useEffect(()=>{const p=++ut.current;let x=!1;if(!K)return Fe(g),()=>{x=!0};if(!g||!g.count||!g.positions||!g.paletteIndices)return Fe(null),()=>{x=!0};if(fe.length===0)return Fe(ms),mt?.({mode:ft,durationMs:0,inputCount:g.count,outputCount:0,polygonCount:0}),()=>{x=!0};const C=(v,q)=>{if(x||p!==ut.current)return;const Ct=v?.drawIndices?v.drawIndices.length:v?.count??0;Fe(v),mt?.({mode:q.mode,durationMs:q.durationMs,inputCount:g.count,outputCount:Ct,polygonCount:fe.length,usedWebGpu:q.usedWebGpu,candidateCount:q.candidateCount,bridgedToDraw:q.bridgedToDraw})};return(async()=>{if(ft==="sync"){const v=performance.now(),q=Pe(g,fe);C(q,{mode:"sync",durationMs:performance.now()-v});return}if(ft==="hybrid-webgpu"){const v=await qr(g,fe,{bridgeToDraw:!0});C(v.data,{mode:v.meta.mode,durationMs:v.meta.durationMs,usedWebGpu:v.meta.usedWebGpu,candidateCount:v.meta.candidateCount,bridgedToDraw:v.meta.bridgedToDraw});return}try{const v=await Zr(g,fe);C(v.data,{mode:v.meta.mode,durationMs:v.meta.durationMs})}catch{const v=performance.now(),q=Pe(g,fe);C(q,{mode:"sync",durationMs:performance.now()-v})}})(),()=>{x=!0}},[K,ft,g,fe,mt]);const Nn=!!(H||W||ht),Lt=d.useMemo(()=>Nn?Ps(we,e):null,[Nn,we,e]),he=d.useCallback(p=>{const x=$.current;if(!x||!Lt)return null;const C=Number(p[0]),I=Number(p[1]);if(!Number.isFinite(C)||!Number.isFinite(I))return null;const v=Math.max(1e-6,x.getViewState().zoom),q=x.getPointSizeByZoom(),Zt=Math.max(ps,q*gs)/v;if(!Number.isFinite(Zt)||Zt<=0)return null;const Se=Lt.cellSize,Le=Math.floor(C/Se),Ne=Math.floor(I/Se),ze=Math.max(1,Math.ceil(Zt/Se)),si=Zt*Zt;let De=-1,Wn=si,Vn=0,Gn=0;for(let an=Le-ze;an<=Le+ze;an+=1){const qn=Lt.buckets.get(an);if(qn)for(let cn=Ne-ze;cn<=Ne+ze;cn+=1){const ke=qn.get(cn);if(!(!ke||ke.length===0))for(let un=0;un<ke.length;un+=1){const Oe=ke[un];if(Oe>=Lt.safeCount)continue;const Hn=Lt.positions[Oe*2],$n=Lt.positions[Oe*2+1],Zn=Hn-C,Kn=$n-I,jn=Zn*Zn+Kn*Kn;jn>Wn||(Wn=jn,De=Oe,Vn=Hn,Gn=$n)}}}if(De<0)return null;const ai=Lt.ids?Number(Lt.ids[De]):null;return{index:De,id:ai,coordinate:[C,I],pointCoordinate:[Vn,Gn]}},[Lt]),ye=d.useCallback((p,x)=>{if(!H)return;const C=p?.index??null,I=p?.id??null;L.current===C&&nt.current===I||(L.current=C,nt.current=I,H({index:C,id:I,coordinate:x,pointCoordinate:p?.pointCoordinate??null}))},[H]),Ue=d.useCallback((p,x)=>{if(!W)return;const C=he(p);C&&W({...C,button:x})},[W,he]);d.useEffect(()=>{if(ht)return ht.current=he,()=>{ht.current===he&&(ht.current=null)}},[ht,he]),d.useEffect(()=>{ue&&ve(j??null)},[ue,j]);const ee=d.useCallback(p=>{String(yt)!==String(p)&&(ue||ve(p),k?.(p))},[yt,ue,k]);d.useEffect(()=>{wt.current=r},[r]),d.useEffect(()=>{it.current=i},[i]),d.useEffect(()=>{lt.current=c,c||M(null)},[c]),d.useEffect(()=>()=>{le()},[le]);const zn=d.useCallback(p=>{it.current?.(p),lt.current&&M(p)},[]),ti=d.useMemo(()=>h?[`tier ${h.tier} | frame ${h.frameMs?.toFixed(2)??"-"} ms | drawCalls ${h.drawCalls??"-"}`,`tiles visible ${h.visible} | rendered ${h.rendered} | fallback ${h.fallback}`,`cache size ${h.cache} | hit ${h.cacheHits??"-"} | miss ${h.cacheMisses??"-"}`,`queue inflight ${h.inflight} | queued ${h.queued??"-"} | retries ${h.retries??"-"} | failed ${h.failed??"-"} | aborted ${h.aborted??"-"}`,`points ${h.points}`].join(`
|
|
158
|
-
`):"stats: waiting for first frame...",[h]);d.useEffect(()=>{!(yt===null?!0:Rt.some((I,v)=>String(Cn(I,v))===String(yt)))&&yt!==null&&
|
|
157
|
+
}`),o=Dt(t,i,"uCamera"),s=Dt(t,i,"uPointSize"),a=Dt(t,i,"uPointStrokeScale"),c=Dt(t,i,"uPalette"),l=Dt(t,i,"uPaletteSize"),f=t.createVertexArray(),b=t.createBuffer(),m=t.createBuffer(),w=t.createBuffer(),g=t.createBuffer(),S=t.createTexture();if(!f||!b||!m||!w||!g||!S)throw new Error("point buffer allocation failed");t.bindVertexArray(f),t.bindBuffer(t.ARRAY_BUFFER,b),t.bufferData(t.ARRAY_BUFFER,0,t.DYNAMIC_DRAW);const T=t.getAttribLocation(i,"aPosition");if(T<0)throw new Error("point position attribute not found");t.enableVertexAttribArray(T),t.vertexAttribPointer(T,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,m),t.bufferData(t.ARRAY_BUFFER,0,t.DYNAMIC_DRAW);const _=t.getAttribLocation(i,"aTerm");if(_<0)throw new Error("point term attribute not found");t.enableVertexAttribArray(_),t.vertexAttribIPointer(_,1,t.UNSIGNED_SHORT,0,0),t.bindBuffer(t.ARRAY_BUFFER,w),t.bufferData(t.ARRAY_BUFFER,0,t.DYNAMIC_DRAW);const B=t.getAttribLocation(i,"aFillMode");if(B<0)throw new Error("point fill mode attribute not found");return t.enableVertexAttribArray(B),t.vertexAttribIPointer(B,1,t.UNSIGNED_BYTE,0,0),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,g),t.bufferData(t.ELEMENT_ARRAY_BUFFER,0,t.DYNAMIC_DRAW),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null),t.bindTexture(t.TEXTURE_2D,S),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,1,1,0,t.RGBA,t.UNSIGNED_BYTE,new Uint8Array([160,160,160,255])),t.bindTexture(t.TEXTURE_2D,null),{program:i,vao:f,posBuffer:b,termBuffer:m,fillModeBuffer:w,indexBuffer:g,paletteTexture:S,uCamera:o,uPointSize:s,uPointStrokeScale:a,uPalette:c,uPaletteSize:l}}handleTileLoaded(t,n){if(this.destroyed||this.contextLost||this.gl.isContextLost()){n.close();return}if(this.cache.has(t.key)){n.close();return}const r=this.createTextureFromBitmap(n);n.close(),r&&(this.cache.set(t.key,{key:t.key,texture:r,bounds:t.bounds,tier:t.tier,lastUsed:this.frameSerial}),this.trimCache(),this.requestRender())}createTextureFromBitmap(t){if(this.contextLost||this.gl.isContextLost())return null;const n=this.gl,r=n.createTexture();return r?(n.bindTexture(n.TEXTURE_2D,r),n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL,1),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.LINEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,n.RGBA,n.UNSIGNED_BYTE,t),n.bindTexture(n.TEXTURE_2D,null),r):null}}const wn=[],ds=[],ms={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)},gs=.65,ps=4,bs=24,ws=1024,ys=4,Ms=6,Ss=.5,As=.58,xs=4096,Ts=180,Ar=20;let Je=null;const Qe=new Map;function Es(e){const t=e.fillModes instanceof Uint8Array?e.fillModes.length:Number.MAX_SAFE_INTEGER;return Math.max(0,Math.min(Math.floor(e.count??0),Math.floor((e.positions?.length??0)/2),e.paletteIndices?.length??0,t))}function Rs(e,t){if(!(e instanceof Uint32Array)||t<=0||e.length===0)return null;let n=!1;for(let o=0;o<e.length;o+=1)if(!(e[o]<t)){n=!0;break}if(!n)return e;const r=new Uint32Array(e.length);let i=0;for(let o=0;o<e.length;o+=1){const s=e[o];s>=t||(r[i]=s,i+=1)}return r.subarray(0,i)}function Cs(e,t){if(!e||t<=0)return 256;const n=Math.max(1,e.width*e.height),i=Math.sqrt(n/Math.max(1,t))*ys;return Math.max(bs,Math.min(ws,i))}function Ps(e,t){if(!e||!e.positions||!e.paletteIndices)return null;const n=Es(e);if(n<=0)return null;const r=e.positions.subarray(0,n*2),i=e.ids instanceof Uint32Array&&e.ids.length>=n?e.ids.subarray(0,n):null,o=Rs(e.drawIndices,n),s=o?o.length:n;if(s===0)return null;const a=Cs(t,s),c=new Map,l=f=>{const b=r[f*2],m=r[f*2+1];if(!Number.isFinite(b)||!Number.isFinite(m))return;const w=Math.floor(b/a),g=Math.floor(m/a);let S=c.get(w);S||(S=new Map,c.set(w,S));const T=S.get(g);T?T.push(f):S.set(g,[f])};if(o)for(let f=0;f<o.length;f+=1)l(o[f]??0);else for(let f=0;f<n;f+=1)l(f);return c.size===0?null:{cellSize:a,safeCount:n,positions:r,ids:i,buckets:c}}function Cn(e,t){return e.id??t}function de(e,t,n){return Math.max(t,Math.min(n,e))}function Is(e){const t=de(e,0,1);return t*t*(3-2*t)}function Pn(e){if(!Array.isArray(e)||e.length<2)return null;const t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:[t,n]}function vs(e){if(e.length===0)return null;let t=1/0;for(const i of e)i[1]<t&&(t=i[1]);if(!Number.isFinite(t))return null;let n=1/0,r=-1/0;for(const i of e)Math.abs(i[1]-t)>Ss||(i[0]<n&&(n=i[0]),i[0]>r&&(r=i[0]));return!Number.isFinite(n)||!Number.isFinite(r)?null:[(n+r)*.5,t]}function _s(e){let t=null;for(const n of e){const r=vs(n.outer);r&&(!t||r[1]<t[1]||r[1]===t[1]&&r[0]<t[0])&&(t=r)}return t}function Fs(e,t,n,r,i,o){const s=i-n,a=o-r,c=s*s+a*a;if(c<=1e-12){const g=e-n,S=t-r;return g*g+S*S}const l=de(((e-n)*s+(t-r)*a)/c,0,1),f=n+s*l,b=r+a*l,m=e-f,w=t-b;return m*m+w*w}function xr(e,t,n,r){for(let i=1;i<n.length;i+=1){const o=n[i-1],s=n[i];if(Fs(e,t,o[0],o[1],s[0],s[1])<=r)return!0}return!1}function Us(e,t,n,r){if(e<n.minX-r||e>n.maxX+r||t<n.minY-r||t>n.maxY+r)return!1;const i=r*r;if(xr(e,t,n.outer,i))return!0;for(const o of n.holes)if(xr(e,t,o,i))return!0;return!1}function Bs(){if(Je)return Je;if(typeof document>"u")return null;const t=document.createElement("canvas").getContext("2d");return t?(Je=t,Je):null}function Ls(e,t){const n=`${t.fontWeight}|${t.fontSize}|${t.fontFamily}|${e}`,r=Qe.get(n);if(r!==void 0)return r;const i=e.length*t.fontSize*As,o=Bs();let s=i;if(o){o.font=`${t.fontWeight} ${t.fontSize}px ${t.fontFamily}`;const a=o.measureText(e).width;Number.isFinite(a)&&a>=0&&(s=a)}return Qe.size>xs&&Qe.clear(),Qe.set(n,s),s}function Ns(e,t,n,r,i,o){if(!e.label||!e.labelAnchor)return!1;const s=Pn(n.worldToScreen(e.labelAnchor[0],e.labelAnchor[1]));if(!s)return!1;const c=Ls(e.label,r)+r.paddingX*2,l=r.fontSize+r.paddingY*2,f=de(s[0],c*.5+1,i-c*.5-1),b=de(s[1]-r.offsetY,l*.5+1,o-l*.5-1),m=f-c*.5,w=f+c*.5,g=b-l*.5,S=b+l*.5;return t[0]>=m&&t[0]<=w&&t[1]>=g&&t[1]<=S}function zs(e){const t=[];for(let n=0;n<e.length;n+=1){const r=e[n],i=Ie([r?.coordinates]);if(i.length===0)continue;const o=typeof r?.label=="string"?r.label.trim():"";t.push({region:r,regionIndex:n,regionId:Cn(r,n),polygons:i,label:o,labelAnchor:o?_s(i):null})}return t}function Ds(e,t,n,r,i,o,s,a,c){const l=e[0],f=e[1],b=Math.max(1e-6,r.getViewState().zoom),m=Math.max(0,s),w=Ms/b;for(let g=n.length-1;g>=0;g-=1){const S=n[g];for(const _ of S.polygons)if(Us(l,f,_,w))return{region:S.region,regionIndex:S.regionIndex,regionId:S.regionId};let T=zr(i,o?.({region:S.region,regionId:S.regionId,regionIndex:S.regionIndex,zoom:b}));if(m>0&&(T={...T,offsetY:T.offsetY+m}),!!Ns(S,t,r,T,a,c))return{region:S.region,regionIndex:S.regionIndex,regionId:S.regionId}}return null}function ks({source:e,viewState:t,imageColorSettings:n=null,onViewStateChange:r,onStats:i,onTileError:o,onContextLost:s,onContextRestored:a,debugOverlay:c=!1,debugOverlayStyle:l,fitNonce:f=0,rotationResetNonce:b=0,authToken:m="",ctrlDragRotate:w=!0,pointData:g=null,pointPalette:S=null,pointSizeByZoom:T,pointStrokeScale:_,minZoom:B,maxZoom:N,viewTransition:W,roiRegions:F,roiPolygons:X,clipPointsToRois:Z=!1,clipMode:lt="worker",onClipStats:mt,onRoiPointGroups:Tt,roiPaletteIndexToTermId:It,interactionLock:Ft=!1,drawTool:nt="cursor",stampOptions:Xt,brushOptions:se,drawFillColor:ae,regionStrokeStyle:J,regionStrokeHoverStyle:Yt,regionStrokeActiveStyle:qt,patchStrokeStyle:me,resolveRegionStrokeStyle:St,resolveRegionLabelStyle:it,overlayShapes:C,customLayers:R,patchRegions:U,regionLabelStyle:Q,drawAreaTooltip:Y,autoLiftRegionLabelAtMaxZoom:st=!1,onPointerWorldMove:gt,onPointHover:K,onPointClick:V,onRegionHover:tt,onRegionClick:at,activeRegionId:j,onActiveRegionChange:k,getCellByCoordinatesRef:ft,onDrawComplete:ct,onPatchComplete:G,overviewMapConfig:pt,className:At,style:Lt}){const Nt=pt?.show??!1,Et=pt?.options,bt=d.useRef(null),H=d.useRef(null),Ht=d.useRef(null),z=d.useRef(null),wt=d.useRef(r),ot=d.useRef(i),ht=d.useRef(c),[Ae,jt]=d.useState(null),[ge,ve]=d.useState(()=>j??null),ce=j!==void 0,yt=ce?j??null:ge,[_e,u]=d.useState(null),[h,M]=d.useState(null),[A,E]=d.useState(0),D=d.useRef(null),L=d.useRef(null),et=d.useRef(null),$=d.useRef(0),O=d.useRef({rafId:null,startMs:0,from:0,to:0}),ut=d.useRef(0),dt=F??wn,Ut=U??wn,xt=X??ds,Mt=(R?.length??0)>0,Wt=d.useMemo(()=>({position:"relative",width:"100%",height:"100%",...Lt}),[Lt]),$t=d.useMemo(()=>({position:"absolute",top:8,left:8,zIndex:7,margin:0,padding:"8px 10px",maxWidth:"min(420px, 80%)",pointerEvents:"none",whiteSpace:"pre-wrap",lineHeight:1.35,fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontSize:11,color:"#cde6ff",background:"rgba(6, 12, 20, 0.82)",border:"1px solid rgba(173, 216, 255, 0.28)",borderRadius:8,boxShadow:"0 8px 22px rgba(0,0,0,0.35)",...l}),[l]),Rt=d.useMemo(()=>dt.length>0?dt:xt.length===0?wn:xt.map((p,x)=>({id:x,coordinates:p})),[dt,xt]),Jt=d.useMemo(()=>zs(Rt),[Rt]),Ln=d.useMemo(()=>_n(Q),[Q]),pe=d.useCallback(p=>{const x=de(p,0,Ar);Math.abs($.current-x)<1e-4||($.current=x,E(x))},[]),ue=d.useCallback(()=>{const p=O.current;p.rafId!==null&&(cancelAnimationFrame(p.rafId),p.rafId=null)},[]),sn=d.useCallback(p=>{const x=de(p,0,Ar),P=O.current,I=$.current;if(Math.abs(I-x)<1e-4){ue(),P.to=x,pe(x);return}ue(),P.startMs=performance.now(),P.from=I,P.to=x;const v=q=>{const Ct=O.current,Zt=Math.max(0,q-Ct.startMs),Me=de(Zt/Ts,0,1),Le=Is(Me),Ne=Ct.from+(Ct.to-Ct.from)*Le;if(pe(Ne),Ht.current?.(),Me>=1){Ct.rafId=null,pe(Ct.to);return}Ct.rafId=requestAnimationFrame(v)};P.rafId=requestAnimationFrame(v)},[pe,ue]),Qt=d.useCallback(p=>{const x=H.current;if(!x||typeof p!="number"||!Number.isFinite(p)){sn(0);return}const P=Br(st,p,x.getZoomRange());sn(P)},[st,sn]),le=d.useMemo(()=>Rt.map(p=>p.coordinates),[Rt]),[be,Fe]=d.useState(g);d.useEffect(()=>{const p=++ut.current;let x=!1;if(!Z)return Fe(g),()=>{x=!0};if(!g||!g.count||!g.positions||!g.paletteIndices)return Fe(null),()=>{x=!0};if(le.length===0)return Fe(ms),mt?.({mode:lt,durationMs:0,inputCount:g.count,outputCount:0,polygonCount:0}),()=>{x=!0};const P=(v,q)=>{if(x||p!==ut.current)return;const Ct=v?.drawIndices?v.drawIndices.length:v?.count??0;Fe(v),mt?.({mode:q.mode,durationMs:q.durationMs,inputCount:g.count,outputCount:Ct,polygonCount:le.length,usedWebGpu:q.usedWebGpu,candidateCount:q.candidateCount,bridgedToDraw:q.bridgedToDraw})};return(async()=>{if(lt==="sync"){const v=performance.now(),q=Pe(g,le);P(q,{mode:"sync",durationMs:performance.now()-v});return}if(lt==="hybrid-webgpu"){const v=await qr(g,le,{bridgeToDraw:!0});P(v.data,{mode:v.meta.mode,durationMs:v.meta.durationMs,usedWebGpu:v.meta.usedWebGpu,candidateCount:v.meta.candidateCount,bridgedToDraw:v.meta.bridgedToDraw});return}try{const v=await Zr(g,le);P(v.data,{mode:v.meta.mode,durationMs:v.meta.durationMs})}catch{const v=performance.now(),q=Pe(g,le);P(q,{mode:"sync",durationMs:performance.now()-v})}})(),()=>{x=!0}},[Z,lt,g,le,mt]);const Nn=!!(K||V||ft),Bt=d.useMemo(()=>Nn?Ps(be,e):null,[Nn,be,e]),fe=d.useCallback(p=>{const x=H.current;if(!x||!Bt)return null;const P=Number(p[0]),I=Number(p[1]);if(!Number.isFinite(P)||!Number.isFinite(I))return null;const v=Math.max(1e-6,x.getViewState().zoom),q=x.getPointSizeByZoom(),Zt=Math.max(ps,q*gs)/v;if(!Number.isFinite(Zt)||Zt<=0)return null;const Me=Bt.cellSize,Le=Math.floor(P/Me),Ne=Math.floor(I/Me),ze=Math.max(1,Math.ceil(Zt/Me)),si=Zt*Zt;let De=-1,Wn=si,Vn=0,Gn=0;for(let an=Le-ze;an<=Le+ze;an+=1){const qn=Bt.buckets.get(an);if(qn)for(let cn=Ne-ze;cn<=Ne+ze;cn+=1){const ke=qn.get(cn);if(!(!ke||ke.length===0))for(let un=0;un<ke.length;un+=1){const Oe=ke[un];if(Oe>=Bt.safeCount)continue;const Hn=Bt.positions[Oe*2],$n=Bt.positions[Oe*2+1],Zn=Hn-P,Kn=$n-I,jn=Zn*Zn+Kn*Kn;jn>Wn||(Wn=jn,De=Oe,Vn=Hn,Gn=$n)}}}if(De<0)return null;const ai=Bt.ids?Number(Bt.ids[De]):null;return{index:De,id:ai,coordinate:[P,I],pointCoordinate:[Vn,Gn]}},[Bt]),we=d.useCallback((p,x)=>{if(!K)return;const P=p?.index??null,I=p?.id??null;L.current===P&&et.current===I||(L.current=P,et.current=I,K({index:P,id:I,coordinate:x,pointCoordinate:p?.pointCoordinate??null}))},[K]),Ue=d.useCallback((p,x)=>{if(!V)return;const P=fe(p);P&&V({...P,button:x})},[V,fe]);d.useEffect(()=>{if(ft)return ft.current=fe,()=>{ft.current===fe&&(ft.current=null)}},[ft,fe]),d.useEffect(()=>{ce&&ve(j??null)},[ce,j]);const te=d.useCallback(p=>{String(yt)!==String(p)&&(ce||ve(p),k?.(p))},[yt,ce,k]);d.useEffect(()=>{wt.current=r},[r]),d.useEffect(()=>{ot.current=i},[i]),d.useEffect(()=>{ht.current=c,c||M(null)},[c]),d.useEffect(()=>()=>{ue()},[ue]);const zn=d.useCallback(p=>{ot.current?.(p),ht.current&&M(p)},[]),ti=d.useMemo(()=>h?[`tier ${h.tier} | frame ${h.frameMs?.toFixed(2)??"-"} ms | drawCalls ${h.drawCalls??"-"}`,`tiles visible ${h.visible} | rendered ${h.rendered} | fallback ${h.fallback}`,`cache size ${h.cache} | hit ${h.cacheHits??"-"} | miss ${h.cacheMisses??"-"}`,`queue inflight ${h.inflight} | queued ${h.queued??"-"} | retries ${h.retries??"-"} | failed ${h.failed??"-"} | aborted ${h.aborted??"-"}`,`points ${h.points}`].join(`
|
|
158
|
+
`):"stats: waiting for first frame...",[h]);d.useEffect(()=>{!(yt===null?!0:Rt.some((I,v)=>String(Cn(I,v))===String(yt)))&&yt!==null&&te(null);const x=D.current;!(x===null?!0:Rt.some((I,v)=>String(Cn(I,v))===String(x)))&&x!==null&&(D.current=null,jt(null),tt?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[Rt,yt,tt,te]),d.useEffect(()=>{const p=L.current;p!==null&&(Bt&&p<Bt.safeCount||(L.current=null,et.current=null,K?.({index:null,id:null,coordinate:null,pointCoordinate:null})))},[Bt,K]);const Dn=d.useCallback(p=>{Qt(p.zoom),Mt&&u(p);const x=wt.current;x&&x(p),Ht.current?.(),z.current?.()},[Mt,Qt]);d.useEffect(()=>{const p=H.current;p&&Qt(p.getViewState().zoom)},[Qt,B,N]),d.useEffect(()=>{nt!=="cursor"&&D.current!==null&&(D.current=null,jt(null),tt?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[nt,tt]),d.useEffect(()=>{nt!=="cursor"&&L.current!==null&&(L.current=null,et.current=null,K?.({index:null,id:null,coordinate:null,pointCoordinate:null}))},[nt,K]);const ee=d.useCallback((p,x)=>{const P=H.current;if(!P)return null;const I=P.screenToWorld(p,x);if(!Array.isArray(I)||I.length<2)return null;const v=Number(I[0]),q=Number(I[1]);return!Number.isFinite(v)||!Number.isFinite(q)?null:[v,q]},[]),kn=d.useCallback((p,x)=>{const P=H.current;if(!P)return null;const I=P.worldToScreen(p,x);return Pn(I)},[]),Be=d.useCallback((p,x)=>{const P=bt.current;if(!P)return null;const I=P.getBoundingClientRect();if(!Number.isFinite(I.width)||!Number.isFinite(I.height)||I.width<=0||I.height<=0)return null;const v=p-I.left,q=x-I.top;return!Number.isFinite(v)||!Number.isFinite(q)?null:{screenCoord:[v,q],canvasWidth:Math.max(1,I.width),canvasHeight:Math.max(1,I.height)}},[]),ye=d.useCallback((p,x,P,I)=>{const v=H.current;return v?Ds(p,x,Jt,v,Ln,it,A,P,I):null},[Jt,Ln,it,A]),On=d.useCallback(()=>{H.current?.requestRender(),Ht.current?.(),z.current?.()},[]),Xn=d.useMemo(()=>_e??H.current?.getViewState()??null,[_e]),Yn=d.useMemo(()=>{if(!e)return null;const p=Xn;return p?{source:e,viewState:p,drawTool:nt,interactionLock:Ft,worldToScreen:kn,screenToWorld:ee,requestRedraw:On}:null},[e,Xn,nt,Ft,kn,ee,On]),ei=d.useCallback(p=>{const x=p.target===bt.current,P=ee(p.clientX,p.clientY);if(gt){const Zt=!!P&&P[0]>=0&&P[1]>=0&&!!e&&P[0]<=e.width&&P[1]<=e.height;gt({coordinate:P,clientX:p.clientX,clientY:p.clientY,insideImage:Zt})}if(nt!=="cursor")return;if(!x){we(null,null),D.current!==null&&(D.current=null,jt(null),tt?.({region:null,regionId:null,regionIndex:-1,coordinate:null}));return}if(!P){we(null,null);return}if(K&&we(fe(P),P),!Jt.length)return;const I=Be(p.clientX,p.clientY);if(!I)return;const v=ye(P,I.screenCoord,I.canvasWidth,I.canvasHeight),q=v?.regionId??null,Ct=D.current;String(Ct)!==String(q)&&(D.current=q,jt(q),tt?.({region:v?.region??null,regionId:q,regionIndex:v?.regionIndex??-1,coordinate:P}))},[nt,Jt,ee,tt,gt,e,we,fe,K,Be,ye]),ni=d.useCallback(()=>{gt?.({coordinate:null,clientX:-1,clientY:-1,insideImage:!1}),we(null,null),D.current!==null&&(D.current=null,jt(null),tt?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[tt,gt,we]),ri=d.useCallback(p=>{if(nt!=="cursor"||p.target!==bt.current)return;const x=ee(p.clientX,p.clientY);if(!x)return;if(Ue(x,p.button),!Jt.length){te(null);return}const P=Be(p.clientX,p.clientY);if(!P)return;const I=ye(x,P.screenCoord,P.canvasWidth,P.canvasHeight);if(!I){te(null);return}const v=yt!==null&&String(yt)===String(I.regionId)?null:I.regionId;te(v),at?.({region:I.region,regionId:I.regionId,regionIndex:I.regionIndex,coordinate:x})},[nt,Jt,ee,at,yt,te,Ue,Be,ye]),ii=d.useCallback(p=>{if(nt!=="brush"||se?.clickSelectRoi!==!0||!Jt.length)return!1;const x=H.current,P=bt.current;if(!x||!P)return!1;const I=P.getBoundingClientRect();if(I.width<=0||I.height<=0)return!1;const v=Pn(x.worldToScreen(p[0],p[1]));if(!v)return!1;const q=ye(p,v,I.width,I.height);if(!q)return!1;const Ct=yt!==null&&String(yt)===String(q.regionId)?null:q.regionId;return te(Ct),at?.({region:q.region,regionId:q.regionId,regionIndex:q.regionIndex,coordinate:p}),!0},[nt,se?.clickSelectRoi,Jt,yt,te,at,ye]),oi=d.useCallback(p=>{if(!V||nt!=="cursor"||p.target!==bt.current)return;p.preventDefault();const x=ee(p.clientX,p.clientY);x&&Ue(x,p.button)},[nt,ee,Ue,V]);return d.useEffect(()=>{const p=bt.current;if(!p||!e)return;const x=new Qr(p,e,{onViewStateChange:Dn,onStats:zn,onTileError:o,onContextLost:s,onContextRestored:a,authToken:m,imageColorSettings:n,ctrlDragRotate:w,pointSizeByZoom:T,pointStrokeScale:_,minZoom:B,maxZoom:N,viewTransition:W});return H.current=x,t&&x.setViewState(t),Qt(x.getViewState().zoom),x.setInteractionLock(Ft),Mt&&u(x.getViewState()),()=>{ue(),pe(0),x.destroy(),H.current=null}},[e,zn,o,s,a,m,w,T,_,Dn,Mt,Qt,ue,pe]),d.useEffect(()=>{const p=H.current;!p||!t||p.setViewState(t)},[t]),d.useEffect(()=>{const p=H.current;p&&p.fitToImage()},[f]),d.useEffect(()=>{const p=H.current;p&&p.resetRotation()},[b]),d.useEffect(()=>{const p=H.current;!p||!S||p.setPointPalette(S)},[S]),d.useEffect(()=>{const p=H.current;p&&p.setPointSizeByZoom(T)},[T]),d.useEffect(()=>{const p=H.current;p&&p.setPointStrokeScale(_)},[_]),d.useEffect(()=>{const p=H.current;p&&(p.setZoomRange(B,N),Qt(p.getViewState().zoom))},[B,N,Qt]),d.useEffect(()=>{const p=H.current;p&&p.setViewTransition(W)},[W]),d.useEffect(()=>{const p=H.current;p&&p.setImageColorSettings(n)},[n]),d.useEffect(()=>{const p=H.current;p&&p.setPointData(be)},[be]),d.useEffect(()=>{if(!Tt)return;const x=Kr(Z?be:g,Rt,{paletteIndexToTermId:It,includeEmptyRegions:!0});Tt(x)},[Tt,Z,g,be,Rt,It]),d.useEffect(()=>{const p=H.current;p&&p.setInteractionLock(Ft)},[Ft]),kt.jsxs("div",{className:At,style:Wt,onPointerMove:ei,onPointerLeave:ni,onClick:ri,onContextMenu:oi,children:[kt.jsx("canvas",{ref:bt,className:"wsi-render-canvas",style:{position:"absolute",inset:0,zIndex:1,width:"100%",height:"100%",display:"block",touchAction:"none",cursor:nt==="cursor"&&Ae!==null?"pointer":Ft?"crosshair":"grab"}}),e&&Yn&&Array.isArray(R)&&R.length>0?R.map((p,x)=>kt.jsx("div",{className:p.className,style:{position:"absolute",inset:0,zIndex:p.zIndex??3,pointerEvents:p.pointerEvents??"none",...p.style},children:p.render(Yn)},p.id??x)):null,e?kt.jsx(kr,{tool:nt,enabled:nt!=="cursor",imageWidth:e.width,imageHeight:e.height,imageMpp:e.mpp,imageZoom:e.maxTierZoom,stampOptions:Xt,brushOptions:se,drawFillColor:ae,projectorRef:H,onBrushTap:ii,viewStateSignal:t,persistedRegions:Rt,patchRegions:Ut,regionStrokeStyle:J,regionStrokeHoverStyle:Yt,regionStrokeActiveStyle:qt,patchStrokeStyle:me,resolveRegionStrokeStyle:St,resolveRegionLabelStyle:it,overlayShapes:C,hoveredRegionId:Ae,activeRegionId:yt,regionLabelStyle:Q,drawAreaTooltip:Y,autoLiftRegionLabelAtMaxZoom:st,regionLabelAutoLiftOffsetPx:A,invalidateRef:Ht,onDrawComplete:ct,onPatchComplete:G}):null,c?kt.jsx("pre",{"data-open-plant-debug-overlay":!0,style:$t,children:ti}):null,e&&Nt&&kt.jsx(Xr,{source:e,projectorRef:H,authToken:m,options:Et,invalidateRef:z,className:pt?.className,style:pt?.style})]})}exports.DEFAULT_POINT_COLOR=In;exports.DrawLayer=kr;exports.M1TileRenderer=Tr;exports.OverviewMap=Xr;exports.TileScheduler=jr;exports.TileViewerCanvas=Vo;exports.WsiTileRenderer=Qr;exports.WsiViewerCanvas=ks;exports.buildTermPalette=qi;exports.calcScaleLength=Wi;exports.calcScaleResolution=vn;exports.clamp=rt;exports.closeRing=vt;exports.computeRoiPointGroups=Kr;exports.createCircle=Mn;exports.createRectangle=on;exports.filterPointDataByPolygons=Pe;exports.filterPointDataByPolygonsHybrid=qr;exports.filterPointDataByPolygonsInWorker=Zr;exports.filterPointIndicesByPolygons=Wr;exports.filterPointIndicesByPolygonsInWorker=ts;exports.getWebGpuCapabilities=jo;exports.hexToRgba=vr;exports.isSameViewState=Vi;exports.normalizeImageInfo=Yo;exports.prefilterPointsByBoundsWebGpu=Gr;exports.terminateRoiClipWorker=Qo;exports.toBearerToken=Gi;exports.toTileUrl=Fn;
|
|
159
159
|
//# sourceMappingURL=index.cjs.map
|