open-plant 1.2.14 → 1.2.15

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