@utsp/render 0.14.0-nightly.20251219144833.1c27cfe → 0.14.0

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/gl/index.cjs CHANGED
@@ -1,11 +1,11 @@
1
- "use strict";var U=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var $=Object.prototype.hasOwnProperty;var z=(f,e,t)=>e in f?U(f,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):f[e]=t;var A=(f,e)=>U(f,"name",{value:e,configurable:!0});var X=(f,e)=>{for(var t in e)U(f,t,{get:e[t],enumerable:!0})},q=(f,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of N(e))!$.call(f,i)&&i!==t&&U(f,i,{get:()=>e[i],enumerable:!(r=Y(e,i))||r.enumerable});return f};var j=f=>q(U({},"__esModule",{value:!0}),f);var n=(f,e,t)=>(z(f,typeof e!="symbol"?e+"":e,t),t);var Q={};X(Q,{DEFAULT_PALETTE:()=>M,GridOverlay:()=>I,ScalingMode:()=>p.ScalingMode,TerminalGL:()=>D,colorToPaletteIndex:()=>V,getAtlasColumns:()=>F,getCharGridPosition:()=>_,getMaxCharCode:()=>L,paletteIndexToColor:()=>k});module.exports=j(Q);var P=class P{constructor(e,t){n(this,"canvas");n(this,"ctx");n(this,"container");n(this,"cols",0);n(this,"rows",0);n(this,"cellWidth",0);n(this,"cellHeight",0);n(this,"offsetX",0);n(this,"offsetY",0);n(this,"strokeColor","rgba(80, 80, 80, 0.4)");n(this,"lineWidth",1);this.container=e,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let r=t?.zIndex??10;this.canvas.style.cssText=`
1
+ "use strict";var y=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var N=(f,e,t)=>e in f?y(f,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):f[e]=t;var C=(f,e)=>y(f,"name",{value:e,configurable:!0});var X=(f,e)=>{for(var t in e)y(f,t,{get:e[t],enumerable:!0})},q=(f,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of k(e))!z.call(f,i)&&i!==t&&y(f,i,{get:()=>e[i],enumerable:!(s=Y(e,i))||s.enumerable});return f};var j=f=>q(y({},"__esModule",{value:!0}),f);var r=(f,e,t)=>(N(f,typeof e!="symbol"?e+"":e,t),t);var Q={};X(Q,{DEFAULT_PALETTE:()=>D,GridOverlay:()=>I,ScalingMode:()=>x.ScalingMode,TerminalGL:()=>_,colorToPaletteIndex:()=>V,getAtlasColumns:()=>B,getCharGridPosition:()=>L,getMaxCharCode:()=>F,paletteIndexToColor:()=>$});module.exports=j(Q);var M=class M{constructor(e,t){r(this,"canvas");r(this,"ctx");r(this,"container");r(this,"cols",0);r(this,"rows",0);r(this,"cellWidth",0);r(this,"cellHeight",0);r(this,"offsetX",0);r(this,"offsetY",0);r(this,"strokeColor","rgba(80, 80, 80, 0.4)");r(this,"lineWidth",1);this.container=e,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let s=t?.zIndex??10;this.canvas.style.cssText=`
2
2
  display: block !important;
3
3
  position: absolute !important;
4
4
  pointer-events: none !important;
5
5
  image-rendering: pixelated !important;
6
6
  image-rendering: crisp-edges !important;
7
- z-index: ${r} !important;
8
- `,this.container.appendChild(this.canvas);let i=this.canvas.getContext("2d");if(!i)throw new Error("[GridOverlay] Impossible de cr\xE9er le contexte 2D");this.ctx=i,t&&(t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth))}setDimensions(e,t,r,i,s=0,a=0){this.cols=e,this.rows=t,this.cellWidth=r,this.cellHeight=i,this.offsetX=s,this.offsetY=a}setCanvasSize(e,t){this.canvas.width=e,this.canvas.height=t,this.ctx.setTransform(1,0,0,1,0,0)}setStyle(e){e.strokeColor&&(this.strokeColor=e.strokeColor),e.lineWidth!==void 0&&(this.lineWidth=e.lineWidth)}setTransform(e,t,r,i,s){let a=i.left-s.left,l=i.top-s.top,o=i.width,c=i.height;(this.canvas.width!==o||this.canvas.height!==c)&&(this.canvas.width=o,this.canvas.height=c);let d=this.canvas.style;d.width=`${o}px`,d.height=`${c}px`,d.left=`${a}px`,d.top=`${l}px`}render(){if(!this.ctx)return;let e=this.cols*this.cellWidth,t=this.rows*this.cellHeight,r=e>0?this.canvas.width/e:1,i=t>0?this.canvas.height/t:1,s=Math.min(r,i),a=this.cellWidth*s,l=this.cellHeight*s,o=this.cols*a,c=this.rows*l,d=this.offsetX*s,h=this.offsetY*s;if(!(o===0||c===0)){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.strokeStyle=this.strokeColor,this.ctx.lineWidth=Math.max(1,this.lineWidth*s),this.ctx.beginPath();for(let u=0;u<=this.cols;u++){let m=d+u*a+.5;this.ctx.moveTo(m,h),this.ctx.lineTo(m,h+c)}for(let u=0;u<=this.rows;u++){let m=h+u*l+.5;this.ctx.moveTo(d,m),this.ctx.lineTo(d+o,m)}this.ctx.stroke()}}update(e,t,r,i,s,a,l=0,o=0){this.setDimensions(e,t,r,i,l,o),this.setCanvasSize(s,a),this.render()}setVisible(e){this.canvas.style.display=e?"block":"none"}destroy(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}};A(P,"GridOverlay");var I=P;function F(f){return Math.sqrt(f)*16}A(F,"getAtlasColumns");function L(f){return f*256-1}A(L,"getMaxCharCode");function _(f,e){let t=Math.floor(f/256),r=f%256,i=Math.sqrt(e),s=t%i,a=Math.floor(t/i),l=r%16,o=Math.floor(r/16);return{col:s*16+l,row:a*16+o}}A(_,"getCharGridPosition");var p=require("@utsp/types");var B=class B{constructor(e,t){n(this,"canvas");n(this,"gl");n(this,"parentElement");n(this,"containerDiv");n(this,"cols");n(this,"rows");n(this,"charWidth");n(this,"charHeight");n(this,"cellWidth",8);n(this,"cellHeight",8);n(this,"glyphOffsetX",0);n(this,"glyphOffsetY",0);n(this,"canvasBgColor");n(this,"showGrid");n(this,"supportsUint32Indices",!1);n(this,"useUint16Indices",!1);n(this,"gridOverlay");n(this,"bitmapFont");n(this,"atlasTexture",null);n(this,"atlasCanvas");n(this,"atlasColumns",0);n(this,"fontLoaded",!1);n(this,"paletteTexture",null);n(this,"program",null);n(this,"positionBuffer",null);n(this,"texCoordBuffer",null);n(this,"colorIndexBuffer",null);n(this,"indexBuffer",null);n(this,"aPosition");n(this,"aTexCoord");n(this,"aColorIndex");n(this,"uResolution",null);n(this,"uTexture",null);n(this,"uPalette",null);n(this,"resizeObserver");n(this,"charCodeToAtlasIndex",new Uint16Array(65536).fill(65535));n(this,"atlasUVs",new Float32Array(0));n(this,"cachedAtlasWidth",0);n(this,"cachedAtlasHeight",0);n(this,"paletteFloat",new Float32Array(256*4));n(this,"maxCells",0);n(this,"renderPositions",new Float32Array(0));n(this,"renderTexCoords",new Float32Array(0));n(this,"renderColorIndices",new Float32Array(0));n(this,"renderIndices",new Uint32Array(0));n(this,"cachedResolution",[0,0]);n(this,"cachedTextureUnit",-1);n(this,"cachedPaletteUnit",-1);n(this,"cachedTextureUniform",!1);n(this,"cachedPaletteUniform",!1);n(this,"paletteHash",0);n(this,"currentScale",1);n(this,"scalingMode",p.ScalingMode.None);n(this,"ambientEffectEnabled",!1);n(this,"ambientEffectCanvas",null);n(this,"ambientEffectCtx",null);n(this,"ambientEffectBlur",p.POST_PROCESS_DEFAULTS.ambientEffect.blur);n(this,"ambientEffectScale",p.POST_PROCESS_DEFAULTS.ambientEffect.scale);n(this,"ambientEffectOpacity",.7);n(this,"onResizeCallback");n(this,"staticPositionsInitialized",!1);n(this,"vaoExtension",null);n(this,"vao",null);n(this,"instancedExtension",null);n(this,"useInstancing",!1);n(this,"instanceDataBuffer",null);n(this,"instanceData",new Float32Array(0));n(this,"templateQuadPositions",new Float32Array(0));n(this,"templateQuadIndices",new Uint16Array(0));if(!e)throw new Error("TerminalGL: Parent element is required");if(!Number.isInteger(t.cols)||t.cols<=0)throw new Error(`TerminalGL: Invalid cols: ${t.cols}. Must be a positive integer.`);if(!Number.isInteger(t.rows)||t.rows<=0)throw new Error(`TerminalGL: Invalid rows: ${t.rows}. Must be a positive integer.`);let r=t.cols*t.rows,i=B.checkCompatibility();if(i.errors.length>0)throw new Error(`TerminalGL: WebGL incompatible - ${i.errors.join(", ")}`);let s=t.forceUint16??!1;if(s&&r>i.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${r} cells) exceeds Uint16 limit of ${i.maxCellsUint16} cells. Maximum size with Uint16: ${Math.floor(Math.sqrt(i.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(i.maxCellsUint16))} (or smaller rectangles like 127\xD764)`);if(!i.uint32Indices&&r>i.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${r} cells) exceeds device limit of ${i.maxCellsUint16} cells (OES_element_index_uint not supported). Maximum size: ${Math.floor(Math.sqrt(i.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(i.maxCellsUint16))}`);r>i.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Large terminal size ${t.cols}\xD7${t.rows} (${r} cells) exceeds recommended limit of ${i.recommendedMaxCells} cells. Performance may be impacted.`),i.warnings.length>0&&console.warn("[TerminalGL] WebGL Compatibility Warnings:",i.warnings);let a=t.charWidth??8,l=t.charHeight??8;if(!Number.isFinite(a)||a<=0)throw new Error(`TerminalGL: Invalid charWidth: ${a}. Must be a positive number.`);if(!Number.isFinite(l)||l<=0)throw new Error(`TerminalGL: Invalid charHeight: ${l}. Must be a positive number.`);for(this.parentElement=e,this.cols=t.cols,this.rows=t.rows,this.charWidth=a,this.charHeight=l,this.canvasBgColor=t.canvasBgColor!==void 0?t.canvasBgColor:null,this.showGrid=t.showGrid??!1,this.scalingMode=t.scalingMode??p.ScalingMode.None,t.ambientEffect&&(this.ambientEffectEnabled=!0,typeof t.ambientEffect=="object"&&(this.ambientEffectBlur=t.ambientEffect.blur??p.POST_PROCESS_DEFAULTS.ambientEffect.blur,this.ambientEffectScale=t.ambientEffect.scale??p.POST_PROCESS_DEFAULTS.ambientEffect.scale,this.ambientEffectOpacity=t.ambientEffect.opacity??.7));this.parentElement.firstChild;)this.parentElement.removeChild(this.parentElement.firstChild);let o=window.getComputedStyle(this.parentElement).position;o!=="relative"&&o!=="absolute"&&o!=="fixed"&&(this.parentElement.style.position="relative"),this.containerDiv=document.createElement("div"),this.containerDiv.className="terminalgl-container",this.containerDiv.style.cssText=`
7
+ z-index: ${s} !important;
8
+ `,this.container.appendChild(this.canvas);let i=this.canvas.getContext("2d");if(!i)throw new Error("[GridOverlay] Impossible de cr\xE9er le contexte 2D");this.ctx=i,t&&(t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth))}setDimensions(e,t,s,i,n=0,a=0){this.cols=e,this.rows=t,this.cellWidth=s,this.cellHeight=i,this.offsetX=n,this.offsetY=a}setCanvasSize(e,t){this.canvas.width=e,this.canvas.height=t,this.ctx.setTransform(1,0,0,1,0,0)}setStyle(e){e.strokeColor&&(this.strokeColor=e.strokeColor),e.lineWidth!==void 0&&(this.lineWidth=e.lineWidth)}setTransform(e,t,s,i,n){let a=i.left-n.left,l=i.top-n.top,o=i.width,c=i.height;(this.canvas.width!==o||this.canvas.height!==c)&&(this.canvas.width=o,this.canvas.height=c);let d=this.canvas.style;d.width=`${o}px`,d.height=`${c}px`,d.left=`${a}px`,d.top=`${l}px`}render(){if(!this.ctx)return;let e=this.cols*this.cellWidth,t=this.rows*this.cellHeight,s=e>0?this.canvas.width/e:1,i=t>0?this.canvas.height/t:1,n=Math.min(s,i),a=this.cellWidth*n,l=this.cellHeight*n,o=this.cols*a,c=this.rows*l,d=this.offsetX*n,h=this.offsetY*n;if(!(o===0||c===0)){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.strokeStyle=this.strokeColor,this.ctx.lineWidth=Math.max(1,this.lineWidth*n),this.ctx.beginPath();for(let m=0;m<=this.cols;m++){let b=d+m*a+.5;this.ctx.moveTo(b,h),this.ctx.lineTo(b,h+c)}for(let m=0;m<=this.rows;m++){let b=h+m*l+.5;this.ctx.moveTo(d,b),this.ctx.lineTo(d+o,b)}this.ctx.stroke()}}update(e,t,s,i,n,a,l=0,o=0){this.setDimensions(e,t,s,i,l,o),this.setCanvasSize(n,a),this.render()}setVisible(e){this.canvas.style.display=e?"block":"none"}destroy(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}};C(M,"GridOverlay");var I=M;function B(f){return Math.sqrt(f)*16}C(B,"getAtlasColumns");function F(f){return f*256-1}C(F,"getMaxCharCode");function L(f,e){let t=Math.floor(f/256),s=f%256,i=Math.sqrt(e),n=t%i,a=Math.floor(t/i),l=s%16,o=Math.floor(s/16);return{col:n*16+l,row:a*16+o}}C(L,"getCharGridPosition");var x=require("@utsp/types");var U=class U{constructor(e,t){r(this,"canvas");r(this,"gl");r(this,"parentElement");r(this,"containerDiv");r(this,"cols");r(this,"rows");r(this,"charWidth");r(this,"charHeight");r(this,"cellWidth",8);r(this,"cellHeight",8);r(this,"glyphOffsetX",0);r(this,"glyphOffsetY",0);r(this,"canvasBgColor");r(this,"showGrid");r(this,"supportsUint32Indices",!1);r(this,"useUint16Indices",!1);r(this,"gridOverlay");r(this,"bitmapFont");r(this,"atlasTexture",null);r(this,"atlasCanvas");r(this,"atlasColumns",0);r(this,"fontLoaded",!1);r(this,"paletteTexture",null);r(this,"program",null);r(this,"positionBuffer",null);r(this,"texCoordBuffer",null);r(this,"colorIndexBuffer",null);r(this,"indexBuffer",null);r(this,"aPosition");r(this,"aTexCoord");r(this,"aColorIndex");r(this,"uResolution",null);r(this,"uTexture",null);r(this,"uPalette",null);r(this,"resizeObserver");r(this,"charCodeToAtlasIndex",new Uint16Array(65536).fill(65535));r(this,"atlasUVs",new Float32Array(0));r(this,"cachedAtlasWidth",0);r(this,"cachedAtlasHeight",0);r(this,"paletteFloat",new Float32Array(256*4));r(this,"maxCells",0);r(this,"renderPositions",new Float32Array(0));r(this,"renderTexCoords",new Float32Array(0));r(this,"renderColorIndices",new Float32Array(0));r(this,"renderIndices",new Uint32Array(0));r(this,"cachedResolution",[0,0]);r(this,"cachedTextureUnit",-1);r(this,"cachedPaletteUnit",-1);r(this,"cachedTextureUniform",!1);r(this,"cachedPaletteUniform",!1);r(this,"paletteHash",0);r(this,"currentScale",1);r(this,"scalingMode",x.ScalingMode.None);r(this,"ambientEffectEnabled",!1);r(this,"ambientEffectCanvas",null);r(this,"ambientEffectCtx",null);r(this,"ambientEffectBlur",x.POST_PROCESS_DEFAULTS.ambientEffect.blur);r(this,"ambientEffectScale",x.POST_PROCESS_DEFAULTS.ambientEffect.scale);r(this,"ambientEffectOpacity",.7);r(this,"onResizeCallback");r(this,"staticPositionsInitialized",!1);r(this,"vaoExtension",null);r(this,"vao",null);r(this,"instancedExtension",null);r(this,"useInstancing",!1);r(this,"instanceDataBuffer",null);r(this,"instanceData",new Float32Array(0));r(this,"templateQuadPositions",new Float32Array(0));r(this,"templateQuadIndices",new Uint16Array(0));r(this,"aInstanceOffset",-1);r(this,"aInstanceUVs",-1);r(this,"aInstanceColors",-1);r(this,"uCellSize",null);if(!e)throw new Error("TerminalGL: Parent element is required");if(!Number.isInteger(t.cols)||t.cols<=0)throw new Error(`TerminalGL: Invalid cols: ${t.cols}. Must be a positive integer.`);if(!Number.isInteger(t.rows)||t.rows<=0)throw new Error(`TerminalGL: Invalid rows: ${t.rows}. Must be a positive integer.`);let s=t.cols*t.rows,i=U.checkCompatibility();if(i.errors.length>0)throw new Error(`TerminalGL: WebGL incompatible - ${i.errors.join(", ")}`);let n=t.forceUint16??!1;if(n&&s>i.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${s} cells) exceeds Uint16 limit of ${i.maxCellsUint16} cells. Maximum size with Uint16: ${Math.floor(Math.sqrt(i.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(i.maxCellsUint16))} (or smaller rectangles like 127\xD764)`);if(!i.uint32Indices&&s>i.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${s} cells) exceeds device limit of ${i.maxCellsUint16} cells (OES_element_index_uint not supported). Maximum size: ${Math.floor(Math.sqrt(i.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(i.maxCellsUint16))}`);s>i.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Large terminal size ${t.cols}\xD7${t.rows} (${s} cells) exceeds recommended limit of ${i.recommendedMaxCells} cells. Performance may be impacted.`),i.warnings.length>0&&console.warn("[TerminalGL] WebGL Compatibility Warnings:",i.warnings);let a=t.charWidth??8,l=t.charHeight??8;if(!Number.isFinite(a)||a<=0)throw new Error(`TerminalGL: Invalid charWidth: ${a}. Must be a positive number.`);if(!Number.isFinite(l)||l<=0)throw new Error(`TerminalGL: Invalid charHeight: ${l}. Must be a positive number.`);for(this.parentElement=e,this.cols=t.cols,this.rows=t.rows,this.charWidth=a,this.charHeight=l,this.canvasBgColor=t.canvasBgColor!==void 0?t.canvasBgColor:null,this.showGrid=t.showGrid??!1,this.scalingMode=t.scalingMode??x.ScalingMode.None,t.ambientEffect&&(this.ambientEffectEnabled=!0,typeof t.ambientEffect=="object"&&(this.ambientEffectBlur=t.ambientEffect.blur??x.POST_PROCESS_DEFAULTS.ambientEffect.blur,this.ambientEffectScale=t.ambientEffect.scale??x.POST_PROCESS_DEFAULTS.ambientEffect.scale,this.ambientEffectOpacity=t.ambientEffect.opacity??.7));this.parentElement.firstChild;)this.parentElement.removeChild(this.parentElement.firstChild);let o=window.getComputedStyle(this.parentElement).position;o!=="relative"&&o!=="absolute"&&o!=="fixed"&&(this.parentElement.style.position="relative"),this.containerDiv=document.createElement("div"),this.containerDiv.className="terminalgl-container",this.containerDiv.style.cssText=`
9
9
  position: absolute !important;
10
10
  top: 0 !important;
11
11
  left: 0 !important;
@@ -32,7 +32,7 @@
32
32
  backface-visibility: hidden !important;
33
33
  position: relative !important;
34
34
  z-index: 1 !important;
35
- `;let c=this.canvas.getContext("webgl",{alpha:this.canvasBgColor===null,premultipliedAlpha:!1});if(!c)throw new Error("TerminalGL: WebGL not supported");this.gl=c,this.supportsUint32Indices=!!c.getExtension("OES_element_index_uint"),this.useUint16Indices=s||!this.supportsUint32Indices,this.useUint16Indices?console.warn(`[TerminalGL] \u{1F4CA} Using Uint16 indices (max ${i.maxCellsUint16} cells)`):console.warn(`[TerminalGL] \u{1F4CA} Using Uint32 indices (max ${i.maxCellsUint32} cells)`),this.vaoExtension=c.getExtension("OES_vertex_array_object"),this.vaoExtension&&console.warn("[TerminalGL] \u2705 VAO extension enabled (faster attribute binding)"),this.instancedExtension=c.getExtension("ANGLE_instanced_arrays"),this.instancedExtension?(this.useInstancing=!0,console.warn("[TerminalGL] \u{1F680} Instanced rendering enabled (massive draw call reduction)")):console.warn("[TerminalGL] \u26A0\uFE0F Instanced rendering not available (fallback to standard rendering)"),this.containerDiv.appendChild(this.canvas),this.ambientEffectEnabled&&(this.createAmbientEffectCanvas(),console.warn("[TerminalGL] \u{1F308} Ambient effect enabled at startup")),this.parentElement.appendChild(this.containerDiv),this.initRenderBuffers();try{this.initWebGL()}catch(d){throw console.error("[TerminalGL] \u274C Failed to initialize WebGL:",d),d}this.showGrid&&this.initGridOverlay(),this.setupResizeObserver()}static checkCompatibility(){let e={webgl1:!1,uint32Indices:!1,maxTextureSize:0,maxViewportDims:[0,0],maxCellsUint16:0,maxCellsUint32:0,recommendedMaxCells:0,warnings:[],errors:[]},t=document.createElement("canvas"),r=t.getContext("webgl")||t.getContext("experimental-webgl");if(!r||!(r instanceof WebGLRenderingContext))return e.errors.push("\u274C WebGL 1.0 not supported by this browser/device"),e;let i=r;e.webgl1=!0;try{e.maxTextureSize=i.getParameter(i.MAX_TEXTURE_SIZE);let o=i.getParameter(i.MAX_VIEWPORT_DIMS);e.maxViewportDims=[o[0],o[1]]}catch(o){return e.errors.push(`\u274C Failed to query WebGL parameters: ${o}`),e}let s=i.getExtension("OES_element_index_uint");e.uint32Indices=!!s;let a=8;if(e.maxCellsUint16=Math.floor(65535/a),e.uint32Indices){let o=Math.floor(e.maxTextureSize*e.maxTextureSize/64);e.maxCellsUint32=Math.min(o,262144)}else e.maxCellsUint32=e.maxCellsUint16,e.warnings.push(`\u26A0\uFE0F OES_element_index_uint not supported - limited to ${e.maxCellsUint16} cells (e.g., 90\xD790 or 127\xD764)`);return e.recommendedMaxCells=Math.floor((e.uint32Indices?e.maxCellsUint32:e.maxCellsUint16)*.8),e.maxTextureSize<256?e.errors.push(`\u274C MAX_TEXTURE_SIZE too small: ${e.maxTextureSize} (minimum 256 required for font atlas)`):e.maxTextureSize<2048&&e.warnings.push(`\u26A0\uFE0F Small MAX_TEXTURE_SIZE: ${e.maxTextureSize} (may limit font atlas)`),(e.maxViewportDims[0]<1024||e.maxViewportDims[1]<768)&&e.warnings.push(`\u26A0\uFE0F Small MAX_VIEWPORT_DIMS: ${e.maxViewportDims[0]}\xD7${e.maxViewportDims[1]}`),i.getExtension("WEBGL_lose_context")||e.warnings.push("\u26A0\uFE0F WEBGL_lose_context not supported - may cause memory leaks"),e}initInstancedBuffers(){let e=this.gl;this.templateQuadPositions=new Float32Array([0,0,this.cellWidth,0,0,this.cellHeight,this.cellWidth,this.cellHeight]),this.templateQuadIndices=new Uint16Array([0,1,2,2,1,3]),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.bufferData(e.ARRAY_BUFFER,this.templateQuadPositions,e.STATIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,this.templateQuadIndices,e.STATIC_DRAW);let t=this.cols*this.rows*2;this.instanceData=new Float32Array(t*8),e.bindBuffer(e.ARRAY_BUFFER,this.instanceDataBuffer),e.bufferData(e.ARRAY_BUFFER,this.instanceData.byteLength,e.DYNAMIC_DRAW)}initRenderBuffers(){this.maxCells=this.cols*this.rows*2,this.renderPositions=new Float32Array(this.maxCells*4*2),this.renderTexCoords=new Float32Array(this.maxCells*4*2),this.renderColorIndices=new Float32Array(this.maxCells*4),this.useUint16Indices?this.renderIndices=new Uint16Array(this.maxCells*6):this.renderIndices=new Uint32Array(this.maxCells*6),this.staticPositionsInitialized=!1}precomputeStaticPositions(){let e=this.cellWidth,t=this.cellHeight,r=this.glyphOffsetX,i=this.glyphOffsetY,s=this.charWidth,a=this.charHeight,l=0,o=0,c=0;for(let h=0;h<this.rows;h++){let u=Math.round(h*t),m=Math.round(u+t);for(let b=0;b<this.cols;b++){let g=Math.round(b*e),E=Math.round(g+e);this.renderPositions[l++]=g,this.renderPositions[l++]=u,this.renderPositions[l++]=E,this.renderPositions[l++]=u,this.renderPositions[l++]=g,this.renderPositions[l++]=m,this.renderPositions[l++]=E,this.renderPositions[l++]=m,this.renderIndices[o++]=c,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+3,c+=4;let T=Math.round(g+r),R=Math.round(u+i),v=Math.round(T+s),C=Math.round(R+a);this.renderPositions[l++]=T,this.renderPositions[l++]=R,this.renderPositions[l++]=v,this.renderPositions[l++]=R,this.renderPositions[l++]=T,this.renderPositions[l++]=C,this.renderPositions[l++]=v,this.renderPositions[l++]=C,this.renderIndices[o++]=c,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+3,c+=4}}let d=this.gl;d.bindBuffer(d.ARRAY_BUFFER,this.positionBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,this.renderPositions),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,this.indexBuffer),d.bufferSubData(d.ELEMENT_ARRAY_BUFFER,0,this.renderIndices),this.staticPositionsInitialized=!0}initWebGL(){let e=this.gl,t;this.useInstancing?t=`
35
+ `;let c=this.canvas.getContext("webgl",{alpha:this.canvasBgColor===null,premultipliedAlpha:!1});if(!c)throw new Error("TerminalGL: WebGL not supported");this.gl=c,this.supportsUint32Indices=!!c.getExtension("OES_element_index_uint"),this.useUint16Indices=n||!this.supportsUint32Indices,this.useUint16Indices?console.warn(`[TerminalGL] \u{1F4CA} Using Uint16 indices (max ${i.maxCellsUint16} cells)`):console.warn(`[TerminalGL] \u{1F4CA} Using Uint32 indices (max ${i.maxCellsUint32} cells)`),this.vaoExtension=c.getExtension("OES_vertex_array_object"),this.vaoExtension&&console.warn("[TerminalGL] \u2705 VAO extension enabled (faster attribute binding)"),this.instancedExtension=c.getExtension("ANGLE_instanced_arrays"),this.instancedExtension?(this.useInstancing=!0,console.warn("[TerminalGL] \u{1F680} Instanced rendering enabled (massive draw call reduction)")):console.warn("[TerminalGL] \u26A0\uFE0F Instanced rendering not available (fallback to standard rendering)"),this.containerDiv.appendChild(this.canvas),this.ambientEffectEnabled&&(this.createAmbientEffectCanvas(),console.warn("[TerminalGL] \u{1F308} Ambient effect enabled at startup")),this.parentElement.appendChild(this.containerDiv),this.initRenderBuffers();try{this.initWebGL()}catch(d){throw console.error("[TerminalGL] \u274C Failed to initialize WebGL:",d),d}this.showGrid&&this.initGridOverlay(),this.setupResizeObserver()}static checkCompatibility(){let e={webgl1:!1,uint32Indices:!1,maxTextureSize:0,maxViewportDims:[0,0],maxCellsUint16:0,maxCellsUint32:0,recommendedMaxCells:0,warnings:[],errors:[]},t=document.createElement("canvas"),s=t.getContext("webgl")||t.getContext("experimental-webgl");if(!s||!(s instanceof WebGLRenderingContext))return e.errors.push("\u274C WebGL 1.0 not supported by this browser/device"),e;let i=s;e.webgl1=!0;try{e.maxTextureSize=i.getParameter(i.MAX_TEXTURE_SIZE);let o=i.getParameter(i.MAX_VIEWPORT_DIMS);e.maxViewportDims=[o[0],o[1]]}catch(o){return e.errors.push(`\u274C Failed to query WebGL parameters: ${o}`),e}let n=i.getExtension("OES_element_index_uint");e.uint32Indices=!!n;let a=8;if(e.maxCellsUint16=Math.floor(65535/a),e.uint32Indices){let o=Math.floor(e.maxTextureSize*e.maxTextureSize/64);e.maxCellsUint32=Math.min(o,262144)}else e.maxCellsUint32=e.maxCellsUint16,e.warnings.push(`\u26A0\uFE0F OES_element_index_uint not supported - limited to ${e.maxCellsUint16} cells (e.g., 90\xD790 or 127\xD764)`);return e.recommendedMaxCells=Math.floor((e.uint32Indices?e.maxCellsUint32:e.maxCellsUint16)*.8),e.maxTextureSize<256?e.errors.push(`\u274C MAX_TEXTURE_SIZE too small: ${e.maxTextureSize} (minimum 256 required for font atlas)`):e.maxTextureSize<2048&&e.warnings.push(`\u26A0\uFE0F Small MAX_TEXTURE_SIZE: ${e.maxTextureSize} (may limit font atlas)`),(e.maxViewportDims[0]<1024||e.maxViewportDims[1]<768)&&e.warnings.push(`\u26A0\uFE0F Small MAX_VIEWPORT_DIMS: ${e.maxViewportDims[0]}\xD7${e.maxViewportDims[1]}`),i.getExtension("WEBGL_lose_context")||e.warnings.push("\u26A0\uFE0F WEBGL_lose_context not supported - may cause memory leaks"),e}initInstancedBuffers(){let e=this.gl;this.templateQuadPositions=new Float32Array([0,0,this.cellWidth,0,0,this.cellHeight,this.cellWidth,this.cellHeight]),this.templateQuadIndices=new Uint16Array([0,1,2,2,1,3]),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.bufferData(e.ARRAY_BUFFER,this.templateQuadPositions,e.STATIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,this.templateQuadIndices,e.STATIC_DRAW),this.instanceData=new Float32Array(this.maxCells*8),console.warn(`[TerminalGL] \u{1F680} initInstancedBuffers: maxCells=${this.maxCells}, instanceData.length=${this.instanceData.length}`),e.bindBuffer(e.ARRAY_BUFFER,this.instanceDataBuffer),e.bufferData(e.ARRAY_BUFFER,this.instanceData.byteLength,e.DYNAMIC_DRAW)}initRenderBuffers(){let e=this.cols*this.rows*2;this.maxCells=Math.ceil(e*2),this.renderPositions=new Float32Array(this.maxCells*4*2),this.renderTexCoords=new Float32Array(this.maxCells*4*2),this.renderColorIndices=new Float32Array(this.maxCells*4),this.useUint16Indices?this.renderIndices=new Uint16Array(this.maxCells*6):this.renderIndices=new Uint32Array(this.maxCells*6),this.staticPositionsInitialized=!1}precomputeStaticPositions(){let e=this.cellWidth,t=this.cellHeight,s=this.glyphOffsetX,i=this.glyphOffsetY,n=this.charWidth,a=this.charHeight,l=0,o=0,c=0;for(let h=0;h<this.rows;h++){let m=Math.round(h*t),b=Math.round(m+t);for(let v=0;v<this.cols;v++){let u=Math.round(v*e),g=Math.round(u+e);this.renderPositions[l++]=u,this.renderPositions[l++]=m,this.renderPositions[l++]=g,this.renderPositions[l++]=m,this.renderPositions[l++]=u,this.renderPositions[l++]=b,this.renderPositions[l++]=g,this.renderPositions[l++]=b,this.renderIndices[o++]=c,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+3,c+=4;let E=Math.round(u+s),p=Math.round(m+i),w=Math.round(E+n),A=Math.round(p+a);this.renderPositions[l++]=E,this.renderPositions[l++]=p,this.renderPositions[l++]=w,this.renderPositions[l++]=p,this.renderPositions[l++]=E,this.renderPositions[l++]=A,this.renderPositions[l++]=w,this.renderPositions[l++]=A,this.renderIndices[o++]=c,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+3,c+=4}}let d=this.gl;d.bindBuffer(d.ARRAY_BUFFER,this.positionBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,this.renderPositions),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,this.indexBuffer),d.bufferSubData(d.ELEMENT_ARRAY_BUFFER,0,this.renderIndices),this.staticPositionsInitialized=!0}initWebGL(){let e=this.gl,t;this.useInstancing?t=`
36
36
  // Per-vertex attributes (template quad)
37
37
  attribute vec2 aPosition; // Local quad position (0,0 to cellW,cellH)
38
38
 
@@ -93,7 +93,7 @@
93
93
  float paletteU = (aColorIndex + 0.5) / 256.0;
94
94
  vColor = texture2D(uPalette, vec2(paletteU, 0.5));
95
95
  }
96
- `;let r=`
96
+ `;let s=`
97
97
  precision mediump float;
98
98
 
99
99
  uniform sampler2D uTexture;
@@ -113,7 +113,7 @@
113
113
  gl_FragColor = vec4(texColor.rgb * vColor.rgb, texColor.a);
114
114
  }
115
115
  }
116
- `,i=this.compileShader(e.VERTEX_SHADER,t),s=this.compileShader(e.FRAGMENT_SHADER,r);if(!i||!s)throw new Error("Shader compilation error");let a=e.createProgram();if(!a)throw new Error("Unable to create WebGL program");if(e.attachShader(a,i),e.attachShader(a,s),e.linkProgram(a),!e.getProgramParameter(a,e.LINK_STATUS)){let l=e.getProgramInfoLog(a);throw new Error("Program linking error: "+l)}this.program=a,this.cachedTextureUniform=!1,this.cachedPaletteUniform=!1,this.aPosition=e.getAttribLocation(a,"aPosition"),this.useInstancing?(this.aTexCoord=e.getAttribLocation(a,"aInstanceOffset"),this.aColorIndex=e.getAttribLocation(a,"aInstanceUVs"),this.instanceDataBuffer=e.createBuffer()):(this.aTexCoord=e.getAttribLocation(a,"aTexCoord"),this.aColorIndex=e.getAttribLocation(a,"aColorIndex")),this.uResolution=e.getUniformLocation(a,"uResolution"),this.uTexture=e.getUniformLocation(a,"uTexture"),this.uPalette=e.getUniformLocation(a,"uPalette"),this.positionBuffer=e.createBuffer(),this.texCoordBuffer=e.createBuffer(),this.colorIndexBuffer=e.createBuffer(),this.indexBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderPositions.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderTexCoords.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderColorIndices.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,e.DYNAMIC_DRAW),this.vaoExtension&&(this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(this.aPosition),e.vertexAttribPointer(this.aPosition,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.enableVertexAttribArray(this.aTexCoord),e.vertexAttribPointer(this.aTexCoord,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.enableVertexAttribArray(this.aColorIndex),e.vertexAttribPointer(this.aColorIndex,1,e.FLOAT,!1,0,0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null))),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA),e.viewport(0,0,this.canvas.width,this.canvas.height)}compileShader(e,t){let r=this.gl,i=r.createShader(e);return i?(r.shaderSource(i,t),r.compileShader(i),r.getShaderParameter(i,r.COMPILE_STATUS)?i:(console.error("Shader compilation error:",r.getShaderInfoLog(i)),r.deleteShader(i),null)):null}initGridOverlay(){this.gridOverlay=new I(this.containerDiv,{strokeColor:"rgba(144, 24, 24, 1)",lineWidth:1,zIndex:10}),this.updateGridOverlay()}updateGridOverlay(){if(!this.gridOverlay)return;let e=this.cols*this.cellWidth,t=this.rows*this.cellHeight,r=this.canvas.getBoundingClientRect(),i=this.containerDiv.getBoundingClientRect();this.gridOverlay.setDimensions(this.cols,this.rows,this.cellWidth,this.cellHeight,0,0),this.gridOverlay.setTransform(this.currentScale,e,t,r,i),this.gridOverlay.render()}setBitmapFont(e,t,r,i,s){this.bitmapFont=e,this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(r),this.cellWidth=Math.round(i),this.cellHeight=Math.round(s),this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&(console.warn("[TerminalGL] \u{1F680} Initializing instanced buffers..."),this.initInstancedBuffers());try{this.generateAtlas()}catch(a){throw console.error("[TerminalGL] \u274C Failed to generate atlas:",a),a}this.buildCharCodeMap(),this.precomputeAtlasUVs(),this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.useInstancing||this.precomputeStaticPositions(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}async setImageFont(e,t,r,i,s,a){this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(r),this.cellWidth=Math.round(i),this.cellHeight=Math.round(s),this.atlasColumns=F(a);let l=L(a);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&(console.warn("[TerminalGL] \u{1F680} Initializing instanced buffers for ImageFont..."),this.initInstancedBuffers()),await this.loadImageFontAtlas(e),this.charCodeToAtlasIndex.fill(65535);for(let o=0;o<=l;o++)this.charCodeToAtlasIndex[o]=o;this.precomputeImageFontUVs(a),this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.useInstancing||this.precomputeStaticPositions(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}async loadImageFontAtlas(e){return new Promise((t,r)=>{let i=new Uint8Array(e),s=new Blob([i],{type:"image/png"}),a=URL.createObjectURL(s),l=new Image;l.onload=()=>{URL.revokeObjectURL(a),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=l.width,this.atlasCanvas.height=l.height;let o=this.atlasCanvas.getContext("2d");if(!o){r(new Error("Failed to create 2D context for atlas"));return}o.drawImage(l,0,0),this.cachedAtlasWidth=l.width,this.cachedAtlasHeight=l.height,this.createAtlasTexture(),t()},l.onerror=()=>{URL.revokeObjectURL(a),r(new Error("Failed to load PNG image for ImageFont atlas"))},l.src=a})}precomputeImageFontUVs(e){let t=e*256;this.atlasUVs=new Float32Array(t*4);let r=this.cachedAtlasWidth,i=this.cachedAtlasHeight,s=.5/r,a=.5/i;for(let l=0;l<t;l++){let{col:o,row:c}=_(l,e),d=(o*this.charWidth+s)/r,h=(c*this.charHeight+a)/i,u=((o+1)*this.charWidth-s)/r,m=((c+1)*this.charHeight-a)/i,b=l*4;this.atlasUVs[b]=d,this.atlasUVs[b+1]=h,this.atlasUVs[b+2]=u,this.atlasUVs[b+3]=m}}generateAtlas(){if(!this.bitmapFont)return;let e=Array.from(this.bitmapFont.keys()).sort((o,c)=>o-c),t=e.length;this.atlasColumns=Math.ceil(Math.sqrt(t));let r=Math.ceil(t/this.atlasColumns),i=this.atlasColumns*this.charWidth,s=r*this.charHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=i,this.atlasCanvas.height=s;let a=this.atlasCanvas.getContext("2d");if(!a)throw new Error("Unable to create 2D context for atlas");a.clearRect(0,0,i,s),a.fillStyle="#ffffff";let l=0;for(let o of e){let c=this.bitmapFont.get(o);if(!c)continue;let d=l%this.atlasColumns,h=Math.floor(l/this.atlasColumns),u=d*this.charWidth,m=h*this.charHeight;for(let b=0;b<Math.min(c.length,this.charHeight);b++){let g=c[b];for(let E=0;E<this.charWidth;E++){let T=1<<7-E;g&T&&a.fillRect(u+E,m+b,1,1)}}l++}this.createAtlasTexture()}buildCharCodeMap(){if(!this.bitmapFont)return;this.charCodeToAtlasIndex.fill(65535);let e=Array.from(this.bitmapFont.keys()).sort((t,r)=>t-r);for(let t=0;t<e.length;t++)this.charCodeToAtlasIndex[e[t]]=t}precomputeAtlasUVs(){if(!this.bitmapFont)return;let e=this.bitmapFont.size;this.atlasUVs=new Float32Array(e*4),this.cachedAtlasWidth=this.atlasColumns*this.charWidth,this.cachedAtlasHeight=Math.ceil(e/this.atlasColumns)*this.charHeight;let t=this.cachedAtlasWidth,r=this.cachedAtlasHeight,i=.5/t,s=.5/r;for(let a=0;a<e;a++){let l=a%this.atlasColumns,o=Math.floor(a/this.atlasColumns),c=(l*this.charWidth+i)/t,d=(o*this.charHeight+s)/r,h=((l+1)*this.charWidth-i)/t,u=((o+1)*this.charHeight-s)/r,m=a*4;this.atlasUVs[m]=c,this.atlasUVs[m+1]=d,this.atlasUVs[m+2]=h,this.atlasUVs[m+3]=u}}createAtlasTexture(){if(this.atlasCanvas)try{let e=this.gl,t=e.createTexture();if(!t)throw new Error("Unable to create texture");e.bindTexture(e.TEXTURE_2D,t),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,this.atlasCanvas),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),this.atlasTexture=t}catch(e){throw console.error("[TerminalGL] \u274C Failed to create atlas texture:",e),e}}clear(){let e=this.gl;e&&e.clear(e.COLOR_BUFFER_BIT)}parseColor(e){if(e.startsWith("#")){let t=e.slice(1),r=0,i=0,s=0;return t.length===3?(r=parseInt(t[0]+t[0],16),i=parseInt(t[1]+t[1],16),s=parseInt(t[2]+t[2],16)):t.length===6&&(r=parseInt(t.slice(0,2),16),i=parseInt(t.slice(2,4),16),s=parseInt(t.slice(4,6),16)),[r/255,i/255,s/255,1]}if(e.startsWith("rgb")){let t=e.match(/rgba?\(([^)]+)\)/);if(t){let r=t[1].split(",").map(i=>parseFloat(i.trim()));return[r[0]/255,r[1]/255,r[2]/255,r[3]!==void 0?r[3]:1]}}return[1,1,1,1]}setupResizeObserver(){if(!(typeof ResizeObserver>"u"))try{this.resizeObserver=new ResizeObserver(()=>{try{this.updateCanvasSize()}catch(e){console.error("[TerminalGL] \u274C Error in resize callback:",e)}}),this.resizeObserver.observe(this.parentElement),this.updateCanvasSize()}catch(e){console.error("[TerminalGL] \u274C Failed to setup ResizeObserver:",e)}}updateCanvasSize(){let e=this.parentElement.clientWidth,t=this.parentElement.clientHeight;if(e===0||t===0)return;let r=this.cols*this.cellWidth,i=this.rows*this.cellHeight;if(r===0||i===0)return;let s=e/r,a=t/i,l=Math.min(s,a),o;switch(this.scalingMode){case p.ScalingMode.Integer:o=Math.max(1,Math.floor(l));break;case p.ScalingMode.Half:o=Math.max(1,Math.floor(l*2)/2);break;case p.ScalingMode.Quarter:o=Math.max(1,Math.floor(l*4)/4);break;case p.ScalingMode.Eighth:o=Math.max(1,Math.floor(l*8)/8);break;case p.ScalingMode.None:default:o=Math.max(.1,l);break}if(this.canvas.style.transform=`scale(${o})`,this.ambientEffectEnabled&&this.ambientEffectCanvas){let c=o*this.ambientEffectScale;this.ambientEffectCanvas.style.transform=`scale(${c})`}this.currentScale=o,this.onResizeCallback&&this.onResizeCallback(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}updateAmbientEffect(){!this.ambientEffectCanvas||!this.ambientEffectCtx||this.ambientEffectCtx.drawImage(this.canvas,0,0)}setPalette(e){let t=0;for(let r=0;r<Math.min(e.length,256);r++){let i=e[r];t=(t<<5)-t+i.r,t=(t<<5)-t+i.g,t=(t<<5)-t+i.b,t=(t<<5)-t+i.a,t=t|0}if(t!==this.paletteHash){this.paletteHash=t;for(let r=0;r<e.length&&r<256;r++){let i=e[r],s=r*4;this.paletteFloat[s]=i.r/255,this.paletteFloat[s+1]=i.g/255,this.paletteFloat[s+2]=i.b/255,this.paletteFloat[s+3]=i.a/255}this.updatePaletteTexture()}}updatePaletteTexture(){try{let e=this.gl;this.paletteTexture||(this.paletteTexture=e.createTexture()),e.bindTexture(e.TEXTURE_2D,this.paletteTexture);let t=new Uint8Array(256*4);for(let r=0;r<256;r++){let i=r*4;t[i]=this.paletteFloat[i]*255,t[i+1]=this.paletteFloat[i+1]*255,t[i+2]=this.paletteFloat[i+2]*255,t[i+3]=this.paletteFloat[i+3]*255}e.texImage2D(e.TEXTURE_2D,0,e.RGBA,256,1,0,e.RGBA,e.UNSIGNED_BYTE,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null)}catch(e){throw console.error("[TerminalGL] \u274C Failed to update palette texture:",e),e}}renderDisplayData(e){try{if(!this.isReady()){console.warn("[TerminalGL] \u26A0\uFE0F Not ready: font not loaded yet");return}(e.width!==this.cols||e.height!==this.rows)&&this.resize(e.width,e.height),this.renderDirect(e),this.ambientEffectEnabled&&this.ambientEffectCanvas&&this.ambientEffectCtx&&this.updateAmbientEffect()}catch(t){console.error("[TerminalGL] \u274C Error rendering display data:",t)}}renderDirect(e){let t=this.gl;if(!this.staticPositionsInitialized&&!this.useInstancing&&this.precomputeStaticPositions(),this.canvasBgColor!==null){let r=this.parseColor(this.canvasBgColor);t.clearColor(r[0],r[1],r[2],r[3])}else t.clearColor(0,0,0,0);t.clear(t.COLOR_BUFFER_BIT),this.useInstancing?this.renderInstanced(e):this.renderDirectBuffers(e)}renderInstanced(e){let t=this.gl,r=this.instancedExtension;if(!this.instanceData||this.instanceData.length===0){console.warn("[TerminalGL] \u26A0\uFE0F Instance data not initialized, falling back to standard rendering"),this.useInstancing=!1,this.renderDirectBuffers(e);return}let i=e.width*e.height;if(this.useUint16Indices&&i>8191){console.warn(`[TerminalGL] \u26A0\uFE0F Terminal too large for instanced rendering with Uint16 (${i} cells > 8191). Falling back to standard rendering.`),this.useInstancing=!1,this.renderDirectBuffers(e);return}let s=0,a=this.instanceData.length/8;for(let u=0;u<e.height;u++)for(let m=0;m<e.width;m++){let b=e.cells[u*e.width+m],g=b.bgColorIndex,E=b.fgColorIndex,T=this.canvasBgColor!==null&&g===255,R=b.char===" "||E===255;if(!T){if(s>=a){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${a}`);break}let v=s*8;this.instanceData[v]=m,this.instanceData[v+1]=u,this.instanceData[v+2]=0,this.instanceData[v+3]=0,this.instanceData[v+4]=0,this.instanceData[v+5]=0,this.instanceData[v+6]=g,this.instanceData[v+7]=0,s++}if(!R){let v=b.char.charCodeAt(0),C=this.charCodeToAtlasIndex[v];if(C!==65535){if(s>=a){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${a}`);break}let w=C*4,x=s*8;this.instanceData[x]=m,this.instanceData[x+1]=u,this.instanceData[x+2]=this.atlasUVs[w],this.instanceData[x+3]=this.atlasUVs[w+1],this.instanceData[x+4]=this.atlasUVs[w+2],this.instanceData[x+5]=this.atlasUVs[w+3],this.instanceData[x+6]=0,this.instanceData[x+7]=E,s++}}}if(s===0){console.warn("[TerminalGL] \u26A0\uFE0F No instances to draw (all cells skipped)");return}t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.instanceData.subarray(0,s*8)),t.useProgram(this.program),t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.enableVertexAttribArray(this.aPosition),t.vertexAttribPointer(this.aPosition,2,t.FLOAT,!1,0,0),r.vertexAttribDivisorANGLE(this.aPosition,0),t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer);let l=8*Float32Array.BYTES_PER_ELEMENT,o=t.getAttribLocation(this.program,"aInstanceOffset");t.enableVertexAttribArray(o),t.vertexAttribPointer(o,2,t.FLOAT,!1,l,0),r.vertexAttribDivisorANGLE(o,1);let c=t.getAttribLocation(this.program,"aInstanceUVs");t.enableVertexAttribArray(c),t.vertexAttribPointer(c,4,t.FLOAT,!1,l,2*Float32Array.BYTES_PER_ELEMENT),r.vertexAttribDivisorANGLE(c,1);let d=t.getAttribLocation(this.program,"aInstanceColors");t.enableVertexAttribArray(d),t.vertexAttribPointer(d,2,t.FLOAT,!1,l,6*Float32Array.BYTES_PER_ELEMENT),r.vertexAttribDivisorANGLE(d,1),t.uniform2f(this.uResolution,this.canvas.width,this.canvas.height);let h=t.getUniformLocation(this.program,"uCellSize");t.uniform2f(h,this.cellWidth,this.cellHeight),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.atlasTexture),t.uniform1i(this.uTexture,0),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,this.paletteTexture),t.uniform1i(this.uPalette,1),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer),r.drawElementsInstancedANGLE(t.TRIANGLES,6,t.UNSIGNED_SHORT,0,s),r.vertexAttribDivisorANGLE(this.aPosition,0),r.vertexAttribDivisorANGLE(o,0),r.vertexAttribDivisorANGLE(c,0),r.vertexAttribDivisorANGLE(d,0)}renderDirectBuffers(e){let t=this.gl,r=e.width*e.height,i=r*2;if(i>this.maxCells){console.error(`[TerminalGL] \u274C Buffer overflow detected! Trying to render ${i} quads but buffer capacity is ${this.maxCells}. This should not happen - resize() should have reallocated.`);return}let s=0,a=0,l=e.cells,o=r;for(let b=0;b<o;b++){let g=l[b],E=g.bgColorIndex,R=this.canvasBgColor!==null&&E===255?255:E,v=0;for(let x=0;x<4;x++)this.renderTexCoords[s++]=v,this.renderTexCoords[s++]=v,this.renderColorIndices[a++]=R;let C=g.fgColorIndex,w=g.char;if(w===" "||C===255)for(let x=0;x<4;x++)this.renderTexCoords[s++]=0,this.renderTexCoords[s++]=0,this.renderColorIndices[a++]=255;else{let x=w.charCodeAt(0),S=this.charCodeToAtlasIndex[x];if(S!==65535){let y=S*4,G=this.atlasUVs[y],W=this.atlasUVs[y+1],O=this.atlasUVs[y+2],H=this.atlasUVs[y+3];this.renderTexCoords[s++]=G,this.renderTexCoords[s++]=W,this.renderColorIndices[a++]=C,this.renderTexCoords[s++]=O,this.renderTexCoords[s++]=W,this.renderColorIndices[a++]=C,this.renderTexCoords[s++]=G,this.renderTexCoords[s++]=H,this.renderColorIndices[a++]=C,this.renderTexCoords[s++]=O,this.renderTexCoords[s++]=H,this.renderColorIndices[a++]=C}else for(let y=0;y<4;y++)this.renderTexCoords[s++]=0,this.renderTexCoords[s++]=0,this.renderColorIndices[a++]=255}}(s!==o*2*4*2||a!==o*2*4)&&console.error("[TerminalGL] \u274C Buffer index mismatch!",{texIdx:s,colorIdx:a,expected:o*2*4}),t.useProgram(this.program),this.vao&&this.vaoExtension?(this.vaoExtension.bindVertexArrayOES(this.vao),t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,s)),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,a))):(t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.enableVertexAttribArray(this.aPosition),t.vertexAttribPointer(this.aPosition,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,s)),t.enableVertexAttribArray(this.aTexCoord),t.vertexAttribPointer(this.aTexCoord,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,a)),t.enableVertexAttribArray(this.aColorIndex),t.vertexAttribPointer(this.aColorIndex,1,t.FLOAT,!1,0,0));let c=this.canvas.width,d=this.canvas.height;(this.cachedResolution[0]!==c||this.cachedResolution[1]!==d)&&(t.uniform2f(this.uResolution,c,d),this.cachedResolution[0]=c,this.cachedResolution[1]=d),this.cachedTextureUnit!==0&&(t.activeTexture(t.TEXTURE0),this.cachedTextureUnit=0),t.bindTexture(t.TEXTURE_2D,this.atlasTexture),this.cachedTextureUniform||(t.uniform1i(this.uTexture,0),this.cachedTextureUniform=!0),this.cachedPaletteUnit!==1&&(t.activeTexture(t.TEXTURE1),this.cachedPaletteUnit=1),t.bindTexture(t.TEXTURE_2D,this.paletteTexture),this.cachedPaletteUniform||(t.uniform1i(this.uPalette,1),this.cachedPaletteUniform=!0),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer);let u=e.width*e.height*2*6,m=this.useUint16Indices?t.UNSIGNED_SHORT:t.UNSIGNED_INT;t.drawElements(t.TRIANGLES,u,m,0)}resize(e,t){if(!Number.isInteger(e)||e<=0){console.error(`[TerminalGL] \u274C Invalid cols: ${e}. Must be positive integer.`);return}if(!Number.isInteger(t)||t<=0){console.error(`[TerminalGL] \u274C Invalid rows: ${t}. Must be positive integer.`);return}if(e===this.cols&&t===this.rows)return;let r=e*t,i=this.useUint16Indices?8191:262144;if(r>i){let d=Math.floor(Math.sqrt(i));console.error(`[TerminalGL] \u274C Cannot resize to ${e}\xD7${t} (${r} cells). Device limit: ${i} cells (max ~${d}\xD7${d}). ${this.useUint16Indices?"Device lacks OES_element_index_uint extension.":""}`);return}let s=B.checkCompatibility();r>s.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Resizing to ${e}\xD7${t} (${r} cells) exceeds recommended limit (${s.recommendedMaxCells} cells). Performance may degrade.`),this.cols=e,this.rows=t,this.staticPositionsInitialized=!1;let a=this.cols*this.rows*2,l=Math.ceil(a*1.5),o=a>this.maxCells,c=this.maxCells>l*4;if(o||c){let d=this.maxCells;this.maxCells=l,this.renderPositions=new Float32Array(this.maxCells*4*2),this.renderTexCoords=new Float32Array(this.maxCells*4*2),this.renderColorIndices=new Float32Array(this.maxCells*4),this.useUint16Indices?this.renderIndices=new Uint16Array(this.maxCells*6):this.renderIndices=new Uint32Array(this.maxCells*6);let h=this.gl;this.useInstancing||(h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderPositions.byteLength,h.DYNAMIC_DRAW)),h.bindBuffer(h.ARRAY_BUFFER,this.texCoordBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderTexCoords.byteLength,h.DYNAMIC_DRAW),h.bindBuffer(h.ARRAY_BUFFER,this.colorIndexBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderColorIndices.byteLength,h.DYNAMIC_DRAW),h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),h.bufferData(h.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,h.DYNAMIC_DRAW),this.vaoExtension&&this.vao&&(this.vaoExtension.deleteVertexArrayOES(this.vao),this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.enableVertexAttribArray(this.aPosition),h.vertexAttribPointer(this.aPosition,2,h.FLOAT,!1,0,0),h.bindBuffer(h.ARRAY_BUFFER,this.texCoordBuffer),h.enableVertexAttribArray(this.aTexCoord),h.vertexAttribPointer(this.aTexCoord,2,h.FLOAT,!1,0,0),h.bindBuffer(h.ARRAY_BUFFER,this.colorIndexBuffer),h.enableVertexAttribArray(this.aColorIndex),h.vertexAttribPointer(this.aColorIndex,1,h.FLOAT,!1,0,0),h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null)));let u=o?"\u{1F4C8} Growing":"\u{1F4C9} Shrinking",m=d*160/1048576,b=this.maxCells*160/1048576;console.warn(`[TerminalGL] ${u} buffers: ${m.toFixed(2)}MB \u2192 ${b.toFixed(2)}MB (${d} \u2192 ${this.maxCells} quads)`)}this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.ambientEffectEnabled&&this.ambientEffectCanvas&&(this.ambientEffectCanvas.width=this.canvas.width,this.ambientEffectCanvas.height=this.canvas.height,this.ambientEffectCanvas.style.width=`${this.canvas.width}px`,this.ambientEffectCanvas.style.height=`${this.canvas.height}px`),this.showGrid&&this.gridOverlay&&this.updateGridOverlay(),this.updateCanvasSize()}getCanvas(){return this.canvas}getGridSize(){return{cols:this.cols,rows:this.rows}}getCellWidth(){return this.cellWidth}getCellHeight(){return this.cellHeight}getCurrentScale(){return this.currentScale}getBaseDimensions(){return{width:this.cols*this.cellWidth,height:this.rows*this.cellHeight}}setOnResizeCallback(e){this.onResizeCallback=e}clearOnResizeCallback(){this.onResizeCallback=void 0}setScalingMode(e){this.scalingMode!==e&&(this.scalingMode=e,this.updateCanvasSize())}getScalingMode(){return this.scalingMode}setGrid(e){e.enabled?(this.gridOverlay?this.gridOverlay.setStyle({strokeColor:e.color,lineWidth:e.lineWidth}):this.gridOverlay=new I(this.containerDiv,{strokeColor:e.color??"rgba(144, 24, 24, 1)",lineWidth:e.lineWidth??1,zIndex:10}),this.showGrid=!0,this.gridOverlay.setVisible(!0),this.updateGridOverlay()):(this.showGrid=!1,this.gridOverlay&&this.gridOverlay.setVisible(!1))}isGridEnabled(){return this.showGrid}setAmbientEffect(e){typeof e=="boolean"?this.ambientEffectEnabled=e:(this.ambientEffectEnabled=!0,e.blur!==void 0&&(this.ambientEffectBlur=e.blur),e.scale!==void 0&&(this.ambientEffectScale=e.scale)),this.ambientEffectEnabled&&!this.ambientEffectCanvas&&this.createAmbientEffectCanvas(),this.ambientEffectCanvas&&(this.ambientEffectEnabled?(this.ambientEffectCanvas.style.display="block",this.ambientEffectCanvas.style.filter=`blur(${this.ambientEffectBlur}px)`,this.ambientEffectCanvas.style.transform=`scale(${this.ambientEffectScale})`,this.updateAmbientEffect()):this.ambientEffectCanvas.style.display="none")}createAmbientEffectCanvas(){this.ambientEffectCanvas||(this.ambientEffectCanvas=document.createElement("canvas"),this.ambientEffectCanvas.className="terminalgl-ambient-effect-canvas",this.ambientEffectCanvas.width=this.canvas.width,this.ambientEffectCanvas.height=this.canvas.height,this.ambientEffectCanvas.style.cssText=`
116
+ `,i=this.compileShader(e.VERTEX_SHADER,t),n=this.compileShader(e.FRAGMENT_SHADER,s);if(!i||!n)throw new Error("Shader compilation error");let a=e.createProgram();if(!a)throw new Error("Unable to create WebGL program");if(e.attachShader(a,i),e.attachShader(a,n),e.linkProgram(a),!e.getProgramParameter(a,e.LINK_STATUS)){let l=e.getProgramInfoLog(a);throw new Error("Program linking error: "+l)}this.program=a,this.cachedTextureUniform=!1,this.cachedPaletteUniform=!1,this.aPosition=e.getAttribLocation(a,"aPosition"),this.useInstancing?(this.aInstanceOffset=e.getAttribLocation(a,"aInstanceOffset"),this.aInstanceUVs=e.getAttribLocation(a,"aInstanceUVs"),this.aInstanceColors=e.getAttribLocation(a,"aInstanceColors"),this.uCellSize=e.getUniformLocation(a,"uCellSize"),this.instanceDataBuffer=e.createBuffer(),this.aTexCoord=this.aInstanceOffset,this.aColorIndex=this.aInstanceUVs):(this.aTexCoord=e.getAttribLocation(a,"aTexCoord"),this.aColorIndex=e.getAttribLocation(a,"aColorIndex")),this.uResolution=e.getUniformLocation(a,"uResolution"),this.uTexture=e.getUniformLocation(a,"uTexture"),this.uPalette=e.getUniformLocation(a,"uPalette"),this.positionBuffer=e.createBuffer(),this.texCoordBuffer=e.createBuffer(),this.colorIndexBuffer=e.createBuffer(),this.indexBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderPositions.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderTexCoords.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderColorIndices.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,e.DYNAMIC_DRAW),this.vaoExtension&&(this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(this.aPosition),e.vertexAttribPointer(this.aPosition,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.enableVertexAttribArray(this.aTexCoord),e.vertexAttribPointer(this.aTexCoord,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.enableVertexAttribArray(this.aColorIndex),e.vertexAttribPointer(this.aColorIndex,1,e.FLOAT,!1,0,0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null))),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA),e.viewport(0,0,this.canvas.width,this.canvas.height)}compileShader(e,t){let s=this.gl,i=s.createShader(e);return i?(s.shaderSource(i,t),s.compileShader(i),s.getShaderParameter(i,s.COMPILE_STATUS)?i:(console.error("Shader compilation error:",s.getShaderInfoLog(i)),s.deleteShader(i),null)):null}initGridOverlay(){this.gridOverlay=new I(this.containerDiv,{strokeColor:"rgba(144, 24, 24, 1)",lineWidth:1,zIndex:10}),this.updateGridOverlay()}updateGridOverlay(){if(!this.gridOverlay)return;let e=this.cols*this.cellWidth,t=this.rows*this.cellHeight,s=this.canvas.getBoundingClientRect(),i=this.containerDiv.getBoundingClientRect();this.gridOverlay.setDimensions(this.cols,this.rows,this.cellWidth,this.cellHeight,0,0),this.gridOverlay.setTransform(this.currentScale,e,t,s,i),this.gridOverlay.render()}setBitmapFont(e,t,s,i,n){this.bitmapFont=e,this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(s),this.cellWidth=Math.round(i),this.cellHeight=Math.round(n),this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&(console.warn("[TerminalGL] \u{1F680} Initializing instanced buffers..."),this.initInstancedBuffers());try{this.generateAtlas()}catch(a){throw console.error("[TerminalGL] \u274C Failed to generate atlas:",a),a}this.buildCharCodeMap(),this.precomputeAtlasUVs(),this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.useInstancing||this.precomputeStaticPositions(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}async setImageFont(e,t,s,i,n,a){this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(s),this.cellWidth=Math.round(i),this.cellHeight=Math.round(n),this.atlasColumns=B(a);let l=F(a);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&(console.warn("[TerminalGL] \u{1F680} Initializing instanced buffers for ImageFont..."),this.initInstancedBuffers()),await this.loadImageFontAtlas(e),this.charCodeToAtlasIndex.fill(65535);for(let o=0;o<=l;o++)this.charCodeToAtlasIndex[o]=o;this.precomputeImageFontUVs(a),this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.useInstancing||this.precomputeStaticPositions(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}async loadImageFontAtlas(e){return new Promise((t,s)=>{let i=new Uint8Array(e),n=new Blob([i],{type:"image/png"}),a=URL.createObjectURL(n),l=new Image;l.onload=()=>{URL.revokeObjectURL(a),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=l.width,this.atlasCanvas.height=l.height;let o=this.atlasCanvas.getContext("2d");if(!o){s(new Error("Failed to create 2D context for atlas"));return}o.drawImage(l,0,0),this.cachedAtlasWidth=l.width,this.cachedAtlasHeight=l.height,this.createAtlasTexture(),t()},l.onerror=()=>{URL.revokeObjectURL(a),s(new Error("Failed to load PNG image for ImageFont atlas"))},l.src=a})}precomputeImageFontUVs(e){let t=e*256;this.atlasUVs=new Float32Array(t*4);let s=this.cachedAtlasWidth,i=this.cachedAtlasHeight,n=.5/s,a=.5/i;for(let l=0;l<t;l++){let{col:o,row:c}=L(l,e),d=(o*this.charWidth+n)/s,h=(c*this.charHeight+a)/i,m=((o+1)*this.charWidth-n)/s,b=((c+1)*this.charHeight-a)/i,v=l*4;this.atlasUVs[v]=d,this.atlasUVs[v+1]=h,this.atlasUVs[v+2]=m,this.atlasUVs[v+3]=b}}generateAtlas(){if(!this.bitmapFont)return;let e=Array.from(this.bitmapFont.keys()).sort((o,c)=>o-c),t=e.length;this.atlasColumns=Math.ceil(Math.sqrt(t));let s=Math.ceil(t/this.atlasColumns),i=this.atlasColumns*this.charWidth,n=s*this.charHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=i,this.atlasCanvas.height=n;let a=this.atlasCanvas.getContext("2d");if(!a)throw new Error("Unable to create 2D context for atlas");a.clearRect(0,0,i,n),a.fillStyle="#ffffff";let l=0;for(let o of e){let c=this.bitmapFont.get(o);if(!c)continue;let d=l%this.atlasColumns,h=Math.floor(l/this.atlasColumns),m=d*this.charWidth,b=h*this.charHeight;for(let v=0;v<Math.min(c.length,this.charHeight);v++){let u=c[v];for(let g=0;g<this.charWidth;g++){let E=1<<7-g;u&E&&a.fillRect(m+g,b+v,1,1)}}l++}this.createAtlasTexture()}buildCharCodeMap(){if(!this.bitmapFont)return;this.charCodeToAtlasIndex.fill(65535);let e=Array.from(this.bitmapFont.keys()).sort((t,s)=>t-s);for(let t=0;t<e.length;t++)this.charCodeToAtlasIndex[e[t]]=t}precomputeAtlasUVs(){if(!this.bitmapFont)return;let e=this.bitmapFont.size;this.atlasUVs=new Float32Array(e*4),this.cachedAtlasWidth=this.atlasColumns*this.charWidth,this.cachedAtlasHeight=Math.ceil(e/this.atlasColumns)*this.charHeight;let t=this.cachedAtlasWidth,s=this.cachedAtlasHeight,i=.5/t,n=.5/s;for(let a=0;a<e;a++){let l=a%this.atlasColumns,o=Math.floor(a/this.atlasColumns),c=(l*this.charWidth+i)/t,d=(o*this.charHeight+n)/s,h=((l+1)*this.charWidth-i)/t,m=((o+1)*this.charHeight-n)/s,b=a*4;this.atlasUVs[b]=c,this.atlasUVs[b+1]=d,this.atlasUVs[b+2]=h,this.atlasUVs[b+3]=m}}createAtlasTexture(){if(this.atlasCanvas)try{let e=this.gl,t=e.createTexture();if(!t)throw new Error("Unable to create texture");e.bindTexture(e.TEXTURE_2D,t),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,this.atlasCanvas),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),this.atlasTexture=t}catch(e){throw console.error("[TerminalGL] \u274C Failed to create atlas texture:",e),e}}clear(){let e=this.gl;e&&e.clear(e.COLOR_BUFFER_BIT)}parseColor(e){if(e.startsWith("#")){let t=e.slice(1),s=0,i=0,n=0;return t.length===3?(s=parseInt(t[0]+t[0],16),i=parseInt(t[1]+t[1],16),n=parseInt(t[2]+t[2],16)):t.length===6&&(s=parseInt(t.slice(0,2),16),i=parseInt(t.slice(2,4),16),n=parseInt(t.slice(4,6),16)),[s/255,i/255,n/255,1]}if(e.startsWith("rgb")){let t=e.match(/rgba?\(([^)]+)\)/);if(t){let s=t[1].split(",").map(i=>parseFloat(i.trim()));return[s[0]/255,s[1]/255,s[2]/255,s[3]!==void 0?s[3]:1]}}return[1,1,1,1]}setupResizeObserver(){if(!(typeof ResizeObserver>"u"))try{this.resizeObserver=new ResizeObserver(()=>{try{this.updateCanvasSize()}catch(e){console.error("[TerminalGL] \u274C Error in resize callback:",e)}}),this.resizeObserver.observe(this.parentElement),this.updateCanvasSize()}catch(e){console.error("[TerminalGL] \u274C Failed to setup ResizeObserver:",e)}}updateCanvasSize(){let e=this.parentElement.clientWidth,t=this.parentElement.clientHeight;if(e===0||t===0)return;let s=this.cols*this.cellWidth,i=this.rows*this.cellHeight;if(s===0||i===0)return;let n=e/s,a=t/i,l=Math.min(n,a),o;switch(this.scalingMode){case x.ScalingMode.Integer:o=Math.max(1,Math.floor(l));break;case x.ScalingMode.Half:o=Math.max(1,Math.floor(l*2)/2);break;case x.ScalingMode.Quarter:o=Math.max(1,Math.floor(l*4)/4);break;case x.ScalingMode.Eighth:o=Math.max(1,Math.floor(l*8)/8);break;case x.ScalingMode.Responsive:o=1;break;case x.ScalingMode.None:default:o=Math.max(.1,l);break}if(this.canvas.style.transform=`scale(${o})`,this.ambientEffectEnabled&&this.ambientEffectCanvas){let c=o*this.ambientEffectScale;this.ambientEffectCanvas.style.transform=`scale(${c})`}this.currentScale=o,this.onResizeCallback&&this.onResizeCallback(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}updateAmbientEffect(){!this.ambientEffectCanvas||!this.ambientEffectCtx||this.ambientEffectCtx.drawImage(this.canvas,0,0)}setPalette(e){let t=0;for(let s=0;s<Math.min(e.length,256);s++){let i=e[s];t=(t<<5)-t+i.r,t=(t<<5)-t+i.g,t=(t<<5)-t+i.b,t=(t<<5)-t+i.a,t=t|0}if(t!==this.paletteHash){this.paletteHash=t;for(let s=0;s<e.length&&s<256;s++){let i=e[s],n=s*4;this.paletteFloat[n]=i.r/255,this.paletteFloat[n+1]=i.g/255,this.paletteFloat[n+2]=i.b/255,this.paletteFloat[n+3]=i.a/255}this.updatePaletteTexture()}}updatePaletteTexture(){try{let e=this.gl;this.paletteTexture||(this.paletteTexture=e.createTexture()),e.bindTexture(e.TEXTURE_2D,this.paletteTexture);let t=new Uint8Array(256*4);for(let s=0;s<256;s++){let i=s*4;t[i]=this.paletteFloat[i]*255,t[i+1]=this.paletteFloat[i+1]*255,t[i+2]=this.paletteFloat[i+2]*255,t[i+3]=this.paletteFloat[i+3]*255}e.texImage2D(e.TEXTURE_2D,0,e.RGBA,256,1,0,e.RGBA,e.UNSIGNED_BYTE,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null)}catch(e){throw console.error("[TerminalGL] \u274C Failed to update palette texture:",e),e}}renderDisplayData(e){try{if(!this.isReady()){console.warn("[TerminalGL] \u26A0\uFE0F Not ready: font not loaded yet");return}(e.width!==this.cols||e.height!==this.rows)&&this.resize(e.width,e.height),this.renderDirect(e),this.ambientEffectEnabled&&this.ambientEffectCanvas&&this.ambientEffectCtx&&this.updateAmbientEffect()}catch(t){console.error("[TerminalGL] \u274C Error rendering display data:",t)}}renderDirect(e){let t=this.gl;if(!this.staticPositionsInitialized&&!this.useInstancing&&this.precomputeStaticPositions(),this.canvasBgColor!==null){let s=this.parseColor(this.canvasBgColor);t.clearColor(s[0],s[1],s[2],s[3])}else t.clearColor(0,0,0,0);t.clear(t.COLOR_BUFFER_BIT),this.useInstancing?this.renderInstanced(e):this.renderDirectBuffers(e)}renderInstanced(e){let t=this.gl,s=this.instancedExtension;if(!this.instanceData||this.instanceData.length===0){console.warn("[TerminalGL] \u26A0\uFE0F Instance data not initialized, falling back to standard rendering"),this.renderDirectBuffers(e);return}let i=0,n=this.instanceData.length/8,a=e.width*e.height*2;if(a>n){console.error(`[TerminalGL] \u274C Instance buffer too small! Need ${a}, have ${n}. Display size: ${e.width}\xD7${e.height}, buffer was sized for smaller terminal.`),this.renderDirectBuffers(e);return}for(let o=0;o<e.height;o++)for(let c=0;c<e.width;c++){let d=e.cells[o*e.width+c],h=d.bgColorIndex,m=d.fgColorIndex,b=this.canvasBgColor!==null&&h===255,v=d.char===" "||m===255;if(!b){if(i>=n){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${i}, max=${n}`);break}let u=i*8;this.instanceData[u]=c,this.instanceData[u+1]=o,this.instanceData[u+2]=0,this.instanceData[u+3]=0,this.instanceData[u+4]=0,this.instanceData[u+5]=0,this.instanceData[u+6]=h,this.instanceData[u+7]=0,i++}if(!v){let u=d.char.charCodeAt(0),g=this.charCodeToAtlasIndex[u];if(g!==65535){if(i>=n){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${i}, max=${n}`);break}let E=g*4,p=i*8;this.instanceData[p]=c,this.instanceData[p+1]=o,this.instanceData[p+2]=this.atlasUVs[E],this.instanceData[p+3]=this.atlasUVs[E+1],this.instanceData[p+4]=this.atlasUVs[E+2],this.instanceData[p+5]=this.atlasUVs[E+3],this.instanceData[p+6]=0,this.instanceData[p+7]=m,i++}}}if(i===0){console.warn("[TerminalGL] \u26A0\uFE0F No instances to draw (all cells skipped)");return}t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.instanceData.subarray(0,i*8)),t.useProgram(this.program),t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.enableVertexAttribArray(this.aPosition),t.vertexAttribPointer(this.aPosition,2,t.FLOAT,!1,0,0),s.vertexAttribDivisorANGLE(this.aPosition,0),t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer);let l=8*Float32Array.BYTES_PER_ELEMENT;t.enableVertexAttribArray(this.aInstanceOffset),t.vertexAttribPointer(this.aInstanceOffset,2,t.FLOAT,!1,l,0),s.vertexAttribDivisorANGLE(this.aInstanceOffset,1),t.enableVertexAttribArray(this.aInstanceUVs),t.vertexAttribPointer(this.aInstanceUVs,4,t.FLOAT,!1,l,2*Float32Array.BYTES_PER_ELEMENT),s.vertexAttribDivisorANGLE(this.aInstanceUVs,1),t.enableVertexAttribArray(this.aInstanceColors),t.vertexAttribPointer(this.aInstanceColors,2,t.FLOAT,!1,l,6*Float32Array.BYTES_PER_ELEMENT),s.vertexAttribDivisorANGLE(this.aInstanceColors,1),t.uniform2f(this.uResolution,this.canvas.width,this.canvas.height),t.uniform2f(this.uCellSize,this.cellWidth,this.cellHeight),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.atlasTexture),t.uniform1i(this.uTexture,0),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,this.paletteTexture),t.uniform1i(this.uPalette,1),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer),s.drawElementsInstancedANGLE(t.TRIANGLES,6,t.UNSIGNED_SHORT,0,i),s.vertexAttribDivisorANGLE(this.aPosition,0),s.vertexAttribDivisorANGLE(this.aInstanceOffset,0),s.vertexAttribDivisorANGLE(this.aInstanceUVs,0),s.vertexAttribDivisorANGLE(this.aInstanceColors,0)}renderDirectBuffers(e){let t=this.gl,s=e.width*e.height,i=s*2;if(i>this.maxCells){console.error(`[TerminalGL] \u274C Buffer overflow detected! Trying to render ${i} quads but buffer capacity is ${this.maxCells}. This should not happen - resize() should have reallocated.`);return}let n=0,a=0,l=e.cells,o=s;for(let v=0;v<o;v++){let u=l[v],g=u.bgColorIndex,p=this.canvasBgColor!==null&&g===255?255:g,w=0;for(let T=0;T<4;T++)this.renderTexCoords[n++]=w,this.renderTexCoords[n++]=w,this.renderColorIndices[a++]=p;let A=u.fgColorIndex,S=u.char;if(S===" "||A===255)for(let T=0;T<4;T++)this.renderTexCoords[n++]=0,this.renderTexCoords[n++]=0,this.renderColorIndices[a++]=255;else{let T=S.charCodeAt(0),P=this.charCodeToAtlasIndex[T];if(P!==65535){let R=P*4,G=this.atlasUVs[R],W=this.atlasUVs[R+1],O=this.atlasUVs[R+2],H=this.atlasUVs[R+3];this.renderTexCoords[n++]=G,this.renderTexCoords[n++]=W,this.renderColorIndices[a++]=A,this.renderTexCoords[n++]=O,this.renderTexCoords[n++]=W,this.renderColorIndices[a++]=A,this.renderTexCoords[n++]=G,this.renderTexCoords[n++]=H,this.renderColorIndices[a++]=A,this.renderTexCoords[n++]=O,this.renderTexCoords[n++]=H,this.renderColorIndices[a++]=A}else for(let R=0;R<4;R++)this.renderTexCoords[n++]=0,this.renderTexCoords[n++]=0,this.renderColorIndices[a++]=255}}(n!==o*2*4*2||a!==o*2*4)&&console.error("[TerminalGL] \u274C Buffer index mismatch!",{texIdx:n,colorIdx:a,expected:o*2*4}),t.useProgram(this.program),this.vao&&this.vaoExtension?(this.vaoExtension.bindVertexArrayOES(this.vao),t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,n)),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,a))):(t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.enableVertexAttribArray(this.aPosition),t.vertexAttribPointer(this.aPosition,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,n)),t.enableVertexAttribArray(this.aTexCoord),t.vertexAttribPointer(this.aTexCoord,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,a)),t.enableVertexAttribArray(this.aColorIndex),t.vertexAttribPointer(this.aColorIndex,1,t.FLOAT,!1,0,0));let c=this.canvas.width,d=this.canvas.height;(this.cachedResolution[0]!==c||this.cachedResolution[1]!==d)&&(t.uniform2f(this.uResolution,c,d),this.cachedResolution[0]=c,this.cachedResolution[1]=d),this.cachedTextureUnit!==0&&(t.activeTexture(t.TEXTURE0),this.cachedTextureUnit=0),t.bindTexture(t.TEXTURE_2D,this.atlasTexture),this.cachedTextureUniform||(t.uniform1i(this.uTexture,0),this.cachedTextureUniform=!0),this.cachedPaletteUnit!==1&&(t.activeTexture(t.TEXTURE1),this.cachedPaletteUnit=1),t.bindTexture(t.TEXTURE_2D,this.paletteTexture),this.cachedPaletteUniform||(t.uniform1i(this.uPalette,1),this.cachedPaletteUniform=!0),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer);let m=e.width*e.height*2*6,b=this.useUint16Indices?t.UNSIGNED_SHORT:t.UNSIGNED_INT;t.drawElements(t.TRIANGLES,m,b,0)}resize(e,t){if(!Number.isInteger(e)||e<=0){console.error(`[TerminalGL] \u274C Invalid cols: ${e}. Must be positive integer.`);return}if(!Number.isInteger(t)||t<=0){console.error(`[TerminalGL] \u274C Invalid rows: ${t}. Must be positive integer.`);return}if(e===this.cols&&t===this.rows)return;let s=e*t,i=this.useInstancing?262144:this.useUint16Indices?8191:262144;if(s>i){let d=Math.floor(Math.sqrt(i));console.error(`[TerminalGL] \u274C Cannot resize to ${e}\xD7${t} (${s} cells). Device limit: ${i} cells (max ~${d}\xD7${d}). ${!this.useInstancing&&this.useUint16Indices?"Device lacks OES_element_index_uint extension.":""}`);return}let n=U.checkCompatibility();s>n.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Resizing to ${e}\xD7${t} (${s} cells) exceeds recommended limit (${n.recommendedMaxCells} cells). Performance may degrade.`),this.cols=e,this.rows=t,this.staticPositionsInitialized=!1;let a=this.cols*this.rows*2,l=Math.ceil(a*1.5),o=a>this.maxCells,c=this.maxCells>l*4;if(console.warn(`[TerminalGL] \u{1F4D0} resize check: cols=${e}, rows=${t}, newMaxCells=${a}, this.maxCells=${this.maxCells}, needGrow=${o}, needShrink=${c}`),o||c){let d=this.maxCells;if(this.maxCells=l,console.warn(`[TerminalGL] \u{1F4D0} resize realloc: ${d} \u2192 ${this.maxCells} (needGrow=${o}, needShrink=${c})`),this.renderPositions=new Float32Array(this.maxCells*4*2),this.renderTexCoords=new Float32Array(this.maxCells*4*2),this.renderColorIndices=new Float32Array(this.maxCells*4),this.useUint16Indices?this.renderIndices=new Uint16Array(this.maxCells*6):this.renderIndices=new Uint32Array(this.maxCells*6),this.useInstancing&&this.instanceDataBuffer){this.instanceData=new Float32Array(this.maxCells*8);let u=this.gl;u.bindBuffer(u.ARRAY_BUFFER,this.instanceDataBuffer),u.bufferData(u.ARRAY_BUFFER,this.instanceData.byteLength,u.DYNAMIC_DRAW)}let h=this.gl;this.useInstancing||(h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderPositions.byteLength,h.DYNAMIC_DRAW)),h.bindBuffer(h.ARRAY_BUFFER,this.texCoordBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderTexCoords.byteLength,h.DYNAMIC_DRAW),h.bindBuffer(h.ARRAY_BUFFER,this.colorIndexBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderColorIndices.byteLength,h.DYNAMIC_DRAW),this.useInstancing||(h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),h.bufferData(h.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,h.DYNAMIC_DRAW)),this.vaoExtension&&this.vao&&(this.vaoExtension.deleteVertexArrayOES(this.vao),this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.enableVertexAttribArray(this.aPosition),h.vertexAttribPointer(this.aPosition,2,h.FLOAT,!1,0,0),h.bindBuffer(h.ARRAY_BUFFER,this.texCoordBuffer),h.enableVertexAttribArray(this.aTexCoord),h.vertexAttribPointer(this.aTexCoord,2,h.FLOAT,!1,0,0),h.bindBuffer(h.ARRAY_BUFFER,this.colorIndexBuffer),h.enableVertexAttribArray(this.aColorIndex),h.vertexAttribPointer(this.aColorIndex,1,h.FLOAT,!1,0,0),h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null)));let m=o?"\u{1F4C8} Growing":"\u{1F4C9} Shrinking",b=d*160/1048576,v=this.maxCells*160/1048576;console.warn(`[TerminalGL] ${m} buffers: ${b.toFixed(2)}MB \u2192 ${v.toFixed(2)}MB (${d} \u2192 ${this.maxCells} quads)`)}this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.canvas.style.width=`${this.canvas.width}px`,this.canvas.style.height=`${this.canvas.height}px`,this.ambientEffectEnabled&&this.ambientEffectCanvas&&(this.ambientEffectCanvas.width=this.canvas.width,this.ambientEffectCanvas.height=this.canvas.height,this.ambientEffectCanvas.style.width=`${this.canvas.width}px`,this.ambientEffectCanvas.style.height=`${this.canvas.height}px`),this.showGrid&&this.gridOverlay&&this.updateGridOverlay(),this.updateCanvasSize()}getCanvas(){return this.canvas}getGridSize(){return{cols:this.cols,rows:this.rows}}getCellWidth(){return this.cellWidth}getCellHeight(){return this.cellHeight}getCurrentScale(){return this.currentScale}getBaseDimensions(){return{width:this.cols*this.cellWidth,height:this.rows*this.cellHeight}}setOnResizeCallback(e){this.onResizeCallback=e}clearOnResizeCallback(){this.onResizeCallback=void 0}getAvailableSize(){return{width:this.parentElement.clientWidth,height:this.parentElement.clientHeight}}setScalingMode(e){this.scalingMode!==e&&(this.scalingMode=e,this.updateCanvasSize())}getScalingMode(){return this.scalingMode}setCellSize(e,t){let s=Math.max(1,Math.min(255,Math.round(e))),i=Math.max(1,Math.min(255,Math.round(t)));this.cellWidth===s&&this.cellHeight===i||(this.cellWidth=s,this.cellHeight=i,this.charWidth=s,this.charHeight=i,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.fontLoaded&&this.generateAtlas(),this.useInstancing&&this.initInstancedBuffers(),this.updateCanvasSize())}getCellSize(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getMaxCells(){return this.useInstancing?262144:this.useUint16Indices?8191:262144}setGrid(e){e.enabled?(this.gridOverlay?this.gridOverlay.setStyle({strokeColor:e.color,lineWidth:e.lineWidth}):this.gridOverlay=new I(this.containerDiv,{strokeColor:e.color??"rgba(144, 24, 24, 1)",lineWidth:e.lineWidth??1,zIndex:10}),this.showGrid=!0,this.gridOverlay.setVisible(!0),this.updateGridOverlay()):(this.showGrid=!1,this.gridOverlay&&this.gridOverlay.setVisible(!1))}isGridEnabled(){return this.showGrid}setAmbientEffect(e){typeof e=="boolean"?this.ambientEffectEnabled=e:(this.ambientEffectEnabled=!0,e.blur!==void 0&&(this.ambientEffectBlur=e.blur),e.scale!==void 0&&(this.ambientEffectScale=e.scale)),this.ambientEffectEnabled&&!this.ambientEffectCanvas&&this.createAmbientEffectCanvas(),this.ambientEffectCanvas&&(this.ambientEffectEnabled?(this.ambientEffectCanvas.style.display="block",this.ambientEffectCanvas.style.filter=`blur(${this.ambientEffectBlur}px)`,this.ambientEffectCanvas.style.transform=`scale(${this.ambientEffectScale})`,this.updateAmbientEffect()):this.ambientEffectCanvas.style.display="none")}createAmbientEffectCanvas(){this.ambientEffectCanvas||(this.ambientEffectCanvas=document.createElement("canvas"),this.ambientEffectCanvas.className="terminalgl-ambient-effect-canvas",this.ambientEffectCanvas.width=this.canvas.width,this.ambientEffectCanvas.height=this.canvas.height,this.ambientEffectCanvas.style.cssText=`
117
117
  display: block !important;
118
118
  position: absolute !important;
119
119
  width: ${this.canvas.width}px !important;
@@ -124,4 +124,4 @@
124
124
  transform: scale(${this.ambientEffectScale}) !important;
125
125
  pointer-events: none !important;
126
126
  z-index: 0 !important;
127
- `,this.ambientEffectCtx=this.ambientEffectCanvas.getContext("2d",{alpha:!0}),this.containerDiv.insertBefore(this.ambientEffectCanvas,this.canvas),console.warn("[TerminalGL] \u{1F308} ambient effect canvas created dynamically"))}isAmbientEffectEnabled(){return this.ambientEffectEnabled}getAmbientEffectConfig(){return{enabled:this.ambientEffectEnabled,blur:this.ambientEffectBlur,scale:this.ambientEffectScale}}getCols(){return this.cols}getRows(){return this.rows}isReady(){return!!(this.fontLoaded&&this.atlasTexture&&this.program)}destroy(){this.dispose()}dispose(){this.resizeObserver&&this.resizeObserver.disconnect();let e=this.gl;this.program&&e.deleteProgram(this.program),this.positionBuffer&&e.deleteBuffer(this.positionBuffer),this.texCoordBuffer&&e.deleteBuffer(this.texCoordBuffer),this.colorIndexBuffer&&e.deleteBuffer(this.colorIndexBuffer),this.indexBuffer&&e.deleteBuffer(this.indexBuffer),this.instanceDataBuffer&&e.deleteBuffer(this.instanceDataBuffer),this.atlasTexture&&e.deleteTexture(this.atlasTexture),this.paletteTexture&&e.deleteTexture(this.paletteTexture),this.vao&&this.vaoExtension&&this.vaoExtension.deleteVertexArrayOES(this.vao);let t=e.getExtension("WEBGL_lose_context");t&&t.loseContext(),this.atlasCanvas&&(this.atlasCanvas.width=0,this.atlasCanvas.height=0,this.atlasCanvas=void 0),this.containerDiv.parentElement&&this.containerDiv.parentElement.removeChild(this.containerDiv),this.canvas.width=0,this.canvas.height=0,this.ambientEffectCanvas&&(this.ambientEffectCanvas.width=0,this.ambientEffectCanvas.height=0,this.ambientEffectCanvas=null),this.gridOverlay&&(this.gridOverlay.destroy(),this.gridOverlay=void 0),this.renderPositions=new Float32Array(0),this.renderTexCoords=new Float32Array(0),this.renderColorIndices=new Float32Array(0),this.renderIndices=new Uint32Array(0),this.paletteFloat=new Float32Array(0),this.atlasUVs=new Float32Array(0),this.instanceData=new Float32Array(0),this.templateQuadPositions=new Float32Array(0),this.templateQuadIndices=new Uint16Array(0)}};A(B,"TerminalGL");var D=B;var M=["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff","#080808","#121212","#1c1c1c","#262626","#303030","#3a3a3a","#444444","#4e4e4e","#585858","#626262","#6c6c6c","#767676","#808080","#8a8a8a","#949494","#9e9e9e","#a80000","#00a800","#a8a800","#0000a8","#a800a8","#00a8a8","#a8a8a8","#545454","#fc5454","#54fc54","#fcfc54","#5454fc","#fc54fc","#54fcfc","#fcfcfc","#000000",...Array(192).fill("#808080")];function k(f,e=M){return f<0||f>=e.length?"#ff00ff":e[f]}A(k,"paletteIndexToColor");function V(f,e=M){let t=e.indexOf(f.toLowerCase());return t>=0?t:0}A(V,"colorToPaletteIndex");
127
+ `,this.ambientEffectCtx=this.ambientEffectCanvas.getContext("2d",{alpha:!0}),this.containerDiv.insertBefore(this.ambientEffectCanvas,this.canvas),console.warn("[TerminalGL] \u{1F308} ambient effect canvas created dynamically"))}isAmbientEffectEnabled(){return this.ambientEffectEnabled}getAmbientEffectConfig(){return{enabled:this.ambientEffectEnabled,blur:this.ambientEffectBlur,scale:this.ambientEffectScale}}getCols(){return this.cols}getRows(){return this.rows}isReady(){return!!(this.fontLoaded&&this.atlasTexture&&this.program)}destroy(){this.dispose()}dispose(){this.resizeObserver&&this.resizeObserver.disconnect();let e=this.gl;this.program&&e.deleteProgram(this.program),this.positionBuffer&&e.deleteBuffer(this.positionBuffer),this.texCoordBuffer&&e.deleteBuffer(this.texCoordBuffer),this.colorIndexBuffer&&e.deleteBuffer(this.colorIndexBuffer),this.indexBuffer&&e.deleteBuffer(this.indexBuffer),this.instanceDataBuffer&&e.deleteBuffer(this.instanceDataBuffer),this.atlasTexture&&e.deleteTexture(this.atlasTexture),this.paletteTexture&&e.deleteTexture(this.paletteTexture),this.vao&&this.vaoExtension&&this.vaoExtension.deleteVertexArrayOES(this.vao);let t=e.getExtension("WEBGL_lose_context");t&&t.loseContext(),this.atlasCanvas&&(this.atlasCanvas.width=0,this.atlasCanvas.height=0,this.atlasCanvas=void 0),this.containerDiv.parentElement&&this.containerDiv.parentElement.removeChild(this.containerDiv),this.canvas.width=0,this.canvas.height=0,this.ambientEffectCanvas&&(this.ambientEffectCanvas.width=0,this.ambientEffectCanvas.height=0,this.ambientEffectCanvas=null),this.gridOverlay&&(this.gridOverlay.destroy(),this.gridOverlay=void 0),this.renderPositions=new Float32Array(0),this.renderTexCoords=new Float32Array(0),this.renderColorIndices=new Float32Array(0),this.renderIndices=new Uint32Array(0),this.paletteFloat=new Float32Array(0),this.atlasUVs=new Float32Array(0),this.instanceData=new Float32Array(0),this.templateQuadPositions=new Float32Array(0),this.templateQuadIndices=new Uint16Array(0)}};C(U,"TerminalGL");var _=U;var D=["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff","#080808","#121212","#1c1c1c","#262626","#303030","#3a3a3a","#444444","#4e4e4e","#585858","#626262","#6c6c6c","#767676","#808080","#8a8a8a","#949494","#9e9e9e","#a80000","#00a800","#a8a800","#0000a8","#a800a8","#00a8a8","#a8a8a8","#545454","#fc5454","#54fc54","#fcfc54","#5454fc","#fc54fc","#54fcfc","#fcfcfc","#000000",...Array(192).fill("#808080")];function $(f,e=D){return f<0||f>=e.length?"#ff00ff":e[f]}C($,"paletteIndexToColor");function V(f,e=D){let t=e.indexOf(f.toLowerCase());return t>=0?t:0}C(V,"colorToPaletteIndex");
@@ -227,6 +227,10 @@ declare class TerminalGL implements IRenderer {
227
227
  private instanceData;
228
228
  private templateQuadPositions;
229
229
  private templateQuadIndices;
230
+ private aInstanceOffset;
231
+ private aInstanceUVs;
232
+ private aInstanceColors;
233
+ private uCellSize;
230
234
  constructor(parentDiv: HTMLDivElement, options: TerminalGLOptions);
231
235
  /**
232
236
  * 🚀 INSTANCING: Initialize template quad and instance buffers
@@ -524,6 +528,17 @@ declare class TerminalGL implements IRenderer {
524
528
  * Clear the resize callback
525
529
  */
526
530
  clearOnResizeCallback(): void;
531
+ /**
532
+ * Get the available size from the parent container.
533
+ * This is the actual pixel space available for rendering.
534
+ * Useful in Responsive mode to calculate how many cells can fit.
535
+ *
536
+ * @returns Object with width and height in pixels
537
+ */
538
+ getAvailableSize(): {
539
+ width: number;
540
+ height: number;
541
+ };
527
542
  /**
528
543
  * Set scaling mode
529
544
  *
@@ -539,6 +554,36 @@ declare class TerminalGL implements IRenderer {
539
554
  * Get current scaling mode
540
555
  */
541
556
  getScalingMode(): ScalingMode;
557
+ /**
558
+ * Set cell dimensions in pixels
559
+ *
560
+ * Changes the native pixel size of each character cell.
561
+ * This will trigger a canvas resize and buffer reallocation.
562
+ *
563
+ * @param cellWidth - Cell width in pixels (1-255)
564
+ * @param cellHeight - Cell height in pixels (1-255)
565
+ */
566
+ setCellSize(cellWidth: number, cellHeight: number): void;
567
+ /**
568
+ * Get current cell size
569
+ */
570
+ getCellSize(): {
571
+ cellWidth: number;
572
+ cellHeight: number;
573
+ };
574
+ /**
575
+ * Get the maximum number of cells this renderer can handle
576
+ *
577
+ * This depends on device capabilities:
578
+ * - With instanced rendering: ~262,144 cells (limited by GPU memory)
579
+ * - With Uint32 indices: ~262,144 cells
580
+ * - With Uint16 indices only: ~8,191 cells (~90×90)
581
+ *
582
+ * Use this in responsive mode to clamp calculated cols/rows.
583
+ *
584
+ * @returns Maximum cells supported by this renderer
585
+ */
586
+ getMaxCells(): number;
542
587
  /**
543
588
  * Enable or configure debug grid overlay
544
589
  *
package/dist/gl/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
- var k=Object.defineProperty;var V=(b,e,t)=>e in b?k(b,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):b[e]=t;var C=(b,e)=>k(b,"name",{value:e,configurable:!0});var n=(b,e,t)=>(V(b,typeof e!="symbol"?e+"":e,t),t);var F=class F{constructor(e,t){n(this,"canvas");n(this,"ctx");n(this,"container");n(this,"cols",0);n(this,"rows",0);n(this,"cellWidth",0);n(this,"cellHeight",0);n(this,"offsetX",0);n(this,"offsetY",0);n(this,"strokeColor","rgba(80, 80, 80, 0.4)");n(this,"lineWidth",1);this.container=e,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let r=t?.zIndex??10;this.canvas.style.cssText=`
1
+ var $=Object.defineProperty;var V=(v,e,t)=>e in v?$(v,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):v[e]=t;var E=(v,e)=>$(v,"name",{value:e,configurable:!0});var r=(v,e,t)=>(V(v,typeof e!="symbol"?e+"":e,t),t);var B=class B{constructor(e,t){r(this,"canvas");r(this,"ctx");r(this,"container");r(this,"cols",0);r(this,"rows",0);r(this,"cellWidth",0);r(this,"cellHeight",0);r(this,"offsetX",0);r(this,"offsetY",0);r(this,"strokeColor","rgba(80, 80, 80, 0.4)");r(this,"lineWidth",1);this.container=e,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let s=t?.zIndex??10;this.canvas.style.cssText=`
2
2
  display: block !important;
3
3
  position: absolute !important;
4
4
  pointer-events: none !important;
5
5
  image-rendering: pixelated !important;
6
6
  image-rendering: crisp-edges !important;
7
- z-index: ${r} !important;
8
- `,this.container.appendChild(this.canvas);let i=this.canvas.getContext("2d");if(!i)throw new Error("[GridOverlay] Impossible de cr\xE9er le contexte 2D");this.ctx=i,t&&(t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth))}setDimensions(e,t,r,i,s=0,a=0){this.cols=e,this.rows=t,this.cellWidth=r,this.cellHeight=i,this.offsetX=s,this.offsetY=a}setCanvasSize(e,t){this.canvas.width=e,this.canvas.height=t,this.ctx.setTransform(1,0,0,1,0,0)}setStyle(e){e.strokeColor&&(this.strokeColor=e.strokeColor),e.lineWidth!==void 0&&(this.lineWidth=e.lineWidth)}setTransform(e,t,r,i,s){let a=i.left-s.left,l=i.top-s.top,o=i.width,c=i.height;(this.canvas.width!==o||this.canvas.height!==c)&&(this.canvas.width=o,this.canvas.height=c);let d=this.canvas.style;d.width=`${o}px`,d.height=`${c}px`,d.left=`${a}px`,d.top=`${l}px`}render(){if(!this.ctx)return;let e=this.cols*this.cellWidth,t=this.rows*this.cellHeight,r=e>0?this.canvas.width/e:1,i=t>0?this.canvas.height/t:1,s=Math.min(r,i),a=this.cellWidth*s,l=this.cellHeight*s,o=this.cols*a,c=this.rows*l,d=this.offsetX*s,h=this.offsetY*s;if(!(o===0||c===0)){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.strokeStyle=this.strokeColor,this.ctx.lineWidth=Math.max(1,this.lineWidth*s),this.ctx.beginPath();for(let f=0;f<=this.cols;f++){let u=d+f*a+.5;this.ctx.moveTo(u,h),this.ctx.lineTo(u,h+c)}for(let f=0;f<=this.rows;f++){let u=h+f*l+.5;this.ctx.moveTo(d,u),this.ctx.lineTo(d+o,u)}this.ctx.stroke()}}update(e,t,r,i,s,a,l=0,o=0){this.setDimensions(e,t,r,i,l,o),this.setCanvasSize(s,a),this.render()}setVisible(e){this.canvas.style.display=e?"block":"none"}destroy(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}};C(F,"GridOverlay");var I=F;function L(b){return Math.sqrt(b)*16}C(L,"getAtlasColumns");function _(b){return b*256-1}C(_,"getMaxCharCode");function D(b,e){let t=Math.floor(b/256),r=b%256,i=Math.sqrt(e),s=t%i,a=Math.floor(t/i),l=r%16,o=Math.floor(r/16);return{col:s*16+l,row:a*16+o}}C(D,"getCharGridPosition");import{POST_PROCESS_DEFAULTS as B,ScalingMode as T}from"@utsp/types";var U=class U{constructor(e,t){n(this,"canvas");n(this,"gl");n(this,"parentElement");n(this,"containerDiv");n(this,"cols");n(this,"rows");n(this,"charWidth");n(this,"charHeight");n(this,"cellWidth",8);n(this,"cellHeight",8);n(this,"glyphOffsetX",0);n(this,"glyphOffsetY",0);n(this,"canvasBgColor");n(this,"showGrid");n(this,"supportsUint32Indices",!1);n(this,"useUint16Indices",!1);n(this,"gridOverlay");n(this,"bitmapFont");n(this,"atlasTexture",null);n(this,"atlasCanvas");n(this,"atlasColumns",0);n(this,"fontLoaded",!1);n(this,"paletteTexture",null);n(this,"program",null);n(this,"positionBuffer",null);n(this,"texCoordBuffer",null);n(this,"colorIndexBuffer",null);n(this,"indexBuffer",null);n(this,"aPosition");n(this,"aTexCoord");n(this,"aColorIndex");n(this,"uResolution",null);n(this,"uTexture",null);n(this,"uPalette",null);n(this,"resizeObserver");n(this,"charCodeToAtlasIndex",new Uint16Array(65536).fill(65535));n(this,"atlasUVs",new Float32Array(0));n(this,"cachedAtlasWidth",0);n(this,"cachedAtlasHeight",0);n(this,"paletteFloat",new Float32Array(256*4));n(this,"maxCells",0);n(this,"renderPositions",new Float32Array(0));n(this,"renderTexCoords",new Float32Array(0));n(this,"renderColorIndices",new Float32Array(0));n(this,"renderIndices",new Uint32Array(0));n(this,"cachedResolution",[0,0]);n(this,"cachedTextureUnit",-1);n(this,"cachedPaletteUnit",-1);n(this,"cachedTextureUniform",!1);n(this,"cachedPaletteUniform",!1);n(this,"paletteHash",0);n(this,"currentScale",1);n(this,"scalingMode",T.None);n(this,"ambientEffectEnabled",!1);n(this,"ambientEffectCanvas",null);n(this,"ambientEffectCtx",null);n(this,"ambientEffectBlur",B.ambientEffect.blur);n(this,"ambientEffectScale",B.ambientEffect.scale);n(this,"ambientEffectOpacity",.7);n(this,"onResizeCallback");n(this,"staticPositionsInitialized",!1);n(this,"vaoExtension",null);n(this,"vao",null);n(this,"instancedExtension",null);n(this,"useInstancing",!1);n(this,"instanceDataBuffer",null);n(this,"instanceData",new Float32Array(0));n(this,"templateQuadPositions",new Float32Array(0));n(this,"templateQuadIndices",new Uint16Array(0));if(!e)throw new Error("TerminalGL: Parent element is required");if(!Number.isInteger(t.cols)||t.cols<=0)throw new Error(`TerminalGL: Invalid cols: ${t.cols}. Must be a positive integer.`);if(!Number.isInteger(t.rows)||t.rows<=0)throw new Error(`TerminalGL: Invalid rows: ${t.rows}. Must be a positive integer.`);let r=t.cols*t.rows,i=U.checkCompatibility();if(i.errors.length>0)throw new Error(`TerminalGL: WebGL incompatible - ${i.errors.join(", ")}`);let s=t.forceUint16??!1;if(s&&r>i.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${r} cells) exceeds Uint16 limit of ${i.maxCellsUint16} cells. Maximum size with Uint16: ${Math.floor(Math.sqrt(i.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(i.maxCellsUint16))} (or smaller rectangles like 127\xD764)`);if(!i.uint32Indices&&r>i.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${r} cells) exceeds device limit of ${i.maxCellsUint16} cells (OES_element_index_uint not supported). Maximum size: ${Math.floor(Math.sqrt(i.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(i.maxCellsUint16))}`);r>i.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Large terminal size ${t.cols}\xD7${t.rows} (${r} cells) exceeds recommended limit of ${i.recommendedMaxCells} cells. Performance may be impacted.`),i.warnings.length>0&&console.warn("[TerminalGL] WebGL Compatibility Warnings:",i.warnings);let a=t.charWidth??8,l=t.charHeight??8;if(!Number.isFinite(a)||a<=0)throw new Error(`TerminalGL: Invalid charWidth: ${a}. Must be a positive number.`);if(!Number.isFinite(l)||l<=0)throw new Error(`TerminalGL: Invalid charHeight: ${l}. Must be a positive number.`);for(this.parentElement=e,this.cols=t.cols,this.rows=t.rows,this.charWidth=a,this.charHeight=l,this.canvasBgColor=t.canvasBgColor!==void 0?t.canvasBgColor:null,this.showGrid=t.showGrid??!1,this.scalingMode=t.scalingMode??T.None,t.ambientEffect&&(this.ambientEffectEnabled=!0,typeof t.ambientEffect=="object"&&(this.ambientEffectBlur=t.ambientEffect.blur??B.ambientEffect.blur,this.ambientEffectScale=t.ambientEffect.scale??B.ambientEffect.scale,this.ambientEffectOpacity=t.ambientEffect.opacity??.7));this.parentElement.firstChild;)this.parentElement.removeChild(this.parentElement.firstChild);let o=window.getComputedStyle(this.parentElement).position;o!=="relative"&&o!=="absolute"&&o!=="fixed"&&(this.parentElement.style.position="relative"),this.containerDiv=document.createElement("div"),this.containerDiv.className="terminalgl-container",this.containerDiv.style.cssText=`
7
+ z-index: ${s} !important;
8
+ `,this.container.appendChild(this.canvas);let i=this.canvas.getContext("2d");if(!i)throw new Error("[GridOverlay] Impossible de cr\xE9er le contexte 2D");this.ctx=i,t&&(t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth))}setDimensions(e,t,s,i,n=0,a=0){this.cols=e,this.rows=t,this.cellWidth=s,this.cellHeight=i,this.offsetX=n,this.offsetY=a}setCanvasSize(e,t){this.canvas.width=e,this.canvas.height=t,this.ctx.setTransform(1,0,0,1,0,0)}setStyle(e){e.strokeColor&&(this.strokeColor=e.strokeColor),e.lineWidth!==void 0&&(this.lineWidth=e.lineWidth)}setTransform(e,t,s,i,n){let a=i.left-n.left,l=i.top-n.top,o=i.width,c=i.height;(this.canvas.width!==o||this.canvas.height!==c)&&(this.canvas.width=o,this.canvas.height=c);let d=this.canvas.style;d.width=`${o}px`,d.height=`${c}px`,d.left=`${a}px`,d.top=`${l}px`}render(){if(!this.ctx)return;let e=this.cols*this.cellWidth,t=this.rows*this.cellHeight,s=e>0?this.canvas.width/e:1,i=t>0?this.canvas.height/t:1,n=Math.min(s,i),a=this.cellWidth*n,l=this.cellHeight*n,o=this.cols*a,c=this.rows*l,d=this.offsetX*n,h=this.offsetY*n;if(!(o===0||c===0)){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.strokeStyle=this.strokeColor,this.ctx.lineWidth=Math.max(1,this.lineWidth*n),this.ctx.beginPath();for(let u=0;u<=this.cols;u++){let m=d+u*a+.5;this.ctx.moveTo(m,h),this.ctx.lineTo(m,h+c)}for(let u=0;u<=this.rows;u++){let m=h+u*l+.5;this.ctx.moveTo(d,m),this.ctx.lineTo(d+o,m)}this.ctx.stroke()}}update(e,t,s,i,n,a,l=0,o=0){this.setDimensions(e,t,s,i,l,o),this.setCanvasSize(n,a),this.render()}setVisible(e){this.canvas.style.display=e?"block":"none"}destroy(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}};E(B,"GridOverlay");var I=B;function F(v){return Math.sqrt(v)*16}E(F,"getAtlasColumns");function L(v){return v*256-1}E(L,"getMaxCharCode");function _(v,e){let t=Math.floor(v/256),s=v%256,i=Math.sqrt(e),n=t%i,a=Math.floor(t/i),l=s%16,o=Math.floor(s/16);return{col:n*16+l,row:a*16+o}}E(_,"getCharGridPosition");import{POST_PROCESS_DEFAULTS as U,ScalingMode as C}from"@utsp/types";var y=class y{constructor(e,t){r(this,"canvas");r(this,"gl");r(this,"parentElement");r(this,"containerDiv");r(this,"cols");r(this,"rows");r(this,"charWidth");r(this,"charHeight");r(this,"cellWidth",8);r(this,"cellHeight",8);r(this,"glyphOffsetX",0);r(this,"glyphOffsetY",0);r(this,"canvasBgColor");r(this,"showGrid");r(this,"supportsUint32Indices",!1);r(this,"useUint16Indices",!1);r(this,"gridOverlay");r(this,"bitmapFont");r(this,"atlasTexture",null);r(this,"atlasCanvas");r(this,"atlasColumns",0);r(this,"fontLoaded",!1);r(this,"paletteTexture",null);r(this,"program",null);r(this,"positionBuffer",null);r(this,"texCoordBuffer",null);r(this,"colorIndexBuffer",null);r(this,"indexBuffer",null);r(this,"aPosition");r(this,"aTexCoord");r(this,"aColorIndex");r(this,"uResolution",null);r(this,"uTexture",null);r(this,"uPalette",null);r(this,"resizeObserver");r(this,"charCodeToAtlasIndex",new Uint16Array(65536).fill(65535));r(this,"atlasUVs",new Float32Array(0));r(this,"cachedAtlasWidth",0);r(this,"cachedAtlasHeight",0);r(this,"paletteFloat",new Float32Array(256*4));r(this,"maxCells",0);r(this,"renderPositions",new Float32Array(0));r(this,"renderTexCoords",new Float32Array(0));r(this,"renderColorIndices",new Float32Array(0));r(this,"renderIndices",new Uint32Array(0));r(this,"cachedResolution",[0,0]);r(this,"cachedTextureUnit",-1);r(this,"cachedPaletteUnit",-1);r(this,"cachedTextureUniform",!1);r(this,"cachedPaletteUniform",!1);r(this,"paletteHash",0);r(this,"currentScale",1);r(this,"scalingMode",C.None);r(this,"ambientEffectEnabled",!1);r(this,"ambientEffectCanvas",null);r(this,"ambientEffectCtx",null);r(this,"ambientEffectBlur",U.ambientEffect.blur);r(this,"ambientEffectScale",U.ambientEffect.scale);r(this,"ambientEffectOpacity",.7);r(this,"onResizeCallback");r(this,"staticPositionsInitialized",!1);r(this,"vaoExtension",null);r(this,"vao",null);r(this,"instancedExtension",null);r(this,"useInstancing",!1);r(this,"instanceDataBuffer",null);r(this,"instanceData",new Float32Array(0));r(this,"templateQuadPositions",new Float32Array(0));r(this,"templateQuadIndices",new Uint16Array(0));r(this,"aInstanceOffset",-1);r(this,"aInstanceUVs",-1);r(this,"aInstanceColors",-1);r(this,"uCellSize",null);if(!e)throw new Error("TerminalGL: Parent element is required");if(!Number.isInteger(t.cols)||t.cols<=0)throw new Error(`TerminalGL: Invalid cols: ${t.cols}. Must be a positive integer.`);if(!Number.isInteger(t.rows)||t.rows<=0)throw new Error(`TerminalGL: Invalid rows: ${t.rows}. Must be a positive integer.`);let s=t.cols*t.rows,i=y.checkCompatibility();if(i.errors.length>0)throw new Error(`TerminalGL: WebGL incompatible - ${i.errors.join(", ")}`);let n=t.forceUint16??!1;if(n&&s>i.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${s} cells) exceeds Uint16 limit of ${i.maxCellsUint16} cells. Maximum size with Uint16: ${Math.floor(Math.sqrt(i.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(i.maxCellsUint16))} (or smaller rectangles like 127\xD764)`);if(!i.uint32Indices&&s>i.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${s} cells) exceeds device limit of ${i.maxCellsUint16} cells (OES_element_index_uint not supported). Maximum size: ${Math.floor(Math.sqrt(i.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(i.maxCellsUint16))}`);s>i.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Large terminal size ${t.cols}\xD7${t.rows} (${s} cells) exceeds recommended limit of ${i.recommendedMaxCells} cells. Performance may be impacted.`),i.warnings.length>0&&console.warn("[TerminalGL] WebGL Compatibility Warnings:",i.warnings);let a=t.charWidth??8,l=t.charHeight??8;if(!Number.isFinite(a)||a<=0)throw new Error(`TerminalGL: Invalid charWidth: ${a}. Must be a positive number.`);if(!Number.isFinite(l)||l<=0)throw new Error(`TerminalGL: Invalid charHeight: ${l}. Must be a positive number.`);for(this.parentElement=e,this.cols=t.cols,this.rows=t.rows,this.charWidth=a,this.charHeight=l,this.canvasBgColor=t.canvasBgColor!==void 0?t.canvasBgColor:null,this.showGrid=t.showGrid??!1,this.scalingMode=t.scalingMode??C.None,t.ambientEffect&&(this.ambientEffectEnabled=!0,typeof t.ambientEffect=="object"&&(this.ambientEffectBlur=t.ambientEffect.blur??U.ambientEffect.blur,this.ambientEffectScale=t.ambientEffect.scale??U.ambientEffect.scale,this.ambientEffectOpacity=t.ambientEffect.opacity??.7));this.parentElement.firstChild;)this.parentElement.removeChild(this.parentElement.firstChild);let o=window.getComputedStyle(this.parentElement).position;o!=="relative"&&o!=="absolute"&&o!=="fixed"&&(this.parentElement.style.position="relative"),this.containerDiv=document.createElement("div"),this.containerDiv.className="terminalgl-container",this.containerDiv.style.cssText=`
9
9
  position: absolute !important;
10
10
  top: 0 !important;
11
11
  left: 0 !important;
@@ -32,7 +32,7 @@ var k=Object.defineProperty;var V=(b,e,t)=>e in b?k(b,e,{enumerable:!0,configura
32
32
  backface-visibility: hidden !important;
33
33
  position: relative !important;
34
34
  z-index: 1 !important;
35
- `;let c=this.canvas.getContext("webgl",{alpha:this.canvasBgColor===null,premultipliedAlpha:!1});if(!c)throw new Error("TerminalGL: WebGL not supported");this.gl=c,this.supportsUint32Indices=!!c.getExtension("OES_element_index_uint"),this.useUint16Indices=s||!this.supportsUint32Indices,this.useUint16Indices?console.warn(`[TerminalGL] \u{1F4CA} Using Uint16 indices (max ${i.maxCellsUint16} cells)`):console.warn(`[TerminalGL] \u{1F4CA} Using Uint32 indices (max ${i.maxCellsUint32} cells)`),this.vaoExtension=c.getExtension("OES_vertex_array_object"),this.vaoExtension&&console.warn("[TerminalGL] \u2705 VAO extension enabled (faster attribute binding)"),this.instancedExtension=c.getExtension("ANGLE_instanced_arrays"),this.instancedExtension?(this.useInstancing=!0,console.warn("[TerminalGL] \u{1F680} Instanced rendering enabled (massive draw call reduction)")):console.warn("[TerminalGL] \u26A0\uFE0F Instanced rendering not available (fallback to standard rendering)"),this.containerDiv.appendChild(this.canvas),this.ambientEffectEnabled&&(this.createAmbientEffectCanvas(),console.warn("[TerminalGL] \u{1F308} Ambient effect enabled at startup")),this.parentElement.appendChild(this.containerDiv),this.initRenderBuffers();try{this.initWebGL()}catch(d){throw console.error("[TerminalGL] \u274C Failed to initialize WebGL:",d),d}this.showGrid&&this.initGridOverlay(),this.setupResizeObserver()}static checkCompatibility(){let e={webgl1:!1,uint32Indices:!1,maxTextureSize:0,maxViewportDims:[0,0],maxCellsUint16:0,maxCellsUint32:0,recommendedMaxCells:0,warnings:[],errors:[]},t=document.createElement("canvas"),r=t.getContext("webgl")||t.getContext("experimental-webgl");if(!r||!(r instanceof WebGLRenderingContext))return e.errors.push("\u274C WebGL 1.0 not supported by this browser/device"),e;let i=r;e.webgl1=!0;try{e.maxTextureSize=i.getParameter(i.MAX_TEXTURE_SIZE);let o=i.getParameter(i.MAX_VIEWPORT_DIMS);e.maxViewportDims=[o[0],o[1]]}catch(o){return e.errors.push(`\u274C Failed to query WebGL parameters: ${o}`),e}let s=i.getExtension("OES_element_index_uint");e.uint32Indices=!!s;let a=8;if(e.maxCellsUint16=Math.floor(65535/a),e.uint32Indices){let o=Math.floor(e.maxTextureSize*e.maxTextureSize/64);e.maxCellsUint32=Math.min(o,262144)}else e.maxCellsUint32=e.maxCellsUint16,e.warnings.push(`\u26A0\uFE0F OES_element_index_uint not supported - limited to ${e.maxCellsUint16} cells (e.g., 90\xD790 or 127\xD764)`);return e.recommendedMaxCells=Math.floor((e.uint32Indices?e.maxCellsUint32:e.maxCellsUint16)*.8),e.maxTextureSize<256?e.errors.push(`\u274C MAX_TEXTURE_SIZE too small: ${e.maxTextureSize} (minimum 256 required for font atlas)`):e.maxTextureSize<2048&&e.warnings.push(`\u26A0\uFE0F Small MAX_TEXTURE_SIZE: ${e.maxTextureSize} (may limit font atlas)`),(e.maxViewportDims[0]<1024||e.maxViewportDims[1]<768)&&e.warnings.push(`\u26A0\uFE0F Small MAX_VIEWPORT_DIMS: ${e.maxViewportDims[0]}\xD7${e.maxViewportDims[1]}`),i.getExtension("WEBGL_lose_context")||e.warnings.push("\u26A0\uFE0F WEBGL_lose_context not supported - may cause memory leaks"),e}initInstancedBuffers(){let e=this.gl;this.templateQuadPositions=new Float32Array([0,0,this.cellWidth,0,0,this.cellHeight,this.cellWidth,this.cellHeight]),this.templateQuadIndices=new Uint16Array([0,1,2,2,1,3]),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.bufferData(e.ARRAY_BUFFER,this.templateQuadPositions,e.STATIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,this.templateQuadIndices,e.STATIC_DRAW);let t=this.cols*this.rows*2;this.instanceData=new Float32Array(t*8),e.bindBuffer(e.ARRAY_BUFFER,this.instanceDataBuffer),e.bufferData(e.ARRAY_BUFFER,this.instanceData.byteLength,e.DYNAMIC_DRAW)}initRenderBuffers(){this.maxCells=this.cols*this.rows*2,this.renderPositions=new Float32Array(this.maxCells*4*2),this.renderTexCoords=new Float32Array(this.maxCells*4*2),this.renderColorIndices=new Float32Array(this.maxCells*4),this.useUint16Indices?this.renderIndices=new Uint16Array(this.maxCells*6):this.renderIndices=new Uint32Array(this.maxCells*6),this.staticPositionsInitialized=!1}precomputeStaticPositions(){let e=this.cellWidth,t=this.cellHeight,r=this.glyphOffsetX,i=this.glyphOffsetY,s=this.charWidth,a=this.charHeight,l=0,o=0,c=0;for(let h=0;h<this.rows;h++){let f=Math.round(h*t),u=Math.round(f+t);for(let m=0;m<this.cols;m++){let p=Math.round(m*e),g=Math.round(p+e);this.renderPositions[l++]=p,this.renderPositions[l++]=f,this.renderPositions[l++]=g,this.renderPositions[l++]=f,this.renderPositions[l++]=p,this.renderPositions[l++]=u,this.renderPositions[l++]=g,this.renderPositions[l++]=u,this.renderIndices[o++]=c,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+3,c+=4;let A=Math.round(p+r),R=Math.round(f+i),v=Math.round(A+s),E=Math.round(R+a);this.renderPositions[l++]=A,this.renderPositions[l++]=R,this.renderPositions[l++]=v,this.renderPositions[l++]=R,this.renderPositions[l++]=A,this.renderPositions[l++]=E,this.renderPositions[l++]=v,this.renderPositions[l++]=E,this.renderIndices[o++]=c,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+3,c+=4}}let d=this.gl;d.bindBuffer(d.ARRAY_BUFFER,this.positionBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,this.renderPositions),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,this.indexBuffer),d.bufferSubData(d.ELEMENT_ARRAY_BUFFER,0,this.renderIndices),this.staticPositionsInitialized=!0}initWebGL(){let e=this.gl,t;this.useInstancing?t=`
35
+ `;let c=this.canvas.getContext("webgl",{alpha:this.canvasBgColor===null,premultipliedAlpha:!1});if(!c)throw new Error("TerminalGL: WebGL not supported");this.gl=c,this.supportsUint32Indices=!!c.getExtension("OES_element_index_uint"),this.useUint16Indices=n||!this.supportsUint32Indices,this.useUint16Indices?console.warn(`[TerminalGL] \u{1F4CA} Using Uint16 indices (max ${i.maxCellsUint16} cells)`):console.warn(`[TerminalGL] \u{1F4CA} Using Uint32 indices (max ${i.maxCellsUint32} cells)`),this.vaoExtension=c.getExtension("OES_vertex_array_object"),this.vaoExtension&&console.warn("[TerminalGL] \u2705 VAO extension enabled (faster attribute binding)"),this.instancedExtension=c.getExtension("ANGLE_instanced_arrays"),this.instancedExtension?(this.useInstancing=!0,console.warn("[TerminalGL] \u{1F680} Instanced rendering enabled (massive draw call reduction)")):console.warn("[TerminalGL] \u26A0\uFE0F Instanced rendering not available (fallback to standard rendering)"),this.containerDiv.appendChild(this.canvas),this.ambientEffectEnabled&&(this.createAmbientEffectCanvas(),console.warn("[TerminalGL] \u{1F308} Ambient effect enabled at startup")),this.parentElement.appendChild(this.containerDiv),this.initRenderBuffers();try{this.initWebGL()}catch(d){throw console.error("[TerminalGL] \u274C Failed to initialize WebGL:",d),d}this.showGrid&&this.initGridOverlay(),this.setupResizeObserver()}static checkCompatibility(){let e={webgl1:!1,uint32Indices:!1,maxTextureSize:0,maxViewportDims:[0,0],maxCellsUint16:0,maxCellsUint32:0,recommendedMaxCells:0,warnings:[],errors:[]},t=document.createElement("canvas"),s=t.getContext("webgl")||t.getContext("experimental-webgl");if(!s||!(s instanceof WebGLRenderingContext))return e.errors.push("\u274C WebGL 1.0 not supported by this browser/device"),e;let i=s;e.webgl1=!0;try{e.maxTextureSize=i.getParameter(i.MAX_TEXTURE_SIZE);let o=i.getParameter(i.MAX_VIEWPORT_DIMS);e.maxViewportDims=[o[0],o[1]]}catch(o){return e.errors.push(`\u274C Failed to query WebGL parameters: ${o}`),e}let n=i.getExtension("OES_element_index_uint");e.uint32Indices=!!n;let a=8;if(e.maxCellsUint16=Math.floor(65535/a),e.uint32Indices){let o=Math.floor(e.maxTextureSize*e.maxTextureSize/64);e.maxCellsUint32=Math.min(o,262144)}else e.maxCellsUint32=e.maxCellsUint16,e.warnings.push(`\u26A0\uFE0F OES_element_index_uint not supported - limited to ${e.maxCellsUint16} cells (e.g., 90\xD790 or 127\xD764)`);return e.recommendedMaxCells=Math.floor((e.uint32Indices?e.maxCellsUint32:e.maxCellsUint16)*.8),e.maxTextureSize<256?e.errors.push(`\u274C MAX_TEXTURE_SIZE too small: ${e.maxTextureSize} (minimum 256 required for font atlas)`):e.maxTextureSize<2048&&e.warnings.push(`\u26A0\uFE0F Small MAX_TEXTURE_SIZE: ${e.maxTextureSize} (may limit font atlas)`),(e.maxViewportDims[0]<1024||e.maxViewportDims[1]<768)&&e.warnings.push(`\u26A0\uFE0F Small MAX_VIEWPORT_DIMS: ${e.maxViewportDims[0]}\xD7${e.maxViewportDims[1]}`),i.getExtension("WEBGL_lose_context")||e.warnings.push("\u26A0\uFE0F WEBGL_lose_context not supported - may cause memory leaks"),e}initInstancedBuffers(){let e=this.gl;this.templateQuadPositions=new Float32Array([0,0,this.cellWidth,0,0,this.cellHeight,this.cellWidth,this.cellHeight]),this.templateQuadIndices=new Uint16Array([0,1,2,2,1,3]),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.bufferData(e.ARRAY_BUFFER,this.templateQuadPositions,e.STATIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,this.templateQuadIndices,e.STATIC_DRAW),this.instanceData=new Float32Array(this.maxCells*8),console.warn(`[TerminalGL] \u{1F680} initInstancedBuffers: maxCells=${this.maxCells}, instanceData.length=${this.instanceData.length}`),e.bindBuffer(e.ARRAY_BUFFER,this.instanceDataBuffer),e.bufferData(e.ARRAY_BUFFER,this.instanceData.byteLength,e.DYNAMIC_DRAW)}initRenderBuffers(){let e=this.cols*this.rows*2;this.maxCells=Math.ceil(e*2),this.renderPositions=new Float32Array(this.maxCells*4*2),this.renderTexCoords=new Float32Array(this.maxCells*4*2),this.renderColorIndices=new Float32Array(this.maxCells*4),this.useUint16Indices?this.renderIndices=new Uint16Array(this.maxCells*6):this.renderIndices=new Uint32Array(this.maxCells*6),this.staticPositionsInitialized=!1}precomputeStaticPositions(){let e=this.cellWidth,t=this.cellHeight,s=this.glyphOffsetX,i=this.glyphOffsetY,n=this.charWidth,a=this.charHeight,l=0,o=0,c=0;for(let h=0;h<this.rows;h++){let u=Math.round(h*t),m=Math.round(u+t);for(let b=0;b<this.cols;b++){let f=Math.round(b*e),p=Math.round(f+e);this.renderPositions[l++]=f,this.renderPositions[l++]=u,this.renderPositions[l++]=p,this.renderPositions[l++]=u,this.renderPositions[l++]=f,this.renderPositions[l++]=m,this.renderPositions[l++]=p,this.renderPositions[l++]=m,this.renderIndices[o++]=c,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+3,c+=4;let g=Math.round(f+s),x=Math.round(u+i),w=Math.round(g+n),A=Math.round(x+a);this.renderPositions[l++]=g,this.renderPositions[l++]=x,this.renderPositions[l++]=w,this.renderPositions[l++]=x,this.renderPositions[l++]=g,this.renderPositions[l++]=A,this.renderPositions[l++]=w,this.renderPositions[l++]=A,this.renderIndices[o++]=c,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+2,this.renderIndices[o++]=c+1,this.renderIndices[o++]=c+3,c+=4}}let d=this.gl;d.bindBuffer(d.ARRAY_BUFFER,this.positionBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,this.renderPositions),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,this.indexBuffer),d.bufferSubData(d.ELEMENT_ARRAY_BUFFER,0,this.renderIndices),this.staticPositionsInitialized=!0}initWebGL(){let e=this.gl,t;this.useInstancing?t=`
36
36
  // Per-vertex attributes (template quad)
37
37
  attribute vec2 aPosition; // Local quad position (0,0 to cellW,cellH)
38
38
 
@@ -93,7 +93,7 @@ var k=Object.defineProperty;var V=(b,e,t)=>e in b?k(b,e,{enumerable:!0,configura
93
93
  float paletteU = (aColorIndex + 0.5) / 256.0;
94
94
  vColor = texture2D(uPalette, vec2(paletteU, 0.5));
95
95
  }
96
- `;let r=`
96
+ `;let s=`
97
97
  precision mediump float;
98
98
 
99
99
  uniform sampler2D uTexture;
@@ -113,7 +113,7 @@ var k=Object.defineProperty;var V=(b,e,t)=>e in b?k(b,e,{enumerable:!0,configura
113
113
  gl_FragColor = vec4(texColor.rgb * vColor.rgb, texColor.a);
114
114
  }
115
115
  }
116
- `,i=this.compileShader(e.VERTEX_SHADER,t),s=this.compileShader(e.FRAGMENT_SHADER,r);if(!i||!s)throw new Error("Shader compilation error");let a=e.createProgram();if(!a)throw new Error("Unable to create WebGL program");if(e.attachShader(a,i),e.attachShader(a,s),e.linkProgram(a),!e.getProgramParameter(a,e.LINK_STATUS)){let l=e.getProgramInfoLog(a);throw new Error("Program linking error: "+l)}this.program=a,this.cachedTextureUniform=!1,this.cachedPaletteUniform=!1,this.aPosition=e.getAttribLocation(a,"aPosition"),this.useInstancing?(this.aTexCoord=e.getAttribLocation(a,"aInstanceOffset"),this.aColorIndex=e.getAttribLocation(a,"aInstanceUVs"),this.instanceDataBuffer=e.createBuffer()):(this.aTexCoord=e.getAttribLocation(a,"aTexCoord"),this.aColorIndex=e.getAttribLocation(a,"aColorIndex")),this.uResolution=e.getUniformLocation(a,"uResolution"),this.uTexture=e.getUniformLocation(a,"uTexture"),this.uPalette=e.getUniformLocation(a,"uPalette"),this.positionBuffer=e.createBuffer(),this.texCoordBuffer=e.createBuffer(),this.colorIndexBuffer=e.createBuffer(),this.indexBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderPositions.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderTexCoords.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderColorIndices.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,e.DYNAMIC_DRAW),this.vaoExtension&&(this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(this.aPosition),e.vertexAttribPointer(this.aPosition,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.enableVertexAttribArray(this.aTexCoord),e.vertexAttribPointer(this.aTexCoord,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.enableVertexAttribArray(this.aColorIndex),e.vertexAttribPointer(this.aColorIndex,1,e.FLOAT,!1,0,0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null))),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA),e.viewport(0,0,this.canvas.width,this.canvas.height)}compileShader(e,t){let r=this.gl,i=r.createShader(e);return i?(r.shaderSource(i,t),r.compileShader(i),r.getShaderParameter(i,r.COMPILE_STATUS)?i:(console.error("Shader compilation error:",r.getShaderInfoLog(i)),r.deleteShader(i),null)):null}initGridOverlay(){this.gridOverlay=new I(this.containerDiv,{strokeColor:"rgba(144, 24, 24, 1)",lineWidth:1,zIndex:10}),this.updateGridOverlay()}updateGridOverlay(){if(!this.gridOverlay)return;let e=this.cols*this.cellWidth,t=this.rows*this.cellHeight,r=this.canvas.getBoundingClientRect(),i=this.containerDiv.getBoundingClientRect();this.gridOverlay.setDimensions(this.cols,this.rows,this.cellWidth,this.cellHeight,0,0),this.gridOverlay.setTransform(this.currentScale,e,t,r,i),this.gridOverlay.render()}setBitmapFont(e,t,r,i,s){this.bitmapFont=e,this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(r),this.cellWidth=Math.round(i),this.cellHeight=Math.round(s),this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&(console.warn("[TerminalGL] \u{1F680} Initializing instanced buffers..."),this.initInstancedBuffers());try{this.generateAtlas()}catch(a){throw console.error("[TerminalGL] \u274C Failed to generate atlas:",a),a}this.buildCharCodeMap(),this.precomputeAtlasUVs(),this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.useInstancing||this.precomputeStaticPositions(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}async setImageFont(e,t,r,i,s,a){this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(r),this.cellWidth=Math.round(i),this.cellHeight=Math.round(s),this.atlasColumns=L(a);let l=_(a);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&(console.warn("[TerminalGL] \u{1F680} Initializing instanced buffers for ImageFont..."),this.initInstancedBuffers()),await this.loadImageFontAtlas(e),this.charCodeToAtlasIndex.fill(65535);for(let o=0;o<=l;o++)this.charCodeToAtlasIndex[o]=o;this.precomputeImageFontUVs(a),this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.useInstancing||this.precomputeStaticPositions(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}async loadImageFontAtlas(e){return new Promise((t,r)=>{let i=new Uint8Array(e),s=new Blob([i],{type:"image/png"}),a=URL.createObjectURL(s),l=new Image;l.onload=()=>{URL.revokeObjectURL(a),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=l.width,this.atlasCanvas.height=l.height;let o=this.atlasCanvas.getContext("2d");if(!o){r(new Error("Failed to create 2D context for atlas"));return}o.drawImage(l,0,0),this.cachedAtlasWidth=l.width,this.cachedAtlasHeight=l.height,this.createAtlasTexture(),t()},l.onerror=()=>{URL.revokeObjectURL(a),r(new Error("Failed to load PNG image for ImageFont atlas"))},l.src=a})}precomputeImageFontUVs(e){let t=e*256;this.atlasUVs=new Float32Array(t*4);let r=this.cachedAtlasWidth,i=this.cachedAtlasHeight,s=.5/r,a=.5/i;for(let l=0;l<t;l++){let{col:o,row:c}=D(l,e),d=(o*this.charWidth+s)/r,h=(c*this.charHeight+a)/i,f=((o+1)*this.charWidth-s)/r,u=((c+1)*this.charHeight-a)/i,m=l*4;this.atlasUVs[m]=d,this.atlasUVs[m+1]=h,this.atlasUVs[m+2]=f,this.atlasUVs[m+3]=u}}generateAtlas(){if(!this.bitmapFont)return;let e=Array.from(this.bitmapFont.keys()).sort((o,c)=>o-c),t=e.length;this.atlasColumns=Math.ceil(Math.sqrt(t));let r=Math.ceil(t/this.atlasColumns),i=this.atlasColumns*this.charWidth,s=r*this.charHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=i,this.atlasCanvas.height=s;let a=this.atlasCanvas.getContext("2d");if(!a)throw new Error("Unable to create 2D context for atlas");a.clearRect(0,0,i,s),a.fillStyle="#ffffff";let l=0;for(let o of e){let c=this.bitmapFont.get(o);if(!c)continue;let d=l%this.atlasColumns,h=Math.floor(l/this.atlasColumns),f=d*this.charWidth,u=h*this.charHeight;for(let m=0;m<Math.min(c.length,this.charHeight);m++){let p=c[m];for(let g=0;g<this.charWidth;g++){let A=1<<7-g;p&A&&a.fillRect(f+g,u+m,1,1)}}l++}this.createAtlasTexture()}buildCharCodeMap(){if(!this.bitmapFont)return;this.charCodeToAtlasIndex.fill(65535);let e=Array.from(this.bitmapFont.keys()).sort((t,r)=>t-r);for(let t=0;t<e.length;t++)this.charCodeToAtlasIndex[e[t]]=t}precomputeAtlasUVs(){if(!this.bitmapFont)return;let e=this.bitmapFont.size;this.atlasUVs=new Float32Array(e*4),this.cachedAtlasWidth=this.atlasColumns*this.charWidth,this.cachedAtlasHeight=Math.ceil(e/this.atlasColumns)*this.charHeight;let t=this.cachedAtlasWidth,r=this.cachedAtlasHeight,i=.5/t,s=.5/r;for(let a=0;a<e;a++){let l=a%this.atlasColumns,o=Math.floor(a/this.atlasColumns),c=(l*this.charWidth+i)/t,d=(o*this.charHeight+s)/r,h=((l+1)*this.charWidth-i)/t,f=((o+1)*this.charHeight-s)/r,u=a*4;this.atlasUVs[u]=c,this.atlasUVs[u+1]=d,this.atlasUVs[u+2]=h,this.atlasUVs[u+3]=f}}createAtlasTexture(){if(this.atlasCanvas)try{let e=this.gl,t=e.createTexture();if(!t)throw new Error("Unable to create texture");e.bindTexture(e.TEXTURE_2D,t),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,this.atlasCanvas),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),this.atlasTexture=t}catch(e){throw console.error("[TerminalGL] \u274C Failed to create atlas texture:",e),e}}clear(){let e=this.gl;e&&e.clear(e.COLOR_BUFFER_BIT)}parseColor(e){if(e.startsWith("#")){let t=e.slice(1),r=0,i=0,s=0;return t.length===3?(r=parseInt(t[0]+t[0],16),i=parseInt(t[1]+t[1],16),s=parseInt(t[2]+t[2],16)):t.length===6&&(r=parseInt(t.slice(0,2),16),i=parseInt(t.slice(2,4),16),s=parseInt(t.slice(4,6),16)),[r/255,i/255,s/255,1]}if(e.startsWith("rgb")){let t=e.match(/rgba?\(([^)]+)\)/);if(t){let r=t[1].split(",").map(i=>parseFloat(i.trim()));return[r[0]/255,r[1]/255,r[2]/255,r[3]!==void 0?r[3]:1]}}return[1,1,1,1]}setupResizeObserver(){if(!(typeof ResizeObserver>"u"))try{this.resizeObserver=new ResizeObserver(()=>{try{this.updateCanvasSize()}catch(e){console.error("[TerminalGL] \u274C Error in resize callback:",e)}}),this.resizeObserver.observe(this.parentElement),this.updateCanvasSize()}catch(e){console.error("[TerminalGL] \u274C Failed to setup ResizeObserver:",e)}}updateCanvasSize(){let e=this.parentElement.clientWidth,t=this.parentElement.clientHeight;if(e===0||t===0)return;let r=this.cols*this.cellWidth,i=this.rows*this.cellHeight;if(r===0||i===0)return;let s=e/r,a=t/i,l=Math.min(s,a),o;switch(this.scalingMode){case T.Integer:o=Math.max(1,Math.floor(l));break;case T.Half:o=Math.max(1,Math.floor(l*2)/2);break;case T.Quarter:o=Math.max(1,Math.floor(l*4)/4);break;case T.Eighth:o=Math.max(1,Math.floor(l*8)/8);break;case T.None:default:o=Math.max(.1,l);break}if(this.canvas.style.transform=`scale(${o})`,this.ambientEffectEnabled&&this.ambientEffectCanvas){let c=o*this.ambientEffectScale;this.ambientEffectCanvas.style.transform=`scale(${c})`}this.currentScale=o,this.onResizeCallback&&this.onResizeCallback(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}updateAmbientEffect(){!this.ambientEffectCanvas||!this.ambientEffectCtx||this.ambientEffectCtx.drawImage(this.canvas,0,0)}setPalette(e){let t=0;for(let r=0;r<Math.min(e.length,256);r++){let i=e[r];t=(t<<5)-t+i.r,t=(t<<5)-t+i.g,t=(t<<5)-t+i.b,t=(t<<5)-t+i.a,t=t|0}if(t!==this.paletteHash){this.paletteHash=t;for(let r=0;r<e.length&&r<256;r++){let i=e[r],s=r*4;this.paletteFloat[s]=i.r/255,this.paletteFloat[s+1]=i.g/255,this.paletteFloat[s+2]=i.b/255,this.paletteFloat[s+3]=i.a/255}this.updatePaletteTexture()}}updatePaletteTexture(){try{let e=this.gl;this.paletteTexture||(this.paletteTexture=e.createTexture()),e.bindTexture(e.TEXTURE_2D,this.paletteTexture);let t=new Uint8Array(256*4);for(let r=0;r<256;r++){let i=r*4;t[i]=this.paletteFloat[i]*255,t[i+1]=this.paletteFloat[i+1]*255,t[i+2]=this.paletteFloat[i+2]*255,t[i+3]=this.paletteFloat[i+3]*255}e.texImage2D(e.TEXTURE_2D,0,e.RGBA,256,1,0,e.RGBA,e.UNSIGNED_BYTE,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null)}catch(e){throw console.error("[TerminalGL] \u274C Failed to update palette texture:",e),e}}renderDisplayData(e){try{if(!this.isReady()){console.warn("[TerminalGL] \u26A0\uFE0F Not ready: font not loaded yet");return}(e.width!==this.cols||e.height!==this.rows)&&this.resize(e.width,e.height),this.renderDirect(e),this.ambientEffectEnabled&&this.ambientEffectCanvas&&this.ambientEffectCtx&&this.updateAmbientEffect()}catch(t){console.error("[TerminalGL] \u274C Error rendering display data:",t)}}renderDirect(e){let t=this.gl;if(!this.staticPositionsInitialized&&!this.useInstancing&&this.precomputeStaticPositions(),this.canvasBgColor!==null){let r=this.parseColor(this.canvasBgColor);t.clearColor(r[0],r[1],r[2],r[3])}else t.clearColor(0,0,0,0);t.clear(t.COLOR_BUFFER_BIT),this.useInstancing?this.renderInstanced(e):this.renderDirectBuffers(e)}renderInstanced(e){let t=this.gl,r=this.instancedExtension;if(!this.instanceData||this.instanceData.length===0){console.warn("[TerminalGL] \u26A0\uFE0F Instance data not initialized, falling back to standard rendering"),this.useInstancing=!1,this.renderDirectBuffers(e);return}let i=e.width*e.height;if(this.useUint16Indices&&i>8191){console.warn(`[TerminalGL] \u26A0\uFE0F Terminal too large for instanced rendering with Uint16 (${i} cells > 8191). Falling back to standard rendering.`),this.useInstancing=!1,this.renderDirectBuffers(e);return}let s=0,a=this.instanceData.length/8;for(let f=0;f<e.height;f++)for(let u=0;u<e.width;u++){let m=e.cells[f*e.width+u],p=m.bgColorIndex,g=m.fgColorIndex,A=this.canvasBgColor!==null&&p===255,R=m.char===" "||g===255;if(!A){if(s>=a){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${a}`);break}let v=s*8;this.instanceData[v]=u,this.instanceData[v+1]=f,this.instanceData[v+2]=0,this.instanceData[v+3]=0,this.instanceData[v+4]=0,this.instanceData[v+5]=0,this.instanceData[v+6]=p,this.instanceData[v+7]=0,s++}if(!R){let v=m.char.charCodeAt(0),E=this.charCodeToAtlasIndex[v];if(E!==65535){if(s>=a){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${a}`);break}let w=E*4,x=s*8;this.instanceData[x]=u,this.instanceData[x+1]=f,this.instanceData[x+2]=this.atlasUVs[w],this.instanceData[x+3]=this.atlasUVs[w+1],this.instanceData[x+4]=this.atlasUVs[w+2],this.instanceData[x+5]=this.atlasUVs[w+3],this.instanceData[x+6]=0,this.instanceData[x+7]=g,s++}}}if(s===0){console.warn("[TerminalGL] \u26A0\uFE0F No instances to draw (all cells skipped)");return}t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.instanceData.subarray(0,s*8)),t.useProgram(this.program),t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.enableVertexAttribArray(this.aPosition),t.vertexAttribPointer(this.aPosition,2,t.FLOAT,!1,0,0),r.vertexAttribDivisorANGLE(this.aPosition,0),t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer);let l=8*Float32Array.BYTES_PER_ELEMENT,o=t.getAttribLocation(this.program,"aInstanceOffset");t.enableVertexAttribArray(o),t.vertexAttribPointer(o,2,t.FLOAT,!1,l,0),r.vertexAttribDivisorANGLE(o,1);let c=t.getAttribLocation(this.program,"aInstanceUVs");t.enableVertexAttribArray(c),t.vertexAttribPointer(c,4,t.FLOAT,!1,l,2*Float32Array.BYTES_PER_ELEMENT),r.vertexAttribDivisorANGLE(c,1);let d=t.getAttribLocation(this.program,"aInstanceColors");t.enableVertexAttribArray(d),t.vertexAttribPointer(d,2,t.FLOAT,!1,l,6*Float32Array.BYTES_PER_ELEMENT),r.vertexAttribDivisorANGLE(d,1),t.uniform2f(this.uResolution,this.canvas.width,this.canvas.height);let h=t.getUniformLocation(this.program,"uCellSize");t.uniform2f(h,this.cellWidth,this.cellHeight),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.atlasTexture),t.uniform1i(this.uTexture,0),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,this.paletteTexture),t.uniform1i(this.uPalette,1),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer),r.drawElementsInstancedANGLE(t.TRIANGLES,6,t.UNSIGNED_SHORT,0,s),r.vertexAttribDivisorANGLE(this.aPosition,0),r.vertexAttribDivisorANGLE(o,0),r.vertexAttribDivisorANGLE(c,0),r.vertexAttribDivisorANGLE(d,0)}renderDirectBuffers(e){let t=this.gl,r=e.width*e.height,i=r*2;if(i>this.maxCells){console.error(`[TerminalGL] \u274C Buffer overflow detected! Trying to render ${i} quads but buffer capacity is ${this.maxCells}. This should not happen - resize() should have reallocated.`);return}let s=0,a=0,l=e.cells,o=r;for(let m=0;m<o;m++){let p=l[m],g=p.bgColorIndex,R=this.canvasBgColor!==null&&g===255?255:g,v=0;for(let x=0;x<4;x++)this.renderTexCoords[s++]=v,this.renderTexCoords[s++]=v,this.renderColorIndices[a++]=R;let E=p.fgColorIndex,w=p.char;if(w===" "||E===255)for(let x=0;x<4;x++)this.renderTexCoords[s++]=0,this.renderTexCoords[s++]=0,this.renderColorIndices[a++]=255;else{let x=w.charCodeAt(0),S=this.charCodeToAtlasIndex[x];if(S!==65535){let y=S*4,G=this.atlasUVs[y],W=this.atlasUVs[y+1],O=this.atlasUVs[y+2],H=this.atlasUVs[y+3];this.renderTexCoords[s++]=G,this.renderTexCoords[s++]=W,this.renderColorIndices[a++]=E,this.renderTexCoords[s++]=O,this.renderTexCoords[s++]=W,this.renderColorIndices[a++]=E,this.renderTexCoords[s++]=G,this.renderTexCoords[s++]=H,this.renderColorIndices[a++]=E,this.renderTexCoords[s++]=O,this.renderTexCoords[s++]=H,this.renderColorIndices[a++]=E}else for(let y=0;y<4;y++)this.renderTexCoords[s++]=0,this.renderTexCoords[s++]=0,this.renderColorIndices[a++]=255}}(s!==o*2*4*2||a!==o*2*4)&&console.error("[TerminalGL] \u274C Buffer index mismatch!",{texIdx:s,colorIdx:a,expected:o*2*4}),t.useProgram(this.program),this.vao&&this.vaoExtension?(this.vaoExtension.bindVertexArrayOES(this.vao),t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,s)),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,a))):(t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.enableVertexAttribArray(this.aPosition),t.vertexAttribPointer(this.aPosition,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,s)),t.enableVertexAttribArray(this.aTexCoord),t.vertexAttribPointer(this.aTexCoord,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,a)),t.enableVertexAttribArray(this.aColorIndex),t.vertexAttribPointer(this.aColorIndex,1,t.FLOAT,!1,0,0));let c=this.canvas.width,d=this.canvas.height;(this.cachedResolution[0]!==c||this.cachedResolution[1]!==d)&&(t.uniform2f(this.uResolution,c,d),this.cachedResolution[0]=c,this.cachedResolution[1]=d),this.cachedTextureUnit!==0&&(t.activeTexture(t.TEXTURE0),this.cachedTextureUnit=0),t.bindTexture(t.TEXTURE_2D,this.atlasTexture),this.cachedTextureUniform||(t.uniform1i(this.uTexture,0),this.cachedTextureUniform=!0),this.cachedPaletteUnit!==1&&(t.activeTexture(t.TEXTURE1),this.cachedPaletteUnit=1),t.bindTexture(t.TEXTURE_2D,this.paletteTexture),this.cachedPaletteUniform||(t.uniform1i(this.uPalette,1),this.cachedPaletteUniform=!0),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer);let f=e.width*e.height*2*6,u=this.useUint16Indices?t.UNSIGNED_SHORT:t.UNSIGNED_INT;t.drawElements(t.TRIANGLES,f,u,0)}resize(e,t){if(!Number.isInteger(e)||e<=0){console.error(`[TerminalGL] \u274C Invalid cols: ${e}. Must be positive integer.`);return}if(!Number.isInteger(t)||t<=0){console.error(`[TerminalGL] \u274C Invalid rows: ${t}. Must be positive integer.`);return}if(e===this.cols&&t===this.rows)return;let r=e*t,i=this.useUint16Indices?8191:262144;if(r>i){let d=Math.floor(Math.sqrt(i));console.error(`[TerminalGL] \u274C Cannot resize to ${e}\xD7${t} (${r} cells). Device limit: ${i} cells (max ~${d}\xD7${d}). ${this.useUint16Indices?"Device lacks OES_element_index_uint extension.":""}`);return}let s=U.checkCompatibility();r>s.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Resizing to ${e}\xD7${t} (${r} cells) exceeds recommended limit (${s.recommendedMaxCells} cells). Performance may degrade.`),this.cols=e,this.rows=t,this.staticPositionsInitialized=!1;let a=this.cols*this.rows*2,l=Math.ceil(a*1.5),o=a>this.maxCells,c=this.maxCells>l*4;if(o||c){let d=this.maxCells;this.maxCells=l,this.renderPositions=new Float32Array(this.maxCells*4*2),this.renderTexCoords=new Float32Array(this.maxCells*4*2),this.renderColorIndices=new Float32Array(this.maxCells*4),this.useUint16Indices?this.renderIndices=new Uint16Array(this.maxCells*6):this.renderIndices=new Uint32Array(this.maxCells*6);let h=this.gl;this.useInstancing||(h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderPositions.byteLength,h.DYNAMIC_DRAW)),h.bindBuffer(h.ARRAY_BUFFER,this.texCoordBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderTexCoords.byteLength,h.DYNAMIC_DRAW),h.bindBuffer(h.ARRAY_BUFFER,this.colorIndexBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderColorIndices.byteLength,h.DYNAMIC_DRAW),h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),h.bufferData(h.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,h.DYNAMIC_DRAW),this.vaoExtension&&this.vao&&(this.vaoExtension.deleteVertexArrayOES(this.vao),this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.enableVertexAttribArray(this.aPosition),h.vertexAttribPointer(this.aPosition,2,h.FLOAT,!1,0,0),h.bindBuffer(h.ARRAY_BUFFER,this.texCoordBuffer),h.enableVertexAttribArray(this.aTexCoord),h.vertexAttribPointer(this.aTexCoord,2,h.FLOAT,!1,0,0),h.bindBuffer(h.ARRAY_BUFFER,this.colorIndexBuffer),h.enableVertexAttribArray(this.aColorIndex),h.vertexAttribPointer(this.aColorIndex,1,h.FLOAT,!1,0,0),h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null)));let f=o?"\u{1F4C8} Growing":"\u{1F4C9} Shrinking",u=d*160/1048576,m=this.maxCells*160/1048576;console.warn(`[TerminalGL] ${f} buffers: ${u.toFixed(2)}MB \u2192 ${m.toFixed(2)}MB (${d} \u2192 ${this.maxCells} quads)`)}this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.ambientEffectEnabled&&this.ambientEffectCanvas&&(this.ambientEffectCanvas.width=this.canvas.width,this.ambientEffectCanvas.height=this.canvas.height,this.ambientEffectCanvas.style.width=`${this.canvas.width}px`,this.ambientEffectCanvas.style.height=`${this.canvas.height}px`),this.showGrid&&this.gridOverlay&&this.updateGridOverlay(),this.updateCanvasSize()}getCanvas(){return this.canvas}getGridSize(){return{cols:this.cols,rows:this.rows}}getCellWidth(){return this.cellWidth}getCellHeight(){return this.cellHeight}getCurrentScale(){return this.currentScale}getBaseDimensions(){return{width:this.cols*this.cellWidth,height:this.rows*this.cellHeight}}setOnResizeCallback(e){this.onResizeCallback=e}clearOnResizeCallback(){this.onResizeCallback=void 0}setScalingMode(e){this.scalingMode!==e&&(this.scalingMode=e,this.updateCanvasSize())}getScalingMode(){return this.scalingMode}setGrid(e){e.enabled?(this.gridOverlay?this.gridOverlay.setStyle({strokeColor:e.color,lineWidth:e.lineWidth}):this.gridOverlay=new I(this.containerDiv,{strokeColor:e.color??"rgba(144, 24, 24, 1)",lineWidth:e.lineWidth??1,zIndex:10}),this.showGrid=!0,this.gridOverlay.setVisible(!0),this.updateGridOverlay()):(this.showGrid=!1,this.gridOverlay&&this.gridOverlay.setVisible(!1))}isGridEnabled(){return this.showGrid}setAmbientEffect(e){typeof e=="boolean"?this.ambientEffectEnabled=e:(this.ambientEffectEnabled=!0,e.blur!==void 0&&(this.ambientEffectBlur=e.blur),e.scale!==void 0&&(this.ambientEffectScale=e.scale)),this.ambientEffectEnabled&&!this.ambientEffectCanvas&&this.createAmbientEffectCanvas(),this.ambientEffectCanvas&&(this.ambientEffectEnabled?(this.ambientEffectCanvas.style.display="block",this.ambientEffectCanvas.style.filter=`blur(${this.ambientEffectBlur}px)`,this.ambientEffectCanvas.style.transform=`scale(${this.ambientEffectScale})`,this.updateAmbientEffect()):this.ambientEffectCanvas.style.display="none")}createAmbientEffectCanvas(){this.ambientEffectCanvas||(this.ambientEffectCanvas=document.createElement("canvas"),this.ambientEffectCanvas.className="terminalgl-ambient-effect-canvas",this.ambientEffectCanvas.width=this.canvas.width,this.ambientEffectCanvas.height=this.canvas.height,this.ambientEffectCanvas.style.cssText=`
116
+ `,i=this.compileShader(e.VERTEX_SHADER,t),n=this.compileShader(e.FRAGMENT_SHADER,s);if(!i||!n)throw new Error("Shader compilation error");let a=e.createProgram();if(!a)throw new Error("Unable to create WebGL program");if(e.attachShader(a,i),e.attachShader(a,n),e.linkProgram(a),!e.getProgramParameter(a,e.LINK_STATUS)){let l=e.getProgramInfoLog(a);throw new Error("Program linking error: "+l)}this.program=a,this.cachedTextureUniform=!1,this.cachedPaletteUniform=!1,this.aPosition=e.getAttribLocation(a,"aPosition"),this.useInstancing?(this.aInstanceOffset=e.getAttribLocation(a,"aInstanceOffset"),this.aInstanceUVs=e.getAttribLocation(a,"aInstanceUVs"),this.aInstanceColors=e.getAttribLocation(a,"aInstanceColors"),this.uCellSize=e.getUniformLocation(a,"uCellSize"),this.instanceDataBuffer=e.createBuffer(),this.aTexCoord=this.aInstanceOffset,this.aColorIndex=this.aInstanceUVs):(this.aTexCoord=e.getAttribLocation(a,"aTexCoord"),this.aColorIndex=e.getAttribLocation(a,"aColorIndex")),this.uResolution=e.getUniformLocation(a,"uResolution"),this.uTexture=e.getUniformLocation(a,"uTexture"),this.uPalette=e.getUniformLocation(a,"uPalette"),this.positionBuffer=e.createBuffer(),this.texCoordBuffer=e.createBuffer(),this.colorIndexBuffer=e.createBuffer(),this.indexBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderPositions.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderTexCoords.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.bufferData(e.ARRAY_BUFFER,this.renderColorIndices.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,e.DYNAMIC_DRAW),this.vaoExtension&&(this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(this.aPosition),e.vertexAttribPointer(this.aPosition,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.enableVertexAttribArray(this.aTexCoord),e.vertexAttribPointer(this.aTexCoord,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.enableVertexAttribArray(this.aColorIndex),e.vertexAttribPointer(this.aColorIndex,1,e.FLOAT,!1,0,0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null))),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA),e.viewport(0,0,this.canvas.width,this.canvas.height)}compileShader(e,t){let s=this.gl,i=s.createShader(e);return i?(s.shaderSource(i,t),s.compileShader(i),s.getShaderParameter(i,s.COMPILE_STATUS)?i:(console.error("Shader compilation error:",s.getShaderInfoLog(i)),s.deleteShader(i),null)):null}initGridOverlay(){this.gridOverlay=new I(this.containerDiv,{strokeColor:"rgba(144, 24, 24, 1)",lineWidth:1,zIndex:10}),this.updateGridOverlay()}updateGridOverlay(){if(!this.gridOverlay)return;let e=this.cols*this.cellWidth,t=this.rows*this.cellHeight,s=this.canvas.getBoundingClientRect(),i=this.containerDiv.getBoundingClientRect();this.gridOverlay.setDimensions(this.cols,this.rows,this.cellWidth,this.cellHeight,0,0),this.gridOverlay.setTransform(this.currentScale,e,t,s,i),this.gridOverlay.render()}setBitmapFont(e,t,s,i,n){this.bitmapFont=e,this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(s),this.cellWidth=Math.round(i),this.cellHeight=Math.round(n),this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&(console.warn("[TerminalGL] \u{1F680} Initializing instanced buffers..."),this.initInstancedBuffers());try{this.generateAtlas()}catch(a){throw console.error("[TerminalGL] \u274C Failed to generate atlas:",a),a}this.buildCharCodeMap(),this.precomputeAtlasUVs(),this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.useInstancing||this.precomputeStaticPositions(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}async setImageFont(e,t,s,i,n,a){this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(s),this.cellWidth=Math.round(i),this.cellHeight=Math.round(n),this.atlasColumns=F(a);let l=L(a);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&(console.warn("[TerminalGL] \u{1F680} Initializing instanced buffers for ImageFont..."),this.initInstancedBuffers()),await this.loadImageFontAtlas(e),this.charCodeToAtlasIndex.fill(65535);for(let o=0;o<=l;o++)this.charCodeToAtlasIndex[o]=o;this.precomputeImageFontUVs(a),this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.useInstancing||this.precomputeStaticPositions(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}async loadImageFontAtlas(e){return new Promise((t,s)=>{let i=new Uint8Array(e),n=new Blob([i],{type:"image/png"}),a=URL.createObjectURL(n),l=new Image;l.onload=()=>{URL.revokeObjectURL(a),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=l.width,this.atlasCanvas.height=l.height;let o=this.atlasCanvas.getContext("2d");if(!o){s(new Error("Failed to create 2D context for atlas"));return}o.drawImage(l,0,0),this.cachedAtlasWidth=l.width,this.cachedAtlasHeight=l.height,this.createAtlasTexture(),t()},l.onerror=()=>{URL.revokeObjectURL(a),s(new Error("Failed to load PNG image for ImageFont atlas"))},l.src=a})}precomputeImageFontUVs(e){let t=e*256;this.atlasUVs=new Float32Array(t*4);let s=this.cachedAtlasWidth,i=this.cachedAtlasHeight,n=.5/s,a=.5/i;for(let l=0;l<t;l++){let{col:o,row:c}=_(l,e),d=(o*this.charWidth+n)/s,h=(c*this.charHeight+a)/i,u=((o+1)*this.charWidth-n)/s,m=((c+1)*this.charHeight-a)/i,b=l*4;this.atlasUVs[b]=d,this.atlasUVs[b+1]=h,this.atlasUVs[b+2]=u,this.atlasUVs[b+3]=m}}generateAtlas(){if(!this.bitmapFont)return;let e=Array.from(this.bitmapFont.keys()).sort((o,c)=>o-c),t=e.length;this.atlasColumns=Math.ceil(Math.sqrt(t));let s=Math.ceil(t/this.atlasColumns),i=this.atlasColumns*this.charWidth,n=s*this.charHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=i,this.atlasCanvas.height=n;let a=this.atlasCanvas.getContext("2d");if(!a)throw new Error("Unable to create 2D context for atlas");a.clearRect(0,0,i,n),a.fillStyle="#ffffff";let l=0;for(let o of e){let c=this.bitmapFont.get(o);if(!c)continue;let d=l%this.atlasColumns,h=Math.floor(l/this.atlasColumns),u=d*this.charWidth,m=h*this.charHeight;for(let b=0;b<Math.min(c.length,this.charHeight);b++){let f=c[b];for(let p=0;p<this.charWidth;p++){let g=1<<7-p;f&g&&a.fillRect(u+p,m+b,1,1)}}l++}this.createAtlasTexture()}buildCharCodeMap(){if(!this.bitmapFont)return;this.charCodeToAtlasIndex.fill(65535);let e=Array.from(this.bitmapFont.keys()).sort((t,s)=>t-s);for(let t=0;t<e.length;t++)this.charCodeToAtlasIndex[e[t]]=t}precomputeAtlasUVs(){if(!this.bitmapFont)return;let e=this.bitmapFont.size;this.atlasUVs=new Float32Array(e*4),this.cachedAtlasWidth=this.atlasColumns*this.charWidth,this.cachedAtlasHeight=Math.ceil(e/this.atlasColumns)*this.charHeight;let t=this.cachedAtlasWidth,s=this.cachedAtlasHeight,i=.5/t,n=.5/s;for(let a=0;a<e;a++){let l=a%this.atlasColumns,o=Math.floor(a/this.atlasColumns),c=(l*this.charWidth+i)/t,d=(o*this.charHeight+n)/s,h=((l+1)*this.charWidth-i)/t,u=((o+1)*this.charHeight-n)/s,m=a*4;this.atlasUVs[m]=c,this.atlasUVs[m+1]=d,this.atlasUVs[m+2]=h,this.atlasUVs[m+3]=u}}createAtlasTexture(){if(this.atlasCanvas)try{let e=this.gl,t=e.createTexture();if(!t)throw new Error("Unable to create texture");e.bindTexture(e.TEXTURE_2D,t),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,this.atlasCanvas),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),this.atlasTexture=t}catch(e){throw console.error("[TerminalGL] \u274C Failed to create atlas texture:",e),e}}clear(){let e=this.gl;e&&e.clear(e.COLOR_BUFFER_BIT)}parseColor(e){if(e.startsWith("#")){let t=e.slice(1),s=0,i=0,n=0;return t.length===3?(s=parseInt(t[0]+t[0],16),i=parseInt(t[1]+t[1],16),n=parseInt(t[2]+t[2],16)):t.length===6&&(s=parseInt(t.slice(0,2),16),i=parseInt(t.slice(2,4),16),n=parseInt(t.slice(4,6),16)),[s/255,i/255,n/255,1]}if(e.startsWith("rgb")){let t=e.match(/rgba?\(([^)]+)\)/);if(t){let s=t[1].split(",").map(i=>parseFloat(i.trim()));return[s[0]/255,s[1]/255,s[2]/255,s[3]!==void 0?s[3]:1]}}return[1,1,1,1]}setupResizeObserver(){if(!(typeof ResizeObserver>"u"))try{this.resizeObserver=new ResizeObserver(()=>{try{this.updateCanvasSize()}catch(e){console.error("[TerminalGL] \u274C Error in resize callback:",e)}}),this.resizeObserver.observe(this.parentElement),this.updateCanvasSize()}catch(e){console.error("[TerminalGL] \u274C Failed to setup ResizeObserver:",e)}}updateCanvasSize(){let e=this.parentElement.clientWidth,t=this.parentElement.clientHeight;if(e===0||t===0)return;let s=this.cols*this.cellWidth,i=this.rows*this.cellHeight;if(s===0||i===0)return;let n=e/s,a=t/i,l=Math.min(n,a),o;switch(this.scalingMode){case C.Integer:o=Math.max(1,Math.floor(l));break;case C.Half:o=Math.max(1,Math.floor(l*2)/2);break;case C.Quarter:o=Math.max(1,Math.floor(l*4)/4);break;case C.Eighth:o=Math.max(1,Math.floor(l*8)/8);break;case C.Responsive:o=1;break;case C.None:default:o=Math.max(.1,l);break}if(this.canvas.style.transform=`scale(${o})`,this.ambientEffectEnabled&&this.ambientEffectCanvas){let c=o*this.ambientEffectScale;this.ambientEffectCanvas.style.transform=`scale(${c})`}this.currentScale=o,this.onResizeCallback&&this.onResizeCallback(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}updateAmbientEffect(){!this.ambientEffectCanvas||!this.ambientEffectCtx||this.ambientEffectCtx.drawImage(this.canvas,0,0)}setPalette(e){let t=0;for(let s=0;s<Math.min(e.length,256);s++){let i=e[s];t=(t<<5)-t+i.r,t=(t<<5)-t+i.g,t=(t<<5)-t+i.b,t=(t<<5)-t+i.a,t=t|0}if(t!==this.paletteHash){this.paletteHash=t;for(let s=0;s<e.length&&s<256;s++){let i=e[s],n=s*4;this.paletteFloat[n]=i.r/255,this.paletteFloat[n+1]=i.g/255,this.paletteFloat[n+2]=i.b/255,this.paletteFloat[n+3]=i.a/255}this.updatePaletteTexture()}}updatePaletteTexture(){try{let e=this.gl;this.paletteTexture||(this.paletteTexture=e.createTexture()),e.bindTexture(e.TEXTURE_2D,this.paletteTexture);let t=new Uint8Array(256*4);for(let s=0;s<256;s++){let i=s*4;t[i]=this.paletteFloat[i]*255,t[i+1]=this.paletteFloat[i+1]*255,t[i+2]=this.paletteFloat[i+2]*255,t[i+3]=this.paletteFloat[i+3]*255}e.texImage2D(e.TEXTURE_2D,0,e.RGBA,256,1,0,e.RGBA,e.UNSIGNED_BYTE,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null)}catch(e){throw console.error("[TerminalGL] \u274C Failed to update palette texture:",e),e}}renderDisplayData(e){try{if(!this.isReady()){console.warn("[TerminalGL] \u26A0\uFE0F Not ready: font not loaded yet");return}(e.width!==this.cols||e.height!==this.rows)&&this.resize(e.width,e.height),this.renderDirect(e),this.ambientEffectEnabled&&this.ambientEffectCanvas&&this.ambientEffectCtx&&this.updateAmbientEffect()}catch(t){console.error("[TerminalGL] \u274C Error rendering display data:",t)}}renderDirect(e){let t=this.gl;if(!this.staticPositionsInitialized&&!this.useInstancing&&this.precomputeStaticPositions(),this.canvasBgColor!==null){let s=this.parseColor(this.canvasBgColor);t.clearColor(s[0],s[1],s[2],s[3])}else t.clearColor(0,0,0,0);t.clear(t.COLOR_BUFFER_BIT),this.useInstancing?this.renderInstanced(e):this.renderDirectBuffers(e)}renderInstanced(e){let t=this.gl,s=this.instancedExtension;if(!this.instanceData||this.instanceData.length===0){console.warn("[TerminalGL] \u26A0\uFE0F Instance data not initialized, falling back to standard rendering"),this.renderDirectBuffers(e);return}let i=0,n=this.instanceData.length/8,a=e.width*e.height*2;if(a>n){console.error(`[TerminalGL] \u274C Instance buffer too small! Need ${a}, have ${n}. Display size: ${e.width}\xD7${e.height}, buffer was sized for smaller terminal.`),this.renderDirectBuffers(e);return}for(let o=0;o<e.height;o++)for(let c=0;c<e.width;c++){let d=e.cells[o*e.width+c],h=d.bgColorIndex,u=d.fgColorIndex,m=this.canvasBgColor!==null&&h===255,b=d.char===" "||u===255;if(!m){if(i>=n){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${i}, max=${n}`);break}let f=i*8;this.instanceData[f]=c,this.instanceData[f+1]=o,this.instanceData[f+2]=0,this.instanceData[f+3]=0,this.instanceData[f+4]=0,this.instanceData[f+5]=0,this.instanceData[f+6]=h,this.instanceData[f+7]=0,i++}if(!b){let f=d.char.charCodeAt(0),p=this.charCodeToAtlasIndex[f];if(p!==65535){if(i>=n){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${i}, max=${n}`);break}let g=p*4,x=i*8;this.instanceData[x]=c,this.instanceData[x+1]=o,this.instanceData[x+2]=this.atlasUVs[g],this.instanceData[x+3]=this.atlasUVs[g+1],this.instanceData[x+4]=this.atlasUVs[g+2],this.instanceData[x+5]=this.atlasUVs[g+3],this.instanceData[x+6]=0,this.instanceData[x+7]=u,i++}}}if(i===0){console.warn("[TerminalGL] \u26A0\uFE0F No instances to draw (all cells skipped)");return}t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.instanceData.subarray(0,i*8)),t.useProgram(this.program),t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.enableVertexAttribArray(this.aPosition),t.vertexAttribPointer(this.aPosition,2,t.FLOAT,!1,0,0),s.vertexAttribDivisorANGLE(this.aPosition,0),t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer);let l=8*Float32Array.BYTES_PER_ELEMENT;t.enableVertexAttribArray(this.aInstanceOffset),t.vertexAttribPointer(this.aInstanceOffset,2,t.FLOAT,!1,l,0),s.vertexAttribDivisorANGLE(this.aInstanceOffset,1),t.enableVertexAttribArray(this.aInstanceUVs),t.vertexAttribPointer(this.aInstanceUVs,4,t.FLOAT,!1,l,2*Float32Array.BYTES_PER_ELEMENT),s.vertexAttribDivisorANGLE(this.aInstanceUVs,1),t.enableVertexAttribArray(this.aInstanceColors),t.vertexAttribPointer(this.aInstanceColors,2,t.FLOAT,!1,l,6*Float32Array.BYTES_PER_ELEMENT),s.vertexAttribDivisorANGLE(this.aInstanceColors,1),t.uniform2f(this.uResolution,this.canvas.width,this.canvas.height),t.uniform2f(this.uCellSize,this.cellWidth,this.cellHeight),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.atlasTexture),t.uniform1i(this.uTexture,0),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,this.paletteTexture),t.uniform1i(this.uPalette,1),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer),s.drawElementsInstancedANGLE(t.TRIANGLES,6,t.UNSIGNED_SHORT,0,i),s.vertexAttribDivisorANGLE(this.aPosition,0),s.vertexAttribDivisorANGLE(this.aInstanceOffset,0),s.vertexAttribDivisorANGLE(this.aInstanceUVs,0),s.vertexAttribDivisorANGLE(this.aInstanceColors,0)}renderDirectBuffers(e){let t=this.gl,s=e.width*e.height,i=s*2;if(i>this.maxCells){console.error(`[TerminalGL] \u274C Buffer overflow detected! Trying to render ${i} quads but buffer capacity is ${this.maxCells}. This should not happen - resize() should have reallocated.`);return}let n=0,a=0,l=e.cells,o=s;for(let b=0;b<o;b++){let f=l[b],p=f.bgColorIndex,x=this.canvasBgColor!==null&&p===255?255:p,w=0;for(let T=0;T<4;T++)this.renderTexCoords[n++]=w,this.renderTexCoords[n++]=w,this.renderColorIndices[a++]=x;let A=f.fgColorIndex,S=f.char;if(S===" "||A===255)for(let T=0;T<4;T++)this.renderTexCoords[n++]=0,this.renderTexCoords[n++]=0,this.renderColorIndices[a++]=255;else{let T=S.charCodeAt(0),P=this.charCodeToAtlasIndex[T];if(P!==65535){let R=P*4,G=this.atlasUVs[R],W=this.atlasUVs[R+1],O=this.atlasUVs[R+2],H=this.atlasUVs[R+3];this.renderTexCoords[n++]=G,this.renderTexCoords[n++]=W,this.renderColorIndices[a++]=A,this.renderTexCoords[n++]=O,this.renderTexCoords[n++]=W,this.renderColorIndices[a++]=A,this.renderTexCoords[n++]=G,this.renderTexCoords[n++]=H,this.renderColorIndices[a++]=A,this.renderTexCoords[n++]=O,this.renderTexCoords[n++]=H,this.renderColorIndices[a++]=A}else for(let R=0;R<4;R++)this.renderTexCoords[n++]=0,this.renderTexCoords[n++]=0,this.renderColorIndices[a++]=255}}(n!==o*2*4*2||a!==o*2*4)&&console.error("[TerminalGL] \u274C Buffer index mismatch!",{texIdx:n,colorIdx:a,expected:o*2*4}),t.useProgram(this.program),this.vao&&this.vaoExtension?(this.vaoExtension.bindVertexArrayOES(this.vao),t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,n)),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,a))):(t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.enableVertexAttribArray(this.aPosition),t.vertexAttribPointer(this.aPosition,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,n)),t.enableVertexAttribArray(this.aTexCoord),t.vertexAttribPointer(this.aTexCoord,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,a)),t.enableVertexAttribArray(this.aColorIndex),t.vertexAttribPointer(this.aColorIndex,1,t.FLOAT,!1,0,0));let c=this.canvas.width,d=this.canvas.height;(this.cachedResolution[0]!==c||this.cachedResolution[1]!==d)&&(t.uniform2f(this.uResolution,c,d),this.cachedResolution[0]=c,this.cachedResolution[1]=d),this.cachedTextureUnit!==0&&(t.activeTexture(t.TEXTURE0),this.cachedTextureUnit=0),t.bindTexture(t.TEXTURE_2D,this.atlasTexture),this.cachedTextureUniform||(t.uniform1i(this.uTexture,0),this.cachedTextureUniform=!0),this.cachedPaletteUnit!==1&&(t.activeTexture(t.TEXTURE1),this.cachedPaletteUnit=1),t.bindTexture(t.TEXTURE_2D,this.paletteTexture),this.cachedPaletteUniform||(t.uniform1i(this.uPalette,1),this.cachedPaletteUniform=!0),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer);let u=e.width*e.height*2*6,m=this.useUint16Indices?t.UNSIGNED_SHORT:t.UNSIGNED_INT;t.drawElements(t.TRIANGLES,u,m,0)}resize(e,t){if(!Number.isInteger(e)||e<=0){console.error(`[TerminalGL] \u274C Invalid cols: ${e}. Must be positive integer.`);return}if(!Number.isInteger(t)||t<=0){console.error(`[TerminalGL] \u274C Invalid rows: ${t}. Must be positive integer.`);return}if(e===this.cols&&t===this.rows)return;let s=e*t,i=this.useInstancing?262144:this.useUint16Indices?8191:262144;if(s>i){let d=Math.floor(Math.sqrt(i));console.error(`[TerminalGL] \u274C Cannot resize to ${e}\xD7${t} (${s} cells). Device limit: ${i} cells (max ~${d}\xD7${d}). ${!this.useInstancing&&this.useUint16Indices?"Device lacks OES_element_index_uint extension.":""}`);return}let n=y.checkCompatibility();s>n.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Resizing to ${e}\xD7${t} (${s} cells) exceeds recommended limit (${n.recommendedMaxCells} cells). Performance may degrade.`),this.cols=e,this.rows=t,this.staticPositionsInitialized=!1;let a=this.cols*this.rows*2,l=Math.ceil(a*1.5),o=a>this.maxCells,c=this.maxCells>l*4;if(console.warn(`[TerminalGL] \u{1F4D0} resize check: cols=${e}, rows=${t}, newMaxCells=${a}, this.maxCells=${this.maxCells}, needGrow=${o}, needShrink=${c}`),o||c){let d=this.maxCells;if(this.maxCells=l,console.warn(`[TerminalGL] \u{1F4D0} resize realloc: ${d} \u2192 ${this.maxCells} (needGrow=${o}, needShrink=${c})`),this.renderPositions=new Float32Array(this.maxCells*4*2),this.renderTexCoords=new Float32Array(this.maxCells*4*2),this.renderColorIndices=new Float32Array(this.maxCells*4),this.useUint16Indices?this.renderIndices=new Uint16Array(this.maxCells*6):this.renderIndices=new Uint32Array(this.maxCells*6),this.useInstancing&&this.instanceDataBuffer){this.instanceData=new Float32Array(this.maxCells*8);let f=this.gl;f.bindBuffer(f.ARRAY_BUFFER,this.instanceDataBuffer),f.bufferData(f.ARRAY_BUFFER,this.instanceData.byteLength,f.DYNAMIC_DRAW)}let h=this.gl;this.useInstancing||(h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderPositions.byteLength,h.DYNAMIC_DRAW)),h.bindBuffer(h.ARRAY_BUFFER,this.texCoordBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderTexCoords.byteLength,h.DYNAMIC_DRAW),h.bindBuffer(h.ARRAY_BUFFER,this.colorIndexBuffer),h.bufferData(h.ARRAY_BUFFER,this.renderColorIndices.byteLength,h.DYNAMIC_DRAW),this.useInstancing||(h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),h.bufferData(h.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,h.DYNAMIC_DRAW)),this.vaoExtension&&this.vao&&(this.vaoExtension.deleteVertexArrayOES(this.vao),this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.enableVertexAttribArray(this.aPosition),h.vertexAttribPointer(this.aPosition,2,h.FLOAT,!1,0,0),h.bindBuffer(h.ARRAY_BUFFER,this.texCoordBuffer),h.enableVertexAttribArray(this.aTexCoord),h.vertexAttribPointer(this.aTexCoord,2,h.FLOAT,!1,0,0),h.bindBuffer(h.ARRAY_BUFFER,this.colorIndexBuffer),h.enableVertexAttribArray(this.aColorIndex),h.vertexAttribPointer(this.aColorIndex,1,h.FLOAT,!1,0,0),h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null)));let u=o?"\u{1F4C8} Growing":"\u{1F4C9} Shrinking",m=d*160/1048576,b=this.maxCells*160/1048576;console.warn(`[TerminalGL] ${u} buffers: ${m.toFixed(2)}MB \u2192 ${b.toFixed(2)}MB (${d} \u2192 ${this.maxCells} quads)`)}this.canvas.width=this.cols*this.cellWidth,this.canvas.height=this.rows*this.cellHeight,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.canvas.style.width=`${this.canvas.width}px`,this.canvas.style.height=`${this.canvas.height}px`,this.ambientEffectEnabled&&this.ambientEffectCanvas&&(this.ambientEffectCanvas.width=this.canvas.width,this.ambientEffectCanvas.height=this.canvas.height,this.ambientEffectCanvas.style.width=`${this.canvas.width}px`,this.ambientEffectCanvas.style.height=`${this.canvas.height}px`),this.showGrid&&this.gridOverlay&&this.updateGridOverlay(),this.updateCanvasSize()}getCanvas(){return this.canvas}getGridSize(){return{cols:this.cols,rows:this.rows}}getCellWidth(){return this.cellWidth}getCellHeight(){return this.cellHeight}getCurrentScale(){return this.currentScale}getBaseDimensions(){return{width:this.cols*this.cellWidth,height:this.rows*this.cellHeight}}setOnResizeCallback(e){this.onResizeCallback=e}clearOnResizeCallback(){this.onResizeCallback=void 0}getAvailableSize(){return{width:this.parentElement.clientWidth,height:this.parentElement.clientHeight}}setScalingMode(e){this.scalingMode!==e&&(this.scalingMode=e,this.updateCanvasSize())}getScalingMode(){return this.scalingMode}setCellSize(e,t){let s=Math.max(1,Math.min(255,Math.round(e))),i=Math.max(1,Math.min(255,Math.round(t)));this.cellWidth===s&&this.cellHeight===i||(this.cellWidth=s,this.cellHeight=i,this.charWidth=s,this.charHeight=i,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.fontLoaded&&this.generateAtlas(),this.useInstancing&&this.initInstancedBuffers(),this.updateCanvasSize())}getCellSize(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getMaxCells(){return this.useInstancing?262144:this.useUint16Indices?8191:262144}setGrid(e){e.enabled?(this.gridOverlay?this.gridOverlay.setStyle({strokeColor:e.color,lineWidth:e.lineWidth}):this.gridOverlay=new I(this.containerDiv,{strokeColor:e.color??"rgba(144, 24, 24, 1)",lineWidth:e.lineWidth??1,zIndex:10}),this.showGrid=!0,this.gridOverlay.setVisible(!0),this.updateGridOverlay()):(this.showGrid=!1,this.gridOverlay&&this.gridOverlay.setVisible(!1))}isGridEnabled(){return this.showGrid}setAmbientEffect(e){typeof e=="boolean"?this.ambientEffectEnabled=e:(this.ambientEffectEnabled=!0,e.blur!==void 0&&(this.ambientEffectBlur=e.blur),e.scale!==void 0&&(this.ambientEffectScale=e.scale)),this.ambientEffectEnabled&&!this.ambientEffectCanvas&&this.createAmbientEffectCanvas(),this.ambientEffectCanvas&&(this.ambientEffectEnabled?(this.ambientEffectCanvas.style.display="block",this.ambientEffectCanvas.style.filter=`blur(${this.ambientEffectBlur}px)`,this.ambientEffectCanvas.style.transform=`scale(${this.ambientEffectScale})`,this.updateAmbientEffect()):this.ambientEffectCanvas.style.display="none")}createAmbientEffectCanvas(){this.ambientEffectCanvas||(this.ambientEffectCanvas=document.createElement("canvas"),this.ambientEffectCanvas.className="terminalgl-ambient-effect-canvas",this.ambientEffectCanvas.width=this.canvas.width,this.ambientEffectCanvas.height=this.canvas.height,this.ambientEffectCanvas.style.cssText=`
117
117
  display: block !important;
118
118
  position: absolute !important;
119
119
  width: ${this.canvas.width}px !important;
@@ -124,4 +124,4 @@ var k=Object.defineProperty;var V=(b,e,t)=>e in b?k(b,e,{enumerable:!0,configura
124
124
  transform: scale(${this.ambientEffectScale}) !important;
125
125
  pointer-events: none !important;
126
126
  z-index: 0 !important;
127
- `,this.ambientEffectCtx=this.ambientEffectCanvas.getContext("2d",{alpha:!0}),this.containerDiv.insertBefore(this.ambientEffectCanvas,this.canvas),console.warn("[TerminalGL] \u{1F308} ambient effect canvas created dynamically"))}isAmbientEffectEnabled(){return this.ambientEffectEnabled}getAmbientEffectConfig(){return{enabled:this.ambientEffectEnabled,blur:this.ambientEffectBlur,scale:this.ambientEffectScale}}getCols(){return this.cols}getRows(){return this.rows}isReady(){return!!(this.fontLoaded&&this.atlasTexture&&this.program)}destroy(){this.dispose()}dispose(){this.resizeObserver&&this.resizeObserver.disconnect();let e=this.gl;this.program&&e.deleteProgram(this.program),this.positionBuffer&&e.deleteBuffer(this.positionBuffer),this.texCoordBuffer&&e.deleteBuffer(this.texCoordBuffer),this.colorIndexBuffer&&e.deleteBuffer(this.colorIndexBuffer),this.indexBuffer&&e.deleteBuffer(this.indexBuffer),this.instanceDataBuffer&&e.deleteBuffer(this.instanceDataBuffer),this.atlasTexture&&e.deleteTexture(this.atlasTexture),this.paletteTexture&&e.deleteTexture(this.paletteTexture),this.vao&&this.vaoExtension&&this.vaoExtension.deleteVertexArrayOES(this.vao);let t=e.getExtension("WEBGL_lose_context");t&&t.loseContext(),this.atlasCanvas&&(this.atlasCanvas.width=0,this.atlasCanvas.height=0,this.atlasCanvas=void 0),this.containerDiv.parentElement&&this.containerDiv.parentElement.removeChild(this.containerDiv),this.canvas.width=0,this.canvas.height=0,this.ambientEffectCanvas&&(this.ambientEffectCanvas.width=0,this.ambientEffectCanvas.height=0,this.ambientEffectCanvas=null),this.gridOverlay&&(this.gridOverlay.destroy(),this.gridOverlay=void 0),this.renderPositions=new Float32Array(0),this.renderTexCoords=new Float32Array(0),this.renderColorIndices=new Float32Array(0),this.renderIndices=new Uint32Array(0),this.paletteFloat=new Float32Array(0),this.atlasUVs=new Float32Array(0),this.instanceData=new Float32Array(0),this.templateQuadPositions=new Float32Array(0),this.templateQuadIndices=new Uint16Array(0)}};C(U,"TerminalGL");var M=U;var P=["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff","#080808","#121212","#1c1c1c","#262626","#303030","#3a3a3a","#444444","#4e4e4e","#585858","#626262","#6c6c6c","#767676","#808080","#8a8a8a","#949494","#9e9e9e","#a80000","#00a800","#a8a800","#0000a8","#a800a8","#00a8a8","#a8a8a8","#545454","#fc5454","#54fc54","#fcfc54","#5454fc","#fc54fc","#54fcfc","#fcfcfc","#000000",...Array(192).fill("#808080")];function Y(b,e=P){return b<0||b>=e.length?"#ff00ff":e[b]}C(Y,"paletteIndexToColor");function N(b,e=P){let t=e.indexOf(b.toLowerCase());return t>=0?t:0}C(N,"colorToPaletteIndex");export{P as DEFAULT_PALETTE,I as GridOverlay,T as ScalingMode,M as TerminalGL,N as colorToPaletteIndex,L as getAtlasColumns,D as getCharGridPosition,_ as getMaxCharCode,Y as paletteIndexToColor};
127
+ `,this.ambientEffectCtx=this.ambientEffectCanvas.getContext("2d",{alpha:!0}),this.containerDiv.insertBefore(this.ambientEffectCanvas,this.canvas),console.warn("[TerminalGL] \u{1F308} ambient effect canvas created dynamically"))}isAmbientEffectEnabled(){return this.ambientEffectEnabled}getAmbientEffectConfig(){return{enabled:this.ambientEffectEnabled,blur:this.ambientEffectBlur,scale:this.ambientEffectScale}}getCols(){return this.cols}getRows(){return this.rows}isReady(){return!!(this.fontLoaded&&this.atlasTexture&&this.program)}destroy(){this.dispose()}dispose(){this.resizeObserver&&this.resizeObserver.disconnect();let e=this.gl;this.program&&e.deleteProgram(this.program),this.positionBuffer&&e.deleteBuffer(this.positionBuffer),this.texCoordBuffer&&e.deleteBuffer(this.texCoordBuffer),this.colorIndexBuffer&&e.deleteBuffer(this.colorIndexBuffer),this.indexBuffer&&e.deleteBuffer(this.indexBuffer),this.instanceDataBuffer&&e.deleteBuffer(this.instanceDataBuffer),this.atlasTexture&&e.deleteTexture(this.atlasTexture),this.paletteTexture&&e.deleteTexture(this.paletteTexture),this.vao&&this.vaoExtension&&this.vaoExtension.deleteVertexArrayOES(this.vao);let t=e.getExtension("WEBGL_lose_context");t&&t.loseContext(),this.atlasCanvas&&(this.atlasCanvas.width=0,this.atlasCanvas.height=0,this.atlasCanvas=void 0),this.containerDiv.parentElement&&this.containerDiv.parentElement.removeChild(this.containerDiv),this.canvas.width=0,this.canvas.height=0,this.ambientEffectCanvas&&(this.ambientEffectCanvas.width=0,this.ambientEffectCanvas.height=0,this.ambientEffectCanvas=null),this.gridOverlay&&(this.gridOverlay.destroy(),this.gridOverlay=void 0),this.renderPositions=new Float32Array(0),this.renderTexCoords=new Float32Array(0),this.renderColorIndices=new Float32Array(0),this.renderIndices=new Uint32Array(0),this.paletteFloat=new Float32Array(0),this.atlasUVs=new Float32Array(0),this.instanceData=new Float32Array(0),this.templateQuadPositions=new Float32Array(0),this.templateQuadIndices=new Uint16Array(0)}};E(y,"TerminalGL");var D=y;var M=["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff","#080808","#121212","#1c1c1c","#262626","#303030","#3a3a3a","#444444","#4e4e4e","#585858","#626262","#6c6c6c","#767676","#808080","#8a8a8a","#949494","#9e9e9e","#a80000","#00a800","#a8a800","#0000a8","#a800a8","#00a8a8","#a8a8a8","#545454","#fc5454","#54fc54","#fcfc54","#5454fc","#fc54fc","#54fcfc","#fcfcfc","#000000",...Array(192).fill("#808080")];function Y(v,e=M){return v<0||v>=e.length?"#ff00ff":e[v]}E(Y,"paletteIndexToColor");function k(v,e=M){let t=e.indexOf(v.toLowerCase());return t>=0?t:0}E(k,"colorToPaletteIndex");export{M as DEFAULT_PALETTE,I as GridOverlay,C as ScalingMode,D as TerminalGL,k as colorToPaletteIndex,F as getAtlasColumns,_ as getCharGridPosition,L as getMaxCharCode,Y as paletteIndexToColor};