glyphcss 0.0.3 → 0.0.4

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.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { G as GlyphSceneHandle, a as GlyphCamera, b as GlyphDirectionalLight, c as GlyphAmbientLight } from './elements-DVWVBIG0.js';
2
- export { d as GlyphHotspotElement, e as GlyphHotspotHandle, f as GlyphHotspotOptions, g as GlyphMapControlsElement, h as GlyphMeshElement, i as GlyphMeshHandle, j as GlyphMeshTransform, k as GlyphOrbitControlsElement, l as GlyphOrthographicCameraElement, m as GlyphOrthographicCameraHandle, n as GlyphOrthographicCameraOptions, o as GlyphPerspectiveCameraElement, p as GlyphPerspectiveCameraHandle, q as GlyphPerspectiveCameraOptions, r as GlyphSceneElement, s as GlyphSceneOptions, t as createGlyphCamera, u as createGlyphOrthographicCamera, v as createGlyphPerspectiveCamera, w as createGlyphScene } from './elements-DVWVBIG0.js';
1
+ import { G as GlyphSceneHandle, a as GlyphCamera, b as GlyphDirectionalLight, c as GlyphAmbientLight, d as GlyphShadowOptions } from './elements-dJUvIMDN.js';
2
+ export { e as GlyphHotspotElement, f as GlyphHotspotHandle, g as GlyphHotspotOptions, h as GlyphMapControlsElement, i as GlyphMeshElement, j as GlyphMeshHandle, k as GlyphMeshTransform, l as GlyphOrbitControlsElement, m as GlyphOrthographicCameraElement, n as GlyphOrthographicCameraHandle, o as GlyphOrthographicCameraOptions, p as GlyphPerspectiveCameraElement, q as GlyphPerspectiveCameraHandle, r as GlyphPerspectiveCameraOptions, s as GlyphSceneElement, t as GlyphSceneOptions, u as createGlyphCamera, v as createGlyphOrthographicCamera, w as createGlyphPerspectiveCamera, x as createGlyphScene } from './elements-dJUvIMDN.js';
3
3
  import { Hotspot, HotspotCell, GridSize, Polygon, WireframeEdge, RenderMode, CharRamp } from '@glyphcss/core';
4
4
  export * from '@glyphcss/core';
5
5
 
@@ -7,8 +7,12 @@ export * from '@glyphcss/core';
7
7
  * createGlyphOrbitControls — orbit-mode camera input for a GlyphScene.
8
8
  *
9
9
  * Left-drag rotates rotX / rotY around the target (orbit). Wheel zooms or
10
- * dollies. Mirrors glyphcss's createPolyOrbitControls semantics, adapted for
10
+ * dollies. Mirrors voxcss's createPolyOrbitControls semantics, adapted for
11
11
  * the ASCII rasterizer's GlyphCamera instead of the CSS matrix3d camera.
12
+ *
13
+ * rotX and rotY are in DEGREES (three.js / voxcss convention).
14
+ * Drag sensitivity: 4 px per degree (POINTER_DRAG_SPEED = 4).
15
+ * Animate speed: degrees per 60 Hz-equivalent frame.
12
16
  */
13
17
 
14
18
  interface GlyphOrbitControlsOptions {
@@ -18,6 +22,12 @@ interface GlyphOrbitControlsOptions {
18
22
  wheel?: boolean;
19
23
  /** Drag-direction inversion. Default: false. */
20
24
  invert?: boolean | number;
25
+ /**
26
+ * Clamp vertical drag to ±90° (camera stays above the equator, never
27
+ * flipping past either pole). Default: true. Set to false for globe-style
28
+ * unrestricted tumbling.
29
+ */
30
+ clampPitch?: boolean;
21
31
  /** Auto-rotate. Pass false or omit to disable. */
22
32
  animate?: false | {
23
33
  speed?: number;
@@ -37,8 +47,12 @@ declare function createGlyphOrbitControls(scene: GlyphSceneHandle, options?: Gly
37
47
  * createGlyphMapControls — map/pan-mode camera input for a GlyphScene.
38
48
  *
39
49
  * Left-drag pans the target (slippy-map semantics). Right-drag or
40
- * Shift+left-drag orbits. Wheel zooms. Mirrors glyphcss's createPolyMapControls
50
+ * Shift+left-drag orbits. Wheel zooms. Mirrors voxcss's createPolyMapControls
41
51
  * semantics, adapted for the ASCII rasterizer's GlyphCamera.
52
+ *
53
+ * rotX and rotY are in DEGREES (three.js / voxcss convention).
54
+ * Drag sensitivity: 4 px per degree (POINTER_DRAG_SPEED = 4).
55
+ * Animate speed: degrees per 60 Hz-equivalent frame.
42
56
  */
43
57
 
44
58
  interface GlyphMapControlsOptions {
@@ -68,12 +82,17 @@ declare function createGlyphMapControls(scene: GlyphSceneHandle, options?: Glyph
68
82
  * detach, restores `eyeMode = false`.
69
83
  *
70
84
  * Mouse-drag looks around (rotX/rotY). WASD or arrow keys move forward/backward/strafe.
85
+ *
86
+ * rotX and rotY are in DEGREES (three.js / voxcss convention).
87
+ * lookSpeed: degrees per pixel. Default: 0.15.
88
+ * moveSpeed: world units per frame.
71
89
  */
72
90
 
73
91
  interface GlyphFirstPersonControlsOptions {
74
92
  drag?: boolean;
75
93
  keyboard?: boolean;
76
94
  moveSpeed?: number;
95
+ /** Mouselook sensitivity in degrees per pixel. Default: 0.15. */
77
96
  lookSpeed?: number;
78
97
  invert?: boolean | number;
79
98
  }
@@ -184,6 +203,25 @@ interface RasterizeContextOptions {
184
203
  * shading; `180` smooths every shared vertex. Default `60`.
185
204
  */
186
205
  creaseAngle?: number;
206
+ shadow?: GlyphShadowOptions;
207
+ /** Per-polygon cast flag (parallel to `polygons` array). True = this poly's mesh has castShadow. */
208
+ castShadowFlags?: boolean[];
209
+ /** Per-polygon receive flag (parallel to `polygons` array). True = this poly's mesh has receiveShadow. */
210
+ receiveShadowFlags?: boolean[];
211
+ }
212
+ /**
213
+ * Cross-frame per-triangle shading cache. The Lambert intensities and lit
214
+ * color depend only on world-space normals + light, never the camera — so
215
+ * during a camera-only change (orbit/zoom drag) they are identical frame to
216
+ * frame. Parallel arrays indexed by positional triangle order; lazily filled
217
+ * as triangles become visible. The scene clears it when geometry, light, or
218
+ * shading options change. Absent/null → always recompute (current behavior).
219
+ */
220
+ interface ShadeCache {
221
+ iA: number[];
222
+ iB: number[];
223
+ iC: number[];
224
+ lit: (string | null)[];
187
225
  }
188
226
  interface RasterizeContext {
189
227
  camera: GlyphCamera;
@@ -198,6 +236,11 @@ interface RasterizeContext {
198
236
  useColors: boolean;
199
237
  smoothShading: boolean;
200
238
  creaseAngle: number;
239
+ shadow: GlyphShadowOptions | undefined;
240
+ castShadowFlags: boolean[];
241
+ receiveShadowFlags: boolean[];
242
+ /** Optional cross-frame shading cache (see {@link ShadeCache}). */
243
+ shadeCache?: ShadeCache | null;
201
244
  }
202
245
  declare function buildRasterizeContext(opts: RasterizeContextOptions): RasterizeContext;
203
246
 
@@ -252,4 +295,4 @@ declare function getWireframeGlyphs(name: string): WireframeGlyphTiers;
252
295
 
253
296
  declare function injectGlyphBaseStyles(doc?: Document): void;
254
297
 
255
- export { DEFAULT_RAMP, GlyphAmbientLight, GlyphCamera, GlyphDirectionalLight, type GlyphEventHandler, type GlyphFirstPersonControlsHandle, type GlyphFirstPersonControlsOptions, type GlyphMapControlsHandle, type GlyphMapControlsOptions, type GlyphMouseEvent, type GlyphOrbitControlsHandle, type GlyphOrbitControlsOptions, type GlyphPointerEvent, GlyphSceneHandle, type GlyphWheelEvent, type RasterizeContext, type RasterizeContextOptions, SOLID_RAMP, WIREFRAME_GLYPHS, WIREFRAME_PALETTES, type WireframeGlyphTiers, bakeFrames, buildRasterizeContext, createGlyphFirstPersonControls, createGlyphMapControls, createGlyphOrbitControls, findGlyphMeshHandle, findMeshUnderPoint, getWireframeGlyphs, injectGlyphBaseStyles, pointInMeshElement, projectHotspots, rasterize };
298
+ export { DEFAULT_RAMP, GlyphAmbientLight, GlyphCamera, GlyphDirectionalLight, type GlyphEventHandler, type GlyphFirstPersonControlsHandle, type GlyphFirstPersonControlsOptions, type GlyphMapControlsHandle, type GlyphMapControlsOptions, type GlyphMouseEvent, type GlyphOrbitControlsHandle, type GlyphOrbitControlsOptions, type GlyphPointerEvent, GlyphSceneHandle, GlyphShadowOptions, type GlyphWheelEvent, type RasterizeContext, type RasterizeContextOptions, SOLID_RAMP, WIREFRAME_GLYPHS, WIREFRAME_PALETTES, type WireframeGlyphTiers, bakeFrames, buildRasterizeContext, createGlyphFirstPersonControls, createGlyphMapControls, createGlyphOrbitControls, findGlyphMeshHandle, findMeshUnderPoint, getWireframeGlyphs, injectGlyphBaseStyles, pointInMeshElement, projectHotspots, rasterize };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- function Fe(n,t,e){let o=Math.cos(t),r=Math.sin(t),s=o*n[1]-r*n[0],i=r*n[1]+o*n[0],a=n[2],u=Math.cos(e),c=Math.sin(e),h=u*i-c*a,d=c*i+u*a;return[s,h,d]}function K(n={}){let t={rotX:n.rotX??0,rotY:n.rotY??0,distance:n.distance??3,zoom:n.zoom??.4,stretch:n.stretch??1,target:[0,0,0],eyeMode:!1,focal:5},[e,o]=n.center??[.5,.5];return{kind:"perspective",get rotX(){return t.rotX},set rotX(r){t.rotX=r},get rotY(){return t.rotY},set rotY(r){t.rotY=r},get distance(){return t.distance},set distance(r){t.distance=r},get zoom(){return t.zoom},set zoom(r){t.zoom=r},get stretch(){return t.stretch},set stretch(r){t.stretch=r},get target(){return t.target},set target(r){t.target=r},get eyeMode(){return t.eyeMode},set eyeMode(r){t.eyeMode=r},project(r,s,i,a){let u=[r[0]-t.target[0],r[1]-t.target[1],r[2]-t.target[2]],c=Fe(u,t.rotY,t.rotX);if(t.eyeMode){if(c[2]>=-.001)return[NaN,NaN,c[2]];let x=t.focal/-c[2],p=Math.min(s,i)*t.zoom*x,b=s*e+c[0]*p*a*t.stretch,l=i*o+c[1]*p;return[b,l,c[2]]}let h=30,d=1.5,f=c[2]*h,m=.001,g=1-f/t.distance;if(g<m)return[NaN,NaN,c[2]];let L=1/g,E=Math.min(s,i)*t.zoom*d*L,S=s*e+c[0]*E*a*t.stretch,A=i*o+c[1]*E;return[S,A,c[2]]}}}function ee(n={}){let t={rotX:n.rotX??0,rotY:n.rotY??0,distance:0,zoom:n.zoom??.4,stretch:1,target:[0,0,0]},[e,o]=n.center??[.5,.5];return{kind:"orthographic",get rotX(){return t.rotX},set rotX(r){t.rotX=r},get rotY(){return t.rotY},set rotY(r){t.rotY=r},get distance(){return t.distance},set distance(r){t.distance=r},get zoom(){return t.zoom},set zoom(r){t.zoom=r},get stretch(){return t.stretch},set stretch(r){t.stretch=r},get target(){return t.target},set target(r){t.target=r},get eyeMode(){return!1},set eyeMode(r){},project(r,s,i,a){let u=[r[0]-t.target[0],r[1]-t.target[1],r[2]-t.target[2]],c=Fe(u,t.rotY,t.rotX),d=Math.min(s,i)*t.zoom*1.5,f=s*e+c[0]*d*a*t.stretch,m=i*o+c[1]*d;return[f,m,c[2]]}}}var tt=ee;var nt={direction:[.5,.7,.5],intensity:1},rt={intensity:.4};function ot(n){let t=new Set,e=[];for(let o of n){let r=o.vertices;if(!(r.length<2))for(let s=0;s<r.length;s++){let i=r[s],a=r[(s+1)%r.length],u=`${i[0]},${i[1]},${i[2]}`,c=`${a[0]},${a[1]},${a[2]}`,h=u<c?`${u}|${c}`:`${c}|${u}`;if(t.has(h))continue;t.add(h);let d={from:i,to:a,weight:2};o.color&&(d.color=o.color),e.push(d)}}return e}function fe(n){let t=n.polygons??[],e=n.mode??(t.length?"solid":"wireframe"),o=n.wireframe??(e==="wireframe"?ot(t):[]);return{camera:n.camera,grid:n.grid,polygons:t,wireframe:o,mode:e,directionalLight:n.directionalLight??nt,ambientLight:n.ambientLight??rt,glyphPalette:n.glyphPalette??"default",useColors:n.useColors??!0,smoothShading:n.smoothShading??!1,creaseAngle:n.creaseAngle??60}}var it=" .:-=+*#%@".split(""),st=" .:-=+*#%@".split(""),te={default:{thin:"\xB7\u22C5\u2219\u02D9\xB7\u22C5\u2219".split(""),normal:"\u254B\u256C\u253C\u2573\u25C6\u25C7\u25CA\u25B2\u25B3\u25BC\u25BD\u25C8\u2B21\u2B22\u2234\u2235\u22A5\u2295\u2297\u2299\u229A\u229B".split(""),core:"\u2726\u2727\u2729\u25C9\u2299\u25CE".split(""),solid:" .:-=+*#%@".split("")},ascii:{thin:".'".split(""),normal:"+*x".split(""),core:"#@".split(""),solid:" .,:;!+=*xX#@".split("")},dots:{thin:"\xB7\u22C5".split(""),normal:"\u2022\u25CF".split(""),core:"\u25C9\u25CE".split(""),solid:" \xB7\u22C5\u2218\u2022\u25CF\u25C9\u25CE\u2B24".split("")},lines:{thin:"\u2500\u2502".split(""),normal:"\u2550\u2551".split(""),core:"\u2588".split(""),solid:" \u2500\u2550\u256C\u2551\u2588\u2593\u2592\u2591".split("")},blocks:{thin:"\u2591\u2581".split(""),normal:"\u2592\u2593\u258C\u2590\u2580\u2584".split(""),core:"\u2588".split(""),solid:" \u2591\u2592\u2593\u258C\u2590\u2588\u2580\u2584\u25A0".split("")},stars:{thin:"\xB7\u22C6".split(""),normal:"\u2726\u2727\u2729\u272A".split(""),core:"\u272B\u272C\u272D\u2605".split(""),solid:" \xB7\u22C6\u2217\u2726\u2727\u2729\u272A\u272B\u2605".split("")},arrows:{thin:"\xB7\u2219".split(""),normal:"\u2190\u2191\u2192\u2193".split(""),core:"\u2196\u2197\u2198\u2199\u2921\u2922".split(""),solid:" \xB7\u2219\u2191\u2197\u2192\u2198\u2193\u2199\u2190\u2196".split("")},braille:{thin:"\u2801\u2802\u2804\u2808".split(""),normal:"\u2803\u2805\u2806\u2809\u280A\u280B\u280C\u280D\u280E\u280F".split(""),core:"\u283F\u28FF".split(""),solid:" \u2801\u2803\u2807\u2827\u2837\u283F\u287F\u28FF".split("")},runes:{thin:".\xB7".split(""),normal:"\u16A0\u16A1\u16A2\u16A3\u16A4\u16A6\u16A8\u16B1\u16B2\u16B3\u16B7\u16B9\u16C3\u16C7\u16C9".split(""),core:"\u16DE\u16DF\u16E1\u16E2\u16E3".split(""),solid:" \xB7\u16A0\u16A3\u16A4\u16A8\u16B1\u16B7\u16DE\u16E2".split("")},math:{thin:"\u2219\u2218".split(""),normal:"\u2211\u220F\u222B\u221A\u221E\u2248\u2260\u2264\u2265\u2282\u2283\u2286\u2287".split(""),core:"\u222E\u222F\u2230\u2202".split(""),solid:" \u2219\u2218\u2211\u222B\u221A\u221E\u2248\u2295\u2297".split("")},binary:{thin:"\xB7.".split(""),normal:"01".split(""),core:"\u2588".split(""),solid:" .:01\u2588\u2588".split("")},hex:{thin:"\xB7\u2219".split(""),normal:"0123456789ABCDEF".split(""),core:"FFAA".split(""),solid:" 0123456789AF".split("")}},lt=te.default;function ne(n){return te[n]??te.default}function re(n){let{camera:t,grid:e,wireframe:o,mode:r}=n,{cols:s,rows:i,cellAspect:a}=e;if(r==="solid")return at(n,s,i,a);let u=ne(n.glyphPalette),c=new Uint8Array(s*i),h=n.useColors?new Array(s*i).fill(null):null;for(let d of o){let f=t.project(d.from,s,i,a),m=t.project(d.to,s,i,a);f[0]!==f[0]||m[0]!==m[0]||mt(c,h,f[0]|0,f[1]|0,m[0]|0,m[1]|0,d.weight??2,d.color??null,s,i)}return ft(c,h,s,i,u)}function at(n,t,e,o){let{camera:r,polygons:s,directionalLight:i,ambientLight:a,smoothShading:u,creaseAngle:c}=n,h=ne(n.glyphPalette).solid,d=h.length-1,f=new Array(t*e).fill(" "),m=n.useColors,g=m?new Array(t*e).fill(null):null,L=new Float64Array(t*e).fill(-1/0),E=i.direction,S=Math.hypot(E[0],E[1],E[2])||1,A=E[0]/S,M=E[1]/S,x=E[2]/S,p=i.intensity??1,b=a.intensity??.4,l=ye(i.color??"#ffffff"),v=ye(a.color??"#ffffff"),G=u&&c>0?dt(s,c):null;for(let C=0;C<s.length;C++){let y=s[C],w=y.vertices;if(!(w.length<3))for(let _=1;_<w.length-1;_++){let H=_,I=_+1,z=w[0],P=w[H],F=w[I],O=r.project(z,t,e,o),k=r.project(P,t,e,o),Y=r.project(F,t,e,o);if(O[0]!==O[0]||k[0]!==k[0]||Y[0]!==Y[0])continue;let D=P[0]-z[0],B=P[1]-z[1],oe=P[2]-z[2],$=F[0]-z[0],N=F[1]-z[1],J=F[2]-z[2],Q=B*J-oe*N,j=oe*$-D*J,Pe=D*N-B*$,ie=Math.hypot(Q,j,Pe)||1,Be=Q/ie,We=j/ie,$e=Pe/ie,se,le,ae,ce,ue,de,pe,he,me;if(G){let U=G[C],X=U[0],V=U[H],q=U[I];se=X[0],le=X[1],ae=X[2],ce=V[0],ue=V[1],de=V[2],pe=q[0],he=q[1],me=q[2]}else se=ce=pe=Be,le=ue=he=We,ae=de=me=$e;let je=se*A+le*M+ae*x,Ue=ce*A+ue*M+de*x,qe=pe*A+he*M+me*x,Oe=Math.min(1,b+Math.max(0,je)*p),ke=Math.min(1,b+Math.max(0,Ue)*p),Re=Math.min(1,b+Math.max(0,qe)*p),Ie=null;if(m){let U=(Oe+ke+Re)/3,X=Math.max(0,U-b),V=y.color?ye(y.color):[255,255,255],q=b*v[0]/255+X*l[0]/255,Ke=b*v[1]/255+X*l[1]/255,Ze=b*v[2]/255+X*l[2]/255,Je=Math.min(255,V[0]*q),Qe=Math.min(255,V[1]*Ke),et=Math.min(255,V[2]*Ze);Ie=`#${ge(Je)}${ge(Qe)}${ge(et)}`}ut(O[0],O[1],O[2],Oe,k[0],k[1],k[2],ke,Y[0],Y[1],Y[2],Re,h,d,Ie,f,g,L,t,e)}}return pt(f,g,t,e)}var ct=new Float64Array([(0+.5)/16,(8+.5)/16,(2+.5)/16,(10+.5)/16,(12+.5)/16,(4+.5)/16,(14+.5)/16,(6+.5)/16,(3+.5)/16,(11+.5)/16,(1+.5)/16,(9+.5)/16,(15+.5)/16,(7+.5)/16,(13+.5)/16,(5+.5)/16]);function ut(n,t,e,o,r,s,i,a,u,c,h,d,f,m,g,L,E,S,A,M){let x=(r-n)*(c-t)-(s-t)*(u-n);if(x===0||x>0)return;let p=1/x,b=x>0,l=n<r?n:r;u<l&&(l=u);let v=n>r?n:r;u>v&&(v=u);let G=t<s?t:s;c<G&&(G=c);let C=t>s?t:s;c>C&&(C=c);let y=Math.max(0,Math.ceil(l)),w=Math.min(A-1,Math.floor(v)),_=Math.max(0,Math.ceil(G)),T=Math.min(M-1,Math.floor(C));if(!(y>w||_>T))for(let H=_;H<=T;H++){let I=H;for(let z=y;z<=w;z++){let P=z,F=(r-P)*(c-I)-(s-I)*(u-P),O=(u-P)*(t-I)-(c-I)*(n-P),k=(n-P)*(s-I)-(t-I)*(r-P);if(b?F<0||O<0||k<0:F>0||O>0||k>0)continue;let Y=(F*e+O*i+k*h)*p,D=H*A+z;if(Y>S[D]){S[D]=Y;let B=(F*o+O*a+k*d)*p,$=(B<0?0:B>1?1:B)*m,N=$|0,J=$-N,Q=ct[(H&3)*4+(z&3)],j=J>Q&&N<m?N+1:N;L[D]=f[j>m?m:j],E&&(E[D]=g)}}}}function dt(n,t){let e=n.length,o=new Array(e);for(let a=0;a<e;a++){let u=n[a].vertices;if(u.length<3){o[a]=[0,0,0];continue}let c=u[0],h=u[1],d=u[2],f=h[0]-c[0],m=h[1]-c[1],g=h[2]-c[2],L=d[0]-c[0],E=d[1]-c[1],S=d[2]-c[2],A=m*S-g*E,M=g*L-f*S,x=f*E-m*L,p=Math.hypot(A,M,x)||1;o[a]=[A/p,M/p,x/p]}let r=new Map;for(let a=0;a<e;a++){let u=n[a].vertices;for(let c=0;c<u.length;c++){let h=u[c],d=`${h[0]},${h[1]},${h[2]}`,f=r.get(d);f||(f=[],r.set(d,f)),(f.length===0||f[f.length-1]!==a)&&f.push(a)}}let s=Math.cos(t*Math.PI/180),i=new Array(e);for(let a=0;a<e;a++){let u=n[a].vertices,c=o[a],h=new Array(u.length);for(let d=0;d<u.length;d++){let f=u[d],m=r.get(`${f[0]},${f[1]},${f[2]}`),g=0,L=0,E=0;for(let A=0;A<m.length;A++){let M=m[A],x=o[M];c[0]*x[0]+c[1]*x[1]+c[2]*x[2]>=s&&(g+=x[0],L+=x[1],E+=x[2])}let S=Math.hypot(g,L,E)||1;h[d]=[g/S,L/S,E/S]}i[a]=h}return i}function pt(n,t,e,o){let r=[],s=null,i="",a=()=>{i&&(s!==null?r.push(`<span style="color:${s}">${i}</span>`):r.push(i),i="")};for(let u=0;u<o;u++){for(let c=0;c<e;c++){let h=u*e+c,d=n[h],f=t&&d!==" "?t[h]??null:null;f!==s&&(a(),s=f),i+=d}a(),s=null,u<o-1&&r.push(`
2
- `)}return r.join("")}function ht(n,t,e="y"){let{camera:o}=n,r=e==="y"?o.rotY:o.rotX,s=new Array(t);for(let i=0;i<t;i++){let a=r+i/t*Math.PI*2;e==="y"?o.rotY=a:o.rotX=a,s[i]=re(n)}return e==="y"?o.rotY=r:o.rotX=r,s}function mt(n,t,e,o,r,s,i,a,u,c){let h=Math.abs(r-e),d=-Math.abs(s-o),f=e<r?1:-1,m=o<s?1:-1,g=h+d;for(;;){if(e>=0&&e<u&&o>=0&&o<c){let E=o*u+e;n[E]<i&&(n[E]=i,t&&(t[E]=a))}if(e===r&&o===s)break;let L=2*g;L>=d&&(g+=d,e+=f),L<=h&&(g+=h,o+=m)}}function ft(n,t,e,o,r){let s=[],i=null,a="",u=()=>{a&&(i!==null?s.push(`<span style="color:${i}">${a}</span>`):s.push(a),a="")};for(let c=0;c<o;c++){for(let h=0;h<e;h++){let d=c*e+h,f=n[d],m,g;f===0?(m=" ",g=null):(m=f===1?r.thin[Math.random()*r.thin.length|0]:f===2?r.normal[Math.random()*r.normal.length|0]:r.core[Math.random()*r.core.length|0],g=t?t[d]??null:null),g!==i&&(u(),i=g),a+=m}u(),i=null,c<o-1&&s.push(`
3
- `)}return s.join("")}function ye(n){let t=n.startsWith("#")?n.slice(1):n;if(t.length===3){let e=parseInt(t[0]+t[0],16),o=parseInt(t[1]+t[1],16),r=parseInt(t[2]+t[2],16);return[e||0,o||0,r||0]}if(t.length===6){let e=parseInt(t.slice(0,2),16),o=parseInt(t.slice(2,4),16),r=parseInt(t.slice(4,6),16);return[e||0,o||0,r||0]}return[255,255,255]}function ge(n){let t=Math.max(0,Math.min(255,n|0)).toString(16);return t.length===1?"0"+t:t}var Ye="glyph-styles";function be(n){let t=n??(typeof document<"u"?document:void 0);if(!t||t.getElementById(Ye))return;let e=t.createElement("style");e.id=Ye,e.textContent=yt,t.head.appendChild(e)}var yt=`
1
+ var at=Math.PI/180;function ct(t,n,e){let o=t[1],r=t[0],s=t[2],l=e*at,i=Math.cos(l),u=Math.sin(l),d=o*i-r*u,h=o*u+r*i,c=s,f=n*at,g=Math.cos(f),y=Math.sin(f),w=h*g-c*y,M=h*y+c*g;return[d,w,M]}function ve(t={}){let n={rotX:t.rotX??65,rotY:t.rotY??45,distance:t.distance??6,zoom:t.zoom??.65,stretch:t.stretch??1,target:[0,0,0],eyeMode:!1,focal:1},[e,o]=t.center??[.5,.5];return{kind:"perspective",get rotX(){return n.rotX},set rotX(r){n.rotX=r},get rotY(){return n.rotY},set rotY(r){n.rotY=r},get distance(){return n.distance},set distance(r){n.distance=r},get zoom(){return n.zoom},set zoom(r){n.zoom=r},get stretch(){return n.stretch},set stretch(r){n.stretch=r},get target(){return n.target},set target(r){n.target=r},get eyeMode(){return n.eyeMode},set eyeMode(r){n.eyeMode=r},project(r,s,l,i){let d=50/i,h=[r[0]-n.target[0],r[1]-n.target[1],r[2]-n.target[2]],c=ct(h,n.rotX,n.rotY);if(n.eyeMode){if(c[2]>=-.001)return[NaN,NaN,c[2]];let v=n.focal/-c[2],E=c[0]*v*n.zoom*50,L=c[1]*v*n.zoom*50,a=s*e+E/d*n.stretch,m=l*o+L/50;return[a,m,c[2]]}let f=.001,g=n.distance-c[2];if(g<f)return[NaN,NaN,c[2]];let y=n.distance/g,w=c[0]*y*n.zoom*50,M=c[1]*y*n.zoom*50,_=s*e+w/d*n.stretch,G=l*o+M/50;return[_,G,c[2]]}}}function Me(t={}){let n={rotX:t.rotX??65,rotY:t.rotY??45,distance:0,zoom:t.zoom??.65,stretch:1,target:[0,0,0]},[e,o]=t.center??[.5,.5];return{kind:"orthographic",get rotX(){return n.rotX},set rotX(r){n.rotX=r},get rotY(){return n.rotY},set rotY(r){n.rotY=r},get distance(){return n.distance},set distance(r){n.distance=r},get zoom(){return n.zoom},set zoom(r){n.zoom=r},get stretch(){return n.stretch},set stretch(r){n.stretch=r},get target(){return n.target},set target(r){n.target=r},get eyeMode(){return!1},set eyeMode(r){},project(r,s,l,i){let d=50/i,h=[r[0]-n.target[0],r[1]-n.target[1],r[2]-n.target[2]],c=ct(h,n.rotX,n.rotY),f=c[0]*n.zoom*50,g=c[1]*n.zoom*50,y=s*e+f/d,w=l*o+g/50;return[y,w,c[2]]}}}var Lt=Me;var _t={direction:[-.5,-.7,-.5],intensity:1},Ht={intensity:.4};function Pt(t){let n=new Set,e=[];for(let o of t){let r=o.vertices;if(!(r.length<2))for(let s=0;s<r.length;s++){let l=r[s],i=r[(s+1)%r.length],u=`${l[0]},${l[1]},${l[2]}`,d=`${i[0]},${i[1]},${i[2]}`,h=u<d?`${u}|${d}`:`${d}|${u}`;if(n.has(h))continue;n.add(h);let c={from:l,to:i,weight:2};o.color&&(c.color=o.color),e.push(c)}}return e}function Be(t){let n=t.polygons??[],e=t.mode??(n.length?"solid":"wireframe"),o=t.wireframe??(e==="wireframe"?Pt(n):[]);return{camera:t.camera,grid:t.grid,polygons:n,wireframe:o,mode:e,directionalLight:t.directionalLight??_t,ambientLight:t.ambientLight??Ht,glyphPalette:t.glyphPalette??"default",useColors:t.useColors??!0,smoothShading:t.smoothShading??!1,creaseAngle:t.creaseAngle??60,shadow:t.shadow,castShadowFlags:t.castShadowFlags??[],receiveShadowFlags:t.receiveShadowFlags??[]}}var Tt=" .:-=+*#%@".split(""),zt=" .:-=+*#%@".split(""),xe={default:{thin:"\xB7\u22C5\u2219\u02D9\xB7\u22C5\u2219".split(""),normal:"\u254B\u256C\u253C\u2573\u25C6\u25C7\u25CA\u25B2\u25B3\u25BC\u25BD\u25C8\u2B21\u2B22\u2234\u2235\u22A5\u2295\u2297\u2299\u229A\u229B".split(""),core:"\u2726\u2727\u2729\u25C9\u2299\u25CE".split(""),solid:" .:-=+*#%@".split("")},ascii:{thin:".'".split(""),normal:"+*x".split(""),core:"#@".split(""),solid:" .,:;!+=*xX#@".split("")},dots:{thin:"\xB7\u22C5".split(""),normal:"\u2022\u25CF".split(""),core:"\u25C9\u25CE".split(""),solid:" \xB7\u22C5\u2218\u2022\u25CF\u25C9\u25CE\u2B24".split("")},lines:{thin:"\u2500\u2502".split(""),normal:"\u2550\u2551".split(""),core:"\u2588".split(""),solid:" \u2500\u2550\u256C\u2551\u2588\u2593\u2592\u2591".split("")},blocks:{thin:"\u2591\u2581".split(""),normal:"\u2592\u2593\u258C\u2590\u2580\u2584".split(""),core:"\u2588".split(""),solid:" \u2591\u2592\u2593\u258C\u2590\u2588\u2580\u2584\u25A0".split("")},stars:{thin:"\xB7\u22C6".split(""),normal:"\u2726\u2727\u2729\u272A".split(""),core:"\u272B\u272C\u272D\u2605".split(""),solid:" \xB7\u22C6\u2217\u2726\u2727\u2729\u272A\u272B\u2605".split("")},arrows:{thin:"\xB7\u2219".split(""),normal:"\u2190\u2191\u2192\u2193".split(""),core:"\u2196\u2197\u2198\u2199\u2921\u2922".split(""),solid:" \xB7\u2219\u2191\u2197\u2192\u2198\u2193\u2199\u2190\u2196".split("")},braille:{thin:"\u2801\u2802\u2804\u2808".split(""),normal:"\u2803\u2805\u2806\u2809\u280A\u280B\u280C\u280D\u280E\u280F".split(""),core:"\u283F\u28FF".split(""),solid:" \u2801\u2803\u2807\u2827\u2837\u283F\u287F\u28FF".split("")},runes:{thin:".\xB7".split(""),normal:"\u16A0\u16A1\u16A2\u16A3\u16A4\u16A6\u16A8\u16B1\u16B2\u16B3\u16B7\u16B9\u16C3\u16C7\u16C9".split(""),core:"\u16DE\u16DF\u16E1\u16E2\u16E3".split(""),solid:" \xB7\u16A0\u16A3\u16A4\u16A8\u16B1\u16B7\u16DE\u16E2".split("")},math:{thin:"\u2219\u2218".split(""),normal:"\u2211\u220F\u222B\u221A\u221E\u2248\u2260\u2264\u2265\u2282\u2283\u2286\u2287".split(""),core:"\u222E\u222F\u2230\u2202".split(""),solid:" \u2219\u2218\u2211\u222B\u221A\u221E\u2248\u2295\u2297".split("")},binary:{thin:"\xB7.".split(""),normal:"01".split(""),core:"\u2588".split(""),solid:" .:01\u2588\u2588".split("")},hex:{thin:"\xB7\u2219".split(""),normal:"0123456789ABCDEF".split(""),core:"FFAA".split(""),solid:" 0123456789AF".split("")}},Ot=xe.default;function Ae(t){return xe[t]??xe.default}function Ge(t){let{camera:n,grid:e,wireframe:o,mode:r}=t,{cols:s,rows:l,cellAspect:i}=e;if(r==="solid")return It(t,s,l,i);let u=Ae(t.glyphPalette),d=new Uint8Array(s*l),h=t.useColors?new Array(s*l).fill(null):null;for(let c of o){let f=n.project(c.from,s,l,i),g=n.project(c.to,s,l,i);f[0]!==f[0]||g[0]!==g[0]||Nt(d,h,f[0]|0,f[1]|0,g[0]|0,g[1]|0,c.weight??2,c.color??null,s,l)}return Vt(d,h,s,l,u)}function It(t,n,e,o){let{camera:r,polygons:s,directionalLight:l,ambientLight:i,smoothShading:u,creaseAngle:d,castShadowFlags:h,receiveShadowFlags:c}=t,f=Ae(t.glyphPalette).solid,g=f.length-1,y=new Array(n*e).fill(" "),w=t.useColors,M=w?new Array(n*e).fill(null):null,_=new Float64Array(n*e).fill(-1/0),G=l.direction,P=Math.hypot(G[0],G[1],G[2])||1,v=G[0]/P,E=G[1]/P,L=G[2]/P,a=l.intensity??1,m=i.intensity??.4,b=Ee(l.color??"#ffffff"),C=Ee(i.color??"#ffffff"),p=u&&d>0?Dt(s,d):null,x=new Map,S=t.shadow,T=S!=null&&h.length>0?Ft(s,h,v,E,L):null,H=S?.opacity??.25,I=S?.lift??.05,R=S?.color??"#000000",q=T?Ee(R):[0,0,0],z=globalThis.__glyphPerfDetail,U=z?performance.now():0,Y=[],O=t.shadeCache??null,k=-1;for(let re=0;re<s.length;re++){let fe=s[re],D=fe.vertices;if(!(D.length<3)){for(let B=0;B<D.length;B++)Y[B]=r.project(D[B],n,e,o);for(let B=1;B<D.length-1;B++){k++;let ye=0,N=B,K=B+1,Z=D[ye],oe=D[N],ie=D[K],F=Y[ye],X=Y[N],V=Y[K];if(F[0]!==F[0]||X[0]!==X[0]||V[0]!==V[0]||(X[0]-F[0])*(V[1]-F[1])-(X[1]-F[1])*(V[0]-F[0])>0)continue;let $,J,Q,se=null;if(O!==null&&O.iA[k]!==void 0)$=O.iA[k],J=O.iB[k],Q=O.iC[k],se=O.lit[k];else{let A=oe[0]-Z[0],le=oe[1]-Z[1],ae=oe[2]-Z[2],ce=ie[0]-Z[0],nt=ie[1]-Z[1],rt=ie[2]-Z[2],ot=le*rt-ae*nt,it=ae*ce-A*rt,st=A*nt-le*ce,He=Math.hypot(ot,it,st)||1,yt=ot/He,gt=it/He,bt=st/He,Pe,Te,ze,Oe,Ie,Re,ke,Fe,Ye;if(p){let ge=p[re],ee=ge[ye],ue=ge[N],be=ge[K];Pe=ee[0],Te=ee[1],ze=ee[2],Oe=ue[0],Ie=ue[1],Re=ue[2],ke=be[0],Fe=be[1],Ye=be[2]}else Pe=Oe=ke=yt,Te=Ie=Fe=gt,ze=Re=Ye=bt;let vt=Math.max(0,-(Pe*v+Te*E+ze*L)),Et=Math.max(0,-(Oe*v+Ie*E+Re*L)),wt=Math.max(0,-(ke*v+Fe*E+Ye*L));if($=Math.min(1,m+vt*a),J=Math.min(1,m+Et*a),Q=Math.min(1,m+wt*a),w){let ge=($+J+Q)/3,ee=Math.max(0,ge-m),ue=fe.color??"#ffffff",be=ee*255|0,lt=`${ue}:${be}`,Ce=x.get(lt);if(Ce===void 0){let De=Ee(ue),Ct=m*C[0]/255+ee*b[0]/255,Mt=m*C[1]/255+ee*b[1]/255,xt=m*C[2]/255+ee*b[2]/255,At=Math.min(255,De[0]*Ct),Gt=Math.min(255,De[1]*Mt),St=Math.min(255,De[2]*xt);Ce=`#${he(At)}${he(Gt)}${he(St)}`,x.set(lt,Ce)}se=Ce}O!==null&&(O.iA[k]=$,O.iB[k]=J,O.iC[k]=Q,O.lit[k]=se)}let _e=c[re]??!1,we=null;if(T!==null&&_e){let A=T,le=de(Z,A.right[0],A.right[1],A.right[2],A.up[0],A.up[1],A.up[2],A.dir[0],A.dir[1],A.dir[2],A.uMin,A.uMax,A.vMin,A.vMax),ae=de(oe,A.right[0],A.right[1],A.right[2],A.up[0],A.up[1],A.up[2],A.dir[0],A.dir[1],A.dir[2],A.uMin,A.uMax,A.vMin,A.vMax),ce=de(ie,A.right[0],A.right[1],A.right[2],A.up[0],A.up[1],A.up[2],A.dir[0],A.dir[1],A.dir[2],A.uMin,A.uMax,A.vMin,A.vMax);we={map:A,luA:le[0],lvA:le[1],ldA:le[2],luB:ae[0],lvB:ae[1],ldB:ae[2],luC:ce[0],lvC:ce[1],ldC:ce[2],lift:I,opacity:H,shadowColorRgb:q,shadowColorHex:R,litCache:x}}Yt(F[0],F[1],F[2],$,X[0],X[1],X[2],J,V[0],V[1],V[2],Q,f,g,se,y,M,_,n,e,we)}}}z&&(z.loop??(z.loop=[])).push(performance.now()-U);let ne=z?performance.now():0,me=Bt(y,M,n,e);return z&&(z.string??(z.string=[])).push(performance.now()-ne),me}var Rt=new Float64Array([(0+.5)/16,(8+.5)/16,(2+.5)/16,(10+.5)/16,(12+.5)/16,(4+.5)/16,(14+.5)/16,(6+.5)/16,(3+.5)/16,(11+.5)/16,(1+.5)/16,(9+.5)/16,(15+.5)/16,(7+.5)/16,(13+.5)/16,(5+.5)/16]),W=256;function de(t,n,e,o,r,s,l,i,u,d,h,c,f,g){let y=n*t[0]+e*t[1]+o*t[2],w=r*t[0]+s*t[1]+l*t[2],M=-(i*t[0]+u*t[1]+d*t[2]),_=(y-h)/(c-h)*(W-1),G=(w-f)/(g-f)*(W-1);return[_,G,M]}function kt(t,n,e,o){let r=n[0],s=n[1],l=n[2],i=e[0],u=e[1],d=e[2],h=o[0],c=o[1],f=o[2],g=(i-r)*(c-s)-(u-s)*(h-r);if(g===0)return;let y=1/g,w=r<i?r:i;h<w&&(w=h);let M=r>i?r:i;h>M&&(M=h);let _=s<u?s:u;c<_&&(_=c);let G=s>u?s:u;c>G&&(G=c);let P=Math.max(0,Math.ceil(w)),v=Math.min(W-1,Math.floor(M)),E=Math.max(0,Math.ceil(_)),L=Math.min(W-1,Math.floor(G));if(P>v||E>L)return;let a=g>0;for(let m=E;m<=L;m++)for(let b=P;b<=v;b++){let C=b,p=m,x=(i-C)*(c-p)-(u-p)*(h-C),S=(h-C)*(s-p)-(c-p)*(r-C),T=(r-C)*(u-p)-(s-p)*(i-C);if(a?x<0||S<0||T<0:x>0||S>0||T>0)continue;let H=(x*l+S*d+T*f)*y,I=m*W+b;H>t[I]&&(t[I]=H)}}function Ft(t,n,e,o,r){let s,l,i;Math.abs(e)<.9?(s=0,l=r,i=-o):(s=-r,l=0,i=e);let u=Math.hypot(s,l,i);s/=u,l/=u,i/=u;let d=l*r-i*o,h=i*e-s*r,c=s*o-l*e,f=1/0,g=-1/0,y=1/0,w=-1/0,M=!1;for(let v=0;v<t.length;v++)if(n[v]){M=!0;for(let E of t[v].vertices){let L=s*E[0]+l*E[1]+i*E[2],a=d*E[0]+h*E[1]+c*E[2];L<f&&(f=L),L>g&&(g=L),a<y&&(y=a),a>w&&(w=a)}}if(!M)return null;let _=(g-f)*.05+.01,G=(w-y)*.05+.01;f-=_,g+=_,y-=G,w+=G;let P=new Float64Array(W*W).fill(-1/0);for(let v=0;v<t.length;v++){if(!n[v])continue;let E=t[v].vertices;if(!(E.length<3))for(let L=1;L<E.length-1;L++){let a=E[0],m=E[L],b=E[L+1],C=de(a,s,l,i,d,h,c,e,o,r,f,g,y,w),p=de(m,s,l,i,d,h,c,e,o,r,f,g,y,w),x=de(b,s,l,i,d,h,c,e,o,r,f,g,y,w);kt(P,C,p,x)}}return{buf:P,right:[s,l,i],up:[d,h,c],dir:[e,o,r],uMin:f,uMax:g,vMin:y,vMax:w}}function Yt(t,n,e,o,r,s,l,i,u,d,h,c,f,g,y,w,M,_,G,P,v){let E=(r-t)*(d-n)-(s-n)*(u-t);if(E===0||E>0)return;let L=1/E,a=E>0,m=t<r?t:r;u<m&&(m=u);let b=t>r?t:r;u>b&&(b=u);let C=n<s?n:s;d<C&&(C=d);let p=n>s?n:s;d>p&&(p=d);let x=Math.max(0,Math.ceil(m)),S=Math.min(G-1,Math.floor(b)),T=Math.max(0,Math.ceil(C)),H=Math.min(P-1,Math.floor(p));if(!(x>S||T>H))for(let I=T;I<=H;I++){let R=I;for(let q=x;q<=S;q++){let z=q,U=(r-z)*(d-R)-(s-R)*(u-z),Y=(u-z)*(n-R)-(d-R)*(t-z),O=(t-z)*(s-R)-(n-R)*(r-z);if(a?U<0||Y<0||O<0:U>0||Y>0||O>0)continue;let k=(U*e+Y*l+O*h)*L,ne=I*G+q;if(k>_[ne]){_[ne]=k;let me=(U*o+Y*i+O*c)*L,fe=(me<0?0:me>1?1:me)*g,D=fe|0,B=fe-D,ye=Rt[(I&3)*4+(q&3)],N=B>ye&&D<g?D+1:D;N>g&&(N=g);let K=y;if(v!==null){let Z=(U*v.luA+Y*v.luB+O*v.luC)*L,oe=(U*v.lvA+Y*v.lvB+O*v.lvC)*L,ie=(U*v.ldA+Y*v.ldB+O*v.ldC)*L,F=Z|0,X=oe|0;if(F>=0&&F<W&&X>=0&&X<W){let V=v.map.buf[X*W+F];if(V>-1/0&&ie+v.lift<V&&(N=Math.max(0,N-Math.round(v.opacity*g)),K!==null)){let Le=`shadow:${K}:${N}`,$=v.litCache.get(Le);if($===void 0){let J=Ee(K),Q=v.shadowColorRgb,se=Math.round(J[0]*(1-v.opacity)+Q[0]*v.opacity),_e=Math.round(J[1]*(1-v.opacity)+Q[1]*v.opacity),we=Math.round(J[2]*(1-v.opacity)+Q[2]*v.opacity);$=`#${he(se)}${he(_e)}${he(we)}`,v.litCache.set(Le,$)}K=$}}}w[ne]=f[N],M&&(M[ne]=K)}}}}function Dt(t,n){let e=t.length,o=new Array(e);for(let i=0;i<e;i++){let u=t[i].vertices;if(u.length<3){o[i]=[0,0,0];continue}let d=u[0],h=u[1],c=u[2],f=h[0]-d[0],g=h[1]-d[1],y=h[2]-d[2],w=c[0]-d[0],M=c[1]-d[1],_=c[2]-d[2],G=g*_-y*M,P=y*w-f*_,v=f*M-g*w,E=Math.hypot(G,P,v)||1;o[i]=[G/E,P/E,v/E]}let r=new Map;for(let i=0;i<e;i++){let u=t[i].vertices;for(let d=0;d<u.length;d++){let h=u[d],c=`${h[0]},${h[1]},${h[2]}`,f=r.get(c);f||(f=[],r.set(c,f)),(f.length===0||f[f.length-1]!==i)&&f.push(i)}}let s=Math.cos(n*Math.PI/180),l=new Array(e);for(let i=0;i<e;i++){let u=t[i].vertices,d=o[i],h=new Array(u.length);for(let c=0;c<u.length;c++){let f=u[c],g=r.get(`${f[0]},${f[1]},${f[2]}`),y=0,w=0,M=0;for(let G=0;G<g.length;G++){let P=g[G],v=o[P];d[0]*v[0]+d[1]*v[1]+d[2]*v[2]>=s&&(y+=v[0],w+=v[1],M+=v[2])}let _=Math.hypot(y,w,M)||1;h[c]=[y/_,w/_,M/_]}l[i]=h}return l}function Bt(t,n,e,o){let r=[],s=null,l="",i=()=>{l&&(s!==null?r.push(`<span style="color:${s}">${l}</span>`):r.push(l),l="")};for(let u=0;u<o;u++){for(let d=0;d<e;d++){let h=u*e+d,c=t[h],f=n&&c!==" "?n[h]??null:null;f!==s&&(i(),s=f),l+=c}i(),s=null,u<o-1&&r.push(`
2
+ `)}return r.join("")}function Xt(t,n,e="y"){let{camera:o}=t,r=e==="y"?o.rotY:o.rotX,s=new Array(n);for(let l=0;l<n;l++){let i=r+l/n*Math.PI*2;e==="y"?o.rotY=i:o.rotX=i,s[l]=Ge(t)}return e==="y"?o.rotY=r:o.rotX=r,s}function Nt(t,n,e,o,r,s,l,i,u,d){let h=Math.abs(r-e),c=-Math.abs(s-o),f=e<r?1:-1,g=o<s?1:-1,y=h+c;for(;;){if(e>=0&&e<u&&o>=0&&o<d){let M=o*u+e;t[M]<l&&(t[M]=l,n&&(n[M]=i))}if(e===r&&o===s)break;let w=2*y;w>=c&&(y+=c,e+=f),w<=h&&(y+=h,o+=g)}}function Vt(t,n,e,o,r){let s=[],l=null,i="",u=()=>{i&&(l!==null?s.push(`<span style="color:${l}">${i}</span>`):s.push(i),i="")};for(let d=0;d<o;d++){for(let h=0;h<e;h++){let c=d*e+h,f=t[c],g,y;f===0?(g=" ",y=null):(g=f===1?r.thin[Math.random()*r.thin.length|0]:f===2?r.normal[Math.random()*r.normal.length|0]:r.core[Math.random()*r.core.length|0],y=n?n[c]??null:null),y!==l&&(u(),l=y),i+=g}u(),l=null,d<o-1&&s.push(`
3
+ `)}return s.join("")}var ut=new Map;function Ee(t){let n=ut.get(t);if(n!==void 0)return n;let e=$t(t);return ut.set(t,e),e}function $t(t){let n=t.startsWith("#")?t.slice(1):t;if(n.length===3){let e=parseInt(n[0]+n[0],16),o=parseInt(n[1]+n[1],16),r=parseInt(n[2]+n[2],16);return[e||0,o||0,r||0]}if(n.length===6){let e=parseInt(n.slice(0,2),16),o=parseInt(n.slice(2,4),16),r=parseInt(n.slice(4,6),16);return[e||0,o||0,r||0]}return[255,255,255]}function he(t){let n=Math.max(0,Math.min(255,t|0)).toString(16);return n.length===1?"0"+n:n}var dt="glyph-styles";function Xe(t){let n=t??(typeof document<"u"?document:void 0);if(!n||n.getElementById(dt))return;let e=n.createElement("style");e.id=dt,e.textContent=Wt,n.head.appendChild(e)}var Wt=`
4
4
  /* \u2500\u2500 React / Vue host wrapper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
5
5
 
6
6
  .glyph-host {
@@ -59,4 +59,5 @@ function Fe(n,t,e){let o=Math.cos(t),r=Math.sin(t),s=o*n[1]-r*n[0],i=r*n[1]+o*n[
59
59
  the content from the 3D vertex being labelled. */
60
60
  transform: translate(-50%, -50%);
61
61
  }
62
- `;function ve(n,t,e,o,r){return n.map(s=>{let[i,a,u]=t.project(s.at,e,o,r),c=u>-3&&i>=0&&i<e&&a>=0&&a<o;return{id:s.id,col:i,row:a,depth:u,visible:c}})}var gt=1;function bt(n,t){let{position:e,scale:o,rotation:r}=t;if(!e&&!o&&!r)return n;let[s,i,a]=e??[0,0,0],u=1,c=1,h=1;o!==void 0&&(typeof o=="number"?u=c=h=o:[u,c,h]=o);let[d,f,m]=r??[0,0,0],g=Math.cos(d),L=Math.sin(d),E=Math.cos(f),S=Math.sin(f),A=Math.cos(m),M=Math.sin(m);function x(p){let b=p[0]*u,l=p[1]*c,v=p[2]*h,G=A*b-M*l,C=M*b+A*l,y=v;return b=E*G+S*y,l=C,v=-S*G+E*y,G=b,C=g*l-L*v,y=L*l+g*v,[G+s,C+i,y+a]}return n.map(p=>({...p,vertices:p.vertices.map(x)}))}function Ee(n,t={}){be(n.ownerDocument??void 0);let e={mode:t.mode??"solid",glyphPalette:t.glyphPalette??"default",useColors:t.useColors??!0,cols:t.cols??80,rows:t.rows??24,cellAspect:t.cellAspect??2,directionalLight:t.directionalLight??{direction:[.5,.7,.5],intensity:1},ambientLight:t.ambientLight??{intensity:.4},camera:t.camera??K(),smoothShading:t.smoothShading??!1,creaseAngle:t.creaseAngle??60,autoSize:t.autoSize??!1},o=n.ownerDocument.createElement("div");o.className="glyph-scene";let r=n.ownerDocument.createElement("pre");r.className="glyph-output";let s=n.ownerDocument.createElement("div");s.className="glyph-hotspot-layer",o.appendChild(r),o.appendChild(s),n.appendChild(o);let i=new Map,a=[],u=!1;function c(){u||(u=!0,Promise.resolve().then(()=>{u=!1,h()}))}function h(){let p=[];for(let v of i.values()){let G=bt(v.polygons,v.transform);for(let C of G)p.push(C)}let b=fe({camera:e.camera,grid:{cols:e.cols,rows:e.rows,cellAspect:e.cellAspect},polygons:p,mode:e.mode,directionalLight:e.directionalLight,ambientLight:e.ambientLight,glyphPalette:e.glyphPalette,useColors:e.useColors,smoothShading:e.smoothShading,creaseAngle:e.creaseAngle}),l=re(b);e.useColors?r.innerHTML=l:r.textContent=l,d()}function d(){let{cols:p,rows:b,cellAspect:l,camera:v}=e,G=ve(a.map(_=>_.hotspot),v,p,b,l),C=r.getBoundingClientRect(),y=p>0?C.width/p:8,w=b>0?C.height/b:16;for(let _=0;_<a.length;_++){let{el:T}=a[_],H=G[_];H.visible?(T.style.display="",T.style.left=`${(H.col+.5)*y}px`,T.style.top=`${(H.row+.5)*w}px`,T.style.zIndex=String(Math.round(H.depth*1e3))):T.style.display="none"}}function f(p,b={}){let l=gt++;return i.set(l,{id:l,polygons:p,transform:b}),c(),{get id(){return l},get name(){return i.get(l)?.transform.id},get polygons(){return p},setTransform(v){let G=i.get(l);G&&(G.transform=v,c())},dispose(){i.delete(l),c()}}}function m(p,b){let l=n.ownerDocument.createElement("div");l.className="glyph-hotspot",l.setAttribute("data-hotspot-id",p.id);let[v,G]=p.size??[1,1];l.style.position="absolute",l.style.width=`${v}ch`,l.style.height=`${G*e.cellAspect}ch`,b&&l.addEventListener("click",b),s.appendChild(l);let C={hotspot:{id:p.id,at:p.at,size:p.size},el:l,onClick:b};return a.push(C),c(),{get el(){return l},remove(){let y=a.indexOf(C);y>=0&&a.splice(y,1),b&&l.removeEventListener("click",b),s.removeChild(l),c()}}}function g(){h()}function L(p){p.mode!==void 0&&(e.mode=p.mode),p.glyphPalette!==void 0&&(e.glyphPalette=p.glyphPalette),p.useColors!==void 0&&(e.useColors=p.useColors),p.cols!==void 0&&(e.cols=p.cols),p.rows!==void 0&&(e.rows=p.rows),p.cellAspect!==void 0&&(e.cellAspect=p.cellAspect),p.directionalLight!==void 0&&(e.directionalLight=p.directionalLight),p.ambientLight!==void 0&&(e.ambientLight=p.ambientLight),p.camera!==void 0&&(e.camera=p.camera),p.smoothShading!==void 0&&(e.smoothShading=p.smoothShading),p.creaseAngle!==void 0&&(e.creaseAngle=p.creaseAngle),p.autoSize!==void 0&&(e.autoSize=p.autoSize,e.autoSize&&!M&&typeof ResizeObserver<"u"?(M=new ResizeObserver(()=>A()),M.observe(n),A()):!e.autoSize&&M&&(M.disconnect(),M=null)),c()}function E(){return{...e}}function S(){let p=n.ownerDocument.createElement("span");p.textContent="M",p.style.cssText="position:absolute;visibility:hidden;font-family:inherit;font-size:inherit;line-height:inherit;white-space:pre;padding:0;margin:0",r.appendChild(p);let b=p.getBoundingClientRect();return p.remove(),{w:b.width||8,h:b.height||16}}function A(){let p=n.clientWidth,b=n.clientHeight;if(!p||!b)return;let l=S(),v=Math.max(20,Math.floor(p/l.w)),G=Math.max(8,Math.floor(b/l.h)),C=l.h/l.w,y=!1;e.cols!==v&&(e.cols=v,y=!0),e.rows!==G&&(e.rows=G,y=!0),Math.abs(e.cellAspect-C)>.01&&(e.cellAspect=C,y=!0),y&&c()}let M=null;e.autoSize&&typeof ResizeObserver<"u"&&(M=new ResizeObserver(()=>A()),M.observe(n),A());function x(){M&&(M.disconnect(),M=null),i.clear(),n.contains(o)&&n.removeChild(o)}return c(),{get host(){return n},get output(){return r},get camera(){return e.camera},add:f,addHotspot:m,rerender:g,setOptions:L,getOptions:E,fit:A,destroy:x}}function Ge(n,t={}){let e=n.host,o=t.drag??!0,r=t.wheel??!0,s=De(t.invert),i=t.animate??!1,a=!1,u=!1,c=null,h=null,d=null,f={x:0,y:0},m=n.camera;function g(l){if(!(!o||a)&&d===null&&l.isPrimary!==!1){l.preventDefault(),d=l.pointerId,f={x:l.clientX,y:l.clientY},e.style.cursor="grabbing";try{l.target.setPointerCapture(l.pointerId)}catch{}i&&i.pauseOnInteraction!==!1&&(u=!0)}}function L(l){if(d===null||l.pointerId!==d||!o||a)return;l.preventDefault();let v=l.clientX-f.x,G=l.clientY-f.y;f={x:l.clientX,y:l.clientY};let C=s,w=1/4*Math.PI/180;m.rotY=m.rotY-v*w*C,m.rotX=Math.max(-Math.PI/2,Math.min(Math.PI/2,m.rotX-G*w*C)),n.rerender()}function E(l){if(d===l.pointerId){d=null,e.style.cursor=o&&!a?"grab":"";try{l.target.releasePointerCapture(l.pointerId)}catch{}i&&(u=!1)}}function S(l){if(!r||a)return;l.preventDefault();let v=l.deltaY*.001;m.zoom=Math.max(.05,Math.min(10,m.zoom*(1-v))),n.rerender()}function A(l){if(!(a||!i)){if(!u){let v=h!==null?Math.min(l-h,50):16.67,G=typeof i=="object"&&i.speed?i.speed:.3,C=typeof i=="object"&&i.axis?i.axis:"y",y=G*(Math.PI/180)*(v/16.67);C==="y"?m.rotY=m.rotY+y:m.rotX=m.rotX+y,n.rerender()}h=l,c=requestAnimationFrame(A)}}function M(){c===null&&typeof requestAnimationFrame<"u"&&i&&(c=requestAnimationFrame(A))}function x(){c!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(c),c=null),h=null}function p(){e.addEventListener("pointerdown",g),e.addEventListener("pointermove",L),e.addEventListener("pointerup",E),e.addEventListener("pointercancel",E),e.addEventListener("wheel",S,{passive:!1}),e.style.cursor=o?"grab":"",e.style.touchAction="none",e.style.userSelect="none"}function b(){e.removeEventListener("pointerdown",g),e.removeEventListener("pointermove",L),e.removeEventListener("pointerup",E),e.removeEventListener("pointercancel",E),e.removeEventListener("wheel",S),e.style.cursor="",e.style.touchAction="",e.style.userSelect=""}return p(),M(),{update(l){let v=!!i;o=l.drag??o,r=l.wheel??r,s=De(l.invert),i=l.animate??i,!a&&d===null&&(e.style.cursor=o?"grab":"");let G=!!i;v&&!G?x():!v&&G&&M()},pause(){a||(a=!0,b(),x(),d=null,u=!1)},resume(){a&&(a=!1,p(),M())},destroy(){a||b(),x(),a=!0}}}function De(n){return n===void 0||n===!1?1:n===!0?-1:n}function Me(n,t={}){let e=n.host,o=t.drag??!0,r=t.wheel??!0,s=Ne(t.invert),i=t.animate??!1,a=!1,u=!1,c=null,h=null,d=null,f={x:0,y:0},m=!1,g=n.camera,L=1/4*Math.PI/180,E=.02;function S(y){if(!(!o||a)&&d===null&&y.isPrimary!==!1){y.preventDefault(),d=y.pointerId,f={x:y.clientX,y:y.clientY},m=y.button===2,e.style.cursor="grabbing";try{y.target.setPointerCapture(y.pointerId)}catch{}i&&i.pauseOnInteraction!==!1&&(u=!0)}}function A(y){if(d===null||y.pointerId!==d||!o||a)return;y.preventDefault();let w=y.clientX-f.x,_=y.clientY-f.y;f={x:y.clientX,y:y.clientY};let T=s;if(m||y.shiftKey)g.rotY=g.rotY-w*L*T,g.rotX=Math.max(-Math.PI/2,Math.min(Math.PI/2,g.rotX+_*L*T));else{let H=g.target;g.target=[H[0]-w*E/g.zoom,H[1]-_*E/g.zoom,H[2]]}n.rerender()}function M(y){if(d===y.pointerId){d=null,m=!1,e.style.cursor=o&&!a?"grab":"";try{y.target.releasePointerCapture(y.pointerId)}catch{}i&&(u=!1)}}function x(y){y.preventDefault()}function p(y){if(!r||a)return;y.preventDefault();let w=y.deltaY*.001;g.zoom=Math.max(.05,Math.min(10,g.zoom*(1-w))),n.rerender()}function b(y){if(!(a||!i)){if(!u){let w=h!==null?Math.min(y-h,50):16.67,_=typeof i=="object"&&i.speed?i.speed:.3,T=typeof i=="object"&&i.axis?i.axis:"y",H=_*(Math.PI/180)*(w/16.67);T==="y"?g.rotY=g.rotY+H:g.rotX=g.rotX+H,n.rerender()}h=y,c=requestAnimationFrame(b)}}function l(){c===null&&typeof requestAnimationFrame<"u"&&i&&(c=requestAnimationFrame(b))}function v(){c!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(c),c=null),h=null}function G(){e.addEventListener("pointerdown",S),e.addEventListener("pointermove",A),e.addEventListener("pointerup",M),e.addEventListener("pointercancel",M),e.addEventListener("contextmenu",x),e.addEventListener("wheel",p,{passive:!1}),e.style.cursor=o?"grab":"",e.style.touchAction="none",e.style.userSelect="none"}function C(){e.removeEventListener("pointerdown",S),e.removeEventListener("pointermove",A),e.removeEventListener("pointerup",M),e.removeEventListener("pointercancel",M),e.removeEventListener("contextmenu",x),e.removeEventListener("wheel",p),e.style.cursor="",e.style.touchAction="",e.style.userSelect=""}return G(),l(),{update(y){let w=!!i;o=y.drag??o,r=y.wheel??r,s=Ne(y.invert),i=y.animate??i,!a&&d===null&&(e.style.cursor=o?"grab":"");let _=!!i;w&&!_?v():!w&&_&&l()},pause(){a||(a=!0,C(),v(),d=null,u=!1)},resume(){a&&(a=!1,G(),l())},destroy(){a||C(),v(),a=!0}}}function Ne(n){return n===void 0||n===!1?1:n===!0?-1:n}function vt(n,t={}){if(n.camera.kind!=="perspective")throw new Error("glyphcss: GlyphFirstPersonControls requires a perspective camera. Use <GlyphPerspectiveCamera> (not <GlyphOrthographicCamera> / <GlyphCamera>).");n.camera.eyeMode=!0;let e=n.host,o=t.drag??!0,r=t.keyboard??!0,s=t.moveSpeed??.05,i=t.lookSpeed??.004,a=Xe(t.invert),u=!1,c=null,h={x:0,y:0},d=new Set,f=null,m=n.camera;function g(l){if(!(!o||u)&&c===null){l.preventDefault(),c=l.pointerId,h={x:l.clientX,y:l.clientY};try{l.target.setPointerCapture(l.pointerId)}catch{}}}function L(l){if(c===null||l.pointerId!==c||!o||u)return;l.preventDefault();let v=l.clientX-h.x,G=l.clientY-h.y;h={x:l.clientX,y:l.clientY},m.rotY=m.rotY-v*i*a,m.rotX=Math.max(-Math.PI/2,Math.min(Math.PI/2,m.rotX+G*i*a)),n.rerender()}function E(l){if(c===l.pointerId){c=null;try{l.target.releasePointerCapture(l.pointerId)}catch{}}}function S(l){r&&!u&&d.add(l.key.toLowerCase())}function A(l){d.delete(l.key.toLowerCase())}function M(){if(u||!r||d.size===0)return;let l=m.target,v=Math.cos(m.rotY),G=Math.sin(m.rotY),C=!1;(d.has("w")||d.has("arrowup"))&&(m.target=[l[0]-G*s,l[1]-v*s,l[2]],C=!0),(d.has("s")||d.has("arrowdown"))&&(m.target=[l[0]+G*s,l[1]+v*s,l[2]],C=!0),(d.has("a")||d.has("arrowleft"))&&(m.target=[l[0]-v*s,l[1]+G*s,l[2]],C=!0),(d.has("d")||d.has("arrowright"))&&(m.target=[l[0]+v*s,l[1]-G*s,l[2]],C=!0),C&&n.rerender()}function x(){u||(M(),f=requestAnimationFrame(x))}function p(){e.addEventListener("pointerdown",g),e.addEventListener("pointermove",L),e.addEventListener("pointerup",E),e.addEventListener("pointercancel",E),r&&(e.ownerDocument?.addEventListener("keydown",S),e.ownerDocument?.addEventListener("keyup",A)),e.style.touchAction="none",e.style.userSelect="none",typeof requestAnimationFrame<"u"&&(f=requestAnimationFrame(x))}function b(){e.removeEventListener("pointerdown",g),e.removeEventListener("pointermove",L),e.removeEventListener("pointerup",E),e.removeEventListener("pointercancel",E),e.ownerDocument?.removeEventListener("keydown",S),e.ownerDocument?.removeEventListener("keyup",A),e.style.touchAction="",e.style.userSelect="",f!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(f),f=null),d.clear(),n.camera.eyeMode=!1}return p(),{update(l){o=l.drag??o,r=l.keyboard??r,s=l.moveSpeed??s,i=l.lookSpeed??i,a=Xe(l.invert)},pause(){u||(u=!0,b(),c=null)},resume(){u&&(u=!1,p())},destroy(){u||b(),u=!0}}}function Xe(n){return n===void 0||n===!1?1:n===!0?-1:n}function Et(n,t){let e=n.querySelector(`[data-glyph-mesh-id="${CSS.escape(t)}"]`);return e instanceof HTMLElement?e:null}function Ve(n,t,e){let o=n.getBoundingClientRect();return o.width<=0||o.height<=0?!1:t>=o.left&&t<=o.right&&e>=o.top&&e<=o.bottom}function Gt(n,t,e){let o=(n instanceof Document,n),r=Array.from(o.querySelectorAll(".glyph-mesh"));for(let s of r)if(Ve(s,t,e))return s;return null}var Mt=typeof HTMLElement<"u"?HTMLElement:class{},Ct=["mode","glyph-palette","use-colors","cols","rows","cell-aspect","directional-direction","directional-intensity","ambient-intensity","auto-size"];function Z(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function xt(n){if(n==="wireframe"||n==="solid"||n==="voxel")return n}function At(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}var Ce=class extends Mt{constructor(){super(...arguments);this._scene=null}static get observedAttributes(){return[...Ct]}getScene(){return this._scene}_readOptions(){let e={},o=xt(this.getAttribute("mode"));o!==void 0&&(e.mode=o);let r=this.getAttribute("glyph-palette");r&&(e.glyphPalette=r);let s=At(this.getAttribute("use-colors"));s!==void 0&&(e.useColors=s);let i=Z(this.getAttribute("cols"));i!==void 0&&(e.cols=i);let a=Z(this.getAttribute("rows"));a!==void 0&&(e.rows=a);let u=Z(this.getAttribute("cell-aspect"));u!==void 0&&(e.cellAspect=u);let c=Z(this.getAttribute("directional-intensity"));c!==void 0&&(e.directionalLight={direction:[.5,.7,.5],intensity:c});let h=Z(this.getAttribute("ambient-intensity"));return h!==void 0&&(e.ambientLight={intensity:h}),this.hasAttribute("auto-size")&&(e.autoSize=!0),e}_findCameraAncestor(){let e=this.parentElement;for(;e;){let o=e.tagName.toLowerCase();if(o==="glyph-perspective-camera"||o==="glyph-orthographic-camera"||o==="glyph-camera")return e;e=e.parentElement}return null}_initScene(e){let o=typeof e.getCamera=="function"?e.getCamera():void 0,r=this._readOptions();o&&(r.camera=o),this._scene=Ee(this,r),this.dispatchEvent(new CustomEvent("glyphcss:scene-ready",{bubbles:!1}))}connectedCallback(){if(this._scene)return;let e=this._findCameraAncestor();if(!e)throw new Error("glyphcss: <glyph-scene> must be placed inside a <glyph-camera>, <glyph-perspective-camera>, or <glyph-orthographic-camera>.");if((typeof e.getCamera=="function"?e.getCamera():null)!==null)this._initScene(e);else{let r=()=>{e.removeEventListener("glyph:camera-ready",r),this._scene||this._initScene(e)};e.addEventListener("glyph:camera-ready",r)}}rerender(){this._scene?.rerender()}disconnectedCallback(){this._scene&&(this._scene.destroy(),this._scene=null)}attributeChangedCallback(e,o,r){o!==r&&this._scene&&this._scene.setOptions(this._readOptions())}};import{loadMesh as Lt,resolveGeometry as St,computeSceneBbox as wt}from"@glyphcss/core";var _t=typeof HTMLElement<"u"?HTMLElement:class{},Ht=["src","geometry","size","color","position","scale","rotation","normalize"];function Tt(n){let t=wt(n),e=(t.min[0]+t.max[0])/2,o=(t.min[1]+t.max[1])/2,r=(t.min[2]+t.max[2])/2,i=2/(Math.max(t.max[0]-t.min[0],t.max[1]-t.min[1],t.max[2]-t.min[2])||1);return n.map(a=>({...a,vertices:a.vertices.map(u=>[(u[0]-e)*i,(u[1]-o)*i,(u[2]-r)*i])}))}function xe(n){if(!n)return;let t=n.split(",").map(e=>parseFloat(e.trim()));if(!(t.length!==3||t.some(e=>!Number.isFinite(e))))return[t[0],t[1],t[2]]}function zt(n){if(n){if(!n.includes(",")){let t=parseFloat(n);return Number.isFinite(t)?t:void 0}return xe(n)}}function Pt(n){return n.closest("glyph-scene")??null}var Ae=class extends _t{constructor(){super(...arguments);this._handle=null;this._loadToken=0}static get observedAttributes(){return[...Ht]}getMeshHandle(){return this._handle}connectedCallback(){this._maybeLoad()}disconnectedCallback(){this._tearDown()}attributeChangedCallback(e,o,r){if(o!==r){if(e==="src"||e==="geometry"||e==="size"||e==="color"){this._tearDown(),this._maybeLoad();return}this._handle&&this._handle.setTransform(this._readTransform())}}_readTransform(){return{position:xe(this.getAttribute("position")),scale:zt(this.getAttribute("scale")),rotation:xe(this.getAttribute("rotation"))}}_tearDown(){if(this._loadToken+=1,this._handle){try{this._handle.dispose()}catch{}this._handle=null}}async _maybeLoad(){let e=this.getAttribute("src"),o=this.getAttribute("geometry"),r=Pt(this);if(r){if(!r.getScene()){let s=()=>{r.removeEventListener("glyphcss:scene-ready",s),this._maybeLoad()};r.addEventListener("glyphcss:scene-ready",s);return}if(e){let s=++this._loadToken,i;try{i=await Lt(e)}catch(h){this.dispatchEvent(new CustomEvent("glyphcss:error",{detail:h,bubbles:!0}));return}if(s!==this._loadToken){try{i.dispose()}catch{}return}let a=r.getScene();if(!a){try{i.dispose()}catch{}return}let c=this.hasAttribute("normalize")?Tt(i.polygons):i.polygons;this._handle=a.add(c,this._readTransform()),this.dispatchEvent(new CustomEvent("glyphcss:loaded",{detail:{polygons:c},bubbles:!0}));return}if(o){let s=r.getScene();if(!s)return;let i=this.getAttribute("size"),a=i!==null?parseFloat(i):1,u=this.getAttribute("color")??void 0,c;try{c=St(o,{size:Number.isFinite(a)?a:1,color:u})}catch(h){this.dispatchEvent(new CustomEvent("glyphcss:error",{detail:h,bubbles:!0}));return}this._handle=s.add(c,this._readTransform()),this.dispatchEvent(new CustomEvent("glyphcss:loaded",{detail:{polygons:c},bubbles:!0}))}}}};var Ot=typeof HTMLElement<"u"?HTMLElement:class{};function kt(n){if(!n)return;let t=n.split(",").map(e=>parseFloat(e.trim()));if(!(t.length!==3||t.some(e=>!Number.isFinite(e))))return[t[0],t[1],t[2]]}function Rt(n){if(!n)return;let t=n.split(",").map(e=>parseFloat(e.trim()));if(!(t.length!==2||t.some(e=>!Number.isFinite(e))))return[t[0],t[1]]}function It(n){return n.closest("glyph-scene")??null}var Le=class extends Ot{constructor(){super(...arguments);this._handle=null}static get observedAttributes(){return["at","size","hotspot-id"]}connectedCallback(){this._register()}disconnectedCallback(){this._handle&&this._unregister()}attributeChangedCallback(e,o,r){o!==r&&(this._handle&&this._unregister(),this._register())}_unregister(){if(!this._handle)return;let e=this._handle.el;for(;e.firstChild;)this.appendChild(e.firstChild);this._handle.remove(),this._handle=null}_register(){let e=kt(this.getAttribute("at"));if(!e)return;let o=It(this);if(!o)return;if(!o.getScene()){let u=()=>{o.removeEventListener("glyphcss:scene-ready",u),this._register()};o.addEventListener("glyphcss:scene-ready",u);return}let r=o.getScene();if(!r)return;let s=this.getAttribute("hotspot-id")??this.getAttribute("id")??String(Math.random()),i=Rt(this.getAttribute("size"));this._handle=r.addHotspot({id:s,at:e,size:i},()=>this.dispatchEvent(new CustomEvent("glyphcss:hotspot-click",{detail:{id:s},bubbles:!0})));let a=this._handle.el;for(;this.firstChild;)a.appendChild(this.firstChild)}};var Ft=typeof HTMLElement<"u"?HTMLElement:class{};function R(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}var Se=class extends Ft{constructor(){super(...arguments);this._camera=null}static get observedAttributes(){return["rot-x","rot-y","distance","zoom","stretch"]}getCamera(){return this._camera}connectedCallback(){this._camera=K({rotX:R(this.getAttribute("rot-x")),rotY:R(this.getAttribute("rot-y")),distance:R(this.getAttribute("distance")),zoom:R(this.getAttribute("zoom")),stretch:R(this.getAttribute("stretch"))}),this.dispatchEvent(new CustomEvent("glyph:camera-ready",{bubbles:!1}))}disconnectedCallback(){this._camera=null}attributeChangedCallback(e,o,r){if(o===r)return;let s=this._camera;if(!s)return;let i=R(this.getAttribute("rot-x")),a=R(this.getAttribute("rot-y")),u=R(this.getAttribute("distance")),c=R(this.getAttribute("zoom")),h=R(this.getAttribute("stretch")),d=!1;i!==void 0&&s.rotX!==i&&(s.rotX=i,d=!0),a!==void 0&&s.rotY!==a&&(s.rotY=a,d=!0),u!==void 0&&s.distance!==u&&(s.distance=u,d=!0),c!==void 0&&s.zoom!==c&&(s.zoom=c,d=!0),h!==void 0&&s.stretch!==h&&(s.stretch=h,d=!0),d&&this.querySelector("glyph-scene")?.rerender?.()}};var Yt=typeof HTMLElement<"u"?HTMLElement:class{};function W(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}var we=class extends Yt{constructor(){super(...arguments);this._camera=null}static get observedAttributes(){return["rot-x","rot-y","zoom"]}getCamera(){return this._camera}connectedCallback(){this._camera=ee({rotX:W(this.getAttribute("rot-x")),rotY:W(this.getAttribute("rot-y")),zoom:W(this.getAttribute("zoom"))}),this.dispatchEvent(new CustomEvent("glyph:camera-ready",{bubbles:!1}))}disconnectedCallback(){this._camera=null}attributeChangedCallback(e,o,r){if(o===r)return;let s=this._camera;if(!s)return;let i=W(this.getAttribute("rot-x")),a=W(this.getAttribute("rot-y")),u=W(this.getAttribute("zoom")),c=!1;i!==void 0&&s.rotX!==i&&(s.rotX=i,c=!0),a!==void 0&&s.rotY!==a&&(s.rotY=a,c=!0),u!==void 0&&s.zoom!==u&&(s.zoom=u,c=!0),c&&this.querySelector("glyph-scene")?.rerender?.()}};var Dt=typeof HTMLElement<"u"?HTMLElement:class{};function Nt(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function _e(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}function Xt(n){return n.closest("glyph-scene")??null}var He=class extends Dt{constructor(){super(...arguments);this._controls=null}static get observedAttributes(){return["drag","wheel","invert","animate-speed","animate-axis"]}connectedCallback(){this._attach()}disconnectedCallback(){this._controls&&(this._controls.destroy(),this._controls=null)}attributeChangedCallback(e,o,r){o!==r&&this._controls?.update(this._readOptions())}_readOptions(){let e=_e(this.getAttribute("drag")),o=_e(this.getAttribute("wheel")),r=_e(this.getAttribute("invert")),s=Nt(this.getAttribute("animate-speed")),i=this.getAttribute("animate-axis")==="x"?"x":"y";return{...e!==void 0?{drag:e}:{},...o!==void 0?{wheel:o}:{},...r!==void 0?{invert:r}:{},...s!==void 0?{animate:{speed:s,axis:i}}:{}}}_attach(){if(this._controls)return;let e=Xt(this);if(!e)return;let o=e.getScene();if(!o){let r=()=>{e.removeEventListener("glyphcss:scene-ready",r),this._attach()};e.addEventListener("glyphcss:scene-ready",r);return}this._controls=Ge(o,this._readOptions())}};var Vt=typeof HTMLElement<"u"?HTMLElement:class{};function Te(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}function Bt(n){return n.closest("glyph-scene")??null}var ze=class extends Vt{constructor(){super(...arguments);this._controls=null}static get observedAttributes(){return["drag","wheel","invert"]}connectedCallback(){this._attach()}disconnectedCallback(){this._controls&&(this._controls.destroy(),this._controls=null)}attributeChangedCallback(e,o,r){o!==r&&this._controls?.update(this._readOptions())}_readOptions(){let e=Te(this.getAttribute("drag")),o=Te(this.getAttribute("wheel")),r=Te(this.getAttribute("invert"));return{...e!==void 0?{drag:e}:{},...o!==void 0?{wheel:o}:{},...r!==void 0?{invert:r}:{}}}_attach(){if(this._controls)return;let e=Bt(this);if(!e)return;let o=e.getScene();if(!o){let r=()=>{e.removeEventListener("glyphcss:scene-ready",r),this._attach()};e.addEventListener("glyphcss:scene-ready",r);return}this._controls=Me(o,this._readOptions())}};export*from"@glyphcss/core";export{it as DEFAULT_RAMP,Le as GlyphHotspotElement,ze as GlyphMapControlsElement,Ae as GlyphMeshElement,He as GlyphOrbitControlsElement,we as GlyphOrthographicCameraElement,Se as GlyphPerspectiveCameraElement,Ce as GlyphSceneElement,st as SOLID_RAMP,lt as WIREFRAME_GLYPHS,te as WIREFRAME_PALETTES,ht as bakeFrames,fe as buildRasterizeContext,tt as createGlyphCamera,vt as createGlyphFirstPersonControls,Me as createGlyphMapControls,Ge as createGlyphOrbitControls,ee as createGlyphOrthographicCamera,K as createGlyphPerspectiveCamera,Ee as createGlyphScene,Et as findGlyphMeshHandle,Gt as findMeshUnderPoint,ne as getWireframeGlyphs,be as injectGlyphBaseStyles,Ve as pointInMeshElement,ve as projectHotspots,re as rasterize};
62
+ `;function Ne(t,n,e,o,r){return t.map(s=>{let[l,i,u]=n.project(s.at,e,o,r),d=u>-3&&l>=0&&l<e&&i>=0&&i<o;return{id:s.id,col:l,row:i,depth:u,visible:d}})}var jt=1;function qt(t,n){let{position:e,scale:o,rotation:r}=n;if(!e&&!o&&!r)return t;let[s,l,i]=e??[0,0,0],u=1,d=1,h=1;o!==void 0&&(typeof o=="number"?u=d=h=o:[u,d,h]=o);let c=Math.PI/180,[f,g,y]=r??[0,0,0],w=f*c,M=g*c,_=y*c,G=Math.cos(w),P=Math.sin(w),v=Math.cos(M),E=Math.sin(M),L=Math.cos(_),a=Math.sin(_);function m(b){let C=b[0]*u,p=b[1]*d,x=b[2]*h,S=L*C-a*p,T=a*C+L*p,H=x;return C=v*S+E*H,p=T,x=-E*S+v*H,S=C,T=G*p-P*x,H=P*p+G*x,[S+s,T+l,H+i]}return t.map(b=>({...b,vertices:b.vertices.map(m)}))}function Ve(t,n={}){Xe(t.ownerDocument??void 0);let e={mode:n.mode??"solid",glyphPalette:n.glyphPalette??"default",useColors:n.useColors??!0,cols:n.cols??80,rows:n.rows??24,cellAspect:n.cellAspect??2,directionalLight:n.directionalLight??{direction:[-.5,-.7,-.5],intensity:1},ambientLight:n.ambientLight??{intensity:.4},camera:n.camera??ve(),smoothShading:n.smoothShading??!1,creaseAngle:n.creaseAngle??60,autoSize:n.autoSize??!1,shadow:n.shadow},o=t.ownerDocument.createElement("div");o.className="glyph-scene";let r=t.ownerDocument.createElement("pre");r.className="glyph-output";let s=t.ownerDocument.createElement("div");s.className="glyph-hotspot-layer",o.appendChild(r),o.appendChild(s),t.appendChild(o);let l=new Map,i=[],u=!1,d={iA:[],iB:[],iC:[],lit:[]};function h(){d.iA.length=0,d.iB.length=0,d.iC.length=0,d.lit.length=0}function c(){u||(u=!0,Promise.resolve().then(()=>{u=!1,f()}))}function f(){let a=[],m=[],b=[];for(let H of l.values()){let I=qt(H.polygons,H.transform),R=H.transform.castShadow??!1,q=H.transform.receiveShadow??!1;for(let z of I)a.push(z),m.push(R),b.push(q)}let C=Be({camera:e.camera,grid:{cols:e.cols,rows:e.rows,cellAspect:e.cellAspect},polygons:a,mode:e.mode,directionalLight:e.directionalLight,ambientLight:e.ambientLight,glyphPalette:e.glyphPalette,useColors:e.useColors,smoothShading:e.smoothShading,creaseAngle:e.creaseAngle,shadow:e.shadow,castShadowFlags:m,receiveShadowFlags:b});C.shadeCache=d;let p=globalThis.__glyphPerf,x=p?performance.now():0,S=Ge(C),T=p?performance.now():0;if(e.useColors?r.innerHTML=S:r.textContent=S,p){let H=performance.now();(p.raster??(p.raster=[])).push(T-x),(p.dom??(p.dom=[])).push(H-T),(p.polys??(p.polys=[])).push(a.length)}g()}function g(){let{cols:a,rows:m,cellAspect:b,camera:C}=e,p=Ne(i.map(H=>H.hotspot),C,a,m,b),x=r.getBoundingClientRect(),S=a>0?x.width/a:8,T=m>0?x.height/m:16;for(let H=0;H<i.length;H++){let{el:I}=i[H],R=p[H];R.visible?(I.style.display="",I.style.left=`${(R.col+.5)*S}px`,I.style.top=`${(R.row+.5)*T}px`,I.style.zIndex=String(Math.round(R.depth*1e3))):I.style.display="none"}}function y(a,m={}){let b=jt++;return l.set(b,{id:b,polygons:a,transform:m}),h(),c(),{get id(){return b},get name(){return l.get(b)?.transform.id},get polygons(){return a},setTransform(C){let p=l.get(b);p&&(p.transform=C,h(),c())},dispose(){l.delete(b),h(),c()}}}function w(a,m){let b=t.ownerDocument.createElement("div");b.className="glyph-hotspot",b.setAttribute("data-hotspot-id",a.id);let[C,p]=a.size??[1,1];b.style.position="absolute",b.style.width=`${C}ch`,b.style.height=`${p*e.cellAspect}ch`,m&&b.addEventListener("click",m),s.appendChild(b);let x={hotspot:{id:a.id,at:a.at,size:a.size},el:b,onClick:m};return i.push(x),c(),{get el(){return b},remove(){let S=i.indexOf(x);S>=0&&i.splice(S,1),m&&b.removeEventListener("click",m),s.removeChild(b),c()}}}function M(){f()}function _(a){a.mode!==void 0&&(e.mode=a.mode),a.glyphPalette!==void 0&&(e.glyphPalette=a.glyphPalette),a.useColors!==void 0&&(e.useColors=a.useColors),a.cols!==void 0&&(e.cols=a.cols),a.rows!==void 0&&(e.rows=a.rows),a.cellAspect!==void 0&&(e.cellAspect=a.cellAspect),a.directionalLight!==void 0&&(e.directionalLight=a.directionalLight),a.ambientLight!==void 0&&(e.ambientLight=a.ambientLight),a.camera!==void 0&&(e.camera=a.camera),a.smoothShading!==void 0&&(e.smoothShading=a.smoothShading),a.creaseAngle!==void 0&&(e.creaseAngle=a.creaseAngle),"shadow"in a&&(e.shadow=a.shadow),a.autoSize!==void 0&&(e.autoSize=a.autoSize,e.autoSize&&!E&&typeof ResizeObserver<"u"?(E=new ResizeObserver(()=>v()),E.observe(t),v()):!e.autoSize&&E&&(E.disconnect(),E=null)),(a.mode!==void 0||a.useColors!==void 0||a.directionalLight!==void 0||a.ambientLight!==void 0||a.smoothShading!==void 0||a.creaseAngle!==void 0||a.glyphPalette!==void 0)&&h(),c()}function G(){return{...e}}function P(){let m=t.ownerDocument.createElement("span");m.textContent=Array(20).fill("M").join(`
63
+ `),m.style.cssText="position:absolute;visibility:hidden;font-family:inherit;font-size:inherit;line-height:inherit;white-space:pre;padding:0;margin:0",r.appendChild(m);let b=m.getBoundingClientRect();return m.remove(),{w:b.width||8,h:b.height?b.height/20:16}}function v(){let a=t.clientWidth,m=t.clientHeight;if(!a||!m)return;let b=P(),C=Math.max(20,Math.floor(a/b.w)),p=Math.max(8,Math.floor(m/b.h)),x=b.h/b.w,S=!1;e.cols!==C&&(e.cols=C,S=!0),e.rows!==p&&(e.rows=p,S=!0),Math.abs(e.cellAspect-x)>.01&&(e.cellAspect=x,S=!0),S&&c()}let E=null;e.autoSize&&typeof ResizeObserver<"u"&&(E=new ResizeObserver(()=>v()),E.observe(t),v());function L(){E&&(E.disconnect(),E=null),l.clear(),t.contains(o)&&t.removeChild(o)}return c(),{get host(){return t},get output(){return r},get camera(){return e.camera},add:y,addHotspot:w,rerender:M,setOptions:_,getOptions:G,fit:v,destroy:L}}function $e(t,n={}){let e=t.host,o=n.drag??!0,r=n.wheel??!0,s=ht(n.invert),l=n.clampPitch??!0,i=n.animate??!1,u=!1,d=!1,h=null,c=null,f=null,g={x:0,y:0},y=t.camera;function w(m){if(!(!o||u)&&f===null&&m.isPrimary!==!1){m.preventDefault(),f=m.pointerId,g={x:m.clientX,y:m.clientY},e.style.cursor="grabbing";try{m.target.setPointerCapture(m.pointerId)}catch{}i&&i.pauseOnInteraction!==!1&&(d=!0)}}function M(m){if(f===null||m.pointerId!==f||!o||u)return;m.preventDefault();let b=m.clientX-g.x,C=m.clientY-g.y;g={x:m.clientX,y:m.clientY};let p=s,x=1/4;y.rotY=y.rotY-b*x*p;let S=y.rotX-C*x*p;y.rotX=l?Math.max(-90,Math.min(90,S)):S,t.rerender()}function _(m){if(f===m.pointerId){f=null,e.style.cursor=o&&!u?"grab":"";try{m.target.releasePointerCapture(m.pointerId)}catch{}i&&(d=!1)}}function G(m){if(!r||u)return;m.preventDefault();let b=m.deltaY*.001;y.zoom=Math.max(.1,Math.min(500,y.zoom*(1-b))),t.rerender()}function P(m){if(!(u||!i)){if(!d){let b=c!==null?Math.min(m-c,50):16.67,C=typeof i=="object"&&i.speed?i.speed:.3,p=typeof i=="object"&&i.axis?i.axis:"y",x=C*(b/16.67);p==="y"?y.rotY=y.rotY+x:y.rotX=y.rotX+x,t.rerender()}c=m,h=requestAnimationFrame(P)}}function v(){h===null&&typeof requestAnimationFrame<"u"&&i&&(h=requestAnimationFrame(P))}function E(){h!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(h),h=null),c=null}function L(){e.addEventListener("pointerdown",w),e.addEventListener("pointermove",M),e.addEventListener("pointerup",_),e.addEventListener("pointercancel",_),e.addEventListener("wheel",G,{passive:!1}),e.style.cursor=o?"grab":"",e.style.touchAction="none",e.style.userSelect="none"}function a(){e.removeEventListener("pointerdown",w),e.removeEventListener("pointermove",M),e.removeEventListener("pointerup",_),e.removeEventListener("pointercancel",_),e.removeEventListener("wheel",G),e.style.cursor="",e.style.touchAction="",e.style.userSelect=""}return L(),v(),{update(m){let b=!!i;o=m.drag??o,r=m.wheel??r,s=ht(m.invert),m.clampPitch!==void 0&&(l=m.clampPitch),i=m.animate??i,!u&&f===null&&(e.style.cursor=o?"grab":"");let C=!!i;b&&!C?E():!b&&C&&v()},pause(){u||(u=!0,a(),E(),f=null,d=!1)},resume(){u&&(u=!1,L(),v())},destroy(){u||a(),E(),u=!0}}}function ht(t){return t===void 0||t===!1?1:t===!0?-1:t}function We(t,n={}){let e=t.host,o=n.drag??!0,r=n.wheel??!0,s=pt(n.invert),l=n.animate??!1,i=!1,u=!1,d=null,h=null,c=null,f={x:0,y:0},g=!1,y=t.camera,w=1/4,M=.02;function _(p){if(!(!o||i)&&c===null&&p.isPrimary!==!1){p.preventDefault(),c=p.pointerId,f={x:p.clientX,y:p.clientY},g=p.button===2,e.style.cursor="grabbing";try{p.target.setPointerCapture(p.pointerId)}catch{}l&&l.pauseOnInteraction!==!1&&(u=!0)}}function G(p){if(c===null||p.pointerId!==c||!o||i)return;p.preventDefault();let x=p.clientX-f.x,S=p.clientY-f.y;f={x:p.clientX,y:p.clientY};let T=s;if(g||p.shiftKey)y.rotY=y.rotY-x*w*T,y.rotX=Math.max(-90,Math.min(90,y.rotX+S*w*T));else{let H=y.target;y.target=[H[0]-x*M/y.zoom,H[1]-S*M/y.zoom,H[2]]}t.rerender()}function P(p){if(c===p.pointerId){c=null,g=!1,e.style.cursor=o&&!i?"grab":"";try{p.target.releasePointerCapture(p.pointerId)}catch{}l&&(u=!1)}}function v(p){p.preventDefault()}function E(p){if(!r||i)return;p.preventDefault();let x=p.deltaY*.001;y.zoom=Math.max(.1,Math.min(500,y.zoom*(1-x))),t.rerender()}function L(p){if(!(i||!l)){if(!u){let x=h!==null?Math.min(p-h,50):16.67,S=typeof l=="object"&&l.speed?l.speed:.3,T=typeof l=="object"&&l.axis?l.axis:"y",H=S*(x/16.67);T==="y"?y.rotY=y.rotY+H:y.rotX=y.rotX+H,t.rerender()}h=p,d=requestAnimationFrame(L)}}function a(){d===null&&typeof requestAnimationFrame<"u"&&l&&(d=requestAnimationFrame(L))}function m(){d!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(d),d=null),h=null}function b(){e.addEventListener("pointerdown",_),e.addEventListener("pointermove",G),e.addEventListener("pointerup",P),e.addEventListener("pointercancel",P),e.addEventListener("contextmenu",v),e.addEventListener("wheel",E,{passive:!1}),e.style.cursor=o?"grab":"",e.style.touchAction="none",e.style.userSelect="none"}function C(){e.removeEventListener("pointerdown",_),e.removeEventListener("pointermove",G),e.removeEventListener("pointerup",P),e.removeEventListener("pointercancel",P),e.removeEventListener("contextmenu",v),e.removeEventListener("wheel",E),e.style.cursor="",e.style.touchAction="",e.style.userSelect=""}return b(),a(),{update(p){let x=!!l;o=p.drag??o,r=p.wheel??r,s=pt(p.invert),l=p.animate??l,!i&&c===null&&(e.style.cursor=o?"grab":"");let S=!!l;x&&!S?m():!x&&S&&a()},pause(){i||(i=!0,C(),m(),c=null,u=!1)},resume(){i&&(i=!1,b(),a())},destroy(){i||C(),m(),i=!0}}}function pt(t){return t===void 0||t===!1?1:t===!0?-1:t}function Ut(t,n={}){if(t.camera.kind!=="perspective")throw new Error("glyphcss: GlyphFirstPersonControls requires a perspective camera. Use <GlyphPerspectiveCamera> (not <GlyphOrthographicCamera> / <GlyphCamera>).");t.camera.eyeMode=!0;let e=t.host,o=n.drag??!0,r=n.keyboard??!0,s=n.moveSpeed??.05,l=n.lookSpeed??.15,i=mt(n.invert),u=!1,d=null,h={x:0,y:0},c=new Set,f=null,g=t.camera;function y(a){if(!(!o||u)&&d===null){a.preventDefault(),d=a.pointerId,h={x:a.clientX,y:a.clientY};try{a.target.setPointerCapture(a.pointerId)}catch{}}}function w(a){if(d===null||a.pointerId!==d||!o||u)return;a.preventDefault();let m=a.clientX-h.x,b=a.clientY-h.y;h={x:a.clientX,y:a.clientY},g.rotY=g.rotY-m*l*i,g.rotX=Math.max(-90,Math.min(90,g.rotX+b*l*i)),t.rerender()}function M(a){if(d===a.pointerId){d=null;try{a.target.releasePointerCapture(a.pointerId)}catch{}}}function _(a){r&&!u&&c.add(a.key.toLowerCase())}function G(a){c.delete(a.key.toLowerCase())}function P(){if(u||!r||c.size===0)return;let a=g.target,m=g.rotY*Math.PI/180,b=Math.cos(m),C=Math.sin(m),p=!1;(c.has("w")||c.has("arrowup"))&&(g.target=[a[0]-C*s,a[1]-b*s,a[2]],p=!0),(c.has("s")||c.has("arrowdown"))&&(g.target=[a[0]+C*s,a[1]+b*s,a[2]],p=!0),(c.has("a")||c.has("arrowleft"))&&(g.target=[a[0]-b*s,a[1]+C*s,a[2]],p=!0),(c.has("d")||c.has("arrowright"))&&(g.target=[a[0]+b*s,a[1]-C*s,a[2]],p=!0),p&&t.rerender()}function v(){u||(P(),f=requestAnimationFrame(v))}function E(){e.addEventListener("pointerdown",y),e.addEventListener("pointermove",w),e.addEventListener("pointerup",M),e.addEventListener("pointercancel",M),r&&(e.ownerDocument?.addEventListener("keydown",_),e.ownerDocument?.addEventListener("keyup",G)),e.style.touchAction="none",e.style.userSelect="none",typeof requestAnimationFrame<"u"&&(f=requestAnimationFrame(v))}function L(){e.removeEventListener("pointerdown",y),e.removeEventListener("pointermove",w),e.removeEventListener("pointerup",M),e.removeEventListener("pointercancel",M),e.ownerDocument?.removeEventListener("keydown",_),e.ownerDocument?.removeEventListener("keyup",G),e.style.touchAction="",e.style.userSelect="",f!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(f),f=null),c.clear(),t.camera.eyeMode=!1}return E(),{update(a){o=a.drag??o,r=a.keyboard??r,s=a.moveSpeed??s,l=a.lookSpeed??l,i=mt(a.invert)},pause(){u||(u=!0,L(),d=null)},resume(){u&&(u=!1,E())},destroy(){u||L(),u=!0}}}function mt(t){return t===void 0||t===!1?1:t===!0?-1:t}function Kt(t,n){let e=t.querySelector(`[data-glyph-mesh-id="${CSS.escape(n)}"]`);return e instanceof HTMLElement?e:null}function ft(t,n,e){let o=t.getBoundingClientRect();return o.width<=0||o.height<=0?!1:n>=o.left&&n<=o.right&&e>=o.top&&e<=o.bottom}function Zt(t,n,e){let o=(t instanceof Document,t),r=Array.from(o.querySelectorAll(".glyph-mesh"));for(let s of r)if(ft(s,n,e))return s;return null}var Jt=typeof HTMLElement<"u"?HTMLElement:class{},Qt=["mode","glyph-palette","use-colors","cols","rows","cell-aspect","directional-direction","directional-intensity","ambient-intensity","auto-size","shadow","shadow-color","shadow-opacity","shadow-lift","shadow-max-extend"];function te(t){if(t==null)return;let n=parseFloat(t);return Number.isFinite(n)?n:void 0}function en(t){if(t==="wireframe"||t==="solid"||t==="voxel")return t}function tn(t){if(t!==null){if(t==="false")return!1;if(t==="true"||t==="")return!0}}var je=class extends Jt{constructor(){super(...arguments);this._scene=null}static get observedAttributes(){return[...Qt]}getScene(){return this._scene}_readOptions(){let e={},o=en(this.getAttribute("mode"));o!==void 0&&(e.mode=o);let r=this.getAttribute("glyph-palette");r&&(e.glyphPalette=r);let s=tn(this.getAttribute("use-colors"));s!==void 0&&(e.useColors=s);let l=te(this.getAttribute("cols"));l!==void 0&&(e.cols=l);let i=te(this.getAttribute("rows"));i!==void 0&&(e.rows=i);let u=te(this.getAttribute("cell-aspect"));u!==void 0&&(e.cellAspect=u);let d=te(this.getAttribute("directional-intensity"));d!==void 0&&(e.directionalLight={direction:[-.5,-.7,-.5],intensity:d});let h=te(this.getAttribute("ambient-intensity"));if(h!==void 0&&(e.ambientLight={intensity:h}),this.hasAttribute("auto-size")&&(e.autoSize=!0),this.hasAttribute("shadow")){let c={color:"#000000",opacity:.25,lift:.05,maxExtend:2e3},f=this.getAttribute("shadow-color");f&&(c.color=f);let g=te(this.getAttribute("shadow-opacity"));g!==void 0&&(c.opacity=g);let y=te(this.getAttribute("shadow-lift"));y!==void 0&&(c.lift=y);let w=te(this.getAttribute("shadow-max-extend"));w!==void 0&&(c.maxExtend=w),e.shadow=c}return e}_findCameraAncestor(){let e=this.parentElement;for(;e;){let o=e.tagName.toLowerCase();if(o==="glyph-perspective-camera"||o==="glyph-orthographic-camera"||o==="glyph-camera")return e;e=e.parentElement}return null}_initScene(e){let o=typeof e.getCamera=="function"?e.getCamera():void 0,r=this._readOptions();o&&(r.camera=o),this._scene=Ve(this,r),this.dispatchEvent(new CustomEvent("glyphcss:scene-ready",{bubbles:!1}))}connectedCallback(){if(this._scene)return;let e=this._findCameraAncestor();if(!e)throw new Error("glyphcss: <glyph-scene> must be placed inside a <glyph-camera>, <glyph-perspective-camera>, or <glyph-orthographic-camera>.");if((typeof e.getCamera=="function"?e.getCamera():null)!==null)this._initScene(e);else{let r=()=>{e.removeEventListener("glyph:camera-ready",r),this._scene||this._initScene(e)};e.addEventListener("glyph:camera-ready",r)}}rerender(){this._scene?.rerender()}disconnectedCallback(){this._scene&&(this._scene.destroy(),this._scene=null)}attributeChangedCallback(e,o,r){o!==r&&this._scene&&this._scene.setOptions(this._readOptions())}};import{loadMesh as nn,resolveGeometry as rn,computeSceneBbox as on}from"@glyphcss/core";var sn=typeof HTMLElement<"u"?HTMLElement:class{},ln=["src","geometry","size","color","position","scale","rotation","normalize","cast-shadow","receive-shadow"];function an(t){let n=on(t),e=(n.min[0]+n.max[0])/2,o=(n.min[1]+n.max[1])/2,r=(n.min[2]+n.max[2])/2,l=2/(Math.max(n.max[0]-n.min[0],n.max[1]-n.min[1],n.max[2]-n.min[2])||1);return t.map(i=>({...i,vertices:i.vertices.map(u=>[(u[0]-e)*l,(u[1]-o)*l,(u[2]-r)*l])}))}function qe(t){if(!t)return;let n=t.split(",").map(e=>parseFloat(e.trim()));if(!(n.length!==3||n.some(e=>!Number.isFinite(e))))return[n[0],n[1],n[2]]}function cn(t){if(t){if(!t.includes(",")){let n=parseFloat(t);return Number.isFinite(n)?n:void 0}return qe(t)}}function un(t){return t.closest("glyph-scene")??null}var Ue=class extends sn{constructor(){super(...arguments);this._handle=null;this._loadToken=0}static get observedAttributes(){return[...ln]}getMeshHandle(){return this._handle}connectedCallback(){this._maybeLoad()}disconnectedCallback(){this._tearDown()}attributeChangedCallback(e,o,r){if(o!==r){if(e==="src"||e==="geometry"||e==="size"||e==="color"){this._tearDown(),this._maybeLoad();return}this._handle&&this._handle.setTransform(this._readTransform())}}_readTransform(){return{position:qe(this.getAttribute("position")),scale:cn(this.getAttribute("scale")),rotation:qe(this.getAttribute("rotation")),castShadow:this.hasAttribute("cast-shadow"),receiveShadow:this.hasAttribute("receive-shadow")}}_tearDown(){if(this._loadToken+=1,this._handle){try{this._handle.dispose()}catch{}this._handle=null}}async _maybeLoad(){let e=this.getAttribute("src"),o=this.getAttribute("geometry"),r=un(this);if(r){if(!r.getScene()){let s=()=>{r.removeEventListener("glyphcss:scene-ready",s),this._maybeLoad()};r.addEventListener("glyphcss:scene-ready",s);return}if(e){let s=++this._loadToken,l;try{l=await nn(e)}catch(h){this.dispatchEvent(new CustomEvent("glyphcss:error",{detail:h,bubbles:!0}));return}if(s!==this._loadToken){try{l.dispose()}catch{}return}let i=r.getScene();if(!i){try{l.dispose()}catch{}return}let d=this.hasAttribute("normalize")?an(l.polygons):l.polygons;this._handle=i.add(d,this._readTransform()),this.dispatchEvent(new CustomEvent("glyphcss:loaded",{detail:{polygons:d},bubbles:!0}));return}if(o){let s=r.getScene();if(!s)return;let l=this.getAttribute("size"),i=l!==null?parseFloat(l):1,u=this.getAttribute("color")??void 0,d;try{d=rn(o,{size:Number.isFinite(i)?i:1,color:u})}catch(h){this.dispatchEvent(new CustomEvent("glyphcss:error",{detail:h,bubbles:!0}));return}this._handle=s.add(d,this._readTransform()),this.dispatchEvent(new CustomEvent("glyphcss:loaded",{detail:{polygons:d},bubbles:!0}))}}}};var dn=typeof HTMLElement<"u"?HTMLElement:class{};function hn(t){if(!t)return;let n=t.split(",").map(e=>parseFloat(e.trim()));if(!(n.length!==3||n.some(e=>!Number.isFinite(e))))return[n[0],n[1],n[2]]}function pn(t){if(!t)return;let n=t.split(",").map(e=>parseFloat(e.trim()));if(!(n.length!==2||n.some(e=>!Number.isFinite(e))))return[n[0],n[1]]}function mn(t){return t.closest("glyph-scene")??null}var Ke=class extends dn{constructor(){super(...arguments);this._handle=null}static get observedAttributes(){return["at","size","hotspot-id"]}connectedCallback(){this._register()}disconnectedCallback(){this._handle&&this._unregister()}attributeChangedCallback(e,o,r){o!==r&&(this._handle&&this._unregister(),this._register())}_unregister(){if(!this._handle)return;let e=this._handle.el;for(;e.firstChild;)this.appendChild(e.firstChild);this._handle.remove(),this._handle=null}_register(){let e=hn(this.getAttribute("at"));if(!e)return;let o=mn(this);if(!o)return;if(!o.getScene()){let u=()=>{o.removeEventListener("glyphcss:scene-ready",u),this._register()};o.addEventListener("glyphcss:scene-ready",u);return}let r=o.getScene();if(!r)return;let s=this.getAttribute("hotspot-id")??this.getAttribute("id")??String(Math.random()),l=pn(this.getAttribute("size"));this._handle=r.addHotspot({id:s,at:e,size:l},()=>this.dispatchEvent(new CustomEvent("glyphcss:hotspot-click",{detail:{id:s},bubbles:!0})));let i=this._handle.el;for(;this.firstChild;)i.appendChild(this.firstChild)}};var fn=typeof HTMLElement<"u"?HTMLElement:class{};function j(t){if(t==null)return;let n=parseFloat(t);return Number.isFinite(n)?n:void 0}var Ze=class extends fn{constructor(){super(...arguments);this._camera=null}static get observedAttributes(){return["rot-x","rot-y","distance","zoom","stretch"]}getCamera(){return this._camera}connectedCallback(){this._camera=ve({rotX:j(this.getAttribute("rot-x")),rotY:j(this.getAttribute("rot-y")),distance:j(this.getAttribute("distance")),zoom:j(this.getAttribute("zoom")),stretch:j(this.getAttribute("stretch"))}),this.dispatchEvent(new CustomEvent("glyph:camera-ready",{bubbles:!1}))}disconnectedCallback(){this._camera=null}attributeChangedCallback(e,o,r){if(o===r)return;let s=this._camera;if(!s)return;let l=j(this.getAttribute("rot-x")),i=j(this.getAttribute("rot-y")),u=j(this.getAttribute("distance")),d=j(this.getAttribute("zoom")),h=j(this.getAttribute("stretch")),c=!1;l!==void 0&&s.rotX!==l&&(s.rotX=l,c=!0),i!==void 0&&s.rotY!==i&&(s.rotY=i,c=!0),u!==void 0&&s.distance!==u&&(s.distance=u,c=!0),d!==void 0&&s.zoom!==d&&(s.zoom=d,c=!0),h!==void 0&&s.stretch!==h&&(s.stretch=h,c=!0),c&&this.querySelector("glyph-scene")?.rerender?.()}};var yn=typeof HTMLElement<"u"?HTMLElement:class{};function pe(t){if(t==null)return;let n=parseFloat(t);return Number.isFinite(n)?n:void 0}var Je=class extends yn{constructor(){super(...arguments);this._camera=null}static get observedAttributes(){return["rot-x","rot-y","zoom"]}getCamera(){return this._camera}connectedCallback(){this._camera=Me({rotX:pe(this.getAttribute("rot-x")),rotY:pe(this.getAttribute("rot-y")),zoom:pe(this.getAttribute("zoom"))}),this.dispatchEvent(new CustomEvent("glyph:camera-ready",{bubbles:!1}))}disconnectedCallback(){this._camera=null}attributeChangedCallback(e,o,r){if(o===r)return;let s=this._camera;if(!s)return;let l=pe(this.getAttribute("rot-x")),i=pe(this.getAttribute("rot-y")),u=pe(this.getAttribute("zoom")),d=!1;l!==void 0&&s.rotX!==l&&(s.rotX=l,d=!0),i!==void 0&&s.rotY!==i&&(s.rotY=i,d=!0),u!==void 0&&s.zoom!==u&&(s.zoom=u,d=!0),d&&this.querySelector("glyph-scene")?.rerender?.()}};var gn=typeof HTMLElement<"u"?HTMLElement:class{};function bn(t){if(t==null)return;let n=parseFloat(t);return Number.isFinite(n)?n:void 0}function Se(t){if(t!==null){if(t==="false")return!1;if(t==="true"||t==="")return!0}}function vn(t){return t.closest("glyph-scene")??null}var Qe=class extends gn{constructor(){super(...arguments);this._controls=null}static get observedAttributes(){return["drag","wheel","invert","clamp-pitch","animate-speed","animate-axis"]}connectedCallback(){this._attach()}disconnectedCallback(){this._controls&&(this._controls.destroy(),this._controls=null)}attributeChangedCallback(e,o,r){o!==r&&this._controls?.update(this._readOptions())}_readOptions(){let e=Se(this.getAttribute("drag")),o=Se(this.getAttribute("wheel")),r=Se(this.getAttribute("invert")),s=Se(this.getAttribute("clamp-pitch")),l=bn(this.getAttribute("animate-speed")),i=this.getAttribute("animate-axis")==="x"?"x":"y";return{...e!==void 0?{drag:e}:{},...o!==void 0?{wheel:o}:{},...r!==void 0?{invert:r}:{},...s!==void 0?{clampPitch:s}:{},...l!==void 0?{animate:{speed:l,axis:i}}:{}}}_attach(){if(this._controls)return;let e=vn(this);if(!e)return;let o=e.getScene();if(!o){let r=()=>{e.removeEventListener("glyphcss:scene-ready",r),this._attach()};e.addEventListener("glyphcss:scene-ready",r);return}this._controls=$e(o,this._readOptions())}};var En=typeof HTMLElement<"u"?HTMLElement:class{};function et(t){if(t!==null){if(t==="false")return!1;if(t==="true"||t==="")return!0}}function wn(t){return t.closest("glyph-scene")??null}var tt=class extends En{constructor(){super(...arguments);this._controls=null}static get observedAttributes(){return["drag","wheel","invert"]}connectedCallback(){this._attach()}disconnectedCallback(){this._controls&&(this._controls.destroy(),this._controls=null)}attributeChangedCallback(e,o,r){o!==r&&this._controls?.update(this._readOptions())}_readOptions(){let e=et(this.getAttribute("drag")),o=et(this.getAttribute("wheel")),r=et(this.getAttribute("invert"));return{...e!==void 0?{drag:e}:{},...o!==void 0?{wheel:o}:{},...r!==void 0?{invert:r}:{}}}_attach(){if(this._controls)return;let e=wn(this);if(!e)return;let o=e.getScene();if(!o){let r=()=>{e.removeEventListener("glyphcss:scene-ready",r),this._attach()};e.addEventListener("glyphcss:scene-ready",r);return}this._controls=We(o,this._readOptions())}};export*from"@glyphcss/core";export{Tt as DEFAULT_RAMP,Ke as GlyphHotspotElement,tt as GlyphMapControlsElement,Ue as GlyphMeshElement,Qe as GlyphOrbitControlsElement,Je as GlyphOrthographicCameraElement,Ze as GlyphPerspectiveCameraElement,je as GlyphSceneElement,zt as SOLID_RAMP,Ot as WIREFRAME_GLYPHS,xe as WIREFRAME_PALETTES,Xt as bakeFrames,Be as buildRasterizeContext,Lt as createGlyphCamera,Ut as createGlyphFirstPersonControls,We as createGlyphMapControls,$e as createGlyphOrbitControls,Me as createGlyphOrthographicCamera,ve as createGlyphPerspectiveCamera,Ve as createGlyphScene,Kt as findGlyphMeshHandle,Zt as findMeshUnderPoint,Ae as getWireframeGlyphs,Xe as injectGlyphBaseStyles,ft as pointInMeshElement,Ne as projectHotspots,Ge as rasterize};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glyphcss",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Glyphcss — ASCII paint backend with glyphcss's scene-composition API. Renders 3D meshes as ASCII art in a <pre> element.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -33,7 +33,7 @@
33
33
  }
34
34
  },
35
35
  "dependencies": {
36
- "@glyphcss/core": "^0.0.3"
36
+ "@glyphcss/core": "^0.0.4"
37
37
  },
38
38
  "devDependencies": {
39
39
  "tsup": "^8.0.1",