(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,90846,t=>{"use strict";let e=["#4e79a7","#f28e2c","#e15759","#76b7b2","#59a14f","#edc949","#af7aa1","#ff9da7","#9c755f","#bab0ab"],i="#ff0000",r="#ffffff";function s(t,e){return{kind:"indices",indices:t,computeTimeMs:e,has:e=>t.has(e)}}function o(t,e,i,r,s){let o=.4*Math.min(r,s)*i.zoom;return{x:r/2+(t-i.centerX)*o,y:s/2-(e-i.centerY)*o}}function a(t,e,i,r,s){let o=.4*Math.min(r,s)*i.zoom;return{x:i.centerX+(t-r/2)/o,y:i.centerY-(e-s/2)/o}}function h(){return{type:"poincare",ax:0,ay:0,displayZoom:1}}function n(t,e,i,r){let s=t-i,o=e-r,a=1-(i*t+r*e),h=-(i*e-r*t),n=a*a+h*h;if(n<1e-12){let t=Math.sqrt(s*s+o*o);return t<1e-12?{x:0,y:0}:{x:s/t*.999,y:o/t*.999}}let l=(s*a+o*h)/n,u=(o*a-s*h)/n,d=l*l+u*u;if(d>=1){let t=Math.sqrt(d);return{x:l/t*.999,y:u/t*.999}}return{x:l,y:u}}function l(t,e,i,r){let s=t+i,o=e+r,a=1+(i*t+r*e),h=i*e-r*t,n=a*a+h*h;if(n<1e-12){let t=Math.sqrt(s*s+o*o);return t<1e-12?{x:0,y:0}:{x:s/t*.999,y:o/t*.999}}let l=(s*a+o*h)/n,u=(o*a-s*h)/n,d=l*l+u*u;if(d>=1){let t=Math.sqrt(d);return{x:l/t*.999,y:u/t*.999}}return{x:l,y:u}}function u(t,e,i,r,s){let o=.45*Math.min(r,s)*i.displayZoom,a=(t-r/2)/o,h=-(e-s/2)/o,n=a*a+h*h;if(n>=1){let t=Math.sqrt(n);return l(a/t*.999,h/t*.999,i.ax,i.ay)}return l(a,h,i.ax,i.ay)}function d(t,e,i,r,s,o,a){let h=.45*Math.min(o,a)*t.displayZoom,n=(t,e,i=.95)=>{let r=t*t+e*e;if(r>i*i){let s=Math.sqrt(r);return{x:t/s*i,y:e/s*i}}return{x:t,y:e}},u=n((e-o/2)/h,-(i-a/2)/h),d=n((r-o/2)/h,-(s-a/2)/h),f=l(u.x,u.y,t.ax,t.ay),c=function(t,e,i,r){let s=i*t-r*e,o=i*e+r*t,a=s*s+o*o-1;if(1e-10>Math.abs(a))return{x:-i,y:-r};let h=t-i,n=r-e,l=(-(1+s)*h+o*n)/a,u=((1-s)*n-o*h)/a,d=l*l+u*u;if(d>=1){let t=Math.sqrt(d);return{x:l/t*.99,y:u/t*.99}}return{x:l,y:u}}(f.x,f.y,d.x,d.y);return{...t,ax:c.x,ay:c.y}}function f(t,e,i){return ti?i:0|t}class c{n;bounds;cellsX;cellsY;cellSizeX;cellSizeY;offsets;ids;constructor(t,e,i=64){this.n=t.length/2|0,this.bounds=e??function(t){let e=1/0,i=1/0,r=-1/0,s=-1/0;for(let o=0;or&&(r=a),hs&&(s=h)}return Number.isFinite(e)&&Number.isFinite(i)?(1e-9>Math.abs(r-e)&&(r=e+1),1e-9>Math.abs(s-i)&&(s=i+1),{minX:e,minY:i,maxX:r,maxY:s}):{minX:0,minY:0,maxX:0,maxY:0}}(t);const r=this.bounds.maxX-this.bounds.minX,s=this.bounds.maxY-this.bounds.minY,o=function(t){return Math.max(64,Math.min(1e6,t))}(Math.ceil(this.n/Math.max(1,i)));let a=Math.round(Math.sqrt(r/s*o)),h=Math.round(o/(a=f(a,8,2048)));h=f(h,8,2048),this.cellsX=a,this.cellsY=h,this.cellSizeX=r/a,this.cellSizeY=s/h;const n=a*h,l=new Uint32Array(n);for(let e=0;er.push(t))}}function p(t,e,i){let r=i.length/2;if(r<3)return!1;let s=!1;for(let o=0,a=r-1;oh||el)return!1;let u=s-i,d=o-r,f=u*u+d*d;if(f<1e-9*1e-9)return 1e-9>=Math.sqrt((t-i)*(t-i)+(e-r)*(e-r));let c=Math.max(0,Math.min(1,((t-i)*u+(e-r)*d)/f)),p=i+c*u,g=r+c*d;return 1e-9>=Math.sqrt((t-p)*(t-p)+(e-g)*(e-g))}(t,e,r,h,n,l))return!0;h>e!=l>e&&t<(n-r)*(e-h)/(l-h)+r&&(s=!s)}return s}function g(t){let e=t.trim();if(!e.startsWith("#"))return[1,1,1,1];let i=e.slice(1);return 3===i.length?[parseInt(i[0]+i[0],16)/255,parseInt(i[1]+i[1],16)/255,parseInt(i[2]+i[2],16)/255,1]:6===i.length||8===i.length?[parseInt(i.slice(0,2),16)/255,parseInt(i.slice(2,4),16)/255,parseInt(i.slice(4,6),16)/255,8===i.length?parseInt(i.slice(6,8),16)/255:1]:[1,1,1,1]}function m(t,e,i){let r=t.createShader(e);if(!r)throw Error("Failed to create shader");if(t.shaderSource(r,i),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS)){let e=t.getShaderInfoLog(r)??"unknown";throw t.deleteShader(r),Error(`Shader compile failed: ${e}`)}return r}function y(t,e,i){let r=m(t,t.VERTEX_SHADER,e),s=m(t,t.FRAGMENT_SHADER,i),o=t.createProgram();if(!o)throw Error("Failed to create program");if(t.attachShader(o,r),t.attachShader(o,s),t.linkProgram(o),t.deleteShader(r),t.deleteShader(s),!t.getProgramParameter(o,t.LINK_STATUS)){let e=t.getProgramInfoLog(o)??"unknown";throw t.deleteProgram(o),Error(`Program link failed: ${e}`)}return o}function b(t,e,i,r){t.width=Math.max(1,Math.floor(e*r)),t.height=Math.max(1,Math.floor(i*r)),t.style.width=`${e}px`,t.style.height=`${i}px`}let x=`#version 300 es precision highp float; precision highp int; flat in uint v_label; // Present in the vertex stage too; redeclare here so we can compute AA width. uniform float u_dpr; uniform float u_pointRadiusCss; uniform sampler2D u_paletteTex; uniform int u_paletteSize; uniform int u_paletteWidth; out vec4 outColor; void main() { vec2 p = gl_PointCoord * 2.0 - 1.0; // Anti-aliased circle: avoid harsh discard edges that can look like // "weird polygons" at small sizes or without MSAA. float r = length(p); // Ensure at least ~1px transition (in point-local coordinates) so small // points remain visually circular. float radiusPx = max(u_pointRadiusCss * u_dpr, 1.0); // Slightly wider than 1px helps circles stay round-looking when zoomed out // (where points are perceptually tiny and aliasing is more obvious). float aa = max(fwidth(r), 1.5 / radiusPx); float alpha = 1.0 - smoothstep(1.0 - aa, 1.0 + aa, r); if (alpha <= 0.0) discard; int size = max(u_paletteSize, 1); int w = max(u_paletteWidth, 1); int idx = int(v_label) % size; int x = idx % w; int y = idx / w; vec4 c = texelFetch(u_paletteTex, ivec2(x, y), 0); outColor = vec4(c.rgb, c.a * alpha); } `,v=`#version 300 es precision highp float; precision highp int; flat in uint v_label; uniform sampler2D u_paletteTex; uniform int u_paletteSize; uniform int u_paletteWidth; out vec4 outColor; void main() { int size = max(u_paletteSize, 1); int w = max(u_paletteWidth, 1); int idx = int(v_label) % size; int x = idx % w; int y = idx / w; outColor = texelFetch(u_paletteTex, ivec2(x, y), 0); } `,R=`#version 300 es precision highp float; precision highp int; uniform float u_dpr; uniform float u_pointRadiusCss; uniform vec4 u_color; uniform float u_pointSizePx; uniform float u_ringThicknessPx; uniform int u_ringMode; // 0 = solid, 1 = ring out vec4 outColor; void main() { vec2 p = gl_PointCoord * 2.0 - 1.0; float r = length(p); float radiusPx = max(u_pointRadiusCss * u_dpr, 1.0); float aa = max(fwidth(r), 1.5 / radiusPx); float outer = 1.0 - smoothstep(1.0 - aa, 1.0 + aa, r); if (outer <= 0.0) discard; float alpha = outer; if (u_ringMode == 1) { float radiusPx = u_pointSizePx * 0.5; float t = clamp(u_ringThicknessPx / max(radiusPx, 1e-6), 0.0, 1.0); float inner = 1.0 - t; // Keep only the outer ring with an anti-aliased inner boundary. float innerMask = smoothstep(inner - aa, inner + aa, r); alpha *= innerMask; if (alpha <= 0.0) discard; } outColor = vec4(u_color.rgb, u_color.a * alpha); } `,P=`#version 300 es precision highp float; out vec2 v_uv; void main() { // Fullscreen triangle // (-1,-1), (3,-1), (-1,3) if (gl_VertexID == 0) { gl_Position = vec4(-1.0, -1.0, 0.0, 1.0); v_uv = vec2(0.0, 0.0); } else if (gl_VertexID == 1) { gl_Position = vec4(3.0, -1.0, 0.0, 1.0); v_uv = vec2(2.0, 0.0); } else { gl_Position = vec4(-1.0, 3.0, 0.0, 1.0); v_uv = vec2(0.0, 2.0); } } `,A=`#version 300 es precision highp float; in vec2 v_uv; uniform sampler2D u_tex; out vec4 outColor; void main() { vec2 uv = clamp(v_uv, 0.0, 1.0); outColor = texture(u_tex, uv); } `,E=`#version 300 es precision highp float; precision highp int; uniform vec2 u_cssSize; uniform float u_dpr; uniform float u_displayZoom; uniform vec4 u_diskFillColor; uniform vec4 u_diskBorderColor; uniform vec4 u_gridColor; uniform float u_diskBorderWidthPx; uniform float u_gridWidthPx; out vec4 outColor; void main() { // Convert framebuffer pixels to CSS pixels vec2 fragCss = gl_FragCoord.xy / max(u_dpr, 1.0); vec2 center = u_cssSize * 0.5; float diskRadius = min(u_cssSize.x, u_cssSize.y) * 0.45 * u_displayZoom; vec2 p = fragCss - center; float dist = length(p); // Reference-like styling vec3 diskFill = u_diskFillColor.rgb; vec3 diskBorder = u_diskBorderColor.rgb; float borderWidth = max(u_diskBorderWidthPx, 0.0); float halfW = 0.5 * borderWidth; // Anti-aliasing width (CSS px). Keep at least 1px for crisp edges. float aa = max(1.0, fwidth(dist)); // Discard outside disk+border region so the clear color remains intact. if (dist > diskRadius + halfW + aa) discard; // Outer fade for anti-aliased boundary float outerAlpha = 1.0 - smoothstep(diskRadius + halfW - aa, diskRadius + halfW + aa, dist); // Border mask float borderInner = smoothstep(diskRadius - halfW - aa, diskRadius - halfW + aa, dist); float borderOuter = 1.0 - smoothstep(diskRadius + halfW - aa, diskRadius + halfW + aa, dist); float borderMask = clamp(borderInner * borderOuter, 0.0, 1.0); vec3 col = mix(diskFill, diskBorder, borderMask); // ------------------------------------------------------------------------ // Reference-like hyperbolic grid overlay // ------------------------------------------------------------------------ // Matches HyperbolicReference.drawHyperbolicGrid(): // - 8 radial lines (geodesics through origin) // - 5 concentric circles vec3 gridCol = u_gridColor.rgb; float gridWidth = max(u_gridWidthPx, 0.0); float halfGrid = 0.5 * gridWidth; // AA width for thin lines in CSS pixel space. float aaLine = max(1.0, fwidth(dist)); float gridMask = 0.0; // Concentric circles (5) for (int i = 1; i <= 5; i++) { float r = (float(i) / 6.0) * diskRadius; float d = abs(dist - r); float m = 1.0 - smoothstep(halfGrid - aaLine, halfGrid + aaLine, d); gridMask = max(gridMask, m); } // Radial lines (8), angle = (i/8)*pi // Distance to line through origin with direction (cos a, sin a): |cross(p, dir)| for (int i = 0; i < 8; i++) { float a = (float(i) / 8.0) * 3.141592653589793; vec2 dir = vec2(cos(a), sin(a)); float d = abs(p.x * dir.y - p.y * dir.x); float m = 1.0 - smoothstep(halfGrid - aaLine, halfGrid + aaLine, d); gridMask = max(gridMask, m); } // Apply grid on top of disk fill/border. Use u_gridColor alpha as intensity. col = mix(col, gridCol, clamp(gridMask, 0.0, 1.0) * clamp(u_gridColor.a, 0.0, 1.0)); outColor = vec4(col, outerAlpha); } `,S=`#version 300 es precision highp float; precision highp int; layout(location = 0) in vec2 a_pos; layout(location = 1) in uint a_label; uniform vec2 u_center; uniform vec2 u_cssSize; uniform float u_zoom; uniform float u_dpr; uniform float u_pointRadiusCss; flat out uint v_label; void main() { float baseScale = min(u_cssSize.x, u_cssSize.y) * 0.4 * u_zoom; float sx = u_cssSize.x * 0.5 + (a_pos.x - u_center.x) * baseScale; float sy = u_cssSize.y * 0.5 - (a_pos.y - u_center.y) * baseScale; vec2 dbufSize = u_cssSize * u_dpr; vec2 dbuf = vec2(sx, sy) * u_dpr; float cx = (dbuf.x / dbufSize.x) * 2.0 - 1.0; float cy = 1.0 - (dbuf.y / dbufSize.y) * 2.0; gl_Position = vec4(cx, cy, 0.0, 1.0); gl_PointSize = (u_pointRadiusCss * 2.0) * u_dpr; v_label = a_label; } `,C=`#version 300 es precision highp float; precision highp int; layout(location = 0) in vec2 a_pos; layout(location = 1) in uint a_label; uniform vec2 u_cssSize; uniform float u_dpr; uniform float u_pointRadiusCss; uniform vec2 u_a; // camera translation (ax, ay) uniform float u_displayZoom; // visual zoom flat out uint v_label; vec2 mobiusTransform(vec2 z, vec2 a) { // (z - a) / (1 - conj(a) * z) vec2 num = z - a; // denom = 1 - (ax*zx + ay*zy) + i * (-(ax*zy - ay*zx)) float denomX = 1.0 - (a.x * z.x + a.y * z.y); float denomY = -(a.x * z.y - a.y * z.x); float denomNormSq = denomX * denomX + denomY * denomY; if (denomNormSq < 1e-12) { // Push outside clip return vec2(2.0, 2.0); } // complex division float rx = (num.x * denomX + num.y * denomY) / denomNormSq; float ry = (num.y * denomX - num.x * denomY) / denomNormSq; return vec2(rx, ry); } void main() { vec2 w = mobiusTransform(a_pos, u_a); float r2 = dot(w, w); if (r2 >= 1.0) { gl_Position = vec4(2.0, 2.0, 0.0, 1.0); gl_PointSize = 0.0; v_label = a_label; return; } float diskRadius = min(u_cssSize.x, u_cssSize.y) * 0.45 * u_displayZoom; float sx = u_cssSize.x * 0.5 + w.x * diskRadius; float sy = u_cssSize.y * 0.5 - w.y * diskRadius; vec2 dbufSize = u_cssSize * u_dpr; vec2 dbuf = vec2(sx, sy) * u_dpr; float cx = (dbuf.x / dbufSize.x) * 2.0 - 1.0; float cy = 1.0 - (dbuf.y / dbufSize.y) * 2.0; gl_Position = vec4(cx, cy, 0.0, 1.0); gl_PointSize = (u_pointRadiusCss * 2.0) * u_dpr; v_label = a_label; } `;class T{canvas=null;overlayCanvas=null;overlayCtx=null;width=0;height=0;deviceDpr=1;canvasDpr=1;dpr=1;dataset=null;selection=new Set;highlight=new Set;hoveredIndex=-1;lassoPolygon=null;lassoStyle={strokeColor:"#6366f1",strokeWidth:2,fillColor:"rgba(99, 102, 241, 0.12)"};pointRadiusCss=3;colors=e;backgroundColor="#0a0a0a";categoryVisibilityMask=new Uint8Array(0);hasCategoryVisibilityMask=!1;categoryAlpha=1;interactionStyle={selectionColor:i,selectionRadiusOffset:2,selectionRingWidth:2,highlightColor:"#94a3b8",highlightRadiusOffset:1,highlightRingWidth:1.5,hoverColor:r,hoverFillColor:null,hoverRadiusOffset:3};poincareDiskFillColor="#141414";poincareDiskBorderColor="#666666";poincareGridColor="#66666633";poincareDiskBorderWidthPx=2;poincareGridWidthPx=.5;paletteSize=0;paletteDirty=!0;paletteTex=null;paletteTexW=0;paletteTexH=0;paletteBytes=new Uint8Array(0);paletteTexUnit=1;scratchIds=[];hoverPosScratch=new Float32Array(2);hoverLabScratch=new Uint16Array(1);hoverIndexScratch=new Uint32Array(1);lastViewChangeTs=0;markViewChanged(){this.lastViewChangeTs=performance.now()}endInteraction(){this.lastViewChangeTs=0}markBackdropDirty(){this.backdropDirty=!0}uploadPoincareDiskStyleUniforms(){let t=this.gl,e=this.poincareDisk;if(!t||!e)return;let i=g(this.poincareDiskFillColor),r=g(this.poincareDiskBorderColor),s=g(this.poincareGridColor);e.uDiskFillColor&&t.uniform4f(e.uDiskFillColor,i[0],i[1],i[2],i[3]),e.uDiskBorderColor&&t.uniform4f(e.uDiskBorderColor,r[0],r[1],r[2],r[3]),e.uGridColor&&t.uniform4f(e.uGridColor,s[0],s[1],s[2],s[3]),e.uDiskBorderWidthPx&&t.uniform1f(e.uDiskBorderWidthPx,this.poincareDiskBorderWidthPx),e.uGridWidthPx&&t.uniform1f(e.uGridWidthPx,this.poincareGridWidthPx)}getBackdropZoom(){return 1}dataIndex=null;gl=null;vao=null;posBuffer=null;labelBuffer=null;hoverVao=null;hoverPosBuffer=null;hoverLabelBuffer=null;selectionVao=null;selectionPosBuffer=null;selectionLabelBuffer=null;selectionOverlayCount=0;highlightVao=null;highlightPosBuffer=null;highlightLabelBuffer=null;highlightOverlayCount=0;selectionEbo=null;highlightEbo=null;hoverEbo=null;interactionEbo=null;interactionCount=0;maxBaseDrawPoints=4e6;maxGpuUploadPoints=1e7;gpuUsesFullDataset=!0;gpuPointCount=0;policy={fragmentBudget:1e8,circleBudget:6e7,squareOnRatio:1,squareOffRatio:.75,minPointsDpr:.35};renderAsSquares=!1;__debugPolicy=null;backdropTex=null;backdropFbo=null;backdropW=0;backdropH=0;backdropDpr=1;backdropZoom=NaN;backdropDirty=!0;pointsTex=null;pointsFbo=null;pointsW=0;pointsH=0;programComposite=null;uCompositeTex=null;poincareDisk=null;pointsCircle=null;pointsSquare=null;programSolid=null;uSolidColor=null;uSolidPointSizePx=null;uSolidRingThicknessPx=null;uSolidRingMode=null;uCssSizeSolid=null;uDprSolid=null;uPointRadiusSolid=null;selectionDirty=!0;highlightDirty=!0;hoverDirty=!0;ensureOverlayCanvas(){if(this.canvas&&"u">typeof document){if(!this.overlayCanvas||!this.overlayCtx||!this.overlayCanvas.isConnected){let t=this.canvas.parentElement;if(!t)return;"static"===window.getComputedStyle(t).position&&(t.style.position="relative");let e=document.createElement("canvas");e.setAttribute("aria-hidden","true"),e.dataset.hyperScatterOverlay="lasso",e.style.position="absolute",e.style.inset="0",e.style.pointerEvents="none";let i=Number.parseInt(window.getComputedStyle(this.canvas).zIndex??"0",10);e.style.zIndex=Number.isFinite(i)?String(i+1):"1",t.appendChild(e),this.overlayCanvas=e,this.overlayCtx=e.getContext("2d")}this.syncOverlayCanvas()}}syncOverlayCanvas(){this.overlayCanvas&&this.overlayCtx&&(b(this.overlayCanvas,this.width,this.height,this.deviceDpr),function(t,e,i,r,s,o){if(t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,Math.max(1,Math.floor(i*e)),Math.max(1,Math.floor(r*e))),s&&!(s.length<6)){t.setTransform(e,0,0,e,0,0),t.beginPath(),t.moveTo(s[0],s[1]);for(let e=2;ethis.maxBaseDrawPoints?this.estimateSubsampleCount(t):t,s=Math.sqrt((t>=1e6?i>1e6?2e5:5e5:t>=5e5?14e5:t>=25e4?21e5:8e6)/i),o=Math.max(.5,this.pointRadiusCss),a=Math.max(1,r)*Math.PI*o*o,h=Math.sqrt(this.policy.fragmentBudget/a),n=t>=1e6?1:t>=5e5?1.25:1.5;return Math.max(t>=1e6?this.policy.minPointsDpr:t>=5e5?.75:1,Math.min(e,n,s,h))}estimateSubsampleCount(t){if(t<5e5)return t;let e=Math.min(t,Math.max(25e4,Math.min(this.maxBaseDrawPoints,Math.floor(.25*t)))),i=Math.max(1,Math.floor(t/e));return Math.min(e,Math.ceil(t/i))}estimatePointFragments(t,e){let i=Math.max(.5,this.pointRadiusCss),r=Math.max(0,e);return Math.max(0,t)*Math.PI*i*i*r*r}updateSquarePointPolicy(t){let e=this.policy.circleBudget*this.policy.squareOnRatio,i=this.policy.circleBudget*this.policy.squareOffRatio;if(this.dpr<=.75){this.renderAsSquares=!0;return}this.renderAsSquares?t<=i&&(this.renderAsSquares=!1):t>=e&&(this.renderAsSquares=!0)}setDataset(t){this.dataset=t,this.selection=new Set,this.highlight=new Set,this.hoveredIndex=-1,this.selectionDirty=!0,this.highlightDirty=!0,this.hoverDirty=!0,this.lassoPolygon=null,this.syncOverlayCanvas();let e=this.chooseRenderDpr(t.n);e!==this.dpr&&(this.dpr=e),this.dataIndex=new c(t.positions,void 0,64),this.gl&&this.uploadDatasetToGPU(),this.markBackdropDirty()}setPalette(t){this.colors=t,this.paletteDirty=!0,this.gl&&this.uploadPaletteUniforms()}setCategoryVisibility(t){if(null==t)this.categoryVisibilityMask=new Uint8Array(0),this.hasCategoryVisibilityMask=!1;else{let e=t.length>>>0,i=new Uint8Array(e);for(let r=0;r=0&&!this.isPointVisibleByCategory(this.hoveredIndex)&&(this.hoveredIndex=-1),this.paletteDirty=!0,this.selectionDirty=!0,this.highlightDirty=!0,this.hoverDirty=!0,this.gl&&(this.uploadPaletteUniforms(),this.uploadSelectionToGPU(),this.uploadHighlightToGPU(),this.uploadHoverToGPU())}setInactiveOpacity(t){let e=Number.isFinite(t)?Math.max(0,Math.min(1,t)):1;!(1e-12>=Math.abs(e-this.categoryAlpha))&&(this.categoryAlpha=e,this.paletteDirty=!0,this.gl&&this.uploadPaletteUniforms())}setInteractionStyle(t){"string"==typeof t.selectionColor&&t.selectionColor.length>0&&(this.interactionStyle.selectionColor=t.selectionColor),"number"==typeof t.selectionRadiusOffset&&Number.isFinite(t.selectionRadiusOffset)&&(this.interactionStyle.selectionRadiusOffset=Math.max(0,t.selectionRadiusOffset)),"number"==typeof t.selectionRingWidth&&Number.isFinite(t.selectionRingWidth)&&(this.interactionStyle.selectionRingWidth=Math.max(.5,t.selectionRingWidth)),"string"==typeof t.highlightColor&&t.highlightColor.length>0&&(this.interactionStyle.highlightColor=t.highlightColor),"number"==typeof t.highlightRadiusOffset&&Number.isFinite(t.highlightRadiusOffset)&&(this.interactionStyle.highlightRadiusOffset=Math.max(0,t.highlightRadiusOffset)),"number"==typeof t.highlightRingWidth&&Number.isFinite(t.highlightRingWidth)&&(this.interactionStyle.highlightRingWidth=Math.max(.5,t.highlightRingWidth)),"string"==typeof t.hoverColor&&t.hoverColor.length>0&&(this.interactionStyle.hoverColor=t.hoverColor),Object.prototype.hasOwnProperty.call(t,"hoverFillColor")&&(this.interactionStyle.hoverFillColor=t.hoverFillColor??null),"number"==typeof t.hoverRadiusOffset&&Number.isFinite(t.hoverRadiusOffset)&&(this.interactionStyle.hoverRadiusOffset=Math.max(0,t.hoverRadiusOffset))}isCategoryVisible(t){if(!this.hasCategoryVisibilityMask)return!0;let e=this.categoryVisibilityMask;return t<0||t>=e.length||0!==e[t]}isPointVisibleByCategory(t){let e=this.dataset;return!!e&&!(t<0)&&!(t>=e.n)&&this.isCategoryVisible(e.labels[t])}resize(t,e){this.width=t,this.height=e,this.syncOverlayCanvas(),this.gl&&this.canvas&&(b(this.canvas,t,e,this.canvasDpr),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.markBackdropDirty())}setSelection(t){let e=t??new Set,i=e.size;this.selection=i<=2e5?new Set(e):e,this.selectionDirty=!0,this.highlightDirty=!0,this.gl&&(this.uploadSelectionToGPU(),this.uploadHighlightToGPU())}getSelection(){return this.selection.size<=2e5?new Set(this.selection):this.selection}setHighlight(t){let e=t??new Set,i=e.size;this.highlight=i<=2e5?new Set(e):e,this.highlightDirty=!0,this.gl&&this.uploadHighlightToGPU()}getHighlight(){return this.highlight.size<=2e5?new Set(this.highlight):this.highlight}setHovered(t){t>=0&&!this.isPointVisibleByCategory(t)?this.hoveredIndex=-1:this.hoveredIndex=t,this.hoverDirty=!0,this.gl&&this.uploadHoverToGPU()}setLassoPolygon(t,e){e&&("string"==typeof e.strokeColor&&e.strokeColor.length>0&&(this.lassoStyle.strokeColor=e.strokeColor),"string"==typeof e.fillColor&&e.fillColor.length>0&&(this.lassoStyle.fillColor=e.fillColor),"number"==typeof e.strokeWidth&&Number.isFinite(e.strokeWidth)&&(this.lassoStyle.strokeWidth=Math.max(1,e.strokeWidth))),this.lassoPolygon=t&&t.length>=6?new Float32Array(t):null,this.ensureOverlayCanvas()}destroy(){let t=this.gl;t&&(this.pointsCircle&&t.deleteProgram(this.pointsCircle.program),this.pointsSquare&&t.deleteProgram(this.pointsSquare.program),this.programSolid&&t.deleteProgram(this.programSolid),this.poincareDisk&&t.deleteProgram(this.poincareDisk.program),this.vao&&t.deleteVertexArray(this.vao),this.hoverVao&&t.deleteVertexArray(this.hoverVao),this.selectionVao&&t.deleteVertexArray(this.selectionVao),this.highlightVao&&t.deleteVertexArray(this.highlightVao),this.posBuffer&&t.deleteBuffer(this.posBuffer),this.labelBuffer&&t.deleteBuffer(this.labelBuffer),this.hoverPosBuffer&&t.deleteBuffer(this.hoverPosBuffer),this.hoverLabelBuffer&&t.deleteBuffer(this.hoverLabelBuffer),this.selectionPosBuffer&&t.deleteBuffer(this.selectionPosBuffer),this.selectionLabelBuffer&&t.deleteBuffer(this.selectionLabelBuffer),this.highlightPosBuffer&&t.deleteBuffer(this.highlightPosBuffer),this.highlightLabelBuffer&&t.deleteBuffer(this.highlightLabelBuffer),this.selectionEbo&&t.deleteBuffer(this.selectionEbo),this.highlightEbo&&t.deleteBuffer(this.highlightEbo),this.hoverEbo&&t.deleteBuffer(this.hoverEbo),this.interactionEbo&&t.deleteBuffer(this.interactionEbo),this.backdropFbo&&t.deleteFramebuffer(this.backdropFbo),this.backdropTex&&t.deleteTexture(this.backdropTex),this.pointsFbo&&t.deleteFramebuffer(this.pointsFbo),this.pointsTex&&t.deleteTexture(this.pointsTex),this.paletteTex&&t.deleteTexture(this.paletteTex),this.programComposite&&t.deleteProgram(this.programComposite)),this.gl=null,this.vao=null,this.hoverVao=null,this.selectionVao=null,this.highlightVao=null,this.posBuffer=null,this.labelBuffer=null,this.hoverPosBuffer=null,this.hoverLabelBuffer=null,this.selectionPosBuffer=null,this.selectionLabelBuffer=null,this.selectionOverlayCount=0,this.highlightPosBuffer=null,this.highlightLabelBuffer=null,this.highlightOverlayCount=0,this.selectionEbo=null,this.highlightEbo=null,this.hoverEbo=null,this.interactionEbo=null,this.interactionCount=0,this.gpuUsesFullDataset=!0,this.gpuPointCount=0,this.backdropFbo=null,this.backdropTex=null,this.backdropW=0,this.backdropH=0,this.backdropDpr=1,this.backdropZoom=NaN,this.backdropDirty=!0,this.pointsFbo=null,this.pointsTex=null,this.pointsW=0,this.pointsH=0,this.programComposite=null,this.uCompositeTex=null,this.pointsCircle=null,this.pointsSquare=null,this.programSolid=null,this.poincareDisk=null,this.paletteTex=null,this.paletteTexW=0,this.paletteTexH=0,this.paletteSize=0,this.paletteDirty=!0,this.removeOverlayCanvas()}uploadPaletteUniforms(){let t=this.gl;if(!t)return;let e=this.colors.length,i=Math.max(1,Math.min(e,65536)),r=t.getParameter(t.MAX_TEXTURE_SIZE),s=Math.min(r,i),o=Math.ceil(i/s);if(o>r)throw Error(`Palette too large for WebGL texture: size=${i}, maxTex=${r}`);let a=s*o;if(this.paletteBytes.length!==4*a?this.paletteBytes=new Uint8Array(4*a):this.paletteBytes.fill(0),0===e){this.paletteBytes[0]=255,this.paletteBytes[1]=255,this.paletteBytes[2]=255;let t=this.isCategoryVisible(0);this.paletteBytes[3]=t?Math.round(255*this.categoryAlpha):0}else for(let t=0;t{e&&(t.useProgram(e.program),e.uPaletteTex&&t.uniform1i(e.uPaletteTex,this.paletteTexUnit),e.uPaletteSize&&t.uniform1i(e.uPaletteSize,this.paletteSize),e.uPaletteWidth&&t.uniform1i(e.uPaletteWidth,this.paletteTexW))};h(this.pointsCircle),h(this.pointsSquare),this.paletteDirty=!1}bindPaletteTexture(){let t=this.gl;t&&this.paletteTex&&(t.activeTexture(t.TEXTURE0+this.paletteTexUnit),t.bindTexture(t.TEXTURE_2D,this.paletteTex),t.activeTexture(t.TEXTURE0))}async countSelection(t,e={}){let i=this.dataset,r=this.dataIndex;if(!i||!r)return 0;if(t.indices){let e=0;for(let i of t.indices)this.isPointVisibleByCategory(i)&&e++;return e}if("geometry"!==t.kind||!t.geometry)return 0;let s=t.geometry.coords;if(s.length/2<3)return 0;let o=t.geometry.bounds;if(!o){let t=1/0,e=1/0,i=-1/0,r=-1/0;for(let o=0;oi&&(i=a),hr&&(r=h)}o={xMin:t,yMin:e,xMax:i,yMax:r}}let a=e.shouldCancel,h=e.onProgress,n="number"==typeof e.yieldEveryMs&&Number.isFinite(e.yieldEveryMs)?Math.max(0,e.yieldEveryMs):8,l=o.xMin-1e-12,u=o.yMin-1e-12,d=o.xMax+1e-12,f=o.yMax+1e-12,c=(t,e,i)=>ti?i:0|t,g=c(Math.floor((l-r.bounds.minX)/r.cellSizeX),0,r.cellsX-1),m=c(Math.floor((u-r.bounds.minY)/r.cellSizeY),0,r.cellsY-1),y=c(Math.floor((d-r.bounds.minX)/r.cellSizeX),0,r.cellsX-1),b=c(Math.floor((f-r.bounds.minY)/r.cellSizeY),0,r.cellsY-1),x=i.positions,v=r.ids,R=r.offsets,P=0,A=0,E=16384,S=n>0?performance.now():0;for(let t=m;t<=b;t++){let e=t*r.cellsX;for(let t=g;t<=y;t++){let r=e+t,l=R[r],u=R[r+1];for(let t=l;to.xMax)&&!(lo.yMax)&&(p(r,l,s)&&P++,A++,n>0&&A>=E)){if(E=A+16384,a?.())return P;performance.now()-S>=n&&(h?.(P,A),await new Promise(t=>requestAnimationFrame(()=>t())),S=performance.now())}}}}return h?.(P,A),P}ensureGL(){if(this.gl)return;if(!this.canvas)throw Error("Renderer not initialized");b(this.canvas,this.width,this.height,this.canvasDpr);let t=this.canvas.getContext("webgl2",{antialias:!1,alpha:!1,depth:!1,stencil:!1,preserveDrawingBuffer:!1,premultipliedAlpha:!1,desynchronized:!0});if(!t)throw Error("Failed to get WebGL2 context (is the canvas already using 2D context?)");this.gl=t,t.disable(t.DEPTH_TEST),t.disable(t.CULL_FACE),t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA);let[e,i,r,s]=g(this.backgroundColor);t.clearColor(e,i,r,s),t.viewport(0,0,this.canvas.width,this.canvas.height),this.createProgramsAndBuffers(),this.uploadPaletteUniforms(),this.dataset&&this.uploadDatasetToGPU(),this.uploadSelectionToGPU(),this.uploadHighlightToGPU(),this.uploadHoverToGPU(),this.markBackdropDirty()}ensurePointsResources(){if(!this.gl||!this.canvas)return;let t=this.gl,e=Math.max(1,Math.floor(this.width*this.dpr)),i=Math.max(1,Math.floor(this.height*this.dpr)),r=t.getParameter(t.MAX_TEXTURE_SIZE);if(e>r||i>r){let t=Math.min(1,r/e,r/i);e=Math.max(1,Math.floor(e*t)),i=Math.max(1,Math.floor(i*t))}if(!this.pointsTex){if(this.pointsTex=t.createTexture(),!this.pointsTex)throw Error("Failed to create points texture");t.bindTexture(t.TEXTURE_2D,this.pointsTex),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.bindTexture(t.TEXTURE_2D,null)}if(!this.pointsFbo&&(this.pointsFbo=t.createFramebuffer(),!this.pointsFbo))throw Error("Failed to create points framebuffer");if(e!==this.pointsW||i!==this.pointsH){this.pointsW=e,this.pointsH=i,t.bindTexture(t.TEXTURE_2D,this.pointsTex),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,e,i,0,t.RGBA,t.UNSIGNED_BYTE,null),t.bindTexture(t.TEXTURE_2D,null),t.bindFramebuffer(t.FRAMEBUFFER,this.pointsFbo),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,this.pointsTex,0);let r=t.checkFramebufferStatus(t.FRAMEBUFFER);if(t.bindFramebuffer(t.FRAMEBUFFER,null),r!==t.FRAMEBUFFER_COMPLETE)throw Error(`Points framebuffer incomplete: ${r}`)}}ensureBackdropResources(){if(!this.gl||!this.canvas||"poincare"!==this.geometryKind()||!this.poincareDisk||!this.vao)return;let t=this.gl,e=Math.max(1,this.canvasDpr),i=Math.max(1,Math.floor(this.width*e)),r=Math.max(1,Math.floor(this.height*e)),s=t.getParameter(t.MAX_TEXTURE_SIZE);if(i>s||r>s){let t=Math.min(1,s/i,s/r);i=Math.max(1,Math.floor(i*t)),r=Math.max(1,Math.floor(r*t)),this.backdropDpr=e*t}else this.backdropDpr=e;if(!this.backdropTex){if(this.backdropTex=t.createTexture(),!this.backdropTex)throw Error("Failed to create backdrop texture");t.bindTexture(t.TEXTURE_2D,this.backdropTex),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.bindTexture(t.TEXTURE_2D,null)}if(!this.backdropFbo&&(this.backdropFbo=t.createFramebuffer(),!this.backdropFbo))throw Error("Failed to create backdrop framebuffer");if(i!==this.backdropW||r!==this.backdropH){this.backdropW=i,this.backdropH=r,t.bindTexture(t.TEXTURE_2D,this.backdropTex),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,i,r,0,t.RGBA,t.UNSIGNED_BYTE,null),t.bindTexture(t.TEXTURE_2D,null),t.bindFramebuffer(t.FRAMEBUFFER,this.backdropFbo),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,this.backdropTex,0);let e=t.checkFramebufferStatus(t.FRAMEBUFFER);if(t.bindFramebuffer(t.FRAMEBUFFER,null),e!==t.FRAMEBUFFER_COMPLETE)throw Error(`Backdrop framebuffer incomplete: ${e}`);this.markBackdropDirty()}}renderBackdropIfNeeded(){if(!this.gl||!this.canvas||"poincare"!==this.geometryKind()||!this.poincareDisk||!this.vao||(this.ensureBackdropResources(),!this.backdropFbo))return;let t=this.getBackdropZoom(),e=Number.isFinite(this.backdropZoom)&&1e-12>=Math.abs(this.backdropZoom-t);if(!this.backdropDirty&&e)return;let i=this.gl;i.bindFramebuffer(i.FRAMEBUFFER,this.backdropFbo),i.viewport(0,0,this.backdropW,this.backdropH);let[r,s,o,a]=g(this.backgroundColor);i.clearColor(r,s,o,a),i.clear(i.COLOR_BUFFER_BIT),i.useProgram(this.poincareDisk.program),this.bindViewUniformsForProgram(this.poincareDisk.program),this.uploadPoincareDiskStyleUniforms(),this.poincareDisk.uCssSize&&i.uniform2f(this.poincareDisk.uCssSize,this.width,this.height),this.poincareDisk.uDpr&&i.uniform1f(this.poincareDisk.uDpr,this.backdropDpr),i.bindVertexArray(this.vao),i.drawArrays(i.TRIANGLES,0,3),i.bindFramebuffer(i.FRAMEBUFFER,null),i.viewport(0,0,this.canvas.width,this.canvas.height),this.backdropZoom=t,this.backdropDirty=!1}createProgramsAndBuffers(){let t=this.gl,e="euclidean"===this.geometryKind()?S:C,i=y(t,e,x),r=y(t,e,v);if(this.programSolid=y(t,e,R),this.programComposite=y(t,P,A),t.useProgram(this.programComposite),this.uCompositeTex=t.getUniformLocation(this.programComposite,"u_tex"),"poincare"===this.geometryKind()){let e=y(t,P,E);this.poincareDisk={program:e,uCssSize:t.getUniformLocation(e,"u_cssSize"),uDpr:t.getUniformLocation(e,"u_dpr"),uDiskFillColor:t.getUniformLocation(e,"u_diskFillColor"),uDiskBorderColor:t.getUniformLocation(e,"u_diskBorderColor"),uGridColor:t.getUniformLocation(e,"u_gridColor"),uDiskBorderWidthPx:t.getUniformLocation(e,"u_diskBorderWidthPx"),uGridWidthPx:t.getUniformLocation(e,"u_gridWidthPx")},t.useProgram(e),this.uploadPoincareDiskStyleUniforms()}if(t.useProgram(i),this.pointsCircle={program:i,uPaletteTex:t.getUniformLocation(i,"u_paletteTex"),uPaletteSize:t.getUniformLocation(i,"u_paletteSize"),uPaletteWidth:t.getUniformLocation(i,"u_paletteWidth"),uCssSize:t.getUniformLocation(i,"u_cssSize"),uDpr:t.getUniformLocation(i,"u_dpr"),uPointRadius:t.getUniformLocation(i,"u_pointRadiusCss")},t.useProgram(r),this.pointsSquare={program:r,uPaletteTex:t.getUniformLocation(r,"u_paletteTex"),uPaletteSize:t.getUniformLocation(r,"u_paletteSize"),uPaletteWidth:t.getUniformLocation(r,"u_paletteWidth"),uCssSize:t.getUniformLocation(r,"u_cssSize"),uDpr:t.getUniformLocation(r,"u_dpr"),uPointRadius:t.getUniformLocation(r,"u_pointRadiusCss")},t.useProgram(this.programSolid),this.uSolidColor=t.getUniformLocation(this.programSolid,"u_color"),this.uSolidPointSizePx=t.getUniformLocation(this.programSolid,"u_pointSizePx"),this.uSolidRingThicknessPx=t.getUniformLocation(this.programSolid,"u_ringThicknessPx"),this.uSolidRingMode=t.getUniformLocation(this.programSolid,"u_ringMode"),this.uCssSizeSolid=t.getUniformLocation(this.programSolid,"u_cssSize"),this.uDprSolid=t.getUniformLocation(this.programSolid,"u_dpr"),this.uPointRadiusSolid=t.getUniformLocation(this.programSolid,"u_pointRadiusCss"),this.vao=t.createVertexArray(),this.posBuffer=t.createBuffer(),this.labelBuffer=t.createBuffer(),this.hoverVao=t.createVertexArray(),this.hoverPosBuffer=t.createBuffer(),this.hoverLabelBuffer=t.createBuffer(),this.selectionVao=t.createVertexArray(),this.selectionPosBuffer=t.createBuffer(),this.selectionLabelBuffer=t.createBuffer(),this.highlightVao=t.createVertexArray(),this.highlightPosBuffer=t.createBuffer(),this.highlightLabelBuffer=t.createBuffer(),this.selectionEbo=t.createBuffer(),this.highlightEbo=t.createBuffer(),this.hoverEbo=t.createBuffer(),this.interactionEbo=t.createBuffer(),!this.vao||!this.posBuffer||!this.labelBuffer||!this.hoverVao||!this.hoverPosBuffer||!this.hoverLabelBuffer||!this.selectionVao||!this.selectionPosBuffer||!this.selectionLabelBuffer||!this.highlightVao||!this.highlightPosBuffer||!this.highlightLabelBuffer||!this.selectionEbo||!this.highlightEbo||!this.hoverEbo||!this.interactionEbo)throw Error("Failed to allocate WebGL resources");t.bindVertexArray(this.vao),t.bindBuffer(t.ARRAY_BUFFER,this.posBuffer),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.labelBuffer),t.enableVertexAttribArray(1),t.vertexAttribIPointer(1,1,t.UNSIGNED_SHORT,0,0),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null),t.bindVertexArray(this.hoverVao),t.bindBuffer(t.ARRAY_BUFFER,this.hoverPosBuffer),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.hoverLabelBuffer),t.enableVertexAttribArray(1),t.vertexAttribIPointer(1,1,t.UNSIGNED_SHORT,0,0),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null),t.bindVertexArray(this.selectionVao),t.bindBuffer(t.ARRAY_BUFFER,this.selectionPosBuffer),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.selectionLabelBuffer),t.enableVertexAttribArray(1),t.vertexAttribIPointer(1,1,t.UNSIGNED_SHORT,0,0),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null),t.bindVertexArray(this.highlightVao),t.bindBuffer(t.ARRAY_BUFFER,this.highlightPosBuffer),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.highlightLabelBuffer),t.enableVertexAttribArray(1),t.vertexAttribIPointer(1,1,t.UNSIGNED_SHORT,0,0),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null)}uploadDatasetToGPU(){let t=this.gl,e=this.dataset;if(!e)return;t.bindVertexArray(this.vao);let i=e.n<=this.maxGpuUploadPoints;if(this.gpuUsesFullDataset=i,i)t.bindBuffer(t.ARRAY_BUFFER,this.posBuffer),t.bufferData(t.ARRAY_BUFFER,e.positions,t.STATIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.labelBuffer),t.bufferData(t.ARRAY_BUFFER,e.labels,t.STATIC_DRAW),this.gpuPointCount=e.n;else{let i=e.n,r=Math.min(i,Math.max(25e4,Math.min(this.maxBaseDrawPoints,Math.floor(.25*i)))),s=Math.max(1,Math.floor(i/r)),o=Math.min(r,Math.ceil(i/s)),a=new Float32Array(2*o),h=new Uint16Array(o),n=0;for(let t=0;t=5e5){let e=Math.min(i,Math.max(25e4,Math.min(this.maxBaseDrawPoints,Math.floor(.25*i)))),r=Math.max(1,Math.floor(i/e)),s=Math.min(e,Math.ceil(i/r)),o=new Uint32Array(s),a=0;for(let t=0;t=r))break;this.selectionOverlayCount=a,t.bindVertexArray(this.selectionVao),t.bindBuffer(t.ARRAY_BUFFER,this.selectionPosBuffer),t.bufferData(t.ARRAY_BUFFER,s,t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.selectionLabelBuffer),t.bufferData(t.ARRAY_BUFFER,o,t.DYNAMIC_DRAW),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null),this.selectionDirty=!1;return}let e=Math.min(this.selection.size,25e4);if(this.selectionOverlayCount=e,0===e){this.selectionDirty=!1;return}let i=new Uint32Array(e),r=0;for(let t of this.selection)if(this.isPointVisibleByCategory(t)&&(i[r++]=t,r>=e))break;this.selectionOverlayCount=r,t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.selectionEbo),t.bufferData(t.ELEMENT_ARRAY_BUFFER,i,t.DYNAMIC_DRAW),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null),this.selectionDirty=!1}uploadHighlightToGPU(){if(!this.gl||!this.highlightEbo)return;let t=this.gl;if(!this.gpuUsesFullDataset){let e=this.dataset;if(!e||!this.highlightVao||!this.highlightPosBuffer||!this.highlightLabelBuffer)return;let i=Math.min(this.highlight.size,25e4);if(this.highlightOverlayCount=i,0===i){this.highlightDirty=!1;return}let r=new Float32Array(2*i),s=new Uint16Array(i),o=0;for(let t of this.highlight)if(!this.selection.has(t)&&this.isPointVisibleByCategory(t)&&(r[2*o]=e.positions[2*t],r[2*o+1]=e.positions[2*t+1],s[o]=e.labels[t],++o>=i))break;this.highlightOverlayCount=o,t.bindVertexArray(this.highlightVao),t.bindBuffer(t.ARRAY_BUFFER,this.highlightPosBuffer),t.bufferData(t.ARRAY_BUFFER,r,t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.highlightLabelBuffer),t.bufferData(t.ARRAY_BUFFER,s,t.DYNAMIC_DRAW),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null),this.highlightDirty=!1;return}let e=Math.min(this.highlight.size,25e4);if(this.highlightOverlayCount=e,0===e){this.highlightDirty=!1;return}let i=new Uint32Array(e),r=0;for(let t of this.highlight)if(!this.selection.has(t)&&this.isPointVisibleByCategory(t)&&(i[r++]=t,r>=e))break;this.highlightOverlayCount=r,t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.highlightEbo),t.bufferData(t.ELEMENT_ARRAY_BUFFER,i,t.DYNAMIC_DRAW),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null),this.highlightDirty=!1}uploadHoverToGPU(){if(!this.gl||!this.hoverEbo)return;let t=this.gl;if(!this.gpuUsesFullDataset){let e=this.dataset;if(!e||!this.hoverVao||!this.hoverPosBuffer||!this.hoverLabelBuffer)return;let i=this.hoveredIndex>=0&&this.hoveredIndex=0?(r[0]=e.positions[2*i],r[1]=e.positions[2*i+1],s[0]=e.labels[i]):(r[0]=2,r[1]=2,s[0]=0),t.bindVertexArray(this.hoverVao),t.bindBuffer(t.ARRAY_BUFFER,this.hoverPosBuffer),t.bufferData(t.ARRAY_BUFFER,r,t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.hoverLabelBuffer),t.bufferData(t.ARRAY_BUFFER,s,t.DYNAMIC_DRAW),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null),this.hoverDirty=!1;return}let e=this.hoveredIndex>=0&&this.isPointVisibleByCategory(this.hoveredIndex)?this.hoveredIndex:0,i=this.hoverIndexScratch;i[0]=e,t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.hoverEbo),t.bufferData(t.ELEMENT_ARRAY_BUFFER,i,t.DYNAMIC_DRAW),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null),this.hoverDirty=!1}drawOverlayPointSet(t,e,i){let r=this.gl;if(r&&!(t<=0)){if(this.gpuUsesFullDataset){if(!e)return;r.bindVertexArray(this.vao),r.bindBuffer(r.ELEMENT_ARRAY_BUFFER,e),r.drawElements(r.POINTS,t,r.UNSIGNED_INT,0),r.bindBuffer(r.ELEMENT_ARRAY_BUFFER,null);return}i&&(r.bindVertexArray(i),r.drawArrays(r.POINTS,0,t),r.bindVertexArray(this.vao))}}drawEmphasisOverlay(t,e,i,r,s,o){let a=this.gl;if(!a||!this.programSolid||t<=0)return;let h=this.pointRadiusCss+Math.max(0,i);if(a.useProgram(this.programSolid),this.bindViewUniformsForProgram(this.programSolid),this.uCssSizeSolid&&a.uniform2f(this.uCssSizeSolid,this.width,this.height),this.uDprSolid&&a.uniform1f(this.uDprSolid,this.dpr),this.uPointRadiusSolid&&a.uniform1f(this.uPointRadiusSolid,h),this.uSolidColor){let[t,i,r,s]=g(e);a.uniform4f(this.uSolidColor,t,i,r,s)}this.uSolidRingMode&&a.uniform1i(this.uSolidRingMode,1),this.uSolidRingThicknessPx&&a.uniform1f(this.uSolidRingThicknessPx,Math.max(.5,r)),this.uSolidPointSizePx&&a.uniform1f(this.uSolidPointSizePx,2*h*this.dpr),this.drawOverlayPointSet(t,s,o);let n=this.pointsCircle;n&&(a.useProgram(n.program),this.bindViewUniformsForProgram(n.program),this.paletteDirty&&this.uploadPaletteUniforms(),this.bindPaletteTexture(),n.uCssSize&&a.uniform2f(n.uCssSize,this.width,this.height),n.uDpr&&a.uniform1f(n.uDpr,this.dpr),n.uPointRadius&&a.uniform1f(n.uPointRadius,this.pointRadiusCss),this.drawOverlayPointSet(t,s,o))}render(){this.ensureGL();let t=this.gl,e=this.dataset;if(!e)return;let i=performance.now()-this.lastViewChangeTs<80,r=!!this.interactionEbo&&this.interactionCount>0,s=i&&"poincare"===this.geometryKind()&&e.n>=2e6&&r,o=e.n>this.maxBaseDrawPoints&&r,a=this.gpuUsesFullDataset&&(s||o),h=this.gpuUsesFullDataset?a?this.interactionCount:e.n:this.gpuPointCount,n=this.estimatePointFragments(h,this.dpr);if(this.updateSquarePointPolicy(n),this.selectionDirty&&this.uploadSelectionToGPU(),this.highlightDirty&&this.uploadHighlightToGPU(),this.hoverDirty&&this.uploadHoverToGPU(),t.bindFramebuffer(t.FRAMEBUFFER,null),t.viewport(0,0,this.canvas.width,this.canvas.height),t.disable(t.BLEND),"poincare"===this.geometryKind())if(this.renderBackdropIfNeeded(),this.backdropTex&&this.programComposite)t.useProgram(this.programComposite),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.backdropTex),this.uCompositeTex&&t.uniform1i(this.uCompositeTex,0),t.bindVertexArray(this.vao),t.drawArrays(t.TRIANGLES,0,3),t.bindTexture(t.TEXTURE_2D,null);else{let[e,i,r,s]=g(this.backgroundColor);t.clearColor(e,i,r,s),t.clear(t.COLOR_BUFFER_BIT)}else{let[e,i,r,s]=g(this.backgroundColor);t.clearColor(e,i,r,s),t.clear(t.COLOR_BUFFER_BIT)}if(this.ensurePointsResources(),!this.pointsFbo||!this.pointsTex||!this.programComposite)return;t.bindFramebuffer(t.FRAMEBUFFER,this.pointsFbo),t.viewport(0,0,this.pointsW,this.pointsH),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT);let l=this.renderAsSquares?this.pointsSquare:this.pointsCircle;if(l){if(t.useProgram(l.program),this.bindViewUniformsForProgram(l.program),this.paletteDirty&&this.uploadPaletteUniforms(),this.bindPaletteTexture(),l.uCssSize&&t.uniform2f(l.uCssSize,this.width,this.height),l.uDpr&&t.uniform1f(l.uDpr,this.dpr),l.uPointRadius&&t.uniform1f(l.uPointRadius,this.pointRadiusCss),this.renderAsSquares?t.disable(t.BLEND):(t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA)),t.bindVertexArray(this.vao),a)t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.interactionEbo),t.drawElements(t.POINTS,this.interactionCount,t.UNSIGNED_INT,0),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null);else{let i=this.gpuUsesFullDataset?e.n:this.gpuPointCount;t.drawArrays(t.POINTS,0,i)}if(this.__debugPolicy={pointsDpr:this.dpr,deviceDpr:this.deviceDpr,canvasDpr:this.canvasDpr,renderAsSquares:this.renderAsSquares,useLod:a,baseDrawCount:h,interactionCount:this.interactionCount,gpuUsesFullDataset:this.gpuUsesFullDataset,gpuPointCount:this.gpuPointCount,estimatedPointFragments:n,fragmentBudget:this.policy.fragmentBudget,isInteracting:i},!i&&this.highlightOverlayCount>0&&this.drawEmphasisOverlay(this.highlightOverlayCount,this.interactionStyle.highlightColor,this.interactionStyle.highlightRadiusOffset,this.interactionStyle.highlightRingWidth,this.highlightEbo,this.highlightVao),!i&&this.selectionOverlayCount>0&&this.drawEmphasisOverlay(this.selectionOverlayCount,this.interactionStyle.selectionColor,this.interactionStyle.selectionRadiusOffset,this.interactionStyle.selectionRingWidth,this.selectionEbo,this.selectionVao),!i&&this.hoveredIndex>=0&&this.hoveredIndex0))return null;let l=s/n*(1+1e-12),u=l*l,d=a(t,e,this.view,this.width,this.height),f=.5*this.width,c=.5*this.height,p=this.view.centerX,g=this.view.centerY,m=-1,y=1/0;if(r.forEachInAABB(d.x-l,d.y-l,d.x+l,d.y+l,r=>{if(!this.isCategoryVisible(i.labels[r]))return;let s=i.positions[2*r],o=i.positions[2*r+1],a=s-d.x,l=o-d.y;if(a*a+l*l>u)return;let b=f+(s-p)*n-t,x=c-(o-g)*n-e,v=b*b+x*x;v<=h&&(vl&&(l=e),iu&&(u=i)}let d={xMin:h,yMin:n,xMax:l,yMax:u};return{kind:"geometry",geometry:{type:"polygon",coords:o,bounds:d},computeTimeMs:performance.now()-r,has:t=>{if(t<0||t>=e.n||!this.isCategoryVisible(e.labels[t]))return!1;let i=e.positions[2*t],r=e.positions[2*t+1];return!(id.xMax)&&!(rd.yMax)&&p(i,r,o)}}}projectToScreen(t,e){return o(t,e,this.view,this.width,this.height)}unprojectFromScreen(t,e){return a(t,e,this.view,this.width,this.height)}}class B extends T{view=h();uniformCache=new Map;lastPanScreenX=0;lastPanScreenY=0;hasPanAnchor=!1;geometryKind(){return"poincare"}getBackdropZoom(){return this.view.displayZoom}setDataset(t){if("poincare"!==t.geometry)throw Error("HyperbolicWebGLCandidate only supports poincare geometry");super.setDataset(t),this.view=h(),this.hasPanAnchor=!1}setView(t){if("poincare"!==t.type)throw Error("HyperbolicWebGLCandidate only supports poincare view state");this.view=t,this.markBackdropDirty()}getView(){return{...this.view}}bindViewUniformsForProgram(t){if(!this.gl)return;let e=this.gl,i=this.uniformCache.get(t);i||(i={uA:e.getUniformLocation(t,"u_a"),uDisplayZoom:e.getUniformLocation(t,"u_displayZoom")},this.uniformCache.set(t,i)),i.uA&&e.uniform2f(i.uA,this.view.ax,this.view.ay),i.uDisplayZoom&&e.uniform1f(i.uDisplayZoom,this.view.displayZoom)}startPan(t,e){this.lastPanScreenX=t,this.lastPanScreenY=e,this.hasPanAnchor=!0}pan(t,e,i){if(!this.hasPanAnchor)throw Error("startPan() must be called before pan()");let r=this.lastPanScreenX,s=this.lastPanScreenY,o=r+t,a=s+e;this.view=d(this.view,r,s,o,a,this.width,this.height),this.markViewChanged(),this.lastPanScreenX=o,this.lastPanScreenY=a}zoom(t,e,i,r){var s,o,a;let h,l,f,c,p,g,m,y;this.view=(s=this.view,o=this.width,a=this.height,h=Math.pow(1.1,i),l=Math.max(.5,Math.min(10,s.displayZoom*h)),f=u(t,e,s,o,a),c=.45*Math.min(o,a)*l,g=o/2+(p=n(f.x,f.y,s.ax,s.ay)).x*c,y=(m=a/2-p.y*c)-e,Math.abs(g-t)>.5||Math.abs(y)>.5?d({...s,displayZoom:l},g,m,t,e,o,a):{...s,displayZoom:l}),this.markViewChanged(),this.markBackdropDirty()}mobiusDerivativeScaleAt(t,e){let i=this.view.ax,r=this.view.ay,s=1-(i*t+r*e),o=-(i*e-r*t),a=s*s+o*o;return a<1e-12?0:Math.max(0,1-(i*i+r*r))/a}conservativeDataRadiusForScreenRadius(t,e,i,r){let s=this.view.ax,o=this.view.ay,a=s*s+o*o,h=Math.sqrt(a),n=Math.max(1e-12,1-a);if(!(r>1e-9)||!(i>0))return 0;let l=1-(s*t+o*e),u=-(s*e-o*t),d=Math.sqrt(l*l+u*u);if(!Number.isFinite(d)||d<1e-12)return 2;let f=i/(r*n),c=f*d*d;for(let t=0;t<5;t++){let t=d+h*c;c=f*t*t}return Number.isFinite(c)?Math.min(1.999,Math.max(0,c*=1.001)):2}hitTest(t,e){let i=this.dataset,r=this.dataIndex;if(!i||!r)return null;let{width:s,height:o,view:a}=this,h=s/2,n=o/2,l=.45*Math.min(s,o)*a.displayZoom,d=l*l,f=this.pointRadiusCss+5,c=f*f,p=t-h,g=e-n,m=l+f;if(p*p+g*g>m*m)return null;let y=u(t,e,a,s,o),b=this.conservativeDataRadiusForScreenRadius(y.x,y.y,f,l),x=-1,v=1/0,R=a.ax,P=a.ay;if(r.forEachInAABB(y.x-b,y.y-b,y.x+b,y.y+b,r=>{if(!this.isCategoryVisible(i.labels[r]))return;let s=i.positions[2*r],o=i.positions[2*r+1],a=s-R,u=o-P,f=1-(R*s+P*o),p=-(R*o-P*s),g=f*f+p*p,m=0,y=0;if(g<1e-12){let t=Math.sqrt(a*a+u*u);t<1e-12?(m=0,y=0):(m=a/t*.999,y=u/t*.999)}else{let t=(m=(a*f+u*p)/g)*m+(y=(u*f-a*p)/g)*y;if(t>=1){let e=Math.sqrt(t);m=m/e*.999,y=y/e*.999}}let b=h+m*l,A=n-y*l,E=b-h,S=A-n;if(E*E+S*S>d)return;let C=b-t,T=A-e,_=C*C+T*T;_<=c&&(_=1){let e=Math.sqrt(t);M=M/e*.999,F=F/e*.999}}return{index:x,screenX:h+M*l,screenY:n-F*l,distance:Math.sqrt(v)}}lassoSelect(t){let e=this.dataset,i=this.dataIndex;if(!e||!i)return s(new Set,0);let r=performance.now(),o=new Float32Array(t.length);for(let e=0;en&&(n=e),il&&(l=i)}let d={xMin:a,yMin:h,xMax:n,yMax:l};return{kind:"geometry",geometry:{type:"polygon",coords:o,bounds:d},computeTimeMs:performance.now()-r,has:t=>{if(t<0||t>=e.n||!this.isCategoryVisible(e.labels[t]))return!1;let i=e.positions[2*t],r=e.positions[2*t+1];return!(id.xMax)&&!(rd.yMax)&&p(i,r,o)}}}projectToScreen(t,e){var i,r,s;let o,a;return i=this.view,r=this.width,s=this.height,o=n(t,e,i.ax,i.ay),a=.45*Math.min(r,s)*i.displayZoom,{x:r/2+o.x*a,y:s/2-o.y*a}}unprojectFromScreen(t,e){return u(t,e,this.view,this.width,this.height)}}let M=[0,1,0];function F(t,e,i){return ti?i:t}function w(){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])}function D(t){return Math.hypot(t[0],t[1],t[2])}function U(t){let e=D(t);return e<1e-12?[0,0,0]:[t[0]/e,t[1]/e,t[2]/e]}function V(t,e){return[t[0]-e[0],t[1]-e[1],t[2]-e[2]]}function k(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function L(t,e,i,r){return[t[0]*e+t[4]*i+t[8]*r+t[12],t[1]*e+t[5]*i+t[9]*r+t[13],t[2]*e+t[6]*i+t[10]*r+t[14],t[3]*e+t[7]*i+t[11]*r+t[15]]}function I(t){let e=t.trim();if(!e.startsWith("#"))return[1,1,1,1];let i=e.slice(1);return 3===i.length?[Number.parseInt(i[0]+i[0],16)/255,Number.parseInt(i[1]+i[1],16)/255,Number.parseInt(i[2]+i[2],16)/255,1]:6===i.length||8===i.length?[Number.parseInt(i.slice(0,2),16)/255,Number.parseInt(i.slice(2,4),16)/255,Number.parseInt(i.slice(4,6),16)/255,8===i.length?Number.parseInt(i.slice(6,8),16)/255:1]:[1,1,1,1]}function N(t,e,i){let r=t.createShader(e);if(!r)throw Error("Failed to create shader");if(t.shaderSource(r,i),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS)){let e=t.getShaderInfoLog(r)??"unknown";throw t.deleteShader(r),Error(`Shader compile failed: ${e}`)}return r}function z(t,e,i){let r=N(t,t.VERTEX_SHADER,e),s=N(t,t.FRAGMENT_SHADER,i),o=t.createProgram();if(!o)throw Error("Failed to create program");if(t.attachShader(o,r),t.attachShader(o,s),t.linkProgram(o),t.deleteShader(r),t.deleteShader(s),!t.getProgramParameter(o,t.LINK_STATUS)){let e=t.getProgramInfoLog(o)??"unknown";throw t.deleteProgram(o),Error(`Program link failed: ${e}`)}return o}function O(t,e,i,r){t.width=Math.max(1,Math.floor(e*r)),t.height=Math.max(1,Math.floor(i*r)),t.style.width=`${e}px`,t.style.height=`${i}px`}function Y(t,e){return{kind:"indices",indices:t,computeTimeMs:e,has:e=>t.has(e)}}let W=`#version 300 es precision highp float; precision highp int; layout(location = 0) in vec3 a_pos; layout(location = 1) in uint a_label; uniform mat4 u_mvp; uniform float u_pointSizePx; flat out uint v_label; void main() { gl_Position = u_mvp * vec4(a_pos, 1.0); gl_PointSize = u_pointSizePx; v_label = a_label; } `,G=`#version 300 es precision highp float; precision highp int; flat in uint v_label; uniform sampler2D u_paletteTex; uniform int u_paletteSize; uniform int u_paletteWidth; out vec4 outColor; void main() { vec2 p = gl_PointCoord * 2.0 - 1.0; float r = length(p); float aa = max(fwidth(r), 0.02); float alpha = 1.0 - smoothstep(1.0 - aa, 1.0 + aa, r); if (alpha <= 0.0) discard; int size = max(u_paletteSize, 1); int w = max(u_paletteWidth, 1); int idx = int(v_label) % size; int x = idx % w; int y = idx / w; vec4 c = texelFetch(u_paletteTex, ivec2(x, y), 0); float outAlpha = c.a * alpha; if (outAlpha <= 0.0) discard; outColor = vec4(c.rgb, outAlpha); } `,X=`#version 300 es precision highp float; layout(location = 0) in vec3 a_pos; uniform mat4 u_mvp; uniform float u_pointSizePx; void main() { gl_Position = u_mvp * vec4(a_pos, 1.0); gl_PointSize = u_pointSizePx; } `,H=`#version 300 es precision highp float; uniform vec4 u_color; uniform float u_pointSizePx; uniform int u_ringMode; uniform float u_ringThicknessPx; out vec4 outColor; void main() { vec2 p = gl_PointCoord * 2.0 - 1.0; float r = length(p); float radiusPx = max(u_pointSizePx * 0.5, 1.0); float aa = max(fwidth(r), 1.2 / radiusPx); float outer = 1.0 - smoothstep(1.0 - aa, 1.0 + aa, r); if (outer <= 0.0) discard; float alpha = outer; if (u_ringMode == 1) { float t = clamp(u_ringThicknessPx / max(radiusPx, 1e-6), 0.0, 1.0); float inner = 1.0 - t; float innerMask = smoothstep(inner - aa, inner + aa, r); alpha *= innerMask; if (alpha <= 0.0) discard; } outColor = vec4(u_color.rgb, u_color.a * alpha); } `,j=`#version 300 es precision highp float; layout(location = 0) in vec3 a_pos; uniform mat4 u_mvp; void main() { gl_Position = u_mvp * vec4(a_pos, 1.0); } `,q=`#version 300 es precision highp float; uniform vec4 u_color; out vec4 outColor; void main() { outColor = u_color; } `;class Z{canvas=null;overlayCanvas=null;overlayCtx=null;gl=null;width=0;height=0;dpr=1;dataset=null;view={type:"orbit3d",yaw:0,pitch:0,distance:3,targetX:0,targetY:0,targetZ:0,orthoScale:1.25};sceneRadius=1;backgroundColor="#0a0a0a";pointRadiusCss=4;colors=e;sphereGuideColor="#94a3b8";sphereGuideOpacity=.2;categoryVisibilityMask=new Uint8Array(0);hasCategoryVisibilityMask=!1;categoryAlpha=1;interactionStyle={selectionColor:i,selectionRadiusOffset:2,selectionRingWidth:2,highlightColor:"#94a3b8",highlightRadiusOffset:1,highlightRingWidth:1.5,hoverColor:r,hoverFillColor:null,hoverRadiusOffset:3};selection=new Set;highlight=new Set;hoveredIndex=-1;lassoPolygon=null;lassoStyle={strokeColor:"#6366f1",strokeWidth:2,fillColor:"rgba(99, 102, 241, 0.12)"};pointsProgram=null;solidProgram=null;guideProgram=null;pointsVao=null;pointsPosBuffer=null;pointsLabelBuffer=null;selectionVao=null;selectionPosBuffer=null;selectionLabelBuffer=null;selectionVertexCount=0;highlightVao=null;highlightPosBuffer=null;highlightLabelBuffer=null;highlightVertexCount=0;hoverVao=null;hoverPosBuffer=null;hoverLabelBuffer=null;hoverVertexCount=0;guideVao=null;guideBuffer=null;guideVertexCount=0;guideSegmentVerts=0;guideAxisVertexOffset=0;guideAxisVertexCount=0;paletteTex=null;paletteSize=0;paletteWidth=0;paletteHeight=0;paletteBytes=new Uint8Array(0);paletteTexUnit=1;mvpMatrix=w();projectedDirty=!0;selectionDirty=!0;highlightDirty=!0;hoverDirty=!0;projectedScreenX=new Float32Array(0);projectedScreenY=new Float32Array(0);projectedDepth=new Float32Array(0);projectedPixelIndex=new Int32Array(0);projectedVisible=new Uint8Array(0);projectedVisibleIndices=new Uint32Array(0);projectedVisibleCount=0;depthBuffer=new Float32Array(0);selectionPositionsScratch=new Float32Array(0);selectionLabelsScratch=new Uint16Array(0);highlightPositionsScratch=new Float32Array(0);highlightLabelsScratch=new Uint16Array(0);hoverPositionScratch=new Float32Array(3);hoverLabelScratch=new Uint16Array(1);ensureOverlayCanvas(){if(this.canvas&&"u">typeof document){if(!this.overlayCanvas||!this.overlayCtx||!this.overlayCanvas.isConnected){let t=this.canvas.parentElement;if(!t)return;"static"===window.getComputedStyle(t).position&&(t.style.position="relative");let e=document.createElement("canvas");e.setAttribute("aria-hidden","true"),e.dataset.hyperScatterOverlay="lasso",e.style.position="absolute",e.style.inset="0",e.style.pointerEvents="none";let i=Number.parseInt(window.getComputedStyle(this.canvas).zIndex??"0",10);e.style.zIndex=Number.isFinite(i)?String(i+1):"1",t.appendChild(e),this.overlayCanvas=e,this.overlayCtx=e.getContext("2d")}this.syncOverlayCanvas()}}syncOverlayCanvas(){this.overlayCanvas&&this.overlayCtx&&(O(this.overlayCanvas,this.width,this.height,this.dpr),function(t,e,i,r,s,o){if(t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,Math.max(1,Math.floor(i*e)),Math.max(1,Math.floor(r*e))),s&&!(s.length<6)){t.setTransform(e,0,0,e,0,0),t.beginPath(),t.moveTo(s[0],s[1]);for(let e=2;e>>0,i=new Uint8Array(e);for(let r=0;r=0&&!this.isPointVisibleByCategory(this.hoveredIndex)&&(this.hoveredIndex=-1),this.selectionDirty=!0,this.highlightDirty=!0,this.hoverDirty=!0,this.projectedDirty=!0,this.gl&&(this.uploadPalette(),this.uploadSelectionToGPU(),this.uploadHighlightToGPU(),this.uploadHoverToGPU())}setInactiveOpacity(t){let e=Number.isFinite(t)?F(t,0,1):1;!(1e-12>=Math.abs(e-this.categoryAlpha))&&(this.categoryAlpha=e,this.gl&&this.uploadPalette())}setInteractionStyle(t){"string"==typeof t.selectionColor&&t.selectionColor.length>0&&(this.interactionStyle.selectionColor=t.selectionColor),"number"==typeof t.selectionRadiusOffset&&Number.isFinite(t.selectionRadiusOffset)&&(this.interactionStyle.selectionRadiusOffset=Math.max(0,t.selectionRadiusOffset)),"number"==typeof t.selectionRingWidth&&Number.isFinite(t.selectionRingWidth)&&(this.interactionStyle.selectionRingWidth=Math.max(.5,t.selectionRingWidth)),"string"==typeof t.highlightColor&&t.highlightColor.length>0&&(this.interactionStyle.highlightColor=t.highlightColor),"number"==typeof t.highlightRadiusOffset&&Number.isFinite(t.highlightRadiusOffset)&&(this.interactionStyle.highlightRadiusOffset=Math.max(0,t.highlightRadiusOffset)),"number"==typeof t.highlightRingWidth&&Number.isFinite(t.highlightRingWidth)&&(this.interactionStyle.highlightRingWidth=Math.max(.5,t.highlightRingWidth)),"string"==typeof t.hoverColor&&t.hoverColor.length>0&&(this.interactionStyle.hoverColor=t.hoverColor),Object.prototype.hasOwnProperty.call(t,"hoverFillColor")&&(this.interactionStyle.hoverFillColor=t.hoverFillColor??null),"number"==typeof t.hoverRadiusOffset&&Number.isFinite(t.hoverRadiusOffset)&&(this.interactionStyle.hoverRadiusOffset=Math.max(0,t.hoverRadiusOffset))}isCategoryVisible(t){if(!this.hasCategoryVisibilityMask)return!0;let e=this.categoryVisibilityMask;return t<0||t>=e.length||0!==e[t]}isPointVisibleByCategory(t){let e=this.dataset;return!!e&&!(t<0)&&!(t>=e.n)&&this.isCategoryVisible(e.labels[t])}setView(t){this.view={...t},this.projectedDirty=!0}getView(){return{...this.view}}resize(t,e){this.width=t,this.height=e,this.canvas&&O(this.canvas,t,e,this.dpr),this.syncOverlayCanvas(),this.gl&&this.canvas&&this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.projectedDirty=!0}setSelection(t){this.selection=new Set(t??new Set),this.selectionDirty=!0,this.highlightDirty=!0}getSelection(){return new Set(this.selection)}setHighlight(t){this.highlight=new Set(t??new Set),this.highlightDirty=!0}getHighlight(){return new Set(this.highlight)}setHovered(t){t>=0&&!this.isPointVisibleByCategory(t)?this.hoveredIndex=-1:this.hoveredIndex=t,this.hoverDirty=!0}setLassoPolygon(t,e){e&&("string"==typeof e.strokeColor&&e.strokeColor.length>0&&(this.lassoStyle.strokeColor=e.strokeColor),"string"==typeof e.fillColor&&e.fillColor.length>0&&(this.lassoStyle.fillColor=e.fillColor),"number"==typeof e.strokeWidth&&Number.isFinite(e.strokeWidth)&&(this.lassoStyle.strokeWidth=Math.max(1,e.strokeWidth))),this.lassoPolygon=t&&t.length>=6?new Float32Array(t):null,this.ensureOverlayCanvas()}pan(t,e,i){if(i.meta||i.ctrl||i.alt){let{right:i,up:r}=this.getCameraFrame(),s=2*this.view.orthoScale/Math.max(1,Math.min(this.width,this.height)),o=-t*s,a=e*s;this.view.targetX+=i[0]*o+r[0]*a,this.view.targetY+=i[1]*o+r[1]*a,this.view.targetZ+=i[2]*o+r[2]*a}else this.view.yaw-=.005*t,this.view.pitch=F(this.view.pitch-.005*e,-1.45,1.45);this.projectedDirty=!0}zoom(t,e,i,r){let s=Math.pow(1.1,-i);this.view.orthoScale=F(this.view.orthoScale*s,.02,1e4),this.view.distance=F(this.view.distance*s,.05,1e4),this.projectedDirty=!0}hitTest(t,e){let i=this.dataset;if(!i)return null;this.ensureProjectedCache();let r=this.pointRadiusCss+5,s=r*r,o=-1,a=1/0,h=1/0;for(let r=0;rs)continue;let f=this.projectedDepth[n];(d=Math.abs(d-a)&&f=Math.abs(d-a)&&1e-12>=Math.abs(f-h)&&no&&(o=i),ha&&(a=h)}let h=new Set;for(let i=0;io||ua||p(l,u,t)&&h.add(n)}return Y(h,performance.now()-i)}async countSelection(t,e={}){let i=t.indices;if(!i)return 0;let r=e.shouldCancel,s=e.onProgress,o="number"==typeof e.yieldEveryMs&&Number.isFinite(e.yieldEveryMs)?Math.max(0,e.yieldEveryMs):8,a=0,h=0,n=16384,l=o>0?performance.now():0;for(let t of i)if(this.isPointVisibleByCategory(t)&&a++,h++,o>0&&h>=n){if(n=h+16384,r?.())return a;performance.now()-l>=o&&(s?.(a,h),await new Promise(t=>requestAnimationFrame(()=>t())),l=performance.now())}return s?.(a,h),a}projectToScreen(t,e,i){this.updateMvpMatrix();let[r,s,o,a]=L(this.mvpMatrix,t,e,i),h=Math.abs(a)>1e-12?1/a:0,n=r*h,l=s*h,u=o*h,d=(.5*n+.5)*this.width;return{x:d,y:(1-(.5*l+.5))*this.height,depth:.5*u+.5,visible:n>=-1&&n<=1&&l>=-1&&l<=1&&u>=-1&&u<=1}}render(){this.ensureGL();let t=this.gl,e=this.dataset,i=this.canvas;if(!t||!e||!i||!this.pointsProgram||!this.solidProgram)return;this.selectionDirty&&this.uploadSelectionToGPU(),this.highlightDirty&&this.uploadHighlightToGPU(),this.hoverDirty&&this.uploadHoverToGPU(),this.updateMvpMatrix();let[r,s,o,a]=I(this.backgroundColor);if(t.clearColor(r,s,o,a),t.clear(t.COLOR_BUFFER_BIT|t.DEPTH_BUFFER_BIT),this.supportsSphereGuide()?this.drawSphereGuide():this.supportsEuclideanGuide()&&this.drawEuclideanGuide(),t.enable(t.DEPTH_TEST),t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA),t.useProgram(this.pointsProgram.program),this.pointsProgram.uMvp&&t.uniformMatrix4fv(this.pointsProgram.uMvp,!1,this.mvpMatrix),this.pointsProgram.uPointSizePx&&t.uniform1f(this.pointsProgram.uPointSizePx,2*this.pointRadiusCss*this.dpr),this.bindPaletteTexture(),this.pointsProgram.uPaletteTex&&t.uniform1i(this.pointsProgram.uPaletteTex,this.paletteTexUnit),this.pointsProgram.uPaletteSize&&t.uniform1i(this.pointsProgram.uPaletteSize,this.paletteSize),this.pointsProgram.uPaletteWidth&&t.uniform1i(this.pointsProgram.uPaletteWidth,this.paletteWidth),t.bindVertexArray(this.pointsVao),t.drawArrays(t.POINTS,0,e.n),t.bindVertexArray(null),this.highlightVertexCount>0&&this.drawEmphasisPoints(this.highlightVao,this.highlightVertexCount,this.interactionStyle.highlightColor,this.interactionStyle.highlightRadiusOffset,this.interactionStyle.highlightRingWidth),this.selectionVertexCount>0&&this.drawEmphasisPoints(this.selectionVao,this.selectionVertexCount,this.interactionStyle.selectionColor,this.interactionStyle.selectionRadiusOffset,this.interactionStyle.selectionRingWidth),this.hoverVertexCount>0)if(this.drawSolidPoints(this.hoverVao,this.hoverVertexCount,this.interactionStyle.hoverColor,this.pointRadiusCss+this.interactionStyle.hoverRadiusOffset,!0),this.selection.has(this.hoveredIndex))this.drawEmphasisPoints(this.hoverVao,this.hoverVertexCount,this.interactionStyle.selectionColor,this.interactionStyle.selectionRadiusOffset,this.interactionStyle.selectionRingWidth);else if(this.highlight.has(this.hoveredIndex))this.drawEmphasisPoints(this.hoverVao,this.hoverVertexCount,this.interactionStyle.highlightColor,this.interactionStyle.highlightRadiusOffset,this.interactionStyle.highlightRingWidth);else{let t=this.interactionStyle.hoverFillColor??this.resolveLabelColor(this.hoveredIndex);this.interactionStyle.hoverFillColor?this.drawSolidPoints(this.hoverVao,this.hoverVertexCount,t,this.pointRadiusCss+1,!1):this.drawPalettePoints(this.hoverVao,this.hoverVertexCount,this.pointRadiusCss+1)}}destroy(){let t=this.gl;t&&(this.pointsProgram&&t.deleteProgram(this.pointsProgram.program),this.solidProgram&&t.deleteProgram(this.solidProgram.program),this.guideProgram&&t.deleteProgram(this.guideProgram.program),this.pointsVao&&t.deleteVertexArray(this.pointsVao),this.selectionVao&&t.deleteVertexArray(this.selectionVao),this.highlightVao&&t.deleteVertexArray(this.highlightVao),this.hoverVao&&t.deleteVertexArray(this.hoverVao),this.guideVao&&t.deleteVertexArray(this.guideVao),this.pointsPosBuffer&&t.deleteBuffer(this.pointsPosBuffer),this.pointsLabelBuffer&&t.deleteBuffer(this.pointsLabelBuffer),this.selectionPosBuffer&&t.deleteBuffer(this.selectionPosBuffer),this.selectionLabelBuffer&&t.deleteBuffer(this.selectionLabelBuffer),this.highlightPosBuffer&&t.deleteBuffer(this.highlightPosBuffer),this.highlightLabelBuffer&&t.deleteBuffer(this.highlightLabelBuffer),this.hoverPosBuffer&&t.deleteBuffer(this.hoverPosBuffer),this.hoverLabelBuffer&&t.deleteBuffer(this.hoverLabelBuffer),this.guideBuffer&&t.deleteBuffer(this.guideBuffer),this.paletteTex&&t.deleteTexture(this.paletteTex)),this.gl=null,this.pointsProgram=null,this.solidProgram=null,this.guideProgram=null,this.pointsVao=null,this.selectionVao=null,this.highlightVao=null,this.hoverVao=null,this.guideVao=null,this.pointsPosBuffer=null,this.pointsLabelBuffer=null,this.selectionPosBuffer=null,this.selectionLabelBuffer=null,this.highlightPosBuffer=null,this.highlightLabelBuffer=null,this.hoverPosBuffer=null,this.hoverLabelBuffer=null,this.guideBuffer=null,this.paletteTex=null,this.removeOverlayCanvas()}ensureGL(){if(this.gl)return;if(!this.canvas)throw Error("Renderer not initialized");let t=this.canvas.getContext("webgl2",{antialias:!1,alpha:!1,depth:!0,stencil:!1,preserveDrawingBuffer:!1,premultipliedAlpha:!1,desynchronized:!0});if(!t)throw Error("Failed to get WebGL2 context");this.gl=t,t.viewport(0,0,this.canvas.width,this.canvas.height),this.createProgramsAndBuffers(),this.uploadPalette(),this.dataset&&(this.uploadDatasetToGPU(),this.rebuildGuideGeometry(),this.uploadSelectionToGPU(),this.uploadHighlightToGPU(),this.uploadHoverToGPU()),this.projectedDirty=!0}createProgramsAndBuffers(){let t=this.gl;if(!t)return;let e=z(t,W,G),i=z(t,X,H),r=z(t,j,q);if(this.pointsProgram={program:e,uMvp:t.getUniformLocation(e,"u_mvp"),uPointSizePx:t.getUniformLocation(e,"u_pointSizePx"),uPaletteTex:t.getUniformLocation(e,"u_paletteTex"),uPaletteSize:t.getUniformLocation(e,"u_paletteSize"),uPaletteWidth:t.getUniformLocation(e,"u_paletteWidth")},this.solidProgram={program:i,uMvp:t.getUniformLocation(i,"u_mvp"),uPointSizePx:t.getUniformLocation(i,"u_pointSizePx"),uColor:t.getUniformLocation(i,"u_color"),uRingMode:t.getUniformLocation(i,"u_ringMode"),uRingThicknessPx:t.getUniformLocation(i,"u_ringThicknessPx")},this.guideProgram={program:r,uMvp:t.getUniformLocation(r,"u_mvp"),uColor:t.getUniformLocation(r,"u_color")},this.pointsVao=t.createVertexArray(),this.pointsPosBuffer=t.createBuffer(),this.pointsLabelBuffer=t.createBuffer(),this.selectionVao=t.createVertexArray(),this.selectionPosBuffer=t.createBuffer(),this.selectionLabelBuffer=t.createBuffer(),this.highlightVao=t.createVertexArray(),this.highlightPosBuffer=t.createBuffer(),this.highlightLabelBuffer=t.createBuffer(),this.hoverVao=t.createVertexArray(),this.hoverPosBuffer=t.createBuffer(),this.hoverLabelBuffer=t.createBuffer(),this.guideVao=t.createVertexArray(),this.guideBuffer=t.createBuffer(),!this.pointsVao||!this.pointsPosBuffer||!this.pointsLabelBuffer||!this.selectionVao||!this.selectionPosBuffer||!this.selectionLabelBuffer||!this.highlightVao||!this.highlightPosBuffer||!this.highlightLabelBuffer||!this.hoverVao||!this.hoverPosBuffer||!this.hoverLabelBuffer||!this.guideVao||!this.guideBuffer)throw Error("Failed to allocate WebGL buffers for 3D renderer");t.bindVertexArray(this.pointsVao),t.bindBuffer(t.ARRAY_BUFFER,this.pointsPosBuffer),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,3,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.pointsLabelBuffer),t.enableVertexAttribArray(1),t.vertexAttribIPointer(1,1,t.UNSIGNED_SHORT,0,0),t.bindVertexArray(null),t.bindVertexArray(this.selectionVao),t.bindBuffer(t.ARRAY_BUFFER,this.selectionPosBuffer),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,3,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.selectionLabelBuffer),t.enableVertexAttribArray(1),t.vertexAttribIPointer(1,1,t.UNSIGNED_SHORT,0,0),t.bindVertexArray(null),t.bindVertexArray(this.highlightVao),t.bindBuffer(t.ARRAY_BUFFER,this.highlightPosBuffer),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,3,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.highlightLabelBuffer),t.enableVertexAttribArray(1),t.vertexAttribIPointer(1,1,t.UNSIGNED_SHORT,0,0),t.bindVertexArray(null),t.bindVertexArray(this.hoverVao),t.bindBuffer(t.ARRAY_BUFFER,this.hoverPosBuffer),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,3,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.hoverLabelBuffer),t.enableVertexAttribArray(1),t.vertexAttribIPointer(1,1,t.UNSIGNED_SHORT,0,0),t.bindVertexArray(null),t.bindVertexArray(this.guideVao),t.bindBuffer(t.ARRAY_BUFFER,this.guideBuffer),t.enableVertexAttribArray(0),t.vertexAttribPointer(0,3,t.FLOAT,!1,0,0),t.bindVertexArray(null),t.bindBuffer(t.ARRAY_BUFFER,null)}uploadPalette(){let t=this.gl;if(!t||!this.pointsProgram)return;let e=this.colors.length,i=Math.max(1,Math.min(e,65536)),r=Math.min(t.getParameter(t.MAX_TEXTURE_SIZE),i),s=Math.ceil(i/r),o=r*s;if(this.paletteBytes.length!==4*o?this.paletteBytes=new Uint8Array(4*o):this.paletteBytes.fill(0),0===e){this.paletteBytes[0]=255,this.paletteBytes[1]=255,this.paletteBytes[2]=255;let t=this.isCategoryVisible(0);this.paletteBytes[3]=t?Math.round(255*this.categoryAlpha):0}else for(let t=0;t=e.n)&&this.isCategoryVisible(e.labels[t])&&(this.selectionPositionsScratch[3*r]=e.positions[3*t],this.selectionPositionsScratch[3*r+1]=e.positions[3*t+1],this.selectionPositionsScratch[3*r+2]=e.positions[3*t+2],this.selectionLabelsScratch[r]=e.labels[t],++r>=i))break;this.selectionVertexCount=r,t.bindBuffer(t.ARRAY_BUFFER,this.selectionPosBuffer),t.bufferData(t.ARRAY_BUFFER,this.selectionPositionsScratch.subarray(0,3*r),t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.selectionLabelBuffer),t.bufferData(t.ARRAY_BUFFER,this.selectionLabelsScratch.subarray(0,r),t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,null),this.selectionDirty=!1}uploadHighlightToGPU(){let t=this.gl,e=this.dataset;if(!t||!e||!this.highlightPosBuffer||!this.highlightLabelBuffer)return;if(0===this.highlight.size){this.highlightVertexCount=0,this.highlightDirty=!1;return}let i=Math.min(this.highlight.size,25e4);this.highlightPositionsScratch.length<3*i&&(this.highlightPositionsScratch=new Float32Array(3*i)),this.highlightLabelsScratch.length=e.n)&&this.isCategoryVisible(e.labels[t])&&(this.highlightPositionsScratch[3*r]=e.positions[3*t],this.highlightPositionsScratch[3*r+1]=e.positions[3*t+1],this.highlightPositionsScratch[3*r+2]=e.positions[3*t+2],this.highlightLabelsScratch[r]=e.labels[t],++r>=i))break;this.highlightVertexCount=r,t.bindBuffer(t.ARRAY_BUFFER,this.highlightPosBuffer),t.bufferData(t.ARRAY_BUFFER,this.highlightPositionsScratch.subarray(0,3*r),t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.highlightLabelBuffer),t.bufferData(t.ARRAY_BUFFER,this.highlightLabelsScratch.subarray(0,r),t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,null),this.highlightDirty=!1}uploadHoverToGPU(){let t=this.gl,e=this.dataset;if(!t||!e||!this.hoverPosBuffer||!this.hoverLabelBuffer)return;let i=this.hoveredIndex;if(i<0||i>=e.n||!this.isCategoryVisible(e.labels[i])){this.hoverVertexCount=0,this.hoverDirty=!1;return}this.hoverPositionScratch[0]=e.positions[3*i],this.hoverPositionScratch[1]=e.positions[3*i+1],this.hoverPositionScratch[2]=e.positions[3*i+2],this.hoverLabelScratch[0]=e.labels[i],t.bindBuffer(t.ARRAY_BUFFER,this.hoverPosBuffer),t.bufferData(t.ARRAY_BUFFER,this.hoverPositionScratch,t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.hoverLabelBuffer),t.bufferData(t.ARRAY_BUFFER,this.hoverLabelScratch,t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,null),this.hoverVertexCount=1,this.hoverDirty=!1}fitViewToDataset(){let t=this.dataset;if(!t||0===t.n)return;let e=0,i=0,r=0;for(let s=0;sD(l)&&(l=[0,0,-1]);let u=U(k(l,M));1e-9>D(u)&&(u=[1,0,0]);let d=U(k(u,l));return{eye:n,target:h,right:u,up:d,forward:l}}updateMvpMatrix(){var t,e;let i,r,s,o,a,{eye:h,target:n,up:l}=this.getCameraFrame(),u=this.width>0&&this.height>0?this.width/this.height:1,d=Math.max(.01,this.view.orthoScale),f=d*u,c=Math.max(1.01,this.view.distance+6*this.sceneRadius+10),p=(i=U(V(h,n)),1e-9>D(r=U(k(l,i)))&&(r=[1,0,0]),s=k(i,r),(o=w())[0]=r[0],o[1]=s[0],o[2]=i[0],o[3]=0,o[4]=r[1],o[5]=s[1],o[6]=i[1],o[7]=0,o[8]=r[2],o[9]=s[2],o[10]=i[2],o[11]=0,o[12]=-(r[0]*h[0]+r[1]*h[1]+r[2]*h[2]),o[13]=-(s[0]*h[0]+s[1]*h[1]+s[2]*h[2]),o[14]=-(i[0]*h[0]+i[1]*h[1]+i[2]*h[2]),o[15]=1,o),g=(t=-f,e=-d,(a=new Float32Array(16))[0]=2/(f-t),a[5]=2/(d-e),a[10]=-2/(c-.01),a[12]=-(f+t)/(f-t),a[13]=-(d+e)/(d-e),a[14]=-(c+.01)/(c-.01),a[15]=1,a);this.mvpMatrix=function(t,e){let i=new Float32Array(16);for(let r=0;r<4;r++)for(let s=0;s<4;s++)i[4*r+s]=t[0+s]*e[4*r+0]+t[4+s]*e[4*r+1]+t[8+s]*e[4*r+2]+t[12+s]*e[4*r+3];return i}(g,p)}ensureProjectedCapacity(t){this.projectedScreenX.length!==t&&(this.projectedScreenX=new Float32Array(t)),this.projectedScreenY.length!==t&&(this.projectedScreenY=new Float32Array(t)),this.projectedDepth.length!==t&&(this.projectedDepth=new Float32Array(t)),this.projectedPixelIndex.length!==t&&(this.projectedPixelIndex=new Int32Array(t)),this.projectedVisible.length!==t&&(this.projectedVisible=new Uint8Array(t)),this.projectedVisibleIndices.length!==t&&(this.projectedVisibleIndices=new Uint32Array(t));let e=Math.max(1,this.width*this.height);this.depthBuffer.length!==e&&(this.depthBuffer=new Float32Array(e))}ensureProjectedCache(){if(!this.projectedDirty)return;let t=this.dataset;if(!t)return;this.updateMvpMatrix(),this.ensureProjectedCapacity(t.n),this.depthBuffer.fill(1/0),this.projectedVisibleCount=0;let e=Math.max(1,this.width),i=Math.max(1,this.height),r=this.hasCategoryVisibilityMask,s=this.categoryVisibilityMask;for(let o=0;o1e-12?1/f:0,p=l*c,g=u*c,m=d*c;if(p<-1||p>1||g<-1||g>1||m<-1||m>1){this.projectedPixelIndex[o]=-1,this.projectedVisible[o]=0;continue}let y=(.5*p+.5)*e,b=(1-(.5*g+.5))*i,x=.5*m+.5,v=Math.floor(y),R=Math.floor(b);if(v<0||v>=e||R<0||R>=i){this.projectedPixelIndex[o]=-1,this.projectedVisible[o]=0;continue}let P=R*e+v;this.projectedScreenX[o]=y,this.projectedScreenY[o]=b,this.projectedDepth[o]=x,this.projectedPixelIndex[o]=P,this.projectedVisible[o]=0,xo&&(o=n),l>a&&(a=l),u>h&&(h=u)}let n=Math.max(0,o-i),l=Math.max(0,a-r),u=Math.max(0,h-s),d=Math.max(n,l,u,2*this.sceneRadius,.001),f=.04*d,c=Math.max(.3*d,.2),p=(i+o)*.5,g=(r+a)*.5,m=(s+h)*.5,y=n>1e-4?.5*n+f:c,b=l>1e-4?.5*l+f:c,x=u>1e-4?.5*u+f:c,v=new Float32Array(18),R=0;v[R++]=p-y,v[R++]=g,v[R++]=m,v[R++]=p+y,v[R++]=g,v[R++]=m,v[R++]=p,v[R++]=g-b,v[R++]=m,v[R++]=p,v[R++]=g+b,v[R++]=m,v[R++]=p,v[R++]=g,v[R++]=m-x,v[R++]=p,v[R++]=g,v[R++]=m+x,t.bindBuffer(t.ARRAY_BUFFER,this.guideBuffer),t.bufferData(t.ARRAY_BUFFER,v,t.STATIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,null),this.guideVertexCount=v.length/3,this.guideAxisVertexOffset=0,this.guideAxisVertexCount=6}estimateGuideRadius(){let t=this.dataset;if(!t||0===t.n)return 1;let e=0;for(let i=0;i=e.n||0===this.colors.length)return r;let i=e.labels[t];return this.colors[i%this.colors.length]}}class $ extends Z{expectedGeometry(){return"euclidean3d"}supportsEuclideanGuide(){return!0}}class K extends Z{expectedGeometry(){return"sphere"}supportsSphereGuide(){return!0}preprocessPositions(t){let e=new Float32Array(t.length);for(let i=0;i65535)throw Error(`label index out of range at ${i}: ${r}`);e[i]=r}return e}function th(t,e){let i=Math.floor(t.length/2);if(i<=e)return new Float32Array(t);let r=t;if(i>2048){let e=new Float32Array(4096);for(let r=0;r<2048;r++){let s=Math.floor(r*i/2048);e[2*r]=t[2*s],e[2*r+1]=t[2*s+1]}r=e}let s=function(t){let e=Array.from(t),i=Math.floor(e.length/2);if(i<3)return e;for(let t=0;t<5&&!((i=Math.floor(e.length/2))<3);t++){let t=Array(4*i),r=0;for(let s=0;sr&&(r=a),hs&&(s=h)}return Number.isFinite(e)&&Number.isFinite(i)?{xMin:e,yMin:i,xMax:r,yMax:s}:{xMin:0,yMin:0,xMax:0,yMax:0}}(s),a=Math.max(o.xMax-o.xMin,o.yMax-o.yMin),h=(t,e,i,r,s,o)=>{let a=s-i,h=o-r,n=a*a+h*h,l=0;n>1e-12&&((l=((t-i)*a+(e-r)*h)/n)<0?l=0:l>1&&(l=1));let u=t-(i+l*a),d=e-(r+l*h);return u*u+d*d},n=t=>{let e=Math.floor(s.length/2);if(e<=2)return s.slice();let i=t*t,r=new Uint8Array(e);r[0]=1,r[e-1]=1;let o=[0,e-1];for(;o.length>0;){let t=o.pop(),e=o.pop(),a=s[2*e],n=s[2*e+1],l=s[2*t],u=s[2*t+1],d=-1,f=-1;for(let i=e+1;id&&(d=t,f=i)}d>i&&f>=0&&(r[f]=1,o.push(e,f),o.push(f,t))}let a=[];for(let t=0;te&&d<20;)l*=1.1,u=n(l),d++;let f=Math.floor(u.length/2);if(f>e){let t=new Float32Array(2*e);for(let i=0;ir&&(r=a),hs&&(s=h)}return Number.isFinite(e)&&Number.isFinite(i)&&Number.isFinite(r)&&Number.isFinite(s)?{xMin:e,yMin:i,xMax:r,yMax:s}:{xMin:0,yMin:0,xMax:0,yMax:0}},"buildSemanticLabelModel",()=>tu.buildSemanticLabelModel,"createDataset",0,Q,"createDataset3D",0,tt,"createDataset3DFromColumns",0,ti,"createDatasetFromColumns",0,te,"createInteractionController",0,function(t,e,i={}){let r=Number.isFinite(i.wheelZoomScale)?i.wheelZoomScale:.01,s=i.lassoPredicate??(t=>t.shiftKey&&(t.metaKey||t.ctrlKey)),o=Number.isFinite(i.lassoMinSampleDistPx)?i.lassoMinSampleDistPx:2,a=Number.isFinite(i.lassoMaxVertsInteraction)?i.lassoMaxVertsInteraction:24,h=Number.isFinite(i.lassoMaxVertsFinal)?i.lassoMaxVertsFinal:48,n=i.observeResize??!0,l=0,u=0,d=0,f=!0,c="idle",p=null,g=0,m=0,y=0,b=0,x={shift:!1,ctrl:!1,alt:!1,meta:!1},v=0,R=0,P=0,A={shift:!1,ctrl:!1,alt:!1,meta:!1},E=!1,S=!1,C=0,T=0,_=-2,B=[],M=null,F=0,w=0,D=!1,U=(e,i)=>{let r=t.getBoundingClientRect();return{x:e-r.left,y:i-r.top}},V=t=>{let i=new Float32Array(t.length);for(let r=0;r{l||(l=requestAnimationFrame(()=>{l=0;let r=!1;if(f){let i,s,o;f=!1,s=tl((i=t.getBoundingClientRect()).width),o=tl(i.height),r=(s!==u||o!==d)&&(u=s,d=o,e.resize(s,o),!0)||r}if((0!==y||0!==b)&&(e.pan(y,b,x),y=0,b=0,r=!0),E&&0!==v&&(e.zoom(R,P,v,A),v=0,E=!1,r=!0),"idle"===c&&S){S=!1;let t=e.hitTest(C,T),s=t?t.index:-1;s!==_&&(_=s,e.setHovered(s),r=!0),i.onHover?.(t)}if("lasso"===c&&D&&i.onLassoUpdate&&B.length>=6){D=!1;let t=th(B,a);M=t;let e=V(t);i.onLassoUpdate(t,e)}r&&e.render()}))},L=i=>{if(0!==i.button)return;let{x:r,y:o}=U(i.clientX,i.clientY);if(p=i.pointerId,g=r,m=o,-1!==_&&(_=-1,e.setHovered(-1)),s(i)){c="lasso",B=[],M=null,F=r,w=o;let t=e.unprojectFromScreen(r,o);B.push(t.x,t.y),D=!0,k()}else c="pan",y=0,b=0,x=tn(i),e.startPan(r,o),k();t.setPointerCapture(i.pointerId)},I=t=>{if(p!==t.pointerId){if("idle"===c){let{x:e,y:i}=U(t.clientX,t.clientY);C=e,T=i,S=!0,k()}return}let{x:i,y:r}=U(t.clientX,t.clientY);if("pan"===c){y+=i-g,b+=r-m,x=tn(t),g=i,m=r,k();return}if("lasso"===c){let t=i-F,s=r-w;if(t*t+s*s>=o*o){let t=e.unprojectFromScreen(i,r);B.push(t.x,t.y),D=!0,F=i,w=r,k()}return}C=i,T=r,S=!0,k()},N=r=>{if(p===r.pointerId){if("pan"===c&&(0!==y||0!==b)&&(e.pan(y,b,x),y=0,b=0,e.render()),"lasso"===c&&B.length>=6){let t=M??th(B,h),r=V(t),s=e.lassoSelect(r);i.onLassoComplete?.(s,t,r)}"endInteraction"in e&&e.endInteraction(),c="idle",p=null,B=[],M=null,D=!1,S=!1;try{t.releasePointerCapture(r.pointerId)}catch{}}},z=t=>{t.preventDefault();let{x:e,y:i}=U(t.clientX,t.clientY),s=-t.deltaY*r;v+=s,R=e,P=i,A=tn(t),E=!0,k()};t.addEventListener("pointerdown",L),t.addEventListener("pointermove",I),t.addEventListener("pointerup",N),t.addEventListener("pointercancel",N),t.addEventListener("wheel",z,{passive:!1});let O=null;return n&&"u">typeof ResizeObserver&&(O=new ResizeObserver(()=>{f=!0,k()})).observe(t),f=!0,k(),{destroy(){l&&(cancelAnimationFrame(l),l=0),t.removeEventListener("pointerdown",L),t.removeEventListener("pointermove",I),t.removeEventListener("pointerup",N),t.removeEventListener("pointercancel",N),t.removeEventListener("wheel",z),O?.disconnect(),O=null},requestResize(){f=!0,k()}}},"createScatterPlot",0,J,"drawSemanticLabels",()=>tu.drawSemanticLabels,"layoutSemanticLabels",()=>tu.layoutSemanticLabels,"packPositions",0,tr,"packPositionsXY",0,ts,"packPositionsXYZ",0,to,"packUint16Labels",0,ta,"pointInPolygon",0,p],90846)}]);