@rosalana/sandbox 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/globals.d.ts CHANGED
@@ -5,11 +5,6 @@ import ModuleRegistry from "./tools/module_registry";
5
5
  * This registry will grow when more modules are defined
6
6
  */
7
7
  export declare const modules: ModuleRegistry;
8
- /**
9
- * A global registry of modules that are currently in use by the webGL context.
10
- * This is flushed on every shader switch.
11
- */
12
- export declare const runtime_modules: ModuleRegistry;
13
8
  /**
14
9
  * Global uniforms that are automatically provided by Sandbox.
15
10
  * These uniforms will NOT be renamed during preprocessing.
package/dist/index.cjs.js CHANGED
@@ -1,22 +1,22 @@
1
- "use strict";var ie=Object.defineProperty;var re=(u,e,t)=>e in u?ie(u,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):u[e]=t;var o=(u,e,t)=>re(u,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class b{constructor(e,t,n,i){this.target=e,this.type=t,this.listener=n,this.options=i,this.target.addEventListener(this.type,this.listener,this.options)}remove(){this.target.removeEventListener(this.type,this.listener,this.options)}static on(e,t,n,i){return e.addEventListener(t,n,i),()=>e.removeEventListener(t,n,i)}}class h extends Error{constructor(t,n){super(t);o(this,"name","SandboxError");this.code=n}}class V extends h{constructor(){super("WebGL is not supported in this browser.","CONTEXT_ERROR")}}class se extends h{constructor(){super("Failed to create WebGL context. The GPU may be unavailable.","CONTEXT_ERROR")}}class I extends h{constructor(e,t){super(`Vertex and fragment shader WebGL versions do not match (${e} vs ${t})`,"VALIDATION_ERROR"),this.vertexVersion=e,this.fragmentVersion=t}}class E extends h{constructor(t,n,i){const r=E.parseErrorLines(i),s=r.length>0?` at line(s): ${r.join(", ")}`:"";super(`${t} shader compilation failed${s}
1
+ "use strict";var ne=Object.defineProperty;var ie=(u,e,t)=>e in u?ne(u,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):u[e]=t;var a=(u,e,t)=>ie(u,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class y{constructor(e,t,n,i){this.target=e,this.type=t,this.listener=n,this.options=i,this.target.addEventListener(this.type,this.listener,this.options)}remove(){this.target.removeEventListener(this.type,this.listener,this.options)}static on(e,t,n,i){return e.addEventListener(t,n,i),()=>e.removeEventListener(t,n,i)}}class h extends Error{constructor(t,n){super(t);a(this,"name","SandboxError");this.code=n}}class O extends h{constructor(){super("WebGL is not supported in this browser.","CONTEXT_ERROR")}}class re extends h{constructor(){super("Failed to create WebGL context. The GPU may be unavailable.","CONTEXT_ERROR")}}class V extends h{constructor(e,t){super(`Vertex and fragment shader WebGL versions do not match (${e} vs ${t})`,"VALIDATION_ERROR"),this.vertexVersion=e,this.fragmentVersion=t}}class w extends h{constructor(t,n,i){const r=w.parseErrorLines(i),s=r.length>0?` at line(s): ${r.join(", ")}`:"";super(`${t} shader compilation failed${s}
2
2
 
3
- ${i}`,"SHADER_ERROR");o(this,"lines");this.shaderType=t,this.source=n,this.infoLog=i,this.lines=r}static parseErrorLines(t){const n=[/ERROR:\s*\d*:(\d+)/g,/(\d+):(\d+)\(\d+\):/g,/^(\d+):/gm],i=new Set;for(const r of n){let s;for(;(s=r.exec(t))!==null;){const a=parseInt(s[1],10);a>0&&i.add(a)}}return[...i].sort((r,s)=>r-s)}}class M extends h{constructor(e,t,n,i){super(`The shader ${e} "${t}" has type "${i}" but expected "${n}"`,"SHADER_ERROR"),this.requirement=e,this.name=t,this.expectedType=n,this.actualType=i}}class P extends h{constructor(){super("Shader source does not contain any function.","SHADER_ERROR")}}class $ extends h{constructor(e,t){super(`Syntax error in shader import statement at line ${e}: ${t}`,"SHADER_ERROR"),this.line=e,this.details=t}}class D extends h{constructor(e,t){super(`Duplicate import name "${e}" found at line ${t}. Each import must have a unique name.`,"SHADER_ERROR"),this.name=e,this.line=t}}class B extends h{constructor(e){super(`Can not find module '${e}'. Check if it is defined before usage or if the name is correct.`,"MODULE_ERROR"),this.moduleName=e}}class N extends h{constructor(e,t){super(`Method '${t}' not found in shader module '${e}'. Check if the method is defined in the module source code or if the name is correct.`,"MODULE_ERROR"),this.moduleName=e,this.methodName=t}}class G extends h{constructor(e){super(`Importing 'main' function from module '${e}' is forbidden.`,"MODULE_ERROR"),this.moduleName=e}}class W extends h{constructor(e){super(`Name 'default' is reserved and cannot be used as a function name in module '${e}'.`,"MODULE_ERROR"),this.moduleName=e}}class z extends h{constructor(e){super(`Module name '${e}' is not allowed. Module names cannot be 'sandbox' or start with 'sandbox/'.`,"MODULE_ERROR"),this.moduleName=e}}class H extends h{constructor(e){super(`Module '${e}' is already defined. Overwriting existing modules is not allowed.`,"MODULE_ERROR"),this.moduleName=e}}class q extends h{constructor(e,t,n){super(`Uniform '${n}' mentioned for function '${t}' of module '${e}' was not found among the module's declared uniforms. Check if the uniform is declared in the module source code or if the name is correct.`,"MODULE_ERROR"),this.moduleName=e,this.functionName=t,this.uniformName=n}}class j extends h{constructor(e,t){super(`Uniform '${t}' mentioned for function '${e}' was not imported from any module. Check if the function is imported from the correct module and if the uniform is declared in that module's source code with the correct name.`,"MODULE_ERROR"),this.functionName=e,this.uniformName=t}}class X extends h{constructor(e,t){super(`Mention '${e}' called in function '${t}' could not be replaced with the corresponding uniform reference. There might be an issue with the compilation process because the referenced uniform was not found among the shader requirements. Try use a different name for uniforms you want to mention in functions or check if the uniform is properly declared and mentioned in the module source code.`,"MODULE_ERROR"),this.mentionName=e,this.calledInFunction=t}}class R extends h{constructor(e){super(`Shader program linking failed
3
+ ${i}`,"SHADER_ERROR");a(this,"lines");this.shaderType=t,this.source=n,this.infoLog=i,this.lines=r}static parseErrorLines(t){const n=[/ERROR:\s*\d*:(\d+)/g,/(\d+):(\d+)\(\d+\):/g,/^(\d+):/gm],i=new Set;for(const r of n){let s;for(;(s=r.exec(t))!==null;){const o=parseInt(s[1],10);o>0&&i.add(o)}}return[...i].sort((r,s)=>r-s)}}class A extends h{constructor(e,t,n,i){super(`The shader ${e} "${t}" has type "${i}" but expected "${n}"`,"SHADER_ERROR"),this.requirement=e,this.name=t,this.expectedType=n,this.actualType=i}}class I extends h{constructor(){super("Shader source does not contain any function.","SHADER_ERROR")}}class P extends h{constructor(e,t){super(`Syntax error in shader import statement at line ${e}: ${t}`,"SHADER_ERROR"),this.line=e,this.details=t}}class $ extends h{constructor(e,t){super(`Duplicate import name "${e}" found at line ${t}. Each import must have a unique name.`,"SHADER_ERROR"),this.name=e,this.line=t}}class D extends h{constructor(e){super(`Can not find module '${e}'. Check if it is defined before usage or if the name is correct.`,"MODULE_ERROR"),this.moduleName=e}}class B extends h{constructor(e,t){super(`Method '${t}' not found in shader module '${e}'. Check if the method is defined in the module source code or if the name is correct.`,"MODULE_ERROR"),this.moduleName=e,this.methodName=t}}class N extends h{constructor(e){super(`Importing 'main' function from module '${e}' is forbidden.`,"MODULE_ERROR"),this.moduleName=e}}class G extends h{constructor(e){super(`Name 'default' is reserved and cannot be used as a function name in module '${e}'.`,"MODULE_ERROR"),this.moduleName=e}}class W extends h{constructor(e){super(`Module name '${e}' is not allowed. Module names cannot be 'sandbox' or start with 'sandbox/'.`,"MODULE_ERROR"),this.moduleName=e}}class z extends h{constructor(e){super(`Module '${e}' is already defined. Overwriting existing modules is not allowed.`,"MODULE_ERROR"),this.moduleName=e}}class H extends h{constructor(e,t,n){super(`Uniform '${n}' mentioned for function '${t}' of module '${e}' was not found among the module's declared uniforms. Check if the uniform is declared in the module source code or if the name is correct.`,"MODULE_ERROR"),this.moduleName=e,this.functionName=t,this.uniformName=n}}class q extends h{constructor(e,t){super(`Uniform '${t}' mentioned for function '${e}' was not imported from any module. Check if the function is imported from the correct module and if the uniform is declared in that module's source code with the correct name.`,"MODULE_ERROR"),this.functionName=e,this.uniformName=t}}class j extends h{constructor(e,t){super(`Mention '${e}' called in function '${t}' could not be replaced with the corresponding uniform reference. There might be an issue with the compilation process because the referenced uniform was not found among the shader requirements. Try use a different name for uniforms you want to mention in functions or check if the uniform is properly declared and mentioned in the module source code.`,"MODULE_ERROR"),this.mentionName=e,this.calledInFunction=t}}class _ extends h{constructor(e){super(`Shader program linking failed
4
4
 
5
- ${e}`,"PROGRAM_ERROR"),this.infoLog=e}}class oe extends h{constructor(t){super(`Failed to create WebGL texture for "${t}".`,"TEXTURE_ERROR");o(this,"name","SandboxTextureCreationError");this.textureName=t}}class ae extends h{constructor(t,n){super(`Cannot bind texture "${t}": all ${n} texture units are in use.`,"TEXTURE_ERROR");o(this,"name","SandboxTextureUnitLimitError");this.textureName=t,this.maxUnits=n}}class Y extends h{constructor(e){super(`Error in onLoad callback: ${e}`,"UNKNOWN_ERROR")}}class K extends h{constructor(e,t){super(`Error in onBefore/onAfter hook callback with ID ${e}: ${t}`,"UNKNOWN_ERROR")}}class le{constructor(){o(this,"time",0);o(this,"delta",0);o(this,"frame",0);o(this,"running",!1);o(this,"fps",0);o(this,"startTime",0);o(this,"lastTime",0);o(this,"rafId",null);o(this,"callback",null);o(this,"maxFps",0);this.loop=this.loop.bind(this)}start(e){if(this.running)return this;this.callback=e,this.running=!0;const t=performance.now();return this.frame===0?this.startTime=t:this.startTime=t-this.time*1e3,this.lastTime=t,this.rafId=requestAnimationFrame(this.loop),this}stop(){return this.running?(this.running=!1,this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this):this}reset(){return this.stop(),this.time=0,this.delta=0,this.frame=0,this.fps=0,this}getState(){return{time:this.time,delta:this.delta,frame:this.frame,running:this.running,fps:Math.round(this.fps)}}tick(e=0){return this.delta=e,this.time+=e,this.frame++,this.callback&&this.callback(this.getState()),this}setTime(e){return this.time=e,this}destroy(){this.reset(),this.callback=null}setMaxFps(e){return this.maxFps=e,this}loop(e){if(!this.running)return;if(this.maxFps>0){const n=1e3/this.maxFps;if(e-this.lastTime<n){this.rafId=requestAnimationFrame(this.loop);return}}this.delta=(e-this.lastTime)/1e3,this.lastTime=e;const t=this.delta>0?1/this.delta:0;this.fps=this.fps*.95+t*.05,this.time=(e-this.startTime)/1e3,this.frame++,this.callback&&this.callback(this.getState()),this.rafId=requestAnimationFrame(this.loop)}}class k{constructor(e){o(this,"gl");o(this,"vao",null);o(this,"vbo",null);o(this,"ibo",null);o(this,"vertexCount",0);o(this,"indexCount",0);o(this,"useIndices",!1);o(this,"vaoExt",null);o(this,"isWebGL2");this.gl=e,this.isWebGL2=e instanceof WebGL2RenderingContext,this.isWebGL2||(this.vaoExt=e.getExtension("OES_vertex_array_object"))}static fullscreenQuad(e){const t=new k(e),n=new Float32Array([-1,-1,0,0,1,-1,1,0,-1,1,0,1,1,1,1,1]),i=new Uint16Array([0,1,2,2,1,3]);return t.setup(n,i),t}setup(e,t){const n=this.gl;return this.createVAO(),this.bindVAO(),this.vbo=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,this.vbo),n.bufferData(n.ARRAY_BUFFER,e,n.STATIC_DRAW),this.vertexCount=e.length/4,t&&(this.ibo=n.createBuffer(),n.bindBuffer(n.ELEMENT_ARRAY_BUFFER,this.ibo),n.bufferData(n.ELEMENT_ARRAY_BUFFER,t,n.STATIC_DRAW),this.indexCount=t.length,this.useIndices=!0),this.unbindVAO(),this}linkAttributes(e){const t=this.gl;this.bindVAO(),t.bindBuffer(t.ARRAY_BUFFER,this.vbo);const n=4*Float32Array.BYTES_PER_ELEMENT,i=this.getPositionLocation(e);i>=0&&(t.enableVertexAttribArray(i),t.vertexAttribPointer(i,2,t.FLOAT,!1,n,0));const r=this.getTexcoordLocation(e);return r>=0&&(t.enableVertexAttribArray(r),t.vertexAttribPointer(r,2,t.FLOAT,!1,n,2*Float32Array.BYTES_PER_ELEMENT)),this.useIndices&&t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.ibo),this.unbindVAO(),this}bind(){return this.bindVAO(),this}unbind(){return this.unbindVAO(),this}draw(){const e=this.gl;return this.bindVAO(),this.useIndices?e.drawElements(e.TRIANGLES,this.indexCount,e.UNSIGNED_SHORT,0):e.drawArrays(e.TRIANGLE_STRIP,0,this.vertexCount),this}destroy(){const e=this.gl;this.deleteVAO(),this.vbo&&(e.deleteBuffer(this.vbo),this.vbo=null),this.ibo&&(e.deleteBuffer(this.ibo),this.ibo=null)}getPositionLocation(e){let t=e.getAttribLocation("a_position");return t>=0||(t=e.getAttribLocation("aPosition"),t>=0)||(t=e.getAttribLocation("position"),t>=0)?t:-1}getTexcoordLocation(e){let t=e.getAttribLocation("a_texcoord");return t>=0||(t=e.getAttribLocation("aTexCoord"),t>=0)||(t=e.getAttribLocation("texcoord"),t>=0)||(t=e.getAttribLocation("a_uv"),t>=0)?t:-1}createVAO(){this.isWebGL2?this.vao=this.gl.createVertexArray():this.vaoExt&&(this.vao=this.vaoExt.createVertexArrayOES())}bindVAO(){this.vao&&(this.isWebGL2?this.gl.bindVertexArray(this.vao):this.vaoExt&&this.vaoExt.bindVertexArrayOES(this.vao))}unbindVAO(){this.isWebGL2?this.gl.bindVertexArray(null):this.vaoExt&&this.vaoExt.bindVertexArrayOES(null)}deleteVAO(){this.vao&&(this.isWebGL2?this.gl.deleteVertexArray(this.vao):this.vaoExt&&this.vaoExt.deleteVertexArrayOES(this.vao),this.vao=null)}}class ce{constructor(e){o(this,"gl");o(this,"program",null);o(this,"vertexShader",null);o(this,"fragmentShader",null);this.gl=e}compile(e,t){return this.destroy(),this.vertexShader=this.compileShader("vertex",e),this.fragmentShader=this.compileShader("fragment",t),this.linkProgram(),this}use(){return this.program&&this.gl.useProgram(this.program),this}getProgram(){return this.program}getAttribLocation(e){return this.program?this.gl.getAttribLocation(this.program,e):-1}getUniformLocation(e){return this.program?this.gl.getUniformLocation(this.program,e):null}destroy(){const e=this.gl;this.program&&(this.vertexShader&&e.detachShader(this.program,this.vertexShader),this.fragmentShader&&e.detachShader(this.program,this.fragmentShader),e.deleteProgram(this.program),this.program=null),this.vertexShader&&(e.deleteShader(this.vertexShader),this.vertexShader=null),this.fragmentShader&&(e.deleteShader(this.fragmentShader),this.fragmentShader=null)}compileShader(e,t){const n=this.gl,i=e==="vertex"?n.VERTEX_SHADER:n.FRAGMENT_SHADER,r=n.createShader(i);if(!r)throw new E(e,t,"Failed to create shader object");if(n.shaderSource(r,t),n.compileShader(r),!n.getShaderParameter(r,n.COMPILE_STATUS)){const a=n.getShaderInfoLog(r)||"Unknown error";throw n.deleteShader(r),new E(e,t,a)}return r}linkProgram(){const e=this.gl;if(!this.vertexShader||!this.fragmentShader)throw new R("Shaders not compiled");const t=e.createProgram();if(!t)throw new R("Failed to create program object");if(e.attachShader(t,this.vertexShader),e.attachShader(t,this.fragmentShader),e.linkProgram(t),!e.getProgramParameter(t,e.LINK_STATUS)){const i=e.getProgramInfoLog(t)||"Unknown error";throw e.deleteProgram(t),new R(i)}this.program=t}}class T{constructor(e,t){o(this,"name");o(this,"method");o(this,"isArray");o(this,"isMatrix");o(this,"location",null);o(this,"locationResolved",!1);o(this,"value");this.name=e,this.value=t;const n=T.inferMethodInfo(t);this.method=n.method,this.isArray=n.isArray,this.isMatrix=n.isMatrix}static inferMethodInfo(e){if(typeof e=="boolean")return{method:"uniform1i",isArray:!1,isMatrix:!1};if(typeof e=="number")return{method:"uniform1f",isArray:!1,isMatrix:!1};if(!Array.isArray(e))return{method:"uniform1f",isArray:!1,isMatrix:!1};const t=e.length,n=e[0];if(Array.isArray(n))switch(n.length){case 2:return{method:"uniform2fv",isArray:!0,isMatrix:!1};case 3:return{method:"uniform3fv",isArray:!0,isMatrix:!1};case 4:return{method:"uniform4fv",isArray:!0,isMatrix:!1};default:return{method:"uniform1fv",isArray:!0,isMatrix:!1}}switch(t){case 2:return{method:"uniform2fv",isArray:!1,isMatrix:!1};case 3:return{method:"uniform3fv",isArray:!1,isMatrix:!1};case 4:return{method:"uniform4fv",isArray:!1,isMatrix:!1};case 9:return{method:"uniformMatrix3fv",isArray:!1,isMatrix:!0};case 16:return{method:"uniformMatrix4fv",isArray:!1,isMatrix:!0};default:return{method:"uniform1fv",isArray:!0,isMatrix:!1}}}resolveLocation(e,t){return this.locationResolved||(this.location=e.getUniformLocation(t,this.name),this.locationResolved=!0),this.location}invalidateLocation(){this.location=null,this.locationResolved=!1}setValue(e){this.value=e}getValue(){return this.value}upload(e,t){const n=this.resolveLocation(e,t);if(n===null)return;const i=this.value;let r;switch(typeof i=="boolean"?r=i?1:0:typeof i=="number"?r=i:this.isArray&&Array.isArray(i[0])?r=new Float32Array(i.flat()):r=new Float32Array(i),this.method){case"uniform1f":e.uniform1f(n,r);break;case"uniform1i":e.uniform1i(n,r);break;case"uniform1fv":e.uniform1fv(n,r);break;case"uniform2fv":e.uniform2fv(n,r);break;case"uniform3fv":e.uniform3fv(n,r);break;case"uniform4fv":e.uniform4fv(n,r);break;case"uniformMatrix2fv":e.uniformMatrix2fv(n,!1,r);break;case"uniformMatrix3fv":e.uniformMatrix3fv(n,!1,r);break;case"uniformMatrix4fv":e.uniformMatrix4fv(n,!1,r);break}}}class _{constructor(e){o(this,"parsed",null);this.source=e}parse(){if(this.parsed)return this.parsed;const e=this.detectVersion(),t=this.detectImports(),n=this.detectUniforms(),i=this.detectFunctions(n);return this.parsed={version:e,imports:t,uniforms:n,functions:i}}isParsed(){return this.parsed!==null}setSource(e){this.source=e,this.parsed=null}version(){return this.detectVersion()}detectVersion(){return/^\s*#version\s+300\s+es/m.test(this.source)?2:1}detectImports(){const e=/^[ \t]*#import\s+(\w+)(?:\s+as\s+(\w+))?\s+from\s+["'](.+)["']/gm,t=/^[ \t]*[^\w\s]?import\b/gm,n=[],i=new Set;let r,s=1,a=0;for(;(r=e.exec(this.source))!==null;){s+=(this.source.substring(a,r.index).match(/\n/g)||[]).length,a=r.index,i.add(s);const f=r[1],c=r[2]||r[1],d=r[3];if(n.some(p=>p.alias===c))throw new D(c,s);n.push({name:f,alias:c,module:d,line:s})}let l;for(;(l=t.exec(this.source))!==null;){const f=(this.source.substring(0,l.index).match(/\n/g)||[]).length+1;if(i.has(f))continue;const c=this.source.split(`
6
- `)[f-1].trim();throw new $(f,this.diagnoseImport(c))}return n}diagnoseImport(e){const t=e.match(/^([^\w\s])import\b/);if(t&&t[1]!=="#")return`Invalid prefix '${t[1]}'. Expected: #import <function> from '<module>'`;if(/^import\b/.test(e))return"Missing '#' prefix. Expected: #import <function> from '<module>'";if(/^#import\s+from\b/.test(e))return"Missing function name. Expected: #import <function> from '<module>'";if(/^#import\s+\w+\s*$/.test(e))return`Missing 'from' clause. Expected: #import ${e.split(/\s+/)[1]} from '<module>'`;if(/^#import\s+\w+\s+as\s*$/.test(e)||/^#import\s+\w+\s+as\s+from\b/.test(e))return`Missing alias name after 'as'. Expected: #import ${e.split(/\s+/)[1]} as <alias> from '<module>'`;if(/^#import\s+\w+\s+as\s+\w+\s*$/.test(e)){const n=e.split(/\s+/);return`Missing 'from' clause. Expected: #import ${n[1]} as ${n[3]} from '<module>'`}if(/^#import\s+\w+(?:\s+as\s+\w+)?\s+from\s+\w+/.test(e)){const n=e.match(/from\s+(\S+)/);return`Module name must be quoted. Expected: from '${n==null?void 0:n[1]}'`}return"Invalid syntax. Expected: #import <function> from '<module>'"}detectUniforms(){const e=/^[ \t]*uniform\s+(?:(?:highp|mediump|lowp)\s+)?(\w+)\s+(\w+)(?:\[(\d+)\])?\s*;/gm,t=[];let n,i=1,r=0;for(;(n=e.exec(this.source))!==null;){i+=(this.source.substring(r,n.index).match(/\n/g)||[]).length,r=n.index;const s=n[1],a=n[2],l=n[3]?parseInt(n[3],10):void 0;t.push({name:a,type:s,line:i,arrayNum:l})}return t}detectFunctions(e){const t=[],n="void|float|int|uint|bool|vec[234]|ivec[234]|uvec[234]|bvec[234]|mat[234](?:x[234])?|sampler2D|samplerCube|sampler3D|sampler2DArray",i=new RegExp(`^[ \\t]*(${n})\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*\\{`,"gm");let r;for(;(r=i.exec(this.source))!==null;){const s=r[1],a=r[2],l=r[3].trim(),f=r.index,c=(this.source.substring(0,f).match(/\n/g)||[]).length+1,d=this.source.indexOf("{",f),p=this.findClosingBrace(this.source,d);if(p===-1)continue;const g=this.source.slice(d,p+1),Z=this.parseParams(l),ee=this.findFunctionCalls(g),te=this.findUniformCalls(g,e),ne=this.findMentionCalls(g);t.push({name:a,type:s,params:Z,body:g,dependencies:[...ee,...te,...ne],line:c})}return t}parseParams(e){if(!e.trim())return[];const t=[],n=e.split(",");for(const i of n){const r=i.trim();if(!r)continue;const a=r.replace(/\b(in|out|inout|const|highp|mediump|lowp)\b\s*/g,"").trim().match(/^(\w+)\s+(\w+)(?:\[\d*\])?$/);a&&t.push({type:a[1],name:a[2]})}return t}findClosingBrace(e,t){let n=0,i=!1,r=!1,s=!1,a=!1;for(let l=t;l<e.length;l++){const f=e[l],c=e[l+1],d=e[l-1];if(!r&&!a&&f==="/"&&c==="/"){s=!0;continue}if(s&&f===`
7
- `){s=!1;continue}if(!r&&!s&&f==="/"&&c==="*"){a=!0,l++;continue}if(a&&f==="*"&&c==="/"){a=!1,l++;continue}if(!(s||a)){if(f==='"'&&d!=="\\"){r=!r;continue}if(!r){if(f==="{")n++,i=!0;else if(f==="}"&&(n--,i&&n===0))return l}}}return-1}findFunctionCalls(e){const t=[],n=new Set(["if","else","for","while","do","switch","case","return","break","continue","discard"]),i=/\b([a-zA-Z_]\w*)\s*\(/g;let r;for(;(r=i.exec(e))!==null;){const s=r[1];n.has(s)||t.push({name:s,type:"function",index:r.index})}return t}findUniformCalls(e,t){const n=[];for(const i of t){const r=new RegExp(`\\b${i.name}\\b`,"g");let s;for(;(s=r.exec(e))!==null;)n.push({name:i.name,type:"uniform",index:s.index})}return n}findMentionCalls(e){const t=[],n=/@(\w+)\.([a-zA-Z_]\w*)/g;let i;for(;(i=n.exec(e))!==null;){const r=i[1],s=i[2];t.push({name:`${r}.${s}`,type:"mention",index:i.index})}return t}}class Q{constructor(e){o(this,"isCompiled",!1);o(this,"original");o(this,"compiled");o(this,"requirements",{uniforms:new Map,functions:new Map});this.original=new _(e),this.compiled=new _(e)}version(){return this.original.version()}source(){return this.original.source}recompile(){return this.isCompiled=!1,this.compile()}compile(){return this.isCompiled?this.compiled.source:(this.original.parse().imports.length>0&&this.processImports(),this.compiled.setSource(this.build()),this.isCompiled=!0,this.compiled.source)}processImports(){const e=this.original.parse(),t=e.functions.flatMap(n=>n.dependencies.filter(i=>i.type==="mention").map(i=>({name:i.name.split(".")[0],uniform:i.name.split(".")[1]})));for(const n of e.imports){const i=w.resolve(n.module),r=i.extract(n.name);let s=t.filter(l=>l.name===r.function.name);if(s.length>0){const l=i.getDefinition().uniforms;if(s=s.filter(f=>{const c=l.find(d=>d.name===`u_${f.uniform}`||d.name===f.uniform);if(c){r.dependencies.uniforms.some(p=>p.name===c.name)||r.dependencies.uniforms.push(c);const d=t.indexOf(f);return d>-1&&t.splice(d,1),!1}return!0}),s.length>0)throw new q(n.module,r.function.name,s[0].uniform)}const a=i.copy();this.processExtraction(r,n.alias,a.options),y.merge(n.module,a)}if(t.length>0)throw new j(t[0].name,t[0].uniform)}processExtraction(e,t,n={}){const i=e.function,r=Math.random().toString(36).substring(2,8),s=`${t}_${r}`;for(let l=e.dependencies.functions.length-1;l>=0;l--){const f=e.dependencies.functions[l],c=this.rewriteFunction(f,t,{uniforms:e.dependencies.uniforms,functions:e.dependencies.functions,unique:s});this.requirements.functions.set(c.name,c)}const a=this.rewriteFunction(i,t,{uniforms:e.dependencies.uniforms,functions:e.dependencies.functions,rename:!0,unique:s});this.requirements.functions.set(a.name,a);for(const l of e.dependencies.uniforms){if(S.has(l.name))continue;const f={...l,name:`${s}_${l.name}${l.arrayNum?`[${l.arrayNum}]`:""}`};if(n[i.name]){const c=Object.entries(n[i.name]).find(([d,p])=>p.uniform===l.name);c&&(c[1].uniform=`${s}_${l.name}`)}this.requirements.uniforms.set(f.name,f)}n[i.name]&&t!==i.name&&(n[t]=n[i.name],delete n[i.name])}rewriteFunction(e,t,n={rename:!1,uniforms:[],functions:[],unique:""}){const i=new Set(n.uniforms.map(c=>c.name)),r=new Set(n.functions.map(c=>c.name)),s=[],a=n.unique?n.unique:t;for(const c of e.dependencies)if(c.index!==void 0)if(c.type==="uniform"&&i.has(c.name)){if(S.has(c.name))continue;s.push({index:c.index,oldText:c.name,newText:`${a}_${c.name}`})}else c.type==="function"&&r.has(c.name)&&s.push({index:c.index,oldText:c.name,newText:`${a}_${c.name}`});const l=this.applyRewrites(e.body,s),f=n.rename?t:`${a}_${e.name}`;return{...e,name:f,body:l}}applyRewrites(e,t){const n=[...t].sort((r,s)=>s.index-r.index);let i=e;for(const r of n)i=i.slice(0,r.index)+r.newText+i.slice(r.index+r.oldText.length);return i}build(){const e=this.original.parse();let t=this.original.source;t=this.removeImportLines(t,e);const n=this.findInsertionPointForUniforms(t),i=this.generateUniformsCode();i&&(t=t.slice(0,n)+i+`
5
+ ${e}`,"PROGRAM_ERROR"),this.infoLog=e}}class se extends h{constructor(t){super(`Failed to create WebGL texture for "${t}".`,"TEXTURE_ERROR");a(this,"name","SandboxTextureCreationError");this.textureName=t}}class oe extends h{constructor(t,n){super(`Cannot bind texture "${t}": all ${n} texture units are in use.`,"TEXTURE_ERROR");a(this,"name","SandboxTextureUnitLimitError");this.textureName=t,this.maxUnits=n}}class X extends h{constructor(e){super(`Error in onLoad callback: ${e}`,"UNKNOWN_ERROR")}}class Y extends h{constructor(e,t){super(`Error in onBefore/onAfter hook callback with ID ${e}: ${t}`,"UNKNOWN_ERROR")}}class ae{constructor(){a(this,"time",0);a(this,"delta",0);a(this,"frame",0);a(this,"running",!1);a(this,"fps",0);a(this,"startTime",0);a(this,"lastTime",0);a(this,"rafId",null);a(this,"callback",null);a(this,"maxFps",0);this.loop=this.loop.bind(this)}start(e){if(this.running)return this;this.callback=e,this.running=!0;const t=performance.now();return this.frame===0?this.startTime=t:this.startTime=t-this.time*1e3,this.lastTime=t,this.rafId=requestAnimationFrame(this.loop),this}stop(){return this.running?(this.running=!1,this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this):this}reset(){return this.stop(),this.time=0,this.delta=0,this.frame=0,this.fps=0,this}getState(){return{time:this.time,delta:this.delta,frame:this.frame,running:this.running,fps:Math.round(this.fps)}}tick(e=0){return this.delta=e,this.time+=e,this.frame++,this.callback&&this.callback(this.getState()),this}setTime(e){return this.time=e,this}destroy(){this.reset(),this.callback=null}setMaxFps(e){return this.maxFps=e,this}loop(e){if(!this.running)return;if(this.maxFps>0){const n=1e3/this.maxFps;if(e-this.lastTime<n){this.rafId=requestAnimationFrame(this.loop);return}}this.delta=(e-this.lastTime)/1e3,this.lastTime=e;const t=this.delta>0?1/this.delta:0;this.fps=this.fps*.95+t*.05,this.time=(e-this.startTime)/1e3,this.frame++,this.callback&&this.callback(this.getState()),this.rafId=requestAnimationFrame(this.loop)}}class M{constructor(e){a(this,"gl");a(this,"vao",null);a(this,"vbo",null);a(this,"ibo",null);a(this,"vertexCount",0);a(this,"indexCount",0);a(this,"useIndices",!1);a(this,"vaoExt",null);a(this,"isWebGL2");this.gl=e,this.isWebGL2=e instanceof WebGL2RenderingContext,this.isWebGL2||(this.vaoExt=e.getExtension("OES_vertex_array_object"))}static fullscreenQuad(e){const t=new M(e),n=new Float32Array([-1,-1,0,0,1,-1,1,0,-1,1,0,1,1,1,1,1]),i=new Uint16Array([0,1,2,2,1,3]);return t.setup(n,i),t}setup(e,t){const n=this.gl;return this.createVAO(),this.bindVAO(),this.vbo=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,this.vbo),n.bufferData(n.ARRAY_BUFFER,e,n.STATIC_DRAW),this.vertexCount=e.length/4,t&&(this.ibo=n.createBuffer(),n.bindBuffer(n.ELEMENT_ARRAY_BUFFER,this.ibo),n.bufferData(n.ELEMENT_ARRAY_BUFFER,t,n.STATIC_DRAW),this.indexCount=t.length,this.useIndices=!0),this.unbindVAO(),this}linkAttributes(e){const t=this.gl;this.bindVAO(),t.bindBuffer(t.ARRAY_BUFFER,this.vbo);const n=4*Float32Array.BYTES_PER_ELEMENT,i=this.getPositionLocation(e);i>=0&&(t.enableVertexAttribArray(i),t.vertexAttribPointer(i,2,t.FLOAT,!1,n,0));const r=this.getTexcoordLocation(e);return r>=0&&(t.enableVertexAttribArray(r),t.vertexAttribPointer(r,2,t.FLOAT,!1,n,2*Float32Array.BYTES_PER_ELEMENT)),this.useIndices&&t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.ibo),this.unbindVAO(),this}bind(){return this.bindVAO(),this}unbind(){return this.unbindVAO(),this}draw(){const e=this.gl;return this.bindVAO(),this.useIndices?e.drawElements(e.TRIANGLES,this.indexCount,e.UNSIGNED_SHORT,0):e.drawArrays(e.TRIANGLE_STRIP,0,this.vertexCount),this}destroy(){const e=this.gl;this.deleteVAO(),this.vbo&&(e.deleteBuffer(this.vbo),this.vbo=null),this.ibo&&(e.deleteBuffer(this.ibo),this.ibo=null)}getPositionLocation(e){let t=e.getAttribLocation("a_position");return t>=0||(t=e.getAttribLocation("aPosition"),t>=0)||(t=e.getAttribLocation("position"),t>=0)?t:-1}getTexcoordLocation(e){let t=e.getAttribLocation("a_texcoord");return t>=0||(t=e.getAttribLocation("aTexCoord"),t>=0)||(t=e.getAttribLocation("texcoord"),t>=0)||(t=e.getAttribLocation("a_uv"),t>=0)?t:-1}createVAO(){this.isWebGL2?this.vao=this.gl.createVertexArray():this.vaoExt&&(this.vao=this.vaoExt.createVertexArrayOES())}bindVAO(){this.vao&&(this.isWebGL2?this.gl.bindVertexArray(this.vao):this.vaoExt&&this.vaoExt.bindVertexArrayOES(this.vao))}unbindVAO(){this.isWebGL2?this.gl.bindVertexArray(null):this.vaoExt&&this.vaoExt.bindVertexArrayOES(null)}deleteVAO(){this.vao&&(this.isWebGL2?this.gl.deleteVertexArray(this.vao):this.vaoExt&&this.vaoExt.deleteVertexArrayOES(this.vao),this.vao=null)}}class le{constructor(e){a(this,"gl");a(this,"program",null);a(this,"vertexShader",null);a(this,"fragmentShader",null);this.gl=e}compile(e,t){return this.destroy(),this.vertexShader=this.compileShader("vertex",e),this.fragmentShader=this.compileShader("fragment",t),this.linkProgram(),this}use(){return this.program&&this.gl.useProgram(this.program),this}getProgram(){return this.program}getAttribLocation(e){return this.program?this.gl.getAttribLocation(this.program,e):-1}getUniformLocation(e){return this.program?this.gl.getUniformLocation(this.program,e):null}destroy(){const e=this.gl;this.program&&(this.vertexShader&&e.detachShader(this.program,this.vertexShader),this.fragmentShader&&e.detachShader(this.program,this.fragmentShader),e.deleteProgram(this.program),this.program=null),this.vertexShader&&(e.deleteShader(this.vertexShader),this.vertexShader=null),this.fragmentShader&&(e.deleteShader(this.fragmentShader),this.fragmentShader=null)}compileShader(e,t){const n=this.gl,i=e==="vertex"?n.VERTEX_SHADER:n.FRAGMENT_SHADER,r=n.createShader(i);if(!r)throw new w(e,t,"Failed to create shader object");if(n.shaderSource(r,t),n.compileShader(r),!n.getShaderParameter(r,n.COMPILE_STATUS)){const o=n.getShaderInfoLog(r)||"Unknown error";throw n.deleteShader(r),new w(e,t,o)}return r}linkProgram(){const e=this.gl;if(!this.vertexShader||!this.fragmentShader)throw new _("Shaders not compiled");const t=e.createProgram();if(!t)throw new _("Failed to create program object");if(e.attachShader(t,this.vertexShader),e.attachShader(t,this.fragmentShader),e.linkProgram(t),!e.getProgramParameter(t,e.LINK_STATUS)){const i=e.getProgramInfoLog(t)||"Unknown error";throw e.deleteProgram(t),new _(i)}this.program=t}}class k{constructor(e,t){a(this,"name");a(this,"method");a(this,"isArray");a(this,"isMatrix");a(this,"location",null);a(this,"locationResolved",!1);a(this,"value");this.name=e,this.value=t;const n=k.inferMethodInfo(t);this.method=n.method,this.isArray=n.isArray,this.isMatrix=n.isMatrix}static inferMethodInfo(e){if(typeof e=="boolean")return{method:"uniform1i",isArray:!1,isMatrix:!1};if(typeof e=="number")return{method:"uniform1f",isArray:!1,isMatrix:!1};if(!Array.isArray(e))return{method:"uniform1f",isArray:!1,isMatrix:!1};const t=e.length,n=e[0];if(Array.isArray(n))switch(n.length){case 2:return{method:"uniform2fv",isArray:!0,isMatrix:!1};case 3:return{method:"uniform3fv",isArray:!0,isMatrix:!1};case 4:return{method:"uniform4fv",isArray:!0,isMatrix:!1};default:return{method:"uniform1fv",isArray:!0,isMatrix:!1}}switch(t){case 2:return{method:"uniform2fv",isArray:!1,isMatrix:!1};case 3:return{method:"uniform3fv",isArray:!1,isMatrix:!1};case 4:return{method:"uniform4fv",isArray:!1,isMatrix:!1};case 9:return{method:"uniformMatrix3fv",isArray:!1,isMatrix:!0};case 16:return{method:"uniformMatrix4fv",isArray:!1,isMatrix:!0};default:return{method:"uniform1fv",isArray:!0,isMatrix:!1}}}resolveLocation(e,t){return this.locationResolved||(this.location=e.getUniformLocation(t,this.name),this.locationResolved=!0),this.location}invalidateLocation(){this.location=null,this.locationResolved=!1}setValue(e){this.value=e}getValue(){return this.value}upload(e,t){const n=this.resolveLocation(e,t);if(n===null)return;const i=this.value;let r;switch(typeof i=="boolean"?r=i?1:0:typeof i=="number"?r=i:this.isArray&&Array.isArray(i[0])?r=new Float32Array(i.flat()):r=new Float32Array(i),this.method){case"uniform1f":e.uniform1f(n,r);break;case"uniform1i":e.uniform1i(n,r);break;case"uniform1fv":e.uniform1fv(n,r);break;case"uniform2fv":e.uniform2fv(n,r);break;case"uniform3fv":e.uniform3fv(n,r);break;case"uniform4fv":e.uniform4fv(n,r);break;case"uniformMatrix2fv":e.uniformMatrix2fv(n,!1,r);break;case"uniformMatrix3fv":e.uniformMatrix3fv(n,!1,r);break;case"uniformMatrix4fv":e.uniformMatrix4fv(n,!1,r);break}}}class E{constructor(e){a(this,"parsed",null);this.source=e}parse(){if(this.parsed)return this.parsed;const e=this.detectVersion(),t=this.detectImports(),n=this.detectUniforms(),i=this.detectFunctions(n);return this.parsed={version:e,imports:t,uniforms:n,functions:i}}isParsed(){return this.parsed!==null}setSource(e){this.source=e,this.parsed=null}version(){return this.detectVersion()}detectVersion(){return/^\s*#version\s+300\s+es/m.test(this.source)?2:1}detectImports(){const e=/^[ \t]*#import\s+(\w+)(?:\s+as\s+(\w+))?\s+from\s+["'](.+)["']/gm,t=/^[ \t]*[^\w\s]?import\b/gm,n=[],i=new Set;let r,s=1,o=0;for(;(r=e.exec(this.source))!==null;){s+=(this.source.substring(o,r.index).match(/\n/g)||[]).length,o=r.index,i.add(s);const f=r[1],c=r[2]||r[1],m=r[3];if(n.some(d=>d.alias===c))throw new $(c,s);n.push({name:f,alias:c,module:m,line:s})}let l;for(;(l=t.exec(this.source))!==null;){const f=(this.source.substring(0,l.index).match(/\n/g)||[]).length+1;if(i.has(f))continue;const c=this.source.split(`
6
+ `)[f-1].trim();throw new P(f,this.diagnoseImport(c))}return n}diagnoseImport(e){const t=e.match(/^([^\w\s])import\b/);if(t&&t[1]!=="#")return`Invalid prefix '${t[1]}'. Expected: #import <function> from '<module>'`;if(/^import\b/.test(e))return"Missing '#' prefix. Expected: #import <function> from '<module>'";if(/^#import\s+from\b/.test(e))return"Missing function name. Expected: #import <function> from '<module>'";if(/^#import\s+\w+\s*$/.test(e))return`Missing 'from' clause. Expected: #import ${e.split(/\s+/)[1]} from '<module>'`;if(/^#import\s+\w+\s+as\s*$/.test(e)||/^#import\s+\w+\s+as\s+from\b/.test(e))return`Missing alias name after 'as'. Expected: #import ${e.split(/\s+/)[1]} as <alias> from '<module>'`;if(/^#import\s+\w+\s+as\s+\w+\s*$/.test(e)){const n=e.split(/\s+/);return`Missing 'from' clause. Expected: #import ${n[1]} as ${n[3]} from '<module>'`}if(/^#import\s+\w+(?:\s+as\s+\w+)?\s+from\s+\w+/.test(e)){const n=e.match(/from\s+(\S+)/);return`Module name must be quoted. Expected: from '${n==null?void 0:n[1]}'`}return"Invalid syntax. Expected: #import <function> from '<module>'"}detectUniforms(){const e=/^[ \t]*uniform\s+(?:(?:highp|mediump|lowp)\s+)?(\w+)\s+(\w+)(?:\[(\d+)\])?\s*;/gm,t=[];let n,i=1,r=0;for(;(n=e.exec(this.source))!==null;){i+=(this.source.substring(r,n.index).match(/\n/g)||[]).length,r=n.index;const s=n[1],o=n[2],l=n[3]?parseInt(n[3],10):void 0;t.push({name:o,type:s,line:i,arrayNum:l})}return t}detectFunctions(e){const t=[],n="void|float|int|uint|bool|vec[234]|ivec[234]|uvec[234]|bvec[234]|mat[234](?:x[234])?|sampler2D|samplerCube|sampler3D|sampler2DArray",i=new RegExp(`^[ \\t]*(${n})\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*\\{`,"gm");let r;for(;(r=i.exec(this.source))!==null;){const s=r[1],o=r[2],l=r[3].trim(),f=r.index,c=(this.source.substring(0,f).match(/\n/g)||[]).length+1,m=this.source.indexOf("{",f),d=this.findClosingBrace(this.source,m);if(d===-1)continue;const v=this.source.slice(m,d+1),J=this.parseParams(l),Z=this.findFunctionCalls(v),ee=this.findUniformCalls(v,e),te=this.findMentionCalls(v);t.push({name:o,type:s,params:J,body:v,dependencies:[...Z,...ee,...te],line:c})}return t}parseParams(e){if(!e.trim())return[];const t=[],n=e.split(",");for(const i of n){const r=i.trim();if(!r)continue;const o=r.replace(/\b(in|out|inout|const|highp|mediump|lowp)\b\s*/g,"").trim().match(/^(\w+)\s+(\w+)(?:\[\d*\])?$/);o&&t.push({type:o[1],name:o[2]})}return t}findClosingBrace(e,t){let n=0,i=!1,r=!1,s=!1,o=!1;for(let l=t;l<e.length;l++){const f=e[l],c=e[l+1],m=e[l-1];if(!r&&!o&&f==="/"&&c==="/"){s=!0;continue}if(s&&f===`
7
+ `){s=!1;continue}if(!r&&!s&&f==="/"&&c==="*"){o=!0,l++;continue}if(o&&f==="*"&&c==="/"){o=!1,l++;continue}if(!(s||o)){if(f==='"'&&m!=="\\"){r=!r;continue}if(!r){if(f==="{")n++,i=!0;else if(f==="}"&&(n--,i&&n===0))return l}}}return-1}findFunctionCalls(e){const t=[],n=new Set(["if","else","for","while","do","switch","case","return","break","continue","discard"]),i=/\b([a-zA-Z_]\w*)\s*\(/g;let r;for(;(r=i.exec(e))!==null;){const s=r[1];n.has(s)||t.push({name:s,type:"function",index:r.index})}return t}findUniformCalls(e,t){const n=[];for(const i of t){const r=new RegExp(`\\b${i.name}\\b`,"g");let s;for(;(s=r.exec(e))!==null;)n.push({name:i.name,type:"uniform",index:s.index})}return n}findMentionCalls(e){const t=[],n=/@(\w+)\.([a-zA-Z_]\w*)/g;let i;for(;(i=n.exec(e))!==null;){const r=i[1],s=i[2];t.push({name:`${r}.${s}`,type:"mention",index:i.index})}return t}}class K{constructor(e){a(this,"isCompiled",!1);a(this,"original");a(this,"compiled");a(this,"requirements",{uniforms:new Map,functions:new Map});this.original=new E(e),this.compiled=new E(e)}version(){return this.original.version()}source(){return this.original.source}recompile(){return this.isCompiled=!1,this.compile()}compile(e){return this.isCompiled?this.compiled.source:(this.original.parse().imports.length>0&&this.processImports(e),this.compiled.setSource(this.build()),this.isCompiled=!0,this.compiled.source)}processImports(e){const t=this.original.parse(),n=t.functions.flatMap(i=>i.dependencies.filter(r=>r.type==="mention").map(r=>({name:r.name.split(".")[0],uniform:r.name.split(".")[1]})));for(const i of t.imports){const r=b.resolve(i.module),s=r.extract(i.name);let o=n.filter(f=>f.name===s.function.name);if(o.length>0){const f=r.getDefinition().uniforms;if(o=o.filter(c=>{const m=f.find(d=>d.name===`u_${c.uniform}`||d.name===c.uniform);if(m){s.dependencies.uniforms.some(v=>v.name===m.name)||s.dependencies.uniforms.push(m);const d=n.indexOf(c);return d>-1&&n.splice(d,1),!1}return!0}),o.length>0)throw new H(i.module,s.function.name,o[0].uniform)}const l=r.copy();this.processExtraction(s,i.alias,l.options),e==null||e.merge(i.module,l)}if(n.length>0)throw new q(n[0].name,n[0].uniform)}processExtraction(e,t,n={}){const i=e.function,r=Math.random().toString(36).substring(2,8),s=`${t}_${r}`;for(let l=e.dependencies.functions.length-1;l>=0;l--){const f=e.dependencies.functions[l],c=this.rewriteFunction(f,t,{uniforms:e.dependencies.uniforms,functions:e.dependencies.functions,unique:s});this.requirements.functions.set(c.name,c)}const o=this.rewriteFunction(i,t,{uniforms:e.dependencies.uniforms,functions:e.dependencies.functions,rename:!0,unique:s});this.requirements.functions.set(o.name,o);for(const l of e.dependencies.uniforms){if(R.has(l.name))continue;const f={...l,name:`${s}_${l.name}${l.arrayNum?`[${l.arrayNum}]`:""}`};if(n[i.name]){const c=Object.entries(n[i.name]).find(([m,d])=>d.uniform===l.name);c&&(c[1].uniform=`${s}_${l.name}`)}this.requirements.uniforms.set(f.name,f)}n[i.name]&&t!==i.name&&(n[t]=n[i.name],delete n[i.name])}rewriteFunction(e,t,n={rename:!1,uniforms:[],functions:[],unique:""}){const i=new Set(n.uniforms.map(c=>c.name)),r=new Set(n.functions.map(c=>c.name)),s=[],o=n.unique?n.unique:t;for(const c of e.dependencies)if(c.index!==void 0)if(c.type==="uniform"&&i.has(c.name)){if(R.has(c.name))continue;s.push({index:c.index,oldText:c.name,newText:`${o}_${c.name}`})}else c.type==="function"&&r.has(c.name)&&s.push({index:c.index,oldText:c.name,newText:`${o}_${c.name}`});const l=this.applyRewrites(e.body,s),f=n.rename?t:`${o}_${e.name}`;return{...e,name:f,body:l}}applyRewrites(e,t){const n=[...t].sort((r,s)=>s.index-r.index);let i=e;for(const r of n)i=i.slice(0,r.index)+r.newText+i.slice(r.index+r.oldText.length);return i}build(){const e=this.original.parse();let t=this.original.source;t=this.removeImportLines(t,e);const n=this.findInsertionPointForUniforms(t),i=this.generateUniformsCode();i&&(t=t.slice(0,n)+i+`
8
8
  `+t.slice(n));const r=this.findInsertionPointForFunctions(t),s=this.generateFunctionCode();return s&&(t=t.slice(0,r)+s+t.slice(r)),t=t.replace(/\n{3,}/g,`
9
9
 
10
- `),t=this.replaceMentions(t,e),t}replaceMentions(e,t){let n=e;const i=t.functions.filter(r=>r.dependencies.some(s=>s.type==="mention"));for(const r of i){const s=r.dependencies.filter(a=>a.type==="mention");for(const a of s){const l=a.name.split("."),f=new RegExp(`\\b${l[0]}_(\\w+)_${l[1]}\\b`,"g"),c=this.requirements.uniforms.keys().find(p=>{var g;return((g=p.match(f))==null?void 0:g[0])===p});if(!c)throw new X(a.name,r.name);const d=new RegExp(`@\\b${a.name}\\b`,"g");n=n.replace(d,c)}}return n}removeImportLines(e,t){const n=e.split(`
11
- `),i=new Set(t.imports.map(r=>r.line));return n.filter((r,s)=>{const a=i.has(s+1);if(!a&&r.trim()===""&&s>0){const l=s-1;if(i.has(l+1))return!1}return!a}).join(`
12
- `)}findInsertionPointForUniforms(e){const t=new _(e).parse(),n=t.uniforms.find(a=>a.line===Math.max(...t.uniforms.map(l=>l.line??0))),i=e.split(`
13
- `);let r=0;if(n&&n.line)r=n.line;else for(let a=0;a<i.length;a++){const l=i[a].trim();if(l.startsWith("#version")){r=a+1;continue}if(l.startsWith("precision ")){r=a+1;continue}if(l===""||l.startsWith("//")){r===a&&(r=a+1);continue}break}let s=0;for(let a=0;a<r;a++)s+=i[a].length+1;return s}findInsertionPointForFunctions(e){const t=new _(e).parse(),n=t.functions.find(a=>a.line===Math.min(...t.functions.map(l=>l.line??1/0))),i=e.split(`
14
- `);let r=0;if(n&&n.line)r=n.line-2;else throw new P;let s=0;for(let a=0;a<r;a++)s+=i[a].length+1;return s}generateUniformsCode(){const e=[];if(this.requirements.uniforms.size>0)for(const t of this.checkUniformsPresence())e.push(`uniform ${t.type} ${t.name};`);return e.length===0?"":e.join(`
10
+ `),t=this.replaceMentions(t,e),t}replaceMentions(e,t){let n=e;const i=t.functions.filter(r=>r.dependencies.some(s=>s.type==="mention"));for(const r of i){const s=r.dependencies.filter(o=>o.type==="mention");for(const o of s){const l=o.name.split("."),f=new RegExp(`\\b${l[0]}_(\\w+)_${l[1]}\\b`,"g"),c=this.requirements.uniforms.keys().find(d=>{var v;return((v=d.match(f))==null?void 0:v[0])===d});if(!c)throw new j(o.name,r.name);const m=new RegExp(`@\\b${o.name}\\b`,"g");n=n.replace(m,c)}}return n}removeImportLines(e,t){const n=e.split(`
11
+ `),i=new Set(t.imports.map(r=>r.line));return n.filter((r,s)=>{const o=i.has(s+1);if(!o&&r.trim()===""&&s>0){const l=s-1;if(i.has(l+1))return!1}return!o}).join(`
12
+ `)}findInsertionPointForUniforms(e){const t=new E(e).parse(),n=t.uniforms.find(o=>o.line===Math.max(...t.uniforms.map(l=>l.line??0))),i=e.split(`
13
+ `);let r=0;if(n&&n.line)r=n.line;else for(let o=0;o<i.length;o++){const l=i[o].trim();if(l.startsWith("#version")){r=o+1;continue}if(l.startsWith("precision ")){r=o+1;continue}if(l===""||l.startsWith("//")){r===o&&(r=o+1);continue}break}let s=0;for(let o=0;o<r;o++)s+=i[o].length+1;return s}findInsertionPointForFunctions(e){const t=new E(e).parse(),n=t.functions.find(o=>o.line===Math.min(...t.functions.map(l=>l.line??1/0))),i=e.split(`
14
+ `);let r=0;if(n&&n.line)r=n.line-2;else throw new I;let s=0;for(let o=0;o<r;o++)s+=i[o].length+1;return s}generateUniformsCode(){const e=[];if(this.requirements.uniforms.size>0)for(const t of this.checkUniformsPresence())e.push(`uniform ${t.type} ${t.name};`);return e.length===0?"":e.join(`
15
15
  `)+`
16
16
  `}generateFunctionCode(){const e=[];if(this.requirements.functions.size>0)for(const t of this.checkFunctionsPresence()){const n=t.params.map(i=>`${i.type} ${i.name}`).join(", ");e.push(`
17
17
  ${t.type} ${t.name}(${n}) ${t.body}`)}return e.length===0?"":e.join(`
18
18
  `)+`
19
- `}checkUniformsPresence(){const e=this.original.parse(),t=[],n=this.requirements.uniforms;for(const[i,r]of n){const s=e.uniforms.find(a=>a.name===i);if(!s){t.push(r);continue}if(s.type!==r.type)throw new M("uniform",i,r.type,s.type)}return t}checkFunctionsPresence(){const e=this.original.parse(),t=[],n=this.requirements.functions;for(const[i,r]of n){const s=e.functions.find(a=>a.name===i);if(!s){t.push(r);continue}if(s.type!==r.type)throw new M("function",i,r.type,s.type)}return t}}class v extends Q{constructor(t,n,i={}){super(n);o(this,"name");o(this,"options",{});this.name=t,this.options=this.resolveOptions(i)}resolveOptions(t){if(!(t!=null&&t.default))return t||{};const n=this.original.parse(),i=t.default;for(const r of n.functions)if(!(r.name==="main"||r.name==="default"))if(t[r.name]){const s=t[r.name];for(const a in i)a in s||(s[a]=i[a])}else t[r.name]={...i};return delete t.default,t||{}}static define(t){const{name:n,source:i,options:r}=t;if(n==="sandbox"||n.startsWith("sandbox/"))throw new z(n);const s=new v(n,i,r);if(w.has(n))throw new H(n);return w.register(n,s),s}static resolve(t){return w.resolve(t)}copy(t="original"){return new v(this.name,this[t].source,JSON.parse(JSON.stringify(this.options)))}merge(t){this.options=this.options||{};const n=this.getDefinition().uniforms.map(i=>i.name);for(const[i,r]of Object.entries(t.options??{}))if(!this.options[i])this.options[i]=r;else for(const[s,a]of Object.entries(r))n.includes(a.uniform)||(this.options[i][s]=a)}getDefinition(){return this.compile(),{name:this.name,methods:this.compiled.parse().functions.map(t=>t.name).filter(t=>t!=="main"&&t!=="default"),uniforms:this.compiled.parse().uniforms.map(t=>({name:t.name,type:t.type})),options:this.options}}extract(t){if(this.compile(),t==="main")throw new G(this.name);if(t==="default")throw new W(this.name);const n=this.compiled.parse(),i=n.functions.find(a=>a.name===t);if(!i)throw new N(this.name,t);const r=new Map,s=new Map;return this.collectDependencies({current:i,scope:{functions:n.functions,uniforms:n.uniforms},collected:{functions:r,uniforms:s},visited:new Set([t])}),{function:i,dependencies:{functions:Array.from(r.values()),uniforms:Array.from(s.values())}}}collectDependencies(t){for(const n of t.current.dependencies)if(n.type==="function"){if(t.visited.has(n.name))continue;const i=t.scope.functions.find(r=>r.name===n.name);i&&(t.visited.add(n.name),t.collected.functions.set(n.name,i),this.collectDependencies({current:i,scope:{functions:t.scope.functions,uniforms:t.scope.uniforms},collected:{functions:t.collected.functions,uniforms:t.collected.uniforms},visited:t.visited}))}else if(n.type==="uniform"){const i=t.scope.uniforms.find(r=>r.name===n.name);i&&!t.collected.uniforms.has(n.name)&&t.collected.uniforms.set(n.name,i)}}}class J{constructor(e=[]){o(this,"modules",new Map);e.forEach(t=>{this.register(t.name,t)})}compile(){this.modules.forEach(e=>{e.compile()})}available(){return Array.from(this.modules.values()).map(e=>e.getDefinition())}defaults(){const e={};return this.modules.forEach(t=>{const n=t.getDefinition();if(n.options)for(const i in n.options){const r=n.options[i];for(const s in r){const a=r[s];a.default!==void 0&&!n.uniforms.map(l=>l.name).includes(a.uniform)&&(e[a.uniform]=a.default)}}}),e}resolveOptions(e){for(const t of this.modules.values())if(t.options&&t.options[e])return t.options[e];return null}register(e,t){this.modules.set(e,t)}merge(e,t){if(!this.modules.has(e))return this.register(e,t);const n=this.modules.get(e);n.merge(t),this.modules.set(e,n)}resolve(e){const t=this.modules.get(e);if(!t)throw new B(e);return t}has(e){return this.modules.has(e)}isEmpty(){return this.modules.size===0}remove(e){this.modules.delete(e)}load(e){e.forEach(t=>{this.register(t.name,t)})}clear(){this.modules.clear()}}const ue=`// ─── Constants ──────────────────────────────────────────────
19
+ `}checkUniformsPresence(){const e=this.original.parse(),t=[],n=this.requirements.uniforms;for(const[i,r]of n){const s=e.uniforms.find(o=>o.name===i);if(!s){t.push(r);continue}if(s.type!==r.type)throw new A("uniform",i,r.type,s.type)}return t}checkFunctionsPresence(){const e=this.original.parse(),t=[],n=this.requirements.functions;for(const[i,r]of n){const s=e.functions.find(o=>o.name===i);if(!s){t.push(r);continue}if(s.type!==r.type)throw new A("function",i,r.type,s.type)}return t}}class g extends K{constructor(t,n,i={}){super(n);a(this,"name");a(this,"options",{});this.name=t,this.options=this.resolveOptions(i)}resolveOptions(t){if(!(t!=null&&t.default))return t||{};const n=this.original.parse(),i=t.default;for(const r of n.functions)if(!(r.name==="main"||r.name==="default"))if(t[r.name]){const s=t[r.name];for(const o in i)o in s||(s[o]=i[o])}else t[r.name]={...i};return delete t.default,t||{}}static define(t){const{name:n,source:i,options:r}=t;if(n==="sandbox"||n.startsWith("sandbox/"))throw new W(n);const s=new g(n,i,r);if(b.has(n))throw new z(n);return b.register(n,s),s}static resolve(t){return b.resolve(t)}copy(t="original"){return new g(this.name,this[t].source,JSON.parse(JSON.stringify(this.options)))}merge(t){this.options=this.options||{};const n=this.getDefinition().uniforms.map(i=>i.name);for(const[i,r]of Object.entries(t.options??{}))if(!this.options[i])this.options[i]=r;else for(const[s,o]of Object.entries(r))n.includes(o.uniform)||(this.options[i][s]=o)}getDefinition(){return this.compile(),{name:this.name,methods:this.compiled.parse().functions.map(t=>t.name).filter(t=>t!=="main"&&t!=="default"),uniforms:this.compiled.parse().uniforms.map(t=>({name:t.name,type:t.type})),options:this.options}}extract(t){if(this.compile(),t==="main")throw new N(this.name);if(t==="default")throw new G(this.name);const n=this.compiled.parse(),i=n.functions.find(o=>o.name===t);if(!i)throw new B(this.name,t);const r=new Map,s=new Map;return this.collectDependencies({current:i,scope:{functions:n.functions,uniforms:n.uniforms},collected:{functions:r,uniforms:s},visited:new Set([t])}),{function:i,dependencies:{functions:Array.from(r.values()),uniforms:Array.from(s.values())}}}collectDependencies(t){for(const n of t.current.dependencies)if(n.type==="function"){if(t.visited.has(n.name))continue;const i=t.scope.functions.find(r=>r.name===n.name);i&&(t.visited.add(n.name),t.collected.functions.set(n.name,i),this.collectDependencies({current:i,scope:{functions:t.scope.functions,uniforms:t.scope.uniforms},collected:{functions:t.collected.functions,uniforms:t.collected.uniforms},visited:t.visited}))}else if(n.type==="uniform"){const i=t.scope.uniforms.find(r=>r.name===n.name);i&&!t.collected.uniforms.has(n.name)&&t.collected.uniforms.set(n.name,i)}}}class Q{constructor(e=[]){a(this,"modules",new Map);e.forEach(t=>{this.register(t.name,t)})}compile(){this.modules.forEach(e=>{e.compile()})}available(){return Array.from(this.modules.values()).map(e=>e.getDefinition())}defaults(){const e={};return this.modules.forEach(t=>{const n=t.getDefinition();if(n.options)for(const i in n.options){const r=n.options[i];for(const s in r){const o=r[s];o.default!==void 0&&!n.uniforms.map(l=>l.name).includes(o.uniform)&&(e[o.uniform]=o.default)}}}),e}resolveOptions(e){for(const t of this.modules.values())if(t.options&&t.options[e])return t.options[e];return null}register(e,t){this.modules.set(e,t)}merge(e,t){if(!this.modules.has(e))return this.register(e,t);const n=this.modules.get(e);n.merge(t),this.modules.set(e,n)}resolve(e){const t=this.modules.get(e);if(!t)throw new D(e);return t}has(e){return this.modules.has(e)}isEmpty(){return this.modules.size===0}remove(e){this.modules.delete(e)}load(e){e.forEach(t=>{this.register(t.name,t)})}clear(){this.modules.clear()}}const ce=`// ─── Constants ──────────────────────────────────────────────
20
20
 
21
21
  const float PI = 3.14159265359;
22
22
  const float TAU = 6.28318530718;
@@ -225,7 +225,7 @@ vec2 voronoi(vec2 p) {
225
225
  }
226
226
 
227
227
  void main() {}
228
- `,fe=`/**
228
+ `,ue=`/**
229
229
  * Hex integer to RGB.
230
230
  * Usage: hex(0xFF6600) → orange
231
231
  */
@@ -324,7 +324,7 @@ vec3 iridescent(vec2 uv, float time, float speed) {
324
324
  }
325
325
 
326
326
  void main() {}
327
- `,he=`// ─── Time Shapers ──────────────────────────────────────────
327
+ `,fe=`// ─── Time Shapers ──────────────────────────────────────────
328
328
  // Convert raw time (u_time) to normalized 0–1 range.
329
329
  // Output feeds directly into easing functions.
330
330
 
@@ -446,7 +446,7 @@ float teleport(float t) {
446
446
  }
447
447
 
448
448
  void main() {}
449
- `,de=`#import hash from 'sandbox'
449
+ `,he=`#import hash from 'sandbox'
450
450
  #import noise from 'sandbox'
451
451
  #import fbm from 'sandbox'
452
452
  #import voronoi from 'sandbox'
@@ -641,7 +641,7 @@ vec2 cells(vec2 uv, float intensity) {
641
641
  }
642
642
 
643
643
  void main() {}
644
- `,me=`#import hash from 'sandbox'
644
+ `,de=`#import hash from 'sandbox'
645
645
 
646
646
  uniform float u_intensity;
647
647
 
@@ -828,7 +828,7 @@ vec3 arcade(vec3 color, vec2 uv, float intensity) {
828
828
  }
829
829
 
830
830
  void main() {}
831
- `,w=new J([new v("sandbox",ue),new v("sandbox/colors",fe),new v("sandbox/time",he),new v("sandbox/effects",de,{default:{intensity:{uniform:"u_intensity",default:1}},pixelate:{intensity:{uniform:"u_intensity",default:20}},twist:{intensity:{uniform:"u_intensity",default:1}},ripple:{intensity:{uniform:"u_intensity",default:1}},fisheye:{intensity:{uniform:"u_intensity",default:1}},wobble:{intensity:{uniform:"u_intensity",default:1}},organic:{intensity:{uniform:"u_intensity",default:3}},glitch:{intensity:{uniform:"u_intensity",default:1}},mirror:{intensity:{uniform:"u_intensity",default:0}},kaleidoscope:{intensity:{uniform:"u_intensity",default:6}},zoom:{intensity:{uniform:"u_intensity",default:1}},warp:{intensity:{uniform:"u_intensity",default:1}},displace:{intensity:{uniform:"u_intensity",default:1}},shatter:{intensity:{uniform:"u_intensity",default:10}},cells:{intensity:{uniform:"u_intensity",default:8}},glass:{intensity:{uniform:"u_intensity",default:1}}}),new v("sandbox/filters",me,{default:{intensity:{uniform:"u_intensity",default:1}},posterize:{intensity:{uniform:"u_intensity",default:8}},threshold:{intensity:{uniform:"u_intensity",default:.5}},grain:{intensity:{uniform:"u_intensity",default:.1}},vignette:{intensity:{uniform:"u_intensity",default:1.4}},glow:{intensity:{uniform:"u_intensity",default:.5}},gamma:{intensity:{uniform:"u_intensity",default:2.2}},dither:{intensity:{uniform:"u_intensity",default:4}},highlights:{intensity:{uniform:"u_intensity",default:.5}}})]),y=new J,S=new Map([["u_resolution","vec2"],["u_time","float"],["u_delta","float"],["u_mouse","vec2"],["u_frame","int"]]);class pe{constructor(e){o(this,"gl");o(this,"program",null);o(this,"uniforms",new Map);this.gl=e}attachProgram(e){this.program=e;for(const t of this.uniforms.values())t.invalidateLocation();return this}set(e,t){const n=this.uniforms.get(e);return n?n.setValue(t):this.uniforms.set(e,new T(e,t)),this}setMany(e){for(const[t,n]of Object.entries(e))this.set(t,n);return this}get(e){var t;return(t=this.uniforms.get(e))==null?void 0:t.getValue()}has(e){return this.uniforms.has(e)}delete(e){return this.uniforms.delete(e)}uploadAll(){if(!this.program)return this;for(const e of this.uniforms.values())e.upload(this.gl,this.program);return this}uploadBuiltIns(e,t,n){if(this.set("u_resolution",t),this.set("u_time",e.time),this.set("u_delta",e.delta),this.set("u_mouse",n),this.set("u_frame",e.frame),!this.program)return this;for(const i of S.keys()){const r=this.uniforms.get(i);r&&r.upload(this.gl,this.program)}return this}clear(){this.uniforms.clear()}destroy(){this.uniforms.clear(),this.program=null}keys(){return this.uniforms.keys()}get size(){return this.uniforms.size}}class x{constructor(e,t,n,i){o(this,"name");o(this,"gl");o(this,"texture",null);o(this,"location",null);o(this,"locationResolved",!1);o(this,"source");o(this,"options");o(this,"dynamicOverride");o(this,"needsUpload",!0);o(this,"needsReupload",!1);this.gl=e,this.name=t,this.source=n,this.dynamicOverride=i==null?void 0:i.dynamic,this.options=x.resolveOptions(n,i),this.needsReupload=this.options.dynamic}setSource(e){this.source=e,this.needsUpload=!0,this.needsReupload=this.dynamicOverride??x.isDynamicSource(e)}resolveLocation(e,t){return this.locationResolved||(this.location=e.getUniformLocation(t,this.name),this.locationResolved=!0),this.location}invalidateLocation(){this.location=null,this.locationResolved=!1}upload(e,t){const n=this.gl,i=this.resolveLocation(n,e);if(i!==null){if(!this.texture){if(this.texture=n.createTexture(),!this.texture)return;this.needsUpload=!0}n.activeTexture(n.TEXTURE0+t),n.bindTexture(n.TEXTURE_2D,this.texture),(this.needsUpload||this.needsReupload)&&(this.uploadPixels(),this.needsUpload=!1),n.uniform1i(i,t)}}destroy(){this.texture&&(this.gl.deleteTexture(this.texture),this.texture=null),this.location=null,this.locationResolved=!1}uploadPixels(){const e=this.gl;e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,this.options.flipY),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,this.source),this.applyParameters()}applyParameters(){const e=this.gl;e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,x.resolveWrap(e,this.options.wrapS)),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,x.resolveWrap(e,this.options.wrapT)),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,this.options.minFilter==="nearest"?e.NEAREST:e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,this.options.magFilter==="nearest"?e.NEAREST:e.LINEAR)}static resolveWrap(e,t){switch(t){case"repeat":return e.REPEAT;case"mirror":return e.MIRRORED_REPEAT;case"clamp":default:return e.CLAMP_TO_EDGE}}static resolveOptions(e,t){const n=(t==null?void 0:t.wrap)??"clamp";return{wrap:n,wrapS:(t==null?void 0:t.wrapS)??n,wrapT:(t==null?void 0:t.wrapT)??n,minFilter:(t==null?void 0:t.minFilter)??"linear",magFilter:(t==null?void 0:t.magFilter)??"linear",flipY:(t==null?void 0:t.flipY)??!0,dynamic:(t==null?void 0:t.dynamic)??x.isDynamicSource(e)}}static isDynamicSource(e){return e instanceof HTMLVideoElement}}class ve{constructor(e){o(this,"gl");o(this,"program",null);o(this,"textures",new Map);this.gl=e}attachProgram(e){this.program=e;for(const t of this.textures.values())t.invalidateLocation();return this}set(e,t,n){const i=this.textures.get(e);return i?i.setSource(t):this.textures.set(e,new x(this.gl,e,t,n)),this}get(e){return this.textures.get(e)}has(e){return this.textures.has(e)}delete(e){const t=this.textures.get(e);return t?(t.destroy(),this.textures.delete(e)):!1}uploadAll(){if(!this.program)return this;let e=0;for(const t of this.textures.values())t.upload(this.program,e),e++;return this}get size(){return this.textures.size}destroy(){for(const e of this.textures.values())e.destroy();this.textures.clear(),this.program=null}}class C{constructor(){o(this,"hooks",new Map)}id(){return Math.random().toString(36).substring(2,10)}add(e){const t=this.id();return this.hooks.set(t,e),()=>this.remove(t)}remove(e){this.hooks.delete(e)}run(e){for(const[t,n]of this.hooks)try{n(e)===!1&&this.remove(t)}catch(i){throw new K(t,i instanceof Error?i.message:String(i))}}destroy(){this.hooks.clear()}}class L{constructor(e,t){o(this,"canvas");o(this,"gl");o(this,"options");o(this,"onBeforeHooks",new C);o(this,"onAfterHooks",new C);o(this,"_program");o(this,"_geometry");o(this,"_uniforms");o(this,"_textures");o(this,"_clock");o(this,"_resolution",[1,1]);o(this,"_mouse",[0,0]);o(this,"_version",1);o(this,"playing",!1);this.canvas=e,this.options=t,this.gl=this.initContext(),this.enableExtensions(),this._program=new ce(this.gl),this._geometry=k.fullscreenQuad(this.gl),this._uniforms=new pe(this.gl),this._textures=new ve(this.gl),this._clock=new le,this.options.fps&&this._clock.setMaxFps(this.options.fps),this.options.onBeforeRender&&this.onBeforeHooks.add(this.options.onBeforeRender),this.options.onAfterRender&&this.onAfterHooks.add(this.options.onAfterRender),this.onRender=this.onRender.bind(this)}static setup(e,t){const n=new L(e,t);return t.vertex&&t.fragment&&n.shader(t.vertex,t.fragment),t.uniforms&&n._uniforms.setMany(t.uniforms),t.textures&&n.texturesFromSchema(t.textures),y.isEmpty()||n._uniforms.setMany(y.defaults()),n}initContext(){const e={antialias:this.options.antialias,preserveDrawingBuffer:this.options.preserveDrawingBuffer,alpha:!0,depth:!1,stencil:!1},t=this.canvas.getContext("webgl2",e);if(t)return this._version=2,t;const n=this.canvas.getContext("webgl",e);if(n)return this._version=1,n;const i=new V;throw this.options.onError(i),i}enableExtensions(){this.gl.getExtension("OES_standard_derivatives"),this.gl.getExtension("OES_texture_float"),this.gl.getExtension("OES_texture_float_linear"),this._version===1&&this.gl.getExtension("OES_vertex_array_object")}viewport(e,t,n,i){return this.canvas.width=n,this.canvas.height=i,this.gl.viewport(e,t,n,i),this._resolution=[n,i],this}clock(e){return this._clock.setTime(e),this}mouse(e,t){return this._mouse=[e,t],this}uniform(e,t){return this._uniforms.set(e,t),this}uniforms(e){return this._uniforms.setMany(e),this}getUniform(e){return this._uniforms.get(e)}texture(e,t,n){return this._textures.set(e,t,n),this}texturesFromSchema(e){for(const[t,n]of Object.entries(e))if(n instanceof HTMLImageElement||n instanceof HTMLCanvasElement||n instanceof HTMLVideoElement||n instanceof ImageBitmap||n instanceof ImageData||n instanceof OffscreenCanvas)this._textures.set(t,n);else{const{source:i,...r}=n;this._textures.set(t,i,r)}return this}removeTexture(e){return this._textures.delete(e),this}shader(e,t){try{if(y.clear(),e.version()!==t.version())throw new I(e.version(),t.version());this._program.compile(e.source(),t.compile()),this._version=t.version(),this._geometry.linkAttributes(this._program);const n=this._program.getProgram();n&&(this._uniforms.attachProgram(n),this._textures.attachProgram(n));try{this.options.onLoad()}catch(i){throw new Y(i instanceof Error?i.message:String(i))}}catch(n){n instanceof h&&this.options.onError(n)}return this}play(){return this.playing?this:(this.playing=!0,this._clock.start(this.onRender),this)}pause(){if(!this.playing)return this;const e=this._clock.getState();try{this.onBeforeHooks.run(e)}catch(t){t instanceof h&&this.options.onError(t)}this.playing=!1,this._clock.stop();try{this.onAfterHooks.run(e)}catch(t){t instanceof h&&this.options.onError(t)}return this}render(){return this.onRender(this._clock.getState()),this}getContext(){return this.gl}getVersion(){return this._version}getClock(){return this._clock}destroy(){this.pause(),this._clock.destroy(),this._geometry.destroy(),this._program.destroy(),this._uniforms.destroy(),this._textures.destroy(),this.onAfterHooks.destroy(),this.onBeforeHooks.destroy(),y.clear()}onRender(e){const t=this.gl;try{this.onBeforeHooks.run(e)}catch(n){n instanceof h&&this.options.onError(n)}t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),this._program.use(),this._uniforms.uploadBuiltIns(e,this._resolution,this._mouse),this._uniforms.uploadAll(),this._textures.uploadAll(),this._geometry.bind(),this._geometry.draw();try{this.onAfterHooks.run(e)}catch(n){n instanceof h&&this.options.onError(n)}}}class m extends Q{constructor(e){super(e),S.forEach((t,n)=>{this.requirements.uniforms.set(n,{name:n,type:t,line:0})})}}const A=`#ifdef GL_ES
831
+ `,b=new Q([new g("sandbox",ce),new g("sandbox/colors",ue),new g("sandbox/time",fe),new g("sandbox/effects",he,{default:{intensity:{uniform:"u_intensity",default:1}},pixelate:{intensity:{uniform:"u_intensity",default:20}},twist:{intensity:{uniform:"u_intensity",default:1}},ripple:{intensity:{uniform:"u_intensity",default:1}},fisheye:{intensity:{uniform:"u_intensity",default:1}},wobble:{intensity:{uniform:"u_intensity",default:1}},organic:{intensity:{uniform:"u_intensity",default:3}},glitch:{intensity:{uniform:"u_intensity",default:1}},mirror:{intensity:{uniform:"u_intensity",default:0}},kaleidoscope:{intensity:{uniform:"u_intensity",default:6}},zoom:{intensity:{uniform:"u_intensity",default:1}},warp:{intensity:{uniform:"u_intensity",default:1}},displace:{intensity:{uniform:"u_intensity",default:1}},shatter:{intensity:{uniform:"u_intensity",default:10}},cells:{intensity:{uniform:"u_intensity",default:8}},glass:{intensity:{uniform:"u_intensity",default:1}}}),new g("sandbox/filters",de,{default:{intensity:{uniform:"u_intensity",default:1}},posterize:{intensity:{uniform:"u_intensity",default:8}},threshold:{intensity:{uniform:"u_intensity",default:.5}},grain:{intensity:{uniform:"u_intensity",default:.1}},vignette:{intensity:{uniform:"u_intensity",default:1.4}},glow:{intensity:{uniform:"u_intensity",default:.5}},gamma:{intensity:{uniform:"u_intensity",default:2.2}},dither:{intensity:{uniform:"u_intensity",default:4}},highlights:{intensity:{uniform:"u_intensity",default:.5}}})]),R=new Map([["u_resolution","vec2"],["u_time","float"],["u_delta","float"],["u_mouse","vec2"],["u_frame","int"]]);class me{constructor(e){a(this,"gl");a(this,"program",null);a(this,"uniforms",new Map);this.gl=e}attachProgram(e){this.program=e;for(const t of this.uniforms.values())t.invalidateLocation();return this}set(e,t){const n=this.uniforms.get(e);return n?n.setValue(t):this.uniforms.set(e,new k(e,t)),this}setMany(e){for(const[t,n]of Object.entries(e))this.set(t,n);return this}get(e){var t;return(t=this.uniforms.get(e))==null?void 0:t.getValue()}has(e){return this.uniforms.has(e)}delete(e){return this.uniforms.delete(e)}uploadAll(){if(!this.program)return this;for(const e of this.uniforms.values())e.upload(this.gl,this.program);return this}uploadBuiltIns(e,t,n){if(this.set("u_resolution",t),this.set("u_time",e.time),this.set("u_delta",e.delta),this.set("u_mouse",n),this.set("u_frame",e.frame),!this.program)return this;for(const i of R.keys()){const r=this.uniforms.get(i);r&&r.upload(this.gl,this.program)}return this}clear(){this.uniforms.clear()}destroy(){this.uniforms.clear(),this.program=null}keys(){return this.uniforms.keys()}get size(){return this.uniforms.size}}class x{constructor(e,t,n,i){a(this,"name");a(this,"gl");a(this,"texture",null);a(this,"location",null);a(this,"locationResolved",!1);a(this,"source");a(this,"options");a(this,"dynamicOverride");a(this,"needsUpload",!0);a(this,"needsReupload",!1);this.gl=e,this.name=t,this.source=n,this.dynamicOverride=i==null?void 0:i.dynamic,this.options=x.resolveOptions(n,i),this.needsReupload=this.options.dynamic}setSource(e){this.source=e,this.needsUpload=!0,this.needsReupload=this.dynamicOverride??x.isDynamicSource(e)}resolveLocation(e,t){return this.locationResolved||(this.location=e.getUniformLocation(t,this.name),this.locationResolved=!0),this.location}invalidateLocation(){this.location=null,this.locationResolved=!1}upload(e,t){const n=this.gl,i=this.resolveLocation(n,e);if(i!==null){if(!this.texture){if(this.texture=n.createTexture(),!this.texture)return;this.needsUpload=!0}n.activeTexture(n.TEXTURE0+t),n.bindTexture(n.TEXTURE_2D,this.texture),(this.needsUpload||this.needsReupload)&&(this.uploadPixels(),this.needsUpload=!1),n.uniform1i(i,t)}}destroy(){this.texture&&(this.gl.deleteTexture(this.texture),this.texture=null),this.location=null,this.locationResolved=!1}uploadPixels(){const e=this.gl;e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,this.options.flipY),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,this.source),this.applyParameters()}applyParameters(){const e=this.gl;e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,x.resolveWrap(e,this.options.wrapS)),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,x.resolveWrap(e,this.options.wrapT)),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,this.options.minFilter==="nearest"?e.NEAREST:e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,this.options.magFilter==="nearest"?e.NEAREST:e.LINEAR)}static resolveWrap(e,t){switch(t){case"repeat":return e.REPEAT;case"mirror":return e.MIRRORED_REPEAT;case"clamp":default:return e.CLAMP_TO_EDGE}}static resolveOptions(e,t){const n=(t==null?void 0:t.wrap)??"clamp";return{wrap:n,wrapS:(t==null?void 0:t.wrapS)??n,wrapT:(t==null?void 0:t.wrapT)??n,minFilter:(t==null?void 0:t.minFilter)??"linear",magFilter:(t==null?void 0:t.magFilter)??"linear",flipY:(t==null?void 0:t.flipY)??!0,dynamic:(t==null?void 0:t.dynamic)??x.isDynamicSource(e)}}static isDynamicSource(e){return e instanceof HTMLVideoElement}}class pe{constructor(e){a(this,"gl");a(this,"program",null);a(this,"textures",new Map);this.gl=e}attachProgram(e){this.program=e;for(const t of this.textures.values())t.invalidateLocation();return this}set(e,t,n){const i=this.textures.get(e);return i?i.setSource(t):this.textures.set(e,new x(this.gl,e,t,n)),this}get(e){return this.textures.get(e)}has(e){return this.textures.has(e)}delete(e){const t=this.textures.get(e);return t?(t.destroy(),this.textures.delete(e)):!1}uploadAll(){if(!this.program)return this;let e=0;for(const t of this.textures.values())t.upload(this.program,e),e++;return this}get size(){return this.textures.size}destroy(){for(const e of this.textures.values())e.destroy();this.textures.clear(),this.program=null}}class L{constructor(){a(this,"hooks",new Map)}id(){return Math.random().toString(36).substring(2,10)}add(e){const t=this.id();return this.hooks.set(t,e),()=>this.remove(t)}remove(e){this.hooks.delete(e)}run(e){for(const[t,n]of this.hooks)try{n(e)===!1&&this.remove(t)}catch(i){throw new Y(t,i instanceof Error?i.message:String(i))}}destroy(){this.hooks.clear()}}class T{constructor(e,t){a(this,"canvas");a(this,"gl");a(this,"options");a(this,"onBeforeHooks",new L);a(this,"onAfterHooks",new L);a(this,"_program");a(this,"_geometry");a(this,"_uniforms");a(this,"_textures");a(this,"_clock");a(this,"_resolution",[1,1]);a(this,"_mouse",[0,0]);a(this,"_version",1);a(this,"_runtimeModules",new Q);a(this,"playing",!1);this.canvas=e,this.options=t,this.gl=this.initContext(),this.enableExtensions(),this._program=new le(this.gl),this._geometry=M.fullscreenQuad(this.gl),this._uniforms=new me(this.gl),this._textures=new pe(this.gl),this._clock=new ae,this.options.fps&&this._clock.setMaxFps(this.options.fps),this.options.onBeforeRender&&this.onBeforeHooks.add(this.options.onBeforeRender),this.options.onAfterRender&&this.onAfterHooks.add(this.options.onAfterRender),this.onRender=this.onRender.bind(this)}static setup(e,t){const n=new T(e,t);return t.vertex&&t.fragment&&n.shader(t.vertex,t.fragment),t.uniforms&&n._uniforms.setMany(t.uniforms),t.textures&&n.texturesFromSchema(t.textures),n._runtimeModules.isEmpty()||n._uniforms.setMany(n._runtimeModules.defaults()),n}initContext(){const e={antialias:this.options.antialias,preserveDrawingBuffer:this.options.preserveDrawingBuffer,alpha:!0,depth:!1,stencil:!1},t=this.canvas.getContext("webgl2",e);if(t)return this._version=2,t;const n=this.canvas.getContext("webgl",e);if(n)return this._version=1,n;const i=new O;throw this.options.onError(i),i}enableExtensions(){this.gl.getExtension("OES_standard_derivatives"),this.gl.getExtension("OES_texture_float"),this.gl.getExtension("OES_texture_float_linear"),this._version===1&&this.gl.getExtension("OES_vertex_array_object")}viewport(e,t,n,i){return this.canvas.width=n,this.canvas.height=i,this.gl.viewport(e,t,n,i),this._resolution=[n,i],this}clock(e){return this._clock.setTime(e),this}mouse(e,t){return this._mouse=[e,t],this}uniform(e,t){return this._uniforms.set(e,t),this}uniforms(e){return this._uniforms.setMany(e),this}getUniform(e){return this._uniforms.get(e)}texture(e,t,n){return this._textures.set(e,t,n),this}texturesFromSchema(e){for(const[t,n]of Object.entries(e))if(n instanceof HTMLImageElement||n instanceof HTMLCanvasElement||n instanceof HTMLVideoElement||n instanceof ImageBitmap||n instanceof ImageData||n instanceof OffscreenCanvas)this._textures.set(t,n);else{const{source:i,...r}=n;this._textures.set(t,i,r)}return this}removeTexture(e){return this._textures.delete(e),this}shader(e,t){try{if(this._runtimeModules.clear(),e.version()!==t.version())throw new V(e.version(),t.version());this._program.compile(e.source(),t.compile(this._runtimeModules)),this._version=t.version(),this._geometry.linkAttributes(this._program);const n=this._program.getProgram();n&&(this._uniforms.attachProgram(n),this._textures.attachProgram(n));try{this.options.onLoad()}catch(i){throw new X(i instanceof Error?i.message:String(i))}}catch(n){n instanceof h&&this.options.onError(n)}return this}play(){return this.playing?this:(this.playing=!0,this._clock.start(this.onRender),this)}pause(){if(!this.playing)return this;const e=this._clock.getState();try{this.onBeforeHooks.run(e)}catch(t){t instanceof h&&this.options.onError(t)}this.playing=!1,this._clock.stop();try{this.onAfterHooks.run(e)}catch(t){t instanceof h&&this.options.onError(t)}return this}render(){return this.onRender(this._clock.getState()),this}getContext(){return this.gl}getUsingModules(){return this._runtimeModules}getVersion(){return this._version}getClock(){return this._clock}destroy(){this.pause(),this._clock.destroy(),this._geometry.destroy(),this._program.destroy(),this._uniforms.destroy(),this._textures.destroy(),this.onAfterHooks.destroy(),this.onBeforeHooks.destroy(),this._runtimeModules.clear()}onRender(e){const t=this.gl;try{this.onBeforeHooks.run(e)}catch(n){n instanceof h&&this.options.onError(n)}t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),this._program.use(),this._uniforms.uploadBuiltIns(e,this._resolution,this._mouse),this._uniforms.uploadAll(),this._textures.uploadAll(),this._geometry.bind(),this._geometry.draw();try{this.onAfterHooks.run(e)}catch(n){n instanceof h&&this.options.onError(n)}}}class p extends K{constructor(e){super(e),R.forEach((t,n)=>{this.requirements.uniforms.set(n,{name:n,type:t,line:0})})}}const S=`#ifdef GL_ES
832
832
  precision mediump float;
833
833
  #endif
834
834
 
@@ -841,7 +841,7 @@ void main() {
841
841
  v_texcoord = a_texcoord;
842
842
  gl_Position = vec4(a_position, 0.0, 1.0);
843
843
  }
844
- `,F=`#ifdef GL_ES
844
+ `,C=`#ifdef GL_ES
845
845
  precision mediump float;
846
846
  #endif
847
847
 
@@ -855,7 +855,7 @@ void main() {
855
855
  vec3 color = vec3(uv.x, uv.y, 0.5 + 0.5 * sin(u_time));
856
856
  gl_FragColor = vec4(color, 1.0);
857
857
  }
858
- `,O=`#version 300 es
858
+ `,F=`#version 300 es
859
859
 
860
860
  in vec2 a_position;
861
861
  in vec2 a_texcoord;
@@ -865,7 +865,7 @@ out vec2 v_texcoord;
865
865
  void main() {
866
866
  v_texcoord = a_texcoord;
867
867
  gl_Position = vec4(a_position, 0.0, 1.0);
868
- }`,ge=`#version 300 es
868
+ }`,ve=`#version 300 es
869
869
  precision highp float;
870
870
 
871
871
  uniform vec2 u_resolution;
@@ -879,5 +879,5 @@ void main() {
879
879
  vec2 uv = gl_FragCoord.xy / u_resolution;
880
880
  vec3 color = vec3(uv.x, uv.y, 0.5 + 0.5 * sin(u_time));
881
881
  fragColor = vec4(color, 1.0);
882
- }`;class U{constructor(e,t){o(this,"listeners",[]);o(this,"canvasEl");o(this,"options");o(this,"engine");o(this,"usingCustomVertex",!1);if(this.canvasEl=e,this.options=this.resolveOptions(t),this.engine=L.setup(this.canvasEl,this.options),this.setupListeners(),this.setViewport(),this.options.modules)for(const[n,i]of Object.entries(this.options.modules))this.module(n,i);this.options.autoplay&&this.play()}static create(e,t){return new U(e,t)}static defineModule(e,t,n={}){v.define({name:e,source:t,options:n})}static availableModules(){return w.available()}static compile(e){return new m(e).compile()}resolveOptions(e){const t={vertex:new m(A),fragment:new m(F),autoplay:!0,pauseWhenHidden:!0,dpr:"auto",fps:0,preserveDrawingBuffer:!1,antialias:!0,onError:s=>{console.error("Oops!",s,`
883
- You can handle errors programmatically by providing an onError callback to suppress this log and implement custom fallback behavior.`)},onLoad:()=>{},onBeforeRender:null,onAfterRender:null,uniforms:{},modules:{},textures:{}};if(e!=null&&e.vertex&&(this.usingCustomVertex=!0),e!=null&&e.vertex&&!(e!=null&&e.fragment)){t.vertex=new m(e.vertex);const s=t.vertex.version();t.fragment=new m(s===2?ge:F)}if(e!=null&&e.fragment&&!(e!=null&&e.vertex)){t.fragment=new m(e.fragment);const s=t.fragment.version();t.vertex=new m(s===2?O:A)}e!=null&&e.vertex&&(e!=null&&e.fragment)&&(t.vertex=new m(e.vertex),t.fragment=new m(e.fragment));const{vertex:n,fragment:i,...r}=e||{};return{...t,...r}}setupListeners(){this.listeners.push(b.on(window,"resize",()=>{this.setViewport()}),b.on(this.canvasEl,"resize",()=>{this.setViewport()}),(()=>{let e=!1;return b.on(document,"scroll",t=>{this.options.pauseWhenHidden&&(this.isInViewport()?e&&!this.isPlaying()&&(this.play(),e=!1):this.isPlaying()&&(this.pause(),e=!0))})})(),b.on(document,"mousemove",e=>{this.setMouse(e.clientX||e.pageX,e.clientY||e.pageY)}),b.on(document,"touchmove",e=>{e.touches.length>0&&this.setMouse(e.touches[0].clientX,e.touches[0].clientY)}))}destroyListeners(){this.listeners.forEach(e=>e()),this.listeners=[]}setViewport(){const e=this.options.dpr==="auto"?Math.min(2,window.devicePixelRatio||1):this.options.dpr,t=this.canvasEl.clientWidth||this.canvasEl.width||1,n=this.canvasEl.clientHeight||this.canvasEl.height||1;this.engine.viewport(0,0,Math.max(1,Math.floor(t*e)),Math.max(1,Math.floor(n*e)))}isInViewport(){const e=this.canvasEl.getBoundingClientRect();return e.bottom>=0&&e.right>=0&&e.top<=(window.innerHeight||document.documentElement.clientHeight)&&e.left<=(window.innerWidth||document.documentElement.clientWidth)}setMouse(e,t){const n=this.canvasEl.getBoundingClientRect();e>=n.left&&e<=n.right&&t>=n.top&&t<=n.bottom&&this.engine.mouse(e-n.left,t-n.top)}setUniform(e,t){return this.engine.uniform(e,t),this}setUniforms(e){return this.engine.uniforms(e),this}getUniform(e){return this.engine.getUniform(e)}setTexture(e,t,n){return this.engine.texture(e,t,n),this}setTextures(e){return this.engine.texturesFromSchema(e),this}removeTexture(e){return this.engine.removeTexture(e),this}setShader(e,t){return this.options.vertex=new m(e),this.options.fragment=new m(t),this.usingCustomVertex=!0,this.engine.shader(this.options.vertex,this.options.fragment),this}setFragment(e){const t=new m(e),n=t.version(),i=this.options.vertex.version();return this.options.fragment=t,n!==i&&(this.usingCustomVertex||(this.options.vertex=new m(n===2?O:A))),this.engine.shader(this.options.vertex,this.options.fragment),this}getFragment(){return this.options.fragment.source()}getVertex(){return this.options.vertex.source()}setFps(e){return this.engine.getClock().setMaxFps(e),this}hook(e,t="before"){return t==="before"?this.engine.onBeforeHooks.add(e):this.engine.onAfterHooks.add(e)}module(e,t){const n=y.resolveOptions(e);if(!n)return console.warn(`Sandbox: Counld not find options for '${e}' function. Make sure you used the correct imported name and the module is currently in use by the shader.`),this;for(const[i,r]of Object.entries(t)){const s=n[i];if(!s){console.warn(`Sandbox: Option '${i}' not found for function '${e}'. Make sure to check available options with Sandbox.availableModules() and provide the correct option name.`);continue}this.setUniform(s.uniform,r)}return this}play(){return this.engine.play(),this}playAt(e){return this.engine.clock(e),this.engine.play(),this}pause(){return this.engine.pause(),this}pauseAt(e){const t=this.hook(n=>{n.time>=e&&(t(),this.pause())},"after");return this}toggle(){return this.engine.playing?this.pause():this.play(),this}time(e){return this.engine.clock(e),this}render(){return this.engine.render(),this}renderAt(e){return this.engine.clock(e),this.engine.render(),this}isPlaying(){return this.engine.playing}get version(){return this.engine.getVersion()}get canvas(){return this.canvasEl}exportAsURL(e="image/png",t){return this.canvas.toDataURL(e,t)}exportAsBlob(e="image/png",t){return new Promise((n,i)=>{this.canvas.toBlob(r=>{r?n(r):i(new Error("Failed to create blob from canvas."))},e,t)})}exportAsImage(e="image/png",t){const n=new Image;return n.src=this.exportAsURL(e,t),n}stream(e){return this.canvasEl.captureStream(e)}destroy(){this.destroyListeners(),this.engine.destroy()}}exports.Sandbox=U;exports.SandboxAttemptedToImportDefaultFunctionError=W;exports.SandboxAttemptedToImportMainFunctionError=G;exports.SandboxContextCreationError=se;exports.SandboxError=h;exports.SandboxForbiddenModuleNameError=z;exports.SandboxGLSLShaderCompilationError=E;exports.SandboxMentionCouldNotBeReplacedError=X;exports.SandboxMentionFunctionNotFoundError=j;exports.SandboxMentionUniformNotFoundError=q;exports.SandboxModuleMethodNotFoundError=N;exports.SandboxModuleNotFoundError=B;exports.SandboxOnHookCallbackError=K;exports.SandboxOnLoadCallbackError=Y;exports.SandboxOverwriteModuleError=H;exports.SandboxProgramError=R;exports.SandboxShaderDuplicateImportNameError=D;exports.SandboxShaderImportSyntaxError=$;exports.SandboxShaderRequirementMismatchError=M;exports.SandboxShaderVersionMismatchError=I;exports.SandboxShaderWithoutFunctionError=P;exports.SandboxTextureCreationError=oe;exports.SandboxTextureUnitLimitError=ae;exports.SandboxWebGLNotSupportedError=V;
882
+ }`;class U{constructor(e,t){a(this,"listeners",[]);a(this,"canvasEl");a(this,"options");a(this,"engine");a(this,"usingCustomVertex",!1);if(this.canvasEl=e,this.options=this.resolveOptions(t),this.engine=T.setup(this.canvasEl,this.options),this.setupListeners(),this.setViewport(),this.options.modules)for(const[n,i]of Object.entries(this.options.modules))this.module(n,i);this.options.autoplay&&this.play()}static create(e,t){return new U(e,t)}static defineModule(e,t,n={}){g.define({name:e,source:t,options:n})}static availableModules(){return b.available()}static compile(e){return new p(e).compile()}resolveOptions(e){const t={vertex:new p(S),fragment:new p(C),autoplay:!0,pauseWhenHidden:!0,dpr:"auto",fps:0,preserveDrawingBuffer:!1,antialias:!0,onError:s=>{console.error("Oops!",s,`
883
+ You can handle errors programmatically by providing an onError callback to suppress this log and implement custom fallback behavior.`)},onLoad:()=>{},onBeforeRender:null,onAfterRender:null,uniforms:{},modules:{},textures:{}};if(e!=null&&e.vertex&&(this.usingCustomVertex=!0),e!=null&&e.vertex&&!(e!=null&&e.fragment)){t.vertex=new p(e.vertex);const s=t.vertex.version();t.fragment=new p(s===2?ve:C)}if(e!=null&&e.fragment&&!(e!=null&&e.vertex)){t.fragment=new p(e.fragment);const s=t.fragment.version();t.vertex=new p(s===2?F:S)}e!=null&&e.vertex&&(e!=null&&e.fragment)&&(t.vertex=new p(e.vertex),t.fragment=new p(e.fragment));const{vertex:n,fragment:i,...r}=e||{};return{...t,...r}}setupListeners(){this.listeners.push(y.on(window,"resize",()=>{this.setViewport()}),y.on(this.canvasEl,"resize",()=>{this.setViewport()}),(()=>{let e=!1;return y.on(document,"scroll",t=>{this.options.pauseWhenHidden&&(this.isInViewport()?e&&!this.isPlaying()&&(this.play(),e=!1):this.isPlaying()&&(this.pause(),e=!0))})})(),y.on(document,"mousemove",e=>{this.setMouse(e.clientX||e.pageX,e.clientY||e.pageY)}),y.on(document,"touchmove",e=>{e.touches.length>0&&this.setMouse(e.touches[0].clientX,e.touches[0].clientY)}))}destroyListeners(){this.listeners.forEach(e=>e()),this.listeners=[]}setViewport(){const e=this.options.dpr==="auto"?Math.min(2,window.devicePixelRatio||1):this.options.dpr,t=this.canvasEl.clientWidth||this.canvasEl.width||1,n=this.canvasEl.clientHeight||this.canvasEl.height||1;this.engine.viewport(0,0,Math.max(1,Math.floor(t*e)),Math.max(1,Math.floor(n*e)))}isInViewport(){const e=this.canvasEl.getBoundingClientRect();return e.bottom>=0&&e.right>=0&&e.top<=(window.innerHeight||document.documentElement.clientHeight)&&e.left<=(window.innerWidth||document.documentElement.clientWidth)}setMouse(e,t){const n=this.canvasEl.getBoundingClientRect();e>=n.left&&e<=n.right&&t>=n.top&&t<=n.bottom&&this.engine.mouse(e-n.left,t-n.top)}setUniform(e,t){return this.engine.uniform(e,t),this}setUniforms(e){return this.engine.uniforms(e),this}getUniform(e){return this.engine.getUniform(e)}setTexture(e,t,n){return this.engine.texture(e,t,n),this}setTextures(e){return this.engine.texturesFromSchema(e),this}removeTexture(e){return this.engine.removeTexture(e),this}setShader(e,t){return this.options.vertex=new p(e),this.options.fragment=new p(t),this.usingCustomVertex=!0,this.engine.shader(this.options.vertex,this.options.fragment),this}setFragment(e){const t=new p(e),n=t.version(),i=this.options.vertex.version();return this.options.fragment=t,n!==i&&(this.usingCustomVertex||(this.options.vertex=new p(n===2?F:S))),this.engine.shader(this.options.vertex,this.options.fragment),this}getFragment(){return this.options.fragment.source()}getVertex(){return this.options.vertex.source()}setFps(e){return this.engine.getClock().setMaxFps(e),this}hook(e,t="before"){return t==="before"?this.engine.onBeforeHooks.add(e):this.engine.onAfterHooks.add(e)}module(e,t){const i=this.engine.getUsingModules().resolveOptions(e);if(!i)return console.warn(`Sandbox: Counld not find options for '${e}' function. Make sure you used the correct imported name and the module is currently in use by the shader.`),this;for(const[r,s]of Object.entries(t)){const o=i[r];if(!o){console.warn(`Sandbox: Option '${r}' not found for function '${e}'. Make sure to check available options with Sandbox.availableModules() and provide the correct option name.`);continue}this.setUniform(o.uniform,s)}return this}play(){return this.engine.play(),this}playAt(e){return this.engine.clock(e),this.engine.play(),this}pause(){return this.engine.pause(),this}pauseAt(e){const t=this.hook(n=>{n.time>=e&&(t(),this.pause())},"after");return this}toggle(){return this.engine.playing?this.pause():this.play(),this}time(e){return this.engine.clock(e),this}render(){return this.engine.render(),this}renderAt(e){return this.engine.clock(e),this.engine.render(),this}isPlaying(){return this.engine.playing}get version(){return this.engine.getVersion()}get canvas(){return this.canvasEl}exportAsURL(e="image/png",t){return this.canvas.toDataURL(e,t)}exportAsBlob(e="image/png",t){return new Promise((n,i)=>{this.canvas.toBlob(r=>{r?n(r):i(new Error("Failed to create blob from canvas."))},e,t)})}exportAsImage(e="image/png",t){const n=new Image;return n.src=this.exportAsURL(e,t),n}stream(e){return this.canvasEl.captureStream(e)}destroy(){this.destroyListeners(),this.engine.destroy()}}exports.Sandbox=U;exports.SandboxAttemptedToImportDefaultFunctionError=G;exports.SandboxAttemptedToImportMainFunctionError=N;exports.SandboxContextCreationError=re;exports.SandboxError=h;exports.SandboxForbiddenModuleNameError=W;exports.SandboxGLSLShaderCompilationError=w;exports.SandboxMentionCouldNotBeReplacedError=j;exports.SandboxMentionFunctionNotFoundError=q;exports.SandboxMentionUniformNotFoundError=H;exports.SandboxModuleMethodNotFoundError=B;exports.SandboxModuleNotFoundError=D;exports.SandboxOnHookCallbackError=Y;exports.SandboxOnLoadCallbackError=X;exports.SandboxOverwriteModuleError=z;exports.SandboxProgramError=_;exports.SandboxShaderDuplicateImportNameError=$;exports.SandboxShaderImportSyntaxError=P;exports.SandboxShaderRequirementMismatchError=A;exports.SandboxShaderVersionMismatchError=V;exports.SandboxShaderWithoutFunctionError=I;exports.SandboxTextureCreationError=se;exports.SandboxTextureUnitLimitError=oe;exports.SandboxWebGLNotSupportedError=O;