@frapx/shader 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +125 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -107,6 +107,23 @@ uniform vec2 u_imageSize;
|
|
|
107
107
|
|
|
108
108
|
Supported v1 sources are image URL, `HTMLImageElement`, and `HTMLCanvasElement`.
|
|
109
109
|
|
|
110
|
+
Textures can be updated at runtime. Updates are async because URL sources must
|
|
111
|
+
load before they can be uploaded to WebGL.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
await fx.setTexture("image", "/next-hero.webp");
|
|
115
|
+
|
|
116
|
+
await fx.setTextures({
|
|
117
|
+
image: "/next-hero.webp",
|
|
118
|
+
mask: nextMaskCanvas
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`setTextures()` is a partial update: omitted texture names are left unchanged.
|
|
123
|
+
If a runtime texture update fails, the previous texture remains active and the
|
|
124
|
+
returned promise rejects. In `"demand"` render mode, successful texture updates
|
|
125
|
+
request a render.
|
|
126
|
+
|
|
110
127
|
## External Uniforms
|
|
111
128
|
|
|
112
129
|
Scroll is intentionally not built in. Use any scroll or animation library and push values into uniforms.
|
|
@@ -194,6 +211,8 @@ fx.stop();
|
|
|
194
211
|
fx.render();
|
|
195
212
|
fx.resize();
|
|
196
213
|
fx.destroy();
|
|
214
|
+
await fx.setTexture("image", "/next-hero.webp");
|
|
215
|
+
await fx.setTextures({ image: "/next-hero.webp" });
|
|
197
216
|
fx.setUniform("progress", 0.5);
|
|
198
217
|
fx.setUniforms({ progress: 0.5, color: [1, 0, 0] });
|
|
199
218
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -72,6 +72,8 @@ type ShaderBackgroundInstance<TUniforms extends UniformInputMap = UniformInputMa
|
|
|
72
72
|
render(): void;
|
|
73
73
|
resize(): void;
|
|
74
74
|
destroy(): void;
|
|
75
|
+
setTexture(name: string, input: TextureInput): Promise<void>;
|
|
76
|
+
setTextures(values: TextureMap): Promise<void>;
|
|
75
77
|
setUniform<K extends keyof TUniforms & string>(name: K, value: UniformRuntimeValue<TUniforms[K]>): void;
|
|
76
78
|
setUniform(name: string, value: UniformInput): void;
|
|
77
79
|
setUniforms(values: Record<string, UniformInput>): void;
|
package/dist/index.js
CHANGED
|
@@ -95,16 +95,6 @@ var applyCanvasStyle = (canvas, options, shouldPosition) => {
|
|
|
95
95
|
var toUniformName = (name) => name.startsWith("u_") ? name : `u_${name}`;
|
|
96
96
|
|
|
97
97
|
// src/internal/textures.ts
|
|
98
|
-
var loadTextures = async (gl, textures, isDestroyed) => {
|
|
99
|
-
const entries = Object.entries(textures ?? {});
|
|
100
|
-
const loaded = [];
|
|
101
|
-
for (let index = 0; index < entries.length; index += 1) {
|
|
102
|
-
if (isDestroyed()) break;
|
|
103
|
-
const [name, input] = entries[index];
|
|
104
|
-
loaded.push(await loadTexture(gl, name, input, index));
|
|
105
|
-
}
|
|
106
|
-
return loaded;
|
|
107
|
-
};
|
|
108
98
|
var loadTexture = async (gl, name, input, unit) => {
|
|
109
99
|
const options = normalizeTextureInput(input);
|
|
110
100
|
const source = await resolveSource(options.source);
|
|
@@ -319,8 +309,12 @@ var ShaderBackground = class {
|
|
|
319
309
|
this.dom = null;
|
|
320
310
|
this.program = null;
|
|
321
311
|
this.buffer = null;
|
|
312
|
+
this.attribLocation = -1;
|
|
322
313
|
this.uniformLocations = /* @__PURE__ */ new Map();
|
|
323
|
-
this.
|
|
314
|
+
this.textureInputs = /* @__PURE__ */ new Map();
|
|
315
|
+
this.textures = /* @__PURE__ */ new Map();
|
|
316
|
+
this.textureUnits = /* @__PURE__ */ new Map();
|
|
317
|
+
this.textureVersions = /* @__PURE__ */ new Map();
|
|
324
318
|
this.resizeObserver = null;
|
|
325
319
|
this.intersectionObserver = null;
|
|
326
320
|
this.rafId = 0;
|
|
@@ -392,15 +386,14 @@ var ShaderBackground = class {
|
|
|
392
386
|
if (!gl) return;
|
|
393
387
|
this.inRender = true;
|
|
394
388
|
this.resize();
|
|
389
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
395
390
|
gl.viewport(0, 0, this.width, this.height);
|
|
396
391
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
397
392
|
gl.useProgram(this.program);
|
|
398
393
|
this.applyBuiltInUniforms(gl);
|
|
399
|
-
this.applyCachedUniforms(gl);
|
|
400
|
-
this.applyTextures(gl);
|
|
401
394
|
const state = this.createRenderState(gl);
|
|
402
395
|
this.options.onBeforeRender?.(state);
|
|
403
|
-
this.
|
|
396
|
+
this.prepareDrawState(gl);
|
|
404
397
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
405
398
|
this.options.onAfterRender?.(state);
|
|
406
399
|
this.frame += 1;
|
|
@@ -433,7 +426,9 @@ var ShaderBackground = class {
|
|
|
433
426
|
this.removeListeners = [];
|
|
434
427
|
const gl = this.dom?.canvas.getContext("webgl");
|
|
435
428
|
if (gl) {
|
|
436
|
-
for (const texture of this.textures
|
|
429
|
+
for (const texture of this.textures.values()) {
|
|
430
|
+
gl.deleteTexture(texture.texture);
|
|
431
|
+
}
|
|
437
432
|
if (this.buffer) gl.deleteBuffer(this.buffer);
|
|
438
433
|
if (this.program) gl.deleteProgram(this.program);
|
|
439
434
|
}
|
|
@@ -473,6 +468,54 @@ var ShaderBackground = class {
|
|
|
473
468
|
this.setUniform(name, value);
|
|
474
469
|
}
|
|
475
470
|
}
|
|
471
|
+
async setTexture(name, input) {
|
|
472
|
+
if (this.destroyed) return;
|
|
473
|
+
let gl = this.dom?.canvas.getContext("webgl");
|
|
474
|
+
if (!gl) {
|
|
475
|
+
await this.ready;
|
|
476
|
+
if (this.destroyed) return;
|
|
477
|
+
gl = this.dom?.canvas.getContext("webgl");
|
|
478
|
+
}
|
|
479
|
+
if (!gl) {
|
|
480
|
+
const error = new TextureLoadError(
|
|
481
|
+
"Cannot set texture before WebGL is ready."
|
|
482
|
+
);
|
|
483
|
+
this.options.onError?.(error);
|
|
484
|
+
throw error;
|
|
485
|
+
}
|
|
486
|
+
const version = (this.textureVersions.get(name) ?? 0) + 1;
|
|
487
|
+
this.textureVersions.set(name, version);
|
|
488
|
+
try {
|
|
489
|
+
const unit = this.resolveTextureUnit(gl, name);
|
|
490
|
+
const loaded = await loadTexture(gl, name, input, unit);
|
|
491
|
+
if (this.destroyed || this.textureVersions.get(name) !== version) {
|
|
492
|
+
gl.deleteTexture(loaded.texture);
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
const previous = this.textures.get(name);
|
|
496
|
+
this.textureInputs.set(name, input);
|
|
497
|
+
this.textures.set(name, loaded);
|
|
498
|
+
if (previous) gl.deleteTexture(previous.texture);
|
|
499
|
+
this.applyTextureSizeUniform(loaded);
|
|
500
|
+
if (this.options.renderMode === "demand" && !this.inRender && this.onscreen) {
|
|
501
|
+
this.render();
|
|
502
|
+
}
|
|
503
|
+
} catch (error) {
|
|
504
|
+
if (!this.textures.has(name) && !this.textureInputs.has(name)) {
|
|
505
|
+
this.textureUnits.delete(name);
|
|
506
|
+
}
|
|
507
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
508
|
+
this.options.onError?.(normalized);
|
|
509
|
+
throw normalized;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
async setTextures(values) {
|
|
513
|
+
await Promise.all(
|
|
514
|
+
Object.entries(values).map(
|
|
515
|
+
([name, input]) => this.setTexture(name, input)
|
|
516
|
+
)
|
|
517
|
+
);
|
|
518
|
+
}
|
|
476
519
|
async init() {
|
|
477
520
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
478
521
|
this.failUnsupported(new UnsupportedError("WebGL requires a browser."));
|
|
@@ -501,11 +544,8 @@ var ShaderBackground = class {
|
|
|
501
544
|
this.setupContextEvents();
|
|
502
545
|
this.setupProgram(gl);
|
|
503
546
|
this.resize();
|
|
504
|
-
this.
|
|
505
|
-
|
|
506
|
-
this.options.textures,
|
|
507
|
-
() => this.destroyed
|
|
508
|
-
);
|
|
547
|
+
this.textureInputs = new Map(Object.entries(this.options.textures ?? {}));
|
|
548
|
+
await this.loadTextureInputs(gl);
|
|
509
549
|
if (this.destroyed) return;
|
|
510
550
|
this.applyTextureSizeUniforms();
|
|
511
551
|
this.currentStatus = "ready";
|
|
@@ -530,8 +570,22 @@ var ShaderBackground = class {
|
|
|
530
570
|
);
|
|
531
571
|
gl.useProgram(this.program);
|
|
532
572
|
this.buffer = createFullscreenBuffer(gl, this.program);
|
|
573
|
+
this.attribLocation = gl.getAttribLocation(this.program, "a_position");
|
|
533
574
|
this.uniformLocations = collectUniformLocations(gl, this.program);
|
|
534
575
|
}
|
|
576
|
+
// Re-bind the core's program, fullscreen geometry, textures and uniforms so a
|
|
577
|
+
// draw is correct regardless of GL state changed by onBeforeRender/onAfterRender.
|
|
578
|
+
prepareDrawState(gl) {
|
|
579
|
+
if (!this.program) return;
|
|
580
|
+
gl.useProgram(this.program);
|
|
581
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
582
|
+
if (this.attribLocation >= 0) {
|
|
583
|
+
gl.enableVertexAttribArray(this.attribLocation);
|
|
584
|
+
gl.vertexAttribPointer(this.attribLocation, 2, gl.FLOAT, false, 0, 0);
|
|
585
|
+
}
|
|
586
|
+
this.applyTextures(gl);
|
|
587
|
+
this.applyCachedUniforms(gl);
|
|
588
|
+
}
|
|
535
589
|
setupDomObservers() {
|
|
536
590
|
if (!this.dom) return;
|
|
537
591
|
if (this.options.autoResize ?? true) {
|
|
@@ -599,9 +653,8 @@ var ShaderBackground = class {
|
|
|
599
653
|
try {
|
|
600
654
|
this.setupProgram(gl);
|
|
601
655
|
this.applyCachedUniforms(gl);
|
|
602
|
-
void
|
|
603
|
-
(
|
|
604
|
-
this.textures = textures;
|
|
656
|
+
void this.loadTextureInputs(gl).then(
|
|
657
|
+
() => {
|
|
605
658
|
this.applyTextureSizeUniforms();
|
|
606
659
|
if (this.contextRestoredShouldRun) this.start();
|
|
607
660
|
else this.render();
|
|
@@ -660,11 +713,22 @@ var ShaderBackground = class {
|
|
|
660
713
|
this.applyCachedUniforms(gl);
|
|
661
714
|
}
|
|
662
715
|
applyTextureSizeUniforms() {
|
|
663
|
-
for (const texture of this.textures) {
|
|
664
|
-
this.
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
716
|
+
for (const texture of this.textures.values()) {
|
|
717
|
+
this.applyTextureSizeUniform(texture);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
applyTextureSizeUniform(texture) {
|
|
721
|
+
const uniform = {
|
|
722
|
+
type: "vec2",
|
|
723
|
+
value: [texture.width, texture.height]
|
|
724
|
+
};
|
|
725
|
+
this.uniformCache.set(texture.sizeUniformName, uniform);
|
|
726
|
+
const gl = this.dom?.canvas.getContext("webgl");
|
|
727
|
+
const location = this.uniformLocations.get(texture.sizeUniformName);
|
|
728
|
+
if (gl && this.program && location) {
|
|
729
|
+
applyProgramUniform(gl, this.program, location, uniform);
|
|
730
|
+
} else if (this.program) {
|
|
731
|
+
this.warnUnknownUniform(texture.sizeUniformName);
|
|
668
732
|
}
|
|
669
733
|
}
|
|
670
734
|
applyCachedUniforms(gl) {
|
|
@@ -678,16 +742,45 @@ var ShaderBackground = class {
|
|
|
678
742
|
}
|
|
679
743
|
}
|
|
680
744
|
applyTextures(gl) {
|
|
681
|
-
for (
|
|
682
|
-
const
|
|
683
|
-
if (
|
|
745
|
+
for (const texture of this.textures.values()) {
|
|
746
|
+
const unit = this.textureUnits.get(texture.name);
|
|
747
|
+
if (unit === void 0) continue;
|
|
684
748
|
const location = this.uniformLocations.get(texture.uniformName);
|
|
685
|
-
if (!location)
|
|
749
|
+
if (!location) {
|
|
750
|
+
this.warnUnknownUniform(texture.uniformName);
|
|
751
|
+
continue;
|
|
752
|
+
}
|
|
686
753
|
gl.activeTexture(gl.TEXTURE0 + unit);
|
|
687
754
|
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
|
|
688
755
|
gl.uniform1i(location, unit);
|
|
689
756
|
}
|
|
690
757
|
}
|
|
758
|
+
async loadTextureInputs(gl) {
|
|
759
|
+
const loadedTextures = /* @__PURE__ */ new Map();
|
|
760
|
+
for (const [name, input] of this.textureInputs) {
|
|
761
|
+
if (this.destroyed) break;
|
|
762
|
+
const unit = this.resolveTextureUnit(gl, name);
|
|
763
|
+
loadedTextures.set(name, await loadTexture(gl, name, input, unit));
|
|
764
|
+
}
|
|
765
|
+
for (const texture of this.textures.values()) {
|
|
766
|
+
gl.deleteTexture(texture.texture);
|
|
767
|
+
}
|
|
768
|
+
this.textures = loadedTextures;
|
|
769
|
+
}
|
|
770
|
+
resolveTextureUnit(gl, name) {
|
|
771
|
+
const existing = this.textureUnits.get(name);
|
|
772
|
+
if (existing !== void 0) return existing;
|
|
773
|
+
const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
|
|
774
|
+
for (let unit = 0; unit < maxUnits; unit += 1) {
|
|
775
|
+
if (![...this.textureUnits.values()].includes(unit)) {
|
|
776
|
+
this.textureUnits.set(name, unit);
|
|
777
|
+
return unit;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
throw new TextureLoadError(
|
|
781
|
+
`Texture unit limit exceeded while loading texture: ${name}`
|
|
782
|
+
);
|
|
783
|
+
}
|
|
691
784
|
createRenderState(gl) {
|
|
692
785
|
return {
|
|
693
786
|
instance: this,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/errors.ts","../src/internal/dom.ts","../src/internal/names.ts","../src/internal/textures.ts","../src/internal/uniforms.ts","../src/internal/webgl.ts","../src/createShaderBackground.ts"],"sourcesContent":["export class ShaderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\nexport class UnsupportedError extends ShaderError {}\nexport class TargetNotFoundError extends ShaderError {}\nexport class ShaderCompileError extends ShaderError {}\nexport class TextureLoadError extends ShaderError {}\nexport class DestroyedError extends ShaderError {}\n","import type { CreateShaderBackgroundOptions, DprOption } from \"../types\";\n\nexport type DomSetup = {\n target: Element;\n canvas: HTMLCanvasElement;\n createdCanvas: boolean;\n restoredPosition: string | null;\n};\n\nexport const resolveElement = (\n target: string | Element | undefined\n): Element | null => {\n if (!target) return null;\n if (typeof target === \"string\") return document.querySelector(target);\n return target;\n};\n\nexport const setupCanvas = (\n options: CreateShaderBackgroundOptions\n): DomSetup | null => {\n const target = resolveElement(options.target);\n const canvas = options.canvas ?? document.createElement(\"canvas\");\n const measurementTarget = target ?? options.canvas;\n\n if (!measurementTarget) return null;\n\n const createdCanvas = !options.canvas;\n const restoredPosition =\n target && getComputedStyle(target).position === \"static\"\n ? (target as HTMLElement).style.position\n : null;\n\n if (target && restoredPosition !== null) {\n (target as HTMLElement).style.position = \"relative\";\n }\n\n applyCanvasStyle(canvas, options, createdCanvas);\n\n if (options.canvasClass) {\n canvas.classList.add(options.canvasClass);\n }\n\n if (options.canvasStyle) {\n Object.assign(canvas.style, options.canvasStyle);\n }\n\n if (createdCanvas && target) {\n if ((options.layer ?? \"background\") === \"overlay\") {\n target.append(canvas);\n } else {\n target.prepend(canvas);\n }\n }\n\n return {\n target: measurementTarget,\n canvas,\n createdCanvas,\n restoredPosition\n };\n};\n\nexport const resolveDpr = (\n dpr: DprOption | undefined,\n maxDpr: number | undefined\n): number => {\n const raw =\n typeof dpr === \"function\"\n ? dpr()\n : typeof dpr === \"number\"\n ? dpr\n : typeof window === \"undefined\"\n ? 1\n : window.devicePixelRatio || 1;\n\n return Math.max(1, Math.min(raw, maxDpr ?? 2));\n};\n\nexport const resizeCanvasToTarget = (\n canvas: HTMLCanvasElement,\n target: Element,\n dpr: number\n): {\n width: number;\n height: number;\n viewportWidth: number;\n viewportHeight: number;\n} => {\n const rect = target.getBoundingClientRect();\n const viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n const viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n const width = Math.max(1, Math.round(viewportWidth * dpr));\n const height = Math.max(1, Math.round(viewportHeight * dpr));\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\nconst applyCanvasStyle = (\n canvas: HTMLCanvasElement,\n options: CreateShaderBackgroundOptions,\n shouldPosition: boolean\n): void => {\n canvas.dataset.frapxShaderCanvas = \"\";\n\n if (!shouldPosition) return;\n\n const layer = options.layer ?? \"background\";\n Object.assign(canvas.style, {\n position: \"absolute\",\n inset: \"0\",\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n pointerEvents: \"none\",\n zIndex: layer === \"overlay\" ? \"1\" : \"0\"\n });\n};\n","export const toUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name : `u_${name}`;\n\nexport const fromUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name.slice(2) : name;\n","import type { TextureInput, TextureOptions, TextureSource } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { toUniformName } from \"./names\";\n\nexport type LoadedTexture = {\n name: string;\n uniformName: string;\n sizeUniformName: string;\n texture: WebGLTexture;\n width: number;\n height: number;\n};\n\nexport const loadTextures = async (\n gl: WebGLRenderingContext,\n textures: Record<string, TextureInput> | undefined,\n isDestroyed: () => boolean\n): Promise<LoadedTexture[]> => {\n const entries = Object.entries(textures ?? {});\n const loaded: LoadedTexture[] = [];\n\n for (let index = 0; index < entries.length; index += 1) {\n if (isDestroyed()) break;\n const [name, input] = entries[index] as [string, TextureInput];\n loaded.push(await loadTexture(gl, name, input, index));\n }\n\n return loaded;\n};\n\nconst loadTexture = async (\n gl: WebGLRenderingContext,\n name: string,\n input: TextureInput,\n unit: number\n): Promise<LoadedTexture> => {\n const options = normalizeTextureInput(input);\n const source = await resolveSource(options.source);\n const texture = gl.createTexture();\n\n if (!texture) {\n throw new TextureLoadError(`Failed to create texture: ${name}`);\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, options.flipY ?? true);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);\n\n const wrap = getWrap(gl, options.wrap ?? \"clamp\");\n const filter = getFilter(gl, options.filter ?? \"linear\");\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n return {\n name,\n uniformName: toUniformName(name),\n sizeUniformName: toUniformName(`${name}Size`),\n texture,\n width: getSourceWidth(source),\n height: getSourceHeight(source)\n };\n};\n\nconst normalizeTextureInput = (input: TextureInput): TextureOptions => {\n if (typeof input === \"string\" || isTextureSource(input)) {\n return { source: input };\n }\n\n return input;\n};\n\nconst resolveSource = async (\n source: TextureSource\n): Promise<HTMLImageElement | HTMLCanvasElement> => {\n if (typeof source !== \"string\") {\n return source;\n }\n\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = source;\n\n try {\n await image.decode();\n } catch (error) {\n throw new TextureLoadError(`Failed to load texture: ${source}`);\n }\n\n return image;\n};\n\nconst getWrap = (\n gl: WebGLRenderingContext,\n wrap: NonNullable<TextureOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n\nconst getFilter = (\n gl: WebGLRenderingContext,\n filter: NonNullable<TextureOptions[\"filter\"]>\n): number => (filter === \"nearest\" ? gl.NEAREST : gl.LINEAR);\n\nconst isTextureSource = (input: unknown): input is HTMLImageElement | HTMLCanvasElement =>\n typeof HTMLImageElement !== \"undefined\" &&\n (input instanceof HTMLImageElement || input instanceof HTMLCanvasElement);\n\nconst getSourceWidth = (source: HTMLImageElement | HTMLCanvasElement): number =>\n \"naturalWidth\" in source ? source.naturalWidth : source.width;\n\nconst getSourceHeight = (source: HTMLImageElement | HTMLCanvasElement): number =>\n \"naturalHeight\" in source ? source.naturalHeight : source.height;\n","import type { ExplicitUniformInput, UniformInput, UniformType } from \"../types\";\nimport { toUniformName } from \"./names\";\n\nexport type NormalizedUniform = {\n type: UniformType;\n value: number[] | Float32Array;\n};\n\nexport const normalizeUniform = (input: UniformInput): NormalizedUniform => {\n if (typeof input === \"number\") {\n return { type: \"float\", value: [input] };\n }\n\n if (input instanceof Float32Array) {\n if (input.length === 9) return { type: \"mat3\", value: input };\n if (input.length === 16) return { type: \"mat4\", value: input };\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n if (isExplicitUniform(input)) {\n return { type: input.type, value: input.value };\n }\n\n if (Array.isArray(input)) {\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n return { type: \"float\", value: [0] };\n};\n\nexport const applyUniform = (\n gl: WebGLRenderingContext,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n const value = uniform.value;\n\n switch (uniform.type) {\n case \"float\":\n gl.uniform1f(location, value[0] ?? 0);\n break;\n case \"vec2\":\n gl.uniform2f(location, value[0] ?? 0, value[1] ?? 0);\n break;\n case \"vec3\":\n gl.uniform3f(location, value[0] ?? 0, value[1] ?? 0, value[2] ?? 0);\n break;\n case \"vec4\":\n gl.uniform4f(\n location,\n value[0] ?? 0,\n value[1] ?? 0,\n value[2] ?? 0,\n value[3] ?? 0\n );\n break;\n case \"mat3\":\n gl.uniformMatrix3fv(location, false, value);\n break;\n case \"mat4\":\n gl.uniformMatrix4fv(location, false, value);\n break;\n }\n};\n\nexport const applyProgramUniform = (\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n gl.useProgram(program);\n applyUniform(gl, location, uniform);\n};\n\nexport const collectUniformLocations = (\n gl: WebGLRenderingContext,\n program: WebGLProgram\n): Map<string, WebGLUniformLocation> => {\n const locations = new Map<string, WebGLUniformLocation>();\n const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) as number;\n\n for (let index = 0; index < count; index += 1) {\n const active = gl.getActiveUniform(program, index);\n if (!active) continue;\n\n const name = active.name.replace(/\\[0\\]$/, \"\");\n const location = gl.getUniformLocation(program, name);\n if (location) {\n locations.set(name, location);\n }\n }\n\n return locations;\n};\n\nexport const createUniformCache = (\n uniforms: Record<string, UniformInput> | undefined\n): Map<string, NormalizedUniform> => {\n const cache = new Map<string, NormalizedUniform>();\n\n for (const [name, value] of Object.entries(uniforms ?? {})) {\n cache.set(toUniformName(name), normalizeUniform(value));\n }\n\n return cache;\n};\n\nconst isExplicitUniform = (input: unknown): input is ExplicitUniformInput => {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return false;\n return \"type\" in input && \"value\" in input;\n};\n","import { ShaderCompileError } from \"./errors\";\n\nexport const defaultVertexShader = `\nattribute vec2 a_position;\nvarying vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const createProgram = (\n gl: WebGLRenderingContext,\n vertexSource: string,\n fragmentSource: string\n): WebGLProgram => {\n const vertex = compileShader(gl, gl.VERTEX_SHADER, vertexSource);\n const fragment = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);\n const program = gl.createProgram();\n\n if (!program) {\n throw new ShaderCompileError(\"Failed to create WebGL program.\");\n }\n\n gl.attachShader(program, vertex);\n gl.attachShader(program, fragment);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program) ?? \"Unknown program link error.\";\n gl.deleteProgram(program);\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n throw new ShaderCompileError(log);\n }\n\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n return program;\n};\n\nexport const createFullscreenBuffer = (\n gl: WebGLRenderingContext,\n program: WebGLProgram\n): WebGLBuffer => {\n const buffer = gl.createBuffer();\n if (!buffer) {\n throw new ShaderCompileError(\"Failed to create fullscreen buffer.\");\n }\n\n const location = gl.getAttribLocation(program, \"a_position\");\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),\n gl.STATIC_DRAW\n );\n\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n};\n\nconst compileShader = (\n gl: WebGLRenderingContext,\n type: number,\n source: string\n): WebGLShader => {\n const shader = gl.createShader(type);\n if (!shader) {\n throw new ShaderCompileError(\"Failed to create WebGL shader.\");\n }\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader) ?? \"Unknown shader compile error.\";\n gl.deleteShader(shader);\n throw new ShaderCompileError(log);\n }\n\n return shader;\n};\n","import type {\n CreateShaderBackgroundOptions,\n RenderState,\n ShaderBackgroundInstance,\n ShaderStatus,\n UniformInput,\n UniformInputMap,\n UniformRuntimeValue\n} from \"./types\";\nimport {\n DestroyedError,\n TargetNotFoundError,\n UnsupportedError\n} from \"./internal/errors\";\nimport {\n resolveDpr,\n resizeCanvasToTarget,\n setupCanvas,\n type DomSetup\n} from \"./internal/dom\";\nimport { toUniformName } from \"./internal/names\";\nimport { loadTextures, type LoadedTexture } from \"./internal/textures\";\nimport {\n applyProgramUniform,\n applyUniform,\n collectUniformLocations,\n createUniformCache,\n normalizeUniform,\n type NormalizedUniform\n} from \"./internal/uniforms\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader\n} from \"./internal/webgl\";\n\nconst MAX_DELTA_SECONDS = 0.1;\n\nexport const createShaderBackground = <\n TUniforms extends UniformInputMap = UniformInputMap\n>(\n options: CreateShaderBackgroundOptions<TUniforms>\n): ShaderBackgroundInstance<TUniforms> => {\n return new ShaderBackground<TUniforms>(options);\n};\n\nclass ShaderBackground<TUniforms extends UniformInputMap>\n implements ShaderBackgroundInstance<TUniforms>\n{\n readonly ready: Promise<void>;\n\n private readonly options: CreateShaderBackgroundOptions<TUniforms>;\n private readonly uniformCache: Map<string, NormalizedUniform>;\n private readonly warnedUniforms = new Set<string>();\n private readyResolve: (() => void) | null = null;\n private readyReject: ((error: Error) => void) | null = null;\n private dom: DomSetup | null = null;\n private program: WebGLProgram | null = null;\n private buffer: WebGLBuffer | null = null;\n private uniformLocations = new Map<string, WebGLUniformLocation>();\n private textures: LoadedTexture[] = [];\n private resizeObserver: ResizeObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private rafId = 0;\n private running = false;\n private inRender = false;\n private destroyed = false;\n private onscreen = true;\n private frame = 0;\n private elapsed = 0;\n private lastTimestamp = 0;\n private pixelRatio = 1;\n private width = 1;\n private height = 1;\n private viewportWidth = 1;\n private viewportHeight = 1;\n private pointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n private removeListeners: Array<() => void> = [];\n private currentStatus: ShaderStatus = \"idle\";\n private contextRestoredShouldRun = false;\n\n constructor(options: CreateShaderBackgroundOptions<TUniforms>) {\n this.options = options;\n this.uniformCache = createUniformCache(options.uniforms);\n this.ready = new Promise<void>((resolve, reject) => {\n this.readyResolve = resolve;\n this.readyReject = reject;\n });\n\n queueMicrotask(() => {\n void this.init();\n });\n }\n\n get canvas(): HTMLCanvasElement | null {\n return this.dom?.canvas ?? null;\n }\n\n get gl(): WebGLRenderingContext | null {\n return this.dom?.canvas.getContext(\"webgl\") ?? null;\n }\n\n get status(): ShaderStatus {\n return this.currentStatus;\n }\n\n get supported(): boolean {\n return ![\"unsupported\", \"destroyed\"].includes(this.currentStatus);\n }\n\n start(): void {\n if (this.destroyed || this.currentStatus === \"unsupported\") return;\n this.running = true;\n\n if (!this.onscreen && (this.options.pauseWhenOffscreen ?? true)) {\n this.currentStatus = \"paused\";\n return;\n }\n\n if (this.options.renderMode === \"demand\") {\n this.currentStatus = \"running\";\n this.render();\n return;\n }\n\n this.currentStatus = \"running\";\n this.scheduleFrame();\n }\n\n stop(): void {\n this.running = false;\n this.cancelFrame();\n if (!this.destroyed && this.currentStatus !== \"unsupported\") {\n this.currentStatus = \"paused\";\n }\n }\n\n render(): void {\n if (\n this.destroyed ||\n !this.dom ||\n !this.program ||\n this.currentStatus === \"unsupported\" ||\n (this.options.pauseWhenOffscreen ?? true) && !this.onscreen\n ) {\n return;\n }\n\n const gl = this.dom.canvas.getContext(\"webgl\");\n if (!gl) return;\n\n this.inRender = true;\n this.resize();\n gl.viewport(0, 0, this.width, this.height);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.useProgram(this.program);\n this.applyBuiltInUniforms(gl);\n this.applyCachedUniforms(gl);\n this.applyTextures(gl);\n\n const state = this.createRenderState(gl);\n this.options.onBeforeRender?.(state);\n this.applyCachedUniforms(gl);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n this.options.onAfterRender?.(state);\n this.frame += 1;\n this.inRender = false;\n }\n\n resize(): void {\n if (this.destroyed || !this.dom) return;\n this.pixelRatio = resolveDpr(this.options.dpr, this.options.maxDpr);\n const size = resizeCanvasToTarget(\n this.dom.canvas,\n this.dom.target,\n this.pixelRatio\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n\n if (this.options.renderMode === \"demand\" && !this.inRender) {\n this.render();\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.running = false;\n this.cancelFrame();\n this.resizeObserver?.disconnect();\n this.intersectionObserver?.disconnect();\n\n for (const remove of this.removeListeners) remove();\n this.removeListeners = [];\n\n const gl = this.dom?.canvas.getContext(\"webgl\");\n if (gl) {\n for (const texture of this.textures) gl.deleteTexture(texture.texture);\n if (this.buffer) gl.deleteBuffer(this.buffer);\n if (this.program) gl.deleteProgram(this.program);\n }\n\n if (this.dom?.createdCanvas) {\n this.dom.canvas.remove();\n }\n\n const dom = this.dom;\n if (dom?.restoredPosition !== null && dom && this.options.target) {\n const target = dom.target as HTMLElement;\n target.style.position = dom.restoredPosition;\n }\n\n this.currentStatus = \"destroyed\";\n this.readyReject?.(new DestroyedError(\"Shader background was destroyed.\"));\n }\n\n setUniform<K extends keyof TUniforms & string>(\n name: K,\n value: UniformRuntimeValue<TUniforms[K]>\n ): void;\n setUniform(name: string, value: UniformInput): void;\n setUniform(name: string, value: UniformInput): void {\n if (this.destroyed) return;\n const uniformName = toUniformName(name);\n this.uniformCache.set(uniformName, normalizeUniform(value));\n\n const gl = this.dom?.canvas.getContext(\"webgl\");\n const location = this.uniformLocations.get(uniformName);\n if (gl && this.program && location) {\n applyProgramUniform(\n gl,\n this.program,\n location,\n this.uniformCache.get(uniformName)!\n );\n } else if (this.program) {\n this.warnUnknownUniform(uniformName);\n }\n\n if (\n this.options.renderMode === \"demand\" &&\n !this.inRender &&\n this.onscreen\n ) {\n this.render();\n }\n }\n\n setUniforms(values: Record<string, UniformInput>): void {\n for (const [name, value] of Object.entries(values)) {\n this.setUniform(name, value);\n }\n }\n\n private async init(): Promise<void> {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n this.failUnsupported(new UnsupportedError(\"WebGL requires a browser.\"));\n return;\n }\n\n this.dom = setupCanvas(this.options);\n if (!this.dom) {\n this.failUnsupported(new TargetNotFoundError(\"Target or canvas not found.\"));\n return;\n }\n\n const gl = this.dom.canvas.getContext(\"webgl\", {\n alpha: true,\n antialias: false,\n depth: false,\n stencil: false,\n premultipliedAlpha: true,\n preserveDrawingBuffer: false\n });\n\n if (!gl) {\n this.failUnsupported(new UnsupportedError(\"WebGL is not supported.\"));\n return;\n }\n\n this.currentStatus = \"loading\";\n\n try {\n this.setupDomObservers();\n this.setupContextEvents();\n this.setupProgram(gl);\n this.resize();\n this.textures = await loadTextures(\n gl,\n this.options.textures,\n () => this.destroyed\n );\n if (this.destroyed) return;\n this.applyTextureSizeUniforms();\n this.currentStatus = \"ready\";\n this.readyResolve?.();\n this.options.onReady?.(this);\n\n if (this.running || (this.options.autoStart ?? true)) {\n this.start();\n } else if (this.options.renderMode === \"demand\") {\n this.render();\n }\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n private setupProgram(gl: WebGLRenderingContext): void {\n if (this.program) gl.deleteProgram(this.program);\n if (this.buffer) gl.deleteBuffer(this.buffer);\n\n this.program = createProgram(\n gl,\n this.options.vertex ?? defaultVertexShader,\n this.options.fragment\n );\n gl.useProgram(this.program);\n this.buffer = createFullscreenBuffer(gl, this.program);\n this.uniformLocations = collectUniformLocations(gl, this.program);\n }\n\n private setupDomObservers(): void {\n if (!this.dom) return;\n\n if (this.options.autoResize ?? true) {\n this.resizeObserver = new ResizeObserver(() => {\n this.resize();\n });\n this.resizeObserver.observe(this.dom.target);\n }\n\n if (this.options.pauseWhenOffscreen ?? true) {\n this.intersectionObserver = new IntersectionObserver((entries) => {\n const entry = entries[0];\n this.onscreen = Boolean(entry?.isIntersecting);\n if (!this.onscreen) {\n this.cancelFrame();\n if (this.running) this.currentStatus = \"paused\";\n return;\n }\n\n if (this.running) {\n this.start();\n } else if (this.options.renderMode === \"demand\") {\n this.render();\n }\n });\n this.intersectionObserver.observe(this.dom.target);\n }\n\n const onPointerMove = (event: Event) => {\n if (!this.dom) return;\n const pointerEvent = event as PointerEvent;\n const rect = this.dom.target.getBoundingClientRect();\n const x = pointerEvent.clientX - rect.left;\n const y = pointerEvent.clientY - rect.top;\n this.pointer.x = x * this.pixelRatio;\n this.pointer.y = (rect.height - y) * this.pixelRatio;\n this.pointer.uvX = rect.width > 0 ? x / rect.width : 0;\n this.pointer.uvY = rect.height > 0 ? 1 - y / rect.height : 0;\n this.pointer.active = 1;\n\n if (this.options.renderMode === \"demand\") this.render();\n };\n const onPointerLeave = () => {\n this.pointer.active = 0;\n if (this.options.renderMode === \"demand\") this.render();\n };\n\n this.dom.target.addEventListener(\"pointermove\", onPointerMove);\n this.dom.target.addEventListener(\"pointerenter\", onPointerMove);\n this.dom.target.addEventListener(\"pointerleave\", onPointerLeave);\n this.removeListeners.push(() => {\n this.dom?.target.removeEventListener(\"pointermove\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerenter\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerleave\", onPointerLeave);\n });\n }\n\n private setupContextEvents(): void {\n if (!this.dom) return;\n\n const onLost = (event: Event) => {\n event.preventDefault();\n this.contextRestoredShouldRun = this.running;\n this.cancelFrame();\n this.currentStatus = \"context-lost\";\n this.options.onError?.(new UnsupportedError(\"WebGL context lost.\"));\n };\n\n const onRestored = () => {\n if (!this.dom || this.destroyed) return;\n const gl = this.dom.canvas.getContext(\"webgl\");\n if (!gl) return;\n\n try {\n this.setupProgram(gl);\n this.applyCachedUniforms(gl);\n void loadTextures(gl, this.options.textures, () => this.destroyed).then(\n (textures) => {\n this.textures = textures;\n this.applyTextureSizeUniforms();\n if (this.contextRestoredShouldRun) this.start();\n else this.render();\n },\n (error: unknown) =>\n this.fail(error instanceof Error ? error : new Error(String(error)))\n );\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n };\n\n this.dom.canvas.addEventListener(\"webglcontextlost\", onLost);\n this.dom.canvas.addEventListener(\"webglcontextrestored\", onRestored);\n this.removeListeners.push(() => {\n this.dom?.canvas.removeEventListener(\"webglcontextlost\", onLost);\n this.dom?.canvas.removeEventListener(\"webglcontextrestored\", onRestored);\n });\n }\n\n private scheduleFrame(): void {\n if (this.rafId || this.options.renderMode === \"demand\") return;\n\n this.rafId = requestAnimationFrame((timestamp) => {\n this.rafId = 0;\n if (!this.running || this.destroyed) return;\n\n const seconds = timestamp / 1000;\n const rawDelta = this.lastTimestamp ? seconds - this.lastTimestamp : 0;\n const delta = Math.min(Math.max(rawDelta, 0), MAX_DELTA_SECONDS);\n this.lastTimestamp = seconds;\n this.elapsed += delta;\n this.setBuiltInTime(delta);\n this.render();\n this.scheduleFrame();\n });\n }\n\n private cancelFrame(): void {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n }\n this.lastTimestamp = 0;\n }\n\n private setBuiltInTime(delta: number): void {\n this.uniformCache.set(\"u_time\", { type: \"float\", value: [this.elapsed] });\n this.uniformCache.set(\"u_delta\", { type: \"float\", value: [delta] });\n }\n\n private applyBuiltInUniforms(gl: WebGLRenderingContext): void {\n const builtIns: Record<string, UniformInput> = {\n resolution: [this.width, this.height],\n viewportSize: [this.viewportWidth, this.viewportHeight],\n pixelRatio: this.pixelRatio,\n pointer: [this.pointer.x, this.pointer.y],\n pointerUv: [this.pointer.uvX, this.pointer.uvY],\n pointerActive: this.pointer.active\n };\n\n for (const [name, value] of Object.entries(builtIns)) {\n this.uniformCache.set(toUniformName(name), normalizeUniform(value));\n }\n\n this.applyCachedUniforms(gl);\n }\n\n private applyTextureSizeUniforms(): void {\n for (const texture of this.textures) {\n this.uniformCache.set(texture.sizeUniformName, {\n type: \"vec2\",\n value: [texture.width, texture.height]\n });\n }\n }\n\n private applyCachedUniforms(gl: WebGLRenderingContext): void {\n for (const [name, uniform] of this.uniformCache) {\n const location = this.uniformLocations.get(name);\n if (!location) {\n this.warnUnknownUniform(name);\n continue;\n }\n applyUniform(gl, location, uniform);\n }\n }\n\n private applyTextures(gl: WebGLRenderingContext): void {\n for (let unit = 0; unit < this.textures.length; unit += 1) {\n const texture = this.textures[unit];\n if (!texture) continue;\n const location = this.uniformLocations.get(texture.uniformName);\n if (!location) continue;\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture.texture);\n gl.uniform1i(location, unit);\n }\n }\n\n private createRenderState(\n gl: WebGLRenderingContext\n ): RenderState<TUniforms> {\n return {\n instance: this,\n gl,\n canvas: this.dom!.canvas,\n time: this.elapsed,\n delta: this.uniformCache.get(\"u_delta\")?.value[0] ?? 0,\n frame: this.frame,\n width: this.width,\n height: this.height,\n viewportWidth: this.viewportWidth,\n viewportHeight: this.viewportHeight,\n pixelRatio: this.pixelRatio\n };\n }\n\n private warnUnknownUniform(name: string): void {\n if (!this.options.debug || this.warnedUniforms.has(name)) return;\n this.warnedUniforms.add(name);\n console.warn(`[frapx/shader] Uniform not found or optimized out: ${name}`);\n }\n\n private failUnsupported(error: Error): void {\n this.currentStatus = \"unsupported\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n private fail(error: Error): void {\n this.currentStatus = \"error\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n private debugWarn(message: string): void {\n if (this.options.debug) {\n console.warn(`[frapx/shader] ${message}`);\n }\n }\n}\n"],"mappings":";;;;;;;;;;AAAO,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO,WAAW;AAAA,EACzB;AACF;AAEO,IAAM,mBAAN,cAA+B,YAAY;AAAC;AAC5C,IAAM,sBAAN,cAAkC,YAAY;AAAC;AAC/C,IAAM,qBAAN,cAAiC,YAAY;AAAC;AAC9C,IAAM,mBAAN,cAA+B,YAAY;AAAC;AAC5C,IAAM,iBAAN,cAA6B,YAAY;AAAC;;;ACF1C,IAAM,iBAAiB,CAC5B,WACmB;AACnB,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,OAAO,WAAW,SAAU,QAAO,SAAS,cAAc,MAAM;AACpE,SAAO;AACT;AAEO,IAAM,cAAc,CACzB,YACoB;AACpB,QAAM,SAAS,eAAe,QAAQ,MAAM;AAC5C,QAAM,SAAS,QAAQ,UAAU,SAAS,cAAc,QAAQ;AAChE,QAAM,oBAAoB,UAAU,QAAQ;AAE5C,MAAI,CAAC,kBAAmB,QAAO;AAE/B,QAAM,gBAAgB,CAAC,QAAQ;AAC/B,QAAM,mBACJ,UAAU,iBAAiB,MAAM,EAAE,aAAa,WAC3C,OAAuB,MAAM,WAC9B;AAEN,MAAI,UAAU,qBAAqB,MAAM;AACvC,IAAC,OAAuB,MAAM,WAAW;AAAA,EAC3C;AAEA,mBAAiB,QAAQ,SAAS,aAAa;AAE/C,MAAI,QAAQ,aAAa;AACvB,WAAO,UAAU,IAAI,QAAQ,WAAW;AAAA,EAC1C;AAEA,MAAI,QAAQ,aAAa;AACvB,WAAO,OAAO,OAAO,OAAO,QAAQ,WAAW;AAAA,EACjD;AAEA,MAAI,iBAAiB,QAAQ;AAC3B,SAAK,QAAQ,SAAS,kBAAkB,WAAW;AACjD,aAAO,OAAO,MAAM;AAAA,IACtB,OAAO;AACL,aAAO,QAAQ,MAAM;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,IAAM,aAAa,CACxB,KACA,WACW;AACX,QAAM,MACJ,OAAO,QAAQ,aACX,IAAI,IACJ,OAAO,QAAQ,WACb,MACA,OAAO,WAAW,cAChB,IACA,OAAO,oBAAoB;AAErC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,UAAU,CAAC,CAAC;AAC/C;AAEO,IAAM,uBAAuB,CAClC,QACA,QACA,QAMG;AACH,QAAM,OAAO,OAAO,sBAAsB;AAC1C,QAAM,gBAAgB,KAAK,IAAI,GAAG,KAAK,SAAS,OAAO,eAAe,CAAC;AACvE,QAAM,iBAAiB,KAAK,IAAI,GAAG,KAAK,UAAU,OAAO,gBAAgB,CAAC;AAC1E,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,gBAAgB,GAAG,CAAC;AACzD,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,iBAAiB,GAAG,CAAC;AAE3D,MAAI,OAAO,UAAU,MAAO,QAAO,QAAQ;AAC3C,MAAI,OAAO,WAAW,OAAQ,QAAO,SAAS;AAE9C,SAAO,EAAE,OAAO,QAAQ,eAAe,eAAe;AACxD;AAEA,IAAM,mBAAmB,CACvB,QACA,SACA,mBACS;AACT,SAAO,QAAQ,oBAAoB;AAEnC,MAAI,CAAC,eAAgB;AAErB,QAAM,QAAQ,QAAQ,SAAS;AAC/B,SAAO,OAAO,OAAO,OAAO;AAAA,IAC1B,UAAU;AAAA,IACV,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,eAAe;AAAA,IACf,QAAQ,UAAU,YAAY,MAAM;AAAA,EACtC,CAAC;AACH;;;ACvHO,IAAM,gBAAgB,CAAC,SAC5B,KAAK,WAAW,IAAI,IAAI,OAAO,KAAK,IAAI;;;ACYnC,IAAM,eAAe,OAC1B,IACA,UACA,gBAC6B;AAC7B,QAAM,UAAU,OAAO,QAAQ,YAAY,CAAC,CAAC;AAC7C,QAAM,SAA0B,CAAC;AAEjC,WAAS,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,GAAG;AACtD,QAAI,YAAY,EAAG;AACnB,UAAM,CAAC,MAAM,KAAK,IAAI,QAAQ,KAAK;AACnC,WAAO,KAAK,MAAM,YAAY,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,EACvD;AAEA,SAAO;AACT;AAEA,IAAM,cAAc,OAClB,IACA,MACA,OACA,SAC2B;AAC3B,QAAM,UAAU,sBAAsB,KAAK;AAC3C,QAAM,SAAS,MAAM,cAAc,QAAQ,MAAM;AACjD,QAAM,UAAU,GAAG,cAAc;AAEjC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,iBAAiB,6BAA6B,IAAI,EAAE;AAAA,EAChE;AAEA,KAAG,cAAc,GAAG,WAAW,IAAI;AACnC,KAAG,YAAY,GAAG,YAAY,OAAO;AACrC,KAAG,YAAY,GAAG,qBAAqB,QAAQ,SAAS,IAAI;AAC5D,KAAG,WAAW,GAAG,YAAY,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,eAAe,MAAM;AAE1E,QAAM,OAAO,QAAQ,IAAI,QAAQ,QAAQ,OAAO;AAChD,QAAM,SAAS,UAAU,IAAI,QAAQ,UAAU,QAAQ;AAEvD,KAAG,cAAc,GAAG,YAAY,GAAG,gBAAgB,IAAI;AACvD,KAAG,cAAc,GAAG,YAAY,GAAG,gBAAgB,IAAI;AACvD,KAAG,cAAc,GAAG,YAAY,GAAG,oBAAoB,MAAM;AAC7D,KAAG,cAAc,GAAG,YAAY,GAAG,oBAAoB,MAAM;AAE7D,SAAO;AAAA,IACL;AAAA,IACA,aAAa,cAAc,IAAI;AAAA,IAC/B,iBAAiB,cAAc,GAAG,IAAI,MAAM;AAAA,IAC5C;AAAA,IACA,OAAO,eAAe,MAAM;AAAA,IAC5B,QAAQ,gBAAgB,MAAM;AAAA,EAChC;AACF;AAEA,IAAM,wBAAwB,CAAC,UAAwC;AACrE,MAAI,OAAO,UAAU,YAAY,gBAAgB,KAAK,GAAG;AACvD,WAAO,EAAE,QAAQ,MAAM;AAAA,EACzB;AAEA,SAAO;AACT;AAEA,IAAM,gBAAgB,OACpB,WACkD;AAClD,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,IAAI,MAAM;AACxB,QAAM,cAAc;AACpB,QAAM,MAAM;AAEZ,MAAI;AACF,UAAM,MAAM,OAAO;AAAA,EACrB,SAAS,OAAO;AACd,UAAM,IAAI,iBAAiB,2BAA2B,MAAM,EAAE;AAAA,EAChE;AAEA,SAAO;AACT;AAEA,IAAM,UAAU,CACd,IACA,SACW;AACX,MAAI,SAAS,SAAU,QAAO,GAAG;AACjC,MAAI,SAAS,SAAU,QAAO,GAAG;AACjC,SAAO,GAAG;AACZ;AAEA,IAAM,YAAY,CAChB,IACA,WACY,WAAW,YAAY,GAAG,UAAU,GAAG;AAErD,IAAM,kBAAkB,CAAC,UACvB,OAAO,qBAAqB,gBAC3B,iBAAiB,oBAAoB,iBAAiB;AAEzD,IAAM,iBAAiB,CAAC,WACtB,kBAAkB,SAAS,OAAO,eAAe,OAAO;AAE1D,IAAM,kBAAkB,CAAC,WACvB,mBAAmB,SAAS,OAAO,gBAAgB,OAAO;;;AC7GrD,IAAM,mBAAmB,CAAC,UAA2C;AAC1E,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,EAAE,MAAM,SAAS,OAAO,CAAC,KAAK,EAAE;AAAA,EACzC;AAEA,MAAI,iBAAiB,cAAc;AACjC,QAAI,MAAM,WAAW,EAAG,QAAO,EAAE,MAAM,QAAQ,OAAO,MAAM;AAC5D,QAAI,MAAM,WAAW,GAAI,QAAO,EAAE,MAAM,QAAQ,OAAO,MAAM;AAC7D,QAAI,MAAM,WAAW,EAAG,QAAO,EAAE,MAAM,QAAQ,OAAO,MAAM;AAC5D,QAAI,MAAM,WAAW,EAAG,QAAO,EAAE,MAAM,QAAQ,OAAO,MAAM;AAC5D,QAAI,MAAM,WAAW,EAAG,QAAO,EAAE,MAAM,QAAQ,OAAO,MAAM;AAAA,EAC9D;AAEA,MAAI,kBAAkB,KAAK,GAAG;AAC5B,WAAO,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM;AAAA,EAChD;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,QAAI,MAAM,WAAW,EAAG,QAAO,EAAE,MAAM,QAAQ,OAAO,MAAM;AAC5D,QAAI,MAAM,WAAW,EAAG,QAAO,EAAE,MAAM,QAAQ,OAAO,MAAM;AAC5D,QAAI,MAAM,WAAW,EAAG,QAAO,EAAE,MAAM,QAAQ,OAAO,MAAM;AAAA,EAC9D;AAEA,SAAO,EAAE,MAAM,SAAS,OAAO,CAAC,CAAC,EAAE;AACrC;AAEO,IAAM,eAAe,CAC1B,IACA,UACA,YACS;AACT,QAAM,QAAQ,QAAQ;AAEtB,UAAQ,QAAQ,MAAM;AAAA,IACpB,KAAK;AACH,SAAG,UAAU,UAAU,MAAM,CAAC,KAAK,CAAC;AACpC;AAAA,IACF,KAAK;AACH,SAAG,UAAU,UAAU,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AACnD;AAAA,IACF,KAAK;AACH,SAAG,UAAU,UAAU,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AAClE;AAAA,IACF,KAAK;AACH,SAAG;AAAA,QACD;AAAA,QACA,MAAM,CAAC,KAAK;AAAA,QACZ,MAAM,CAAC,KAAK;AAAA,QACZ,MAAM,CAAC,KAAK;AAAA,QACZ,MAAM,CAAC,KAAK;AAAA,MACd;AACA;AAAA,IACF,KAAK;AACH,SAAG,iBAAiB,UAAU,OAAO,KAAK;AAC1C;AAAA,IACF,KAAK;AACH,SAAG,iBAAiB,UAAU,OAAO,KAAK;AAC1C;AAAA,EACJ;AACF;AAEO,IAAM,sBAAsB,CACjC,IACA,SACA,UACA,YACS;AACT,KAAG,WAAW,OAAO;AACrB,eAAa,IAAI,UAAU,OAAO;AACpC;AAEO,IAAM,0BAA0B,CACrC,IACA,YACsC;AACtC,QAAM,YAAY,oBAAI,IAAkC;AACxD,QAAM,QAAQ,GAAG,oBAAoB,SAAS,GAAG,eAAe;AAEhE,WAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS,GAAG;AAC7C,UAAM,SAAS,GAAG,iBAAiB,SAAS,KAAK;AACjD,QAAI,CAAC,OAAQ;AAEb,UAAM,OAAO,OAAO,KAAK,QAAQ,UAAU,EAAE;AAC7C,UAAM,WAAW,GAAG,mBAAmB,SAAS,IAAI;AACpD,QAAI,UAAU;AACZ,gBAAU,IAAI,MAAM,QAAQ;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,qBAAqB,CAChC,aACmC;AACnC,QAAM,QAAQ,oBAAI,IAA+B;AAEjD,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,YAAY,CAAC,CAAC,GAAG;AAC1D,UAAM,IAAI,cAAc,IAAI,GAAG,iBAAiB,KAAK,CAAC;AAAA,EACxD;AAEA,SAAO;AACT;AAEA,IAAM,oBAAoB,CAAC,UAAkD;AAC3E,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AACxE,SAAO,UAAU,SAAS,WAAW;AACvC;;;ACjHO,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU5B,IAAM,gBAAgB,CAC3B,IACA,cACA,mBACiB;AACjB,QAAM,SAAS,cAAc,IAAI,GAAG,eAAe,YAAY;AAC/D,QAAM,WAAW,cAAc,IAAI,GAAG,iBAAiB,cAAc;AACrE,QAAM,UAAU,GAAG,cAAc;AAEjC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,mBAAmB,iCAAiC;AAAA,EAChE;AAEA,KAAG,aAAa,SAAS,MAAM;AAC/B,KAAG,aAAa,SAAS,QAAQ;AACjC,KAAG,YAAY,OAAO;AAEtB,MAAI,CAAC,GAAG,oBAAoB,SAAS,GAAG,WAAW,GAAG;AACpD,UAAM,MAAM,GAAG,kBAAkB,OAAO,KAAK;AAC7C,OAAG,cAAc,OAAO;AACxB,OAAG,aAAa,MAAM;AACtB,OAAG,aAAa,QAAQ;AACxB,UAAM,IAAI,mBAAmB,GAAG;AAAA,EAClC;AAEA,KAAG,aAAa,MAAM;AACtB,KAAG,aAAa,QAAQ;AACxB,SAAO;AACT;AAEO,IAAM,yBAAyB,CACpC,IACA,YACgB;AAChB,QAAM,SAAS,GAAG,aAAa;AAC/B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,mBAAmB,qCAAqC;AAAA,EACpE;AAEA,QAAM,WAAW,GAAG,kBAAkB,SAAS,YAAY;AAC3D,KAAG,WAAW,GAAG,cAAc,MAAM;AACrC,KAAG;AAAA,IACD,GAAG;AAAA,IACH,IAAI,aAAa,CAAC,IAAI,IAAI,GAAG,IAAI,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC;AAAA,IAC3D,GAAG;AAAA,EACL;AAEA,MAAI,YAAY,GAAG;AACjB,OAAG,wBAAwB,QAAQ;AACnC,OAAG,oBAAoB,UAAU,GAAG,GAAG,OAAO,OAAO,GAAG,CAAC;AAAA,EAC3D;AAEA,SAAO;AACT;AAEA,IAAM,gBAAgB,CACpB,IACA,MACA,WACgB;AAChB,QAAM,SAAS,GAAG,aAAa,IAAI;AACnC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,mBAAmB,gCAAgC;AAAA,EAC/D;AAEA,KAAG,aAAa,QAAQ,MAAM;AAC9B,KAAG,cAAc,MAAM;AAEvB,MAAI,CAAC,GAAG,mBAAmB,QAAQ,GAAG,cAAc,GAAG;AACrD,UAAM,MAAM,GAAG,iBAAiB,MAAM,KAAK;AAC3C,OAAG,aAAa,MAAM;AACtB,UAAM,IAAI,mBAAmB,GAAG;AAAA,EAClC;AAEA,SAAO;AACT;;;ACnDA,IAAM,oBAAoB;AAEnB,IAAM,yBAAyB,CAGpC,YACwC;AACxC,SAAO,IAAI,iBAA4B,OAAO;AAChD;AAEA,IAAM,mBAAN,MAEA;AAAA,EAiCE,YAAY,SAAmD;AA5B/D,SAAiB,iBAAiB,oBAAI,IAAY;AAClD,SAAQ,eAAoC;AAC5C,SAAQ,cAA+C;AACvD,SAAQ,MAAuB;AAC/B,SAAQ,UAA+B;AACvC,SAAQ,SAA6B;AACrC,SAAQ,mBAAmB,oBAAI,IAAkC;AACjE,SAAQ,WAA4B,CAAC;AACrC,SAAQ,iBAAwC;AAChD,SAAQ,uBAAoD;AAC5D,SAAQ,QAAQ;AAChB,SAAQ,UAAU;AAClB,SAAQ,WAAW;AACnB,SAAQ,YAAY;AACpB,SAAQ,WAAW;AACnB,SAAQ,QAAQ;AAChB,SAAQ,UAAU;AAClB,SAAQ,gBAAgB;AACxB,SAAQ,aAAa;AACrB,SAAQ,QAAQ;AAChB,SAAQ,SAAS;AACjB,SAAQ,gBAAgB;AACxB,SAAQ,iBAAiB;AACzB,SAAQ,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,EAAE;AAC1D,SAAQ,kBAAqC,CAAC;AAC9C,SAAQ,gBAA8B;AACtC,SAAQ,2BAA2B;AAGjC,SAAK,UAAU;AACf,SAAK,eAAe,mBAAmB,QAAQ,QAAQ;AACvD,SAAK,QAAQ,IAAI,QAAc,CAAC,SAAS,WAAW;AAClD,WAAK,eAAe;AACpB,WAAK,cAAc;AAAA,IACrB,CAAC;AAED,mBAAe,MAAM;AACnB,WAAK,KAAK,KAAK;AAAA,IACjB,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,SAAmC;AACrC,WAAO,KAAK,KAAK,UAAU;AAAA,EAC7B;AAAA,EAEA,IAAI,KAAmC;AACrC,WAAO,KAAK,KAAK,OAAO,WAAW,OAAO,KAAK;AAAA,EACjD;AAAA,EAEA,IAAI,SAAuB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,CAAC,CAAC,eAAe,WAAW,EAAE,SAAS,KAAK,aAAa;AAAA,EAClE;AAAA,EAEA,QAAc;AACZ,QAAI,KAAK,aAAa,KAAK,kBAAkB,cAAe;AAC5D,SAAK,UAAU;AAEf,QAAI,CAAC,KAAK,aAAa,KAAK,QAAQ,sBAAsB,OAAO;AAC/D,WAAK,gBAAgB;AACrB;AAAA,IACF;AAEA,QAAI,KAAK,QAAQ,eAAe,UAAU;AACxC,WAAK,gBAAgB;AACrB,WAAK,OAAO;AACZ;AAAA,IACF;AAEA,SAAK,gBAAgB;AACrB,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,OAAa;AACX,SAAK,UAAU;AACf,SAAK,YAAY;AACjB,QAAI,CAAC,KAAK,aAAa,KAAK,kBAAkB,eAAe;AAC3D,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,SAAe;AACb,QACE,KAAK,aACL,CAAC,KAAK,OACN,CAAC,KAAK,WACN,KAAK,kBAAkB,kBACtB,KAAK,QAAQ,sBAAsB,SAAS,CAAC,KAAK,UACnD;AACA;AAAA,IACF;AAEA,UAAM,KAAK,KAAK,IAAI,OAAO,WAAW,OAAO;AAC7C,QAAI,CAAC,GAAI;AAET,SAAK,WAAW;AAChB,SAAK,OAAO;AACZ,OAAG,SAAS,GAAG,GAAG,KAAK,OAAO,KAAK,MAAM;AACzC,OAAG,MAAM,GAAG,gBAAgB;AAC5B,OAAG,WAAW,KAAK,OAAO;AAC1B,SAAK,qBAAqB,EAAE;AAC5B,SAAK,oBAAoB,EAAE;AAC3B,SAAK,cAAc,EAAE;AAErB,UAAM,QAAQ,KAAK,kBAAkB,EAAE;AACvC,SAAK,QAAQ,iBAAiB,KAAK;AACnC,SAAK,oBAAoB,EAAE;AAE3B,OAAG,WAAW,GAAG,WAAW,GAAG,CAAC;AAChC,SAAK,QAAQ,gBAAgB,KAAK;AAClC,SAAK,SAAS;AACd,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,SAAe;AACb,QAAI,KAAK,aAAa,CAAC,KAAK,IAAK;AACjC,SAAK,aAAa,WAAW,KAAK,QAAQ,KAAK,KAAK,QAAQ,MAAM;AAClE,UAAM,OAAO;AAAA,MACX,KAAK,IAAI;AAAA,MACT,KAAK,IAAI;AAAA,MACT,KAAK;AAAA,IACP;AACA,SAAK,QAAQ,KAAK;AAClB,SAAK,SAAS,KAAK;AACnB,SAAK,gBAAgB,KAAK;AAC1B,SAAK,iBAAiB,KAAK;AAE3B,QAAI,KAAK,QAAQ,eAAe,YAAY,CAAC,KAAK,UAAU;AAC1D,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEA,UAAgB;AACd,QAAI,KAAK,UAAW;AACpB,SAAK,YAAY;AACjB,SAAK,UAAU;AACf,SAAK,YAAY;AACjB,SAAK,gBAAgB,WAAW;AAChC,SAAK,sBAAsB,WAAW;AAEtC,eAAW,UAAU,KAAK,gBAAiB,QAAO;AAClD,SAAK,kBAAkB,CAAC;AAExB,UAAM,KAAK,KAAK,KAAK,OAAO,WAAW,OAAO;AAC9C,QAAI,IAAI;AACN,iBAAW,WAAW,KAAK,SAAU,IAAG,cAAc,QAAQ,OAAO;AACrE,UAAI,KAAK,OAAQ,IAAG,aAAa,KAAK,MAAM;AAC5C,UAAI,KAAK,QAAS,IAAG,cAAc,KAAK,OAAO;AAAA,IACjD;AAEA,QAAI,KAAK,KAAK,eAAe;AAC3B,WAAK,IAAI,OAAO,OAAO;AAAA,IACzB;AAEA,UAAM,MAAM,KAAK;AACjB,QAAI,KAAK,qBAAqB,QAAQ,OAAO,KAAK,QAAQ,QAAQ;AAChE,YAAM,SAAS,IAAI;AACnB,aAAO,MAAM,WAAW,IAAI;AAAA,IAC9B;AAEA,SAAK,gBAAgB;AACrB,SAAK,cAAc,IAAI,eAAe,kCAAkC,CAAC;AAAA,EAC3E;AAAA,EAOA,WAAW,MAAc,OAA2B;AAClD,QAAI,KAAK,UAAW;AACpB,UAAM,cAAc,cAAc,IAAI;AACtC,SAAK,aAAa,IAAI,aAAa,iBAAiB,KAAK,CAAC;AAE1D,UAAM,KAAK,KAAK,KAAK,OAAO,WAAW,OAAO;AAC9C,UAAM,WAAW,KAAK,iBAAiB,IAAI,WAAW;AACtD,QAAI,MAAM,KAAK,WAAW,UAAU;AAClC;AAAA,QACE;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA,KAAK,aAAa,IAAI,WAAW;AAAA,MACnC;AAAA,IACF,WAAW,KAAK,SAAS;AACvB,WAAK,mBAAmB,WAAW;AAAA,IACrC;AAEA,QACE,KAAK,QAAQ,eAAe,YAC5B,CAAC,KAAK,YACN,KAAK,UACL;AACA,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEA,YAAY,QAA4C;AACtD,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAClD,WAAK,WAAW,MAAM,KAAK;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAc,OAAsB;AAClC,QAAI,OAAO,WAAW,eAAe,OAAO,aAAa,aAAa;AACpE,WAAK,gBAAgB,IAAI,iBAAiB,2BAA2B,CAAC;AACtE;AAAA,IACF;AAEA,SAAK,MAAM,YAAY,KAAK,OAAO;AACnC,QAAI,CAAC,KAAK,KAAK;AACb,WAAK,gBAAgB,IAAI,oBAAoB,6BAA6B,CAAC;AAC3E;AAAA,IACF;AAEA,UAAM,KAAK,KAAK,IAAI,OAAO,WAAW,SAAS;AAAA,MAC7C,OAAO;AAAA,MACP,WAAW;AAAA,MACX,OAAO;AAAA,MACP,SAAS;AAAA,MACT,oBAAoB;AAAA,MACpB,uBAAuB;AAAA,IACzB,CAAC;AAED,QAAI,CAAC,IAAI;AACP,WAAK,gBAAgB,IAAI,iBAAiB,yBAAyB,CAAC;AACpE;AAAA,IACF;AAEA,SAAK,gBAAgB;AAErB,QAAI;AACF,WAAK,kBAAkB;AACvB,WAAK,mBAAmB;AACxB,WAAK,aAAa,EAAE;AACpB,WAAK,OAAO;AACZ,WAAK,WAAW,MAAM;AAAA,QACpB;AAAA,QACA,KAAK,QAAQ;AAAA,QACb,MAAM,KAAK;AAAA,MACb;AACA,UAAI,KAAK,UAAW;AACpB,WAAK,yBAAyB;AAC9B,WAAK,gBAAgB;AACrB,WAAK,eAAe;AACpB,WAAK,QAAQ,UAAU,IAAI;AAE3B,UAAI,KAAK,YAAY,KAAK,QAAQ,aAAa,OAAO;AACpD,aAAK,MAAM;AAAA,MACb,WAAW,KAAK,QAAQ,eAAe,UAAU;AAC/C,aAAK,OAAO;AAAA,MACd;AAAA,IACF,SAAS,OAAO;AACd,WAAK,KAAK,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,IACrE;AAAA,EACF;AAAA,EAEQ,aAAa,IAAiC;AACpD,QAAI,KAAK,QAAS,IAAG,cAAc,KAAK,OAAO;AAC/C,QAAI,KAAK,OAAQ,IAAG,aAAa,KAAK,MAAM;AAE5C,SAAK,UAAU;AAAA,MACb;AAAA,MACA,KAAK,QAAQ,UAAU;AAAA,MACvB,KAAK,QAAQ;AAAA,IACf;AACA,OAAG,WAAW,KAAK,OAAO;AAC1B,SAAK,SAAS,uBAAuB,IAAI,KAAK,OAAO;AACrD,SAAK,mBAAmB,wBAAwB,IAAI,KAAK,OAAO;AAAA,EAClE;AAAA,EAEQ,oBAA0B;AAChC,QAAI,CAAC,KAAK,IAAK;AAEf,QAAI,KAAK,QAAQ,cAAc,MAAM;AACnC,WAAK,iBAAiB,IAAI,eAAe,MAAM;AAC7C,aAAK,OAAO;AAAA,MACd,CAAC;AACD,WAAK,eAAe,QAAQ,KAAK,IAAI,MAAM;AAAA,IAC7C;AAEA,QAAI,KAAK,QAAQ,sBAAsB,MAAM;AAC3C,WAAK,uBAAuB,IAAI,qBAAqB,CAAC,YAAY;AAChE,cAAM,QAAQ,QAAQ,CAAC;AACvB,aAAK,WAAW,QAAQ,OAAO,cAAc;AAC7C,YAAI,CAAC,KAAK,UAAU;AAClB,eAAK,YAAY;AACjB,cAAI,KAAK,QAAS,MAAK,gBAAgB;AACvC;AAAA,QACF;AAEA,YAAI,KAAK,SAAS;AAChB,eAAK,MAAM;AAAA,QACb,WAAW,KAAK,QAAQ,eAAe,UAAU;AAC/C,eAAK,OAAO;AAAA,QACd;AAAA,MACF,CAAC;AACD,WAAK,qBAAqB,QAAQ,KAAK,IAAI,MAAM;AAAA,IACnD;AAEA,UAAM,gBAAgB,CAAC,UAAiB;AACtC,UAAI,CAAC,KAAK,IAAK;AACf,YAAM,eAAe;AACrB,YAAM,OAAO,KAAK,IAAI,OAAO,sBAAsB;AACnD,YAAM,IAAI,aAAa,UAAU,KAAK;AACtC,YAAM,IAAI,aAAa,UAAU,KAAK;AACtC,WAAK,QAAQ,IAAI,IAAI,KAAK;AAC1B,WAAK,QAAQ,KAAK,KAAK,SAAS,KAAK,KAAK;AAC1C,WAAK,QAAQ,MAAM,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ;AACrD,WAAK,QAAQ,MAAM,KAAK,SAAS,IAAI,IAAI,IAAI,KAAK,SAAS;AAC3D,WAAK,QAAQ,SAAS;AAEtB,UAAI,KAAK,QAAQ,eAAe,SAAU,MAAK,OAAO;AAAA,IACxD;AACA,UAAM,iBAAiB,MAAM;AAC3B,WAAK,QAAQ,SAAS;AACtB,UAAI,KAAK,QAAQ,eAAe,SAAU,MAAK,OAAO;AAAA,IACxD;AAEA,SAAK,IAAI,OAAO,iBAAiB,eAAe,aAAa;AAC7D,SAAK,IAAI,OAAO,iBAAiB,gBAAgB,aAAa;AAC9D,SAAK,IAAI,OAAO,iBAAiB,gBAAgB,cAAc;AAC/D,SAAK,gBAAgB,KAAK,MAAM;AAC9B,WAAK,KAAK,OAAO,oBAAoB,eAAe,aAAa;AACjE,WAAK,KAAK,OAAO,oBAAoB,gBAAgB,aAAa;AAClE,WAAK,KAAK,OAAO,oBAAoB,gBAAgB,cAAc;AAAA,IACrE,CAAC;AAAA,EACH;AAAA,EAEQ,qBAA2B;AACjC,QAAI,CAAC,KAAK,IAAK;AAEf,UAAM,SAAS,CAAC,UAAiB;AAC/B,YAAM,eAAe;AACrB,WAAK,2BAA2B,KAAK;AACrC,WAAK,YAAY;AACjB,WAAK,gBAAgB;AACrB,WAAK,QAAQ,UAAU,IAAI,iBAAiB,qBAAqB,CAAC;AAAA,IACpE;AAEA,UAAM,aAAa,MAAM;AACvB,UAAI,CAAC,KAAK,OAAO,KAAK,UAAW;AACjC,YAAM,KAAK,KAAK,IAAI,OAAO,WAAW,OAAO;AAC7C,UAAI,CAAC,GAAI;AAET,UAAI;AACF,aAAK,aAAa,EAAE;AACpB,aAAK,oBAAoB,EAAE;AAC3B,aAAK,aAAa,IAAI,KAAK,QAAQ,UAAU,MAAM,KAAK,SAAS,EAAE;AAAA,UACjE,CAAC,aAAa;AACZ,iBAAK,WAAW;AAChB,iBAAK,yBAAyB;AAC9B,gBAAI,KAAK,yBAA0B,MAAK,MAAM;AAAA,gBACzC,MAAK,OAAO;AAAA,UACnB;AAAA,UACA,CAAC,UACC,KAAK,KAAK,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,QACvE;AAAA,MACF,SAAS,OAAO;AACd,aAAK,KAAK,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,MACrE;AAAA,IACF;AAEA,SAAK,IAAI,OAAO,iBAAiB,oBAAoB,MAAM;AAC3D,SAAK,IAAI,OAAO,iBAAiB,wBAAwB,UAAU;AACnE,SAAK,gBAAgB,KAAK,MAAM;AAC9B,WAAK,KAAK,OAAO,oBAAoB,oBAAoB,MAAM;AAC/D,WAAK,KAAK,OAAO,oBAAoB,wBAAwB,UAAU;AAAA,IACzE,CAAC;AAAA,EACH;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,KAAK,SAAS,KAAK,QAAQ,eAAe,SAAU;AAExD,SAAK,QAAQ,sBAAsB,CAAC,cAAc;AAChD,WAAK,QAAQ;AACb,UAAI,CAAC,KAAK,WAAW,KAAK,UAAW;AAErC,YAAM,UAAU,YAAY;AAC5B,YAAM,WAAW,KAAK,gBAAgB,UAAU,KAAK,gBAAgB;AACrE,YAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,UAAU,CAAC,GAAG,iBAAiB;AAC/D,WAAK,gBAAgB;AACrB,WAAK,WAAW;AAChB,WAAK,eAAe,KAAK;AACzB,WAAK,OAAO;AACZ,WAAK,cAAc;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEQ,cAAoB;AAC1B,QAAI,KAAK,OAAO;AACd,2BAAqB,KAAK,KAAK;AAC/B,WAAK,QAAQ;AAAA,IACf;AACA,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEQ,eAAe,OAAqB;AAC1C,SAAK,aAAa,IAAI,UAAU,EAAE,MAAM,SAAS,OAAO,CAAC,KAAK,OAAO,EAAE,CAAC;AACxE,SAAK,aAAa,IAAI,WAAW,EAAE,MAAM,SAAS,OAAO,CAAC,KAAK,EAAE,CAAC;AAAA,EACpE;AAAA,EAEQ,qBAAqB,IAAiC;AAC5D,UAAM,WAAyC;AAAA,MAC7C,YAAY,CAAC,KAAK,OAAO,KAAK,MAAM;AAAA,MACpC,cAAc,CAAC,KAAK,eAAe,KAAK,cAAc;AAAA,MACtD,YAAY,KAAK;AAAA,MACjB,SAAS,CAAC,KAAK,QAAQ,GAAG,KAAK,QAAQ,CAAC;AAAA,MACxC,WAAW,CAAC,KAAK,QAAQ,KAAK,KAAK,QAAQ,GAAG;AAAA,MAC9C,eAAe,KAAK,QAAQ;AAAA,IAC9B;AAEA,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACpD,WAAK,aAAa,IAAI,cAAc,IAAI,GAAG,iBAAiB,KAAK,CAAC;AAAA,IACpE;AAEA,SAAK,oBAAoB,EAAE;AAAA,EAC7B;AAAA,EAEQ,2BAAiC;AACvC,eAAW,WAAW,KAAK,UAAU;AACnC,WAAK,aAAa,IAAI,QAAQ,iBAAiB;AAAA,QAC7C,MAAM;AAAA,QACN,OAAO,CAAC,QAAQ,OAAO,QAAQ,MAAM;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,oBAAoB,IAAiC;AAC3D,eAAW,CAAC,MAAM,OAAO,KAAK,KAAK,cAAc;AAC/C,YAAM,WAAW,KAAK,iBAAiB,IAAI,IAAI;AAC/C,UAAI,CAAC,UAAU;AACb,aAAK,mBAAmB,IAAI;AAC5B;AAAA,MACF;AACA,mBAAa,IAAI,UAAU,OAAO;AAAA,IACpC;AAAA,EACF;AAAA,EAEQ,cAAc,IAAiC;AACrD,aAAS,OAAO,GAAG,OAAO,KAAK,SAAS,QAAQ,QAAQ,GAAG;AACzD,YAAM,UAAU,KAAK,SAAS,IAAI;AAClC,UAAI,CAAC,QAAS;AACd,YAAM,WAAW,KAAK,iBAAiB,IAAI,QAAQ,WAAW;AAC9D,UAAI,CAAC,SAAU;AAEf,SAAG,cAAc,GAAG,WAAW,IAAI;AACnC,SAAG,YAAY,GAAG,YAAY,QAAQ,OAAO;AAC7C,SAAG,UAAU,UAAU,IAAI;AAAA,IAC7B;AAAA,EACF;AAAA,EAEQ,kBACN,IACwB;AACxB,WAAO;AAAA,MACL,UAAU;AAAA,MACV;AAAA,MACA,QAAQ,KAAK,IAAK;AAAA,MAClB,MAAM,KAAK;AAAA,MACX,OAAO,KAAK,aAAa,IAAI,SAAS,GAAG,MAAM,CAAC,KAAK;AAAA,MACrD,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,eAAe,KAAK;AAAA,MACpB,gBAAgB,KAAK;AAAA,MACrB,YAAY,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,mBAAmB,MAAoB;AAC7C,QAAI,CAAC,KAAK,QAAQ,SAAS,KAAK,eAAe,IAAI,IAAI,EAAG;AAC1D,SAAK,eAAe,IAAI,IAAI;AAC5B,YAAQ,KAAK,sDAAsD,IAAI,EAAE;AAAA,EAC3E;AAAA,EAEQ,gBAAgB,OAAoB;AAC1C,SAAK,gBAAgB;AACrB,SAAK,UAAU,MAAM,OAAO;AAC5B,SAAK,QAAQ,UAAU,KAAK;AAC5B,SAAK,cAAc,KAAK;AAAA,EAC1B;AAAA,EAEQ,KAAK,OAAoB;AAC/B,SAAK,gBAAgB;AACrB,SAAK,UAAU,MAAM,OAAO;AAC5B,SAAK,QAAQ,UAAU,KAAK;AAC5B,SAAK,cAAc,KAAK;AAAA,EAC1B;AAAA,EAEQ,UAAU,SAAuB;AACvC,QAAI,KAAK,QAAQ,OAAO;AACtB,cAAQ,KAAK,kBAAkB,OAAO,EAAE;AAAA,IAC1C;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/errors.ts","../src/internal/dom.ts","../src/internal/names.ts","../src/internal/textures.ts","../src/internal/uniforms.ts","../src/internal/webgl.ts","../src/createShaderBackground.ts"],"sourcesContent":["export class ShaderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\nexport class UnsupportedError extends ShaderError {}\nexport class TargetNotFoundError extends ShaderError {}\nexport class ShaderCompileError extends ShaderError {}\nexport class TextureLoadError extends ShaderError {}\nexport class DestroyedError extends ShaderError {}\n","import type { CreateShaderBackgroundOptions, DprOption } from \"../types\";\n\nexport type DomSetup = {\n target: Element;\n canvas: HTMLCanvasElement;\n createdCanvas: boolean;\n restoredPosition: string | null;\n};\n\nexport const resolveElement = (\n target: string | Element | undefined\n): Element | null => {\n if (!target) return null;\n if (typeof target === \"string\") return document.querySelector(target);\n return target;\n};\n\nexport const setupCanvas = (\n options: CreateShaderBackgroundOptions\n): DomSetup | null => {\n const target = resolveElement(options.target);\n const canvas = options.canvas ?? document.createElement(\"canvas\");\n const measurementTarget = target ?? options.canvas;\n\n if (!measurementTarget) return null;\n\n const createdCanvas = !options.canvas;\n const restoredPosition =\n target && getComputedStyle(target).position === \"static\"\n ? (target as HTMLElement).style.position\n : null;\n\n if (target && restoredPosition !== null) {\n (target as HTMLElement).style.position = \"relative\";\n }\n\n applyCanvasStyle(canvas, options, createdCanvas);\n\n if (options.canvasClass) {\n canvas.classList.add(options.canvasClass);\n }\n\n if (options.canvasStyle) {\n Object.assign(canvas.style, options.canvasStyle);\n }\n\n if (createdCanvas && target) {\n if ((options.layer ?? \"background\") === \"overlay\") {\n target.append(canvas);\n } else {\n target.prepend(canvas);\n }\n }\n\n return {\n target: measurementTarget,\n canvas,\n createdCanvas,\n restoredPosition\n };\n};\n\nexport const resolveDpr = (\n dpr: DprOption | undefined,\n maxDpr: number | undefined\n): number => {\n const raw =\n typeof dpr === \"function\"\n ? dpr()\n : typeof dpr === \"number\"\n ? dpr\n : typeof window === \"undefined\"\n ? 1\n : window.devicePixelRatio || 1;\n\n return Math.max(1, Math.min(raw, maxDpr ?? 2));\n};\n\nexport const resizeCanvasToTarget = (\n canvas: HTMLCanvasElement,\n target: Element,\n dpr: number\n): {\n width: number;\n height: number;\n viewportWidth: number;\n viewportHeight: number;\n} => {\n const rect = target.getBoundingClientRect();\n const viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n const viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n const width = Math.max(1, Math.round(viewportWidth * dpr));\n const height = Math.max(1, Math.round(viewportHeight * dpr));\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\nconst applyCanvasStyle = (\n canvas: HTMLCanvasElement,\n options: CreateShaderBackgroundOptions,\n shouldPosition: boolean\n): void => {\n canvas.dataset.frapxShaderCanvas = \"\";\n\n if (!shouldPosition) return;\n\n const layer = options.layer ?? \"background\";\n Object.assign(canvas.style, {\n position: \"absolute\",\n inset: \"0\",\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n pointerEvents: \"none\",\n zIndex: layer === \"overlay\" ? \"1\" : \"0\"\n });\n};\n","export const toUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name : `u_${name}`;\n\nexport const fromUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name.slice(2) : name;\n","import type { TextureInput, TextureOptions, TextureSource } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { toUniformName } from \"./names\";\n\nexport type LoadedTexture = {\n name: string;\n uniformName: string;\n sizeUniformName: string;\n texture: WebGLTexture;\n width: number;\n height: number;\n};\n\nexport const loadTextures = async (\n gl: WebGLRenderingContext,\n textures: Record<string, TextureInput> | undefined,\n isDestroyed: () => boolean\n): Promise<LoadedTexture[]> => {\n const entries = Object.entries(textures ?? {});\n const loaded: LoadedTexture[] = [];\n\n for (let index = 0; index < entries.length; index += 1) {\n if (isDestroyed()) break;\n const [name, input] = entries[index] as [string, TextureInput];\n loaded.push(await loadTexture(gl, name, input, index));\n }\n\n return loaded;\n};\n\nexport const loadTexture = async (\n gl: WebGLRenderingContext,\n name: string,\n input: TextureInput,\n unit: number\n): Promise<LoadedTexture> => {\n const options = normalizeTextureInput(input);\n const source = await resolveSource(options.source);\n const texture = gl.createTexture();\n\n if (!texture) {\n throw new TextureLoadError(`Failed to create texture: ${name}`);\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, options.flipY ?? true);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);\n\n const wrap = getWrap(gl, options.wrap ?? \"clamp\");\n const filter = getFilter(gl, options.filter ?? \"linear\");\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n return {\n name,\n uniformName: toUniformName(name),\n sizeUniformName: toUniformName(`${name}Size`),\n texture,\n width: getSourceWidth(source),\n height: getSourceHeight(source)\n };\n};\n\nconst normalizeTextureInput = (input: TextureInput): TextureOptions => {\n if (typeof input === \"string\" || isTextureSource(input)) {\n return { source: input };\n }\n\n return input;\n};\n\nconst resolveSource = async (\n source: TextureSource\n): Promise<HTMLImageElement | HTMLCanvasElement> => {\n if (typeof source !== \"string\") {\n return source;\n }\n\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = source;\n\n try {\n await image.decode();\n } catch (error) {\n throw new TextureLoadError(`Failed to load texture: ${source}`);\n }\n\n return image;\n};\n\nconst getWrap = (\n gl: WebGLRenderingContext,\n wrap: NonNullable<TextureOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n\nconst getFilter = (\n gl: WebGLRenderingContext,\n filter: NonNullable<TextureOptions[\"filter\"]>\n): number => (filter === \"nearest\" ? gl.NEAREST : gl.LINEAR);\n\nconst isTextureSource = (input: unknown): input is HTMLImageElement | HTMLCanvasElement =>\n typeof HTMLImageElement !== \"undefined\" &&\n (input instanceof HTMLImageElement || input instanceof HTMLCanvasElement);\n\nconst getSourceWidth = (source: HTMLImageElement | HTMLCanvasElement): number =>\n \"naturalWidth\" in source ? source.naturalWidth : source.width;\n\nconst getSourceHeight = (source: HTMLImageElement | HTMLCanvasElement): number =>\n \"naturalHeight\" in source ? source.naturalHeight : source.height;\n","import type { ExplicitUniformInput, UniformInput, UniformType } from \"../types\";\nimport { toUniformName } from \"./names\";\n\nexport type NormalizedUniform = {\n type: UniformType;\n value: number[] | Float32Array;\n};\n\nexport const normalizeUniform = (input: UniformInput): NormalizedUniform => {\n if (typeof input === \"number\") {\n return { type: \"float\", value: [input] };\n }\n\n if (input instanceof Float32Array) {\n if (input.length === 9) return { type: \"mat3\", value: input };\n if (input.length === 16) return { type: \"mat4\", value: input };\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n if (isExplicitUniform(input)) {\n return { type: input.type, value: input.value };\n }\n\n if (Array.isArray(input)) {\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n return { type: \"float\", value: [0] };\n};\n\nexport const applyUniform = (\n gl: WebGLRenderingContext,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n const value = uniform.value;\n\n switch (uniform.type) {\n case \"float\":\n gl.uniform1f(location, value[0] ?? 0);\n break;\n case \"vec2\":\n gl.uniform2f(location, value[0] ?? 0, value[1] ?? 0);\n break;\n case \"vec3\":\n gl.uniform3f(location, value[0] ?? 0, value[1] ?? 0, value[2] ?? 0);\n break;\n case \"vec4\":\n gl.uniform4f(\n location,\n value[0] ?? 0,\n value[1] ?? 0,\n value[2] ?? 0,\n value[3] ?? 0\n );\n break;\n case \"mat3\":\n gl.uniformMatrix3fv(location, false, value);\n break;\n case \"mat4\":\n gl.uniformMatrix4fv(location, false, value);\n break;\n }\n};\n\nexport const applyProgramUniform = (\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n gl.useProgram(program);\n applyUniform(gl, location, uniform);\n};\n\nexport const collectUniformLocations = (\n gl: WebGLRenderingContext,\n program: WebGLProgram\n): Map<string, WebGLUniformLocation> => {\n const locations = new Map<string, WebGLUniformLocation>();\n const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) as number;\n\n for (let index = 0; index < count; index += 1) {\n const active = gl.getActiveUniform(program, index);\n if (!active) continue;\n\n const name = active.name.replace(/\\[0\\]$/, \"\");\n const location = gl.getUniformLocation(program, name);\n if (location) {\n locations.set(name, location);\n }\n }\n\n return locations;\n};\n\nexport const createUniformCache = (\n uniforms: Record<string, UniformInput> | undefined\n): Map<string, NormalizedUniform> => {\n const cache = new Map<string, NormalizedUniform>();\n\n for (const [name, value] of Object.entries(uniforms ?? {})) {\n cache.set(toUniformName(name), normalizeUniform(value));\n }\n\n return cache;\n};\n\nconst isExplicitUniform = (input: unknown): input is ExplicitUniformInput => {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return false;\n return \"type\" in input && \"value\" in input;\n};\n","import { ShaderCompileError } from \"./errors\";\n\nexport const defaultVertexShader = `\nattribute vec2 a_position;\nvarying vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const createProgram = (\n gl: WebGLRenderingContext,\n vertexSource: string,\n fragmentSource: string\n): WebGLProgram => {\n const vertex = compileShader(gl, gl.VERTEX_SHADER, vertexSource);\n const fragment = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);\n const program = gl.createProgram();\n\n if (!program) {\n throw new ShaderCompileError(\"Failed to create WebGL program.\");\n }\n\n gl.attachShader(program, vertex);\n gl.attachShader(program, fragment);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program) ?? \"Unknown program link error.\";\n gl.deleteProgram(program);\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n throw new ShaderCompileError(log);\n }\n\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n return program;\n};\n\nexport const createFullscreenBuffer = (\n gl: WebGLRenderingContext,\n program: WebGLProgram\n): WebGLBuffer => {\n const buffer = gl.createBuffer();\n if (!buffer) {\n throw new ShaderCompileError(\"Failed to create fullscreen buffer.\");\n }\n\n const location = gl.getAttribLocation(program, \"a_position\");\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),\n gl.STATIC_DRAW\n );\n\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n};\n\nconst compileShader = (\n gl: WebGLRenderingContext,\n type: number,\n source: string\n): WebGLShader => {\n const shader = gl.createShader(type);\n if (!shader) {\n throw new ShaderCompileError(\"Failed to create WebGL shader.\");\n }\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader) ?? \"Unknown shader compile error.\";\n gl.deleteShader(shader);\n throw new ShaderCompileError(log);\n }\n\n return shader;\n};\n","import type {\n CreateShaderBackgroundOptions,\n RenderState,\n ShaderBackgroundInstance,\n ShaderStatus,\n TextureInput,\n TextureMap,\n UniformInput,\n UniformInputMap,\n UniformRuntimeValue\n} from \"./types\";\nimport {\n DestroyedError,\n TargetNotFoundError,\n TextureLoadError,\n UnsupportedError\n} from \"./internal/errors\";\nimport {\n resolveDpr,\n resizeCanvasToTarget,\n setupCanvas,\n type DomSetup\n} from \"./internal/dom\";\nimport { toUniformName } from \"./internal/names\";\nimport { loadTexture, type LoadedTexture } from \"./internal/textures\";\nimport {\n applyProgramUniform,\n applyUniform,\n collectUniformLocations,\n createUniformCache,\n normalizeUniform,\n type NormalizedUniform\n} from \"./internal/uniforms\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader\n} from \"./internal/webgl\";\n\nconst MAX_DELTA_SECONDS = 0.1;\n\nexport const createShaderBackground = <\n TUniforms extends UniformInputMap = UniformInputMap\n>(\n options: CreateShaderBackgroundOptions<TUniforms>\n): ShaderBackgroundInstance<TUniforms> => {\n return new ShaderBackground<TUniforms>(options);\n};\n\nclass ShaderBackground<TUniforms extends UniformInputMap>\n implements ShaderBackgroundInstance<TUniforms>\n{\n readonly ready: Promise<void>;\n\n private readonly options: CreateShaderBackgroundOptions<TUniforms>;\n private readonly uniformCache: Map<string, NormalizedUniform>;\n private readonly warnedUniforms = new Set<string>();\n private readyResolve: (() => void) | null = null;\n private readyReject: ((error: Error) => void) | null = null;\n private dom: DomSetup | null = null;\n private program: WebGLProgram | null = null;\n private buffer: WebGLBuffer | null = null;\n private attribLocation = -1;\n private uniformLocations = new Map<string, WebGLUniformLocation>();\n private textureInputs = new Map<string, TextureInput>();\n private textures = new Map<string, LoadedTexture>();\n private textureUnits = new Map<string, number>();\n private textureVersions = new Map<string, number>();\n private resizeObserver: ResizeObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private rafId = 0;\n private running = false;\n private inRender = false;\n private destroyed = false;\n private onscreen = true;\n private frame = 0;\n private elapsed = 0;\n private lastTimestamp = 0;\n private pixelRatio = 1;\n private width = 1;\n private height = 1;\n private viewportWidth = 1;\n private viewportHeight = 1;\n private pointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n private removeListeners: Array<() => void> = [];\n private currentStatus: ShaderStatus = \"idle\";\n private contextRestoredShouldRun = false;\n\n constructor(options: CreateShaderBackgroundOptions<TUniforms>) {\n this.options = options;\n this.uniformCache = createUniformCache(options.uniforms);\n this.ready = new Promise<void>((resolve, reject) => {\n this.readyResolve = resolve;\n this.readyReject = reject;\n });\n\n queueMicrotask(() => {\n void this.init();\n });\n }\n\n get canvas(): HTMLCanvasElement | null {\n return this.dom?.canvas ?? null;\n }\n\n get gl(): WebGLRenderingContext | null {\n return this.dom?.canvas.getContext(\"webgl\") ?? null;\n }\n\n get status(): ShaderStatus {\n return this.currentStatus;\n }\n\n get supported(): boolean {\n return ![\"unsupported\", \"destroyed\"].includes(this.currentStatus);\n }\n\n start(): void {\n if (this.destroyed || this.currentStatus === \"unsupported\") return;\n this.running = true;\n\n if (!this.onscreen && (this.options.pauseWhenOffscreen ?? true)) {\n this.currentStatus = \"paused\";\n return;\n }\n\n if (this.options.renderMode === \"demand\") {\n this.currentStatus = \"running\";\n this.render();\n return;\n }\n\n this.currentStatus = \"running\";\n this.scheduleFrame();\n }\n\n stop(): void {\n this.running = false;\n this.cancelFrame();\n if (!this.destroyed && this.currentStatus !== \"unsupported\") {\n this.currentStatus = \"paused\";\n }\n }\n\n render(): void {\n if (\n this.destroyed ||\n !this.dom ||\n !this.program ||\n this.currentStatus === \"unsupported\" ||\n (this.options.pauseWhenOffscreen ?? true) && !this.onscreen\n ) {\n return;\n }\n\n const gl = this.dom.canvas.getContext(\"webgl\");\n if (!gl) return;\n\n this.inRender = true;\n this.resize();\n // Reset to the default framebuffer each frame so a render-target left bound\n // by an extension (e.g. in onAfterRender) cannot leak into this frame.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.viewport(0, 0, this.width, this.height);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.useProgram(this.program);\n this.applyBuiltInUniforms(gl);\n\n const state = this.createRenderState(gl);\n this.options.onBeforeRender?.(state);\n // Re-establish all of the core's draw state after the user hook so any GL\n // side-effects (program, array buffer, attrib pointer, textures) cannot\n // corrupt the core draw. This is what makes the core a safe FBO host.\n this.prepareDrawState(gl);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n this.options.onAfterRender?.(state);\n this.frame += 1;\n this.inRender = false;\n }\n\n resize(): void {\n if (this.destroyed || !this.dom) return;\n this.pixelRatio = resolveDpr(this.options.dpr, this.options.maxDpr);\n const size = resizeCanvasToTarget(\n this.dom.canvas,\n this.dom.target,\n this.pixelRatio\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n\n if (this.options.renderMode === \"demand\" && !this.inRender) {\n this.render();\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.running = false;\n this.cancelFrame();\n this.resizeObserver?.disconnect();\n this.intersectionObserver?.disconnect();\n\n for (const remove of this.removeListeners) remove();\n this.removeListeners = [];\n\n const gl = this.dom?.canvas.getContext(\"webgl\");\n if (gl) {\n for (const texture of this.textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n if (this.buffer) gl.deleteBuffer(this.buffer);\n if (this.program) gl.deleteProgram(this.program);\n }\n\n if (this.dom?.createdCanvas) {\n this.dom.canvas.remove();\n }\n\n const dom = this.dom;\n if (dom?.restoredPosition !== null && dom && this.options.target) {\n const target = dom.target as HTMLElement;\n target.style.position = dom.restoredPosition;\n }\n\n this.currentStatus = \"destroyed\";\n this.readyReject?.(new DestroyedError(\"Shader background was destroyed.\"));\n }\n\n setUniform<K extends keyof TUniforms & string>(\n name: K,\n value: UniformRuntimeValue<TUniforms[K]>\n ): void;\n setUniform(name: string, value: UniformInput): void;\n setUniform(name: string, value: UniformInput): void {\n if (this.destroyed) return;\n const uniformName = toUniformName(name);\n this.uniformCache.set(uniformName, normalizeUniform(value));\n\n const gl = this.dom?.canvas.getContext(\"webgl\");\n const location = this.uniformLocations.get(uniformName);\n if (gl && this.program && location) {\n applyProgramUniform(\n gl,\n this.program,\n location,\n this.uniformCache.get(uniformName)!\n );\n } else if (this.program) {\n this.warnUnknownUniform(uniformName);\n }\n\n if (\n this.options.renderMode === \"demand\" &&\n !this.inRender &&\n this.onscreen\n ) {\n this.render();\n }\n }\n\n setUniforms(values: Record<string, UniformInput>): void {\n for (const [name, value] of Object.entries(values)) {\n this.setUniform(name, value);\n }\n }\n\n async setTexture(name: string, input: TextureInput): Promise<void> {\n if (this.destroyed) return;\n\n let gl = this.dom?.canvas.getContext(\"webgl\");\n if (!gl) {\n await this.ready;\n if (this.destroyed) return;\n gl = this.dom?.canvas.getContext(\"webgl\");\n }\n\n if (!gl) {\n const error = new TextureLoadError(\n \"Cannot set texture before WebGL is ready.\"\n );\n this.options.onError?.(error);\n throw error;\n }\n\n const version = (this.textureVersions.get(name) ?? 0) + 1;\n this.textureVersions.set(name, version);\n\n try {\n const unit = this.resolveTextureUnit(gl, name);\n const loaded = await loadTexture(gl, name, input, unit);\n\n if (this.destroyed || this.textureVersions.get(name) !== version) {\n gl.deleteTexture(loaded.texture);\n return;\n }\n\n const previous = this.textures.get(name);\n this.textureInputs.set(name, input);\n this.textures.set(name, loaded);\n if (previous) gl.deleteTexture(previous.texture);\n this.applyTextureSizeUniform(loaded);\n\n if (\n this.options.renderMode === \"demand\" &&\n !this.inRender &&\n this.onscreen\n ) {\n this.render();\n }\n } catch (error) {\n if (!this.textures.has(name) && !this.textureInputs.has(name)) {\n this.textureUnits.delete(name);\n }\n const normalized =\n error instanceof Error ? error : new Error(String(error));\n this.options.onError?.(normalized);\n throw normalized;\n }\n }\n\n async setTextures(values: TextureMap): Promise<void> {\n await Promise.all(\n Object.entries(values).map(([name, input]) =>\n this.setTexture(name, input)\n )\n );\n }\n\n private async init(): Promise<void> {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n this.failUnsupported(new UnsupportedError(\"WebGL requires a browser.\"));\n return;\n }\n\n this.dom = setupCanvas(this.options);\n if (!this.dom) {\n this.failUnsupported(new TargetNotFoundError(\"Target or canvas not found.\"));\n return;\n }\n\n const gl = this.dom.canvas.getContext(\"webgl\", {\n alpha: true,\n antialias: false,\n depth: false,\n stencil: false,\n premultipliedAlpha: true,\n preserveDrawingBuffer: false\n });\n\n if (!gl) {\n this.failUnsupported(new UnsupportedError(\"WebGL is not supported.\"));\n return;\n }\n\n this.currentStatus = \"loading\";\n\n try {\n this.setupDomObservers();\n this.setupContextEvents();\n this.setupProgram(gl);\n this.resize();\n this.textureInputs = new Map(Object.entries(this.options.textures ?? {}));\n await this.loadTextureInputs(gl);\n if (this.destroyed) return;\n this.applyTextureSizeUniforms();\n this.currentStatus = \"ready\";\n this.readyResolve?.();\n this.options.onReady?.(this);\n\n if (this.running || (this.options.autoStart ?? true)) {\n this.start();\n } else if (this.options.renderMode === \"demand\") {\n this.render();\n }\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n private setupProgram(gl: WebGLRenderingContext): void {\n if (this.program) gl.deleteProgram(this.program);\n if (this.buffer) gl.deleteBuffer(this.buffer);\n\n this.program = createProgram(\n gl,\n this.options.vertex ?? defaultVertexShader,\n this.options.fragment\n );\n gl.useProgram(this.program);\n this.buffer = createFullscreenBuffer(gl, this.program);\n this.attribLocation = gl.getAttribLocation(this.program, \"a_position\");\n this.uniformLocations = collectUniformLocations(gl, this.program);\n }\n\n // Re-bind the core's program, fullscreen geometry, textures and uniforms so a\n // draw is correct regardless of GL state changed by onBeforeRender/onAfterRender.\n private prepareDrawState(gl: WebGLRenderingContext): void {\n if (!this.program) return;\n gl.useProgram(this.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n if (this.attribLocation >= 0) {\n gl.enableVertexAttribArray(this.attribLocation);\n gl.vertexAttribPointer(this.attribLocation, 2, gl.FLOAT, false, 0, 0);\n }\n this.applyTextures(gl);\n this.applyCachedUniforms(gl);\n }\n\n private setupDomObservers(): void {\n if (!this.dom) return;\n\n if (this.options.autoResize ?? true) {\n this.resizeObserver = new ResizeObserver(() => {\n this.resize();\n });\n this.resizeObserver.observe(this.dom.target);\n }\n\n if (this.options.pauseWhenOffscreen ?? true) {\n this.intersectionObserver = new IntersectionObserver((entries) => {\n const entry = entries[0];\n this.onscreen = Boolean(entry?.isIntersecting);\n if (!this.onscreen) {\n this.cancelFrame();\n if (this.running) this.currentStatus = \"paused\";\n return;\n }\n\n if (this.running) {\n this.start();\n } else if (this.options.renderMode === \"demand\") {\n this.render();\n }\n });\n this.intersectionObserver.observe(this.dom.target);\n }\n\n const onPointerMove = (event: Event) => {\n if (!this.dom) return;\n const pointerEvent = event as PointerEvent;\n const rect = this.dom.target.getBoundingClientRect();\n const x = pointerEvent.clientX - rect.left;\n const y = pointerEvent.clientY - rect.top;\n this.pointer.x = x * this.pixelRatio;\n this.pointer.y = (rect.height - y) * this.pixelRatio;\n this.pointer.uvX = rect.width > 0 ? x / rect.width : 0;\n this.pointer.uvY = rect.height > 0 ? 1 - y / rect.height : 0;\n this.pointer.active = 1;\n\n if (this.options.renderMode === \"demand\") this.render();\n };\n const onPointerLeave = () => {\n this.pointer.active = 0;\n if (this.options.renderMode === \"demand\") this.render();\n };\n\n this.dom.target.addEventListener(\"pointermove\", onPointerMove);\n this.dom.target.addEventListener(\"pointerenter\", onPointerMove);\n this.dom.target.addEventListener(\"pointerleave\", onPointerLeave);\n this.removeListeners.push(() => {\n this.dom?.target.removeEventListener(\"pointermove\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerenter\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerleave\", onPointerLeave);\n });\n }\n\n private setupContextEvents(): void {\n if (!this.dom) return;\n\n const onLost = (event: Event) => {\n event.preventDefault();\n this.contextRestoredShouldRun = this.running;\n this.cancelFrame();\n this.currentStatus = \"context-lost\";\n this.options.onError?.(new UnsupportedError(\"WebGL context lost.\"));\n };\n\n const onRestored = () => {\n if (!this.dom || this.destroyed) return;\n const gl = this.dom.canvas.getContext(\"webgl\");\n if (!gl) return;\n\n try {\n this.setupProgram(gl);\n this.applyCachedUniforms(gl);\n void this.loadTextureInputs(gl).then(\n () => {\n this.applyTextureSizeUniforms();\n if (this.contextRestoredShouldRun) this.start();\n else this.render();\n },\n (error: unknown) =>\n this.fail(error instanceof Error ? error : new Error(String(error)))\n );\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n };\n\n this.dom.canvas.addEventListener(\"webglcontextlost\", onLost);\n this.dom.canvas.addEventListener(\"webglcontextrestored\", onRestored);\n this.removeListeners.push(() => {\n this.dom?.canvas.removeEventListener(\"webglcontextlost\", onLost);\n this.dom?.canvas.removeEventListener(\"webglcontextrestored\", onRestored);\n });\n }\n\n private scheduleFrame(): void {\n if (this.rafId || this.options.renderMode === \"demand\") return;\n\n this.rafId = requestAnimationFrame((timestamp) => {\n this.rafId = 0;\n if (!this.running || this.destroyed) return;\n\n const seconds = timestamp / 1000;\n const rawDelta = this.lastTimestamp ? seconds - this.lastTimestamp : 0;\n const delta = Math.min(Math.max(rawDelta, 0), MAX_DELTA_SECONDS);\n this.lastTimestamp = seconds;\n this.elapsed += delta;\n this.setBuiltInTime(delta);\n this.render();\n this.scheduleFrame();\n });\n }\n\n private cancelFrame(): void {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n }\n this.lastTimestamp = 0;\n }\n\n private setBuiltInTime(delta: number): void {\n this.uniformCache.set(\"u_time\", { type: \"float\", value: [this.elapsed] });\n this.uniformCache.set(\"u_delta\", { type: \"float\", value: [delta] });\n }\n\n private applyBuiltInUniforms(gl: WebGLRenderingContext): void {\n const builtIns: Record<string, UniformInput> = {\n resolution: [this.width, this.height],\n viewportSize: [this.viewportWidth, this.viewportHeight],\n pixelRatio: this.pixelRatio,\n pointer: [this.pointer.x, this.pointer.y],\n pointerUv: [this.pointer.uvX, this.pointer.uvY],\n pointerActive: this.pointer.active\n };\n\n for (const [name, value] of Object.entries(builtIns)) {\n this.uniformCache.set(toUniformName(name), normalizeUniform(value));\n }\n\n this.applyCachedUniforms(gl);\n }\n\n private applyTextureSizeUniforms(): void {\n for (const texture of this.textures.values()) {\n this.applyTextureSizeUniform(texture);\n }\n }\n\n private applyTextureSizeUniform(texture: LoadedTexture): void {\n const uniform = {\n type: \"vec2\" as const,\n value: [texture.width, texture.height]\n };\n this.uniformCache.set(texture.sizeUniformName, uniform);\n\n const gl = this.dom?.canvas.getContext(\"webgl\");\n const location = this.uniformLocations.get(texture.sizeUniformName);\n if (gl && this.program && location) {\n applyProgramUniform(gl, this.program, location, uniform);\n } else if (this.program) {\n this.warnUnknownUniform(texture.sizeUniformName);\n }\n }\n\n private applyCachedUniforms(gl: WebGLRenderingContext): void {\n for (const [name, uniform] of this.uniformCache) {\n const location = this.uniformLocations.get(name);\n if (!location) {\n this.warnUnknownUniform(name);\n continue;\n }\n applyUniform(gl, location, uniform);\n }\n }\n\n private applyTextures(gl: WebGLRenderingContext): void {\n for (const texture of this.textures.values()) {\n const unit = this.textureUnits.get(texture.name);\n if (unit === undefined) continue;\n const location = this.uniformLocations.get(texture.uniformName);\n if (!location) {\n this.warnUnknownUniform(texture.uniformName);\n continue;\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture.texture);\n gl.uniform1i(location, unit);\n }\n }\n\n private async loadTextureInputs(gl: WebGLRenderingContext): Promise<void> {\n const loadedTextures = new Map<string, LoadedTexture>();\n\n for (const [name, input] of this.textureInputs) {\n if (this.destroyed) break;\n const unit = this.resolveTextureUnit(gl, name);\n loadedTextures.set(name, await loadTexture(gl, name, input, unit));\n }\n\n for (const texture of this.textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n this.textures = loadedTextures;\n }\n\n private resolveTextureUnit(gl: WebGLRenderingContext, name: string): number {\n const existing = this.textureUnits.get(name);\n if (existing !== undefined) return existing;\n\n const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) as number;\n\n for (let unit = 0; unit < maxUnits; unit += 1) {\n if (![...this.textureUnits.values()].includes(unit)) {\n this.textureUnits.set(name, unit);\n return unit;\n }\n }\n\n throw new TextureLoadError(\n `Texture unit limit exceeded while loading texture: ${name}`\n );\n }\n\n private createRenderState(\n gl: WebGLRenderingContext\n ): RenderState<TUniforms> {\n return {\n instance: this,\n gl,\n canvas: this.dom!.canvas,\n time: this.elapsed,\n delta: this.uniformCache.get(\"u_delta\")?.value[0] ?? 0,\n frame: this.frame,\n width: this.width,\n height: this.height,\n viewportWidth: this.viewportWidth,\n viewportHeight: this.viewportHeight,\n pixelRatio: this.pixelRatio\n };\n }\n\n private warnUnknownUniform(name: string): void {\n if (!this.options.debug || this.warnedUniforms.has(name)) return;\n this.warnedUniforms.add(name);\n console.warn(`[frapx/shader] Uniform not found or optimized out: ${name}`);\n }\n\n private failUnsupported(error: Error): void {\n this.currentStatus = \"unsupported\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n private fail(error: Error): void {\n this.currentStatus = \"error\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n private debugWarn(message: string): void {\n if (this.options.debug) {\n console.warn(`[frapx/shader] ${message}`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|