open-plant 1.2.7 → 1.2.9

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 CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var lr=Object.defineProperty;var fr=(e,t,n)=>t in e?lr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var w=(e,t,n)=>fr(e,typeof t!="symbol"?t+"":t,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const gt=require("react/jsx-runtime"),d=require("react");var Pe=typeof document<"u"?document.currentScript:null;function pn(e,t,n){const r=e.createShader(t);if(!r)throw new Error("Failed to create shader.");if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS)){const o=e.getShaderInfoLog(r)??"unknown shader error";throw e.deleteShader(r),new Error(o)}return r}function hr(e,t,n){const r=pn(e,e.VERTEX_SHADER,t),i=pn(e,e.FRAGMENT_SHADER,n),o=e.createProgram();if(!o)throw e.deleteShader(r),e.deleteShader(i),new Error("Failed to create program.");if(e.attachShader(o,r),e.attachShader(o,i),e.linkProgram(o),e.deleteShader(r),e.deleteShader(i),!e.getProgramParameter(o,e.LINK_STATUS)){const a=e.getProgramInfoLog(o)??"unknown link error";throw e.deleteProgram(o),new Error(a)}return o}function Ae(e,t,n){const r=e.getUniformLocation(t,n);if(!r)throw new Error(`Failed to get uniform location: ${n}`);return r}function dr(e){const t=e.getContext("webgl2",{alpha:!1,antialias:!1,depth:!1,stencil:!1,preserveDrawingBuffer:!1,powerPreference:"high-performance"});if(!t)throw new Error("WebGL2 is not available.");return t}let mr=class{constructor(){w(this,"viewportWidth",1);w(this,"viewportHeight",1);w(this,"viewState",{offsetX:0,offsetY:0,zoom:1})}setViewport(t,n){this.viewportWidth=Math.max(1,t),this.viewportHeight=Math.max(1,n)}getViewportSize(){return{width:this.viewportWidth,height:this.viewportHeight}}setViewState(t){t.offsetX!==void 0&&(this.viewState.offsetX=t.offsetX),t.offsetY!==void 0&&(this.viewState.offsetY=t.offsetY),t.zoom!==void 0&&(this.viewState.zoom=Math.max(1e-4,t.zoom))}getViewState(){return{...this.viewState}}getMatrix(){const t=this.viewportWidth/this.viewState.zoom,n=this.viewportHeight/this.viewState.zoom,r=2/t,i=-2/n,o=-1-this.viewState.offsetX*r,s=1-this.viewState.offsetY*i;return new Float32Array([r,0,0,0,i,0,o,s,1])}};const gr=`#version 300 es
1
+ "use strict";var xr=Object.defineProperty;var Mr=(t,e,n)=>e in t?xr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var w=(t,e,n)=>Mr(t,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Se=require("react/jsx-runtime"),d=require("react");var Bt=typeof document<"u"?document.currentScript:null;function Tn(t,e,n){const r=t.createShader(e);if(!r)throw new Error("Failed to create shader.");if(t.shaderSource(r,n),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS)){const o=t.getShaderInfoLog(r)??"unknown shader error";throw t.deleteShader(r),new Error(o)}return r}function Tr(t,e,n){const r=Tn(t,t.VERTEX_SHADER,e),i=Tn(t,t.FRAGMENT_SHADER,n),o=t.createProgram();if(!o)throw t.deleteShader(r),t.deleteShader(i),new Error("Failed to create program.");if(t.attachShader(o,r),t.attachShader(o,i),t.linkProgram(o),t.deleteShader(r),t.deleteShader(i),!t.getProgramParameter(o,t.LINK_STATUS)){const a=t.getProgramInfoLog(o)??"unknown link error";throw t.deleteProgram(o),new Error(a)}return o}function Ut(t,e,n){const r=t.getUniformLocation(e,n);if(!r)throw new Error(`Failed to get uniform location: ${n}`);return r}function Rr(t){const e=t.getContext("webgl2",{alpha:!1,antialias:!1,depth:!1,stencil:!1,preserveDrawingBuffer:!1,powerPreference:"high-performance"});if(!e)throw new Error("WebGL2 is not available.");return e}let Er=class{constructor(){w(this,"viewportWidth",1);w(this,"viewportHeight",1);w(this,"viewState",{offsetX:0,offsetY:0,zoom:1})}setViewport(e,n){this.viewportWidth=Math.max(1,e),this.viewportHeight=Math.max(1,n)}getViewportSize(){return{width:this.viewportWidth,height:this.viewportHeight}}setViewState(e){e.offsetX!==void 0&&(this.viewState.offsetX=e.offsetX),e.offsetY!==void 0&&(this.viewState.offsetY=e.offsetY),e.zoom!==void 0&&(this.viewState.zoom=Math.max(1e-4,e.zoom))}getViewState(){return{...this.viewState}}getMatrix(){const e=this.viewportWidth/this.viewState.zoom,n=this.viewportHeight/this.viewState.zoom,r=2/e,i=-2/n,o=-1-this.viewState.offsetX*r,s=1-this.viewState.offsetY*i;return new Float32Array([r,0,0,0,i,0,o,s,1])}};const Pr=`#version 300 es
2
2
  precision highp float;
3
3
 
4
4
  in vec2 aUnit;
@@ -18,7 +18,7 @@ void main() {
18
18
  gl_Position = vec4(clip.xy, 0.0, 1.0);
19
19
  vUv = aUv;
20
20
  }
21
- `,pr=`#version 300 es
21
+ `,Ar=`#version 300 es
22
22
  precision highp float;
23
23
 
24
24
  in vec2 vUv;
@@ -29,7 +29,7 @@ out vec4 outColor;
29
29
  void main() {
30
30
  outColor = texture(uTexture, vUv);
31
31
  }
32
- `;class Un{constructor(t){w(this,"canvas");w(this,"gl");w(this,"camera",new mr);w(this,"imageWidth");w(this,"imageHeight");w(this,"clearColor");w(this,"program");w(this,"vao");w(this,"quadBuffer");w(this,"uCameraLocation");w(this,"uBoundsLocation");w(this,"uTextureLocation");w(this,"resizeObserver");w(this,"tiles",[]);w(this,"frameId",null);w(this,"loadVersion",0);w(this,"destroyed",!1);w(this,"fitted",!1);w(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=dr(this.canvas),this.program=hr(this.gl,gr,pr);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=Ae(this.gl,this.program,"uCamera"),this.uBoundsLocation=Ae(this.gl,this.program,"uBounds"),this.uTextureLocation=Ae(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 br=.1,wr=4e6,yr=4096,xr=64,Bn=1e-6,Sr=24;function Le(e,t,n){return Math.max(t,Math.min(n,e))}function kt(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 Mr(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 Tr(e,t,n){if(t<=Bn||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 kt(r)}function ve(e,t){if(!e.length)return[];let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[a,u]of e)a<n&&(n=a),a>i&&(i=a),u<r&&(r=u),u>o&&(o=u);if(!Number.isFinite(n)||!Number.isFinite(r))return[];const s=Math.max(t,1);return kt([[n-s,r-s],[i+s,r-s],[i+s,o+s],[n-s,o+s]])}function Rr(e,t){let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[a,u]of e)a<n&&(n=a),a>i&&(i=a),u<r&&(r=u),u>o&&(o=u);const s=Math.max(t,1);return[n-s,r-s,i+s,o+s]}function Er(e,t,n){const r=Math.max(br,Number(n.minRasterStep)||0),i=Math.max(32768,Math.floor(n.maxRasterPixels||wr)),o=Math.max(256,Math.floor(n.maxRasterSize||yr)),s=Math.max(.001,e[2]-e[0]),a=Math.max(.001,e[3]-e[1]);let u=Math.max(r,Number.EPSILON),c=3,f=Math.ceil(s/u)+c*2+1,p=Math.ceil(a/u)+c*2+1;for(;(f>o||p>o||f*p>i)&&(u*=1.15,f=Math.ceil(s/u)+c*2+1,p=Math.ceil(a/u)+c*2+1,!(u>Math.max(s,a))););return f=Math.max(8,f),p=Math.max(8,p),{minX:e[0],minY:e[1],step:u,padding:c,width:f,height:p}}function Cr(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 Pr(e,t){return[(e[0]-t.minX)/t.step+t.padding,(e[1]-t.minY)/t.step+t.padding]}function Ar(e,t,n){const r=Cr(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=>Pr(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]>=Sr?1:0;return s}function vr(e,t,n){const r=[],i=t+1,o=(a,u)=>u*i+a,s=(a,u)=>a>=0&&u>=0&&a<t&&u<n&&e[u*t+a]>0;for(let a=0;a<n;a+=1)for(let u=0;u<t;u+=1)s(u,a)&&(s(u,a-1)||r.push({start:o(u,a),end:o(u+1,a),dir:0}),s(u+1,a)||r.push({start:o(u+1,a),end:o(u+1,a+1),dir:1}),s(u,a+1)||r.push({start:o(u+1,a+1),end:o(u,a+1),dir:2}),s(u-1,a)||r.push({start:o(u,a+1),end:o(u,a),dir:3}));return r}function Ir(e,t){const n=(t-e+4)%4;return n===1?0:n===0?1:n===3?2:3}function _r(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,u=o.dir;const c=[o.start,o.end];n[i]=1;let f=0;const p=e.length*3;for(;a!==s&&f<p;){const m=t.get(a);if(!m||m.length===0)break;let b=-1,S=1/0;for(const C of m){if(n[C])continue;const k=e[C],I=Ir(u,k.dir);I<S&&(S=I,b=C)}if(b<0)break;n[b]=1;const M=e[b];a=M.end,u=M.dir,c.push(a),f+=1}c.length>=4&&c[0]===c[c.length-1]&&r.push(c)}return r}function Ur(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 kt(i)}function Br(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 Fr(e,t=1e-9){const n=kt(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],u=(s[0]-o[0])*(a[1]-s[1])-(s[1]-o[1])*(a[0]-s[0]);Math.abs(u)<=t||r.push(s)}return r.push(r[0]),kt(r)}function Lr(e,t,n){const r=n[0]-t[0],i=n[1]-t[1],o=r*r+i*i;if(o<=1e-12){const p=e[0]-t[0],m=e[1]-t[1];return p*p+m*m}const s=Le(((e[0]-t[0])*r+(e[1]-t[1])*i)/o,0,1),a=t[0]+r*s,u=t[1]+i*s,c=e[0]-a,f=e[1]-u;return c*c+f*f}function zr(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,u]=s;if(u-a<=1)continue;let c=0,f=-1;for(let p=a+1;p<u;p+=1){const m=Lr(e[p],e[a],e[u]);m>c&&(c=m,f=p)}f>=0&&c>r&&(n[f]=1,i.push([a,f],[f,u]))}const o=[];for(let s=0;s<e.length;s+=1)n[s]&&o.push(e[s]);return o}function Dr(e,t){const n=kt(e);if(n.length<5||t<=0)return n;const r=n.slice(0,-1),i=zr(r,t);return i.length<3?n:kt(i)}function te(e,t){return t?kt(e.map(([n,r])=>[Le(n,t[0],t[2]),Le(r,t[1],t[3])])):e}function Nr(e,t){const n=Mr(e),r=Math.max(Bn,Number(t.radius)||0);if(n.length===0||!Number.isFinite(r))return[];const i=Math.max(12,Math.floor(t.circleSides||xr));if(n.length===1)return te(Tr(n[0],r,i),t.clipBounds);const o=Rr(n,r),s=Er(o,r,t),a=Ar(n,r,s);if(!a.length)return te(ve(n,r),t.clipBounds);const u=vr(a,s.width,s.height),c=_r(u);if(!c.length)return te(ve(n,r),t.clipBounds);let f=[],p=0;for(const S of c){const M=Ur(S,s.width,s),C=Math.abs(Br(M));C<=p||(p=C,f=M)}if(!f.length)return te(ve(n,r),t.clipBounds);const m=typeof t.simplifyTolerance=="number"&&Number.isFinite(t.simplifyTolerance)?Math.max(0,t.simplifyTolerance):s.step*.2,b=Dr(Fr(f,s.step*.001),m);return te(b,t.clipBounds)}const Ge=[160,160,160,255];function et(e,t,n){return Math.max(t,Math.min(n,e))}function qe(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 kr(e,t,n){let i=100*qe(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 Xr(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 Yr(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 Fn(e){const n=String(e??"").trim().match(/^#?([0-9a-fA-F]{6})$/);if(!n)return[...Ge];const r=Number.parseInt(n[1],16);return[r>>16&255,r>>8&255,r&255,255]}function Wr(e){const t=[[...Ge]],n=new Map;for(const i of e??[]){const o=String(i?.termId??"");!o||n.has(o)||(n.set(o,t.length),t.push(Fn(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 bn(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 Or="rgba(255, 77, 79, 0.16)",Vr=3,Gr=2,Ln=96,qr=1,wn=[],Me=[],yn=1e3,zn=2,Dn=2,$r=4096,Hr=.2,Zr=1.12,Kr=.89,jr=32,Jr="#000000",Qr=.1,ti="#FFCF00",ei="#FF0000",ni=1.5,xn=[2,2],ri=1,ii=.25,oi=4,si=1.5,Dt={color:"#ff4d4f",width:2,lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},ai={color:"#4cc9f0",width:2,lineDash:[10,8],lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},Et={fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontSize:12,fontWeight:500,textColor:"#ffffff",backgroundColor:"rgba(8, 14, 22, 0.88)",borderColor:"rgba(255, 77, 79, 0.85)",borderWidth:1,paddingX:6,paddingY:4,offsetY:10,borderRadius:3};function Jt(e,t,n){return Math.max(t,Math.min(n,e))}function ge(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 ne(e,t){return typeof e!="number"||!Number.isFinite(e)||e<=0?t:e}function ui(e){return{rectangleAreaMm2:ne(e?.rectangleAreaMm2,zn),circleAreaMm2:ne(e?.circleAreaMm2,Dn),rectanglePixelSize:ne(e?.rectanglePixelSize,$r)}}function ci(e,t){return typeof e!="number"||!Number.isFinite(e)?t:Jt(e,0,1)}function li(e){if(!Array.isArray(e))return xn;const t=e.filter(n=>Number.isFinite(n)&&n>=0);return t.length>0?t:xn}function fi(e){return typeof e!="number"||!Number.isFinite(e)?ri:Jt(e,ii,oi)}function hi(e){const t=ne(e?.radius,jr),n=ne(e?.cursorLineWidth,ni),r=fi(e?.edgeDetail);return{radius:t,edgeDetail:r,clickSelectRoi:e?.clickSelectRoi===!0,fillColor:e?.fillColor||Jr,fillOpacity:ci(e?.fillOpacity,Qr),cursorColor:e?.cursorColor||ti,cursorActiveColor:e?.cursorActiveColor||ei,cursorLineWidth:n,cursorLineDash:li(e?.cursorLineDash)}}function di(e){return e*yn*yn}function Sn(e,t){return!e||!Number.isFinite(t)||t<=0?[]:Mt([[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 mi(e,t,n=Ln){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 Mt(r)}function Mt(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 ze(e,t){return!e||!t?[]:Mt([[e[0],e[1]],[t[0],e[1]],[t[0],t[1]],[e[0],t[1]]])}function De(e,t,n=Ln){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 u=a/n*Math.PI*2;s.push([r+Math.cos(u)*o,i+Math.sin(u)*o])}return Mt(s)}function Ne(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 Mn(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 Tn(e){return Array.isArray(e)&&e.length>=4&&Ne(e)>qr}function ke(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 Zt(e,t,n,r=!1,i=!1){t.length!==0&&(e.beginPath(),ke(e,t,r),i&&r&&(e.fillStyle=Or,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(Me),e.shadowColor="rgba(0, 0, 0, 0)",e.shadowBlur=0,e.shadowOffsetX=0,e.shadowOffsetY=0)}function Nn(e){const t=Array.isArray(e?.lineDash)?e.lineDash.filter(s=>Number.isFinite(s)&&s>=0):Me,n=typeof e?.width=="number"&&Number.isFinite(e.width)?Math.max(0,e.width):Dt.width,r=typeof e?.shadowBlur=="number"&&Number.isFinite(e.shadowBlur)?Math.max(0,e.shadowBlur):Dt.shadowBlur,i=typeof e?.shadowOffsetX=="number"&&Number.isFinite(e.shadowOffsetX)?e.shadowOffsetX:Dt.shadowOffsetX,o=typeof e?.shadowOffsetY=="number"&&Number.isFinite(e.shadowOffsetY)?e.shadowOffsetY:Dt.shadowOffsetY;return{color:e?.color||Dt.color,width:n,lineDash:t.length?t:Me,lineJoin:e?.lineJoin||Dt.lineJoin,lineCap:e?.lineCap||Dt.lineCap,shadowColor:e?.shadowColor||Dt.shadowColor,shadowBlur:r,shadowOffsetX:i,shadowOffsetY:o}}function ee(e,t){return t?Nn({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 Rn(e,t){return e==null||t===null||t===void 0?!1:String(e)===String(t)}function gi(e){const t=e[0];return Array.isArray(t)&&Array.isArray(t[0])}function En(e){return typeof e=="number"&&Number.isFinite(e)}function pi(e){return Array.isArray(e)&&e.length>=2&&En(e[0])&&En(e[1])}function bi(e){return Array.isArray(e)&&e.length>=2&&e.every(t=>pi(t))}function kn(e,t){if(!(!Array.isArray(e)||e.length===0)){if(bi(e)){t.push(e.map(([n,r])=>[n,r]));return}for(const n of e)kn(n,t)}}function Cn(e,t){const n=[];kn(e,n);const r=[];for(const i of n){if(i.length<2)continue;const o=t?Mt(i):i;o.length>=(t?4:2)&&r.push(o)}return r}function wi(e,t,n,r){if(!(t.length<4||n.length===0)){e.save(),e.beginPath(),ke(e,t,!0);for(const i of n)i.length<4||ke(e,i,!0);e.fillStyle=r,e.fill("evenodd"),e.restore()}}function yi(e){const t=typeof e?.paddingX=="number"&&Number.isFinite(e.paddingX)?Math.max(0,e.paddingX):Et.paddingX,n=typeof e?.paddingY=="number"&&Number.isFinite(e.paddingY)?Math.max(0,e.paddingY):Et.paddingY,r=typeof e?.fontSize=="number"&&Number.isFinite(e.fontSize)?Math.max(8,e.fontSize):Et.fontSize,i=typeof e?.borderWidth=="number"&&Number.isFinite(e.borderWidth)?Math.max(0,e.borderWidth):Et.borderWidth,o=typeof e?.offsetY=="number"&&Number.isFinite(e.offsetY)?e.offsetY:Et.offsetY,s=typeof e?.borderRadius=="number"&&Number.isFinite(e.borderRadius)?Math.max(0,e.borderRadius):Et.borderRadius;return{fontFamily:e?.fontFamily||Et.fontFamily,fontSize:r,fontWeight:e?.fontWeight||Et.fontWeight,textColor:e?.textColor||Et.textColor,backgroundColor:e?.backgroundColor||Et.backgroundColor,borderColor:e?.borderColor||Et.borderColor,borderWidth:i,paddingX:t,paddingY:n,offsetY:o,borderRadius:s}}function xi(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 Si(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 Mi(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 u=e.measureText(s).width+o.paddingX*2,c=o.fontSize+o.paddingY*2,f=Jt(n[0],u*.5+1,r-u*.5-1),p=Jt(n[1]-o.offsetY,c*.5+1,i-c*.5-1),m=f-u*.5,b=p-c*.5;e.fillStyle=o.backgroundColor,e.strokeStyle=o.borderColor,e.lineWidth=o.borderWidth,xi(e,m,b,u,c,o.borderRadius),e.fill(),o.borderWidth>0&&e.stroke(),e.fillStyle=o.textColor,e.fillText(s,f,p+.5),e.restore()}function Ie(e,t,n){return[Jt(e[0],0,t),Jt(e[1],0,n)]}function Kt(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 Xn({tool:e,imageWidth:t,imageHeight:n,imageMpp:r,imageZoom:i,stampOptions:o,brushOptions:s,projectorRef:a,onBrushTap:u,onDrawComplete:c,onPatchComplete:f,enabled:p,viewStateSignal:m,persistedRegions:b,patchRegions:S,persistedPolygons:M,regionStrokeStyle:C,regionStrokeHoverStyle:k,regionStrokeActiveStyle:I,patchStrokeStyle:P,resolveRegionStrokeStyle:D,overlayShapes:K,hoveredRegionId:ct=null,activeRegionId:it=null,regionLabelStyle:q,invalidateRef:ut,className:Ct,style:Yt}){const Z=d.useRef(null),Pt=d.useRef(!1),Ut=d.useRef(new Map),$t=d.useRef(e),lt=d.useRef({isDrawing:!1,pointerId:null,start:null,current:null,cursor:null,points:[],stampCenter:null}),j=p??e!=="cursor",R=d.useMemo(()=>b&&b.length>0?b:!M||M.length===0?wn:M.map((l,h)=>({id:h,coordinates:l})),[b,M]),_=d.useMemo(()=>S??wn,[S]),E=d.useMemo(()=>Nn(C),[C]),z=d.useMemo(()=>ee(E,k),[E,k]),H=d.useMemo(()=>ee(E,I),[E,I]),J=d.useMemo(()=>ee(ai,P),[P]),ft=d.useMemo(()=>yi(q),[q]),bt=d.useMemo(()=>ui(o),[o]),F=d.useMemo(()=>hi(s),[s]),Tt=d.useMemo(()=>({position:"absolute",inset:0,zIndex:2,width:"100%",height:"100%",display:"block",touchAction:"none",pointerEvents:j?"auto":"none",cursor:j?e==="brush"?"none":"crosshair":"default",...Yt}),[j,e,Yt]),ht=d.useCallback(()=>{const l=Z.current;if(!l)return;const h=l.getBoundingClientRect(),y=Math.max(1,window.devicePixelRatio||1),x=Math.max(1,Math.round(h.width*y)),A=Math.max(1,Math.round(h.height*y));(l.width!==x||l.height!==A)&&(l.width=x,l.height=A)},[]),N=d.useCallback(l=>{const h=a.current;if(!h||l.length===0)return[];const y=new Array(l.length);for(let x=0;x<l.length;x+=1){const A=Kt(h.worldToScreen(l[x][0],l[x][1]));if(!A)return[];y[x]=A}return y},[a]),V=d.useCallback((l,h)=>{if(!Number.isFinite(h)||h<=0)return 0;const y=a.current;if(!y)return 0;const x=Kt(y.worldToScreen(l[0],l[1])),A=Kt(y.worldToScreen(l[0]+h,l[1]));return!x||!A?0:Math.hypot(A[0]-x[0],A[1]-x[1])},[a]),ot=d.useCallback(l=>{if(!Number.isFinite(l)||l<=0)return 0;const h=typeof r=="number"&&Number.isFinite(r)&&r>0?r:1,y=typeof i=="number"&&Number.isFinite(i)?i:0,x=a.current?.getViewState?.().zoom,A=typeof x=="number"&&Number.isFinite(x)&&x>0?x:1,v=y+Math.log2(A),X=Math.max(1e-9,qe(h,y,v));return l/X/A},[r,i,a]),Q=d.useCallback((l,h)=>{if(!h)return[];let y=0;if(l==="stamp-rectangle-4096px"){const v=bt.rectanglePixelSize*.5;return Sn(h,v).map(W=>Ie(W,t,n))}if(l==="stamp-rectangle"||l==="stamp-rectangle-2mm2"?y=l==="stamp-rectangle-2mm2"?zn:bt.rectangleAreaMm2:(l==="stamp-circle"||l==="stamp-circle-2mm2"||l==="stamp-circle-hpf-0.2mm2")&&(y=l==="stamp-circle-hpf-0.2mm2"?Hr:l==="stamp-circle-2mm2"?Dn:bt.circleAreaMm2),!Number.isFinite(y)||y<=0)return[];const x=di(y);let A=[];if(l==="stamp-rectangle"||l==="stamp-rectangle-2mm2"){const v=ot(Math.sqrt(x)*.5);A=Sn(h,v)}else if(l==="stamp-circle"||l==="stamp-circle-2mm2"||l==="stamp-circle-hpf-0.2mm2"){const v=ot(Math.sqrt(x/Math.PI));A=mi(h,v)}return A.length?A.map(v=>Ie(v,t,n)):[]},[ot,t,n,bt]),tt=d.useCallback(()=>{const l=lt.current;return ge(e)?Q(e,l.stampCenter):e==="brush"?[]:l.isDrawing?e==="freehand"?l.points:e==="rectangle"?ze(l.start,l.current):e==="circular"?De(l.start,l.current):[]:[]},[e,Q]),G=d.useCallback(l=>{const h=lt.current;if(!h.isDrawing||h.points.length===0)return;const y=N(h.points);if(y.length===0)return;const x=h.points[h.points.length-1]??h.points[0],A=V(x,F.radius);if(!(!Number.isFinite(A)||A<=0)){if(l.save(),l.globalAlpha=F.fillOpacity,l.fillStyle=F.fillColor,l.strokeStyle=F.fillColor,l.lineCap="round",l.lineJoin="round",l.lineWidth=A*2,y.length===1)l.beginPath(),l.arc(y[0][0],y[0][1],A,0,Math.PI*2),l.fill();else{l.beginPath(),l.moveTo(y[0][0],y[0][1]);for(let v=1;v<y.length;v+=1)l.lineTo(y[v][0],y[v][1]);l.stroke()}l.restore()}},[N,V,F]),At=d.useCallback(l=>{const h=lt.current,y=h.cursor;if(!y)return;const x=Kt(a.current?.worldToScreen(y[0],y[1])??[]);if(!x)return;const A=V(y,F.radius);!Number.isFinite(A)||A<=0||(l.save(),l.beginPath(),l.arc(x[0],x[1],A,0,Math.PI*2),l.strokeStyle=h.isDrawing?F.cursorActiveColor:F.cursorColor,l.lineWidth=F.cursorLineWidth,l.setLineDash(F.cursorLineDash),l.stroke(),l.setLineDash(Me),l.restore())},[a,V,F]),vt=d.useCallback(()=>{ht();const l=Z.current;if(!l)return;const h=l.getContext("2d");if(!h)return;const y=Math.max(1,window.devicePixelRatio||1),x=l.width/y,A=l.height/y;if(h.setTransform(1,0,0,1,0,0),h.clearRect(0,0,l.width,l.height),h.setTransform(y,0,0,y,0,0),R.length>0)for(let v=0;v<R.length;v+=1){const X=R[v],W=X?.coordinates;if(!W||W.length<3)continue;const Y=Mt(W),at=N(Y);if(at.length>=4){const Rt=X.id??v,Vt=Rn(it,Rt)?"active":Rn(ct,Rt)?"hover":"default";let wt=Vt==="active"?H:Vt==="hover"?z:E;if(D){const $=D({region:X,regionId:Rt,regionIndex:v,state:Vt});wt=ee(wt,$||void 0)}Zt(h,at,wt,!0,!1)}}if(_.length>0)for(let v=0;v<_.length;v+=1){const W=_[v]?.coordinates;if(!W||W.length<3)continue;const Y=Mt(W),at=N(Y);at.length<4||Zt(h,at,J,!0,!1)}if(Array.isArray(K)&&K.length>0){const v=!!globalThis.__OPEN_PLANT_DEBUG_OVERLAY__,X=N(Mt([[0,0],[t,0],[t,n],[0,n]]));for(let W=0;W<K.length;W+=1){const Y=K[W];if(!Y?.coordinates?.length||Y.visible===!1)continue;const at=Y.closed??gi(Y.coordinates),Rt=Cn(Y.coordinates,at);if(Y.invertedFill?.fillColor){const wt=[],$=Cn(Y.coordinates,!0);for(const yt of $){const xt=N(yt);xt.length>=4&&wt.push(xt)}if(v){const yt=String(Y.id??W),xt=`${X.length}|${$.length}|${wt.length}|${Y.invertedFill.fillColor}`;Ut.current.get(yt)!==xt&&(Ut.current.set(yt,xt),console.debug("[open-plant] invertedFill",{id:Y.id??W,outerRingPoints:X.length,sourceRingCount:$.length,holeRingCount:wt.length,fillColor:Y.invertedFill.fillColor}))}wi(h,X,wt,Y.invertedFill.fillColor)}if(Rt.length===0)continue;const Vt=ee(E,Y.stroke??Y.strokeStyle);for(const wt of Rt){const $=N(wt);$.length<2||Zt(h,$,Vt,at,Y.fill??!1)}}}if(j)if(e==="brush")G(h),At(h);else{const v=tt();if(v.length>0)if(e==="freehand"){const X=N(v);X.length>=2&&Zt(h,X,E,!1,!1),X.length>=3&&Zt(h,N(Mt(v)),E,!0,!0)}else{const X=N(v);X.length>=4&&Zt(h,X,E,!0,!0)}}if(R.length>0)for(const v of R){if(!v.label)continue;const X=v?.coordinates;if(!X||X.length<3)continue;const W=Mt(X),Y=Si(W);if(!Y)continue;const at=Kt(a.current?.worldToScreen(Y[0],Y[1])??[]);at&&Mi(h,v.label,at,x,A,ft)}},[j,e,tt,G,At,ht,N,t,n,a,R,K,ct,it,E,z,H,_,J,D,ft]),B=d.useCallback(()=>{Pt.current||(Pt.current=!0,requestAnimationFrame(()=>{Pt.current=!1,vt()}))},[vt]),st=d.useCallback((l=!1)=>{const h=lt.current,y=Z.current;if(y&&h.pointerId!==null&&y.hasPointerCapture(h.pointerId))try{y.releasePointerCapture(h.pointerId)}catch{}h.isDrawing=!1,h.pointerId=null,h.start=null,h.current=null,h.points=[],h.stampCenter=null,l||(h.cursor=null)},[]),nt=d.useCallback(l=>{const h=a.current;if(!h||t<=0||n<=0)return null;const y=Kt(h.screenToWorld(l.clientX,l.clientY));return y?Ie(y,t,n):null},[a,t,n]),Wt=d.useCallback(()=>{const l=lt.current;if(!l.isDrawing){st(!0),B();return}let h=[];if(e==="freehand")l.points.length>=Vr&&(h=Mt(l.points));else if(e==="rectangle")h=ze(l.start,l.current);else if(e==="circular")h=De(l.start,l.current);else if(e==="brush"){const y=l.points[l.points.length-1]??l.current??l.start;if(F.clickSelectRoi&&y&&l.points.length<=1&&u?.(y)){st(!0),B();return}const x=Math.max(1e-6,a.current?.getViewState?.().zoom??1),A=F.edgeDetail,v=.75/(x*A);h=Nr(l.points,{radius:F.radius,clipBounds:[0,0,t,n],minRasterStep:v,circleSides:Math.max(24,Math.round(64*A)),simplifyTolerance:v*.4})}(e==="freehand"||e==="rectangle"||e==="circular"||e==="brush")&&Tn(h)&&c&&c({tool:e,intent:e==="brush"?"brush":"roi",coordinates:h,bbox:Mn(h),areaPx:Ne(h)}),st(!0),B()},[e,c,st,B,F.radius,F.edgeDetail,F.clickSelectRoi,t,n,a,u]),It=d.useCallback((l,h)=>{const y=Q(l,h);if(!Tn(y))return;const x=l==="stamp-rectangle-4096px"?"patch":"roi",A={tool:l,intent:x,coordinates:y,bbox:Mn(y),areaPx:Ne(y)};c?.(A),x==="patch"&&f&&f(A)},[Q,c,f]),_t=d.useCallback((l,h)=>{const y=a.current,x=Math.max(1e-6,y?.getViewState?.().zoom??1),A=si/x,v=A*A,X=l.points[l.points.length-1];if(!X){l.points.push(h),l.current=h;return}const W=h[0]-X[0],Y=h[1]-X[1];W*W+Y*Y>=v?l.points.push(h):l.points[l.points.length-1]=h,l.current=h},[a]),Ot=d.useCallback(l=>{if(!j||e==="cursor"||l.button!==0)return;const h=nt(l);if(!h)return;if(l.preventDefault(),l.stopPropagation(),ge(e)){const A=lt.current;A.stampCenter=h,It(e,h),B();return}const y=Z.current;y&&y.setPointerCapture(l.pointerId);const x=lt.current;x.isDrawing=!0,x.pointerId=l.pointerId,x.start=h,x.current=h,x.cursor=h,x.points=e==="freehand"||e==="brush"?[h]:[],B()},[j,e,nt,It,B]),dt=d.useCallback(l=>{if(!j||e==="cursor")return;const h=nt(l);if(!h)return;if(ge(e)){const x=lt.current;x.stampCenter=h,l.preventDefault(),l.stopPropagation(),B();return}const y=lt.current;if(e==="brush"){if(y.cursor=h,!y.isDrawing||y.pointerId!==l.pointerId){B();return}l.preventDefault(),l.stopPropagation(),_t(y,h),B();return}if(!(!y.isDrawing||y.pointerId!==l.pointerId)){if(l.preventDefault(),l.stopPropagation(),e==="freehand"){const x=a.current,A=Math.max(1e-6,x?.getViewState?.().zoom??1),v=Gr/A,X=v*v,W=y.points[y.points.length-1];if(!W)y.points.push(h);else{const Y=h[0]-W[0],at=h[1]-W[1];Y*Y+at*at>=X&&y.points.push(h)}}else y.current=h;B()}},[j,e,nt,B,a,_t]),oe=d.useCallback(l=>{const h=lt.current;if(!h.isDrawing||h.pointerId!==l.pointerId)return;l.preventDefault(),l.stopPropagation();const y=nt(l);y&&(h.cursor=y,e==="brush"?_t(h,y):h.current=y);const x=Z.current;if(x&&x.hasPointerCapture(l.pointerId))try{x.releasePointerCapture(l.pointerId)}catch{}Wt()},[Wt,nt,e,_t]),se=d.useCallback(()=>{const l=lt.current;let h=!1;e==="brush"&&!l.isDrawing&&l.cursor&&(l.cursor=null,h=!0),ge(e)&&l.stampCenter&&(l.stampCenter=null,h=!0),h&&B()},[e,B]);return d.useEffect(()=>{ht(),B();const l=Z.current;if(!l)return;const h=new ResizeObserver(()=>{ht(),B()});return h.observe(l),()=>{h.disconnect()}},[ht,B]),d.useEffect(()=>{j||st(),B()},[j,B,st]),d.useEffect(()=>{$t.current!==e&&($t.current=e,st(),B())},[e,st,B]),d.useEffect(()=>{B()},[m,R,K,B]),d.useEffect(()=>{if(ut)return ut.current=B,()=>{ut.current===B&&(ut.current=null)}},[ut,B]),d.useEffect(()=>{if(!j)return;const l=h=>{h.key==="Escape"&&(st(),B())};return window.addEventListener("keydown",l),()=>{window.removeEventListener("keydown",l)}},[j,st,B]),gt.jsx("canvas",{ref:Z,className:Ct,style:Tt,onPointerDown:Ot,onPointerMove:dt,onPointerUp:oe,onPointerCancel:oe,onPointerLeave:se,onContextMenu:l=>{j&&l.preventDefault()},onWheel:l=>{if(!j)return;const h=Z.current,y=a.current;if(!h||typeof y?.zoomBy!="function")return;l.preventDefault(),l.stopPropagation();const x=h.getBoundingClientRect(),A=l.clientX-x.left,v=l.clientY-x.top;y.zoomBy(l.deltaY<0?Zr:Kr,A,v),B()}})}function Pn(e){return String(e??"").replace(/\/+$/,"")}function Yn(e){const t=String(e??"");return t.startsWith("/")?t:`/${t}`}function Ti(e){const t=Pn(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=Pn(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 Ri(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),u=String(n.path??e?.path??""),c=Number(n.mpp??e?.mpp??0);if(!i||!o||!s||!u)throw new Error("이미지 메타데이터가 불완전합니다. width/height/tileSize/path 확인 필요");const f=Array.isArray(e?.terms)?e.terms.map(S=>({termId:String(S?.termId??""),termName:String(S?.termName??""),termColor:String(S?.termColor??"")})):[],p=Yn(u),m=Ti(t),b=r?(S,M,C)=>`${m}${p}/${S}/${C}_${M}.webp`:void 0;return{id:e?._id||"unknown",name:e?.name||"unknown",width:i,height:o,mpp:Number.isFinite(c)&&c>0?c:void 0,tileSize:s,maxTierZoom:Number.isFinite(a)?Math.max(0,Math.floor(a)):0,tilePath:u,tileBaseUrl:t,terms:f,tileUrlBuilder:b}}function $e(e,t,n,r){if(e.tileUrlBuilder)return e.tileUrlBuilder(t,n,r);const i=Yn(e.tilePath);return`${e.tileBaseUrl}${i}/${t}/${r}_${n}.webp`}const mt={width:220,height:140,margin:16,position:"bottom-right",borderRadius:10,borderWidth:1.5,backgroundColor:"rgba(4, 10, 18, 0.88)",borderColor:"rgba(230, 244, 255, 0.35)",viewportStrokeColor:"rgba(255, 106, 61, 0.95)",viewportFillColor:"rgba(255, 106, 61, 0.2)",interactive:!0,showThumbnail:!0,maxThumbnailTiles:16};function jt(e,t,n=1){return typeof e!="number"||!Number.isFinite(e)?t:Math.max(n,e)}function pe(e){return Array.isArray(e)&&e.length===4&&Number.isFinite(e[0])&&Number.isFinite(e[1])&&Number.isFinite(e[2])&&Number.isFinite(e[3])}function Wn({source:e,projectorRef:t,authToken:n="",options:r,invalidateRef:i,className:o,style:s}){const a=d.useRef(null),u=d.useRef(null),c=d.useRef(null),f=d.useRef({active:!1,pointerId:null}),p=d.useRef(null),m=d.useRef(!1),b=jt(r?.width,mt.width,64),S=jt(r?.height,mt.height,48),M=jt(r?.margin,mt.margin,0),C=jt(r?.borderRadius,mt.borderRadius,0),k=jt(r?.borderWidth,mt.borderWidth,0),I=Math.max(1,Math.round(jt(r?.maxThumbnailTiles,mt.maxThumbnailTiles,1))),P=r?.backgroundColor||mt.backgroundColor,D=r?.borderColor||mt.borderColor,K=r?.viewportStrokeColor||mt.viewportStrokeColor,ct=r?.viewportFillColor||mt.viewportFillColor,it=r?.interactive??mt.interactive,q=r?.showThumbnail??mt.showThumbnail,ut=r?.position||mt.position,Ct=d.useMemo(()=>{const R={};return ut==="top-left"||ut==="bottom-left"?R.left=M:R.right=M,ut==="top-left"||ut==="top-right"?R.top=M:R.bottom=M,{position:"absolute",...R,width:b,height:S,borderRadius:C,overflow:"hidden",zIndex:4,pointerEvents:it?"auto":"none",touchAction:"none",boxShadow:"0 10px 22px rgba(0, 0, 0, 0.3)",...s}},[M,ut,b,S,C,it,s]),Yt=d.useCallback(()=>{const R=a.current;if(!R)return;const _=R.getContext("2d");if(!_)return;const E=b,z=S,H=Math.max(1,window.devicePixelRatio||1),J=Math.max(1,Math.round(E*H)),ft=Math.max(1,Math.round(z*H));(R.width!==J||R.height!==ft)&&(R.width=J,R.height=ft),_.setTransform(1,0,0,1,0,0),_.clearRect(0,0,R.width,R.height),_.setTransform(H,0,0,H,0,0),_.fillStyle=P,_.fillRect(0,0,E,z);const bt=u.current;bt&&_.drawImage(bt,0,0,E,z),_.strokeStyle=D,_.lineWidth=k,_.strokeRect(k*.5,k*.5,E-k,z-k);const F=t.current,Tt=F?.getViewBounds?.(),ht=F?.getViewCorners?.(),N=pe(Tt)?Tt:pe(c.current)?c.current:null;if(!N)return;c.current=N;const V=E/Math.max(1,e.width),ot=z/Math.max(1,e.height),Q=Array.isArray(ht)&&ht.length>=4&&ht.every(nt=>Array.isArray(nt)&&nt.length>=2&&Number.isFinite(nt[0])&&Number.isFinite(nt[1]))?ht:null;if(Q){_.beginPath();for(let nt=0;nt<Q.length;nt+=1){const Wt=Q[nt],It=et(Wt[0]*V,0,E),_t=et(Wt[1]*ot,0,z);nt===0?_.moveTo(It,_t):_.lineTo(It,_t)}_.closePath(),_.fillStyle=ct,_.fill(),_.strokeStyle=K,_.lineWidth=1.5,_.stroke();return}const tt=et(N[0]*V,0,E),G=et(N[1]*ot,0,z),At=et(N[2]*V,0,E),vt=et(N[3]*ot,0,z),B=Math.max(1,At-tt),st=Math.max(1,vt-G);_.fillStyle=ct,_.fillRect(tt,G,B,st),_.strokeStyle=K,_.lineWidth=1.5,_.strokeRect(tt+.5,G+.5,Math.max(1,B-1),Math.max(1,st-1))},[b,S,P,D,k,t,e.width,e.height,ct,K]),Z=d.useCallback(()=>{m.current||(m.current=!0,p.current=requestAnimationFrame(()=>{m.current=!1,p.current=null,Yt()}))},[Yt]),Pt=d.useCallback((R,_)=>{const E=a.current;if(!E)return null;const z=E.getBoundingClientRect();if(!z.width||!z.height)return null;const H=et((R-z.left)/z.width,0,1),J=et((_-z.top)/z.height,0,1);return[H*e.width,J*e.height]},[e.width,e.height]),Ut=d.useCallback((R,_)=>{const E=t.current;if(!E)return;if(E.setViewCenter){E.setViewCenter(R,_),Z();return}const z=E.getViewBounds?.(),H=pe(z)?z:pe(c.current)?c.current:null;if(!H)return;const J=Math.max(1e-6,H[2]-H[0]),ft=Math.max(1e-6,H[3]-H[1]);E.setViewState({offsetX:R-J*.5,offsetY:_-ft*.5}),Z()},[t,Z]),$t=d.useCallback(R=>{if(!it||R.button!==0)return;const _=a.current;if(!_)return;const E=Pt(R.clientX,R.clientY);E&&(R.preventDefault(),R.stopPropagation(),_.setPointerCapture(R.pointerId),f.current={active:!0,pointerId:R.pointerId},Ut(E[0],E[1]))},[it,Pt,Ut]),lt=d.useCallback(R=>{const _=f.current;if(!_.active||_.pointerId!==R.pointerId)return;const E=Pt(R.clientX,R.clientY);E&&(R.preventDefault(),R.stopPropagation(),Ut(E[0],E[1]))},[Pt,Ut]),j=d.useCallback(R=>{const _=f.current;if(!_.active||_.pointerId!==R.pointerId)return;const E=a.current;if(E&&E.hasPointerCapture(R.pointerId))try{E.releasePointerCapture(R.pointerId)}catch{}f.current={active:!1,pointerId:null},Z()},[Z]);return d.useEffect(()=>{let R=!1;u.current=null,Z();const _=0,E=2**(e.maxTierZoom-_),z=Math.ceil(e.width/E),H=Math.ceil(e.height/E),J=Math.max(1,Math.ceil(z/e.tileSize)),ft=Math.max(1,Math.ceil(H/e.tileSize)),bt=J*ft;if(!q||bt>I)return;const F=document.createElement("canvas");F.width=Math.max(1,Math.round(b)),F.height=Math.max(1,Math.round(S));const Tt=F.getContext("2d");if(!Tt)return;Tt.fillStyle=P,Tt.fillRect(0,0,F.width,F.height);const ht=[];for(let N=0;N<ft;N+=1)for(let V=0;V<J;V+=1){const ot=V*e.tileSize*E,Q=N*e.tileSize*E,tt=Math.min((V+1)*e.tileSize,z)*E,G=Math.min((N+1)*e.tileSize,H)*E;ht.push({url:$e(e,_,V,N),bounds:[ot,Q,tt,G]})}return Promise.allSettled(ht.map(async N=>{const V=!!n,ot=await fetch(N.url,{headers:V?{Authorization:n}:void 0});if(!ot.ok)throw new Error(`HTTP ${ot.status}`);const Q=await createImageBitmap(await ot.blob());return{tile:N,bitmap:Q}})).then(N=>{if(R){for(const Q of N)Q.status==="fulfilled"&&Q.value.bitmap.close();return}const V=F.width/Math.max(1,e.width),ot=F.height/Math.max(1,e.height);for(const Q of N){if(Q.status!=="fulfilled")continue;const{tile:{bounds:tt},bitmap:G}=Q.value,At=tt[0]*V,vt=tt[1]*ot,B=Math.max(1,(tt[2]-tt[0])*V),st=Math.max(1,(tt[3]-tt[1])*ot);Tt.drawImage(G,At,vt,B,st),G.close()}u.current=F,Z()}),()=>{R=!0}},[e,n,b,S,P,q,I,Z]),d.useEffect(()=>{Z()},[Z]),d.useEffect(()=>{if(i)return i.current=Z,()=>{i.current===Z&&(i.current=null)}},[i,Z]),d.useEffect(()=>()=>{f.current={active:!1,pointerId:null},p.current!==null&&(cancelAnimationFrame(p.current),p.current=null),m.current=!1},[]),gt.jsx("canvas",{ref:a,className:o,style:Ct,onPointerDown:$t,onPointerMove:lt,onPointerUp:j,onPointerCancel:j,onContextMenu:R=>{R.preventDefault()},onWheel:R=>{R.preventDefault(),R.stopPropagation()}})}function Ei({imageWidth:e,imageHeight:t,tiles:n,viewState:r,className:i,style:o}){const s=d.useRef(null),a=d.useRef(null),u=d.useMemo(()=>({width:"100%",height:"100%",display:"block",...o}),[o]);return d.useEffect(()=>{const c=s.current;if(!c)return;const f=new Un({canvas:c,imageWidth:e,imageHeight:t,initialViewState:r});return a.current=f,f.setTiles(n),()=>{f.destroy(),a.current=null}},[e,t]),d.useEffect(()=>{const c=a.current;c&&c.setTiles(n)},[n]),d.useEffect(()=>{const c=a.current;!c||!r||c.setViewState(r)},[r]),gt.jsx("canvas",{ref:s,className:i,style:u})}function On(e){return Math.max(0,Math.min(Math.floor(e.count??0),Math.floor((e.positions?.length??0)/2),e.paletteIndices?.length??0))}function Ci(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 Vn(e){const t=[];for(const n of e??[]){const r=Ci(n);if(r.length<4)continue;let i=1/0,o=1/0,s=-1/0,a=-1/0;for(const[u,c]of r)u<i&&(i=u),u>s&&(s=u),c<o&&(o=c),c>a&&(a=c);!Number.isFinite(i)||!Number.isFinite(o)||t.push({ring:r,minX:i,minY:o,maxX:s,maxY:a})}return t}function Pi(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],u=n[o][0],c=n[o][1];a>t!=c>t&&e<(u-s)*(t-a)/(c-a||Number.EPSILON)+s&&(r=!r)}return r}function Gn(e,t,n){for(const r of n)if(!(e<r.minX||e>r.maxX||t<r.minY||t>r.maxY)&&Pi(e,t,r.ring))return!0;return!1}function ie(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return null;const n=Vn(t??[]);if(n.length===0)return{count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};const r=On(e),i=e.positions,o=e.paletteIndices,s=e.ids instanceof Uint32Array&&e.ids.length>=r?e.ids:null,a=new Float32Array(r*2),u=new Uint16Array(r),c=s?new Uint32Array(r):null;let f=0;for(let m=0;m<r;m+=1){const b=i[m*2],S=i[m*2+1];Gn(b,S,n)&&(a[f*2]=b,a[f*2+1]=S,u[f]=o[m],c&&(c[f]=s[m]),f+=1)}const p={count:f,positions:a.subarray(0,f*2),paletteIndices:u.subarray(0,f)};return c&&(p.ids=c.subarray(0,f)),p}function qn(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return new Uint32Array(0);const n=Vn(t??[]);if(n.length===0)return new Uint32Array(0);const r=On(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 u=i[a*2],c=i[a*2+1];Gn(u,c,n)&&(o[s]=a,s+=1)}return o.subarray(0,s)}let be=null;const Ai=`
32
+ `;class On{constructor(e){w(this,"canvas");w(this,"gl");w(this,"camera",new Er);w(this,"imageWidth");w(this,"imageHeight");w(this,"clearColor");w(this,"program");w(this,"vao");w(this,"quadBuffer");w(this,"uCameraLocation");w(this,"uBoundsLocation");w(this,"uTextureLocation");w(this,"resizeObserver");w(this,"tiles",[]);w(this,"frameId",null);w(this,"loadVersion",0);w(this,"destroyed",!1);w(this,"fitted",!1);w(this,"controlledViewState",!1);this.canvas=e.canvas,this.imageWidth=Math.max(1,e.imageWidth),this.imageHeight=Math.max(1,e.imageHeight),this.clearColor=e.clearColor??[.03,.05,.08,1],this.gl=Rr(this.canvas),this.program=Tr(this.gl,Pr,Ar);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=Ut(this.gl,this.program,"uCamera"),this.uBoundsLocation=Ut(this.gl,this.program,"uBounds"),this.uTextureLocation=Ut(this.gl,this.program,"uTexture"),e.initialViewState&&(this.controlledViewState=!0,this.camera.setViewState(e.initialViewState)),this.resizeObserver=new ResizeObserver(()=>{this.resize()}),this.resizeObserver.observe(this.canvas),this.resize()}async setTiles(e){if(this.destroyed)return;const n=++this.loadVersion,r=await Promise.all(e.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(e){this.controlledViewState=!0,this.camera.setViewState(e),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(e,n){try{const r=await fetch(e.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:e.id,bounds:e.bounds,texture:s}}catch(r){return console.error(`[M1TileRenderer] tile load failed: ${e.id}`,r),null}}resize(){if(this.destroyed)return;const e=this.canvas.getBoundingClientRect(),n=Math.max(1,e.width||this.canvas.clientWidth||1),r=Math.max(1,e.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 e=this.camera.getViewportSize(),n=Math.min(e.width/this.imageWidth,e.height/this.imageHeight),r=Number.isFinite(n)&&n>0?n:1,i=e.width/r,o=e.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 e of this.tiles)this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,e.texture),this.gl.uniform4f(this.uBoundsLocation,e.bounds[0],e.bounds[1],e.bounds[2],e.bounds[3]),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4);this.gl.bindTexture(this.gl.TEXTURE_2D,null),this.gl.bindVertexArray(null)}}disposeTiles(e){for(const n of e)this.gl.deleteTexture(n.texture)}}const Cr=.1,vr=4e6,Ir=4096,_r=64,Br=1,Ur=4,Yn=1e-6,Fr=24;function Rt(t,e,n){return Math.max(e,Math.min(n,t))}function _e(t){if(!Array.isArray(t)||t.length<3)return[];const e=t.map(([i,o])=>[i,o]),n=e[0],r=e[e.length-1];return!n||!r?[]:((n[0]!==r[0]||n[1]!==r[1])&&e.push([n[0],n[1]]),e)}function Lr(t){if(!Array.isArray(t)||t.length===0)return[];const e=[];for(const n of t){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=e[e.length-1];o&&Math.abs(o[0]-r)<1e-9&&Math.abs(o[1]-i)<1e-9||e.push([r,i])}return e}function zr(t,e,n){if(e<=Yn||n<8)return[];const r=[];for(let i=0;i<=n;i+=1){const o=i/n*Math.PI*2;r.push([t[0]+Math.cos(o)*e,t[1]+Math.sin(o)*e])}return _e(r)}function Ft(t,e){if(!t.length)return[];let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[a,c]of t)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(e,1);return _e([[n-s,r-s],[i+s,r-s],[i+s,o+s],[n-s,o+s]])}function kr(t,e){let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[a,c]of t)a<n&&(n=a),a>i&&(i=a),c<r&&(r=c),c>o&&(o=c);const s=Math.max(e,1);return[n-s,r-s,i+s,o+s]}function Dr(t,e,n){const r=Math.max(Cr,Number(n.minRasterStep)||0),i=Math.max(32768,Math.floor(n.maxRasterPixels||vr)),o=Math.max(256,Math.floor(n.maxRasterSize||Ir)),s=Math.max(.001,t[2]-t[0]),a=Math.max(.001,t[3]-t[1]);let c=Math.max(r,Number.EPSILON),h=3,l=Math.ceil(s/c)+h*2+1,g=Math.ceil(a/c)+h*2+1;for(;(l>o||g>o||l*g>i)&&(c*=1.15,l=Math.ceil(s/c)+h*2+1,g=Math.ceil(a/c)+h*2+1,!(c>Math.max(s,a))););return l=Math.max(8,l),g=Math.max(8,g),{minX:t[0],minY:t[1],step:c,padding:h,width:l,height:g}}function Nr(t,e){if(typeof OffscreenCanvas<"u"){const r=new OffscreenCanvas(t,e).getContext("2d",{willReadFrequently:!0});if(r)return r}if(typeof document<"u"){const n=document.createElement("canvas");return n.width=t,n.height=e,n.getContext("2d",{willReadFrequently:!0})}return null}function Wr(t,e){return[(t[0]-e.minX)/e.step+e.padding,(t[1]-e.minY)/e.step+e.padding]}function Xr(t,e,n){const r=Nr(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=e*2/n.step;const i=t.map(a=>Wr(a,n));if(i.length<=1){const a=i[0];if(!a)return new Uint8Array(0);r.beginPath(),r.arc(a[0],a[1],e/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]>=Fr?1:0;return s}function Or(t,e,n){const r=[],i=e+1,o=(a,c)=>c*i+a,s=(a,c)=>a>=0&&c>=0&&a<e&&c<n&&t[c*e+a]>0;for(let a=0;a<n;a+=1)for(let c=0;c<e;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 Yr(t,e){const n=(e-t+4)%4;return n===1?0:n===0?1:n===3?2:3}function Vr(t){if(!t.length)return[];const e=new Map;for(let i=0;i<t.length;i+=1){const o=e.get(t[i].start);o?o.push(i):e.set(t[i].start,[i])}const n=new Uint8Array(t.length),r=[];for(let i=0;i<t.length;i+=1){if(n[i])continue;const o=t[i],s=o.start;let a=o.end,c=o.dir;const h=[o.start,o.end];n[i]=1;let l=0;const g=t.length*3;for(;a!==s&&l<g;){const m=e.get(a);if(!m||m.length===0)break;let y=-1,x=1/0;for(const T of m){if(n[T])continue;const z=t[T],v=Yr(c,z.dir);v<x&&(x=v,y=T)}if(y<0)break;n[y]=1;const M=t[y];a=M.end,c=M.dir,h.push(a),l+=1}h.length>=4&&h[0]===h[h.length-1]&&r.push(h)}return r}function Gr(t,e,n){const r=e+1,i=[];for(const o of t){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 _e(i)}function qr(t){if(t.length<4)return 0;let e=0;for(let n=0;n<t.length-1;n+=1){const r=t[n],i=t[n+1];e+=r[0]*i[1]-i[0]*r[1]}return e*.5}function Hr(t,e=1e-9){const n=_e(t);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)<=e||r.push(s)}return r.push(r[0]),_e(r)}function $r(t,e,n){const r=n[0]-e[0],i=n[1]-e[1],o=r*r+i*i;if(o<=1e-12){const g=t[0]-e[0],m=t[1]-e[1];return g*g+m*m}const s=Rt(((t[0]-e[0])*r+(t[1]-e[1])*i)/o,0,1),a=e[0]+r*s,c=e[1]+i*s,h=t[0]-a,l=t[1]-c;return h*h+l*l}function Zr(t,e){if(t.length<=2||e<=0)return t.slice();const n=new Uint8Array(t.length);n[0]=1,n[t.length-1]=1;const r=e*e,i=[[0,t.length-1]];for(;i.length>0;){const s=i.pop();if(!s)break;const[a,c]=s;if(c-a<=1)continue;let h=0,l=-1;for(let g=a+1;g<c;g+=1){const m=$r(t[g],t[a],t[c]);m>h&&(h=m,l=g)}l>=0&&h>r&&(n[l]=1,i.push([a,l],[l,c]))}const o=[];for(let s=0;s<t.length;s+=1)n[s]&&o.push(t[s]);return o}function Kr(t,e){const n=_e(t);if(n.length<5||e<=0)return n;const r=n.slice(0,-1),i=Zr(r,e);return i.length<3?n:_e(i)}function jr(t,e){let n=_e(t);if(e<=0||n.length<5)return n;for(let r=0;r<e;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=_e(o)}return n}function nt(t,e){return e?_e(t.map(([n,r])=>[Rt(n,e[0],e[2]),Rt(r,e[1],e[3])])):t}function Jr(t,e){const n=Lr(t),r=Math.max(Yn,Number(e.radius)||0);if(n.length===0||!Number.isFinite(r))return[];const i=Math.max(12,Math.floor(e.circleSides||_r));if(n.length===1)return nt(zr(n[0],r,i),e.clipBounds);const o=kr(n,r),s=Dr(o,r,e),a=Xr(n,r,s);if(!a.length)return nt(Ft(n,r),e.clipBounds);const c=Or(a,s.width,s.height),h=Vr(c);if(!h.length)return nt(Ft(n,r),e.clipBounds);let l=[],g=0;for(const M of h){const T=Gr(M,s.width,s),z=Math.abs(qr(T));z<=g||(g=z,l=T)}if(!l.length)return nt(Ft(n,r),e.clipBounds);const m=typeof e.simplifyTolerance=="number"&&Number.isFinite(e.simplifyTolerance)?Math.max(0,e.simplifyTolerance):s.step*.2,y=typeof e.smoothingPasses=="number"&&Number.isFinite(e.smoothingPasses)?Math.round(Rt(e.smoothingPasses,0,Ur)):Br,x=Kr(jr(Hr(l,s.step*.001),y),m);return nt(x,e.clipBounds)}function Rn(t){return typeof t=="number"&&Number.isFinite(t)}function Qr(t){return Array.isArray(t)&&t.length>=2&&Rn(t[0])&&Rn(t[1])}function Vn(t){return Array.isArray(t)&&t.length>0&&t.every(e=>Qr(e))}function Gn(t){return Array.isArray(t)&&t.length>0&&t.every(e=>Vn(e))}function ei(t){return Array.isArray(t)&&t.length>0&&t.every(e=>Gn(e))}function ti(t){if(!Array.isArray(t)||t.length<3)return[];const e=[];for(const i of t){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=e[e.length-1];a&&a[0]===o&&a[1]===s||e.push([o,s])}if(e.length<3)return[];const n=e[0],r=e[e.length-1];return(n[0]!==r[0]||n[1]!==r[1])&&e.push([n[0],n[1]]),e.length>=4?e:[]}function Xt(t){if(!Array.isArray(t)||t.length<4)return 0;let e=0;for(let n=0;n<t.length-1;n+=1){const r=t[n],i=t[n+1];e+=r[0]*i[1]-i[0]*r[1]}return e*.5}function Lt(t){if(!Array.isArray(t)||t.length===0)return[];const e=[];for(const o of t){const s=ti(o);s.length>=4&&e.push(s)}if(e.length===0)return[];if(e.length===1)return[e[0]];let n=0,r=0;for(let o=0;o<e.length;o+=1){const s=Math.abs(Xt(e[o]));s<=r||(r=s,n=o)}const i=[e[n]];for(let o=0;o<e.length;o+=1)o!==n&&i.push(e[o]);return i}function qn(t){if(!t)return[];if(Vn(t)){const e=Lt([t]);return e.length>0?[e]:[]}if(Gn(t)){const e=Lt(t);return e.length>0?[e]:[]}if(ei(t)){const e=[];for(const n of t){const r=Lt(n);r.length>0&&e.push(r)}return e}return[]}function En(t,e,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],h=n[o][1];a>e!=h>e&&t<(c-s)*(e-a)/(h-a||Number.EPSILON)+s&&(r=!r)}return r}function at(t){const e=[];for(const n of t??[]){const r=qn(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,h=-1/0;for(const[g,m]of o)g<s&&(s=g),g>c&&(c=g),m<a&&(a=m),m>h&&(h=m);if(!Number.isFinite(s)||!Number.isFinite(a)||!Number.isFinite(c)||!Number.isFinite(h))continue;let l=Math.abs(Xt(o));for(let g=1;g<i.length;g+=1)l-=Math.abs(Xt(i[g]));e.push({outer:o,holes:i.slice(1),minX:s,minY:a,maxX:c,maxY:h,area:Math.max(1e-6,l)})}}return e}function jt(t,e,n){if(t<n.minX||t>n.maxX||e<n.minY||e>n.maxY||!En(t,e,n.outer))return!1;for(const r of n.holes)if(En(t,e,r))return!1;return!0}function Et(t,e,n){for(const r of n)if(jt(t,e,r))return!0;return!1}const Jt=[160,160,160,255];function J(t,e,n){return Math.max(e,Math.min(n,t))}function Qt(t,e,n){const r=Number(t),i=Number(e),o=Number(n);return!Number.isFinite(r)||r<=0?1:!Number.isFinite(i)||!Number.isFinite(o)?r:Math.pow(2,i-o)*r}function ni(t,e,n){let i=100*Qt(t,e,n);if(Number(t)){let o="μm";return i>1e3&&(i/=1e3,o="mm"),`${i.toPrecision(3)} ${o}`}return`${Math.round(i*1e3)/1e3} pixels`}function ri(t,e){return!t&&!e?!0:!t||!e?!1:Math.abs((t.zoom??0)-(e.zoom??0))<1e-6&&Math.abs((t.offsetX??0)-(e.offsetX??0))<1e-6&&Math.abs((t.offsetY??0)-(e.offsetY??0))<1e-6&&Math.abs((t.rotationDeg??0)-(e.rotationDeg??0))<1e-6}function ii(t){const e=String(t??"").trim();if(!e)return"";if(/^bearer\s+/i.test(e)){const n=e.replace(/^bearer\s+/i,"").trim();return n?`Bearer ${n}`:""}return`Bearer ${e}`}function Hn(t){const n=String(t??"").trim().match(/^#?([0-9a-fA-F]{6})$/);if(!n)return[...Jt];const r=Number.parseInt(n[1],16);return[r>>16&255,r>>8&255,r&255,255]}function oi(t){const e=[[...Jt]],n=new Map;for(const i of t??[]){const o=String(i?.termId??"");!o||n.has(o)||(n.set(o,e.length),e.push(Hn(i?.termColor)))}const r=new Uint8Array(e.length*4);for(let i=0;i<e.length;i+=1)r[i*4]=e[i][0],r[i*4+1]=e[i][1],r[i*4+2]=e[i][2],r[i*4+3]=e[i][3];return{colors:r,termToPaletteIndex:n}}function Pn(t,e,n){const r=t.createShader(t.VERTEX_SHADER),i=t.createShader(t.FRAGMENT_SHADER);if(!r||!i)throw new Error("Shader allocation failed");if(t.shaderSource(r,e),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS))throw new Error(t.getShaderInfoLog(r)||"vertex compile failed");if(t.shaderSource(i,n),t.compileShader(i),!t.getShaderParameter(i,t.COMPILE_STATUS))throw new Error(t.getShaderInfoLog(i)||"fragment compile failed");const o=t.createProgram();if(!o)throw new Error("Program allocation failed");if(t.attachShader(o,r),t.attachShader(o,i),t.linkProgram(o),t.deleteShader(r),t.deleteShader(i),!t.getProgramParameter(o,t.LINK_STATUS))throw new Error(t.getProgramInfoLog(o)||"program link failed");return o}const si="rgba(255, 77, 79, 0.16)",ai=3,ui=2,$n=96,ci=1,An=[],Pt=[],Cn=1e3,Zn=2,Kn=2,li=4096,hi=.2,fi=1.12,di=.89,mi=32,gi="#000000",pi=.1,bi="#FFCF00",wi="#FF0000",yi=1.5,vn=[2,2],Si=1,xi=.25,Mi=4,Ti=1,Ri=0,Ei=4,Pi=.05,Ai=256,Ci=1.5,Oe={color:"#ff4d4f",width:2,lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},vi={color:"#4cc9f0",width:2,lineDash:[10,8],lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},Ee={fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontSize:12,fontWeight:500,textColor:"#ffffff",backgroundColor:"rgba(8, 14, 22, 0.88)",borderColor:"rgba(255, 77, 79, 0.85)",borderWidth:1,paddingX:6,paddingY:4,offsetY:10,borderRadius:3};function $e(t,e,n){return Math.max(e,Math.min(n,t))}function bt(t){return t==="stamp-rectangle"||t==="stamp-circle"||t==="stamp-rectangle-4096px"||t==="stamp-rectangle-2mm2"||t==="stamp-circle-2mm2"||t==="stamp-circle-hpf-0.2mm2"}function it(t,e){return typeof t!="number"||!Number.isFinite(t)||t<=0?e:t}function Ii(t){return{rectangleAreaMm2:it(t?.rectangleAreaMm2,Zn),circleAreaMm2:it(t?.circleAreaMm2,Kn),rectanglePixelSize:it(t?.rectanglePixelSize,li)}}function _i(t,e){return typeof t!="number"||!Number.isFinite(t)?e:$e(t,0,1)}function Bi(t){if(!Array.isArray(t))return vn;const e=t.filter(n=>Number.isFinite(n)&&n>=0);return e.length>0?e:vn}function Ui(t){return typeof t!="number"||!Number.isFinite(t)?Si:$e(t,xi,Mi)}function Fi(t){return typeof t!="number"||!Number.isFinite(t)?Ti:Math.round($e(t,Ri,Ei))}function Li(t){const e=it(t?.radius,mi),n=it(t?.cursorLineWidth,yi),r=Ui(t?.edgeDetail),i=Fi(t?.edgeSmoothing);return{radius:e,edgeDetail:r,edgeSmoothing:i,clickSelectRoi:t?.clickSelectRoi===!0,fillColor:t?.fillColor||gi,fillOpacity:_i(t?.fillOpacity,pi),cursorColor:t?.cursorColor||bi,cursorActiveColor:t?.cursorActiveColor||wi,cursorLineWidth:n,cursorLineDash:Bi(t?.cursorLineDash)}}function zi(t){return t*Cn*Cn}function In(t,e){return!t||!Number.isFinite(e)||e<=0?[]:Le([[t[0]-e,t[1]-e],[t[0]+e,t[1]-e],[t[0]+e,t[1]+e],[t[0]-e,t[1]+e]])}function ki(t,e,n=$n){if(!t||!Number.isFinite(e)||e<=0)return[];const r=[];for(let i=0;i<=n;i+=1){const o=i/n*Math.PI*2;r.push([t[0]+Math.cos(o)*e,t[1]+Math.sin(o)*e])}return Le(r)}function Le(t){if(!Array.isArray(t)||t.length<3)return[];const e=t.map(([i,o])=>[i,o]),n=e[0],r=e[e.length-1];return!n||!r?[]:((n[0]!==r[0]||n[1]!==r[1])&&e.push([n[0],n[1]]),e)}function Ot(t,e){return!t||!e?[]:Le([[t[0],t[1]],[e[0],t[1]],[e[0],e[1]],[t[0],e[1]]])}function Yt(t,e,n=$n){if(!t||!e)return[];const r=(t[0]+e[0])*.5,i=(t[1]+e[1])*.5,o=Math.hypot(e[0]-t[0],e[1]-t[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 Le(s)}function Vt(t){if(!Array.isArray(t)||t.length<4)return 0;let e=0;for(let n=0;n<t.length-1;n+=1){const r=t[n],i=t[n+1];e+=r[0]*i[1]-i[0]*r[1]}return Math.abs(e*.5)}function _n(t){if(!Array.isArray(t)||t.length===0)return[0,0,0,0];let e=1/0,n=1/0,r=-1/0,i=-1/0;for(const[o,s]of t)o<e&&(e=o),o>r&&(r=o),s<n&&(n=s),s>i&&(i=s);return[e,n,r,i]}function Bn(t){return Array.isArray(t)&&t.length>=4&&Vt(t)>ci}function Gt(t,e,n=!1){if(e.length!==0){t.moveTo(e[0][0],e[0][1]);for(let r=1;r<e.length;r+=1)t.lineTo(e[r][0],e[r][1]);n&&t.closePath()}}function Ye(t,e,n,r=!1,i=!1){e.length!==0&&(t.beginPath(),Gt(t,e,r),i&&r&&(t.fillStyle=si,t.fill()),t.strokeStyle=n.color,t.lineWidth=n.width,t.lineJoin=n.lineJoin,t.lineCap=n.lineCap,t.shadowColor=n.shadowColor,t.shadowBlur=n.shadowBlur,t.shadowOffsetX=n.shadowOffsetX,t.shadowOffsetY=n.shadowOffsetY,t.setLineDash(n.lineDash),t.stroke(),t.setLineDash(Pt),t.shadowColor="rgba(0, 0, 0, 0)",t.shadowBlur=0,t.shadowOffsetX=0,t.shadowOffsetY=0)}function jn(t){const e=Array.isArray(t?.lineDash)?t.lineDash.filter(s=>Number.isFinite(s)&&s>=0):Pt,n=typeof t?.width=="number"&&Number.isFinite(t.width)?Math.max(0,t.width):Oe.width,r=typeof t?.shadowBlur=="number"&&Number.isFinite(t.shadowBlur)?Math.max(0,t.shadowBlur):Oe.shadowBlur,i=typeof t?.shadowOffsetX=="number"&&Number.isFinite(t.shadowOffsetX)?t.shadowOffsetX:Oe.shadowOffsetX,o=typeof t?.shadowOffsetY=="number"&&Number.isFinite(t.shadowOffsetY)?t.shadowOffsetY:Oe.shadowOffsetY;return{color:t?.color||Oe.color,width:n,lineDash:e.length?e:Pt,lineJoin:t?.lineJoin||Oe.lineJoin,lineCap:t?.lineCap||Oe.lineCap,shadowColor:t?.shadowColor||Oe.shadowColor,shadowBlur:r,shadowOffsetX:i,shadowOffsetY:o}}function rt(t,e){return e?jn({color:e.color??t.color,width:e.width??t.width,lineDash:e.lineDash??t.lineDash,lineJoin:e.lineJoin??t.lineJoin,lineCap:e.lineCap??t.lineCap,shadowColor:e.shadowColor??t.shadowColor,shadowBlur:e.shadowBlur??t.shadowBlur,shadowOffsetX:e.shadowOffsetX??t.shadowOffsetX,shadowOffsetY:e.shadowOffsetY??t.shadowOffsetY}):t}function Un(t,e){return t==null||e===null||e===void 0?!1:String(t)===String(e)}function Di(t){const e=t[0];return Array.isArray(e)&&Array.isArray(e[0])}function Fn(t){return typeof t=="number"&&Number.isFinite(t)}function Ni(t){return Array.isArray(t)&&t.length>=2&&Fn(t[0])&&Fn(t[1])}function Wi(t){return Array.isArray(t)&&t.length>=2&&t.every(e=>Ni(e))}function Jn(t,e){if(!(!Array.isArray(t)||t.length===0)){if(Wi(t)){e.push(t.map(([n,r])=>[n,r]));return}for(const n of t)Jn(n,e)}}function Ln(t,e){const n=[];Jn(t,n);const r=[];for(const i of n){if(i.length<2)continue;const o=e?Le(i):i;o.length>=(e?4:2)&&r.push(o)}return r}function Xi(t,e,n,r){if(!(e.length<4||n.length===0)){t.save(),t.beginPath(),Gt(t,e,!0);for(const i of n)i.length<4||Gt(t,i,!0);t.fillStyle=r,t.fill("evenodd"),t.restore()}}function Oi(t){const e=typeof t?.paddingX=="number"&&Number.isFinite(t.paddingX)?Math.max(0,t.paddingX):Ee.paddingX,n=typeof t?.paddingY=="number"&&Number.isFinite(t.paddingY)?Math.max(0,t.paddingY):Ee.paddingY,r=typeof t?.fontSize=="number"&&Number.isFinite(t.fontSize)?Math.max(8,t.fontSize):Ee.fontSize,i=typeof t?.borderWidth=="number"&&Number.isFinite(t.borderWidth)?Math.max(0,t.borderWidth):Ee.borderWidth,o=typeof t?.offsetY=="number"&&Number.isFinite(t.offsetY)?t.offsetY:Ee.offsetY,s=typeof t?.borderRadius=="number"&&Number.isFinite(t.borderRadius)?Math.max(0,t.borderRadius):Ee.borderRadius;return{fontFamily:t?.fontFamily||Ee.fontFamily,fontSize:r,fontWeight:t?.fontWeight||Ee.fontWeight,textColor:t?.textColor||Ee.textColor,backgroundColor:t?.backgroundColor||Ee.backgroundColor,borderColor:t?.borderColor||Ee.borderColor,borderWidth:i,paddingX:e,paddingY:n,offsetY:o,borderRadius:s}}function Yi(t,e,n,r,i,o){const s=Math.max(0,Math.min(o,r*.5,i*.5));t.beginPath(),t.moveTo(e+s,n),t.lineTo(e+r-s,n),t.quadraticCurveTo(e+r,n,e+r,n+s),t.lineTo(e+r,n+i-s),t.quadraticCurveTo(e+r,n+i,e+r-s,n+i),t.lineTo(e+s,n+i),t.quadraticCurveTo(e,n+i,e,n+i-s),t.lineTo(e,n+s),t.quadraticCurveTo(e,n,e+s,n),t.closePath()}function Vi(t){if(!t.length)return null;let e=1/0;for(const i of t)i[1]<e&&(e=i[1]);if(!Number.isFinite(e))return null;let n=1/0,r=-1/0;for(const i of t)Math.abs(i[1]-e)>.5||(i[0]<n&&(n=i[0]),i[0]>r&&(r=i[0]));return!Number.isFinite(n)||!Number.isFinite(r)?null:[(n+r)*.5,e]}function Gi(t){let e=null;for(const n of t){const r=Vi(n.outer);r&&(!e||r[1]<e[1]||r[1]===e[1]&&r[0]<e[0])&&(e=r)}return e}function zn(t){const e=qn(t);if(e.length===0)return[];const n=[];for(const r of e){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(([h,l])=>[h,l]))}n.push({outer:o,holes:s})}return n}function qi(t,e,n,r,i,o){const s=e.trim();if(!s)return;t.save(),t.font=`${o.fontWeight} ${o.fontSize}px ${o.fontFamily}`,t.textAlign="center",t.textBaseline="middle";const c=t.measureText(s).width+o.paddingX*2,h=o.fontSize+o.paddingY*2,l=$e(n[0],c*.5+1,r-c*.5-1),g=$e(n[1]-o.offsetY,h*.5+1,i-h*.5-1),m=l-c*.5,y=g-h*.5;t.fillStyle=o.backgroundColor,t.strokeStyle=o.borderColor,t.lineWidth=o.borderWidth,Yi(t,m,y,c,h,o.borderRadius),t.fill(),o.borderWidth>0&&t.stroke(),t.fillStyle=o.textColor,t.fillText(s,l,g+.5),t.restore()}function zt(t,e,n){return[$e(t[0],0,e),$e(t[1],0,n)]}function je(t){if(!Array.isArray(t)||t.length<2)return null;const e=Number(t[0]),n=Number(t[1]);return!Number.isFinite(e)||!Number.isFinite(n)?null:[e,n]}function Qn({tool:t,imageWidth:e,imageHeight:n,imageMpp:r,imageZoom:i,stampOptions:o,brushOptions:s,projectorRef:a,onBrushTap:c,onDrawComplete:h,onPatchComplete:l,enabled:g,viewStateSignal:m,persistedRegions:y,patchRegions:x,persistedPolygons:M,regionStrokeStyle:T,regionStrokeHoverStyle:z,regionStrokeActiveStyle:v,patchStrokeStyle:P,resolveRegionStrokeStyle:F,overlayShapes:G,hoveredRegionId:le=null,activeRegionId:ge=null,regionLabelStyle:he,invalidateRef:N,className:ze,style:Be}){const H=d.useRef(null),Pe=d.useRef(!1),Ue=d.useRef(new Map),Ze=d.useRef(t),de=d.useRef({isDrawing:!1,pointerId:null,start:null,current:null,cursor:null,points:[],stampCenter:null}),Q=g??t!=="cursor",E=d.useMemo(()=>y&&y.length>0?y:!M||M.length===0?An:M.map((u,f)=>({id:f,coordinates:u})),[y,M]),C=d.useMemo(()=>x??An,[x]),I=d.useMemo(()=>{const u=[];for(let f=0;f<E.length;f+=1){const b=E[f],S=zn(b.coordinates);S.length!==0&&u.push({region:b,regionIndex:f,regionKey:b.id??f,polygons:S})}return u},[E]),X=d.useMemo(()=>{const u=[];for(let f=0;f<C.length;f+=1){const b=C[f],S=zn(b.coordinates);S.length!==0&&u.push({region:b,regionIndex:f,regionKey:b.id??f,polygons:S})}return u},[C]),L=d.useMemo(()=>jn(T),[T]),ne=d.useMemo(()=>rt(L,z),[L,z]),ee=d.useMemo(()=>rt(L,v),[L,v]),be=d.useMemo(()=>rt(vi,P),[P]),ue=d.useMemo(()=>Oi(he),[he]),re=d.useMemo(()=>Ii(o),[o]),O=d.useMemo(()=>Li(s),[s]),K=d.useMemo(()=>({position:"absolute",inset:0,zIndex:2,width:"100%",height:"100%",display:"block",touchAction:"none",pointerEvents:Q?"auto":"none",cursor:Q?t==="brush"?"none":"crosshair":"default",...Be}),[Q,t,Be]),$=d.useCallback(()=>{const u=H.current;if(!u)return;const f=u.getBoundingClientRect(),b=Math.max(1,window.devicePixelRatio||1),S=Math.max(1,Math.round(f.width*b)),A=Math.max(1,Math.round(f.height*b));(u.width!==S||u.height!==A)&&(u.width=S,u.height=A)},[]),D=d.useCallback(u=>{const f=a.current;if(!f||u.length===0)return[];const b=new Array(u.length);for(let S=0;S<u.length;S+=1){const A=je(f.worldToScreen(u[S][0],u[S][1]));if(!A)return[];b[S]=A}return b},[a]),te=d.useCallback((u,f)=>{if(!Number.isFinite(f)||f<=0)return 0;const b=a.current;if(!b)return 0;const S=je(b.worldToScreen(u[0],u[1])),A=je(b.worldToScreen(u[0]+f,u[1]));return!S||!A?0:Math.hypot(A[0]-S[0],A[1]-S[1])},[a]),ie=d.useCallback(u=>{if(!Number.isFinite(u)||u<=0)return 0;const f=typeof r=="number"&&Number.isFinite(r)&&r>0?r:1,b=typeof i=="number"&&Number.isFinite(i)?i:0,S=a.current?.getViewState?.().zoom,A=typeof S=="number"&&Number.isFinite(S)&&S>0?S:1,U=b+Math.log2(A),W=Math.max(1e-9,Qt(f,b,U));return u/W/A},[r,i,a]),oe=d.useCallback((u,f)=>{if(!f)return[];let b=0;if(u==="stamp-rectangle-4096px"){const U=re.rectanglePixelSize*.5;return In(f,U).map(q=>zt(q,e,n))}if(u==="stamp-rectangle"||u==="stamp-rectangle-2mm2"?b=u==="stamp-rectangle-2mm2"?Zn:re.rectangleAreaMm2:(u==="stamp-circle"||u==="stamp-circle-2mm2"||u==="stamp-circle-hpf-0.2mm2")&&(b=u==="stamp-circle-hpf-0.2mm2"?hi:u==="stamp-circle-2mm2"?Kn:re.circleAreaMm2),!Number.isFinite(b)||b<=0)return[];const S=zi(b);let A=[];if(u==="stamp-rectangle"||u==="stamp-rectangle-2mm2"){const U=ie(Math.sqrt(S)*.5);A=In(f,U)}else if(u==="stamp-circle"||u==="stamp-circle-2mm2"||u==="stamp-circle-hpf-0.2mm2"){const U=ie(Math.sqrt(S/Math.PI));A=ki(f,U)}return A.length?A.map(U=>zt(U,e,n)):[]},[ie,e,n,re]),Z=d.useCallback(()=>{const u=de.current;return bt(t)?oe(t,u.stampCenter):t==="brush"?[]:u.isDrawing?t==="freehand"?u.points:t==="rectangle"?Ot(u.start,u.current):t==="circular"?Yt(u.start,u.current):[]:[]},[t,oe]),Ae=d.useCallback(u=>{const f=de.current;if(!f.isDrawing||f.points.length===0)return;const b=D(f.points);if(b.length===0)return;const S=f.points[f.points.length-1]??f.points[0],A=te(S,O.radius);if(!(!Number.isFinite(A)||A<=0)){if(u.save(),u.globalAlpha=O.fillOpacity,u.fillStyle=O.fillColor,u.strokeStyle=O.fillColor,u.lineCap="round",u.lineJoin="round",u.lineWidth=A*2,b.length===1)u.beginPath(),u.arc(b[0][0],b[0][1],A,0,Math.PI*2),u.fill();else{u.beginPath(),u.moveTo(b[0][0],b[0][1]);for(let U=1;U<b.length;U+=1)u.lineTo(b[U][0],b[U][1]);u.stroke()}u.restore()}},[D,te,O]),Te=d.useCallback(u=>{const f=de.current,b=f.cursor;if(!b)return;const S=je(a.current?.worldToScreen(b[0],b[1])??[]);if(!S)return;const A=te(b,O.radius);!Number.isFinite(A)||A<=0||(u.save(),u.beginPath(),u.arc(S[0],S[1],A,0,Math.PI*2),u.strokeStyle=f.isDrawing?O.cursorActiveColor:O.cursorColor,u.lineWidth=O.cursorLineWidth,u.setLineDash(O.cursorLineDash),u.stroke(),u.setLineDash(Pt),u.restore())},[a,te,O]),Ce=d.useCallback(()=>{$();const u=H.current;if(!u)return;const f=u.getContext("2d");if(!f)return;const b=Math.max(1,window.devicePixelRatio||1),S=u.width/b,A=u.height/b;if(f.setTransform(1,0,0,1,0,0),f.clearRect(0,0,u.width,u.height),f.setTransform(b,0,0,b,0,0),I.length>0)for(const U of I){const{region:W,polygons:q,regionIndex:Y,regionKey:ce}=U,ke=Un(ge,ce)?"active":Un(le,ce)?"hover":"default";let De=ke==="active"?ee:ke==="hover"?ne:L;if(F){const j=F({region:W,regionId:ce,regionIndex:Y,state:ke});De=rt(De,j||void 0)}for(const j of q){const se=D(j.outer);se.length>=4&&Ye(f,se,De,!0,!1);for(const pe of j.holes){const me=D(pe);me.length>=4&&Ye(f,me,De,!0,!1)}}}if(X.length>0)for(const U of X)for(const W of U.polygons){const q=D(W.outer);q.length>=4&&Ye(f,q,be,!0,!1);for(const Y of W.holes){const ce=D(Y);ce.length>=4&&Ye(f,ce,be,!0,!1)}}if(Array.isArray(G)&&G.length>0){const U=!!globalThis.__OPEN_PLANT_DEBUG_OVERLAY__,W=D(Le([[0,0],[e,0],[e,n],[0,n]]));for(let q=0;q<G.length;q+=1){const Y=G[q];if(!Y?.coordinates?.length||Y.visible===!1)continue;const ce=Y.closed??Di(Y.coordinates),ke=Ln(Y.coordinates,ce);if(Y.invertedFill?.fillColor){const j=[],se=Ln(Y.coordinates,!0);for(const pe of se){const me=D(pe);me.length>=4&&j.push(me)}if(U){const pe=String(Y.id??q),me=`${W.length}|${se.length}|${j.length}|${Y.invertedFill.fillColor}`;Ue.current.get(pe)!==me&&(Ue.current.set(pe,me),console.debug("[open-plant] invertedFill",{id:Y.id??q,outerRingPoints:W.length,sourceRingCount:se.length,holeRingCount:j.length,fillColor:Y.invertedFill.fillColor}))}Xi(f,W,j,Y.invertedFill.fillColor)}if(ke.length===0)continue;const De=rt(L,Y.stroke??Y.strokeStyle);for(const j of ke){const se=D(j);se.length<2||Ye(f,se,De,ce,Y.fill??!1)}}}if(Q)if(t==="brush")Ae(f),Te(f);else{const U=Z();if(U.length>0)if(t==="freehand"){const W=D(U);W.length>=2&&Ye(f,W,L,!1,!1),W.length>=3&&Ye(f,D(Le(U)),L,!0,!0)}else{const W=D(U);W.length>=4&&Ye(f,W,L,!0,!0)}}if(I.length>0)for(const U of I){if(!U.region.label)continue;const W=Gi(U.polygons);if(!W)continue;const q=je(a.current?.worldToScreen(W[0],W[1])??[]);q&&qi(f,U.region.label,q,S,A,ue)}},[Q,t,Z,Ae,Te,$,D,e,n,a,I,G,le,ge,L,ne,ee,X,be,F,ue]),B=d.useCallback(()=>{Pe.current||(Pe.current=!0,requestAnimationFrame(()=>{Pe.current=!1,Ce()}))},[Ce]),fe=d.useCallback((u=!1)=>{const f=de.current,b=H.current;if(b&&f.pointerId!==null&&b.hasPointerCapture(f.pointerId))try{b.releasePointerCapture(f.pointerId)}catch{}f.isDrawing=!1,f.pointerId=null,f.start=null,f.current=null,f.points=[],f.stampCenter=null,u||(f.cursor=null)},[]),Re=d.useCallback(u=>{const f=a.current;if(!f||e<=0||n<=0)return null;const b=je(f.screenToWorld(u.clientX,u.clientY));return b?zt(b,e,n):null},[a,e,n]),ve=d.useCallback(()=>{const u=de.current;if(!u.isDrawing){fe(!0),B();return}let f=[];if(t==="freehand")u.points.length>=ai&&(f=Le(u.points));else if(t==="rectangle")f=Ot(u.start,u.current);else if(t==="circular")f=Yt(u.start,u.current);else if(t==="brush"){const b=u.points[u.points.length-1]??u.current??u.start;if(O.clickSelectRoi&&b&&u.points.length<=1&&c?.(b)){fe(!0),B();return}const S=O.edgeDetail,A=Math.max(Pi,O.radius*2/(Ai*S));f=Jr(u.points,{radius:O.radius,clipBounds:[0,0,e,n],minRasterStep:A,circleSides:Math.max(24,Math.round(64*S)),simplifyTolerance:A*.25,smoothingPasses:O.edgeSmoothing})}(t==="freehand"||t==="rectangle"||t==="circular"||t==="brush")&&Bn(f)&&h&&h({tool:t,intent:t==="brush"?"brush":"roi",coordinates:f,bbox:_n(f),areaPx:Vt(f)}),fe(!0),B()},[t,h,fe,B,O.radius,O.edgeDetail,O.edgeSmoothing,O.clickSelectRoi,e,n,c]),Qe=d.useCallback((u,f)=>{const b=oe(u,f);if(!Bn(b))return;const S=u==="stamp-rectangle-4096px"?"patch":"roi",A={tool:u,intent:S,coordinates:b,bbox:_n(b),areaPx:Vt(b)};h?.(A),S==="patch"&&l&&l(A)},[oe,h,l]),Ie=d.useCallback((u,f)=>{const b=a.current,S=Math.max(1e-6,b?.getViewState?.().zoom??1),A=Ci/S,U=A*A,W=u.points[u.points.length-1];if(!W){u.points.push(f),u.current=f;return}const q=f[0]-W[0],Y=f[1]-W[1];q*q+Y*Y>=U?u.points.push(f):u.points[u.points.length-1]=f,u.current=f},[a]),we=d.useCallback(u=>{if(!Q||t==="cursor"||u.button!==0)return;const f=Re(u);if(!f)return;if(u.preventDefault(),u.stopPropagation(),bt(t)){const A=de.current;A.stampCenter=f,Qe(t,f),B();return}const b=H.current;b&&b.setPointerCapture(u.pointerId);const S=de.current;S.isDrawing=!0,S.pointerId=u.pointerId,S.start=f,S.current=f,S.cursor=f,S.points=t==="freehand"||t==="brush"?[f]:[],B()},[Q,t,Re,Qe,B]),At=d.useCallback(u=>{if(!Q||t==="cursor")return;const f=Re(u);if(!f)return;if(bt(t)){const S=de.current;S.stampCenter=f,u.preventDefault(),u.stopPropagation(),B();return}const b=de.current;if(t==="brush"){if(b.cursor=f,!b.isDrawing||b.pointerId!==u.pointerId){B();return}u.preventDefault(),u.stopPropagation(),Ie(b,f),B();return}if(!(!b.isDrawing||b.pointerId!==u.pointerId)){if(u.preventDefault(),u.stopPropagation(),t==="freehand"){const S=a.current,A=Math.max(1e-6,S?.getViewState?.().zoom??1),U=ui/A,W=U*U,q=b.points[b.points.length-1];if(!q)b.points.push(f);else{const Y=f[0]-q[0],ce=f[1]-q[1];Y*Y+ce*ce>=W&&b.points.push(f)}}else b.current=f;B()}},[Q,t,Re,B,a,Ie]),et=d.useCallback(u=>{const f=de.current;if(!f.isDrawing||f.pointerId!==u.pointerId)return;u.preventDefault(),u.stopPropagation();const b=Re(u);b&&(f.cursor=b,t==="brush"?Ie(f,b):f.current=b);const S=H.current;if(S&&S.hasPointerCapture(u.pointerId))try{S.releasePointerCapture(u.pointerId)}catch{}ve()},[ve,Re,t,Ie]),ut=d.useCallback(()=>{const u=de.current;let f=!1;t==="brush"&&!u.isDrawing&&u.cursor&&(u.cursor=null,f=!0),bt(t)&&u.stampCenter&&(u.stampCenter=null,f=!0),f&&B()},[t,B]);return d.useEffect(()=>{$(),B();const u=H.current;if(!u)return;const f=new ResizeObserver(()=>{$(),B()});return f.observe(u),()=>{f.disconnect()}},[$,B]),d.useEffect(()=>{Q||fe(),B()},[Q,B,fe]),d.useEffect(()=>{Ze.current!==t&&(Ze.current=t,fe(),B())},[t,fe,B]),d.useEffect(()=>{B()},[m,E,G,B]),d.useEffect(()=>{if(N)return N.current=B,()=>{N.current===B&&(N.current=null)}},[N,B]),d.useEffect(()=>{if(!Q)return;const u=f=>{f.key==="Escape"&&(fe(),B())};return window.addEventListener("keydown",u),()=>{window.removeEventListener("keydown",u)}},[Q,fe,B]),Se.jsx("canvas",{ref:H,className:ze,style:K,onPointerDown:we,onPointerMove:At,onPointerUp:et,onPointerCancel:et,onPointerLeave:ut,onContextMenu:u=>{Q&&u.preventDefault()},onWheel:u=>{if(!Q)return;const f=H.current,b=a.current;if(!f||typeof b?.zoomBy!="function")return;u.preventDefault(),u.stopPropagation();const S=f.getBoundingClientRect(),A=u.clientX-S.left,U=u.clientY-S.top;b.zoomBy(u.deltaY<0?fi:di,A,U),B()}})}function kn(t){return String(t??"").replace(/\/+$/,"")}function er(t){const e=String(t??"");return e.startsWith("/")?e:`/${e}`}function Hi(t){const e=kn(t);if(!e)return"";if(/\/TileGroup\d+$/i.test(e))return e;let n=null;try{n=new URL(e)}catch{n=null}if(n){const r=`${n.protocol}//${n.host}`,i=kn(n.pathname||"");return/\/ims$/i.test(i)?`${r}${i}`:/\/tiles$/i.test(i)?`${r}${i}`:`${r}${i}/tiles`}return/\/ims$/i.test(e)?"/ims":/\/tiles$/i.test(e)?`${e}`:`${e}/tiles`}function $i(t,e){const n=t?.imsInfo||{},r=!!t?.imsInfo,i=Number(n.width??t?.width??0),o=Number(n.height??t?.height??0),s=Number(n.tileSize??t?.tileSize??0),a=Number(n.zoom??t?.zoom??0),c=String(n.path??t?.path??""),h=Number(n.mpp??t?.mpp??0);if(!i||!o||!s||!c)throw new Error("이미지 메타데이터가 불완전합니다. width/height/tileSize/path 확인 필요");const l=Array.isArray(t?.terms)?t.terms.map(x=>({termId:String(x?.termId??""),termName:String(x?.termName??""),termColor:String(x?.termColor??"")})):[],g=er(c),m=Hi(e),y=r?(x,M,T)=>`${m}${g}/${x}/${T}_${M}.webp`:void 0;return{id:t?._id||"unknown",name:t?.name||"unknown",width:i,height:o,mpp:Number.isFinite(h)&&h>0?h:void 0,tileSize:s,maxTierZoom:Number.isFinite(a)?Math.max(0,Math.floor(a)):0,tilePath:c,tileBaseUrl:e,terms:l,tileUrlBuilder:y}}function en(t,e,n,r){if(t.tileUrlBuilder)return t.tileUrlBuilder(e,n,r);const i=er(t.tilePath);return`${t.tileBaseUrl}${i}/${e}/${r}_${n}.webp`}const ye={width:220,height:140,margin:16,position:"bottom-right",borderRadius:10,borderWidth:1.5,backgroundColor:"rgba(4, 10, 18, 0.88)",borderColor:"rgba(230, 244, 255, 0.35)",viewportStrokeColor:"rgba(255, 106, 61, 0.95)",viewportFillColor:"rgba(255, 106, 61, 0.2)",interactive:!0,showThumbnail:!0,maxThumbnailTiles:16};function Je(t,e,n=1){return typeof t!="number"||!Number.isFinite(t)?e:Math.max(n,t)}function wt(t){return Array.isArray(t)&&t.length===4&&Number.isFinite(t[0])&&Number.isFinite(t[1])&&Number.isFinite(t[2])&&Number.isFinite(t[3])}function tr({source:t,projectorRef:e,authToken:n="",options:r,invalidateRef:i,className:o,style:s}){const a=d.useRef(null),c=d.useRef(null),h=d.useRef(null),l=d.useRef({active:!1,pointerId:null}),g=d.useRef(null),m=d.useRef(!1),y=Je(r?.width,ye.width,64),x=Je(r?.height,ye.height,48),M=Je(r?.margin,ye.margin,0),T=Je(r?.borderRadius,ye.borderRadius,0),z=Je(r?.borderWidth,ye.borderWidth,0),v=Math.max(1,Math.round(Je(r?.maxThumbnailTiles,ye.maxThumbnailTiles,1))),P=r?.backgroundColor||ye.backgroundColor,F=r?.borderColor||ye.borderColor,G=r?.viewportStrokeColor||ye.viewportStrokeColor,le=r?.viewportFillColor||ye.viewportFillColor,ge=r?.interactive??ye.interactive,he=r?.showThumbnail??ye.showThumbnail,N=r?.position||ye.position,ze=d.useMemo(()=>{const E={};return N==="top-left"||N==="bottom-left"?E.left=M:E.right=M,N==="top-left"||N==="top-right"?E.top=M:E.bottom=M,{position:"absolute",...E,width:y,height:x,borderRadius:T,overflow:"hidden",zIndex:4,pointerEvents:ge?"auto":"none",touchAction:"none",boxShadow:"0 10px 22px rgba(0, 0, 0, 0.3)",...s}},[M,N,y,x,T,ge,s]),Be=d.useCallback(()=>{const E=a.current;if(!E)return;const C=E.getContext("2d");if(!C)return;const I=y,X=x,L=Math.max(1,window.devicePixelRatio||1),ne=Math.max(1,Math.round(I*L)),ee=Math.max(1,Math.round(X*L));(E.width!==ne||E.height!==ee)&&(E.width=ne,E.height=ee),C.setTransform(1,0,0,1,0,0),C.clearRect(0,0,E.width,E.height),C.setTransform(L,0,0,L,0,0),C.fillStyle=P,C.fillRect(0,0,I,X);const be=c.current;be&&C.drawImage(be,0,0,I,X),C.strokeStyle=F,C.lineWidth=z,C.strokeRect(z*.5,z*.5,I-z,X-z);const ue=e.current,re=ue?.getViewBounds?.(),O=ue?.getViewCorners?.(),K=wt(re)?re:wt(h.current)?h.current:null;if(!K)return;h.current=K;const $=I/Math.max(1,t.width),D=X/Math.max(1,t.height),te=Array.isArray(O)&&O.length>=4&&O.every(B=>Array.isArray(B)&&B.length>=2&&Number.isFinite(B[0])&&Number.isFinite(B[1]))?O:null;if(te){C.beginPath();for(let B=0;B<te.length;B+=1){const fe=te[B],Re=J(fe[0]*$,0,I),ve=J(fe[1]*D,0,X);B===0?C.moveTo(Re,ve):C.lineTo(Re,ve)}C.closePath(),C.fillStyle=le,C.fill(),C.strokeStyle=G,C.lineWidth=1.5,C.stroke();return}const ie=J(K[0]*$,0,I),oe=J(K[1]*D,0,X),Z=J(K[2]*$,0,I),Ae=J(K[3]*D,0,X),Te=Math.max(1,Z-ie),Ce=Math.max(1,Ae-oe);C.fillStyle=le,C.fillRect(ie,oe,Te,Ce),C.strokeStyle=G,C.lineWidth=1.5,C.strokeRect(ie+.5,oe+.5,Math.max(1,Te-1),Math.max(1,Ce-1))},[y,x,P,F,z,e,t.width,t.height,le,G]),H=d.useCallback(()=>{m.current||(m.current=!0,g.current=requestAnimationFrame(()=>{m.current=!1,g.current=null,Be()}))},[Be]),Pe=d.useCallback((E,C)=>{const I=a.current;if(!I)return null;const X=I.getBoundingClientRect();if(!X.width||!X.height)return null;const L=J((E-X.left)/X.width,0,1),ne=J((C-X.top)/X.height,0,1);return[L*t.width,ne*t.height]},[t.width,t.height]),Ue=d.useCallback((E,C)=>{const I=e.current;if(!I)return;if(I.setViewCenter){I.setViewCenter(E,C),H();return}const X=I.getViewBounds?.(),L=wt(X)?X:wt(h.current)?h.current:null;if(!L)return;const ne=Math.max(1e-6,L[2]-L[0]),ee=Math.max(1e-6,L[3]-L[1]);I.setViewState({offsetX:E-ne*.5,offsetY:C-ee*.5}),H()},[e,H]),Ze=d.useCallback(E=>{if(!ge||E.button!==0)return;const C=a.current;if(!C)return;const I=Pe(E.clientX,E.clientY);I&&(E.preventDefault(),E.stopPropagation(),C.setPointerCapture(E.pointerId),l.current={active:!0,pointerId:E.pointerId},Ue(I[0],I[1]))},[ge,Pe,Ue]),de=d.useCallback(E=>{const C=l.current;if(!C.active||C.pointerId!==E.pointerId)return;const I=Pe(E.clientX,E.clientY);I&&(E.preventDefault(),E.stopPropagation(),Ue(I[0],I[1]))},[Pe,Ue]),Q=d.useCallback(E=>{const C=l.current;if(!C.active||C.pointerId!==E.pointerId)return;const I=a.current;if(I&&I.hasPointerCapture(E.pointerId))try{I.releasePointerCapture(E.pointerId)}catch{}l.current={active:!1,pointerId:null},H()},[H]);return d.useEffect(()=>{let E=!1;c.current=null,H();const C=0,I=2**(t.maxTierZoom-C),X=Math.ceil(t.width/I),L=Math.ceil(t.height/I),ne=Math.max(1,Math.ceil(X/t.tileSize)),ee=Math.max(1,Math.ceil(L/t.tileSize)),be=ne*ee;if(!he||be>v)return;const ue=document.createElement("canvas");ue.width=Math.max(1,Math.round(y)),ue.height=Math.max(1,Math.round(x));const re=ue.getContext("2d");if(!re)return;re.fillStyle=P,re.fillRect(0,0,ue.width,ue.height);const O=[];for(let K=0;K<ee;K+=1)for(let $=0;$<ne;$+=1){const D=$*t.tileSize*I,te=K*t.tileSize*I,ie=Math.min(($+1)*t.tileSize,X)*I,oe=Math.min((K+1)*t.tileSize,L)*I;O.push({url:en(t,C,$,K),bounds:[D,te,ie,oe]})}return Promise.allSettled(O.map(async K=>{const $=!!n,D=await fetch(K.url,{headers:$?{Authorization:n}:void 0});if(!D.ok)throw new Error(`HTTP ${D.status}`);const te=await createImageBitmap(await D.blob());return{tile:K,bitmap:te}})).then(K=>{if(E){for(const te of K)te.status==="fulfilled"&&te.value.bitmap.close();return}const $=ue.width/Math.max(1,t.width),D=ue.height/Math.max(1,t.height);for(const te of K){if(te.status!=="fulfilled")continue;const{tile:{bounds:ie},bitmap:oe}=te.value,Z=ie[0]*$,Ae=ie[1]*D,Te=Math.max(1,(ie[2]-ie[0])*$),Ce=Math.max(1,(ie[3]-ie[1])*D);re.drawImage(oe,Z,Ae,Te,Ce),oe.close()}c.current=ue,H()}),()=>{E=!0}},[t,n,y,x,P,he,v,H]),d.useEffect(()=>{H()},[H]),d.useEffect(()=>{if(i)return i.current=H,()=>{i.current===H&&(i.current=null)}},[i,H]),d.useEffect(()=>()=>{l.current={active:!1,pointerId:null},g.current!==null&&(cancelAnimationFrame(g.current),g.current=null),m.current=!1},[]),Se.jsx("canvas",{ref:a,className:o,style:ze,onPointerDown:Ze,onPointerMove:de,onPointerUp:Q,onPointerCancel:Q,onContextMenu:E=>{E.preventDefault()},onWheel:E=>{E.preventDefault(),E.stopPropagation()}})}function Zi({imageWidth:t,imageHeight:e,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 h=s.current;if(!h)return;const l=new On({canvas:h,imageWidth:t,imageHeight:e,initialViewState:r});return a.current=l,l.setTiles(n),()=>{l.destroy(),a.current=null}},[t,e]),d.useEffect(()=>{const h=a.current;h&&h.setTiles(n)},[n]),d.useEffect(()=>{const h=a.current;!h||!r||h.setViewState(r)},[r]),Se.jsx("canvas",{ref:s,className:i,style:c})}function nr(t){return Math.max(0,Math.min(Math.floor(t.count??0),Math.floor((t.positions?.length??0)/2),t.paletteIndices?.length??0))}function st(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return null;const n=at(e??[]);if(n.length===0)return{count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};const r=nr(t),i=t.positions,o=t.paletteIndices,s=t.ids instanceof Uint32Array&&t.ids.length>=r?t.ids:null,a=new Float32Array(r*2),c=new Uint16Array(r),h=s?new Uint32Array(r):null;let l=0;for(let m=0;m<r;m+=1){const y=i[m*2],x=i[m*2+1];Et(y,x,n)&&(a[l*2]=y,a[l*2+1]=x,c[l]=o[m],h&&(h[l]=s[m]),l+=1)}const g={count:l,positions:a.subarray(0,l*2),paletteIndices:c.subarray(0,l)};return h&&(g.ids=h.subarray(0,l)),g}function rr(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return new Uint32Array(0);const n=at(e??[]);if(n.length===0)return new Uint32Array(0);const r=nr(t);if(r===0)return new Uint32Array(0);const i=t.positions,o=new Uint32Array(r);let s=0;for(let a=0;a<r;a+=1){const c=i[a*2],h=i[a*2+1];Et(c,h,n)&&(o[s]=a,s+=1)}return o.subarray(0,s)}let yt=null;const Ki=`
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 vi(){if(typeof navigator>"u")return!1;const e=navigator;return typeof e.gpu=="object"&&e.gpu!==null}function $n(){if(!vi())return null;const t=navigator.gpu;if(!t||typeof t!="object")return null;const n=t;return typeof n.requestAdapter!="function"?null:n}const we=globalThis.GPUShaderStage?.COMPUTE??4,_e=globalThis.GPUBufferUsage?.STORAGE??128,ye=globalThis.GPUBufferUsage?.COPY_DST??8,Ii=globalThis.GPUBufferUsage?.COPY_SRC??4,_i=globalThis.GPUBufferUsage?.UNIFORM??64,Ui=globalThis.GPUBufferUsage?.MAP_READ??1,Bi=globalThis.GPUMapMode?.READ??1;async function Fi(){const e=$n();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 Li(){return be||(be=(async()=>{const e=$n();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:we,buffer:{type:"read-only-storage"}},{binding:1,visibility:we,buffer:{type:"read-only-storage"}},{binding:2,visibility:we,buffer:{type:"storage"}},{binding:3,visibility:we,buffer:{type:"uniform"}}]}),i=n.createComputePipeline({layout:n.createPipelineLayout({bindGroupLayouts:[r]}),compute:{module:n.createShaderModule({code:Ai}),entryPoint:"main"}});return{device:n,pipeline:i,bindGroupLayout:r}})(),be)}function xe(e,t){return Math.ceil(e/t)*t}async function Hn(e,t,n){const r=await Li();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,u=o*4*Float32Array.BYTES_PER_ELEMENT,c=s*Uint32Array.BYTES_PER_ELEMENT,f=Number(r.device.limits.maxStorageBufferBindingSize);if(a>f||u>f||c>f)return null;const p=r.device.createBuffer({size:xe(a,4),usage:_e|ye}),m=r.device.createBuffer({size:xe(u,4),usage:_e|ye}),b=r.device.createBuffer({size:xe(c,4),usage:_e|Ii}),S=r.device.createBuffer({size:16,usage:_i|ye}),M=r.device.createBuffer({size:xe(c,4),usage:ye|Ui});r.device.queue.writeBuffer(p,0,e.buffer,e.byteOffset,a),r.device.queue.writeBuffer(m,0,n.buffer,n.byteOffset,u),r.device.queue.writeBuffer(S,0,new Uint32Array([s,o,0,0]));const C=r.device.createBindGroup({layout:r.bindGroupLayout,entries:[{binding:0,resource:{buffer:p}},{binding:1,resource:{buffer:m}},{binding:2,resource:{buffer:b}},{binding:3,resource:{buffer:S}}]}),k=r.device.createCommandEncoder(),I=k.beginComputePass();I.setPipeline(r.pipeline),I.setBindGroup(0,C),I.dispatchWorkgroups(Math.ceil(s/256)),I.end(),k.copyBufferToBuffer(b,0,M,0,c),r.device.queue.submit([k.finish()]),await M.mapAsync(Bi);const P=M.getMappedRange(),D=new Uint32Array(P.slice(0));return M.unmap(),p.destroy(),m.destroy(),b.destroy(),S.destroy(),M.destroy(),D}function Bt(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function zi(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 Di(e){const t=[];for(const n of e??[]){const r=zi(n);if(r.length<4)continue;let i=1/0,o=1/0,s=-1/0,a=-1/0;for(const[u,c]of r)u<i&&(i=u),u>s&&(s=u),c<o&&(o=c),c>a&&(a=c);!Number.isFinite(i)||!Number.isFinite(o)||t.push({ring:r,minX:i,minY:o,maxX:s,maxY:a})}return t}function Ni(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],u=n[o][0],c=n[o][1];a>t!=c>t&&e<(u-s)*(t-a)/(c-a||Number.EPSILON)+s&&(r=!r)}return r}function An(e,t,n){for(const r of n)if(!(e<r.minX||e>r.maxX||t<r.minY||t>r.maxY)&&Ni(e,t,r.ring))return!0;return!1}async function Zn(e,t,n={}){const r=Bt(),i=n.bridgeToDraw===!0;if(!e||!e.count||!e.positions||!e.paletteIndices)return{data:null,meta:{mode:"hybrid-webgpu",durationMs:Bt()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}};const o=Di(t??[]);if(o.length===0)return{data:{count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)},meta:{mode:"hybrid-webgpu",durationMs:Bt()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}};const s=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length)),a=e.ids instanceof Uint32Array&&e.ids.length>=s?e.ids:null;if(s===0)return{data:{count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)},meta:{mode:"hybrid-webgpu",durationMs:Bt()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}};const u=new Float32Array(o.length*4);for(let I=0;I<o.length;I+=1){const P=I*4,D=o[I];u[P]=D.minX,u[P+1]=D.minY,u[P+2]=D.maxX,u[P+3]=D.maxY}let c=null,f=!1;try{c=await Hn(e.positions,s,u),f=!!c}catch{c=null,f=!1}if(!c)return{data:ie(e,t),meta:{mode:"hybrid-webgpu",durationMs:Bt()-r,usedWebGpu:!1,candidateCount:s,bridgedToDraw:!1}};let p=0;for(let I=0;I<s;I+=1)c[I]===1&&(p+=1);const m=new Uint32Array(p);if(p>0){let I=0;for(let P=0;P<s;P+=1)c[P]===1&&(m[I]=P,I+=1)}if(p===0){if(i){const I={count:s,positions:e.positions.subarray(0,s*2),paletteIndices:e.paletteIndices.subarray(0,s),drawIndices:new Uint32Array(0)};return a&&(I.ids=a.subarray(0,s)),{data:I,meta:{mode:"hybrid-webgpu",durationMs:Bt()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!0}}}return{data:{count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0),...a?{ids:new Uint32Array(0)}:{}},meta:{mode:"hybrid-webgpu",durationMs:Bt()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!1}}}if(i){const I=new Uint32Array(p);let P=0;for(let K=0;K<p;K+=1){const ct=m[K]??0,it=e.positions[ct*2],q=e.positions[ct*2+1];An(it,q,o)&&(I[P]=ct,P+=1)}const D={count:s,positions:e.positions.subarray(0,s*2),paletteIndices:e.paletteIndices.subarray(0,s),drawIndices:I.subarray(0,P)};return a&&(D.ids=a.subarray(0,s)),{data:D,meta:{mode:"hybrid-webgpu",durationMs:Bt()-r,usedWebGpu:!0,candidateCount:p,bridgedToDraw:!0}}}const b=new Float32Array(p*2),S=new Uint16Array(p),M=a?new Uint32Array(p):null;let C=0;for(let I=0;I<p;I+=1){const P=m[I]??0,D=e.positions[P*2],K=e.positions[P*2+1];An(D,K,o)&&(b[C*2]=D,b[C*2+1]=K,S[C]=e.paletteIndices[P],M&&(M[C]=a[P]),C+=1)}const k={count:C,positions:b.subarray(0,C*2),paletteIndices:S.subarray(0,C)};return M&&(k.ids=M.subarray(0,C)),{data:k,meta:{mode:"hybrid-webgpu",durationMs:Bt()-r,usedWebGpu:!0,candidateCount:p,bridgedToDraw:!1}}}let pt=null,Xe=!0,Kn=1;const Xt=new Map;function Nt(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function jn(){if(!Xe)return null;if(pt)return pt;try{const e=new Worker(new URL(""+(typeof document>"u"?require("url").pathToFileURL(__dirname+"/assets/roi-clip-worker-D3hALtsJ.js").href:new URL("assets/roi-clip-worker-D3hALtsJ.js",document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),typeof document>"u"?require("url").pathToFileURL(__filename).href:Pe&&Pe.tagName.toUpperCase()==="SCRIPT"&&Pe.src||new URL("index.cjs",document.baseURI).href),{type:"module"});return e.addEventListener("message",He),e.addEventListener("error",Ze),pt=e,e}catch{return Xe=!1,null}}function He(e){const t=e.data;if(!t)return;const n=Xt.get(t.id);if(!n)return;if(Xt.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 u=Math.max(0,Math.floor(t.count)),c=new Uint32Array(t.indices).subarray(0,u);n.resolve({indices:c,meta:{mode:"worker",durationMs:Number.isFinite(t.durationMs)?t.durationMs:Nt()-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.ids?new Uint32Array(t.ids):null,a={count:r,positions:i.subarray(0,r*2),paletteIndices:o.subarray(0,r)};s&&(a.ids=s.subarray(0,r)),n.resolve({data:a,meta:{mode:"worker",durationMs:Number.isFinite(t.durationMs)?t.durationMs:Nt()-n.startMs}})}function Ze(){Xe=!1,pt&&(pt.removeEventListener("message",He),pt.removeEventListener("error",Ze),pt.terminate(),pt=null);for(const[,e]of Xt)e.reject(new Error("worker crashed"));Xt.clear()}function ki(){if(pt){pt.removeEventListener("message",He),pt.removeEventListener("error",Ze),pt.terminate(),pt=null;for(const[,e]of Xt)e.reject(new Error("worker terminated"));Xt.clear()}}async function Jn(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return{data:null,meta:{mode:"worker",durationMs:0}};const n=jn();if(!n){const c=Nt();return{data:ie(e,t),meta:{mode:"sync",durationMs:Nt()-c}}}const r=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length)),i=e.positions.slice(0,r*2),o=e.paletteIndices.slice(0,r),s=e.ids instanceof Uint32Array&&e.ids.length>=r?e.ids.slice(0,r):null,a=Kn++,u=Nt();return new Promise((c,f)=>{Xt.set(a,{kind:"data",resolve:c,reject:f,startMs:u});const p={type:"roi-clip-request",id:a,count:r,positions:i.buffer,paletteIndices:o.buffer,ids:s?.buffer,polygons:t??[]},m=[i.buffer,o.buffer];s&&m.push(s.buffer),n.postMessage(p,m)})}async function Xi(e,t){if(!e||!e.count||!e.positions||!e.paletteIndices)return{indices:new Uint32Array(0),meta:{mode:"worker",durationMs:0}};const n=jn();if(!n){const a=Nt();return{indices:qn(e,t),meta:{mode:"sync",durationMs:Nt()-a}}}const r=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length)),i=e.positions.slice(0,r*2),o=Kn++,s=Nt();return new Promise((a,u)=>{Xt.set(o,{kind:"index",resolve:a,reject:u,startMs:s});const c={type:"roi-clip-index-request",id:o,count:r,positions:i.buffer,polygons:t??[]};n.postMessage(c,[i.buffer])})}function Yi(e){if(!Array.isArray(e)||e.length<3)return[];const t=e.map(i=>[Number(i[0]),Number(i[1])]),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 Wi(e){let t=0;for(let n=0;n<e.length-1;n+=1){const[r,i]=e[n],[o,s]=e[n+1];t+=r*s-o*i}return Math.abs(t*.5)}function Oi(e){const t=[];for(let n=0;n<e.length;n+=1){const r=e[n];if(!r?.coordinates?.length)continue;const i=Yi(r.coordinates);if(i.length<4)continue;let o=1/0,s=1/0,a=-1/0,u=-1/0;for(const[c,f]of i)c<o&&(o=c),c>a&&(a=c),f<s&&(s=f),f>u&&(u=f);!Number.isFinite(o)||!Number.isFinite(s)||!Number.isFinite(a)||!Number.isFinite(u)||t.push({regionId:r.id??n,regionIndex:n,ring:i,minX:o,minY:s,maxX:a,maxY:u,area:Math.max(1e-6,Wi(i))})}return t}function Vi(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],u=n[o][0],c=n[o][1];a>t!=c>t&&e<(u-s)*(t-a)/(c-a||Number.EPSILON)+s&&(r=!r)}return r}function Gi(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 Qn(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));let i=null;if(e?.drawIndices instanceof Uint32Array){const m=e.drawIndices;let b=m.length;for(let S=0;S<m.length;S+=1)m[S]<r||(b-=1);if(b===m.length)i=m;else if(b>0){const S=new Uint32Array(b);let M=0;for(let C=0;C<m.length;C+=1){const k=m[C];k>=r||(S[M]=k,M+=1)}i=S}else i=new Uint32Array(0)}const o=i?i.length:r,s=Oi(t??[]);if(!e||o===0||s.length===0)return{groups:[],inputPointCount:o,pointsInsideAnyRegion:0,unmatchedPointCount:o};const a=new Map,u=new Map;let c=0;for(let m=0;m<o;m+=1){const b=i?i[m]:m,S=e.positions[b*2],M=e.positions[b*2+1];let C=null;for(const P of s)S<P.minX||S>P.maxX||M<P.minY||M>P.maxY||Vi(S,M,P.ring)&&(!C||P.area<C.area)&&(C=P);if(!C)continue;c+=1;const k=e.paletteIndices[b]??0,I=a.get(C.regionIndex)??new Map;I.set(k,(I.get(k)??0)+1),a.set(C.regionIndex,I),u.set(C.regionIndex,(u.get(C.regionIndex)??0)+1)}const f=n.includeEmptyRegions??!1,p=[];for(const m of s){const b=u.get(m.regionIndex)??0;if(!f&&b<=0)continue;const S=a.get(m.regionIndex)??new Map,M=Array.from(S.entries()).map(([C,k])=>({termId:Gi(C,n.paletteIndexToTermId),paletteIndex:C,count:k})).sort((C,k)=>k.count-C.count||C.paletteIndex-k.paletteIndex);p.push({regionId:m.regionId,regionIndex:m.regionIndex,totalCount:b,termCounts:M})}return{groups:p,inputPointCount:o,pointsInsideAnyRegion:c,unmatchedPointCount:Math.max(0,o-c)}}function Se(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function qi(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 tr{constructor(t){w(this,"maxConcurrency");w(this,"maxRetries");w(this,"retryBaseDelayMs");w(this,"retryMaxDelayMs");w(this,"onTileLoad");w(this,"onTileError");w(this,"onStateChange");w(this,"authToken");w(this,"destroyed",!1);w(this,"queue",[]);w(this,"queuedByKey",new Map);w(this,"inflight",new Map);w(this,"visibleKeys",new Set);w(this,"timerId",null);w(this,"abortedCount",0);w(this,"retryCount",0);w(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:Se()};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-Se());this.timerId=window.setTimeout(()=>{this.timerId=null,this.pump()},n)}takeNextReadyQueueItem(){if(this.queue.length===0)return null;const t=Se(),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=qi(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,u=this.getRetryDelay(a),c={tile:t.tile,attempt:a,readyAt:Se()+u},f=this.queuedByKey.get(t.tile.key);f?(f.tile=c.tile,f.readyAt=Math.min(f.readyAt,c.readyAt),f.attempt=Math.max(f.attempt,c.attempt)):(this.queue.push(c),this.queuedByKey.set(c.tile.key,c)),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 vn=.35,Ye=.5,$i=256,We=[{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 Hi{constructor(){w(this,"viewportWidth",1);w(this,"viewportHeight",1);w(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,u=(n-this.viewportHeight*.5)/i,c=re(r.rotationDeg),f=Math.cos(c),p=Math.sin(c);return[o+a*f-u*p,s+a*p+u*f]}worldToScreen(t,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,s]=this.getCenter(),a=t-o,u=n-s,c=re(r.rotationDeg),f=Math.cos(c),p=Math.sin(c),m=a*f+u*p,b=-a*p+u*f;return[this.viewportWidth*.5+m*i,this.viewportHeight*.5+b*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,u=2*t*s/this.viewportWidth,c=2*t*s/this.viewportHeight,f=-2*t*o/this.viewportHeight,p=-(a*n+u*r),m=-(c*n+f*r);return new Float32Array([a,c,0,u,f,0,p,m,1])}}function re(e){return e*Math.PI/180}function In(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function qt(e,t,n){const r=e.getUniformLocation(t,n);if(!r)throw new Error(`uniform location lookup failed: ${n}`);return r}function Ue(e,t){return!e||!t?e===t:e.buffer===t.buffer&&e.byteOffset===t.byteOffset&&e.byteLength===t.byteLength}function Oe(e){return e.map(t=>({zoom:t.zoom,size:t.size}))}function _n(e){if(!e)return Oe(We);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?Oe(We):Array.from(t.entries()).sort((n,r)=>n[0]-r[0]).map(([n,r])=>({zoom:n,size:r}))}function Zi(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 Ki(e,t){if(!Number.isFinite(e))return t[0]?.size??Ye;if(t.length===0)return Ye;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],u=t[s];if(e>u.zoom)continue;const c=Math.max(1e-6,u.zoom-a.zoom),f=et((e-a.zoom)/c,0,1);return a.size+(u.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}class er{constructor(t,n,r={}){w(this,"canvas");w(this,"source");w(this,"gl");w(this,"camera",new Hi);w(this,"onViewStateChange");w(this,"onStats");w(this,"onTileError");w(this,"onContextLost");w(this,"onContextRestored");w(this,"resizeObserver");w(this,"tileProgram");w(this,"pointProgram");w(this,"tileScheduler");w(this,"authToken");w(this,"destroyed",!1);w(this,"contextLost",!1);w(this,"frame",null);w(this,"frameSerial",0);w(this,"dragging",!1);w(this,"interactionMode","none");w(this,"rotateLastAngleRad",null);w(this,"pointerId",null);w(this,"lastPointerX",0);w(this,"lastPointerY",0);w(this,"interactionLocked",!1);w(this,"ctrlDragRotate",!0);w(this,"rotationDragSensitivityDegPerPixel",.35);w(this,"maxCacheTiles");w(this,"fitZoom",1);w(this,"minZoom",1e-6);w(this,"maxZoom",1);w(this,"currentTier",0);w(this,"pointCount",0);w(this,"usePointIndices",!1);w(this,"pointBuffersDirty",!0);w(this,"pointPaletteSize",1);w(this,"pointSizeStops",Oe(We));w(this,"lastPointData",null);w(this,"lastPointPalette",null);w(this,"cache",new Map);w(this,"boundPointerDown");w(this,"boundPointerMove");w(this,"boundPointerUp");w(this,"boundWheel");w(this,"boundDoubleClick");w(this,"boundContextMenu");w(this,"boundContextLost");w(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):vn,this.pointSizeStops=_n(r.pointSizeByZoom);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 tr({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(),this.resize()}setAuthToken(t){this.authToken=String(t??""),this.tileScheduler.setAuthToken(this.authToken)}setViewState(t){const n={...t};typeof n.zoom=="number"&&(n.zoom=et(n.zoom,this.minZoom,this.maxZoom)),this.camera.setViewState(n),this.clampViewState(),this.emitViewState(),this.requestRender()}getViewState(){return this.camera.getViewState()}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=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length)),r=t.positions.subarray(0,n*2),i=t.paletteIndices.subarray(0,n),o=t.drawIndices instanceof Uint32Array,s=o?this.sanitizeDrawIndices(t.drawIndices,n):null,a=this.lastPointData;let u=this.pointBuffersDirty||!a||a.count!==n||!Ue(a.positions,r)||!Ue(a.paletteIndices,i),c=this.pointBuffersDirty||o&&(!a?.drawIndices||!Ue(a.drawIndices,s))||!o&&!!a?.drawIndices;if(this.lastPointData={count:n,positions:r,paletteIndices:i,drawIndices:o?s??void 0:void 0},this.contextLost||this.gl.isContextLost())return;const f=this.gl;u&&(f.bindBuffer(f.ARRAY_BUFFER,this.pointProgram.posBuffer),f.bufferData(f.ARRAY_BUFFER,this.lastPointData.positions,f.STATIC_DRAW),f.bindBuffer(f.ARRAY_BUFFER,this.pointProgram.termBuffer),f.bufferData(f.ARRAY_BUFFER,this.lastPointData.paletteIndices,f.STATIC_DRAW),f.bindBuffer(f.ARRAY_BUFFER,null)),o&&c&&(f.bindBuffer(f.ELEMENT_ARRAY_BUFFER,this.pointProgram.indexBuffer),f.bufferData(f.ELEMENT_ARRAY_BUFFER,s??new Uint32Array(0),f.DYNAMIC_DRAW),f.bindBuffer(f.ELEMENT_ARRAY_BUFFER,null)),this.usePointIndices=o,this.pointCount=o?s?.length??0:this.lastPointData.count,(u||c)&&(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}setInteractionLock(t){const n=!!t;this.interactionLocked!==n&&(this.interactionLocked=n,n&&this.cancelDrag())}setPointSizeByZoom(t){const n=_n(t);Zi(this.pointSizeStops,n)||(this.pointSizeStops=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){!Number.isFinite(t)||!Number.isFinite(n)||(this.camera.setCenter(t,n),this.clampViewState(),this.emitViewState(),this.requestRender())}getViewCorners(){return this.camera.getViewCorners()}resetRotation(){const t=this.camera.getViewState();Math.abs(t.rotationDeg)<1e-6||(this.camera.setViewState({rotationDeg:0}),this.clampViewState(),this.emitViewState(),this.requestRender())}getPointSizeByZoom(){const t=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(t),r=Ki(n,this.pointSizeStops);return et(r,Ye,$i)}fitToImage(){const t=this.canvas.getBoundingClientRect(),n=Math.max(1,t.width||1),r=Math.max(1,t.height||1),i=Math.min(n/this.source.width,r/this.source.height),o=Number.isFinite(i)&&i>0?i:1;this.fitZoom=o,this.minZoom=Math.max(this.fitZoom*.5,1e-6),this.maxZoom=Math.max(1,this.fitZoom*8),this.minZoom>this.maxZoom&&(this.minZoom=this.maxZoom);const s=n/o,a=r/o;this.camera.setViewState({zoom:et(o,this.minZoom,this.maxZoom),offsetX:(this.source.width-s)*.5,offsetY:(this.source.height-a)*.5,rotationDeg:0}),this.clampViewState(),this.emitViewState(),this.requestRender()}zoomBy(t,n,r){const i=this.camera.getViewState(),o=et(i.zoom*t,this.minZoom,this.maxZoom);if(o===i.zoom)return;const[s,a]=this.camera.screenToWorld(n,r);this.camera.setViewState({zoom:o});const u=this.camera.getViewport(),c=n-u.width*.5,f=r-u.height*.5,p=re(this.camera.getViewState().rotationDeg),m=Math.cos(p),b=Math.sin(p),S=c/o*m-f/o*b,M=c/o*b+f/o*m;this.camera.setCenter(s-S,a-M),this.clampViewState(),this.emitViewState(),this.requestRender()}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(),u=n*.5,c=r*.5,f=u-i,p=this.source.width-u+i,m=c-o,b=this.source.height-c+o,S=f<=p?et(s,f,p):this.source.width*.5,M=m<=b?et(a,m,b):this.source.height*.5;this.camera.setCenter(S,M)}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 et(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)),u=n[0],c=n[1],f=n[2],p=n[3],m=et(Math.floor(u/r/this.source.tileSize),0,s-1),b=et(Math.floor((f-1)/r/this.source.tileSize),0,s-1),S=et(Math.floor(c/r/this.source.tileSize),0,a-1),M=et(Math.floor((p-1)/r/this.source.tileSize),0,a-1);if(m>b||S>M)return[];const C=(u+f)*.5/r/this.source.tileSize,k=(c+p)*.5/r/this.source.tileSize,I=[];for(let P=S;P<=M;P+=1)for(let D=m;D<=b;D+=1){const K=D*this.source.tileSize*r,ct=P*this.source.tileSize*r,it=Math.min((D+1)*this.source.tileSize,i)*r,q=Math.min((P+1)*this.source.tileSize,o)*r,ut=D-C,Ct=P-k;I.push({key:`${t}/${D}/${P}`,tier:t,x:D,y:P,bounds:[K,ct,it,q],distance2:ut*ut+Ct*Ct,url:$e(this.source,t,D,P)})}return I.sort((P,D)=>P.distance2-D.distance2),I}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=In();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);const u=[];for(const[,m]of this.cache)a.has(m.key)||this.intersectsBounds(m.bounds,s)&&u.push(m);u.sort((m,b)=>m.tier-b.tier);for(const m of u)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 c=0;const f=[];for(const m of o){const b=this.cache.get(m.key);if(!b){f.push(m);continue}b.lastUsed=this.frameSerial,n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,b.texture),n.uniform4f(r.uBounds,b.bounds[0],b.bounds[1],b.bounds[2],b.bounds[3]),n.drawArrays(n.TRIANGLE_STRIP,0,4),c+=1}this.tileScheduler.schedule(f),n.bindTexture(n.TEXTURE_2D,null),n.bindVertexArray(null);let p=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.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),p=this.pointCount),this.onStats){const m=this.tileScheduler.getSnapshot(),b=c,S=f.length,M=u.length+c+(p>0?1:0);this.onStats({tier:this.currentTier,visible:o.length,rendered:c,points:p,fallback:u.length,cache:this.cache.size,inflight:m.inflight,queued:m.queued,retries:m.retries,failed:m.failed,aborted:m.aborted,cacheHits:b,cacheMisses:S,drawCalls:M,frameMs:In()-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)&&(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)),u=this.rotationDragSensitivityDegPerPixel/vn,c=this.camera.getViewState();this.camera.setViewState({rotationDeg:c.rotationDeg-a*180/Math.PI*u})}}else{const i=this.camera.getViewState(),o=Math.max(1e-6,i.zoom),s=re(i.rotationDeg),a=Math.cos(s),u=Math.sin(s),c=(n*a-r*u)/o,f=(n*u+r*a)/o;this.camera.setViewState({offsetX:i.offsetX-c,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.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.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.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=bn(t,`#version 300 es
63
+ `;function ji(){if(typeof navigator>"u")return!1;const t=navigator;return typeof t.gpu=="object"&&t.gpu!==null}function ir(){if(!ji())return null;const e=navigator.gpu;if(!e||typeof e!="object")return null;const n=e;return typeof n.requestAdapter!="function"?null:n}const St=globalThis.GPUShaderStage?.COMPUTE??4,kt=globalThis.GPUBufferUsage?.STORAGE??128,xt=globalThis.GPUBufferUsage?.COPY_DST??8,Ji=globalThis.GPUBufferUsage?.COPY_SRC??4,Qi=globalThis.GPUBufferUsage?.UNIFORM??64,eo=globalThis.GPUBufferUsage?.MAP_READ??1,to=globalThis.GPUMapMode?.READ??1;async function no(){const t=ir();if(!t)return{supported:!1,features:[]};const e=await t.requestAdapter();return e?{supported:!0,adapterName:e.info?.description??e.info?.vendor??"unknown",features:Array.from(e.features),limits:{maxStorageBufferBindingSize:Number(e.limits.maxStorageBufferBindingSize),maxComputeInvocationsPerWorkgroup:Number(e.limits.maxComputeInvocationsPerWorkgroup),maxComputeWorkgroupSizeX:Number(e.limits.maxComputeWorkgroupSizeX)}}:{supported:!1,features:[]}}async function ro(){return yt||(yt=(async()=>{const t=ir();if(!t)return null;const e=await t.requestAdapter();if(!e)return null;const n=await e.requestDevice(),r=n.createBindGroupLayout({entries:[{binding:0,visibility:St,buffer:{type:"read-only-storage"}},{binding:1,visibility:St,buffer:{type:"read-only-storage"}},{binding:2,visibility:St,buffer:{type:"storage"}},{binding:3,visibility:St,buffer:{type:"uniform"}}]}),i=n.createComputePipeline({layout:n.createPipelineLayout({bindGroupLayouts:[r]}),compute:{module:n.createShaderModule({code:Ki}),entryPoint:"main"}});return{device:n,pipeline:i,bindGroupLayout:r}})(),yt)}function Mt(t,e){return Math.ceil(t/e)*e}async function or(t,e,n){const r=await ro();if(!r)return null;const i=Math.max(0,Math.floor(e)),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(t.length/2));if(s===0)return new Uint32Array(0);const a=s*2*Float32Array.BYTES_PER_ELEMENT,c=o*4*Float32Array.BYTES_PER_ELEMENT,h=s*Uint32Array.BYTES_PER_ELEMENT,l=Number(r.device.limits.maxStorageBufferBindingSize);if(a>l||c>l||h>l)return null;const g=r.device.createBuffer({size:Mt(a,4),usage:kt|xt}),m=r.device.createBuffer({size:Mt(c,4),usage:kt|xt}),y=r.device.createBuffer({size:Mt(h,4),usage:kt|Ji}),x=r.device.createBuffer({size:16,usage:Qi|xt}),M=r.device.createBuffer({size:Mt(h,4),usage:xt|eo});r.device.queue.writeBuffer(g,0,t.buffer,t.byteOffset,a),r.device.queue.writeBuffer(m,0,n.buffer,n.byteOffset,c),r.device.queue.writeBuffer(x,0,new Uint32Array([s,o,0,0]));const T=r.device.createBindGroup({layout:r.bindGroupLayout,entries:[{binding:0,resource:{buffer:g}},{binding:1,resource:{buffer:m}},{binding:2,resource:{buffer:y}},{binding:3,resource:{buffer:x}}]}),z=r.device.createCommandEncoder(),v=z.beginComputePass();v.setPipeline(r.pipeline),v.setBindGroup(0,T),v.dispatchWorkgroups(Math.ceil(s/256)),v.end(),z.copyBufferToBuffer(y,0,M,0,h),r.device.queue.submit([z.finish()]),await M.mapAsync(to);const P=M.getMappedRange(),F=new Uint32Array(P.slice(0));return M.unmap(),g.destroy(),m.destroy(),y.destroy(),x.destroy(),M.destroy(),F}function Fe(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}async function sr(t,e,n={}){const r=Fe(),i=n.bridgeToDraw===!0;if(!t||!t.count||!t.positions||!t.paletteIndices)return{data:null,meta:{mode:"hybrid-webgpu",durationMs:Fe()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}};const o=at(e??[]);if(o.length===0)return{data:{count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)},meta:{mode:"hybrid-webgpu",durationMs:Fe()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}};const s=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length)),a=t.ids instanceof Uint32Array&&t.ids.length>=s?t.ids:null;if(s===0)return{data:{count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)},meta:{mode:"hybrid-webgpu",durationMs:Fe()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}};const c=new Float32Array(o.length*4);for(let v=0;v<o.length;v+=1){const P=v*4,F=o[v];c[P]=F.minX,c[P+1]=F.minY,c[P+2]=F.maxX,c[P+3]=F.maxY}let h=null,l=!1;try{h=await or(t.positions,s,c),l=!!h}catch{h=null,l=!1}if(!h)return{data:st(t,e),meta:{mode:"hybrid-webgpu",durationMs:Fe()-r,usedWebGpu:!1,candidateCount:s,bridgedToDraw:!1}};let g=0;for(let v=0;v<s;v+=1)h[v]===1&&(g+=1);const m=new Uint32Array(g);if(g>0){let v=0;for(let P=0;P<s;P+=1)h[P]===1&&(m[v]=P,v+=1)}if(g===0){if(i){const v={count:s,positions:t.positions.subarray(0,s*2),paletteIndices:t.paletteIndices.subarray(0,s),drawIndices:new Uint32Array(0)};return a&&(v.ids=a.subarray(0,s)),{data:v,meta:{mode:"hybrid-webgpu",durationMs:Fe()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!0}}}return{data:{count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0),...a?{ids:new Uint32Array(0)}:{}},meta:{mode:"hybrid-webgpu",durationMs:Fe()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!1}}}if(i){const v=new Uint32Array(g);let P=0;for(let G=0;G<g;G+=1){const le=m[G]??0,ge=t.positions[le*2],he=t.positions[le*2+1];Et(ge,he,o)&&(v[P]=le,P+=1)}const F={count:s,positions:t.positions.subarray(0,s*2),paletteIndices:t.paletteIndices.subarray(0,s),drawIndices:v.subarray(0,P)};return a&&(F.ids=a.subarray(0,s)),{data:F,meta:{mode:"hybrid-webgpu",durationMs:Fe()-r,usedWebGpu:!0,candidateCount:g,bridgedToDraw:!0}}}const y=new Float32Array(g*2),x=new Uint16Array(g),M=a?new Uint32Array(g):null;let T=0;for(let v=0;v<g;v+=1){const P=m[v]??0,F=t.positions[P*2],G=t.positions[P*2+1];Et(F,G,o)&&(y[T*2]=F,y[T*2+1]=G,x[T]=t.paletteIndices[P],M&&(M[T]=a[P]),T+=1)}const z={count:T,positions:y.subarray(0,T*2),paletteIndices:x.subarray(0,T)};return M&&(z.ids=M.subarray(0,T)),{data:z,meta:{mode:"hybrid-webgpu",durationMs:Fe()-r,usedWebGpu:!0,candidateCount:g,bridgedToDraw:!1}}}let xe=null,qt=!0,ar=1;const qe=new Map;function Ge(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function ur(){if(!qt)return null;if(xe)return xe;try{const t=new Worker(new URL(""+(typeof document>"u"?require("url").pathToFileURL(__dirname+"/assets/roi-clip-worker-BRaTL8Jd.js").href:new URL("assets/roi-clip-worker-BRaTL8Jd.js",document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),typeof document>"u"?require("url").pathToFileURL(__filename).href:Bt&&Bt.tagName.toUpperCase()==="SCRIPT"&&Bt.src||new URL("index.cjs",document.baseURI).href),{type:"module"});return t.addEventListener("message",tn),t.addEventListener("error",nn),xe=t,t}catch{return qt=!1,null}}function tn(t){const e=t.data;if(!e)return;const n=qe.get(e.id);if(!n)return;if(qe.delete(e.id),e.type==="roi-clip-failure"){n.reject(new Error(e.error||"worker clip failed"));return}if(e.type==="roi-clip-index-success"){if(n.kind!=="index"){n.reject(new Error("worker response mismatch: expected point data result"));return}const c=Math.max(0,Math.floor(e.count)),h=new Uint32Array(e.indices).subarray(0,c);n.resolve({indices:h,meta:{mode:"worker",durationMs:Number.isFinite(e.durationMs)?e.durationMs:Ge()-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(e.count)),i=new Float32Array(e.positions),o=new Uint16Array(e.paletteIndices),s=e.ids?new Uint32Array(e.ids):null,a={count:r,positions:i.subarray(0,r*2),paletteIndices:o.subarray(0,r)};s&&(a.ids=s.subarray(0,r)),n.resolve({data:a,meta:{mode:"worker",durationMs:Number.isFinite(e.durationMs)?e.durationMs:Ge()-n.startMs}})}function nn(){qt=!1,xe&&(xe.removeEventListener("message",tn),xe.removeEventListener("error",nn),xe.terminate(),xe=null);for(const[,t]of qe)t.reject(new Error("worker crashed"));qe.clear()}function io(){if(xe){xe.removeEventListener("message",tn),xe.removeEventListener("error",nn),xe.terminate(),xe=null;for(const[,t]of qe)t.reject(new Error("worker terminated"));qe.clear()}}async function cr(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return{data:null,meta:{mode:"worker",durationMs:0}};const n=ur();if(!n){const h=Ge();return{data:st(t,e),meta:{mode:"sync",durationMs:Ge()-h}}}const r=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length)),i=t.positions.slice(0,r*2),o=t.paletteIndices.slice(0,r),s=t.ids instanceof Uint32Array&&t.ids.length>=r?t.ids.slice(0,r):null,a=ar++,c=Ge();return new Promise((h,l)=>{qe.set(a,{kind:"data",resolve:h,reject:l,startMs:c});const g={type:"roi-clip-request",id:a,count:r,positions:i.buffer,paletteIndices:o.buffer,ids:s?.buffer,polygons:e??[]},m=[i.buffer,o.buffer];s&&m.push(s.buffer),n.postMessage(g,m)})}async function oo(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return{indices:new Uint32Array(0),meta:{mode:"worker",durationMs:0}};const n=ur();if(!n){const a=Ge();return{indices:rr(t,e),meta:{mode:"sync",durationMs:Ge()-a}}}const r=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length)),i=t.positions.slice(0,r*2),o=ar++,s=Ge();return new Promise((a,c)=>{qe.set(o,{kind:"index",resolve:a,reject:c,startMs:s});const h={type:"roi-clip-index-request",id:o,count:r,positions:i.buffer,polygons:e??[]};n.postMessage(h,[i.buffer])})}function so(t){const e=[];for(let n=0;n<t.length;n+=1){const r=t[n],i=at([r?.coordinates]);if(i.length===0)continue;let o=0;for(const s of i)o+=s.area;e.push({regionId:r.id??n,regionIndex:n,polygons:i,area:Math.max(1e-6,o)})}return e}function ao(t,e){if(Array.isArray(e)){const n=e[t];if(typeof n=="string"&&n.length>0)return n}if(e instanceof Map){const n=e.get(t);if(typeof n=="string"&&n.length>0)return n}return String(t)}function lr(t,e,n={}){const r=Math.max(0,Math.min(Math.floor(t?.count??0),Math.floor((t?.positions?.length??0)/2),t?.paletteIndices?.length??0));let i=null;if(t?.drawIndices instanceof Uint32Array){const m=t.drawIndices;let y=m.length;for(let x=0;x<m.length;x+=1)m[x]<r||(y-=1);if(y===m.length)i=m;else if(y>0){const x=new Uint32Array(y);let M=0;for(let T=0;T<m.length;T+=1){const z=m[T];z>=r||(x[M]=z,M+=1)}i=x}else i=new Uint32Array(0)}const o=i?i.length:r,s=so(e??[]);if(!t||o===0||s.length===0)return{groups:[],inputPointCount:o,pointsInsideAnyRegion:0,unmatchedPointCount:o};const a=new Map,c=new Map;let h=0;for(let m=0;m<o;m+=1){const y=i?i[m]:m,x=t.positions[y*2],M=t.positions[y*2+1];let T=null;for(const P of s){let F=!1;for(const G of P.polygons)if(jt(x,M,G)){F=!0;break}F&&(!T||P.area<T.area)&&(T=P)}if(!T)continue;h+=1;const z=t.paletteIndices[y]??0,v=a.get(T.regionIndex)??new Map;v.set(z,(v.get(z)??0)+1),a.set(T.regionIndex,v),c.set(T.regionIndex,(c.get(T.regionIndex)??0)+1)}const l=n.includeEmptyRegions??!1,g=[];for(const m of s){const y=c.get(m.regionIndex)??0;if(!l&&y<=0)continue;const x=a.get(m.regionIndex)??new Map,M=Array.from(x.entries()).map(([T,z])=>({termId:ao(T,n.paletteIndexToTermId),paletteIndex:T,count:z})).sort((T,z)=>z.count-T.count||T.paletteIndex-z.paletteIndex);g.push({regionId:m.regionId,regionIndex:m.regionIndex,totalCount:y,termCounts:M})}return{groups:g,inputPointCount:o,pointsInsideAnyRegion:h,unmatchedPointCount:Math.max(0,o-h)}}function Tt(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function uo(t,e){if(!e)return!1;try{const r=new URL(t,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 hr{constructor(e){w(this,"maxConcurrency");w(this,"maxRetries");w(this,"retryBaseDelayMs");w(this,"retryMaxDelayMs");w(this,"onTileLoad");w(this,"onTileError");w(this,"onStateChange");w(this,"authToken");w(this,"destroyed",!1);w(this,"queue",[]);w(this,"queuedByKey",new Map);w(this,"inflight",new Map);w(this,"visibleKeys",new Set);w(this,"timerId",null);w(this,"abortedCount",0);w(this,"retryCount",0);w(this,"failedCount",0);this.maxConcurrency=Math.max(1,Math.floor(e.maxConcurrency??12)),this.maxRetries=Math.max(0,Math.floor(e.maxRetries??2)),this.retryBaseDelayMs=Math.max(10,Math.floor(e.retryBaseDelayMs??120)),this.retryMaxDelayMs=Math.max(this.retryBaseDelayMs,Math.floor(e.retryMaxDelayMs??1200)),this.authToken=e.authToken??"",this.onTileLoad=e.onTileLoad,this.onTileError=e.onTileError,this.onStateChange=e.onStateChange}setAuthToken(e){this.authToken=String(e??"")}schedule(e){if(this.destroyed)return;const n=new Set;for(const r of e)n.add(r.key);this.visibleKeys=n,this.dropInvisibleQueued(n),this.abortInvisibleInflight(n);for(const r of e){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:Tt()};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[,e]of this.inflight)e.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(e){if(this.queue.length===0)return;const n=[];for(const r of this.queue){if(!e.has(r.tile.key)){this.queuedByKey.delete(r.tile.key);continue}n.push(r)}this.queue=n}abortInvisibleInflight(e){for(const[n,r]of this.inflight)e.has(n)||(this.inflight.delete(n),this.abortedCount+=1,r.controller.abort())}sortQueue(){this.queue.sort((e,n)=>e.readyAt!==n.readyAt?e.readyAt-n.readyAt:e.tile.distance2!==n.tile.distance2?e.tile.distance2-n.tile.distance2:e.tile.tier!==n.tile.tier?n.tile.tier-e.tile.tier:e.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 e=this.queue[0]?.readyAt;if(typeof e!="number")return;const n=Math.max(0,e-Tt());this.timerId=window.setTimeout(()=>{this.timerId=null,this.pump()},n)}takeNextReadyQueueItem(){if(this.queue.length===0)return null;const e=Tt(),n=this.queue[0];return!n||n.readyAt>e?null:(this.queue.shift(),this.queuedByKey.delete(n.tile.key),n)}startFetch(e){const n=new AbortController,r={tile:e.tile,attempt:e.attempt,controller:n};this.inflight.set(e.tile.key,r),this.emitStateChange();const i=uo(e.tile.url,this.authToken);fetch(e.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(e.tile.key)){o.close();return}this.onTileLoad(e.tile,o)}).catch(o=>{if(n.signal.aborted||this.destroyed)return;if(e.attempt<this.maxRetries&&this.visibleKeys.has(e.tile.key)){this.retryCount+=1;const a=e.attempt+1,c=this.getRetryDelay(a),h={tile:e.tile,attempt:a,readyAt:Tt()+c},l=this.queuedByKey.get(e.tile.key);l?(l.tile=h.tile,l.readyAt=Math.min(l.readyAt,h.readyAt),l.attempt=Math.max(l.attempt,h.attempt)):(this.queue.push(h),this.queuedByKey.set(h.tile.key,h)),this.sortQueue();return}this.failedCount+=1,this.onTileError?.(e.tile,o,e.attempt+1)}).finally(()=>{this.inflight.delete(e.tile.key),this.pump(),this.emitStateChange()})}getRetryDelay(e){const n=Math.max(0,e-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 Dn=.35,Ht=.5,co=256,$t=[{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 lo{constructor(){w(this,"viewportWidth",1);w(this,"viewportHeight",1);w(this,"viewState",{zoom:1,offsetX:0,offsetY:0,rotationDeg:0})}setViewport(e,n){this.viewportWidth=Math.max(1,e),this.viewportHeight=Math.max(1,n)}getViewport(){return{width:this.viewportWidth,height:this.viewportHeight}}setViewState(e){typeof e.zoom=="number"&&(this.viewState.zoom=Math.max(1e-4,e.zoom)),typeof e.offsetX=="number"&&(this.viewState.offsetX=e.offsetX),typeof e.offsetY=="number"&&(this.viewState.offsetY=e.offsetY),typeof e.rotationDeg=="number"&&Number.isFinite(e.rotationDeg)&&(this.viewState.rotationDeg=e.rotationDeg)}getViewState(){return{...this.viewState}}getCenter(){const e=Math.max(1e-6,this.viewState.zoom);return[this.viewState.offsetX+this.viewportWidth/(2*e),this.viewState.offsetY+this.viewportHeight/(2*e)]}setCenter(e,n){const r=Math.max(1e-6,this.viewState.zoom);this.viewState.offsetX=e-this.viewportWidth/(2*r),this.viewState.offsetY=n-this.viewportHeight/(2*r)}screenToWorld(e,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,s]=this.getCenter(),a=(e-this.viewportWidth*.5)/i,c=(n-this.viewportHeight*.5)/i,h=ot(r.rotationDeg),l=Math.cos(h),g=Math.sin(h);return[o+a*l-c*g,s+a*g+c*l]}worldToScreen(e,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,s]=this.getCenter(),a=e-o,c=n-s,h=ot(r.rotationDeg),l=Math.cos(h),g=Math.sin(h),m=a*l+c*g,y=-a*g+c*l;return[this.viewportWidth*.5+m*i,this.viewportHeight*.5+y*i]}getViewCorners(){const e=this.viewportWidth,n=this.viewportHeight;return[this.screenToWorld(0,0),this.screenToWorld(e,0),this.screenToWorld(e,n),this.screenToWorld(0,n)]}getMatrix(){const e=Math.max(1e-6,this.viewState.zoom),[n,r]=this.getCenter(),i=ot(this.viewState.rotationDeg),o=Math.cos(i),s=Math.sin(i),a=2*e*o/this.viewportWidth,c=2*e*s/this.viewportWidth,h=2*e*s/this.viewportHeight,l=-2*e*o/this.viewportHeight,g=-(a*n+c*r),m=-(h*n+l*r);return new Float32Array([a,h,0,c,l,0,g,m,1])}}function ot(t){return t*Math.PI/180}function Nn(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function Ve(t,e,n){const r=t.getUniformLocation(e,n);if(!r)throw new Error(`uniform location lookup failed: ${n}`);return r}function Dt(t,e){return!t||!e?t===e:t.buffer===e.buffer&&t.byteOffset===e.byteOffset&&t.byteLength===e.byteLength}function Zt(t){return t.map(e=>({zoom:e.zoom,size:e.size}))}function Wn(t){if(!t)return Zt($t);const e=new Map;for(const[n,r]of Object.entries(t)){const i=Number(n),o=Number(r);!Number.isFinite(i)||!Number.isFinite(o)||o<=0||e.set(i,o)}return e.size===0?Zt($t):Array.from(e.entries()).sort((n,r)=>n[0]-r[0]).map(([n,r])=>({zoom:n,size:r}))}function ho(t,e){if(t===e)return!0;if(t.length!==e.length)return!1;for(let n=0;n<t.length;n+=1)if(t[n].zoom!==e[n].zoom||t[n].size!==e[n].size)return!1;return!0}function fo(t,e){if(!Number.isFinite(t))return e[0]?.size??Ht;if(e.length===0)return Ht;if(e.length===1||t<=e[0].zoom)return e[0].size;for(let s=1;s<e.length;s+=1){const a=e[s-1],c=e[s];if(t>c.zoom)continue;const h=Math.max(1e-6,c.zoom-a.zoom),l=J((t-a.zoom)/h,0,1);return a.size+(c.size-a.size)*l}const n=e[e.length-1],r=e[e.length-2],i=Math.max(1e-6,n.zoom-r.zoom),o=(n.size-r.size)/i;return n.size+(t-n.zoom)*o}const mo=.1,go=5;function Xn(t){return typeof t!="number"||!Number.isFinite(t)?1:J(t,mo,go)}class fr{constructor(e,n,r={}){w(this,"canvas");w(this,"source");w(this,"gl");w(this,"camera",new lo);w(this,"onViewStateChange");w(this,"onStats");w(this,"onTileError");w(this,"onContextLost");w(this,"onContextRestored");w(this,"resizeObserver");w(this,"tileProgram");w(this,"pointProgram");w(this,"tileScheduler");w(this,"authToken");w(this,"destroyed",!1);w(this,"contextLost",!1);w(this,"frame",null);w(this,"frameSerial",0);w(this,"dragging",!1);w(this,"interactionMode","none");w(this,"rotateLastAngleRad",null);w(this,"pointerId",null);w(this,"lastPointerX",0);w(this,"lastPointerY",0);w(this,"interactionLocked",!1);w(this,"ctrlDragRotate",!0);w(this,"rotationDragSensitivityDegPerPixel",.35);w(this,"maxCacheTiles");w(this,"fitZoom",1);w(this,"minZoom",1e-6);w(this,"maxZoom",1);w(this,"currentTier",0);w(this,"pointCount",0);w(this,"usePointIndices",!1);w(this,"pointBuffersDirty",!0);w(this,"pointPaletteSize",1);w(this,"pointSizeStops",Zt($t));w(this,"pointStrokeScale",1);w(this,"lastPointData",null);w(this,"lastPointPalette",null);w(this,"cache",new Map);w(this,"boundPointerDown");w(this,"boundPointerMove");w(this,"boundPointerUp");w(this,"boundWheel");w(this,"boundDoubleClick");w(this,"boundContextMenu");w(this,"boundContextLost");w(this,"boundContextRestored");this.canvas=e,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):Dn,this.pointSizeStops=Wn(r.pointSizeByZoom),this.pointStrokeScale=Xn(r.pointStrokeScale);const i=e.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 hr({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(e),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),e.addEventListener("pointerdown",this.boundPointerDown),e.addEventListener("pointermove",this.boundPointerMove),e.addEventListener("pointerup",this.boundPointerUp),e.addEventListener("pointercancel",this.boundPointerUp),e.addEventListener("wheel",this.boundWheel,{passive:!1}),e.addEventListener("dblclick",this.boundDoubleClick),e.addEventListener("contextmenu",this.boundContextMenu),e.addEventListener("webglcontextlost",this.boundContextLost),e.addEventListener("webglcontextrestored",this.boundContextRestored),this.fitToImage(),this.resize()}setAuthToken(e){this.authToken=String(e??""),this.tileScheduler.setAuthToken(this.authToken)}setViewState(e){const n={...e};typeof n.zoom=="number"&&(n.zoom=J(n.zoom,this.minZoom,this.maxZoom)),this.camera.setViewState(n),this.clampViewState(),this.emitViewState(),this.requestRender()}getViewState(){return this.camera.getViewState()}setPointPalette(e){if(!e||e.length===0){this.lastPointPalette=null;return}if(this.lastPointPalette=new Uint8Array(e),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(e){if(!e||!e.count||!e.positions||!e.paletteIndices){this.lastPointData=null,this.pointCount=0,this.usePointIndices=!1,this.requestRender();return}const n=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length)),r=e.positions.subarray(0,n*2),i=e.paletteIndices.subarray(0,n),o=e.drawIndices instanceof Uint32Array,s=o?this.sanitizeDrawIndices(e.drawIndices,n):null,a=this.lastPointData;let c=this.pointBuffersDirty||!a||a.count!==n||!Dt(a.positions,r)||!Dt(a.paletteIndices,i),h=this.pointBuffersDirty||o&&(!a?.drawIndices||!Dt(a.drawIndices,s))||!o&&!!a?.drawIndices;if(this.lastPointData={count:n,positions:r,paletteIndices:i,drawIndices:o?s??void 0:void 0},this.contextLost||this.gl.isContextLost())return;const l=this.gl;c&&(l.bindBuffer(l.ARRAY_BUFFER,this.pointProgram.posBuffer),l.bufferData(l.ARRAY_BUFFER,this.lastPointData.positions,l.STATIC_DRAW),l.bindBuffer(l.ARRAY_BUFFER,this.pointProgram.termBuffer),l.bufferData(l.ARRAY_BUFFER,this.lastPointData.paletteIndices,l.STATIC_DRAW),l.bindBuffer(l.ARRAY_BUFFER,null)),o&&h&&(l.bindBuffer(l.ELEMENT_ARRAY_BUFFER,this.pointProgram.indexBuffer),l.bufferData(l.ELEMENT_ARRAY_BUFFER,s??new Uint32Array(0),l.DYNAMIC_DRAW),l.bindBuffer(l.ELEMENT_ARRAY_BUFFER,null)),this.usePointIndices=o,this.pointCount=o?s?.length??0:this.lastPointData.count,(c||h)&&(this.pointBuffersDirty=!1),this.requestRender()}sanitizeDrawIndices(e,n){if(n<=0||e.length===0)return new Uint32Array(0);let r=e.length;for(let s=0;s<e.length;s+=1)e[s]<n||(r-=1);if(r===e.length)return e;if(r<=0)return new Uint32Array(0);const i=new Uint32Array(r);let o=0;for(let s=0;s<e.length;s+=1){const a=e[s];a>=n||(i[o]=a,o+=1)}return i}setInteractionLock(e){const n=!!e;this.interactionLocked!==n&&(this.interactionLocked=n,n&&this.cancelDrag())}setPointSizeByZoom(e){const n=Wn(e);ho(this.pointSizeStops,n)||(this.pointSizeStops=n,this.requestRender())}setPointStrokeScale(e){const n=Xn(e);this.pointStrokeScale!==n&&(this.pointStrokeScale=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(e,n){const r=this.canvas.getBoundingClientRect(),i=e-r.left-r.width*.5,o=n-r.top-r.height*.5;return Math.atan2(o,i)}screenToWorld(e,n){const r=this.canvas.getBoundingClientRect(),i=e-r.left,o=n-r.top;return this.camera.screenToWorld(i,o)}worldToScreen(e,n){return this.camera.worldToScreen(e,n)}setViewCenter(e,n){!Number.isFinite(e)||!Number.isFinite(n)||(this.camera.setCenter(e,n),this.clampViewState(),this.emitViewState(),this.requestRender())}getViewCorners(){return this.camera.getViewCorners()}resetRotation(){const e=this.camera.getViewState();Math.abs(e.rotationDeg)<1e-6||(this.camera.setViewState({rotationDeg:0}),this.clampViewState(),this.emitViewState(),this.requestRender())}getPointSizeByZoom(){const e=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(e),r=fo(n,this.pointSizeStops);return J(r,Ht,co)}fitToImage(){const e=this.canvas.getBoundingClientRect(),n=Math.max(1,e.width||1),r=Math.max(1,e.height||1),i=Math.min(n/this.source.width,r/this.source.height),o=Number.isFinite(i)&&i>0?i:1;this.fitZoom=o,this.minZoom=Math.max(this.fitZoom*.5,1e-6),this.maxZoom=Math.max(1,this.fitZoom*8),this.minZoom>this.maxZoom&&(this.minZoom=this.maxZoom);const s=n/o,a=r/o;this.camera.setViewState({zoom:J(o,this.minZoom,this.maxZoom),offsetX:(this.source.width-s)*.5,offsetY:(this.source.height-a)*.5,rotationDeg:0}),this.clampViewState(),this.emitViewState(),this.requestRender()}zoomBy(e,n,r){const i=this.camera.getViewState(),o=J(i.zoom*e,this.minZoom,this.maxZoom);if(o===i.zoom)return;const[s,a]=this.camera.screenToWorld(n,r);this.camera.setViewState({zoom:o});const c=this.camera.getViewport(),h=n-c.width*.5,l=r-c.height*.5,g=ot(this.camera.getViewState().rotationDeg),m=Math.cos(g),y=Math.sin(g),x=h/o*m-l/o*y,M=h/o*y+l/o*m;this.camera.setCenter(s-x,a-M),this.clampViewState(),this.emitViewState(),this.requestRender()}clampViewState(){const e=this.getViewBounds(),n=Math.max(1e-6,e[2]-e[0]),r=Math.max(1e-6,e[3]-e[1]),i=n*.2,o=r*.2,[s,a]=this.camera.getCenter(),c=n*.5,h=r*.5,l=c-i,g=this.source.width-c+i,m=h-o,y=this.source.height-h+o,x=l<=g?J(s,l,g):this.source.width*.5,M=m<=y?J(a,m,y):this.source.height*.5;this.camera.setCenter(x,M)}emitViewState(){this.onViewStateChange?.(this.camera.getViewState())}selectTier(){const e=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(e);return J(Math.floor(n),0,this.source.maxTierZoom)}getViewBounds(){const e=this.camera.getViewCorners();let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[s,a]of e)s<n&&(n=s),s>i&&(i=s),a<r&&(r=a),a>o&&(o=a);return[n,r,i,o]}intersectsBounds(e,n){return!(e[2]<=n[0]||e[0]>=n[2]||e[3]<=n[1]||e[1]>=n[3])}getVisibleTiles(){const e=this.selectTier();this.currentTier=e;const n=this.getViewBounds(),r=Math.pow(2,this.source.maxTierZoom-e),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],h=n[1],l=n[2],g=n[3],m=J(Math.floor(c/r/this.source.tileSize),0,s-1),y=J(Math.floor((l-1)/r/this.source.tileSize),0,s-1),x=J(Math.floor(h/r/this.source.tileSize),0,a-1),M=J(Math.floor((g-1)/r/this.source.tileSize),0,a-1);if(m>y||x>M)return[];const T=(c+l)*.5/r/this.source.tileSize,z=(h+g)*.5/r/this.source.tileSize,v=[];for(let P=x;P<=M;P+=1)for(let F=m;F<=y;F+=1){const G=F*this.source.tileSize*r,le=P*this.source.tileSize*r,ge=Math.min((F+1)*this.source.tileSize,i)*r,he=Math.min((P+1)*this.source.tileSize,o)*r,N=F-T,ze=P-z;v.push({key:`${e}/${F}/${P}`,tier:e,x:F,y:P,bounds:[G,le,ge,he],distance2:N*N+ze*ze,url:en(this.source,e,F,P)})}return v.sort((P,F)=>P.distance2-F.distance2),v}trimCache(){if(this.cache.size<=this.maxCacheTiles)return;const e=Array.from(this.cache.entries());e.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]=e[r];this.gl.deleteTexture(o.texture),this.cache.delete(i)}}render(){if(this.destroyed||this.contextLost||this.gl.isContextLost())return;const e=Nn();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);const c=[];for(const[,m]of this.cache)a.has(m.key)||this.intersectsBounds(m.bounds,s)&&c.push(m);c.sort((m,y)=>m.tier-y.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 h=0;const l=[];for(const m of o){const y=this.cache.get(m.key);if(!y){l.push(m);continue}y.lastUsed=this.frameSerial,n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,y.texture),n.uniform4f(r.uBounds,y.bounds[0],y.bounds[1],y.bounds[2],y.bounds[3]),n.drawArrays(n.TRIANGLE_STRIP,0,4),h+=1}this.tileScheduler.schedule(l),n.bindTexture(n.TEXTURE_2D,null),n.bindVertexArray(null);let g=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),g=this.pointCount),this.onStats){const m=this.tileScheduler.getSnapshot(),y=h,x=l.length,M=c.length+h+(g>0?1:0);this.onStats({tier:this.currentTier,visible:o.length,rendered:h,points:g,fallback:c.length,cache:this.cache.size,inflight:m.inflight,queued:m.queued,retries:m.retries,failed:m.failed,aborted:m.aborted,cacheHits:y,cacheMisses:x,drawCalls:M,frameMs:Nn()-e})}}requestRender(){this.frame!==null||this.destroyed||this.contextLost||this.gl.isContextLost()||(this.frame=requestAnimationFrame(()=>{this.frame=null,this.render()}))}resize(){const e=this.canvas.getBoundingClientRect(),n=Math.max(1,e.width||this.canvas.clientWidth||1),r=Math.max(1,e.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(e){if(this.interactionLocked)return;const n=this.ctrlDragRotate&&(e.ctrlKey||e.metaKey);(e.button===0||n&&e.button===2)&&(n&&e.preventDefault(),this.dragging=!0,this.interactionMode=n?"rotate":"pan",this.pointerId=e.pointerId,this.lastPointerX=e.clientX,this.lastPointerY=e.clientY,this.rotateLastAngleRad=this.interactionMode==="rotate"?this.getPointerAngleRad(e.clientX,e.clientY):null,this.canvas.classList.add("dragging"),this.canvas.setPointerCapture(e.pointerId))}onPointerMove(e){if(this.interactionLocked||!this.dragging||e.pointerId!==this.pointerId)return;const n=e.clientX-this.lastPointerX,r=e.clientY-this.lastPointerY;if(this.lastPointerX=e.clientX,this.lastPointerY=e.clientY,this.interactionMode==="rotate"){const i=this.getPointerAngleRad(e.clientX,e.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/Dn,h=this.camera.getViewState();this.camera.setViewState({rotationDeg:h.rotationDeg-a*180/Math.PI*c})}}else{const i=this.camera.getViewState(),o=Math.max(1e-6,i.zoom),s=ot(i.rotationDeg),a=Math.cos(s),c=Math.sin(s),h=(n*a-r*c)/o,l=(n*c+r*a)/o;this.camera.setViewState({offsetX:i.offsetX-h,offsetY:i.offsetY-l})}this.clampViewState(),this.emitViewState(),this.requestRender()}onPointerUp(e){this.interactionLocked||e.pointerId===this.pointerId&&this.cancelDrag()}onWheel(e){if(this.interactionLocked){e.preventDefault();return}e.preventDefault();const n=this.canvas.getBoundingClientRect(),r=e.clientX-n.left,i=e.clientY-n.top,o=e.deltaY<0?1.12:.89;this.zoomBy(o,r,i)}onDoubleClick(e){if(this.interactionLocked)return;const n=this.canvas.getBoundingClientRect(),r=e.clientX-n.left,i=e.clientY-n.top;this.zoomBy(e.shiftKey?.8:1.25,r,i)}onContextMenu(e){(this.dragging||e.ctrlKey||e.metaKey)&&e.preventDefault()}onWebGlContextLost(e){e.preventDefault(),!(this.destroyed||this.contextLost)&&(this.contextLost=!0,this.pointBuffersDirty=!0,this.frame!==null&&(cancelAnimationFrame(this.frame),this.frame=null),this.cancelDrag(),this.tileScheduler.clear(),this.cache.clear(),this.onContextLost?.())}onWebGlContextRestored(e){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.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[,e]of this.cache)this.gl.deleteTexture(e.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.indexBuffer),this.gl.deleteTexture(this.pointProgram.paletteTexture),this.gl.deleteVertexArray(this.pointProgram.vao),this.gl.deleteProgram(this.pointProgram.program)}this.cache.clear()}}initTileProgram(){const e=this.gl,i=Pn(e,`#version 300 es
64
64
  precision highp float;
65
65
  in vec2 aUnit;
66
66
  in vec2 aUv;
@@ -82,7 +82,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
82
82
  out vec4 outColor;
83
83
  void main() {
84
84
  outColor = texture(uTexture, vUv);
85
- }`),o=qt(t,i,"uCamera"),s=qt(t,i,"uBounds"),a=qt(t,i,"uTexture"),u=t.createVertexArray(),c=t.createBuffer();if(!u||!c)throw new Error("buffer allocation failed");t.bindVertexArray(u),t.bindBuffer(t.ARRAY_BUFFER,c),t.bufferData(t.ARRAY_BUFFER,new Float32Array([0,0,0,0,1,0,1,0,0,1,0,1,1,1,1,1]),t.STATIC_DRAW);const f=t.getAttribLocation(i,"aUnit"),p=t.getAttribLocation(i,"aUv");if(f<0||p<0)throw new Error("tile attribute lookup failed");return t.enableVertexAttribArray(f),t.enableVertexAttribArray(p),t.vertexAttribPointer(f,2,t.FLOAT,!1,16,0),t.vertexAttribPointer(p,2,t.FLOAT,!1,16,8),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null),{program:i,vao:u,vbo:c,uCamera:o,uBounds:s,uTexture:a}}initPointProgram(){const t=this.gl,i=bn(t,`#version 300 es
85
+ }`),o=Ve(e,i,"uCamera"),s=Ve(e,i,"uBounds"),a=Ve(e,i,"uTexture"),c=e.createVertexArray(),h=e.createBuffer();if(!c||!h)throw new Error("buffer allocation failed");e.bindVertexArray(c),e.bindBuffer(e.ARRAY_BUFFER,h),e.bufferData(e.ARRAY_BUFFER,new Float32Array([0,0,0,0,1,0,1,0,0,1,0,1,1,1,1,1]),e.STATIC_DRAW);const l=e.getAttribLocation(i,"aUnit"),g=e.getAttribLocation(i,"aUv");if(l<0||g<0)throw new Error("tile attribute lookup failed");return e.enableVertexAttribArray(l),e.enableVertexAttribArray(g),e.vertexAttribPointer(l,2,e.FLOAT,!1,16,0),e.vertexAttribPointer(g,2,e.FLOAT,!1,16,8),e.bindVertexArray(null),e.bindBuffer(e.ARRAY_BUFFER,null),{program:i,vao:c,vbo:h,uCamera:o,uBounds:s,uTexture:a}}initPointProgram(){const e=this.gl,i=Pn(e,`#version 300 es
86
86
  precision highp float;
87
87
  in vec2 aPosition;
88
88
  in uint aTerm;
@@ -100,6 +100,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
100
100
  uniform sampler2D uPalette;
101
101
  uniform float uPaletteSize;
102
102
  uniform float uPointSize;
103
+ uniform float uPointStrokeScale;
103
104
  out vec4 outColor;
104
105
  void main() {
105
106
  vec2 pc = gl_PointCoord * 2.0 - 1.0;
@@ -111,7 +112,8 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
111
112
  vec4 color = texture(uPalette, uv);
112
113
  if (color.a <= 0.0) discard;
113
114
 
114
- float ringWidth = clamp(3.0 / max(1.0, uPointSize), 0.12, 0.62);
115
+ float s = uPointStrokeScale;
116
+ float ringWidth = clamp(3.0 * s / max(1.0, uPointSize), 0.12 * s, 0.62 * s);
115
117
  float innerRadius = 1.0 - ringWidth;
116
118
  float aa = 1.5 / max(1.0, uPointSize);
117
119
 
@@ -121,6 +123,6 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
121
123
  if (alpha <= 0.001) discard;
122
124
 
123
125
  outColor = vec4(color.rgb * alpha, alpha);
124
- }`),o=qt(t,i,"uCamera"),s=qt(t,i,"uPointSize"),a=qt(t,i,"uPalette"),u=qt(t,i,"uPaletteSize"),c=t.createVertexArray(),f=t.createBuffer(),p=t.createBuffer(),m=t.createBuffer(),b=t.createTexture();if(!c||!f||!p||!m||!b)throw new Error("point buffer allocation failed");t.bindVertexArray(c),t.bindBuffer(t.ARRAY_BUFFER,f),t.bufferData(t.ARRAY_BUFFER,0,t.DYNAMIC_DRAW);const S=t.getAttribLocation(i,"aPosition");if(S<0)throw new Error("point position attribute not found");t.enableVertexAttribArray(S),t.vertexAttribPointer(S,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,p),t.bufferData(t.ARRAY_BUFFER,0,t.DYNAMIC_DRAW);const M=t.getAttribLocation(i,"aTerm");if(M<0)throw new Error("point term attribute not found");return t.enableVertexAttribArray(M),t.vertexAttribIPointer(M,1,t.UNSIGNED_SHORT,0,0),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,m),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,b),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:c,posBuffer:f,termBuffer:p,indexBuffer:m,paletteTexture:b,uCamera:o,uPointSize:s,uPalette:a,uPaletteSize:u}}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 Be=[],ji=[],Ji={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)},Qi=.65,to=4,eo=24,no=1024,ro=4;function io(e){return Math.max(0,Math.min(Math.floor(e.count??0),Math.floor((e.positions?.length??0)/2),e.paletteIndices?.length??0))}function oo(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 so(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))*ro;return Math.max(eo,Math.min(no,i))}function ao(e,t){if(!e||!e.positions||!e.paletteIndices)return null;const n=io(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=oo(e.drawIndices,n),s=o?o.length:n;if(s===0)return null;const a=so(t,s),u=new Map,c=f=>{const p=r[f*2],m=r[f*2+1];if(!Number.isFinite(p)||!Number.isFinite(m))return;const b=Math.floor(p/a),S=Math.floor(m/a);let M=u.get(b);M||(M=new Map,u.set(b,M));const C=M.get(S);C?C.push(f):M.set(S,[f])};if(o)for(let f=0;f<o.length;f+=1)c(o[f]??0);else for(let f=0;f<n;f+=1)c(f);return u.size===0?null:{cellSize:a,safeCount:n,positions:r,ids:i,buckets:u}}function Ve(e,t){return e.id??t}function uo(e,t){if(!Array.isArray(t)||t.length<3)return!1;const[n,r]=e;let i=!1;for(let o=0,s=t.length-1;o<t.length;s=o++){const[a,u]=t[o],[c,f]=t[s];u>r!=f>r&&n<(c-a)*(r-u)/Math.max(1e-12,f-u)+a&&(i=!i)}return i}function Fe(e,t){for(let n=t.length-1;n>=0;n-=1){const r=t[n];if(r?.coordinates?.length&&uo(e,r.coordinates))return{region:r,regionIndex:n,regionId:Ve(r,n)}}return null}function co({source:e,viewState:t,onViewStateChange:n,onStats:r,onTileError:i,onContextLost:o,onContextRestored:s,debugOverlay:a=!1,debugOverlayStyle:u,fitNonce:c=0,rotationResetNonce:f=0,authToken:p="",ctrlDragRotate:m=!0,pointData:b=null,pointPalette:S=null,pointSizeByZoom:M,roiRegions:C,roiPolygons:k,clipPointsToRois:I=!1,clipMode:P="worker",onClipStats:D,onRoiPointGroups:K,roiPaletteIndexToTermId:ct,interactionLock:it=!1,drawTool:q="cursor",stampOptions:ut,brushOptions:Ct,regionStrokeStyle:Yt,regionStrokeHoverStyle:Z,regionStrokeActiveStyle:Pt,patchStrokeStyle:Ut,resolveRegionStrokeStyle:$t,overlayShapes:lt,customLayers:j,patchRegions:R,regionLabelStyle:_,onPointerWorldMove:E,onPointHover:z,onPointClick:H,onRegionHover:J,onRegionClick:ft,onActiveRegionChange:bt,getCellByCoordinatesRef:F,onDrawComplete:Tt,onPatchComplete:ht,showOverviewMap:N=!1,overviewMapOptions:V,className:ot,style:Q}){const tt=d.useRef(null),G=d.useRef(null),At=d.useRef(null),vt=d.useRef(null),B=d.useRef(n),st=d.useRef(r),nt=d.useRef(a),[Wt,It]=d.useState(!0),[_t,Ot]=d.useState(null),[dt,oe]=d.useState(null),[se,l]=d.useState(null),[h,y]=d.useState(null),x=d.useRef(null),A=d.useRef(null),v=d.useRef(null),X=d.useRef(0),W=C??Be,Y=R??Be,at=k??ji,Rt=(j?.length??0)>0,Vt=d.useMemo(()=>({position:"relative",width:"100%",height:"100%",...Q}),[Q]),wt=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)",...u}),[u]),$=d.useMemo(()=>W.length>0?W:at.length===0?Be:at.map((g,T)=>({id:T,coordinates:g})),[W,at]),yt=d.useMemo(()=>$.map(g=>g.coordinates),[$]),[xt,ae]=d.useState(b);d.useEffect(()=>{const g=++X.current;let T=!1;if(!I)return ae(b),()=>{T=!0};if(!b||!b.count||!b.positions||!b.paletteIndices)return ae(null),()=>{T=!0};if(yt.length===0)return ae(Ji),D?.({mode:P,durationMs:0,inputCount:b.count,outputCount:0,polygonCount:0}),()=>{T=!0};const U=(L,rt)=>{if(T||g!==X.current)return;const le=L?.drawIndices?L.drawIndices.length:L?.count??0;ae(L),D?.({mode:rt.mode,durationMs:rt.durationMs,inputCount:b.count,outputCount:le,polygonCount:yt.length,usedWebGpu:rt.usedWebGpu,candidateCount:rt.candidateCount,bridgedToDraw:rt.bridgedToDraw})};return(async()=>{if(P==="sync"){const L=performance.now(),rt=ie(b,yt);U(rt,{mode:"sync",durationMs:performance.now()-L});return}if(P==="hybrid-webgpu"){const L=await Zn(b,yt,{bridgeToDraw:!0});U(L.data,{mode:L.meta.mode,durationMs:L.meta.durationMs,usedWebGpu:L.meta.usedWebGpu,candidateCount:L.meta.candidateCount,bridgedToDraw:L.meta.bridgedToDraw});return}try{const L=await Jn(b,yt);U(L.data,{mode:L.meta.mode,durationMs:L.meta.durationMs})}catch{const L=performance.now(),rt=ie(b,yt);U(rt,{mode:"sync",durationMs:performance.now()-L})}})(),()=>{T=!0}},[I,P,b,yt,D]);const Ke=!!(z||H||F),St=d.useMemo(()=>Ke?ao(xt,e):null,[Ke,xt,e]),Gt=d.useCallback(g=>{const T=G.current;if(!T||!St)return null;const U=Number(g[0]),O=Number(g[1]);if(!Number.isFinite(U)||!Number.isFinite(O))return null;const L=Math.max(1e-6,T.getViewState().zoom),rt=T.getPointSizeByZoom(),Qt=Math.max(to,rt*Qi)/L;if(!Number.isFinite(Qt)||Qt<=0)return null;const Te=St.cellSize,on=Math.floor(U/Te),sn=Math.floor(O/Te),fe=Math.max(1,Math.ceil(Qt/Te)),ur=Qt*Qt;let he=-1,an=ur,un=0,cn=0;for(let Re=on-fe;Re<=on+fe;Re+=1){const ln=St.buckets.get(Re);if(ln)for(let Ee=sn-fe;Ee<=sn+fe;Ee+=1){const de=ln.get(Ee);if(!(!de||de.length===0))for(let Ce=0;Ce<de.length;Ce+=1){const me=de[Ce];if(me>=St.safeCount)continue;const fn=St.positions[me*2],hn=St.positions[me*2+1],dn=fn-U,mn=hn-O,gn=dn*dn+mn*mn;gn>an||(an=gn,he=me,un=fn,cn=hn)}}}if(he<0)return null;const cr=St.ids?Number(St.ids[he]):null;return{index:he,id:cr,coordinate:[U,O],pointCoordinate:[un,cn]}},[St]),Ht=d.useCallback((g,T)=>{if(!z)return;const U=g?.index??null,O=g?.id??null;A.current===U&&v.current===O||(A.current=U,v.current=O,z({index:U,id:O,coordinate:T,pointCoordinate:g?.pointCoordinate??null}))},[z]),ue=d.useCallback((g,T)=>{if(!H)return;const U=Gt(g);U&&H({...U,button:T})},[H,Gt]);d.useMemo(()=>{const g=Number(V?.width??220);return Number.isFinite(g)?Math.max(64,g):220},[V?.width]);const je=d.useMemo(()=>{const g=Number(V?.height??140);return Number.isFinite(g)?Math.max(48,g):140},[V?.height]),Ft=d.useMemo(()=>{const g=Number(V?.margin??16);return Number.isFinite(g)?Math.max(0,g):16},[V?.margin]),ce=V?.position||"bottom-right";d.useEffect(()=>{if(F)return F.current=Gt,()=>{F.current===Gt&&(F.current=null)}},[F,Gt]);const Lt=d.useCallback(g=>{oe(T=>String(T)===String(g)?T:(bt?.(g),g))},[bt]);d.useEffect(()=>{B.current=n},[n]),d.useEffect(()=>{st.current=r},[r]),d.useEffect(()=>{nt.current=a,a||y(null)},[a]);const Je=d.useCallback(g=>{st.current?.(g),nt.current&&y(g)},[]),nr=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(`
125
- `):"stats: waiting for first frame...",[h]);d.useEffect(()=>{!(dt===null?!0:$.some((O,L)=>String(Ve(O,L))===String(dt)))&&dt!==null&&Lt(null);const T=x.current;!(T===null?!0:$.some((O,L)=>String(Ve(O,L))===String(T)))&&T!==null&&(x.current=null,Ot(null),J?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[$,dt,J,Lt]),d.useEffect(()=>{const g=A.current;g!==null&&(St&&g<St.safeCount||(A.current=null,v.current=null,z?.({index:null,id:null,coordinate:null,pointCoordinate:null})))},[St,z]);const Qe=d.useCallback(g=>{Rt&&l(g);const T=B.current;T&&T(g),At.current?.(),vt.current?.()},[Rt]);d.useEffect(()=>{if(!N){It(!1);return}It(!0)},[N,e?.id]),d.useEffect(()=>{q!=="cursor"&&x.current!==null&&(x.current=null,Ot(null),J?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[q,J]),d.useEffect(()=>{q!=="cursor"&&A.current!==null&&(A.current=null,v.current=null,z?.({index:null,id:null,coordinate:null,pointCoordinate:null}))},[q,z]);const zt=d.useCallback((g,T)=>{const U=G.current;if(!U)return null;const O=U.screenToWorld(g,T);if(!Array.isArray(O)||O.length<2)return null;const L=Number(O[0]),rt=Number(O[1]);return!Number.isFinite(L)||!Number.isFinite(rt)?null:[L,rt]},[]),tn=d.useCallback((g,T)=>{const U=G.current;if(!U)return null;const O=U.worldToScreen(g,T);if(!Array.isArray(O)||O.length<2)return null;const L=Number(O[0]),rt=Number(O[1]);return!Number.isFinite(L)||!Number.isFinite(rt)?null:[L,rt]},[]),en=d.useCallback(()=>{G.current?.requestRender(),At.current?.(),vt.current?.()},[]),nn=d.useMemo(()=>se??G.current?.getViewState()??null,[se]),rn=d.useMemo(()=>{if(!e)return null;const g=nn;return g?{source:e,viewState:g,drawTool:q,interactionLock:it,worldToScreen:tn,screenToWorld:zt,requestRedraw:en}:null},[e,nn,q,it,tn,zt,en]),rr=d.useCallback(g=>{const T=g.target===tt.current,U=zt(g.clientX,g.clientY);if(E){const le=!!U&&U[0]>=0&&U[1]>=0&&!!e&&U[0]<=e.width&&U[1]<=e.height;E({coordinate:U,clientX:g.clientX,clientY:g.clientY,insideImage:le})}if(q!=="cursor")return;if(!T){Ht(null,null),x.current!==null&&(x.current=null,Ot(null),J?.({region:null,regionId:null,regionIndex:-1,coordinate:null}));return}if(!U){Ht(null,null);return}if(z&&Ht(Gt(U),U),!$.length)return;const O=Fe(U,$),L=O?.regionId??null,rt=x.current;String(rt)!==String(L)&&(x.current=L,Ot(L),J?.({region:O?.region??null,regionId:L,regionIndex:O?.regionIndex??-1,coordinate:U}))},[q,$,zt,J,E,e,Ht,Gt,z]),ir=d.useCallback(()=>{E?.({coordinate:null,clientX:-1,clientY:-1,insideImage:!1}),Ht(null,null),x.current!==null&&(x.current=null,Ot(null),J?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[J,E,Ht]),or=d.useCallback(g=>{if(q!=="cursor"||g.target!==tt.current)return;const T=zt(g.clientX,g.clientY);if(!T)return;if(ue(T,g.button),!$.length){Lt(null);return}const U=Fe(T,$);if(!U){Lt(null);return}const O=dt!==null&&String(dt)===String(U.regionId)?null:U.regionId;Lt(O),ft?.({region:U.region,regionId:U.regionId,regionIndex:U.regionIndex,coordinate:T})},[q,$,zt,ft,dt,Lt,ue]),sr=d.useCallback(g=>{if(q!=="brush"||Ct?.clickSelectRoi!==!0||!$.length)return!1;const T=Fe(g,$);if(!T)return!1;const U=dt!==null&&String(dt)===String(T.regionId)?null:T.regionId;return Lt(U),ft?.({region:T.region,regionId:T.regionId,regionIndex:T.regionIndex,coordinate:g}),!0},[q,Ct?.clickSelectRoi,$,dt,Lt,ft]),ar=d.useCallback(g=>{if(!H||q!=="cursor"||g.target!==tt.current)return;g.preventDefault();const T=zt(g.clientX,g.clientY);T&&ue(T,g.button)},[q,zt,ue,H]);return d.useEffect(()=>{const g=tt.current;if(!g||!e)return;const T=new er(g,e,{onViewStateChange:Qe,onStats:Je,onTileError:i,onContextLost:o,onContextRestored:s,authToken:p,ctrlDragRotate:m,pointSizeByZoom:M});return G.current=T,t&&T.setViewState(t),T.setInteractionLock(it),Rt&&l(T.getViewState()),()=>{T.destroy(),G.current=null}},[e,Je,i,o,s,p,m,M,Qe,Rt]),d.useEffect(()=>{const g=G.current;!g||!t||g.setViewState(t)},[t]),d.useEffect(()=>{const g=G.current;g&&g.fitToImage()},[c]),d.useEffect(()=>{const g=G.current;g&&g.resetRotation()},[f]),d.useEffect(()=>{const g=G.current;!g||!S||g.setPointPalette(S)},[S]),d.useEffect(()=>{const g=G.current;g&&g.setPointSizeByZoom(M)},[M]),d.useEffect(()=>{const g=G.current;g&&g.setPointData(xt)},[xt]),d.useEffect(()=>{if(!K)return;const T=Qn(I?xt:b,$,{paletteIndexToTermId:ct,includeEmptyRegions:!0});K(T)},[K,I,b,xt,$,ct]),d.useEffect(()=>{const g=G.current;g&&g.setInteractionLock(it)},[it]),gt.jsxs("div",{className:ot,style:Vt,onPointerMove:rr,onPointerLeave:ir,onClick:or,onContextMenu:ar,children:[gt.jsx("canvas",{ref:tt,className:"wsi-render-canvas",style:{position:"absolute",inset:0,zIndex:1,width:"100%",height:"100%",display:"block",touchAction:"none",cursor:q==="cursor"&&_t!==null?"pointer":it?"crosshair":"grab"}}),e&&rn&&Array.isArray(j)&&j.length>0?j.map((g,T)=>gt.jsx("div",{className:g.className,style:{position:"absolute",inset:0,zIndex:g.zIndex??3,pointerEvents:g.pointerEvents??"none",...g.style},children:g.render(rn)},g.id??T)):null,e?gt.jsx(Xn,{tool:q,enabled:q!=="cursor",imageWidth:e.width,imageHeight:e.height,imageMpp:e.mpp,imageZoom:e.maxTierZoom,stampOptions:ut,brushOptions:Ct,projectorRef:G,onBrushTap:sr,viewStateSignal:t,persistedRegions:$,patchRegions:Y,regionStrokeStyle:Yt,regionStrokeHoverStyle:Z,regionStrokeActiveStyle:Pt,patchStrokeStyle:Ut,resolveRegionStrokeStyle:$t,overlayShapes:lt,hoveredRegionId:_t,activeRegionId:dt,regionLabelStyle:_,invalidateRef:At,onDrawComplete:Tt,onPatchComplete:ht}):null,a?gt.jsx("pre",{"data-open-plant-debug-overlay":!0,style:wt,children:nr}):null,e&&N?Wt?gt.jsxs(gt.Fragment,{children:[gt.jsx(Wn,{source:e,projectorRef:G,authToken:p,options:V,invalidateRef:vt}),gt.jsx("button",{type:"button","aria-label":"Hide overview map",onClick:()=>It(!1),style:{position:"absolute",zIndex:6,...ce.includes("left")?{left:Ft}:{right:Ft},...ce.includes("top")?{top:Ft+je+8}:{bottom:Ft+je+8},width:20,height:20,borderRadius:999,border:"1px solid rgba(255,255,255,0.4)",background:"rgba(8, 14, 22, 0.9)",color:"#fff",fontSize:13,lineHeight:1,cursor:"pointer",padding:0},children:"×"})]}):gt.jsx("button",{type:"button","aria-label":"Show overview map",onClick:()=>It(!0),style:{position:"absolute",zIndex:6,...ce.includes("left")?{left:Ft}:{right:Ft},...ce.includes("top")?{top:Ft}:{bottom:Ft},height:24,minWidth:40,borderRadius:999,border:"1px solid rgba(255,255,255,0.45)",background:"rgba(8, 14, 22, 0.9)",color:"#dff8ff",fontSize:11,fontWeight:700,cursor:"pointer",padding:"0 8px"},children:"Map"}):null]})}exports.DEFAULT_POINT_COLOR=Ge;exports.DrawLayer=Xn;exports.M1TileRenderer=Un;exports.OverviewMap=Wn;exports.TileScheduler=tr;exports.TileViewerCanvas=Ei;exports.WsiTileRenderer=er;exports.WsiViewerCanvas=co;exports.buildTermPalette=Wr;exports.calcScaleLength=kr;exports.calcScaleResolution=qe;exports.clamp=et;exports.closeRing=Mt;exports.computeRoiPointGroups=Qn;exports.createCircle=De;exports.createRectangle=ze;exports.filterPointDataByPolygons=ie;exports.filterPointDataByPolygonsHybrid=Zn;exports.filterPointDataByPolygonsInWorker=Jn;exports.filterPointIndicesByPolygons=qn;exports.filterPointIndicesByPolygonsInWorker=Xi;exports.getWebGpuCapabilities=Fi;exports.hexToRgba=Fn;exports.isSameViewState=Xr;exports.normalizeImageInfo=Ri;exports.prefilterPointsByBoundsWebGpu=Hn;exports.terminateRoiClipWorker=ki;exports.toBearerToken=Yr;exports.toTileUrl=$e;
126
+ }`),o=Ve(e,i,"uCamera"),s=Ve(e,i,"uPointSize"),a=Ve(e,i,"uPointStrokeScale"),c=Ve(e,i,"uPalette"),h=Ve(e,i,"uPaletteSize"),l=e.createVertexArray(),g=e.createBuffer(),m=e.createBuffer(),y=e.createBuffer(),x=e.createTexture();if(!l||!g||!m||!y||!x)throw new Error("point buffer allocation failed");e.bindVertexArray(l),e.bindBuffer(e.ARRAY_BUFFER,g),e.bufferData(e.ARRAY_BUFFER,0,e.DYNAMIC_DRAW);const M=e.getAttribLocation(i,"aPosition");if(M<0)throw new Error("point position attribute not found");e.enableVertexAttribArray(M),e.vertexAttribPointer(M,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,m),e.bufferData(e.ARRAY_BUFFER,0,e.DYNAMIC_DRAW);const T=e.getAttribLocation(i,"aTerm");if(T<0)throw new Error("point term attribute not found");return e.enableVertexAttribArray(T),e.vertexAttribIPointer(T,1,e.UNSIGNED_SHORT,0,0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,y),e.bufferData(e.ELEMENT_ARRAY_BUFFER,0,e.DYNAMIC_DRAW),e.bindVertexArray(null),e.bindBuffer(e.ARRAY_BUFFER,null),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,null),e.bindTexture(e.TEXTURE_2D,x),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,new Uint8Array([160,160,160,255])),e.bindTexture(e.TEXTURE_2D,null),{program:i,vao:l,posBuffer:g,termBuffer:m,indexBuffer:y,paletteTexture:x,uCamera:o,uPointSize:s,uPointStrokeScale:a,uPalette:c,uPaletteSize:h}}handleTileLoaded(e,n){if(this.destroyed||this.contextLost||this.gl.isContextLost()){n.close();return}if(this.cache.has(e.key)){n.close();return}const r=this.createTextureFromBitmap(n);n.close(),r&&(this.cache.set(e.key,{key:e.key,texture:r,bounds:e.bounds,tier:e.tier,lastUsed:this.frameSerial}),this.trimCache(),this.requestRender())}createTextureFromBitmap(e){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,e),n.bindTexture(n.TEXTURE_2D,null),r):null}}const Nt=[],po=[],bo={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)},wo=.65,yo=4,So=24,xo=1024,Mo=4;function To(t){return Math.max(0,Math.min(Math.floor(t.count??0),Math.floor((t.positions?.length??0)/2),t.paletteIndices?.length??0))}function Ro(t,e){if(!(t instanceof Uint32Array)||e<=0||t.length===0)return null;let n=!1;for(let o=0;o<t.length;o+=1)if(!(t[o]<e)){n=!0;break}if(!n)return t;const r=new Uint32Array(t.length);let i=0;for(let o=0;o<t.length;o+=1){const s=t[o];s>=e||(r[i]=s,i+=1)}return r.subarray(0,i)}function Eo(t,e){if(!t||e<=0)return 256;const n=Math.max(1,t.width*t.height),i=Math.sqrt(n/Math.max(1,e))*Mo;return Math.max(So,Math.min(xo,i))}function Po(t,e){if(!t||!t.positions||!t.paletteIndices)return null;const n=To(t);if(n<=0)return null;const r=t.positions.subarray(0,n*2),i=t.ids instanceof Uint32Array&&t.ids.length>=n?t.ids.subarray(0,n):null,o=Ro(t.drawIndices,n),s=o?o.length:n;if(s===0)return null;const a=Eo(e,s),c=new Map,h=l=>{const g=r[l*2],m=r[l*2+1];if(!Number.isFinite(g)||!Number.isFinite(m))return;const y=Math.floor(g/a),x=Math.floor(m/a);let M=c.get(y);M||(M=new Map,c.set(y,M));const T=M.get(x);T?T.push(l):M.set(x,[l])};if(o)for(let l=0;l<o.length;l+=1)h(o[l]??0);else for(let l=0;l<n;l+=1)h(l);return c.size===0?null:{cellSize:a,safeCount:n,positions:r,ids:i,buckets:c}}function Kt(t,e){return t.id??e}function Ao(t){const e=[];for(let n=0;n<t.length;n+=1){const r=t[n],i=at([r?.coordinates]);i.length!==0&&e.push({region:r,regionIndex:n,regionId:Kt(r,n),polygons:i})}return e}function Wt(t,e){const n=t[0],r=t[1];for(let i=e.length-1;i>=0;i-=1){const o=e[i];for(const s of o.polygons)if(jt(n,r,s))return{region:o.region,regionIndex:o.regionIndex,regionId:o.regionId}}return null}function Co({source:t,viewState:e,onViewStateChange:n,onStats:r,onTileError:i,onContextLost:o,onContextRestored:s,debugOverlay:a=!1,debugOverlayStyle:c,fitNonce:h=0,rotationResetNonce:l=0,authToken:g="",ctrlDragRotate:m=!0,pointData:y=null,pointPalette:x=null,pointSizeByZoom:M,pointStrokeScale:T,roiRegions:z,roiPolygons:v,clipPointsToRois:P=!1,clipMode:F="worker",onClipStats:G,onRoiPointGroups:le,roiPaletteIndexToTermId:ge,interactionLock:he=!1,drawTool:N="cursor",stampOptions:ze,brushOptions:Be,regionStrokeStyle:H,regionStrokeHoverStyle:Pe,regionStrokeActiveStyle:Ue,patchStrokeStyle:Ze,resolveRegionStrokeStyle:de,overlayShapes:Q,customLayers:E,patchRegions:C,regionLabelStyle:I,onPointerWorldMove:X,onPointHover:L,onPointClick:ne,onRegionHover:ee,onRegionClick:be,onActiveRegionChange:ue,getCellByCoordinatesRef:re,onDrawComplete:O,onPatchComplete:K,showOverviewMap:$=!1,overviewMapOptions:D,className:te,style:ie}){const oe=d.useRef(null),Z=d.useRef(null),Ae=d.useRef(null),Te=d.useRef(null),Ce=d.useRef(n),B=d.useRef(r),fe=d.useRef(a),[Re,ve]=d.useState(!0),[Qe,Ie]=d.useState(null),[we,At]=d.useState(null),[et,ut]=d.useState(null),[u,f]=d.useState(null),b=d.useRef(null),S=d.useRef(null),A=d.useRef(null),U=d.useRef(0),W=z??Nt,q=C??Nt,Y=v??po,ce=(E?.length??0)>0,ke=d.useMemo(()=>({position:"relative",width:"100%",height:"100%",...ie}),[ie]),De=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)",...c}),[c]),j=d.useMemo(()=>W.length>0?W:Y.length===0?Nt:Y.map((p,R)=>({id:R,coordinates:p})),[W,Y]),se=d.useMemo(()=>Ao(j),[j]),pe=d.useMemo(()=>j.map(p=>p.coordinates),[j]),[me,ct]=d.useState(y);d.useEffect(()=>{const p=++U.current;let R=!1;if(!P)return ct(y),()=>{R=!0};if(!y||!y.count||!y.positions||!y.paletteIndices)return ct(null),()=>{R=!0};if(pe.length===0)return ct(bo),G?.({mode:F,durationMs:0,inputCount:y.count,outputCount:0,polygonCount:0}),()=>{R=!0};const _=(k,ae)=>{if(R||p!==U.current)return;const ft=k?.drawIndices?k.drawIndices.length:k?.count??0;ct(k),G?.({mode:ae.mode,durationMs:ae.durationMs,inputCount:y.count,outputCount:ft,polygonCount:pe.length,usedWebGpu:ae.usedWebGpu,candidateCount:ae.candidateCount,bridgedToDraw:ae.bridgedToDraw})};return(async()=>{if(F==="sync"){const k=performance.now(),ae=st(y,pe);_(ae,{mode:"sync",durationMs:performance.now()-k});return}if(F==="hybrid-webgpu"){const k=await sr(y,pe,{bridgeToDraw:!0});_(k.data,{mode:k.meta.mode,durationMs:k.meta.durationMs,usedWebGpu:k.meta.usedWebGpu,candidateCount:k.meta.candidateCount,bridgedToDraw:k.meta.bridgedToDraw});return}try{const k=await cr(y,pe);_(k.data,{mode:k.meta.mode,durationMs:k.meta.durationMs})}catch{const k=performance.now(),ae=st(y,pe);_(ae,{mode:"sync",durationMs:performance.now()-k})}})(),()=>{R=!0}},[P,F,y,pe,G]);const rn=!!(L||ne||re),Me=d.useMemo(()=>rn?Po(me,t):null,[rn,me,t]),He=d.useCallback(p=>{const R=Z.current;if(!R||!Me)return null;const _=Number(p[0]),V=Number(p[1]);if(!Number.isFinite(_)||!Number.isFinite(V))return null;const k=Math.max(1e-6,R.getViewState().zoom),ae=R.getPointSizeByZoom(),tt=Math.max(yo,ae*wo)/k;if(!Number.isFinite(tt)||tt<=0)return null;const Ct=Me.cellSize,fn=Math.floor(_/Ct),dn=Math.floor(V/Ct),dt=Math.max(1,Math.ceil(tt/Ct)),yr=tt*tt;let mt=-1,mn=yr,gn=0,pn=0;for(let vt=fn-dt;vt<=fn+dt;vt+=1){const bn=Me.buckets.get(vt);if(bn)for(let It=dn-dt;It<=dn+dt;It+=1){const gt=bn.get(It);if(!(!gt||gt.length===0))for(let _t=0;_t<gt.length;_t+=1){const pt=gt[_t];if(pt>=Me.safeCount)continue;const wn=Me.positions[pt*2],yn=Me.positions[pt*2+1],Sn=wn-_,xn=yn-V,Mn=Sn*Sn+xn*xn;Mn>mn||(mn=Mn,mt=pt,gn=wn,pn=yn)}}}if(mt<0)return null;const Sr=Me.ids?Number(Me.ids[mt]):null;return{index:mt,id:Sr,coordinate:[_,V],pointCoordinate:[gn,pn]}},[Me]),Ke=d.useCallback((p,R)=>{if(!L)return;const _=p?.index??null,V=p?.id??null;S.current===_&&A.current===V||(S.current=_,A.current=V,L({index:_,id:V,coordinate:R,pointCoordinate:p?.pointCoordinate??null}))},[L]),lt=d.useCallback((p,R)=>{if(!ne)return;const _=He(p);_&&ne({..._,button:R})},[ne,He]);d.useMemo(()=>{const p=Number(D?.width??220);return Number.isFinite(p)?Math.max(64,p):220},[D?.width]);const on=d.useMemo(()=>{const p=Number(D?.height??140);return Number.isFinite(p)?Math.max(48,p):140},[D?.height]),Ne=d.useMemo(()=>{const p=Number(D?.margin??16);return Number.isFinite(p)?Math.max(0,p):16},[D?.margin]),ht=D?.position||"bottom-right";d.useEffect(()=>{if(re)return re.current=He,()=>{re.current===He&&(re.current=null)}},[re,He]);const We=d.useCallback(p=>{At(R=>String(R)===String(p)?R:(ue?.(p),p))},[ue]);d.useEffect(()=>{Ce.current=n},[n]),d.useEffect(()=>{B.current=r},[r]),d.useEffect(()=>{fe.current=a,a||f(null)},[a]);const sn=d.useCallback(p=>{B.current?.(p),fe.current&&f(p)},[]),dr=d.useMemo(()=>u?[`tier ${u.tier} | frame ${u.frameMs?.toFixed(2)??"-"} ms | drawCalls ${u.drawCalls??"-"}`,`tiles visible ${u.visible} | rendered ${u.rendered} | fallback ${u.fallback}`,`cache size ${u.cache} | hit ${u.cacheHits??"-"} | miss ${u.cacheMisses??"-"}`,`queue inflight ${u.inflight} | queued ${u.queued??"-"} | retries ${u.retries??"-"} | failed ${u.failed??"-"} | aborted ${u.aborted??"-"}`,`points ${u.points}`].join(`
127
+ `):"stats: waiting for first frame...",[u]);d.useEffect(()=>{!(we===null?!0:j.some((V,k)=>String(Kt(V,k))===String(we)))&&we!==null&&We(null);const R=b.current;!(R===null?!0:j.some((V,k)=>String(Kt(V,k))===String(R)))&&R!==null&&(b.current=null,Ie(null),ee?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[j,we,ee,We]),d.useEffect(()=>{const p=S.current;p!==null&&(Me&&p<Me.safeCount||(S.current=null,A.current=null,L?.({index:null,id:null,coordinate:null,pointCoordinate:null})))},[Me,L]);const an=d.useCallback(p=>{ce&&ut(p);const R=Ce.current;R&&R(p),Ae.current?.(),Te.current?.()},[ce]);d.useEffect(()=>{if(!$){ve(!1);return}ve(!0)},[$,t?.id]),d.useEffect(()=>{N!=="cursor"&&b.current!==null&&(b.current=null,Ie(null),ee?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[N,ee]),d.useEffect(()=>{N!=="cursor"&&S.current!==null&&(S.current=null,A.current=null,L?.({index:null,id:null,coordinate:null,pointCoordinate:null}))},[N,L]);const Xe=d.useCallback((p,R)=>{const _=Z.current;if(!_)return null;const V=_.screenToWorld(p,R);if(!Array.isArray(V)||V.length<2)return null;const k=Number(V[0]),ae=Number(V[1]);return!Number.isFinite(k)||!Number.isFinite(ae)?null:[k,ae]},[]),un=d.useCallback((p,R)=>{const _=Z.current;if(!_)return null;const V=_.worldToScreen(p,R);if(!Array.isArray(V)||V.length<2)return null;const k=Number(V[0]),ae=Number(V[1]);return!Number.isFinite(k)||!Number.isFinite(ae)?null:[k,ae]},[]),cn=d.useCallback(()=>{Z.current?.requestRender(),Ae.current?.(),Te.current?.()},[]),ln=d.useMemo(()=>et??Z.current?.getViewState()??null,[et]),hn=d.useMemo(()=>{if(!t)return null;const p=ln;return p?{source:t,viewState:p,drawTool:N,interactionLock:he,worldToScreen:un,screenToWorld:Xe,requestRedraw:cn}:null},[t,ln,N,he,un,Xe,cn]),mr=d.useCallback(p=>{const R=p.target===oe.current,_=Xe(p.clientX,p.clientY);if(X){const ft=!!_&&_[0]>=0&&_[1]>=0&&!!t&&_[0]<=t.width&&_[1]<=t.height;X({coordinate:_,clientX:p.clientX,clientY:p.clientY,insideImage:ft})}if(N!=="cursor")return;if(!R){Ke(null,null),b.current!==null&&(b.current=null,Ie(null),ee?.({region:null,regionId:null,regionIndex:-1,coordinate:null}));return}if(!_){Ke(null,null);return}if(L&&Ke(He(_),_),!se.length)return;const V=Wt(_,se),k=V?.regionId??null,ae=b.current;String(ae)!==String(k)&&(b.current=k,Ie(k),ee?.({region:V?.region??null,regionId:k,regionIndex:V?.regionIndex??-1,coordinate:_}))},[N,se,Xe,ee,X,t,Ke,He,L]),gr=d.useCallback(()=>{X?.({coordinate:null,clientX:-1,clientY:-1,insideImage:!1}),Ke(null,null),b.current!==null&&(b.current=null,Ie(null),ee?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[ee,X,Ke]),pr=d.useCallback(p=>{if(N!=="cursor"||p.target!==oe.current)return;const R=Xe(p.clientX,p.clientY);if(!R)return;if(lt(R,p.button),!se.length){We(null);return}const _=Wt(R,se);if(!_){We(null);return}const V=we!==null&&String(we)===String(_.regionId)?null:_.regionId;We(V),be?.({region:_.region,regionId:_.regionId,regionIndex:_.regionIndex,coordinate:R})},[N,se,Xe,be,we,We,lt]),br=d.useCallback(p=>{if(N!=="brush"||Be?.clickSelectRoi!==!0||!se.length)return!1;const R=Wt(p,se);if(!R)return!1;const _=we!==null&&String(we)===String(R.regionId)?null:R.regionId;return We(_),be?.({region:R.region,regionId:R.regionId,regionIndex:R.regionIndex,coordinate:p}),!0},[N,Be?.clickSelectRoi,se,we,We,be]),wr=d.useCallback(p=>{if(!ne||N!=="cursor"||p.target!==oe.current)return;p.preventDefault();const R=Xe(p.clientX,p.clientY);R&&lt(R,p.button)},[N,Xe,lt,ne]);return d.useEffect(()=>{const p=oe.current;if(!p||!t)return;const R=new fr(p,t,{onViewStateChange:an,onStats:sn,onTileError:i,onContextLost:o,onContextRestored:s,authToken:g,ctrlDragRotate:m,pointSizeByZoom:M,pointStrokeScale:T});return Z.current=R,e&&R.setViewState(e),R.setInteractionLock(he),ce&&ut(R.getViewState()),()=>{R.destroy(),Z.current=null}},[t,sn,i,o,s,g,m,M,T,an,ce]),d.useEffect(()=>{const p=Z.current;!p||!e||p.setViewState(e)},[e]),d.useEffect(()=>{const p=Z.current;p&&p.fitToImage()},[h]),d.useEffect(()=>{const p=Z.current;p&&p.resetRotation()},[l]),d.useEffect(()=>{const p=Z.current;!p||!x||p.setPointPalette(x)},[x]),d.useEffect(()=>{const p=Z.current;p&&p.setPointSizeByZoom(M)},[M]),d.useEffect(()=>{const p=Z.current;p&&p.setPointStrokeScale(T)},[T]),d.useEffect(()=>{const p=Z.current;p&&p.setPointData(me)},[me]),d.useEffect(()=>{if(!le)return;const R=lr(P?me:y,j,{paletteIndexToTermId:ge,includeEmptyRegions:!0});le(R)},[le,P,y,me,j,ge]),d.useEffect(()=>{const p=Z.current;p&&p.setInteractionLock(he)},[he]),Se.jsxs("div",{className:te,style:ke,onPointerMove:mr,onPointerLeave:gr,onClick:pr,onContextMenu:wr,children:[Se.jsx("canvas",{ref:oe,className:"wsi-render-canvas",style:{position:"absolute",inset:0,zIndex:1,width:"100%",height:"100%",display:"block",touchAction:"none",cursor:N==="cursor"&&Qe!==null?"pointer":he?"crosshair":"grab"}}),t&&hn&&Array.isArray(E)&&E.length>0?E.map((p,R)=>Se.jsx("div",{className:p.className,style:{position:"absolute",inset:0,zIndex:p.zIndex??3,pointerEvents:p.pointerEvents??"none",...p.style},children:p.render(hn)},p.id??R)):null,t?Se.jsx(Qn,{tool:N,enabled:N!=="cursor",imageWidth:t.width,imageHeight:t.height,imageMpp:t.mpp,imageZoom:t.maxTierZoom,stampOptions:ze,brushOptions:Be,projectorRef:Z,onBrushTap:br,viewStateSignal:e,persistedRegions:j,patchRegions:q,regionStrokeStyle:H,regionStrokeHoverStyle:Pe,regionStrokeActiveStyle:Ue,patchStrokeStyle:Ze,resolveRegionStrokeStyle:de,overlayShapes:Q,hoveredRegionId:Qe,activeRegionId:we,regionLabelStyle:I,invalidateRef:Ae,onDrawComplete:O,onPatchComplete:K}):null,a?Se.jsx("pre",{"data-open-plant-debug-overlay":!0,style:De,children:dr}):null,t&&$?Re?Se.jsxs(Se.Fragment,{children:[Se.jsx(tr,{source:t,projectorRef:Z,authToken:g,options:D,invalidateRef:Te}),Se.jsx("button",{type:"button","aria-label":"Hide overview map",onClick:()=>ve(!1),style:{position:"absolute",zIndex:6,...ht.includes("left")?{left:Ne}:{right:Ne},...ht.includes("top")?{top:Ne+on+8}:{bottom:Ne+on+8},width:20,height:20,borderRadius:999,border:"1px solid rgba(255,255,255,0.4)",background:"rgba(8, 14, 22, 0.9)",color:"#fff",fontSize:13,lineHeight:1,cursor:"pointer",padding:0},children:"×"})]}):Se.jsx("button",{type:"button","aria-label":"Show overview map",onClick:()=>ve(!0),style:{position:"absolute",zIndex:6,...ht.includes("left")?{left:Ne}:{right:Ne},...ht.includes("top")?{top:Ne}:{bottom:Ne},height:24,minWidth:40,borderRadius:999,border:"1px solid rgba(255,255,255,0.45)",background:"rgba(8, 14, 22, 0.9)",color:"#dff8ff",fontSize:11,fontWeight:700,cursor:"pointer",padding:"0 8px"},children:"Map"}):null]})}exports.DEFAULT_POINT_COLOR=Jt;exports.DrawLayer=Qn;exports.M1TileRenderer=On;exports.OverviewMap=tr;exports.TileScheduler=hr;exports.TileViewerCanvas=Zi;exports.WsiTileRenderer=fr;exports.WsiViewerCanvas=Co;exports.buildTermPalette=oi;exports.calcScaleLength=ni;exports.calcScaleResolution=Qt;exports.clamp=J;exports.closeRing=Le;exports.computeRoiPointGroups=lr;exports.createCircle=Yt;exports.createRectangle=Ot;exports.filterPointDataByPolygons=st;exports.filterPointDataByPolygonsHybrid=sr;exports.filterPointDataByPolygonsInWorker=cr;exports.filterPointIndicesByPolygons=rr;exports.filterPointIndicesByPolygonsInWorker=oo;exports.getWebGpuCapabilities=no;exports.hexToRgba=Hn;exports.isSameViewState=ri;exports.normalizeImageInfo=$i;exports.prefilterPointsByBoundsWebGpu=or;exports.terminateRoiClipWorker=io;exports.toBearerToken=ii;exports.toTileUrl=en;
126
128
  //# sourceMappingURL=index.cjs.map