@utsp/render 0.17.0-nightly.20260120215017.712755a → 0.17.0-nightly.20260123123115.a871a17

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 k=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var V=(u,e,t)=>e in u?U(u,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):u[e]=t;var p=(u,e)=>U(u,"name",{value:e,configurable:!0});var X=(u,e)=>{for(var t in e)U(u,t,{get:e[t],enumerable:!0})},q=(u,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of k(e))!z.call(u,s)&&s!==t&&U(u,s,{get:()=>e[s],enumerable:!(i=Y(e,s))||i.enumerable});return u};var Q=u=>q(U({},"__esModule",{value:!0}),u);var a=(u,e,t)=>(V(u,typeof e!="symbol"?e+"":e,t),t);var j={};X(j,{DEFAULT_PALETTE:()=>D,GridOverlay:()=>I,ScalingMode:()=>v.ScalingMode,TerminalGL:()=>L,colorToPaletteIndex:()=>N,getAtlasColumns:()=>w,getCharGridPosition:()=>_,getMaxCharCode:()=>B,paletteIndexToColor:()=>$});module.exports=Q(j);var M=class M{constructor(e,t){a(this,"canvas");a(this,"ctx");a(this,"container");a(this,"cols",0);a(this,"rows",0);a(this,"cellWidth",0);a(this,"cellHeight",0);a(this,"offsetX",0);a(this,"offsetY",0);a(this,"strokeColor","rgba(80, 80, 80, 0.4)");a(this,"lineWidth",1);this.container=e,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let i=t?.zIndex??10;this.canvas.style.cssText=`
1
+ "use strict";var U=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var X=(d,t,e)=>t in d?U(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var g=(d,t)=>U(d,"name",{value:t,configurable:!0});var $=(d,t)=>{for(var e in t)U(d,e,{get:t[e],enumerable:!0})},q=(d,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of V(t))!z.call(d,s)&&s!==e&&U(d,s,{get:()=>t[s],enumerable:!(i=k(t,s))||i.enumerable});return d};var Q=d=>q(U({},"__esModule",{value:!0}),d);var n=(d,t,e)=>(X(d,typeof t!="symbol"?t+"":t,e),e);var j={};$(j,{DEFAULT_PALETTE:()=>L,GridOverlay:()=>I,ScalingMode:()=>v.ScalingMode,TerminalGL:()=>F,colorToPaletteIndex:()=>N,getAtlasColumns:()=>y,getCharGridPosition:()=>_,getMaxCharCode:()=>B,paletteIndexToColor:()=>Y});module.exports=Q(j);var S=class S{constructor(t,e){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=t,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let i=e?.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
7
  z-index: ${i} !important;
8
- `,this.container.appendChild(this.canvas);let s=this.canvas.getContext("2d");if(!s)throw new Error("[GridOverlay] Impossible de cr\xE9er le contexte 2D");this.ctx=s,t&&(t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth))}setDimensions(e,t,i,s,r=0,l=0){this.cols=e,this.rows=t,this.cellWidth=i,this.cellHeight=s,this.offsetX=r,this.offsetY=l}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,i,s,r){let l=s.left-r.left,o=s.top-r.top,n=s.width,c=s.height;(this.canvas.width!==n||this.canvas.height!==c)&&(this.canvas.width=n,this.canvas.height=c);let h=this.canvas.style;h.width=`${n}px`,h.height=`${c}px`,h.left=`${l}px`,h.top=`${o}px`}render(){if(!this.ctx)return;let e=this.cols*this.cellWidth,t=this.rows*this.cellHeight,i=e>0?this.canvas.width/e:1,s=t>0?this.canvas.height/t:1,r=Math.min(i,s),l=this.cellWidth*r,o=this.cellHeight*r,n=this.cols*l,c=this.rows*o,h=this.offsetX*r,d=this.offsetY*r;if(!(n===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*r),this.ctx.beginPath();for(let m=0;m<=this.cols;m++){let b=h+m*l+.5;this.ctx.moveTo(b,d),this.ctx.lineTo(b,d+c)}for(let m=0;m<=this.rows;m++){let b=d+m*o+.5;this.ctx.moveTo(h,b),this.ctx.lineTo(h+n,b)}this.ctx.stroke()}}update(e,t,i,s,r,l,o=0,n=0){this.setDimensions(e,t,i,s,o,n),this.setCanvasSize(r,l),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}};p(M,"GridOverlay");var I=M;function w(u){return Math.sqrt(u)*16}p(w,"getAtlasColumns");function B(u){return u*256-1}p(B,"getMaxCharCode");function _(u,e){let t=Math.floor(u/256),i=u%256,s=Math.sqrt(e),r=t%s,l=Math.floor(t/s),o=i%16,n=Math.floor(i/16);return{col:r*16+o,row:l*16+n}}p(_,"getCharGridPosition");var v=require("@utsp/types");var F=class F{constructor(e,t){a(this,"canvas");a(this,"gl");a(this,"parentElement");a(this,"containerDiv");a(this,"cols");a(this,"rows");a(this,"charWidth");a(this,"charHeight");a(this,"cellWidth",8);a(this,"cellHeight",8);a(this,"glyphOffsetX",0);a(this,"glyphOffsetY",0);a(this,"canvasBgColor");a(this,"showGrid");a(this,"supportsUint32Indices",!1);a(this,"useUint16Indices",!1);a(this,"gridOverlay");a(this,"bitmapFont");a(this,"atlasTexture",null);a(this,"atlasCanvas");a(this,"atlasColumns",0);a(this,"fontLoaded",!1);a(this,"paletteTexture",null);a(this,"program",null);a(this,"positionBuffer",null);a(this,"texCoordBuffer",null);a(this,"colorIndexBuffer",null);a(this,"indexBuffer",null);a(this,"aPosition");a(this,"aTexCoord");a(this,"aColorIndex");a(this,"uResolution",null);a(this,"uTexture",null);a(this,"uPalette",null);a(this,"resizeObserver");a(this,"charCodeToAtlasIndex",new Uint16Array(65536).fill(65535));a(this,"atlasUVs",new Float32Array(0));a(this,"cachedAtlasWidth",0);a(this,"cachedAtlasHeight",0);a(this,"paletteFloat",new Float32Array(256*4));a(this,"maxCells",0);a(this,"renderPositions",new Float32Array(0));a(this,"renderTexCoords",new Float32Array(0));a(this,"renderColorIndices",new Float32Array(0));a(this,"renderIndices",new Uint32Array(0));a(this,"cachedResolution",[0,0]);a(this,"cachedTextureUnit",-1);a(this,"cachedPaletteUnit",-1);a(this,"cachedTextureUniform",!1);a(this,"cachedPaletteUniform",!1);a(this,"paletteHash",0);a(this,"currentScale",1);a(this,"scalingMode",v.ScalingMode.None);a(this,"ambientEffectEnabled",!1);a(this,"ambientEffectCanvas",null);a(this,"ambientEffectCtx",null);a(this,"ambientEffectBlur",v.POST_PROCESS_DEFAULTS.ambientEffect.blur);a(this,"ambientEffectScale",v.POST_PROCESS_DEFAULTS.ambientEffect.scale);a(this,"ambientEffectOpacity",.7);a(this,"onResizeCallback");a(this,"staticPositionsInitialized",!1);a(this,"vaoExtension",null);a(this,"vao",null);a(this,"instancedExtension",null);a(this,"useInstancing",!1);a(this,"instanceDataBuffer",null);a(this,"instanceData",new Float32Array(0));a(this,"templateQuadPositions",new Float32Array(0));a(this,"templateQuadIndices",new Uint16Array(0));a(this,"aInstanceOffset",-1);a(this,"aInstanceUVs",-1);a(this,"aInstanceColors",-1);a(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 i=t.cols*t.rows,s=F.checkCompatibility();if(s.errors.length>0)throw new Error(`TerminalGL: WebGL incompatible - ${s.errors.join(", ")}`);let r=t.forceUint16??!1;if(r&&i>s.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${i} cells) exceeds Uint16 limit of ${s.maxCellsUint16} cells. Maximum size with Uint16: ${Math.floor(Math.sqrt(s.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(s.maxCellsUint16))} (or smaller rectangles like 127\xD764)`);if(!s.uint32Indices&&i>s.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${i} cells) exceeds device limit of ${s.maxCellsUint16} cells (OES_element_index_uint not supported). Maximum size: ${Math.floor(Math.sqrt(s.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(s.maxCellsUint16))}`);i>s.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Large terminal size ${t.cols}\xD7${t.rows} (${i} cells) exceeds recommended limit of ${s.recommendedMaxCells} cells. Performance may be impacted.`),s.warnings.length>0&&console.warn("[TerminalGL] WebGL Compatibility Warnings:",s.warnings);let l=t.charWidth??8,o=t.charHeight??8;if(!Number.isFinite(l)||l<=0)throw new Error(`TerminalGL: Invalid charWidth: ${l}. Must be a positive number.`);if(!Number.isFinite(o)||o<=0)throw new Error(`TerminalGL: Invalid charHeight: ${o}. Must be a positive number.`);for(this.parentElement=e,this.cols=t.cols,this.rows=t.rows,this.charWidth=l,this.charHeight=o,this.canvasBgColor=t.canvasBgColor!==void 0?t.canvasBgColor:null,this.showGrid=t.showGrid??!1,this.scalingMode=t.scalingMode??v.ScalingMode.None,t.ambientEffect&&(this.ambientEffectEnabled=!0,typeof t.ambientEffect=="object"&&(this.ambientEffectBlur=t.ambientEffect.blur??v.POST_PROCESS_DEFAULTS.ambientEffect.blur,this.ambientEffectScale=t.ambientEffect.scale??v.POST_PROCESS_DEFAULTS.ambientEffect.scale,this.ambientEffectOpacity=t.ambientEffect.opacity??.7));this.parentElement.firstChild;)this.parentElement.removeChild(this.parentElement.firstChild);let n=window.getComputedStyle(this.parentElement).position;n!=="relative"&&n!=="absolute"&&n!=="fixed"&&(this.parentElement.style.position="relative"),this.containerDiv=document.createElement("div"),this.containerDiv.className="terminalgl-container",this.containerDiv.style.cssText=`
8
+ `,this.container.appendChild(this.canvas);let s=this.canvas.getContext("2d");if(!s)throw new Error("[GridOverlay] Impossible de cr\xE9er le contexte 2D");this.ctx=s,e&&(e.strokeColor&&(this.strokeColor=e.strokeColor),e.lineWidth!==void 0&&(this.lineWidth=e.lineWidth))}setDimensions(t,e,i,s,a=0,h=0){this.cols=t,this.rows=e,this.cellWidth=i,this.cellHeight=s,this.offsetX=a,this.offsetY=h}setCanvasSize(t,e){this.canvas.width=t,this.canvas.height=e,this.ctx.setTransform(1,0,0,1,0,0)}setStyle(t){t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth)}setTransform(t,e,i,s,a){let h=s.left-a.left,o=s.top-a.top,l=s.width,r=s.height;(this.canvas.width!==l||this.canvas.height!==r)&&(this.canvas.width=l,this.canvas.height=r);let c=this.canvas.style;c.width=`${l}px`,c.height=`${r}px`,c.left=`${h}px`,c.top=`${o}px`}render(){if(!this.ctx)return;let t=this.cols*this.cellWidth,e=this.rows*this.cellHeight,i=t>0?this.canvas.width/t:1,s=e>0?this.canvas.height/e:1,a=Math.min(i,s),h=this.cellWidth*a,o=this.cellHeight*a,l=this.cols*h,r=this.rows*o,c=this.offsetX*a,x=this.offsetY*a;if(!(l===0||r===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*a),this.ctx.beginPath();for(let u=0;u<=this.cols;u++){let m=c+u*h+.5;this.ctx.moveTo(m,x),this.ctx.lineTo(m,x+r)}for(let u=0;u<=this.rows;u++){let m=x+u*o+.5;this.ctx.moveTo(c,m),this.ctx.lineTo(c+l,m)}this.ctx.stroke()}}update(t,e,i,s,a,h,o=0,l=0){this.setDimensions(t,e,i,s,o,l),this.setCanvasSize(a,h),this.render()}setVisible(t){this.canvas.style.display=t?"block":"none"}destroy(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}};g(S,"GridOverlay");var I=S;function y(d){return Math.sqrt(d)*16}g(y,"getAtlasColumns");function B(d){return d*256-1}g(B,"getMaxCharCode");function _(d,t){let e=Math.floor(d/256),i=d%256,s=Math.sqrt(t),a=e%s,h=Math.floor(e/s),o=i%16,l=Math.floor(i/16);return{col:a*16+o,row:h*16+l}}g(_,"getCharGridPosition");var v=require("@utsp/types");var D=class D{constructor(t,e){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",v.ScalingMode.None);n(this,"ambientEffectEnabled",!1);n(this,"ambientEffectCanvas",null);n(this,"ambientEffectCtx",null);n(this,"ambientEffectBlur",v.POST_PROCESS_DEFAULTS.ambientEffect.blur);n(this,"ambientEffectScale",v.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));n(this,"aInstanceOffset",-1);n(this,"aInstanceUVs",-1);n(this,"aInstanceColors",-1);n(this,"uCellSize",null);if(!t)throw new Error("TerminalGL: Parent element is required");if(!Number.isInteger(e.cols)||e.cols<=0)throw new Error(`TerminalGL: Invalid cols: ${e.cols}. Must be a positive integer.`);if(!Number.isInteger(e.rows)||e.rows<=0)throw new Error(`TerminalGL: Invalid rows: ${e.rows}. Must be a positive integer.`);let i=e.cols*e.rows,s=D.checkCompatibility();if(s.errors.length>0)throw new Error(`TerminalGL: WebGL incompatible - ${s.errors.join(", ")}`);let a=e.forceUint16??!1;if(a&&i>s.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${e.cols}\xD7${e.rows} (${i} cells) exceeds Uint16 limit of ${s.maxCellsUint16} cells. Maximum size with Uint16: ${Math.floor(Math.sqrt(s.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(s.maxCellsUint16))} (or smaller rectangles like 127\xD764)`);if(!s.uint32Indices&&i>s.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${e.cols}\xD7${e.rows} (${i} cells) exceeds device limit of ${s.maxCellsUint16} cells (OES_element_index_uint not supported). Maximum size: ${Math.floor(Math.sqrt(s.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(s.maxCellsUint16))}`);let h=e.charWidth??8,o=e.charHeight??8;if(!Number.isFinite(h)||h<=0)throw new Error(`TerminalGL: Invalid charWidth: ${h}. Must be a positive number.`);if(!Number.isFinite(o)||o<=0)throw new Error(`TerminalGL: Invalid charHeight: ${o}. Must be a positive number.`);for(this.parentElement=t,this.cols=e.cols,this.rows=e.rows,this.charWidth=h,this.charHeight=o,this.canvasBgColor=e.canvasBgColor!==void 0?e.canvasBgColor:null,this.showGrid=e.showGrid??!1,this.scalingMode=e.scalingMode??v.ScalingMode.None,e.ambientEffect&&(this.ambientEffectEnabled=!0,typeof e.ambientEffect=="object"&&(this.ambientEffectBlur=e.ambientEffect.blur??v.POST_PROCESS_DEFAULTS.ambientEffect.blur,this.ambientEffectScale=e.ambientEffect.scale??v.POST_PROCESS_DEFAULTS.ambientEffect.scale,this.ambientEffectOpacity=e.ambientEffect.opacity??.7));this.parentElement.firstChild;)this.parentElement.removeChild(this.parentElement.firstChild);let l=window.getComputedStyle(this.parentElement).position;l!=="relative"&&l!=="absolute"&&l!=="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;
@@ -35,7 +35,7 @@
35
35
  z-index: 1 !important;
36
36
  pointer-events: auto !important;
37
37
  touch-action: none !important;
38
- `;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=r||!this.supportsUint32Indices,this.useUint16Indices?console.warn(`[TerminalGL] \u{1F4CA} Using Uint16 indices (max ${s.maxCellsUint16} cells)`):console.warn(`[TerminalGL] \u{1F4CA} Using Uint32 indices (max ${s.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(h){throw console.error("[TerminalGL] \u274C Failed to initialize WebGL:",h),h}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"),i=t.getContext("webgl")||t.getContext("experimental-webgl");if(!i||!(i instanceof WebGLRenderingContext))return e.errors.push("\u274C WebGL 1.0 not supported by this browser/device"),e;let s=i;e.webgl1=!0;try{e.maxTextureSize=s.getParameter(s.MAX_TEXTURE_SIZE);let n=s.getParameter(s.MAX_VIEWPORT_DIMS);e.maxViewportDims=[n[0],n[1]]}catch(n){return e.errors.push(`\u274C Failed to query WebGL parameters: ${n}`),e}let r=s.getExtension("OES_element_index_uint");e.uint32Indices=!!r;let l=8;if(e.maxCellsUint16=Math.floor(65535/l),e.uint32Indices){let n=Math.floor(e.maxTextureSize*e.maxTextureSize/64);e.maxCellsUint32=Math.min(n,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]}`),s.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,i=this.glyphOffsetX,s=this.glyphOffsetY,r=this.charWidth,l=this.charHeight,o=0,n=0,c=0;for(let d=0;d<this.rows;d++){let m=Math.round(d*t),b=Math.round(m+t);for(let x=0;x<this.cols;x++){let f=Math.round(x*e),E=Math.round(f+e);this.renderPositions[o++]=f,this.renderPositions[o++]=m,this.renderPositions[o++]=E,this.renderPositions[o++]=m,this.renderPositions[o++]=f,this.renderPositions[o++]=b,this.renderPositions[o++]=E,this.renderPositions[o++]=b,this.renderIndices[n++]=c,this.renderIndices[n++]=c+1,this.renderIndices[n++]=c+2,this.renderIndices[n++]=c+2,this.renderIndices[n++]=c+1,this.renderIndices[n++]=c+3,c+=4;let C=Math.round(f+i),g=Math.round(m+s),y=Math.round(C+r),A=Math.round(g+l);this.renderPositions[o++]=C,this.renderPositions[o++]=g,this.renderPositions[o++]=y,this.renderPositions[o++]=g,this.renderPositions[o++]=C,this.renderPositions[o++]=A,this.renderPositions[o++]=y,this.renderPositions[o++]=A,this.renderIndices[n++]=c,this.renderIndices[n++]=c+1,this.renderIndices[n++]=c+2,this.renderIndices[n++]=c+2,this.renderIndices[n++]=c+1,this.renderIndices[n++]=c+3,c+=4}}let h=this.gl;h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.bufferSubData(h.ARRAY_BUFFER,0,this.renderPositions),h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),h.bufferSubData(h.ELEMENT_ARRAY_BUFFER,0,this.renderIndices),this.staticPositionsInitialized=!0}initWebGL(){let e=this.gl,t;this.useInstancing?t=`
38
+ `;let r=this.canvas.getContext("webgl",{alpha:this.canvasBgColor===null,premultipliedAlpha:!1});if(!r)throw new Error("TerminalGL: WebGL not supported");this.gl=r,this.supportsUint32Indices=!!r.getExtension("OES_element_index_uint"),this.useUint16Indices=a||!this.supportsUint32Indices,this.vaoExtension=r.getExtension("OES_vertex_array_object"),this.instancedExtension=r.getExtension("ANGLE_instanced_arrays"),this.instancedExtension&&(this.useInstancing=!0),this.containerDiv.appendChild(this.canvas),this.ambientEffectEnabled&&this.createAmbientEffectCanvas(),this.parentElement.appendChild(this.containerDiv),this.initRenderBuffers();try{this.initWebGL()}catch(c){throw console.error("[TerminalGL] \u274C Failed to initialize WebGL:",c),c}this.showGrid&&this.initGridOverlay(),this.setupResizeObserver()}static checkCompatibility(){let t={webgl1:!1,uint32Indices:!1,maxTextureSize:0,maxViewportDims:[0,0],maxCellsUint16:0,maxCellsUint32:0,recommendedMaxCells:0,warnings:[],errors:[]},e=document.createElement("canvas"),i=e.getContext("webgl")||e.getContext("experimental-webgl");if(!i||!(i instanceof WebGLRenderingContext))return t.errors.push("\u274C WebGL 1.0 not supported by this browser/device"),t;let s=i;t.webgl1=!0;try{t.maxTextureSize=s.getParameter(s.MAX_TEXTURE_SIZE);let l=s.getParameter(s.MAX_VIEWPORT_DIMS);t.maxViewportDims=[l[0],l[1]]}catch(l){return t.errors.push(`\u274C Failed to query WebGL parameters: ${l}`),t}let a=s.getExtension("OES_element_index_uint");t.uint32Indices=!!a;let h=8;if(t.maxCellsUint16=Math.floor(65535/h),t.uint32Indices){let l=Math.floor(t.maxTextureSize*t.maxTextureSize/64);t.maxCellsUint32=Math.min(l,262144)}else t.maxCellsUint32=t.maxCellsUint16,t.warnings.push(`\u26A0\uFE0F OES_element_index_uint not supported - limited to ${t.maxCellsUint16} cells (e.g., 90\xD790 or 127\xD764)`);return t.recommendedMaxCells=Math.floor((t.uint32Indices?t.maxCellsUint32:t.maxCellsUint16)*.8),t.maxTextureSize<256?t.errors.push(`\u274C MAX_TEXTURE_SIZE too small: ${t.maxTextureSize} (minimum 256 required for font atlas)`):t.maxTextureSize<2048&&t.warnings.push(`\u26A0\uFE0F Small MAX_TEXTURE_SIZE: ${t.maxTextureSize} (may limit font atlas)`),(t.maxViewportDims[0]<1024||t.maxViewportDims[1]<768)&&t.warnings.push(`\u26A0\uFE0F Small MAX_VIEWPORT_DIMS: ${t.maxViewportDims[0]}\xD7${t.maxViewportDims[1]}`),s.getExtension("WEBGL_lose_context")||t.warnings.push("\u26A0\uFE0F WEBGL_lose_context not supported - may cause memory leaks"),t}initInstancedBuffers(){let t=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]),t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.bufferData(t.ARRAY_BUFFER,this.templateQuadPositions,t.STATIC_DRAW),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer),t.bufferData(t.ELEMENT_ARRAY_BUFFER,this.templateQuadIndices,t.STATIC_DRAW),this.instanceData=new Float32Array(this.maxCells*8),t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer),t.bufferData(t.ARRAY_BUFFER,this.instanceData.byteLength,t.DYNAMIC_DRAW)}initRenderBuffers(){let t=this.cols*this.rows*2;this.maxCells=Math.ceil(t*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 t=this.cellWidth,e=this.cellHeight,i=this.glyphOffsetX,s=this.glyphOffsetY,a=this.charWidth,h=this.charHeight,o=0,l=0,r=0;for(let x=0;x<this.rows;x++){let u=Math.round(x*e),m=Math.round(u+e);for(let b=0;b<this.cols;b++){let f=Math.round(b*t),E=Math.round(f+t);this.renderPositions[o++]=f,this.renderPositions[o++]=u,this.renderPositions[o++]=E,this.renderPositions[o++]=u,this.renderPositions[o++]=f,this.renderPositions[o++]=m,this.renderPositions[o++]=E,this.renderPositions[o++]=m,this.renderIndices[l++]=r,this.renderIndices[l++]=r+1,this.renderIndices[l++]=r+2,this.renderIndices[l++]=r+2,this.renderIndices[l++]=r+1,this.renderIndices[l++]=r+3,r+=4;let C=Math.round(f+i),p=Math.round(u+s),w=Math.round(C+a),A=Math.round(p+h);this.renderPositions[o++]=C,this.renderPositions[o++]=p,this.renderPositions[o++]=w,this.renderPositions[o++]=p,this.renderPositions[o++]=C,this.renderPositions[o++]=A,this.renderPositions[o++]=w,this.renderPositions[o++]=A,this.renderIndices[l++]=r,this.renderIndices[l++]=r+1,this.renderIndices[l++]=r+2,this.renderIndices[l++]=r+2,this.renderIndices[l++]=r+1,this.renderIndices[l++]=r+3,r+=4}}let c=this.gl;c.bindBuffer(c.ARRAY_BUFFER,this.positionBuffer),c.bufferSubData(c.ARRAY_BUFFER,0,this.renderPositions),c.bindBuffer(c.ELEMENT_ARRAY_BUFFER,this.indexBuffer),c.bufferSubData(c.ELEMENT_ARRAY_BUFFER,0,this.renderIndices),this.staticPositionsInitialized=!0}initWebGL(){let t=this.gl,e;this.useInstancing?e=`
39
39
  // Per-vertex attributes (template quad)
40
40
  attribute vec2 aPosition; // Local quad position (0,0 to cellW,cellH)
41
41
 
@@ -74,7 +74,7 @@
74
74
  float paletteU = (colorIndex + 0.5) / 256.0;
75
75
  vColor = texture2D(uPalette, vec2(paletteU, 0.5));
76
76
  }
77
- `:t=`
77
+ `:e=`
78
78
  attribute vec2 aPosition;
79
79
  attribute vec2 aTexCoord;
80
80
  attribute float aColorIndex; // \u{1F680} Index dans palette (0-255)
@@ -116,7 +116,7 @@
116
116
  gl_FragColor = vec4(texColor.rgb * vColor.rgb, texColor.a);
117
117
  }
118
118
  }
119
- `,s=this.compileShader(e.VERTEX_SHADER,t),r=this.compileShader(e.FRAGMENT_SHADER,i);if(!s||!r)throw new Error("Shader compilation error");let l=e.createProgram();if(!l)throw new Error("Unable to create WebGL program");if(e.attachShader(l,s),e.attachShader(l,r),e.linkProgram(l),!e.getProgramParameter(l,e.LINK_STATUS)){let o=e.getProgramInfoLog(l);throw new Error("Program linking error: "+o)}this.program=l,this.cachedTextureUniform=!1,this.cachedPaletteUniform=!1,this.aPosition=e.getAttribLocation(l,"aPosition"),this.useInstancing?(this.aInstanceOffset=e.getAttribLocation(l,"aInstanceOffset"),this.aInstanceUVs=e.getAttribLocation(l,"aInstanceUVs"),this.aInstanceColors=e.getAttribLocation(l,"aInstanceColors"),this.uCellSize=e.getUniformLocation(l,"uCellSize"),this.instanceDataBuffer=e.createBuffer(),this.aTexCoord=this.aInstanceOffset,this.aColorIndex=this.aInstanceUVs):(this.aTexCoord=e.getAttribLocation(l,"aTexCoord"),this.aColorIndex=e.getAttribLocation(l,"aColorIndex")),this.uResolution=e.getUniformLocation(l,"uResolution"),this.uTexture=e.getUniformLocation(l,"uTexture"),this.uPalette=e.getUniformLocation(l,"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 i=this.gl,s=i.createShader(e);return s?(i.shaderSource(s,t),i.compileShader(s),i.getShaderParameter(s,i.COMPILE_STATUS)?s:(console.error("Shader compilation error:",i.getShaderInfoLog(s)),i.deleteShader(s),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,i=this.canvas.getBoundingClientRect(),s=this.containerDiv.getBoundingClientRect();this.gridOverlay.setDimensions(this.cols,this.rows,this.cellWidth,this.cellHeight,0,0),this.gridOverlay.setTransform(this.currentScale,e,t,i,s),this.gridOverlay.render()}setBitmapFont(e,t,i,s=t,r=i){this.bitmapFont=e,this.fontLoaded=!0,this.charWidth=t,this.charHeight=i,this.cellWidth=s,this.cellHeight=r,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),this.generateAtlas(),this.updateCanvasSize()}generateAtlas(){if(!this.bitmapFont)return;this.atlasColumns=16;let e=256,t=this.atlasColumns*this.charWidth,s=Math.ceil(e/this.atlasColumns)*this.charHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=t,this.atlasCanvas.height=s;let r=this.atlasCanvas.getContext("2d",{willReadFrequently:!0});if(!r)return;r.clearRect(0,0,t,s);let l=Array.from(this.bitmapFont.keys());for(let o of l){let n=this.bitmapFont.get(o);if(!n)continue;let c=o%this.atlasColumns,h=Math.floor(o/this.atlasColumns),d=c*this.charWidth,m=h*this.charHeight;for(let b=0;b<this.charHeight&&!(b>=n.length);b++){let x=n[b];for(let f=0;f<this.charWidth;f++){let E=1<<7-f;x&E&&(r.fillStyle="#FFFFFF",r.fillRect(d+f,m+b,1,1))}}}this.cachedAtlasWidth=t,this.cachedAtlasHeight=s,this.createAtlasTexture(),this.charCodeToAtlasIndex.fill(65535);for(let o=0;o<e;o++)this.charCodeToAtlasIndex[o]=o}async setImageFontStructure(e,t,i,s,r){let l=this.atlasCanvas&&this.fontLoaded&&this.charWidth===Math.round(e)&&this.charHeight===Math.round(t),o=this.atlasCanvas;this.fontLoaded=!0,this.charWidth=Math.round(e),this.charHeight=Math.round(t),this.cellWidth=Math.round(i),this.cellHeight=Math.round(s),this.atlasColumns=w(r);let n=B(r);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers();let c=w(r);if(this.cachedAtlasWidth=c*this.charWidth,this.cachedAtlasHeight=c*this.charHeight,this.allocateAtlasTexture(this.cachedAtlasWidth,this.cachedAtlasHeight),l&&o){console.warn("[TerminalGL] \u267B\uFE0F Preserving existing BitmapFont as Block 0");let h=this.gl;h.bindTexture(h.TEXTURE_2D,this.atlasTexture),h.texSubImage2D(h.TEXTURE_2D,0,0,0,h.RGBA,h.UNSIGNED_BYTE,o)}this.charCodeToAtlasIndex.fill(65535);for(let h=0;h<=n;h++)this.charCodeToAtlasIndex[h]=h;this.precomputeImageFontUVs(r),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()}async setImageFontBlock(e,t){let i=this.gl;if(!this.atlasTexture)return;let s=new Blob([t],{type:"image/png"}),r=await createImageBitmap(s),l=this.atlasColumns/16,o=e%l,n=Math.floor(e/l),c=o*16*this.charWidth,h=n*16*this.charHeight;i.bindTexture(i.TEXTURE_2D,this.atlasTexture),i.texSubImage2D(i.TEXTURE_2D,0,c,h,i.RGBA,i.UNSIGNED_BYTE,r),r.close()}async setImageFont(e,t,i,s,r,l){this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(i),this.cellWidth=Math.round(s),this.cellHeight=Math.round(r),this.atlasColumns=w(l);let o=B(l);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 n=0;n<=o;n++)this.charCodeToAtlasIndex[n]=n;this.precomputeImageFontUVs(l),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,i)=>{let s=new Uint8Array(e),r=new Blob([s],{type:"image/png"}),l=URL.createObjectURL(r),o=new Image;o.onload=()=>{URL.revokeObjectURL(l),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=o.width,this.atlasCanvas.height=o.height;let n=this.atlasCanvas.getContext("2d");if(!n){i(new Error("Failed to create 2D context for atlas"));return}n.drawImage(o,0,0),this.cachedAtlasWidth=o.width,this.cachedAtlasHeight=o.height,this.createAtlasTexture(),t()},o.onerror=()=>{URL.revokeObjectURL(l),i(new Error("Failed to load PNG image for ImageFont atlas"))},o.src=l})}precomputeImageFontUVs(e){let t=e*256;this.atlasUVs=new Float32Array(t*4);let i=this.cachedAtlasWidth,s=this.cachedAtlasHeight,r=.5/i,l=.5/s;for(let o=0;o<t;o++){let{col:n,row:c}=_(o,e),h=(n*this.charWidth+r)/i,d=(c*this.charHeight+l)/s,m=((n+1)*this.charWidth-r)/i,b=((c+1)*this.charHeight-l)/s,x=o*4;this.atlasUVs[x]=h,this.atlasUVs[x+1]=d,this.atlasUVs[x+2]=m,this.atlasUVs[x+3]=b}}allocateAtlasTexture(e,t){try{let i=this.gl,s=i.createTexture();if(!s)throw new Error("Unable to create texture");i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,e,t,0,i.RGBA,i.UNSIGNED_BYTE,null),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_S,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_T,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MIN_FILTER,i.NEAREST),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MAG_FILTER,i.NEAREST),this.atlasTexture=s}catch(i){throw console.error("[TerminalGL] \u274C Failed to create atlas texture:",i),i}}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),i=0,s=0,r=0;return t.length===3?(i=parseInt(t[0]+t[0],16),s=parseInt(t[1]+t[1],16),r=parseInt(t[2]+t[2],16)):t.length===6&&(i=parseInt(t.slice(0,2),16),s=parseInt(t.slice(2,4),16),r=parseInt(t.slice(4,6),16)),[i/255,s/255,r/255,1]}if(e.startsWith("rgb")){let t=e.match(/rgba?\(([^)]+)\)/);if(t){let i=t[1].split(",").map(s=>parseFloat(s.trim()));return[i[0]/255,i[1]/255,i[2]/255,i[3]!==void 0?i[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 i=this.cols*this.cellWidth,s=this.rows*this.cellHeight;if(i===0||s===0)return;let r=e/i,l=t/s,o=Math.min(r,l),n;switch(this.scalingMode){case v.ScalingMode.Integer:n=Math.max(1,Math.floor(o));break;case v.ScalingMode.Half:n=Math.max(1,Math.floor(o*2)/2);break;case v.ScalingMode.Quarter:n=Math.max(1,Math.floor(o*4)/4);break;case v.ScalingMode.Eighth:n=Math.max(1,Math.floor(o*8)/8);break;case v.ScalingMode.Responsive:n=1;break;case v.ScalingMode.None:default:n=Math.max(.1,o);break}if(this.canvas.style.transform=`scale(${n})`,this.ambientEffectEnabled&&this.ambientEffectCanvas){let c=n*this.ambientEffectScale;this.ambientEffectCanvas.style.transform=`scale(${c})`}this.currentScale=n,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 i=0;i<Math.min(e.length,256);i++){let s=e[i];t=(t<<5)-t+s.r,t=(t<<5)-t+s.g,t=(t<<5)-t+s.b,t=(t<<5)-t+s.a,t=t|0}if(t!==this.paletteHash){this.paletteHash=t;for(let i=0;i<e.length&&i<256;i++){let s=e[i],r=i*4;this.paletteFloat[r]=s.r/255,this.paletteFloat[r+1]=s.g/255,this.paletteFloat[r+2]=s.b/255,this.paletteFloat[r+3]=s.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 i=0;i<256;i++){let s=i*4;t[s]=this.paletteFloat[s]*255,t[s+1]=this.paletteFloat[s+1]*255,t[s+2]=this.paletteFloat[s+2]*255,t[s+3]=this.paletteFloat[s+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),e.passes&&e.passes.length>0?this.renderMultiPass(e,e.passes):this.renderDirect(e),this.ambientEffectEnabled&&this.ambientEffectCanvas&&this.ambientEffectCtx&&this.updateAmbientEffect()}catch(t){console.error("[TerminalGL] \u274C Error rendering display data:",t)}}renderMultiPass(e,t){for(let i=0;i<t.length;i++){let s=t[i],r={id:e.id,width:e.width,height:e.height,palette:e.palette,cells:s.cells};this.renderDirect(r,i===0)}}renderDirect(e,t=!0){let i=this.gl;if(!this.staticPositionsInitialized&&!this.useInstancing&&this.precomputeStaticPositions(),t){if(this.canvasBgColor!==null){let s=this.parseColor(this.canvasBgColor);i.clearColor(s[0],s[1],s[2],s[3])}else i.clearColor(0,0,0,0);i.clear(i.COLOR_BUFFER_BIT)}this.useInstancing?this.renderInstanced(e):this.renderDirectBuffers(e)}renderInstanced(e){let t=this.gl,i=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 s=0,r=this.instanceData.length/8,l=e.width*e.height*2;if(l>r){console.error(`[TerminalGL] \u274C Instance buffer too small! Need ${l}, have ${r}. Display size: ${e.width}\xD7${e.height}, buffer was sized for smaller terminal.`),this.renderDirectBuffers(e);return}for(let n=0;n<e.height;n++)for(let c=0;c<e.width;c++){let h=e.cells[n*e.width+c],d=h.bgColorIndex,m=h.fgColorIndex,b=this.canvasBgColor!==null&&d===255,x=h.char===" "||m===255;if(!b){if(s>=r){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${r}`);break}let f=s*8;this.instanceData[f]=c,this.instanceData[f+1]=n,this.instanceData[f+2]=0,this.instanceData[f+3]=0,this.instanceData[f+4]=0,this.instanceData[f+5]=0,this.instanceData[f+6]=d,this.instanceData[f+7]=0,s++}if(!x){let f=h.char.charCodeAt(0),E=this.charCodeToAtlasIndex[f];if(E!==65535){if(s>=r){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${r}`);break}let C=E*4,g=s*8;this.instanceData[g]=c,this.instanceData[g+1]=n,this.instanceData[g+2]=this.atlasUVs[C],this.instanceData[g+3]=this.atlasUVs[C+1],this.instanceData[g+4]=this.atlasUVs[C+2],this.instanceData[g+5]=this.atlasUVs[C+3],this.instanceData[g+6]=0,this.instanceData[g+7]=m,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),i.vertexAttribDivisorANGLE(this.aPosition,0),t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer);let o=8*Float32Array.BYTES_PER_ELEMENT;t.enableVertexAttribArray(this.aInstanceOffset),t.vertexAttribPointer(this.aInstanceOffset,2,t.FLOAT,!1,o,0),i.vertexAttribDivisorANGLE(this.aInstanceOffset,1),t.enableVertexAttribArray(this.aInstanceUVs),t.vertexAttribPointer(this.aInstanceUVs,4,t.FLOAT,!1,o,2*Float32Array.BYTES_PER_ELEMENT),i.vertexAttribDivisorANGLE(this.aInstanceUVs,1),t.enableVertexAttribArray(this.aInstanceColors),t.vertexAttribPointer(this.aInstanceColors,2,t.FLOAT,!1,o,6*Float32Array.BYTES_PER_ELEMENT),i.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),i.drawElementsInstancedANGLE(t.TRIANGLES,6,t.UNSIGNED_SHORT,0,s),i.vertexAttribDivisorANGLE(this.aPosition,0),i.vertexAttribDivisorANGLE(this.aInstanceOffset,0),i.vertexAttribDivisorANGLE(this.aInstanceUVs,0),i.vertexAttribDivisorANGLE(this.aInstanceColors,0)}renderDirectBuffers(e){let t=this.gl,i=e.width*e.height,s=i*2;if(s>this.maxCells){console.error(`[TerminalGL] \u274C Buffer overflow detected! Trying to render ${s} quads but buffer capacity is ${this.maxCells}. This should not happen - resize() should have reallocated.`);return}let r=0,l=0,o=e.cells,n=i;for(let x=0;x<n;x++){let f=o[x],E=f.bgColorIndex,g=this.canvasBgColor!==null&&E===255?255:E,y=0;for(let T=0;T<4;T++)this.renderTexCoords[r++]=y,this.renderTexCoords[r++]=y,this.renderColorIndices[l++]=g;let A=f.fgColorIndex,S=f.char;if(S===" "||A===255)for(let T=0;T<4;T++)this.renderTexCoords[r++]=0,this.renderTexCoords[r++]=0,this.renderColorIndices[l++]=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[r++]=G,this.renderTexCoords[r++]=W,this.renderColorIndices[l++]=A,this.renderTexCoords[r++]=O,this.renderTexCoords[r++]=W,this.renderColorIndices[l++]=A,this.renderTexCoords[r++]=G,this.renderTexCoords[r++]=H,this.renderColorIndices[l++]=A,this.renderTexCoords[r++]=O,this.renderTexCoords[r++]=H,this.renderColorIndices[l++]=A}else for(let R=0;R<4;R++)this.renderTexCoords[r++]=0,this.renderTexCoords[r++]=0,this.renderColorIndices[l++]=255}}(r!==n*2*4*2||l!==n*2*4)&&console.error("[TerminalGL] \u274C Buffer index mismatch!",{texIdx:r,colorIdx:l,expected:n*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,r)),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,l))):(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,r)),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,l)),t.enableVertexAttribArray(this.aColorIndex),t.vertexAttribPointer(this.aColorIndex,1,t.FLOAT,!1,0,0));let c=this.canvas.width,h=this.canvas.height;(this.cachedResolution[0]!==c||this.cachedResolution[1]!==h)&&(t.uniform2f(this.uResolution,c,h),this.cachedResolution[0]=c,this.cachedResolution[1]=h),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 i=e*t,s=this.useInstancing?262144:this.useUint16Indices?8191:262144;if(i>s){let h=Math.floor(Math.sqrt(s));console.error(`[TerminalGL] \u274C Cannot resize to ${e}\xD7${t} (${i} cells). Device limit: ${s} cells (max ~${h}\xD7${h}). ${!this.useInstancing&&this.useUint16Indices?"Device lacks OES_element_index_uint extension.":""}`);return}let r=F.checkCompatibility();i>r.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Resizing to ${e}\xD7${t} (${i} cells) exceeds recommended limit (${r.recommendedMaxCells} cells). Performance may degrade.`),this.cols=e,this.rows=t,this.staticPositionsInitialized=!1;let l=this.cols*this.rows*2,o=Math.ceil(l*1.5),n=l>this.maxCells,c=this.maxCells>o*4;if(console.warn(`[TerminalGL] \u{1F4D0} resize check: cols=${e}, rows=${t}, newMaxCells=${l}, this.maxCells=${this.maxCells}, needGrow=${n}, needShrink=${c}`),n||c){let h=this.maxCells;if(this.maxCells=o,console.warn(`[TerminalGL] \u{1F4D0} resize realloc: ${h} \u2192 ${this.maxCells} (needGrow=${n}, 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 d=this.gl;this.useInstancing||(d.bindBuffer(d.ARRAY_BUFFER,this.positionBuffer),d.bufferData(d.ARRAY_BUFFER,this.renderPositions.byteLength,d.DYNAMIC_DRAW)),d.bindBuffer(d.ARRAY_BUFFER,this.texCoordBuffer),d.bufferData(d.ARRAY_BUFFER,this.renderTexCoords.byteLength,d.DYNAMIC_DRAW),d.bindBuffer(d.ARRAY_BUFFER,this.colorIndexBuffer),d.bufferData(d.ARRAY_BUFFER,this.renderColorIndices.byteLength,d.DYNAMIC_DRAW),this.useInstancing||(d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,this.indexBuffer),d.bufferData(d.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,d.DYNAMIC_DRAW)),this.vaoExtension&&this.vao&&(this.vaoExtension.deleteVertexArrayOES(this.vao),this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),d.bindBuffer(d.ARRAY_BUFFER,this.positionBuffer),d.enableVertexAttribArray(this.aPosition),d.vertexAttribPointer(this.aPosition,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,this.texCoordBuffer),d.enableVertexAttribArray(this.aTexCoord),d.vertexAttribPointer(this.aTexCoord,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,this.colorIndexBuffer),d.enableVertexAttribArray(this.aColorIndex),d.vertexAttribPointer(this.aColorIndex,1,d.FLOAT,!1,0,0),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null)));let m=n?"\u{1F4C8} Growing":"\u{1F4C9} Shrinking",b=h*160/1048576,x=this.maxCells*160/1048576;console.warn(`[TerminalGL] ${m} buffers: ${b.toFixed(2)}MB \u2192 ${x.toFixed(2)}MB (${h} \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 i=Math.max(1,Math.min(255,Math.round(e))),s=Math.max(1,Math.min(255,Math.round(t)));this.cellWidth===i&&this.cellHeight===s||(this.cellWidth=i,this.cellHeight=s,this.charWidth=i,this.charHeight=s,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),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=`
119
+ `,s=this.compileShader(t.VERTEX_SHADER,e),a=this.compileShader(t.FRAGMENT_SHADER,i);if(!s||!a)throw new Error("Shader compilation error");let h=t.createProgram();if(!h)throw new Error("Unable to create WebGL program");if(t.attachShader(h,s),t.attachShader(h,a),t.linkProgram(h),!t.getProgramParameter(h,t.LINK_STATUS)){let o=t.getProgramInfoLog(h);throw new Error("Program linking error: "+o)}this.program=h,this.cachedTextureUniform=!1,this.cachedPaletteUniform=!1,this.aPosition=t.getAttribLocation(h,"aPosition"),this.useInstancing?(this.aInstanceOffset=t.getAttribLocation(h,"aInstanceOffset"),this.aInstanceUVs=t.getAttribLocation(h,"aInstanceUVs"),this.aInstanceColors=t.getAttribLocation(h,"aInstanceColors"),this.uCellSize=t.getUniformLocation(h,"uCellSize"),this.instanceDataBuffer=t.createBuffer(),this.aTexCoord=this.aInstanceOffset,this.aColorIndex=this.aInstanceUVs):(this.aTexCoord=t.getAttribLocation(h,"aTexCoord"),this.aColorIndex=t.getAttribLocation(h,"aColorIndex")),this.uResolution=t.getUniformLocation(h,"uResolution"),this.uTexture=t.getUniformLocation(h,"uTexture"),this.uPalette=t.getUniformLocation(h,"uPalette"),this.positionBuffer=t.createBuffer(),this.texCoordBuffer=t.createBuffer(),this.colorIndexBuffer=t.createBuffer(),this.indexBuffer=t.createBuffer(),t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.bufferData(t.ARRAY_BUFFER,this.renderPositions.byteLength,t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferData(t.ARRAY_BUFFER,this.renderTexCoords.byteLength,t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferData(t.ARRAY_BUFFER,this.renderColorIndices.byteLength,t.DYNAMIC_DRAW),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer),t.bufferData(t.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,t.DYNAMIC_DRAW),this.vaoExtension&&(this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),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.enableVertexAttribArray(this.aTexCoord),t.vertexAttribPointer(this.aTexCoord,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.enableVertexAttribArray(this.aColorIndex),t.vertexAttribPointer(this.aColorIndex,1,t.FLOAT,!1,0,0),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null))),t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA),t.viewport(0,0,this.canvas.width,this.canvas.height)}compileShader(t,e){let i=this.gl,s=i.createShader(t);return s?(i.shaderSource(s,e),i.compileShader(s),i.getShaderParameter(s,i.COMPILE_STATUS)?s:(console.error("Shader compilation error:",i.getShaderInfoLog(s)),i.deleteShader(s),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 t=this.cols*this.cellWidth,e=this.rows*this.cellHeight,i=this.canvas.getBoundingClientRect(),s=this.containerDiv.getBoundingClientRect();this.gridOverlay.setDimensions(this.cols,this.rows,this.cellWidth,this.cellHeight,0,0),this.gridOverlay.setTransform(this.currentScale,t,e,i,s),this.gridOverlay.render()}setBitmapFont(t,e,i,s=e,a=i){this.bitmapFont=t,this.fontLoaded=!0,this.charWidth=e,this.charHeight=i,this.cellWidth=s,this.cellHeight=a,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),this.generateAtlas(),this.updateCanvasSize()}generateAtlas(){if(!this.bitmapFont)return;this.atlasColumns=16;let t=256,e=this.atlasColumns*this.charWidth,s=Math.ceil(t/this.atlasColumns)*this.charHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=e,this.atlasCanvas.height=s;let a=this.atlasCanvas.getContext("2d",{willReadFrequently:!0});if(!a)return;a.clearRect(0,0,e,s);let h=Array.from(this.bitmapFont.keys());for(let o of h){let l=this.bitmapFont.get(o);if(!l)continue;let r=o%this.atlasColumns,c=Math.floor(o/this.atlasColumns),x=r*this.charWidth,u=c*this.charHeight;for(let m=0;m<this.charHeight&&!(m>=l.length);m++){let b=l[m];for(let f=0;f<this.charWidth;f++){let E=1<<7-f;b&E&&(a.fillStyle="#FFFFFF",a.fillRect(x+f,u+m,1,1))}}}this.cachedAtlasWidth=e,this.cachedAtlasHeight=s,this.createAtlasTexture(),this.charCodeToAtlasIndex.fill(65535);for(let o=0;o<t;o++)this.charCodeToAtlasIndex[o]=o}async setImageFontStructure(t,e,i,s,a){let h=this.atlasCanvas&&this.fontLoaded&&this.charWidth===Math.round(t)&&this.charHeight===Math.round(e),o=this.atlasCanvas;this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(e),this.cellWidth=Math.round(i),this.cellHeight=Math.round(s),this.atlasColumns=y(a);let l=B(a);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers();let r=y(a);if(this.cachedAtlasWidth=r*this.charWidth,this.cachedAtlasHeight=r*this.charHeight,this.allocateAtlasTexture(this.cachedAtlasWidth,this.cachedAtlasHeight),h&&o){let c=this.gl;c.bindTexture(c.TEXTURE_2D,this.atlasTexture),c.texSubImage2D(c.TEXTURE_2D,0,0,0,c.RGBA,c.UNSIGNED_BYTE,o)}this.charCodeToAtlasIndex.fill(65535);for(let c=0;c<=l;c++)this.charCodeToAtlasIndex[c]=c;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()}async setImageFontBlock(t,e){let i=this.gl;if(!this.atlasTexture)return;let s=new Blob([e],{type:"image/png"}),a=await createImageBitmap(s),h=this.atlasColumns/16,o=t%h,l=Math.floor(t/h),r=o*16*this.charWidth,c=l*16*this.charHeight;i.bindTexture(i.TEXTURE_2D,this.atlasTexture),i.texSubImage2D(i.TEXTURE_2D,0,r,c,i.RGBA,i.UNSIGNED_BYTE,a),a.close()}async setImageFont(t,e,i,s,a,h){this.fontLoaded=!0,this.charWidth=Math.round(e),this.charHeight=Math.round(i),this.cellWidth=Math.round(s),this.cellHeight=Math.round(a),this.atlasColumns=y(h);let o=B(h);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),await this.loadImageFontAtlas(t),this.charCodeToAtlasIndex.fill(65535);for(let l=0;l<=o;l++)this.charCodeToAtlasIndex[l]=l;this.precomputeImageFontUVs(h),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(t){return new Promise((e,i)=>{let s=new Uint8Array(t),a=new Blob([s],{type:"image/png"}),h=URL.createObjectURL(a),o=new Image;o.onload=()=>{URL.revokeObjectURL(h),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=o.width,this.atlasCanvas.height=o.height;let l=this.atlasCanvas.getContext("2d");if(!l){i(new Error("Failed to create 2D context for atlas"));return}l.drawImage(o,0,0),this.cachedAtlasWidth=o.width,this.cachedAtlasHeight=o.height,this.createAtlasTexture(),e()},o.onerror=()=>{URL.revokeObjectURL(h),i(new Error("Failed to load PNG image for ImageFont atlas"))},o.src=h})}precomputeImageFontUVs(t){let e=t*256;this.atlasUVs=new Float32Array(e*4);let i=this.cachedAtlasWidth,s=this.cachedAtlasHeight,a=.5/i,h=.5/s;for(let o=0;o<e;o++){let{col:l,row:r}=_(o,t),c=(l*this.charWidth+a)/i,x=(r*this.charHeight+h)/s,u=((l+1)*this.charWidth-a)/i,m=((r+1)*this.charHeight-h)/s,b=o*4;this.atlasUVs[b]=c,this.atlasUVs[b+1]=x,this.atlasUVs[b+2]=u,this.atlasUVs[b+3]=m}}allocateAtlasTexture(t,e){try{let i=this.gl,s=i.createTexture();if(!s)throw new Error("Unable to create texture");i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,t,e,0,i.RGBA,i.UNSIGNED_BYTE,null),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_S,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_T,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MIN_FILTER,i.NEAREST),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MAG_FILTER,i.NEAREST),this.atlasTexture=s}catch(i){throw console.error("[TerminalGL] \u274C Failed to create atlas texture:",i),i}}createAtlasTexture(){if(this.atlasCanvas)try{let t=this.gl,e=t.createTexture();if(!e)throw new Error("Unable to create texture");t.bindTexture(t.TEXTURE_2D,e),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.atlasCanvas),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),this.atlasTexture=e}catch(t){throw console.error("[TerminalGL] \u274C Failed to create atlas texture:",t),t}}clear(){let t=this.gl;t&&t.clear(t.COLOR_BUFFER_BIT)}parseColor(t){if(t.startsWith("#")){let e=t.slice(1),i=0,s=0,a=0;return e.length===3?(i=parseInt(e[0]+e[0],16),s=parseInt(e[1]+e[1],16),a=parseInt(e[2]+e[2],16)):e.length===6&&(i=parseInt(e.slice(0,2),16),s=parseInt(e.slice(2,4),16),a=parseInt(e.slice(4,6),16)),[i/255,s/255,a/255,1]}if(t.startsWith("rgb")){let e=t.match(/rgba?\(([^)]+)\)/);if(e){let i=e[1].split(",").map(s=>parseFloat(s.trim()));return[i[0]/255,i[1]/255,i[2]/255,i[3]!==void 0?i[3]:1]}}return[1,1,1,1]}setupResizeObserver(){if(!(typeof ResizeObserver>"u"))try{this.resizeObserver=new ResizeObserver(()=>{try{this.updateCanvasSize()}catch(t){console.error("[TerminalGL] \u274C Error in resize callback:",t)}}),this.resizeObserver.observe(this.parentElement),this.updateCanvasSize()}catch(t){console.error("[TerminalGL] \u274C Failed to setup ResizeObserver:",t)}}updateCanvasSize(){let t=this.parentElement.clientWidth,e=this.parentElement.clientHeight;if(t===0||e===0)return;let i=this.cols*this.cellWidth,s=this.rows*this.cellHeight;if(i===0||s===0)return;let a=t/i,h=e/s,o=Math.min(a,h),l;switch(this.scalingMode){case v.ScalingMode.Integer:l=Math.max(1,Math.floor(o));break;case v.ScalingMode.Half:l=Math.max(1,Math.floor(o*2)/2);break;case v.ScalingMode.Quarter:l=Math.max(1,Math.floor(o*4)/4);break;case v.ScalingMode.Eighth:l=Math.max(1,Math.floor(o*8)/8);break;case v.ScalingMode.Responsive:l=1;break;case v.ScalingMode.None:default:l=Math.max(.1,o);break}if(this.canvas.style.transform=`scale(${l})`,this.ambientEffectEnabled&&this.ambientEffectCanvas){let r=l*this.ambientEffectScale;this.ambientEffectCanvas.style.transform=`scale(${r})`}this.currentScale=l,this.onResizeCallback&&this.onResizeCallback(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}updateAmbientEffect(){!this.ambientEffectCanvas||!this.ambientEffectCtx||this.ambientEffectCtx.drawImage(this.canvas,0,0)}setPalette(t){let e=0;for(let i=0;i<Math.min(t.length,256);i++){let s=t[i];e=(e<<5)-e+s.r,e=(e<<5)-e+s.g,e=(e<<5)-e+s.b,e=(e<<5)-e+s.a,e=e|0}if(e!==this.paletteHash){this.paletteHash=e;for(let i=0;i<t.length&&i<256;i++){let s=t[i],a=i*4;this.paletteFloat[a]=s.r/255,this.paletteFloat[a+1]=s.g/255,this.paletteFloat[a+2]=s.b/255,this.paletteFloat[a+3]=s.a/255}this.updatePaletteTexture()}}updatePaletteTexture(){try{let t=this.gl;this.paletteTexture||(this.paletteTexture=t.createTexture()),t.bindTexture(t.TEXTURE_2D,this.paletteTexture);let e=new Uint8Array(256*4);for(let i=0;i<256;i++){let s=i*4;e[s]=this.paletteFloat[s]*255,e[s+1]=this.paletteFloat[s+1]*255,e[s+2]=this.paletteFloat[s+2]*255,e[s+3]=this.paletteFloat[s+3]*255}t.texImage2D(t.TEXTURE_2D,0,t.RGBA,256,1,0,t.RGBA,t.UNSIGNED_BYTE,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.bindTexture(t.TEXTURE_2D,null)}catch(t){throw console.error("[TerminalGL] \u274C Failed to update palette texture:",t),t}}renderDisplayData(t){try{if(!this.isReady())return;(t.width!==this.cols||t.height!==this.rows)&&this.resize(t.width,t.height),t.passes&&t.passes.length>0?this.renderMultiPass(t,t.passes):this.renderDirect(t),this.ambientEffectEnabled&&this.ambientEffectCanvas&&this.ambientEffectCtx&&this.updateAmbientEffect()}catch(e){console.error("[TerminalGL] \u274C Error rendering display data:",e)}}renderMultiPass(t,e){for(let i=0;i<e.length;i++){let s=e[i],a={id:t.id,width:t.width,height:t.height,palette:t.palette,cells:s.cells};this.renderDirect(a,i===0)}}renderDirect(t,e=!0){let i=this.gl;if(!this.staticPositionsInitialized&&!this.useInstancing&&this.precomputeStaticPositions(),e){if(this.canvasBgColor!==null){let s=this.parseColor(this.canvasBgColor);i.clearColor(s[0],s[1],s[2],s[3])}else i.clearColor(0,0,0,0);i.clear(i.COLOR_BUFFER_BIT)}this.useInstancing?this.renderInstanced(t):this.renderDirectBuffers(t)}renderInstanced(t){let e=this.gl,i=this.instancedExtension;if(!this.instanceData||this.instanceData.length===0){this.renderDirectBuffers(t);return}let s=0,a=this.instanceData.length/8,h=t.width*t.height*2;if(h>a){console.error(`[TerminalGL] \u274C Instance buffer too small! Need ${h}, have ${a}. Display size: ${t.width}\xD7${t.height}, buffer was sized for smaller terminal.`),this.renderDirectBuffers(t);return}for(let l=0;l<t.height;l++)for(let r=0;r<t.width;r++){let c=t.cells[l*t.width+r],x=c.bgColorIndex,u=c.fgColorIndex,m=this.canvasBgColor!==null&&x===255,b=c.char===" "||u===255;if(!m){if(s>=a){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${a}`);break}let f=s*8;this.instanceData[f]=r,this.instanceData[f+1]=l,this.instanceData[f+2]=0,this.instanceData[f+3]=0,this.instanceData[f+4]=0,this.instanceData[f+5]=0,this.instanceData[f+6]=x,this.instanceData[f+7]=0,s++}if(!b){let f=c.char.charCodeAt(0),E=this.charCodeToAtlasIndex[f];if(E!==65535){if(s>=a){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${a}`);break}let C=E*4,p=s*8;this.instanceData[p]=r,this.instanceData[p+1]=l,this.instanceData[p+2]=this.atlasUVs[C],this.instanceData[p+3]=this.atlasUVs[C+1],this.instanceData[p+4]=this.atlasUVs[C+2],this.instanceData[p+5]=this.atlasUVs[C+3],this.instanceData[p+6]=0,this.instanceData[p+7]=u,s++}}}if(s===0)return;e.bindBuffer(e.ARRAY_BUFFER,this.instanceDataBuffer),e.bufferSubData(e.ARRAY_BUFFER,0,this.instanceData.subarray(0,s*8)),e.useProgram(this.program),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(this.aPosition),e.vertexAttribPointer(this.aPosition,2,e.FLOAT,!1,0,0),i.vertexAttribDivisorANGLE(this.aPosition,0),e.bindBuffer(e.ARRAY_BUFFER,this.instanceDataBuffer);let o=8*Float32Array.BYTES_PER_ELEMENT;e.enableVertexAttribArray(this.aInstanceOffset),e.vertexAttribPointer(this.aInstanceOffset,2,e.FLOAT,!1,o,0),i.vertexAttribDivisorANGLE(this.aInstanceOffset,1),e.enableVertexAttribArray(this.aInstanceUVs),e.vertexAttribPointer(this.aInstanceUVs,4,e.FLOAT,!1,o,2*Float32Array.BYTES_PER_ELEMENT),i.vertexAttribDivisorANGLE(this.aInstanceUVs,1),e.enableVertexAttribArray(this.aInstanceColors),e.vertexAttribPointer(this.aInstanceColors,2,e.FLOAT,!1,o,6*Float32Array.BYTES_PER_ELEMENT),i.vertexAttribDivisorANGLE(this.aInstanceColors,1),e.uniform2f(this.uResolution,this.canvas.width,this.canvas.height),e.uniform2f(this.uCellSize,this.cellWidth,this.cellHeight),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.atlasTexture),e.uniform1i(this.uTexture,0),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.paletteTexture),e.uniform1i(this.uPalette,1),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),i.drawElementsInstancedANGLE(e.TRIANGLES,6,e.UNSIGNED_SHORT,0,s),i.vertexAttribDivisorANGLE(this.aPosition,0),i.vertexAttribDivisorANGLE(this.aInstanceOffset,0),i.vertexAttribDivisorANGLE(this.aInstanceUVs,0),i.vertexAttribDivisorANGLE(this.aInstanceColors,0)}renderDirectBuffers(t){let e=this.gl,i=t.width*t.height,s=i*2;if(s>this.maxCells){console.error(`[TerminalGL] \u274C Buffer overflow detected! Trying to render ${s} quads but buffer capacity is ${this.maxCells}. This should not happen - resize() should have reallocated.`);return}let a=0,h=0,o=t.cells,l=i;for(let b=0;b<l;b++){let f=o[b],E=f.bgColorIndex,p=this.canvasBgColor!==null&&E===255?255:E,w=0;for(let T=0;T<4;T++)this.renderTexCoords[a++]=w,this.renderTexCoords[a++]=w,this.renderColorIndices[h++]=p;let A=f.fgColorIndex,M=f.char;if(M===" "||A===255)for(let T=0;T<4;T++)this.renderTexCoords[a++]=0,this.renderTexCoords[a++]=0,this.renderColorIndices[h++]=255;else{let T=M.charCodeAt(0),P=this.charCodeToAtlasIndex[T];if(P!==65535){let R=P*4,W=this.atlasUVs[R],G=this.atlasUVs[R+1],O=this.atlasUVs[R+2],H=this.atlasUVs[R+3];this.renderTexCoords[a++]=W,this.renderTexCoords[a++]=G,this.renderColorIndices[h++]=A,this.renderTexCoords[a++]=O,this.renderTexCoords[a++]=G,this.renderColorIndices[h++]=A,this.renderTexCoords[a++]=W,this.renderTexCoords[a++]=H,this.renderColorIndices[h++]=A,this.renderTexCoords[a++]=O,this.renderTexCoords[a++]=H,this.renderColorIndices[h++]=A}else for(let R=0;R<4;R++)this.renderTexCoords[a++]=0,this.renderTexCoords[a++]=0,this.renderColorIndices[h++]=255}}(a!==l*2*4*2||h!==l*2*4)&&console.error("[TerminalGL] \u274C Buffer index mismatch!",{texIdx:a,colorIdx:h,expected:l*2*4}),e.useProgram(this.program),this.vao&&this.vaoExtension?(this.vaoExtension.bindVertexArrayOES(this.vao),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.bufferSubData(e.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,a)),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.bufferSubData(e.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,h))):(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.bufferSubData(e.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,a)),e.enableVertexAttribArray(this.aTexCoord),e.vertexAttribPointer(this.aTexCoord,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.bufferSubData(e.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,h)),e.enableVertexAttribArray(this.aColorIndex),e.vertexAttribPointer(this.aColorIndex,1,e.FLOAT,!1,0,0));let r=this.canvas.width,c=this.canvas.height;(this.cachedResolution[0]!==r||this.cachedResolution[1]!==c)&&(e.uniform2f(this.uResolution,r,c),this.cachedResolution[0]=r,this.cachedResolution[1]=c),this.cachedTextureUnit!==0&&(e.activeTexture(e.TEXTURE0),this.cachedTextureUnit=0),e.bindTexture(e.TEXTURE_2D,this.atlasTexture),this.cachedTextureUniform||(e.uniform1i(this.uTexture,0),this.cachedTextureUniform=!0),this.cachedPaletteUnit!==1&&(e.activeTexture(e.TEXTURE1),this.cachedPaletteUnit=1),e.bindTexture(e.TEXTURE_2D,this.paletteTexture),this.cachedPaletteUniform||(e.uniform1i(this.uPalette,1),this.cachedPaletteUniform=!0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer);let u=t.width*t.height*2*6,m=this.useUint16Indices?e.UNSIGNED_SHORT:e.UNSIGNED_INT;e.drawElements(e.TRIANGLES,u,m,0)}resize(t,e){if(!Number.isInteger(t)||t<=0){console.error(`[TerminalGL] \u274C Invalid cols: ${t}. Must be positive integer.`);return}if(!Number.isInteger(e)||e<=0){console.error(`[TerminalGL] \u274C Invalid rows: ${e}. Must be positive integer.`);return}if(t===this.cols&&e===this.rows)return;let i=t*e,s=this.useInstancing?262144:this.useUint16Indices?8191:262144;if(i>s){let r=Math.floor(Math.sqrt(s));console.error(`[TerminalGL] \u274C Cannot resize to ${t}\xD7${e} (${i} cells). Device limit: ${s} cells (max ~${r}\xD7${r}). ${!this.useInstancing&&this.useUint16Indices?"Device lacks OES_element_index_uint extension.":""}`);return}this.cols=t,this.rows=e,this.staticPositionsInitialized=!1;let a=this.cols*this.rows*2,h=Math.ceil(a*1.5),o=a>this.maxCells,l=this.maxCells>h*4;if(o||l){if(this.maxCells=h,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 c=this.gl;c.bindBuffer(c.ARRAY_BUFFER,this.instanceDataBuffer),c.bufferData(c.ARRAY_BUFFER,this.instanceData.byteLength,c.DYNAMIC_DRAW)}let r=this.gl;this.useInstancing||(r.bindBuffer(r.ARRAY_BUFFER,this.positionBuffer),r.bufferData(r.ARRAY_BUFFER,this.renderPositions.byteLength,r.DYNAMIC_DRAW)),r.bindBuffer(r.ARRAY_BUFFER,this.texCoordBuffer),r.bufferData(r.ARRAY_BUFFER,this.renderTexCoords.byteLength,r.DYNAMIC_DRAW),r.bindBuffer(r.ARRAY_BUFFER,this.colorIndexBuffer),r.bufferData(r.ARRAY_BUFFER,this.renderColorIndices.byteLength,r.DYNAMIC_DRAW),this.useInstancing||(r.bindBuffer(r.ELEMENT_ARRAY_BUFFER,this.indexBuffer),r.bufferData(r.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,r.DYNAMIC_DRAW)),this.vaoExtension&&this.vao&&(this.vaoExtension.deleteVertexArrayOES(this.vao),this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),r.bindBuffer(r.ARRAY_BUFFER,this.positionBuffer),r.enableVertexAttribArray(this.aPosition),r.vertexAttribPointer(this.aPosition,2,r.FLOAT,!1,0,0),r.bindBuffer(r.ARRAY_BUFFER,this.texCoordBuffer),r.enableVertexAttribArray(this.aTexCoord),r.vertexAttribPointer(this.aTexCoord,2,r.FLOAT,!1,0,0),r.bindBuffer(r.ARRAY_BUFFER,this.colorIndexBuffer),r.enableVertexAttribArray(this.aColorIndex),r.vertexAttribPointer(this.aColorIndex,1,r.FLOAT,!1,0,0),r.bindBuffer(r.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null)))}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(t){this.onResizeCallback=t}clearOnResizeCallback(){this.onResizeCallback=void 0}getAvailableSize(){return{width:this.parentElement.clientWidth,height:this.parentElement.clientHeight}}setScalingMode(t){this.scalingMode!==t&&(this.scalingMode=t,this.updateCanvasSize())}getScalingMode(){return this.scalingMode}setCellSize(t,e){let i=Math.max(1,Math.min(255,Math.round(t))),s=Math.max(1,Math.min(255,Math.round(e)));this.cellWidth===i&&this.cellHeight===s||(this.cellWidth=i,this.cellHeight=s,this.charWidth=i,this.charHeight=s,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),this.updateCanvasSize())}getCellSize(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getMaxCells(){return this.useInstancing?262144:this.useUint16Indices?8191:262144}setGrid(t){t.enabled?(this.gridOverlay?this.gridOverlay.setStyle({strokeColor:t.color,lineWidth:t.lineWidth}):this.gridOverlay=new I(this.containerDiv,{strokeColor:t.color??"rgba(144, 24, 24, 1)",lineWidth:t.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(t){typeof t=="boolean"?this.ambientEffectEnabled=t:(this.ambientEffectEnabled=!0,t.blur!==void 0&&(this.ambientEffectBlur=t.blur),t.scale!==void 0&&(this.ambientEffectScale=t.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=`
120
120
  display: block !important;
121
121
  position: absolute !important;
122
122
  width: ${this.canvas.width}px !important;
@@ -127,4 +127,4 @@
127
127
  transform: scale(${this.ambientEffectScale}) !important;
128
128
  pointer-events: none !important;
129
129
  z-index: 0 !important;
130
- `,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)}};p(F,"TerminalGL");var L=F;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 $(u,e=D){return u<0||u>=e.length?"#ff00ff":e[u]}p($,"paletteIndexToColor");function N(u,e=D){let t=e.indexOf(u.toLowerCase());return t>=0?t:0}p(N,"colorToPaletteIndex");
130
+ `,this.ambientEffectCtx=this.ambientEffectCanvas.getContext("2d",{alpha:!0}),this.containerDiv.insertBefore(this.ambientEffectCanvas,this.canvas))}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 t=this.gl;this.program&&t.deleteProgram(this.program),this.positionBuffer&&t.deleteBuffer(this.positionBuffer),this.texCoordBuffer&&t.deleteBuffer(this.texCoordBuffer),this.colorIndexBuffer&&t.deleteBuffer(this.colorIndexBuffer),this.indexBuffer&&t.deleteBuffer(this.indexBuffer),this.instanceDataBuffer&&t.deleteBuffer(this.instanceDataBuffer),this.atlasTexture&&t.deleteTexture(this.atlasTexture),this.paletteTexture&&t.deleteTexture(this.paletteTexture),this.vao&&this.vaoExtension&&this.vaoExtension.deleteVertexArrayOES(this.vao);let e=t.getExtension("WEBGL_lose_context");e&&e.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)}};g(D,"TerminalGL");var F=D;var L=["#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(d,t=L){return d<0||d>=t.length?"#ff00ff":t[d]}g(Y,"paletteIndexToColor");function N(d,t=L){let e=t.indexOf(d.toLowerCase());return e>=0?e:0}g(N,"colorToPaletteIndex");
package/dist/gl/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
- var $=Object.defineProperty;var N=(b,e,t)=>e in b?$(b,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):b[e]=t;var g=(b,e)=>$(b,"name",{value:e,configurable:!0});var a=(b,e,t)=>(N(b,typeof e!="symbol"?e+"":e,t),t);var _=class _{constructor(e,t){a(this,"canvas");a(this,"ctx");a(this,"container");a(this,"cols",0);a(this,"rows",0);a(this,"cellWidth",0);a(this,"cellHeight",0);a(this,"offsetX",0);a(this,"offsetY",0);a(this,"strokeColor","rgba(80, 80, 80, 0.4)");a(this,"lineWidth",1);this.container=e,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let i=t?.zIndex??10;this.canvas.style.cssText=`
1
+ var Y=Object.defineProperty;var N=(u,t,e)=>t in u?Y(u,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):u[t]=e;var p=(u,t)=>Y(u,"name",{value:t,configurable:!0});var n=(u,t,e)=>(N(u,typeof t!="symbol"?t+"":t,e),e);var F=class F{constructor(t,e){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=t,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let i=e?.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
7
  z-index: ${i} !important;
8
- `,this.container.appendChild(this.canvas);let s=this.canvas.getContext("2d");if(!s)throw new Error("[GridOverlay] Impossible de cr\xE9er le contexte 2D");this.ctx=s,t&&(t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth))}setDimensions(e,t,i,s,r=0,l=0){this.cols=e,this.rows=t,this.cellWidth=i,this.cellHeight=s,this.offsetX=r,this.offsetY=l}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,i,s,r){let l=s.left-r.left,o=s.top-r.top,n=s.width,c=s.height;(this.canvas.width!==n||this.canvas.height!==c)&&(this.canvas.width=n,this.canvas.height=c);let h=this.canvas.style;h.width=`${n}px`,h.height=`${c}px`,h.left=`${l}px`,h.top=`${o}px`}render(){if(!this.ctx)return;let e=this.cols*this.cellWidth,t=this.rows*this.cellHeight,i=e>0?this.canvas.width/e:1,s=t>0?this.canvas.height/t:1,r=Math.min(i,s),l=this.cellWidth*r,o=this.cellHeight*r,n=this.cols*l,c=this.rows*o,h=this.offsetX*r,d=this.offsetY*r;if(!(n===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*r),this.ctx.beginPath();for(let u=0;u<=this.cols;u++){let m=h+u*l+.5;this.ctx.moveTo(m,d),this.ctx.lineTo(m,d+c)}for(let u=0;u<=this.rows;u++){let m=d+u*o+.5;this.ctx.moveTo(h,m),this.ctx.lineTo(h+n,m)}this.ctx.stroke()}}update(e,t,i,s,r,l,o=0,n=0){this.setDimensions(e,t,i,s,o,n),this.setCanvasSize(r,l),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}};g(_,"GridOverlay");var I=_;function y(b){return Math.sqrt(b)*16}g(y,"getAtlasColumns");function B(b){return b*256-1}g(B,"getMaxCharCode");function L(b,e){let t=Math.floor(b/256),i=b%256,s=Math.sqrt(e),r=t%s,l=Math.floor(t/s),o=i%16,n=Math.floor(i/16);return{col:r*16+o,row:l*16+n}}g(L,"getCharGridPosition");import{POST_PROCESS_DEFAULTS as F,ScalingMode as C}from"@utsp/types";var U=class U{constructor(e,t){a(this,"canvas");a(this,"gl");a(this,"parentElement");a(this,"containerDiv");a(this,"cols");a(this,"rows");a(this,"charWidth");a(this,"charHeight");a(this,"cellWidth",8);a(this,"cellHeight",8);a(this,"glyphOffsetX",0);a(this,"glyphOffsetY",0);a(this,"canvasBgColor");a(this,"showGrid");a(this,"supportsUint32Indices",!1);a(this,"useUint16Indices",!1);a(this,"gridOverlay");a(this,"bitmapFont");a(this,"atlasTexture",null);a(this,"atlasCanvas");a(this,"atlasColumns",0);a(this,"fontLoaded",!1);a(this,"paletteTexture",null);a(this,"program",null);a(this,"positionBuffer",null);a(this,"texCoordBuffer",null);a(this,"colorIndexBuffer",null);a(this,"indexBuffer",null);a(this,"aPosition");a(this,"aTexCoord");a(this,"aColorIndex");a(this,"uResolution",null);a(this,"uTexture",null);a(this,"uPalette",null);a(this,"resizeObserver");a(this,"charCodeToAtlasIndex",new Uint16Array(65536).fill(65535));a(this,"atlasUVs",new Float32Array(0));a(this,"cachedAtlasWidth",0);a(this,"cachedAtlasHeight",0);a(this,"paletteFloat",new Float32Array(256*4));a(this,"maxCells",0);a(this,"renderPositions",new Float32Array(0));a(this,"renderTexCoords",new Float32Array(0));a(this,"renderColorIndices",new Float32Array(0));a(this,"renderIndices",new Uint32Array(0));a(this,"cachedResolution",[0,0]);a(this,"cachedTextureUnit",-1);a(this,"cachedPaletteUnit",-1);a(this,"cachedTextureUniform",!1);a(this,"cachedPaletteUniform",!1);a(this,"paletteHash",0);a(this,"currentScale",1);a(this,"scalingMode",C.None);a(this,"ambientEffectEnabled",!1);a(this,"ambientEffectCanvas",null);a(this,"ambientEffectCtx",null);a(this,"ambientEffectBlur",F.ambientEffect.blur);a(this,"ambientEffectScale",F.ambientEffect.scale);a(this,"ambientEffectOpacity",.7);a(this,"onResizeCallback");a(this,"staticPositionsInitialized",!1);a(this,"vaoExtension",null);a(this,"vao",null);a(this,"instancedExtension",null);a(this,"useInstancing",!1);a(this,"instanceDataBuffer",null);a(this,"instanceData",new Float32Array(0));a(this,"templateQuadPositions",new Float32Array(0));a(this,"templateQuadIndices",new Uint16Array(0));a(this,"aInstanceOffset",-1);a(this,"aInstanceUVs",-1);a(this,"aInstanceColors",-1);a(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 i=t.cols*t.rows,s=U.checkCompatibility();if(s.errors.length>0)throw new Error(`TerminalGL: WebGL incompatible - ${s.errors.join(", ")}`);let r=t.forceUint16??!1;if(r&&i>s.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${i} cells) exceeds Uint16 limit of ${s.maxCellsUint16} cells. Maximum size with Uint16: ${Math.floor(Math.sqrt(s.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(s.maxCellsUint16))} (or smaller rectangles like 127\xD764)`);if(!s.uint32Indices&&i>s.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${t.cols}\xD7${t.rows} (${i} cells) exceeds device limit of ${s.maxCellsUint16} cells (OES_element_index_uint not supported). Maximum size: ${Math.floor(Math.sqrt(s.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(s.maxCellsUint16))}`);i>s.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Large terminal size ${t.cols}\xD7${t.rows} (${i} cells) exceeds recommended limit of ${s.recommendedMaxCells} cells. Performance may be impacted.`),s.warnings.length>0&&console.warn("[TerminalGL] WebGL Compatibility Warnings:",s.warnings);let l=t.charWidth??8,o=t.charHeight??8;if(!Number.isFinite(l)||l<=0)throw new Error(`TerminalGL: Invalid charWidth: ${l}. Must be a positive number.`);if(!Number.isFinite(o)||o<=0)throw new Error(`TerminalGL: Invalid charHeight: ${o}. Must be a positive number.`);for(this.parentElement=e,this.cols=t.cols,this.rows=t.rows,this.charWidth=l,this.charHeight=o,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??F.ambientEffect.blur,this.ambientEffectScale=t.ambientEffect.scale??F.ambientEffect.scale,this.ambientEffectOpacity=t.ambientEffect.opacity??.7));this.parentElement.firstChild;)this.parentElement.removeChild(this.parentElement.firstChild);let n=window.getComputedStyle(this.parentElement).position;n!=="relative"&&n!=="absolute"&&n!=="fixed"&&(this.parentElement.style.position="relative"),this.containerDiv=document.createElement("div"),this.containerDiv.className="terminalgl-container",this.containerDiv.style.cssText=`
8
+ `,this.container.appendChild(this.canvas);let s=this.canvas.getContext("2d");if(!s)throw new Error("[GridOverlay] Impossible de cr\xE9er le contexte 2D");this.ctx=s,e&&(e.strokeColor&&(this.strokeColor=e.strokeColor),e.lineWidth!==void 0&&(this.lineWidth=e.lineWidth))}setDimensions(t,e,i,s,a=0,h=0){this.cols=t,this.rows=e,this.cellWidth=i,this.cellHeight=s,this.offsetX=a,this.offsetY=h}setCanvasSize(t,e){this.canvas.width=t,this.canvas.height=e,this.ctx.setTransform(1,0,0,1,0,0)}setStyle(t){t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth)}setTransform(t,e,i,s,a){let h=s.left-a.left,o=s.top-a.top,l=s.width,r=s.height;(this.canvas.width!==l||this.canvas.height!==r)&&(this.canvas.width=l,this.canvas.height=r);let c=this.canvas.style;c.width=`${l}px`,c.height=`${r}px`,c.left=`${h}px`,c.top=`${o}px`}render(){if(!this.ctx)return;let t=this.cols*this.cellWidth,e=this.rows*this.cellHeight,i=t>0?this.canvas.width/t:1,s=e>0?this.canvas.height/e:1,a=Math.min(i,s),h=this.cellWidth*a,o=this.cellHeight*a,l=this.cols*h,r=this.rows*o,c=this.offsetX*a,v=this.offsetY*a;if(!(l===0||r===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*a),this.ctx.beginPath();for(let f=0;f<=this.cols;f++){let m=c+f*h+.5;this.ctx.moveTo(m,v),this.ctx.lineTo(m,v+r)}for(let f=0;f<=this.rows;f++){let m=v+f*o+.5;this.ctx.moveTo(c,m),this.ctx.lineTo(c+l,m)}this.ctx.stroke()}}update(t,e,i,s,a,h,o=0,l=0){this.setDimensions(t,e,i,s,o,l),this.setCanvasSize(a,h),this.render()}setVisible(t){this.canvas.style.display=t?"block":"none"}destroy(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}};p(F,"GridOverlay");var I=F;function w(u){return Math.sqrt(u)*16}p(w,"getAtlasColumns");function U(u){return u*256-1}p(U,"getMaxCharCode");function D(u,t){let e=Math.floor(u/256),i=u%256,s=Math.sqrt(t),a=e%s,h=Math.floor(e/s),o=i%16,l=Math.floor(i/16);return{col:a*16+o,row:h*16+l}}p(D,"getCharGridPosition");import{POST_PROCESS_DEFAULTS as B,ScalingMode as C}from"@utsp/types";var _=class _{constructor(t,e){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",C.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));n(this,"aInstanceOffset",-1);n(this,"aInstanceUVs",-1);n(this,"aInstanceColors",-1);n(this,"uCellSize",null);if(!t)throw new Error("TerminalGL: Parent element is required");if(!Number.isInteger(e.cols)||e.cols<=0)throw new Error(`TerminalGL: Invalid cols: ${e.cols}. Must be a positive integer.`);if(!Number.isInteger(e.rows)||e.rows<=0)throw new Error(`TerminalGL: Invalid rows: ${e.rows}. Must be a positive integer.`);let i=e.cols*e.rows,s=_.checkCompatibility();if(s.errors.length>0)throw new Error(`TerminalGL: WebGL incompatible - ${s.errors.join(", ")}`);let a=e.forceUint16??!1;if(a&&i>s.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${e.cols}\xD7${e.rows} (${i} cells) exceeds Uint16 limit of ${s.maxCellsUint16} cells. Maximum size with Uint16: ${Math.floor(Math.sqrt(s.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(s.maxCellsUint16))} (or smaller rectangles like 127\xD764)`);if(!s.uint32Indices&&i>s.maxCellsUint16)throw new Error(`TerminalGL: Terminal size ${e.cols}\xD7${e.rows} (${i} cells) exceeds device limit of ${s.maxCellsUint16} cells (OES_element_index_uint not supported). Maximum size: ${Math.floor(Math.sqrt(s.maxCellsUint16))}\xD7${Math.floor(Math.sqrt(s.maxCellsUint16))}`);let h=e.charWidth??8,o=e.charHeight??8;if(!Number.isFinite(h)||h<=0)throw new Error(`TerminalGL: Invalid charWidth: ${h}. Must be a positive number.`);if(!Number.isFinite(o)||o<=0)throw new Error(`TerminalGL: Invalid charHeight: ${o}. Must be a positive number.`);for(this.parentElement=t,this.cols=e.cols,this.rows=e.rows,this.charWidth=h,this.charHeight=o,this.canvasBgColor=e.canvasBgColor!==void 0?e.canvasBgColor:null,this.showGrid=e.showGrid??!1,this.scalingMode=e.scalingMode??C.None,e.ambientEffect&&(this.ambientEffectEnabled=!0,typeof e.ambientEffect=="object"&&(this.ambientEffectBlur=e.ambientEffect.blur??B.ambientEffect.blur,this.ambientEffectScale=e.ambientEffect.scale??B.ambientEffect.scale,this.ambientEffectOpacity=e.ambientEffect.opacity??.7));this.parentElement.firstChild;)this.parentElement.removeChild(this.parentElement.firstChild);let l=window.getComputedStyle(this.parentElement).position;l!=="relative"&&l!=="absolute"&&l!=="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;
@@ -35,7 +35,7 @@ var $=Object.defineProperty;var N=(b,e,t)=>e in b?$(b,e,{enumerable:!0,configura
35
35
  z-index: 1 !important;
36
36
  pointer-events: auto !important;
37
37
  touch-action: none !important;
38
- `;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=r||!this.supportsUint32Indices,this.useUint16Indices?console.warn(`[TerminalGL] \u{1F4CA} Using Uint16 indices (max ${s.maxCellsUint16} cells)`):console.warn(`[TerminalGL] \u{1F4CA} Using Uint32 indices (max ${s.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(h){throw console.error("[TerminalGL] \u274C Failed to initialize WebGL:",h),h}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"),i=t.getContext("webgl")||t.getContext("experimental-webgl");if(!i||!(i instanceof WebGLRenderingContext))return e.errors.push("\u274C WebGL 1.0 not supported by this browser/device"),e;let s=i;e.webgl1=!0;try{e.maxTextureSize=s.getParameter(s.MAX_TEXTURE_SIZE);let n=s.getParameter(s.MAX_VIEWPORT_DIMS);e.maxViewportDims=[n[0],n[1]]}catch(n){return e.errors.push(`\u274C Failed to query WebGL parameters: ${n}`),e}let r=s.getExtension("OES_element_index_uint");e.uint32Indices=!!r;let l=8;if(e.maxCellsUint16=Math.floor(65535/l),e.uint32Indices){let n=Math.floor(e.maxTextureSize*e.maxTextureSize/64);e.maxCellsUint32=Math.min(n,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]}`),s.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,i=this.glyphOffsetX,s=this.glyphOffsetY,r=this.charWidth,l=this.charHeight,o=0,n=0,c=0;for(let d=0;d<this.rows;d++){let u=Math.round(d*t),m=Math.round(u+t);for(let x=0;x<this.cols;x++){let f=Math.round(x*e),p=Math.round(f+e);this.renderPositions[o++]=f,this.renderPositions[o++]=u,this.renderPositions[o++]=p,this.renderPositions[o++]=u,this.renderPositions[o++]=f,this.renderPositions[o++]=m,this.renderPositions[o++]=p,this.renderPositions[o++]=m,this.renderIndices[n++]=c,this.renderIndices[n++]=c+1,this.renderIndices[n++]=c+2,this.renderIndices[n++]=c+2,this.renderIndices[n++]=c+1,this.renderIndices[n++]=c+3,c+=4;let E=Math.round(f+i),v=Math.round(u+s),w=Math.round(E+r),A=Math.round(v+l);this.renderPositions[o++]=E,this.renderPositions[o++]=v,this.renderPositions[o++]=w,this.renderPositions[o++]=v,this.renderPositions[o++]=E,this.renderPositions[o++]=A,this.renderPositions[o++]=w,this.renderPositions[o++]=A,this.renderIndices[n++]=c,this.renderIndices[n++]=c+1,this.renderIndices[n++]=c+2,this.renderIndices[n++]=c+2,this.renderIndices[n++]=c+1,this.renderIndices[n++]=c+3,c+=4}}let h=this.gl;h.bindBuffer(h.ARRAY_BUFFER,this.positionBuffer),h.bufferSubData(h.ARRAY_BUFFER,0,this.renderPositions),h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,this.indexBuffer),h.bufferSubData(h.ELEMENT_ARRAY_BUFFER,0,this.renderIndices),this.staticPositionsInitialized=!0}initWebGL(){let e=this.gl,t;this.useInstancing?t=`
38
+ `;let r=this.canvas.getContext("webgl",{alpha:this.canvasBgColor===null,premultipliedAlpha:!1});if(!r)throw new Error("TerminalGL: WebGL not supported");this.gl=r,this.supportsUint32Indices=!!r.getExtension("OES_element_index_uint"),this.useUint16Indices=a||!this.supportsUint32Indices,this.vaoExtension=r.getExtension("OES_vertex_array_object"),this.instancedExtension=r.getExtension("ANGLE_instanced_arrays"),this.instancedExtension&&(this.useInstancing=!0),this.containerDiv.appendChild(this.canvas),this.ambientEffectEnabled&&this.createAmbientEffectCanvas(),this.parentElement.appendChild(this.containerDiv),this.initRenderBuffers();try{this.initWebGL()}catch(c){throw console.error("[TerminalGL] \u274C Failed to initialize WebGL:",c),c}this.showGrid&&this.initGridOverlay(),this.setupResizeObserver()}static checkCompatibility(){let t={webgl1:!1,uint32Indices:!1,maxTextureSize:0,maxViewportDims:[0,0],maxCellsUint16:0,maxCellsUint32:0,recommendedMaxCells:0,warnings:[],errors:[]},e=document.createElement("canvas"),i=e.getContext("webgl")||e.getContext("experimental-webgl");if(!i||!(i instanceof WebGLRenderingContext))return t.errors.push("\u274C WebGL 1.0 not supported by this browser/device"),t;let s=i;t.webgl1=!0;try{t.maxTextureSize=s.getParameter(s.MAX_TEXTURE_SIZE);let l=s.getParameter(s.MAX_VIEWPORT_DIMS);t.maxViewportDims=[l[0],l[1]]}catch(l){return t.errors.push(`\u274C Failed to query WebGL parameters: ${l}`),t}let a=s.getExtension("OES_element_index_uint");t.uint32Indices=!!a;let h=8;if(t.maxCellsUint16=Math.floor(65535/h),t.uint32Indices){let l=Math.floor(t.maxTextureSize*t.maxTextureSize/64);t.maxCellsUint32=Math.min(l,262144)}else t.maxCellsUint32=t.maxCellsUint16,t.warnings.push(`\u26A0\uFE0F OES_element_index_uint not supported - limited to ${t.maxCellsUint16} cells (e.g., 90\xD790 or 127\xD764)`);return t.recommendedMaxCells=Math.floor((t.uint32Indices?t.maxCellsUint32:t.maxCellsUint16)*.8),t.maxTextureSize<256?t.errors.push(`\u274C MAX_TEXTURE_SIZE too small: ${t.maxTextureSize} (minimum 256 required for font atlas)`):t.maxTextureSize<2048&&t.warnings.push(`\u26A0\uFE0F Small MAX_TEXTURE_SIZE: ${t.maxTextureSize} (may limit font atlas)`),(t.maxViewportDims[0]<1024||t.maxViewportDims[1]<768)&&t.warnings.push(`\u26A0\uFE0F Small MAX_VIEWPORT_DIMS: ${t.maxViewportDims[0]}\xD7${t.maxViewportDims[1]}`),s.getExtension("WEBGL_lose_context")||t.warnings.push("\u26A0\uFE0F WEBGL_lose_context not supported - may cause memory leaks"),t}initInstancedBuffers(){let t=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]),t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.bufferData(t.ARRAY_BUFFER,this.templateQuadPositions,t.STATIC_DRAW),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer),t.bufferData(t.ELEMENT_ARRAY_BUFFER,this.templateQuadIndices,t.STATIC_DRAW),this.instanceData=new Float32Array(this.maxCells*8),t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer),t.bufferData(t.ARRAY_BUFFER,this.instanceData.byteLength,t.DYNAMIC_DRAW)}initRenderBuffers(){let t=this.cols*this.rows*2;this.maxCells=Math.ceil(t*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 t=this.cellWidth,e=this.cellHeight,i=this.glyphOffsetX,s=this.glyphOffsetY,a=this.charWidth,h=this.charHeight,o=0,l=0,r=0;for(let v=0;v<this.rows;v++){let f=Math.round(v*e),m=Math.round(f+e);for(let b=0;b<this.cols;b++){let d=Math.round(b*t),g=Math.round(d+t);this.renderPositions[o++]=d,this.renderPositions[o++]=f,this.renderPositions[o++]=g,this.renderPositions[o++]=f,this.renderPositions[o++]=d,this.renderPositions[o++]=m,this.renderPositions[o++]=g,this.renderPositions[o++]=m,this.renderIndices[l++]=r,this.renderIndices[l++]=r+1,this.renderIndices[l++]=r+2,this.renderIndices[l++]=r+2,this.renderIndices[l++]=r+1,this.renderIndices[l++]=r+3,r+=4;let E=Math.round(d+i),x=Math.round(f+s),y=Math.round(E+a),A=Math.round(x+h);this.renderPositions[o++]=E,this.renderPositions[o++]=x,this.renderPositions[o++]=y,this.renderPositions[o++]=x,this.renderPositions[o++]=E,this.renderPositions[o++]=A,this.renderPositions[o++]=y,this.renderPositions[o++]=A,this.renderIndices[l++]=r,this.renderIndices[l++]=r+1,this.renderIndices[l++]=r+2,this.renderIndices[l++]=r+2,this.renderIndices[l++]=r+1,this.renderIndices[l++]=r+3,r+=4}}let c=this.gl;c.bindBuffer(c.ARRAY_BUFFER,this.positionBuffer),c.bufferSubData(c.ARRAY_BUFFER,0,this.renderPositions),c.bindBuffer(c.ELEMENT_ARRAY_BUFFER,this.indexBuffer),c.bufferSubData(c.ELEMENT_ARRAY_BUFFER,0,this.renderIndices),this.staticPositionsInitialized=!0}initWebGL(){let t=this.gl,e;this.useInstancing?e=`
39
39
  // Per-vertex attributes (template quad)
40
40
  attribute vec2 aPosition; // Local quad position (0,0 to cellW,cellH)
41
41
 
@@ -74,7 +74,7 @@ var $=Object.defineProperty;var N=(b,e,t)=>e in b?$(b,e,{enumerable:!0,configura
74
74
  float paletteU = (colorIndex + 0.5) / 256.0;
75
75
  vColor = texture2D(uPalette, vec2(paletteU, 0.5));
76
76
  }
77
- `:t=`
77
+ `:e=`
78
78
  attribute vec2 aPosition;
79
79
  attribute vec2 aTexCoord;
80
80
  attribute float aColorIndex; // \u{1F680} Index dans palette (0-255)
@@ -116,7 +116,7 @@ var $=Object.defineProperty;var N=(b,e,t)=>e in b?$(b,e,{enumerable:!0,configura
116
116
  gl_FragColor = vec4(texColor.rgb * vColor.rgb, texColor.a);
117
117
  }
118
118
  }
119
- `,s=this.compileShader(e.VERTEX_SHADER,t),r=this.compileShader(e.FRAGMENT_SHADER,i);if(!s||!r)throw new Error("Shader compilation error");let l=e.createProgram();if(!l)throw new Error("Unable to create WebGL program");if(e.attachShader(l,s),e.attachShader(l,r),e.linkProgram(l),!e.getProgramParameter(l,e.LINK_STATUS)){let o=e.getProgramInfoLog(l);throw new Error("Program linking error: "+o)}this.program=l,this.cachedTextureUniform=!1,this.cachedPaletteUniform=!1,this.aPosition=e.getAttribLocation(l,"aPosition"),this.useInstancing?(this.aInstanceOffset=e.getAttribLocation(l,"aInstanceOffset"),this.aInstanceUVs=e.getAttribLocation(l,"aInstanceUVs"),this.aInstanceColors=e.getAttribLocation(l,"aInstanceColors"),this.uCellSize=e.getUniformLocation(l,"uCellSize"),this.instanceDataBuffer=e.createBuffer(),this.aTexCoord=this.aInstanceOffset,this.aColorIndex=this.aInstanceUVs):(this.aTexCoord=e.getAttribLocation(l,"aTexCoord"),this.aColorIndex=e.getAttribLocation(l,"aColorIndex")),this.uResolution=e.getUniformLocation(l,"uResolution"),this.uTexture=e.getUniformLocation(l,"uTexture"),this.uPalette=e.getUniformLocation(l,"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 i=this.gl,s=i.createShader(e);return s?(i.shaderSource(s,t),i.compileShader(s),i.getShaderParameter(s,i.COMPILE_STATUS)?s:(console.error("Shader compilation error:",i.getShaderInfoLog(s)),i.deleteShader(s),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,i=this.canvas.getBoundingClientRect(),s=this.containerDiv.getBoundingClientRect();this.gridOverlay.setDimensions(this.cols,this.rows,this.cellWidth,this.cellHeight,0,0),this.gridOverlay.setTransform(this.currentScale,e,t,i,s),this.gridOverlay.render()}setBitmapFont(e,t,i,s=t,r=i){this.bitmapFont=e,this.fontLoaded=!0,this.charWidth=t,this.charHeight=i,this.cellWidth=s,this.cellHeight=r,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),this.generateAtlas(),this.updateCanvasSize()}generateAtlas(){if(!this.bitmapFont)return;this.atlasColumns=16;let e=256,t=this.atlasColumns*this.charWidth,s=Math.ceil(e/this.atlasColumns)*this.charHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=t,this.atlasCanvas.height=s;let r=this.atlasCanvas.getContext("2d",{willReadFrequently:!0});if(!r)return;r.clearRect(0,0,t,s);let l=Array.from(this.bitmapFont.keys());for(let o of l){let n=this.bitmapFont.get(o);if(!n)continue;let c=o%this.atlasColumns,h=Math.floor(o/this.atlasColumns),d=c*this.charWidth,u=h*this.charHeight;for(let m=0;m<this.charHeight&&!(m>=n.length);m++){let x=n[m];for(let f=0;f<this.charWidth;f++){let p=1<<7-f;x&p&&(r.fillStyle="#FFFFFF",r.fillRect(d+f,u+m,1,1))}}}this.cachedAtlasWidth=t,this.cachedAtlasHeight=s,this.createAtlasTexture(),this.charCodeToAtlasIndex.fill(65535);for(let o=0;o<e;o++)this.charCodeToAtlasIndex[o]=o}async setImageFontStructure(e,t,i,s,r){let l=this.atlasCanvas&&this.fontLoaded&&this.charWidth===Math.round(e)&&this.charHeight===Math.round(t),o=this.atlasCanvas;this.fontLoaded=!0,this.charWidth=Math.round(e),this.charHeight=Math.round(t),this.cellWidth=Math.round(i),this.cellHeight=Math.round(s),this.atlasColumns=y(r);let n=B(r);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers();let c=y(r);if(this.cachedAtlasWidth=c*this.charWidth,this.cachedAtlasHeight=c*this.charHeight,this.allocateAtlasTexture(this.cachedAtlasWidth,this.cachedAtlasHeight),l&&o){console.warn("[TerminalGL] \u267B\uFE0F Preserving existing BitmapFont as Block 0");let h=this.gl;h.bindTexture(h.TEXTURE_2D,this.atlasTexture),h.texSubImage2D(h.TEXTURE_2D,0,0,0,h.RGBA,h.UNSIGNED_BYTE,o)}this.charCodeToAtlasIndex.fill(65535);for(let h=0;h<=n;h++)this.charCodeToAtlasIndex[h]=h;this.precomputeImageFontUVs(r),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()}async setImageFontBlock(e,t){let i=this.gl;if(!this.atlasTexture)return;let s=new Blob([t],{type:"image/png"}),r=await createImageBitmap(s),l=this.atlasColumns/16,o=e%l,n=Math.floor(e/l),c=o*16*this.charWidth,h=n*16*this.charHeight;i.bindTexture(i.TEXTURE_2D,this.atlasTexture),i.texSubImage2D(i.TEXTURE_2D,0,c,h,i.RGBA,i.UNSIGNED_BYTE,r),r.close()}async setImageFont(e,t,i,s,r,l){this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(i),this.cellWidth=Math.round(s),this.cellHeight=Math.round(r),this.atlasColumns=y(l);let o=B(l);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 n=0;n<=o;n++)this.charCodeToAtlasIndex[n]=n;this.precomputeImageFontUVs(l),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,i)=>{let s=new Uint8Array(e),r=new Blob([s],{type:"image/png"}),l=URL.createObjectURL(r),o=new Image;o.onload=()=>{URL.revokeObjectURL(l),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=o.width,this.atlasCanvas.height=o.height;let n=this.atlasCanvas.getContext("2d");if(!n){i(new Error("Failed to create 2D context for atlas"));return}n.drawImage(o,0,0),this.cachedAtlasWidth=o.width,this.cachedAtlasHeight=o.height,this.createAtlasTexture(),t()},o.onerror=()=>{URL.revokeObjectURL(l),i(new Error("Failed to load PNG image for ImageFont atlas"))},o.src=l})}precomputeImageFontUVs(e){let t=e*256;this.atlasUVs=new Float32Array(t*4);let i=this.cachedAtlasWidth,s=this.cachedAtlasHeight,r=.5/i,l=.5/s;for(let o=0;o<t;o++){let{col:n,row:c}=L(o,e),h=(n*this.charWidth+r)/i,d=(c*this.charHeight+l)/s,u=((n+1)*this.charWidth-r)/i,m=((c+1)*this.charHeight-l)/s,x=o*4;this.atlasUVs[x]=h,this.atlasUVs[x+1]=d,this.atlasUVs[x+2]=u,this.atlasUVs[x+3]=m}}allocateAtlasTexture(e,t){try{let i=this.gl,s=i.createTexture();if(!s)throw new Error("Unable to create texture");i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,e,t,0,i.RGBA,i.UNSIGNED_BYTE,null),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_S,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_T,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MIN_FILTER,i.NEAREST),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MAG_FILTER,i.NEAREST),this.atlasTexture=s}catch(i){throw console.error("[TerminalGL] \u274C Failed to create atlas texture:",i),i}}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),i=0,s=0,r=0;return t.length===3?(i=parseInt(t[0]+t[0],16),s=parseInt(t[1]+t[1],16),r=parseInt(t[2]+t[2],16)):t.length===6&&(i=parseInt(t.slice(0,2),16),s=parseInt(t.slice(2,4),16),r=parseInt(t.slice(4,6),16)),[i/255,s/255,r/255,1]}if(e.startsWith("rgb")){let t=e.match(/rgba?\(([^)]+)\)/);if(t){let i=t[1].split(",").map(s=>parseFloat(s.trim()));return[i[0]/255,i[1]/255,i[2]/255,i[3]!==void 0?i[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 i=this.cols*this.cellWidth,s=this.rows*this.cellHeight;if(i===0||s===0)return;let r=e/i,l=t/s,o=Math.min(r,l),n;switch(this.scalingMode){case C.Integer:n=Math.max(1,Math.floor(o));break;case C.Half:n=Math.max(1,Math.floor(o*2)/2);break;case C.Quarter:n=Math.max(1,Math.floor(o*4)/4);break;case C.Eighth:n=Math.max(1,Math.floor(o*8)/8);break;case C.Responsive:n=1;break;case C.None:default:n=Math.max(.1,o);break}if(this.canvas.style.transform=`scale(${n})`,this.ambientEffectEnabled&&this.ambientEffectCanvas){let c=n*this.ambientEffectScale;this.ambientEffectCanvas.style.transform=`scale(${c})`}this.currentScale=n,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 i=0;i<Math.min(e.length,256);i++){let s=e[i];t=(t<<5)-t+s.r,t=(t<<5)-t+s.g,t=(t<<5)-t+s.b,t=(t<<5)-t+s.a,t=t|0}if(t!==this.paletteHash){this.paletteHash=t;for(let i=0;i<e.length&&i<256;i++){let s=e[i],r=i*4;this.paletteFloat[r]=s.r/255,this.paletteFloat[r+1]=s.g/255,this.paletteFloat[r+2]=s.b/255,this.paletteFloat[r+3]=s.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 i=0;i<256;i++){let s=i*4;t[s]=this.paletteFloat[s]*255,t[s+1]=this.paletteFloat[s+1]*255,t[s+2]=this.paletteFloat[s+2]*255,t[s+3]=this.paletteFloat[s+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),e.passes&&e.passes.length>0?this.renderMultiPass(e,e.passes):this.renderDirect(e),this.ambientEffectEnabled&&this.ambientEffectCanvas&&this.ambientEffectCtx&&this.updateAmbientEffect()}catch(t){console.error("[TerminalGL] \u274C Error rendering display data:",t)}}renderMultiPass(e,t){for(let i=0;i<t.length;i++){let s=t[i],r={id:e.id,width:e.width,height:e.height,palette:e.palette,cells:s.cells};this.renderDirect(r,i===0)}}renderDirect(e,t=!0){let i=this.gl;if(!this.staticPositionsInitialized&&!this.useInstancing&&this.precomputeStaticPositions(),t){if(this.canvasBgColor!==null){let s=this.parseColor(this.canvasBgColor);i.clearColor(s[0],s[1],s[2],s[3])}else i.clearColor(0,0,0,0);i.clear(i.COLOR_BUFFER_BIT)}this.useInstancing?this.renderInstanced(e):this.renderDirectBuffers(e)}renderInstanced(e){let t=this.gl,i=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 s=0,r=this.instanceData.length/8,l=e.width*e.height*2;if(l>r){console.error(`[TerminalGL] \u274C Instance buffer too small! Need ${l}, have ${r}. Display size: ${e.width}\xD7${e.height}, buffer was sized for smaller terminal.`),this.renderDirectBuffers(e);return}for(let n=0;n<e.height;n++)for(let c=0;c<e.width;c++){let h=e.cells[n*e.width+c],d=h.bgColorIndex,u=h.fgColorIndex,m=this.canvasBgColor!==null&&d===255,x=h.char===" "||u===255;if(!m){if(s>=r){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${r}`);break}let f=s*8;this.instanceData[f]=c,this.instanceData[f+1]=n,this.instanceData[f+2]=0,this.instanceData[f+3]=0,this.instanceData[f+4]=0,this.instanceData[f+5]=0,this.instanceData[f+6]=d,this.instanceData[f+7]=0,s++}if(!x){let f=h.char.charCodeAt(0),p=this.charCodeToAtlasIndex[f];if(p!==65535){if(s>=r){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${r}`);break}let E=p*4,v=s*8;this.instanceData[v]=c,this.instanceData[v+1]=n,this.instanceData[v+2]=this.atlasUVs[E],this.instanceData[v+3]=this.atlasUVs[E+1],this.instanceData[v+4]=this.atlasUVs[E+2],this.instanceData[v+5]=this.atlasUVs[E+3],this.instanceData[v+6]=0,this.instanceData[v+7]=u,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),i.vertexAttribDivisorANGLE(this.aPosition,0),t.bindBuffer(t.ARRAY_BUFFER,this.instanceDataBuffer);let o=8*Float32Array.BYTES_PER_ELEMENT;t.enableVertexAttribArray(this.aInstanceOffset),t.vertexAttribPointer(this.aInstanceOffset,2,t.FLOAT,!1,o,0),i.vertexAttribDivisorANGLE(this.aInstanceOffset,1),t.enableVertexAttribArray(this.aInstanceUVs),t.vertexAttribPointer(this.aInstanceUVs,4,t.FLOAT,!1,o,2*Float32Array.BYTES_PER_ELEMENT),i.vertexAttribDivisorANGLE(this.aInstanceUVs,1),t.enableVertexAttribArray(this.aInstanceColors),t.vertexAttribPointer(this.aInstanceColors,2,t.FLOAT,!1,o,6*Float32Array.BYTES_PER_ELEMENT),i.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),i.drawElementsInstancedANGLE(t.TRIANGLES,6,t.UNSIGNED_SHORT,0,s),i.vertexAttribDivisorANGLE(this.aPosition,0),i.vertexAttribDivisorANGLE(this.aInstanceOffset,0),i.vertexAttribDivisorANGLE(this.aInstanceUVs,0),i.vertexAttribDivisorANGLE(this.aInstanceColors,0)}renderDirectBuffers(e){let t=this.gl,i=e.width*e.height,s=i*2;if(s>this.maxCells){console.error(`[TerminalGL] \u274C Buffer overflow detected! Trying to render ${s} quads but buffer capacity is ${this.maxCells}. This should not happen - resize() should have reallocated.`);return}let r=0,l=0,o=e.cells,n=i;for(let x=0;x<n;x++){let f=o[x],p=f.bgColorIndex,v=this.canvasBgColor!==null&&p===255?255:p,w=0;for(let T=0;T<4;T++)this.renderTexCoords[r++]=w,this.renderTexCoords[r++]=w,this.renderColorIndices[l++]=v;let A=f.fgColorIndex,S=f.char;if(S===" "||A===255)for(let T=0;T<4;T++)this.renderTexCoords[r++]=0,this.renderTexCoords[r++]=0,this.renderColorIndices[l++]=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[r++]=G,this.renderTexCoords[r++]=W,this.renderColorIndices[l++]=A,this.renderTexCoords[r++]=O,this.renderTexCoords[r++]=W,this.renderColorIndices[l++]=A,this.renderTexCoords[r++]=G,this.renderTexCoords[r++]=H,this.renderColorIndices[l++]=A,this.renderTexCoords[r++]=O,this.renderTexCoords[r++]=H,this.renderColorIndices[l++]=A}else for(let R=0;R<4;R++)this.renderTexCoords[r++]=0,this.renderTexCoords[r++]=0,this.renderColorIndices[l++]=255}}(r!==n*2*4*2||l!==n*2*4)&&console.error("[TerminalGL] \u274C Buffer index mismatch!",{texIdx:r,colorIdx:l,expected:n*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,r)),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,l))):(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,r)),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,l)),t.enableVertexAttribArray(this.aColorIndex),t.vertexAttribPointer(this.aColorIndex,1,t.FLOAT,!1,0,0));let c=this.canvas.width,h=this.canvas.height;(this.cachedResolution[0]!==c||this.cachedResolution[1]!==h)&&(t.uniform2f(this.uResolution,c,h),this.cachedResolution[0]=c,this.cachedResolution[1]=h),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 i=e*t,s=this.useInstancing?262144:this.useUint16Indices?8191:262144;if(i>s){let h=Math.floor(Math.sqrt(s));console.error(`[TerminalGL] \u274C Cannot resize to ${e}\xD7${t} (${i} cells). Device limit: ${s} cells (max ~${h}\xD7${h}). ${!this.useInstancing&&this.useUint16Indices?"Device lacks OES_element_index_uint extension.":""}`);return}let r=U.checkCompatibility();i>r.recommendedMaxCells&&console.warn(`[TerminalGL] \u26A0\uFE0F Resizing to ${e}\xD7${t} (${i} cells) exceeds recommended limit (${r.recommendedMaxCells} cells). Performance may degrade.`),this.cols=e,this.rows=t,this.staticPositionsInitialized=!1;let l=this.cols*this.rows*2,o=Math.ceil(l*1.5),n=l>this.maxCells,c=this.maxCells>o*4;if(console.warn(`[TerminalGL] \u{1F4D0} resize check: cols=${e}, rows=${t}, newMaxCells=${l}, this.maxCells=${this.maxCells}, needGrow=${n}, needShrink=${c}`),n||c){let h=this.maxCells;if(this.maxCells=o,console.warn(`[TerminalGL] \u{1F4D0} resize realloc: ${h} \u2192 ${this.maxCells} (needGrow=${n}, 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 d=this.gl;this.useInstancing||(d.bindBuffer(d.ARRAY_BUFFER,this.positionBuffer),d.bufferData(d.ARRAY_BUFFER,this.renderPositions.byteLength,d.DYNAMIC_DRAW)),d.bindBuffer(d.ARRAY_BUFFER,this.texCoordBuffer),d.bufferData(d.ARRAY_BUFFER,this.renderTexCoords.byteLength,d.DYNAMIC_DRAW),d.bindBuffer(d.ARRAY_BUFFER,this.colorIndexBuffer),d.bufferData(d.ARRAY_BUFFER,this.renderColorIndices.byteLength,d.DYNAMIC_DRAW),this.useInstancing||(d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,this.indexBuffer),d.bufferData(d.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,d.DYNAMIC_DRAW)),this.vaoExtension&&this.vao&&(this.vaoExtension.deleteVertexArrayOES(this.vao),this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),d.bindBuffer(d.ARRAY_BUFFER,this.positionBuffer),d.enableVertexAttribArray(this.aPosition),d.vertexAttribPointer(this.aPosition,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,this.texCoordBuffer),d.enableVertexAttribArray(this.aTexCoord),d.vertexAttribPointer(this.aTexCoord,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,this.colorIndexBuffer),d.enableVertexAttribArray(this.aColorIndex),d.vertexAttribPointer(this.aColorIndex,1,d.FLOAT,!1,0,0),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null)));let u=n?"\u{1F4C8} Growing":"\u{1F4C9} Shrinking",m=h*160/1048576,x=this.maxCells*160/1048576;console.warn(`[TerminalGL] ${u} buffers: ${m.toFixed(2)}MB \u2192 ${x.toFixed(2)}MB (${h} \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 i=Math.max(1,Math.min(255,Math.round(e))),s=Math.max(1,Math.min(255,Math.round(t)));this.cellWidth===i&&this.cellHeight===s||(this.cellWidth=i,this.cellHeight=s,this.charWidth=i,this.charHeight=s,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),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=`
119
+ `,s=this.compileShader(t.VERTEX_SHADER,e),a=this.compileShader(t.FRAGMENT_SHADER,i);if(!s||!a)throw new Error("Shader compilation error");let h=t.createProgram();if(!h)throw new Error("Unable to create WebGL program");if(t.attachShader(h,s),t.attachShader(h,a),t.linkProgram(h),!t.getProgramParameter(h,t.LINK_STATUS)){let o=t.getProgramInfoLog(h);throw new Error("Program linking error: "+o)}this.program=h,this.cachedTextureUniform=!1,this.cachedPaletteUniform=!1,this.aPosition=t.getAttribLocation(h,"aPosition"),this.useInstancing?(this.aInstanceOffset=t.getAttribLocation(h,"aInstanceOffset"),this.aInstanceUVs=t.getAttribLocation(h,"aInstanceUVs"),this.aInstanceColors=t.getAttribLocation(h,"aInstanceColors"),this.uCellSize=t.getUniformLocation(h,"uCellSize"),this.instanceDataBuffer=t.createBuffer(),this.aTexCoord=this.aInstanceOffset,this.aColorIndex=this.aInstanceUVs):(this.aTexCoord=t.getAttribLocation(h,"aTexCoord"),this.aColorIndex=t.getAttribLocation(h,"aColorIndex")),this.uResolution=t.getUniformLocation(h,"uResolution"),this.uTexture=t.getUniformLocation(h,"uTexture"),this.uPalette=t.getUniformLocation(h,"uPalette"),this.positionBuffer=t.createBuffer(),this.texCoordBuffer=t.createBuffer(),this.colorIndexBuffer=t.createBuffer(),this.indexBuffer=t.createBuffer(),t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.bufferData(t.ARRAY_BUFFER,this.renderPositions.byteLength,t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.texCoordBuffer),t.bufferData(t.ARRAY_BUFFER,this.renderTexCoords.byteLength,t.DYNAMIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.bufferData(t.ARRAY_BUFFER,this.renderColorIndices.byteLength,t.DYNAMIC_DRAW),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer),t.bufferData(t.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,t.DYNAMIC_DRAW),this.vaoExtension&&(this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),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.enableVertexAttribArray(this.aTexCoord),t.vertexAttribPointer(this.aTexCoord,2,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.colorIndexBuffer),t.enableVertexAttribArray(this.aColorIndex),t.vertexAttribPointer(this.aColorIndex,1,t.FLOAT,!1,0,0),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null))),t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA),t.viewport(0,0,this.canvas.width,this.canvas.height)}compileShader(t,e){let i=this.gl,s=i.createShader(t);return s?(i.shaderSource(s,e),i.compileShader(s),i.getShaderParameter(s,i.COMPILE_STATUS)?s:(console.error("Shader compilation error:",i.getShaderInfoLog(s)),i.deleteShader(s),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 t=this.cols*this.cellWidth,e=this.rows*this.cellHeight,i=this.canvas.getBoundingClientRect(),s=this.containerDiv.getBoundingClientRect();this.gridOverlay.setDimensions(this.cols,this.rows,this.cellWidth,this.cellHeight,0,0),this.gridOverlay.setTransform(this.currentScale,t,e,i,s),this.gridOverlay.render()}setBitmapFont(t,e,i,s=e,a=i){this.bitmapFont=t,this.fontLoaded=!0,this.charWidth=e,this.charHeight=i,this.cellWidth=s,this.cellHeight=a,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),this.generateAtlas(),this.updateCanvasSize()}generateAtlas(){if(!this.bitmapFont)return;this.atlasColumns=16;let t=256,e=this.atlasColumns*this.charWidth,s=Math.ceil(t/this.atlasColumns)*this.charHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=e,this.atlasCanvas.height=s;let a=this.atlasCanvas.getContext("2d",{willReadFrequently:!0});if(!a)return;a.clearRect(0,0,e,s);let h=Array.from(this.bitmapFont.keys());for(let o of h){let l=this.bitmapFont.get(o);if(!l)continue;let r=o%this.atlasColumns,c=Math.floor(o/this.atlasColumns),v=r*this.charWidth,f=c*this.charHeight;for(let m=0;m<this.charHeight&&!(m>=l.length);m++){let b=l[m];for(let d=0;d<this.charWidth;d++){let g=1<<7-d;b&g&&(a.fillStyle="#FFFFFF",a.fillRect(v+d,f+m,1,1))}}}this.cachedAtlasWidth=e,this.cachedAtlasHeight=s,this.createAtlasTexture(),this.charCodeToAtlasIndex.fill(65535);for(let o=0;o<t;o++)this.charCodeToAtlasIndex[o]=o}async setImageFontStructure(t,e,i,s,a){let h=this.atlasCanvas&&this.fontLoaded&&this.charWidth===Math.round(t)&&this.charHeight===Math.round(e),o=this.atlasCanvas;this.fontLoaded=!0,this.charWidth=Math.round(t),this.charHeight=Math.round(e),this.cellWidth=Math.round(i),this.cellHeight=Math.round(s),this.atlasColumns=w(a);let l=U(a);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers();let r=w(a);if(this.cachedAtlasWidth=r*this.charWidth,this.cachedAtlasHeight=r*this.charHeight,this.allocateAtlasTexture(this.cachedAtlasWidth,this.cachedAtlasHeight),h&&o){let c=this.gl;c.bindTexture(c.TEXTURE_2D,this.atlasTexture),c.texSubImage2D(c.TEXTURE_2D,0,0,0,c.RGBA,c.UNSIGNED_BYTE,o)}this.charCodeToAtlasIndex.fill(65535);for(let c=0;c<=l;c++)this.charCodeToAtlasIndex[c]=c;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()}async setImageFontBlock(t,e){let i=this.gl;if(!this.atlasTexture)return;let s=new Blob([e],{type:"image/png"}),a=await createImageBitmap(s),h=this.atlasColumns/16,o=t%h,l=Math.floor(t/h),r=o*16*this.charWidth,c=l*16*this.charHeight;i.bindTexture(i.TEXTURE_2D,this.atlasTexture),i.texSubImage2D(i.TEXTURE_2D,0,r,c,i.RGBA,i.UNSIGNED_BYTE,a),a.close()}async setImageFont(t,e,i,s,a,h){this.fontLoaded=!0,this.charWidth=Math.round(e),this.charHeight=Math.round(i),this.cellWidth=Math.round(s),this.cellHeight=Math.round(a),this.atlasColumns=w(h);let o=U(h);this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),await this.loadImageFontAtlas(t),this.charCodeToAtlasIndex.fill(65535);for(let l=0;l<=o;l++)this.charCodeToAtlasIndex[l]=l;this.precomputeImageFontUVs(h),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(t){return new Promise((e,i)=>{let s=new Uint8Array(t),a=new Blob([s],{type:"image/png"}),h=URL.createObjectURL(a),o=new Image;o.onload=()=>{URL.revokeObjectURL(h),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=o.width,this.atlasCanvas.height=o.height;let l=this.atlasCanvas.getContext("2d");if(!l){i(new Error("Failed to create 2D context for atlas"));return}l.drawImage(o,0,0),this.cachedAtlasWidth=o.width,this.cachedAtlasHeight=o.height,this.createAtlasTexture(),e()},o.onerror=()=>{URL.revokeObjectURL(h),i(new Error("Failed to load PNG image for ImageFont atlas"))},o.src=h})}precomputeImageFontUVs(t){let e=t*256;this.atlasUVs=new Float32Array(e*4);let i=this.cachedAtlasWidth,s=this.cachedAtlasHeight,a=.5/i,h=.5/s;for(let o=0;o<e;o++){let{col:l,row:r}=D(o,t),c=(l*this.charWidth+a)/i,v=(r*this.charHeight+h)/s,f=((l+1)*this.charWidth-a)/i,m=((r+1)*this.charHeight-h)/s,b=o*4;this.atlasUVs[b]=c,this.atlasUVs[b+1]=v,this.atlasUVs[b+2]=f,this.atlasUVs[b+3]=m}}allocateAtlasTexture(t,e){try{let i=this.gl,s=i.createTexture();if(!s)throw new Error("Unable to create texture");i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,t,e,0,i.RGBA,i.UNSIGNED_BYTE,null),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_S,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_T,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MIN_FILTER,i.NEAREST),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MAG_FILTER,i.NEAREST),this.atlasTexture=s}catch(i){throw console.error("[TerminalGL] \u274C Failed to create atlas texture:",i),i}}createAtlasTexture(){if(this.atlasCanvas)try{let t=this.gl,e=t.createTexture();if(!e)throw new Error("Unable to create texture");t.bindTexture(t.TEXTURE_2D,e),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.atlasCanvas),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),this.atlasTexture=e}catch(t){throw console.error("[TerminalGL] \u274C Failed to create atlas texture:",t),t}}clear(){let t=this.gl;t&&t.clear(t.COLOR_BUFFER_BIT)}parseColor(t){if(t.startsWith("#")){let e=t.slice(1),i=0,s=0,a=0;return e.length===3?(i=parseInt(e[0]+e[0],16),s=parseInt(e[1]+e[1],16),a=parseInt(e[2]+e[2],16)):e.length===6&&(i=parseInt(e.slice(0,2),16),s=parseInt(e.slice(2,4),16),a=parseInt(e.slice(4,6),16)),[i/255,s/255,a/255,1]}if(t.startsWith("rgb")){let e=t.match(/rgba?\(([^)]+)\)/);if(e){let i=e[1].split(",").map(s=>parseFloat(s.trim()));return[i[0]/255,i[1]/255,i[2]/255,i[3]!==void 0?i[3]:1]}}return[1,1,1,1]}setupResizeObserver(){if(!(typeof ResizeObserver>"u"))try{this.resizeObserver=new ResizeObserver(()=>{try{this.updateCanvasSize()}catch(t){console.error("[TerminalGL] \u274C Error in resize callback:",t)}}),this.resizeObserver.observe(this.parentElement),this.updateCanvasSize()}catch(t){console.error("[TerminalGL] \u274C Failed to setup ResizeObserver:",t)}}updateCanvasSize(){let t=this.parentElement.clientWidth,e=this.parentElement.clientHeight;if(t===0||e===0)return;let i=this.cols*this.cellWidth,s=this.rows*this.cellHeight;if(i===0||s===0)return;let a=t/i,h=e/s,o=Math.min(a,h),l;switch(this.scalingMode){case C.Integer:l=Math.max(1,Math.floor(o));break;case C.Half:l=Math.max(1,Math.floor(o*2)/2);break;case C.Quarter:l=Math.max(1,Math.floor(o*4)/4);break;case C.Eighth:l=Math.max(1,Math.floor(o*8)/8);break;case C.Responsive:l=1;break;case C.None:default:l=Math.max(.1,o);break}if(this.canvas.style.transform=`scale(${l})`,this.ambientEffectEnabled&&this.ambientEffectCanvas){let r=l*this.ambientEffectScale;this.ambientEffectCanvas.style.transform=`scale(${r})`}this.currentScale=l,this.onResizeCallback&&this.onResizeCallback(),this.showGrid&&this.gridOverlay&&this.updateGridOverlay()}updateAmbientEffect(){!this.ambientEffectCanvas||!this.ambientEffectCtx||this.ambientEffectCtx.drawImage(this.canvas,0,0)}setPalette(t){let e=0;for(let i=0;i<Math.min(t.length,256);i++){let s=t[i];e=(e<<5)-e+s.r,e=(e<<5)-e+s.g,e=(e<<5)-e+s.b,e=(e<<5)-e+s.a,e=e|0}if(e!==this.paletteHash){this.paletteHash=e;for(let i=0;i<t.length&&i<256;i++){let s=t[i],a=i*4;this.paletteFloat[a]=s.r/255,this.paletteFloat[a+1]=s.g/255,this.paletteFloat[a+2]=s.b/255,this.paletteFloat[a+3]=s.a/255}this.updatePaletteTexture()}}updatePaletteTexture(){try{let t=this.gl;this.paletteTexture||(this.paletteTexture=t.createTexture()),t.bindTexture(t.TEXTURE_2D,this.paletteTexture);let e=new Uint8Array(256*4);for(let i=0;i<256;i++){let s=i*4;e[s]=this.paletteFloat[s]*255,e[s+1]=this.paletteFloat[s+1]*255,e[s+2]=this.paletteFloat[s+2]*255,e[s+3]=this.paletteFloat[s+3]*255}t.texImage2D(t.TEXTURE_2D,0,t.RGBA,256,1,0,t.RGBA,t.UNSIGNED_BYTE,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.bindTexture(t.TEXTURE_2D,null)}catch(t){throw console.error("[TerminalGL] \u274C Failed to update palette texture:",t),t}}renderDisplayData(t){try{if(!this.isReady())return;(t.width!==this.cols||t.height!==this.rows)&&this.resize(t.width,t.height),t.passes&&t.passes.length>0?this.renderMultiPass(t,t.passes):this.renderDirect(t),this.ambientEffectEnabled&&this.ambientEffectCanvas&&this.ambientEffectCtx&&this.updateAmbientEffect()}catch(e){console.error("[TerminalGL] \u274C Error rendering display data:",e)}}renderMultiPass(t,e){for(let i=0;i<e.length;i++){let s=e[i],a={id:t.id,width:t.width,height:t.height,palette:t.palette,cells:s.cells};this.renderDirect(a,i===0)}}renderDirect(t,e=!0){let i=this.gl;if(!this.staticPositionsInitialized&&!this.useInstancing&&this.precomputeStaticPositions(),e){if(this.canvasBgColor!==null){let s=this.parseColor(this.canvasBgColor);i.clearColor(s[0],s[1],s[2],s[3])}else i.clearColor(0,0,0,0);i.clear(i.COLOR_BUFFER_BIT)}this.useInstancing?this.renderInstanced(t):this.renderDirectBuffers(t)}renderInstanced(t){let e=this.gl,i=this.instancedExtension;if(!this.instanceData||this.instanceData.length===0){this.renderDirectBuffers(t);return}let s=0,a=this.instanceData.length/8,h=t.width*t.height*2;if(h>a){console.error(`[TerminalGL] \u274C Instance buffer too small! Need ${h}, have ${a}. Display size: ${t.width}\xD7${t.height}, buffer was sized for smaller terminal.`),this.renderDirectBuffers(t);return}for(let l=0;l<t.height;l++)for(let r=0;r<t.width;r++){let c=t.cells[l*t.width+r],v=c.bgColorIndex,f=c.fgColorIndex,m=this.canvasBgColor!==null&&v===255,b=c.char===" "||f===255;if(!m){if(s>=a){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${a}`);break}let d=s*8;this.instanceData[d]=r,this.instanceData[d+1]=l,this.instanceData[d+2]=0,this.instanceData[d+3]=0,this.instanceData[d+4]=0,this.instanceData[d+5]=0,this.instanceData[d+6]=v,this.instanceData[d+7]=0,s++}if(!b){let d=c.char.charCodeAt(0),g=this.charCodeToAtlasIndex[d];if(g!==65535){if(s>=a){console.error(`[TerminalGL] \u274C Instance buffer overflow! instanceIdx=${s}, max=${a}`);break}let E=g*4,x=s*8;this.instanceData[x]=r,this.instanceData[x+1]=l,this.instanceData[x+2]=this.atlasUVs[E],this.instanceData[x+3]=this.atlasUVs[E+1],this.instanceData[x+4]=this.atlasUVs[E+2],this.instanceData[x+5]=this.atlasUVs[E+3],this.instanceData[x+6]=0,this.instanceData[x+7]=f,s++}}}if(s===0)return;e.bindBuffer(e.ARRAY_BUFFER,this.instanceDataBuffer),e.bufferSubData(e.ARRAY_BUFFER,0,this.instanceData.subarray(0,s*8)),e.useProgram(this.program),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(this.aPosition),e.vertexAttribPointer(this.aPosition,2,e.FLOAT,!1,0,0),i.vertexAttribDivisorANGLE(this.aPosition,0),e.bindBuffer(e.ARRAY_BUFFER,this.instanceDataBuffer);let o=8*Float32Array.BYTES_PER_ELEMENT;e.enableVertexAttribArray(this.aInstanceOffset),e.vertexAttribPointer(this.aInstanceOffset,2,e.FLOAT,!1,o,0),i.vertexAttribDivisorANGLE(this.aInstanceOffset,1),e.enableVertexAttribArray(this.aInstanceUVs),e.vertexAttribPointer(this.aInstanceUVs,4,e.FLOAT,!1,o,2*Float32Array.BYTES_PER_ELEMENT),i.vertexAttribDivisorANGLE(this.aInstanceUVs,1),e.enableVertexAttribArray(this.aInstanceColors),e.vertexAttribPointer(this.aInstanceColors,2,e.FLOAT,!1,o,6*Float32Array.BYTES_PER_ELEMENT),i.vertexAttribDivisorANGLE(this.aInstanceColors,1),e.uniform2f(this.uResolution,this.canvas.width,this.canvas.height),e.uniform2f(this.uCellSize,this.cellWidth,this.cellHeight),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.atlasTexture),e.uniform1i(this.uTexture,0),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.paletteTexture),e.uniform1i(this.uPalette,1),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer),i.drawElementsInstancedANGLE(e.TRIANGLES,6,e.UNSIGNED_SHORT,0,s),i.vertexAttribDivisorANGLE(this.aPosition,0),i.vertexAttribDivisorANGLE(this.aInstanceOffset,0),i.vertexAttribDivisorANGLE(this.aInstanceUVs,0),i.vertexAttribDivisorANGLE(this.aInstanceColors,0)}renderDirectBuffers(t){let e=this.gl,i=t.width*t.height,s=i*2;if(s>this.maxCells){console.error(`[TerminalGL] \u274C Buffer overflow detected! Trying to render ${s} quads but buffer capacity is ${this.maxCells}. This should not happen - resize() should have reallocated.`);return}let a=0,h=0,o=t.cells,l=i;for(let b=0;b<l;b++){let d=o[b],g=d.bgColorIndex,x=this.canvasBgColor!==null&&g===255?255:g,y=0;for(let T=0;T<4;T++)this.renderTexCoords[a++]=y,this.renderTexCoords[a++]=y,this.renderColorIndices[h++]=x;let A=d.fgColorIndex,M=d.char;if(M===" "||A===255)for(let T=0;T<4;T++)this.renderTexCoords[a++]=0,this.renderTexCoords[a++]=0,this.renderColorIndices[h++]=255;else{let T=M.charCodeAt(0),P=this.charCodeToAtlasIndex[T];if(P!==65535){let R=P*4,W=this.atlasUVs[R],G=this.atlasUVs[R+1],O=this.atlasUVs[R+2],H=this.atlasUVs[R+3];this.renderTexCoords[a++]=W,this.renderTexCoords[a++]=G,this.renderColorIndices[h++]=A,this.renderTexCoords[a++]=O,this.renderTexCoords[a++]=G,this.renderColorIndices[h++]=A,this.renderTexCoords[a++]=W,this.renderTexCoords[a++]=H,this.renderColorIndices[h++]=A,this.renderTexCoords[a++]=O,this.renderTexCoords[a++]=H,this.renderColorIndices[h++]=A}else for(let R=0;R<4;R++)this.renderTexCoords[a++]=0,this.renderTexCoords[a++]=0,this.renderColorIndices[h++]=255}}(a!==l*2*4*2||h!==l*2*4)&&console.error("[TerminalGL] \u274C Buffer index mismatch!",{texIdx:a,colorIdx:h,expected:l*2*4}),e.useProgram(this.program),this.vao&&this.vaoExtension?(this.vaoExtension.bindVertexArrayOES(this.vao),e.bindBuffer(e.ARRAY_BUFFER,this.texCoordBuffer),e.bufferSubData(e.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,a)),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.bufferSubData(e.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,h))):(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.bufferSubData(e.ARRAY_BUFFER,0,this.renderTexCoords.subarray(0,a)),e.enableVertexAttribArray(this.aTexCoord),e.vertexAttribPointer(this.aTexCoord,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.colorIndexBuffer),e.bufferSubData(e.ARRAY_BUFFER,0,this.renderColorIndices.subarray(0,h)),e.enableVertexAttribArray(this.aColorIndex),e.vertexAttribPointer(this.aColorIndex,1,e.FLOAT,!1,0,0));let r=this.canvas.width,c=this.canvas.height;(this.cachedResolution[0]!==r||this.cachedResolution[1]!==c)&&(e.uniform2f(this.uResolution,r,c),this.cachedResolution[0]=r,this.cachedResolution[1]=c),this.cachedTextureUnit!==0&&(e.activeTexture(e.TEXTURE0),this.cachedTextureUnit=0),e.bindTexture(e.TEXTURE_2D,this.atlasTexture),this.cachedTextureUniform||(e.uniform1i(this.uTexture,0),this.cachedTextureUniform=!0),this.cachedPaletteUnit!==1&&(e.activeTexture(e.TEXTURE1),this.cachedPaletteUnit=1),e.bindTexture(e.TEXTURE_2D,this.paletteTexture),this.cachedPaletteUniform||(e.uniform1i(this.uPalette,1),this.cachedPaletteUniform=!0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.indexBuffer);let f=t.width*t.height*2*6,m=this.useUint16Indices?e.UNSIGNED_SHORT:e.UNSIGNED_INT;e.drawElements(e.TRIANGLES,f,m,0)}resize(t,e){if(!Number.isInteger(t)||t<=0){console.error(`[TerminalGL] \u274C Invalid cols: ${t}. Must be positive integer.`);return}if(!Number.isInteger(e)||e<=0){console.error(`[TerminalGL] \u274C Invalid rows: ${e}. Must be positive integer.`);return}if(t===this.cols&&e===this.rows)return;let i=t*e,s=this.useInstancing?262144:this.useUint16Indices?8191:262144;if(i>s){let r=Math.floor(Math.sqrt(s));console.error(`[TerminalGL] \u274C Cannot resize to ${t}\xD7${e} (${i} cells). Device limit: ${s} cells (max ~${r}\xD7${r}). ${!this.useInstancing&&this.useUint16Indices?"Device lacks OES_element_index_uint extension.":""}`);return}this.cols=t,this.rows=e,this.staticPositionsInitialized=!1;let a=this.cols*this.rows*2,h=Math.ceil(a*1.5),o=a>this.maxCells,l=this.maxCells>h*4;if(o||l){if(this.maxCells=h,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 c=this.gl;c.bindBuffer(c.ARRAY_BUFFER,this.instanceDataBuffer),c.bufferData(c.ARRAY_BUFFER,this.instanceData.byteLength,c.DYNAMIC_DRAW)}let r=this.gl;this.useInstancing||(r.bindBuffer(r.ARRAY_BUFFER,this.positionBuffer),r.bufferData(r.ARRAY_BUFFER,this.renderPositions.byteLength,r.DYNAMIC_DRAW)),r.bindBuffer(r.ARRAY_BUFFER,this.texCoordBuffer),r.bufferData(r.ARRAY_BUFFER,this.renderTexCoords.byteLength,r.DYNAMIC_DRAW),r.bindBuffer(r.ARRAY_BUFFER,this.colorIndexBuffer),r.bufferData(r.ARRAY_BUFFER,this.renderColorIndices.byteLength,r.DYNAMIC_DRAW),this.useInstancing||(r.bindBuffer(r.ELEMENT_ARRAY_BUFFER,this.indexBuffer),r.bufferData(r.ELEMENT_ARRAY_BUFFER,this.renderIndices.byteLength,r.DYNAMIC_DRAW)),this.vaoExtension&&this.vao&&(this.vaoExtension.deleteVertexArrayOES(this.vao),this.vao=this.vaoExtension.createVertexArrayOES(),this.vao&&(this.vaoExtension.bindVertexArrayOES(this.vao),r.bindBuffer(r.ARRAY_BUFFER,this.positionBuffer),r.enableVertexAttribArray(this.aPosition),r.vertexAttribPointer(this.aPosition,2,r.FLOAT,!1,0,0),r.bindBuffer(r.ARRAY_BUFFER,this.texCoordBuffer),r.enableVertexAttribArray(this.aTexCoord),r.vertexAttribPointer(this.aTexCoord,2,r.FLOAT,!1,0,0),r.bindBuffer(r.ARRAY_BUFFER,this.colorIndexBuffer),r.enableVertexAttribArray(this.aColorIndex),r.vertexAttribPointer(this.aColorIndex,1,r.FLOAT,!1,0,0),r.bindBuffer(r.ELEMENT_ARRAY_BUFFER,this.indexBuffer),this.vaoExtension.bindVertexArrayOES(null)))}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(t){this.onResizeCallback=t}clearOnResizeCallback(){this.onResizeCallback=void 0}getAvailableSize(){return{width:this.parentElement.clientWidth,height:this.parentElement.clientHeight}}setScalingMode(t){this.scalingMode!==t&&(this.scalingMode=t,this.updateCanvasSize())}getScalingMode(){return this.scalingMode}setCellSize(t,e){let i=Math.max(1,Math.min(255,Math.round(t))),s=Math.max(1,Math.min(255,Math.round(e)));this.cellWidth===i&&this.cellHeight===s||(this.cellWidth=i,this.cellHeight=s,this.charWidth=i,this.charHeight=s,this.glyphOffsetX=Math.round((this.cellWidth-this.charWidth)/2),this.glyphOffsetY=Math.round((this.cellHeight-this.charHeight)/2),this.useInstancing&&this.initInstancedBuffers(),this.updateCanvasSize())}getCellSize(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getMaxCells(){return this.useInstancing?262144:this.useUint16Indices?8191:262144}setGrid(t){t.enabled?(this.gridOverlay?this.gridOverlay.setStyle({strokeColor:t.color,lineWidth:t.lineWidth}):this.gridOverlay=new I(this.containerDiv,{strokeColor:t.color??"rgba(144, 24, 24, 1)",lineWidth:t.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(t){typeof t=="boolean"?this.ambientEffectEnabled=t:(this.ambientEffectEnabled=!0,t.blur!==void 0&&(this.ambientEffectBlur=t.blur),t.scale!==void 0&&(this.ambientEffectScale=t.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=`
120
120
  display: block !important;
121
121
  position: absolute !important;
122
122
  width: ${this.canvas.width}px !important;
@@ -127,4 +127,4 @@ var $=Object.defineProperty;var N=(b,e,t)=>e in b?$(b,e,{enumerable:!0,configura
127
127
  transform: scale(${this.ambientEffectScale}) !important;
128
128
  pointer-events: none !important;
129
129
  z-index: 0 !important;
130
- `,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)}};g(U,"TerminalGL");var D=U;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(b,e=M){return b<0||b>=e.length?"#ff00ff":e[b]}g(Y,"paletteIndexToColor");function k(b,e=M){let t=e.indexOf(b.toLowerCase());return t>=0?t:0}g(k,"colorToPaletteIndex");export{M as DEFAULT_PALETTE,I as GridOverlay,C as ScalingMode,D as TerminalGL,k as colorToPaletteIndex,y as getAtlasColumns,L as getCharGridPosition,B as getMaxCharCode,Y as paletteIndexToColor};
130
+ `,this.ambientEffectCtx=this.ambientEffectCanvas.getContext("2d",{alpha:!0}),this.containerDiv.insertBefore(this.ambientEffectCanvas,this.canvas))}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 t=this.gl;this.program&&t.deleteProgram(this.program),this.positionBuffer&&t.deleteBuffer(this.positionBuffer),this.texCoordBuffer&&t.deleteBuffer(this.texCoordBuffer),this.colorIndexBuffer&&t.deleteBuffer(this.colorIndexBuffer),this.indexBuffer&&t.deleteBuffer(this.indexBuffer),this.instanceDataBuffer&&t.deleteBuffer(this.instanceDataBuffer),this.atlasTexture&&t.deleteTexture(this.atlasTexture),this.paletteTexture&&t.deleteTexture(this.paletteTexture),this.vao&&this.vaoExtension&&this.vaoExtension.deleteVertexArrayOES(this.vao);let e=t.getExtension("WEBGL_lose_context");e&&e.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)}};p(_,"TerminalGL");var L=_;var S=["#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(u,t=S){return u<0||u>=t.length?"#ff00ff":t[u]}p(k,"paletteIndexToColor");function V(u,t=S){let e=t.indexOf(u.toLowerCase());return e>=0?e:0}p(V,"colorToPaletteIndex");export{S as DEFAULT_PALETTE,I as GridOverlay,C as ScalingMode,L as TerminalGL,V as colorToPaletteIndex,w as getAtlasColumns,D as getCharGridPosition,U as getMaxCharCode,k as paletteIndexToColor};