shaderpad 1.0.0-beta.82 → 1.0.0-beta.83

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +19 -2
  3. package/dist/chunk-4UKNQUGK.mjs +5 -0
  4. package/dist/chunk-4UKNQUGK.mjs.map +1 -0
  5. package/dist/chunk-FVO6LH2F.mjs +2 -0
  6. package/dist/chunk-FVO6LH2F.mjs.map +1 -0
  7. package/dist/dev/{chunk-YN3AO6HP.mjs → chunk-UOFU6ODR.mjs} +3 -2
  8. package/dist/dev/chunk-UOFU6ODR.mjs.map +1 -0
  9. package/dist/dev/{chunk-TTKZ43JC.mjs → chunk-YB3GMXKV.mjs} +15 -7
  10. package/dist/dev/chunk-YB3GMXKV.mjs.map +1 -0
  11. package/dist/dev/index.js +14 -6
  12. package/dist/dev/index.js.map +1 -1
  13. package/dist/dev/index.mjs +1 -1
  14. package/dist/dev/plugins/pose.js +14 -6
  15. package/dist/dev/plugins/pose.js.map +1 -1
  16. package/dist/dev/plugins/pose.mjs +1 -1
  17. package/dist/dev/plugins/segmenter.js +14 -6
  18. package/dist/dev/plugins/segmenter.js.map +1 -1
  19. package/dist/dev/plugins/segmenter.mjs +1 -1
  20. package/dist/dev/react.js +16 -7
  21. package/dist/dev/react.js.map +1 -1
  22. package/dist/dev/react.mjs +2 -2
  23. package/dist/dev/web-component.js +16 -7
  24. package/dist/dev/web-component.js.map +1 -1
  25. package/dist/dev/web-component.mjs +2 -2
  26. package/dist/index.d.mts +4 -2
  27. package/dist/index.d.ts +4 -2
  28. package/dist/index.js +4 -4
  29. package/dist/index.js.map +1 -1
  30. package/dist/index.mjs +1 -1
  31. package/dist/plugins/pose.js +29 -29
  32. package/dist/plugins/pose.js.map +1 -1
  33. package/dist/plugins/pose.mjs +1 -1
  34. package/dist/plugins/segmenter.js +10 -10
  35. package/dist/plugins/segmenter.js.map +1 -1
  36. package/dist/plugins/segmenter.mjs +1 -1
  37. package/dist/react.js +3 -3
  38. package/dist/react.js.map +1 -1
  39. package/dist/react.mjs +1 -1
  40. package/dist/web-component.js +4 -4
  41. package/dist/web-component.js.map +1 -1
  42. package/dist/web-component.mjs +1 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-B3EEZDUT.mjs +0 -5
  45. package/dist/chunk-B3EEZDUT.mjs.map +0 -1
  46. package/dist/chunk-O3TAD633.mjs +0 -2
  47. package/dist/chunk-O3TAD633.mjs.map +0 -1
  48. package/dist/dev/chunk-TTKZ43JC.mjs.map +0 -1
  49. package/dist/dev/chunk-YN3AO6HP.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # shaderpad
2
2
 
3
+ ## 1.0.0-beta.83
4
+
5
+ ### Minor Changes
6
+
7
+ - Add support for wide-gamut color
8
+
3
9
  ## 1.0.0-beta.82
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -222,6 +222,7 @@ shader.initializeTexture('u_canvas', canvasElement, { preserveY: true });
222
222
  - `magFilter?: string` - Magnification filter (default: `'LINEAR'`). Examples: `'LINEAR'`, `'NEAREST'`
223
223
  - `wrapS?: string` - Wrap mode for S coordinate (default: `'CLAMP_TO_EDGE'`). Examples: `'CLAMP_TO_EDGE'`, `'REPEAT'`, `'MIRRORED_REPEAT'`
224
224
  - `wrapT?: string` - Wrap mode for T coordinate (default: `'CLAMP_TO_EDGE'`). Examples: `'CLAMP_TO_EDGE'`, `'REPEAT'`, `'MIRRORED_REPEAT'`
225
+ - `colorSpace?: 'srgb' | 'display-p3'` - Color space for DOM texture upload conversion where supported
225
226
 
226
227
  **Note:** For typed array sources (`CustomTexture`), you must provide data in bottom-up orientation (WebGL convention). The `preserveY` option is ignored for typed arrays.
227
228
 
@@ -314,7 +315,7 @@ shader.destroy(); // Clean up resources.
314
315
  ### Type exports
315
316
 
316
317
  `shaderpad` exports `Options`, `StepOptions`, `TextureOptions`, `InitializeTextureOptions`, `TextureSource`,
317
- `UpdateTextureSource`, `CustomTexture`, `PartialCustomTexture`, `Plugin`, `PluginContext`, `ShaderPadEventName`, and
318
+ `UpdateTextureSource`, `CustomTexture`, `PartialCustomTexture`, `Plugin`, `PluginContext`, `ShaderPadEventName`, `ColorSpace`, and
318
319
  the GL literal string types. `shaderpad/util` exports `ToBlobOptions` and `SaveOptions`.
319
320
 
320
321
  ### Event Listeners
@@ -388,7 +389,7 @@ examples, browse the
388
389
  ShaderPad’s constructor accepts an optional `options` object.
389
390
 
390
391
  In addition to the fields below, constructor options also accept texture storage/filter/wrap settings such as
391
- `internalFormat`, `format`, `type`, `minFilter`, `magFilter`, `wrapS`, and `wrapT`. These configure ShaderPad’s
392
+ `internalFormat`, `format`, `type`, `minFilter`, `magFilter`, `wrapS`, `wrapT`, and `colorSpace`. These configure ShaderPad’s
392
393
  internal render targets and history buffers, which is mainly useful for float/integer pipelines and chained shaders.
393
394
 
394
395
  ### canvas
@@ -464,6 +465,22 @@ float zIndex = historyZ(u_webcam, u_webcamFrameOffset, nFramesAgo);
464
465
  vec4 historyColor = texture(u_webcam, vec3(v_uv, zIndex));
465
466
  ```
466
467
 
468
+ ### colorSpace
469
+
470
+ Opt into browser color management for wide-gamut work.
471
+
472
+ ```typescript
473
+ const shader = new ShaderPad(fragmentShaderSrc, {
474
+ colorSpace: 'display-p3',
475
+ });
476
+
477
+ shader.initializeTexture('u_image', imageElement, {
478
+ colorSpace: 'display-p3',
479
+ });
480
+ ```
481
+
482
+ On the constructor, `colorSpace` applies to the WebGL drawing buffer and ShaderPad’s internal render texture. On `initializeTexture()`, it applies while uploading DOM image-like sources such as images, videos, canvases, and `ImageBitmap`. Typed-array textures are not color-converted.
483
+
467
484
  ### plugins
468
485
 
469
486
  ShaderPad adds additional functionality through plugins, which keeps bundle sizes small.
@@ -0,0 +1,5 @@
1
+ import{a as m,b as S}from"./chunk-QROQ7JVO.mjs";var C=`#version 300 es
2
+ in vec2 a_position;out vec2 v_uv;void main(){gl_Position=vec4(a_position,0.,1.);v_uv=a_position*.5+.5;}`,M=[["8UI","UNSIGNED_BYTE"],["8I","BYTE"],["16UI","UNSIGNED_SHORT"],["16I","SHORT"],["16F","HALF_FLOAT"],["32UI","UNSIGNED_INT"],["32I","INT"],["32F","FLOAT"],["8","UNSIGNED_BYTE"]],N={float:"f",int:"i",uint:"ui"};function B(l){return l&&M.find(([r])=>l.endsWith(r))?.[1]}var v=Symbol("u_history"),g=Symbol("__SHADERPAD_BUFFER"),F=new WeakMap;function H(l,r){if(!r?.length)return l;let e=l.split(`
3
+ `),i=e.findLastIndex(t=>{let s=t.trimStart();return s.startsWith("precision ")||s.startsWith("#version ")})+1;return e.splice(i,0,...r),e.join(`
4
+ `)}function O(l){return l instanceof WebGLTexture?{width:0,height:0}:l instanceof I?{width:l.canvas.width,height:l.canvas.height}:l instanceof HTMLVideoElement?{width:l.videoWidth,height:l.videoHeight}:l instanceof HTMLImageElement?{width:l.naturalWidth??l.width,height:l.naturalHeight??l.height}:{width:l.width,height:l.height}}function P(l){return typeof l=="symbol"?l.description??"":l}var I=class l{isHeadless=!1;isTouch=!1;uniforms=new Map;textures=new Map;buffer=null;vao=null;program=null;listeners=new Map;frame=0;tElapsed=0;tStart=NaN;cursorPos=[.5,.5];clickPos=[.5,.5];isClicked=!1;resObserver=null;hooks=new Map;historyDepth=0;intermediateFbo=null;constructor(r,{canvas:e,plugins:i,history:t,cursorTarget:s,...a}={}){if(e&&"getContext"in e)this.canvas=e;else{let{width:f=1,height:E=1}=e||{};this.canvas=new OffscreenCanvas(f,E),this.isHeadless=!0}let n=this.canvas.getContext("webgl2",{antialias:!1});if(!n)throw m(0);a.colorSpace&&"drawingBufferColorSpace"in n&&(n.drawingBufferColorSpace=a.colorSpace),this.gl=n,this.typeArrays=new Map([[n.FLOAT,Float32Array],[n.HALF_FLOAT,Uint16Array],[n.UNSIGNED_SHORT,Uint16Array],[n.SHORT,Int16Array],[n.BYTE,Int8Array],[n.UNSIGNED_INT,Uint32Array],[n.INT,Int32Array]]),this.typeFormats=new Map([[n.FLOAT,"RGBA32F"],[n.HALF_FLOAT,"RGBA16F"],[n.UNSIGNED_SHORT,"RGBA32UI"],[n.SHORT,"RGBA32I"],[n.BYTE,"RGBA32I"],[n.UNSIGNED_INT,"RGBA32UI"],[n.INT,"RGBA32I"]]),this.uintTypes=new Set([n.UNSIGNED_BYTE,n.UNSIGNED_SHORT,n.UNSIGNED_INT]);let o=F.get(this.canvas);o||(o={texPool:{free:[],next:0,max:n.getParameter(n.MAX_COMBINED_TEXTURE_IMAGE_UNITS)},instances:new Set([this])},F.set(this.canvas,o)),this.texPool=o.texPool,o.instances.add(this),this.texOptions=a,t&&(this.historyDepth=t),this.cursorTgt=s??(this.canvas instanceof HTMLCanvasElement?this.canvas:void 0),this.frameId=null;let h=[];i&&i.forEach(f=>f(this,{injectGLSL:E=>{h.push(E)},emit:this.emit.bind(this),updateTexture:this.updateTex.bind(this)}));let u=n.createProgram();if(!u)throw m(1);this.program=u;let c=this.createShader(n.VERTEX_SHADER,C),p=this.createShader(n.FRAGMENT_SHADER,H(r,h));if(n.attachShader(u,c),n.attachShader(u,p),n.bindAttribLocation(u,0,"a_position"),n.linkProgram(u),n.deleteShader(c),n.deleteShader(p),!n.getProgramParameter(u,n.LINK_STATUS)){let f=m(2);throw n.deleteProgram(u),f}if(this.vao=n.createVertexArray(),n.bindVertexArray(this.vao),this.buffer=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,this.buffer),n.bufferData(n.ARRAY_BUFFER,new Float32Array([-1,-1,3,-1,-1,3]),n.STATIC_DRAW),n.enableVertexAttribArray(0),n.vertexAttribPointer(0,2,n.FLOAT,!1,0,0),n.viewport(0,0,n.drawingBufferWidth,n.drawingBufferHeight),n.useProgram(u),this.canvas instanceof HTMLCanvasElement)this.resObserver=new MutationObserver(()=>this.syncRes()),this.resObserver.observe(this.canvas,{attributes:!0,attributeFilter:["width","height"]});else{let f=E=>{let b=Object.getOwnPropertyDescriptor(OffscreenCanvas.prototype,E),x=this.canvas;Object.defineProperty(x,E,{get:()=>b.get.call(x),set:d=>{b.set.call(x,d);let T=F.get(x);if(T)for(let _ of T.instances)_.syncRes()},configurable:b.configurable,enumerable:b.enumerable})};f("width"),f("height")}this.syncRes(),this.initializeUniform("u_cursor","float",this.cursorPos,{allowMissing:!0}),this.initializeUniform("u_click","float",[...this.clickPos,this.isClicked?1:0],{allowMissing:!0}),this.initializeUniform("u_time","float",0,{allowMissing:!0}),this.initializeUniform("u_frame","int",0,{allowMissing:!0}),this.initTex(g,this.canvas,{...this.texOptions}),this.intermediateFbo=n.createFramebuffer(),this.bindIntermediate(),n.bindFramebuffer(n.FRAMEBUFFER,null),this.historyDepth>0&&this.initTex(v,this.canvas,{history:this.historyDepth,...this.texOptions}),this.addListeners(),this.emit("_init")}resolveGLConst(r){let i=this.gl[r];if(i===void 0)throw m(3);return i}emit(r,...e){this.hooks.get(r)?.forEach(i=>i.call(this,...e))}on(r,e){this.hooks.has(r)||this.hooks.set(r,[]),this.hooks.get(r).push(e)}off(r,e){let i=this.hooks.get(r);if(i){let t=i.indexOf(e);t>=0&&i.splice(t,1)}}createShader(r,e){let i=this.gl,t=i.createShader(r);if(i.shaderSource(t,e),i.compileShader(t),!i.getShaderParameter(t,i.COMPILE_STATUS)){console.error(i.getShaderInfoLog(t));let s=m(4);throw i.deleteShader(t),s}return t}getCursorTgtRect(){let r=this.cursorTgt;return r===window?{left:0,top:0,width:window.innerWidth,height:window.innerHeight}:r.getBoundingClientRect()}addListeners(){if(!this.cursorTgt)return;let r=(i,t)=>{if(!this.uniforms.has("u_cursor"))return;let s=this.getCursorTgtRect(),a=(i-s.left)/s.width,n=1-(t-s.top)/s.height;this.cursorPos[0]=Math.max(0,Math.min(1,a)),this.cursorPos[1]=Math.max(0,Math.min(1,n)),this.updateUniforms({u_cursor:this.cursorPos})},e=(i,t,s)=>{if(this.uniforms.has("u_click")){if(this.isClicked=i,i){let a=this.getCursorTgtRect(),n=t,o=s;this.clickPos[0]=Math.max(0,Math.min(1,(n-a.left)/a.width)),this.clickPos[1]=Math.max(0,Math.min(1,1-(o-a.top)/a.height))}this.updateUniforms({u_click:[...this.clickPos,this.isClicked?1:0]})}};this.listeners.set("mousemove",i=>{let t=i;this.isTouch||r(t.clientX,t.clientY)}),this.listeners.set("mousedown",i=>{let t=i;this.isTouch||t.button===0&&(this.isClicked=!0,e(!0,t.clientX,t.clientY))}),this.listeners.set("mouseup",i=>{let t=i;this.isTouch||t.button===0&&e(!1)}),this.listeners.set("touchmove",i=>{let t=i;t.touches.length>0&&r(t.touches[0].clientX,t.touches[0].clientY)}),this.listeners.set("touchstart",i=>{let t=i;this.isTouch=!0,t.touches.length>0&&(r(t.touches[0].clientX,t.touches[0].clientY),e(!0,t.touches[0].clientX,t.touches[0].clientY))}),this.listeners.set("touchend",i=>{i.touches.length===0&&e(!1)}),this.listeners.forEach((i,t)=>{this.cursorTgt.addEventListener(t,i)})}syncRes(){let r=this.gl,e=[r.drawingBufferWidth,r.drawingBufferHeight];r.viewport(0,0,...e),this.uniforms.has("u_resolution")?this.updateUniforms({u_resolution:e}):this.initializeUniform("u_resolution","float",e,{allowMissing:!0}),this.resizeTex(g,...e),this.historyDepth>0&&this.resizeTex(v,...e),this.emit("updateResolution",...e)}resizeTex(r,e,i){let t=this.textures.get(r);if(!t||t.width===e&&t.height===i)return;this.gl.deleteTexture(t.texture),t.width=e,t.height=i;let{texture:a}=this.createTex(r,t);t.texture=a,this.resetHist(r,t)}reserveTex(r){let e=this.textures.get(r);if(e)return e.unitIndex;if(this.texPool.free.length>0)return this.texPool.free.pop();if(this.texPool.next>=this.texPool.max)throw m(5);return this.texPool.next++}resolveTexOpts(r){let{gl:e}=this,i=r?.internalFormat,t=r?.type??B(i)??"UNSIGNED_BYTE",s=this.resolveGLConst(t),a=i??this.typeFormats.get(s)??"RGBA8",n=/^(R|RG|RGB|RGBA)(8|16|32)(UI|I)$/.test(a),o=r?.format??(n?"RGBA_INTEGER":"RGBA"),h={type:s,format:this.resolveGLConst(o),internalFormat:this.resolveGLConst(a),minFilter:this.resolveGLConst(r?.minFilter??"LINEAR"),magFilter:this.resolveGLConst(r?.magFilter??"LINEAR"),wrapS:this.resolveGLConst(r?.wrapS??"CLAMP_TO_EDGE"),wrapT:this.resolveGLConst(r?.wrapT??"CLAMP_TO_EDGE"),colorSpace:r?.colorSpace,preserveY:r?.preserveY,isIntegerColorFormat:n};if((h.internalFormat===e.RGBA16F||h.internalFormat===e.RGBA32F)&&!e.getExtension("EXT_color_buffer_float"))throw m(6);return h}getPxArray(r,e){let i=this.typeArrays.get(r)??Uint8Array;return new i(e)}isRgba(r){let e=this.gl;return r===e.RGBA||r===e.RGBA_INTEGER}clearHistTexLayers(r){if(!r.history)return;let e=this.gl,{type:i,format:t}=r.options,s=this.getPxArray(i,r.width*r.height*4);e.activeTexture(e.TEXTURE0+r.unitIndex),e.bindTexture(e.TEXTURE_2D_ARRAY,r.texture);let a=!this.isRgba(t),n;a&&(n=e.getParameter(e.UNPACK_ALIGNMENT),e.pixelStorei(e.UNPACK_ALIGNMENT,1));for(let o=0;o<r.history.depth;++o)e.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,o,r.width,r.height,1,t,i,s);a&&e.pixelStorei(e.UNPACK_ALIGNMENT,n)}updateFrameOffset(r,e,i){this.updateUniforms({[`${P(r)}FrameOffset`]:e},i)}resetHist(r,e){e.history&&(e.history.writeIndex=0,this.clearHistTexLayers(e),this.updateFrameOffset(r,0,{allowMissing:!0}))}initializeUniform(r,e,i,t){let s=t?.arrayLength,a=t?.allowMissing??!1;if(this.uniforms.has(r))throw m(7);if(!N[e])throw m(8);if(s&&!(Array.isArray(i)&&i.length===s))throw m(9);let n=this.gl,o=n.getUniformLocation(this.program,r);if(!o&&s&&(o=n.getUniformLocation(this.program,`${r}[0]`)),!o){if(a)return;throw m(19)}let h=s?i[0]:i,u=Array.isArray(h)?h.length:1;this.uniforms.set(r,{type:e,length:u,location:o,arrayLength:s});try{this.updateUniforms({[r]:i})}catch(c){throw this.uniforms.delete(r),c}this.emit("initializeUniform",...arguments)}updateUniforms(r,e){let i=this.gl;i.useProgram(this.program),Object.entries(r).forEach(([t,s])=>{let a=this.uniforms.get(t);if(!a){if(e?.allowMissing)return;throw m(20)}let n=`uniform${a.length}${N[a.type]}`;if(a.arrayLength){if(!Array.isArray(s))throw m(10);let o=s.length;if(!o)return;if(o>a.arrayLength)throw m(11);if(s.some(p=>(Array.isArray(p)?p.length:1)!==a.length))throw m(12);let h=s.flat(),u=a.type==="float"?new Float32Array(h):a.type==="uint"?new Uint32Array(h):new Int32Array(h),c=a.location;if(e?.startIndex){let p=i.getUniformLocation(this.program,`${t}[${e.startIndex}]`);if(!p)throw m(13);c=p}i[n+"v"](c,u)}else{Array.isArray(s)||(s=[s]);let o=s;if(o.length!==a.length)throw m(14);i[n](a.location,...o)}}),this.emit("updateUniforms",...arguments)}createTex(r,e){let i=this.gl,{width:t,height:s}=e,a=e.history?.depth??0,n=i.createTexture();if(!n)throw m(15);let o=e.unitIndex;if(typeof o!="number")try{o=this.reserveTex(r)}catch(p){throw i.deleteTexture(n),p}let h=a>0,u=h?i.TEXTURE_2D_ARRAY:i.TEXTURE_2D,{options:c}=e;return i.activeTexture(i.TEXTURE0+o),i.bindTexture(u,n),i.texParameteri(u,i.TEXTURE_WRAP_S,c.wrapS),i.texParameteri(u,i.TEXTURE_WRAP_T,c.wrapT),i.texParameteri(u,i.TEXTURE_MIN_FILTER,c.minFilter),i.texParameteri(u,i.TEXTURE_MAG_FILTER,c.magFilter),h?i.texStorage3D(u,1,c.internalFormat,t,s,a):r===g&&i.texImage2D(i.TEXTURE_2D,0,c.internalFormat,t,s,0,c.format,c.type,null),{texture:n,unitIndex:o}}initTex(r,e,i){let t=this.gl;if(this.textures.has(r))throw m(16);let{history:s=0,...a}=i??{},{width:n,height:o}=O(e);if(!n||!o)throw m(17);let h={width:n,height:o,options:e instanceof l&&Object.keys(a).length===0&&e.textures.has(g)?e.textures.get(g).options:this.resolveTexOpts(a)};s>0&&(h.history={depth:s,writeIndex:0});let{texture:u,unitIndex:c}=this.createTex(r,h),p={texture:u,unitIndex:c,...h};s>0&&(this.initializeUniform(`${P(r)}FrameOffset`,"int",0,{allowMissing:!0}),this.clearHistTexLayers(p)),this.textures.set(r,p),r!==g&&r!==v&&this.updateTex(r,e),t.useProgram(this.program);let f=t.getUniformLocation(this.program,P(r));f&&t.uniform1i(f,c)}initializeTexture(r,e,i){let t=i?.history!=null&&i.history>0?{...i,history:i.history+1}:i;this.initTex(r,e,t),this.emit("initializeTexture",...arguments)}updateTextures(r){Object.entries(r).forEach(([e,i])=>{this.updateTex(e,i)}),this.emit("updateTextures",...arguments)}updateTex(r,e,i){let t=this.gl,s=this.textures.get(r);if(!s)throw m(18);if(e instanceof WebGLTexture){t.activeTexture(t.TEXTURE0+s.unitIndex),t.bindTexture(t.TEXTURE_2D,e);return}let a=e;if(e instanceof l){let d=e.textures.get(g),T=d.width,_=d.height;if(e.gl===t){if(!s.history){t.activeTexture(t.TEXTURE0+s.unitIndex),t.bindTexture(t.TEXTURE_2D,d.texture);return}let{depth:w}=s.history,D=i===void 0?[s.history.writeIndex]:Array.isArray(i)?i.map(U=>S(U,w)):[S(i,w)];t.activeTexture(t.TEXTURE0+s.unitIndex),t.bindTexture(t.TEXTURE_2D_ARRAY,s.texture),t.bindFramebuffer(t.READ_FRAMEBUFFER,e.intermediateFbo);for(let U of D)t.copyTexSubImage3D(t.TEXTURE_2D_ARRAY,0,0,0,U,0,0,T,_);t.bindFramebuffer(t.READ_FRAMEBUFFER,null),this.updateFrameOffset(r,D[D.length-1],{allowMissing:!0}),i===void 0&&(s.history.writeIndex=(s.history.writeIndex+1)%w);return}let{width:y,height:R,options:{format:L,type:A}}=d,G=this.getPxArray(A,y*R*4);e.gl.bindFramebuffer(e.gl.FRAMEBUFFER,e.intermediateFbo),e.gl.readPixels(0,0,y,R,L,A,G),e.gl.bindFramebuffer(e.gl.FRAMEBUFFER,null),a={data:G,width:y,height:R}}let{width:n,height:o}=O(a);if(!n||!o)return;let h="isPartial"in a&&a.isPartial;h||this.resizeTex(r,n,o);let u="data"in a&&a.data,c=!u&&!s.options?.preserveY,p=t.getParameter(t.UNPACK_FLIP_Y_WEBGL),f=u&&!this.isRgba(s.options.format),E=!u&&s.options.colorSpace&&"unpackColorSpace"in t,b=t.unpackColorSpace,x;if(f&&(x=t.getParameter(t.UNPACK_ALIGNMENT),t.pixelStorei(t.UNPACK_ALIGNMENT,1)),E&&(t.unpackColorSpace=s.options.colorSpace),s.history){t.activeTexture(t.TEXTURE0+s.unitIndex),t.bindTexture(t.TEXTURE_2D_ARRAY,s.texture);let{depth:d}=s.history,T=i===void 0?[s.history.writeIndex]:Array.isArray(i)?i.map(A=>S(A,d)):[S(i,d)];t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,c);let _=a,y=_.data??a,R=h?_.x??0:0,L=h?_.y??0:0;for(let A of T)t.texSubImage3D(t.TEXTURE_2D_ARRAY,0,R,L,A,n,o,1,s.options.format,s.options.type,y);t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,p),this.updateFrameOffset(r,T[T.length-1]),i===void 0&&(s.history.writeIndex=(s.history.writeIndex+1)%d)}else{if(t.activeTexture(t.TEXTURE0+s.unitIndex),t.bindTexture(t.TEXTURE_2D,s.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,c),h){let d=a;t.texSubImage2D(t.TEXTURE_2D,0,d.x??0,d.y??0,n,o,s.options.format,s.options.type,d.data)}else t.texImage2D(t.TEXTURE_2D,0,s.options.internalFormat,n,o,0,s.options.format,s.options.type,a.data??a);t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,p)}E&&(t.unpackColorSpace=b),f&&t.pixelStorei(t.UNPACK_ALIGNMENT,x)}bindIntermediate(){let r=this.gl,e=this.textures.get(g);r.bindFramebuffer(r.FRAMEBUFFER,this.intermediateFbo),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,e.texture,0)}clear(){this.bindIntermediate();let r=this.gl,e=this.textures.get(g);if(e.options.isIntegerColorFormat){let i=e.options.type;this.uintTypes.has(i)?r.clearBufferuiv(r.COLOR,0,new Uint32Array(4)):r.clearBufferiv(r.COLOR,0,new Int32Array(4))}else r.clear(r.COLOR_BUFFER_BIT)}draw(r){this.emit("preDraw",...arguments);let e=this.gl,i=e.drawingBufferWidth,t=e.drawingBufferHeight;r?.skipClear?this.bindIntermediate():this.clear(),e.useProgram(this.program),e.bindVertexArray(this.vao),e.viewport(0,0,i,t),e.drawArrays(e.TRIANGLES,0,3),this.isHeadless||this.textures.get(g).options.isIntegerColorFormat||(e.bindFramebuffer(e.READ_FRAMEBUFFER,this.intermediateFbo),e.bindFramebuffer(e.DRAW_FRAMEBUFFER,null),e.blitFramebuffer(0,0,i,t,0,0,i,t,e.COLOR_BUFFER_BIT,e.NEAREST),e.bindFramebuffer(e.FRAMEBUFFER,null)),this.emit("postDraw",...arguments)}step(r){this._step(performance.now(),r)}tick(){let r={};this.uniforms.has("u_time")&&(r.u_time=this.tElapsed),this.uniforms.has("u_frame")&&(r.u_frame=this.frame),Object.keys(r).length&&this.updateUniforms(r)}_step(r,e){let i=this.getElapsed(r);this.tElapsed=i,this.tStart=r;let t=typeof e=="function"?e(i,this.frame):e;this.emit("preStep",i,this.frame,t),this.tick(),this.draw(t);let s=this.textures.get(v);if(s&&!t?.skipHistory){let{writeIndex:a,depth:n}=s.history,o=this.gl;o.bindFramebuffer(o.READ_FRAMEBUFFER,this.intermediateFbo),o.bindTexture(o.TEXTURE_2D_ARRAY,s.texture),o.copyTexSubImage3D(o.TEXTURE_2D_ARRAY,0,0,0,a,0,0,o.drawingBufferWidth,o.drawingBufferHeight),o.bindFramebuffer(o.READ_FRAMEBUFFER,null);let h=(a+1)%n;this.updateFrameOffset(v,h,{allowMissing:!0}),s.history.writeIndex=h}++this.frame,this.emit("postStep",i,this.frame,t)}play(r){this._pause();let e=i=>{this._step(i,r),this.frameId!=null&&(this.frameId=requestAnimationFrame(e))};this.frameId=requestAnimationFrame(e),this.emit("play")}getElapsed(r){return isNaN(this.tStart)?this.tElapsed:this.tElapsed+(r-this.tStart)/1e3}_pause(){if(!(isNaN(this.tStart)&&this.frameId==null))return this.frameId!=null&&(cancelAnimationFrame(this.frameId),this.frameId=null),this.tElapsed=this.getElapsed(performance.now()),this.tStart=NaN,!0}pause(){this._pause()&&this.emit("pause")}rewind(){this.frame=0,this.tElapsed=0,this.tStart=NaN,this.tick()}reset(){this.rewind(),this.textures.forEach((r,e)=>{this.resetHist(e,r)}),this.clear(),this.emit("reset")}destroy(){this.emit("destroy"),this._pause();let r=this.gl;this.cursorTgt&&(this.listeners.forEach((i,t)=>{this.cursorTgt.removeEventListener(t,i)}),this.listeners.clear()),this.resObserver&&(this.resObserver.disconnect(),this.resObserver=null),this.program&&(r.deleteProgram(this.program),this.program=null),this.intermediateFbo&&(r.deleteFramebuffer(this.intermediateFbo),this.intermediateFbo=null),this.textures.forEach(i=>{this.texPool.free.push(i.unitIndex),r.deleteTexture(i.texture)}),this.textures.clear();let e=F.get(this.canvas);e&&(e.instances.delete(this),e.instances.size===0&&F.delete(this.canvas)),this.vao&&(r.deleteVertexArray(this.vao),this.vao=null),this.buffer&&(r.deleteBuffer(this.buffer),this.buffer=null),this.uniforms.clear(),this.hooks.clear()}},Y=I;export{Y as a};
5
+ //# sourceMappingURL=chunk-4UKNQUGK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { safeMod, spError } from './internal/util';\n\nconst DEFAULT_VERTEX_SHADER_SRC = `#version 300 es\nin vec2 a_position;out vec2 v_uv;void main(){gl_Position=vec4(a_position,0.,1.);v_uv=a_position*.5+.5;}`;\n\ninterface Uniform {\n\ttype: 'float' | 'int' | 'uint';\n\tlength: 1 | 2 | 3 | 4;\n\tlocation: WebGLUniformLocation;\n\tarrayLength?: number;\n}\n\ntype GLInternalFormatChannels = 'R' | 'RG' | 'RGB' | 'RGBA';\ntype GLInternalFormatDepth = '8' | '16F' | '32F' | '8UI' | '8I' | '16UI' | '16I' | '32UI' | '32I';\nexport type GLInternalFormatString = `${GLInternalFormatChannels}${GLInternalFormatDepth}`;\n\nexport type GLFormatString =\n\t| 'RED'\n\t| 'RG'\n\t| 'RGB'\n\t| 'RGBA'\n\t| 'RED_INTEGER'\n\t| 'RG_INTEGER'\n\t| 'RGB_INTEGER'\n\t| 'RGBA_INTEGER';\nexport type GLTypeString =\n\t| 'UNSIGNED_BYTE'\n\t| 'BYTE'\n\t| 'FLOAT'\n\t| 'HALF_FLOAT'\n\t| 'UNSIGNED_SHORT'\n\t| 'SHORT'\n\t| 'UNSIGNED_INT'\n\t| 'INT';\nexport type GLFilterString = 'LINEAR' | 'NEAREST';\nexport type GLWrapString = 'CLAMP_TO_EDGE' | 'REPEAT' | 'MIRRORED_REPEAT';\nexport type ColorSpace = PredefinedColorSpace;\n\nconst FORMAT_TYPE_SUFFIXES: [string, GLTypeString][] = [\n\t['8UI', 'UNSIGNED_BYTE'],\n\t['8I', 'BYTE'],\n\t['16UI', 'UNSIGNED_SHORT'],\n\t['16I', 'SHORT'],\n\t['16F', 'HALF_FLOAT'],\n\t['32UI', 'UNSIGNED_INT'],\n\t['32I', 'INT'],\n\t['32F', 'FLOAT'],\n\t['8', 'UNSIGNED_BYTE'],\n];\n\nconst UNIFORM_TYPE_SUFFIXES: Record<Uniform['type'], string> = {\n\tfloat: 'f',\n\tint: 'i',\n\tuint: 'ui',\n};\n\nfunction typeFromInternalFormatString(internalFormatString?: GLInternalFormatString): GLTypeString | undefined {\n\treturn internalFormatString && FORMAT_TYPE_SUFFIXES.find(([suffix]) => internalFormatString.endsWith(suffix))?.[1];\n}\n\ntype GLConstantString = GLInternalFormatString | GLFormatString | GLTypeString | GLFilterString | GLWrapString;\n\nexport interface TextureOptions {\n\tinternalFormat?: GLInternalFormatString;\n\tformat?: GLFormatString;\n\ttype?: GLTypeString;\n\tminFilter?: GLFilterString;\n\tmagFilter?: GLFilterString;\n\twrapS?: GLWrapString;\n\twrapT?: GLWrapString;\n\tcolorSpace?: ColorSpace;\n\tpreserveY?: boolean;\n}\ntype ResolvedTextureOptions = {\n\ttype: number;\n\tformat: number;\n\tinternalFormat: number;\n\tminFilter: number;\n\tmagFilter: number;\n\twrapS: number;\n\twrapT: number;\n\tcolorSpace?: ColorSpace;\n\tpreserveY?: boolean;\n\tisIntegerColorFormat: boolean;\n};\n\ninterface Texture {\n\ttexture: WebGLTexture;\n\tunitIndex: number;\n\twidth: number;\n\theight: number;\n\thistory?: {\n\t\tdepth: number;\n\t\twriteIndex: number;\n\t};\n\toptions: ResolvedTextureOptions;\n}\n\nexport interface CustomTexture {\n\tdata: ArrayBufferView | null;\n\twidth: number;\n\theight: number;\n}\n\nexport interface PartialCustomTexture extends CustomTexture {\n\tisPartial?: boolean;\n\tx?: number;\n\ty?: number;\n}\n\nexport interface InitializeTextureOptions extends TextureOptions {\n\thistory?: number;\n}\n\nexport type TextureSource =\n\t| HTMLImageElement\n\t| HTMLVideoElement\n\t| HTMLCanvasElement\n\t| OffscreenCanvas\n\t| ImageBitmap\n\t| WebGLTexture\n\t| CustomTexture\n\t| ShaderPad;\n\n// Custom textures allow partial updates starting from (x, y).\nexport type UpdateTextureSource = Exclude<TextureSource, CustomTexture> | PartialCustomTexture;\n\nexport interface PluginContext {\n\tinjectGLSL: (code: string) => void;\n\temit: (name: ShaderPadEventName, ...args: any[]) => void;\n\tupdateTexture: (name: string, source: UpdateTextureSource, historySlots?: HistorySlots) => void;\n}\n\nexport type Plugin = (shaderPad: ShaderPad, context: PluginContext) => void;\n\nexport type ShaderPadEventName =\n\t| '_init'\n\t| 'initializeTexture'\n\t| 'initializeUniform'\n\t| 'updateTextures'\n\t| 'updateUniforms'\n\t| 'preStep'\n\t| 'postStep'\n\t| 'preDraw'\n\t| 'postDraw'\n\t| 'updateResolution'\n\t| 'play'\n\t| 'pause'\n\t| 'reset'\n\t| 'destroy'\n\t| `${string}:${string}`;\n\nexport type RenderTextureOptions = Omit<TextureOptions, 'preserveY'>;\n\nexport interface Options extends RenderTextureOptions {\n\tcanvas?: HTMLCanvasElement | OffscreenCanvas | { width: number; height: number } | null;\n\tplugins?: Plugin[];\n\thistory?: number;\n\tcursorTarget?: Window | Element;\n}\n\nexport interface StepOptions {\n\tskipClear?: boolean;\n\tskipHistory?: boolean;\n}\n\ntype HistorySlots = number | number[];\n\ntype TextureUnitPool = {\n\tfree: number[];\n\tnext: number;\n\tmax: number;\n};\n\nconst HISTORY_TEXTURE_KEY = Symbol('u_history');\nconst INTERMEDIATE_TEXTURE_KEY = Symbol('__SHADERPAD_BUFFER');\n\nconst canvasRegistry = new WeakMap<\n\tHTMLCanvasElement | OffscreenCanvas,\n\t{ texPool: TextureUnitPool; instances: Set<ShaderPad> }\n>();\n\nfunction combineShaderCode(shader: string, injections: string[]): string {\n\tif (!injections?.length) return shader;\n\tconst lines = shader.split('\\n');\n\tconst insertAt =\n\t\tlines.findLastIndex(line => {\n\t\t\tconst trimmed = line.trimStart();\n\t\t\treturn trimmed.startsWith('precision ') || trimmed.startsWith('#version ');\n\t\t}) + 1;\n\tlines.splice(insertAt, 0, ...injections);\n\treturn lines.join('\\n');\n}\n\nfunction getSourceDimensions(source: TextureSource): {\n\twidth: number;\n\theight: number;\n} {\n\tif (source instanceof WebGLTexture) {\n\t\treturn { width: 0, height: 0 }; // Invalid - dimensions not readable.\n\t}\n\tif (source instanceof ShaderPad) {\n\t\treturn { width: source.canvas.width, height: source.canvas.height };\n\t}\n\tif (source instanceof HTMLVideoElement) {\n\t\treturn { width: source.videoWidth, height: source.videoHeight };\n\t}\n\tif (source instanceof HTMLImageElement) {\n\t\treturn {\n\t\t\twidth: source.naturalWidth ?? source.width,\n\t\t\theight: source.naturalHeight ?? source.height,\n\t\t};\n\t}\n\t// CustomTexture, HTMLCanvasElement, OffscreenCanvas, ImageBitmap.\n\treturn { width: source.width, height: source.height };\n}\n\nfunction stringFrom(name: string | symbol) {\n\treturn typeof name === 'symbol' ? (name.description ?? '') : name;\n}\n\nclass ShaderPad {\n\tprivate isHeadless = false;\n\tprivate isTouch = false;\n\tdeclare public readonly gl: WebGL2RenderingContext;\n\tdeclare private typeArrays: Map<number, new (length: number) => ArrayBufferView>;\n\tdeclare private typeFormats: Map<number, GLInternalFormatString>;\n\tdeclare private uintTypes: Set<number>;\n\tprivate uniforms: Map<string, Uniform> = new Map();\n\tprivate textures: Map<string | symbol, Texture> = new Map();\n\tdeclare private texPool: TextureUnitPool;\n\tprivate buffer: WebGLBuffer | null = null;\n\tprivate vao: WebGLVertexArrayObject | null = null;\n\tprivate program: WebGLProgram | null = null;\n\tdeclare private frameId: number | null;\n\tprivate listeners: Map<string, EventListener> = new Map();\n\tprivate frame = 0;\n\tprivate tElapsed = 0;\n\tprivate tStart = NaN;\n\tprivate cursorPos = [0.5, 0.5];\n\tprivate clickPos = [0.5, 0.5];\n\tprivate isClicked = false;\n\tdeclare public canvas: HTMLCanvasElement | OffscreenCanvas;\n\tprivate resObserver: MutationObserver | null = null;\n\tprivate hooks: Map<ShaderPadEventName, Function[]> = new Map();\n\tprivate historyDepth = 0;\n\tdeclare private texOptions: TextureOptions;\n\tdeclare private cursorTgt: Window | Element | undefined;\n\t// WebGL can’t read from and write to the history texture at the same time.\n\t// We write to an intermediate texture then blit to the history texture.\n\tprivate intermediateFbo: WebGLFramebuffer | null = null;\n\n\tconstructor(fragmentShaderSrc: string, { canvas, plugins, history, cursorTarget, ...texOptions }: Options = {}) {\n\t\tif (canvas && 'getContext' in canvas) {\n\t\t\tthis.canvas = canvas;\n\t\t} else {\n\t\t\tconst { width = 1, height = 1 } = canvas || {};\n\t\t\tthis.canvas = new OffscreenCanvas(width, height);\n\t\t\tthis.isHeadless = true;\n\t\t}\n\n\t\tconst gl = this.canvas.getContext('webgl2', {\n\t\t\tantialias: false,\n\t\t}) as WebGL2RenderingContext;\n\t\tif (!gl) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(0, {\n\t\t\t\t\t\tcanvasType: this.canvas.constructor.name,\n\t\t\t\t\t\tisHeadless: this.isHeadless,\n\t\t\t\t\t\tcanvasWidth: this.canvas.width,\n\t\t\t\t\t\tcanvasHeight: this.canvas.height,\n\t\t\t\t\t})\n\t\t\t\t: spError(0);\n\t\t}\n\t\tif (texOptions.colorSpace && 'drawingBufferColorSpace' in gl) {\n\t\t\tgl.drawingBufferColorSpace = texOptions.colorSpace;\n\t\t}\n\t\tthis.gl = gl;\n\t\tthis.typeArrays = new Map<number, new (length: number) => ArrayBufferView>([\n\t\t\t[gl.FLOAT, Float32Array],\n\t\t\t[gl.HALF_FLOAT, Uint16Array],\n\t\t\t[gl.UNSIGNED_SHORT, Uint16Array],\n\t\t\t[gl.SHORT, Int16Array],\n\t\t\t[gl.BYTE, Int8Array],\n\t\t\t[gl.UNSIGNED_INT, Uint32Array],\n\t\t\t[gl.INT, Int32Array],\n\t\t]);\n\t\tthis.typeFormats = new Map<number, GLInternalFormatString>([\n\t\t\t[gl.FLOAT, 'RGBA32F'],\n\t\t\t[gl.HALF_FLOAT, 'RGBA16F'],\n\t\t\t[gl.UNSIGNED_SHORT, 'RGBA32UI'],\n\t\t\t[gl.SHORT, 'RGBA32I'],\n\t\t\t[gl.BYTE, 'RGBA32I'],\n\t\t\t[gl.UNSIGNED_INT, 'RGBA32UI'],\n\t\t\t[gl.INT, 'RGBA32I'],\n\t\t]);\n\t\tthis.uintTypes = new Set([gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT, gl.UNSIGNED_INT]);\n\n\t\tlet registryEntry = canvasRegistry.get(this.canvas);\n\t\tif (!registryEntry) {\n\t\t\tregistryEntry = {\n\t\t\t\ttexPool: {\n\t\t\t\t\tfree: [],\n\t\t\t\t\tnext: 0,\n\t\t\t\t\tmax: gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS),\n\t\t\t\t},\n\t\t\t\tinstances: new Set([this]),\n\t\t\t};\n\t\t\tcanvasRegistry.set(this.canvas, registryEntry);\n\t\t}\n\t\tthis.texPool = registryEntry.texPool;\n\t\tregistryEntry.instances.add(this);\n\n\t\tthis.texOptions = texOptions;\n\n\t\tif (history) this.historyDepth = history;\n\t\tthis.cursorTgt = cursorTarget ?? (this.canvas instanceof HTMLCanvasElement ? this.canvas : undefined);\n\t\tthis.frameId = null;\n\n\t\tconst glslInjections: string[] = [];\n\t\tif (plugins) {\n\t\t\tplugins.forEach(plugin =>\n\t\t\t\tplugin(this, {\n\t\t\t\t\tinjectGLSL: (code: string) => {\n\t\t\t\t\t\tglslInjections.push(code);\n\t\t\t\t\t},\n\t\t\t\t\temit: this.emit.bind(this),\n\t\t\t\t\tupdateTexture: this.updateTex.bind(this),\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst program = gl.createProgram();\n\t\tif (!program) {\n\t\t\tthrow spError(1);\n\t\t}\n\t\tthis.program = program;\n\n\t\tconst vertexShader = this.createShader(gl.VERTEX_SHADER, DEFAULT_VERTEX_SHADER_SRC);\n\t\tconst fragmentShader = this.createShader(\n\t\t\tgl.FRAGMENT_SHADER,\n\t\t\tcombineShaderCode(fragmentShaderSrc, glslInjections),\n\t\t);\n\t\tgl.attachShader(program, vertexShader);\n\t\tgl.attachShader(program, fragmentShader);\n\t\tgl.bindAttribLocation(program, 0, 'a_position');\n\t\tgl.linkProgram(program);\n\t\tgl.deleteShader(vertexShader);\n\t\tgl.deleteShader(fragmentShader);\n\n\t\tif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n\t\t\tconst linkError = __SHADERPAD_DEV__\n\t\t\t\t? spError(2, {\n\t\t\t\t\t\tprogramInfoLog: gl.getProgramInfoLog(program),\n\t\t\t\t\t\tfragmentShaderLength: fragmentShaderSrc.length,\n\t\t\t\t\t\tglslInjectionCount: glslInjections.length,\n\t\t\t\t\t})\n\t\t\t\t: spError(2);\n\t\t\tgl.deleteProgram(program);\n\t\t\tthrow linkError;\n\t\t}\n\n\t\tthis.vao = gl.createVertexArray();\n\t\tgl.bindVertexArray(this.vao);\n\t\tthis.buffer = gl.createBuffer();\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n\t\tgl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW);\n\t\tgl.enableVertexAttribArray(0);\n\t\tgl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);\n\n\t\tgl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\n\t\tgl.useProgram(program);\n\n\t\tif (this.canvas instanceof HTMLCanvasElement) {\n\t\t\tthis.resObserver = new MutationObserver(() => this.syncRes());\n\t\t\tthis.resObserver.observe(this.canvas, {\n\t\t\t\tattributes: true,\n\t\t\t\tattributeFilter: ['width', 'height'],\n\t\t\t});\n\t\t} else {\n\t\t\tconst wrapDimension = (dimension: 'width' | 'height') => {\n\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(OffscreenCanvas.prototype, dimension)!;\n\t\t\t\tconst canvas = this.canvas;\n\t\t\t\tObject.defineProperty(canvas, dimension, {\n\t\t\t\t\tget: () => descriptor.get!.call(canvas),\n\t\t\t\t\tset: v => {\n\t\t\t\t\t\tdescriptor.set!.call(canvas, v);\n\t\t\t\t\t\tconst entry = canvasRegistry.get(canvas);\n\t\t\t\t\t\tif (entry) {\n\t\t\t\t\t\t\tfor (const instance of entry.instances) {\n\t\t\t\t\t\t\t\tinstance.syncRes();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tconfigurable: descriptor.configurable,\n\t\t\t\t\tenumerable: descriptor.enumerable,\n\t\t\t\t});\n\t\t\t};\n\t\t\twrapDimension('width');\n\t\t\twrapDimension('height');\n\t\t}\n\t\tthis.syncRes();\n\n\t\tthis.initializeUniform('u_cursor', 'float', this.cursorPos, { allowMissing: true });\n\t\tthis.initializeUniform('u_click', 'float', [...this.clickPos, this.isClicked ? 1.0 : 0.0], {\n\t\t\tallowMissing: true,\n\t\t});\n\t\tthis.initializeUniform('u_time', 'float', 0, { allowMissing: true });\n\t\tthis.initializeUniform('u_frame', 'int', 0, { allowMissing: true });\n\n\t\tthis.initTex(INTERMEDIATE_TEXTURE_KEY, this.canvas, {\n\t\t\t...this.texOptions,\n\t\t});\n\t\tthis.intermediateFbo = gl.createFramebuffer();\n\t\tthis.bindIntermediate();\n\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n\t\tif (this.historyDepth > 0) {\n\t\t\tthis.initTex(HISTORY_TEXTURE_KEY, this.canvas, {\n\t\t\t\thistory: this.historyDepth,\n\t\t\t\t...this.texOptions,\n\t\t\t});\n\t\t}\n\t\tthis.addListeners();\n\t\tthis.emit('_init');\n\t}\n\n\tprivate resolveGLConst(value: GLConstantString): number {\n\t\tconst gl = this.gl;\n\t\tconst resolved = gl[value];\n\t\tif (resolved === undefined) {\n\t\t\tthrow __SHADERPAD_DEV__ ? spError(3, { value }) : spError(3);\n\t\t}\n\t\treturn resolved;\n\t}\n\n\tprivate emit(name: ShaderPadEventName, ...args: any[]) {\n\t\tthis.hooks.get(name)?.forEach(hook => hook.call(this, ...args));\n\t}\n\n\ton(name: ShaderPadEventName, fn: Function) {\n\t\tif (!this.hooks.has(name)) {\n\t\t\tthis.hooks.set(name, []);\n\t\t}\n\t\tthis.hooks.get(name)!.push(fn);\n\t}\n\n\toff(name: ShaderPadEventName, fn: Function) {\n\t\tconst hooks = this.hooks.get(name);\n\t\tif (hooks) {\n\t\t\tconst index = hooks.indexOf(fn);\n\t\t\tif (index >= 0) {\n\t\t\t\thooks.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate createShader(type: number, source: string): WebGLShader {\n\t\tconst gl = this.gl;\n\t\tconst shader = gl.createShader(type)!;\n\t\tgl.shaderSource(shader, source);\n\t\tgl.compileShader(shader);\n\t\tif (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n\t\t\tconsole.error(gl.getShaderInfoLog(shader));\n\t\t\tconst compilationError = __SHADERPAD_DEV__\n\t\t\t\t? spError(4, {\n\t\t\t\t\t\tshaderType: type === gl.VERTEX_SHADER ? 'vertex' : 'fragment',\n\t\t\t\t\t\tsource,\n\t\t\t\t\t})\n\t\t\t\t: spError(4);\n\t\t\tgl.deleteShader(shader);\n\t\t\tthrow compilationError;\n\t\t}\n\t\treturn shader;\n\t}\n\n\tprivate getCursorTgtRect(): {\n\t\tleft: number;\n\t\ttop: number;\n\t\twidth: number;\n\t\theight: number;\n\t} {\n\t\tconst target = this.cursorTgt!;\n\t\tif (target === window) {\n\t\t\treturn {\n\t\t\t\tleft: 0,\n\t\t\t\ttop: 0,\n\t\t\t\twidth: window.innerWidth,\n\t\t\t\theight: window.innerHeight,\n\t\t\t};\n\t\t}\n\t\treturn (target as Element).getBoundingClientRect();\n\t}\n\n\tprivate addListeners() {\n\t\tif (!this.cursorTgt) return;\n\t\tconst updateCursor = (x: number, y: number) => {\n\t\t\tif (!this.uniforms.has('u_cursor')) return;\n\t\t\tconst rect = this.getCursorTgtRect();\n\t\t\tconst u = (x - rect.left) / rect.width;\n\t\t\tconst v = 1 - (y - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\tthis.cursorPos[0] = Math.max(0, Math.min(1, u));\n\t\t\tthis.cursorPos[1] = Math.max(0, Math.min(1, v));\n\t\t\tthis.updateUniforms({ u_cursor: this.cursorPos });\n\t\t};\n\n\t\tconst updateClick = (isClicked: boolean, x?: number, y?: number) => {\n\t\t\tif (!this.uniforms.has('u_click')) return;\n\t\t\tthis.isClicked = isClicked;\n\t\t\tif (isClicked) {\n\t\t\t\tconst rect = this.getCursorTgtRect();\n\t\t\t\tconst xVal = x as number;\n\t\t\t\tconst yVal = y as number;\n\t\t\t\tthis.clickPos[0] = Math.max(0, Math.min(1, (xVal - rect.left) / rect.width));\n\t\t\t\tthis.clickPos[1] = Math.max(0, Math.min(1, 1 - (yVal - rect.top) / rect.height)); // Flip Y for WebGL\n\t\t\t}\n\t\t\tthis.updateUniforms({\n\t\t\t\tu_click: [...this.clickPos, this.isClicked ? 1.0 : 0.0],\n\t\t\t});\n\t\t};\n\n\t\tthis.listeners.set('mousemove', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouch) {\n\t\t\t\tupdateCursor(mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.listeners.set('mousedown', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouch) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tthis.isClicked = true;\n\t\t\t\t\tupdateClick(true, mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.listeners.set('mouseup', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouch) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tupdateClick(false);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.listeners.set('touchmove', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.listeners.set('touchstart', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tthis.isTouch = true;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t\tupdateClick(true, touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.listeners.set('touchend', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length === 0) {\n\t\t\t\tupdateClick(false);\n\t\t\t}\n\t\t});\n\n\t\tthis.listeners.forEach((listener, event) => {\n\t\t\tthis.cursorTgt!.addEventListener(event, listener);\n\t\t});\n\t}\n\n\tprivate syncRes() {\n\t\tconst gl = this.gl;\n\t\tconst resolution: [number, number] = [gl.drawingBufferWidth, gl.drawingBufferHeight];\n\t\tgl.viewport(0, 0, ...resolution);\n\t\tif (this.uniforms.has('u_resolution')) {\n\t\t\tthis.updateUniforms({ u_resolution: resolution });\n\t\t} else {\n\t\t\tthis.initializeUniform('u_resolution', 'float', resolution, { allowMissing: true });\n\t\t}\n\t\tthis.resizeTex(INTERMEDIATE_TEXTURE_KEY, ...resolution);\n\t\tif (this.historyDepth > 0) {\n\t\t\tthis.resizeTex(HISTORY_TEXTURE_KEY, ...resolution);\n\t\t}\n\t\tthis.emit('updateResolution', ...resolution);\n\t}\n\n\tprivate resizeTex(name: string | symbol, width: number, height: number) {\n\t\tconst info = this.textures.get(name);\n\t\tif (!info || (info.width === width && info.height === height)) return;\n\n\t\tconst gl = this.gl;\n\t\tgl.deleteTexture(info.texture);\n\t\tinfo.width = width;\n\t\tinfo.height = height;\n\t\tconst { texture } = this.createTex(name, info);\n\t\tinfo.texture = texture;\n\t\tthis.resetHist(name, info);\n\t}\n\n\tprivate reserveTex(name: string | symbol) {\n\t\tconst existing = this.textures.get(name);\n\t\tif (existing) return existing.unitIndex;\n\t\tif (this.texPool.free.length > 0) return this.texPool.free.pop()!;\n\t\tif (this.texPool.next >= this.texPool.max) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(5, {\n\t\t\t\t\t\tname: stringFrom(name),\n\t\t\t\t\t\tnextTextureUnit: this.texPool.next,\n\t\t\t\t\t\tmaxTextureUnits: this.texPool.max,\n\t\t\t\t\t\tfreeTextureUnits: this.texPool.free.length,\n\t\t\t\t\t})\n\t\t\t\t: spError(5);\n\t\t}\n\t\treturn this.texPool.next++;\n\t}\n\n\tprivate resolveTexOpts(options?: TextureOptions): ResolvedTextureOptions {\n\t\tconst { gl } = this;\n\t\tconst internalFormatOption = options?.internalFormat;\n\t\tconst typeString = options?.type ?? typeFromInternalFormatString(internalFormatOption) ?? 'UNSIGNED_BYTE';\n\t\tconst type = this.resolveGLConst(typeString);\n\t\tconst internalFormatString = internalFormatOption ?? this.typeFormats.get(type) ?? 'RGBA8';\n\t\tconst isIntegerColorFormat = /^(R|RG|RGB|RGBA)(8|16|32)(UI|I)$/.test(internalFormatString);\n\t\tconst formatString = options?.format ?? (isIntegerColorFormat ? 'RGBA_INTEGER' : 'RGBA');\n\t\tconst result: ResolvedTextureOptions = {\n\t\t\ttype,\n\t\t\tformat: this.resolveGLConst(formatString),\n\t\t\tinternalFormat: this.resolveGLConst(internalFormatString),\n\t\t\tminFilter: this.resolveGLConst(options?.minFilter ?? 'LINEAR'),\n\t\t\tmagFilter: this.resolveGLConst(options?.magFilter ?? 'LINEAR'),\n\t\t\twrapS: this.resolveGLConst(options?.wrapS ?? 'CLAMP_TO_EDGE'),\n\t\t\twrapT: this.resolveGLConst(options?.wrapT ?? 'CLAMP_TO_EDGE'),\n\t\t\tcolorSpace: options?.colorSpace,\n\t\t\tpreserveY: options?.preserveY,\n\t\t\tisIntegerColorFormat,\n\t\t};\n\t\tconst isFloatColorFormat = result.internalFormat === gl.RGBA16F || result.internalFormat === gl.RGBA32F;\n\t\t// gl.getExtension isn’t just a check, it’s a required side-effect to enable floats.\n\t\tif (isFloatColorFormat && !gl.getExtension('EXT_color_buffer_float')) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(6, {\n\t\t\t\t\t\tinternalFormat: internalFormatString,\n\t\t\t\t\t\ttype: typeString,\n\t\t\t\t\t})\n\t\t\t\t: spError(6);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate getPxArray(type: number, size: number): ArrayBufferView {\n\t\tconst ArrayType = this.typeArrays.get(type) ?? Uint8Array;\n\t\treturn new ArrayType(size);\n\t}\n\n\tprivate isRgba(format: number): boolean {\n\t\tconst gl = this.gl;\n\t\treturn format === gl.RGBA || format === gl.RGBA_INTEGER;\n\t}\n\n\tprivate clearHistTexLayers(textureInfo: Texture): void {\n\t\tif (!textureInfo.history) return;\n\n\t\tconst gl = this.gl;\n\t\tconst { type, format } = textureInfo.options;\n\t\tconst transparent = this.getPxArray(type, textureInfo.width * textureInfo.height * 4);\n\t\tgl.activeTexture(gl.TEXTURE0 + textureInfo.unitIndex);\n\t\tgl.bindTexture(gl.TEXTURE_2D_ARRAY, textureInfo.texture);\n\t\tconst needsAlignmentFix = !this.isRgba(format);\n\t\tlet previousAlignment;\n\t\tif (needsAlignmentFix) {\n\t\t\tpreviousAlignment = gl.getParameter(gl.UNPACK_ALIGNMENT);\n\t\t\tgl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);\n\t\t}\n\t\tfor (let layer = 0; layer < textureInfo.history.depth; ++layer) {\n\t\t\tgl.texSubImage3D(\n\t\t\t\tgl.TEXTURE_2D_ARRAY,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tlayer,\n\t\t\t\ttextureInfo.width,\n\t\t\t\ttextureInfo.height,\n\t\t\t\t1,\n\t\t\t\tformat,\n\t\t\t\ttype,\n\t\t\t\ttransparent,\n\t\t\t);\n\t\t}\n\t\tif (needsAlignmentFix) gl.pixelStorei(gl.UNPACK_ALIGNMENT, previousAlignment);\n\t}\n\n\tprivate updateFrameOffset(\n\t\tname: string | symbol,\n\t\tframeOffset: number,\n\t\toptions?: {\n\t\t\tallowMissing?: boolean;\n\t\t},\n\t) {\n\t\tthis.updateUniforms(\n\t\t\t{\n\t\t\t\t[`${stringFrom(name)}FrameOffset`]: frameOffset,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n\n\tprivate resetHist(name: string | symbol, textureInfo: Texture) {\n\t\tif (!textureInfo.history) return;\n\t\ttextureInfo.history.writeIndex = 0;\n\t\tthis.clearHistTexLayers(textureInfo);\n\t\tthis.updateFrameOffset(name, 0, { allowMissing: true });\n\t}\n\n\tinitializeUniform(\n\t\tname: string,\n\t\ttype: Uniform['type'],\n\t\tvalue: number | number[] | (number | number[])[],\n\t\toptions?: { arrayLength?: number; allowMissing?: boolean },\n\t) {\n\t\tconst arrayLength = options?.arrayLength;\n\t\tconst allowMissing = options?.allowMissing ?? false;\n\t\tif (this.uniforms.has(name)) {\n\t\t\tthrow __SHADERPAD_DEV__ ? spError(7, { name, arrayLength: arrayLength ?? null }) : spError(7);\n\t\t}\n\t\tif (!UNIFORM_TYPE_SUFFIXES[type]) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(8, {\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttype,\n\t\t\t\t\t\tsupportedTypes: Object.keys(UNIFORM_TYPE_SUFFIXES),\n\t\t\t\t\t})\n\t\t\t\t: spError(8);\n\t\t}\n\t\tif (arrayLength && !(Array.isArray(value) && value.length === arrayLength)) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(9, {\n\t\t\t\t\t\tname,\n\t\t\t\t\t\texpectedLength: arrayLength,\n\t\t\t\t\t\treceivedLength: Array.isArray(value) ? value.length : 1,\n\t\t\t\t\t})\n\t\t\t\t: spError(9);\n\t\t}\n\n\t\tconst gl = this.gl;\n\t\tlet location = gl.getUniformLocation(this.program!, name);\n\t\tif (!location && arrayLength) {\n\t\t\tlocation = gl.getUniformLocation(this.program!, `${name}[0]`);\n\t\t}\n\t\tif (!location) {\n\t\t\tif (allowMissing) return;\n\t\t\tthrow __SHADERPAD_DEV__ ? spError(19, { name, arrayLength: arrayLength ?? null }) : spError(19);\n\t\t}\n\n\t\tconst probeValue = arrayLength ? (value as number[] | number[][])[0] : value;\n\t\tconst length = Array.isArray(probeValue) ? (probeValue.length as 1 | 2 | 3 | 4) : 1;\n\t\tthis.uniforms.set(name, { type, length, location, arrayLength });\n\n\t\ttry {\n\t\t\tthis.updateUniforms({ [name]: value });\n\t\t} catch (error) {\n\t\t\tthis.uniforms.delete(name);\n\t\t\tthrow error;\n\t\t}\n\t\tthis.emit('initializeUniform', ...arguments);\n\t}\n\n\tupdateUniforms(\n\t\tupdates: Record<string, number | number[] | (number | number[])[]>,\n\t\toptions?: { startIndex?: number; allowMissing?: boolean },\n\t) {\n\t\tconst gl = this.gl;\n\t\tgl.useProgram(this.program);\n\t\tObject.entries(updates).forEach(([name, newValue]) => {\n\t\t\tconst uniform = this.uniforms.get(name);\n\t\t\tif (!uniform) {\n\t\t\t\tif (options?.allowMissing) return;\n\t\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t\t? spError(20, {\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tstartIndex: options?.startIndex ?? null,\n\t\t\t\t\t\t})\n\t\t\t\t\t: spError(20);\n\t\t\t}\n\t\t\tlet glFunctionName = `uniform${uniform.length}${UNIFORM_TYPE_SUFFIXES[uniform.type]}`;\n\t\t\tif (uniform.arrayLength) {\n\t\t\t\tif (!Array.isArray(newValue)) {\n\t\t\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t\t\t? spError(10, {\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\treceivedType: typeof newValue,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: spError(10);\n\t\t\t\t}\n\t\t\t\tconst nValues = newValue.length;\n\t\t\t\tif (!nValues) return;\n\t\t\t\tif (nValues > uniform.arrayLength) {\n\t\t\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t\t\t? spError(11, {\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\treceivedLength: nValues,\n\t\t\t\t\t\t\t\tmaxLength: uniform.arrayLength,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: spError(11);\n\t\t\t\t}\n\t\t\t\tif (newValue.some(item => (Array.isArray(item) ? item.length : 1) !== uniform.length)) {\n\t\t\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t\t\t? spError(12, {\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\texpectedElementLength: uniform.length,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: spError(12);\n\t\t\t\t}\n\t\t\t\tconst flat = newValue.flat();\n\t\t\t\tconst typedArray =\n\t\t\t\t\tuniform.type === 'float'\n\t\t\t\t\t\t? new Float32Array(flat)\n\t\t\t\t\t\t: uniform.type === 'uint'\n\t\t\t\t\t\t\t? new Uint32Array(flat)\n\t\t\t\t\t\t\t: new Int32Array(flat);\n\t\t\t\tlet location = uniform.location;\n\t\t\t\tif (options?.startIndex) {\n\t\t\t\t\tconst newLocation = gl.getUniformLocation(this.program!, `${name}[${options.startIndex}]`);\n\t\t\t\t\tif (!newLocation) {\n\t\t\t\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t\t\t\t? spError(13, {\n\t\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\t\tstartIndex: options.startIndex,\n\t\t\t\t\t\t\t\t\tarrayLength: uniform.arrayLength,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t: spError(13);\n\t\t\t\t\t}\n\t\t\t\t\tlocation = newLocation;\n\t\t\t\t}\n\t\t\t\t(gl as any)[glFunctionName + 'v'](location, typedArray);\n\t\t\t} else {\n\t\t\t\tif (!Array.isArray(newValue)) newValue = [newValue];\n\t\t\t\tconst scalarValue = newValue as number[];\n\t\t\t\tif (scalarValue.length !== uniform.length) {\n\t\t\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t\t\t? spError(14, {\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\treceivedLength: scalarValue.length,\n\t\t\t\t\t\t\t\texpectedLength: uniform.length,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: spError(14);\n\t\t\t\t}\n\t\t\t\t(gl as any)[glFunctionName](uniform.location, ...scalarValue);\n\t\t\t}\n\t\t});\n\t\tthis.emit('updateUniforms', ...arguments);\n\t}\n\n\tprivate createTex(\n\t\tname: string | symbol,\n\t\ttextureInfo: Pick<Texture, 'width' | 'height' | 'history' | 'options'> & { unitIndex?: number },\n\t) {\n\t\tconst gl = this.gl;\n\t\tconst { width, height } = textureInfo;\n\t\tconst historyDepth = textureInfo.history?.depth ?? 0;\n\n\t\tconst texture = gl.createTexture();\n\t\tif (!texture) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(15, {\n\t\t\t\t\t\tname: stringFrom(name),\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t\thistoryDepth,\n\t\t\t\t\t})\n\t\t\t\t: spError(15);\n\t\t}\n\n\t\tlet unitIndex = textureInfo.unitIndex;\n\t\tif (typeof unitIndex !== 'number') {\n\t\t\ttry {\n\t\t\t\tunitIndex = this.reserveTex(name);\n\t\t\t} catch (error) {\n\t\t\t\tgl.deleteTexture(texture);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\tconst hasHistory = historyDepth > 0;\n\t\tconst textureTarget = hasHistory ? gl.TEXTURE_2D_ARRAY : gl.TEXTURE_2D;\n\t\tconst { options } = textureInfo;\n\t\tgl.activeTexture(gl.TEXTURE0 + unitIndex);\n\t\tgl.bindTexture(textureTarget, texture);\n\t\tgl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, options.wrapS);\n\t\tgl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, options.wrapT);\n\t\tgl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, options.minFilter);\n\t\tgl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, options.magFilter);\n\t\tif (hasHistory) {\n\t\t\tgl.texStorage3D(textureTarget, 1, options.internalFormat, width, height, historyDepth);\n\t\t} else if (name === INTERMEDIATE_TEXTURE_KEY) {\n\t\t\tgl.texImage2D(\n\t\t\t\tgl.TEXTURE_2D,\n\t\t\t\t0,\n\t\t\t\toptions.internalFormat,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\t0,\n\t\t\t\toptions.format,\n\t\t\t\toptions.type,\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\t\treturn { texture, unitIndex };\n\t}\n\n\tprivate initTex(name: string | symbol, source: TextureSource, options?: InitializeTextureOptions) {\n\t\tconst gl = this.gl;\n\t\tif (this.textures.has(name)) {\n\t\t\tthrow __SHADERPAD_DEV__ ? spError(16, { name: stringFrom(name) }) : spError(16);\n\t\t}\n\n\t\tconst { history: historyDepth = 0, ...texOptions } = options ?? {};\n\t\tconst { width, height } = getSourceDimensions(source);\n\t\tif (!width || !height) {\n\t\t\tthrow __SHADERPAD_DEV__\n\t\t\t\t? spError(17, {\n\t\t\t\t\t\tname: stringFrom(name),\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t\tsourceType: source.constructor.name,\n\t\t\t\t\t})\n\t\t\t\t: spError(17);\n\t\t}\n\t\tconst textureInfo: Pick<Texture, 'width' | 'height' | 'history' | 'options'> = {\n\t\t\twidth,\n\t\t\theight,\n\t\t\toptions:\n\t\t\t\tsource instanceof ShaderPad &&\n\t\t\t\tObject.keys(texOptions).length === 0 &&\n\t\t\t\tsource.textures.has(INTERMEDIATE_TEXTURE_KEY)\n\t\t\t\t\t? source.textures.get(INTERMEDIATE_TEXTURE_KEY)!.options\n\t\t\t\t\t: this.resolveTexOpts(texOptions),\n\t\t};\n\t\tif (historyDepth > 0) {\n\t\t\ttextureInfo.history = { depth: historyDepth, writeIndex: 0 };\n\t\t}\n\t\tconst { texture, unitIndex } = this.createTex(name, textureInfo);\n\t\tconst completeTextureInfo: Texture = {\n\t\t\ttexture,\n\t\t\tunitIndex,\n\t\t\t...textureInfo,\n\t\t};\n\t\tif (historyDepth > 0) {\n\t\t\tthis.initializeUniform(`${stringFrom(name)}FrameOffset`, 'int', 0, { allowMissing: true });\n\t\t\tthis.clearHistTexLayers(completeTextureInfo);\n\t\t}\n\t\tthis.textures.set(name, completeTextureInfo);\n\t\tif (name !== INTERMEDIATE_TEXTURE_KEY && name !== HISTORY_TEXTURE_KEY) {\n\t\t\tthis.updateTex(name, source);\n\t\t}\n\n\t\t// Set a uniform to access the texture in the fragment shader.\n\t\tgl.useProgram(this.program!);\n\t\tconst uSampler = gl.getUniformLocation(this.program!, stringFrom(name));\n\t\tif (uSampler) {\n\t\t\tgl.uniform1i(uSampler, unitIndex);\n\t\t}\n\t}\n\n\tinitializeTexture(name: string, source: TextureSource, options?: InitializeTextureOptions) {\n\t\t// Since history[0] is the current frame, add 1 to history depth to allow history[maxHistory].\n\t\tconst opts =\n\t\t\toptions?.history != null && options.history > 0 ? { ...options, history: options.history + 1 } : options;\n\t\tthis.initTex(name, source, opts);\n\t\tthis.emit('initializeTexture', ...arguments);\n\t}\n\n\tupdateTextures(updates: Record<string, UpdateTextureSource>) {\n\t\tObject.entries(updates).forEach(([name, source]) => {\n\t\t\tthis.updateTex(name, source);\n\t\t});\n\t\tthis.emit('updateTextures', ...arguments);\n\t}\n\n\tprivate updateTex(name: string | symbol, source: UpdateTextureSource, historySlots?: HistorySlots) {\n\t\tconst gl = this.gl;\n\t\tconst info = this.textures.get(name);\n\t\tif (!info) {\n\t\t\tthrow __SHADERPAD_DEV__ ? spError(18, { name: stringFrom(name) }) : spError(18);\n\t\t}\n\n\t\tif (source instanceof WebGLTexture) {\n\t\t\tgl.activeTexture(gl.TEXTURE0 + info.unitIndex);\n\t\t\tgl.bindTexture(gl.TEXTURE_2D, source);\n\t\t\treturn;\n\t\t}\n\n\t\tlet nonShaderPadSource = source as Exclude<UpdateTextureSource, ShaderPad>;\n\t\tif (source instanceof ShaderPad) {\n\t\t\tconst sourceIntermediateInfo = source.textures.get(INTERMEDIATE_TEXTURE_KEY)!;\n\t\t\tconst srcW = sourceIntermediateInfo.width;\n\t\t\tconst srcH = sourceIntermediateInfo.height;\n\n\t\t\tif (source.gl === gl) {\n\t\t\t\tif (!info.history) {\n\t\t\t\t\tgl.activeTexture(gl.TEXTURE0 + info.unitIndex);\n\t\t\t\t\tgl.bindTexture(gl.TEXTURE_2D, sourceIntermediateInfo.texture);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst { depth } = info.history;\n\t\t\t\tconst targetSlots =\n\t\t\t\t\thistorySlots === undefined\n\t\t\t\t\t\t? [info.history.writeIndex]\n\t\t\t\t\t\t: Array.isArray(historySlots)\n\t\t\t\t\t\t\t? historySlots.map(i => safeMod(i, depth))\n\t\t\t\t\t\t\t: [safeMod(historySlots, depth)];\n\t\t\t\tgl.activeTexture(gl.TEXTURE0 + info.unitIndex);\n\t\t\t\tgl.bindTexture(gl.TEXTURE_2D_ARRAY, info.texture);\n\t\t\t\tgl.bindFramebuffer(gl.READ_FRAMEBUFFER, source.intermediateFbo);\n\t\t\t\tfor (const slot of targetSlots) {\n\t\t\t\t\tgl.copyTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, slot, 0, 0, srcW, srcH);\n\t\t\t\t}\n\t\t\t\tgl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);\n\t\t\t\tthis.updateFrameOffset(name, targetSlots[targetSlots.length - 1], { allowMissing: true });\n\t\t\t\tif (historySlots === undefined) {\n\t\t\t\t\tinfo.history.writeIndex = (info.history.writeIndex + 1) % depth;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Different contexts - transfer via readPixels to preserve precision.\n\t\t\tconst {\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\toptions: { format, type },\n\t\t\t} = sourceIntermediateInfo;\n\t\t\tconst pixels = this.getPxArray(type, width * height * 4);\n\t\t\tsource.gl.bindFramebuffer(source.gl.FRAMEBUFFER, source.intermediateFbo);\n\t\t\tsource.gl.readPixels(0, 0, width, height, format, type, pixels);\n\t\t\tsource.gl.bindFramebuffer(source.gl.FRAMEBUFFER, null);\n\t\t\tnonShaderPadSource = { data: pixels, width, height };\n\t\t}\n\n\t\t// If dimensions changed, recreate the texture with new dimensions.\n\t\tconst { width, height } = getSourceDimensions(nonShaderPadSource);\n\t\tif (!width || !height) return;\n\n\t\tconst isPartial = 'isPartial' in nonShaderPadSource && nonShaderPadSource.isPartial;\n\t\tif (!isPartial) {\n\t\t\tthis.resizeTex(name, width, height);\n\t\t}\n\n\t\t// UNPACK_FLIP_Y_WEBGL only works for DOM element sources, not typed arrays.\n\t\tconst isCustomTexture = 'data' in nonShaderPadSource && nonShaderPadSource.data;\n\t\tconst shouldFlipY = !isCustomTexture && !info.options?.preserveY;\n\t\tconst previousFlipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL);\n\t\tconst needsAlignmentFix = isCustomTexture && !this.isRgba(info.options.format);\n\t\tconst shouldConvertColorSpace = !isCustomTexture && info.options.colorSpace && 'unpackColorSpace' in gl;\n\t\tconst previousColorSpace = gl.unpackColorSpace;\n\t\tlet previousAlignment;\n\t\tif (needsAlignmentFix) {\n\t\t\tpreviousAlignment = gl.getParameter(gl.UNPACK_ALIGNMENT);\n\t\t\tgl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);\n\t\t}\n\t\tif (shouldConvertColorSpace) gl.unpackColorSpace = info.options.colorSpace!;\n\n\t\tif (info.history) {\n\t\t\tgl.activeTexture(gl.TEXTURE0 + info.unitIndex);\n\t\t\tgl.bindTexture(gl.TEXTURE_2D_ARRAY, info.texture);\n\t\t\tconst { depth } = info.history;\n\t\t\tconst targetSlots =\n\t\t\t\thistorySlots === undefined\n\t\t\t\t\t? [info.history.writeIndex]\n\t\t\t\t\t: Array.isArray(historySlots)\n\t\t\t\t\t\t? historySlots.map(i => safeMod(i, depth))\n\t\t\t\t\t\t: [safeMod(historySlots, depth)];\n\n\t\t\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, shouldFlipY);\n\t\t\tconst partialSource = nonShaderPadSource as PartialCustomTexture;\n\t\t\tconst sourceData =\n\t\t\t\tpartialSource.data ?? (nonShaderPadSource as Exclude<TextureSource, CustomTexture | ShaderPad>);\n\t\t\tconst xOffset = isPartial ? (partialSource.x ?? 0) : 0;\n\t\t\tconst yOffset = isPartial ? (partialSource.y ?? 0) : 0;\n\n\t\t\tfor (const slot of targetSlots) {\n\t\t\t\tgl.texSubImage3D(\n\t\t\t\t\tgl.TEXTURE_2D_ARRAY,\n\t\t\t\t\t0,\n\t\t\t\t\txOffset,\n\t\t\t\t\tyOffset,\n\t\t\t\t\tslot,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\t1,\n\t\t\t\t\tinfo.options.format,\n\t\t\t\t\tinfo.options.type,\n\t\t\t\t\tsourceData as any,\n\t\t\t\t);\n\t\t\t}\n\t\t\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, previousFlipY);\n\t\t\tthis.updateFrameOffset(name, targetSlots[targetSlots.length - 1]);\n\t\t\tif (historySlots === undefined) {\n\t\t\t\tinfo.history.writeIndex = (info.history.writeIndex + 1) % depth;\n\t\t\t}\n\t\t} else {\n\t\t\tgl.activeTexture(gl.TEXTURE0 + info.unitIndex);\n\t\t\tgl.bindTexture(gl.TEXTURE_2D, info.texture);\n\t\t\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, shouldFlipY);\n\n\t\t\tif (isPartial) {\n\t\t\t\tconst partialSource = nonShaderPadSource as PartialCustomTexture;\n\t\t\t\tgl.texSubImage2D(\n\t\t\t\t\tgl.TEXTURE_2D,\n\t\t\t\t\t0,\n\t\t\t\t\tpartialSource.x ?? 0,\n\t\t\t\t\tpartialSource.y ?? 0,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tinfo.options.format,\n\t\t\t\t\tinfo.options.type,\n\t\t\t\t\tpartialSource.data,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tgl.texImage2D(\n\t\t\t\t\tgl.TEXTURE_2D,\n\t\t\t\t\t0,\n\t\t\t\t\tinfo.options.internalFormat,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\t0,\n\t\t\t\t\tinfo.options.format,\n\t\t\t\t\tinfo.options.type,\n\t\t\t\t\t((nonShaderPadSource as PartialCustomTexture).data ??\n\t\t\t\t\t\t(nonShaderPadSource as Exclude<TextureSource, CustomTexture | ShaderPad>)) as any,\n\t\t\t\t);\n\t\t\t}\n\t\t\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, previousFlipY);\n\t\t}\n\n\t\tif (shouldConvertColorSpace) gl.unpackColorSpace = previousColorSpace;\n\t\tif (needsAlignmentFix) gl.pixelStorei(gl.UNPACK_ALIGNMENT, previousAlignment);\n\t}\n\n\tprivate bindIntermediate() {\n\t\tconst gl = this.gl;\n\t\tconst intermediateInfo = this.textures.get(INTERMEDIATE_TEXTURE_KEY)!;\n\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, this.intermediateFbo);\n\t\tgl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, intermediateInfo.texture, 0);\n\t}\n\n\tclear() {\n\t\tthis.bindIntermediate();\n\t\tconst gl = this.gl;\n\t\tconst intermediateInfo = this.textures.get(INTERMEDIATE_TEXTURE_KEY)!;\n\t\tif (intermediateInfo.options.isIntegerColorFormat) {\n\t\t\tconst t = intermediateInfo.options.type;\n\t\t\tif (this.uintTypes.has(t)) {\n\t\t\t\tgl.clearBufferuiv(gl.COLOR, 0, new Uint32Array(4));\n\t\t\t} else {\n\t\t\t\tgl.clearBufferiv(gl.COLOR, 0, new Int32Array(4));\n\t\t\t}\n\t\t} else {\n\t\t\tgl.clear(gl.COLOR_BUFFER_BIT);\n\t\t}\n\t}\n\n\tdraw(options?: StepOptions | void) {\n\t\tthis.emit('preDraw', ...arguments);\n\t\tconst gl = this.gl;\n\t\tconst w = gl.drawingBufferWidth;\n\t\tconst h = gl.drawingBufferHeight;\n\n\t\tif (options?.skipClear) {\n\t\t\tthis.bindIntermediate();\n\t\t} else {\n\t\t\tthis.clear();\n\t\t}\n\n\t\tgl.useProgram(this.program);\n\t\tgl.bindVertexArray(this.vao);\n\t\tgl.viewport(0, 0, w, h);\n\t\tgl.drawArrays(gl.TRIANGLES, 0, 3);\n\n\t\tif (!this.isHeadless) {\n\t\t\tconst intermediateInfo = this.textures.get(INTERMEDIATE_TEXTURE_KEY)!;\n\t\t\tif (!intermediateInfo.options.isIntegerColorFormat) {\n\t\t\t\tgl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.intermediateFbo);\n\t\t\t\tgl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n\t\t\t\tgl.blitFramebuffer(0, 0, w, h, 0, 0, w, h, gl.COLOR_BUFFER_BIT, gl.NEAREST);\n\t\t\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\t\t\t}\n\t\t}\n\t\tthis.emit('postDraw', ...arguments);\n\t}\n\n\tstep(options?: StepOptions) {\n\t\tthis._step(performance.now(), options);\n\t}\n\n\tprivate tick() {\n\t\tconst updates: Record<string, number> = {};\n\t\tif (this.uniforms.has('u_time')) updates.u_time = this.tElapsed;\n\t\tif (this.uniforms.has('u_frame')) updates.u_frame = this.frame;\n\t\tif (Object.keys(updates).length) this.updateUniforms(updates);\n\t}\n\n\tprivate _step(now: number, opts?: StepOptions | ((time: number, frame: number) => StepOptions | void)) {\n\t\tconst t = this.getElapsed(now);\n\t\tthis.tElapsed = t;\n\t\tthis.tStart = now;\n\t\tconst options = typeof opts === 'function' ? opts(t, this.frame) : opts;\n\t\tthis.emit('preStep', t, this.frame, options);\n\t\tthis.tick();\n\t\tthis.draw(options);\n\t\tconst historyInfo = this.textures.get(HISTORY_TEXTURE_KEY);\n\t\tif (historyInfo && !options?.skipHistory) {\n\t\t\tconst { writeIndex, depth } = historyInfo.history!;\n\t\t\tconst gl = this.gl;\n\t\t\tgl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.intermediateFbo);\n\t\t\tgl.bindTexture(gl.TEXTURE_2D_ARRAY, historyInfo.texture);\n\t\t\tgl.copyTexSubImage3D(\n\t\t\t\tgl.TEXTURE_2D_ARRAY,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\twriteIndex,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tgl.drawingBufferWidth,\n\t\t\t\tgl.drawingBufferHeight,\n\t\t\t);\n\t\t\tgl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);\n\t\t\tconst nextWriteIndex = (writeIndex + 1) % depth;\n\t\t\tthis.updateFrameOffset(HISTORY_TEXTURE_KEY, nextWriteIndex, { allowMissing: true });\n\t\t\thistoryInfo.history!.writeIndex = nextWriteIndex;\n\t\t}\n\t\t++this.frame;\n\t\tthis.emit('postStep', t, this.frame, options);\n\t}\n\n\tplay(onPreStep?: (time: number, frame: number) => StepOptions | void) {\n\t\tthis._pause();\n\t\tconst loop = (now: number) => {\n\t\t\tthis._step(now, onPreStep);\n\t\t\tif (this.frameId != null) this.frameId = requestAnimationFrame(loop);\n\t\t};\n\t\tthis.frameId = requestAnimationFrame(loop);\n\t\tthis.emit('play');\n\t}\n\n\tprivate getElapsed(time: number) {\n\t\tif (isNaN(this.tStart)) return this.tElapsed;\n\t\treturn this.tElapsed + (time - this.tStart) / 1000;\n\t}\n\n\tprivate _pause() {\n\t\tif (isNaN(this.tStart) && this.frameId == null) return;\n\t\tif (this.frameId != null) {\n\t\t\tcancelAnimationFrame(this.frameId);\n\t\t\tthis.frameId = null;\n\t\t}\n\t\tthis.tElapsed = this.getElapsed(performance.now());\n\t\tthis.tStart = NaN;\n\t\treturn true;\n\t}\n\n\tpause() {\n\t\tif (this._pause()) this.emit('pause');\n\t}\n\n\trewind() {\n\t\tthis.frame = 0;\n\t\tthis.tElapsed = 0;\n\t\tthis.tStart = NaN;\n\t\tthis.tick();\n\t}\n\n\treset() {\n\t\tthis.rewind();\n\t\tthis.textures.forEach((texture, name) => {\n\t\t\tthis.resetHist(name, texture);\n\t\t});\n\t\tthis.clear();\n\t\tthis.emit('reset');\n\t}\n\n\tdestroy() {\n\t\tthis.emit('destroy');\n\n\t\tthis._pause();\n\t\tconst gl = this.gl;\n\n\t\tif (this.cursorTgt) {\n\t\t\tthis.listeners.forEach((listener, event) => {\n\t\t\t\tthis.cursorTgt!.removeEventListener(event, listener);\n\t\t\t});\n\t\t\tthis.listeners.clear();\n\t\t}\n\n\t\tif (this.resObserver) {\n\t\t\tthis.resObserver.disconnect();\n\t\t\tthis.resObserver = null;\n\t\t}\n\n\t\tif (this.program) {\n\t\t\tgl.deleteProgram(this.program);\n\t\t\tthis.program = null;\n\t\t}\n\n\t\tif (this.intermediateFbo) {\n\t\t\tgl.deleteFramebuffer(this.intermediateFbo);\n\t\t\tthis.intermediateFbo = null;\n\t\t}\n\n\t\tthis.textures.forEach(texture => {\n\t\t\tthis.texPool.free.push(texture.unitIndex);\n\t\t\tgl.deleteTexture(texture.texture);\n\t\t});\n\t\tthis.textures.clear();\n\t\tconst entry = canvasRegistry.get(this.canvas);\n\t\tif (entry) {\n\t\t\tentry.instances.delete(this);\n\t\t\tif (entry.instances.size === 0) {\n\t\t\t\tcanvasRegistry.delete(this.canvas);\n\t\t\t}\n\t\t}\n\n\t\tif (this.vao) {\n\t\t\tgl.deleteVertexArray(this.vao);\n\t\t\tthis.vao = null;\n\t\t}\n\n\t\tif (this.buffer) {\n\t\t\tgl.deleteBuffer(this.buffer);\n\t\t\tthis.buffer = null;\n\t\t}\n\n\t\tthis.uniforms.clear();\n\t\tthis.hooks.clear();\n\t}\n}\n\nexport default ShaderPad;\n"],"mappings":"gDAEA,IAAMA,EAA4B;AAAA,yGAoC5BC,EAAiD,CACtD,CAAC,MAAO,eAAe,EACvB,CAAC,KAAM,MAAM,EACb,CAAC,OAAQ,gBAAgB,EACzB,CAAC,MAAO,OAAO,EACf,CAAC,MAAO,YAAY,EACpB,CAAC,OAAQ,cAAc,EACvB,CAAC,MAAO,KAAK,EACb,CAAC,MAAO,OAAO,EACf,CAAC,IAAK,eAAe,CACtB,EAEMC,EAAyD,CAC9D,MAAO,IACP,IAAK,IACL,KAAM,IACP,EAEA,SAASC,EAA6BC,EAAyE,CAC9G,OAAOA,GAAwBH,EAAqB,KAAK,CAAC,CAACI,CAAM,IAAMD,EAAqB,SAASC,CAAM,CAAC,IAAI,CAAC,CAClH,CAoHA,IAAMC,EAAsB,OAAO,WAAW,EACxCC,EAA2B,OAAO,oBAAoB,EAEtDC,EAAiB,IAAI,QAK3B,SAASC,EAAkBC,EAAgBC,EAA8B,CACxE,GAAI,CAACA,GAAY,OAAQ,OAAOD,EAChC,IAAME,EAAQF,EAAO,MAAM;AAAA,CAAI,EACzBG,EACLD,EAAM,cAAcE,GAAQ,CAC3B,IAAMC,EAAUD,EAAK,UAAU,EAC/B,OAAOC,EAAQ,WAAW,YAAY,GAAKA,EAAQ,WAAW,WAAW,CAC1E,CAAC,EAAI,EACN,OAAAH,EAAM,OAAOC,EAAU,EAAG,GAAGF,CAAU,EAChCC,EAAM,KAAK;AAAA,CAAI,CACvB,CAEA,SAASI,EAAoBC,EAG3B,CACD,OAAIA,aAAkB,aACd,CAAE,MAAO,EAAG,OAAQ,CAAE,EAE1BA,aAAkBC,EACd,CAAE,MAAOD,EAAO,OAAO,MAAO,OAAQA,EAAO,OAAO,MAAO,EAE/DA,aAAkB,iBACd,CAAE,MAAOA,EAAO,WAAY,OAAQA,EAAO,WAAY,EAE3DA,aAAkB,iBACd,CACN,MAAOA,EAAO,cAAgBA,EAAO,MACrC,OAAQA,EAAO,eAAiBA,EAAO,MACxC,EAGM,CAAE,MAAOA,EAAO,MAAO,OAAQA,EAAO,MAAO,CACrD,CAEA,SAASE,EAAWC,EAAuB,CAC1C,OAAO,OAAOA,GAAS,SAAYA,EAAK,aAAe,GAAMA,CAC9D,CAEA,IAAMF,EAAN,MAAMG,CAAU,CACP,WAAa,GACb,QAAU,GAKV,SAAiC,IAAI,IACrC,SAA0C,IAAI,IAE9C,OAA6B,KAC7B,IAAqC,KACrC,QAA+B,KAE/B,UAAwC,IAAI,IAC5C,MAAQ,EACR,SAAW,EACX,OAAS,IACT,UAAY,CAAC,GAAK,EAAG,EACrB,SAAW,CAAC,GAAK,EAAG,EACpB,UAAY,GAEZ,YAAuC,KACvC,MAA6C,IAAI,IACjD,aAAe,EAKf,gBAA2C,KAEnD,YAAYC,EAA2B,CAAE,OAAAC,EAAQ,QAAAC,EAAS,QAAAC,EAAS,aAAAC,EAAc,GAAGC,CAAW,EAAa,CAAC,EAAG,CAC/G,GAAIJ,GAAU,eAAgBA,EAC7B,KAAK,OAASA,MACR,CACN,GAAM,CAAE,MAAAK,EAAQ,EAAG,OAAAC,EAAS,CAAE,EAAIN,GAAU,CAAC,EAC7C,KAAK,OAAS,IAAI,gBAAgBK,EAAOC,CAAM,EAC/C,KAAK,WAAa,EACnB,CAEA,IAAMC,EAAK,KAAK,OAAO,WAAW,SAAU,CAC3C,UAAW,EACZ,CAAC,EACD,GAAI,CAACA,EACJ,MAOGC,EAAQ,CAAC,EAETJ,EAAW,YAAc,4BAA6BG,IACzDA,EAAG,wBAA0BH,EAAW,YAEzC,KAAK,GAAKG,EACV,KAAK,WAAa,IAAI,IAAqD,CAC1E,CAACA,EAAG,MAAO,YAAY,EACvB,CAACA,EAAG,WAAY,WAAW,EAC3B,CAACA,EAAG,eAAgB,WAAW,EAC/B,CAACA,EAAG,MAAO,UAAU,EACrB,CAACA,EAAG,KAAM,SAAS,EACnB,CAACA,EAAG,aAAc,WAAW,EAC7B,CAACA,EAAG,IAAK,UAAU,CACpB,CAAC,EACD,KAAK,YAAc,IAAI,IAAoC,CAC1D,CAACA,EAAG,MAAO,SAAS,EACpB,CAACA,EAAG,WAAY,SAAS,EACzB,CAACA,EAAG,eAAgB,UAAU,EAC9B,CAACA,EAAG,MAAO,SAAS,EACpB,CAACA,EAAG,KAAM,SAAS,EACnB,CAACA,EAAG,aAAc,UAAU,EAC5B,CAACA,EAAG,IAAK,SAAS,CACnB,CAAC,EACD,KAAK,UAAY,IAAI,IAAI,CAACA,EAAG,cAAeA,EAAG,eAAgBA,EAAG,YAAY,CAAC,EAE/E,IAAIE,EAAgBxB,EAAe,IAAI,KAAK,MAAM,EAC7CwB,IACJA,EAAgB,CACf,QAAS,CACR,KAAM,CAAC,EACP,KAAM,EACN,IAAKF,EAAG,aAAaA,EAAG,gCAAgC,CACzD,EACA,UAAW,IAAI,IAAI,CAAC,IAAI,CAAC,CAC1B,EACAtB,EAAe,IAAI,KAAK,OAAQwB,CAAa,GAE9C,KAAK,QAAUA,EAAc,QAC7BA,EAAc,UAAU,IAAI,IAAI,EAEhC,KAAK,WAAaL,EAEdF,IAAS,KAAK,aAAeA,GACjC,KAAK,UAAYC,IAAiB,KAAK,kBAAkB,kBAAoB,KAAK,OAAS,QAC3F,KAAK,QAAU,KAEf,IAAMO,EAA2B,CAAC,EAC9BT,GACHA,EAAQ,QAAQU,GACfA,EAAO,KAAM,CACZ,WAAaC,GAAiB,CAC7BF,EAAe,KAAKE,CAAI,CACzB,EACA,KAAM,KAAK,KAAK,KAAK,IAAI,EACzB,cAAe,KAAK,UAAU,KAAK,IAAI,CACxC,CAAC,CACF,EAGD,IAAMC,EAAUN,EAAG,cAAc,EACjC,GAAI,CAACM,EACJ,MAAML,EAAQ,CAAC,EAEhB,KAAK,QAAUK,EAEf,IAAMC,EAAe,KAAK,aAAaP,EAAG,cAAe9B,CAAyB,EAC5EsC,EAAiB,KAAK,aAC3BR,EAAG,gBACHrB,EAAkBa,EAAmBW,CAAc,CACpD,EAQA,GAPAH,EAAG,aAAaM,EAASC,CAAY,EACrCP,EAAG,aAAaM,EAASE,CAAc,EACvCR,EAAG,mBAAmBM,EAAS,EAAG,YAAY,EAC9CN,EAAG,YAAYM,CAAO,EACtBN,EAAG,aAAaO,CAAY,EAC5BP,EAAG,aAAaQ,CAAc,EAE1B,CAACR,EAAG,oBAAoBM,EAASN,EAAG,WAAW,EAAG,CACrD,IAAMS,EAMHR,EAAQ,CAAC,EACZ,MAAAD,EAAG,cAAcM,CAAO,EAClBG,CACP,CAcA,GAZA,KAAK,IAAMT,EAAG,kBAAkB,EAChCA,EAAG,gBAAgB,KAAK,GAAG,EAC3B,KAAK,OAASA,EAAG,aAAa,EAC9BA,EAAG,WAAWA,EAAG,aAAc,KAAK,MAAM,EAC1CA,EAAG,WAAWA,EAAG,aAAc,IAAI,aAAa,CAAC,GAAI,GAAI,EAAG,GAAI,GAAI,CAAC,CAAC,EAAGA,EAAG,WAAW,EACvFA,EAAG,wBAAwB,CAAC,EAC5BA,EAAG,oBAAoB,EAAG,EAAGA,EAAG,MAAO,GAAO,EAAG,CAAC,EAElDA,EAAG,SAAS,EAAG,EAAGA,EAAG,mBAAoBA,EAAG,mBAAmB,EAE/DA,EAAG,WAAWM,CAAO,EAEjB,KAAK,kBAAkB,kBAC1B,KAAK,YAAc,IAAI,iBAAiB,IAAM,KAAK,QAAQ,CAAC,EAC5D,KAAK,YAAY,QAAQ,KAAK,OAAQ,CACrC,WAAY,GACZ,gBAAiB,CAAC,QAAS,QAAQ,CACpC,CAAC,MACK,CACN,IAAMI,EAAiBC,GAAkC,CACxD,IAAMC,EAAa,OAAO,yBAAyB,gBAAgB,UAAWD,CAAS,EACjFlB,EAAS,KAAK,OACpB,OAAO,eAAeA,EAAQkB,EAAW,CACxC,IAAK,IAAMC,EAAW,IAAK,KAAKnB,CAAM,EACtC,IAAKoB,GAAK,CACTD,EAAW,IAAK,KAAKnB,EAAQoB,CAAC,EAC9B,IAAMC,EAAQpC,EAAe,IAAIe,CAAM,EACvC,GAAIqB,EACH,QAAWC,KAAYD,EAAM,UAC5BC,EAAS,QAAQ,CAGpB,EACA,aAAcH,EAAW,aACzB,WAAYA,EAAW,UACxB,CAAC,CACF,EACAF,EAAc,OAAO,EACrBA,EAAc,QAAQ,CACvB,CACA,KAAK,QAAQ,EAEb,KAAK,kBAAkB,WAAY,QAAS,KAAK,UAAW,CAAE,aAAc,EAAK,CAAC,EAClF,KAAK,kBAAkB,UAAW,QAAS,CAAC,GAAG,KAAK,SAAU,KAAK,UAAY,EAAM,CAAG,EAAG,CAC1F,aAAc,EACf,CAAC,EACD,KAAK,kBAAkB,SAAU,QAAS,EAAG,CAAE,aAAc,EAAK,CAAC,EACnE,KAAK,kBAAkB,UAAW,MAAO,EAAG,CAAE,aAAc,EAAK,CAAC,EAElE,KAAK,QAAQjC,EAA0B,KAAK,OAAQ,CACnD,GAAG,KAAK,UACT,CAAC,EACD,KAAK,gBAAkBuB,EAAG,kBAAkB,EAC5C,KAAK,iBAAiB,EACtBA,EAAG,gBAAgBA,EAAG,YAAa,IAAI,EAEnC,KAAK,aAAe,GACvB,KAAK,QAAQxB,EAAqB,KAAK,OAAQ,CAC9C,QAAS,KAAK,aACd,GAAG,KAAK,UACT,CAAC,EAEF,KAAK,aAAa,EAClB,KAAK,KAAK,OAAO,CAClB,CAEQ,eAAewC,EAAiC,CAEvD,IAAMC,EADK,KAAK,GACID,CAAK,EACzB,GAAIC,IAAa,OAChB,MAAkDhB,EAAQ,CAAC,EAE5D,OAAOgB,CACR,CAEQ,KAAK3B,KAA6B4B,EAAa,CACtD,KAAK,MAAM,IAAI5B,CAAI,GAAG,QAAQ6B,GAAQA,EAAK,KAAK,KAAM,GAAGD,CAAI,CAAC,CAC/D,CAEA,GAAG5B,EAA0B8B,EAAc,CACrC,KAAK,MAAM,IAAI9B,CAAI,GACvB,KAAK,MAAM,IAAIA,EAAM,CAAC,CAAC,EAExB,KAAK,MAAM,IAAIA,CAAI,EAAG,KAAK8B,CAAE,CAC9B,CAEA,IAAI9B,EAA0B8B,EAAc,CAC3C,IAAMC,EAAQ,KAAK,MAAM,IAAI/B,CAAI,EACjC,GAAI+B,EAAO,CACV,IAAMC,EAAQD,EAAM,QAAQD,CAAE,EAC1BE,GAAS,GACZD,EAAM,OAAOC,EAAO,CAAC,CAEvB,CACD,CAEQ,aAAaC,EAAcpC,EAA6B,CAC/D,IAAMa,EAAK,KAAK,GACVpB,EAASoB,EAAG,aAAauB,CAAI,EAGnC,GAFAvB,EAAG,aAAapB,EAAQO,CAAM,EAC9Ba,EAAG,cAAcpB,CAAM,EACnB,CAACoB,EAAG,mBAAmBpB,EAAQoB,EAAG,cAAc,EAAG,CACtD,QAAQ,MAAMA,EAAG,iBAAiBpB,CAAM,CAAC,EACzC,IAAM4C,EAKHvB,EAAQ,CAAC,EACZ,MAAAD,EAAG,aAAapB,CAAM,EAChB4C,CACP,CACA,OAAO5C,CACR,CAEQ,kBAKN,CACD,IAAM6C,EAAS,KAAK,UACpB,OAAIA,IAAW,OACP,CACN,KAAM,EACN,IAAK,EACL,MAAO,OAAO,WACd,OAAQ,OAAO,WAChB,EAEOA,EAAmB,sBAAsB,CAClD,CAEQ,cAAe,CACtB,GAAI,CAAC,KAAK,UAAW,OACrB,IAAMC,EAAe,CAACC,EAAWC,IAAc,CAC9C,GAAI,CAAC,KAAK,SAAS,IAAI,UAAU,EAAG,OACpC,IAAMC,EAAO,KAAK,iBAAiB,EAC7BC,GAAKH,EAAIE,EAAK,MAAQA,EAAK,MAC3BhB,EAAI,GAAKe,EAAIC,EAAK,KAAOA,EAAK,OACpC,KAAK,UAAU,CAAC,EAAI,KAAK,IAAI,EAAG,KAAK,IAAI,EAAGC,CAAC,CAAC,EAC9C,KAAK,UAAU,CAAC,EAAI,KAAK,IAAI,EAAG,KAAK,IAAI,EAAGjB,CAAC,CAAC,EAC9C,KAAK,eAAe,CAAE,SAAU,KAAK,SAAU,CAAC,CACjD,EAEMkB,EAAc,CAACC,EAAoBL,EAAYC,IAAe,CACnE,GAAK,KAAK,SAAS,IAAI,SAAS,EAEhC,IADA,KAAK,UAAYI,EACbA,EAAW,CACd,IAAMH,EAAO,KAAK,iBAAiB,EAC7BI,EAAON,EACPO,EAAON,EACb,KAAK,SAAS,CAAC,EAAI,KAAK,IAAI,EAAG,KAAK,IAAI,GAAIK,EAAOJ,EAAK,MAAQA,EAAK,KAAK,CAAC,EAC3E,KAAK,SAAS,CAAC,EAAI,KAAK,IAAI,EAAG,KAAK,IAAI,EAAG,GAAKK,EAAOL,EAAK,KAAOA,EAAK,MAAM,CAAC,CAChF,CACA,KAAK,eAAe,CACnB,QAAS,CAAC,GAAG,KAAK,SAAU,KAAK,UAAY,EAAM,CAAG,CACvD,CAAC,EACF,EAEA,KAAK,UAAU,IAAI,YAAaM,GAAS,CACxC,IAAMC,EAAaD,EACd,KAAK,SACTT,EAAaU,EAAW,QAASA,EAAW,OAAO,CAErD,CAAC,EAED,KAAK,UAAU,IAAI,YAAaD,GAAS,CACxC,IAAMC,EAAaD,EACd,KAAK,SACLC,EAAW,SAAW,IACzB,KAAK,UAAY,GACjBL,EAAY,GAAMK,EAAW,QAASA,EAAW,OAAO,EAG3D,CAAC,EAED,KAAK,UAAU,IAAI,UAAWD,GAAS,CACtC,IAAMC,EAAaD,EACd,KAAK,SACLC,EAAW,SAAW,GACzBL,EAAY,EAAK,CAGpB,CAAC,EAED,KAAK,UAAU,IAAI,YAAaI,GAAS,CACxC,IAAME,EAAaF,EACfE,EAAW,QAAQ,OAAS,GAC/BX,EAAaW,EAAW,QAAQ,CAAC,EAAE,QAASA,EAAW,QAAQ,CAAC,EAAE,OAAO,CAE3E,CAAC,EAED,KAAK,UAAU,IAAI,aAAcF,GAAS,CACzC,IAAME,EAAaF,EACnB,KAAK,QAAU,GACXE,EAAW,QAAQ,OAAS,IAC/BX,EAAaW,EAAW,QAAQ,CAAC,EAAE,QAASA,EAAW,QAAQ,CAAC,EAAE,OAAO,EACzEN,EAAY,GAAMM,EAAW,QAAQ,CAAC,EAAE,QAASA,EAAW,QAAQ,CAAC,EAAE,OAAO,EAEhF,CAAC,EAED,KAAK,UAAU,IAAI,WAAYF,GAAS,CACpBA,EACJ,QAAQ,SAAW,GACjCJ,EAAY,EAAK,CAEnB,CAAC,EAED,KAAK,UAAU,QAAQ,CAACO,EAAUH,IAAU,CAC3C,KAAK,UAAW,iBAAiBA,EAAOG,CAAQ,CACjD,CAAC,CACF,CAEQ,SAAU,CACjB,IAAMtC,EAAK,KAAK,GACVuC,EAA+B,CAACvC,EAAG,mBAAoBA,EAAG,mBAAmB,EACnFA,EAAG,SAAS,EAAG,EAAG,GAAGuC,CAAU,EAC3B,KAAK,SAAS,IAAI,cAAc,EACnC,KAAK,eAAe,CAAE,aAAcA,CAAW,CAAC,EAEhD,KAAK,kBAAkB,eAAgB,QAASA,EAAY,CAAE,aAAc,EAAK,CAAC,EAEnF,KAAK,UAAU9D,EAA0B,GAAG8D,CAAU,EAClD,KAAK,aAAe,GACvB,KAAK,UAAU/D,EAAqB,GAAG+D,CAAU,EAElD,KAAK,KAAK,mBAAoB,GAAGA,CAAU,CAC5C,CAEQ,UAAUjD,EAAuBQ,EAAeC,EAAgB,CACvE,IAAMyC,EAAO,KAAK,SAAS,IAAIlD,CAAI,EACnC,GAAI,CAACkD,GAASA,EAAK,QAAU1C,GAAS0C,EAAK,SAAWzC,EAAS,OAEpD,KAAK,GACb,cAAcyC,EAAK,OAAO,EAC7BA,EAAK,MAAQ1C,EACb0C,EAAK,OAASzC,EACd,GAAM,CAAE,QAAA0C,CAAQ,EAAI,KAAK,UAAUnD,EAAMkD,CAAI,EAC7CA,EAAK,QAAUC,EACf,KAAK,UAAUnD,EAAMkD,CAAI,CAC1B,CAEQ,WAAWlD,EAAuB,CACzC,IAAMoD,EAAW,KAAK,SAAS,IAAIpD,CAAI,EACvC,GAAIoD,EAAU,OAAOA,EAAS,UAC9B,GAAI,KAAK,QAAQ,KAAK,OAAS,EAAG,OAAO,KAAK,QAAQ,KAAK,IAAI,EAC/D,GAAI,KAAK,QAAQ,MAAQ,KAAK,QAAQ,IACrC,MAOGzC,EAAQ,CAAC,EAEb,OAAO,KAAK,QAAQ,MACrB,CAEQ,eAAe0C,EAAkD,CACxE,GAAM,CAAE,GAAA3C,CAAG,EAAI,KACT4C,EAAuBD,GAAS,eAChCE,EAAaF,GAAS,MAAQtE,EAA6BuE,CAAoB,GAAK,gBACpFrB,EAAO,KAAK,eAAesB,CAAU,EACrCvE,EAAuBsE,GAAwB,KAAK,YAAY,IAAIrB,CAAI,GAAK,QAC7EuB,EAAuB,mCAAmC,KAAKxE,CAAoB,EACnFyE,EAAeJ,GAAS,SAAWG,EAAuB,eAAiB,QAC3EE,EAAiC,CACtC,KAAAzB,EACA,OAAQ,KAAK,eAAewB,CAAY,EACxC,eAAgB,KAAK,eAAezE,CAAoB,EACxD,UAAW,KAAK,eAAeqE,GAAS,WAAa,QAAQ,EAC7D,UAAW,KAAK,eAAeA,GAAS,WAAa,QAAQ,EAC7D,MAAO,KAAK,eAAeA,GAAS,OAAS,eAAe,EAC5D,MAAO,KAAK,eAAeA,GAAS,OAAS,eAAe,EAC5D,WAAYA,GAAS,WACrB,UAAWA,GAAS,UACpB,qBAAAG,CACD,EAGA,IAF2BE,EAAO,iBAAmBhD,EAAG,SAAWgD,EAAO,iBAAmBhD,EAAG,UAEtE,CAACA,EAAG,aAAa,wBAAwB,EAClE,MAKGC,EAAQ,CAAC,EAEb,OAAO+C,CACR,CAEQ,WAAWzB,EAAc0B,EAA+B,CAC/D,IAAMC,EAAY,KAAK,WAAW,IAAI3B,CAAI,GAAK,WAC/C,OAAO,IAAI2B,EAAUD,CAAI,CAC1B,CAEQ,OAAOE,EAAyB,CACvC,IAAMnD,EAAK,KAAK,GAChB,OAAOmD,IAAWnD,EAAG,MAAQmD,IAAWnD,EAAG,YAC5C,CAEQ,mBAAmBoD,EAA4B,CACtD,GAAI,CAACA,EAAY,QAAS,OAE1B,IAAMpD,EAAK,KAAK,GACV,CAAE,KAAAuB,EAAM,OAAA4B,CAAO,EAAIC,EAAY,QAC/BC,EAAc,KAAK,WAAW9B,EAAM6B,EAAY,MAAQA,EAAY,OAAS,CAAC,EACpFpD,EAAG,cAAcA,EAAG,SAAWoD,EAAY,SAAS,EACpDpD,EAAG,YAAYA,EAAG,iBAAkBoD,EAAY,OAAO,EACvD,IAAME,EAAoB,CAAC,KAAK,OAAOH,CAAM,EACzCI,EACAD,IACHC,EAAoBvD,EAAG,aAAaA,EAAG,gBAAgB,EACvDA,EAAG,YAAYA,EAAG,iBAAkB,CAAC,GAEtC,QAASwD,EAAQ,EAAGA,EAAQJ,EAAY,QAAQ,MAAO,EAAEI,EACxDxD,EAAG,cACFA,EAAG,iBACH,EACA,EACA,EACAwD,EACAJ,EAAY,MACZA,EAAY,OACZ,EACAD,EACA5B,EACA8B,CACD,EAEGC,GAAmBtD,EAAG,YAAYA,EAAG,iBAAkBuD,CAAiB,CAC7E,CAEQ,kBACPjE,EACAmE,EACAd,EAGC,CACD,KAAK,eACJ,CACC,CAAC,GAAGtD,EAAWC,CAAI,CAAC,aAAa,EAAGmE,CACrC,EACAd,CACD,CACD,CAEQ,UAAUrD,EAAuB8D,EAAsB,CACzDA,EAAY,UACjBA,EAAY,QAAQ,WAAa,EACjC,KAAK,mBAAmBA,CAAW,EACnC,KAAK,kBAAkB9D,EAAM,EAAG,CAAE,aAAc,EAAK,CAAC,EACvD,CAEA,kBACCA,EACAiC,EACAP,EACA2B,EACC,CACD,IAAMe,EAAcf,GAAS,YACvBgB,EAAehB,GAAS,cAAgB,GAC9C,GAAI,KAAK,SAAS,IAAIrD,CAAI,EACzB,MAAmFW,EAAQ,CAAC,EAE7F,GAAI,CAAC7B,EAAsBmD,CAAI,EAC9B,MAMGtB,EAAQ,CAAC,EAEb,GAAIyD,GAAe,EAAE,MAAM,QAAQ1C,CAAK,GAAKA,EAAM,SAAW0C,GAC7D,MAMGzD,EAAQ,CAAC,EAGb,IAAMD,EAAK,KAAK,GACZ4D,EAAW5D,EAAG,mBAAmB,KAAK,QAAUV,CAAI,EAIxD,GAHI,CAACsE,GAAYF,IAChBE,EAAW5D,EAAG,mBAAmB,KAAK,QAAU,GAAGV,CAAI,KAAK,GAEzD,CAACsE,EAAU,CACd,GAAID,EAAc,OAClB,MAAoF1D,EAAQ,EAAE,CAC/F,CAEA,IAAM4D,EAAaH,EAAe1C,EAAgC,CAAC,EAAIA,EACjE8C,EAAS,MAAM,QAAQD,CAAU,EAAKA,EAAW,OAA2B,EAClF,KAAK,SAAS,IAAIvE,EAAM,CAAE,KAAAiC,EAAM,OAAAuC,EAAQ,SAAAF,EAAU,YAAAF,CAAY,CAAC,EAE/D,GAAI,CACH,KAAK,eAAe,CAAE,CAACpE,CAAI,EAAG0B,CAAM,CAAC,CACtC,OAAS+C,EAAO,CACf,WAAK,SAAS,OAAOzE,CAAI,EACnByE,CACP,CACA,KAAK,KAAK,oBAAqB,GAAG,SAAS,CAC5C,CAEA,eACCC,EACArB,EACC,CACD,IAAM3C,EAAK,KAAK,GAChBA,EAAG,WAAW,KAAK,OAAO,EAC1B,OAAO,QAAQgE,CAAO,EAAE,QAAQ,CAAC,CAAC1E,EAAM2E,CAAQ,IAAM,CACrD,IAAMC,EAAU,KAAK,SAAS,IAAI5E,CAAI,EACtC,GAAI,CAAC4E,EAAS,CACb,GAAIvB,GAAS,aAAc,OAC3B,MAKG1C,EAAQ,EAAE,CACd,CACA,IAAIkE,EAAiB,UAAUD,EAAQ,MAAM,GAAG9F,EAAsB8F,EAAQ,IAAI,CAAC,GACnF,GAAIA,EAAQ,YAAa,CACxB,GAAI,CAAC,MAAM,QAAQD,CAAQ,EAC1B,MAKGhE,EAAQ,EAAE,EAEd,IAAMmE,EAAUH,EAAS,OACzB,GAAI,CAACG,EAAS,OACd,GAAIA,EAAUF,EAAQ,YACrB,MAMGjE,EAAQ,EAAE,EAEd,GAAIgE,EAAS,KAAKI,IAAS,MAAM,QAAQA,CAAI,EAAIA,EAAK,OAAS,KAAOH,EAAQ,MAAM,EACnF,MAKGjE,EAAQ,EAAE,EAEd,IAAMqE,EAAOL,EAAS,KAAK,EACrBM,EACLL,EAAQ,OAAS,QACd,IAAI,aAAaI,CAAI,EACrBJ,EAAQ,OAAS,OAChB,IAAI,YAAYI,CAAI,EACpB,IAAI,WAAWA,CAAI,EACpBV,EAAWM,EAAQ,SACvB,GAAIvB,GAAS,WAAY,CACxB,IAAM6B,EAAcxE,EAAG,mBAAmB,KAAK,QAAU,GAAGV,CAAI,IAAIqD,EAAQ,UAAU,GAAG,EACzF,GAAI,CAAC6B,EACJ,MAMGvE,EAAQ,EAAE,EAEd2D,EAAWY,CACZ,CACCxE,EAAWmE,EAAiB,GAAG,EAAEP,EAAUW,CAAU,CACvD,KAAO,CACD,MAAM,QAAQN,CAAQ,IAAGA,EAAW,CAACA,CAAQ,GAClD,IAAMQ,EAAcR,EACpB,GAAIQ,EAAY,SAAWP,EAAQ,OAClC,MAMGjE,EAAQ,EAAE,EAEbD,EAAWmE,CAAc,EAAED,EAAQ,SAAU,GAAGO,CAAW,CAC7D,CACD,CAAC,EACD,KAAK,KAAK,iBAAkB,GAAG,SAAS,CACzC,CAEQ,UACPnF,EACA8D,EACC,CACD,IAAMpD,EAAK,KAAK,GACV,CAAE,MAAAF,EAAO,OAAAC,CAAO,EAAIqD,EACpBsB,EAAetB,EAAY,SAAS,OAAS,EAE7CX,EAAUzC,EAAG,cAAc,EACjC,GAAI,CAACyC,EACJ,MAOGxC,EAAQ,EAAE,EAGd,IAAI0E,EAAYvB,EAAY,UAC5B,GAAI,OAAOuB,GAAc,SACxB,GAAI,CACHA,EAAY,KAAK,WAAWrF,CAAI,CACjC,OAASyE,EAAO,CACf,MAAA/D,EAAG,cAAcyC,CAAO,EAClBsB,CACP,CAGD,IAAMa,EAAaF,EAAe,EAC5BG,EAAgBD,EAAa5E,EAAG,iBAAmBA,EAAG,WACtD,CAAE,QAAA2C,CAAQ,EAAIS,EACpB,OAAApD,EAAG,cAAcA,EAAG,SAAW2E,CAAS,EACxC3E,EAAG,YAAY6E,EAAepC,CAAO,EACrCzC,EAAG,cAAc6E,EAAe7E,EAAG,eAAgB2C,EAAQ,KAAK,EAChE3C,EAAG,cAAc6E,EAAe7E,EAAG,eAAgB2C,EAAQ,KAAK,EAChE3C,EAAG,cAAc6E,EAAe7E,EAAG,mBAAoB2C,EAAQ,SAAS,EACxE3C,EAAG,cAAc6E,EAAe7E,EAAG,mBAAoB2C,EAAQ,SAAS,EACpEiC,EACH5E,EAAG,aAAa6E,EAAe,EAAGlC,EAAQ,eAAgB7C,EAAOC,EAAQ2E,CAAY,EAC3EpF,IAASb,GACnBuB,EAAG,WACFA,EAAG,WACH,EACA2C,EAAQ,eACR7C,EACAC,EACA,EACA4C,EAAQ,OACRA,EAAQ,KACR,IACD,EAEM,CAAE,QAAAF,EAAS,UAAAkC,CAAU,CAC7B,CAEQ,QAAQrF,EAAuBH,EAAuBwD,EAAoC,CACjG,IAAM3C,EAAK,KAAK,GAChB,GAAI,KAAK,SAAS,IAAIV,CAAI,EACzB,MAAoEW,EAAQ,EAAE,EAG/E,GAAM,CAAE,QAASyE,EAAe,EAAG,GAAG7E,CAAW,EAAI8C,GAAW,CAAC,EAC3D,CAAE,MAAA7C,EAAO,OAAAC,CAAO,EAAIb,EAAoBC,CAAM,EACpD,GAAI,CAACW,GAAS,CAACC,EACd,MAOGE,EAAQ,EAAE,EAEd,IAAMmD,EAAyE,CAC9E,MAAAtD,EACA,OAAAC,EACA,QACCZ,aAAkBI,GAClB,OAAO,KAAKM,CAAU,EAAE,SAAW,GACnCV,EAAO,SAAS,IAAIV,CAAwB,EACzCU,EAAO,SAAS,IAAIV,CAAwB,EAAG,QAC/C,KAAK,eAAeoB,CAAU,CACnC,EACI6E,EAAe,IAClBtB,EAAY,QAAU,CAAE,MAAOsB,EAAc,WAAY,CAAE,GAE5D,GAAM,CAAE,QAAAjC,EAAS,UAAAkC,CAAU,EAAI,KAAK,UAAUrF,EAAM8D,CAAW,EACzD0B,EAA+B,CACpC,QAAArC,EACA,UAAAkC,EACA,GAAGvB,CACJ,EACIsB,EAAe,IAClB,KAAK,kBAAkB,GAAGrF,EAAWC,CAAI,CAAC,cAAe,MAAO,EAAG,CAAE,aAAc,EAAK,CAAC,EACzF,KAAK,mBAAmBwF,CAAmB,GAE5C,KAAK,SAAS,IAAIxF,EAAMwF,CAAmB,EACvCxF,IAASb,GAA4Ba,IAASd,GACjD,KAAK,UAAUc,EAAMH,CAAM,EAI5Ba,EAAG,WAAW,KAAK,OAAQ,EAC3B,IAAM+E,EAAW/E,EAAG,mBAAmB,KAAK,QAAUX,EAAWC,CAAI,CAAC,EAClEyF,GACH/E,EAAG,UAAU+E,EAAUJ,CAAS,CAElC,CAEA,kBAAkBrF,EAAcH,EAAuBwD,EAAoC,CAE1F,IAAMqC,EACLrC,GAAS,SAAW,MAAQA,EAAQ,QAAU,EAAI,CAAE,GAAGA,EAAS,QAASA,EAAQ,QAAU,CAAE,EAAIA,EAClG,KAAK,QAAQrD,EAAMH,EAAQ6F,CAAI,EAC/B,KAAK,KAAK,oBAAqB,GAAG,SAAS,CAC5C,CAEA,eAAehB,EAA8C,CAC5D,OAAO,QAAQA,CAAO,EAAE,QAAQ,CAAC,CAAC1E,EAAMH,CAAM,IAAM,CACnD,KAAK,UAAUG,EAAMH,CAAM,CAC5B,CAAC,EACD,KAAK,KAAK,iBAAkB,GAAG,SAAS,CACzC,CAEQ,UAAUG,EAAuBH,EAA6B8F,EAA6B,CAClG,IAAMjF,EAAK,KAAK,GACVwC,EAAO,KAAK,SAAS,IAAIlD,CAAI,EACnC,GAAI,CAACkD,EACJ,MAAoEvC,EAAQ,EAAE,EAG/E,GAAId,aAAkB,aAAc,CACnCa,EAAG,cAAcA,EAAG,SAAWwC,EAAK,SAAS,EAC7CxC,EAAG,YAAYA,EAAG,WAAYb,CAAM,EACpC,MACD,CAEA,IAAI+F,EAAqB/F,EACzB,GAAIA,aAAkBI,EAAW,CAChC,IAAM4F,EAAyBhG,EAAO,SAAS,IAAIV,CAAwB,EACrE2G,EAAOD,EAAuB,MAC9BE,EAAOF,EAAuB,OAEpC,GAAIhG,EAAO,KAAOa,EAAI,CACrB,GAAI,CAACwC,EAAK,QAAS,CAClBxC,EAAG,cAAcA,EAAG,SAAWwC,EAAK,SAAS,EAC7CxC,EAAG,YAAYA,EAAG,WAAYmF,EAAuB,OAAO,EAC5D,MACD,CACA,GAAM,CAAE,MAAAG,CAAM,EAAI9C,EAAK,QACjB+C,EACLN,IAAiB,OACd,CAACzC,EAAK,QAAQ,UAAU,EACxB,MAAM,QAAQyC,CAAY,EACzBA,EAAa,IAAIO,GAAKC,EAAQD,EAAGF,CAAK,CAAC,EACvC,CAACG,EAAQR,EAAcK,CAAK,CAAC,EAClCtF,EAAG,cAAcA,EAAG,SAAWwC,EAAK,SAAS,EAC7CxC,EAAG,YAAYA,EAAG,iBAAkBwC,EAAK,OAAO,EAChDxC,EAAG,gBAAgBA,EAAG,iBAAkBb,EAAO,eAAe,EAC9D,QAAWuG,KAAQH,EAClBvF,EAAG,kBAAkBA,EAAG,iBAAkB,EAAG,EAAG,EAAG0F,EAAM,EAAG,EAAGN,EAAMC,CAAI,EAE1ErF,EAAG,gBAAgBA,EAAG,iBAAkB,IAAI,EAC5C,KAAK,kBAAkBV,EAAMiG,EAAYA,EAAY,OAAS,CAAC,EAAG,CAAE,aAAc,EAAK,CAAC,EACpFN,IAAiB,SACpBzC,EAAK,QAAQ,YAAcA,EAAK,QAAQ,WAAa,GAAK8C,GAE3D,MACD,CAGA,GAAM,CACL,MAAAxF,EACA,OAAAC,EACA,QAAS,CAAE,OAAAoD,EAAQ,KAAA5B,CAAK,CACzB,EAAI4D,EACEQ,EAAS,KAAK,WAAWpE,EAAMzB,EAAQC,EAAS,CAAC,EACvDZ,EAAO,GAAG,gBAAgBA,EAAO,GAAG,YAAaA,EAAO,eAAe,EACvEA,EAAO,GAAG,WAAW,EAAG,EAAGW,EAAOC,EAAQoD,EAAQ5B,EAAMoE,CAAM,EAC9DxG,EAAO,GAAG,gBAAgBA,EAAO,GAAG,YAAa,IAAI,EACrD+F,EAAqB,CAAE,KAAMS,EAAQ,MAAA7F,EAAO,OAAAC,CAAO,CACpD,CAGA,GAAM,CAAE,MAAAD,EAAO,OAAAC,CAAO,EAAIb,EAAoBgG,CAAkB,EAChE,GAAI,CAACpF,GAAS,CAACC,EAAQ,OAEvB,IAAM6F,EAAY,cAAeV,GAAsBA,EAAmB,UACrEU,GACJ,KAAK,UAAUtG,EAAMQ,EAAOC,CAAM,EAInC,IAAM8F,EAAkB,SAAUX,GAAsBA,EAAmB,KACrEY,EAAc,CAACD,GAAmB,CAACrD,EAAK,SAAS,UACjDuD,EAAgB/F,EAAG,aAAaA,EAAG,mBAAmB,EACtDsD,EAAoBuC,GAAmB,CAAC,KAAK,OAAOrD,EAAK,QAAQ,MAAM,EACvEwD,EAA0B,CAACH,GAAmBrD,EAAK,QAAQ,YAAc,qBAAsBxC,EAC/FiG,EAAqBjG,EAAG,iBAC1BuD,EAOJ,GANID,IACHC,EAAoBvD,EAAG,aAAaA,EAAG,gBAAgB,EACvDA,EAAG,YAAYA,EAAG,iBAAkB,CAAC,GAElCgG,IAAyBhG,EAAG,iBAAmBwC,EAAK,QAAQ,YAE5DA,EAAK,QAAS,CACjBxC,EAAG,cAAcA,EAAG,SAAWwC,EAAK,SAAS,EAC7CxC,EAAG,YAAYA,EAAG,iBAAkBwC,EAAK,OAAO,EAChD,GAAM,CAAE,MAAA8C,CAAM,EAAI9C,EAAK,QACjB+C,EACLN,IAAiB,OACd,CAACzC,EAAK,QAAQ,UAAU,EACxB,MAAM,QAAQyC,CAAY,EACzBA,EAAa,IAAIO,GAAKC,EAAQD,EAAGF,CAAK,CAAC,EACvC,CAACG,EAAQR,EAAcK,CAAK,CAAC,EAElCtF,EAAG,YAAYA,EAAG,oBAAqB8F,CAAW,EAClD,IAAMI,EAAgBhB,EAChBiB,EACLD,EAAc,MAAShB,EAClBkB,EAAUR,EAAaM,EAAc,GAAK,EAAK,EAC/CG,EAAUT,EAAaM,EAAc,GAAK,EAAK,EAErD,QAAWR,KAAQH,EAClBvF,EAAG,cACFA,EAAG,iBACH,EACAoG,EACAC,EACAX,EACA5F,EACAC,EACA,EACAyC,EAAK,QAAQ,OACbA,EAAK,QAAQ,KACb2D,CACD,EAEDnG,EAAG,YAAYA,EAAG,oBAAqB+F,CAAa,EACpD,KAAK,kBAAkBzG,EAAMiG,EAAYA,EAAY,OAAS,CAAC,CAAC,EAC5DN,IAAiB,SACpBzC,EAAK,QAAQ,YAAcA,EAAK,QAAQ,WAAa,GAAK8C,EAE5D,KAAO,CAKN,GAJAtF,EAAG,cAAcA,EAAG,SAAWwC,EAAK,SAAS,EAC7CxC,EAAG,YAAYA,EAAG,WAAYwC,EAAK,OAAO,EAC1CxC,EAAG,YAAYA,EAAG,oBAAqB8F,CAAW,EAE9CF,EAAW,CACd,IAAMM,EAAgBhB,EACtBlF,EAAG,cACFA,EAAG,WACH,EACAkG,EAAc,GAAK,EACnBA,EAAc,GAAK,EACnBpG,EACAC,EACAyC,EAAK,QAAQ,OACbA,EAAK,QAAQ,KACb0D,EAAc,IACf,CACD,MACClG,EAAG,WACFA,EAAG,WACH,EACAwC,EAAK,QAAQ,eACb1C,EACAC,EACA,EACAyC,EAAK,QAAQ,OACbA,EAAK,QAAQ,KACX0C,EAA4C,MAC5CA,CACH,EAEDlF,EAAG,YAAYA,EAAG,oBAAqB+F,CAAa,CACrD,CAEIC,IAAyBhG,EAAG,iBAAmBiG,GAC/C3C,GAAmBtD,EAAG,YAAYA,EAAG,iBAAkBuD,CAAiB,CAC7E,CAEQ,kBAAmB,CAC1B,IAAMvD,EAAK,KAAK,GACVsG,EAAmB,KAAK,SAAS,IAAI7H,CAAwB,EACnEuB,EAAG,gBAAgBA,EAAG,YAAa,KAAK,eAAe,EACvDA,EAAG,qBAAqBA,EAAG,YAAaA,EAAG,kBAAmBA,EAAG,WAAYsG,EAAiB,QAAS,CAAC,CACzG,CAEA,OAAQ,CACP,KAAK,iBAAiB,EACtB,IAAMtG,EAAK,KAAK,GACVsG,EAAmB,KAAK,SAAS,IAAI7H,CAAwB,EACnE,GAAI6H,EAAiB,QAAQ,qBAAsB,CAClD,IAAMC,EAAID,EAAiB,QAAQ,KAC/B,KAAK,UAAU,IAAIC,CAAC,EACvBvG,EAAG,eAAeA,EAAG,MAAO,EAAG,IAAI,YAAY,CAAC,CAAC,EAEjDA,EAAG,cAAcA,EAAG,MAAO,EAAG,IAAI,WAAW,CAAC,CAAC,CAEjD,MACCA,EAAG,MAAMA,EAAG,gBAAgB,CAE9B,CAEA,KAAK2C,EAA8B,CAClC,KAAK,KAAK,UAAW,GAAG,SAAS,EACjC,IAAM3C,EAAK,KAAK,GACVwG,EAAIxG,EAAG,mBACPyG,EAAIzG,EAAG,oBAET2C,GAAS,UACZ,KAAK,iBAAiB,EAEtB,KAAK,MAAM,EAGZ3C,EAAG,WAAW,KAAK,OAAO,EAC1BA,EAAG,gBAAgB,KAAK,GAAG,EAC3BA,EAAG,SAAS,EAAG,EAAGwG,EAAGC,CAAC,EACtBzG,EAAG,WAAWA,EAAG,UAAW,EAAG,CAAC,EAE3B,KAAK,YACgB,KAAK,SAAS,IAAIvB,CAAwB,EAC7C,QAAQ,uBAC7BuB,EAAG,gBAAgBA,EAAG,iBAAkB,KAAK,eAAe,EAC5DA,EAAG,gBAAgBA,EAAG,iBAAkB,IAAI,EAC5CA,EAAG,gBAAgB,EAAG,EAAGwG,EAAGC,EAAG,EAAG,EAAGD,EAAGC,EAAGzG,EAAG,iBAAkBA,EAAG,OAAO,EAC1EA,EAAG,gBAAgBA,EAAG,YAAa,IAAI,GAGzC,KAAK,KAAK,WAAY,GAAG,SAAS,CACnC,CAEA,KAAK2C,EAAuB,CAC3B,KAAK,MAAM,YAAY,IAAI,EAAGA,CAAO,CACtC,CAEQ,MAAO,CACd,IAAMqB,EAAkC,CAAC,EACrC,KAAK,SAAS,IAAI,QAAQ,IAAGA,EAAQ,OAAS,KAAK,UACnD,KAAK,SAAS,IAAI,SAAS,IAAGA,EAAQ,QAAU,KAAK,OACrD,OAAO,KAAKA,CAAO,EAAE,QAAQ,KAAK,eAAeA,CAAO,CAC7D,CAEQ,MAAM0C,EAAa1B,EAA4E,CACtG,IAAMuB,EAAI,KAAK,WAAWG,CAAG,EAC7B,KAAK,SAAWH,EAChB,KAAK,OAASG,EACd,IAAM/D,EAAU,OAAOqC,GAAS,WAAaA,EAAKuB,EAAG,KAAK,KAAK,EAAIvB,EACnE,KAAK,KAAK,UAAWuB,EAAG,KAAK,MAAO5D,CAAO,EAC3C,KAAK,KAAK,EACV,KAAK,KAAKA,CAAO,EACjB,IAAMgE,EAAc,KAAK,SAAS,IAAInI,CAAmB,EACzD,GAAImI,GAAe,CAAChE,GAAS,YAAa,CACzC,GAAM,CAAE,WAAAiE,EAAY,MAAAtB,CAAM,EAAIqB,EAAY,QACpC3G,EAAK,KAAK,GAChBA,EAAG,gBAAgBA,EAAG,iBAAkB,KAAK,eAAe,EAC5DA,EAAG,YAAYA,EAAG,iBAAkB2G,EAAY,OAAO,EACvD3G,EAAG,kBACFA,EAAG,iBACH,EACA,EACA,EACA4G,EACA,EACA,EACA5G,EAAG,mBACHA,EAAG,mBACJ,EACAA,EAAG,gBAAgBA,EAAG,iBAAkB,IAAI,EAC5C,IAAM6G,GAAkBD,EAAa,GAAKtB,EAC1C,KAAK,kBAAkB9G,EAAqBqI,EAAgB,CAAE,aAAc,EAAK,CAAC,EAClFF,EAAY,QAAS,WAAaE,CACnC,CACA,EAAE,KAAK,MACP,KAAK,KAAK,WAAYN,EAAG,KAAK,MAAO5D,CAAO,CAC7C,CAEA,KAAKmE,EAAiE,CACrE,KAAK,OAAO,EACZ,IAAMC,EAAQL,GAAgB,CAC7B,KAAK,MAAMA,EAAKI,CAAS,EACrB,KAAK,SAAW,OAAM,KAAK,QAAU,sBAAsBC,CAAI,EACpE,EACA,KAAK,QAAU,sBAAsBA,CAAI,EACzC,KAAK,KAAK,MAAM,CACjB,CAEQ,WAAWC,EAAc,CAChC,OAAI,MAAM,KAAK,MAAM,EAAU,KAAK,SAC7B,KAAK,UAAYA,EAAO,KAAK,QAAU,GAC/C,CAEQ,QAAS,CAChB,GAAI,QAAM,KAAK,MAAM,GAAK,KAAK,SAAW,MAC1C,OAAI,KAAK,SAAW,OACnB,qBAAqB,KAAK,OAAO,EACjC,KAAK,QAAU,MAEhB,KAAK,SAAW,KAAK,WAAW,YAAY,IAAI,CAAC,EACjD,KAAK,OAAS,IACP,EACR,CAEA,OAAQ,CACH,KAAK,OAAO,GAAG,KAAK,KAAK,OAAO,CACrC,CAEA,QAAS,CACR,KAAK,MAAQ,EACb,KAAK,SAAW,EAChB,KAAK,OAAS,IACd,KAAK,KAAK,CACX,CAEA,OAAQ,CACP,KAAK,OAAO,EACZ,KAAK,SAAS,QAAQ,CAACvE,EAASnD,IAAS,CACxC,KAAK,UAAUA,EAAMmD,CAAO,CAC7B,CAAC,EACD,KAAK,MAAM,EACX,KAAK,KAAK,OAAO,CAClB,CAEA,SAAU,CACT,KAAK,KAAK,SAAS,EAEnB,KAAK,OAAO,EACZ,IAAMzC,EAAK,KAAK,GAEZ,KAAK,YACR,KAAK,UAAU,QAAQ,CAACsC,EAAUH,IAAU,CAC3C,KAAK,UAAW,oBAAoBA,EAAOG,CAAQ,CACpD,CAAC,EACD,KAAK,UAAU,MAAM,GAGlB,KAAK,cACR,KAAK,YAAY,WAAW,EAC5B,KAAK,YAAc,MAGhB,KAAK,UACRtC,EAAG,cAAc,KAAK,OAAO,EAC7B,KAAK,QAAU,MAGZ,KAAK,kBACRA,EAAG,kBAAkB,KAAK,eAAe,EACzC,KAAK,gBAAkB,MAGxB,KAAK,SAAS,QAAQyC,GAAW,CAChC,KAAK,QAAQ,KAAK,KAAKA,EAAQ,SAAS,EACxCzC,EAAG,cAAcyC,EAAQ,OAAO,CACjC,CAAC,EACD,KAAK,SAAS,MAAM,EACpB,IAAM3B,EAAQpC,EAAe,IAAI,KAAK,MAAM,EACxCoC,IACHA,EAAM,UAAU,OAAO,IAAI,EACvBA,EAAM,UAAU,OAAS,GAC5BpC,EAAe,OAAO,KAAK,MAAM,GAI/B,KAAK,MACRsB,EAAG,kBAAkB,KAAK,GAAG,EAC7B,KAAK,IAAM,MAGR,KAAK,SACRA,EAAG,aAAa,KAAK,MAAM,EAC3B,KAAK,OAAS,MAGf,KAAK,SAAS,MAAM,EACpB,KAAK,MAAM,MAAM,CAClB,CACD,EAEOiH,EAAQ7H","names":["DEFAULT_VERTEX_SHADER_SRC","FORMAT_TYPE_SUFFIXES","UNIFORM_TYPE_SUFFIXES","typeFromInternalFormatString","internalFormatString","suffix","HISTORY_TEXTURE_KEY","INTERMEDIATE_TEXTURE_KEY","canvasRegistry","combineShaderCode","shader","injections","lines","insertAt","line","trimmed","getSourceDimensions","source","ShaderPad","stringFrom","name","_ShaderPad","fragmentShaderSrc","canvas","plugins","history","cursorTarget","texOptions","width","height","gl","spError","registryEntry","glslInjections","plugin","code","program","vertexShader","fragmentShader","linkError","wrapDimension","dimension","descriptor","v","entry","instance","value","resolved","args","hook","fn","hooks","index","type","compilationError","target","updateCursor","x","y","rect","u","updateClick","isClicked","xVal","yVal","event","mouseEvent","touchEvent","listener","resolution","info","texture","existing","options","internalFormatOption","typeString","isIntegerColorFormat","formatString","result","size","ArrayType","format","textureInfo","transparent","needsAlignmentFix","previousAlignment","layer","frameOffset","arrayLength","allowMissing","location","probeValue","length","error","updates","newValue","uniform","glFunctionName","nValues","item","flat","typedArray","newLocation","scalarValue","historyDepth","unitIndex","hasHistory","textureTarget","completeTextureInfo","uSampler","opts","historySlots","nonShaderPadSource","sourceIntermediateInfo","srcW","srcH","depth","targetSlots","i","safeMod","slot","pixels","isPartial","isCustomTexture","shouldFlipY","previousFlipY","shouldConvertColorSpace","previousColorSpace","partialSource","sourceData","xOffset","yOffset","intermediateInfo","t","w","h","now","historyInfo","writeIndex","nextWriteIndex","onPreStep","loop","time","index_default"]}
@@ -0,0 +1,2 @@
1
+ function T(e){let t=e.ownerDocument.defaultView??window,n=e.getBoundingClientRect();return n.width>0&&n.height>0&&n.bottom>0&&n.right>0&&n.top<t.innerHeight&&n.left<t.innerWidth}function M({target:e,autoplay:t,autopause:n,isPlaying:a,play:s,pause:i,onVisibilityChange:u}){let o=e.ownerDocument,l=t,f=n,p=o.visibilityState==="visible",m=T(e),c=!1,v=null,h=()=>p&&(typeof IntersectionObserver=="function"?m:T(e))&&e.isConnected,d=()=>{let r=h();if(v!==r&&(v=r,u?.(r)),!l){c&&a()&&i(),c=!1;return}if(!f||r){a()||s(),c=!0;return}c&&a()&&i(),c=!1},E=()=>{p=o.visibilityState==="visible",d()};o.addEventListener("visibilitychange",E);let b=typeof IntersectionObserver=="function"?new IntersectionObserver(r=>{m=r.some(x=>x.isIntersecting),d()}):null;return b?.observe(e),{sync:d,update(r){l=r.autoplay,f=r.autopause,d()},destroy(){b?.disconnect(),o.removeEventListener("visibilitychange",E)}}}var V=[["internal-format","internalFormat"],["format","format"],["type","type"],["min-filter","minFilter"],["mag-filter","magFilter"],["wrap-s","wrapS"],["wrap-t","wrapT"],["color-space","colorSpace"]];function y(e){if(!(e==null||e===!1))return String(e)}function g(e,t){if(e==null)return t;if(typeof e=="boolean")return e;switch(String(e).trim().toLowerCase()){case"false":case"0":case"no":case"off":return!1;default:return!0}}function w(e,t=""){let n={},a=y(e(`${t}history`));if(a!=null){let i=Number.parseInt(a,10);Number.isFinite(i)&&i>=0&&(n.history=i)}let s=e(`${t}preserve-y`);s!=null&&(n.preserveY=g(s,!0));for(let[i,u]of V){let o=y(e(`${t}${i}`));o&&(n[u]=o)}return n}function D(e,t=""){return w(n=>e.getAttribute(n),t)}function S(e){return e instanceof HTMLImageElement||e instanceof HTMLVideoElement||e instanceof HTMLCanvasElement}function O(e){return!(e instanceof HTMLImageElement)}function L(e,t){let n={once:!0};return new Promise((a,s)=>{let i=()=>{e.removeEventListener(t,u),e.removeEventListener("error",o)},u=l=>{i(),a(l)},o=l=>{i(),s(l)};e.addEventListener(t,u,n),e.addEventListener("error",o,n)})}async function H(e){return e.complete&&e.naturalWidth>0&&e.naturalHeight>0||await L(e,"load"),e}async function I(e){return e.videoWidth>0&&e.videoHeight>0||await L(e,"loadedmetadata"),e}async function P(e){if(e instanceof HTMLImageElement)return H(e);if(e instanceof HTMLVideoElement)return I(e);if(e.width<=0||e.height<=0)throw new Error("Texture canvas elements must have a positive width and height.");return e}function k(e){if(e instanceof HTMLVideoElement)return e.videoWidth>0&&e.videoHeight>0?e:void 0;if(e instanceof HTMLCanvasElement)return e.width>0&&e.height>0?e:void 0}function A(e,t){if(e instanceof HTMLImageElement)return e.addEventListener("load",t),()=>e.removeEventListener("load",t);if(e instanceof HTMLVideoElement)return e.addEventListener("loadedmetadata",t),()=>e.removeEventListener("loadedmetadata",t)}export{M as a,g as b,w as c,D as d,S as e,O as f,P as g,k as h,A as i};
2
+ //# sourceMappingURL=chunk-FVO6LH2F.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/autoplay.ts","../src/internal/declarative-textures.ts"],"sourcesContent":["export type PlaybackVisibilityController = {\n\tsync: () => void;\n\tupdate: (options: { autoplay: boolean; autopause: boolean }) => void;\n\tdestroy: () => void;\n};\n\ntype PlaybackVisibilityOptions = {\n\ttarget: HTMLElement;\n\tautoplay: boolean;\n\tautopause: boolean;\n\tisPlaying: () => boolean;\n\tplay: () => void;\n\tpause: () => void;\n\tonVisibilityChange?: (isVisible: boolean) => void;\n};\n\nfunction isElementInViewport(element: HTMLElement) {\n\tconst view = element.ownerDocument.defaultView ?? window;\n\tconst rect = element.getBoundingClientRect();\n\treturn (\n\t\trect.width > 0 &&\n\t\trect.height > 0 &&\n\t\trect.bottom > 0 &&\n\t\trect.right > 0 &&\n\t\trect.top < view.innerHeight &&\n\t\trect.left < view.innerWidth\n\t);\n}\n\nexport function createPlaybackVisibilityController({\n\ttarget,\n\tautoplay,\n\tautopause,\n\tisPlaying,\n\tplay,\n\tpause,\n\tonVisibilityChange,\n}: PlaybackVisibilityOptions): PlaybackVisibilityController {\n\tconst documentRef = target.ownerDocument;\n\tlet currentAutoplay = autoplay;\n\tlet currentAutopause = autopause;\n\tlet isDocumentVisible = documentRef.visibilityState === 'visible';\n\tlet isIntersecting = isElementInViewport(target);\n\tlet isManagedPlayback = false;\n\tlet lastVisible: boolean | null = null;\n\n\tconst getIsVisible = () =>\n\t\tisDocumentVisible &&\n\t\t(typeof IntersectionObserver === 'function' ? isIntersecting : isElementInViewport(target)) &&\n\t\ttarget.isConnected;\n\n\tconst sync = () => {\n\t\tconst isVisible = getIsVisible();\n\t\tif (lastVisible !== isVisible) {\n\t\t\tlastVisible = isVisible;\n\t\t\tonVisibilityChange?.(isVisible);\n\t\t}\n\n\t\tif (!currentAutoplay) {\n\t\t\tif (isManagedPlayback && isPlaying()) {\n\t\t\t\tpause();\n\t\t\t}\n\t\t\tisManagedPlayback = false;\n\t\t\treturn;\n\t\t}\n\n\t\tif (!currentAutopause || isVisible) {\n\t\t\tif (!isPlaying()) {\n\t\t\t\tplay();\n\t\t\t}\n\t\t\tisManagedPlayback = true;\n\t\t\treturn;\n\t\t}\n\n\t\tif (isManagedPlayback && isPlaying()) {\n\t\t\tpause();\n\t\t}\n\t\tisManagedPlayback = false;\n\t};\n\n\tconst handleVisibilityChange = () => {\n\t\tisDocumentVisible = documentRef.visibilityState === 'visible';\n\t\tsync();\n\t};\n\tdocumentRef.addEventListener('visibilitychange', handleVisibilityChange);\n\n\tconst intersectionObserver =\n\t\ttypeof IntersectionObserver === 'function'\n\t\t\t? new IntersectionObserver(entries => {\n\t\t\t\t\tisIntersecting = entries.some(entry => entry.isIntersecting);\n\t\t\t\t\tsync();\n\t\t\t\t})\n\t\t\t: null;\n\tintersectionObserver?.observe(target);\n\n\treturn {\n\t\tsync,\n\t\tupdate(options) {\n\t\t\tcurrentAutoplay = options.autoplay;\n\t\t\tcurrentAutopause = options.autopause;\n\t\t\tsync();\n\t\t},\n\t\tdestroy() {\n\t\t\tintersectionObserver?.disconnect();\n\t\t\tdocumentRef.removeEventListener('visibilitychange', handleVisibilityChange);\n\t\t},\n\t};\n}\n","import type CoreShaderPad from '..';\nimport type { InitializeTextureOptions } from '..';\n\nexport type DomTextureElement = HTMLImageElement | HTMLVideoElement | HTMLCanvasElement;\nexport type LiveTextureSource = HTMLVideoElement | HTMLCanvasElement | CoreShaderPad;\n\nconst TEXTURE_OPTION_ATTRIBUTES = [\n\t['internal-format', 'internalFormat'],\n\t['format', 'format'],\n\t['type', 'type'],\n\t['min-filter', 'minFilter'],\n\t['mag-filter', 'magFilter'],\n\t['wrap-s', 'wrapS'],\n\t['wrap-t', 'wrapT'],\n\t['color-space', 'colorSpace'],\n] as const;\n\ntype AttributeValue = string | number | boolean | null | undefined;\n\nfunction stringFromAttribute(value: AttributeValue) {\n\tif (value == null || value === false) return undefined;\n\treturn String(value);\n}\n\nexport function parseBooleanLikeValue(value: AttributeValue, defaultValue: boolean) {\n\tif (value == null) return defaultValue;\n\tif (typeof value === 'boolean') return value;\n\n\tswitch (String(value).trim().toLowerCase()) {\n\t\tcase 'false':\n\t\tcase '0':\n\t\tcase 'no':\n\t\tcase 'off':\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn true;\n\t}\n}\n\nexport function parseTextureOptionsFromAttributes(\n\treadAttribute: (name: string) => AttributeValue,\n\tprefix = '',\n): InitializeTextureOptions {\n\tconst options: InitializeTextureOptions = {};\n\n\tconst historyValue = stringFromAttribute(readAttribute(`${prefix}history`));\n\tif (historyValue != null) {\n\t\tconst parsed = Number.parseInt(historyValue, 10);\n\t\tif (Number.isFinite(parsed) && parsed >= 0) options.history = parsed;\n\t}\n\n\tconst preserveYValue = readAttribute(`${prefix}preserve-y`);\n\tif (preserveYValue != null) {\n\t\toptions.preserveY = parseBooleanLikeValue(preserveYValue, true);\n\t}\n\n\tfor (const [attribute, option] of TEXTURE_OPTION_ATTRIBUTES) {\n\t\tconst value = stringFromAttribute(readAttribute(`${prefix}${attribute}`));\n\t\tif (value) (options as Record<string, unknown>)[option] = value;\n\t}\n\n\treturn options;\n}\n\nexport function parseTextureOptions(element: Element, prefix = '') {\n\treturn parseTextureOptionsFromAttributes(name => element.getAttribute(name), prefix);\n}\n\nexport function isDomTextureElement(element: Element): element is DomTextureElement {\n\treturn (\n\t\telement instanceof HTMLImageElement ||\n\t\telement instanceof HTMLVideoElement ||\n\t\telement instanceof HTMLCanvasElement\n\t);\n}\n\nexport function isLiveDomTextureElement(element: DomTextureElement) {\n\treturn !(element instanceof HTMLImageElement);\n}\n\nfunction onceEvent<T extends Event>(target: EventTarget, type: string): Promise<T> {\n\tconst options = { once: true };\n\n\treturn new Promise((resolve, reject) => {\n\t\tconst cleanup = () => {\n\t\t\ttarget.removeEventListener(type, onResolve);\n\t\t\ttarget.removeEventListener('error', onReject as EventListener);\n\t\t};\n\n\t\tconst onResolve = (event: Event) => {\n\t\t\tcleanup();\n\t\t\tresolve(event as T);\n\t\t};\n\n\t\tconst onReject = (event: Event) => {\n\t\t\tcleanup();\n\t\t\treject(event);\n\t\t};\n\n\t\ttarget.addEventListener(type, onResolve, options);\n\t\ttarget.addEventListener('error', onReject as EventListener, options);\n\t});\n}\n\nasync function loadImageSource(image: HTMLImageElement) {\n\tif (image.complete && image.naturalWidth > 0 && image.naturalHeight > 0) return image;\n\tawait onceEvent(image, 'load');\n\treturn image;\n}\n\nasync function loadVideoSource(video: HTMLVideoElement) {\n\tif (video.videoWidth > 0 && video.videoHeight > 0) return video;\n\tawait onceEvent(video, 'loadedmetadata');\n\treturn video;\n}\n\nexport async function loadDomTextureSource(element: DomTextureElement) {\n\tif (element instanceof HTMLImageElement) return loadImageSource(element);\n\tif (element instanceof HTMLVideoElement) return loadVideoSource(element);\n\tif (element.width <= 0 || element.height <= 0) {\n\t\tthrow new Error('Texture canvas elements must have a positive width and height.');\n\t}\n\treturn element;\n}\n\nexport function getLiveDomTextureSource(element: DomTextureElement) {\n\tif (element instanceof HTMLVideoElement) {\n\t\treturn element.videoWidth > 0 && element.videoHeight > 0 ? element : undefined;\n\t}\n\tif (element instanceof HTMLCanvasElement) {\n\t\treturn element.width > 0 && element.height > 0 ? element : undefined;\n\t}\n\treturn undefined;\n}\n\nexport function addDomTextureRefreshListener(element: DomTextureElement, listener: () => void) {\n\tif (element instanceof HTMLImageElement) {\n\t\telement.addEventListener('load', listener);\n\t\treturn () => element.removeEventListener('load', listener);\n\t}\n\tif (element instanceof HTMLVideoElement) {\n\t\telement.addEventListener('loadedmetadata', listener);\n\t\treturn () => element.removeEventListener('loadedmetadata', listener);\n\t}\n\treturn undefined;\n}\n"],"mappings":"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","names":["isElementInViewport","element","view","rect","createPlaybackVisibilityController","target","autoplay","autopause","isPlaying","play","pause","onVisibilityChange","documentRef","currentAutoplay","currentAutopause","isDocumentVisible","isIntersecting","isManagedPlayback","lastVisible","getIsVisible","sync","isVisible","handleVisibilityChange","intersectionObserver","entries","entry","options","TEXTURE_OPTION_ATTRIBUTES","stringFromAttribute","value","parseBooleanLikeValue","defaultValue","parseTextureOptionsFromAttributes","readAttribute","prefix","options","historyValue","parsed","preserveYValue","attribute","option","parseTextureOptions","element","name","isDomTextureElement","isLiveDomTextureElement","onceEvent","target","type","resolve","reject","cleanup","onResolve","onReject","event","loadImageSource","image","loadVideoSource","video","loadDomTextureSource","getLiveDomTextureSource","addDomTextureRefreshListener","listener"]}
@@ -78,7 +78,8 @@ var TEXTURE_OPTION_ATTRIBUTES = [
78
78
  ["min-filter", "minFilter"],
79
79
  ["mag-filter", "magFilter"],
80
80
  ["wrap-s", "wrapS"],
81
- ["wrap-t", "wrapT"]
81
+ ["wrap-t", "wrapT"],
82
+ ["color-space", "colorSpace"]
82
83
  ];
83
84
  function stringFromAttribute(value) {
84
85
  if (value == null || value === false) return void 0;
@@ -192,4 +193,4 @@ export {
192
193
  getLiveDomTextureSource,
193
194
  addDomTextureRefreshListener
194
195
  };
195
- //# sourceMappingURL=chunk-YN3AO6HP.mjs.map
196
+ //# sourceMappingURL=chunk-UOFU6ODR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/internal/autoplay.ts","../../src/internal/declarative-textures.ts"],"sourcesContent":["export type PlaybackVisibilityController = {\n\tsync: () => void;\n\tupdate: (options: { autoplay: boolean; autopause: boolean }) => void;\n\tdestroy: () => void;\n};\n\ntype PlaybackVisibilityOptions = {\n\ttarget: HTMLElement;\n\tautoplay: boolean;\n\tautopause: boolean;\n\tisPlaying: () => boolean;\n\tplay: () => void;\n\tpause: () => void;\n\tonVisibilityChange?: (isVisible: boolean) => void;\n};\n\nfunction isElementInViewport(element: HTMLElement) {\n\tconst view = element.ownerDocument.defaultView ?? window;\n\tconst rect = element.getBoundingClientRect();\n\treturn (\n\t\trect.width > 0 &&\n\t\trect.height > 0 &&\n\t\trect.bottom > 0 &&\n\t\trect.right > 0 &&\n\t\trect.top < view.innerHeight &&\n\t\trect.left < view.innerWidth\n\t);\n}\n\nexport function createPlaybackVisibilityController({\n\ttarget,\n\tautoplay,\n\tautopause,\n\tisPlaying,\n\tplay,\n\tpause,\n\tonVisibilityChange,\n}: PlaybackVisibilityOptions): PlaybackVisibilityController {\n\tconst documentRef = target.ownerDocument;\n\tlet currentAutoplay = autoplay;\n\tlet currentAutopause = autopause;\n\tlet isDocumentVisible = documentRef.visibilityState === 'visible';\n\tlet isIntersecting = isElementInViewport(target);\n\tlet isManagedPlayback = false;\n\tlet lastVisible: boolean | null = null;\n\n\tconst getIsVisible = () =>\n\t\tisDocumentVisible &&\n\t\t(typeof IntersectionObserver === 'function' ? isIntersecting : isElementInViewport(target)) &&\n\t\ttarget.isConnected;\n\n\tconst sync = () => {\n\t\tconst isVisible = getIsVisible();\n\t\tif (lastVisible !== isVisible) {\n\t\t\tlastVisible = isVisible;\n\t\t\tonVisibilityChange?.(isVisible);\n\t\t}\n\n\t\tif (!currentAutoplay) {\n\t\t\tif (isManagedPlayback && isPlaying()) {\n\t\t\t\tpause();\n\t\t\t}\n\t\t\tisManagedPlayback = false;\n\t\t\treturn;\n\t\t}\n\n\t\tif (!currentAutopause || isVisible) {\n\t\t\tif (!isPlaying()) {\n\t\t\t\tplay();\n\t\t\t}\n\t\t\tisManagedPlayback = true;\n\t\t\treturn;\n\t\t}\n\n\t\tif (isManagedPlayback && isPlaying()) {\n\t\t\tpause();\n\t\t}\n\t\tisManagedPlayback = false;\n\t};\n\n\tconst handleVisibilityChange = () => {\n\t\tisDocumentVisible = documentRef.visibilityState === 'visible';\n\t\tsync();\n\t};\n\tdocumentRef.addEventListener('visibilitychange', handleVisibilityChange);\n\n\tconst intersectionObserver =\n\t\ttypeof IntersectionObserver === 'function'\n\t\t\t? new IntersectionObserver(entries => {\n\t\t\t\t\tisIntersecting = entries.some(entry => entry.isIntersecting);\n\t\t\t\t\tsync();\n\t\t\t\t})\n\t\t\t: null;\n\tintersectionObserver?.observe(target);\n\n\treturn {\n\t\tsync,\n\t\tupdate(options) {\n\t\t\tcurrentAutoplay = options.autoplay;\n\t\t\tcurrentAutopause = options.autopause;\n\t\t\tsync();\n\t\t},\n\t\tdestroy() {\n\t\t\tintersectionObserver?.disconnect();\n\t\t\tdocumentRef.removeEventListener('visibilitychange', handleVisibilityChange);\n\t\t},\n\t};\n}\n","import type CoreShaderPad from '..';\nimport type { InitializeTextureOptions } from '..';\n\nexport type DomTextureElement = HTMLImageElement | HTMLVideoElement | HTMLCanvasElement;\nexport type LiveTextureSource = HTMLVideoElement | HTMLCanvasElement | CoreShaderPad;\n\nconst TEXTURE_OPTION_ATTRIBUTES = [\n\t['internal-format', 'internalFormat'],\n\t['format', 'format'],\n\t['type', 'type'],\n\t['min-filter', 'minFilter'],\n\t['mag-filter', 'magFilter'],\n\t['wrap-s', 'wrapS'],\n\t['wrap-t', 'wrapT'],\n\t['color-space', 'colorSpace'],\n] as const;\n\ntype AttributeValue = string | number | boolean | null | undefined;\n\nfunction stringFromAttribute(value: AttributeValue) {\n\tif (value == null || value === false) return undefined;\n\treturn String(value);\n}\n\nexport function parseBooleanLikeValue(value: AttributeValue, defaultValue: boolean) {\n\tif (value == null) return defaultValue;\n\tif (typeof value === 'boolean') return value;\n\n\tswitch (String(value).trim().toLowerCase()) {\n\t\tcase 'false':\n\t\tcase '0':\n\t\tcase 'no':\n\t\tcase 'off':\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn true;\n\t}\n}\n\nexport function parseTextureOptionsFromAttributes(\n\treadAttribute: (name: string) => AttributeValue,\n\tprefix = '',\n): InitializeTextureOptions {\n\tconst options: InitializeTextureOptions = {};\n\n\tconst historyValue = stringFromAttribute(readAttribute(`${prefix}history`));\n\tif (historyValue != null) {\n\t\tconst parsed = Number.parseInt(historyValue, 10);\n\t\tif (Number.isFinite(parsed) && parsed >= 0) options.history = parsed;\n\t}\n\n\tconst preserveYValue = readAttribute(`${prefix}preserve-y`);\n\tif (preserveYValue != null) {\n\t\toptions.preserveY = parseBooleanLikeValue(preserveYValue, true);\n\t}\n\n\tfor (const [attribute, option] of TEXTURE_OPTION_ATTRIBUTES) {\n\t\tconst value = stringFromAttribute(readAttribute(`${prefix}${attribute}`));\n\t\tif (value) (options as Record<string, unknown>)[option] = value;\n\t}\n\n\treturn options;\n}\n\nexport function parseTextureOptions(element: Element, prefix = '') {\n\treturn parseTextureOptionsFromAttributes(name => element.getAttribute(name), prefix);\n}\n\nexport function isDomTextureElement(element: Element): element is DomTextureElement {\n\treturn (\n\t\telement instanceof HTMLImageElement ||\n\t\telement instanceof HTMLVideoElement ||\n\t\telement instanceof HTMLCanvasElement\n\t);\n}\n\nexport function isLiveDomTextureElement(element: DomTextureElement) {\n\treturn !(element instanceof HTMLImageElement);\n}\n\nfunction onceEvent<T extends Event>(target: EventTarget, type: string): Promise<T> {\n\tconst options = { once: true };\n\n\treturn new Promise((resolve, reject) => {\n\t\tconst cleanup = () => {\n\t\t\ttarget.removeEventListener(type, onResolve);\n\t\t\ttarget.removeEventListener('error', onReject as EventListener);\n\t\t};\n\n\t\tconst onResolve = (event: Event) => {\n\t\t\tcleanup();\n\t\t\tresolve(event as T);\n\t\t};\n\n\t\tconst onReject = (event: Event) => {\n\t\t\tcleanup();\n\t\t\treject(event);\n\t\t};\n\n\t\ttarget.addEventListener(type, onResolve, options);\n\t\ttarget.addEventListener('error', onReject as EventListener, options);\n\t});\n}\n\nasync function loadImageSource(image: HTMLImageElement) {\n\tif (image.complete && image.naturalWidth > 0 && image.naturalHeight > 0) return image;\n\tawait onceEvent(image, 'load');\n\treturn image;\n}\n\nasync function loadVideoSource(video: HTMLVideoElement) {\n\tif (video.videoWidth > 0 && video.videoHeight > 0) return video;\n\tawait onceEvent(video, 'loadedmetadata');\n\treturn video;\n}\n\nexport async function loadDomTextureSource(element: DomTextureElement) {\n\tif (element instanceof HTMLImageElement) return loadImageSource(element);\n\tif (element instanceof HTMLVideoElement) return loadVideoSource(element);\n\tif (element.width <= 0 || element.height <= 0) {\n\t\tthrow new Error('Texture canvas elements must have a positive width and height.');\n\t}\n\treturn element;\n}\n\nexport function getLiveDomTextureSource(element: DomTextureElement) {\n\tif (element instanceof HTMLVideoElement) {\n\t\treturn element.videoWidth > 0 && element.videoHeight > 0 ? element : undefined;\n\t}\n\tif (element instanceof HTMLCanvasElement) {\n\t\treturn element.width > 0 && element.height > 0 ? element : undefined;\n\t}\n\treturn undefined;\n}\n\nexport function addDomTextureRefreshListener(element: DomTextureElement, listener: () => void) {\n\tif (element instanceof HTMLImageElement) {\n\t\telement.addEventListener('load', listener);\n\t\treturn () => element.removeEventListener('load', listener);\n\t}\n\tif (element instanceof HTMLVideoElement) {\n\t\telement.addEventListener('loadedmetadata', listener);\n\t\treturn () => element.removeEventListener('loadedmetadata', listener);\n\t}\n\treturn undefined;\n}\n"],"mappings":";AAgBA,SAAS,oBAAoB,SAAsB;AAClD,QAAM,OAAO,QAAQ,cAAc,eAAe;AAClD,QAAM,OAAO,QAAQ,sBAAsB;AAC3C,SACC,KAAK,QAAQ,KACb,KAAK,SAAS,KACd,KAAK,SAAS,KACd,KAAK,QAAQ,KACb,KAAK,MAAM,KAAK,eAChB,KAAK,OAAO,KAAK;AAEnB;AAEO,SAAS,mCAAmC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAA4D;AAC3D,QAAM,cAAc,OAAO;AAC3B,MAAI,kBAAkB;AACtB,MAAI,mBAAmB;AACvB,MAAI,oBAAoB,YAAY,oBAAoB;AACxD,MAAI,iBAAiB,oBAAoB,MAAM;AAC/C,MAAI,oBAAoB;AACxB,MAAI,cAA8B;AAElC,QAAM,eAAe,MACpB,sBACC,OAAO,yBAAyB,aAAa,iBAAiB,oBAAoB,MAAM,MACzF,OAAO;AAER,QAAM,OAAO,MAAM;AAClB,UAAM,YAAY,aAAa;AAC/B,QAAI,gBAAgB,WAAW;AAC9B,oBAAc;AACd,2BAAqB,SAAS;AAAA,IAC/B;AAEA,QAAI,CAAC,iBAAiB;AACrB,UAAI,qBAAqB,UAAU,GAAG;AACrC,cAAM;AAAA,MACP;AACA,0BAAoB;AACpB;AAAA,IACD;AAEA,QAAI,CAAC,oBAAoB,WAAW;AACnC,UAAI,CAAC,UAAU,GAAG;AACjB,aAAK;AAAA,MACN;AACA,0BAAoB;AACpB;AAAA,IACD;AAEA,QAAI,qBAAqB,UAAU,GAAG;AACrC,YAAM;AAAA,IACP;AACA,wBAAoB;AAAA,EACrB;AAEA,QAAM,yBAAyB,MAAM;AACpC,wBAAoB,YAAY,oBAAoB;AACpD,SAAK;AAAA,EACN;AACA,cAAY,iBAAiB,oBAAoB,sBAAsB;AAEvE,QAAM,uBACL,OAAO,yBAAyB,aAC7B,IAAI,qBAAqB,aAAW;AACpC,qBAAiB,QAAQ,KAAK,WAAS,MAAM,cAAc;AAC3D,SAAK;AAAA,EACN,CAAC,IACA;AACJ,wBAAsB,QAAQ,MAAM;AAEpC,SAAO;AAAA,IACN;AAAA,IACA,OAAO,SAAS;AACf,wBAAkB,QAAQ;AAC1B,yBAAmB,QAAQ;AAC3B,WAAK;AAAA,IACN;AAAA,IACA,UAAU;AACT,4BAAsB,WAAW;AACjC,kBAAY,oBAAoB,oBAAoB,sBAAsB;AAAA,IAC3E;AAAA,EACD;AACD;;;ACrGA,IAAM,4BAA4B;AAAA,EACjC,CAAC,mBAAmB,gBAAgB;AAAA,EACpC,CAAC,UAAU,QAAQ;AAAA,EACnB,CAAC,QAAQ,MAAM;AAAA,EACf,CAAC,cAAc,WAAW;AAAA,EAC1B,CAAC,cAAc,WAAW;AAAA,EAC1B,CAAC,UAAU,OAAO;AAAA,EAClB,CAAC,UAAU,OAAO;AAAA,EAClB,CAAC,eAAe,YAAY;AAC7B;AAIA,SAAS,oBAAoB,OAAuB;AACnD,MAAI,SAAS,QAAQ,UAAU,MAAO,QAAO;AAC7C,SAAO,OAAO,KAAK;AACpB;AAEO,SAAS,sBAAsB,OAAuB,cAAuB;AACnF,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,OAAO,UAAU,UAAW,QAAO;AAEvC,UAAQ,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,GAAG;AAAA,IAC3C,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAEO,SAAS,kCACf,eACA,SAAS,IACkB;AAC3B,QAAM,UAAoC,CAAC;AAE3C,QAAM,eAAe,oBAAoB,cAAc,GAAG,MAAM,SAAS,CAAC;AAC1E,MAAI,gBAAgB,MAAM;AACzB,UAAM,SAAS,OAAO,SAAS,cAAc,EAAE;AAC/C,QAAI,OAAO,SAAS,MAAM,KAAK,UAAU,EAAG,SAAQ,UAAU;AAAA,EAC/D;AAEA,QAAM,iBAAiB,cAAc,GAAG,MAAM,YAAY;AAC1D,MAAI,kBAAkB,MAAM;AAC3B,YAAQ,YAAY,sBAAsB,gBAAgB,IAAI;AAAA,EAC/D;AAEA,aAAW,CAAC,WAAW,MAAM,KAAK,2BAA2B;AAC5D,UAAM,QAAQ,oBAAoB,cAAc,GAAG,MAAM,GAAG,SAAS,EAAE,CAAC;AACxE,QAAI,MAAO,CAAC,QAAoC,MAAM,IAAI;AAAA,EAC3D;AAEA,SAAO;AACR;AAEO,SAAS,oBAAoB,SAAkB,SAAS,IAAI;AAClE,SAAO,kCAAkC,UAAQ,QAAQ,aAAa,IAAI,GAAG,MAAM;AACpF;AAEO,SAAS,oBAAoB,SAAgD;AACnF,SACC,mBAAmB,oBACnB,mBAAmB,oBACnB,mBAAmB;AAErB;AAEO,SAAS,wBAAwB,SAA4B;AACnE,SAAO,EAAE,mBAAmB;AAC7B;AAEA,SAAS,UAA2B,QAAqB,MAA0B;AAClF,QAAM,UAAU,EAAE,MAAM,KAAK;AAE7B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,UAAM,UAAU,MAAM;AACrB,aAAO,oBAAoB,MAAM,SAAS;AAC1C,aAAO,oBAAoB,SAAS,QAAyB;AAAA,IAC9D;AAEA,UAAM,YAAY,CAAC,UAAiB;AACnC,cAAQ;AACR,cAAQ,KAAU;AAAA,IACnB;AAEA,UAAM,WAAW,CAAC,UAAiB;AAClC,cAAQ;AACR,aAAO,KAAK;AAAA,IACb;AAEA,WAAO,iBAAiB,MAAM,WAAW,OAAO;AAChD,WAAO,iBAAiB,SAAS,UAA2B,OAAO;AAAA,EACpE,CAAC;AACF;AAEA,eAAe,gBAAgB,OAAyB;AACvD,MAAI,MAAM,YAAY,MAAM,eAAe,KAAK,MAAM,gBAAgB,EAAG,QAAO;AAChF,QAAM,UAAU,OAAO,MAAM;AAC7B,SAAO;AACR;AAEA,eAAe,gBAAgB,OAAyB;AACvD,MAAI,MAAM,aAAa,KAAK,MAAM,cAAc,EAAG,QAAO;AAC1D,QAAM,UAAU,OAAO,gBAAgB;AACvC,SAAO;AACR;AAEA,eAAsB,qBAAqB,SAA4B;AACtE,MAAI,mBAAmB,iBAAkB,QAAO,gBAAgB,OAAO;AACvE,MAAI,mBAAmB,iBAAkB,QAAO,gBAAgB,OAAO;AACvE,MAAI,QAAQ,SAAS,KAAK,QAAQ,UAAU,GAAG;AAC9C,UAAM,IAAI,MAAM,gEAAgE;AAAA,EACjF;AACA,SAAO;AACR;AAEO,SAAS,wBAAwB,SAA4B;AACnE,MAAI,mBAAmB,kBAAkB;AACxC,WAAO,QAAQ,aAAa,KAAK,QAAQ,cAAc,IAAI,UAAU;AAAA,EACtE;AACA,MAAI,mBAAmB,mBAAmB;AACzC,WAAO,QAAQ,QAAQ,KAAK,QAAQ,SAAS,IAAI,UAAU;AAAA,EAC5D;AACA,SAAO;AACR;AAEO,SAAS,6BAA6B,SAA4B,UAAsB;AAC9F,MAAI,mBAAmB,kBAAkB;AACxC,YAAQ,iBAAiB,QAAQ,QAAQ;AACzC,WAAO,MAAM,QAAQ,oBAAoB,QAAQ,QAAQ;AAAA,EAC1D;AACA,MAAI,mBAAmB,kBAAkB;AACxC,YAAQ,iBAAiB,kBAAkB,QAAQ;AACnD,WAAO,MAAM,QAAQ,oBAAoB,kBAAkB,QAAQ;AAAA,EACpE;AACA,SAAO;AACR;","names":[]}
@@ -99,6 +99,9 @@ var ShaderPad = class _ShaderPad {
99
99
  canvasHeight: this.canvas.height
100
100
  }) : spError(0);
101
101
  }
102
+ if (texOptions.colorSpace && "drawingBufferColorSpace" in gl) {
103
+ gl.drawingBufferColorSpace = texOptions.colorSpace;
104
+ }
102
105
  this.gl = gl;
103
106
  this.typeArrays = /* @__PURE__ */ new Map([
104
107
  [gl.FLOAT, Float32Array],
@@ -415,6 +418,7 @@ var ShaderPad = class _ShaderPad {
415
418
  magFilter: this.resolveGLConst(options?.magFilter ?? "LINEAR"),
416
419
  wrapS: this.resolveGLConst(options?.wrapS ?? "CLAMP_TO_EDGE"),
417
420
  wrapT: this.resolveGLConst(options?.wrapT ?? "CLAMP_TO_EDGE"),
421
+ colorSpace: options?.colorSpace,
418
422
  preserveY: options?.preserveY,
419
423
  isIntegerColorFormat
420
424
  };
@@ -431,9 +435,9 @@ var ShaderPad = class _ShaderPad {
431
435
  const ArrayType = this.typeArrays.get(type) ?? Uint8Array;
432
436
  return new ArrayType(size);
433
437
  }
434
- isNotRgba(format) {
438
+ isRgba(format) {
435
439
  const gl = this.gl;
436
- return format !== gl.RGBA && format !== gl.RGBA_INTEGER;
440
+ return format === gl.RGBA || format === gl.RGBA_INTEGER;
437
441
  }
438
442
  clearHistTexLayers(textureInfo) {
439
443
  if (!textureInfo.history) return;
@@ -442,7 +446,7 @@ var ShaderPad = class _ShaderPad {
442
446
  const transparent = this.getPxArray(type, textureInfo.width * textureInfo.height * 4);
443
447
  gl.activeTexture(gl.TEXTURE0 + textureInfo.unitIndex);
444
448
  gl.bindTexture(gl.TEXTURE_2D_ARRAY, textureInfo.texture);
445
- const needsAlignmentFix = this.isNotRgba(format);
449
+ const needsAlignmentFix = !this.isRgba(format);
446
450
  let previousAlignment;
447
451
  if (needsAlignmentFix) {
448
452
  previousAlignment = gl.getParameter(gl.UNPACK_ALIGNMENT);
@@ -740,15 +744,18 @@ var ShaderPad = class _ShaderPad {
740
744
  if (!isPartial) {
741
745
  this.resizeTex(name, width, height);
742
746
  }
743
- const isTypedArray = "data" in nonShaderPadSource && nonShaderPadSource.data;
744
- const shouldFlipY = !isTypedArray && !info.options?.preserveY;
747
+ const isCustomTexture = "data" in nonShaderPadSource && nonShaderPadSource.data;
748
+ const shouldFlipY = !isCustomTexture && !info.options?.preserveY;
745
749
  const previousFlipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL);
746
- const needsAlignmentFix = isTypedArray && this.isNotRgba(info.options.format);
750
+ const needsAlignmentFix = isCustomTexture && !this.isRgba(info.options.format);
751
+ const shouldConvertColorSpace = !isCustomTexture && info.options.colorSpace && "unpackColorSpace" in gl;
752
+ const previousColorSpace = gl.unpackColorSpace;
747
753
  let previousAlignment;
748
754
  if (needsAlignmentFix) {
749
755
  previousAlignment = gl.getParameter(gl.UNPACK_ALIGNMENT);
750
756
  gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
751
757
  }
758
+ if (shouldConvertColorSpace) gl.unpackColorSpace = info.options.colorSpace;
752
759
  if (info.history) {
753
760
  gl.activeTexture(gl.TEXTURE0 + info.unitIndex);
754
761
  gl.bindTexture(gl.TEXTURE_2D_ARRAY, info.texture);
@@ -811,6 +818,7 @@ var ShaderPad = class _ShaderPad {
811
818
  }
812
819
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, previousFlipY);
813
820
  }
821
+ if (shouldConvertColorSpace) gl.unpackColorSpace = previousColorSpace;
814
822
  if (needsAlignmentFix) gl.pixelStorei(gl.UNPACK_ALIGNMENT, previousAlignment);
815
823
  }
816
824
  bindIntermediate() {
@@ -992,4 +1000,4 @@ var index_default = ShaderPad;
992
1000
  export {
993
1001
  index_default
994
1002
  };
995
- //# sourceMappingURL=chunk-TTKZ43JC.mjs.map
1003
+ //# sourceMappingURL=chunk-YB3GMXKV.mjs.map