diff --git a/README.md b/README.md index edc6281b..c35dc5d9 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ GPU.js automatically transpiles simple JavaScript functions into shader language In case a GPU is not available, the functions will still run in regular JavaScript. For some more quick concepts, see [Quick Concepts](https://github.com/gpujs/gpu.js/wiki/Quick-Concepts) on the wiki. +**New to GPU programming?** [**Learn GPGPU in your browser**](https://gpu.rocks/learn) — a free, hands-on course that teaches the subject itself, not just this library. See [Learn GPGPU](#learn-gpgpu) below. + [![CI](https://github.com/gpujs/gpu.js/actions/workflows/ci.yml/badge.svg)](https://github.com/gpujs/gpu.js/actions/workflows/ci.yml) [![BrowserStack](https://automate.browserstack.com/badge.svg?badge_key=RHFnb0dPTWdmUlZKRFdMb3lZWFdGSDcwU1dEL0tGZC9HT21BVVJPeGZ1az0tLW43V3JMeGtjdjlhWHlpZ2dZRk5ZclE9PQ%3D%3D--a13f87b6ab74da0caa0381873de301faed81c914)](https://automate.browserstack.com/public-build/RHFnb0dPTWdmUlZKRFdMb3lZWFdGSDcwU1dEL0tGZC9HT21BVVJPeGZ1az0tLW43V3JMeGtjdjlhWHlpZ2dZRk5ZclE9PQ%3D%3D--a13f87b6ab74da0caa0381873de301faed81c914) @@ -15,7 +17,7 @@ For some more quick concepts, see [Quick Concepts](https://github.com/gpujs/gpu. Creates a GPU accelerated kernel transpiled from a javascript function that computes a single element in the 512 x 512 matrix (2D array). The kernel functions are ran in tandem on the GPU often resulting in very fast computations! -You can run a benchmark of this [here](http://gpu.rocks). Typically, it will run 1-15x faster depending on your hardware. +You can run a benchmark of this [here](https://gpu.rocks/). Typically, it will run 1-15x faster depending on your hardware. Matrix multiplication (perform matrix multiplication on 2 matrices of size 512 x 512) written in GPU.js: ## Browser @@ -74,11 +76,64 @@ const c = multiplyMatrix(a, b) as number[][]; [Click here](/examples) for more typescript examples. +## v3 Will Be Async by Default + +> [!WARNING] +> **The next major version of GPU.js will make every kernel call return a `Promise`.** This is a breaking API change: synchronous kernel calls as you write them today will not survive the v3 upgrade unchanged. Code written against `mode: 'async'` (new in 2.20.0) already conforms and will run on v3 unchanged — the [migration guide](#migrating-a-sync-kernel-to-async) below is five steps. + +This breaks the API you are using today, so it warrants both notice and an apology. We owe you the apology because the original synchronous design was not forward-thinking, and we should have started async in the first place. A GPU is an asynchronous device: you hand it work, and the results are ready later. WebGL let this library pretend otherwise — `readPixels` silently freezes the page until the GPU catches up, and we built our API on that pretense because it made the first example look like an ordinary function call. The cost has been paid by every user since: every kernel readback blocks the main thread for its full duration (measurably ~96% of a readback-heavy loop frozen, in one stall as long as the whole loop), and WebGPU — which has no synchronous readback at all, correctly — cannot be offered under the synchronous contract except as a walled-off special mode. An async-first API would have cost one `await` in the examples and none of this debt. + +v3 corrects the mistake: async everywhere, one contract, every backend. The WebGL backends keep a synchronous escape hatch (`setAsyncMode(false)`) through the migration; WebGPU can never offer one. + +### Why WebGPU is worth breaking the API for + +Async-by-default is not an aesthetic preference — it is the price of making WebGPU a first-class backend instead of a walled-off special mode, and WebGPU earns that price twice over. + +**Performance.** Measured on the same kernels, same machine (Apple M1 Max), against our own WebGL2 backend at its best: + +* 1024×1024 matrix multiplication including readback: **3× faster** (6.3 ms vs 18.5 ms; 370× vs the CPU). +* A three-kernel pipeline chain, end to end: **4× faster** (9.0 ms vs 36.6 ms) — readback, WebGL's most expensive step, is dramatically cheaper. +* And the readback that remains no longer freezes the page: it happens off the main thread by construction, not as a 100 ms stall the UI must absorb. + +**Accuracy.** This one matters more than the speed. Every GPU backend before WebGPU computes by pretending a fragment shader is a compute unit, and this library carries years of scar tissue from that pretense — workarounds you may be relying on without knowing it: + +* **No more lossy packing.** In `precision: 'unsigned'` mode, every float in and out of a kernel is encoded into an 8-bit-per-channel RGBA pixel and decoded on the far side — a quantizing round-trip. WebGPU kernels read and write raw IEEE-754 `f32` storage buffers; there is no encode step to lose bits in. +* **Integer math that is actually integer.** GLSL fragment shaders forced float emulation of integers — the `fixIntegerDivisionAccuracy` setting exists because some GPUs return `2.999…` for `9/3` and this library has to patch around them card by card. WGSL has true 32-bit integers with exact division. No setting, no patch, correct by construction. +* **Exact addressing.** Fragment-shader kernels locate your data by float texture-coordinate arithmetic, which is where a whole family of large-array off-by-one bugs has historically lived. A WGSL kernel indexes its buffer with an integer thread id — `data[i]` means element `i`, at any size. +* **A smaller surface for driver bugs.** GLSL from this library is recompiled by whatever shader stack each machine ships — an eight-year-old wrong-results bug on Windows (#300) traced to Microsoft's `d3dcompiler_47.dll` miscompiling a nested texture read, and it was invisible on every other platform. WGSL is a smaller, more rigorously specified language with a conformance-tested compilation path; entire categories of that risk simply do not apply to compute shaders reading storage buffers. + +The synchronous API is the only thing standing between users and those improvements being the default. That is why it goes. + +### Migrating a sync kernel to async + +The v3 contract is available today — opt in with `mode: 'async'` (or `asyncMode: true` per kernel) and your code is already v3-shaped: + +```js +// v2 (sync) +const gpu = new GPU(); +const kernel = gpu.createKernel(fn).setOutput([512, 512]); +const result = kernel(a, b); + +// v3 (async) — works today with { mode: 'async' } +const gpu = new GPU({ mode: 'async' }); +const kernel = gpu.createKernel(fn).setOutput([512, 512]); +const result = await kernel(a, b); +``` + +1. **`await` every kernel call.** The resolved value has exactly the shape the sync call returned — nothing else about your code changes. Callers become `async` functions; at the top level, wrap in an async IIFE or use top-level `await`. +2. **Sequential loops just gain the `await`:** `for (…) { total = await step(total); }` — iteration order and semantics are unchanged. +3. **Pipeline results: `await result.toArray()`.** `await` is harmless on the synchronous backends' textures, so this form is portable across all backends today. +4. **Chains of kernels: keep `pipeline: true` and await only the end.** Handles pass between kernels without readback, exactly as before; you pay one `await` at the final readback instead of a main-thread stall at every stage. +5. **Library authors:** return the Promise; don't resolve it on your callers' behalf. Code written against `mode: 'async'` in v2 will run unchanged on v3. + # Table of Contents Notice documentation is off? We do try our hardest, but if you find something, [please bring it to our attention](https://github.com/gpujs/gpu.js/issues), or _[become a contributor](#contributors)_! +* [v3 Will Be Async by Default](#v3-will-be-async-by-default) +* [Learn GPGPU](#learn-gpgpu) +* [Supported Backends](#supported-backends) * [Demos](#demos) * [Installation](#installation) * [`GPU` Settings](#gpu-settings) @@ -108,6 +163,8 @@ Notice documentation is off? We do try our hardest, but if you find something, * [Typescript Typings](#typescript-typings) * [Destructured Assignments](#destructured-assignments-new-in-v2) * [Dealing With Transpilation](#dealing-with-transpilation) +* [WebGPU](#webgpu) +* [Asynchronous Kernels](#asynchronous-kernels) * [Full API reference](#full-api-reference) * [How possible in node](#how-possible-in-node) * [Testing](#testing) @@ -117,6 +174,36 @@ Notice documentation is off? We do try our hardest, but if you find something, * [Terms Explained](#terms-explained) * [License](#license) +## Learn GPGPU + +**[Learn GPGPU in your browser](https://gpu.rocks/learn)** — a free, hands-on course built on GPU.js. Fifteen lessons across three modules, roughly ten hours, with no toolchain to install: you write real kernels in the page and run them on your own GPU, with the results in front of you. + +The point worth making is that **it teaches GPGPU, not just this library**. GPU.js is the vehicle, chosen because JavaScript in a browser is the shortest path from "no setup" to "code running on your GPU" — but what you take away is the subject itself, and it transfers: + +* **The mental model is universal.** A kernel is one function run across a grid of threads; `this.thread` is CUDA's `threadIdx`/`blockIdx`, WGSL's `global_invocation_id`, and OpenCL's `get_global_id()` wearing different clothes. Once you think in kernels, the syntax is a detail. +* **The hard-won lessons are hardware lessons, not API lessons.** Why moving data usually costs more than computing on it, why keeping intermediate results on the device (pipelining) changes everything, why a parallel reduction is shaped the way it is, why float precision bites, and how to measure a GPU honestly instead of timing an unsynchronized queue — every one of those is as true in CUDA or Metal as it is here. +* **The algorithms are the canonical ones.** Matrix multiply, reductions, convolution, Monte Carlo, N-body, cellular automata, reaction–diffusion, ray marching — the same worked examples you meet in any GPU course, just without a two-hour install first. + +| module | lessons | +|---|---| +| **1 — Fundamentals** | Hello, Kernel · Data In, Data Out · Thinking in Parallel · Pipelines & Textures · Measuring Speed Honestly | +| **2 — Real algorithms** | Matrix Multiply · Reductions · Convolution & Filters · Monte Carlo Methods · N-Body Gravity | +| **3 — Graphics** | Pixels from Scratch · Escape-Time Fractals · Cellular Automata · Reaction–Diffusion · Ray-Marched Metaballs | + +Start at [Hello, Kernel](https://gpu.rocks/learn/1-1) — if you can write a JavaScript `for` loop, you have the prerequisites. + +## Supported Backends + +Representative performance factor: 1024×1024 matrix multiplication including readback, versus the CPU backend on the same machine (Apple M1 Max, Chromium; your hardware will vary — run `node scripts/benchmark-webgpu.mjs` for yours). + +| Backend | Environment | Technology | Perf factor | Notes | +|---|---|---|---|---| +| `webgpu` **New in 2.20.0!** | Browser | WGSL compute shaders | **~370×** | Async API; opt-in via `mode: 'webgpu'` or automatic via `mode: 'async'` | +| `webgl2` | Browser | GLSL ES 3.00 fragment shaders | ~127× | The default browser backend. 2.20.0 renders scalar single-precision kernels to `R32F` and reads back one float per value where the driver allows | +| `webgl` | Browser | GLSL ES 1.00 fragment shaders | ~87× | Fallback for older browsers | +| `headlessgl` | Node | GLSL ES 1.00 via ANGLE | ~123× | The default Node backend | +| `cpu` | Anywhere | Plain JavaScript | 1× | Guaranteed fallback; also the reference for correctness | + ## Demos GPU.js in the wild, all around the net. Add yours here! * [Temperature interpolation using GPU.js](https://observablehq.com/@rveciana/temperature-interpolation-using-gpu-js) @@ -147,7 +234,7 @@ GPU.js in the wild, all around the net. Add yours here! * [Animated parallel raytracer in TypeScript and GPU.js](https://raytracer.crypt.sg) * [Bilinear interpolation on an image](https://jsfiddle.net/shadowwarriorpro/tndphL1f/) -More examples with screenshots: [gpu.rocks examples gallery](https://gpu.rocks/#/examples) +More examples with screenshots: [gpu.rocks examples gallery](https://gpu.rocks/examples) ### Community projects Libraries and tools built on GPU.js: @@ -206,6 +293,15 @@ Settings are an object used to create an instance of `GPU`. Example: `new GPU(s * 'webgl2': Use the `WebGL2Kernel` for transpiling a kernel * 'headlessgl' **New in V2!**: Use the `HeadlessGLKernel` for transpiling a kernel * 'cpu': Use the `CPUKernel` for transpiling a kernel + * 'webgpu' **New!**: Use the `WebGPUKernel` — kernels compile to WGSL compute shaders over storage buffers. Explicit opt-in only, never auto-selected, because every kernel call returns a `Promise` of its result (WebGPU readback is inherently asynchronous). Check `GPU.isWebGPUSupported` (synchronous, `navigator.gpu` presence) or `await GPU.isWebGPUAvailable()` (requests an actual adapter). + * 'async' **New!**: Auto-selection under the Promise contract. Picks the best available backend (webgl2 → webgl → cpu), turns `asyncMode` on for every kernel, and upgrades a kernel to webgpu on its first call if an adapter answers — falling back to the proven backend if the upgraded kernel cannot handle it. Write `await kernel(...)` once and the same code runs everywhere: + ```js + const gpu = new GPU({ mode: 'async' }); + const kernel = gpu.createKernel(function(a) { + return a[this.thread.x] * 2; + }).setOutput([64]); + const result = await kernel(myArray); // webgpu, webgl2 or cpu underneath + ``` * `onIstanbulCoverageVariable`: Removed in v2.11.0, use v8 coverage * `removeIstanbulCoverage`: Removed in v2.11.0, use v8 coverage @@ -224,6 +320,7 @@ Settings are an object used to create a `kernel` or `kernelMap`. Example: `gpu. ```js kernel(texture); ``` +* `asyncMode` or `kernel.setAsyncMode(boolean)` **New!**: boolean, default = `false` - every call to the kernel returns a `Promise` of the usual result. On `webgl2` the readback goes through a pixel-pack buffer and a fence, so the main thread stays free while the GPU works (a synchronous kernel call blocks it for the whole readback); on `webgpu` kernels are always asynchronous; the other backends resolve their synchronous result so the calling contract is uniform everywhere. Adds a small per-readback latency on webgl2 (fence completion granularity) in exchange for the unblocked main thread — pipeline intermediate kernels and await only final results where that matters. See `mode: 'async'` for automatic backend selection under this contract. * `graphical` or `kernel.setGraphical(boolean)`: boolean, default = `false` * `loopMaxIterations` or `kernel.setLoopMaxIterations(number)`: number, default = 1000 * `constants` or `kernel.setConstants(object)`: object, default = null @@ -1188,6 +1285,66 @@ Here is a list of a few things that GPU.js does to fix transpilation: * When a transpiler such as [Babel](https://babeljs.io/) changes `myCall()` to `(0, _myCall.myCall)`, it is gracefully handled. +## WebGPU + +**New in 2.20.0!** + +WebGPU is what this library always wanted underneath: real compute shaders over real buffers. Every other GPU backend here works by drawing a full-screen quad and abusing a fragment shader as a compute unit — values packed into texture pixels on the way in, unpacked on the way out. The WebGPU backend compiles your kernel to a WGSL compute shader reading and writing `f32` storage buffers directly, and it shows: on an Apple M1 Max, a 1024×1024 matrix multiplication including readback runs about **3× faster than the WebGL2 backend** and 370× faster than the CPU. + +Because WebGPU has no synchronous readback (correctly — see [v3 Will Be Async by Default](#v3-will-be-async-by-default)), kernel calls in this mode return a `Promise` of the usual result: + +```js +const gpu = new GPU({ mode: 'webgpu' }); +const kernel = gpu.createKernel(function(a, b) { + let sum = 0; + for (let i = 0; i < 512; i++) { + sum += a[this.thread.y][i] * b[i][this.thread.x]; + } + return sum; +}).setOutput([512, 512]); + +const c = await kernel(a, b); // same result shapes as every other backend +``` + +Feature detection is two-tier, because `navigator.gpu` can exist on a machine with no usable adapter: + +```js +GPU.isWebGPUSupported; // sync: the API surface exists +await GPU.isWebGPUAvailable(); // async: an adapter actually answered +``` + +`pipeline: true` resolves to a GPU-resident buffer handle that passes straight into downstream kernels with no readback, and `await handle.toArray()` reads it back when you want the values. Large 1D outputs dispatch past the 65,535-workgroup limit automatically. + +The mode is explicit opt-in and is never auto-selected — a synchronous caller handed a Promise would fail in silent, confusing ways. If you want automatic selection, that is exactly what [`mode: 'async'`](#asynchronous-kernels) is for. Not yet supported (each throws a clear error): kernel maps, `graphical`, `toString()`, `precision: 'unsigned'`, `Math.random`. + +## Asynchronous Kernels + +**New in 2.20.0!** + +Async is a property any kernel can have, on any backend. `asyncMode: true` (or `kernel.setAsyncMode(true)`) makes every call return a `Promise` of the usual result: + +```js +const kernel = gpu.createKernel(fn, { output: [64], asyncMode: true }); +const result = await kernel(myArray); +``` + +What that buys depends on the backend, but the contract never changes: + +* **webgl2** — the readback becomes genuinely non-blocking: results are read through a pixel-pack buffer behind a GPU fence, and the main thread keeps running while the GPU works. In a readback-heavy loop that froze the page for 105 ms straight, the same loop under `asyncMode` never stalls the main thread longer than 5 ms (measure yours: `node scripts/benchmark-async.mjs`). The trade is a few milliseconds of added latency per readback, so pipeline intermediate kernels and await only final results where throughput matters. +* **webgpu** — kernels are natively asynchronous; `asyncMode` is always on. +* **cpu, webgl, headlessgl** — the synchronous result is resolved, so the calling contract stays uniform and your code stays portable. + +`mode: 'async'` puts the whole `GPU` instance under this contract and picks the backend for you — the best synchronously-provable one immediately (webgl2 → webgl → cpu), upgraded to WebGPU on a kernel's first call if an adapter actually answers. The Promise contract is exactly what buys the room for that probe. A kernel the WebGPU backend cannot take yet (a kernel map, say) simply stays on the proven backend: + +```js +const gpu = new GPU({ mode: 'async' }); +const kernel = gpu.createKernel(function(a) { + return a[this.thread.x] * 2; +}).setOutput([64]); + +const result = await kernel(myArray); // webgpu, webgl2 or cpu underneath — same code +``` + ## Full API Reference You can find a [complete API reference here](https://gpu.rocks/api/). diff --git a/dist/gpu-browser-core.js b/dist/gpu-browser-core.js index ab2ed017..b21ab7bd 100644 --- a/dist/gpu-browser-core.js +++ b/dist/gpu-browser-core.js @@ -1,11 +1,11 @@ /** * gpu.js - * http://gpu.rocks/ + * https://gpu.rocks/ * * GPU Accelerated JavaScript * * @version 2.19.9 - * @date Wed Jul 29 2026 05:05:56 GMT+0800 (Singapore Standard Time) + * @date Thu Jul 30 2026 13:21:38 GMT+0800 (Singapore Standard Time) * * @license MIT * The MIT License @@ -347,6 +347,25 @@ isArray(array) { return !isNaN(array.length); }, + typeFitsValue(type, value) { + if (typeof type !== "string" || value === null || value === void 0) return true; + if (value.type) return true; + switch (type) { + case "Input": + return value instanceof Input; + + case "Boolean": + return typeof value === "boolean"; + + case "Number": + case "Integer": + case "Float": + return typeof value === "number"; + } + if (type.indexOf("Texture") !== -1) return Boolean(value.type); + if (type.indexOf("Array") === 0) return utils.isArray(value); + return true; + }, getVariableType(value, strictIntegers) { if (utils.isArray(value)) { if (value.length > 0 && value[0].nodeName === "IMG") return "HTMLImageArray"; @@ -1016,7 +1035,7 @@ utils: utils }; }); - var require_kernel$5 = __commonJSMin((exports, module) => { + var require_kernel$6 = __commonJSMin((exports, module) => { const {utils: utils} = require_utils(); const {Input: Input} = require_input(); var Kernel = class { @@ -1049,6 +1068,7 @@ this.useLegacyEncoder = false; this.fallbackRequested = false; this.onRequestFallback = null; + this.onRequestSwitchKernel = null; this.argumentNames = typeof source === "string" ? utils.getArgumentNamesFromString(source) : null; this.argumentTypes = null; this.argumentSizes = null; @@ -1077,6 +1097,7 @@ this.validate = true; this.immutable = false; this.pipeline = false; + this.asyncMode = false; this.precision = null; this.tactic = null; this.plugins = null; @@ -1089,6 +1110,7 @@ this.randomSeed = null; this.built = false; this.signature = null; + this.switchingKernels = null; } mergeSettings(settings) { for (let p in settings) { @@ -1256,6 +1278,10 @@ this.pipeline = flag; return this; } + setAsyncMode(flag) { + this.asyncMode = flag; + return this; + } setPrecision(flag) { this.precision = flag; return this; @@ -1415,11 +1441,11 @@ case "Integer": case "Float": case "ArrayTexture(1)": - argumentTypes[i] = utils.getVariableType(arg); + argumentTypes[i] = utils.getVariableType(arg, kernel.strictIntegers); break; default: - argumentTypes[i] = type; + argumentTypes[i] = utils.typeFitsValue(type, arg) ? type : utils.getVariableType(arg, kernel.strictIntegers); } } return argumentTypes; @@ -1440,6 +1466,23 @@ }; } onActivate(previousKernel) {} + switchKernels(reason) { + if (this.switchingKernels) this.switchingKernels.push(reason); else this.switchingKernels = [ reason ]; + } + resetSwitchingKernels() { + const existingValue = this.switchingKernels; + this.switchingKernels = null; + return existingValue; + } + checkArgumentTypes(args) { + if (!this.argumentTypes) return; + const length = Math.min(args.length, this.argumentTypes.length); + for (let i = 0; i < length; i++) if (!utils.typeFitsValue(this.argumentTypes[i], args[i])) this.switchKernels({ + type: "argumentTypeMismatch", + index: i, + needed: utils.getVariableType(args[i], this.strictIntegers) + }); + } }; function splitArgumentTypes(argumentTypesObject) { const argumentNames = Object.keys(argumentTypesObject); @@ -2091,7 +2134,7 @@ FunctionTracer: FunctionTracer }; }); - var require_function_node$3 = __commonJSMin((exports, module) => { + var require_function_node$4 = __commonJSMin((exports, module) => { const acorn = require_empty_module(); const {utils: utils} = require_utils(); const {FunctionTracer: FunctionTracer} = require_function_tracer(); @@ -3151,8 +3194,8 @@ FunctionNode: FunctionNode }; }); - var require_function_node$2 = __commonJSMin((exports, module) => { - const {FunctionNode: FunctionNode} = require_function_node$3(); + var require_function_node$3 = __commonJSMin((exports, module) => { + const {FunctionNode: FunctionNode} = require_function_node$4(); var CPUFunctionNode = class extends FunctionNode { astFunction(ast, retArr) { if (!this.isRootKernel) { @@ -3683,10 +3726,10 @@ cpuKernelString: cpuKernelString }; }); - var require_kernel$4 = __commonJSMin((exports, module) => { - const {Kernel: Kernel} = require_kernel$5(); + var require_kernel$5 = __commonJSMin((exports, module) => { + const {Kernel: Kernel} = require_kernel$6(); const {FunctionBuilder: FunctionBuilder} = require_function_builder(); - const {CPUFunctionNode: CPUFunctionNode} = require_function_node$2(); + const {CPUFunctionNode: CPUFunctionNode} = require_function_node$3(); const {utils: utils} = require_utils(); const {cpuKernelString: cpuKernelString} = require_kernel_string$1(); var CPUKernel = class extends Kernel { @@ -4496,8 +4539,8 @@ GLTextureGraphical: GLTextureGraphical }; }); - var require_kernel$3 = __commonJSMin((exports, module) => { - const {Kernel: Kernel} = require_kernel$5(); + var require_kernel$4 = __commonJSMin((exports, module) => { + const {Kernel: Kernel} = require_kernel$6(); const {utils: utils} = require_utils(); const {GLTextureArray2Float: GLTextureArray2Float} = require_array_2_float(); const {GLTextureArray2Float2D: GLTextureArray2Float2D} = require_array_2_float_2d(); @@ -5151,11 +5194,6 @@ if (this.immutable) for (let i = 0; i < this.subKernels.length; i++) result[this.subKernels[i].property] = this.mappedTextures[i].clone(); else for (let i = 0; i < this.subKernels.length; i++) result[this.subKernels[i].property] = this.mappedTextures[i]; return result; } - resetSwitchingKernels() { - const existingValue = this.switchingKernels; - this.switchingKernels = null; - return existingValue; - } setOutput(output) { const newOutput = this.toKernelOutput(output); if (this.program) { @@ -5204,9 +5242,6 @@ renderValues() { return this.formatValues(this.transferValues(), this.output[0], this.output[1], this.output[2]); } - switchKernels(reason) { - if (this.switchingKernels) this.switchingKernels.push(reason); else this.switchingKernels = [ reason ]; - } getVariablePrecisionString(textureSize = this.texSize, tactic = this.tactic, isInt = false) { if (!tactic) { if (!this.constructor.features.isSpeedTacticSupported) return "highp"; @@ -5284,9 +5319,9 @@ GLKernel: GLKernel }; }); - var require_function_node$1 = __commonJSMin((exports, module) => { + var require_function_node$2 = __commonJSMin((exports, module) => { const {utils: utils} = require_utils(); - const {FunctionNode: FunctionNode} = require_function_node$3(); + const {FunctionNode: FunctionNode} = require_function_node$4(); var WebGLFunctionNode = class extends FunctionNode { constructor(source, settings) { super(source, settings); @@ -8882,6 +8917,7 @@ if (!precision) throw new Error("precision missing"); if (value.type) type = value.type; const types = kernelValueMaps[precision][dynamic]; + if (type === "WebGPUBuffer") throw new Error("this kernel runs on WebGL but received a WebGPU pipeline buffer; await handle.toArray() first, or give this kernel the async contract (asyncMode: true / mode: 'async') so the readback happens for you"); if (types[type] === false) return null; else if (types[type] === void 0) throw new Error(`Could not find a KernelValue for ${type}`); return types[type]; } @@ -8890,10 +8926,10 @@ kernelValueMaps: kernelValueMaps }; }); - var require_kernel$2 = __commonJSMin((exports, module) => { - const {GLKernel: GLKernel} = require_kernel$3(); + var require_kernel$3 = __commonJSMin((exports, module) => { + const {GLKernel: GLKernel} = require_kernel$4(); const {FunctionBuilder: FunctionBuilder} = require_function_builder(); - const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$1(); + const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$2(); const {utils: utils} = require_utils(); const mrud = require_math_random_uniformly_distributed(); const {fragmentShader: fragmentShader} = require_fragment_shader$1(); @@ -9840,9 +9876,9 @@ WebGLKernel: WebGLKernel }; }); - var require_kernel$1 = __commonJSMin((exports, module) => { + var require_kernel$2 = __commonJSMin((exports, module) => { const getContext = require_empty_module(); - const {WebGLKernel: WebGLKernel} = require_kernel$2(); + const {WebGLKernel: WebGLKernel} = require_kernel$3(); const {glKernelString: glKernelString} = require_kernel_string(); let isSupported = null; let testCanvas = null; @@ -9954,9 +9990,9 @@ HeadlessGLKernel: HeadlessGLKernel }; }); - var require_function_node = __commonJSMin((exports, module) => { + var require_function_node$1 = __commonJSMin((exports, module) => { const {utils: utils} = require_utils(); - const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$1(); + const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$2(); var WebGL2FunctionNode = class extends WebGLFunctionNode { astIdentifierExpression(idtNode, retArr) { if (idtNode.type !== "Identifier") throw this.astErrorOutput("IdentifierExpression - not an Identifier", idtNode); @@ -10629,6 +10665,7 @@ if (!precision) throw new Error("precision missing"); if (value.type) type = value.type; const types = kernelValueMaps[precision][dynamic]; + if (type === "WebGPUBuffer") throw new Error("this kernel runs on WebGL but received a WebGPU pipeline buffer; await handle.toArray() first, or give this kernel the async contract (asyncMode: true / mode: 'async') so the readback happens for you"); if (types[type] === false) return null; else if (types[type] === void 0) throw new Error(`Could not find a KernelValue for ${type}`); return types[type]; } @@ -10637,9 +10674,9 @@ lookupKernelValueType: lookupKernelValueType }; }); - var require_kernel = __commonJSMin((exports, module) => { - const {WebGLKernel: WebGLKernel} = require_kernel$2(); - const {WebGL2FunctionNode: WebGL2FunctionNode} = require_function_node(); + var require_kernel$1 = __commonJSMin((exports, module) => { + const {WebGLKernel: WebGLKernel} = require_kernel$3(); + const {WebGL2FunctionNode: WebGL2FunctionNode} = require_function_node$1(); const {FunctionBuilder: FunctionBuilder} = require_function_builder(); const {utils: utils} = require_utils(); const {fragmentShader: fragmentShader} = require_fragment_shader(); @@ -10821,6 +10858,76 @@ gl.readPixels(0, 0, w, h, gl.RED, gl.FLOAT, result); return result; } + renderOutputAsync() { + if (this.renderOutput !== this.renderValues) return Promise.resolve(this.renderOutput()); + return this.renderValuesAsync(); + } + renderValuesAsync() { + if (this._tightRead === void 0) this._detectTightRead(); + const formatValues = this.formatValues; + const [x, y, z] = this.output; + return this.transferValuesAsync().then(pixels => formatValues(pixels, x, y, z)); + } + transferValuesAsync() { + const {texSize: texSize, context: gl} = this; + const w = texSize[0]; + const h = texSize[1]; + let format, type, result; + if (this.precision === "single") { + format = this._tightRead ? gl.RED : gl.RGBA; + type = gl.FLOAT; + result = new Float32Array(w * h * (this._tightRead ? 1 : 4)); + } else { + format = gl.RGBA; + type = gl.UNSIGNED_BYTE; + result = new Uint8Array(w * h * 4); + } + const pbo = gl.createBuffer(); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo); + gl.bufferData(gl.PIXEL_PACK_BUFFER, result.byteLength, gl.STREAM_READ); + gl.readPixels(0, 0, w, h, format, type, 0); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); + const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0); + gl.flush(); + return this._pollFence(sync).then(() => { + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo); + gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, result); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); + gl.deleteBuffer(pbo); + return this.precision === "single" ? result : new Float32Array(result.buffer); + }, error => { + gl.deleteBuffer(pbo); + throw error; + }); + } + _pollFence(sync) { + const gl = this.context; + return new Promise((resolve, reject) => { + let schedule; + let channel = null; + if (typeof MessageChannel !== "undefined") { + channel = new MessageChannel; + channel.port1.onmessage = () => poll(); + schedule = () => channel.port2.postMessage(0); + } else schedule = () => setTimeout(poll, 0); + const settle = (fn, value) => { + gl.deleteSync(sync); + if (channel) { + channel.port1.close(); + channel.port2.close(); + } + fn(value); + }; + const poll = () => { + if (gl.isContextLost()) return settle(reject, new Error("WebGL context lost while awaiting kernel result")); + const status = gl.clientWaitSync(sync, 0, 0); + if (status === gl.ALREADY_SIGNALED || status === gl.CONDITION_SATISFIED) return settle(resolve); + if (status === gl.WAIT_FAILED) return settle(reject, new Error("clientWaitSync failed while awaiting kernel result")); + schedule(); + }; + poll(); + }); + } _detectTightRead() { const gl = this.context; this._tightRead = false; @@ -11053,181 +11160,2302 @@ WebGL2Kernel: WebGL2Kernel }; }); - var require_kernel_run_shortcut = __commonJSMin((exports, module) => { - const {utils: utils} = require_utils(); - function kernelRunShortcut(kernel) { - let run = function() { - kernel.build.apply(kernel, arguments); - run = function() { - let result = kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - const reasons = kernel.resetSwitchingKernels(); - const newKernel = kernel.onRequestSwitchKernel(reasons, arguments, kernel); - shortcut.kernel = kernel = newKernel; - result = newKernel.run.apply(newKernel, arguments); - } - if (kernel.renderKernels) return kernel.renderKernels(); else if (kernel.renderOutput) return kernel.renderOutput(); else return result; - }; - return run.apply(kernel, arguments); - }; - const shortcut = function() { - return run.apply(kernel, arguments); - }; - shortcut.exec = function() { - return new Promise((accept, reject) => { - try { - accept(run.apply(this, arguments)); - } catch (e) { - reject(e); - } - }); - }; - shortcut.replaceKernel = function(replacementKernel) { - kernel = replacementKernel; - bindKernelToShortcut(kernel, shortcut); - }; - bindKernelToShortcut(kernel, shortcut); - return shortcut; - } - function bindKernelToShortcut(kernel, shortcut) { - if (shortcut.kernel) { - shortcut.kernel = kernel; - return; - } - const properties = utils.allPropertiesOf(kernel); - for (let i = 0; i < properties.length; i++) { - const property = properties[i]; - if (property[0] === "_" && property[1] === "_") continue; - if (typeof kernel[property] === "function") if (property.substring(0, 3) === "add" || property.substring(0, 3) === "set") shortcut[property] = function() { - shortcut.kernel[property].apply(shortcut.kernel, arguments); - return shortcut; - }; else shortcut[property] = function() { - return shortcut.kernel[property].apply(shortcut.kernel, arguments); - }; else { - shortcut.__defineGetter__(property, () => shortcut.kernel[property]); - shortcut.__defineSetter__(property, value => { - shortcut.kernel[property] = value; - }); - } - } - shortcut.kernel = kernel; - } - module.exports = { - kernelRunShortcut: kernelRunShortcut - }; - }); - var require_gpu = __commonJSMin((exports, module) => { - const {gpuMock: gpuMock} = require_gpu_mock_js(); + var require_function_node = __commonJSMin((exports, module) => { const {utils: utils} = require_utils(); - const {Kernel: Kernel} = require_kernel$5(); - const {CPUKernel: CPUKernel} = require_kernel$4(); - const {HeadlessGLKernel: HeadlessGLKernel} = require_kernel$1(); - const {WebGL2Kernel: WebGL2Kernel} = require_kernel(); - const {WebGLKernel: WebGLKernel} = require_kernel$2(); - const {kernelRunShortcut: kernelRunShortcut} = require_kernel_run_shortcut(); - const kernelOrder = [ HeadlessGLKernel, WebGL2Kernel, WebGLKernel ]; - const kernelTypes = [ "gpu", "cpu" ]; - const internalKernels = { - headlessgl: HeadlessGLKernel, - webgl2: WebGL2Kernel, - webgl: WebGLKernel - }; - let validate = true; - var GPU = class { - static disableValidation() { - validate = false; - } - static enableValidation() { - validate = true; - } - static get isGPUSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported); - } - static get isKernelMapSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap); - } - static get isOffscreenCanvasSupported() { - return typeof Worker !== "undefined" && typeof OffscreenCanvas !== "undefined" || typeof importScripts !== "undefined"; - } - static get isWebGLSupported() { - return WebGLKernel.isSupported; - } - static get isWebGL2Supported() { - return WebGL2Kernel.isSupported; + const {FunctionNode: FunctionNode} = require_function_node$4(); + var WGSLFunctionNode = class extends FunctionNode { + wgslFloat(value) { + if (value === Infinity) return "0x1.fffffep+127"; + if (value === -Infinity) return "-0x1.fffffep+127"; + if (value > 34028234663852886e22) return "0x1.fffffep+127"; + if (value < -34028234663852886e22) return "-0x1.fffffep+127"; + const str = `${value}`; + if (str.indexOf(".") !== -1 || str.indexOf("e") !== -1 || str.indexOf("E") !== -1) return str; + return `${str}.0`; + } + wgslInt(value) { + return `${Math.round(value)}`; + } + mangleFunctionName(name) { + if (reservedNames.indexOf(name) !== -1) return `fn_${name}`; + return utils.sanitizeName(name); } - static get isHeadlessGLSupported() { - return HeadlessGLKernel.isSupported; - } - static get isCanvasSupported() { - return typeof HTMLCanvasElement !== "undefined"; + getLookupType(type) { + if (type === "WebGPUBuffer") return "Number"; + return super.getLookupType(type); } - static get isGPUHTMLImageArraySupported() { - return WebGL2Kernel.isSupported; + astUpdateExpression(uNode, retArr) { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + return retArr; } - static get isSinglePrecisionSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); + getType(ast) { + if (ast && ast.type === "ConditionalExpression") { + const consequentType = this.getType(ast.consequent); + if (consequentType === "Integer" || consequentType === "LiteralInteger") { + const alternateType = this.getType(ast.alternate); + if (alternateType === "Number" || alternateType === "Float") return "Number"; + } + } + return super.getType(ast); } - constructor(settings) { - settings = settings || {}; - this.canvas = settings.canvas || null; - this.context = settings.context || null; - this.mode = settings.mode; - this.Kernel = null; - this.kernels = []; - this.functions = []; - this.nativeFunctions = []; - this.injectedNative = null; - if (this.mode === "dev") return; - this.chooseKernel(); - if (settings.functions) for (let i = 0; i < settings.functions.length; i++) this.addFunction(settings.functions[i]); - if (settings.nativeFunctions) for (const p in settings.nativeFunctions) { - if (!settings.nativeFunctions.hasOwnProperty(p)) continue; - const s = settings.nativeFunctions[p]; - const {name: name, source: source} = s; - this.addNativeFunction(name, source, s); + astConditionalExpression(ast, retArr) { + if (ast.type !== "ConditionalExpression") throw this.astErrorOutput("Not a conditional expression", ast); + const consequentType = this.getType(ast.consequent); + const alternateType = this.getType(ast.alternate); + if (consequentType === null && alternateType === null) { + retArr.push("if ("); + this.astGeneric(ast.test, retArr); + retArr.push(") {"); + this.astGeneric(ast.consequent, retArr); + retArr.push(";"); + retArr.push("} else {"); + this.astGeneric(ast.alternate, retArr); + retArr.push(";"); + retArr.push("}"); + return retArr; } + let targetType = consequentType === "LiteralInteger" ? "Number" : consequentType; + if (targetType === "Integer" && (alternateType === "Number" || alternateType === "Float")) targetType = "Number"; + const emitBranch = branch => { + const branchType = this.getType(branch); + switch (targetType) { + case "Number": + case "Float": + if (branchType === "Integer") this.castValueToFloat(branch, retArr); else if (branchType === "LiteralInteger") this.castLiteralToFloat(branch, retArr); else this.astGeneric(branch, retArr); + break; + + case "Integer": + if (branchType === "Number" || branchType === "Float") this.castValueToInteger(branch, retArr); else if (branchType === "LiteralInteger") this.castLiteralToInteger(branch, retArr); else this.astGeneric(branch, retArr); + break; + + default: + this.astGeneric(branch, retArr); + } + }; + retArr.push("select("); + emitBranch(ast.alternate); + retArr.push(", "); + emitBranch(ast.consequent); + retArr.push(", "); + this.astGeneric(ast.test, retArr); + retArr.push(")"); + return retArr; } - chooseKernel() { - if (this.Kernel) return; - let Kernel = null; - if (this.context) { - for (let i = 0; i < kernelOrder.length; i++) { - const ExternalKernel = kernelOrder[i]; - if (ExternalKernel.isContextMatch(this.context)) { - if (!ExternalKernel.isSupported) throw new Error(`Kernel type ${ExternalKernel.name} not supported`); - Kernel = ExternalKernel; - break; - } + astFunction(ast, retArr) { + if (this.isRootKernel) { + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push("\n"); } - if (Kernel === null) throw new Error("unknown Context"); - } else if (this.mode) { - if (this.mode in internalKernels) { - if (!validate || internalKernels[this.mode].isSupported) Kernel = internalKernels[this.mode]; - } else if (this.mode === "gpu") { - for (let i = 0; i < kernelOrder.length; i++) if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; - } - } else if (this.mode === "cpu") Kernel = CPUKernel; - if (!Kernel) throw new Error(`A requested mode of "${this.mode}" and is not supported`); - } else { - for (let i = 0; i < kernelOrder.length; i++) if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; + return retArr; + } + if (!this.returnType) { + if (this.findLastReturn()) { + this.returnType = this.getType(ast.body); + if (this.returnType === "LiteralInteger") this.returnType = "Number"; } - if (!Kernel) Kernel = CPUKernel; } - if (!this.mode) this.mode = Kernel.mode; - this.Kernel = Kernel; - } - createKernel(source, settings) { - if (typeof source === "undefined") throw new Error("Missing source parameter"); - if (typeof source !== "object" && !utils.isFunction(source) && typeof source !== "string") throw new Error("source parameter not a function"); - const kernels = this.kernels; - if (this.mode === "dev") { - const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); - kernels.push(devKernel); - return devKernel; + const {returnType: returnType} = this; + let type = null; + if (returnType) { + type = typeMap[returnType]; + if (!type) throw this.astErrorOutput(`unknown return type ${returnType}`, ast); + } + retArr.push(`fn ${this.mangleFunctionName(this.name)}(`); + for (let i = 0; i < this.argumentNames.length; ++i) { + const argumentName = this.argumentNames[i]; + if (i > 0) retArr.push(", "); + let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)]; + if (!argumentType) throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast); + if (argumentType === "LiteralInteger") this.argumentTypes[i] = argumentType = "Number"; + const wgslType = typeMap[argumentType]; + if (!wgslType) throw this.astErrorOutput(`WebGPU backend does not yet support ${argumentType} arguments to helper functions`, ast); + retArr.push(`user_${utils.sanitizeName(argumentName)} : ${wgslType}`); + } + retArr.push(")"); + if (type) retArr.push(` -> ${type}`); + retArr.push(" {\n"); + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push("\n"); + } + retArr.push("}\n"); + return retArr; + } + astReturnStatement(ast, retArr) { + if (!ast.argument) throw this.astErrorOutput("Unexpected return statement", ast); + this.pushState("skip-literal-correction"); + const type = this.getType(ast.argument); + this.popState("skip-literal-correction"); + const result = []; + if (!this.returnType) if (type === "LiteralInteger" || type === "Integer") this.returnType = "Number"; else this.returnType = type; + switch (this.returnType) { + case "LiteralInteger": + case "Number": + case "Float": + switch (type) { + case "Integer": + result.push("f32("); + this.astGeneric(ast.argument, result); + result.push(")"); + break; + + case "LiteralInteger": + this.castLiteralToFloat(ast.argument, result); + if (this.getType(ast.argument) === "Integer") { + result.unshift("f32("); + result.push(")"); + } + break; + + default: + this.astGeneric(ast.argument, result); + } + break; + + case "Integer": + switch (type) { + case "Float": + case "Number": + this.castValueToInteger(ast.argument, result); + break; + + case "LiteralInteger": + this.castLiteralToInteger(ast.argument, result); + break; + + default: + this.astGeneric(ast.argument, result); + } + break; + + case "Boolean": + case "Array(4)": + case "Array(3)": + case "Array(2)": + this.astGeneric(ast.argument, result); + break; + + default: + throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast); + } + if (this.isRootKernel) switch (this.returnType) { + case "Array(4)": + case "Array(3)": + case "Array(2)": + { + const n = parseInt(this.returnType.substring(6), 10); + const temp = this.getInternalVariableName("kernelResultVec"); + retArr.push(`let ${temp} : ${typeMap[this.returnType]} = ${result.join("")};\n`); + for (let c = 0; c < n; c++) retArr.push(`result[data_index * ${n} + ${c}] = ${temp}.${vectorComponents[c]};\n`); + retArr.push("return;"); + break; + } + + case "Integer": + retArr.push(`result[data_index] = f32(${result.join("")});`); + retArr.push("return;"); + break; + + default: + retArr.push(`result[data_index] = ${result.join("")};`); + retArr.push("return;"); + } else if (this.isSubKernel) throw this.astErrorOutput("WebGPU backend does not yet support createKernelMap", ast); else retArr.push(`return ${result.join("")};`); + return retArr; + } + astLiteral(ast, retArr) { + if (ast.value === true || ast.value === false) { + retArr.push(ast.value ? "true" : "false"); + return retArr; + } + if (isNaN(ast.value)) throw this.astErrorOutput("Non-numeric literal not supported : " + ast.value, ast); + const key = this.astKey(ast); + if (Number.isInteger(ast.value)) if (this.isState("casting-to-integer") || this.isState("building-integer")) { + this.literalTypes[key] = "Integer"; + retArr.push(this.wgslInt(ast.value)); + } else { + this.literalTypes[key] = "Number"; + retArr.push(this.wgslFloat(ast.value)); + } else if (this.isState("casting-to-integer") || this.isState("building-integer")) { + this.literalTypes[key] = "Integer"; + retArr.push(this.wgslInt(ast.value)); + } else { + this.literalTypes[key] = "Number"; + retArr.push(this.wgslFloat(ast.value)); + } + return retArr; + } + astBinaryExpression(ast, retArr) { + if (this.checkAndUpconvertOperator(ast, retArr)) return retArr; + if (ast.operator === "/" || ast.operator === "%") { + retArr.push("("); + this.pushState("building-float"); + switch (this.getType(ast.left)) { + case "Integer": + this.castValueToFloat(ast.left, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(ast.left, retArr); + break; + + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(ast.operator); + switch (this.getType(ast.right)) { + case "Integer": + this.castValueToFloat(ast.right, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(ast.right, retArr); + break; + + default: + this.astGeneric(ast.right, retArr); + } + this.popState("building-float"); + retArr.push(")"); + return retArr; + } + retArr.push("("); + const leftType = this.getType(ast.left) || "Number"; + const rightType = this.getType(ast.right) || "Number"; + const key = leftType + " & " + rightType; + switch (key) { + case "Integer & Integer": + this.pushState("building-integer"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-integer"); + break; + + case "Number & Float": + case "Float & Number": + case "Float & Float": + case "Number & Number": + this.pushState("building-float"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-float"); + break; + + case "LiteralInteger & LiteralInteger": + if (this.isState("casting-to-integer") || this.isState("building-integer")) { + this.pushState("building-integer"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-integer"); + } else { + this.pushState("building-float"); + this.castLiteralToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); + this.popState("building-float"); + } + break; + + case "Integer & Float": + case "Integer & Number": + if ((ast.operator === ">" || ast.operator === "<") && ast.right.type === "Literal") { + if (!Number.isInteger(ast.right.value)) { + this.pushState("building-float"); + this.castValueToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-float"); + break; + } + } + this.pushState("building-integer"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState("casting-to-integer"); + if (ast.right.type === "Literal") { + const literalResult = []; + this.astGeneric(ast.right, literalResult); + if (this.getType(ast.right) === "Integer") retArr.push(literalResult.join("")); else throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); + } else { + retArr.push("i32("); + this.astGeneric(ast.right, retArr); + retArr.push(")"); + } + this.popState("casting-to-integer"); + this.popState("building-integer"); + break; + + case "Integer & LiteralInteger": + this.pushState("building-integer"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToInteger(ast.right, retArr); + this.popState("building-integer"); + break; + + case "Number & Integer": + this.pushState("building-float"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToFloat(ast.right, retArr); + this.popState("building-float"); + break; + + case "Float & LiteralInteger": + case "Number & LiteralInteger": + this.pushState("building-float"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); + this.popState("building-float"); + break; + + case "LiteralInteger & Float": + case "LiteralInteger & Number": + if (this.isState("casting-to-integer")) { + this.pushState("building-integer"); + this.castLiteralToInteger(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToInteger(ast.right, retArr); + this.popState("building-integer"); + } else { + this.pushState("building-float"); + this.castLiteralToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState("casting-to-float"); + this.astGeneric(ast.right, retArr); + this.popState("casting-to-float"); + this.popState("building-float"); + } + break; + + case "LiteralInteger & Integer": + this.pushState("building-integer"); + this.castLiteralToInteger(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-integer"); + break; + + case "Boolean & Boolean": + this.pushState("building-boolean"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-boolean"); + break; + + case "Float & Integer": + this.pushState("building-float"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToFloat(ast.right, retArr); + this.popState("building-float"); + break; + + default: + throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast); + } + retArr.push(")"); + return retArr; + } + checkAndUpconvertOperator(ast, retArr) { + if (this.checkAndUpconvertBitwiseOperators(ast, retArr)) return retArr; + if (ast.operator !== "**") return null; + retArr.push("_pow"); + retArr.push("("); + switch (this.getType(ast.left)) { + case "Integer": + this.castValueToFloat(ast.left, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(ast.left, retArr); + break; + + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(","); + switch (this.getType(ast.right)) { + case "Integer": + this.castValueToFloat(ast.right, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(ast.right, retArr); + break; + + default: + this.astGeneric(ast.right, retArr); + } + retArr.push(")"); + return retArr; + } + checkAndUpconvertBitwiseOperators(ast, retArr) { + if (!{ + "&": true, + "|": true, + "^": true, + "<<": true, + ">>": true, + ">>>": true + }[ast.operator]) return null; + const emitAsInteger = side => { + switch (this.getType(side)) { + case "Number": + case "Float": + this.castValueToInteger(side, retArr); + break; + + case "LiteralInteger": + this.castLiteralToInteger(side, retArr); + break; + + default: + this.pushState("building-integer"); + this.astGeneric(side, retArr); + this.popState("building-integer"); + } + }; + retArr.push("("); + if (ast.operator === ">>>") { + retArr.push("bitcast(bitcast("); + emitAsInteger(ast.left); + retArr.push(") >> u32("); + emitAsInteger(ast.right); + retArr.push("))"); + } else if (ast.operator === "<<" || ast.operator === ">>") { + emitAsInteger(ast.left); + retArr.push(` ${ast.operator} u32(`); + emitAsInteger(ast.right); + retArr.push(")"); + } else { + emitAsInteger(ast.left); + retArr.push(` ${ast.operator} `); + emitAsInteger(ast.right); + } + retArr.push(")"); + return retArr; + } + checkAndUpconvertBitwiseUnary(ast, retArr) { + if (ast.operator !== "~") return null; + retArr.push("~("); + switch (this.getType(ast.argument)) { + case "Number": + case "Float": + this.castValueToInteger(ast.argument, retArr); + break; + + case "LiteralInteger": + this.castLiteralToInteger(ast.argument, retArr); + break; + + default: + this.astGeneric(ast.argument, retArr); + } + retArr.push(")"); + return retArr; + } + astUnaryExpression(uNode, retArr) { + if (this.checkAndUpconvertBitwiseUnary(uNode, retArr)) return retArr; + if (uNode.operator === "+") { + this.astGeneric(uNode.argument, retArr); + return retArr; + } + if (uNode.prefix) { + retArr.push(uNode.operator); + this.astGeneric(uNode.argument, retArr); + } else { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + } + return retArr; + } + castLiteralToInteger(ast, retArr) { + this.pushState("casting-to-integer"); + this.astGeneric(ast, retArr); + this.popState("casting-to-integer"); + return retArr; + } + castLiteralToFloat(ast, retArr) { + this.pushState("casting-to-float"); + this.astGeneric(ast, retArr); + this.popState("casting-to-float"); + return retArr; + } + castValueToInteger(ast, retArr) { + this.pushState("casting-to-integer"); + retArr.push("i32("); + this.astGeneric(ast, retArr); + retArr.push(")"); + this.popState("casting-to-integer"); + return retArr; + } + castValueToFloat(ast, retArr) { + this.pushState("casting-to-float"); + retArr.push("f32("); + this.astGeneric(ast, retArr); + retArr.push(")"); + this.popState("casting-to-float"); + return retArr; + } + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== "Identifier") throw this.astErrorOutput("IdentifierExpression - not an Identifier", idtNode); + const type = this.getType(idtNode); + const name = utils.sanitizeName(idtNode.name); + if (idtNode.name === "Infinity") { + retArr.push("0x1.fffffep+127"); + return retArr; + } + if (this.isRootKernel && this.argumentNames.indexOf(idtNode.name) !== -1 && (type === "Number" || type === "Float" || type === "Integer" || type === "Boolean")) { + if (type === "Boolean") retArr.push(`bool(params.user_${name})`); else retArr.push(`params.user_${name}`); + return retArr; + } + retArr.push(`user_${name}`); + return retArr; + } + astForStatement(forNode, retArr) { + if (forNode.type !== "ForStatement") throw this.astErrorOutput("Invalid for statement", forNode); + const initArr = []; + const testArr = []; + const updateArr = []; + const bodyArr = []; + let isSafe = null; + if (forNode.init) { + const {declarations: declarations} = forNode.init; + if (declarations.length > 1) isSafe = false; + this.astGeneric(forNode.init, initArr); + for (let i = 0; i < declarations.length; i++) if (declarations[i].init && declarations[i].init.type !== "Literal") isSafe = false; + } else isSafe = false; + if (forNode.test) this.astGeneric(forNode.test, testArr); else isSafe = false; + if (forNode.update) { + if (forNode.update.type === "AssignmentExpression") this.pushState("assignment-as-statement"); + this.astGeneric(forNode.update, updateArr); + } else isSafe = false; + if (forNode.body) { + this.pushState("loop-body"); + this.astGeneric(forNode.body, bodyArr); + this.popState("loop-body"); + } + if (isSafe === null) isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); + if (isSafe) { + const initString = initArr.join(""); + const initNeedsSemiColon = initString[initString.length - 1] !== ";"; + retArr.push(`for (${initString}${initNeedsSemiColon ? ";" : ""}${testArr.join("")};${updateArr.join("")}){\n`); + retArr.push(bodyArr.join("")); + retArr.push("}\n"); + } else { + const iVariableName = this.getInternalVariableName("safeI"); + if (initArr.length > 0) retArr.push(initArr.join(""), "\n"); + retArr.push(`for (var ${iVariableName} : i32 = 0;${iVariableName} 0) retArr.push(`if (!(${testArr.join("")})) { break; }\n`); + retArr.push(bodyArr.join("")); + retArr.push(`\n${updateArr.join("")};`); + retArr.push("}\n"); + } + return retArr; + } + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== "WhileStatement") throw this.astErrorOutput("Invalid while statement", whileNode); + const iVariableName = this.getInternalVariableName("safeI"); + retArr.push(`for (var ${iVariableName} : i32 = 0;${iVariableName} { + if (!node || typeof node !== "object") return false; + if (Array.isArray(node)) return node.some(containsBreak); + if (node.type === "BreakStatement") return true; + if (node.type === "ForStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement" || node.type === "SwitchStatement") return false; + for (const key in node) { + if (key === "loc" || key === "range" || key === "parent") continue; + if (containsBreak(node[key])) return true; + } + return false; + }; + if (containsBreak(statements[i])) throw this.astErrorOutput("break inside a switch case is only supported as the case terminator", statements[i]); + } + for (let i = 0; i < statements.length; i++) { + this.astGeneric(statements[i], retArr); + retArr.push("\n"); + } + return retArr; + } + astSwitchStatement(ast, retArr) { + if (ast.type !== "SwitchStatement") throw this.astErrorOutput("Invalid switch statement", ast); + const {discriminant: discriminant, cases: cases} = ast; + const type = this.getType(discriminant); + const varName = `switchDiscriminant${this.astKey(ast, "_")}`; + switch (type) { + case "Float": + case "Number": + retArr.push(`var ${varName} : f32 = `); + this.astGeneric(discriminant, retArr); + retArr.push(";\n"); + break; + + case "Integer": + retArr.push(`var ${varName} : i32 = `); + this.astGeneric(discriminant, retArr); + retArr.push(";\n"); + break; + + default: + throw this.astErrorOutput(`Unhandled switch discriminant type "${type}"`, ast); + } + if (cases.length === 1 && !cases[0].test) { + this.astSwitchCaseConsequent(cases[0].consequent, retArr); + return retArr; + } + let fallingThrough = false; + let defaultResult = []; + let movingDefaultToEnd = false; + let pastFirstIf = false; + for (let i = 0; i < cases.length; i++) { + if (!cases[i].test) if (cases.length > i + 1) { + movingDefaultToEnd = true; + this.astSwitchCaseConsequent(cases[i].consequent, defaultResult); + continue; + } else retArr.push(" else {\n"); else { + if (i === 0 || !pastFirstIf) { + pastFirstIf = true; + retArr.push(`if (${varName} == `); + } else if (fallingThrough) { + retArr.push(`${varName} == `); + fallingThrough = false; + } else retArr.push(` else if (${varName} == `); + if (type === "Integer") switch (this.getType(cases[i].test)) { + case "Number": + case "Float": + this.castValueToInteger(cases[i].test, retArr); + break; + + case "LiteralInteger": + this.castLiteralToInteger(cases[i].test, retArr); + break; + } else switch (this.getType(cases[i].test)) { + case "LiteralInteger": + this.castLiteralToFloat(cases[i].test, retArr); + break; + + case "Integer": + this.castValueToFloat(cases[i].test, retArr); + break; + + default: + this.astGeneric(cases[i].test, retArr); + } + if (!cases[i].consequent || cases[i].consequent.length === 0) { + fallingThrough = true; + retArr.push(" || "); + continue; + } + retArr.push(`) {\n`); + } + this.astSwitchCaseConsequent(cases[i].consequent, retArr); + retArr.push("\n}"); + } + if (movingDefaultToEnd) { + retArr.push(" else {"); + retArr.push(defaultResult.join("")); + retArr.push("}"); + } + retArr.push("\n"); + return retArr; + } + astThisExpression(tNode, retArr) { + retArr.push("this"); + return retArr; + } + astSequenceExpression(sNode, retArr) { + const {expressions: expressions} = sNode; + if (expressions.length === 1) { + this.astGeneric(expressions[0], retArr); + return retArr; + } + throw this.astErrorOutput("WebGPU backend does not yet support the comma operator", sNode); + } + astMemberExpression(mNode, retArr) { + const {property: property, name: name, signature: signature, origin: origin, type: type, xProperty: xProperty, yProperty: yProperty, zProperty: zProperty} = this.getMemberExpressionDetails(mNode); + switch (signature) { + case "value.thread.value": + case "this.thread.value": + if (name !== "x" && name !== "y" && name !== "z") throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`", mNode); + retArr.push(`i32(threadGid.${name})`); + return retArr; + + case "this.output.value": + { + const axisIndex = { + x: 0, + y: 1, + z: 2 + }[name]; + if (axisIndex === void 0) throw this.astErrorOutput("Unexpected expression", mNode); + if (this.dynamicOutput) { + const member = `params.output${name.toUpperCase()}`; + if (this.isState("casting-to-float")) retArr.push(`f32(${member})`); else retArr.push(`i32(${member})`); + } else if (this.isState("casting-to-integer")) retArr.push(`${this.output[axisIndex]}`); else retArr.push(`${this.output[axisIndex]}.0`); + return retArr; + } + + case "value": + throw this.astErrorOutput("Unexpected expression", mNode); + + case "value[]": + case "value[][]": + case "value[][][]": + case "value[][][][]": + case "value.value": + if (origin === "Math") { + retArr.push(this.wgslFloat(Math[name])); + return retArr; + } + switch (property) { + case "r": + retArr.push(`user_${utils.sanitizeName(name)}.x`); + return retArr; + + case "g": + retArr.push(`user_${utils.sanitizeName(name)}.y`); + return retArr; + + case "b": + retArr.push(`user_${utils.sanitizeName(name)}.z`); + return retArr; + + case "a": + retArr.push(`user_${utils.sanitizeName(name)}.w`); + return retArr; + } + break; + + case "this.constants.value": + { + const value = this.constants[name]; + switch (type) { + case "Integer": + if (this.isState("casting-to-float")) retArr.push(this.wgslFloat(value)); else retArr.push(this.wgslInt(value)); + return retArr; + + case "Number": + case "Float": + if (this.isState("casting-to-integer")) retArr.push(this.wgslInt(value)); else retArr.push(this.wgslFloat(value)); + return retArr; + + case "Boolean": + retArr.push(value ? "true" : "false"); + return retArr; + + case "Array(2)": + case "Array(3)": + case "Array(4)": + { + const n = parseInt(type.substring(6), 10); + const parts = []; + for (let i = 0; i < n; i++) parts.push(this.wgslFloat(value[i])); + retArr.push(`${typeMap[type]}(${parts.join(", ")})`); + return retArr; + } + + default: + throw this.astErrorOutput(`WebGPU backend does not yet support constant type ${type}`, mNode); + } + } + + case "this.constants.value[]": + case "this.constants.value[][]": + case "this.constants.value[][][]": + case "this.constants.value[][][][]": + break; + + case "fn()[]": + this.astCallExpression(mNode.object, retArr); + retArr.push("["); + retArr.push(this.memberExpressionPropertyMarkup(property)); + retArr.push("]"); + return retArr; + + default: + throw this.astErrorOutput(`WebGPU backend does not yet support expression signature "${signature}"`, mNode); + } + const markupName = `${origin}_${utils.sanitizeName(name)}`; + switch (type) { + case "Array(2)": + case "Array(3)": + case "Array(4)": + this.astGeneric(mNode.object, retArr); + retArr.push("["); + retArr.push(this.memberExpressionPropertyMarkup(xProperty)); + retArr.push("]"); + break; + + case "Array": + case "Array2D": + case "Array3D": + case "Input": + case "WebGPUBuffer": + case "Number": + case "Float": + case "Integer": + retArr.push(`get_${markupName}(`); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(")"); + break; + + case "Matrix(2)": + case "Matrix(3)": + case "Matrix(4)": + throw this.astErrorOutput("WebGPU backend does not yet support Matrix types", mNode); + + default: + throw this.astErrorOutput(`WebGPU backend does not yet support member expression type "${type}"`, mNode); + } + return retArr; + } + astCallExpression(ast, retArr) { + if (!ast.callee) throw this.astErrorOutput("Unknown CallExpression", ast); + let functionName = null; + const isMathFunction = this.isAstMathFunction(ast); + if (isMathFunction || ast.callee.object && ast.callee.object.type === "ThisExpression") functionName = ast.callee.property.name; else if (ast.callee.type === "SequenceExpression" && ast.callee.expressions[0].type === "Literal" && !isNaN(ast.callee.expressions[0].raw)) functionName = ast.callee.expressions[1].property.name; else functionName = ast.callee.name; + if (!functionName) throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast); + let emitName = functionName; + if (isMathFunction) { + if (functionName === "random") throw this.astErrorOutput("WebGPU backend does not yet support Math.random", ast); + if (mathFunctionRenames[functionName]) functionName = mathFunctionRenames[functionName]; + emitName = functionName; + } else emitName = this.mangleFunctionName(functionName); + if (this.calledFunctions.indexOf(functionName) < 0) this.calledFunctions.push(functionName); + if (this.onFunctionCall) this.onFunctionCall(this.name, functionName, ast.arguments); + const needsIntegerWrap = isMathFunction && integerResultMathFunctions[functionName] && this.isState("building-integer"); + if (needsIntegerWrap) retArr.push("i32("); + retArr.push(emitName); + retArr.push("("); + if (isMathFunction) for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + const argumentType = this.getType(argument); + if (i > 0) retArr.push(", "); + switch (argumentType) { + case "Integer": + this.castValueToFloat(argument, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(argument, retArr); + break; + + default: + this.astGeneric(argument, retArr); + break; + } + } else { + const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + let targetType = targetTypes[i]; + if (i > 0) retArr.push(", "); + const argumentType = this.getType(argument); + if (!targetType) { + this.triggerImplyArgumentType(functionName, i, argumentType, this); + targetType = argumentType; + } + switch (argumentType) { + case "Boolean": + this.astGeneric(argument, retArr); + continue; + + case "Number": + case "Float": + if (targetType === "Integer") { + retArr.push("i32("); + this.astGeneric(argument, retArr); + retArr.push(")"); + continue; + } else if (targetType === "Number" || targetType === "Float") { + this.astGeneric(argument, retArr); + continue; + } else if (targetType === "LiteralInteger") { + this.castLiteralToFloat(argument, retArr); + continue; + } + break; + + case "Integer": + if (targetType === "Number" || targetType === "Float") { + retArr.push("f32("); + this.astGeneric(argument, retArr); + retArr.push(")"); + continue; + } else if (targetType === "Integer") { + this.astGeneric(argument, retArr); + continue; + } + break; + + case "LiteralInteger": + if (targetType === "Integer") { + this.castLiteralToInteger(argument, retArr); + continue; + } else if (targetType === "Number" || targetType === "Float") { + this.castLiteralToFloat(argument, retArr); + continue; + } else if (targetType === "LiteralInteger") { + this.astGeneric(argument, retArr); + continue; + } + break; + + case "Array(2)": + case "Array(3)": + case "Array(4)": + if (targetType === argumentType) { + if (argument.type === "Identifier") retArr.push(`user_${utils.sanitizeName(argument.name)}`); else this.astGeneric(argument, retArr); + continue; + } + break; + + case "Array": + case "Array2D": + case "Array3D": + case "Input": + case "WebGPUBuffer": + throw this.astErrorOutput("WebGPU backend does not yet support array arguments to helper functions", ast); + } + throw this.astErrorOutput(`Unhandled argument combination of ${argumentType} and ${targetType} for argument named "${argument.name}"`, ast); + } + } + retArr.push(")"); + if (needsIntegerWrap) retArr.push(")"); + return retArr; + } + astArrayExpression(arrNode, retArr) { + switch (this.getType(arrNode)) { + case "Matrix(2)": + case "Matrix(3)": + case "Matrix(4)": + throw this.astErrorOutput("WebGPU backend does not yet support Matrix types", arrNode); + } + const arrLen = arrNode.elements.length; + retArr.push(`vec${arrLen}(`); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) retArr.push(", "); + const subNode = arrNode.elements[i]; + switch (this.getType(subNode)) { + case "Integer": + this.castValueToFloat(subNode, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(subNode, retArr); + break; + + default: + this.astGeneric(subNode, retArr); + } + } + retArr.push(")"); + return retArr; + } + memberExpressionXYZ(x, y, z, retArr) { + if (z) retArr.push(this.memberExpressionPropertyMarkup(z), ", "); else retArr.push("0, "); + if (y) retArr.push(this.memberExpressionPropertyMarkup(y), ", "); else retArr.push("0, "); + retArr.push(this.memberExpressionPropertyMarkup(x)); + return retArr; + } + memberExpressionPropertyMarkup(property) { + if (!property) throw new Error("Property not set"); + const type = this.getType(property); + const result = []; + switch (type) { + case "Number": + case "Float": + this.castValueToInteger(property, result); + break; + + case "LiteralInteger": + this.castLiteralToInteger(property, result); + break; + + case "Integer": + this.pushState("building-integer"); + result.push("i32("); + this.astGeneric(property, result); + result.push(")"); + this.popState("building-integer"); + break; + + default: + this.astGeneric(property, result); + } + return result.join(""); + } + }; + const typeMap = { + Number: "f32", + Float: "f32", + Integer: "i32", + LiteralInteger: "f32", + Boolean: "bool", + "Array(2)": "vec2", + "Array(3)": "vec3", + "Array(4)": "vec4" + }; + const operatorMap = { + "===": "==", + "!==": "!=" + }; + const vectorComponents = [ "x", "y", "z", "w" ]; + const mathFunctionRenames = { + pow: "_pow", + round: "_round" + }; + const integerResultMathFunctions = { + ceil: true, + floor: true, + _round: true + }; + const reservedNames = [ "alias", "break", "case", "const", "const_assert", "continue", "continuing", "default", "diagnostic", "discard", "else", "enable", "false", "fn", "for", "if", "let", "loop", "override", "requires", "return", "struct", "switch", "true", "var", "while", "main", "params", "result", "gid", "threadGid", "data_index", "select", "abs", "acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", "ceil", "clamp", "cos", "cosh", "cross", "degrees", "distance", "dot", "exp", "exp2", "floor", "fma", "fract", "inverseSqrt", "length", "log", "log2", "max", "min", "mix", "modf", "normalize", "pow", "radians", "round", "sign", "sin", "sinh", "smoothstep", "sqrt", "step", "tan", "tanh", "trunc", "cbrt", "expm1", "fround", "imul", "log10", "log1p", "clz32", "_pow", "_round", "LOOP_MAX", "bitcast", "ptr", "array", "vec2", "vec3", "vec4", "mat2x2", "mat3x3", "mat4x4", "f32", "i32", "u32", "bool" ]; + module.exports = { + WGSLFunctionNode: WGSLFunctionNode + }; + }); + var require_context = __commonJSMin((exports, module) => { + let contextPromise = null; + module.exports = { + WebGPUContext: class WebGPUContext { + static get isSupported() { + return typeof navigator !== "undefined" && !!navigator.gpu; + } + static acquire() { + if (contextPromise) return contextPromise; + const promise = (async () => { + if (!WebGPUContext.isSupported) throw new Error("WebGPU is not supported on this platform (navigator.gpu is missing)"); + const adapter = await navigator.gpu.requestAdapter(); + if (!adapter) throw new Error("WebGPU is present (navigator.gpu) but no adapter is available. On headless Chromium there is no adapter; run headed. Use `await GPU.isWebGPUAvailable()` to feature-detect."); + const device = await adapter.requestDevice({ + requiredLimits: { + maxStorageBufferBindingSize: adapter.limits.maxStorageBufferBindingSize, + maxBufferSize: adapter.limits.maxBufferSize + } + }); + const context = { + adapter: adapter, + device: device, + isLost: false + }; + device.lost.then(info => { + context.isLost = true; + if (info.reason !== "destroyed") console.error(`gpu.js [webgpu]: device lost: ${info.message}`); + if (contextPromise === promise) contextPromise = null; + }); + device.onuncapturederror = e => { + console.error(`gpu.js [webgpu]: ${e.error.message}`); + }; + return context; + })(); + promise.catch(() => { + if (contextPromise === promise) contextPromise = null; + }); + return contextPromise = promise; + } + static destroy() { + if (!contextPromise) return Promise.resolve(); + const promise = contextPromise; + contextPromise = null; + return promise.then(({device: device}) => { + device.destroy(); + }, () => {}); + } + } + }; + }); + var require_buffer_result = __commonJSMin((exports, module) => { + module.exports = { + WebGPUBufferResult: class WebGPUBufferResult { + constructor(settings) { + this.buffer = settings.buffer; + this.output = settings.output; + this.componentCount = settings.componentCount || 1; + this.context = settings.context; + this.kernel = settings.kernel; + this.type = "WebGPUBuffer"; + this._deleted = false; + if (this.buffer._refs) this.buffer._refs++; else this.buffer._refs = 1; + } + toArray() { + if (this._deleted) return Promise.reject(new Error("WebGPUBufferResult has been deleted")); + return this.kernel.readBufferResult(this); + } + delete() { + if (this._deleted) return; + this._deleted = true; + if (--this.buffer._refs === 0) this.buffer.destroy(); + } + clone() { + return new WebGPUBufferResult(this); + } + } + }; + }); + var require_kernel = __commonJSMin((exports, module) => { + const {Kernel: Kernel} = require_kernel$6(); + const {FunctionBuilder: FunctionBuilder} = require_function_builder(); + const {WGSLFunctionNode: WGSLFunctionNode} = require_function_node(); + const {WebGPUContext: WebGPUContext} = require_context(); + const {WebGPUBufferResult: WebGPUBufferResult} = require_buffer_result(); + const {utils: utils} = require_utils(); + const {Input: Input} = require_input(); + const USAGE_STORAGE = 128; + const MAP_MODE_READ = 1; + const features = Object.freeze({ + kernelMap: false, + isIntegerDivisionAccurate: true, + isSpeedTacticSupported: false, + isTextureFloat: true, + isDrawBuffers: false, + kernelMapSize: 0, + channelCount: 1, + maxTextureSize: Infinity, + isFloatRead: true + }); + const wgslHelpers = { + _pow: "fn _pow(v1 : f32, v2 : f32) -> f32 {\n if (v2 == 0.0) { return 1.0; }\n return pow(v1, v2);\n}", + _round: "fn _round(x : f32) -> f32 {\n return floor(x + 0.5);\n}", + cbrt: "fn cbrt(x : f32) -> f32 {\n return sign(x) * pow(abs(x), 1.0 / 3.0);\n}", + expm1: "fn expm1(x : f32) -> f32 {\n return exp(x) - 1.0;\n}", + fround: "fn fround(x : f32) -> f32 {\n return x;\n}", + imul: "fn imul(a : f32, b : f32) -> f32 {\n return f32(i32(a) * i32(b));\n}", + log10: `fn log10(x : f32) -> f32 {\n return log2(x) * ${1 / Math.log2(10)};\n}`, + log1p: "fn log1p(x : f32) -> f32 {\n return log(1.0 + x);\n}", + clz32: "fn clz32(x : f32) -> f32 {\n return f32(countLeadingZeros(u32(x)));\n}" + }; + var WebGPUKernel = class extends Kernel { + static get isSupported() { + return WebGPUContext.isSupported; + } + static get isAsync() { + return true; + } + static isContextMatch(context) { + return Boolean(context && typeof context.createShaderModule === "function" && typeof context.createComputePipeline === "function"); + } + static getFeatures() { + return features; + } + static get features() { + return features; + } + static get mode() { + return "webgpu"; + } + static getSignature(kernel, argumentTypes) { + return "webgpu" + (argumentTypes.length > 0 ? ":" + argumentTypes.join(",") : ""); + } + static destroyContext(context) {} + static nativeFunctionArguments() { + throw new Error("WebGPU backend does not yet support native functions"); + } + static nativeFunctionReturnType() { + throw new Error("WebGPU backend does not yet support native functions"); + } + static combineKernels() { + throw new Error("WebGPU backend does not yet support combineKernels; chain kernels with `await` and pipeline mode instead"); + } + constructor(source, settings) { + super(source, settings); + if (settings) { + if (settings.graphical) throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend"); + if (settings.precision === "unsigned") throw new Error(`WebGPU backend does not yet support precision: 'unsigned'; it is single precision only`); + if (settings.subKernels) throw new Error("WebGPU backend does not yet support createKernelMap"); + } + this.mergeSettings(source.settings || settings); + if (this.precision === null) this.precision = "single"; + this.asyncMode = true; + this.threadDim = null; + this.componentCount = 1; + this.compiledSource = null; + this.translatedBody = null; + this.translatedFunctions = null; + this.paramsLayout = null; + this._buildPromise = null; + this._device = null; + this.computePipeline = null; + this.bindGroupLayout = null; + this.bindGroup = null; + this.bindGroupDirty = true; + this.paramsBuffer = null; + this.paramsMirror = null; + this.outputBuffer = null; + this.argumentBuffers = null; + this.constantBuffers = null; + this.stagingPool = []; + } + initCanvas() { + return null; + } + initContext() { + return null; + } + initPlugins(settings) { + return []; + } + setGraphical(flag) { + if (flag) throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend"); + return super.setGraphical(flag); + } + setOutput(output) { + const newOutput = this.toKernelOutput(output); + if (this.built) { + if (!this.dynamicOutput) throw new Error("Resizing a kernel with dynamicOutput: false is not possible"); + if (newOutput.length !== this.output.length) throw new Error("WebGPU backend does not yet support changing the output rank of a built kernel; the workgroup shape is fixed at build"); + } + this.output = newOutput; + return this; + } + toString() { + throw new Error("WebGPU backend does not yet support toString"); + } + validateSettings(args) { + if (this.graphical) throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend"); + if (this.precision === "unsigned") throw new Error(`WebGPU backend does not yet support precision: 'unsigned'; it is single precision only`); + this.precision = "single"; + if (this.subKernels && this.subKernels.length > 0) throw new Error("WebGPU backend does not yet support createKernelMap"); + if (!this.output || this.output.length === 0) { + if (args.length !== 1) throw new Error("Auto output only supported for kernels with only one input"); + const argType = utils.getVariableType(args[0], this.strictIntegers); + if (argType === "Array") this.output = Array.from(utils.getDimensions(args[0])); else if (argType === "WebGPUBuffer") this.output = Array.from(args[0].output); else throw new Error("Auto output not supported for input type: " + argType); + } + this.checkOutput(); + } + setupArguments(args) { + super.setupArguments(args); + for (let i = 0; i < this.argumentTypes.length; i++) switch (this.argumentTypes[i]) { + case "Array": + case "Input": + case "WebGPUBuffer": + case "Number": + case "Float": + case "Integer": + case "Boolean": + continue; + + default: + throw new Error(`WebGPU backend does not yet support argument type ${this.argumentTypes[i]} (argument "${this.argumentNames[i]}")`); + } + } + setupConstants() { + super.setupConstants(); + for (const name in this.constantTypes) switch (this.constantTypes[name]) { + case "Array": + case "Input": + case "Number": + case "Float": + case "Integer": + case "Boolean": + case "Array(2)": + case "Array(3)": + case "Array(4)": + continue; + + default: + throw new Error(`WebGPU backend does not yet support constant type ${this.constantTypes[name]} (constant "${name}")`); + } + } + build() { + if (this.built) return Promise.resolve(); + if (this._buildPromise) return this._buildPromise; + this.setupConstants(); + this.setupArguments(arguments); + this.validateSettings(arguments); + const threadDim = this.threadDim = Array.from(this.output); + while (threadDim.length < 3) threadDim.push(1); + this.translateSource(); + this.paramsLayout = this.computeParamsLayout(); + this.compiledSource = this.assembleWGSL(); + if (this.debug) { + console.log("WGSL Shader Output:"); + console.log(this.compiledSource); + } + this.buildSignature(arguments); + return this._buildPromise = this._buildAsync(); + } + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WGSLFunctionNode); + const prototypes = functionBuilder.getPrototypes("kernel"); + this.translatedBody = prototypes[prototypes.length - 1]; + this.translatedFunctions = prototypes.slice(0, -1).join("\n"); + if (!this.returnType) this.returnType = functionBuilder.getKernelResultType(); + switch (this.returnType) { + case "Number": + case "Float": + case "Integer": + case "LiteralInteger": + this.componentCount = 1; + break; + + case "Array(2)": + this.componentCount = 2; + break; + + case "Array(3)": + this.componentCount = 3; + break; + + case "Array(4)": + this.componentCount = 4; + break; + + default: + throw new Error(`WebGPU backend does not yet support returning ${this.returnType}`); + } + } + computeParamsLayout() { + const arrayArgs = []; + const scalarArgs = []; + let offset = 16; + for (let i = 0; i < this.argumentTypes.length; i++) { + const type = this.argumentTypes[i]; + const name = utils.sanitizeName(this.argumentNames[i]); + if (type === "Array" || type === "Input" || type === "WebGPUBuffer") { + arrayArgs.push({ + name: name, + index: i, + type: type, + dimsOffset: offset, + buffer: null, + boundBuffer: null + }); + offset += 16; + } else scalarArgs.push({ + name: name, + index: i, + type: type, + offset: null + }); + } + for (let i = 0; i < scalarArgs.length; i++) { + scalarArgs[i].offset = offset; + offset += 4; + } + const bufferConstants = []; + if (this.constants) for (const name in this.constants) { + if (!this.constants.hasOwnProperty(name)) continue; + const type = this.constantTypes[name]; + if (type === "Array" || type === "Input") bufferConstants.push({ + name: utils.sanitizeName(name), + constantName: name, + buffer: null + }); + } + return { + arrayArgs: arrayArgs, + scalarArgs: scalarArgs, + bufferConstants: bufferConstants, + byteLength: Math.ceil(offset / 16) * 16 + }; + } + scalarWGSLType(type) { + switch (type) { + case "Integer": + return "i32"; + + case "Boolean": + return "u32"; + + default: + return "f32"; + } + } + assembleWGSL() { + const {arrayArgs: arrayArgs, scalarArgs: scalarArgs, bufferConstants: bufferConstants} = this.paramsLayout; + const wgsl = []; + const structMembers = [ " outputX : u32,", " outputY : u32,", " outputZ : u32,", " dispatchWidth : u32," ]; + for (let i = 0; i < arrayArgs.length; i++) structMembers.push(` user_${arrayArgs[i].name}_dims : vec4,`); + for (let i = 0; i < scalarArgs.length; i++) structMembers.push(` user_${scalarArgs[i].name} : ${this.scalarWGSLType(scalarArgs[i].type)},`); + wgsl.push("struct Params {", structMembers.join("\n"), "}"); + wgsl.push("@group(0) @binding(0) var params : Params;"); + for (let i = 0; i < arrayArgs.length; i++) wgsl.push(`@group(0) @binding(${1 + i}) var user_${arrayArgs[i].name} : array;`); + const outBinding = 1 + arrayArgs.length; + wgsl.push(`@group(0) @binding(${outBinding}) var result : array;`); + for (let i = 0; i < bufferConstants.length; i++) wgsl.push(`@group(0) @binding(${outBinding + 1 + i}) var constants_${bufferConstants[i].name} : array;`); + wgsl.push("var threadGid : vec3;"); + const translated = `${this.translatedFunctions}\n${this.translatedBody}`; + if (/\bLOOP_MAX\b/.test(translated)) wgsl.push(`const LOOP_MAX : i32 = ${parseInt(this.loopMaxIterations, 10) || 1e3};`); + for (const helperName in wgslHelpers) if (new RegExp(`\\b${helperName}\\(`).test(translated)) wgsl.push(wgslHelpers[helperName]); + for (let i = 0; i < arrayArgs.length; i++) { + const name = arrayArgs[i].name; + wgsl.push(`fn get_user_${name}(z : i32, y : i32, x : i32) -> f32 {\n return user_${name}[u32(x + i32(params.user_${name}_dims.x) * (y + i32(params.user_${name}_dims.y) * z))];\n}`); + } + for (let i = 0; i < bufferConstants.length; i++) { + const record = bufferConstants[i]; + const value = this.constants[record.constantName]; + const dims = this.constantDimensions(value); + wgsl.push(`fn get_constants_${record.name}(z : i32, y : i32, x : i32) -> f32 {\n return constants_${record.name}[u32(x + ${dims[0]} * (y + ${dims[1]} * z))];\n}`); + } + if (this.translatedFunctions) wgsl.push(this.translatedFunctions); + const workgroupSize = this.output.length === 1 ? [ 64, 1, 1 ] : [ 8, 8, 1 ]; + this.workgroupSize = workgroupSize; + if (this.output.length === 1) wgsl.push(`@compute @workgroup_size(${workgroupSize[0]}, ${workgroupSize[1]}, ${workgroupSize[2]})\nfn main(@builtin(global_invocation_id) gid : vec3) {\n let flat_index : u32 = gid.x + gid.y * params.dispatchWidth;\n threadGid = vec3(flat_index, 0u, 0u);\n if (flat_index >= params.outputX) { return; }\n let data_index : i32 = i32(flat_index);\n${this.translatedBody}\n}`); else wgsl.push(`@compute @workgroup_size(${workgroupSize[0]}, ${workgroupSize[1]}, ${workgroupSize[2]})\nfn main(@builtin(global_invocation_id) gid : vec3) {\n threadGid = gid;\n if (gid.x >= params.outputX || gid.y >= params.outputY || gid.z >= params.outputZ) { return; }\n let data_index : i32 = i32(gid.x + params.outputX * (gid.y + params.outputY * gid.z));\n${this.translatedBody}\n}`); + return wgsl.join("\n"); + } + constantDimensions(value) { + const dims = value instanceof Input ? Array.from(value.size) : Array.from(utils.getDimensions(value)); + while (dims.length < 3) dims.push(1); + return dims; + } + async _buildAsync() { + const context = await WebGPUContext.acquire(); + this.context = context; + const device = this._device = context.device; + const module$1 = device.createShaderModule({ + code: this.compiledSource + }); + const errors = (await module$1.getCompilationInfo()).messages.filter(message => message.type === "error"); + if (errors.length > 0) throw new Error("Error compiling WGSL compute shader:\n" + errors.map(message => ` ${message.lineNum}:${message.linePos} ${message.message}`).join("\n") + `\n--- generated WGSL ---\n${this.compiledSource}`); + const {arrayArgs: arrayArgs, bufferConstants: bufferConstants, byteLength: byteLength} = this.paramsLayout; + const layoutEntries = [ { + binding: 0, + visibility: 4, + buffer: { + type: "uniform" + } + } ]; + for (let i = 0; i < arrayArgs.length; i++) layoutEntries.push({ + binding: 1 + i, + visibility: 4, + buffer: { + type: "read-only-storage" + } + }); + const outBinding = 1 + arrayArgs.length; + layoutEntries.push({ + binding: outBinding, + visibility: 4, + buffer: { + type: "storage" + } + }); + for (let i = 0; i < bufferConstants.length; i++) layoutEntries.push({ + binding: outBinding + 1 + i, + visibility: 4, + buffer: { + type: "read-only-storage" + } + }); + this.bindGroupLayout = device.createBindGroupLayout({ + entries: layoutEntries + }); + device.pushErrorScope("validation"); + this.computePipeline = device.createComputePipeline({ + layout: device.createPipelineLayout({ + bindGroupLayouts: [ this.bindGroupLayout ] + }), + compute: { + module: module$1, + entryPoint: "main" + } + }); + const pipelineError = await device.popErrorScope(); + if (pipelineError) throw new Error(`Error creating WebGPU compute pipeline for kernel: ${pipelineError.message}`); + this.paramsBuffer = device.createBuffer({ + size: byteLength, + usage: 72 + }); + this.paramsMirror = new ArrayBuffer(byteLength); + this.paramsU32 = new Uint32Array(this.paramsMirror); + this.paramsI32 = new Int32Array(this.paramsMirror); + this.paramsF32 = new Float32Array(this.paramsMirror); + this.constantBuffers = []; + for (let i = 0; i < bufferConstants.length; i++) { + const record = bufferConstants[i]; + const value = this.constants[record.constantName]; + const dims = this.constantDimensions(value); + const flatLength = dims[0] * dims[1] * dims[2]; + this._checkBufferSize(flatLength * 4, `constant "${record.constantName}"`); + const buffer = device.createBuffer({ + size: Math.max(flatLength * 4, 4), + usage: USAGE_STORAGE, + mappedAtCreation: true + }); + const mapped = new Float32Array(buffer.getMappedRange()); + utils.flattenTo(value instanceof Input ? value.value : value, mapped.subarray(0, flatLength)); + buffer.unmap(); + record.buffer = buffer; + this.constantBuffers.push(buffer); + } + this._ensureOutputBuffer(); + this.bindGroupDirty = true; + this.built = true; + } + _computeDispatch(threadDim) { + const [wx, wy, wz] = this.workgroupSize; + const groups = [ Math.ceil(threadDim[0] / wx), Math.ceil(threadDim[1] / wy), Math.ceil(threadDim[2] / wz) ]; + const maxGroups = this._device.limits.maxComputeWorkgroupsPerDimension; + let dispatchWidth = 0; + if (this.output.length === 1) { + if (groups[0] > maxGroups) { + groups[1] = Math.ceil(groups[0] / maxGroups); + groups[0] = Math.ceil(groups[0] / groups[1]); + } + dispatchWidth = groups[0] * wx; + } + for (let i = 0; i < 3; i++) if (groups[i] > maxGroups) throw new Error(`output dimension ${i} needs ${groups[i]} workgroups, over this device's limit of ${maxGroups}`); + return { + groups: groups, + dispatchWidth: dispatchWidth + }; + } + _ensureOutputBuffer() { + const [tx, ty, tz] = this.threadDim; + const byteLength = tx * ty * tz * 4 * this.componentCount; + if (this.immutable && this.pipeline && this.outputBuffer) { + if (--this.outputBuffer._refs === 0) this.outputBuffer.destroy(); + this.outputBuffer = null; + this.bindGroupDirty = true; + } + if (this.outputBuffer && this.outputBuffer.size >= byteLength) return; + if (this.outputBuffer) { + if (--this.outputBuffer._refs === 0) this.outputBuffer.destroy(); + } + this._checkBufferSize(byteLength, `output [${this.output.join(", ")}]`); + this.outputBuffer = this._device.createBuffer({ + size: byteLength, + usage: 132 + }); + this.outputBuffer._refs = 1; + this.bindGroupDirty = true; + } + _checkBufferSize(byteLength, what) { + const limits = this._device.limits; + const max = Math.min(limits.maxStorageBufferBindingSize, limits.maxBufferSize); + if (byteLength > max) throw new Error(`WebGPU backend: ${what} needs ${byteLength} bytes but this device allows ${max} per storage buffer (maxStorageBufferBindingSize/maxBufferSize); reduce the output or split the work across kernels`); + } + _snapshotArguments(args) { + const snapshot = new Array(args.length); + for (let i = 0; i < args.length; i++) { + const value = args[i]; + const type = this.argumentTypes[i]; + if (value instanceof WebGPUBufferResult) { + snapshot[i] = { + kind: "buffer", + handle: value + }; + continue; + } + switch (type) { + case "Array": + { + const dims = Array.from(utils.getDimensions(value)); + while (dims.length < 3) dims.push(1); + const flat = new Float32Array(dims[0] * dims[1] * dims[2]); + utils.flattenTo(value, flat); + snapshot[i] = { + kind: "array", + dims: dims, + flat: flat + }; + break; + } + + case "Input": + { + const dims = Array.from(value.size); + while (dims.length < 3) dims.push(1); + const flat = new Float32Array(dims[0] * dims[1] * dims[2]); + utils.flattenTo(value.value, flat); + snapshot[i] = { + kind: "array", + dims: dims, + flat: flat + }; + break; + } + + case "WebGPUBuffer": + snapshot[i] = { + kind: "buffer", + handle: value + }; + break; + + case "Boolean": + snapshot[i] = { + kind: "scalar", + value: value ? 1 : 0 + }; + break; + + default: + snapshot[i] = { + kind: "scalar", + value: value + }; + } + } + return snapshot; + } + run() { + if (!this.built && !this._buildPromise) this.build.apply(this, arguments); + const snapshot = this._snapshotArguments(arguments); + if (!this.built) return this._buildPromise.then(() => this._runInternal(snapshot)); + return this._runInternal(snapshot); + } + _runInternal(snapshot) { + if (this.context && this.context.isLost) throw new Error("WebGPU device was lost; call kernel.destroy() (or gpu.destroy()) and run again to rebuild on a fresh device"); + const device = this._device; + const queue = device.queue; + const {arrayArgs: arrayArgs, scalarArgs: scalarArgs, bufferConstants: bufferConstants} = this.paramsLayout; + const threadDim = this.threadDim = Array.from(this.output); + while (threadDim.length < 3) threadDim.push(1); + this._ensureOutputBuffer(); + this.paramsU32[0] = threadDim[0]; + this.paramsU32[1] = threadDim[1]; + this.paramsU32[2] = threadDim[2]; + this.paramsU32[3] = this._computeDispatch(threadDim).dispatchWidth; + for (let i = 0; i < arrayArgs.length; i++) { + const record = arrayArgs[i]; + const snap = snapshot[record.index]; + let dims; + if (snap.kind === "buffer") { + const handle = snap.handle; + if (handle._deleted) throw new Error(`WebGPUBufferResult passed as argument "${this.argumentNames[record.index]}" has been deleted`); + if (handle.context !== this.context) throw new Error(`WebGPUBufferResult passed as argument "${this.argumentNames[record.index]}" is from a different WebGPU device`); + if (handle.buffer === this.outputBuffer) throw new Error(`WebGPUBufferResult passed as argument "${this.argumentNames[record.index]}" is this kernel's own output buffer; use a second kernel or clone the result`); + if (handle.componentCount !== 1) throw new Error(`WebGPU backend does not yet support Array(${handle.componentCount}) pipeline results as kernel arguments`); + dims = Array.from(handle.output); + while (dims.length < 3) dims.push(1); + if (record.boundBuffer !== handle.buffer) { + record.boundBuffer = handle.buffer; + this.bindGroupDirty = true; + } + } else { + dims = snap.dims; + const byteLength = snap.flat.byteLength; + if (!record.buffer || record.buffer.size < byteLength) { + if (record.buffer) { + if (!this.dynamicArguments) throw new Error(`argument "${this.argumentNames[record.index]}" grew from ${record.buffer.size / 4} to ${snap.flat.length} values; use dynamicArguments: true for varying input sizes`); + record.buffer.destroy(); + } + this._checkBufferSize(byteLength, `argument "${this.argumentNames[record.index]}"`); + record.buffer = device.createBuffer({ + size: byteLength, + usage: 136 + }); + this.bindGroupDirty = true; + } + queue.writeBuffer(record.buffer, 0, snap.flat); + if (record.boundBuffer !== record.buffer) { + record.boundBuffer = record.buffer; + this.bindGroupDirty = true; + } + } + const base = record.dimsOffset / 4; + this.paramsU32[base] = dims[0]; + this.paramsU32[base + 1] = dims[1]; + this.paramsU32[base + 2] = dims[2]; + this.paramsU32[base + 3] = dims[0] * dims[1] * dims[2]; + } + for (let i = 0; i < scalarArgs.length; i++) { + const record = scalarArgs[i]; + const slot = record.offset / 4; + switch (record.type) { + case "Integer": + this.paramsI32[slot] = snapshot[record.index].value; + break; + + case "Boolean": + this.paramsU32[slot] = snapshot[record.index].value; + break; + + default: + this.paramsF32[slot] = snapshot[record.index].value; + } + } + queue.writeBuffer(this.paramsBuffer, 0, this.paramsMirror); + if (this.bindGroupDirty) { + const entries = [ { + binding: 0, + resource: { + buffer: this.paramsBuffer + } + } ]; + for (let i = 0; i < arrayArgs.length; i++) entries.push({ + binding: 1 + i, + resource: { + buffer: arrayArgs[i].boundBuffer + } + }); + const outBinding = 1 + arrayArgs.length; + entries.push({ + binding: outBinding, + resource: { + buffer: this.outputBuffer + } + }); + for (let i = 0; i < bufferConstants.length; i++) entries.push({ + binding: outBinding + 1 + i, + resource: { + buffer: bufferConstants[i].buffer + } + }); + this.bindGroup = device.createBindGroup({ + layout: this.bindGroupLayout, + entries: entries + }); + this.bindGroupDirty = false; + } + const {groups: groups} = this._computeDispatch(threadDim); + const byteLength = threadDim[0] * threadDim[1] * threadDim[2] * 4 * this.componentCount; + const encoder = device.createCommandEncoder(); + const pass = encoder.beginComputePass(); + pass.setPipeline(this.computePipeline); + pass.setBindGroup(0, this.bindGroup); + pass.dispatchWorkgroups(groups[0], groups[1], groups[2]); + pass.end(); + if (this.pipeline) { + queue.submit([ encoder.finish() ]); + return Promise.resolve(new WebGPUBufferResult({ + buffer: this.outputBuffer, + output: Array.from(this.output), + componentCount: this.componentCount, + context: this.context, + kernel: this + })); + } + const staging = this._acquireStaging(byteLength); + encoder.copyBufferToBuffer(this.outputBuffer, 0, staging.buffer, 0, byteLength); + queue.submit([ encoder.finish() ]); + const output = Array.from(this.output); + return staging.buffer.mapAsync(MAP_MODE_READ, 0, byteLength).then(() => { + const data = new Float32Array(staging.buffer.getMappedRange(0, byteLength).slice(0)); + staging.buffer.unmap(); + this._releaseStaging(staging); + return this._shapeOutput(data, output, this.componentCount); + }, error => { + this._releaseStaging(staging); + throw error; + }); + } + _acquireStaging(byteLength) { + for (let i = 0; i < this.stagingPool.length; i++) { + const entry = this.stagingPool[i]; + if (!entry.busy && entry.size >= byteLength) { + entry.busy = true; + return entry; + } + } + const entry = { + buffer: this._device.createBuffer({ + size: byteLength, + usage: 9 + }), + size: byteLength, + busy: true, + pooled: this.stagingPool.length < 3 + }; + if (entry.pooled) this.stagingPool.push(entry); + return entry; + } + _releaseStaging(entry) { + if (entry.pooled) entry.busy = false; else entry.buffer.destroy(); + } + _shapeOutput(data, output, componentCount) { + const [width, height, depth] = [ output[0], output[1] || 1, output[2] || 1 ]; + if (componentCount === 1) switch (output.length) { + case 1: + return utils.erectMemoryOptimizedFloat(data, width); + + case 2: + return utils.erectMemoryOptimized2DFloat(data, width, height); + + default: + return utils.erectMemoryOptimized3DFloat(data, width, height, depth); + } + const n = componentCount; + const erectRow = offset => { + const row = new Array(width); + for (let x = 0; x < width; x++) row[x] = data.subarray(offset + x * n, offset + x * n + n); + return row; + }; + switch (output.length) { + case 1: + return erectRow(0); + + case 2: + { + const rows = new Array(height); + for (let y = 0; y < height; y++) rows[y] = erectRow(y * width * n); + return rows; + } + + default: + { + const layers = new Array(depth); + for (let z = 0; z < depth; z++) { + const rows = new Array(height); + for (let y = 0; y < height; y++) rows[y] = erectRow((z * height + y) * width * n); + layers[z] = rows; + } + return layers; + } + } + } + readBufferResult(handle) { + const device = this._device || handle.context && handle.context.device; + if (!device) return Promise.reject(new Error("no WebGPU device available to read this buffer")); + if (handle.context && handle.context.isLost) return Promise.reject(new Error("WebGPU device was lost; this buffer no longer holds data \u2014 rebuild the producing kernel and run again")); + const output = Array.from(handle.output); + const dims = Array.from(output); + while (dims.length < 3) dims.push(1); + const byteLength = dims[0] * dims[1] * dims[2] * 4 * handle.componentCount; + const staging = this._acquireStaging(byteLength); + const encoder = device.createCommandEncoder(); + encoder.copyBufferToBuffer(handle.buffer, 0, staging.buffer, 0, byteLength); + device.queue.submit([ encoder.finish() ]); + return staging.buffer.mapAsync(MAP_MODE_READ, 0, byteLength).then(() => { + const data = new Float32Array(staging.buffer.getMappedRange(0, byteLength).slice(0)); + staging.buffer.unmap(); + this._releaseStaging(staging); + return this._shapeOutput(data, output, handle.componentCount); + }, error => { + this._releaseStaging(staging); + throw error; + }); + } + destroy(removeCanvasReferences) { + if (this.paramsBuffer) { + this.paramsBuffer.destroy(); + this.paramsBuffer = null; + } + if (this.paramsLayout) for (let i = 0; i < this.paramsLayout.arrayArgs.length; i++) { + const record = this.paramsLayout.arrayArgs[i]; + if (record.buffer) { + record.buffer.destroy(); + record.buffer = null; + } + record.boundBuffer = null; + } + if (this.constantBuffers) { + for (let i = 0; i < this.constantBuffers.length; i++) this.constantBuffers[i].destroy(); + this.constantBuffers = null; + } + for (let i = 0; i < this.stagingPool.length; i++) this.stagingPool[i].buffer.destroy(); + this.stagingPool = []; + if (this.outputBuffer) { + if (--this.outputBuffer._refs === 0) this.outputBuffer.destroy(); + this.outputBuffer = null; + } + this.bindGroup = null; + this.bindGroupLayout = null; + this.computePipeline = null; + this.built = false; + this._buildPromise = null; + if (this.gpu && this.gpu.kernels) { + const index = this.gpu.kernels.indexOf(this); + if (index !== -1) this.gpu.kernels.splice(index, 1); + } + } + }; + module.exports = { + WebGPUKernel: WebGPUKernel + }; + }); + var require_kernel_run_shortcut = __commonJSMin((exports, module) => { + const {utils: utils} = require_utils(); + const {Input: Input} = require_input(); + function kernelRunShortcut(kernel) { + const MAX_SWITCHES = 4; + function syncBody(args) { + kernel.build.apply(kernel, args); + kernel.checkArgumentTypes(args); + let result = kernel.switchingKernels ? void 0 : kernel.run.apply(kernel, args); + for (let i = 0; kernel.switchingKernels; i++) { + if (i >= MAX_SWITCHES) { + const reasons = kernel.resetSwitchingKernels(); + throw new Error(`this kernel cannot run the arguments it was given (${describeReasons(reasons)}); it did not settle on a kernel for them after ${MAX_SWITCHES} attempts. Create a separate kernel for this call's argument types.`); + } + const reasons = kernel.resetSwitchingKernels(); + const newKernel = kernel.onRequestSwitchKernel(reasons, args, kernel); + shortcut.kernel = kernel = newKernel; + newKernel.checkArgumentTypes(args); + result = newKernel.switchingKernels ? void 0 : newKernel.run.apply(newKernel, args); + } + return result; + } + function describeReasons(reasons) { + if (!reasons || !reasons.length) return "unknown reason"; + return reasons.map(reason => { + if (reason.type === "argumentTypeMismatch") return `argument ${reason.index} is now ${reason.needed}`; + return reason.type; + }).join(", "); + } + function syncRun(args) { + const result = syncBody(args); + if (kernel.renderKernels) return kernel.renderKernels(); else if (kernel.renderOutput) return kernel.renderOutput(); else return result; + } + function asyncRun(args) { + if (kernel.onAsyncModeUpgrade) { + const upgrade = kernel.onAsyncModeUpgrade; + kernel.onAsyncModeUpgrade = null; + const snapped = snapshotArguments(args); + return upgrade(snapped, kernel).then(upgradedKernel => { + if (upgradedKernel) shortcut.replaceKernel(upgradedKernel); + return asyncRun(snapped); + }); + } + try { + if (kernel.constructor.isAsync === true) { + kernel.build.apply(kernel, args); + return Promise.resolve(kernel.run.apply(kernel, args)); + } + for (let i = 0; i < args.length; i++) if (isWebGPUHandle(args[i])) return resolveHandles(args).then(resolved => asyncRun(resolved)); + const result = syncBody(args); + if (kernel.renderKernels) return Promise.resolve(kernel.renderKernels()); else if (kernel.renderOutput) { + if (kernel.renderOutputAsync) return kernel.renderOutputAsync(); + return Promise.resolve(kernel.renderOutput()); + } else return Promise.resolve(result); + } catch (e) { + return Promise.reject(e); + } + } + function isWebGPUHandle(value) { + return Boolean(value) && value.type === "WebGPUBuffer"; + } + function resolveHandles(args) { + const snapped = snapshotArguments(args); + const pending = []; + for (let i = 0; i < snapped.length; i++) if (isWebGPUHandle(snapped[i])) { + const index = i; + pending.push(Promise.resolve(snapped[index].toArray()).then(value => { + snapped[index] = value; + })); + } + return Promise.all(pending).then(() => snapped); + } + function snapshotArguments(args) { + const copy = new Array(args.length); + for (let i = 0; i < args.length; i++) copy[i] = snapshotValue(args[i]); + return copy; + } + function snapshotValue(value) { + if (!value || typeof value !== "object") return value; + if (isWebGPUHandle(value) || typeof value.delete === "function") return value; + if (ArrayBuffer.isView(value)) return value.slice(0); + if (Array.isArray(value)) return value.map(snapshotValue); + if (value instanceof Input) return new Input(snapshotValue(value.value), value.size); + return value; + } + function run() { + if (kernel.constructor.isAsync === true || kernel.asyncMode === true) return asyncRun(arguments); + return syncRun(arguments); + } + const shortcut = function() { + return run.apply(kernel, arguments); + }; + shortcut.exec = function() { + return new Promise((accept, reject) => { + try { + accept(run.apply(this, arguments)); + } catch (e) { + reject(e); + } + }); + }; + shortcut.replaceKernel = function(replacementKernel) { + kernel = replacementKernel; + bindKernelToShortcut(kernel, shortcut); + }; + bindKernelToShortcut(kernel, shortcut); + return shortcut; + } + function bindKernelToShortcut(kernel, shortcut) { + if (shortcut.kernel) { + shortcut.kernel = kernel; + return; + } + const properties = utils.allPropertiesOf(kernel); + for (let i = 0; i < properties.length; i++) { + const property = properties[i]; + if (property[0] === "_" && property[1] === "_") continue; + if (typeof kernel[property] === "function") if (property.substring(0, 3) === "add" || property.substring(0, 3) === "set") shortcut[property] = function() { + shortcut.kernel[property].apply(shortcut.kernel, arguments); + return shortcut; + }; else shortcut[property] = function() { + return shortcut.kernel[property].apply(shortcut.kernel, arguments); + }; else { + shortcut.__defineGetter__(property, () => shortcut.kernel[property]); + shortcut.__defineSetter__(property, value => { + shortcut.kernel[property] = value; + }); + } + } + shortcut.kernel = kernel; + } + module.exports = { + kernelRunShortcut: kernelRunShortcut + }; + }); + var require_gpu = __commonJSMin((exports, module) => { + const {gpuMock: gpuMock} = require_gpu_mock_js(); + const {utils: utils} = require_utils(); + const {Kernel: Kernel} = require_kernel$6(); + const {CPUKernel: CPUKernel} = require_kernel$5(); + const {HeadlessGLKernel: HeadlessGLKernel} = require_kernel$2(); + const {WebGL2Kernel: WebGL2Kernel} = require_kernel$1(); + const {WebGLKernel: WebGLKernel} = require_kernel$3(); + const {WebGPUKernel: WebGPUKernel} = require_kernel(); + const {kernelRunShortcut: kernelRunShortcut} = require_kernel_run_shortcut(); + const kernelOrder = [ HeadlessGLKernel, WebGL2Kernel, WebGLKernel ]; + const kernelTypes = [ "gpu", "cpu" ]; + const internalKernels = { + headlessgl: HeadlessGLKernel, + webgl2: WebGL2Kernel, + webgl: WebGLKernel, + webgpu: WebGPUKernel + }; + let validate = true; + var GPU = class GPU { + static disableValidation() { + validate = false; + } + static enableValidation() { + validate = true; + } + static get isGPUSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported); + } + static get isKernelMapSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap); + } + static get isOffscreenCanvasSupported() { + return typeof Worker !== "undefined" && typeof OffscreenCanvas !== "undefined" || typeof importScripts !== "undefined"; + } + static get isWebGLSupported() { + return WebGLKernel.isSupported; + } + static get isWebGL2Supported() { + return WebGL2Kernel.isSupported; + } + static get isHeadlessGLSupported() { + return HeadlessGLKernel.isSupported; + } + static get isWebGPUSupported() { + return WebGPUKernel.isSupported; + } + static isWebGPUAvailable() { + if (!WebGPUKernel.isSupported) return Promise.resolve(false); + return navigator.gpu.requestAdapter().then(adapter => adapter !== null, () => false); + } + static get isCanvasSupported() { + return typeof HTMLCanvasElement !== "undefined"; + } + static get isGPUHTMLImageArraySupported() { + return WebGL2Kernel.isSupported; + } + static get isSinglePrecisionSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); + } + constructor(settings) { + settings = settings || {}; + this.canvas = settings.canvas || null; + this.context = settings.context || null; + this.mode = settings.mode; + this.Kernel = null; + this.kernels = []; + this.functions = []; + this.nativeFunctions = []; + this.injectedNative = null; + if (this.mode === "dev") return; + this.chooseKernel(); + if (settings.functions) for (let i = 0; i < settings.functions.length; i++) this.addFunction(settings.functions[i]); + if (settings.nativeFunctions) for (const p in settings.nativeFunctions) { + if (!settings.nativeFunctions.hasOwnProperty(p)) continue; + const s = settings.nativeFunctions[p]; + const {name: name, source: source} = s; + this.addNativeFunction(name, source, s); + } + } + chooseKernel() { + if (this.Kernel) return; + let Kernel = null; + if (this.context) { + for (let i = 0; i < kernelOrder.length; i++) { + const ExternalKernel = kernelOrder[i]; + if (ExternalKernel.isContextMatch(this.context)) { + if (!ExternalKernel.isSupported) throw new Error(`Kernel type ${ExternalKernel.name} not supported`); + Kernel = ExternalKernel; + break; + } + } + if (Kernel === null) throw new Error("unknown Context"); + } else if (this.mode) { + if (this.mode in internalKernels) { + if (!validate || internalKernels[this.mode].isSupported) Kernel = internalKernels[this.mode]; + } else if (this.mode === "gpu") { + for (let i = 0; i < kernelOrder.length; i++) if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } + } else if (this.mode === "async") { + for (let i = 0; i < kernelOrder.length; i++) if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } + if (!Kernel) Kernel = CPUKernel; + } else if (this.mode === "cpu") Kernel = CPUKernel; + if (!Kernel) throw new Error(`A requested mode of "${this.mode}" and is not supported`); + } else { + for (let i = 0; i < kernelOrder.length; i++) if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } + if (!Kernel) Kernel = CPUKernel; + } + if (!this.mode) this.mode = Kernel.mode; + this.Kernel = Kernel; + } + createKernel(source, settings) { + if (typeof source === "undefined") throw new Error("Missing source parameter"); + if (typeof source !== "object" && !utils.isFunction(source) && typeof source !== "string") throw new Error("source parameter not a function"); + const kernels = this.kernels; + if (this.mode === "dev") { + const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); + kernels.push(devKernel); + return devKernel; } source = typeof source === "function" ? source.toString() : source; const switchableKernels = {}; @@ -11255,7 +13483,8 @@ subKernels: kernelRun.subKernels, strictIntegers: kernelRun.strictIntegers, randomSeed: kernelRun.randomSeed, - debug: kernelRun.debug + debug: kernelRun.debug, + asyncMode: kernelRun.asyncMode }); fallbackKernel.build.apply(fallbackKernel, args); const result = fallbackKernel.run.apply(fallbackKernel, args); @@ -11301,6 +13530,7 @@ strictIntegers: _kernel.strictIntegers, randomSeed: _kernel.randomSeed, debug: _kernel.debug, + asyncMode: _kernel.asyncMode, gpu: _kernel.gpu, validate: validate, returnType: _kernel.returnType, @@ -11327,8 +13557,56 @@ onRequestFallback: onRequestFallback, onRequestSwitchKernel: onRequestSwitchKernel }, settingsCopy); + if (this.mode === "async") mergedSettings.asyncMode = true; const kernel = new this.Kernel(source, mergedSettings); const kernelRun = kernelRunShortcut(kernel); + if (this.mode === "async" && WebGPUKernel.isSupported && !(kernel instanceof WebGPUKernel)) { + const gpu = this; + kernel.onAsyncModeUpgrade = function onAsyncModeUpgrade(args, currentKernel) { + return GPU.isWebGPUAvailable().then(available => { + if (!available) return null; + let webGPUKernel; + try { + webGPUKernel = new WebGPUKernel(source, { + functions: currentKernel.functions, + nativeFunctions: currentKernel.nativeFunctions, + injectedNative: currentKernel.injectedNative, + gpu: gpu, + validate: validate, + asyncMode: true, + output: currentKernel.output, + pipeline: currentKernel.pipeline, + immutable: currentKernel.immutable, + dynamicOutput: currentKernel.dynamicOutput, + dynamicArguments: true, + loopMaxIterations: currentKernel.loopMaxIterations, + constants: currentKernel.constants, + constantTypes: currentKernel.constantTypes, + argumentTypes: currentKernel.argumentTypes, + precision: currentKernel.precision, + tactic: currentKernel.tactic, + strictIntegers: currentKernel.strictIntegers, + fixIntegerDivisionAccuracy: currentKernel.fixIntegerDivisionAccuracy, + subKernels: currentKernel.subKernels, + graphical: currentKernel.graphical, + debug: currentKernel.debug + }); + webGPUKernel.build.apply(webGPUKernel, args); + } catch (e) { + if (currentKernel.debug) console.warn("webgpu upgrade declined: " + e.message); + return null; + } + return webGPUKernel._buildPromise.then(() => { + kernels.push(webGPUKernel); + return webGPUKernel; + }, e => { + if (currentKernel.debug) console.warn("webgpu upgrade declined: " + e.message); + webGPUKernel.destroy(); + return null; + }); + }, () => null); + }; + } if (!this.canvas) this.canvas = kernel.canvas; if (!this.context) this.context = kernel.context; kernels.push(kernel); @@ -11344,6 +13622,7 @@ } else fn = arguments[arguments.length - 1]; if (this.mode !== "dev") { if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) { + if (this.Kernel.mode === "webgpu") throw new Error("WebGPU backend does not yet support createKernelMap"); if (this.mode && kernelTypes.indexOf(this.mode) < 0) throw new Error(`kernelMap not supported on ${this.Kernel.name}`); } } @@ -11380,7 +13659,9 @@ combineKernels() { const firstKernel = arguments[0]; const combinedKernel = arguments[arguments.length - 1]; + if (this.mode === "async" || firstKernel.kernel.asyncMode) throw new Error(`mode 'async' does not yet support combineKernels; chain kernels with \`await\` and pipeline mode instead`); if (firstKernel.kernel.constructor.mode === "cpu") return combinedKernel; + if (firstKernel.kernel.constructor.mode === "webgpu") throw new Error("WebGPU backend does not yet support combineKernels; chain kernels with `await` and pipeline mode instead"); const canvas = arguments[0].canvas; const context = arguments[0].context; const max = arguments.length - 1; @@ -11482,18 +13763,22 @@ const {Input: Input, input: input} = require_input(); const {Texture: Texture} = require_texture$1(); const {FunctionBuilder: FunctionBuilder} = require_function_builder(); - const {FunctionNode: FunctionNode} = require_function_node$3(); - const {CPUFunctionNode: CPUFunctionNode} = require_function_node$2(); - const {CPUKernel: CPUKernel} = require_kernel$4(); - const {HeadlessGLKernel: HeadlessGLKernel} = require_kernel$1(); - const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$1(); - const {WebGLKernel: WebGLKernel} = require_kernel$2(); + const {FunctionNode: FunctionNode} = require_function_node$4(); + const {CPUFunctionNode: CPUFunctionNode} = require_function_node$3(); + const {CPUKernel: CPUKernel} = require_kernel$5(); + const {HeadlessGLKernel: HeadlessGLKernel} = require_kernel$2(); + const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$2(); + const {WebGLKernel: WebGLKernel} = require_kernel$3(); const {kernelValueMaps: webGLKernelValueMaps} = require_kernel_value_maps$1(); - const {WebGL2FunctionNode: WebGL2FunctionNode} = require_function_node(); - const {WebGL2Kernel: WebGL2Kernel} = require_kernel(); + const {WebGL2FunctionNode: WebGL2FunctionNode} = require_function_node$1(); + const {WebGL2Kernel: WebGL2Kernel} = require_kernel$1(); const {kernelValueMaps: webGL2KernelValueMaps} = require_kernel_value_maps(); - const {GLKernel: GLKernel} = require_kernel$3(); - const {Kernel: Kernel} = require_kernel$5(); + const {WGSLFunctionNode: WGSLFunctionNode} = require_function_node(); + const {WebGPUKernel: WebGPUKernel} = require_kernel(); + const {WebGPUContext: WebGPUContext} = require_context(); + const {WebGPUBufferResult: WebGPUBufferResult} = require_buffer_result(); + const {GLKernel: GLKernel} = require_kernel$4(); + const {Kernel: Kernel} = require_kernel$6(); const {FunctionTracer: FunctionTracer} = require_function_tracer(); module.exports = { alias: alias, @@ -11513,6 +13798,10 @@ WebGLFunctionNode: WebGLFunctionNode, WebGLKernel: WebGLKernel, webGLKernelValueMaps: webGLKernelValueMaps, + WGSLFunctionNode: WGSLFunctionNode, + WebGPUKernel: WebGPUKernel, + WebGPUContext: WebGPUContext, + WebGPUBufferResult: WebGPUBufferResult, GLKernel: GLKernel, Kernel: Kernel, FunctionTracer: FunctionTracer, diff --git a/dist/gpu-browser-core.min.js b/dist/gpu-browser-core.min.js index de6dd9e1..6ffe6c91 100644 --- a/dist/gpu-browser-core.min.js +++ b/dist/gpu-browser-core.min.js @@ -1,11 +1,11 @@ /** * gpu.js - * http://gpu.rocks/ + * https://gpu.rocks/ * * GPU Accelerated JavaScript * * @version 2.19.9 - * @date Wed Jul 29 2026 05:05:57 GMT+0800 (Singapore Standard Time) + * @date Thu Jul 30 2026 13:21:39 GMT+0800 (Singapore Standard Time) * * @license MIT * The MIT License @@ -13,16 +13,16 @@ * Copyright (c) 2026 gpu.js Team *//** * gpu.js - * http://gpu.rocks/ + * https://gpu.rocks/ * * GPU Accelerated JavaScript * * @version 2.19.9 - * @date Wed Jul 29 2026 05:05:56 GMT+0800 (Singapore Standard Time) + * @date Thu Jul 30 2026 13:21:38 GMT+0800 (Singapore Standard Time) * * @license MIT * The MIT License * * Copyright (c) 2026 gpu.js Team */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):(e="undefined"!=typeof globalThis?globalThis:e||self).GPU=t()}(this,function(){var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),t=e((e,t)=>{function n(e){const t=new Array(e.length);for(let n=0;n{e.output=l(t),e.graphical&&u(e)},e.toJSON=()=>{throw new Error("Not usable with gpuMock")},e.setConstants=t=>(e.constants=t,e),e.setGraphical=t=>(e.graphical=t,e),e.setCanvas=t=>(e.canvas=t,e),e.setContext=t=>(e.context=t,e),e.destroy=()=>{},e.validateSettings=()=>{},e.graphical&&e.output&&u(e),e.exec=function(){return new Promise((t,n)=>{try{t(e.apply(e,arguments))}catch(e){n(e)}})},e.getPixels=t=>{const{x:n,y:r}=e.output;return t?function(e,t,n){const r=n/2|0,s=4*t,i=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee,n=["setWarnVarUsage","setArgumentTypes","setTactic","setOptimizeFloatMemory","setDebug","setLoopMaxIterations","setConstantTypes","setFunctions","setNativeFunctions","setInjectedNative","setPipeline","setPrecision","setOutputToTexture","setImmutable","setStrictIntegers","setDynamicOutput","setHardcodeConstants","setDynamicArguments","setUseLegacyEncoder","setWarnVarUsage","addSubKernel"];for(let r=0;r{t.exports={}}),r=e((e,t)=>{var n=class{constructor(e,t){this.value=e,Array.isArray(t)?this.size=t:(this.size=new Int32Array(3),t.z?this.size=new Int32Array([t.x,t.y,t.z]):t.y?this.size=new Int32Array([t.x,t.y]):this.size=new Int32Array([t.x]));const[n,r,s]=this.size;if(s){if(this.value.length!==n*r*s)throw new Error(`Input size ${this.value.length} does not match ${n} * ${r} * ${s} = ${r*n*s}`)}else if(r){if(this.value.length!==n*r)throw new Error(`Input size ${this.value.length} does not match ${n} * ${r} = ${r*n}`)}else if(this.value.length!==n)throw new Error(`Input size ${this.value.length} does not match ${n}`)}toArray(){const{utils:e}=i(),[t,n,r]=this.size;return r?e.erectMemoryOptimized3DFloat(this.value.subarray?this.value:new Float32Array(this.value),t,n,r):n?e.erectMemoryOptimized2DFloat(this.value.subarray?this.value:new Float32Array(this.value),t,n):this.value}};t.exports={Input:n,input:function(e,t){return new n(e,t)}}}),s=e((e,t)=>{t.exports={Texture:class{constructor(e){const{texture:t,size:n,dimensions:r,output:s,context:i,type:a="NumberTexture",kernel:o,internalFormat:u,textureFormat:l}=e;if(!s)throw new Error('settings property "output" required.');if(!i)throw new Error('settings property "context" required.');if(!t)throw new Error('settings property "texture" required.');if(!o)throw new Error('settings property "kernel" required.');this.texture=t,t._refs?t._refs++:t._refs=1,this.size=n,this.dimensions=r,this.output=s,this.context=i,this.kernel=o,this.type=a,this._deleted=!1,this.internalFormat=u,this.textureFormat=l}toArray(){throw new Error(`Not implemented on ${this.constructor.name}`)}clone(){throw new Error(`Not implemented on ${this.constructor.name}`)}delete(){throw new Error(`Not implemented on ${this.constructor.name}`)}clear(){throw new Error(`Not implemented on ${this.constructor.name}`)}}}}),i=e((e,t)=>{const i=n(),{Input:a}=r(),{Texture:o}=s(),u=/function ([^(]*)/,l=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,h=/([^\s,]+)/g,c={systemEndianness:()=>g,getSystemEndianness(){const e=new ArrayBuffer(4),t=new Uint32Array(e),n=new Uint8Array(e);if(t[0]=3735928559,239===n[0])return"LE";if(222===n[0])return"BE";throw new Error("unknown endianness")},isFunction:e=>"function"==typeof e,isFunctionString:e=>"string"==typeof e&&"function"===e.slice(0,8).toLowerCase(),getFunctionNameFromString(e){const t=u.exec(e);return t&&0!==t.length?t[1].trim():null},getFunctionBodyFromString:e=>e.substring(e.indexOf("{")+1,e.lastIndexOf("}")),getArgumentNamesFromString(e){const t=e.replace(l,"");let n=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(h);return null===n&&(n=[]),n},clone(e){if(null===e||"object"!=typeof e||e.hasOwnProperty("isActiveClone"))return e;const t=e.constructor();for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&(e.isActiveClone=null,t[n]=c.clone(e[n]),delete e.isActiveClone);return t},isArray:e=>!isNaN(e.length),getVariableType(e,t){if(c.isArray(e))return e.length>0&&"IMG"===e[0].nodeName?"HTMLImageArray":"Array";switch(e.constructor){case Boolean:return"Boolean";case Number:return t&&Number.isInteger(e)?"Integer":"Float";case o:return e.type;case a:return"Input"}if("nodeName"in e)switch(e.nodeName){case"IMG":case"CANVAS":return"HTMLImage";case"VIDEO":return"HTMLVideo"}else{if(e.hasOwnProperty("type"))return e.type;if("undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return"OffscreenCanvas";if("undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap)return"ImageBitmap";if("undefined"!=typeof ImageData&&e instanceof ImageData)return"ImageData"}return"Unknown"},getKernelTextureSize(e,t){let[n,r,s]=t,i=(n||1)*(r||1)*(s||1);return e.optimizeFloatMemory&&"single"===e.precision&&(n=i=Math.ceil(i/4)),r>1&&n*r===i?new Int32Array([n,r]):c.closestSquareDimensions(i)},closestSquareDimensions(e){const t=Math.sqrt(e);let n=Math.ceil(t),r=Math.floor(t);for(;n*rMath.floor((e+t-1)/t)*t,getDimensions(e,t){let n;if(c.isArray(e)){const t=[];let r=e;for(;c.isArray(r);)t.push(r.length),r=r[0];n=t.reverse()}else if(e instanceof o)n=e.output;else{if(!(e instanceof a))throw new Error(`Unknown dimensions of ${e}`);n=e.size}if(t)for(n=Array.from(n);n.length<3;)n.push(1);return new Int32Array(n)},flatten2dArrayTo(e,t){let n=0;for(let r=0;re.length>0?e.join(";\n")+";\n":"\n",warnDeprecated(e,t,n){n?console.warn(`You are using a deprecated ${e} "${t}". It has been replaced with "${n}". Fixing, but please upgrade as it will soon be removed.`):console.warn(`You are using a deprecated ${e} "${t}". It has been removed. Fixing, but please upgrade as it will soon be removed.`)},flipPixels:(e,t,n)=>{const r=n/2|0,s=4*t,i=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee.subarray(0,t),erect2DPackedFloat:(e,t,n)=>{const r=new Array(n);for(let s=0;s{const s=new Array(r);for(let i=0;ie.subarray(0,t),erectMemoryOptimized2DFloat:(e,t,n)=>{const r=new Array(n);for(let s=0;s{const s=new Array(r);for(let i=0;i{const n=new Float32Array(t);let r=0;for(let s=0;s{const r=new Array(n);let s=0;for(let i=0;i{const s=new Array(r);let i=0;for(let a=0;a{const n=new Array(t),r=4*t;let s=0;for(let t=0;t{const r=new Array(n),s=4*t;for(let i=0;i{const s=4*t,i=new Array(r);for(let a=0;a{const n=new Array(t),r=4*t;let s=0;for(let t=0;t{const r=4*t,s=new Array(n);for(let i=0;i{const s=4*t,i=new Array(r);for(let a=0;a{const n=new Array(e),r=4*t;let s=0;for(let t=0;t{const r=4*t,s=new Array(n);for(let i=0;i{const s=4*t,i=new Array(r);for(let a=0;a{const{findDependency:n,thisLookup:r,doNotDefine:s}=t;let a=t.flattened;a||(a=t.flattened={});const o=i.parse(e,{ecmaVersion:2020}),u=[];let l=0;const h=function e(t){if(Array.isArray(t)){const n=[];for(let r=0;rnull!==e);return s.length<1?"":`${t.kind} ${s.join(",")}`;case"VariableDeclarator":return t.init?t.init.object&&"ThisExpression"===t.init.object.type?r(t.init.property.name,!0)?`${t.id.name} = ${e(t.init)}`:null:`${t.id.name} = ${e(t.init)}`:t.id.name;case"CallExpression":if("subarray"===t.callee.property.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("gl"===t.callee.object.name||"context"===t.callee.object.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("ThisExpression"===t.callee.object.type)return u.push(n("this",t.callee.property.name)),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;if(t.callee.object.name){const r=n(t.callee.object.name,t.callee.property.name);return null===r?`${t.callee.object.name}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`:(u.push(r),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`)}if("MemberExpression"===t.callee.object.type)return`${e(t.callee.object)}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;throw new Error("unknown ast.callee");case"ReturnStatement":return`return ${e(t.argument)}`;case"BinaryExpression":return`(${e(t.left)}${t.operator}${e(t.right)})`;case"UnaryExpression":return t.prefix?`${t.operator} ${e(t.argument)}`:`${e(t.argument)} ${t.operator}`;case"ExpressionStatement":return`${e(t.expression)}`;case"SequenceExpression":return`(${e(t.expressions)})`;case"ArrowFunctionExpression":return`(${t.params.map(e).join(", ")}) => ${e(t.body)}`;case"Literal":return t.raw;case"Identifier":return t.name;case"MemberExpression":return"ThisExpression"===t.object.type?r(t.property.name):t.computed?`${e(t.object)}[${e(t.property)}]`:e(t.object)+"."+e(t.property);case"ThisExpression":return"this";case"NewExpression":return`new ${e(t.callee)}(${t.arguments.map(t=>e(t)).join(", ")})`;case"ForStatement":return`for (${e(t.init)};${e(t.test)};${e(t.update)}) ${e(t.body)}`;case"AssignmentExpression":return`${e(t.left)}${t.operator}${e(t.right)}`;case"UpdateExpression":return`${e(t.argument)}${t.operator}`;case"IfStatement":{const n=e(t.consequent);if(!t.alternate)return`if (${e(t.test)}) ${n}`;const r="BlockStatement"===t.consequent.type?"":";";return`if (${e(t.test)}) ${n}${r} else ${e(t.alternate)}`}case"ThrowStatement":return`throw ${e(t.argument)}`;case"ObjectPattern":return t.properties.map(e).join(", ");case"ArrayPattern":return t.elements.map(e).join(", ");case"DebuggerStatement":return"debugger;";case"ConditionalExpression":return`${e(t.test)}?${e(t.consequent)}:${e(t.alternate)}`;case"Property":if("init"===t.kind)return e(t.key)}throw new Error(`unhandled ast.type of ${t.type}`)}(o);if(u.length>0){const e=[];for(let n=0;n{if("VariableDeclaration"!==e.type)throw new Error('Ast is not of type "VariableDeclaration"');const t=[];for(let n=0;n{const n=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].r},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),r=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].g},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),s=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].b},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),i=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].a},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),a=[n(t),r(t),s(t),i(t)];return a.rKernel=n,a.gKernel=r,a.bKernel=s,a.aKernel=i,a.gpu=e,a},splitRGBAToCanvases:(e,t,n,r)=>{const s=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(t.r/255,0,0,255)},{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});s(t);const i=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(0,t.g/255,0,255)},{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});i(t);const a=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(0,0,t.b/255,255)},{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});a(t);const o=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(255,255,255,t.a/255)},{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});return o(t),[s.canvas,i.canvas,a.canvas,o.canvas]},getMinifySafeName:e=>{try{const{init:t}=i.parse(`const value = ${e.toString()}`,{ecmaVersion:2020}).body[0].declarations[0];return t.body.name||t.body.body[0].argument.name}catch(e){throw new Error("Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }")}},sanitizeName:function(e){return p.test(e)&&(e=e.replace(p,"S_S")),m.test(e)?e=e.replace(m,"U_U"):d.test(e)&&(e=e.replace(d,"u_u")),e}},p=/\$/,m=/__/,d=/_/,g=c.getSystemEndianness();t.exports={utils:c}}),a=e((e,t)=>{const{utils:n}=i(),{Input:s}=r();t.exports={Kernel:class{static get isSupported(){throw new Error(`"isSupported" not implemented on ${this.name}`)}static isContextMatch(e){throw new Error(`"isContextMatch" not implemented on ${this.name}`)}static getFeatures(){throw new Error(`"getFeatures" not implemented on ${this.name}`)}static destroyContext(e){throw new Error(`"destroyContext" called on ${this.name}`)}static nativeFunctionArguments(){throw new Error(`"nativeFunctionArguments" called on ${this.name}`)}static nativeFunctionReturnType(){throw new Error(`"nativeFunctionReturnType" called on ${this.name}`)}static combineKernels(){throw new Error(`"combineKernels" called on ${this.name}`)}constructor(e,t){if("object"!=typeof e){if("string"!=typeof e)throw new Error("source not a string");if(!n.isFunctionString(e))throw new Error("source not a function string")}this.useLegacyEncoder=!1,this.fallbackRequested=!1,this.onRequestFallback=null,this.argumentNames="string"==typeof e?n.getArgumentNamesFromString(e):null,this.argumentTypes=null,this.argumentSizes=null,this.argumentBitRatios=null,this.kernelArguments=null,this.kernelConstants=null,this.forceUploadKernelConstants=null,this.source=e,this.output=null,this.debug=!1,this.graphical=!1,this.loopMaxIterations=0,this.constants=null,this.constantTypes=null,this.constantBitRatios=null,this.dynamicArguments=!1,this.dynamicOutput=!1,this.canvas=null,this.context=null,this.checkContext=null,this.gpu=null,this.functions=null,this.nativeFunctions=null,this.injectedNative=null,this.subKernels=null,this.validate=!0,this.immutable=!1,this.pipeline=!1,this.precision=null,this.tactic=null,this.plugins=null,this.returnType=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.optimizeFloatMemory=null,this.strictIntegers=!1,this.fixIntegerDivisionAccuracy=null,this.randomSeed=null,this.built=!1,this.signature=null}mergeSettings(e){for(let t in e)if(e.hasOwnProperty(t)&&this.hasOwnProperty(t)){switch(t){case"output":if(!Array.isArray(e.output)){this.setOutput(e.output);continue}break;case"functions":this.functions=[];for(let t=0;te.name):null,returnType:this.returnType}}}buildSignature(e){const t=this.constructor;this.signature=t.getSignature(this,t.getArgumentTypes(this,e))}static getArgumentTypes(e,t){const r=new Array(t.length);for(let s=0;st.argumentTypes[e])||[]:t.argumentTypes||[],{name:n.getFunctionNameFromString(r)||null,source:r,argumentTypes:s,returnType:t.returnType||null}}onActivate(e){}}}}),o=e((e,t)=>{t.exports={FunctionBuilder:class e{static fromKernel(t,n,r){const{kernelArguments:s,kernelConstants:i,argumentNames:a,argumentSizes:o,argumentBitRatios:u,constants:l,constantBitRatios:h,debug:c,loopMaxIterations:p,nativeFunctions:m,output:d,optimizeFloatMemory:g,precision:f,plugins:x,source:y,subKernels:T,functions:b,leadingReturnStatement:S,followingReturnStatement:A,dynamicArguments:E,dynamicOutput:_}=t,v=new Array(s.length),w={};for(let e=0;eU.needsArgumentType(e,t),I=(e,t,n)=>{U.assignArgumentType(e,t,n)},$=(e,t,n)=>U.lookupReturnType(e,t,n),F=e=>U.lookupFunctionArgumentTypes(e),R=(e,t)=>U.lookupFunctionArgumentName(e,t),L=(e,t)=>U.lookupFunctionArgumentBitRatio(e,t),z=(e,t,n,r)=>{U.assignArgumentType(e,t,n,r)},C=(e,t,n,r)=>{U.assignArgumentBitRatio(e,t,n,r)},M=(e,t,n)=>{U.trackFunctionCall(e,t,n)},N=(e,t)=>{const r=[];for(let t=0;tnew n(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:d,plugins:x,constants:l,constantTypes:w,constantBitRatios:h,optimizeFloatMemory:g,precision:f,lookupReturnType:$,lookupFunctionArgumentTypes:F,lookupFunctionArgumentName:R,lookupFunctionArgumentBitRatio:L,needsArgumentType:D,assignArgumentType:I,triggerImplyArgumentType:z,triggerImplyArgumentBitRatio:C,onFunctionCall:M,onNestedFunction:N})));let G=null;T&&(G=T.map(e=>{const{name:t,source:r}=e;return new n(r,Object.assign({},V,{name:t,isSubKernel:!0,isRootKernel:!1}))}));const U=new e({kernel:t,rootNode:k,functionNodes:K,nativeFunctions:m,subKernelNodes:G});return U}constructor(e){if(e=e||{},this.kernel=e.kernel,this.rootNode=e.rootNode,this.functionNodes=e.functionNodes||[],this.subKernelNodes=e.subKernelNodes||[],this.nativeFunctions=e.nativeFunctions||[],this.functionMap={},this.nativeFunctionNames=[],this.lookupChain=[],this.functionNodeDependencies={},this.functionCalls={},this.rootNode&&(this.functionMap.kernel=this.rootNode),this.functionNodes)for(let e=0;e-1){const n=t.indexOf(e);if(-1===n)t.push(e);else{const e=t.splice(n,1)[0];t.push(e)}return t}const n=this.functionMap[e];if(n){const r=t.indexOf(e);if(-1===r){t.push(e),n.toString();for(let e=0;e-1){t.push(this.nativeFunctions[s].source);continue}const i=this.functionMap[r];i&&t.push(i.toString())}return t}toJSON(){return this.traceFunctionCalls(this.rootNode.name).reverse().map(e=>{const t=this.nativeFunctions.indexOf(e);if(t>-1)return{name:e,source:this.nativeFunctions[t].source};if(this.functionMap[e])return this.functionMap[e].toJSON();throw new Error(`function ${e} not found`)})}fromJSON(e,t){this.functionMap={};for(let n=0;n0){const s=t.arguments;for(let t=0;t{const{utils:n}=i();function r(e){return e.length>0?e[e.length-1]:null}const s="trackIdentifiers",a="memberExpression",o="inForLoopInit";t.exports={FunctionTracer:class{constructor(e){this.runningContexts=[],this.functionContexts=[],this.contexts=[],this.functionCalls=[],this.declarations=[],this.identifiers=[],this.functions=[],this.returnStatements=[],this.trackedIdentifiers=null,this.states=[],this.newFunctionContext(),this.scan(e)}isState(e){return this.states[this.states.length-1]===e}hasState(e){return this.states.indexOf(e)>-1}pushState(e){this.states.push(e)}popState(e){if(!this.isState(e))throw new Error(`Cannot pop the non-active state "${e}"`);this.states.pop()}get currentFunctionContext(){return r(this.functionContexts)}get currentContext(){return r(this.runningContexts)}newFunctionContext(){const e={"@contextType":"function"};this.contexts.push(e),this.functionContexts.push(e)}newContext(e){const t=Object.assign({"@contextType":"const/let"},this.currentContext);this.contexts.push(t),this.runningContexts.push(t),e();const{currentFunctionContext:n}=this;for(const e in n)n.hasOwnProperty(e)&&!t.hasOwnProperty(e)&&(t[e]=n[e]);return this.runningContexts.pop(),t}useFunctionContext(e){const t=r(this.functionContexts);this.runningContexts.push(t),e(),this.runningContexts.pop()}getIdentifiers(e){const t=this.trackedIdentifiers=[];return this.pushState(s),e(),this.trackedIdentifiers=null,this.popState(s),t}getDeclaration(e){const{currentContext:t,currentFunctionContext:n,runningContexts:r}=this,s=t[e]||n[e]||null;if(!s&&t===n&&r.length>0){const t=r[r.length-2];if(t[e])return t[e]}return s}scan(e){if(e)if(Array.isArray(e))for(let t=0;t{this.scan(e.body)});break;case"BlockStatement":this.newContext(()=>{this.scan(e.body)});break;case"AssignmentExpression":case"LogicalExpression":case"BinaryExpression":this.scan(e.left),this.scan(e.right);break;case"UpdateExpression":if("++"===e.operator){const t=this.getDeclaration(e.argument.name);t&&(t.suggestedType="Integer")}this.scan(e.argument);break;case"UnaryExpression":this.scan(e.argument);break;case"VariableDeclaration":"var"===e.kind?this.useFunctionContext(()=>{e.declarations=n.normalizeDeclarations(e),this.scan(e.declarations)}):(e.declarations=n.normalizeDeclarations(e),this.scan(e.declarations));break;case"VariableDeclarator":{const{currentContext:t}=this,n=this.hasState(o),r={ast:e,context:t,name:e.id.name,origin:"declaration",inForLoopInit:n,inForLoopTest:null,assignable:t===this.currentFunctionContext||!n&&!t.hasOwnProperty(e.id.name),suggestedType:null,valueType:null,dependencies:null,isSafe:null};t[e.id.name]||(t[e.id.name]=r),this.declarations.push(r),this.scan(e.id),this.scan(e.init);break}case"FunctionExpression":case"FunctionDeclaration":0===this.runningContexts.length?this.scan(e.body):this.functions.push(e);break;case"IfStatement":this.scan(e.test),this.scan(e.consequent),e.alternate&&this.scan(e.alternate);break;case"ForStatement":{let t;const n=this.newContext(()=>{this.pushState(o),this.scan(e.init),this.popState(o),t=this.getIdentifiers(()=>{this.scan(e.test)}),this.scan(e.update),this.newContext(()=>{this.scan(e.body)})});if(t)for(const e in n)"@contextType"!==e&&t.indexOf(e)>-1&&(n[e].inForLoopTest=!0);break}case"DoWhileStatement":case"WhileStatement":this.newContext(()=>{this.scan(e.body),this.scan(e.test)});break;case"Identifier":this.isState(s)&&this.trackedIdentifiers.push(e.name),this.identifiers.push({context:this.currentContext,declaration:this.getDeclaration(e.name),ast:e});break;case"ReturnStatement":this.returnStatements.push(e),this.scan(e.argument);break;case"MemberExpression":this.pushState(a),this.scan(e.object),this.scan(e.property),this.popState(a);break;case"ExpressionStatement":this.scan(e.expression);break;case"SequenceExpression":this.scan(e.expressions);break;case"CallExpression":this.functionCalls.push({context:this.currentContext,ast:e}),this.scan(e.arguments);break;case"ArrayExpression":this.scan(e.elements);break;case"ConditionalExpression":this.scan(e.test),this.scan(e.alternate),this.scan(e.consequent);break;case"SwitchStatement":this.scan(e.discriminant),this.scan(e.cases);break;case"SwitchCase":this.scan(e.test),this.scan(e.consequent);break;case"ThisExpression":case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${e.type}"`)}}}}}),l=e((e,t)=>{const r=n(),{utils:s}=i(),{FunctionTracer:a}=u(),o=["E","PI","SQRT2","SQRT1_2","LN2","LN10","LOG2E","LOG10E"],l=["abs","acos","acosh","asin","asinh","atan","atan2","atanh","cbrt","ceil","clz32","cos","cosh","expm1","exp","floor","fround","imul","log","log2","log10","log1p","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc"],h=["value","value[]","value[][]","value[][][]","value[][][][]","value.value","value.thread.value","this.thread.value","this.output.value","this.constants.value","this.constants.value[]","this.constants.value[][]","this.constants.value[][][]","this.constants.value[][][][]","fn()[]","fn()[][]","fn()[][][]","[][]"];const c={Number:"Number",Float:"Float",Integer:"Integer",Array:"Number","Array(2)":"Number","Array(3)":"Number","Array(4)":"Number","Matrix(2)":"Number","Matrix(3)":"Number","Matrix(4)":"Number",Array2D:"Number",Array3D:"Number",Input:"Number",HTMLCanvas:"Array(4)",OffscreenCanvas:"Array(4)",HTMLImage:"Array(4)",ImageBitmap:"Array(4)",ImageData:"Array(4)",HTMLVideo:"Array(4)",HTMLImageArray:"Array(4)",NumberTexture:"Number",MemoryOptimizedNumberTexture:"Number","Array1D(2)":"Array(2)","Array1D(3)":"Array(3)","Array1D(4)":"Array(4)","Array2D(2)":"Array(2)","Array2D(3)":"Array(3)","Array2D(4)":"Array(4)","Array3D(2)":"Array(2)","Array3D(3)":"Array(3)","Array3D(4)":"Array(4)","ArrayTexture(1)":"Number","ArrayTexture(2)":"Array(2)","ArrayTexture(3)":"Array(3)","ArrayTexture(4)":"Array(4)"};t.exports={FunctionNode:class{constructor(e,t){if(!e&&!t.ast)throw new Error("source parameter is missing");if(t=t||{},this.source=e,this.ast=null,this.name="string"==typeof e?t.isRootKernel?"kernel":t.name||s.getFunctionNameFromString(e):null,this.calledFunctions=[],this.constants={},this.constantTypes={},this.constantBitRatios={},this.isRootKernel=!1,this.isSubKernel=!1,this.debug=null,this.functions=null,this.identifiers=null,this.contexts=null,this.functionCalls=null,this.states=[],this.needsArgumentType=null,this.assignArgumentType=null,this.lookupReturnType=null,this.lookupFunctionArgumentTypes=null,this.lookupFunctionArgumentBitRatio=null,this.triggerImplyArgumentType=null,this.triggerImplyArgumentBitRatio=null,this.onNestedFunction=null,this.onFunctionCall=null,this.optimizeFloatMemory=null,this.precision=null,this.loopMaxIterations=null,this.argumentNames="string"==typeof this.source?s.getArgumentNamesFromString(this.source):null,this.argumentTypes=[],this.argumentSizes=[],this.argumentBitRatios=null,this.returnType=null,this.output=[],this.plugins=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.dynamicOutput=null,this.dynamicArguments=null,this.strictTypingChecking=!1,this.fixIntegerDivisionAccuracy=null,t)for(const e in t)t.hasOwnProperty(e)&&this.hasOwnProperty(e)&&(this[e]=t[e]);this.literalTypes={},this.validate(),this._string=null,this._internalVariableNames={}}validate(){if("string"!=typeof this.source&&!this.ast)throw new Error("this.source not a string");if(!this.ast&&!s.isFunctionString(this.source))throw new Error("this.source not a function string");if(!this.name)throw new Error("this.name could not be set");if(this.argumentTypes.length>0&&this.argumentTypes.length!==this.argumentNames.length)throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`);if(this.output.length<1)throw new Error("this.output is not big enough")}isIdentifierConstant(e){return!!this.constants&&this.constants.hasOwnProperty(e)}isInput(e){return"Input"===this.argumentTypes[this.argumentNames.indexOf(e)]}pushState(e){this.states.push(e)}popState(e){if(this.state!==e)throw new Error(`Cannot popState ${e} when in ${this.state}`);this.states.pop()}isState(e){return this.state===e}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(e){if("Identifier"===e.type)return e.name;if("ThisExpression"===e.type)return"this";if("MemberExpression"===e.type&&e.object&&e.property)return e.object.hasOwnProperty("name")&&"Math"!==e.object.name?this.astMemberExpressionUnroll(e.property):this.astMemberExpressionUnroll(e.object)+"."+this.astMemberExpressionUnroll(e.property);if(e.hasOwnProperty("expressions")){const t=e.expressions[0];if("Literal"===t.type&&0===t.value&&2===e.expressions.length)return this.astMemberExpressionUnroll(e.expressions[1])}throw this.astErrorOutput("Unknown astMemberExpressionUnroll",e)}getJsAST(e){if(this.ast)return this.ast;if("object"==typeof this.source)return this.traceFunctionAST(this.source),this.ast=this.source;if(null===(e=e||r))throw new Error("Missing JS to AST parser");const t=Object.freeze(e.parse(`const parser_${this.name} = ${this.source};`,{locations:!0,ecmaVersion:2020})),n=t.body[0].declarations[0].init;if(this.traceFunctionAST(n),!t)throw new Error("Failed to parse JS code");return this.ast=n}traceFunctionAST(e){const{contexts:t,declarations:n,functions:r,identifiers:s,functionCalls:i}=new a(e);this.contexts=t,this.identifiers=s,this.functionCalls=i,this.functions=r;for(let e=0;e":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const n=this.getType(e.left);if(this.isState("skip-literal-correction"))return n;if("LiteralInteger"===n){const t=this.getType(e.right);return"LiteralInteger"===t?e.left.value%1==0?"Integer":"Float":t}return c[n]||n;case"UpdateExpression":case"ReturnStatement":return this.getType(e.argument);case"UnaryExpression":return"~"===e.operator?"Integer":this.getType(e.argument);case"VariableDeclaration":{const t=e.declarations;let n;for(let e=0;ee.isSafe)}getDependencies(e,t,n){if(t||(t=[]),!e)return null;if(Array.isArray(e)){for(let r=0;r-1/0&&e.value<1/0&&!isNaN(e.value))});break;case"VariableDeclarator":return this.getDependencies(e.init,t,n);case"Identifier":const r=this.getDeclaration(e);if(r)t.push({name:e.name,origin:"declaration",isSafe:!n&&this.isSafeDependencies(r.dependencies)});else if(this.argumentNames.indexOf(e.name)>-1)t.push({name:e.name,origin:"argument",isSafe:!1});else if(this.strictTypingChecking)throw new Error(`Cannot find identifier origin "${e.name}"`);break;case"FunctionDeclaration":return this.getDependencies(e.body.body[e.body.body.length-1],t,n);case"ReturnStatement":return this.getDependencies(e.argument,t);case"BinaryExpression":case"LogicalExpression":return n="/"===e.operator||"*"===e.operator,this.getDependencies(e.left,t,n),this.getDependencies(e.right,t,n),t;case"UnaryExpression":case"UpdateExpression":return this.getDependencies(e.argument,t,n);case"VariableDeclaration":return this.getDependencies(e.declarations,t,n);case"ArrayExpression":return t.push({origin:"declaration",isSafe:!0}),t;case"CallExpression":return t.push({origin:"function",isSafe:!0}),t;case"MemberExpression":const s=this.getMemberExpressionDetails(e);switch(s.signature){case"value[]":this.getDependencies(e.object,t,n);break;case"value[][]":this.getDependencies(e.object.object,t,n);break;case"value[][][]":this.getDependencies(e.object.object.object,t,n);break;case"this.output.value":this.dynamicOutput&&t.push({name:s.name,origin:"output",isSafe:!1})}if(s)return s.property&&this.getDependencies(s.property,t,n),s.xProperty&&this.getDependencies(s.xProperty,t,n),s.yProperty&&this.getDependencies(s.yProperty,t,n),s.zProperty&&this.getDependencies(s.zProperty,t,n),t;case"SequenceExpression":return this.getDependencies(e.expressions,t,n);default:throw this.astErrorOutput(`Unhandled type ${e.type} in getDependencies`,e)}return t}getVariableSignature(e,t){if(!this.isAstVariable(e))throw new Error(`ast of type "${e.type}" is not a variable signature`);if("Identifier"===e.type)return"value";const n=[];for(;e;)e.computed?n.push("[]"):"ThisExpression"===e.type?n.unshift("this"):e.property&&e.property.name?"x"===e.property.name||"y"===e.property.name||"z"===e.property.name?n.unshift(t?"."+e.property.name:".value"):"constants"===e.property.name||"thread"===e.property.name||"output"===e.property.name?n.unshift("."+e.property.name):n.unshift(t?"."+e.property.name:".value"):e.name?n.unshift(t?e.name:"value"):e.callee&&e.callee.name?n.unshift(t?e.callee.name+"()":"fn()"):e.elements?n.unshift("[]"):n.unshift("unknown"),e=e.object;const r=n.join("");return t||h.includes(r)?r:null}build(){return this.toString().length>0}astGeneric(e,t){if(null===e)throw this.astErrorOutput("NULL ast",e);if(Array.isArray(e)){for(let n=0;n0?r[r.length-1]:0;return new Error(`${e} on line ${r.length}, position ${i.length}:\n ${n}`)}astDebuggerStatement(e,t){return t}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);return t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t}astFunction(e,t){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}astFunctionExpression(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}isChildFunction(e){for(let t=0;t1?t.push("(",r.join(","),")"):t.push(r[0]),t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)||(e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator))),t}checkAndUpconvertBitwiseUnary(e,t){}astUpdateExpression(e,t){return e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t}astLogicalExpression(e,t){return t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t.push(")"),t}astMemberExpression(e,t){return t}astCallExpression(e,t){return t}astArrayExpression(e,t){return t}getMemberExpressionDetails(e){if("MemberExpression"!==e.type)throw this.astErrorOutput(`Expression ${e.type} not a MemberExpression`,e);let t=null,n=null;const r=this.getVariableSignature(e);switch(r){case"value":return null;case"value.thread.value":case"this.thread.value":case"this.output.value":return{signature:r,type:"Integer",name:e.property.name};case"value[]":if("string"!=typeof e.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object),xProperty:e.property};case"value[][]":if("string"!=typeof e.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object.object),yProperty:e.object.property,xProperty:e.property};case"value[][][]":if("string"!=typeof e.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value[][][][]":if("string"!=typeof e.object.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(this.isAstMathVariable(e))return t=e.property.name,{name:t,origin:"Math",type:"Number",signature:r};switch(e.property.name){case"r":case"g":case"b":case"a":return t=e.object.name,{name:t,property:e.property.name,origin:"user",signature:r,type:"Number"};default:throw this.astErrorOutput("Unexpected expression",e)}case"this.constants.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r};case"this.constants.value[]":if("string"!=typeof e.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,xProperty:e.property};case"this.constants.value[][]":if("string"!=typeof e.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,yProperty:e.object.property,xProperty:e.property};case"this.constants.value[][][]":if("string"!=typeof e.object.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.object.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"fn()[]":case"fn()[][]":case"[][]":return{signature:r,property:e.property};default:throw this.astErrorOutput("Unexpected expression",e)}}findIdentifierOrigin(e){const t=[this.ast];for(;t.length>0;){const n=t[0];if("VariableDeclarator"===n.type&&n.id&&n.id.name&&n.id.name===e.name)return n;if(t.shift(),n.argument)t.push(n.argument);else if(n.body)t.push(n.body);else if(n.declarations)t.push(n.declarations);else if(Array.isArray(n))for(let e=0;e0;){const e=t.pop();if("ReturnStatement"===e.type)return e;if("FunctionDeclaration"!==e.type)if(e.argument)t.push(e.argument);else if(e.body)t.push(e.body);else if(e.declarations)t.push(e.declarations);else if(Array.isArray(e))for(let n=0;n{const{FunctionNode:n}=l();t.exports={CPUFunctionNode:class extends n{astFunction(e,t){if(!this.isRootKernel){t.push("function"),t.push(" "),t.push(this.name),t.push("(");for(let e=0;e0&&t.push(", "),t.push("user_"),t.push(n)}t.push(") {\n")}for(let n=0;n0&&t.push(n.join(""),";\n"),t.push(`for (let ${e}=0;${e}0&&t.push(`if (!${r.join("")}) break;\n`),t.push(i.join("")),t.push(`\n${s.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),t.push("if ("),this.astGeneric(e.test,t),t.push(") {\n"),this.astGeneric(e.body,t),t.push("} else {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astDoWhileStatement(e,t){if("DoWhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),this.astGeneric(e.body,t),t.push("if (!"),this.astGeneric(e.test,t),t.push(") {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astAssignmentExpression(e,t){const n=this.getDeclaration(e.left);if(n&&!n.assignable)throw this.astErrorOutput(`Variable ${e.left.name} is not assignable here`,e);const r=this.isState("assignment-as-statement");return r?this.popState("assignment-as-statement"):t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),r||t.push(")"),t}astBlockStatement(e,t){if(this.isState("loop-body")){this.pushState("block-body");for(let n=0;n0&&t.push(",");const r=n[e],s=this.getDeclaration(r.id);s.valueType||(s.valueType=this.getType(r.init)),this.astGeneric(r,t)}return this.isState("in-for-loop-init")||t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchStatement(e,t){const{discriminant:n,cases:r}=e;t.push("switch ("),this.astGeneric(n,t),t.push(") {\n");for(let e=0;e0&&(this.astGeneric(r[e].consequent,t),t.push("break;\n"))):(t.push("default:\n"),this.astGeneric(r[e].consequent,t),r[e].consequent&&r[e].consequent.length>0&&t.push("break;\n"));t.push("\n}")}astThisExpression(e,t){return t.push("_this"),t}astMemberExpression(e,t){const{signature:n,type:r,property:s,xProperty:i,yProperty:a,zProperty:o,name:u,origin:l}=this.getMemberExpressionDetails(e);switch(n){case"this.thread.value":return t.push(`_this.thread.${u}`),t;case"this.output.value":switch(u){case"x":t.push("outputX");break;case"y":t.push("outputY");break;case"z":t.push("outputZ");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":default:throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value.value":if("Math"===l)return t.push(Math[u]),t;switch(s){case"r":return t.push(`user_${u}[0]`),t;case"g":return t.push(`user_${u}[1]`),t;case"b":return t.push(`user_${u}[2]`),t;case"a":return t.push(`user_${u}[3]`),t}break;case"this.constants.value":case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":break;case"fn()[]":return this.astGeneric(e.object,t),t.push("["),this.astGeneric(e.property,t),t.push("]"),t;case"fn()[][]":return this.astGeneric(e.object.object,t),t.push("["),this.astGeneric(e.object.property,t),t.push("]"),t.push("["),this.astGeneric(e.property,t),t.push("]"),t}if(!e.computed)switch(r){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${l}_${u}`),t}const h=`${l}_${u}`;{let e,n;if("constants"===l){const t=this.constants[u];n="Input"===this.constantTypes[u],e=n?t.size:null}else n=this.isInput(u),e=n?this.argumentSizes[this.argumentNames.indexOf(u)]:null;t.push(`${h}`),o&&a?n?(t.push("[("),this.astGeneric(o,t),t.push(`*${this.dynamicArguments?"(outputY * outputX)":e[1]*e[0]})+(`),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(i,t),t.push("]")):(t.push("["),this.astGeneric(o,t),t.push("]"),t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(i,t),t.push("]")):a?n?(t.push("[("),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(i,t),t.push("]")):(t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(i,t),t.push("]")):void 0!==i&&(t.push("["),this.astGeneric(i,t),t.push("]"))}return t}astCallExpression(e,t){if("CallExpression"!==e.type)throw this.astErrorOutput("Unknown CallExpression",e);let n=this.astMemberExpressionUnroll(e.callee);this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n),this.isAstMathFunction(e),this.onFunctionCall&&this.onFunctionCall(this.name,n,e.arguments),t.push(n),t.push("(");const r=this.lookupFunctionArgumentTypes(n)||[];for(let s=0;s0&&t.push(", "),this.astGeneric(i,t)}return t.push(")"),t}astArrayExpression(e,t){const n=this.getType(e),r=e.elements.length,s=[];for(let t=0;t{const{utils:n}=i();t.exports={cpuKernelString:function(e,t){const r=[],s=[],i=[],a=!/^function/.test(e.color.toString());if(r.push(" const { context, canvas, constants: incomingConstants } = settings;",` const output = new Int32Array(${JSON.stringify(Array.from(e.output))});`,` const _constantTypes = ${JSON.stringify(e.constantTypes)};`,` const _constants = ${function(e,t){const n=[];for(const r in t){if(!t.hasOwnProperty(r))continue;const s=t[r],i=e[r];switch(s){case"Number":case"Integer":case"Float":case"Boolean":n.push(`${r}:${i}`);break;case"Array(2)":case"Array(3)":case"Array(4)":case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":n.push(`${r}:new ${i.constructor.name}(${JSON.stringify(Array.from(i))})`)}}return`{ ${n.join()} }`}(e.constants,e.constantTypes)};`),s.push(" constants: _constants,"," context,"," output,"," thread: {x: 0, y: 0, z: 0},"),e.graphical){r.push(` const _imageData = context.createImageData(${e.output[0]}, ${e.output[1]});`),r.push(` const _colorData = new Uint8ClampedArray(${e.output[0]} * ${e.output[1]} * 4);`);const t=n.flattenFunctionToString((a?"function ":"")+e.color.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:(e,t)=>null}),o=n.flattenFunctionToString((a?"function ":"")+e.getPixels.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:()=>null});s.push(" _imageData,"," _colorData,",` color: ${t},`),i.push(` kernel.getPixels = ${o};`)}const o=[],u=Object.keys(e.constantTypes);for(let t=0;t"this"===t?(a?"function ":"")+e[n].toString():null,thisLookup:e=>{switch(e){case"canvas":return;case"context":return"context"}}});i.push(t),s.push(" _mediaTo2DArray,"),s.push(" _imageTo3DArray,")}else if(-1!==e.argumentTypes.indexOf("HTMLImage")||-1!==o.indexOf("HTMLImage")){const t=n.flattenFunctionToString((a?"function ":"")+e._mediaTo2DArray.toString(),{findDependency:(e,t)=>null,thisLookup:e=>{switch(e){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});i.push(t),s.push(" _mediaTo2DArray,")}return`function(settings) {\n${r.join("\n")}\n for (const p in _constantTypes) {\n if (!_constantTypes.hasOwnProperty(p)) continue;\n const type = _constantTypes[p];\n switch (type) {\n case 'Number':\n case 'Integer':\n case 'Float':\n case 'Boolean':\n case 'Array(2)':\n case 'Array(3)':\n case 'Array(4)':\n case 'Matrix(2)':\n case 'Matrix(3)':\n case 'Matrix(4)':\n if (incomingConstants.hasOwnProperty(p)) {\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\n }\n continue;\n }\n if (!incomingConstants.hasOwnProperty(p)) {\n throw new Error('constant ' + p + ' not found');\n }\n _constants[p] = incomingConstants[p];\n }\n const kernel = (function() {\n${e._kernelString}\n })\n .apply({ ${s.join("\n")} });\n ${i.join("\n")}\n return kernel;\n}`}}}),p=e((e,t)=>{const{Kernel:n}=a(),{FunctionBuilder:r}=o(),{CPUFunctionNode:s}=h(),{utils:u}=i(),{cpuKernelString:l}=c();t.exports={CPUKernel:class extends n{static getFeatures(){return this.features}static get features(){return Object.freeze({kernelMap:!0,isIntegerDivisionAccurate:!0})}static get isSupported(){return!0}static isContextMatch(e){return!1}static get mode(){return"cpu"}static nativeFunctionArguments(){return null}static nativeFunctionReturnType(){throw new Error(`Looking up native function return type not supported on ${this.name}`)}static combineKernels(e){return e}static getSignature(e,t){return"cpu"+(t.length>0?":"+t.join(","):"")}constructor(e,t){super(e,t),this.mergeSettings(e.settings||t),this._imageData=null,this._colorData=null,this._kernelString=null,this._prependedString=[],this.thread={x:0,y:0,z:0},this.translatedSources=null}initCanvas(){return"undefined"!=typeof document?document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(0,0):void 0}initContext(){return this.canvas?this.canvas.getContext("2d",{willReadFrequently:!0}):null}initPlugins(e){return[]}validateSettings(e){if(!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=u.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=u.getDimensions(t);else{if("NumberTexture"!==t&&"ArrayTexture(4)"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=e[0].output}}if(this.graphical&&2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");this.checkOutput()}translateSource(){if(this.leadingReturnStatement=this.output.length>1?"resultX[x] = ":"result[x] = ",this.subKernels){const e=[];for(let t=0;t1?`resultX_${n}[x] = subKernelResult_${n};\n`:`result_${n}[x] = subKernelResult_${n};\n`)}this.followingReturnStatement=e.join("")}const e=r.fromKernel(this,s);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){if(this.built)return;if(null!==this.randomSeed&&console.warn("randomSeed is not supported in cpu mode; Math.random() will be unseeded"),this.setupConstants(),this.setupArguments(arguments),this.validateSettings(arguments),this.translateSource(),this.graphical){const{canvas:e,output:t}=this;if(!e)throw new Error("no canvas available for using graphical output");const n=t[0],r=t[1]||1;e.width=n,e.height=r,this._imageData=this.context.createImageData(n,r),this._colorData=new Uint8ClampedArray(n*r*4)}const e=this.getKernelString();this.kernelString=e,this.debug&&(console.log("Function output:"),console.log(e));try{this.run=new Function([],e).bind(this)()}catch(e){console.error("An error occurred compiling the javascript: ",e)}this.buildSignature(arguments),this.built=!0}color(e,t,n,r){void 0===r&&(r=1),e=Math.floor(255*e),t=Math.floor(255*t),n=Math.floor(255*n),r=Math.floor(255*r);const s=this.output[0],i=this.output[1],a=this.thread.x+(i-this.thread.y-1)*s;this._colorData[4*a+0]=e,this._colorData[4*a+1]=t,this._colorData[4*a+2]=n,this._colorData[4*a+3]=r}getKernelString(){if(null!==this._kernelString)return this._kernelString;let e=null,{translatedSources:t}=this;return t.length>1?t=t.filter(t=>/^function/.test(t)?t:(e=t,!1)):e=t.shift(),this._kernelString=` const LOOP_MAX = ${this._getLoopMaxString()};\n ${this.injectedNative||""}\n const _this = this;\n ${this._resultKernelHeader()}\n ${this._processConstants()}\n return (${this.argumentNames.map(e=>"user_"+e).join(", ")}) => {\n ${this._prependedString.join("")}\n ${this._earlyThrows()}\n ${this._processArguments()}\n ${this.graphical?this._graphicalKernelBody(e):this._resultKernelBody(e)}\n ${t.length>0?t.join("\n"):""}\n };`}toString(){return l(this)}_getLoopMaxString(){return this.loopMaxIterations?` ${parseInt(this.loopMaxIterations)};`:" 1000;"}_processConstants(){if(!this.constants)return"";const e=[];for(let t in this.constants)switch(this.constantTypes[t]){case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":e.push(` const constants_${t} = this._mediaTo2DArray(this.constants.${t});\n`);break;case"HTMLImageArray":e.push(` const constants_${t} = this._imageTo3DArray(this.constants.${t});\n`);break;case"Input":e.push(` const constants_${t} = this.constants.${t}.value;\n`);break;default:e.push(` const constants_${t} = this.constants.${t};\n`)}return e.join("")}_earlyThrows(){if(this.graphical)return"";if(this.immutable)return"";if(!this.pipeline)return"";const e=[];for(let t=0;t`user_${r} === result_${e.name}`).join(" || ");t.push(`user_${r} === result${s?` || ${s}`:""}`)}return`if (${t.join(" || ")}) throw new Error('Source and destination arrays are the same. Use immutable = true');`}_processArguments(){const e=[];for(let t=0;t0?e.width:e.videoWidth,r=e.height>0?e.height:e.videoHeight;t.width=0;e--){const t=a[e]=new Array(n);for(let e=0;e`const result_${e.name} = new ${t}(outputX);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_mutableKernel1DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const result = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const result_${t.name} = new ${e}(outputX);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}`}_resultMutableKernel1DLoop(e){return` const outputX = _this.output[0];\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_resultImmutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y] = new ${t}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_mutableKernel2DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n const resultX = result[y] = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const resultX_${t.name} = result_${t.name}[y] = new ${e}(outputX);\n`).join("")}\n }`}_resultMutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y];\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_graphicalKernel2DLoop(e){return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_resultImmutableKernel3DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputZ);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels(e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y] = new ${t}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = resultY_${e.name}[y] = new ${t}(outputX);\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_mutableKernel3DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputZ);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels(e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n const resultX = resultY[y] = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const resultX_${t.name} = resultY_${t.name}[y] = new ${e}(outputX);\n`).join(" ")}\n }\n }`}_resultMutableKernel3DLoop(e){return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z];\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y];\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_kernelOutput(){return this.subKernels?`\n return {\n result: result,\n ${this.subKernels.map(e=>`${e.property}: result_${e.name}`).join(",\n ")}\n };`:"\n return result;"}_mapSubKernels(e){return null===this.subKernels?[""]:this.subKernels.map(e)}destroy(e){e&&delete this.canvas}static destroyContext(e){}toJSON(){const e=super.toJSON();return e.functionNodes=r.fromKernel(this,s).toJSON(),e}setOutput(e){super.setOutput(e);const[t,n]=this.output;this.graphical&&(this._imageData=this.context.createImageData(t,n),this._colorData=new Uint8ClampedArray(t*n*4))}prependString(e){if(this._kernelString)throw new Error("Kernel already built");this._prependedString.push(e)}hasPrependString(e){return this._prependedString.indexOf(e)>-1}}}}),m=e((e,t)=>{const{Texture:n}=s();function r(e,t){e.activeTexture(e.TEXTURE15),e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST)}t.exports={GLTexture:class extends n{get textureType(){throw new Error(`"textureType" not implemented on ${this.name}`)}clone(){return new this.constructor(this)}beforeMutate(){return this.texture._refs>1&&(this.newTexture(),!0)}cloneTexture(){this.texture._refs--;const{context:e,size:t,texture:n,kernel:s}=this;s.debug&&console.warn("cloning internal texture"),e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),r(e,n),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,n,0);const i=e.createTexture();r(e,i),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),e.copyTexSubImage2D(e.TEXTURE_2D,0,0,0,0,0,t[0],t[1]),i._refs=1,this.texture=i}newTexture(){this.texture._refs--;const e=this.context,t=this.size;this.kernel.debug&&console.warn("new internal texture");const n=e.createTexture();r(e,n),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),n._refs=1,this.texture=n}clear(){if(this.texture._refs){this.texture._refs--;const e=this.context,t=this.texture=e.createTexture();r(e,t);const n=this.size;t._refs=1,e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,n[0],n[1],0,this.textureFormat,this.textureType,null)}const{context:e,texture:t}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.bindTexture(e.TEXTURE_2D,t),r(e,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}delete(){this._deleted||(this._deleted=!0,this.texture._refs&&(this.texture._refs--,this.texture._refs)||(this.kernel&&this.kernel.deleteTexture?this.kernel.deleteTexture(this.texture):this.context.deleteTexture(this.texture)))}framebuffer(){return this._framebuffer||(this._framebuffer=this.kernel.getRawValueFramebuffer(this.size[0],this.size[1])),this._framebuffer}}}}),d=e((e,t)=>{const{utils:n}=i(),{GLTexture:r}=m();t.exports={GLTextureFloat:class extends r{get textureType(){return this.context.FLOAT}constructor(e){super(e),this.type="ArrayTexture(1)"}renderRawOutput(){const e=this.context,t=this.size;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const n=new Float32Array(t[0]*t[1]*4);return e.readPixels(0,0,t[0],t[1],e.RGBA,e.FLOAT,n),n}renderValues(){return this._deleted?null:this.renderRawOutput()}toArray(){return n.erectFloat(this.renderValues(),this.output[0])}}}}),g=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureArray2Float:class extends r{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return n.erectArray2(this.renderValues(),this.output[0],this.output[1])}}}}),f=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureArray2Float2D:class extends r{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return n.erect2DArray2(this.renderValues(),this.output[0],this.output[1])}}}}),x=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureArray2Float3D:class extends r{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return n.erect3DArray2(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),y=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureArray3Float:class extends r{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return n.erectArray3(this.renderValues(),this.output[0])}}}}),T=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureArray3Float2D:class extends r{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return n.erect2DArray3(this.renderValues(),this.output[0],this.output[1])}}}}),b=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureArray3Float3D:class extends r{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return n.erect3DArray3(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),S=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureArray4Float:class extends r{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return n.erectArray4(this.renderValues(),this.output[0])}}}}),A=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureArray4Float2D:class extends r{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return n.erect2DArray4(this.renderValues(),this.output[0],this.output[1])}}}}),E=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureArray4Float3D:class extends r{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return n.erect3DArray4(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),_=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureFloat2D:class extends r{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return n.erect2DFloat(this.renderValues(),this.output[0],this.output[1])}}}}),v=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureFloat3D:class extends r{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return n.erect3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),w=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureMemoryOptimized:class extends r{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return n.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}}}),D=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureMemoryOptimized2D:class extends r{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return n.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}}}),I=e((e,t)=>{const{utils:n}=i(),{GLTextureFloat:r}=d();t.exports={GLTextureMemoryOptimized3D:class extends r{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return n.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),$=e((e,t)=>{const{utils:n}=i(),{GLTexture:r}=m();t.exports={GLTextureUnsigned:class extends r{get textureType(){return this.context.UNSIGNED_BYTE}constructor(e){super(e),this.type="NumberTexture"}renderRawOutput(){const{context:e}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const t=new Uint8Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.UNSIGNED_BYTE,t),t}renderValues(){return this._deleted?null:new Float32Array(this.renderRawOutput().buffer)}toArray(){return n.erectPackedFloat(this.renderValues(),this.output[0])}}}}),F=e((e,t)=>{const{utils:n}=i(),{GLTextureUnsigned:r}=$();t.exports={GLTextureUnsigned2D:class extends r{constructor(e){super(e),this.type="NumberTexture"}toArray(){return n.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}}}),R=e((e,t)=>{const{utils:n}=i(),{GLTextureUnsigned:r}=$();t.exports={GLTextureUnsigned3D:class extends r{constructor(e){super(e),this.type="NumberTexture"}toArray(){return n.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),L=e((e,t)=>{const{GLTextureUnsigned:n}=$();t.exports={GLTextureGraphical:class extends n{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return this.renderValues()}}}}),z=e((e,t)=>{const{Kernel:n}=a(),{utils:r}=i(),{GLTextureArray2Float:s}=g(),{GLTextureArray2Float2D:o}=f(),{GLTextureArray2Float3D:u}=x(),{GLTextureArray3Float:l}=y(),{GLTextureArray3Float2D:h}=T(),{GLTextureArray3Float3D:c}=b(),{GLTextureArray4Float:p}=S(),{GLTextureArray4Float2D:m}=A(),{GLTextureArray4Float3D:z}=E(),{GLTextureFloat:C}=d(),{GLTextureFloat2D:M}=_(),{GLTextureFloat3D:N}=v(),{GLTextureMemoryOptimized:V}=w(),{GLTextureMemoryOptimized2D:O}=D(),{GLTextureMemoryOptimized3D:k}=I(),{GLTextureUnsigned:K}=$(),{GLTextureUnsigned2D:G}=F(),{GLTextureUnsigned3D:U}=R(),{GLTextureGraphical:P}=L();const B={int:"Integer",float:"Number",vec2:"Array(2)",vec3:"Array(3)",vec4:"Array(4)"};t.exports={GLKernel:class extends n{static get mode(){return"gpu"}static getIsFloatRead(){const e=new this("function kernelFunction() {\n return 1;\n }",{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[1],precision:"single",returnType:"Number",tactic:"speed"});e.build(),e.run();const t=e.renderOutput();return e.destroy(!0),1===t[0]}static getIsIntegerDivisionAccurate(){const e=new this(function(e,t){return e[this.thread.x]/t[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[2],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[6,6030401],[3,3991]];e.build.apply(e,t),e.run.apply(e,t);const n=e.renderOutput();return e.destroy(!0),2===n[0]&&1511===n[1]}static getIsSpeedTacticSupported(){const e=new this(function(e){return e[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[4],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[0,1,2,3]];e.build.apply(e,t),e.run.apply(e,t);const n=e.renderOutput();return e.destroy(!0),0===Math.round(n[0])&&1===Math.round(n[1])&&2===Math.round(n[2])&&3===Math.round(n[3])}static get testCanvas(){throw new Error(`"testCanvas" not defined on ${this.name}`)}static get testContext(){throw new Error(`"testContext" not defined on ${this.name}`)}static getFeatures(){const e=this.testContext,t=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isSpeedTacticSupported:this.getIsSpeedTacticSupported(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:t,kernelMap:t,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize(),lowIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT),lowFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT),mediumIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT),mediumFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT),highIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT),highFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)})}static setupFeatureChecks(){throw new Error(`"setupFeatureChecks" not defined on ${this.name}`)}static getSignature(e,t){return e.getVariablePrecisionString()+(t.length>0?":"+t.join(","):"")}setFixIntegerDivisionAccuracy(e){return this.fixIntegerDivisionAccuracy=e,this}setPrecision(e){return this.precision=e,this}setFloatTextures(e){return r.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],n=[],r=[],s=/^[a-zA-Z_]/,i=/[a-zA-Z_0-9]/;let a=0,o=null,u=null;for(;a0?r[r.length-1]:null;if("FUNCTION_ARGUMENTS"!==c||"/"!==l||"*"!==h)if("MULTI_LINE_COMMENT"!==c||"*"!==l||"/"!==h)if("FUNCTION_ARGUMENTS"!==c||"/"!==l||"/"!==h)if("COMMENT"!==c||"\n"!==l)if(null!==c||"("!==l){if("FUNCTION_ARGUMENTS"===c){if(")"===l){r.pop();break}if("f"===l&&"l"===h&&"o"===e[a+2]&&"a"===e[a+3]&&"t"===e[a+4]&&" "===e[a+5]){r.push("DECLARE_VARIABLE"),u="float",o="",a+=6;continue}if("i"===l&&"n"===h&&"t"===e[a+2]&&" "===e[a+3]){r.push("DECLARE_VARIABLE"),u="int",o="",a+=4;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"2"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec2",o="",a+=5;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"3"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec3",o="",a+=5;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"4"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec4",o="",a+=5;continue}}else if("DECLARE_VARIABLE"===c){if(""===o){if(" "===l){a++;continue}if(!s.test(l))throw new Error("variable name is not expected string")}o+=l,i.test(h)||(r.pop(),n.push(o),t.push(B[u]))}a++}else r.push("FUNCTION_ARGUMENTS"),a++;else r.pop(),a++;else r.push("COMMENT"),a+=2;else r.pop(),a+=2;else r.push("MULTI_LINE_COMMENT"),a+=2}if(r.length>0)throw new Error("GLSL function was not parsable");return{argumentNames:n,argumentTypes:t}}static nativeFunctionReturnType(e){return B[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:n,context:s,threadDim:i}=t.texSize;let a;if("single"===t.precision){const e=n[0],t=Math.ceil(n[1]/4);a=new Float32Array(e*t*4*4),s.readPixels(0,0,e,4*t,s.RGBA,s.FLOAT,a)}else{const e=new Uint8Array(n[0]*n[1]*4);s.readPixels(0,0,n[0],n[1],s.RGBA,s.UNSIGNED_BYTE,e),a=new Float32Array(e.buffer)}return a=a.subarray(0,i[0]*i[1]*i[2]),1===t.output.length?a:2===t.output.length?r.splitArray(a,t.output[0]):3===t.output.length?r.splitArray(a,t.output[0]*t.output[1]).map(function(e){return r.splitArray(e,t.output[0])}):void 0}constructor(e,t){super(e,t),this.transferValues=null,this.formatValues=null,this.TextureConstructor=null,this.renderOutput=null,this.renderRawOutput=null,this.texSize=null,this.translatedSource=null,this.compiledFragmentShader=null,this.compiledVertexShader=null,this.switchingKernels=null,this._textureSwitched=null,this._mappedTextureSwitched=null}checkTextureSize(){const{features:e}=this.constructor;if(this.texSize[0]>e.maxTextureSize||this.texSize[1]>e.maxTextureSize)throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${e.maxTextureSize},${e.maxTextureSize}]`)}translateSource(){throw new Error(`"translateSource" not defined on ${this.constructor.name}`)}pickRenderStrategy(e){if(this.graphical)return this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=e=>e,this.TextureConstructor=P,null;if("unsigned"===this.precision)if(this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=this.readPackedPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=U,null):this.output[1]>0?(this.TextureConstructor=G,null):(this.TextureConstructor=K,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else switch(null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.renderOutput=this.renderValues,this.output[2]>0?(this.TextureConstructor=U,this.formatValues=r.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=G,this.formatValues=r.erect2DPackedFloat,null):(this.TextureConstructor=K,this.formatValues=r.erectPackedFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else{if("single"!==this.precision)throw new Error(`unhandled precision of "${this.precision}"`);if(this.renderRawOutput=this.readFloatPixelsToFloat32Array,this.transferValues=this.readFloatPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.optimizeFloatMemory?this.output[2]>0?(this.TextureConstructor=k,null):this.output[1]>0?(this.TextureConstructor=O,null):(this.TextureConstructor=V,null):this.output[2]>0?(this.TextureConstructor=N,null):this.output[1]>0?(this.TextureConstructor=M,null):(this.TextureConstructor=C,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,null):this.output[1]>0?(this.TextureConstructor=o,null):(this.TextureConstructor=s,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,null):this.output[1]>0?(this.TextureConstructor=h,null):(this.TextureConstructor=l,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=z,null):this.output[1]>0?(this.TextureConstructor=m,null):(this.TextureConstructor=p,null)}if(this.renderOutput=this.renderValues,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.optimizeFloatMemory)switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=k,this.formatValues=r.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=O,this.formatValues=r.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=V,this.formatValues=r.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.formatValues=r.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.formatValues=r.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=r.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,this.formatValues=r.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=h,this.formatValues=r.erect2DArray3,null):(this.TextureConstructor=l,this.formatValues=r.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=z,this.formatValues=r.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=m,this.formatValues=r.erect2DArray4,null):(this.TextureConstructor=p,this.formatValues=r.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=N,this.formatValues=r.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=M,this.formatValues=r.erect2DFloat,null):(this.TextureConstructor=C,this.formatValues=r.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.formatValues=r.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.formatValues=r.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=r.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,this.formatValues=r.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=h,this.formatValues=r.erect2DArray3,null):(this.TextureConstructor=l,this.formatValues=r.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=z,this.formatValues=r.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=m,this.formatValues=r.erect2DArray4,null):(this.TextureConstructor=p,this.formatValues=r.erectArray4,null)}}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error("abstract method call")}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error("abstract method call")}getMainResultSubKernelNumberTexture(){throw new Error("abstract method call")}getMainResultKernelArray2Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray2Texture(){throw new Error("abstract method call")}getMainResultKernelArray3Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray3Texture(){throw new Error("abstract method call")}getMainResultKernelArray4Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray4Texture(){throw new Error("abstract method call")}getMainResultGraphical(){throw new Error("abstract method call")}getMainResultMemoryOptimizedFloats(){throw new Error("abstract method call")}getMainResultPackedPixels(){throw new Error("abstract method call")}getMainResultString(){return this.graphical?this.getMainResultGraphical():"single"===this.precision?this.optimizeFloatMemory?this.getMainResultMemoryOptimizedFloats():this.getMainResultTexture():this.getMainResultPackedPixels()}getMainResultNumberTexture(){return r.linesToString(this.getMainResultKernelNumberTexture())+r.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return r.linesToString(this.getMainResultKernelArray2Texture())+r.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return r.linesToString(this.getMainResultKernelArray3Texture())+r.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return r.linesToString(this.getMainResultKernelArray4Texture())+r.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} float;\n`}getIntTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic,!0)} int;\n`}getSampler2DTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2D;\n`}getSampler2DArrayTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2DArray;\n`}renderTexture(){return this.immutable?this.texture.clone():this.texture}readPackedPixelsToUint8Array(){if("unsigned"!==this.precision)throw new Error('Requires this.precision to be "unsigned"');const{texSize:e,context:t}=this,n=new Uint8Array(e[0]*e[1]*4);return t.readPixels(0,0,e[0],e[1],t.RGBA,t.UNSIGNED_BYTE,n),n}readPackedPixelsToFloat32Array(){return new Float32Array(this.readPackedPixelsToUint8Array().buffer)}readFloatPixelsToFloat32Array(){if("single"!==this.precision)throw new Error('Requires this.precision to be "single"');const{texSize:e,context:t}=this,n=e[0],r=e[1],s=new Float32Array(n*r*4);return t.readPixels(0,0,n,r,t.RGBA,t.FLOAT,s),s}getPixels(e){const{context:t,output:n}=this,[s,i]=n,a=new Uint8Array(s*i*4);return t.readPixels(0,0,s,i,t.RGBA,t.UNSIGNED_BYTE,a),new Uint8ClampedArray((e?a:r.flipPixels(a,s,i)).buffer)}renderKernelsToArrays(){const e={result:this.renderOutput()};for(let t=0;t0){for(let e=0;e0){const{mappedTextures:n}=this;for(let r=0;r{const{utils:n}=i(),{FunctionNode:r}=l();function s(e){if(!e||"object"!=typeof e)return!0;if(Array.isArray(e))return e.every(s);if("UpdateExpression"===e.type||"AssignmentExpression"===e.type||"SequenceExpression"===e.type)return!1;for(const t in e)if("loc"!==t&&"range"!==t&&"parent"!==t&&!s(e[t]))return!1;return!0}function a(e){let t=!1;function n(e){if(!e||"object"!=typeof e||t)return!1;if(Array.isArray(e))return e.some(n);if("MemberExpression"===e.type&&e.computed)return!0;for(const t in e)if("loc"!==t&&"range"!==t&&"parent"!==t&&n(e[t]))return!0;return!1}return function e(r){if(r&&"object"==typeof r&&!t)if(Array.isArray(r))r.forEach(e);else if("MemberExpression"===r.type&&r.computed&&n(r.property))t=!0;else for(const t in r)"loc"!==t&&"range"!==t&&"parent"!==t&&e(r[t])}(e),t}function o(e,t){if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return e.some(e=>o(e,t));if("CallExpression"===e.type&&"Identifier"===e.callee.type&&e.callee.name===t)return!0;for(const n in e)if("loc"!==n&&"range"!==n&&"parent"!==n&&o(e[n],t))return!0;return!1}function u(e){let t=!1;return function e(n){if(n&&"object"==typeof n&&!t)if(Array.isArray(n))n.forEach(e);else if("CallExpression"===n.type&&"Identifier"===n.callee.type&&n.arguments.some(e=>o(e,n.callee.name)))t=!0;else for(const t in n)"loc"!==t&&"range"!==t&&"parent"!==t&&e(n[t])}(e),t}function h(e){const t="ExpressionStatement"===e.type&&"AssignmentExpression"===e.expression.type?e.expression:null;return function e(n){if(!n||"object"!=typeof n)return!0;if(Array.isArray(n))return n.every(e);if("string"==typeof n.type){if("UpdateExpression"===n.type||"SequenceExpression"===n.type)return!1;if("AssignmentExpression"===n.type&&n!==t)return!1}for(const t in n)if("loc"!==t&&"range"!==t&&"parent"!==t&&!e(n[t]))return!1;return!0}(e)}const c={"Matrix(2)":2,"Matrix(3)":3,"Matrix(4)":4},p={Array:"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4","Matrix(2)":"mat2","Matrix(3)":"mat3","Matrix(4)":"mat4",Array2D:"sampler2D",Array3D:"sampler2D",Boolean:"bool",Float:"float",Input:"sampler2D",Integer:"int",Number:"float",LiteralInteger:"float",NumberTexture:"sampler2D",MemoryOptimizedNumberTexture:"sampler2D","ArrayTexture(1)":"sampler2D","ArrayTexture(2)":"sampler2D","ArrayTexture(3)":"sampler2D","ArrayTexture(4)":"sampler2D",HTMLVideo:"sampler2D",HTMLCanvas:"sampler2D",OffscreenCanvas:"sampler2D",HTMLImage:"sampler2D",ImageBitmap:"sampler2D",ImageData:"sampler2D",HTMLImageArray:"sampler2DArray"},m={"===":"==","!==":"!="};t.exports={WebGLFunctionNode:class extends r{constructor(e,t){super(e,t),t&&t.hasOwnProperty("fixIntegerDivisionAccuracy")&&(this.fixIntegerDivisionAccuracy=t.fixIntegerDivisionAccuracy)}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);const n=this.getType(e.consequent),r=this.getType(e.alternate);return null===n&&null===r?(t.push("if ("),this.astGeneric(e.test,t),t.push(") {"),this.astGeneric(e.consequent,t),t.push(";"),t.push("} else {"),this.astGeneric(e.alternate,t),t.push(";"),t.push("}"),t):(t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t)}astFunction(e,t){if(this.isRootKernel)t.push("void");else{this.returnType||this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"));const{returnType:n}=this;if(n){const e=p[n];if(!e)throw new Error(`unknown type ${n}`);t.push(e)}else t.push("void")}if(t.push(" "),t.push(this.name),t.push("("),!this.isRootKernel)for(let r=0;r0&&t.push(", ");let i=this.argumentTypes[this.argumentNames.indexOf(s)];if(!i)throw this.astErrorOutput(`Unknown argument ${s} type`,e);"LiteralInteger"===i&&(this.argumentTypes[r]=i="Number");const a=p[i];if(!a)throw this.astErrorOutput("Unexpected expression",e);const o=n.sanitizeName(s);"sampler2D"===a||"sampler2DArray"===a?t.push(`${a} user_${o},ivec2 user_${o}Size,ivec3 user_${o}Dim`):t.push(`${a} user_${o}`)}t.push(") {\n");for(let n=0;n"===e.operator||"<"===e.operator&&"Literal"===e.right.type)&&!Number.isInteger(e.right.value)){this.pushState("building-float"),this.castValueToFloat(e.left,t),t.push(m[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-float");break}if(this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(m[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const n=[];if(this.astGeneric(e.right,n),"Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(n.join(""))}else t.push("int("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(m[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(m[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(m[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float");break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(m[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(m[e.operator]||e.operator),this.pushState("casting-to-float"),this.astGeneric(e.right,t),this.popState("casting-to-float"),this.popState("building-float"));break;case"LiteralInteger & Integer":this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(m[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean"),this.astGeneric(e.left,t),t.push(m[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${s}`,e)}return t.push(")"),t}checkAndUpconvertOperator(e,t){const n=this.checkAndUpconvertBitwiseOperators(e,t);if(n)return n;const r={"%":this.fixIntegerDivisionAccuracy?"integerCorrectionModulo":"modulo","**":"pow"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){const n={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.left)){case"Number":case"Float":this.castValueToInteger(e.left,t);break;case"LiteralInteger":this.castLiteralToInteger(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Number":case"Float":this.castValueToInteger(e.right,t);break;case"LiteralInteger":this.castLiteralToInteger(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){const n={"~":"bitwiseNot"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("int("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("float("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const r=this.getType(e),s=n.sanitizeName(e.name);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===r&&this.argumentNames.indexOf(s)>-1?t.push(`bool(user_${s})`):t.push(`user_${s}`),t}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const n=[],r=[],s=[],i=[];let a=null;if(e.init){const{declarations:t}=e.init;t.length>1&&(a=!1),this.astGeneric(e.init,n);for(let e=0;e0&&t.push(n.join(""),"\n"),t.push(`for (int ${e}=0;${e}0&&t.push(`if (!${r.join("")}) break;\n`),t.push(i.join("")),t.push(`\n${s.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);const n=this.getInternalVariableName("safeI");return t.push(`for (int ${n}=0;${n}null!==e&&(a(e)||u(e))))return null;const i=e=>JSON.parse(JSON.stringify(e)),o=e=>({type:"IfStatement",test:{type:"UnaryExpression",operator:"!",prefix:!0,argument:e},consequent:{type:"BlockStatement",body:[{type:"BreakStatement",label:null}]},alternate:null}),l=e=>"VariableDeclaration"===e.type?e:{type:"ExpressionStatement",expression:e},h="BlockStatement"===e.body.type?e.body.body.slice():[e.body],c=(e,t)=>{const n=e=>{if(!e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map(n);switch(e.type){case"ContinueStatement":return{type:"BlockStatement",body:[...t(),e]};case"ForStatement":case"WhileStatement":case"DoWhileStatement":default:return e;case"IfStatement":return{...e,consequent:n(e.consequent),alternate:n(e.alternate)};case"BlockStatement":return{...e,body:e.body.map(n)};case"SwitchStatement":return{...e,cases:e.cases.map(e=>({...e,consequent:e.consequent.map(n)}))}}};return e.map(n)},p=[];"DoWhileStatement"===t?(p.push(...r?c(h,()=>[o(i(r))]):h),r&&p.push(o(r))):(r&&p.push(o(r)),p.push(...s?c(h,()=>[l(i(s))]):h),s&&p.push(l(s)));const m={type:"BlockStatement",body:[...n?[l(n)]:[],{type:"WhileStatement",test:{type:"Literal",value:!0,raw:"true"},body:{type:"BlockStatement",body:p}}]};let d=this.syntheticNodeId||1073741824;const g=e=>{if(e&&"object"==typeof e)if(Array.isArray(e))e.forEach(g);else{"string"==typeof e.type&&void 0===e.start&&(e.start=d,e.end=d+1,d+=2);for(const t in e)"loc"!==t&&"range"!==t&&"parent"!==t&&g(e[t])}};return g(m),this.syntheticNodeId=d,m}linearizeStatement(e){const t=[];let n=!1,r=this.linearTempId||0;const i=e=>({type:"Identifier",name:e}),a=(e,t,n)=>({type:"VariableDeclaration",kind:e,declarations:[{type:"VariableDeclarator",id:i(t),init:n}]}),u=(e,t)=>{const n="hoistSeq"+r++;return e.push(a("const",n,t)),i(n)},l=e=>!s(e),h=(e,t)=>{if(n||!e||"object"!=typeof e)return e;switch(e.type){case"Identifier":case"Literal":case"ThisExpression":return e;case"MemberExpression":{const n=h(e.object,t),r=e.computed?h(e.property,t):e.property;return{...e,object:n,property:r}}case"CallExpression":{const n=e.arguments.map(e=>h(e,t));if("Identifier"===e.callee.type)for(let r=0;rh(e,t))};case"UpdateExpression":{if("Identifier"!==e.argument.type)return n=!0,e;if(e.prefix)return t.push({type:"ExpressionStatement",expression:e}),u(t,e.argument);const r=u(t,e.argument);return t.push({type:"ExpressionStatement",expression:e}),r}case"AssignmentExpression":{if("Identifier"!==e.left.type)return n=!0,e;const r=h(e.right,t);return t.push({type:"ExpressionStatement",expression:{...e,right:r}}),u(t,e.left)}case"SequenceExpression":for(let n=0;n({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:i(e),right:t}});return o.push(m(s,c)),u.push(m(s,p)),t.push({type:"IfStatement",test:n,consequent:{type:"BlockStatement",body:o},alternate:{type:"BlockStatement",body:u}}),i(s)}case"LogicalExpression":{if(!l(e.right))return{...e,left:h(e.left,t)};const n=h(e.left,t),s="hoistSeq"+r++;t.push(a("let",s,n));const o=[],u=h(e.right,o);return o.push({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:i(s),right:u}}),t.push({type:"IfStatement",test:"&&"===e.operator?i(s):{type:"UnaryExpression",operator:"!",prefix:!0,argument:i(s)},consequent:{type:"BlockStatement",body:o},alternate:null}),i(s)}default:return n=!0,e}};switch(e.type){case"ExpressionStatement":{const n=e.expression;if("AssignmentExpression"===n.type&&"Identifier"===n.left.type){const e=h(n.right,t);t.push({type:"ExpressionStatement",expression:{...n,right:e}})}else{const e=h(n,t);"UpdateExpression"!==e.type&&"AssignmentExpression"!==e.type||t.push({type:"ExpressionStatement",expression:e})}break}case"VariableDeclaration":for(let n=0;n{if(e&&"object"==typeof e)if(Array.isArray(e))e.forEach(p);else{"string"==typeof e.type&&void 0===e.start&&(e.start=c,e.end=c+1,c+=2);for(const t in e)"loc"!==t&&"range"!==t&&"parent"!==t&&p(e[t])}};return p(t),this.syntheticNodeId=c,t}astStatementWithHoisting(e,t){switch(e.type){case"ExpressionStatement":case"VariableDeclaration":case"ReturnStatement":{if(!h(e))return this.astGeneric(e,t);const n=this.hoistedIndexReads,r=this.hoistedIndexReads=[],s=[];return this.astGeneric(e,s),this.hoistedIndexReads=n,t.push(...r,...s),t}default:return this.astGeneric(e,t)}}astVariableDeclaration(e,t){const r=e.declarations;if(!r||!r[0]||!r[0].init)throw this.astErrorOutput("Unexpected expression",e);const s=[];let i=null;const a=[];let o=[];for(let t=0;t0&&a.push(o.join(",")),s.push(a.join(";")),t.push(s.join("")),t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchCaseConsequent(e,t){const n=[];for(let t=0;t{if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return e.some(t);if("BreakStatement"===e.type)return!0;if("ForStatement"===e.type||"WhileStatement"===e.type||"DoWhileStatement"===e.type||"SwitchStatement"===e.type)return!1;for(const n in e)if("loc"!==n&&"range"!==n&&"parent"!==n&&t(e[n]))return!0;return!1};if(t(n[e]))throw this.astErrorOutput("break inside a switch case is only supported as the case terminator",n[e])}for(let e=0;en+1){u=!0,this.astSwitchCaseConsequent(r[n].consequent,o);continue}t.push(" else {\n")}this.astSwitchCaseConsequent(r[n].consequent,t),t.push("\n}")}return u&&(t.push(" else {"),t.push(o.join("")),t.push("}")),t}astThisExpression(e,t){return t.push("this"),t}astMemberExpression(e,t){const{property:r,name:s,signature:i,origin:a,type:o,xProperty:u,yProperty:l,zProperty:h}=this.getMemberExpressionDetails(e);switch(i){case"value.thread.value":case"this.thread.value":if("x"!==s&&"y"!==s&&"z"!==s)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`threadId.${s}`),t;case"this.output.value":if(this.dynamicOutput)switch(s){case"x":this.isState("casting-to-float")?t.push("float(uOutputDim.x)"):t.push("uOutputDim.x");break;case"y":this.isState("casting-to-float")?t.push("float(uOutputDim.y)"):t.push("uOutputDim.y");break;case"z":this.isState("casting-to-float")?t.push("float(uOutputDim.z)"):t.push("uOutputDim.z");break;default:throw this.astErrorOutput("Unexpected expression",e)}else switch(s){case"x":this.isState("casting-to-integer")?t.push(this.output[0]):t.push(this.output[0],".0");break;case"y":this.isState("casting-to-integer")?t.push(this.output[1]):t.push(this.output[1],".0");break;case"z":this.isState("casting-to-integer")?t.push(this.output[2]):t.push(this.output[2],".0");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if("Math"===a)return t.push(Math[s]),t;const i=n.sanitizeName(s);switch(r){case"r":return t.push(`user_${i}.r`),t;case"g":return t.push(`user_${i}.g`),t;case"b":return t.push(`user_${i}.b`),t;case"a":return t.push(`user_${i}.a`),t}break;case"this.constants.value":if(void 0===u)switch(o){case"Array(2)":case"Array(3)":case"Array(4)":return t.push(`constants_${n.sanitizeName(s)}`),t}case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":case"this.constants.value[][][][]":break;case"fn()[]":return this.astCallExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(r)),t.push("]"),t;case"fn()[][]":{const n=e.object.property,r=e.property,s=c[this.getType(e.object.object)],i=e=>"LiteralInteger"===this.getType(e);return!s||i(n)&&i(r)?(this.astCallExpression(e.object.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t.push("["),t.push(this.memberExpressionPropertyMarkup(r)),t.push("]"),t):(t.push(`getMatrix${s}(`),this.astCallExpression(e.object.object,t),t.push(", "),t.push(this.memberExpressionPropertyMarkup(n)),t.push(", "),t.push(this.memberExpressionPropertyMarkup(r)),t.push(")"),t)}case"[][]":return this.astArrayExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(r)),t.push("]"),t;default:throw this.astErrorOutput("Unexpected expression",e)}if(!1===e.computed)switch(o){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${a}_${n.sanitizeName(s)}`),t}const p=`${a}_${n.sanitizeName(s)}`;switch(o){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(u)),t.push("]");break;case"HTMLImageArray":t.push(`getImage3D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":t.push(`getVec4FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if("single"===this.precision)t.push(`getMemoryOptimized32(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");else{const e="user"===a?this.lookupFunctionArgumentBitRatio(this.name,s):this.constantBitRatios[s];switch(e){case 1:t.push(`get8(${p}, ${p}Size, ${p}Dim, `);break;case 2:t.push(`get16(${p}, ${p}Size, ${p}Dim, `);break;case 4:case 0:t.push(`get32(${p}, ${p}Size, ${p}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${e}`)}this.memberExpressionXYZ(u,l,h,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`${p}[${this.memberExpressionPropertyMarkup(l)}]`),l&&t.push(`[${this.memberExpressionPropertyMarkup(u)}]`);break;default:throw new Error(`unhandled member expression "${o}"`)}return t}astCallExpression(e,t){if(!e.callee)throw this.astErrorOutput("Unknown CallExpression",e);let r=null;const s=this.isAstMathFunction(e);if(r=s||e.callee.object&&"ThisExpression"===e.callee.object.type?e.callee.property.name:"SequenceExpression"!==e.callee.type||"Literal"!==e.callee.expressions[0].type||isNaN(e.callee.expressions[0].raw)?e.callee.name:e.callee.expressions[1].property.name,!r)throw this.astErrorOutput("Unhandled function, couldn't find name",e);switch(r){case"pow":r="_pow";break;case"round":r="_round"}if(this.calledFunctions.indexOf(r)<0&&this.calledFunctions.push(r),"random"===r&&this.plugins&&this.plugins.length>0)for(let e=0;e0&&t.push(", "),"Integer"===s)this.castValueToFloat(r,t);else this.astGeneric(r,t)}else{const s=this.lookupFunctionArgumentTypes(r)||[];for(let i=0;i0&&t.push(", ");const u=this.getType(a);switch(o||(this.triggerImplyArgumentType(r,i,u,this),o=u),u){case"Boolean":this.astGeneric(a,t);continue;case"Number":case"Float":if("Integer"===o){t.push("int("),this.astGeneric(a,t),t.push(")");continue}if("Number"===o||"Float"===o){this.astGeneric(a,t);continue}if("LiteralInteger"===o){this.castLiteralToFloat(a,t);continue}break;case"Integer":if("Number"===o||"Float"===o){t.push("float("),this.astGeneric(a,t),t.push(")");continue}if("Integer"===o){this.astGeneric(a,t);continue}break;case"LiteralInteger":if("Integer"===o){this.castLiteralToInteger(a,t);continue}if("Number"===o||"Float"===o){this.castLiteralToFloat(a,t);continue}if("LiteralInteger"===o){this.astGeneric(a,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(o===u){if("Identifier"===a.type)t.push(`user_${n.sanitizeName(a.name)}`);else{if("ArrayExpression"!==a.type&&"MemberExpression"!==a.type&&"CallExpression"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.astGeneric(a,t)}continue}break;case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(o===u){if("Identifier"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.triggerImplyArgumentBitRatio(this.name,a.name,r,i);const s=n.sanitizeName(a.name);t.push(`user_${s},user_${s}Size,user_${s}Dim`);continue}}throw this.astErrorOutput(`Unhandled argument combination of ${u} and ${o} for argument named "${a.name}"`,e)}}return t.push(")"),t}astArrayExpression(e,t){const n=this.getType(e),r=e.elements.length;switch(n){case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`mat${r}(`);break;default:t.push(`vec${r}(`)}for(let n=0;n0&&t.push(", ");const r=e.elements[n];this.astGeneric(r,t)}return t.push(")"),t}memberExpressionXYZ(e,t,n,r){return n?r.push(this.memberExpressionPropertyMarkup(n),", "):r.push("0, "),t?r.push(this.memberExpressionPropertyMarkup(t),", "):r.push("0, "),r.push(this.memberExpressionPropertyMarkup(e)),r}memberExpressionPropertyMarkup(e){if(!e)throw new Error("Property not set");const t=[];switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;default:this.astGeneric(e,t)}const r=t.join("");if(this.hoistedIndexReads&&/\b\w+\((user_|constants_)\w+, \1\w+Size/.test(r)){const e=`hoisted_${this.hoistedIndexReads.length}_${n.sanitizeName(this.name)}`,t=r.startsWith("int(");return this.hoistedIndexReads.push(`${t?"int":"float"} ${e}=${r};\n`),e}return r}}}}),M=e((e,t)=>{t.exports={name:"math-random-uniformly-distributed",onBeforeRun:e=>{if(null===e.randomSeed||void 0===e.randomSeed)return e.setUniform1f("randomSeed1",Math.random()),void e.setUniform1f("randomSeed2",Math.random());e._mathRandomGenerator&&e._mathRandomGeneratorSeed===e.randomSeed||(e._mathRandomGenerator=function(e){let t=e>>>0;return function(){t=t+1831565813>>>0;let e=t;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296}}(e.randomSeed),e._mathRandomGeneratorSeed=e.randomSeed),e.setUniform1f("randomSeed1",e._mathRandomGenerator()),e.setUniform1f("randomSeed2",e._mathRandomGenerator())},functionMatch:"Math.random()",functionReplace:"nrand(vTexCoord)",functionReturnType:"Number",source:"// https://www.shadertoy.com/view/4t2SDh\n//note: uniformly distributed, normalized rand, [0,1]\nhighp float randomSeedShift = 1.0;\nhighp float slide = 1.0;\nuniform highp float randomSeed1;\nuniform highp float randomSeed2;\n\nhighp float nrand(highp vec2 n) {\n highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453);\n randomSeedShift = result;\n if (randomSeedShift > 0.5) {\n slide += 0.00009; \n } else {\n slide += 0.0009;\n }\n return result;\n}"}}),N=e((e,t)=>{t.exports={fragmentShader:`__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nvarying vec2 vTexCoord;\n\nfloat acosh(float x) {\n return log(x + sqrt(x * x - 1.0));\n}\n\nfloat sinh(float x) {\n return (pow(${Math.E}, x) - pow(${Math.E}, -x)) / 2.0;\n}\n\nfloat asinh(float x) {\n return log(x + sqrt(x * x + 1.0));\n}\n\nfloat atan2(float v1, float v2) {\n if (v2 == 0.0) {\n if (v1 == 0.0) return 0.0;\n if (v1 > 0.0) return 1.5707963267948966;\n if (v1 < 0.0) return -1.5707963267948966;\n }\n return atan(v1, v2);\n}\n\nfloat atanh(float x) {\n x = (x + 1.0) / (x - 1.0);\n if (x < 0.0) {\n return 0.5 * log(-x);\n }\n return 0.5 * log(x);\n}\n\nfloat cbrt(float x) {\n if (x >= 0.0) {\n return pow(x, 1.0 / 3.0);\n } else {\n return -pow(x, 1.0 / 3.0);\n }\n}\n\nfloat cosh(float x) {\n return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0; \n}\n\nfloat expm1(float x) {\n return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n return x;\n}\n\nfloat imul(float v1, float v2) {\n return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n if (v2 == 0.0) return 1.0;\n return pow(v1, v2);\n}\n\nfloat tanh(float x) {\n float e = exp(2.0 * x);\n return (e - 1.0) / (e + 1.0);\n}\n\nfloat trunc(float x) {\n if (x >= 0.0) {\n return floor(x); \n } else {\n return ceil(x);\n }\n}\n\nvec4 _round(vec4 x) {\n return floor(x + 0.5);\n}\n\nfloat _round(float x) {\n return floor(x + 0.5);\n}\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n // ~a is identically -a - 1 in two's complement, for every value including\n // negatives. The previous bit-by-bit loop only worked for a >= 0, where it\n // leaned on 32-bit overflow wrapping to reach the negative answer; given a\n // negative input it computed ~abs(a), so ~(-1) gave -2 and ~~x never\n // returned x.\n return -a - 1;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\n// _pow2 is defined further down, alongside encode32/decode32\nfloat _pow2(float e);\nint bitwiseSignedRightShift(int num, int shifts) {\n // pow(2.0, n) is approximate on many GPUs, and landing 1 ulp high makes the\n // division fall just under a whole number, which floor() then rounds away:\n // 2 >> 1 came out 0, 8 >> 1 came out 3. Only exact left operands were\n // affected, odd ones having enough slack to survive. _pow2 is exact.\n return int(floor(float(num) / _pow2(float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x / y));\n}\n\n// GLSL ES 1.00 accepts only a constant or a loop symbol inside an index\n// expression, so m[y][x] does not compile when y and x come from kernel\n// arguments -- the error is "Index expression can only contain const or loop\n// symbols". Loop counters are legal indices, so walk the matrix with them\n// instead. These are 2x2 to 4x4, so it costs at most sixteen comparisons.\nfloat getMatrix2(mat2 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 2; i++) {\n for (int j = 0; j < 2; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix3(mat3 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 3; i++) {\n for (int j = 0; j < 3; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix4(mat4 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 4; i++) {\n for (int j = 0; j < 4; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\n// Exact powers of two built from exact constant multiplies: exp2/log2/pow\n// are approximate on some GPUs (notably Apple silicon), and 1-2 ulp there\n// corrupts the packed bytes (#659)\nfloat _pow2(float e) {\n float r = 1.0;\n float a = abs(e);\n bool n = e < 0.0;\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 32.0) { r *= n ? 2.3283064365386963e-10 : 4294967296.0; a -= 32.0; }\n if (a >= 16.0) { r *= n ? 0.0000152587890625 : 65536.0; a -= 16.0; }\n if (a >= 8.0) { r *= n ? 0.00390625 : 256.0; a -= 8.0; }\n if (a >= 4.0) { r *= n ? 0.0625 : 16.0; a -= 4.0; }\n if (a >= 2.0) { r *= n ? 0.25 : 4.0; a -= 2.0; }\n if (a >= 1.0) { r *= n ? 0.5 : 2.0; }\n return r;\n}\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = _pow2(_round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * _pow2(_round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\n return 0.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n if (channel == 0) return texel.r * 255.0;\n if (channel == 1) return texel.g * 255.0;\n if (channel == 2) return texel.b * 255.0;\n if (channel == 3) return texel.a * 255.0;\n return 0.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n float p2 = _pow2(exponent);\n // approximate log2 can land one off; correct by direct comparison\n if (p2 > value) { exponent -= 1.0; p2 *= 0.5; }\n else if (p2 * 2.0 <= value) { exponent += 1.0; p2 *= 2.0; }\n\n mantissa = value / p2 - 1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return texel.r;\n if (channel == 1) return texel.g;\n if (channel == 2) return texel.b;\n if (channel == 3) return texel.a;\n return 0.0;\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture2D(tex, st / vec2(texSize));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n \n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nvoid color(sampler2D image) {\n actualColor = texture2D(image, vTexCoord);\n}\n\nfloat modulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -mod(number, divisor);\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}`}}),V=e((e,t)=>{t.exports={vertexShader:"__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nattribute vec2 aPos;\nattribute vec2 aTexCoord;\n\nvarying vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"}}),O=e((e,t)=>{function n(e,t={}){const{contextName:n="gl",throwGetError:a,useTrackablePrimitives:o,recording:u=[],variables:l={},onReadPixels:h,onUnrecognizedArgumentLookup:c}=t,p=new Proxy(e,{get:function(t,p){switch(p){case"addComment":return E;case"checkThrowError":return _;case"getReadPixelsVariableName":return g;case"insertVariable":return T;case"reset":return y;case"setIndent":return S;case"toString":return x;case"getContextVariableName":return w}return"function"==typeof e[p]?function(){switch(p){case"getError":return a?u.push(`${f}if (${n}.getError() !== ${n}.NONE) throw new Error('error');`):u.push(`${f}${n}.getError();`),e.getError();case"getExtension":{const t=`${n}Variables${m.length}`;u.push(`${f}const ${t} = ${n}.getExtension('${arguments[0]}');`);const s=e.getExtension(arguments[0]);if(s&&"object"==typeof s){const e=r(s,{getEntity:b,useTrackablePrimitives:o,recording:u,contextName:t,contextVariables:m,variables:l,indent:f,onUnrecognizedArgumentLookup:c});return m.push(e),e}return m.push(null),s}case"readPixels":const t=m.indexOf(arguments[6]);let i;if(-1===t){const e=function(e){if(l)for(const t in l)if(l[t]===e)return t;return null}(arguments[6]);e?(i=e,u.push(`${f}${e}`)):(i=`${n}Variable${m.length}`,m.push(arguments[6]),u.push(`${f}const ${i} = new ${arguments[6].constructor.name}(${arguments[6].length});`))}else i=`${n}Variable${t}`;g=i;const p=[arguments[0],arguments[1],arguments[2],arguments[3],b(arguments[4]),b(arguments[5]),i];return u.push(`${f}${n}.readPixels(${p.join(", ")});`),h&&h(i,p),e.readPixels.apply(e,arguments);case"drawBuffers":return u.push(`${f}${n}.drawBuffers([${s(arguments[0],{contextName:n,contextVariables:m,getEntity:b,addVariable:A,variables:l,onUnrecognizedArgumentLookup:c})}]);`),e.drawBuffers(arguments[0])}let t=e[p].apply(e,arguments);switch(typeof t){case"undefined":return void u.push(`${f}${v(p,arguments)};`);case"number":case"boolean":if(o&&-1===m.indexOf(i(t))){u.push(`${f}const ${n}Variable${m.length} = ${v(p,arguments)};`),m.push(t=i(t));break}default:null===t?u.push(`${v(p,arguments)};`):u.push(`${f}const ${n}Variable${m.length} = ${v(p,arguments)};`),m.push(t)}return t}:(d[e[p]]=p,e[p])}}),m=[],d={};let g,f="";return p;function x(){return u.join("\n")}function y(){for(;u.length>0;)u.pop()}function T(e,t){l[e]=t}function b(e){const t=d[e];return t?n+"."+t:e}function S(e){f=" ".repeat(e)}function A(e,t){const r=`${n}Variable${m.length}`;return u.push(`${f}const ${r} = ${t};`),m.push(e),r}function E(e){u.push(`${f}// ${e}`)}function _(){u.push(`${f}(() => {\n${f}const error = ${n}.getError();\n${f}if (error !== ${n}.NONE) {\n${f} const names = Object.getOwnPropertyNames(gl);\n${f} for (let i = 0; i < names.length; i++) {\n${f} const name = names[i];\n${f} if (${n}[name] === error) {\n${f} throw new Error('${n} threw ' + name);\n${f} }\n${f} }\n${f}}\n${f}})();`)}function v(e,t){return`${n}.${e}(${s(t,{contextName:n,contextVariables:m,getEntity:b,addVariable:A,variables:l,onUnrecognizedArgumentLookup:c})})`}function w(e){const t=m.indexOf(e);return-1!==t?`${n}Variable${t}`:null}}function r(e,t){const n=new Proxy(e,{get:function(t,n){return"function"==typeof t[n]?function(){if("drawBuffersWEBGL"===n)return h.push(`${p}${a}.drawBuffersWEBGL([${s(arguments[0],{contextName:a,contextVariables:o,getEntity:d,addVariable:f,variables:c,onUnrecognizedArgumentLookup:m})}]);`),e.drawBuffersWEBGL(arguments[0]);let t=e[n].apply(e,arguments);switch(typeof t){case"undefined":return void h.push(`${p}${g(n,arguments)};`);case"number":case"boolean":l&&-1===o.indexOf(i(t))?(h.push(`${p}const ${a}Variable${o.length} = ${g(n,arguments)};`),o.push(t=i(t))):(h.push(`${p}const ${a}Variable${o.length} = ${g(n,arguments)};`),o.push(t));break;default:null===t?h.push(`${g(n,arguments)};`):h.push(`${p}const ${a}Variable${o.length} = ${g(n,arguments)};`),o.push(t)}return t}:(r[e[n]]=n,e[n])}}),r={},{contextName:a,contextVariables:o,getEntity:u,useTrackablePrimitives:l,recording:h,variables:c,indent:p,onUnrecognizedArgumentLookup:m}=t;return n;function d(e){return r.hasOwnProperty(e)?`${a}.${r[e]}`:u(e)}function g(e,t){return`${a}.${e}(${s(t,{contextName:a,contextVariables:o,getEntity:d,addVariable:f,variables:c,onUnrecognizedArgumentLookup:m})})`}function f(e,t){const n=`${a}Variable${o.length}`;return o.push(e),h.push(`${p}const ${n} = ${t};`),n}}function s(e,t){const{variables:n,onUnrecognizedArgumentLookup:r}=t;return Array.from(e).map(e=>{const s=function(e){if(n)for(const t in n)if(n.hasOwnProperty(t)&&n[t]===e)return t;return r?r(e):null}(e);return s||function(e,t){const{contextName:n,contextVariables:r,getEntity:s,addVariable:i,onUnrecognizedArgumentLookup:a}=t;if(void 0===e)return"undefined";if(null===e)return"null";const o=r.indexOf(e);if(o>-1)return`${n}Variable${o}`;switch(e.constructor.name){case"String":const t=/\n/.test(e),n=/'/.test(e),r=/"/.test(e);return t?"`"+e+"`":n&&!r?'"'+e+'"':"'"+e+"'";case"Number":case"Boolean":return s(e);case"Array":return i(e,`new ${e.constructor.name}([${Array.from(e).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return i(e,`new ${e.constructor.name}(${JSON.stringify(Array.from(e))})`);default:if(a){const t=a(e);if(t)return t}throw new Error(`unrecognized argument type ${e.constructor.name}`)}}(e,t)}).join(", ")}function i(e){return new e.constructor(e)}void 0!==t&&(t.exports={glWiretap:n,glExtensionWiretap:r}),"undefined"!=typeof window&&(n.glExtensionWiretap=r,window.glWiretap=n)}),k=e((e,t)=>{const{glWiretap:n}=O(),{utils:r}=i();function s(e){let t=e.toString().replace(/^function /,"");const n=t.indexOf("=>");if(-1!==n&&!/[{]|\bfunction\b/.test(t.slice(0,n))){const e=t.slice(0,n).trim(),r=t.slice(n+2).trim();t=r.startsWith("{")?`${e} ${r}`:`${e} { return ${r}; }`}return t.replace(/utils[.]/g,"/*utils.*/")}function a(e,t){const n="single"===t.precision?e:`new Float32Array(${e}.buffer)`;return t.output[2]?`renderOutput(${n}, ${t.output[0]}, ${t.output[1]}, ${t.output[2]})`:t.output[1]?`renderOutput(${n}, ${t.output[0]}, ${t.output[1]})`:`renderOutput(${n}, ${t.output[0]})`}function o(e,t){const n=e.toArray.toString(),s=!/^function/.test(n);return`() => {\n function framebuffer() { return getReadFramebuffer(); };\n ${r.flattenFunctionToString(`${s?"function ":""}${n}`,{findDependency:(t,n)=>{if("utils"===t)return`const ${n} = ${r[n].toString()};`;if("this"===t)return"framebuffer"===n?"":`${s?"function ":""}${e[n].toString()}`;throw new Error("unhandled fromObject")},thisLookup:(n,r)=>{if("texture"===n)return t;if("context"===n)return r?null:"gl";if(e.hasOwnProperty(n))return JSON.stringify(e[n]);throw new Error(`unhandled thisLookup ${n}`)}})}\n return toArray();\n }`}function u(e,t,n,r,s){if(null===e)return null;if(null===t)return null;switch(typeof e){case"boolean":case"number":return null}if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement)for(let s=0;s{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}}):null;const c=[],p=[],m=n(i.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if(M.subKernels){if(d){const t=M.subKernels[g++].property;p.push(` result${isNaN(t)?"."+t:`[${t}]`} = ${a(e,M)};`)}else p.push(` const result = { result: ${a(e,M)} };`),d=!0;g===M.subKernels.length&&p.push(" return result;")}else e?p.push(` return ${a(e,M)};`):p.push(" return null;")},onUnrecognizedArgumentLookup:e=>{const t=u(e,M.kernelArguments,[],m,c);if(t)return t;const n=u(e,M.kernelConstants,A?Object.keys(A).map(e=>A[e]):[],m,c);return n||null}});let d=!1,g=0;const{source:f,canvas:x,output:y,pipeline:T,graphical:b,loopMaxIterations:S,constants:A,optimizeFloatMemory:E,precision:_,fixIntegerDivisionAccuracy:v,functions:w,nativeFunctions:D,subKernels:I,immutable:$,argumentTypes:F,constantTypes:R,kernelArguments:L,kernelConstants:z,tactic:C}=i,M=new e(f,{canvas:x,context:m,checkContext:!1,output:y,pipeline:T,graphical:b,loopMaxIterations:S,constants:A,optimizeFloatMemory:E,precision:_,fixIntegerDivisionAccuracy:v,functions:w,nativeFunctions:D,subKernels:I,immutable:$,argumentTypes:F,constantTypes:R,tactic:C});let N=[];if(m.setIndent(2),M.build.apply(M,t),N.push(m.toString()),m.reset(),M.kernelArguments.forEach((e,n)=>{switch(e.type){case"Integer":case"Boolean":case"Number":case"Float":case"Array":case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":case"Input":m.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let r=0;re.varName).join(", ")}) {`),m.setIndent(4),M.run.apply(M,t),M.renderKernels?M.renderKernels():M.renderOutput&&M.renderOutput(),N.push(" /** start setup uploads for kernel values **/"),M.kernelArguments.forEach(e=>{N.push(" "+e.getStringValueHandler().split("\n").join("\n "))}),N.push(" /** end setup uploads for kernel values **/"),N.push(m.toString()),M.renderOutput===M.renderTexture)if(m.reset(),M.renderKernels){const e=M.renderKernels(),t=m.getContextVariableName(M.texture.texture);N.push(` return {\n result: {\n texture: ${t},\n type: '${e.result.type}',\n toArray: ${o(e.result,t)}\n },`);const{subKernels:n,mappedTextures:r}=M;for(let t=0;t"utils"===e?`const ${t} = ${r[t].toString()};`:null,thisLookup:t=>{if("context"===t)return null;if(e.hasOwnProperty(t))return JSON.stringify(e[t]);throw new Error(`unhandled thisLookup ${t}`)}})}(M)),N.push(" innerKernel.getPixels = getPixels;")),N.push(" return innerKernel;");let V=[];return z.forEach(e=>{V.push(`${e.getStringValueHandler()}`)}),`function kernel(settings) {\n const { context, constants } = settings;\n ${V.join("")}\n ${l||""}\n${N.join("\n")}\n}`}}}),K=e((e,t)=>{t.exports={KernelValue:class{constructor(e,t){const{name:n,kernel:r,context:s,checkContext:i,onRequestContextHandle:a,onUpdateValueMismatch:o,origin:u,strictIntegers:l,type:h,tactic:c}=t;if(!n)throw new Error("name not set");if(!h)throw new Error("type not set");if(!u)throw new Error("origin not set");if("user"!==u&&"constants"!==u)throw new Error(`origin must be "user" or "constants" value is "${u}"`);if(!a)throw new Error("onRequestContextHandle is not set");this.name=n,this.origin=u,this.tactic=c,this.varName="constants"===u?`constants.${n}`:n,this.kernel=r,this.strictIntegers=l,this.type=e.type||h,this.size=e.size||null,this.index=null,this.context=s,this.checkContext=null==i||i,this.contextHandle=null,this.onRequestContextHandle=a,this.onUpdateValueMismatch=o,this.forceUploadEachRun=null}get id(){return`${this.origin}_${name}`}getSource(){throw new Error(`"getSource" not defined on ${this.constructor.name}`)}updateValue(e){throw new Error(`"updateValue" not defined on ${this.constructor.name}`)}}}}),G=e((e,t)=>{const{utils:n}=i(),{KernelValue:r}=K();t.exports={WebGLKernelValue:class extends r{constructor(e,t){super(e,t),this.dimensionsId=null,this.sizeId=null,this.initialValueConstructor=e.constructor,this.onRequestTexture=t.onRequestTexture,this.onRequestIndex=t.onRequestIndex,this.uploadValue=null,this.textureSize=null,this.bitRatio=null,this.prevArg=null}get id(){return`${this.origin}_${n.sanitizeName(this.name)}`}setup(){}getTransferArrayType(e){if(Array.isArray(e[0]))return this.getTransferArrayType(e[0]);switch(e.constructor){case Array:case Int32Array:case Int16Array:case Int8Array:return Float32Array;case Uint8ClampedArray:case Uint8Array:case Uint16Array:case Uint32Array:case Float32Array:case Float64Array:return e.constructor}return console.warn("Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros"),e.constructor}getStringValueHandler(){throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`)}getVariablePrecisionString(){return this.kernel.getVariablePrecisionString(this.textureSize||void 0,this.tactic||void 0)}destroy(){}}}}),U=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValue:r}=G();t.exports={WebGLKernelValueBoolean:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const bool ${this.id} = ${e};\n`:`uniform bool ${this.id};\n`}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),P=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValue:r}=G();t.exports={WebGLKernelValueFloat:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?Number.isInteger(e)?`const float ${this.id} = ${e}.0;\n`:`const float ${this.id} = ${e};\n`:`uniform float ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1f(this.id,this.uploadValue=e)}}}}),B=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValue:r}=G();t.exports={WebGLKernelValueInteger:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?`const int ${this.id} = ${parseInt(e)};\n`:`uniform int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),j=e((e,t)=>{const{WebGLKernelValue:n}=G(),{Input:s}=r();t.exports={WebGLKernelArray:class extends n{checkSize(e,t){if(!this.kernel.validate)return;const{maxTextureSize:n}=this.kernel.constructor.features;if(e>n||t>n)throw e>t?new Error(`Argument texture width of ${e} larger than maximum size of ${n} for your GPU`):e{const{utils:n}=i(),{WebGLKernelArray:r}=j();function s(e){return{width:e.width>0?e.width:e.videoWidth,height:e.height>0?e.height:e.videoHeight}}t.exports={WebGLKernelValueHTMLImage:class extends r{constructor(e,t){super(e,t);const{width:n,height:r}=s(e);this.checkSize(n,r),this.dimensions=[n,r,1],this.textureSize=[n,r],this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue=e),this.kernel.setUniform1i(this.id,this.index)}},mediaSize:s}}),H=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueHTMLImage:r,mediaSize:s}=W();t.exports={WebGLKernelValueDynamicHTMLImage:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:n}=s(e);this.checkSize(t,n),this.dimensions=[t,n,1],this.textureSize=[t,n],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),X=e((e,t)=>{const{WebGLKernelValueHTMLImage:n}=W();t.exports={WebGLKernelValueHTMLVideo:class extends n{}}}),q=e((e,t)=>{const{WebGLKernelValueDynamicHTMLImage:n}=H();t.exports={WebGLKernelValueDynamicHTMLVideo:class extends n{}}}),Y=e((e,t)=>{const{utils:n}=i(),{WebGLKernelArray:r}=j();t.exports={WebGLKernelValueSingleInput:class extends r{constructor(e,t){super(e,t),this.bitRatio=4;let[r,s,i]=e.size;this.dimensions=new Int32Array([r||1,s||1,i||1]),this.textureSize=n.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return n.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}.value, uploadValue_${this.name})`])}getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;n.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Z=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueSingleInput:r}=Y();t.exports={WebGLKernelValueDynamicSingleInput:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,r,s]=e.size;this.dimensions=new Int32Array([t||1,r||1,s||1]),this.textureSize=n.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),J=e((e,t)=>{const{utils:n}=i(),{WebGLKernelArray:r}=j();t.exports={WebGLKernelValueUnsignedInput:class extends r{constructor(e,t){super(e,t),this.bitRatio=this.getBitRatio(e);const[r,s,i]=e.size;this.dimensions=new Int32Array([r||1,s||1,i||1]),this.textureSize=n.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]),this.TranserArrayType=this.getTransferArrayType(e.value),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return n.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}.value, preUploadValue_${this.name})`])}getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(value.constructor);const{context:t}=this;n.flattenTo(e.value,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Q=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueUnsignedInput:r}=J();t.exports={WebGLKernelValueDynamicUnsignedInput:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,r,s]=e.size;this.dimensions=new Int32Array([t||1,r||1,s||1]),this.textureSize=n.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]);const i=this.getTransferArrayType(e.value);this.preUploadValue=new i(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ee=e((e,t)=>{const{utils:n}=i(),{WebGLKernelArray:r}=j(),s="Source and destination textures are the same. Use immutable = true and manually cleanup kernel output texture memory with texture.delete()";t.exports={WebGLKernelValueMemoryOptimizedNumberTexture:class extends r{constructor(e,t){super(e,t);const[n,r]=e.size;this.checkSize(n,r),this.dimensions=e.dimensions,this.textureSize=e.size,this.uploadValue=e.texture,this.forceUploadEachRun=!0}setup(){this.setupTexture()}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{kernel:t,context:n}=this;if(t.pipeline)if(t.immutable)t.updateTextureArgumentRefs(this,e);else{if(t.texture&&t.texture.texture===e.texture)throw new Error(s);if(t.mappedTextures){const{mappedTextures:n}=t;for(let t=0;t{const{utils:n}=i(),{WebGLKernelValueMemoryOptimizedNumberTexture:r}=ee();t.exports={WebGLKernelValueDynamicMemoryOptimizedNumberTexture:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ne=e((e,t)=>{const{utils:n}=i(),{WebGLKernelArray:r}=j(),{sameError:s}=ee();t.exports={WebGLKernelValueNumberTexture:class extends r{constructor(e,t){super(e,t);const[n,r]=e.size;this.checkSize(n,r);const{size:s,dimensions:i}=e;this.bitRatio=this.getBitRatio(e),this.dimensions=i,this.textureSize=s,this.uploadValue=e.texture,this.forceUploadEachRun=!0}setup(){this.setupTexture()}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{kernel:t,context:n}=this;if(t.pipeline)if(t.immutable)t.updateTextureArgumentRefs(this,e);else{if(t.texture&&t.texture.texture===e.texture)throw new Error(s);if(t.mappedTextures){const{mappedTextures:n}=t;for(let t=0;t{const{utils:n}=i(),{WebGLKernelValueNumberTexture:r}=ne();t.exports={WebGLKernelValueDynamicNumberTexture:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),se=e((e,t)=>{const{utils:n}=i(),{WebGLKernelArray:r}=j();t.exports={WebGLKernelValueSingleArray:class extends r{constructor(e,t){super(e,t),this.bitRatio=4,this.dimensions=n.getDimensions(e,!0),this.textureSize=n.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return n.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;n.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ie=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueSingleArray:r}=se();t.exports={WebGLKernelValueDynamicSingleArray:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=n.getDimensions(e,!0),this.textureSize=n.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ae=e((e,t)=>{const{utils:n}=i(),{WebGLKernelArray:r}=j();t.exports={WebGLKernelValueSingleArray1DI:class extends r{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=n.getDimensions(e,!0);this.textureSize=n.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],1,1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return n.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;n.flatten2dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),oe=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueSingleArray1DI:r}=ae();t.exports={WebGLKernelValueDynamicSingleArray1DI:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ue=e((e,t)=>{const{utils:n}=i(),{WebGLKernelArray:r}=j();t.exports={WebGLKernelValueSingleArray2DI:class extends r{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=n.getDimensions(e,!0);this.textureSize=n.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return n.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;n.flatten3dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),le=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueSingleArray2DI:r}=ue();t.exports={WebGLKernelValueDynamicSingleArray2DI:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),he=e((e,t)=>{const{utils:n}=i(),{WebGLKernelArray:r}=j();t.exports={WebGLKernelValueSingleArray3DI:class extends r{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=n.getDimensions(e,!0);this.textureSize=n.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],t[3]]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return n.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;n.flatten4dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ce=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueSingleArray3DI:r}=he();t.exports={WebGLKernelValueDynamicSingleArray3DI:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),pe=e((e,t)=>{const{WebGLKernelValue:n}=G();t.exports={WebGLKernelValueArray2:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec2 ${this.id} = vec2(${e[0]},${e[1]});\n`:`uniform vec2 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform2fv(this.id,this.uploadValue=e)}}}}),me=e((e,t)=>{const{WebGLKernelValue:n}=G();t.exports={WebGLKernelValueArray3:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec3 ${this.id} = vec3(${e[0]},${e[1]},${e[2]});\n`:`uniform vec3 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform3fv(this.id,this.uploadValue=e)}}}}),de=e((e,t)=>{const{WebGLKernelValue:n}=G();t.exports={WebGLKernelValueArray4:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec4 ${this.id} = vec4(${e[0]},${e[1]},${e[2]},${e[3]});\n`:`uniform vec4 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform4fv(this.id,this.uploadValue=e)}}}}),ge=e((e,t)=>{const{utils:n}=i(),{WebGLKernelArray:r}=j();t.exports={WebGLKernelValueUnsignedArray:class extends r{constructor(e,t){super(e,t),this.bitRatio=this.getBitRatio(e),this.dimensions=n.getDimensions(e,!0),this.textureSize=n.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]),this.TranserArrayType=this.getTransferArrayType(e),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return n.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}, preUploadValue_${this.name})`])}getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;n.flattenTo(e,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),fe=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueUnsignedArray:r}=ge();t.exports={WebGLKernelValueDynamicUnsignedArray:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=n.getDimensions(e,!0),this.textureSize=n.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]);const t=this.getTransferArrayType(e);this.preUploadValue=new t(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),xe=e((e,t)=>{const{WebGLKernelValueBoolean:n}=U(),{WebGLKernelValueFloat:r}=P(),{WebGLKernelValueInteger:s}=B(),{WebGLKernelValueHTMLImage:i}=W(),{WebGLKernelValueDynamicHTMLImage:a}=H(),{WebGLKernelValueHTMLVideo:o}=X(),{WebGLKernelValueDynamicHTMLVideo:u}=q(),{WebGLKernelValueSingleInput:l}=Y(),{WebGLKernelValueDynamicSingleInput:h}=Z(),{WebGLKernelValueUnsignedInput:c}=J(),{WebGLKernelValueDynamicUnsignedInput:p}=Q(),{WebGLKernelValueMemoryOptimizedNumberTexture:m}=ee(),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:d}=te(),{WebGLKernelValueNumberTexture:g}=ne(),{WebGLKernelValueDynamicNumberTexture:f}=re(),{WebGLKernelValueSingleArray:x}=se(),{WebGLKernelValueDynamicSingleArray:y}=ie(),{WebGLKernelValueSingleArray1DI:T}=ae(),{WebGLKernelValueDynamicSingleArray1DI:b}=oe(),{WebGLKernelValueSingleArray2DI:S}=ue(),{WebGLKernelValueDynamicSingleArray2DI:A}=le(),{WebGLKernelValueSingleArray3DI:E}=he(),{WebGLKernelValueDynamicSingleArray3DI:_}=ce(),{WebGLKernelValueArray2:v}=pe(),{WebGLKernelValueArray3:w}=me(),{WebGLKernelValueArray4:D}=de(),{WebGLKernelValueUnsignedArray:I}=ge(),{WebGLKernelValueDynamicUnsignedArray:$}=fe(),F={unsigned:{dynamic:{Boolean:n,Integer:s,Float:r,Array:$,"Array(2)":v,"Array(3)":w,"Array(4)":D,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:p,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:d,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u},static:{Boolean:n,Float:r,Integer:s,Array:I,"Array(2)":v,"Array(3)":w,"Array(4)":D,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:c,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:m,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:!1,HTMLVideo:o}},single:{dynamic:{Boolean:n,Integer:s,Float:r,Array:y,"Array(2)":v,"Array(3)":w,"Array(4)":D,"Array1D(2)":b,"Array1D(3)":b,"Array1D(4)":b,"Array2D(2)":A,"Array2D(3)":A,"Array2D(4)":A,"Array3D(2)":_,"Array3D(3)":_,"Array3D(4)":_,Input:h,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:d,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u},static:{Boolean:n,Float:r,Integer:s,Array:x,"Array(2)":v,"Array(3)":w,"Array(4)":D,"Array1D(2)":T,"Array1D(3)":T,"Array1D(4)":T,"Array2D(2)":S,"Array2D(3)":S,"Array2D(4)":S,"Array3D(2)":E,"Array3D(3)":E,"Array3D(4)":E,Input:l,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:m,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:!1,HTMLVideo:o}}};t.exports={lookupKernelValueType:function(e,t,n,r){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!n)throw new Error("precision missing");r.type&&(e=r.type);const s=F[n][t];if(!1===s[e])return null;if(void 0===s[e])throw new Error(`Could not find a KernelValue for ${e}`);return s[e]},kernelValueMaps:F}}),ye=e((e,t)=>{const{GLKernel:n}=z(),{FunctionBuilder:r}=o(),{WebGLFunctionNode:s}=C(),{utils:a}=i(),u=M(),{fragmentShader:l}=N(),{vertexShader:h}=V(),{glKernelString:c}=k(),{lookupKernelValueType:p}=xe();let m=null,d=null,g=null,f=null,x=null;const y=[u],T=[],b={};t.exports={WebGLKernel:class extends n{static get isSupported(){return null!==m||(this.setupFeatureChecks(),m=this.isContextMatch(g)),m}static setupFeatureChecks(){"undefined"!=typeof document?d=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(d=new OffscreenCanvas(0,0)),d&&(g=d.getContext("webgl"),g||d instanceof OffscreenCanvas||(g=d.getContext("experimental-webgl")),g&&g.getExtension&&(f={OES_texture_float:g.getExtension("OES_texture_float"),OES_texture_float_linear:g.getExtension("OES_texture_float_linear"),OES_element_index_uint:g.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:g.getExtension("WEBGL_draw_buffers")},x=this.getFeatures()))}static isContextMatch(e){return"undefined"!=typeof WebGLRenderingContext&&e instanceof WebGLRenderingContext}static getIsTextureFloat(){return Boolean(f.OES_texture_float)}static getIsDrawBuffers(){return Boolean(f.WEBGL_draw_buffers)}static getChannelCount(){return f.WEBGL_draw_buffers?g.getParameter(f.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return g.getParameter(g.MAX_TEXTURE_SIZE)}static lookupKernelValueType(e,t,n,r){return p(e,t,n,r)}static get testCanvas(){return d}static get testContext(){return g}static get features(){return x}static get fragmentShader(){return l}static get vertexShader(){return h}constructor(e,t){super(e,t),this.program=null,this.pipeline=t.pipeline,this.endianness=a.systemEndianness(),this.extensions={},this.argumentTextureCount=0,this.constantTextureCount=0,this.fragShader=null,this.vertShader=null,this.drawBuffersMap=null,this.maxTexSize=null,this.onRequestSwitchKernel=null,this.texture=null,this.mappedTextures=null,this.mergeSettings(e.settings||t),this.threadDim=null,this.framebuffer=null,this.buffer=null,this.textureCache=[],this.programUniformLocationCache={},this.uniform1fCache={},this.uniform1iCache={},this.uniform2fCache={},this.uniform2fvCache={},this.uniform2ivCache={},this.uniform3fvCache={},this.uniform3ivCache={},this.uniform4fvCache={},this.uniform4ivCache={}}initCanvas(){if("undefined"!=typeof document){const e=document.createElement("canvas");return e.width=2,e.height=2,e}if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(0,0)}initContext(){const e={alpha:!1,depth:!1,antialias:!1};return this.canvas.getContext("webgl",e)||this.canvas.getContext("experimental-webgl",e)}initPlugins(e){const t=[],{source:n}=this;if("string"==typeof n)for(let e=0;ee===r.name)&&t.push(r)}return t}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if(!0===this.optimizeFloatMemory&&!t.isTextureFloat)throw new Error("Float textures are not supported");if("single"===this.precision&&!t.isFloatRead)throw new Error("Single precision not supported");if(this.graphical||null!==this.precision||(this.precision=t.isTextureFloat&&t.isFloatRead?"single":"unsigned"),this.subKernels&&this.subKernels.length>0&&!this.extensions.WEBGL_draw_buffers)throw new Error("could not instantiate draw buffers extension");if(null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);switch(t){case"Array":this.output=a.getDimensions(t);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=e[0].output;break;default:throw new Error("Auto output not supported for input type: "+t)}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"precision"===this.precision&&(this.precision="unsigned",console.warn("Cannot use graphical mode and single precision at the same time")),void(this.texSize=a.clone(this.output))}null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}updateMaxTexSize(){const{texSize:e,canvas:t}=this;if(null===this.maxTexSize){let n=T.indexOf(t);-1===n&&(n=T.length,T.push(t),b[n]=[e[0],e[1]]),this.maxTexSize=b[n]}this.maxTexSize[0]this.argumentNames.length)throw new Error("too many arguments for kernel");const{context:n}=this;let r=0;const s=()=>this.createTexture(),i=()=>this.constantTextureCount+r++,o=e=>{this.switchKernels({type:"argumentMismatch",needed:e})},u=()=>n.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++;for(let r=0;rthis.createTexture(),onRequestIndex:()=>r++,onRequestContextHandle:()=>t.TEXTURE0+this.constantTextureCount++});this.constantBitRatios[s]=l.bitRatio,this.kernelConstants.push(l),l.setup(),l.forceUploadEachRun&&this.forceUploadKernelConstants.push(l)}}build(){if(this.built)return;if(this.initExtensions(),this.validateSettings(arguments),this.setupConstants(arguments),this.fallbackRequested)return;if(this.setupArguments(arguments),this.fallbackRequested)return;this.updateMaxTexSize(),this.translateSource();const e=this.pickRenderStrategy(arguments);if(e)return e;const{texSize:t,context:n,canvas:r}=this;n.enable(n.SCISSOR_TEST),this.pipeline&&this.precision,n.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]),r.width=this.maxTexSize[0],r.height=this.maxTexSize[1];const s=this.threadDim=Array.from(this.output);for(;s.length<3;)s.push(1);const i=this.getVertexShader(arguments),a=n.createShader(n.VERTEX_SHADER);n.shaderSource(a,i),n.compileShader(a),this.vertShader=a;const o=this.getFragmentShader(arguments),u=n.createShader(n.FRAGMENT_SHADER);if(n.shaderSource(u,o),n.compileShader(u),this.fragShader=u,this.debug&&(console.log("GLSL Shader Output:"),console.log(o)),!n.getShaderParameter(a,n.COMPILE_STATUS))throw new Error("Error compiling vertex shader: "+n.getShaderInfoLog(a));if(!n.getShaderParameter(u,n.COMPILE_STATUS))throw new Error("Error compiling fragment shader: "+n.getShaderInfoLog(u));const l=this.program=n.createProgram();n.attachShader(l,a),n.attachShader(l,u),n.linkProgram(l),this.framebuffer=n.createFramebuffer(),this.framebuffer.width=t[0],this.framebuffer.height=t[1],this.rawValueFramebuffers={};const h=new Float32Array([-1,-1,1,-1,-1,1,1,1]),c=new Float32Array([0,0,1,0,0,1,1,1]),p=h.byteLength;let m=this.buffer;m?n.bindBuffer(n.ARRAY_BUFFER,m):(m=this.buffer=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,m),n.bufferData(n.ARRAY_BUFFER,h.byteLength+c.byteLength,n.STATIC_DRAW)),n.bufferSubData(n.ARRAY_BUFFER,0,h),n.bufferSubData(n.ARRAY_BUFFER,p,c);const d=n.getAttribLocation(this.program,"aPos");-1!==d&&(n.enableVertexAttribArray(d),n.vertexAttribPointer(d,2,n.FLOAT,!1,0,0));const g=n.getAttribLocation(this.program,"aTexCoord");-1!==g&&(n.enableVertexAttribArray(g),n.vertexAttribPointer(g,2,n.FLOAT,!1,0,p)),n.bindFramebuffer(n.FRAMEBUFFER,this.framebuffer);let f=0;n.useProgram(this.program);for(let e in this.constants)this.kernelConstants[f++].updateValue(this.constants[e]);this._setupOutputTexture(),null!==this.subKernels&&this.subKernels.length>0&&(this._mappedTextureSwitched={},this._setupSubOutputTextures()),this.buildSignature(arguments),this.built=!0}translateSource(){const e=r.fromKernel(this,s,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=e.getPrototypeString("kernel"),this.setupReturnTypes(e)}setupReturnTypes(e){if(this.graphical||this.returnType||(this.returnType=e.getKernelResultType()),this.subKernels&&this.subKernels.length>0)for(let t=0;te.source&&this.source.match(e.functionMatch)?e.source:"").join("\n"):"\n"}_getConstantsString(){const e=[],{threadDim:t,texSize:n}=this;return this.dynamicOutput?e.push("uniform ivec3 uOutputDim","uniform ivec2 uTexSize"):e.push(`ivec3 uOutputDim = ivec3(${t[0]}, ${t[1]}, ${t[2]})`,`ivec2 uTexSize = ivec2(${n[0]}, ${n[1]})`),a.linesToString(e)}_getTextureCoordinate(){const e=this.subKernels;return null===e||e.length<1?"varying vec2 vTexCoord;\n":"out vec2 vTexCoord;\n"}_getDecode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getEncode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getDivideWithIntegerCheckString(){return this.fixIntegerDivisionAccuracy?"float divWithIntCheck(float x, float y) {\n if (floor(x) == x && floor(y) == y) {\n float q = floor(x / y + 0.5);\n if (y * q == x) {\n return q;\n }\n }\n return x / y;\n}\n\nfloat integerCorrectionModulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -(number - (divisor * floor(divWithIntCheck(number, divisor))));\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return number - (divisor * floor(divWithIntCheck(number, divisor)));\n}":""}_getMainArgumentsString(e){const t=[],{argumentNames:n}=this;for(let r=0;r{if(t.hasOwnProperty(n))return t[n];throw`unhandled artifact ${n}`})}getFragmentShader(e){return null!==this.compiledFragmentShader?this.compiledFragmentShader:this.compiledFragmentShader=this.replaceArtifacts(this.constructor.fragmentShader,this._getFragShaderArtifactMap(e))}getVertexShader(e){return null!==this.compiledVertexShader?this.compiledVertexShader:this.compiledVertexShader=this.replaceArtifacts(this.constructor.vertexShader,this._getVertShaderArtifactMap(e))}toString(){const e=a.linesToString(["const gl = context"]);return c(this.constructor,arguments,this,e)}destroy(e){if(!this.context)return;this.buffer&&this.context.deleteBuffer(this.buffer),this.framebuffer&&this.context.deleteFramebuffer(this.framebuffer);for(const e in this.rawValueFramebuffers){for(const t in this.rawValueFramebuffers[e])this.context.deleteFramebuffer(this.rawValueFramebuffers[e][t]),delete this.rawValueFramebuffers[e][t];delete this.rawValueFramebuffers[e]}if(this.vertShader&&this.context.deleteShader(this.vertShader),this.fragShader&&this.context.deleteShader(this.fragShader),this.program&&this.context.deleteProgram(this.program),this.texture){this.texture.delete();const e=this.textureCache.indexOf(this.texture.texture);e>-1&&this.textureCache.splice(e,1),this.texture=null}if(this.mappedTextures&&this.mappedTextures.length){for(let e=0;e-1&&this.textureCache.splice(n,1)}this.mappedTextures=null}if(this.kernelArguments)for(let e=0;e0;){const e=this.textureCache.pop();this.context.deleteTexture(e)}if(e){const e=T.indexOf(this.canvas);e>=0&&(T[e]=null,b[e]=null)}if(this.destroyExtensions(),delete this.context,delete this.canvas,!this.gpu)return;const t=this.gpu.kernels.indexOf(this);-1!==t&&this.gpu.kernels.splice(t,1)}destroyExtensions(){this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("WEBGL_lose_context");t&&t.loseContext()}toJSON(){const e=super.toJSON();return e.functionNodes=r.fromKernel(this,s).toJSON(),e.settings.threadDim=this.threadDim,e}}}}),Te=e((e,t)=>{const r=n(),{WebGLKernel:s}=ye(),{glKernelString:i}=k();let a=null,o=null,u=null,l=null,h=null;t.exports={HeadlessGLKernel:class extends s{static get isSupported(){return null!==a||(this.setupFeatureChecks(),a=null!==u),a}static setupFeatureChecks(){if(o=null,l=null,"function"==typeof r)try{if(u=r(2,2,{preserveDrawingBuffer:!0}),!u||!u.getExtension)return;l={STACKGL_resize_drawingbuffer:u.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:u.getExtension("STACKGL_destroy_context"),OES_texture_float:u.getExtension("OES_texture_float"),OES_texture_float_linear:u.getExtension("OES_texture_float_linear"),OES_element_index_uint:u.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:u.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:u.getExtension("WEBGL_color_buffer_float")},h=this.getFeatures()}catch(e){console.warn(e)}}static isContextMatch(e){try{return"ANGLE"===e.getParameter(e.RENDERER)}catch(e){return!1}}static getIsTextureFloat(){return Boolean(l.OES_texture_float)}static getIsDrawBuffers(){return Boolean(l.WEBGL_draw_buffers)}static getChannelCount(){return l.WEBGL_draw_buffers?u.getParameter(l.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return u.getParameter(u.MAX_TEXTURE_SIZE)}static get testCanvas(){return o}static get testContext(){return u}static get features(){return h}initCanvas(){return{}}initContext(){return r(2,2,{preserveDrawingBuffer:!0})}initExtensions(){this.extensions={STACKGL_resize_drawingbuffer:this.context.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:this.context.getExtension("STACKGL_destroy_context"),OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers")}}build(){super.build.apply(this,arguments),this.fallbackRequested||this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}destroyExtensions(){this.extensions.STACKGL_resize_drawingbuffer=null,this.extensions.STACKGL_destroy_context=null,this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("STACKGL_destroy_context");t&&t.destroy&&t.destroy()}toString(){return i(this.constructor,arguments,this,"const gl = context || require('gl')(1, 1);\n"," if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n")}setOutput(e){return super.setOutput(e),this.graphical&&this.extensions.STACKGL_resize_drawingbuffer&&this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1]),this}}}}),be=e((e,t)=>{const{utils:n}=i(),{WebGLFunctionNode:r}=C();t.exports={WebGL2FunctionNode:class extends r{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const r=this.getType(e),s=n.sanitizeName(e.name);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===r&&this.argumentNames.indexOf(s)>-1?t.push(`bool(user_${s})`):t.push(`user_${s}`),t}}}}),Se=e((e,t)=>{t.exports={fragmentShader:`#version 300 es\n__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nin vec2 vTexCoord;\n\nfloat atan2(float v1, float v2) {\n if (v2 == 0.0) {\n if (v1 == 0.0) return 0.0;\n if (v1 > 0.0) return 1.5707963267948966;\n if (v1 < 0.0) return -1.5707963267948966;\n }\n return atan(v1, v2);\n}\n\nfloat cbrt(float x) {\n if (x >= 0.0) {\n return pow(x, 1.0 / 3.0);\n } else {\n return -pow(x, 1.0 / 3.0);\n }\n}\n\nfloat expm1(float x) {\n return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n return x;\n}\n\nfloat imul(float v1, float v2) {\n return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n if (v2 == 0.0) return 1.0;\n return pow(v1, v2);\n}\n\nfloat _round(float x) {\n return floor(x + 0.5);\n}\n\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n // ~a is identically -a - 1 in two's complement, for every value including\n // negatives. The previous bit-by-bit loop only worked for a >= 0, where it\n // leaned on 32-bit overflow wrapping to reach the negative answer; given a\n // negative input it computed ~abs(a), so ~(-1) gave -2 and ~~x never\n // returned x.\n return -a - 1;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\n// _pow2 is defined further down, alongside encode32/decode32\nfloat _pow2(float e);\nint bitwiseSignedRightShift(int num, int shifts) {\n // pow(2.0, n) is approximate on many GPUs, and landing 1 ulp high makes the\n // division fall just under a whole number, which floor() then rounds away:\n // 2 >> 1 came out 0, 8 >> 1 came out 3. Only exact left operands were\n // affected, odd ones having enough slack to survive. _pow2 is exact.\n return int(floor(float(num) / _pow2(float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x/y));\n}\n\n// GLSL ES 1.00 accepts only a constant or a loop symbol inside an index\n// expression, so m[y][x] does not compile when y and x come from kernel\n// arguments -- the error is "Index expression can only contain const or loop\n// symbols". Loop counters are legal indices, so walk the matrix with them\n// instead. These are 2x2 to 4x4, so it costs at most sixteen comparisons.\nfloat getMatrix2(mat2 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 2; i++) {\n for (int j = 0; j < 2; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix3(mat3 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 3; i++) {\n for (int j = 0; j < 3; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix4(mat4 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 4; i++) {\n for (int j = 0; j < 4; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\n// Exact powers of two built from exact constant multiplies: exp2/log2/pow\n// are approximate on some GPUs (notably Apple silicon), and 1-2 ulp there\n// corrupts the packed bytes (#659)\nfloat _pow2(float e) {\n float r = 1.0;\n float a = abs(e);\n bool n = e < 0.0;\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 32.0) { r *= n ? 2.3283064365386963e-10 : 4294967296.0; a -= 32.0; }\n if (a >= 16.0) { r *= n ? 0.0000152587890625 : 65536.0; a -= 16.0; }\n if (a >= 8.0) { r *= n ? 0.00390625 : 256.0; a -= 8.0; }\n if (a >= 4.0) { r *= n ? 0.0625 : 16.0; a -= 4.0; }\n if (a >= 2.0) { r *= n ? 0.25 : 4.0; a -= 2.0; }\n if (a >= 1.0) { r *= n ? 0.5 : 2.0; }\n return r;\n}\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = _pow2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * _pow2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n return texel[channel] * 255.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n float p2 = _pow2(exponent);\n // approximate log2 can land one off; correct by direct comparison\n if (p2 > value) { exponent -= 1.0; p2 *= 0.5; }\n else if (p2 * 2.0 <= value) { exponent += 1.0; p2 *= 2.0; }\n\n mantissa = value / p2 - 1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n index = index / 4;\n vec4 texel = texture(tex, st / vec2(texSize));\n return texel[channel];\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, st / vec2(texSize));\n}\n\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, vec3(st / vec2(texSize), z));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n\n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nfloat modulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -mod(number, divisor);\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}`}}),Ae=e((e,t)=>{t.exports={vertexShader:"#version 300 es\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nin vec2 aPos;\nin vec2 aTexCoord;\n\nout vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"}}),Ee=e((e,t)=>{const{WebGLKernelValueBoolean:n}=U();t.exports={WebGL2KernelValueBoolean:class extends n{}}}),_e=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueFloat:r}=P();t.exports={WebGL2KernelValueFloat:class extends r{}}}),ve=e((e,t)=>{const{WebGLKernelValueInteger:n}=B();t.exports={WebGL2KernelValueInteger:class extends n{getSource(e){const t=this.getVariablePrecisionString();return"constants"===this.origin?`const ${t} int ${this.id} = ${parseInt(e)};\n`:`uniform ${t} int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),we=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueHTMLImage:r}=W();t.exports={WebGL2KernelValueHTMLImage:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),De=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueDynamicHTMLImage:r}=H();t.exports={WebGL2KernelValueDynamicHTMLImage:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Ie=e((e,t)=>{const{utils:n}=i(),{WebGLKernelArray:r}=j();t.exports={WebGL2KernelValueHTMLImageArray:class extends r{constructor(e,t){super(e,t),this.checkSize(e[0].width,e[0].height),this.dimensions=[e[0].width,e[0].height,e.length],this.textureSize=[e[0].width,e[0].height]}defineTexture(){const{context:e}=this;e.activeTexture(this.contextHandle),e.bindTexture(e.TEXTURE_2D_ARRAY,this.texture),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MIN_FILTER,e.NEAREST)}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D_ARRAY,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage3D(t.TEXTURE_2D_ARRAY,0,t.RGBA,e[0].width,e[0].height,e.length,0,t.RGBA,t.UNSIGNED_BYTE,null);for(let n=0;n{const{utils:n}=i(),{WebGL2KernelValueHTMLImageArray:r}=Ie();t.exports={WebGL2KernelValueDynamicHTMLImageArray:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:n}=e[0];this.checkSize(t,n),this.dimensions=[t,n,e.length],this.textureSize=[t,n],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Fe=e((e,t)=>{const{utils:n}=i(),{WebGL2KernelValueHTMLImage:r}=we();t.exports={WebGL2KernelValueHTMLVideo:class extends r{}}}),Re=e((e,t)=>{const{utils:n}=i(),{WebGL2KernelValueDynamicHTMLImage:r}=De();t.exports={WebGL2KernelValueDynamicHTMLVideo:class extends r{}}}),Le=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueSingleInput:r}=Y();t.exports={WebGL2KernelValueSingleInput:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;n.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ze=e((e,t)=>{const{utils:n}=i(),{WebGL2KernelValueSingleInput:r}=Le();t.exports={WebGL2KernelValueDynamicSingleInput:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,r,s]=e.size;this.dimensions=new Int32Array([t||1,r||1,s||1]),this.textureSize=n.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Ce=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueUnsignedInput:r}=J();t.exports={WebGL2KernelValueUnsignedInput:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),Me=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueDynamicUnsignedInput:r}=Q();t.exports={WebGL2KernelValueDynamicUnsignedInput:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Ne=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueMemoryOptimizedNumberTexture:r}=ee();t.exports={WebGL2KernelValueMemoryOptimizedNumberTexture:class extends r{getSource(){const{id:e,sizeId:t,textureSize:r,dimensionsId:s,dimensions:i}=this,a=this.getVariablePrecisionString();return n.linesToString([`uniform sampler2D ${e}`,`${a} ivec2 ${t} = ivec2(${r[0]}, ${r[1]})`,`${a} ivec3 ${s} = ivec3(${i[0]}, ${i[1]}, ${i[2]})`])}}}}),Ve=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:r}=te();t.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:class extends r{getSource(){return n.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}}}),Oe=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueNumberTexture:r}=ne();t.exports={WebGL2KernelValueNumberTexture:class extends r{getSource(){const{id:e,sizeId:t,textureSize:r,dimensionsId:s,dimensions:i}=this,a=this.getVariablePrecisionString();return n.linesToString([`uniform ${a} sampler2D ${e}`,`${a} ivec2 ${t} = ivec2(${r[0]}, ${r[1]})`,`${a} ivec3 ${s} = ivec3(${i[0]}, ${i[1]}, ${i[2]})`])}}}}),ke=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueDynamicNumberTexture:r}=re();t.exports={WebGL2KernelValueDynamicNumberTexture:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Ke=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueSingleArray:r}=se();t.exports={WebGL2KernelValueSingleArray:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;n.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Ge=e((e,t)=>{const{utils:n}=i(),{WebGL2KernelValueSingleArray:r}=Ke();t.exports={WebGL2KernelValueDynamicSingleArray:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=n.getDimensions(e,!0),this.textureSize=n.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Ue=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueSingleArray1DI:r}=ae();t.exports={WebGL2KernelValueSingleArray1DI:class extends r{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;n.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Pe=e((e,t)=>{const{utils:n}=i(),{WebGL2KernelValueSingleArray1DI:r}=Ue();t.exports={WebGL2KernelValueDynamicSingleArray1DI:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Be=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueSingleArray2DI:r}=ue();t.exports={WebGL2KernelValueSingleArray2DI:class extends r{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;n.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),je=e((e,t)=>{const{utils:n}=i(),{WebGL2KernelValueSingleArray2DI:r}=Be();t.exports={WebGL2KernelValueDynamicSingleArray2DI:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),We=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueSingleArray3DI:r}=he();t.exports={WebGL2KernelValueSingleArray3DI:class extends r{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;n.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),He=e((e,t)=>{const{utils:n}=i(),{WebGL2KernelValueSingleArray3DI:r}=We();t.exports={WebGL2KernelValueDynamicSingleArray3DI:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Xe=e((e,t)=>{const{WebGLKernelValueArray2:n}=pe();t.exports={WebGL2KernelValueArray2:class extends n{}}}),qe=e((e,t)=>{const{WebGLKernelValueArray3:n}=me();t.exports={WebGL2KernelValueArray3:class extends n{}}}),Ye=e((e,t)=>{const{WebGLKernelValueArray4:n}=de();t.exports={WebGL2KernelValueArray4:class extends n{}}}),Ze=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueUnsignedArray:r}=ge();t.exports={WebGL2KernelValueUnsignedArray:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),Je=e((e,t)=>{const{utils:n}=i(),{WebGLKernelValueDynamicUnsignedArray:r}=fe();t.exports={WebGL2KernelValueDynamicUnsignedArray:class extends r{getSource(){const e=this.getVariablePrecisionString();return n.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Qe=e((e,t)=>{const{WebGL2KernelValueBoolean:n}=Ee(),{WebGL2KernelValueFloat:r}=_e(),{WebGL2KernelValueInteger:s}=ve(),{WebGL2KernelValueHTMLImage:i}=we(),{WebGL2KernelValueDynamicHTMLImage:a}=De(),{WebGL2KernelValueHTMLImageArray:o}=Ie(),{WebGL2KernelValueDynamicHTMLImageArray:u}=$e(),{WebGL2KernelValueHTMLVideo:l}=Fe(),{WebGL2KernelValueDynamicHTMLVideo:h}=Re(),{WebGL2KernelValueSingleInput:c}=Le(),{WebGL2KernelValueDynamicSingleInput:p}=ze(),{WebGL2KernelValueUnsignedInput:m}=Ce(),{WebGL2KernelValueDynamicUnsignedInput:d}=Me(),{WebGL2KernelValueMemoryOptimizedNumberTexture:g}=Ne(),{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:f}=Ve(),{WebGL2KernelValueNumberTexture:x}=Oe(),{WebGL2KernelValueDynamicNumberTexture:y}=ke(),{WebGL2KernelValueSingleArray:T}=Ke(),{WebGL2KernelValueDynamicSingleArray:b}=Ge(),{WebGL2KernelValueSingleArray1DI:S}=Ue(),{WebGL2KernelValueDynamicSingleArray1DI:A}=Pe(),{WebGL2KernelValueSingleArray2DI:E}=Be(),{WebGL2KernelValueDynamicSingleArray2DI:_}=je(),{WebGL2KernelValueSingleArray3DI:v}=We(),{WebGL2KernelValueDynamicSingleArray3DI:w}=He(),{WebGL2KernelValueArray2:D}=Xe(),{WebGL2KernelValueArray3:I}=qe(),{WebGL2KernelValueArray4:$}=Ye(),{WebGL2KernelValueUnsignedArray:F}=Ze(),{WebGL2KernelValueDynamicUnsignedArray:R}=Je(),L={unsigned:{dynamic:{Boolean:n,Integer:s,Float:r,Array:R,"Array(2)":D,"Array(3)":I,"Array(4)":$,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:d,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:f,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:h},static:{Boolean:n,Float:r,Integer:s,Array:F,"Array(2)":D,"Array(3)":I,"Array(4)":$,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:m,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:f,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:o,HTMLVideo:l}},single:{dynamic:{Boolean:n,Integer:s,Float:r,Array:b,"Array(2)":D,"Array(3)":I,"Array(4)":$,"Array1D(2)":A,"Array1D(3)":A,"Array1D(4)":A,"Array2D(2)":_,"Array2D(3)":_,"Array2D(4)":_,"Array3D(2)":w,"Array3D(3)":w,"Array3D(4)":w,Input:p,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:f,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:h},static:{Boolean:n,Float:r,Integer:s,Array:T,"Array(2)":D,"Array(3)":I,"Array(4)":$,"Array1D(2)":S,"Array1D(3)":S,"Array1D(4)":S,"Array2D(2)":E,"Array2D(3)":E,"Array2D(4)":E,"Array3D(2)":v,"Array3D(3)":v,"Array3D(4)":v,Input:c,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:o,HTMLVideo:l}}};t.exports={kernelValueMaps:L,lookupKernelValueType:function(e,t,n,r){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!n)throw new Error("precision missing");r.type&&(e=r.type);const s=L[n][t];if(!1===s[e])return null;if(void 0===s[e])throw new Error(`Could not find a KernelValue for ${e}`);return s[e]}}}),et=e((e,t)=>{const{WebGLKernel:n}=ye(),{WebGL2FunctionNode:r}=be(),{FunctionBuilder:s}=o(),{utils:a}=i(),{fragmentShader:u}=Se(),{vertexShader:l}=Ae(),{lookupKernelValueType:h}=Qe();let c=null,p=null,m=null,d=null;t.exports={WebGL2Kernel:class extends n{static get isSupported(){return null!==c||(this.setupFeatureChecks(),c=this.isContextMatch(m)),c}static setupFeatureChecks(){"undefined"!=typeof document?p=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(p=new OffscreenCanvas(0,0)),p&&(m=p.getContext("webgl2"),m&&m.getExtension&&(m.getExtension("EXT_color_buffer_float"),m.getExtension("OES_texture_float_linear"),d=this.getFeatures()))}static isContextMatch(e){return"undefined"!=typeof WebGL2RenderingContext&&e instanceof WebGL2RenderingContext}static getFeatures(){const e=this.testContext;return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isSpeedTacticSupported:this.getIsSpeedTacticSupported(),kernelMap:!0,isTextureFloat:!0,isDrawBuffers:!0,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize(),lowIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT),lowFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT),mediumIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT),mediumFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT),highIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT),highFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)})}static getIsTextureFloat(){return!0}static getChannelCount(){return m.getParameter(m.MAX_DRAW_BUFFERS)}static getMaxTextureSize(){return m.getParameter(m.MAX_TEXTURE_SIZE)}static lookupKernelValueType(e,t,n,r){return h(e,t,n,r)}static get testCanvas(){return p}static get testContext(){return m}static get features(){return d}static get fragmentShader(){return u}static get vertexShader(){return l}initContext(){return this.canvas.getContext("webgl2",{alpha:!1,depth:!1,antialias:!1})}initExtensions(){this.extensions={EXT_color_buffer_float:this.context.getExtension("EXT_color_buffer_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if("single"===this.precision&&!t.isFloatRead)throw new Error("Float texture outputs are not supported");if(this.graphical||null!==this.precision||(this.precision=t.isFloatRead?"single":"unsigned"),null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);switch(t){case"Array":this.output=a.getDimensions(t);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=e[0].output;break;default:throw new Error("Auto output not supported for input type: "+t)}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"single"===this.precision&&(console.warn("Cannot use graphical mode and single precision at the same time"),this.precision="unsigned"),void(this.texSize=a.clone(this.output))}!this.graphical&&null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}translateSource(){const e=s.fromKernel(this,r,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=e.getPrototypeString("kernel"),this.setupReturnTypes(e)}drawBuffers(){this.context.drawBuffers(this.drawBuffersMap)}getTextureFormat(){const{context:e}=this;switch(this.getInternalFormat()){case e.R32F:return e.RED;case e.RG32F:return e.RG;case e.RGBA32F:case e.RGBA:return e.RGBA;default:throw new Error("Unknown internal format")}}renderValues(){return void 0===this._tightRead&&this._detectTightRead(),super.renderValues()}renderKernelsToArrays(){return void 0===this._tightRead&&this._detectTightRead(),super.renderKernelsToArrays()}readFloatPixelsToFloat32Array(){if(!this._tightRead)return super.readFloatPixelsToFloat32Array();const{texSize:e,context:t}=this,n=e[0],r=e[1],s=new Float32Array(n*r);return t.readPixels(0,0,n,r,t.RED,t.FLOAT,s),s}_detectTightRead(){const e=this.context;this._tightRead=!1,e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer);const t="Number"===this.returnType||"Float"===this.returnType||"Integer"===this.returnType||"LiteralInteger"===this.returnType;if("single"===this.precision&&!this.optimizeFloatMemory&&!this.graphical&&t&&e.getParameter(e.IMPLEMENTATION_COLOR_READ_FORMAT)===e.RED&&e.getParameter(e.IMPLEMENTATION_COLOR_READ_TYPE)===e.FLOAT){if(this.formatValues===a.erectFloat)this.formatValues=a.erectMemoryOptimizedFloat;else if(this.formatValues===a.erect2DFloat)this.formatValues=a.erectMemoryOptimized2DFloat;else if(this.formatValues===a.erect3DFloat)this.formatValues=a.erectMemoryOptimized3DFloat;else if(this.formatValues!==a.erectMemoryOptimizedFloat&&this.formatValues!==a.erectMemoryOptimized2DFloat&&this.formatValues!==a.erectMemoryOptimized3DFloat)return;this._tightRead=!0}}getInternalFormat(){const{context:e}=this;if("single"===this.precision)switch(this.returnType){case"Number":case"Float":case"Integer":return this.optimizeFloatMemory?e.RGBA32F:e.R32F;case"Array(2)":return e.RG32F;case"Array(3)":case"Array(4)":return e.RGBA32F;default:throw new Error("Unhandled return type")}return e.RGBA}_setupOutputTexture(){const e=this.context;if(this.texture)return e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture.texture,0),void(this._tightRead=void 0);e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer);const t=e.createTexture(),n=this.texSize;e.activeTexture(e.TEXTURE0+this.constantTextureCount+this.argumentTextureCount),e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);const r=this.getInternalFormat();"single"===this.precision?e.texStorage2D(e.TEXTURE_2D,1,r,n[0],n[1]):e.texImage2D(e.TEXTURE_2D,0,r,n[0],n[1],0,r,e.UNSIGNED_BYTE,null),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),this.texture=new this.TextureConstructor({texture:t,size:n,dimensions:this.threadDim,output:this.output,context:this.context,internalFormat:this.getInternalFormat(),textureFormat:this.getTextureFormat(),kernel:this}),this._tightRead=void 0}_setupSubOutputTextures(){const e=this.context;if(this.mappedTextures){for(let t=0;t{const{utils:n}=i();function r(e,t){if(t.kernel)return void(t.kernel=e);const r=n.allPropertiesOf(e);for(let n=0;nt.kernel[s]),t.__defineSetter__(s,e=>{t.kernel[s]=e})))}t.kernel=e}t.exports={kernelRunShortcut:function(e){let t=function(){return e.build.apply(e,arguments),t=function(){let t=e.run.apply(e,arguments);if(e.switchingKernels){const r=e.resetSwitchingKernels(),s=e.onRequestSwitchKernel(r,arguments,e);n.kernel=e=s,t=s.run.apply(s,arguments)}return e.renderKernels?e.renderKernels():e.renderOutput?e.renderOutput():t},t.apply(e,arguments)};const n=function(){return t.apply(e,arguments)};return n.exec=function(){return new Promise((e,n)=>{try{e(t.apply(this,arguments))}catch(e){n(e)}})},n.replaceKernel=function(t){r(e=t,n)},r(e,n),n}}}),nt=e((e,n)=>{const{gpuMock:r}=t(),{utils:s}=i(),{Kernel:o}=a(),{CPUKernel:u}=p(),{HeadlessGLKernel:l}=Te(),{WebGL2Kernel:h}=et(),{WebGLKernel:c}=ye(),{kernelRunShortcut:m}=tt(),d=[l,h,c],g=["gpu","cpu"],f={headlessgl:l,webgl2:h,webgl:c};let x=!0;function y(e){if(!e)return{};const t=Object.assign({},e);return e.hasOwnProperty("floatOutput")&&(s.warnDeprecated("setting","floatOutput","precision"),t.precision=e.floatOutput?"single":"unsigned"),e.hasOwnProperty("outputToTexture")&&(s.warnDeprecated("setting","outputToTexture","pipeline"),t.pipeline=Boolean(e.outputToTexture)),e.hasOwnProperty("outputImmutable")&&(s.warnDeprecated("setting","outputImmutable","immutable"),t.immutable=Boolean(e.outputImmutable)),e.hasOwnProperty("floatTextures")&&(s.warnDeprecated("setting","floatTextures","optimizeFloatMemory"),t.optimizeFloatMemory=Boolean(e.floatTextures)),t}n.exports={GPU:class{static disableValidation(){x=!1}static enableValidation(){x=!0}static get isGPUSupported(){return d.some(e=>e.isSupported)}static get isKernelMapSupported(){return d.some(e=>e.isSupported&&e.features.kernelMap)}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return c.isSupported}static get isWebGL2Supported(){return h.isSupported}static get isHeadlessGLSupported(){return l.isSupported}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return h.isSupported}static get isSinglePrecisionSupported(){return d.some(e=>e.isSupported&&e.features.isFloatRead&&e.features.isTextureFloat)}constructor(e){if(e=e||{},this.canvas=e.canvas||null,this.context=e.context||null,this.mode=e.mode,this.Kernel=null,this.kernels=[],this.functions=[],this.nativeFunctions=[],this.injectedNative=null,"dev"!==this.mode){if(this.chooseKernel(),e.functions)for(let t=0;tt.argumentTypes[e]));const l=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate:x,onRequestFallback:o,onRequestSwitchKernel:function t(r,s,a){a.debug&&console.warn("Switching kernels");let u=null;if(a.signature&&!i[a.signature]&&(i[a.signature]=a),a.dynamicOutput)for(let e=r.length-1;e>=0;e--){const t=r[e];"outputPrecisionMismatch"===t.type&&(u=t.needed)}const l=a.constructor,h=l.getArgumentTypes(a,s),p=l.getSignature(a,h),m=i[p];if(m)return m.onActivate(a),m;const d=i[p]=new l(e,{argumentTypes:h,constantTypes:a.constantTypes,graphical:a.graphical,loopMaxIterations:a.loopMaxIterations,constants:a.constants,dynamicOutput:a.dynamicOutput,dynamicArgument:a.dynamicArguments,context:a.context,canvas:a.canvas,output:u||a.output,precision:a.precision,pipeline:a.pipeline,immutable:a.immutable,optimizeFloatMemory:a.optimizeFloatMemory,fixIntegerDivisionAccuracy:a.fixIntegerDivisionAccuracy,functions:a.functions,nativeFunctions:a.nativeFunctions,injectedNative:a.injectedNative,subKernels:a.subKernels,strictIntegers:a.strictIntegers,randomSeed:a.randomSeed,debug:a.debug,gpu:a.gpu,validate:x,returnType:a.returnType,tactic:a.tactic,onRequestFallback:o,onRequestSwitchKernel:t,texture:a.texture,mappedTextures:a.mappedTextures,drawBuffersMap:a.drawBuffersMap});return d.build.apply(d,s),c.replaceKernel(d),n.push(d),d}},a),h=new this.Kernel(e,l),c=m(h);return this.canvas||(this.canvas=h.canvas),this.context||(this.context=h.context),n.push(h),c}createKernelMap(){let e,t;const n=typeof arguments[arguments.length-2];if("function"===n||"string"===n?(e=arguments[arguments.length-2],t=arguments[arguments.length-1]):e=arguments[arguments.length-1],"dev"!==this.mode&&(!this.Kernel.isSupported||!this.Kernel.features.kernelMap)&&this.mode&&g.indexOf(this.mode)<0)throw new Error(`kernelMap not supported on ${this.Kernel.name}`);const r=y(t);if(t&&"object"==typeof t.argumentTypes&&(r.argumentTypes=Object.keys(t.argumentTypes).map(e=>t.argumentTypes[e])),Array.isArray(arguments[0])){r.subKernels=[];const e=arguments[0];for(let t=0;t0)throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');return this.nativeFunctions.push(Object.assign({name:e,source:t},n)),this}injectNative(e){return this.injectedNative=e,this}destroy(){return new Promise((e,t)=>{this.kernels||e(),setTimeout(()=>{try{const e=this.kernels.slice();for(let t=0;t{const{utils:n}=i();t.exports={alias:function(e,t){const r=t.toString();return new Function(`return function ${e} (${n.getArgumentNamesFromString(r).join(", ")}) {\n ${n.getFunctionBodyFromString(r)}\n}`)()}}}),st=e((e,t)=>{const{GPU:n}=nt(),{alias:c}=rt(),{utils:m}=i(),{Input:d,input:g}=r(),{Texture:f}=s(),{FunctionBuilder:x}=o(),{FunctionNode:y}=l(),{CPUFunctionNode:T}=h(),{CPUKernel:b}=p(),{HeadlessGLKernel:S}=Te(),{WebGLFunctionNode:A}=C(),{WebGLKernel:E}=ye(),{kernelValueMaps:_}=xe(),{WebGL2FunctionNode:v}=be(),{WebGL2Kernel:w}=et(),{kernelValueMaps:D}=Qe(),{GLKernel:I}=z(),{Kernel:$}=a(),{FunctionTracer:F}=u();t.exports={alias:c,CPUFunctionNode:T,CPUKernel:b,GPU:n,FunctionBuilder:x,FunctionNode:y,HeadlessGLKernel:S,Input:d,input:g,Texture:f,utils:m,WebGL2FunctionNode:v,WebGL2Kernel:w,webGL2KernelValueMaps:D,WebGLFunctionNode:A,WebGLKernel:E,webGLKernelValueMaps:_,GLKernel:I,Kernel:$,FunctionTracer:F,plugins:{mathRandom:M()}}});return e((e,t)=>{const n=st(),r=n.GPU;for(const e in n)n.hasOwnProperty(e)&&"GPU"!==e&&(r[e]=n[e]);function s(e){e.GPU&&e.GPU.prototype&&e.GPU.prototype.createKernel||Object.defineProperty(e,"GPU",{configurable:!0,get:()=>r,set(){}})}r.GPU=r,"undefined"!=typeof window&&s(window),"undefined"!=typeof self&&s(self),t.exports=r})()}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):(e="undefined"!=typeof globalThis?globalThis:e||self).GPU=t()}(this,function(){var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),t=e((e,t)=>{function r(e){const t=new Array(e.length);for(let r=0;r{e.output=l(t),e.graphical&&u(e)},e.toJSON=()=>{throw new Error("Not usable with gpuMock")},e.setConstants=t=>(e.constants=t,e),e.setGraphical=t=>(e.graphical=t,e),e.setCanvas=t=>(e.canvas=t,e),e.setContext=t=>(e.context=t,e),e.destroy=()=>{},e.validateSettings=()=>{},e.graphical&&e.output&&u(e),e.exec=function(){return new Promise((t,r)=>{try{t(e.apply(e,arguments))}catch(e){r(e)}})},e.getPixels=t=>{const{x:r,y:n}=e.output;return t?function(e,t,r){const n=r/2|0,s=4*t,i=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee,r=["setWarnVarUsage","setArgumentTypes","setTactic","setOptimizeFloatMemory","setDebug","setLoopMaxIterations","setConstantTypes","setFunctions","setNativeFunctions","setInjectedNative","setPipeline","setPrecision","setOutputToTexture","setImmutable","setStrictIntegers","setDynamicOutput","setHardcodeConstants","setDynamicArguments","setUseLegacyEncoder","setWarnVarUsage","addSubKernel"];for(let n=0;n{t.exports={}}),n=e((e,t)=>{var r=class{constructor(e,t){this.value=e,Array.isArray(t)?this.size=t:(this.size=new Int32Array(3),t.z?this.size=new Int32Array([t.x,t.y,t.z]):t.y?this.size=new Int32Array([t.x,t.y]):this.size=new Int32Array([t.x]));const[r,n,s]=this.size;if(s){if(this.value.length!==r*n*s)throw new Error(`Input size ${this.value.length} does not match ${r} * ${n} * ${s} = ${n*r*s}`)}else if(n){if(this.value.length!==r*n)throw new Error(`Input size ${this.value.length} does not match ${r} * ${n} = ${n*r}`)}else if(this.value.length!==r)throw new Error(`Input size ${this.value.length} does not match ${r}`)}toArray(){const{utils:e}=i(),[t,r,n]=this.size;return n?e.erectMemoryOptimized3DFloat(this.value.subarray?this.value:new Float32Array(this.value),t,r,n):r?e.erectMemoryOptimized2DFloat(this.value.subarray?this.value:new Float32Array(this.value),t,r):this.value}};t.exports={Input:r,input:function(e,t){return new r(e,t)}}}),s=e((e,t)=>{t.exports={Texture:class{constructor(e){const{texture:t,size:r,dimensions:n,output:s,context:i,type:a="NumberTexture",kernel:o,internalFormat:u,textureFormat:l}=e;if(!s)throw new Error('settings property "output" required.');if(!i)throw new Error('settings property "context" required.');if(!t)throw new Error('settings property "texture" required.');if(!o)throw new Error('settings property "kernel" required.');this.texture=t,t._refs?t._refs++:t._refs=1,this.size=r,this.dimensions=n,this.output=s,this.context=i,this.kernel=o,this.type=a,this._deleted=!1,this.internalFormat=u,this.textureFormat=l}toArray(){throw new Error(`Not implemented on ${this.constructor.name}`)}clone(){throw new Error(`Not implemented on ${this.constructor.name}`)}delete(){throw new Error(`Not implemented on ${this.constructor.name}`)}clear(){throw new Error(`Not implemented on ${this.constructor.name}`)}}}}),i=e((e,t)=>{const i=r(),{Input:a}=n(),{Texture:o}=s(),u=/function ([^(]*)/,l=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,h=/([^\s,]+)/g,c={systemEndianness:()=>f,getSystemEndianness(){const e=new ArrayBuffer(4),t=new Uint32Array(e),r=new Uint8Array(e);if(t[0]=3735928559,239===r[0])return"LE";if(222===r[0])return"BE";throw new Error("unknown endianness")},isFunction:e=>"function"==typeof e,isFunctionString:e=>"string"==typeof e&&"function"===e.slice(0,8).toLowerCase(),getFunctionNameFromString(e){const t=u.exec(e);return t&&0!==t.length?t[1].trim():null},getFunctionBodyFromString:e=>e.substring(e.indexOf("{")+1,e.lastIndexOf("}")),getArgumentNamesFromString(e){const t=e.replace(l,"");let r=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(h);return null===r&&(r=[]),r},clone(e){if(null===e||"object"!=typeof e||e.hasOwnProperty("isActiveClone"))return e;const t=e.constructor();for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(e.isActiveClone=null,t[r]=c.clone(e[r]),delete e.isActiveClone);return t},isArray:e=>!isNaN(e.length),typeFitsValue(e,t){if("string"!=typeof e||null==t)return!0;if(t.type)return!0;switch(e){case"Input":return t instanceof a;case"Boolean":return"boolean"==typeof t;case"Number":case"Integer":case"Float":return"number"==typeof t}return-1!==e.indexOf("Texture")?Boolean(t.type):0!==e.indexOf("Array")||c.isArray(t)},getVariableType(e,t){if(c.isArray(e))return e.length>0&&"IMG"===e[0].nodeName?"HTMLImageArray":"Array";switch(e.constructor){case Boolean:return"Boolean";case Number:return t&&Number.isInteger(e)?"Integer":"Float";case o:return e.type;case a:return"Input"}if("nodeName"in e)switch(e.nodeName){case"IMG":case"CANVAS":return"HTMLImage";case"VIDEO":return"HTMLVideo"}else{if(e.hasOwnProperty("type"))return e.type;if("undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return"OffscreenCanvas";if("undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap)return"ImageBitmap";if("undefined"!=typeof ImageData&&e instanceof ImageData)return"ImageData"}return"Unknown"},getKernelTextureSize(e,t){let[r,n,s]=t,i=(r||1)*(n||1)*(s||1);return e.optimizeFloatMemory&&"single"===e.precision&&(r=i=Math.ceil(i/4)),n>1&&r*n===i?new Int32Array([r,n]):c.closestSquareDimensions(i)},closestSquareDimensions(e){const t=Math.sqrt(e);let r=Math.ceil(t),n=Math.floor(t);for(;r*nMath.floor((e+t-1)/t)*t,getDimensions(e,t){let r;if(c.isArray(e)){const t=[];let n=e;for(;c.isArray(n);)t.push(n.length),n=n[0];r=t.reverse()}else if(e instanceof o)r=e.output;else{if(!(e instanceof a))throw new Error(`Unknown dimensions of ${e}`);r=e.size}if(t)for(r=Array.from(r);r.length<3;)r.push(1);return new Int32Array(r)},flatten2dArrayTo(e,t){let r=0;for(let n=0;ne.length>0?e.join(";\n")+";\n":"\n",warnDeprecated(e,t,r){r?console.warn(`You are using a deprecated ${e} "${t}". It has been replaced with "${r}". Fixing, but please upgrade as it will soon be removed.`):console.warn(`You are using a deprecated ${e} "${t}". It has been removed. Fixing, but please upgrade as it will soon be removed.`)},flipPixels:(e,t,r)=>{const n=r/2|0,s=4*t,i=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee.subarray(0,t),erect2DPackedFloat:(e,t,r)=>{const n=new Array(r);for(let s=0;s{const s=new Array(n);for(let i=0;ie.subarray(0,t),erectMemoryOptimized2DFloat:(e,t,r)=>{const n=new Array(r);for(let s=0;s{const s=new Array(n);for(let i=0;i{const r=new Float32Array(t);let n=0;for(let s=0;s{const n=new Array(r);let s=0;for(let i=0;i{const s=new Array(n);let i=0;for(let a=0;a{const r=new Array(t),n=4*t;let s=0;for(let t=0;t{const n=new Array(r),s=4*t;for(let i=0;i{const s=4*t,i=new Array(n);for(let a=0;a{const r=new Array(t),n=4*t;let s=0;for(let t=0;t{const n=4*t,s=new Array(r);for(let i=0;i{const s=4*t,i=new Array(n);for(let a=0;a{const r=new Array(e),n=4*t;let s=0;for(let t=0;t{const n=4*t,s=new Array(r);for(let i=0;i{const s=4*t,i=new Array(n);for(let a=0;a{const{findDependency:r,thisLookup:n,doNotDefine:s}=t;let a=t.flattened;a||(a=t.flattened={});const o=i.parse(e,{ecmaVersion:2020}),u=[];let l=0;const h=function e(t){if(Array.isArray(t)){const r=[];for(let n=0;nnull!==e);return s.length<1?"":`${t.kind} ${s.join(",")}`;case"VariableDeclarator":return t.init?t.init.object&&"ThisExpression"===t.init.object.type?n(t.init.property.name,!0)?`${t.id.name} = ${e(t.init)}`:null:`${t.id.name} = ${e(t.init)}`:t.id.name;case"CallExpression":if("subarray"===t.callee.property.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("gl"===t.callee.object.name||"context"===t.callee.object.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("ThisExpression"===t.callee.object.type)return u.push(r("this",t.callee.property.name)),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;if(t.callee.object.name){const n=r(t.callee.object.name,t.callee.property.name);return null===n?`${t.callee.object.name}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`:(u.push(n),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`)}if("MemberExpression"===t.callee.object.type)return`${e(t.callee.object)}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;throw new Error("unknown ast.callee");case"ReturnStatement":return`return ${e(t.argument)}`;case"BinaryExpression":return`(${e(t.left)}${t.operator}${e(t.right)})`;case"UnaryExpression":return t.prefix?`${t.operator} ${e(t.argument)}`:`${e(t.argument)} ${t.operator}`;case"ExpressionStatement":return`${e(t.expression)}`;case"SequenceExpression":return`(${e(t.expressions)})`;case"ArrowFunctionExpression":return`(${t.params.map(e).join(", ")}) => ${e(t.body)}`;case"Literal":return t.raw;case"Identifier":return t.name;case"MemberExpression":return"ThisExpression"===t.object.type?n(t.property.name):t.computed?`${e(t.object)}[${e(t.property)}]`:e(t.object)+"."+e(t.property);case"ThisExpression":return"this";case"NewExpression":return`new ${e(t.callee)}(${t.arguments.map(t=>e(t)).join(", ")})`;case"ForStatement":return`for (${e(t.init)};${e(t.test)};${e(t.update)}) ${e(t.body)}`;case"AssignmentExpression":return`${e(t.left)}${t.operator}${e(t.right)}`;case"UpdateExpression":return`${e(t.argument)}${t.operator}`;case"IfStatement":{const r=e(t.consequent);if(!t.alternate)return`if (${e(t.test)}) ${r}`;const n="BlockStatement"===t.consequent.type?"":";";return`if (${e(t.test)}) ${r}${n} else ${e(t.alternate)}`}case"ThrowStatement":return`throw ${e(t.argument)}`;case"ObjectPattern":return t.properties.map(e).join(", ");case"ArrayPattern":return t.elements.map(e).join(", ");case"DebuggerStatement":return"debugger;";case"ConditionalExpression":return`${e(t.test)}?${e(t.consequent)}:${e(t.alternate)}`;case"Property":if("init"===t.kind)return e(t.key)}throw new Error(`unhandled ast.type of ${t.type}`)}(o);if(u.length>0){const e=[];for(let r=0;r{if("VariableDeclaration"!==e.type)throw new Error('Ast is not of type "VariableDeclaration"');const t=[];for(let r=0;r{const r=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].r},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),n=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].g},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),s=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].b},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),i=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].a},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),a=[r(t),n(t),s(t),i(t)];return a.rKernel=r,a.gKernel=n,a.bKernel=s,a.aKernel=i,a.gpu=e,a},splitRGBAToCanvases:(e,t,r,n)=>{const s=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(t.r/255,0,0,255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});s(t);const i=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(0,t.g/255,0,255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});i(t);const a=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(0,0,t.b/255,255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});a(t);const o=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(255,255,255,t.a/255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});return o(t),[s.canvas,i.canvas,a.canvas,o.canvas]},getMinifySafeName:e=>{try{const{init:t}=i.parse(`const value = ${e.toString()}`,{ecmaVersion:2020}).body[0].declarations[0];return t.body.name||t.body.body[0].argument.name}catch(e){throw new Error("Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }")}},sanitizeName:function(e){return p.test(e)&&(e=e.replace(p,"S_S")),d.test(e)?e=e.replace(d,"U_U"):m.test(e)&&(e=e.replace(m,"u_u")),e}},p=/\$/,d=/__/,m=/_/,f=c.getSystemEndianness();t.exports={utils:c}}),a=e((e,t)=>{const{utils:r}=i(),{Input:s}=n();t.exports={Kernel:class{static get isSupported(){throw new Error(`"isSupported" not implemented on ${this.name}`)}static isContextMatch(e){throw new Error(`"isContextMatch" not implemented on ${this.name}`)}static getFeatures(){throw new Error(`"getFeatures" not implemented on ${this.name}`)}static destroyContext(e){throw new Error(`"destroyContext" called on ${this.name}`)}static nativeFunctionArguments(){throw new Error(`"nativeFunctionArguments" called on ${this.name}`)}static nativeFunctionReturnType(){throw new Error(`"nativeFunctionReturnType" called on ${this.name}`)}static combineKernels(){throw new Error(`"combineKernels" called on ${this.name}`)}constructor(e,t){if("object"!=typeof e){if("string"!=typeof e)throw new Error("source not a string");if(!r.isFunctionString(e))throw new Error("source not a function string")}this.useLegacyEncoder=!1,this.fallbackRequested=!1,this.onRequestFallback=null,this.onRequestSwitchKernel=null,this.argumentNames="string"==typeof e?r.getArgumentNamesFromString(e):null,this.argumentTypes=null,this.argumentSizes=null,this.argumentBitRatios=null,this.kernelArguments=null,this.kernelConstants=null,this.forceUploadKernelConstants=null,this.source=e,this.output=null,this.debug=!1,this.graphical=!1,this.loopMaxIterations=0,this.constants=null,this.constantTypes=null,this.constantBitRatios=null,this.dynamicArguments=!1,this.dynamicOutput=!1,this.canvas=null,this.context=null,this.checkContext=null,this.gpu=null,this.functions=null,this.nativeFunctions=null,this.injectedNative=null,this.subKernels=null,this.validate=!0,this.immutable=!1,this.pipeline=!1,this.asyncMode=!1,this.precision=null,this.tactic=null,this.plugins=null,this.returnType=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.optimizeFloatMemory=null,this.strictIntegers=!1,this.fixIntegerDivisionAccuracy=null,this.randomSeed=null,this.built=!1,this.signature=null,this.switchingKernels=null}mergeSettings(e){for(let t in e)if(e.hasOwnProperty(t)&&this.hasOwnProperty(t)){switch(t){case"output":if(!Array.isArray(e.output)){this.setOutput(e.output);continue}break;case"functions":this.functions=[];for(let t=0;te.name):null,returnType:this.returnType}}}buildSignature(e){const t=this.constructor;this.signature=t.getSignature(this,t.getArgumentTypes(this,e))}static getArgumentTypes(e,t){const n=new Array(t.length);for(let s=0;st.argumentTypes[e])||[]:t.argumentTypes||[],{name:r.getFunctionNameFromString(n)||null,source:n,argumentTypes:s,returnType:t.returnType||null}}onActivate(e){}switchKernels(e){this.switchingKernels?this.switchingKernels.push(e):this.switchingKernels=[e]}resetSwitchingKernels(){const e=this.switchingKernels;return this.switchingKernels=null,e}checkArgumentTypes(e){if(!this.argumentTypes)return;const t=Math.min(e.length,this.argumentTypes.length);for(let n=0;n{t.exports={FunctionBuilder:class e{static fromKernel(t,r,n){const{kernelArguments:s,kernelConstants:i,argumentNames:a,argumentSizes:o,argumentBitRatios:u,constants:l,constantBitRatios:h,debug:c,loopMaxIterations:p,nativeFunctions:d,output:m,optimizeFloatMemory:f,precision:g,plugins:y,source:x,subKernels:b,functions:T,leadingReturnStatement:S,followingReturnStatement:A,dynamicArguments:w,dynamicOutput:E}=t,_=new Array(s.length),v={};for(let e=0;eU.needsArgumentType(e,t),$=(e,t,r)=>{U.assignArgumentType(e,t,r)},D=(e,t,r)=>U.lookupReturnType(e,t,r),F=e=>U.lookupFunctionArgumentTypes(e),L=(e,t)=>U.lookupFunctionArgumentName(e,t),R=(e,t)=>U.lookupFunctionArgumentBitRatio(e,t),k=(e,t,r,n)=>{U.assignArgumentType(e,t,r,n)},z=(e,t,r,n)=>{U.assignArgumentBitRatio(e,t,r,n)},M=(e,t,r)=>{U.trackFunctionCall(e,t,r)},G=(e,t)=>{const n=[];for(let t=0;tnew r(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:m,plugins:y,constants:l,constantTypes:v,constantBitRatios:h,optimizeFloatMemory:f,precision:g,lookupReturnType:D,lookupFunctionArgumentTypes:F,lookupFunctionArgumentName:L,lookupFunctionArgumentBitRatio:R,needsArgumentType:I,assignArgumentType:$,triggerImplyArgumentType:k,triggerImplyArgumentBitRatio:z,onFunctionCall:M,onNestedFunction:G})));let K=null;b&&(K=b.map(e=>{const{name:t,source:n}=e;return new r(n,Object.assign({},C,{name:t,isSubKernel:!0,isRootKernel:!1}))}));const U=new e({kernel:t,rootNode:O,functionNodes:V,nativeFunctions:d,subKernelNodes:K});return U}constructor(e){if(e=e||{},this.kernel=e.kernel,this.rootNode=e.rootNode,this.functionNodes=e.functionNodes||[],this.subKernelNodes=e.subKernelNodes||[],this.nativeFunctions=e.nativeFunctions||[],this.functionMap={},this.nativeFunctionNames=[],this.lookupChain=[],this.functionNodeDependencies={},this.functionCalls={},this.rootNode&&(this.functionMap.kernel=this.rootNode),this.functionNodes)for(let e=0;e-1){const r=t.indexOf(e);if(-1===r)t.push(e);else{const e=t.splice(r,1)[0];t.push(e)}return t}const r=this.functionMap[e];if(r){const n=t.indexOf(e);if(-1===n){t.push(e),r.toString();for(let e=0;e-1){t.push(this.nativeFunctions[s].source);continue}const i=this.functionMap[n];i&&t.push(i.toString())}return t}toJSON(){return this.traceFunctionCalls(this.rootNode.name).reverse().map(e=>{const t=this.nativeFunctions.indexOf(e);if(t>-1)return{name:e,source:this.nativeFunctions[t].source};if(this.functionMap[e])return this.functionMap[e].toJSON();throw new Error(`function ${e} not found`)})}fromJSON(e,t){this.functionMap={};for(let r=0;r0){const s=t.arguments;for(let t=0;t{const{utils:r}=i();function n(e){return e.length>0?e[e.length-1]:null}const s="trackIdentifiers",a="memberExpression",o="inForLoopInit";t.exports={FunctionTracer:class{constructor(e){this.runningContexts=[],this.functionContexts=[],this.contexts=[],this.functionCalls=[],this.declarations=[],this.identifiers=[],this.functions=[],this.returnStatements=[],this.trackedIdentifiers=null,this.states=[],this.newFunctionContext(),this.scan(e)}isState(e){return this.states[this.states.length-1]===e}hasState(e){return this.states.indexOf(e)>-1}pushState(e){this.states.push(e)}popState(e){if(!this.isState(e))throw new Error(`Cannot pop the non-active state "${e}"`);this.states.pop()}get currentFunctionContext(){return n(this.functionContexts)}get currentContext(){return n(this.runningContexts)}newFunctionContext(){const e={"@contextType":"function"};this.contexts.push(e),this.functionContexts.push(e)}newContext(e){const t=Object.assign({"@contextType":"const/let"},this.currentContext);this.contexts.push(t),this.runningContexts.push(t),e();const{currentFunctionContext:r}=this;for(const e in r)r.hasOwnProperty(e)&&!t.hasOwnProperty(e)&&(t[e]=r[e]);return this.runningContexts.pop(),t}useFunctionContext(e){const t=n(this.functionContexts);this.runningContexts.push(t),e(),this.runningContexts.pop()}getIdentifiers(e){const t=this.trackedIdentifiers=[];return this.pushState(s),e(),this.trackedIdentifiers=null,this.popState(s),t}getDeclaration(e){const{currentContext:t,currentFunctionContext:r,runningContexts:n}=this,s=t[e]||r[e]||null;if(!s&&t===r&&n.length>0){const t=n[n.length-2];if(t[e])return t[e]}return s}scan(e){if(e)if(Array.isArray(e))for(let t=0;t{this.scan(e.body)});break;case"BlockStatement":this.newContext(()=>{this.scan(e.body)});break;case"AssignmentExpression":case"LogicalExpression":case"BinaryExpression":this.scan(e.left),this.scan(e.right);break;case"UpdateExpression":if("++"===e.operator){const t=this.getDeclaration(e.argument.name);t&&(t.suggestedType="Integer")}this.scan(e.argument);break;case"UnaryExpression":this.scan(e.argument);break;case"VariableDeclaration":"var"===e.kind?this.useFunctionContext(()=>{e.declarations=r.normalizeDeclarations(e),this.scan(e.declarations)}):(e.declarations=r.normalizeDeclarations(e),this.scan(e.declarations));break;case"VariableDeclarator":{const{currentContext:t}=this,r=this.hasState(o),n={ast:e,context:t,name:e.id.name,origin:"declaration",inForLoopInit:r,inForLoopTest:null,assignable:t===this.currentFunctionContext||!r&&!t.hasOwnProperty(e.id.name),suggestedType:null,valueType:null,dependencies:null,isSafe:null};t[e.id.name]||(t[e.id.name]=n),this.declarations.push(n),this.scan(e.id),this.scan(e.init);break}case"FunctionExpression":case"FunctionDeclaration":0===this.runningContexts.length?this.scan(e.body):this.functions.push(e);break;case"IfStatement":this.scan(e.test),this.scan(e.consequent),e.alternate&&this.scan(e.alternate);break;case"ForStatement":{let t;const r=this.newContext(()=>{this.pushState(o),this.scan(e.init),this.popState(o),t=this.getIdentifiers(()=>{this.scan(e.test)}),this.scan(e.update),this.newContext(()=>{this.scan(e.body)})});if(t)for(const e in r)"@contextType"!==e&&t.indexOf(e)>-1&&(r[e].inForLoopTest=!0);break}case"DoWhileStatement":case"WhileStatement":this.newContext(()=>{this.scan(e.body),this.scan(e.test)});break;case"Identifier":this.isState(s)&&this.trackedIdentifiers.push(e.name),this.identifiers.push({context:this.currentContext,declaration:this.getDeclaration(e.name),ast:e});break;case"ReturnStatement":this.returnStatements.push(e),this.scan(e.argument);break;case"MemberExpression":this.pushState(a),this.scan(e.object),this.scan(e.property),this.popState(a);break;case"ExpressionStatement":this.scan(e.expression);break;case"SequenceExpression":this.scan(e.expressions);break;case"CallExpression":this.functionCalls.push({context:this.currentContext,ast:e}),this.scan(e.arguments);break;case"ArrayExpression":this.scan(e.elements);break;case"ConditionalExpression":this.scan(e.test),this.scan(e.alternate),this.scan(e.consequent);break;case"SwitchStatement":this.scan(e.discriminant),this.scan(e.cases);break;case"SwitchCase":this.scan(e.test),this.scan(e.consequent);break;case"ThisExpression":case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${e.type}"`)}}}}}),l=e((e,t)=>{const n=r(),{utils:s}=i(),{FunctionTracer:a}=u(),o=["E","PI","SQRT2","SQRT1_2","LN2","LN10","LOG2E","LOG10E"],l=["abs","acos","acosh","asin","asinh","atan","atan2","atanh","cbrt","ceil","clz32","cos","cosh","expm1","exp","floor","fround","imul","log","log2","log10","log1p","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc"],h=["value","value[]","value[][]","value[][][]","value[][][][]","value.value","value.thread.value","this.thread.value","this.output.value","this.constants.value","this.constants.value[]","this.constants.value[][]","this.constants.value[][][]","this.constants.value[][][][]","fn()[]","fn()[][]","fn()[][][]","[][]"];const c={Number:"Number",Float:"Float",Integer:"Integer",Array:"Number","Array(2)":"Number","Array(3)":"Number","Array(4)":"Number","Matrix(2)":"Number","Matrix(3)":"Number","Matrix(4)":"Number",Array2D:"Number",Array3D:"Number",Input:"Number",HTMLCanvas:"Array(4)",OffscreenCanvas:"Array(4)",HTMLImage:"Array(4)",ImageBitmap:"Array(4)",ImageData:"Array(4)",HTMLVideo:"Array(4)",HTMLImageArray:"Array(4)",NumberTexture:"Number",MemoryOptimizedNumberTexture:"Number","Array1D(2)":"Array(2)","Array1D(3)":"Array(3)","Array1D(4)":"Array(4)","Array2D(2)":"Array(2)","Array2D(3)":"Array(3)","Array2D(4)":"Array(4)","Array3D(2)":"Array(2)","Array3D(3)":"Array(3)","Array3D(4)":"Array(4)","ArrayTexture(1)":"Number","ArrayTexture(2)":"Array(2)","ArrayTexture(3)":"Array(3)","ArrayTexture(4)":"Array(4)"};t.exports={FunctionNode:class{constructor(e,t){if(!e&&!t.ast)throw new Error("source parameter is missing");if(t=t||{},this.source=e,this.ast=null,this.name="string"==typeof e?t.isRootKernel?"kernel":t.name||s.getFunctionNameFromString(e):null,this.calledFunctions=[],this.constants={},this.constantTypes={},this.constantBitRatios={},this.isRootKernel=!1,this.isSubKernel=!1,this.debug=null,this.functions=null,this.identifiers=null,this.contexts=null,this.functionCalls=null,this.states=[],this.needsArgumentType=null,this.assignArgumentType=null,this.lookupReturnType=null,this.lookupFunctionArgumentTypes=null,this.lookupFunctionArgumentBitRatio=null,this.triggerImplyArgumentType=null,this.triggerImplyArgumentBitRatio=null,this.onNestedFunction=null,this.onFunctionCall=null,this.optimizeFloatMemory=null,this.precision=null,this.loopMaxIterations=null,this.argumentNames="string"==typeof this.source?s.getArgumentNamesFromString(this.source):null,this.argumentTypes=[],this.argumentSizes=[],this.argumentBitRatios=null,this.returnType=null,this.output=[],this.plugins=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.dynamicOutput=null,this.dynamicArguments=null,this.strictTypingChecking=!1,this.fixIntegerDivisionAccuracy=null,t)for(const e in t)t.hasOwnProperty(e)&&this.hasOwnProperty(e)&&(this[e]=t[e]);this.literalTypes={},this.validate(),this._string=null,this._internalVariableNames={}}validate(){if("string"!=typeof this.source&&!this.ast)throw new Error("this.source not a string");if(!this.ast&&!s.isFunctionString(this.source))throw new Error("this.source not a function string");if(!this.name)throw new Error("this.name could not be set");if(this.argumentTypes.length>0&&this.argumentTypes.length!==this.argumentNames.length)throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`);if(this.output.length<1)throw new Error("this.output is not big enough")}isIdentifierConstant(e){return!!this.constants&&this.constants.hasOwnProperty(e)}isInput(e){return"Input"===this.argumentTypes[this.argumentNames.indexOf(e)]}pushState(e){this.states.push(e)}popState(e){if(this.state!==e)throw new Error(`Cannot popState ${e} when in ${this.state}`);this.states.pop()}isState(e){return this.state===e}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(e){if("Identifier"===e.type)return e.name;if("ThisExpression"===e.type)return"this";if("MemberExpression"===e.type&&e.object&&e.property)return e.object.hasOwnProperty("name")&&"Math"!==e.object.name?this.astMemberExpressionUnroll(e.property):this.astMemberExpressionUnroll(e.object)+"."+this.astMemberExpressionUnroll(e.property);if(e.hasOwnProperty("expressions")){const t=e.expressions[0];if("Literal"===t.type&&0===t.value&&2===e.expressions.length)return this.astMemberExpressionUnroll(e.expressions[1])}throw this.astErrorOutput("Unknown astMemberExpressionUnroll",e)}getJsAST(e){if(this.ast)return this.ast;if("object"==typeof this.source)return this.traceFunctionAST(this.source),this.ast=this.source;if(null===(e=e||n))throw new Error("Missing JS to AST parser");const t=Object.freeze(e.parse(`const parser_${this.name} = ${this.source};`,{locations:!0,ecmaVersion:2020})),r=t.body[0].declarations[0].init;if(this.traceFunctionAST(r),!t)throw new Error("Failed to parse JS code");return this.ast=r}traceFunctionAST(e){const{contexts:t,declarations:r,functions:n,identifiers:s,functionCalls:i}=new a(e);this.contexts=t,this.identifiers=s,this.functionCalls=i,this.functions=n;for(let e=0;e":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const r=this.getType(e.left);if(this.isState("skip-literal-correction"))return r;if("LiteralInteger"===r){const t=this.getType(e.right);return"LiteralInteger"===t?e.left.value%1==0?"Integer":"Float":t}return c[r]||r;case"UpdateExpression":case"ReturnStatement":return this.getType(e.argument);case"UnaryExpression":return"~"===e.operator?"Integer":this.getType(e.argument);case"VariableDeclaration":{const t=e.declarations;let r;for(let e=0;ee.isSafe)}getDependencies(e,t,r){if(t||(t=[]),!e)return null;if(Array.isArray(e)){for(let n=0;n-1/0&&e.value<1/0&&!isNaN(e.value))});break;case"VariableDeclarator":return this.getDependencies(e.init,t,r);case"Identifier":const n=this.getDeclaration(e);if(n)t.push({name:e.name,origin:"declaration",isSafe:!r&&this.isSafeDependencies(n.dependencies)});else if(this.argumentNames.indexOf(e.name)>-1)t.push({name:e.name,origin:"argument",isSafe:!1});else if(this.strictTypingChecking)throw new Error(`Cannot find identifier origin "${e.name}"`);break;case"FunctionDeclaration":return this.getDependencies(e.body.body[e.body.body.length-1],t,r);case"ReturnStatement":return this.getDependencies(e.argument,t);case"BinaryExpression":case"LogicalExpression":return r="/"===e.operator||"*"===e.operator,this.getDependencies(e.left,t,r),this.getDependencies(e.right,t,r),t;case"UnaryExpression":case"UpdateExpression":return this.getDependencies(e.argument,t,r);case"VariableDeclaration":return this.getDependencies(e.declarations,t,r);case"ArrayExpression":return t.push({origin:"declaration",isSafe:!0}),t;case"CallExpression":return t.push({origin:"function",isSafe:!0}),t;case"MemberExpression":const s=this.getMemberExpressionDetails(e);switch(s.signature){case"value[]":this.getDependencies(e.object,t,r);break;case"value[][]":this.getDependencies(e.object.object,t,r);break;case"value[][][]":this.getDependencies(e.object.object.object,t,r);break;case"this.output.value":this.dynamicOutput&&t.push({name:s.name,origin:"output",isSafe:!1})}if(s)return s.property&&this.getDependencies(s.property,t,r),s.xProperty&&this.getDependencies(s.xProperty,t,r),s.yProperty&&this.getDependencies(s.yProperty,t,r),s.zProperty&&this.getDependencies(s.zProperty,t,r),t;case"SequenceExpression":return this.getDependencies(e.expressions,t,r);default:throw this.astErrorOutput(`Unhandled type ${e.type} in getDependencies`,e)}return t}getVariableSignature(e,t){if(!this.isAstVariable(e))throw new Error(`ast of type "${e.type}" is not a variable signature`);if("Identifier"===e.type)return"value";const r=[];for(;e;)e.computed?r.push("[]"):"ThisExpression"===e.type?r.unshift("this"):e.property&&e.property.name?"x"===e.property.name||"y"===e.property.name||"z"===e.property.name?r.unshift(t?"."+e.property.name:".value"):"constants"===e.property.name||"thread"===e.property.name||"output"===e.property.name?r.unshift("."+e.property.name):r.unshift(t?"."+e.property.name:".value"):e.name?r.unshift(t?e.name:"value"):e.callee&&e.callee.name?r.unshift(t?e.callee.name+"()":"fn()"):e.elements?r.unshift("[]"):r.unshift("unknown"),e=e.object;const n=r.join("");return t||h.includes(n)?n:null}build(){return this.toString().length>0}astGeneric(e,t){if(null===e)throw this.astErrorOutput("NULL ast",e);if(Array.isArray(e)){for(let r=0;r0?n[n.length-1]:0;return new Error(`${e} on line ${n.length}, position ${i.length}:\n ${r}`)}astDebuggerStatement(e,t){return t}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);return t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t}astFunction(e,t){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}astFunctionExpression(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}isChildFunction(e){for(let t=0;t1?t.push("(",n.join(","),")"):t.push(n[0]),t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)||(e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator))),t}checkAndUpconvertBitwiseUnary(e,t){}astUpdateExpression(e,t){return e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t}astLogicalExpression(e,t){return t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t.push(")"),t}astMemberExpression(e,t){return t}astCallExpression(e,t){return t}astArrayExpression(e,t){return t}getMemberExpressionDetails(e){if("MemberExpression"!==e.type)throw this.astErrorOutput(`Expression ${e.type} not a MemberExpression`,e);let t=null,r=null;const n=this.getVariableSignature(e);switch(n){case"value":return null;case"value.thread.value":case"this.thread.value":case"this.output.value":return{signature:n,type:"Integer",name:e.property.name};case"value[]":if("string"!=typeof e.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object),xProperty:e.property};case"value[][]":if("string"!=typeof e.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object.object),yProperty:e.object.property,xProperty:e.property};case"value[][][]":if("string"!=typeof e.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value[][][][]":if("string"!=typeof e.object.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(this.isAstMathVariable(e))return t=e.property.name,{name:t,origin:"Math",type:"Number",signature:n};switch(e.property.name){case"r":case"g":case"b":case"a":return t=e.object.name,{name:t,property:e.property.name,origin:"user",signature:n,type:"Number"};default:throw this.astErrorOutput("Unexpected expression",e)}case"this.constants.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n};case"this.constants.value[]":if("string"!=typeof e.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,xProperty:e.property};case"this.constants.value[][]":if("string"!=typeof e.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,yProperty:e.object.property,xProperty:e.property};case"this.constants.value[][][]":if("string"!=typeof e.object.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.object.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"fn()[]":case"fn()[][]":case"[][]":return{signature:n,property:e.property};default:throw this.astErrorOutput("Unexpected expression",e)}}findIdentifierOrigin(e){const t=[this.ast];for(;t.length>0;){const r=t[0];if("VariableDeclarator"===r.type&&r.id&&r.id.name&&r.id.name===e.name)return r;if(t.shift(),r.argument)t.push(r.argument);else if(r.body)t.push(r.body);else if(r.declarations)t.push(r.declarations);else if(Array.isArray(r))for(let e=0;e0;){const e=t.pop();if("ReturnStatement"===e.type)return e;if("FunctionDeclaration"!==e.type)if(e.argument)t.push(e.argument);else if(e.body)t.push(e.body);else if(e.declarations)t.push(e.declarations);else if(Array.isArray(e))for(let r=0;r{const{FunctionNode:r}=l();t.exports={CPUFunctionNode:class extends r{astFunction(e,t){if(!this.isRootKernel){t.push("function"),t.push(" "),t.push(this.name),t.push("(");for(let e=0;e0&&t.push(", "),t.push("user_"),t.push(r)}t.push(") {\n")}for(let r=0;r0&&t.push(r.join(""),";\n"),t.push(`for (let ${e}=0;${e}0&&t.push(`if (!${n.join("")}) break;\n`),t.push(i.join("")),t.push(`\n${s.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),t.push("if ("),this.astGeneric(e.test,t),t.push(") {\n"),this.astGeneric(e.body,t),t.push("} else {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astDoWhileStatement(e,t){if("DoWhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),this.astGeneric(e.body,t),t.push("if (!"),this.astGeneric(e.test,t),t.push(") {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astAssignmentExpression(e,t){const r=this.getDeclaration(e.left);if(r&&!r.assignable)throw this.astErrorOutput(`Variable ${e.left.name} is not assignable here`,e);const n=this.isState("assignment-as-statement");return n?this.popState("assignment-as-statement"):t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),n||t.push(")"),t}astBlockStatement(e,t){if(this.isState("loop-body")){this.pushState("block-body");for(let r=0;r0&&t.push(",");const n=r[e],s=this.getDeclaration(n.id);s.valueType||(s.valueType=this.getType(n.init)),this.astGeneric(n,t)}return this.isState("in-for-loop-init")||t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchStatement(e,t){const{discriminant:r,cases:n}=e;t.push("switch ("),this.astGeneric(r,t),t.push(") {\n");for(let e=0;e0&&(this.astGeneric(n[e].consequent,t),t.push("break;\n"))):(t.push("default:\n"),this.astGeneric(n[e].consequent,t),n[e].consequent&&n[e].consequent.length>0&&t.push("break;\n"));t.push("\n}")}astThisExpression(e,t){return t.push("_this"),t}astMemberExpression(e,t){const{signature:r,type:n,property:s,xProperty:i,yProperty:a,zProperty:o,name:u,origin:l}=this.getMemberExpressionDetails(e);switch(r){case"this.thread.value":return t.push(`_this.thread.${u}`),t;case"this.output.value":switch(u){case"x":t.push("outputX");break;case"y":t.push("outputY");break;case"z":t.push("outputZ");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":default:throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value.value":if("Math"===l)return t.push(Math[u]),t;switch(s){case"r":return t.push(`user_${u}[0]`),t;case"g":return t.push(`user_${u}[1]`),t;case"b":return t.push(`user_${u}[2]`),t;case"a":return t.push(`user_${u}[3]`),t}break;case"this.constants.value":case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":break;case"fn()[]":return this.astGeneric(e.object,t),t.push("["),this.astGeneric(e.property,t),t.push("]"),t;case"fn()[][]":return this.astGeneric(e.object.object,t),t.push("["),this.astGeneric(e.object.property,t),t.push("]"),t.push("["),this.astGeneric(e.property,t),t.push("]"),t}if(!e.computed)switch(n){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${l}_${u}`),t}const h=`${l}_${u}`;{let e,r;if("constants"===l){const t=this.constants[u];r="Input"===this.constantTypes[u],e=r?t.size:null}else r=this.isInput(u),e=r?this.argumentSizes[this.argumentNames.indexOf(u)]:null;t.push(`${h}`),o&&a?r?(t.push("[("),this.astGeneric(o,t),t.push(`*${this.dynamicArguments?"(outputY * outputX)":e[1]*e[0]})+(`),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(i,t),t.push("]")):(t.push("["),this.astGeneric(o,t),t.push("]"),t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(i,t),t.push("]")):a?r?(t.push("[("),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(i,t),t.push("]")):(t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(i,t),t.push("]")):void 0!==i&&(t.push("["),this.astGeneric(i,t),t.push("]"))}return t}astCallExpression(e,t){if("CallExpression"!==e.type)throw this.astErrorOutput("Unknown CallExpression",e);let r=this.astMemberExpressionUnroll(e.callee);this.calledFunctions.indexOf(r)<0&&this.calledFunctions.push(r),this.isAstMathFunction(e),this.onFunctionCall&&this.onFunctionCall(this.name,r,e.arguments),t.push(r),t.push("(");const n=this.lookupFunctionArgumentTypes(r)||[];for(let s=0;s0&&t.push(", "),this.astGeneric(i,t)}return t.push(")"),t}astArrayExpression(e,t){const r=this.getType(e),n=e.elements.length,s=[];for(let t=0;t{const{utils:r}=i();t.exports={cpuKernelString:function(e,t){const n=[],s=[],i=[],a=!/^function/.test(e.color.toString());if(n.push(" const { context, canvas, constants: incomingConstants } = settings;",` const output = new Int32Array(${JSON.stringify(Array.from(e.output))});`,` const _constantTypes = ${JSON.stringify(e.constantTypes)};`,` const _constants = ${function(e,t){const r=[];for(const n in t){if(!t.hasOwnProperty(n))continue;const s=t[n],i=e[n];switch(s){case"Number":case"Integer":case"Float":case"Boolean":r.push(`${n}:${i}`);break;case"Array(2)":case"Array(3)":case"Array(4)":case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":r.push(`${n}:new ${i.constructor.name}(${JSON.stringify(Array.from(i))})`)}}return`{ ${r.join()} }`}(e.constants,e.constantTypes)};`),s.push(" constants: _constants,"," context,"," output,"," thread: {x: 0, y: 0, z: 0},"),e.graphical){n.push(` const _imageData = context.createImageData(${e.output[0]}, ${e.output[1]});`),n.push(` const _colorData = new Uint8ClampedArray(${e.output[0]} * ${e.output[1]} * 4);`);const t=r.flattenFunctionToString((a?"function ":"")+e.color.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:(e,t)=>null}),o=r.flattenFunctionToString((a?"function ":"")+e.getPixels.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:()=>null});s.push(" _imageData,"," _colorData,",` color: ${t},`),i.push(` kernel.getPixels = ${o};`)}const o=[],u=Object.keys(e.constantTypes);for(let t=0;t"this"===t?(a?"function ":"")+e[r].toString():null,thisLookup:e=>{switch(e){case"canvas":return;case"context":return"context"}}});i.push(t),s.push(" _mediaTo2DArray,"),s.push(" _imageTo3DArray,")}else if(-1!==e.argumentTypes.indexOf("HTMLImage")||-1!==o.indexOf("HTMLImage")){const t=r.flattenFunctionToString((a?"function ":"")+e._mediaTo2DArray.toString(),{findDependency:(e,t)=>null,thisLookup:e=>{switch(e){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});i.push(t),s.push(" _mediaTo2DArray,")}return`function(settings) {\n${n.join("\n")}\n for (const p in _constantTypes) {\n if (!_constantTypes.hasOwnProperty(p)) continue;\n const type = _constantTypes[p];\n switch (type) {\n case 'Number':\n case 'Integer':\n case 'Float':\n case 'Boolean':\n case 'Array(2)':\n case 'Array(3)':\n case 'Array(4)':\n case 'Matrix(2)':\n case 'Matrix(3)':\n case 'Matrix(4)':\n if (incomingConstants.hasOwnProperty(p)) {\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\n }\n continue;\n }\n if (!incomingConstants.hasOwnProperty(p)) {\n throw new Error('constant ' + p + ' not found');\n }\n _constants[p] = incomingConstants[p];\n }\n const kernel = (function() {\n${e._kernelString}\n })\n .apply({ ${s.join("\n")} });\n ${i.join("\n")}\n return kernel;\n}`}}}),p=e((e,t)=>{const{Kernel:r}=a(),{FunctionBuilder:n}=o(),{CPUFunctionNode:s}=h(),{utils:u}=i(),{cpuKernelString:l}=c();t.exports={CPUKernel:class extends r{static getFeatures(){return this.features}static get features(){return Object.freeze({kernelMap:!0,isIntegerDivisionAccurate:!0})}static get isSupported(){return!0}static isContextMatch(e){return!1}static get mode(){return"cpu"}static nativeFunctionArguments(){return null}static nativeFunctionReturnType(){throw new Error(`Looking up native function return type not supported on ${this.name}`)}static combineKernels(e){return e}static getSignature(e,t){return"cpu"+(t.length>0?":"+t.join(","):"")}constructor(e,t){super(e,t),this.mergeSettings(e.settings||t),this._imageData=null,this._colorData=null,this._kernelString=null,this._prependedString=[],this.thread={x:0,y:0,z:0},this.translatedSources=null}initCanvas(){return"undefined"!=typeof document?document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(0,0):void 0}initContext(){return this.canvas?this.canvas.getContext("2d",{willReadFrequently:!0}):null}initPlugins(e){return[]}validateSettings(e){if(!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=u.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=u.getDimensions(t);else{if("NumberTexture"!==t&&"ArrayTexture(4)"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=e[0].output}}if(this.graphical&&2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");this.checkOutput()}translateSource(){if(this.leadingReturnStatement=this.output.length>1?"resultX[x] = ":"result[x] = ",this.subKernels){const e=[];for(let t=0;t1?`resultX_${r}[x] = subKernelResult_${r};\n`:`result_${r}[x] = subKernelResult_${r};\n`)}this.followingReturnStatement=e.join("")}const e=n.fromKernel(this,s);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){if(this.built)return;if(null!==this.randomSeed&&console.warn("randomSeed is not supported in cpu mode; Math.random() will be unseeded"),this.setupConstants(),this.setupArguments(arguments),this.validateSettings(arguments),this.translateSource(),this.graphical){const{canvas:e,output:t}=this;if(!e)throw new Error("no canvas available for using graphical output");const r=t[0],n=t[1]||1;e.width=r,e.height=n,this._imageData=this.context.createImageData(r,n),this._colorData=new Uint8ClampedArray(r*n*4)}const e=this.getKernelString();this.kernelString=e,this.debug&&(console.log("Function output:"),console.log(e));try{this.run=new Function([],e).bind(this)()}catch(e){console.error("An error occurred compiling the javascript: ",e)}this.buildSignature(arguments),this.built=!0}color(e,t,r,n){void 0===n&&(n=1),e=Math.floor(255*e),t=Math.floor(255*t),r=Math.floor(255*r),n=Math.floor(255*n);const s=this.output[0],i=this.output[1],a=this.thread.x+(i-this.thread.y-1)*s;this._colorData[4*a+0]=e,this._colorData[4*a+1]=t,this._colorData[4*a+2]=r,this._colorData[4*a+3]=n}getKernelString(){if(null!==this._kernelString)return this._kernelString;let e=null,{translatedSources:t}=this;return t.length>1?t=t.filter(t=>/^function/.test(t)?t:(e=t,!1)):e=t.shift(),this._kernelString=` const LOOP_MAX = ${this._getLoopMaxString()};\n ${this.injectedNative||""}\n const _this = this;\n ${this._resultKernelHeader()}\n ${this._processConstants()}\n return (${this.argumentNames.map(e=>"user_"+e).join(", ")}) => {\n ${this._prependedString.join("")}\n ${this._earlyThrows()}\n ${this._processArguments()}\n ${this.graphical?this._graphicalKernelBody(e):this._resultKernelBody(e)}\n ${t.length>0?t.join("\n"):""}\n };`}toString(){return l(this)}_getLoopMaxString(){return this.loopMaxIterations?` ${parseInt(this.loopMaxIterations)};`:" 1000;"}_processConstants(){if(!this.constants)return"";const e=[];for(let t in this.constants)switch(this.constantTypes[t]){case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":e.push(` const constants_${t} = this._mediaTo2DArray(this.constants.${t});\n`);break;case"HTMLImageArray":e.push(` const constants_${t} = this._imageTo3DArray(this.constants.${t});\n`);break;case"Input":e.push(` const constants_${t} = this.constants.${t}.value;\n`);break;default:e.push(` const constants_${t} = this.constants.${t};\n`)}return e.join("")}_earlyThrows(){if(this.graphical)return"";if(this.immutable)return"";if(!this.pipeline)return"";const e=[];for(let t=0;t`user_${n} === result_${e.name}`).join(" || ");t.push(`user_${n} === result${s?` || ${s}`:""}`)}return`if (${t.join(" || ")}) throw new Error('Source and destination arrays are the same. Use immutable = true');`}_processArguments(){const e=[];for(let t=0;t0?e.width:e.videoWidth,n=e.height>0?e.height:e.videoHeight;t.width=0;e--){const t=a[e]=new Array(r);for(let e=0;e`const result_${e.name} = new ${t}(outputX);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_mutableKernel1DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const result = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const result_${t.name} = new ${e}(outputX);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}`}_resultMutableKernel1DLoop(e){return` const outputX = _this.output[0];\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_resultImmutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y] = new ${t}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_mutableKernel2DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n const resultX = result[y] = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const resultX_${t.name} = result_${t.name}[y] = new ${e}(outputX);\n`).join("")}\n }`}_resultMutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y];\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_graphicalKernel2DLoop(e){return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_resultImmutableKernel3DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputZ);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels(e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y] = new ${t}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = resultY_${e.name}[y] = new ${t}(outputX);\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_mutableKernel3DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputZ);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels(e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n const resultX = resultY[y] = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const resultX_${t.name} = resultY_${t.name}[y] = new ${e}(outputX);\n`).join(" ")}\n }\n }`}_resultMutableKernel3DLoop(e){return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z];\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y];\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_kernelOutput(){return this.subKernels?`\n return {\n result: result,\n ${this.subKernels.map(e=>`${e.property}: result_${e.name}`).join(",\n ")}\n };`:"\n return result;"}_mapSubKernels(e){return null===this.subKernels?[""]:this.subKernels.map(e)}destroy(e){e&&delete this.canvas}static destroyContext(e){}toJSON(){const e=super.toJSON();return e.functionNodes=n.fromKernel(this,s).toJSON(),e}setOutput(e){super.setOutput(e);const[t,r]=this.output;this.graphical&&(this._imageData=this.context.createImageData(t,r),this._colorData=new Uint8ClampedArray(t*r*4))}prependString(e){if(this._kernelString)throw new Error("Kernel already built");this._prependedString.push(e)}hasPrependString(e){return this._prependedString.indexOf(e)>-1}}}}),d=e((e,t)=>{const{Texture:r}=s();function n(e,t){e.activeTexture(e.TEXTURE15),e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST)}t.exports={GLTexture:class extends r{get textureType(){throw new Error(`"textureType" not implemented on ${this.name}`)}clone(){return new this.constructor(this)}beforeMutate(){return this.texture._refs>1&&(this.newTexture(),!0)}cloneTexture(){this.texture._refs--;const{context:e,size:t,texture:r,kernel:s}=this;s.debug&&console.warn("cloning internal texture"),e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),n(e,r),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,r,0);const i=e.createTexture();n(e,i),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),e.copyTexSubImage2D(e.TEXTURE_2D,0,0,0,0,0,t[0],t[1]),i._refs=1,this.texture=i}newTexture(){this.texture._refs--;const e=this.context,t=this.size;this.kernel.debug&&console.warn("new internal texture");const r=e.createTexture();n(e,r),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),r._refs=1,this.texture=r}clear(){if(this.texture._refs){this.texture._refs--;const e=this.context,t=this.texture=e.createTexture();n(e,t);const r=this.size;t._refs=1,e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,r[0],r[1],0,this.textureFormat,this.textureType,null)}const{context:e,texture:t}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.bindTexture(e.TEXTURE_2D,t),n(e,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}delete(){this._deleted||(this._deleted=!0,this.texture._refs&&(this.texture._refs--,this.texture._refs)||(this.kernel&&this.kernel.deleteTexture?this.kernel.deleteTexture(this.texture):this.context.deleteTexture(this.texture)))}framebuffer(){return this._framebuffer||(this._framebuffer=this.kernel.getRawValueFramebuffer(this.size[0],this.size[1])),this._framebuffer}}}}),m=e((e,t)=>{const{utils:r}=i(),{GLTexture:n}=d();t.exports={GLTextureFloat:class extends n{get textureType(){return this.context.FLOAT}constructor(e){super(e),this.type="ArrayTexture(1)"}renderRawOutput(){const e=this.context,t=this.size;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const r=new Float32Array(t[0]*t[1]*4);return e.readPixels(0,0,t[0],t[1],e.RGBA,e.FLOAT,r),r}renderValues(){return this._deleted?null:this.renderRawOutput()}toArray(){return r.erectFloat(this.renderValues(),this.output[0])}}}}),f=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray2Float:class extends n{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erectArray2(this.renderValues(),this.output[0],this.output[1])}}}}),g=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray2Float2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erect2DArray2(this.renderValues(),this.output[0],this.output[1])}}}}),y=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray2Float3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erect3DArray2(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),x=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray3Float:class extends n{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erectArray3(this.renderValues(),this.output[0])}}}}),b=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray3Float2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erect2DArray3(this.renderValues(),this.output[0],this.output[1])}}}}),T=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray3Float3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erect3DArray3(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),S=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray4Float:class extends n{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erectArray4(this.renderValues(),this.output[0])}}}}),A=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray4Float2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erect2DArray4(this.renderValues(),this.output[0],this.output[1])}}}}),w=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray4Float3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erect3DArray4(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),E=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureFloat2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return r.erect2DFloat(this.renderValues(),this.output[0],this.output[1])}}}}),_=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureFloat3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return r.erect3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),v=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureMemoryOptimized:class extends n{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}}}),I=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureMemoryOptimized2D:class extends n{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}}}),$=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureMemoryOptimized3D:class extends n{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),D=e((e,t)=>{const{utils:r}=i(),{GLTexture:n}=d();t.exports={GLTextureUnsigned:class extends n{get textureType(){return this.context.UNSIGNED_BYTE}constructor(e){super(e),this.type="NumberTexture"}renderRawOutput(){const{context:e}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const t=new Uint8Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.UNSIGNED_BYTE,t),t}renderValues(){return this._deleted?null:new Float32Array(this.renderRawOutput().buffer)}toArray(){return r.erectPackedFloat(this.renderValues(),this.output[0])}}}}),F=e((e,t)=>{const{utils:r}=i(),{GLTextureUnsigned:n}=D();t.exports={GLTextureUnsigned2D:class extends n{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}}}),L=e((e,t)=>{const{utils:r}=i(),{GLTextureUnsigned:n}=D();t.exports={GLTextureUnsigned3D:class extends n{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),R=e((e,t)=>{const{GLTextureUnsigned:r}=D();t.exports={GLTextureGraphical:class extends r{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return this.renderValues()}}}}),k=e((e,t)=>{const{Kernel:r}=a(),{utils:n}=i(),{GLTextureArray2Float:s}=f(),{GLTextureArray2Float2D:o}=g(),{GLTextureArray2Float3D:u}=y(),{GLTextureArray3Float:l}=x(),{GLTextureArray3Float2D:h}=b(),{GLTextureArray3Float3D:c}=T(),{GLTextureArray4Float:p}=S(),{GLTextureArray4Float2D:d}=A(),{GLTextureArray4Float3D:k}=w(),{GLTextureFloat:z}=m(),{GLTextureFloat2D:M}=E(),{GLTextureFloat3D:G}=_(),{GLTextureMemoryOptimized:C}=v(),{GLTextureMemoryOptimized2D:N}=I(),{GLTextureMemoryOptimized3D:O}=$(),{GLTextureUnsigned:V}=D(),{GLTextureUnsigned2D:K}=F(),{GLTextureUnsigned3D:U}=L(),{GLTextureGraphical:P}=R();const B={int:"Integer",float:"Number",vec2:"Array(2)",vec3:"Array(3)",vec4:"Array(4)"};t.exports={GLKernel:class extends r{static get mode(){return"gpu"}static getIsFloatRead(){const e=new this("function kernelFunction() {\n return 1;\n }",{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[1],precision:"single",returnType:"Number",tactic:"speed"});e.build(),e.run();const t=e.renderOutput();return e.destroy(!0),1===t[0]}static getIsIntegerDivisionAccurate(){const e=new this(function(e,t){return e[this.thread.x]/t[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[2],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[6,6030401],[3,3991]];e.build.apply(e,t),e.run.apply(e,t);const r=e.renderOutput();return e.destroy(!0),2===r[0]&&1511===r[1]}static getIsSpeedTacticSupported(){const e=new this(function(e){return e[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[4],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[0,1,2,3]];e.build.apply(e,t),e.run.apply(e,t);const r=e.renderOutput();return e.destroy(!0),0===Math.round(r[0])&&1===Math.round(r[1])&&2===Math.round(r[2])&&3===Math.round(r[3])}static get testCanvas(){throw new Error(`"testCanvas" not defined on ${this.name}`)}static get testContext(){throw new Error(`"testContext" not defined on ${this.name}`)}static getFeatures(){const e=this.testContext,t=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isSpeedTacticSupported:this.getIsSpeedTacticSupported(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:t,kernelMap:t,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize(),lowIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT),lowFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT),mediumIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT),mediumFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT),highIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT),highFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)})}static setupFeatureChecks(){throw new Error(`"setupFeatureChecks" not defined on ${this.name}`)}static getSignature(e,t){return e.getVariablePrecisionString()+(t.length>0?":"+t.join(","):"")}setFixIntegerDivisionAccuracy(e){return this.fixIntegerDivisionAccuracy=e,this}setPrecision(e){return this.precision=e,this}setFloatTextures(e){return n.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],r=[],n=[],s=/^[a-zA-Z_]/,i=/[a-zA-Z_0-9]/;let a=0,o=null,u=null;for(;a0?n[n.length-1]:null;if("FUNCTION_ARGUMENTS"!==c||"/"!==l||"*"!==h)if("MULTI_LINE_COMMENT"!==c||"*"!==l||"/"!==h)if("FUNCTION_ARGUMENTS"!==c||"/"!==l||"/"!==h)if("COMMENT"!==c||"\n"!==l)if(null!==c||"("!==l){if("FUNCTION_ARGUMENTS"===c){if(")"===l){n.pop();break}if("f"===l&&"l"===h&&"o"===e[a+2]&&"a"===e[a+3]&&"t"===e[a+4]&&" "===e[a+5]){n.push("DECLARE_VARIABLE"),u="float",o="",a+=6;continue}if("i"===l&&"n"===h&&"t"===e[a+2]&&" "===e[a+3]){n.push("DECLARE_VARIABLE"),u="int",o="",a+=4;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"2"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec2",o="",a+=5;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"3"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec3",o="",a+=5;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"4"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec4",o="",a+=5;continue}}else if("DECLARE_VARIABLE"===c){if(""===o){if(" "===l){a++;continue}if(!s.test(l))throw new Error("variable name is not expected string")}o+=l,i.test(h)||(n.pop(),r.push(o),t.push(B[u]))}a++}else n.push("FUNCTION_ARGUMENTS"),a++;else n.pop(),a++;else n.push("COMMENT"),a+=2;else n.pop(),a+=2;else n.push("MULTI_LINE_COMMENT"),a+=2}if(n.length>0)throw new Error("GLSL function was not parsable");return{argumentNames:r,argumentTypes:t}}static nativeFunctionReturnType(e){return B[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:r,context:s,threadDim:i}=t.texSize;let a;if("single"===t.precision){const e=r[0],t=Math.ceil(r[1]/4);a=new Float32Array(e*t*4*4),s.readPixels(0,0,e,4*t,s.RGBA,s.FLOAT,a)}else{const e=new Uint8Array(r[0]*r[1]*4);s.readPixels(0,0,r[0],r[1],s.RGBA,s.UNSIGNED_BYTE,e),a=new Float32Array(e.buffer)}return a=a.subarray(0,i[0]*i[1]*i[2]),1===t.output.length?a:2===t.output.length?n.splitArray(a,t.output[0]):3===t.output.length?n.splitArray(a,t.output[0]*t.output[1]).map(function(e){return n.splitArray(e,t.output[0])}):void 0}constructor(e,t){super(e,t),this.transferValues=null,this.formatValues=null,this.TextureConstructor=null,this.renderOutput=null,this.renderRawOutput=null,this.texSize=null,this.translatedSource=null,this.compiledFragmentShader=null,this.compiledVertexShader=null,this.switchingKernels=null,this._textureSwitched=null,this._mappedTextureSwitched=null}checkTextureSize(){const{features:e}=this.constructor;if(this.texSize[0]>e.maxTextureSize||this.texSize[1]>e.maxTextureSize)throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${e.maxTextureSize},${e.maxTextureSize}]`)}translateSource(){throw new Error(`"translateSource" not defined on ${this.constructor.name}`)}pickRenderStrategy(e){if(this.graphical)return this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=e=>e,this.TextureConstructor=P,null;if("unsigned"===this.precision)if(this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=this.readPackedPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=U,null):this.output[1]>0?(this.TextureConstructor=K,null):(this.TextureConstructor=V,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else switch(null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.renderOutput=this.renderValues,this.output[2]>0?(this.TextureConstructor=U,this.formatValues=n.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=K,this.formatValues=n.erect2DPackedFloat,null):(this.TextureConstructor=V,this.formatValues=n.erectPackedFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else{if("single"!==this.precision)throw new Error(`unhandled precision of "${this.precision}"`);if(this.renderRawOutput=this.readFloatPixelsToFloat32Array,this.transferValues=this.readFloatPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.optimizeFloatMemory?this.output[2]>0?(this.TextureConstructor=O,null):this.output[1]>0?(this.TextureConstructor=N,null):(this.TextureConstructor=C,null):this.output[2]>0?(this.TextureConstructor=G,null):this.output[1]>0?(this.TextureConstructor=M,null):(this.TextureConstructor=z,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,null):this.output[1]>0?(this.TextureConstructor=o,null):(this.TextureConstructor=s,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,null):this.output[1]>0?(this.TextureConstructor=h,null):(this.TextureConstructor=l,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=k,null):this.output[1]>0?(this.TextureConstructor=d,null):(this.TextureConstructor=p,null)}if(this.renderOutput=this.renderValues,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.optimizeFloatMemory)switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=O,this.formatValues=n.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=N,this.formatValues=n.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=C,this.formatValues=n.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.formatValues=n.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.formatValues=n.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=n.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,this.formatValues=n.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=h,this.formatValues=n.erect2DArray3,null):(this.TextureConstructor=l,this.formatValues=n.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=k,this.formatValues=n.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=d,this.formatValues=n.erect2DArray4,null):(this.TextureConstructor=p,this.formatValues=n.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=G,this.formatValues=n.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=M,this.formatValues=n.erect2DFloat,null):(this.TextureConstructor=z,this.formatValues=n.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.formatValues=n.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.formatValues=n.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=n.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,this.formatValues=n.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=h,this.formatValues=n.erect2DArray3,null):(this.TextureConstructor=l,this.formatValues=n.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=k,this.formatValues=n.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=d,this.formatValues=n.erect2DArray4,null):(this.TextureConstructor=p,this.formatValues=n.erectArray4,null)}}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error("abstract method call")}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error("abstract method call")}getMainResultSubKernelNumberTexture(){throw new Error("abstract method call")}getMainResultKernelArray2Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray2Texture(){throw new Error("abstract method call")}getMainResultKernelArray3Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray3Texture(){throw new Error("abstract method call")}getMainResultKernelArray4Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray4Texture(){throw new Error("abstract method call")}getMainResultGraphical(){throw new Error("abstract method call")}getMainResultMemoryOptimizedFloats(){throw new Error("abstract method call")}getMainResultPackedPixels(){throw new Error("abstract method call")}getMainResultString(){return this.graphical?this.getMainResultGraphical():"single"===this.precision?this.optimizeFloatMemory?this.getMainResultMemoryOptimizedFloats():this.getMainResultTexture():this.getMainResultPackedPixels()}getMainResultNumberTexture(){return n.linesToString(this.getMainResultKernelNumberTexture())+n.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return n.linesToString(this.getMainResultKernelArray2Texture())+n.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return n.linesToString(this.getMainResultKernelArray3Texture())+n.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return n.linesToString(this.getMainResultKernelArray4Texture())+n.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} float;\n`}getIntTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic,!0)} int;\n`}getSampler2DTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2D;\n`}getSampler2DArrayTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2DArray;\n`}renderTexture(){return this.immutable?this.texture.clone():this.texture}readPackedPixelsToUint8Array(){if("unsigned"!==this.precision)throw new Error('Requires this.precision to be "unsigned"');const{texSize:e,context:t}=this,r=new Uint8Array(e[0]*e[1]*4);return t.readPixels(0,0,e[0],e[1],t.RGBA,t.UNSIGNED_BYTE,r),r}readPackedPixelsToFloat32Array(){return new Float32Array(this.readPackedPixelsToUint8Array().buffer)}readFloatPixelsToFloat32Array(){if("single"!==this.precision)throw new Error('Requires this.precision to be "single"');const{texSize:e,context:t}=this,r=e[0],n=e[1],s=new Float32Array(r*n*4);return t.readPixels(0,0,r,n,t.RGBA,t.FLOAT,s),s}getPixels(e){const{context:t,output:r}=this,[s,i]=r,a=new Uint8Array(s*i*4);return t.readPixels(0,0,s,i,t.RGBA,t.UNSIGNED_BYTE,a),new Uint8ClampedArray((e?a:n.flipPixels(a,s,i)).buffer)}renderKernelsToArrays(){const e={result:this.renderOutput()};for(let t=0;t0){for(let e=0;e0){const{mappedTextures:r}=this;for(let n=0;n{const{utils:r}=i(),{FunctionNode:n}=l();function s(e){if(!e||"object"!=typeof e)return!0;if(Array.isArray(e))return e.every(s);if("UpdateExpression"===e.type||"AssignmentExpression"===e.type||"SequenceExpression"===e.type)return!1;for(const t in e)if("loc"!==t&&"range"!==t&&"parent"!==t&&!s(e[t]))return!1;return!0}function a(e){let t=!1;function r(e){if(!e||"object"!=typeof e||t)return!1;if(Array.isArray(e))return e.some(r);if("MemberExpression"===e.type&&e.computed)return!0;for(const t in e)if("loc"!==t&&"range"!==t&&"parent"!==t&&r(e[t]))return!0;return!1}return function e(n){if(n&&"object"==typeof n&&!t)if(Array.isArray(n))n.forEach(e);else if("MemberExpression"===n.type&&n.computed&&r(n.property))t=!0;else for(const t in n)"loc"!==t&&"range"!==t&&"parent"!==t&&e(n[t])}(e),t}function o(e,t){if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return e.some(e=>o(e,t));if("CallExpression"===e.type&&"Identifier"===e.callee.type&&e.callee.name===t)return!0;for(const r in e)if("loc"!==r&&"range"!==r&&"parent"!==r&&o(e[r],t))return!0;return!1}function u(e){let t=!1;return function e(r){if(r&&"object"==typeof r&&!t)if(Array.isArray(r))r.forEach(e);else if("CallExpression"===r.type&&"Identifier"===r.callee.type&&r.arguments.some(e=>o(e,r.callee.name)))t=!0;else for(const t in r)"loc"!==t&&"range"!==t&&"parent"!==t&&e(r[t])}(e),t}function h(e){const t="ExpressionStatement"===e.type&&"AssignmentExpression"===e.expression.type?e.expression:null;return function e(r){if(!r||"object"!=typeof r)return!0;if(Array.isArray(r))return r.every(e);if("string"==typeof r.type){if("UpdateExpression"===r.type||"SequenceExpression"===r.type)return!1;if("AssignmentExpression"===r.type&&r!==t)return!1}for(const t in r)if("loc"!==t&&"range"!==t&&"parent"!==t&&!e(r[t]))return!1;return!0}(e)}const c={"Matrix(2)":2,"Matrix(3)":3,"Matrix(4)":4},p={Array:"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4","Matrix(2)":"mat2","Matrix(3)":"mat3","Matrix(4)":"mat4",Array2D:"sampler2D",Array3D:"sampler2D",Boolean:"bool",Float:"float",Input:"sampler2D",Integer:"int",Number:"float",LiteralInteger:"float",NumberTexture:"sampler2D",MemoryOptimizedNumberTexture:"sampler2D","ArrayTexture(1)":"sampler2D","ArrayTexture(2)":"sampler2D","ArrayTexture(3)":"sampler2D","ArrayTexture(4)":"sampler2D",HTMLVideo:"sampler2D",HTMLCanvas:"sampler2D",OffscreenCanvas:"sampler2D",HTMLImage:"sampler2D",ImageBitmap:"sampler2D",ImageData:"sampler2D",HTMLImageArray:"sampler2DArray"},d={"===":"==","!==":"!="};t.exports={WebGLFunctionNode:class extends n{constructor(e,t){super(e,t),t&&t.hasOwnProperty("fixIntegerDivisionAccuracy")&&(this.fixIntegerDivisionAccuracy=t.fixIntegerDivisionAccuracy)}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);const r=this.getType(e.consequent),n=this.getType(e.alternate);return null===r&&null===n?(t.push("if ("),this.astGeneric(e.test,t),t.push(") {"),this.astGeneric(e.consequent,t),t.push(";"),t.push("} else {"),this.astGeneric(e.alternate,t),t.push(";"),t.push("}"),t):(t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t)}astFunction(e,t){if(this.isRootKernel)t.push("void");else{this.returnType||this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"));const{returnType:r}=this;if(r){const e=p[r];if(!e)throw new Error(`unknown type ${r}`);t.push(e)}else t.push("void")}if(t.push(" "),t.push(this.name),t.push("("),!this.isRootKernel)for(let n=0;n0&&t.push(", ");let i=this.argumentTypes[this.argumentNames.indexOf(s)];if(!i)throw this.astErrorOutput(`Unknown argument ${s} type`,e);"LiteralInteger"===i&&(this.argumentTypes[n]=i="Number");const a=p[i];if(!a)throw this.astErrorOutput("Unexpected expression",e);const o=r.sanitizeName(s);"sampler2D"===a||"sampler2DArray"===a?t.push(`${a} user_${o},ivec2 user_${o}Size,ivec3 user_${o}Dim`):t.push(`${a} user_${o}`)}t.push(") {\n");for(let r=0;r"===e.operator||"<"===e.operator&&"Literal"===e.right.type)&&!Number.isInteger(e.right.value)){this.pushState("building-float"),this.castValueToFloat(e.left,t),t.push(d[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-float");break}if(this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const r=[];if(this.astGeneric(e.right,r),"Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(r.join(""))}else t.push("int("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float");break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(d[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.pushState("casting-to-float"),this.astGeneric(e.right,t),this.popState("casting-to-float"),this.popState("building-float"));break;case"LiteralInteger & Integer":this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(d[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${s}`,e)}return t.push(")"),t}checkAndUpconvertOperator(e,t){const r=this.checkAndUpconvertBitwiseOperators(e,t);if(r)return r;const n={"%":this.fixIntegerDivisionAccuracy?"integerCorrectionModulo":"modulo","**":"pow"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){const r={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.left)){case"Number":case"Float":this.castValueToInteger(e.left,t);break;case"LiteralInteger":this.castLiteralToInteger(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Number":case"Float":this.castValueToInteger(e.right,t);break;case"LiteralInteger":this.castLiteralToInteger(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){const r={"~":"bitwiseNot"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("int("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("float("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),s=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===n&&this.argumentNames.indexOf(s)>-1?t.push(`bool(user_${s})`):t.push(`user_${s}`),t}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const r=[],n=[],s=[],i=[];let a=null;if(e.init){const{declarations:t}=e.init;t.length>1&&(a=!1),this.astGeneric(e.init,r);for(let e=0;e0&&t.push(r.join(""),"\n"),t.push(`for (int ${e}=0;${e}0&&t.push(`if (!${n.join("")}) break;\n`),t.push(i.join("")),t.push(`\n${s.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);const r=this.getInternalVariableName("safeI");return t.push(`for (int ${r}=0;${r}null!==e&&(a(e)||u(e))))return null;const i=e=>JSON.parse(JSON.stringify(e)),o=e=>({type:"IfStatement",test:{type:"UnaryExpression",operator:"!",prefix:!0,argument:e},consequent:{type:"BlockStatement",body:[{type:"BreakStatement",label:null}]},alternate:null}),l=e=>"VariableDeclaration"===e.type?e:{type:"ExpressionStatement",expression:e},h="BlockStatement"===e.body.type?e.body.body.slice():[e.body],c=(e,t)=>{const r=e=>{if(!e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map(r);switch(e.type){case"ContinueStatement":return{type:"BlockStatement",body:[...t(),e]};case"ForStatement":case"WhileStatement":case"DoWhileStatement":default:return e;case"IfStatement":return{...e,consequent:r(e.consequent),alternate:r(e.alternate)};case"BlockStatement":return{...e,body:e.body.map(r)};case"SwitchStatement":return{...e,cases:e.cases.map(e=>({...e,consequent:e.consequent.map(r)}))}}};return e.map(r)},p=[];"DoWhileStatement"===t?(p.push(...n?c(h,()=>[o(i(n))]):h),n&&p.push(o(n))):(n&&p.push(o(n)),p.push(...s?c(h,()=>[l(i(s))]):h),s&&p.push(l(s)));const d={type:"BlockStatement",body:[...r?[l(r)]:[],{type:"WhileStatement",test:{type:"Literal",value:!0,raw:"true"},body:{type:"BlockStatement",body:p}}]};let m=this.syntheticNodeId||1073741824;const f=e=>{if(e&&"object"==typeof e)if(Array.isArray(e))e.forEach(f);else{"string"==typeof e.type&&void 0===e.start&&(e.start=m,e.end=m+1,m+=2);for(const t in e)"loc"!==t&&"range"!==t&&"parent"!==t&&f(e[t])}};return f(d),this.syntheticNodeId=m,d}linearizeStatement(e){const t=[];let r=!1,n=this.linearTempId||0;const i=e=>({type:"Identifier",name:e}),a=(e,t,r)=>({type:"VariableDeclaration",kind:e,declarations:[{type:"VariableDeclarator",id:i(t),init:r}]}),u=(e,t)=>{const r="hoistSeq"+n++;return e.push(a("const",r,t)),i(r)},l=e=>!s(e),h=(e,t)=>{if(r||!e||"object"!=typeof e)return e;switch(e.type){case"Identifier":case"Literal":case"ThisExpression":return e;case"MemberExpression":{const r=h(e.object,t),n=e.computed?h(e.property,t):e.property;return{...e,object:r,property:n}}case"CallExpression":{const r=e.arguments.map(e=>h(e,t));if("Identifier"===e.callee.type)for(let n=0;nh(e,t))};case"UpdateExpression":{if("Identifier"!==e.argument.type)return r=!0,e;if(e.prefix)return t.push({type:"ExpressionStatement",expression:e}),u(t,e.argument);const n=u(t,e.argument);return t.push({type:"ExpressionStatement",expression:e}),n}case"AssignmentExpression":{if("Identifier"!==e.left.type)return r=!0,e;const n=h(e.right,t);return t.push({type:"ExpressionStatement",expression:{...e,right:n}}),u(t,e.left)}case"SequenceExpression":for(let r=0;r({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:i(e),right:t}});return o.push(d(s,c)),u.push(d(s,p)),t.push({type:"IfStatement",test:r,consequent:{type:"BlockStatement",body:o},alternate:{type:"BlockStatement",body:u}}),i(s)}case"LogicalExpression":{if(!l(e.right))return{...e,left:h(e.left,t)};const r=h(e.left,t),s="hoistSeq"+n++;t.push(a("let",s,r));const o=[],u=h(e.right,o);return o.push({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:i(s),right:u}}),t.push({type:"IfStatement",test:"&&"===e.operator?i(s):{type:"UnaryExpression",operator:"!",prefix:!0,argument:i(s)},consequent:{type:"BlockStatement",body:o},alternate:null}),i(s)}default:return r=!0,e}};switch(e.type){case"ExpressionStatement":{const r=e.expression;if("AssignmentExpression"===r.type&&"Identifier"===r.left.type){const e=h(r.right,t);t.push({type:"ExpressionStatement",expression:{...r,right:e}})}else{const e=h(r,t);"UpdateExpression"!==e.type&&"AssignmentExpression"!==e.type||t.push({type:"ExpressionStatement",expression:e})}break}case"VariableDeclaration":for(let r=0;r{if(e&&"object"==typeof e)if(Array.isArray(e))e.forEach(p);else{"string"==typeof e.type&&void 0===e.start&&(e.start=c,e.end=c+1,c+=2);for(const t in e)"loc"!==t&&"range"!==t&&"parent"!==t&&p(e[t])}};return p(t),this.syntheticNodeId=c,t}astStatementWithHoisting(e,t){switch(e.type){case"ExpressionStatement":case"VariableDeclaration":case"ReturnStatement":{if(!h(e))return this.astGeneric(e,t);const r=this.hoistedIndexReads,n=this.hoistedIndexReads=[],s=[];return this.astGeneric(e,s),this.hoistedIndexReads=r,t.push(...n,...s),t}default:return this.astGeneric(e,t)}}astVariableDeclaration(e,t){const n=e.declarations;if(!n||!n[0]||!n[0].init)throw this.astErrorOutput("Unexpected expression",e);const s=[];let i=null;const a=[];let o=[];for(let t=0;t0&&a.push(o.join(",")),s.push(a.join(";")),t.push(s.join("")),t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchCaseConsequent(e,t){const r=[];for(let t=0;t{if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return e.some(t);if("BreakStatement"===e.type)return!0;if("ForStatement"===e.type||"WhileStatement"===e.type||"DoWhileStatement"===e.type||"SwitchStatement"===e.type)return!1;for(const r in e)if("loc"!==r&&"range"!==r&&"parent"!==r&&t(e[r]))return!0;return!1};if(t(r[e]))throw this.astErrorOutput("break inside a switch case is only supported as the case terminator",r[e])}for(let e=0;er+1){u=!0,this.astSwitchCaseConsequent(n[r].consequent,o);continue}t.push(" else {\n")}this.astSwitchCaseConsequent(n[r].consequent,t),t.push("\n}")}return u&&(t.push(" else {"),t.push(o.join("")),t.push("}")),t}astThisExpression(e,t){return t.push("this"),t}astMemberExpression(e,t){const{property:n,name:s,signature:i,origin:a,type:o,xProperty:u,yProperty:l,zProperty:h}=this.getMemberExpressionDetails(e);switch(i){case"value.thread.value":case"this.thread.value":if("x"!==s&&"y"!==s&&"z"!==s)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`threadId.${s}`),t;case"this.output.value":if(this.dynamicOutput)switch(s){case"x":this.isState("casting-to-float")?t.push("float(uOutputDim.x)"):t.push("uOutputDim.x");break;case"y":this.isState("casting-to-float")?t.push("float(uOutputDim.y)"):t.push("uOutputDim.y");break;case"z":this.isState("casting-to-float")?t.push("float(uOutputDim.z)"):t.push("uOutputDim.z");break;default:throw this.astErrorOutput("Unexpected expression",e)}else switch(s){case"x":this.isState("casting-to-integer")?t.push(this.output[0]):t.push(this.output[0],".0");break;case"y":this.isState("casting-to-integer")?t.push(this.output[1]):t.push(this.output[1],".0");break;case"z":this.isState("casting-to-integer")?t.push(this.output[2]):t.push(this.output[2],".0");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if("Math"===a)return t.push(Math[s]),t;const i=r.sanitizeName(s);switch(n){case"r":return t.push(`user_${i}.r`),t;case"g":return t.push(`user_${i}.g`),t;case"b":return t.push(`user_${i}.b`),t;case"a":return t.push(`user_${i}.a`),t}break;case"this.constants.value":if(void 0===u)switch(o){case"Array(2)":case"Array(3)":case"Array(4)":return t.push(`constants_${r.sanitizeName(s)}`),t}case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":case"this.constants.value[][][][]":break;case"fn()[]":return this.astCallExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;case"fn()[][]":{const r=e.object.property,n=e.property,s=c[this.getType(e.object.object)],i=e=>"LiteralInteger"===this.getType(e);return!s||i(r)&&i(n)?(this.astCallExpression(e.object.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(r)),t.push("]"),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t):(t.push(`getMatrix${s}(`),this.astCallExpression(e.object.object,t),t.push(", "),t.push(this.memberExpressionPropertyMarkup(r)),t.push(", "),t.push(this.memberExpressionPropertyMarkup(n)),t.push(")"),t)}case"[][]":return this.astArrayExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;default:throw this.astErrorOutput("Unexpected expression",e)}if(!1===e.computed)switch(o){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${a}_${r.sanitizeName(s)}`),t}const p=`${a}_${r.sanitizeName(s)}`;switch(o){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(u)),t.push("]");break;case"HTMLImageArray":t.push(`getImage3D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":t.push(`getVec4FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if("single"===this.precision)t.push(`getMemoryOptimized32(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");else{const e="user"===a?this.lookupFunctionArgumentBitRatio(this.name,s):this.constantBitRatios[s];switch(e){case 1:t.push(`get8(${p}, ${p}Size, ${p}Dim, `);break;case 2:t.push(`get16(${p}, ${p}Size, ${p}Dim, `);break;case 4:case 0:t.push(`get32(${p}, ${p}Size, ${p}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${e}`)}this.memberExpressionXYZ(u,l,h,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`${p}[${this.memberExpressionPropertyMarkup(l)}]`),l&&t.push(`[${this.memberExpressionPropertyMarkup(u)}]`);break;default:throw new Error(`unhandled member expression "${o}"`)}return t}astCallExpression(e,t){if(!e.callee)throw this.astErrorOutput("Unknown CallExpression",e);let n=null;const s=this.isAstMathFunction(e);if(n=s||e.callee.object&&"ThisExpression"===e.callee.object.type?e.callee.property.name:"SequenceExpression"!==e.callee.type||"Literal"!==e.callee.expressions[0].type||isNaN(e.callee.expressions[0].raw)?e.callee.name:e.callee.expressions[1].property.name,!n)throw this.astErrorOutput("Unhandled function, couldn't find name",e);switch(n){case"pow":n="_pow";break;case"round":n="_round"}if(this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n),"random"===n&&this.plugins&&this.plugins.length>0)for(let e=0;e0&&t.push(", "),"Integer"===s)this.castValueToFloat(n,t);else this.astGeneric(n,t)}else{const s=this.lookupFunctionArgumentTypes(n)||[];for(let i=0;i0&&t.push(", ");const u=this.getType(a);switch(o||(this.triggerImplyArgumentType(n,i,u,this),o=u),u){case"Boolean":this.astGeneric(a,t);continue;case"Number":case"Float":if("Integer"===o){t.push("int("),this.astGeneric(a,t),t.push(")");continue}if("Number"===o||"Float"===o){this.astGeneric(a,t);continue}if("LiteralInteger"===o){this.castLiteralToFloat(a,t);continue}break;case"Integer":if("Number"===o||"Float"===o){t.push("float("),this.astGeneric(a,t),t.push(")");continue}if("Integer"===o){this.astGeneric(a,t);continue}break;case"LiteralInteger":if("Integer"===o){this.castLiteralToInteger(a,t);continue}if("Number"===o||"Float"===o){this.castLiteralToFloat(a,t);continue}if("LiteralInteger"===o){this.astGeneric(a,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(o===u){if("Identifier"===a.type)t.push(`user_${r.sanitizeName(a.name)}`);else{if("ArrayExpression"!==a.type&&"MemberExpression"!==a.type&&"CallExpression"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.astGeneric(a,t)}continue}break;case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(o===u){if("Identifier"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.triggerImplyArgumentBitRatio(this.name,a.name,n,i);const s=r.sanitizeName(a.name);t.push(`user_${s},user_${s}Size,user_${s}Dim`);continue}}throw this.astErrorOutput(`Unhandled argument combination of ${u} and ${o} for argument named "${a.name}"`,e)}}return t.push(")"),t}astArrayExpression(e,t){const r=this.getType(e),n=e.elements.length;switch(r){case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`mat${n}(`);break;default:t.push(`vec${n}(`)}for(let r=0;r0&&t.push(", ");const n=e.elements[r];this.astGeneric(n,t)}return t.push(")"),t}memberExpressionXYZ(e,t,r,n){return r?n.push(this.memberExpressionPropertyMarkup(r),", "):n.push("0, "),t?n.push(this.memberExpressionPropertyMarkup(t),", "):n.push("0, "),n.push(this.memberExpressionPropertyMarkup(e)),n}memberExpressionPropertyMarkup(e){if(!e)throw new Error("Property not set");const t=[];switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;default:this.astGeneric(e,t)}const n=t.join("");if(this.hoistedIndexReads&&/\b\w+\((user_|constants_)\w+, \1\w+Size/.test(n)){const e=`hoisted_${this.hoistedIndexReads.length}_${r.sanitizeName(this.name)}`,t=n.startsWith("int(");return this.hoistedIndexReads.push(`${t?"int":"float"} ${e}=${n};\n`),e}return n}}}}),M=e((e,t)=>{t.exports={name:"math-random-uniformly-distributed",onBeforeRun:e=>{if(null===e.randomSeed||void 0===e.randomSeed)return e.setUniform1f("randomSeed1",Math.random()),void e.setUniform1f("randomSeed2",Math.random());e._mathRandomGenerator&&e._mathRandomGeneratorSeed===e.randomSeed||(e._mathRandomGenerator=function(e){let t=e>>>0;return function(){t=t+1831565813>>>0;let e=t;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296}}(e.randomSeed),e._mathRandomGeneratorSeed=e.randomSeed),e.setUniform1f("randomSeed1",e._mathRandomGenerator()),e.setUniform1f("randomSeed2",e._mathRandomGenerator())},functionMatch:"Math.random()",functionReplace:"nrand(vTexCoord)",functionReturnType:"Number",source:"// https://www.shadertoy.com/view/4t2SDh\n//note: uniformly distributed, normalized rand, [0,1]\nhighp float randomSeedShift = 1.0;\nhighp float slide = 1.0;\nuniform highp float randomSeed1;\nuniform highp float randomSeed2;\n\nhighp float nrand(highp vec2 n) {\n highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453);\n randomSeedShift = result;\n if (randomSeedShift > 0.5) {\n slide += 0.00009; \n } else {\n slide += 0.0009;\n }\n return result;\n}"}}),G=e((e,t)=>{t.exports={fragmentShader:`__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nvarying vec2 vTexCoord;\n\nfloat acosh(float x) {\n return log(x + sqrt(x * x - 1.0));\n}\n\nfloat sinh(float x) {\n return (pow(${Math.E}, x) - pow(${Math.E}, -x)) / 2.0;\n}\n\nfloat asinh(float x) {\n return log(x + sqrt(x * x + 1.0));\n}\n\nfloat atan2(float v1, float v2) {\n if (v2 == 0.0) {\n if (v1 == 0.0) return 0.0;\n if (v1 > 0.0) return 1.5707963267948966;\n if (v1 < 0.0) return -1.5707963267948966;\n }\n return atan(v1, v2);\n}\n\nfloat atanh(float x) {\n x = (x + 1.0) / (x - 1.0);\n if (x < 0.0) {\n return 0.5 * log(-x);\n }\n return 0.5 * log(x);\n}\n\nfloat cbrt(float x) {\n if (x >= 0.0) {\n return pow(x, 1.0 / 3.0);\n } else {\n return -pow(x, 1.0 / 3.0);\n }\n}\n\nfloat cosh(float x) {\n return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0; \n}\n\nfloat expm1(float x) {\n return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n return x;\n}\n\nfloat imul(float v1, float v2) {\n return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n if (v2 == 0.0) return 1.0;\n return pow(v1, v2);\n}\n\nfloat tanh(float x) {\n float e = exp(2.0 * x);\n return (e - 1.0) / (e + 1.0);\n}\n\nfloat trunc(float x) {\n if (x >= 0.0) {\n return floor(x); \n } else {\n return ceil(x);\n }\n}\n\nvec4 _round(vec4 x) {\n return floor(x + 0.5);\n}\n\nfloat _round(float x) {\n return floor(x + 0.5);\n}\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n // ~a is identically -a - 1 in two's complement, for every value including\n // negatives. The previous bit-by-bit loop only worked for a >= 0, where it\n // leaned on 32-bit overflow wrapping to reach the negative answer; given a\n // negative input it computed ~abs(a), so ~(-1) gave -2 and ~~x never\n // returned x.\n return -a - 1;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\n// _pow2 is defined further down, alongside encode32/decode32\nfloat _pow2(float e);\nint bitwiseSignedRightShift(int num, int shifts) {\n // pow(2.0, n) is approximate on many GPUs, and landing 1 ulp high makes the\n // division fall just under a whole number, which floor() then rounds away:\n // 2 >> 1 came out 0, 8 >> 1 came out 3. Only exact left operands were\n // affected, odd ones having enough slack to survive. _pow2 is exact.\n return int(floor(float(num) / _pow2(float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x / y));\n}\n\n// GLSL ES 1.00 accepts only a constant or a loop symbol inside an index\n// expression, so m[y][x] does not compile when y and x come from kernel\n// arguments -- the error is "Index expression can only contain const or loop\n// symbols". Loop counters are legal indices, so walk the matrix with them\n// instead. These are 2x2 to 4x4, so it costs at most sixteen comparisons.\nfloat getMatrix2(mat2 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 2; i++) {\n for (int j = 0; j < 2; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix3(mat3 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 3; i++) {\n for (int j = 0; j < 3; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix4(mat4 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 4; i++) {\n for (int j = 0; j < 4; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\n// Exact powers of two built from exact constant multiplies: exp2/log2/pow\n// are approximate on some GPUs (notably Apple silicon), and 1-2 ulp there\n// corrupts the packed bytes (#659)\nfloat _pow2(float e) {\n float r = 1.0;\n float a = abs(e);\n bool n = e < 0.0;\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 32.0) { r *= n ? 2.3283064365386963e-10 : 4294967296.0; a -= 32.0; }\n if (a >= 16.0) { r *= n ? 0.0000152587890625 : 65536.0; a -= 16.0; }\n if (a >= 8.0) { r *= n ? 0.00390625 : 256.0; a -= 8.0; }\n if (a >= 4.0) { r *= n ? 0.0625 : 16.0; a -= 4.0; }\n if (a >= 2.0) { r *= n ? 0.25 : 4.0; a -= 2.0; }\n if (a >= 1.0) { r *= n ? 0.5 : 2.0; }\n return r;\n}\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = _pow2(_round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * _pow2(_round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\n return 0.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n if (channel == 0) return texel.r * 255.0;\n if (channel == 1) return texel.g * 255.0;\n if (channel == 2) return texel.b * 255.0;\n if (channel == 3) return texel.a * 255.0;\n return 0.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n float p2 = _pow2(exponent);\n // approximate log2 can land one off; correct by direct comparison\n if (p2 > value) { exponent -= 1.0; p2 *= 0.5; }\n else if (p2 * 2.0 <= value) { exponent += 1.0; p2 *= 2.0; }\n\n mantissa = value / p2 - 1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return texel.r;\n if (channel == 1) return texel.g;\n if (channel == 2) return texel.b;\n if (channel == 3) return texel.a;\n return 0.0;\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture2D(tex, st / vec2(texSize));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n \n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nvoid color(sampler2D image) {\n actualColor = texture2D(image, vTexCoord);\n}\n\nfloat modulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -mod(number, divisor);\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}`}}),C=e((e,t)=>{t.exports={vertexShader:"__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nattribute vec2 aPos;\nattribute vec2 aTexCoord;\n\nvarying vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"}}),N=e((e,t)=>{function r(e,t={}){const{contextName:r="gl",throwGetError:a,useTrackablePrimitives:o,recording:u=[],variables:l={},onReadPixels:h,onUnrecognizedArgumentLookup:c}=t,p=new Proxy(e,{get:function(t,p){switch(p){case"addComment":return w;case"checkThrowError":return E;case"getReadPixelsVariableName":return f;case"insertVariable":return b;case"reset":return x;case"setIndent":return S;case"toString":return y;case"getContextVariableName":return v}return"function"==typeof e[p]?function(){switch(p){case"getError":return a?u.push(`${g}if (${r}.getError() !== ${r}.NONE) throw new Error('error');`):u.push(`${g}${r}.getError();`),e.getError();case"getExtension":{const t=`${r}Variables${d.length}`;u.push(`${g}const ${t} = ${r}.getExtension('${arguments[0]}');`);const s=e.getExtension(arguments[0]);if(s&&"object"==typeof s){const e=n(s,{getEntity:T,useTrackablePrimitives:o,recording:u,contextName:t,contextVariables:d,variables:l,indent:g,onUnrecognizedArgumentLookup:c});return d.push(e),e}return d.push(null),s}case"readPixels":const t=d.indexOf(arguments[6]);let i;if(-1===t){const e=function(e){if(l)for(const t in l)if(l[t]===e)return t;return null}(arguments[6]);e?(i=e,u.push(`${g}${e}`)):(i=`${r}Variable${d.length}`,d.push(arguments[6]),u.push(`${g}const ${i} = new ${arguments[6].constructor.name}(${arguments[6].length});`))}else i=`${r}Variable${t}`;f=i;const p=[arguments[0],arguments[1],arguments[2],arguments[3],T(arguments[4]),T(arguments[5]),i];return u.push(`${g}${r}.readPixels(${p.join(", ")});`),h&&h(i,p),e.readPixels.apply(e,arguments);case"drawBuffers":return u.push(`${g}${r}.drawBuffers([${s(arguments[0],{contextName:r,contextVariables:d,getEntity:T,addVariable:A,variables:l,onUnrecognizedArgumentLookup:c})}]);`),e.drawBuffers(arguments[0])}let t=e[p].apply(e,arguments);switch(typeof t){case"undefined":return void u.push(`${g}${_(p,arguments)};`);case"number":case"boolean":if(o&&-1===d.indexOf(i(t))){u.push(`${g}const ${r}Variable${d.length} = ${_(p,arguments)};`),d.push(t=i(t));break}default:null===t?u.push(`${_(p,arguments)};`):u.push(`${g}const ${r}Variable${d.length} = ${_(p,arguments)};`),d.push(t)}return t}:(m[e[p]]=p,e[p])}}),d=[],m={};let f,g="";return p;function y(){return u.join("\n")}function x(){for(;u.length>0;)u.pop()}function b(e,t){l[e]=t}function T(e){const t=m[e];return t?r+"."+t:e}function S(e){g=" ".repeat(e)}function A(e,t){const n=`${r}Variable${d.length}`;return u.push(`${g}const ${n} = ${t};`),d.push(e),n}function w(e){u.push(`${g}// ${e}`)}function E(){u.push(`${g}(() => {\n${g}const error = ${r}.getError();\n${g}if (error !== ${r}.NONE) {\n${g} const names = Object.getOwnPropertyNames(gl);\n${g} for (let i = 0; i < names.length; i++) {\n${g} const name = names[i];\n${g} if (${r}[name] === error) {\n${g} throw new Error('${r} threw ' + name);\n${g} }\n${g} }\n${g}}\n${g}})();`)}function _(e,t){return`${r}.${e}(${s(t,{contextName:r,contextVariables:d,getEntity:T,addVariable:A,variables:l,onUnrecognizedArgumentLookup:c})})`}function v(e){const t=d.indexOf(e);return-1!==t?`${r}Variable${t}`:null}}function n(e,t){const r=new Proxy(e,{get:function(t,r){return"function"==typeof t[r]?function(){if("drawBuffersWEBGL"===r)return h.push(`${p}${a}.drawBuffersWEBGL([${s(arguments[0],{contextName:a,contextVariables:o,getEntity:m,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})}]);`),e.drawBuffersWEBGL(arguments[0]);let t=e[r].apply(e,arguments);switch(typeof t){case"undefined":return void h.push(`${p}${f(r,arguments)};`);case"number":case"boolean":l&&-1===o.indexOf(i(t))?(h.push(`${p}const ${a}Variable${o.length} = ${f(r,arguments)};`),o.push(t=i(t))):(h.push(`${p}const ${a}Variable${o.length} = ${f(r,arguments)};`),o.push(t));break;default:null===t?h.push(`${f(r,arguments)};`):h.push(`${p}const ${a}Variable${o.length} = ${f(r,arguments)};`),o.push(t)}return t}:(n[e[r]]=r,e[r])}}),n={},{contextName:a,contextVariables:o,getEntity:u,useTrackablePrimitives:l,recording:h,variables:c,indent:p,onUnrecognizedArgumentLookup:d}=t;return r;function m(e){return n.hasOwnProperty(e)?`${a}.${n[e]}`:u(e)}function f(e,t){return`${a}.${e}(${s(t,{contextName:a,contextVariables:o,getEntity:m,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})})`}function g(e,t){const r=`${a}Variable${o.length}`;return o.push(e),h.push(`${p}const ${r} = ${t};`),r}}function s(e,t){const{variables:r,onUnrecognizedArgumentLookup:n}=t;return Array.from(e).map(e=>{const s=function(e){if(r)for(const t in r)if(r.hasOwnProperty(t)&&r[t]===e)return t;return n?n(e):null}(e);return s||function(e,t){const{contextName:r,contextVariables:n,getEntity:s,addVariable:i,onUnrecognizedArgumentLookup:a}=t;if(void 0===e)return"undefined";if(null===e)return"null";const o=n.indexOf(e);if(o>-1)return`${r}Variable${o}`;switch(e.constructor.name){case"String":const t=/\n/.test(e),r=/'/.test(e),n=/"/.test(e);return t?"`"+e+"`":r&&!n?'"'+e+'"':"'"+e+"'";case"Number":case"Boolean":return s(e);case"Array":return i(e,`new ${e.constructor.name}([${Array.from(e).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return i(e,`new ${e.constructor.name}(${JSON.stringify(Array.from(e))})`);default:if(a){const t=a(e);if(t)return t}throw new Error(`unrecognized argument type ${e.constructor.name}`)}}(e,t)}).join(", ")}function i(e){return new e.constructor(e)}void 0!==t&&(t.exports={glWiretap:r,glExtensionWiretap:n}),"undefined"!=typeof window&&(r.glExtensionWiretap=n,window.glWiretap=r)}),O=e((e,t)=>{const{glWiretap:r}=N(),{utils:n}=i();function s(e){let t=e.toString().replace(/^function /,"");const r=t.indexOf("=>");if(-1!==r&&!/[{]|\bfunction\b/.test(t.slice(0,r))){const e=t.slice(0,r).trim(),n=t.slice(r+2).trim();t=n.startsWith("{")?`${e} ${n}`:`${e} { return ${n}; }`}return t.replace(/utils[.]/g,"/*utils.*/")}function a(e,t){const r="single"===t.precision?e:`new Float32Array(${e}.buffer)`;return t.output[2]?`renderOutput(${r}, ${t.output[0]}, ${t.output[1]}, ${t.output[2]})`:t.output[1]?`renderOutput(${r}, ${t.output[0]}, ${t.output[1]})`:`renderOutput(${r}, ${t.output[0]})`}function o(e,t){const r=e.toArray.toString(),s=!/^function/.test(r);return`() => {\n function framebuffer() { return getReadFramebuffer(); };\n ${n.flattenFunctionToString(`${s?"function ":""}${r}`,{findDependency:(t,r)=>{if("utils"===t)return`const ${r} = ${n[r].toString()};`;if("this"===t)return"framebuffer"===r?"":`${s?"function ":""}${e[r].toString()}`;throw new Error("unhandled fromObject")},thisLookup:(r,n)=>{if("texture"===r)return t;if("context"===r)return n?null:"gl";if(e.hasOwnProperty(r))return JSON.stringify(e[r]);throw new Error(`unhandled thisLookup ${r}`)}})}\n return toArray();\n }`}function u(e,t,r,n,s){if(null===e)return null;if(null===t)return null;switch(typeof e){case"boolean":case"number":return null}if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement)for(let s=0;s{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}}):null;const c=[],p=[],d=r(i.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if(M.subKernels){if(m){const t=M.subKernels[f++].property;p.push(` result${isNaN(t)?"."+t:`[${t}]`} = ${a(e,M)};`)}else p.push(` const result = { result: ${a(e,M)} };`),m=!0;f===M.subKernels.length&&p.push(" return result;")}else e?p.push(` return ${a(e,M)};`):p.push(" return null;")},onUnrecognizedArgumentLookup:e=>{const t=u(e,M.kernelArguments,[],d,c);if(t)return t;const r=u(e,M.kernelConstants,A?Object.keys(A).map(e=>A[e]):[],d,c);return r||null}});let m=!1,f=0;const{source:g,canvas:y,output:x,pipeline:b,graphical:T,loopMaxIterations:S,constants:A,optimizeFloatMemory:w,precision:E,fixIntegerDivisionAccuracy:_,functions:v,nativeFunctions:I,subKernels:$,immutable:D,argumentTypes:F,constantTypes:L,kernelArguments:R,kernelConstants:k,tactic:z}=i,M=new e(g,{canvas:y,context:d,checkContext:!1,output:x,pipeline:b,graphical:T,loopMaxIterations:S,constants:A,optimizeFloatMemory:w,precision:E,fixIntegerDivisionAccuracy:_,functions:v,nativeFunctions:I,subKernels:$,immutable:D,argumentTypes:F,constantTypes:L,tactic:z});let G=[];if(d.setIndent(2),M.build.apply(M,t),G.push(d.toString()),d.reset(),M.kernelArguments.forEach((e,r)=>{switch(e.type){case"Integer":case"Boolean":case"Number":case"Float":case"Array":case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":case"Input":d.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let n=0;ne.varName).join(", ")}) {`),d.setIndent(4),M.run.apply(M,t),M.renderKernels?M.renderKernels():M.renderOutput&&M.renderOutput(),G.push(" /** start setup uploads for kernel values **/"),M.kernelArguments.forEach(e=>{G.push(" "+e.getStringValueHandler().split("\n").join("\n "))}),G.push(" /** end setup uploads for kernel values **/"),G.push(d.toString()),M.renderOutput===M.renderTexture)if(d.reset(),M.renderKernels){const e=M.renderKernels(),t=d.getContextVariableName(M.texture.texture);G.push(` return {\n result: {\n texture: ${t},\n type: '${e.result.type}',\n toArray: ${o(e.result,t)}\n },`);const{subKernels:r,mappedTextures:n}=M;for(let t=0;t"utils"===e?`const ${t} = ${n[t].toString()};`:null,thisLookup:t=>{if("context"===t)return null;if(e.hasOwnProperty(t))return JSON.stringify(e[t]);throw new Error(`unhandled thisLookup ${t}`)}})}(M)),G.push(" innerKernel.getPixels = getPixels;")),G.push(" return innerKernel;");let C=[];return k.forEach(e=>{C.push(`${e.getStringValueHandler()}`)}),`function kernel(settings) {\n const { context, constants } = settings;\n ${C.join("")}\n ${l||""}\n${G.join("\n")}\n}`}}}),V=e((e,t)=>{t.exports={KernelValue:class{constructor(e,t){const{name:r,kernel:n,context:s,checkContext:i,onRequestContextHandle:a,onUpdateValueMismatch:o,origin:u,strictIntegers:l,type:h,tactic:c}=t;if(!r)throw new Error("name not set");if(!h)throw new Error("type not set");if(!u)throw new Error("origin not set");if("user"!==u&&"constants"!==u)throw new Error(`origin must be "user" or "constants" value is "${u}"`);if(!a)throw new Error("onRequestContextHandle is not set");this.name=r,this.origin=u,this.tactic=c,this.varName="constants"===u?`constants.${r}`:r,this.kernel=n,this.strictIntegers=l,this.type=e.type||h,this.size=e.size||null,this.index=null,this.context=s,this.checkContext=null==i||i,this.contextHandle=null,this.onRequestContextHandle=a,this.onUpdateValueMismatch=o,this.forceUploadEachRun=null}get id(){return`${this.origin}_${name}`}getSource(){throw new Error(`"getSource" not defined on ${this.constructor.name}`)}updateValue(e){throw new Error(`"updateValue" not defined on ${this.constructor.name}`)}}}}),K=e((e,t)=>{const{utils:r}=i(),{KernelValue:n}=V();t.exports={WebGLKernelValue:class extends n{constructor(e,t){super(e,t),this.dimensionsId=null,this.sizeId=null,this.initialValueConstructor=e.constructor,this.onRequestTexture=t.onRequestTexture,this.onRequestIndex=t.onRequestIndex,this.uploadValue=null,this.textureSize=null,this.bitRatio=null,this.prevArg=null}get id(){return`${this.origin}_${r.sanitizeName(this.name)}`}setup(){}getTransferArrayType(e){if(Array.isArray(e[0]))return this.getTransferArrayType(e[0]);switch(e.constructor){case Array:case Int32Array:case Int16Array:case Int8Array:return Float32Array;case Uint8ClampedArray:case Uint8Array:case Uint16Array:case Uint32Array:case Float32Array:case Float64Array:return e.constructor}return console.warn("Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros"),e.constructor}getStringValueHandler(){throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`)}getVariablePrecisionString(){return this.kernel.getVariablePrecisionString(this.textureSize||void 0,this.tactic||void 0)}destroy(){}}}}),U=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValue:n}=K();t.exports={WebGLKernelValueBoolean:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const bool ${this.id} = ${e};\n`:`uniform bool ${this.id};\n`}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),P=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValue:n}=K();t.exports={WebGLKernelValueFloat:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?Number.isInteger(e)?`const float ${this.id} = ${e}.0;\n`:`const float ${this.id} = ${e};\n`:`uniform float ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1f(this.id,this.uploadValue=e)}}}}),B=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValue:n}=K();t.exports={WebGLKernelValueInteger:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?`const int ${this.id} = ${parseInt(e)};\n`:`uniform int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),W=e((e,t)=>{const{WebGLKernelValue:r}=K(),{Input:s}=n();t.exports={WebGLKernelArray:class extends r{checkSize(e,t){if(!this.kernel.validate)return;const{maxTextureSize:r}=this.kernel.constructor.features;if(e>r||t>r)throw e>t?new Error(`Argument texture width of ${e} larger than maximum size of ${r} for your GPU`):e{const{utils:r}=i(),{WebGLKernelArray:n}=W();function s(e){return{width:e.width>0?e.width:e.videoWidth,height:e.height>0?e.height:e.videoHeight}}t.exports={WebGLKernelValueHTMLImage:class extends n{constructor(e,t){super(e,t);const{width:r,height:n}=s(e);this.checkSize(r,n),this.dimensions=[r,n,1],this.textureSize=[r,n],this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue=e),this.kernel.setUniform1i(this.id,this.index)}},mediaSize:s}}),X=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueHTMLImage:n,mediaSize:s}=j();t.exports={WebGLKernelValueDynamicHTMLImage:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:r}=s(e);this.checkSize(t,r),this.dimensions=[t,r,1],this.textureSize=[t,r],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),H=e((e,t)=>{const{WebGLKernelValueHTMLImage:r}=j();t.exports={WebGLKernelValueHTMLVideo:class extends r{}}}),q=e((e,t)=>{const{WebGLKernelValueDynamicHTMLImage:r}=X();t.exports={WebGLKernelValueDynamicHTMLVideo:class extends r{}}}),Y=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueSingleInput:class extends n{constructor(e,t){super(e,t),this.bitRatio=4;let[n,s,i]=e.size;this.dimensions=new Int32Array([n||1,s||1,i||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}.value, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Z=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleInput:n}=Y();t.exports={WebGLKernelValueDynamicSingleInput:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,s]=e.size;this.dimensions=new Int32Array([t||1,n||1,s||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),J=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueUnsignedInput:class extends n{constructor(e,t){super(e,t),this.bitRatio=this.getBitRatio(e);const[n,s,i]=e.size;this.dimensions=new Int32Array([n||1,s||1,i||1]),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]),this.TranserArrayType=this.getTransferArrayType(e.value),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return r.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}.value, preUploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(value.constructor);const{context:t}=this;r.flattenTo(e.value,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Q=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedInput:n}=J();t.exports={WebGLKernelValueDynamicUnsignedInput:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,s]=e.size;this.dimensions=new Int32Array([t||1,n||1,s||1]),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]);const i=this.getTransferArrayType(e.value);this.preUploadValue=new i(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ee=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W(),s="Source and destination textures are the same. Use immutable = true and manually cleanup kernel output texture memory with texture.delete()";t.exports={WebGLKernelValueMemoryOptimizedNumberTexture:class extends n{constructor(e,t){super(e,t);const[r,n]=e.size;this.checkSize(r,n),this.dimensions=e.dimensions,this.textureSize=e.size,this.uploadValue=e.texture,this.forceUploadEachRun=!0}setup(){this.setupTexture()}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{kernel:t,context:r}=this;if(t.pipeline)if(t.immutable)t.updateTextureArgumentRefs(this,e);else{if(t.texture&&t.texture.texture===e.texture)throw new Error(s);if(t.mappedTextures){const{mappedTextures:r}=t;for(let t=0;t{const{utils:r}=i(),{WebGLKernelValueMemoryOptimizedNumberTexture:n}=ee();t.exports={WebGLKernelValueDynamicMemoryOptimizedNumberTexture:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),re=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W(),{sameError:s}=ee();t.exports={WebGLKernelValueNumberTexture:class extends n{constructor(e,t){super(e,t);const[r,n]=e.size;this.checkSize(r,n);const{size:s,dimensions:i}=e;this.bitRatio=this.getBitRatio(e),this.dimensions=i,this.textureSize=s,this.uploadValue=e.texture,this.forceUploadEachRun=!0}setup(){this.setupTexture()}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{kernel:t,context:r}=this;if(t.pipeline)if(t.immutable)t.updateTextureArgumentRefs(this,e);else{if(t.texture&&t.texture.texture===e.texture)throw new Error(s);if(t.mappedTextures){const{mappedTextures:r}=t;for(let t=0;t{const{utils:r}=i(),{WebGLKernelValueNumberTexture:n}=re();t.exports={WebGLKernelValueDynamicNumberTexture:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),se=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueSingleArray:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ie=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray:n}=se();t.exports={WebGLKernelValueDynamicSingleArray:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ae=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueSingleArray1DI:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],1,1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flatten2dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),oe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray1DI:n}=ae();t.exports={WebGLKernelValueDynamicSingleArray1DI:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ue=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueSingleArray2DI:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flatten3dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),le=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray2DI:n}=ue();t.exports={WebGLKernelValueDynamicSingleArray2DI:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),he=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueSingleArray3DI:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],t[3]]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flatten4dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ce=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray3DI:n}=he();t.exports={WebGLKernelValueDynamicSingleArray3DI:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),pe=e((e,t)=>{const{WebGLKernelValue:r}=K();t.exports={WebGLKernelValueArray2:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec2 ${this.id} = vec2(${e[0]},${e[1]});\n`:`uniform vec2 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform2fv(this.id,this.uploadValue=e)}}}}),de=e((e,t)=>{const{WebGLKernelValue:r}=K();t.exports={WebGLKernelValueArray3:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec3 ${this.id} = vec3(${e[0]},${e[1]},${e[2]});\n`:`uniform vec3 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform3fv(this.id,this.uploadValue=e)}}}}),me=e((e,t)=>{const{WebGLKernelValue:r}=K();t.exports={WebGLKernelValueArray4:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec4 ${this.id} = vec4(${e[0]},${e[1]},${e[2]},${e[3]});\n`:`uniform vec4 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform4fv(this.id,this.uploadValue=e)}}}}),fe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueUnsignedArray:class extends n{constructor(e,t){super(e,t),this.bitRatio=this.getBitRatio(e),this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]),this.TranserArrayType=this.getTransferArrayType(e),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return r.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}, preUploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ge=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedArray:n}=fe();t.exports={WebGLKernelValueDynamicUnsignedArray:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]);const t=this.getTransferArrayType(e);this.preUploadValue=new t(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ye=e((e,t)=>{const{WebGLKernelValueBoolean:r}=U(),{WebGLKernelValueFloat:n}=P(),{WebGLKernelValueInteger:s}=B(),{WebGLKernelValueHTMLImage:i}=j(),{WebGLKernelValueDynamicHTMLImage:a}=X(),{WebGLKernelValueHTMLVideo:o}=H(),{WebGLKernelValueDynamicHTMLVideo:u}=q(),{WebGLKernelValueSingleInput:l}=Y(),{WebGLKernelValueDynamicSingleInput:h}=Z(),{WebGLKernelValueUnsignedInput:c}=J(),{WebGLKernelValueDynamicUnsignedInput:p}=Q(),{WebGLKernelValueMemoryOptimizedNumberTexture:d}=ee(),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:m}=te(),{WebGLKernelValueNumberTexture:f}=re(),{WebGLKernelValueDynamicNumberTexture:g}=ne(),{WebGLKernelValueSingleArray:y}=se(),{WebGLKernelValueDynamicSingleArray:x}=ie(),{WebGLKernelValueSingleArray1DI:b}=ae(),{WebGLKernelValueDynamicSingleArray1DI:T}=oe(),{WebGLKernelValueSingleArray2DI:S}=ue(),{WebGLKernelValueDynamicSingleArray2DI:A}=le(),{WebGLKernelValueSingleArray3DI:w}=he(),{WebGLKernelValueDynamicSingleArray3DI:E}=ce(),{WebGLKernelValueArray2:_}=pe(),{WebGLKernelValueArray3:v}=de(),{WebGLKernelValueArray4:I}=me(),{WebGLKernelValueUnsignedArray:$}=fe(),{WebGLKernelValueDynamicUnsignedArray:D}=ge(),F={unsigned:{dynamic:{Boolean:r,Integer:s,Float:n,Array:D,"Array(2)":_,"Array(3)":v,"Array(4)":I,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:p,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:m,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u},static:{Boolean:r,Float:n,Integer:s,Array:$,"Array(2)":_,"Array(3)":v,"Array(4)":I,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:c,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:d,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:!1,HTMLVideo:o}},single:{dynamic:{Boolean:r,Integer:s,Float:n,Array:x,"Array(2)":_,"Array(3)":v,"Array(4)":I,"Array1D(2)":T,"Array1D(3)":T,"Array1D(4)":T,"Array2D(2)":A,"Array2D(3)":A,"Array2D(4)":A,"Array3D(2)":E,"Array3D(3)":E,"Array3D(4)":E,Input:h,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:m,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u},static:{Boolean:r,Float:n,Integer:s,Array:y,"Array(2)":_,"Array(3)":v,"Array(4)":I,"Array1D(2)":b,"Array1D(3)":b,"Array1D(4)":b,"Array2D(2)":S,"Array2D(3)":S,"Array2D(4)":S,"Array3D(2)":w,"Array3D(3)":w,"Array3D(4)":w,Input:l,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:d,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:!1,HTMLVideo:o}}};t.exports={lookupKernelValueType:function(e,t,r,n){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!r)throw new Error("precision missing");n.type&&(e=n.type);const s=F[r][t];if("WebGPUBuffer"===e)throw new Error("this kernel runs on WebGL but received a WebGPU pipeline buffer; await handle.toArray() first, or give this kernel the async contract (asyncMode: true / mode: 'async') so the readback happens for you");if(!1===s[e])return null;if(void 0===s[e])throw new Error(`Could not find a KernelValue for ${e}`);return s[e]},kernelValueMaps:F}}),xe=e((e,t)=>{const{GLKernel:r}=k(),{FunctionBuilder:n}=o(),{WebGLFunctionNode:s}=z(),{utils:a}=i(),u=M(),{fragmentShader:l}=G(),{vertexShader:h}=C(),{glKernelString:c}=O(),{lookupKernelValueType:p}=ye();let d=null,m=null,f=null,g=null,y=null;const x=[u],b=[],T={};t.exports={WebGLKernel:class extends r{static get isSupported(){return null!==d||(this.setupFeatureChecks(),d=this.isContextMatch(f)),d}static setupFeatureChecks(){"undefined"!=typeof document?m=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(m=new OffscreenCanvas(0,0)),m&&(f=m.getContext("webgl"),f||m instanceof OffscreenCanvas||(f=m.getContext("experimental-webgl")),f&&f.getExtension&&(g={OES_texture_float:f.getExtension("OES_texture_float"),OES_texture_float_linear:f.getExtension("OES_texture_float_linear"),OES_element_index_uint:f.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:f.getExtension("WEBGL_draw_buffers")},y=this.getFeatures()))}static isContextMatch(e){return"undefined"!=typeof WebGLRenderingContext&&e instanceof WebGLRenderingContext}static getIsTextureFloat(){return Boolean(g.OES_texture_float)}static getIsDrawBuffers(){return Boolean(g.WEBGL_draw_buffers)}static getChannelCount(){return g.WEBGL_draw_buffers?f.getParameter(g.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return f.getParameter(f.MAX_TEXTURE_SIZE)}static lookupKernelValueType(e,t,r,n){return p(e,t,r,n)}static get testCanvas(){return m}static get testContext(){return f}static get features(){return y}static get fragmentShader(){return l}static get vertexShader(){return h}constructor(e,t){super(e,t),this.program=null,this.pipeline=t.pipeline,this.endianness=a.systemEndianness(),this.extensions={},this.argumentTextureCount=0,this.constantTextureCount=0,this.fragShader=null,this.vertShader=null,this.drawBuffersMap=null,this.maxTexSize=null,this.onRequestSwitchKernel=null,this.texture=null,this.mappedTextures=null,this.mergeSettings(e.settings||t),this.threadDim=null,this.framebuffer=null,this.buffer=null,this.textureCache=[],this.programUniformLocationCache={},this.uniform1fCache={},this.uniform1iCache={},this.uniform2fCache={},this.uniform2fvCache={},this.uniform2ivCache={},this.uniform3fvCache={},this.uniform3ivCache={},this.uniform4fvCache={},this.uniform4ivCache={}}initCanvas(){if("undefined"!=typeof document){const e=document.createElement("canvas");return e.width=2,e.height=2,e}if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(0,0)}initContext(){const e={alpha:!1,depth:!1,antialias:!1};return this.canvas.getContext("webgl",e)||this.canvas.getContext("experimental-webgl",e)}initPlugins(e){const t=[],{source:r}=this;if("string"==typeof r)for(let e=0;ee===n.name)&&t.push(n)}return t}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if(!0===this.optimizeFloatMemory&&!t.isTextureFloat)throw new Error("Float textures are not supported");if("single"===this.precision&&!t.isFloatRead)throw new Error("Single precision not supported");if(this.graphical||null!==this.precision||(this.precision=t.isTextureFloat&&t.isFloatRead?"single":"unsigned"),this.subKernels&&this.subKernels.length>0&&!this.extensions.WEBGL_draw_buffers)throw new Error("could not instantiate draw buffers extension");if(null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);switch(t){case"Array":this.output=a.getDimensions(t);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=e[0].output;break;default:throw new Error("Auto output not supported for input type: "+t)}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"precision"===this.precision&&(this.precision="unsigned",console.warn("Cannot use graphical mode and single precision at the same time")),void(this.texSize=a.clone(this.output))}null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}updateMaxTexSize(){const{texSize:e,canvas:t}=this;if(null===this.maxTexSize){let r=b.indexOf(t);-1===r&&(r=b.length,b.push(t),T[r]=[e[0],e[1]]),this.maxTexSize=T[r]}this.maxTexSize[0]this.argumentNames.length)throw new Error("too many arguments for kernel");const{context:r}=this;let n=0;const s=()=>this.createTexture(),i=()=>this.constantTextureCount+n++,o=e=>{this.switchKernels({type:"argumentMismatch",needed:e})},u=()=>r.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++;for(let n=0;nthis.createTexture(),onRequestIndex:()=>n++,onRequestContextHandle:()=>t.TEXTURE0+this.constantTextureCount++});this.constantBitRatios[s]=l.bitRatio,this.kernelConstants.push(l),l.setup(),l.forceUploadEachRun&&this.forceUploadKernelConstants.push(l)}}build(){if(this.built)return;if(this.initExtensions(),this.validateSettings(arguments),this.setupConstants(arguments),this.fallbackRequested)return;if(this.setupArguments(arguments),this.fallbackRequested)return;this.updateMaxTexSize(),this.translateSource();const e=this.pickRenderStrategy(arguments);if(e)return e;const{texSize:t,context:r,canvas:n}=this;r.enable(r.SCISSOR_TEST),this.pipeline&&this.precision,r.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]),n.width=this.maxTexSize[0],n.height=this.maxTexSize[1];const s=this.threadDim=Array.from(this.output);for(;s.length<3;)s.push(1);const i=this.getVertexShader(arguments),a=r.createShader(r.VERTEX_SHADER);r.shaderSource(a,i),r.compileShader(a),this.vertShader=a;const o=this.getFragmentShader(arguments),u=r.createShader(r.FRAGMENT_SHADER);if(r.shaderSource(u,o),r.compileShader(u),this.fragShader=u,this.debug&&(console.log("GLSL Shader Output:"),console.log(o)),!r.getShaderParameter(a,r.COMPILE_STATUS))throw new Error("Error compiling vertex shader: "+r.getShaderInfoLog(a));if(!r.getShaderParameter(u,r.COMPILE_STATUS))throw new Error("Error compiling fragment shader: "+r.getShaderInfoLog(u));const l=this.program=r.createProgram();r.attachShader(l,a),r.attachShader(l,u),r.linkProgram(l),this.framebuffer=r.createFramebuffer(),this.framebuffer.width=t[0],this.framebuffer.height=t[1],this.rawValueFramebuffers={};const h=new Float32Array([-1,-1,1,-1,-1,1,1,1]),c=new Float32Array([0,0,1,0,0,1,1,1]),p=h.byteLength;let d=this.buffer;d?r.bindBuffer(r.ARRAY_BUFFER,d):(d=this.buffer=r.createBuffer(),r.bindBuffer(r.ARRAY_BUFFER,d),r.bufferData(r.ARRAY_BUFFER,h.byteLength+c.byteLength,r.STATIC_DRAW)),r.bufferSubData(r.ARRAY_BUFFER,0,h),r.bufferSubData(r.ARRAY_BUFFER,p,c);const m=r.getAttribLocation(this.program,"aPos");-1!==m&&(r.enableVertexAttribArray(m),r.vertexAttribPointer(m,2,r.FLOAT,!1,0,0));const f=r.getAttribLocation(this.program,"aTexCoord");-1!==f&&(r.enableVertexAttribArray(f),r.vertexAttribPointer(f,2,r.FLOAT,!1,0,p)),r.bindFramebuffer(r.FRAMEBUFFER,this.framebuffer);let g=0;r.useProgram(this.program);for(let e in this.constants)this.kernelConstants[g++].updateValue(this.constants[e]);this._setupOutputTexture(),null!==this.subKernels&&this.subKernels.length>0&&(this._mappedTextureSwitched={},this._setupSubOutputTextures()),this.buildSignature(arguments),this.built=!0}translateSource(){const e=n.fromKernel(this,s,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=e.getPrototypeString("kernel"),this.setupReturnTypes(e)}setupReturnTypes(e){if(this.graphical||this.returnType||(this.returnType=e.getKernelResultType()),this.subKernels&&this.subKernels.length>0)for(let t=0;te.source&&this.source.match(e.functionMatch)?e.source:"").join("\n"):"\n"}_getConstantsString(){const e=[],{threadDim:t,texSize:r}=this;return this.dynamicOutput?e.push("uniform ivec3 uOutputDim","uniform ivec2 uTexSize"):e.push(`ivec3 uOutputDim = ivec3(${t[0]}, ${t[1]}, ${t[2]})`,`ivec2 uTexSize = ivec2(${r[0]}, ${r[1]})`),a.linesToString(e)}_getTextureCoordinate(){const e=this.subKernels;return null===e||e.length<1?"varying vec2 vTexCoord;\n":"out vec2 vTexCoord;\n"}_getDecode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getEncode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getDivideWithIntegerCheckString(){return this.fixIntegerDivisionAccuracy?"float divWithIntCheck(float x, float y) {\n if (floor(x) == x && floor(y) == y) {\n float q = floor(x / y + 0.5);\n if (y * q == x) {\n return q;\n }\n }\n return x / y;\n}\n\nfloat integerCorrectionModulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -(number - (divisor * floor(divWithIntCheck(number, divisor))));\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return number - (divisor * floor(divWithIntCheck(number, divisor)));\n}":""}_getMainArgumentsString(e){const t=[],{argumentNames:r}=this;for(let n=0;n{if(t.hasOwnProperty(r))return t[r];throw`unhandled artifact ${r}`})}getFragmentShader(e){return null!==this.compiledFragmentShader?this.compiledFragmentShader:this.compiledFragmentShader=this.replaceArtifacts(this.constructor.fragmentShader,this._getFragShaderArtifactMap(e))}getVertexShader(e){return null!==this.compiledVertexShader?this.compiledVertexShader:this.compiledVertexShader=this.replaceArtifacts(this.constructor.vertexShader,this._getVertShaderArtifactMap(e))}toString(){const e=a.linesToString(["const gl = context"]);return c(this.constructor,arguments,this,e)}destroy(e){if(!this.context)return;this.buffer&&this.context.deleteBuffer(this.buffer),this.framebuffer&&this.context.deleteFramebuffer(this.framebuffer);for(const e in this.rawValueFramebuffers){for(const t in this.rawValueFramebuffers[e])this.context.deleteFramebuffer(this.rawValueFramebuffers[e][t]),delete this.rawValueFramebuffers[e][t];delete this.rawValueFramebuffers[e]}if(this.vertShader&&this.context.deleteShader(this.vertShader),this.fragShader&&this.context.deleteShader(this.fragShader),this.program&&this.context.deleteProgram(this.program),this.texture){this.texture.delete();const e=this.textureCache.indexOf(this.texture.texture);e>-1&&this.textureCache.splice(e,1),this.texture=null}if(this.mappedTextures&&this.mappedTextures.length){for(let e=0;e-1&&this.textureCache.splice(r,1)}this.mappedTextures=null}if(this.kernelArguments)for(let e=0;e0;){const e=this.textureCache.pop();this.context.deleteTexture(e)}if(e){const e=b.indexOf(this.canvas);e>=0&&(b[e]=null,T[e]=null)}if(this.destroyExtensions(),delete this.context,delete this.canvas,!this.gpu)return;const t=this.gpu.kernels.indexOf(this);-1!==t&&this.gpu.kernels.splice(t,1)}destroyExtensions(){this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("WEBGL_lose_context");t&&t.loseContext()}toJSON(){const e=super.toJSON();return e.functionNodes=n.fromKernel(this,s).toJSON(),e.settings.threadDim=this.threadDim,e}}}}),be=e((e,t)=>{const n=r(),{WebGLKernel:s}=xe(),{glKernelString:i}=O();let a=null,o=null,u=null,l=null,h=null;t.exports={HeadlessGLKernel:class extends s{static get isSupported(){return null!==a||(this.setupFeatureChecks(),a=null!==u),a}static setupFeatureChecks(){if(o=null,l=null,"function"==typeof n)try{if(u=n(2,2,{preserveDrawingBuffer:!0}),!u||!u.getExtension)return;l={STACKGL_resize_drawingbuffer:u.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:u.getExtension("STACKGL_destroy_context"),OES_texture_float:u.getExtension("OES_texture_float"),OES_texture_float_linear:u.getExtension("OES_texture_float_linear"),OES_element_index_uint:u.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:u.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:u.getExtension("WEBGL_color_buffer_float")},h=this.getFeatures()}catch(e){console.warn(e)}}static isContextMatch(e){try{return"ANGLE"===e.getParameter(e.RENDERER)}catch(e){return!1}}static getIsTextureFloat(){return Boolean(l.OES_texture_float)}static getIsDrawBuffers(){return Boolean(l.WEBGL_draw_buffers)}static getChannelCount(){return l.WEBGL_draw_buffers?u.getParameter(l.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return u.getParameter(u.MAX_TEXTURE_SIZE)}static get testCanvas(){return o}static get testContext(){return u}static get features(){return h}initCanvas(){return{}}initContext(){return n(2,2,{preserveDrawingBuffer:!0})}initExtensions(){this.extensions={STACKGL_resize_drawingbuffer:this.context.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:this.context.getExtension("STACKGL_destroy_context"),OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers")}}build(){super.build.apply(this,arguments),this.fallbackRequested||this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}destroyExtensions(){this.extensions.STACKGL_resize_drawingbuffer=null,this.extensions.STACKGL_destroy_context=null,this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("STACKGL_destroy_context");t&&t.destroy&&t.destroy()}toString(){return i(this.constructor,arguments,this,"const gl = context || require('gl')(1, 1);\n"," if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n")}setOutput(e){return super.setOutput(e),this.graphical&&this.extensions.STACKGL_resize_drawingbuffer&&this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1]),this}}}}),Te=e((e,t)=>{const{utils:r}=i(),{WebGLFunctionNode:n}=z();t.exports={WebGL2FunctionNode:class extends n{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),s=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===n&&this.argumentNames.indexOf(s)>-1?t.push(`bool(user_${s})`):t.push(`user_${s}`),t}}}}),Se=e((e,t)=>{t.exports={fragmentShader:`#version 300 es\n__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nin vec2 vTexCoord;\n\nfloat atan2(float v1, float v2) {\n if (v2 == 0.0) {\n if (v1 == 0.0) return 0.0;\n if (v1 > 0.0) return 1.5707963267948966;\n if (v1 < 0.0) return -1.5707963267948966;\n }\n return atan(v1, v2);\n}\n\nfloat cbrt(float x) {\n if (x >= 0.0) {\n return pow(x, 1.0 / 3.0);\n } else {\n return -pow(x, 1.0 / 3.0);\n }\n}\n\nfloat expm1(float x) {\n return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n return x;\n}\n\nfloat imul(float v1, float v2) {\n return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n if (v2 == 0.0) return 1.0;\n return pow(v1, v2);\n}\n\nfloat _round(float x) {\n return floor(x + 0.5);\n}\n\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n // ~a is identically -a - 1 in two's complement, for every value including\n // negatives. The previous bit-by-bit loop only worked for a >= 0, where it\n // leaned on 32-bit overflow wrapping to reach the negative answer; given a\n // negative input it computed ~abs(a), so ~(-1) gave -2 and ~~x never\n // returned x.\n return -a - 1;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\n// _pow2 is defined further down, alongside encode32/decode32\nfloat _pow2(float e);\nint bitwiseSignedRightShift(int num, int shifts) {\n // pow(2.0, n) is approximate on many GPUs, and landing 1 ulp high makes the\n // division fall just under a whole number, which floor() then rounds away:\n // 2 >> 1 came out 0, 8 >> 1 came out 3. Only exact left operands were\n // affected, odd ones having enough slack to survive. _pow2 is exact.\n return int(floor(float(num) / _pow2(float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x/y));\n}\n\n// GLSL ES 1.00 accepts only a constant or a loop symbol inside an index\n// expression, so m[y][x] does not compile when y and x come from kernel\n// arguments -- the error is "Index expression can only contain const or loop\n// symbols". Loop counters are legal indices, so walk the matrix with them\n// instead. These are 2x2 to 4x4, so it costs at most sixteen comparisons.\nfloat getMatrix2(mat2 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 2; i++) {\n for (int j = 0; j < 2; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix3(mat3 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 3; i++) {\n for (int j = 0; j < 3; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix4(mat4 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 4; i++) {\n for (int j = 0; j < 4; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\n// Exact powers of two built from exact constant multiplies: exp2/log2/pow\n// are approximate on some GPUs (notably Apple silicon), and 1-2 ulp there\n// corrupts the packed bytes (#659)\nfloat _pow2(float e) {\n float r = 1.0;\n float a = abs(e);\n bool n = e < 0.0;\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 32.0) { r *= n ? 2.3283064365386963e-10 : 4294967296.0; a -= 32.0; }\n if (a >= 16.0) { r *= n ? 0.0000152587890625 : 65536.0; a -= 16.0; }\n if (a >= 8.0) { r *= n ? 0.00390625 : 256.0; a -= 8.0; }\n if (a >= 4.0) { r *= n ? 0.0625 : 16.0; a -= 4.0; }\n if (a >= 2.0) { r *= n ? 0.25 : 4.0; a -= 2.0; }\n if (a >= 1.0) { r *= n ? 0.5 : 2.0; }\n return r;\n}\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = _pow2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * _pow2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n return texel[channel] * 255.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n float p2 = _pow2(exponent);\n // approximate log2 can land one off; correct by direct comparison\n if (p2 > value) { exponent -= 1.0; p2 *= 0.5; }\n else if (p2 * 2.0 <= value) { exponent += 1.0; p2 *= 2.0; }\n\n mantissa = value / p2 - 1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n index = index / 4;\n vec4 texel = texture(tex, st / vec2(texSize));\n return texel[channel];\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, st / vec2(texSize));\n}\n\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, vec3(st / vec2(texSize), z));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n\n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nfloat modulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -mod(number, divisor);\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}`}}),Ae=e((e,t)=>{t.exports={vertexShader:"#version 300 es\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nin vec2 aPos;\nin vec2 aTexCoord;\n\nout vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"}}),we=e((e,t)=>{const{WebGLKernelValueBoolean:r}=U();t.exports={WebGL2KernelValueBoolean:class extends r{}}}),Ee=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueFloat:n}=P();t.exports={WebGL2KernelValueFloat:class extends n{}}}),_e=e((e,t)=>{const{WebGLKernelValueInteger:r}=B();t.exports={WebGL2KernelValueInteger:class extends r{getSource(e){const t=this.getVariablePrecisionString();return"constants"===this.origin?`const ${t} int ${this.id} = ${parseInt(e)};\n`:`uniform ${t} int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),ve=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueHTMLImage:n}=j();t.exports={WebGL2KernelValueHTMLImage:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),Ie=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicHTMLImage:n}=X();t.exports={WebGL2KernelValueDynamicHTMLImage:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),$e=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGL2KernelValueHTMLImageArray:class extends n{constructor(e,t){super(e,t),this.checkSize(e[0].width,e[0].height),this.dimensions=[e[0].width,e[0].height,e.length],this.textureSize=[e[0].width,e[0].height]}defineTexture(){const{context:e}=this;e.activeTexture(this.contextHandle),e.bindTexture(e.TEXTURE_2D_ARRAY,this.texture),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MIN_FILTER,e.NEAREST)}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D_ARRAY,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage3D(t.TEXTURE_2D_ARRAY,0,t.RGBA,e[0].width,e[0].height,e.length,0,t.RGBA,t.UNSIGNED_BYTE,null);for(let r=0;r{const{utils:r}=i(),{WebGL2KernelValueHTMLImageArray:n}=$e();t.exports={WebGL2KernelValueDynamicHTMLImageArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:r}=e[0];this.checkSize(t,r),this.dimensions=[t,r,e.length],this.textureSize=[t,r],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Fe=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueHTMLImage:n}=ve();t.exports={WebGL2KernelValueHTMLVideo:class extends n{}}}),Le=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueDynamicHTMLImage:n}=Ie();t.exports={WebGL2KernelValueDynamicHTMLVideo:class extends n{}}}),Re=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleInput:n}=Y();t.exports={WebGL2KernelValueSingleInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;r.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ke=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleInput:n}=Re();t.exports={WebGL2KernelValueDynamicSingleInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,s]=e.size;this.dimensions=new Int32Array([t||1,n||1,s||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ze=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedInput:n}=J();t.exports={WebGL2KernelValueUnsignedInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),Me=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicUnsignedInput:n}=Q();t.exports={WebGL2KernelValueDynamicUnsignedInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Ge=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueMemoryOptimizedNumberTexture:n}=ee();t.exports={WebGL2KernelValueMemoryOptimizedNumberTexture:class extends n{getSource(){const{id:e,sizeId:t,textureSize:n,dimensionsId:s,dimensions:i}=this,a=this.getVariablePrecisionString();return r.linesToString([`uniform sampler2D ${e}`,`${a} ivec2 ${t} = ivec2(${n[0]}, ${n[1]})`,`${a} ivec3 ${s} = ivec3(${i[0]}, ${i[1]}, ${i[2]})`])}}}}),Ce=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:n}=te();t.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}}}),Ne=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueNumberTexture:n}=re();t.exports={WebGL2KernelValueNumberTexture:class extends n{getSource(){const{id:e,sizeId:t,textureSize:n,dimensionsId:s,dimensions:i}=this,a=this.getVariablePrecisionString();return r.linesToString([`uniform ${a} sampler2D ${e}`,`${a} ivec2 ${t} = ivec2(${n[0]}, ${n[1]})`,`${a} ivec3 ${s} = ivec3(${i[0]}, ${i[1]}, ${i[2]})`])}}}}),Oe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicNumberTexture:n}=ne();t.exports={WebGL2KernelValueDynamicNumberTexture:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Ve=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray:n}=se();t.exports={WebGL2KernelValueSingleArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Ke=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray:n}=Ve();t.exports={WebGL2KernelValueDynamicSingleArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Ue=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray1DI:n}=ae();t.exports={WebGL2KernelValueSingleArray1DI:class extends n{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Pe=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray1DI:n}=Ue();t.exports={WebGL2KernelValueDynamicSingleArray1DI:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Be=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray2DI:n}=ue();t.exports={WebGL2KernelValueSingleArray2DI:class extends n{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),We=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray2DI:n}=Be();t.exports={WebGL2KernelValueDynamicSingleArray2DI:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),je=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray3DI:n}=he();t.exports={WebGL2KernelValueSingleArray3DI:class extends n{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Xe=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray3DI:n}=je();t.exports={WebGL2KernelValueDynamicSingleArray3DI:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),He=e((e,t)=>{const{WebGLKernelValueArray2:r}=pe();t.exports={WebGL2KernelValueArray2:class extends r{}}}),qe=e((e,t)=>{const{WebGLKernelValueArray3:r}=de();t.exports={WebGL2KernelValueArray3:class extends r{}}}),Ye=e((e,t)=>{const{WebGLKernelValueArray4:r}=me();t.exports={WebGL2KernelValueArray4:class extends r{}}}),Ze=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedArray:n}=fe();t.exports={WebGL2KernelValueUnsignedArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),Je=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicUnsignedArray:n}=ge();t.exports={WebGL2KernelValueDynamicUnsignedArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Qe=e((e,t)=>{const{WebGL2KernelValueBoolean:r}=we(),{WebGL2KernelValueFloat:n}=Ee(),{WebGL2KernelValueInteger:s}=_e(),{WebGL2KernelValueHTMLImage:i}=ve(),{WebGL2KernelValueDynamicHTMLImage:a}=Ie(),{WebGL2KernelValueHTMLImageArray:o}=$e(),{WebGL2KernelValueDynamicHTMLImageArray:u}=De(),{WebGL2KernelValueHTMLVideo:l}=Fe(),{WebGL2KernelValueDynamicHTMLVideo:h}=Le(),{WebGL2KernelValueSingleInput:c}=Re(),{WebGL2KernelValueDynamicSingleInput:p}=ke(),{WebGL2KernelValueUnsignedInput:d}=ze(),{WebGL2KernelValueDynamicUnsignedInput:m}=Me(),{WebGL2KernelValueMemoryOptimizedNumberTexture:f}=Ge(),{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:g}=Ce(),{WebGL2KernelValueNumberTexture:y}=Ne(),{WebGL2KernelValueDynamicNumberTexture:x}=Oe(),{WebGL2KernelValueSingleArray:b}=Ve(),{WebGL2KernelValueDynamicSingleArray:T}=Ke(),{WebGL2KernelValueSingleArray1DI:S}=Ue(),{WebGL2KernelValueDynamicSingleArray1DI:A}=Pe(),{WebGL2KernelValueSingleArray2DI:w}=Be(),{WebGL2KernelValueDynamicSingleArray2DI:E}=We(),{WebGL2KernelValueSingleArray3DI:_}=je(),{WebGL2KernelValueDynamicSingleArray3DI:v}=Xe(),{WebGL2KernelValueArray2:I}=He(),{WebGL2KernelValueArray3:$}=qe(),{WebGL2KernelValueArray4:D}=Ye(),{WebGL2KernelValueUnsignedArray:F}=Ze(),{WebGL2KernelValueDynamicUnsignedArray:L}=Je(),R={unsigned:{dynamic:{Boolean:r,Integer:s,Float:n,Array:L,"Array(2)":I,"Array(3)":$,"Array(4)":D,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:m,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:h},static:{Boolean:r,Float:n,Integer:s,Array:F,"Array(2)":I,"Array(3)":$,"Array(4)":D,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:d,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:g,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:o,HTMLVideo:l}},single:{dynamic:{Boolean:r,Integer:s,Float:n,Array:T,"Array(2)":I,"Array(3)":$,"Array(4)":D,"Array1D(2)":A,"Array1D(3)":A,"Array1D(4)":A,"Array2D(2)":E,"Array2D(3)":E,"Array2D(4)":E,"Array3D(2)":v,"Array3D(3)":v,"Array3D(4)":v,Input:p,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:h},static:{Boolean:r,Float:n,Integer:s,Array:b,"Array(2)":I,"Array(3)":$,"Array(4)":D,"Array1D(2)":S,"Array1D(3)":S,"Array1D(4)":S,"Array2D(2)":w,"Array2D(3)":w,"Array2D(4)":w,"Array3D(2)":_,"Array3D(3)":_,"Array3D(4)":_,Input:c,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:f,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:o,HTMLVideo:l}}};t.exports={kernelValueMaps:R,lookupKernelValueType:function(e,t,r,n){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!r)throw new Error("precision missing");n.type&&(e=n.type);const s=R[r][t];if("WebGPUBuffer"===e)throw new Error("this kernel runs on WebGL but received a WebGPU pipeline buffer; await handle.toArray() first, or give this kernel the async contract (asyncMode: true / mode: 'async') so the readback happens for you");if(!1===s[e])return null;if(void 0===s[e])throw new Error(`Could not find a KernelValue for ${e}`);return s[e]}}}),et=e((e,t)=>{const{WebGLKernel:r}=xe(),{WebGL2FunctionNode:n}=Te(),{FunctionBuilder:s}=o(),{utils:a}=i(),{fragmentShader:u}=Se(),{vertexShader:l}=Ae(),{lookupKernelValueType:h}=Qe();let c=null,p=null,d=null,m=null;t.exports={WebGL2Kernel:class extends r{static get isSupported(){return null!==c||(this.setupFeatureChecks(),c=this.isContextMatch(d)),c}static setupFeatureChecks(){"undefined"!=typeof document?p=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(p=new OffscreenCanvas(0,0)),p&&(d=p.getContext("webgl2"),d&&d.getExtension&&(d.getExtension("EXT_color_buffer_float"),d.getExtension("OES_texture_float_linear"),m=this.getFeatures()))}static isContextMatch(e){return"undefined"!=typeof WebGL2RenderingContext&&e instanceof WebGL2RenderingContext}static getFeatures(){const e=this.testContext;return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isSpeedTacticSupported:this.getIsSpeedTacticSupported(),kernelMap:!0,isTextureFloat:!0,isDrawBuffers:!0,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize(),lowIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT),lowFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT),mediumIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT),mediumFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT),highIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT),highFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)})}static getIsTextureFloat(){return!0}static getChannelCount(){return d.getParameter(d.MAX_DRAW_BUFFERS)}static getMaxTextureSize(){return d.getParameter(d.MAX_TEXTURE_SIZE)}static lookupKernelValueType(e,t,r,n){return h(e,t,r,n)}static get testCanvas(){return p}static get testContext(){return d}static get features(){return m}static get fragmentShader(){return u}static get vertexShader(){return l}initContext(){return this.canvas.getContext("webgl2",{alpha:!1,depth:!1,antialias:!1})}initExtensions(){this.extensions={EXT_color_buffer_float:this.context.getExtension("EXT_color_buffer_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if("single"===this.precision&&!t.isFloatRead)throw new Error("Float texture outputs are not supported");if(this.graphical||null!==this.precision||(this.precision=t.isFloatRead?"single":"unsigned"),null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);switch(t){case"Array":this.output=a.getDimensions(t);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=e[0].output;break;default:throw new Error("Auto output not supported for input type: "+t)}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"single"===this.precision&&(console.warn("Cannot use graphical mode and single precision at the same time"),this.precision="unsigned"),void(this.texSize=a.clone(this.output))}!this.graphical&&null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}translateSource(){const e=s.fromKernel(this,n,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=e.getPrototypeString("kernel"),this.setupReturnTypes(e)}drawBuffers(){this.context.drawBuffers(this.drawBuffersMap)}getTextureFormat(){const{context:e}=this;switch(this.getInternalFormat()){case e.R32F:return e.RED;case e.RG32F:return e.RG;case e.RGBA32F:case e.RGBA:return e.RGBA;default:throw new Error("Unknown internal format")}}renderValues(){return void 0===this._tightRead&&this._detectTightRead(),super.renderValues()}renderKernelsToArrays(){return void 0===this._tightRead&&this._detectTightRead(),super.renderKernelsToArrays()}readFloatPixelsToFloat32Array(){if(!this._tightRead)return super.readFloatPixelsToFloat32Array();const{texSize:e,context:t}=this,r=e[0],n=e[1],s=new Float32Array(r*n);return t.readPixels(0,0,r,n,t.RED,t.FLOAT,s),s}renderOutputAsync(){return this.renderOutput!==this.renderValues?Promise.resolve(this.renderOutput()):this.renderValuesAsync()}renderValuesAsync(){void 0===this._tightRead&&this._detectTightRead();const e=this.formatValues,[t,r,n]=this.output;return this.transferValuesAsync().then(s=>e(s,t,r,n))}transferValuesAsync(){const{texSize:e,context:t}=this,r=e[0],n=e[1];let s,i,a;"single"===this.precision?(s=this._tightRead?t.RED:t.RGBA,i=t.FLOAT,a=new Float32Array(r*n*(this._tightRead?1:4))):(s=t.RGBA,i=t.UNSIGNED_BYTE,a=new Uint8Array(r*n*4));const o=t.createBuffer();t.bindBuffer(t.PIXEL_PACK_BUFFER,o),t.bufferData(t.PIXEL_PACK_BUFFER,a.byteLength,t.STREAM_READ),t.readPixels(0,0,r,n,s,i,0),t.bindBuffer(t.PIXEL_PACK_BUFFER,null);const u=t.fenceSync(t.SYNC_GPU_COMMANDS_COMPLETE,0);return t.flush(),this._pollFence(u).then(()=>(t.bindBuffer(t.PIXEL_PACK_BUFFER,o),t.getBufferSubData(t.PIXEL_PACK_BUFFER,0,a),t.bindBuffer(t.PIXEL_PACK_BUFFER,null),t.deleteBuffer(o),"single"===this.precision?a:new Float32Array(a.buffer)),e=>{throw t.deleteBuffer(o),e})}_pollFence(e){const t=this.context;return new Promise((r,n)=>{let s,i=null;"undefined"!=typeof MessageChannel?(i=new MessageChannel,i.port1.onmessage=()=>o(),s=()=>i.port2.postMessage(0)):s=()=>setTimeout(o,0);const a=(r,n)=>{t.deleteSync(e),i&&(i.port1.close(),i.port2.close()),r(n)},o=()=>{if(t.isContextLost())return a(n,new Error("WebGL context lost while awaiting kernel result"));const i=t.clientWaitSync(e,0,0);return i===t.ALREADY_SIGNALED||i===t.CONDITION_SATISFIED?a(r):i===t.WAIT_FAILED?a(n,new Error("clientWaitSync failed while awaiting kernel result")):void s()};o()})}_detectTightRead(){const e=this.context;this._tightRead=!1,e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer);const t="Number"===this.returnType||"Float"===this.returnType||"Integer"===this.returnType||"LiteralInteger"===this.returnType;if("single"===this.precision&&!this.optimizeFloatMemory&&!this.graphical&&t&&e.getParameter(e.IMPLEMENTATION_COLOR_READ_FORMAT)===e.RED&&e.getParameter(e.IMPLEMENTATION_COLOR_READ_TYPE)===e.FLOAT){if(this.formatValues===a.erectFloat)this.formatValues=a.erectMemoryOptimizedFloat;else if(this.formatValues===a.erect2DFloat)this.formatValues=a.erectMemoryOptimized2DFloat;else if(this.formatValues===a.erect3DFloat)this.formatValues=a.erectMemoryOptimized3DFloat;else if(this.formatValues!==a.erectMemoryOptimizedFloat&&this.formatValues!==a.erectMemoryOptimized2DFloat&&this.formatValues!==a.erectMemoryOptimized3DFloat)return;this._tightRead=!0}}getInternalFormat(){const{context:e}=this;if("single"===this.precision)switch(this.returnType){case"Number":case"Float":case"Integer":return this.optimizeFloatMemory?e.RGBA32F:e.R32F;case"Array(2)":return e.RG32F;case"Array(3)":case"Array(4)":return e.RGBA32F;default:throw new Error("Unhandled return type")}return e.RGBA}_setupOutputTexture(){const e=this.context;if(this.texture)return e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture.texture,0),void(this._tightRead=void 0);e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer);const t=e.createTexture(),r=this.texSize;e.activeTexture(e.TEXTURE0+this.constantTextureCount+this.argumentTextureCount),e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);const n=this.getInternalFormat();"single"===this.precision?e.texStorage2D(e.TEXTURE_2D,1,n,r[0],r[1]):e.texImage2D(e.TEXTURE_2D,0,n,r[0],r[1],0,n,e.UNSIGNED_BYTE,null),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),this.texture=new this.TextureConstructor({texture:t,size:r,dimensions:this.threadDim,output:this.output,context:this.context,internalFormat:this.getInternalFormat(),textureFormat:this.getTextureFormat(),kernel:this}),this._tightRead=void 0}_setupSubOutputTextures(){const e=this.context;if(this.mappedTextures){for(let t=0;t{const{utils:r}=i(),{FunctionNode:n}=l();const s={Number:"f32",Float:"f32",Integer:"i32",LiteralInteger:"f32",Boolean:"bool","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4"},a={"===":"==","!==":"!="},o=["x","y","z","w"],u={pow:"_pow",round:"_round"},h={ceil:!0,floor:!0,_round:!0},c=["alias","break","case","const","const_assert","continue","continuing","default","diagnostic","discard","else","enable","false","fn","for","if","let","loop","override","requires","return","struct","switch","true","var","while","main","params","result","gid","threadGid","data_index","select","abs","acos","acosh","asin","asinh","atan","atan2","atanh","ceil","clamp","cos","cosh","cross","degrees","distance","dot","exp","exp2","floor","fma","fract","inverseSqrt","length","log","log2","max","min","mix","modf","normalize","pow","radians","round","sign","sin","sinh","smoothstep","sqrt","step","tan","tanh","trunc","cbrt","expm1","fround","imul","log10","log1p","clz32","_pow","_round","LOOP_MAX","bitcast","ptr","array","vec2","vec3","vec4","mat2x2","mat3x3","mat4x4","f32","i32","u32","bool"];t.exports={WGSLFunctionNode:class extends n{wgslFloat(e){if(e===1/0)return"0x1.fffffep+127";if(e===-1/0)return"-0x1.fffffep+127";if(e>34028234663852886e22)return"0x1.fffffep+127";if(e<-34028234663852886e22)return"-0x1.fffffep+127";const t=`${e}`;return-1!==t.indexOf(".")||-1!==t.indexOf("e")||-1!==t.indexOf("E")?t:`${t}.0`}wgslInt(e){return`${Math.round(e)}`}mangleFunctionName(e){return-1!==c.indexOf(e)?`fn_${e}`:r.sanitizeName(e)}getLookupType(e){return"WebGPUBuffer"===e?"Number":super.getLookupType(e)}astUpdateExpression(e,t){return this.astGeneric(e.argument,t),t.push(e.operator),t}getType(e){if(e&&"ConditionalExpression"===e.type){const t=this.getType(e.consequent);if("Integer"===t||"LiteralInteger"===t){const t=this.getType(e.alternate);if("Number"===t||"Float"===t)return"Number"}}return super.getType(e)}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);const r=this.getType(e.consequent),n=this.getType(e.alternate);if(null===r&&null===n)return t.push("if ("),this.astGeneric(e.test,t),t.push(") {"),this.astGeneric(e.consequent,t),t.push(";"),t.push("} else {"),this.astGeneric(e.alternate,t),t.push(";"),t.push("}"),t;let s="LiteralInteger"===r?"Number":r;"Integer"!==s||"Number"!==n&&"Float"!==n||(s="Number");const i=e=>{const r=this.getType(e);switch(s){case"Number":case"Float":"Integer"===r?this.castValueToFloat(e,t):"LiteralInteger"===r?this.castLiteralToFloat(e,t):this.astGeneric(e,t);break;case"Integer":"Number"===r||"Float"===r?this.castValueToInteger(e,t):"LiteralInteger"===r?this.castLiteralToInteger(e,t):this.astGeneric(e,t);break;default:this.astGeneric(e,t)}};return t.push("select("),i(e.alternate),t.push(", "),i(e.consequent),t.push(", "),this.astGeneric(e.test,t),t.push(")"),t}astFunction(e,t){if(this.isRootKernel){for(let r=0;r0&&t.push(", ");let a=this.argumentTypes[this.argumentNames.indexOf(i)];if(!a)throw this.astErrorOutput(`Unknown argument ${i} type`,e);"LiteralInteger"===a&&(this.argumentTypes[n]=a="Number");const o=s[a];if(!o)throw this.astErrorOutput(`WebGPU backend does not yet support ${a} arguments to helper functions`,e);t.push(`user_${r.sanitizeName(i)} : ${o}`)}t.push(")"),i&&t.push(` -> ${i}`),t.push(" {\n");for(let r=0;r"===e.operator||"<"===e.operator)&&"Literal"===e.right.type&&!Number.isInteger(e.right.value)){this.pushState("building-float"),this.castValueToFloat(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-float");break}if(this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const r=[];if(this.astGeneric(e.right,r),"Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(r.join(""))}else t.push("i32("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float");break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.castLiteralToFloat(e.left,t),t.push(a[e.operator]||e.operator),this.pushState("casting-to-float"),this.astGeneric(e.right,t),this.popState("casting-to-float"),this.popState("building-float"));break;case"LiteralInteger & Integer":this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${r}`,e)}return t.push(")"),t}checkAndUpconvertOperator(e,t){if(this.checkAndUpconvertBitwiseOperators(e,t))return t;if("**"!==e.operator)return null;switch(t.push("_pow"),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){if(!{"&":!0,"|":!0,"^":!0,"<<":!0,">>":!0,">>>":!0}[e.operator])return null;const r=e=>{switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;default:this.pushState("building-integer"),this.astGeneric(e,t),this.popState("building-integer")}};return t.push("("),">>>"===e.operator?(t.push("bitcast(bitcast("),r(e.left),t.push(") >> u32("),r(e.right),t.push("))")):"<<"===e.operator||">>"===e.operator?(r(e.left),t.push(` ${e.operator} u32(`),r(e.right),t.push(")")):(r(e.left),t.push(` ${e.operator} `),r(e.right)),t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){if("~"!==e.operator)return null;switch(t.push("~("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)?t:"+"===e.operator?(this.astGeneric(e.argument,t),t):(e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t)}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("i32("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("f32("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),s=r.sanitizeName(e.name);return"Infinity"===e.name?(t.push("0x1.fffffep+127"),t):!this.isRootKernel||-1===this.argumentNames.indexOf(e.name)||"Number"!==n&&"Float"!==n&&"Integer"!==n&&"Boolean"!==n?(t.push(`user_${s}`),t):("Boolean"===n?t.push(`bool(params.user_${s})`):t.push(`params.user_${s}`),t)}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const r=[],n=[],s=[],i=[];let a=null;if(e.init){const{declarations:t}=e.init;t.length>1&&(a=!1),this.astGeneric(e.init,r);for(let e=0;e0&&t.push(r.join(""),"\n"),t.push(`for (var ${e} : i32 = 0;${e}0&&t.push(`if (!(${n.join("")})) { break; }\n`),t.push(i.join("")),t.push(`\n${s.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);const r=this.getInternalVariableName("safeI");return t.push(`for (var ${r} : i32 = 0;${r}{if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return e.some(t);if("BreakStatement"===e.type)return!0;if("ForStatement"===e.type||"WhileStatement"===e.type||"DoWhileStatement"===e.type||"SwitchStatement"===e.type)return!1;for(const r in e)if("loc"!==r&&"range"!==r&&"parent"!==r&&t(e[r]))return!0;return!1};if(t(r[e]))throw this.astErrorOutput("break inside a switch case is only supported as the case terminator",r[e])}for(let e=0;ee+1){u=!0,this.astSwitchCaseConsequent(n[e].consequent,o);continue}t.push(" else {\n")}this.astSwitchCaseConsequent(n[e].consequent,t),t.push("\n}")}return u&&(t.push(" else {"),t.push(o.join("")),t.push("}")),t.push("\n"),t}astThisExpression(e,t){return t.push("this"),t}astSequenceExpression(e,t){const{expressions:r}=e;if(1===r.length)return this.astGeneric(r[0],t),t;throw this.astErrorOutput("WebGPU backend does not yet support the comma operator",e)}astMemberExpression(e,t){const{property:n,name:i,signature:a,origin:o,type:u,xProperty:l,yProperty:h,zProperty:c}=this.getMemberExpressionDetails(e);switch(a){case"value.thread.value":case"this.thread.value":if("x"!==i&&"y"!==i&&"z"!==i)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`i32(threadGid.${i})`),t;case"this.output.value":{const r={x:0,y:1,z:2}[i];if(void 0===r)throw this.astErrorOutput("Unexpected expression",e);if(this.dynamicOutput){const e=`params.output${i.toUpperCase()}`;this.isState("casting-to-float")?t.push(`f32(${e})`):t.push(`i32(${e})`)}else this.isState("casting-to-integer")?t.push(`${this.output[r]}`):t.push(`${this.output[r]}.0`);return t}case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if("Math"===o)return t.push(this.wgslFloat(Math[i])),t;switch(n){case"r":return t.push(`user_${r.sanitizeName(i)}.x`),t;case"g":return t.push(`user_${r.sanitizeName(i)}.y`),t;case"b":return t.push(`user_${r.sanitizeName(i)}.z`),t;case"a":return t.push(`user_${r.sanitizeName(i)}.w`),t}break;case"this.constants.value":{const r=this.constants[i];switch(u){case"Integer":return this.isState("casting-to-float")?t.push(this.wgslFloat(r)):t.push(this.wgslInt(r)),t;case"Number":case"Float":return this.isState("casting-to-integer")?t.push(this.wgslInt(r)):t.push(this.wgslFloat(r)),t;case"Boolean":return t.push(r?"true":"false"),t;case"Array(2)":case"Array(3)":case"Array(4)":{const e=parseInt(u.substring(6),10),n=[];for(let t=0;t0&&t.push(", "),s){case"Integer":this.castValueToFloat(n,t);break;case"LiteralInteger":this.castLiteralToFloat(n,t);break;default:this.astGeneric(n,t)}}else{const s=this.lookupFunctionArgumentTypes(n)||[];for(let i=0;i0&&t.push(", ");const u=this.getType(a);switch(o||(this.triggerImplyArgumentType(n,i,u,this),o=u),u){case"Boolean":this.astGeneric(a,t);continue;case"Number":case"Float":if("Integer"===o){t.push("i32("),this.astGeneric(a,t),t.push(")");continue}if("Number"===o||"Float"===o){this.astGeneric(a,t);continue}if("LiteralInteger"===o){this.castLiteralToFloat(a,t);continue}break;case"Integer":if("Number"===o||"Float"===o){t.push("f32("),this.astGeneric(a,t),t.push(")");continue}if("Integer"===o){this.astGeneric(a,t);continue}break;case"LiteralInteger":if("Integer"===o){this.castLiteralToInteger(a,t);continue}if("Number"===o||"Float"===o){this.castLiteralToFloat(a,t);continue}if("LiteralInteger"===o){this.astGeneric(a,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(o===u){"Identifier"===a.type?t.push(`user_${r.sanitizeName(a.name)}`):this.astGeneric(a,t);continue}break;case"Array":case"Array2D":case"Array3D":case"Input":case"WebGPUBuffer":throw this.astErrorOutput("WebGPU backend does not yet support array arguments to helper functions",e)}throw this.astErrorOutput(`Unhandled argument combination of ${u} and ${o} for argument named "${a.name}"`,e)}}return t.push(")"),a&&t.push(")"),t}astArrayExpression(e,t){switch(this.getType(e)){case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":throw this.astErrorOutput("WebGPU backend does not yet support Matrix types",e)}const r=e.elements.length;t.push(`vec${r}(`);for(let n=0;n0&&t.push(", ");const r=e.elements[n];switch(this.getType(r)){case"Integer":this.castValueToFloat(r,t);break;case"LiteralInteger":this.castLiteralToFloat(r,t);break;default:this.astGeneric(r,t)}}return t.push(")"),t}memberExpressionXYZ(e,t,r,n){return r?n.push(this.memberExpressionPropertyMarkup(r),", "):n.push("0, "),t?n.push(this.memberExpressionPropertyMarkup(t),", "):n.push("0, "),n.push(this.memberExpressionPropertyMarkup(e)),n}memberExpressionPropertyMarkup(e){if(!e)throw new Error("Property not set");const t=[];switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;case"Integer":this.pushState("building-integer"),t.push("i32("),this.astGeneric(e,t),t.push(")"),this.popState("building-integer");break;default:this.astGeneric(e,t)}return t.join("")}}}}),rt=e((e,t)=>{let r=null;t.exports={WebGPUContext:class e{static get isSupported(){return"undefined"!=typeof navigator&&!!navigator.gpu}static acquire(){if(r)return r;const t=(async()=>{if(!e.isSupported)throw new Error("WebGPU is not supported on this platform (navigator.gpu is missing)");const n=await navigator.gpu.requestAdapter();if(!n)throw new Error("WebGPU is present (navigator.gpu) but no adapter is available. On headless Chromium there is no adapter; run headed. Use `await GPU.isWebGPUAvailable()` to feature-detect.");const s=await n.requestDevice({requiredLimits:{maxStorageBufferBindingSize:n.limits.maxStorageBufferBindingSize,maxBufferSize:n.limits.maxBufferSize}}),i={adapter:n,device:s,isLost:!1};return s.lost.then(e=>{i.isLost=!0,"destroyed"!==e.reason&&console.error(`gpu.js [webgpu]: device lost: ${e.message}`),r===t&&(r=null)}),s.onuncapturederror=e=>{console.error(`gpu.js [webgpu]: ${e.error.message}`)},i})();return t.catch(()=>{r===t&&(r=null)}),r=t}static destroy(){if(!r)return Promise.resolve();const e=r;return r=null,e.then(({device:e})=>{e.destroy()},()=>{})}}}}),nt=e((e,t)=>{t.exports={WebGPUBufferResult:class e{constructor(e){this.buffer=e.buffer,this.output=e.output,this.componentCount=e.componentCount||1,this.context=e.context,this.kernel=e.kernel,this.type="WebGPUBuffer",this._deleted=!1,this.buffer._refs?this.buffer._refs++:this.buffer._refs=1}toArray(){return this._deleted?Promise.reject(new Error("WebGPUBufferResult has been deleted")):this.kernel.readBufferResult(this)}delete(){this._deleted||(this._deleted=!0,0===--this.buffer._refs&&this.buffer.destroy())}clone(){return new e(this)}}}}),st=e((e,t)=>{const{Kernel:r}=a(),{FunctionBuilder:s}=o(),{WGSLFunctionNode:u}=tt(),{WebGPUContext:l}=rt(),{WebGPUBufferResult:h}=nt(),{utils:c}=i(),{Input:p}=n(),d=Object.freeze({kernelMap:!1,isIntegerDivisionAccurate:!0,isSpeedTacticSupported:!1,isTextureFloat:!0,isDrawBuffers:!1,kernelMapSize:0,channelCount:1,maxTextureSize:1/0,isFloatRead:!0}),m={_pow:"fn _pow(v1 : f32, v2 : f32) -> f32 {\n if (v2 == 0.0) { return 1.0; }\n return pow(v1, v2);\n}",_round:"fn _round(x : f32) -> f32 {\n return floor(x + 0.5);\n}",cbrt:"fn cbrt(x : f32) -> f32 {\n return sign(x) * pow(abs(x), 1.0 / 3.0);\n}",expm1:"fn expm1(x : f32) -> f32 {\n return exp(x) - 1.0;\n}",fround:"fn fround(x : f32) -> f32 {\n return x;\n}",imul:"fn imul(a : f32, b : f32) -> f32 {\n return f32(i32(a) * i32(b));\n}",log10:`fn log10(x : f32) -> f32 {\n return log2(x) * ${1/Math.log2(10)};\n}`,log1p:"fn log1p(x : f32) -> f32 {\n return log(1.0 + x);\n}",clz32:"fn clz32(x : f32) -> f32 {\n return f32(countLeadingZeros(u32(x)));\n}"};t.exports={WebGPUKernel:class extends r{static get isSupported(){return l.isSupported}static get isAsync(){return!0}static isContextMatch(e){return Boolean(e&&"function"==typeof e.createShaderModule&&"function"==typeof e.createComputePipeline)}static getFeatures(){return d}static get features(){return d}static get mode(){return"webgpu"}static getSignature(e,t){return"webgpu"+(t.length>0?":"+t.join(","):"")}static destroyContext(e){}static nativeFunctionArguments(){throw new Error("WebGPU backend does not yet support native functions")}static nativeFunctionReturnType(){throw new Error("WebGPU backend does not yet support native functions")}static combineKernels(){throw new Error("WebGPU backend does not yet support combineKernels; chain kernels with `await` and pipeline mode instead")}constructor(e,t){if(super(e,t),t){if(t.graphical)throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend");if("unsigned"===t.precision)throw new Error("WebGPU backend does not yet support precision: 'unsigned'; it is single precision only");if(t.subKernels)throw new Error("WebGPU backend does not yet support createKernelMap")}this.mergeSettings(e.settings||t),null===this.precision&&(this.precision="single"),this.asyncMode=!0,this.threadDim=null,this.componentCount=1,this.compiledSource=null,this.translatedBody=null,this.translatedFunctions=null,this.paramsLayout=null,this._buildPromise=null,this._device=null,this.computePipeline=null,this.bindGroupLayout=null,this.bindGroup=null,this.bindGroupDirty=!0,this.paramsBuffer=null,this.paramsMirror=null,this.outputBuffer=null,this.argumentBuffers=null,this.constantBuffers=null,this.stagingPool=[]}initCanvas(){return null}initContext(){return null}initPlugins(e){return[]}setGraphical(e){if(e)throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend");return super.setGraphical(e)}setOutput(e){const t=this.toKernelOutput(e);if(this.built){if(!this.dynamicOutput)throw new Error("Resizing a kernel with dynamicOutput: false is not possible");if(t.length!==this.output.length)throw new Error("WebGPU backend does not yet support changing the output rank of a built kernel; the workgroup shape is fixed at build")}return this.output=t,this}toString(){throw new Error("WebGPU backend does not yet support toString")}validateSettings(e){if(this.graphical)throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend");if("unsigned"===this.precision)throw new Error("WebGPU backend does not yet support precision: 'unsigned'; it is single precision only");if(this.precision="single",this.subKernels&&this.subKernels.length>0)throw new Error("WebGPU backend does not yet support createKernelMap");if(!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=c.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=Array.from(c.getDimensions(e[0]));else{if("WebGPUBuffer"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=Array.from(e[0].output)}}this.checkOutput()}setupArguments(e){super.setupArguments(e);for(let e=0;e,`);for(let e=0;e params : Params;");for(let t=0;t user_${e[t].name} : array;`);const i=1+e.length;n.push(`@group(0) @binding(${i}) var result : array;`);for(let e=0;e constants_${r[e].name} : array;`);n.push("var threadGid : vec3;");const a=`${this.translatedFunctions}\n${this.translatedBody}`;/\bLOOP_MAX\b/.test(a)&&n.push(`const LOOP_MAX : i32 = ${parseInt(this.loopMaxIterations,10)||1e3};`);for(const e in m)new RegExp(`\\b${e}\\(`).test(a)&&n.push(m[e]);for(let t=0;t f32 {\n return user_${r}[u32(x + i32(params.user_${r}_dims.x) * (y + i32(params.user_${r}_dims.y) * z))];\n}`)}for(let e=0;e f32 {\n return constants_${t.name}[u32(x + ${i[0]} * (y + ${i[1]} * z))];\n}`)}this.translatedFunctions&&n.push(this.translatedFunctions);const o=1===this.output.length?[64,1,1]:[8,8,1];return this.workgroupSize=o,1===this.output.length?n.push(`@compute @workgroup_size(${o[0]}, ${o[1]}, ${o[2]})\nfn main(@builtin(global_invocation_id) gid : vec3) {\n let flat_index : u32 = gid.x + gid.y * params.dispatchWidth;\n threadGid = vec3(flat_index, 0u, 0u);\n if (flat_index >= params.outputX) { return; }\n let data_index : i32 = i32(flat_index);\n${this.translatedBody}\n}`):n.push(`@compute @workgroup_size(${o[0]}, ${o[1]}, ${o[2]})\nfn main(@builtin(global_invocation_id) gid : vec3) {\n threadGid = gid;\n if (gid.x >= params.outputX || gid.y >= params.outputY || gid.z >= params.outputZ) { return; }\n let data_index : i32 = i32(gid.x + params.outputX * (gid.y + params.outputY * gid.z));\n${this.translatedBody}\n}`),n.join("\n")}constantDimensions(e){const t=e instanceof p?Array.from(e.size):Array.from(c.getDimensions(e));for(;t.length<3;)t.push(1);return t}async _buildAsync(){const e=await l.acquire();this.context=e;const t=this._device=e.device,r=t.createShaderModule({code:this.compiledSource}),n=(await r.getCompilationInfo()).messages.filter(e=>"error"===e.type);if(n.length>0)throw new Error("Error compiling WGSL compute shader:\n"+n.map(e=>` ${e.lineNum}:${e.linePos} ${e.message}`).join("\n")+`\n--- generated WGSL ---\n${this.compiledSource}`);const{arrayArgs:s,bufferConstants:i,byteLength:a}=this.paramsLayout,o=[{binding:0,visibility:4,buffer:{type:"uniform"}}];for(let e=0;ei&&(s[1]=Math.ceil(s[0]/i),s[0]=Math.ceil(s[0]/s[1])),a=s[0]*t);for(let e=0;e<3;e++)if(s[e]>i)throw new Error(`output dimension ${e} needs ${s[e]} workgroups, over this device's limit of ${i}`);return{groups:s,dispatchWidth:a}}_ensureOutputBuffer(){const[e,t,r]=this.threadDim,n=e*t*r*4*this.componentCount;this.immutable&&this.pipeline&&this.outputBuffer&&(0===--this.outputBuffer._refs&&this.outputBuffer.destroy(),this.outputBuffer=null,this.bindGroupDirty=!0),this.outputBuffer&&this.outputBuffer.size>=n||(this.outputBuffer&&0===--this.outputBuffer._refs&&this.outputBuffer.destroy(),this._checkBufferSize(n,`output [${this.output.join(", ")}]`),this.outputBuffer=this._device.createBuffer({size:n,usage:132}),this.outputBuffer._refs=1,this.bindGroupDirty=!0)}_checkBufferSize(e,t){const r=this._device.limits,n=Math.min(r.maxStorageBufferBindingSize,r.maxBufferSize);if(e>n)throw new Error(`WebGPU backend: ${t} needs ${e} bytes but this device allows ${n} per storage buffer (maxStorageBufferBindingSize/maxBufferSize); reduce the output or split the work across kernels`)}_snapshotArguments(e){const t=new Array(e.length);for(let r=0;rthis._runInternal(e))}_runInternal(e){if(this.context&&this.context.isLost)throw new Error("WebGPU device was lost; call kernel.destroy() (or gpu.destroy()) and run again to rebuild on a fresh device");const t=this._device,r=t.queue,{arrayArgs:n,scalarArgs:s,bufferConstants:i}=this.paramsLayout,a=this.threadDim=Array.from(this.output);for(;a.length<3;)a.push(1);this._ensureOutputBuffer(),this.paramsU32[0]=a[0],this.paramsU32[1]=a[1],this.paramsU32[2]=a[2],this.paramsU32[3]=this._computeDispatch(a).dispatchWidth;for(let s=0;s{const e=new Float32Array(p.buffer.getMappedRange(0,u).slice(0));return p.buffer.unmap(),this._releaseStaging(p),this._shapeOutput(e,d,this.componentCount)},e=>{throw this._releaseStaging(p),e})}_acquireStaging(e){for(let t=0;t=e)return r.busy=!0,r}const t={buffer:this._device.createBuffer({size:e,usage:9}),size:e,busy:!0,pooled:this.stagingPool.length<3};return t.pooled&&this.stagingPool.push(t),t}_releaseStaging(e){e.pooled?e.busy=!1:e.buffer.destroy()}_shapeOutput(e,t,r){const[n,s,i]=[t[0],t[1]||1,t[2]||1];if(1===r)switch(t.length){case 1:return c.erectMemoryOptimizedFloat(e,n);case 2:return c.erectMemoryOptimized2DFloat(e,n,s);default:return c.erectMemoryOptimized3DFloat(e,n,s,i)}const a=r,o=t=>{const r=new Array(n);for(let s=0;s{const t=new Float32Array(i.buffer.getMappedRange(0,s).slice(0));return i.buffer.unmap(),this._releaseStaging(i),this._shapeOutput(t,r,e.componentCount)},e=>{throw this._releaseStaging(i),e})}destroy(e){if(this.paramsBuffer&&(this.paramsBuffer.destroy(),this.paramsBuffer=null),this.paramsLayout)for(let e=0;e{const{utils:r}=i(),{Input:s}=n();function a(e,t){if(t.kernel)return void(t.kernel=e);const n=r.allPropertiesOf(e);for(let r=0;rt.kernel[s]),t.__defineSetter__(s,e=>{t.kernel[s]=e})))}t.kernel=e}t.exports={kernelRunShortcut:function(e){function t(t){e.build.apply(e,t),e.checkArgumentTypes(t);let n=e.switchingKernels?void 0:e.run.apply(e,t);for(let s=0;e.switchingKernels;s++){if(s>=4){const t=e.resetSwitchingKernels();throw new Error(`this kernel cannot run the arguments it was given (${r(t)}); it did not settle on a kernel for them after 4 attempts. Create a separate kernel for this call's argument types.`)}const i=e.resetSwitchingKernels(),a=e.onRequestSwitchKernel(i,t,e);c.kernel=e=a,a.checkArgumentTypes(t),n=a.switchingKernels?void 0:a.run.apply(a,t)}return n}function r(e){return e&&e.length?e.map(e=>"argumentTypeMismatch"===e.type?`argument ${e.index} is now ${e.needed}`:e.type).join(", "):"unknown reason"}function n(r){if(e.onAsyncModeUpgrade){const t=e.onAsyncModeUpgrade;e.onAsyncModeUpgrade=null;const s=u(r);return t(s,e).then(e=>(e&&c.replaceKernel(e),n(s)))}try{if(!0===e.constructor.isAsync)return e.build.apply(e,r),Promise.resolve(e.run.apply(e,r));for(let e=0;en(e));const s=t(r);return e.renderKernels?Promise.resolve(e.renderKernels()):e.renderOutput?e.renderOutputAsync?e.renderOutputAsync():Promise.resolve(e.renderOutput()):Promise.resolve(s)}catch(e){return Promise.reject(e)}}function i(e){return Boolean(e)&&"WebGPUBuffer"===e.type}function o(e){const t=u(e),r=[];for(let e=0;e{t[n]=e}))}return Promise.all(r).then(()=>t)}function u(e){const t=new Array(e.length);for(let r=0;r{try{e(h.apply(this,arguments))}catch(e){t(e)}})},c.replaceKernel=function(t){a(e=t,c)},a(e,c),c}}}),at=e((e,r)=>{const{gpuMock:n}=t(),{utils:s}=i(),{Kernel:o}=a(),{CPUKernel:u}=p(),{HeadlessGLKernel:l}=be(),{WebGL2Kernel:h}=et(),{WebGLKernel:c}=xe(),{WebGPUKernel:d}=st(),{kernelRunShortcut:m}=it(),f=[l,h,c],g=["gpu","cpu"],y={headlessgl:l,webgl2:h,webgl:c,webgpu:d};let x=!0;function b(e){if(!e)return{};const t=Object.assign({},e);return e.hasOwnProperty("floatOutput")&&(s.warnDeprecated("setting","floatOutput","precision"),t.precision=e.floatOutput?"single":"unsigned"),e.hasOwnProperty("outputToTexture")&&(s.warnDeprecated("setting","outputToTexture","pipeline"),t.pipeline=Boolean(e.outputToTexture)),e.hasOwnProperty("outputImmutable")&&(s.warnDeprecated("setting","outputImmutable","immutable"),t.immutable=Boolean(e.outputImmutable)),e.hasOwnProperty("floatTextures")&&(s.warnDeprecated("setting","floatTextures","optimizeFloatMemory"),t.optimizeFloatMemory=Boolean(e.floatTextures)),t}r.exports={GPU:class e{static disableValidation(){x=!1}static enableValidation(){x=!0}static get isGPUSupported(){return f.some(e=>e.isSupported)}static get isKernelMapSupported(){return f.some(e=>e.isSupported&&e.features.kernelMap)}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return c.isSupported}static get isWebGL2Supported(){return h.isSupported}static get isHeadlessGLSupported(){return l.isSupported}static get isWebGPUSupported(){return d.isSupported}static isWebGPUAvailable(){return d.isSupported?navigator.gpu.requestAdapter().then(e=>null!==e,()=>!1):Promise.resolve(!1)}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return h.isSupported}static get isSinglePrecisionSupported(){return f.some(e=>e.isSupported&&e.features.isFloatRead&&e.features.isTextureFloat)}constructor(e){if(e=e||{},this.canvas=e.canvas||null,this.context=e.context||null,this.mode=e.mode,this.Kernel=null,this.kernels=[],this.functions=[],this.nativeFunctions=[],this.injectedNative=null,"dev"!==this.mode){if(this.chooseKernel(),e.functions)for(let t=0;tr.argumentTypes[e]));const h=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate:x,onRequestFallback:l,onRequestSwitchKernel:function e(r,n,s){s.debug&&console.warn("Switching kernels");let o=null;if(s.signature&&!a[s.signature]&&(a[s.signature]=s),s.dynamicOutput)for(let e=r.length-1;e>=0;e--){const t=r[e];"outputPrecisionMismatch"===t.type&&(o=t.needed)}const u=s.constructor,h=u.getArgumentTypes(s,n),c=u.getSignature(s,h),d=a[c];if(d)return d.onActivate(s),d;const m=a[c]=new u(t,{argumentTypes:h,constantTypes:s.constantTypes,graphical:s.graphical,loopMaxIterations:s.loopMaxIterations,constants:s.constants,dynamicOutput:s.dynamicOutput,dynamicArgument:s.dynamicArguments,context:s.context,canvas:s.canvas,output:o||s.output,precision:s.precision,pipeline:s.pipeline,immutable:s.immutable,optimizeFloatMemory:s.optimizeFloatMemory,fixIntegerDivisionAccuracy:s.fixIntegerDivisionAccuracy,functions:s.functions,nativeFunctions:s.nativeFunctions,injectedNative:s.injectedNative,subKernels:s.subKernels,strictIntegers:s.strictIntegers,randomSeed:s.randomSeed,debug:s.debug,asyncMode:s.asyncMode,gpu:s.gpu,validate:x,returnType:s.returnType,tactic:s.tactic,onRequestFallback:l,onRequestSwitchKernel:e,texture:s.texture,mappedTextures:s.mappedTextures,drawBuffersMap:s.drawBuffersMap});return m.build.apply(m,n),p.replaceKernel(m),i.push(m),m}},o);"async"===this.mode&&(h.asyncMode=!0);const c=new this.Kernel(t,h),p=m(c);if("async"===this.mode&&d.isSupported&&!(c instanceof d)){const r=this;c.onAsyncModeUpgrade=function(n,s){return e.isWebGPUAvailable().then(e=>{if(!e)return null;let a;try{a=new d(t,{functions:s.functions,nativeFunctions:s.nativeFunctions,injectedNative:s.injectedNative,gpu:r,validate:x,asyncMode:!0,output:s.output,pipeline:s.pipeline,immutable:s.immutable,dynamicOutput:s.dynamicOutput,dynamicArguments:!0,loopMaxIterations:s.loopMaxIterations,constants:s.constants,constantTypes:s.constantTypes,argumentTypes:s.argumentTypes,precision:s.precision,tactic:s.tactic,strictIntegers:s.strictIntegers,fixIntegerDivisionAccuracy:s.fixIntegerDivisionAccuracy,subKernels:s.subKernels,graphical:s.graphical,debug:s.debug}),a.build.apply(a,n)}catch(e){return s.debug&&console.warn("webgpu upgrade declined: "+e.message),null}return a._buildPromise.then(()=>(i.push(a),a),e=>(s.debug&&console.warn("webgpu upgrade declined: "+e.message),a.destroy(),null))},()=>null)}}return this.canvas||(this.canvas=c.canvas),this.context||(this.context=c.context),i.push(c),p}createKernelMap(){let e,t;const r=typeof arguments[arguments.length-2];if("function"===r||"string"===r?(e=arguments[arguments.length-2],t=arguments[arguments.length-1]):e=arguments[arguments.length-1],!("dev"===this.mode||this.Kernel.isSupported&&this.Kernel.features.kernelMap)){if("webgpu"===this.Kernel.mode)throw new Error("WebGPU backend does not yet support createKernelMap");if(this.mode&&g.indexOf(this.mode)<0)throw new Error(`kernelMap not supported on ${this.Kernel.name}`)}const n=b(t);if(t&&"object"==typeof t.argumentTypes&&(n.argumentTypes=Object.keys(t.argumentTypes).map(e=>t.argumentTypes[e])),Array.isArray(arguments[0])){n.subKernels=[];const e=arguments[0];for(let t=0;t0)throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');return this.nativeFunctions.push(Object.assign({name:e,source:t},r)),this}injectNative(e){return this.injectedNative=e,this}destroy(){return new Promise((e,t)=>{this.kernels||e(),setTimeout(()=>{try{const e=this.kernels.slice();for(let t=0;t{const{utils:r}=i();t.exports={alias:function(e,t){const n=t.toString();return new Function(`return function ${e} (${r.getArgumentNamesFromString(n).join(", ")}) {\n ${r.getFunctionBodyFromString(n)}\n}`)()}}}),ut=e((e,t)=>{const{GPU:r}=at(),{alias:c}=ot(),{utils:d}=i(),{Input:m,input:f}=n(),{Texture:g}=s(),{FunctionBuilder:y}=o(),{FunctionNode:x}=l(),{CPUFunctionNode:b}=h(),{CPUKernel:T}=p(),{HeadlessGLKernel:S}=be(),{WebGLFunctionNode:A}=z(),{WebGLKernel:w}=xe(),{kernelValueMaps:E}=ye(),{WebGL2FunctionNode:_}=Te(),{WebGL2Kernel:v}=et(),{kernelValueMaps:I}=Qe(),{WGSLFunctionNode:$}=tt(),{WebGPUKernel:D}=st(),{WebGPUContext:F}=rt(),{WebGPUBufferResult:L}=nt(),{GLKernel:R}=k(),{Kernel:G}=a(),{FunctionTracer:C}=u();t.exports={alias:c,CPUFunctionNode:b,CPUKernel:T,GPU:r,FunctionBuilder:y,FunctionNode:x,HeadlessGLKernel:S,Input:m,input:f,Texture:g,utils:d,WebGL2FunctionNode:_,WebGL2Kernel:v,webGL2KernelValueMaps:I,WebGLFunctionNode:A,WebGLKernel:w,webGLKernelValueMaps:E,WGSLFunctionNode:$,WebGPUKernel:D,WebGPUContext:F,WebGPUBufferResult:L,GLKernel:R,Kernel:G,FunctionTracer:C,plugins:{mathRandom:M()}}});return e((e,t)=>{const r=ut(),n=r.GPU;for(const e in r)r.hasOwnProperty(e)&&"GPU"!==e&&(n[e]=r[e]);function s(e){e.GPU&&e.GPU.prototype&&e.GPU.prototype.createKernel||Object.defineProperty(e,"GPU",{configurable:!0,get:()=>n,set(){}})}n.GPU=n,"undefined"!=typeof window&&s(window),"undefined"!=typeof self&&s(self),t.exports=n})()}); \ No newline at end of file diff --git a/dist/gpu-browser.js b/dist/gpu-browser.js index 920e738f..dfa048a7 100644 --- a/dist/gpu-browser.js +++ b/dist/gpu-browser.js @@ -1,11 +1,11 @@ /** * gpu.js - * http://gpu.rocks/ + * https://gpu.rocks/ * * GPU Accelerated JavaScript * * @version 2.19.9 - * @date Wed Jul 29 2026 05:05:55 GMT+0800 (Singapore Standard Time) + * @date Thu Jul 30 2026 13:21:38 GMT+0800 (Singapore Standard Time) * * @license MIT * The MIT License @@ -4541,6 +4541,25 @@ isArray(array) { return !isNaN(array.length); }, + typeFitsValue(type, value) { + if (typeof type !== "string" || value === null || value === void 0) return true; + if (value.type) return true; + switch (type) { + case "Input": + return value instanceof Input; + + case "Boolean": + return typeof value === "boolean"; + + case "Number": + case "Integer": + case "Float": + return typeof value === "number"; + } + if (type.indexOf("Texture") !== -1) return Boolean(value.type); + if (type.indexOf("Array") === 0) return utils.isArray(value); + return true; + }, getVariableType(value, strictIntegers) { if (utils.isArray(value)) { if (value.length > 0 && value[0].nodeName === "IMG") return "HTMLImageArray"; @@ -5210,7 +5229,7 @@ utils: utils }; }); - var require_kernel$5 = __commonJSMin((exports, module) => { + var require_kernel$6 = __commonJSMin((exports, module) => { const {utils: utils} = require_utils(); const {Input: Input} = require_input(); var Kernel = class { @@ -5243,6 +5262,7 @@ this.useLegacyEncoder = false; this.fallbackRequested = false; this.onRequestFallback = null; + this.onRequestSwitchKernel = null; this.argumentNames = typeof source === "string" ? utils.getArgumentNamesFromString(source) : null; this.argumentTypes = null; this.argumentSizes = null; @@ -5271,6 +5291,7 @@ this.validate = true; this.immutable = false; this.pipeline = false; + this.asyncMode = false; this.precision = null; this.tactic = null; this.plugins = null; @@ -5283,6 +5304,7 @@ this.randomSeed = null; this.built = false; this.signature = null; + this.switchingKernels = null; } mergeSettings(settings) { for (let p in settings) { @@ -5450,6 +5472,10 @@ this.pipeline = flag; return this; } + setAsyncMode(flag) { + this.asyncMode = flag; + return this; + } setPrecision(flag) { this.precision = flag; return this; @@ -5609,11 +5635,11 @@ case "Integer": case "Float": case "ArrayTexture(1)": - argumentTypes[i] = utils.getVariableType(arg); + argumentTypes[i] = utils.getVariableType(arg, kernel.strictIntegers); break; default: - argumentTypes[i] = type; + argumentTypes[i] = utils.typeFitsValue(type, arg) ? type : utils.getVariableType(arg, kernel.strictIntegers); } } return argumentTypes; @@ -5634,6 +5660,23 @@ }; } onActivate(previousKernel) {} + switchKernels(reason) { + if (this.switchingKernels) this.switchingKernels.push(reason); else this.switchingKernels = [ reason ]; + } + resetSwitchingKernels() { + const existingValue = this.switchingKernels; + this.switchingKernels = null; + return existingValue; + } + checkArgumentTypes(args) { + if (!this.argumentTypes) return; + const length = Math.min(args.length, this.argumentTypes.length); + for (let i = 0; i < length; i++) if (!utils.typeFitsValue(this.argumentTypes[i], args[i])) this.switchKernels({ + type: "argumentTypeMismatch", + index: i, + needed: utils.getVariableType(args[i], this.strictIntegers) + }); + } }; function splitArgumentTypes(argumentTypesObject) { const argumentNames = Object.keys(argumentTypesObject); @@ -6285,7 +6328,7 @@ FunctionTracer: FunctionTracer }; }); - var require_function_node$3 = __commonJSMin((exports, module) => { + var require_function_node$4 = __commonJSMin((exports, module) => { const acorn = require_acorn(); const {utils: utils} = require_utils(); const {FunctionTracer: FunctionTracer} = require_function_tracer(); @@ -7345,8 +7388,8 @@ FunctionNode: FunctionNode }; }); - var require_function_node$2 = __commonJSMin((exports, module) => { - const {FunctionNode: FunctionNode} = require_function_node$3(); + var require_function_node$3 = __commonJSMin((exports, module) => { + const {FunctionNode: FunctionNode} = require_function_node$4(); var CPUFunctionNode = class extends FunctionNode { astFunction(ast, retArr) { if (!this.isRootKernel) { @@ -7877,10 +7920,10 @@ cpuKernelString: cpuKernelString }; }); - var require_kernel$4 = __commonJSMin((exports, module) => { - const {Kernel: Kernel} = require_kernel$5(); + var require_kernel$5 = __commonJSMin((exports, module) => { + const {Kernel: Kernel} = require_kernel$6(); const {FunctionBuilder: FunctionBuilder} = require_function_builder(); - const {CPUFunctionNode: CPUFunctionNode} = require_function_node$2(); + const {CPUFunctionNode: CPUFunctionNode} = require_function_node$3(); const {utils: utils} = require_utils(); const {cpuKernelString: cpuKernelString} = require_kernel_string$1(); var CPUKernel = class extends Kernel { @@ -8693,8 +8736,8 @@ GLTextureGraphical: GLTextureGraphical }; }); - var require_kernel$3 = __commonJSMin((exports, module) => { - const {Kernel: Kernel} = require_kernel$5(); + var require_kernel$4 = __commonJSMin((exports, module) => { + const {Kernel: Kernel} = require_kernel$6(); const {utils: utils} = require_utils(); const {GLTextureArray2Float: GLTextureArray2Float} = require_array_2_float(); const {GLTextureArray2Float2D: GLTextureArray2Float2D} = require_array_2_float_2d(); @@ -9348,11 +9391,6 @@ if (this.immutable) for (let i = 0; i < this.subKernels.length; i++) result[this.subKernels[i].property] = this.mappedTextures[i].clone(); else for (let i = 0; i < this.subKernels.length; i++) result[this.subKernels[i].property] = this.mappedTextures[i]; return result; } - resetSwitchingKernels() { - const existingValue = this.switchingKernels; - this.switchingKernels = null; - return existingValue; - } setOutput(output) { const newOutput = this.toKernelOutput(output); if (this.program) { @@ -9401,9 +9439,6 @@ renderValues() { return this.formatValues(this.transferValues(), this.output[0], this.output[1], this.output[2]); } - switchKernels(reason) { - if (this.switchingKernels) this.switchingKernels.push(reason); else this.switchingKernels = [ reason ]; - } getVariablePrecisionString(textureSize = this.texSize, tactic = this.tactic, isInt = false) { if (!tactic) { if (!this.constructor.features.isSpeedTacticSupported) return "highp"; @@ -9481,9 +9516,9 @@ GLKernel: GLKernel }; }); - var require_function_node$1 = __commonJSMin((exports, module) => { + var require_function_node$2 = __commonJSMin((exports, module) => { const {utils: utils} = require_utils(); - const {FunctionNode: FunctionNode} = require_function_node$3(); + const {FunctionNode: FunctionNode} = require_function_node$4(); var WebGLFunctionNode = class extends FunctionNode { constructor(source, settings) { super(source, settings); @@ -13079,6 +13114,7 @@ if (!precision) throw new Error("precision missing"); if (value.type) type = value.type; const types = kernelValueMaps[precision][dynamic]; + if (type === "WebGPUBuffer") throw new Error("this kernel runs on WebGL but received a WebGPU pipeline buffer; await handle.toArray() first, or give this kernel the async contract (asyncMode: true / mode: 'async') so the readback happens for you"); if (types[type] === false) return null; else if (types[type] === void 0) throw new Error(`Could not find a KernelValue for ${type}`); return types[type]; } @@ -13087,10 +13123,10 @@ kernelValueMaps: kernelValueMaps }; }); - var require_kernel$2 = __commonJSMin((exports, module) => { - const {GLKernel: GLKernel} = require_kernel$3(); + var require_kernel$3 = __commonJSMin((exports, module) => { + const {GLKernel: GLKernel} = require_kernel$4(); const {FunctionBuilder: FunctionBuilder} = require_function_builder(); - const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$1(); + const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$2(); const {utils: utils} = require_utils(); const mrud = require_math_random_uniformly_distributed(); const {fragmentShader: fragmentShader} = require_fragment_shader$1(); @@ -14037,9 +14073,9 @@ WebGLKernel: WebGLKernel }; }); - var require_kernel$1 = __commonJSMin((exports, module) => { + var require_kernel$2 = __commonJSMin((exports, module) => { const getContext = require_empty_module(); - const {WebGLKernel: WebGLKernel} = require_kernel$2(); + const {WebGLKernel: WebGLKernel} = require_kernel$3(); const {glKernelString: glKernelString} = require_kernel_string(); let isSupported = null; let testCanvas = null; @@ -14151,9 +14187,9 @@ HeadlessGLKernel: HeadlessGLKernel }; }); - var require_function_node = __commonJSMin((exports, module) => { + var require_function_node$1 = __commonJSMin((exports, module) => { const {utils: utils} = require_utils(); - const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$1(); + const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$2(); var WebGL2FunctionNode = class extends WebGLFunctionNode { astIdentifierExpression(idtNode, retArr) { if (idtNode.type !== "Identifier") throw this.astErrorOutput("IdentifierExpression - not an Identifier", idtNode); @@ -14826,6 +14862,7 @@ if (!precision) throw new Error("precision missing"); if (value.type) type = value.type; const types = kernelValueMaps[precision][dynamic]; + if (type === "WebGPUBuffer") throw new Error("this kernel runs on WebGL but received a WebGPU pipeline buffer; await handle.toArray() first, or give this kernel the async contract (asyncMode: true / mode: 'async') so the readback happens for you"); if (types[type] === false) return null; else if (types[type] === void 0) throw new Error(`Could not find a KernelValue for ${type}`); return types[type]; } @@ -14834,9 +14871,9 @@ lookupKernelValueType: lookupKernelValueType }; }); - var require_kernel = __commonJSMin((exports, module) => { - const {WebGLKernel: WebGLKernel} = require_kernel$2(); - const {WebGL2FunctionNode: WebGL2FunctionNode} = require_function_node(); + var require_kernel$1 = __commonJSMin((exports, module) => { + const {WebGLKernel: WebGLKernel} = require_kernel$3(); + const {WebGL2FunctionNode: WebGL2FunctionNode} = require_function_node$1(); const {FunctionBuilder: FunctionBuilder} = require_function_builder(); const {utils: utils} = require_utils(); const {fragmentShader: fragmentShader} = require_fragment_shader(); @@ -15018,6 +15055,76 @@ gl.readPixels(0, 0, w, h, gl.RED, gl.FLOAT, result); return result; } + renderOutputAsync() { + if (this.renderOutput !== this.renderValues) return Promise.resolve(this.renderOutput()); + return this.renderValuesAsync(); + } + renderValuesAsync() { + if (this._tightRead === void 0) this._detectTightRead(); + const formatValues = this.formatValues; + const [x, y, z] = this.output; + return this.transferValuesAsync().then(pixels => formatValues(pixels, x, y, z)); + } + transferValuesAsync() { + const {texSize: texSize, context: gl} = this; + const w = texSize[0]; + const h = texSize[1]; + let format, type, result; + if (this.precision === "single") { + format = this._tightRead ? gl.RED : gl.RGBA; + type = gl.FLOAT; + result = new Float32Array(w * h * (this._tightRead ? 1 : 4)); + } else { + format = gl.RGBA; + type = gl.UNSIGNED_BYTE; + result = new Uint8Array(w * h * 4); + } + const pbo = gl.createBuffer(); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo); + gl.bufferData(gl.PIXEL_PACK_BUFFER, result.byteLength, gl.STREAM_READ); + gl.readPixels(0, 0, w, h, format, type, 0); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); + const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0); + gl.flush(); + return this._pollFence(sync).then(() => { + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo); + gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, result); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); + gl.deleteBuffer(pbo); + return this.precision === "single" ? result : new Float32Array(result.buffer); + }, error => { + gl.deleteBuffer(pbo); + throw error; + }); + } + _pollFence(sync) { + const gl = this.context; + return new Promise((resolve, reject) => { + let schedule; + let channel = null; + if (typeof MessageChannel !== "undefined") { + channel = new MessageChannel; + channel.port1.onmessage = () => poll(); + schedule = () => channel.port2.postMessage(0); + } else schedule = () => setTimeout(poll, 0); + const settle = (fn, value) => { + gl.deleteSync(sync); + if (channel) { + channel.port1.close(); + channel.port2.close(); + } + fn(value); + }; + const poll = () => { + if (gl.isContextLost()) return settle(reject, new Error("WebGL context lost while awaiting kernel result")); + const status = gl.clientWaitSync(sync, 0, 0); + if (status === gl.ALREADY_SIGNALED || status === gl.CONDITION_SATISFIED) return settle(resolve); + if (status === gl.WAIT_FAILED) return settle(reject, new Error("clientWaitSync failed while awaiting kernel result")); + schedule(); + }; + poll(); + }); + } _detectTightRead() { const gl = this.context; this._tightRead = false; @@ -15250,181 +15357,2302 @@ WebGL2Kernel: WebGL2Kernel }; }); - var require_kernel_run_shortcut = __commonJSMin((exports, module) => { - const {utils: utils} = require_utils(); - function kernelRunShortcut(kernel) { - let run = function() { - kernel.build.apply(kernel, arguments); - run = function() { - let result = kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - const reasons = kernel.resetSwitchingKernels(); - const newKernel = kernel.onRequestSwitchKernel(reasons, arguments, kernel); - shortcut.kernel = kernel = newKernel; - result = newKernel.run.apply(newKernel, arguments); - } - if (kernel.renderKernels) return kernel.renderKernels(); else if (kernel.renderOutput) return kernel.renderOutput(); else return result; - }; - return run.apply(kernel, arguments); - }; - const shortcut = function() { - return run.apply(kernel, arguments); - }; - shortcut.exec = function() { - return new Promise((accept, reject) => { - try { - accept(run.apply(this, arguments)); - } catch (e) { - reject(e); - } - }); - }; - shortcut.replaceKernel = function(replacementKernel) { - kernel = replacementKernel; - bindKernelToShortcut(kernel, shortcut); - }; - bindKernelToShortcut(kernel, shortcut); - return shortcut; - } - function bindKernelToShortcut(kernel, shortcut) { - if (shortcut.kernel) { - shortcut.kernel = kernel; - return; - } - const properties = utils.allPropertiesOf(kernel); - for (let i = 0; i < properties.length; i++) { - const property = properties[i]; - if (property[0] === "_" && property[1] === "_") continue; - if (typeof kernel[property] === "function") if (property.substring(0, 3) === "add" || property.substring(0, 3) === "set") shortcut[property] = function() { - shortcut.kernel[property].apply(shortcut.kernel, arguments); - return shortcut; - }; else shortcut[property] = function() { - return shortcut.kernel[property].apply(shortcut.kernel, arguments); - }; else { - shortcut.__defineGetter__(property, () => shortcut.kernel[property]); - shortcut.__defineSetter__(property, value => { - shortcut.kernel[property] = value; - }); - } - } - shortcut.kernel = kernel; - } - module.exports = { - kernelRunShortcut: kernelRunShortcut - }; - }); - var require_gpu = __commonJSMin((exports, module) => { - const {gpuMock: gpuMock} = require_gpu_mock_js(); + var require_function_node = __commonJSMin((exports, module) => { const {utils: utils} = require_utils(); - const {Kernel: Kernel} = require_kernel$5(); - const {CPUKernel: CPUKernel} = require_kernel$4(); - const {HeadlessGLKernel: HeadlessGLKernel} = require_kernel$1(); - const {WebGL2Kernel: WebGL2Kernel} = require_kernel(); - const {WebGLKernel: WebGLKernel} = require_kernel$2(); - const {kernelRunShortcut: kernelRunShortcut} = require_kernel_run_shortcut(); - const kernelOrder = [ HeadlessGLKernel, WebGL2Kernel, WebGLKernel ]; - const kernelTypes = [ "gpu", "cpu" ]; - const internalKernels = { - headlessgl: HeadlessGLKernel, - webgl2: WebGL2Kernel, - webgl: WebGLKernel - }; - let validate = true; - var GPU = class { - static disableValidation() { - validate = false; - } - static enableValidation() { - validate = true; - } - static get isGPUSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported); - } - static get isKernelMapSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap); - } - static get isOffscreenCanvasSupported() { - return typeof Worker !== "undefined" && typeof OffscreenCanvas !== "undefined" || typeof importScripts !== "undefined"; - } - static get isWebGLSupported() { - return WebGLKernel.isSupported; - } - static get isWebGL2Supported() { - return WebGL2Kernel.isSupported; + const {FunctionNode: FunctionNode} = require_function_node$4(); + var WGSLFunctionNode = class extends FunctionNode { + wgslFloat(value) { + if (value === Infinity) return "0x1.fffffep+127"; + if (value === -Infinity) return "-0x1.fffffep+127"; + if (value > 34028234663852886e22) return "0x1.fffffep+127"; + if (value < -34028234663852886e22) return "-0x1.fffffep+127"; + const str = `${value}`; + if (str.indexOf(".") !== -1 || str.indexOf("e") !== -1 || str.indexOf("E") !== -1) return str; + return `${str}.0`; + } + wgslInt(value) { + return `${Math.round(value)}`; + } + mangleFunctionName(name) { + if (reservedNames.indexOf(name) !== -1) return `fn_${name}`; + return utils.sanitizeName(name); } - static get isHeadlessGLSupported() { - return HeadlessGLKernel.isSupported; - } - static get isCanvasSupported() { - return typeof HTMLCanvasElement !== "undefined"; + getLookupType(type) { + if (type === "WebGPUBuffer") return "Number"; + return super.getLookupType(type); } - static get isGPUHTMLImageArraySupported() { - return WebGL2Kernel.isSupported; + astUpdateExpression(uNode, retArr) { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + return retArr; } - static get isSinglePrecisionSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); + getType(ast) { + if (ast && ast.type === "ConditionalExpression") { + const consequentType = this.getType(ast.consequent); + if (consequentType === "Integer" || consequentType === "LiteralInteger") { + const alternateType = this.getType(ast.alternate); + if (alternateType === "Number" || alternateType === "Float") return "Number"; + } + } + return super.getType(ast); } - constructor(settings) { - settings = settings || {}; - this.canvas = settings.canvas || null; - this.context = settings.context || null; - this.mode = settings.mode; - this.Kernel = null; - this.kernels = []; - this.functions = []; - this.nativeFunctions = []; - this.injectedNative = null; - if (this.mode === "dev") return; - this.chooseKernel(); - if (settings.functions) for (let i = 0; i < settings.functions.length; i++) this.addFunction(settings.functions[i]); - if (settings.nativeFunctions) for (const p in settings.nativeFunctions) { - if (!settings.nativeFunctions.hasOwnProperty(p)) continue; - const s = settings.nativeFunctions[p]; - const {name: name, source: source} = s; - this.addNativeFunction(name, source, s); + astConditionalExpression(ast, retArr) { + if (ast.type !== "ConditionalExpression") throw this.astErrorOutput("Not a conditional expression", ast); + const consequentType = this.getType(ast.consequent); + const alternateType = this.getType(ast.alternate); + if (consequentType === null && alternateType === null) { + retArr.push("if ("); + this.astGeneric(ast.test, retArr); + retArr.push(") {"); + this.astGeneric(ast.consequent, retArr); + retArr.push(";"); + retArr.push("} else {"); + this.astGeneric(ast.alternate, retArr); + retArr.push(";"); + retArr.push("}"); + return retArr; } + let targetType = consequentType === "LiteralInteger" ? "Number" : consequentType; + if (targetType === "Integer" && (alternateType === "Number" || alternateType === "Float")) targetType = "Number"; + const emitBranch = branch => { + const branchType = this.getType(branch); + switch (targetType) { + case "Number": + case "Float": + if (branchType === "Integer") this.castValueToFloat(branch, retArr); else if (branchType === "LiteralInteger") this.castLiteralToFloat(branch, retArr); else this.astGeneric(branch, retArr); + break; + + case "Integer": + if (branchType === "Number" || branchType === "Float") this.castValueToInteger(branch, retArr); else if (branchType === "LiteralInteger") this.castLiteralToInteger(branch, retArr); else this.astGeneric(branch, retArr); + break; + + default: + this.astGeneric(branch, retArr); + } + }; + retArr.push("select("); + emitBranch(ast.alternate); + retArr.push(", "); + emitBranch(ast.consequent); + retArr.push(", "); + this.astGeneric(ast.test, retArr); + retArr.push(")"); + return retArr; } - chooseKernel() { - if (this.Kernel) return; - let Kernel = null; - if (this.context) { - for (let i = 0; i < kernelOrder.length; i++) { - const ExternalKernel = kernelOrder[i]; - if (ExternalKernel.isContextMatch(this.context)) { - if (!ExternalKernel.isSupported) throw new Error(`Kernel type ${ExternalKernel.name} not supported`); - Kernel = ExternalKernel; - break; - } + astFunction(ast, retArr) { + if (this.isRootKernel) { + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push("\n"); } - if (Kernel === null) throw new Error("unknown Context"); - } else if (this.mode) { - if (this.mode in internalKernels) { - if (!validate || internalKernels[this.mode].isSupported) Kernel = internalKernels[this.mode]; - } else if (this.mode === "gpu") { - for (let i = 0; i < kernelOrder.length; i++) if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; - } - } else if (this.mode === "cpu") Kernel = CPUKernel; - if (!Kernel) throw new Error(`A requested mode of "${this.mode}" and is not supported`); - } else { - for (let i = 0; i < kernelOrder.length; i++) if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; + return retArr; + } + if (!this.returnType) { + if (this.findLastReturn()) { + this.returnType = this.getType(ast.body); + if (this.returnType === "LiteralInteger") this.returnType = "Number"; } - if (!Kernel) Kernel = CPUKernel; } - if (!this.mode) this.mode = Kernel.mode; - this.Kernel = Kernel; - } - createKernel(source, settings) { - if (typeof source === "undefined") throw new Error("Missing source parameter"); - if (typeof source !== "object" && !utils.isFunction(source) && typeof source !== "string") throw new Error("source parameter not a function"); - const kernels = this.kernels; - if (this.mode === "dev") { - const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); - kernels.push(devKernel); - return devKernel; + const {returnType: returnType} = this; + let type = null; + if (returnType) { + type = typeMap[returnType]; + if (!type) throw this.astErrorOutput(`unknown return type ${returnType}`, ast); + } + retArr.push(`fn ${this.mangleFunctionName(this.name)}(`); + for (let i = 0; i < this.argumentNames.length; ++i) { + const argumentName = this.argumentNames[i]; + if (i > 0) retArr.push(", "); + let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)]; + if (!argumentType) throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast); + if (argumentType === "LiteralInteger") this.argumentTypes[i] = argumentType = "Number"; + const wgslType = typeMap[argumentType]; + if (!wgslType) throw this.astErrorOutput(`WebGPU backend does not yet support ${argumentType} arguments to helper functions`, ast); + retArr.push(`user_${utils.sanitizeName(argumentName)} : ${wgslType}`); + } + retArr.push(")"); + if (type) retArr.push(` -> ${type}`); + retArr.push(" {\n"); + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push("\n"); + } + retArr.push("}\n"); + return retArr; + } + astReturnStatement(ast, retArr) { + if (!ast.argument) throw this.astErrorOutput("Unexpected return statement", ast); + this.pushState("skip-literal-correction"); + const type = this.getType(ast.argument); + this.popState("skip-literal-correction"); + const result = []; + if (!this.returnType) if (type === "LiteralInteger" || type === "Integer") this.returnType = "Number"; else this.returnType = type; + switch (this.returnType) { + case "LiteralInteger": + case "Number": + case "Float": + switch (type) { + case "Integer": + result.push("f32("); + this.astGeneric(ast.argument, result); + result.push(")"); + break; + + case "LiteralInteger": + this.castLiteralToFloat(ast.argument, result); + if (this.getType(ast.argument) === "Integer") { + result.unshift("f32("); + result.push(")"); + } + break; + + default: + this.astGeneric(ast.argument, result); + } + break; + + case "Integer": + switch (type) { + case "Float": + case "Number": + this.castValueToInteger(ast.argument, result); + break; + + case "LiteralInteger": + this.castLiteralToInteger(ast.argument, result); + break; + + default: + this.astGeneric(ast.argument, result); + } + break; + + case "Boolean": + case "Array(4)": + case "Array(3)": + case "Array(2)": + this.astGeneric(ast.argument, result); + break; + + default: + throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast); + } + if (this.isRootKernel) switch (this.returnType) { + case "Array(4)": + case "Array(3)": + case "Array(2)": + { + const n = parseInt(this.returnType.substring(6), 10); + const temp = this.getInternalVariableName("kernelResultVec"); + retArr.push(`let ${temp} : ${typeMap[this.returnType]} = ${result.join("")};\n`); + for (let c = 0; c < n; c++) retArr.push(`result[data_index * ${n} + ${c}] = ${temp}.${vectorComponents[c]};\n`); + retArr.push("return;"); + break; + } + + case "Integer": + retArr.push(`result[data_index] = f32(${result.join("")});`); + retArr.push("return;"); + break; + + default: + retArr.push(`result[data_index] = ${result.join("")};`); + retArr.push("return;"); + } else if (this.isSubKernel) throw this.astErrorOutput("WebGPU backend does not yet support createKernelMap", ast); else retArr.push(`return ${result.join("")};`); + return retArr; + } + astLiteral(ast, retArr) { + if (ast.value === true || ast.value === false) { + retArr.push(ast.value ? "true" : "false"); + return retArr; + } + if (isNaN(ast.value)) throw this.astErrorOutput("Non-numeric literal not supported : " + ast.value, ast); + const key = this.astKey(ast); + if (Number.isInteger(ast.value)) if (this.isState("casting-to-integer") || this.isState("building-integer")) { + this.literalTypes[key] = "Integer"; + retArr.push(this.wgslInt(ast.value)); + } else { + this.literalTypes[key] = "Number"; + retArr.push(this.wgslFloat(ast.value)); + } else if (this.isState("casting-to-integer") || this.isState("building-integer")) { + this.literalTypes[key] = "Integer"; + retArr.push(this.wgslInt(ast.value)); + } else { + this.literalTypes[key] = "Number"; + retArr.push(this.wgslFloat(ast.value)); + } + return retArr; + } + astBinaryExpression(ast, retArr) { + if (this.checkAndUpconvertOperator(ast, retArr)) return retArr; + if (ast.operator === "/" || ast.operator === "%") { + retArr.push("("); + this.pushState("building-float"); + switch (this.getType(ast.left)) { + case "Integer": + this.castValueToFloat(ast.left, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(ast.left, retArr); + break; + + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(ast.operator); + switch (this.getType(ast.right)) { + case "Integer": + this.castValueToFloat(ast.right, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(ast.right, retArr); + break; + + default: + this.astGeneric(ast.right, retArr); + } + this.popState("building-float"); + retArr.push(")"); + return retArr; + } + retArr.push("("); + const leftType = this.getType(ast.left) || "Number"; + const rightType = this.getType(ast.right) || "Number"; + const key = leftType + " & " + rightType; + switch (key) { + case "Integer & Integer": + this.pushState("building-integer"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-integer"); + break; + + case "Number & Float": + case "Float & Number": + case "Float & Float": + case "Number & Number": + this.pushState("building-float"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-float"); + break; + + case "LiteralInteger & LiteralInteger": + if (this.isState("casting-to-integer") || this.isState("building-integer")) { + this.pushState("building-integer"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-integer"); + } else { + this.pushState("building-float"); + this.castLiteralToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); + this.popState("building-float"); + } + break; + + case "Integer & Float": + case "Integer & Number": + if ((ast.operator === ">" || ast.operator === "<") && ast.right.type === "Literal") { + if (!Number.isInteger(ast.right.value)) { + this.pushState("building-float"); + this.castValueToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-float"); + break; + } + } + this.pushState("building-integer"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState("casting-to-integer"); + if (ast.right.type === "Literal") { + const literalResult = []; + this.astGeneric(ast.right, literalResult); + if (this.getType(ast.right) === "Integer") retArr.push(literalResult.join("")); else throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); + } else { + retArr.push("i32("); + this.astGeneric(ast.right, retArr); + retArr.push(")"); + } + this.popState("casting-to-integer"); + this.popState("building-integer"); + break; + + case "Integer & LiteralInteger": + this.pushState("building-integer"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToInteger(ast.right, retArr); + this.popState("building-integer"); + break; + + case "Number & Integer": + this.pushState("building-float"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToFloat(ast.right, retArr); + this.popState("building-float"); + break; + + case "Float & LiteralInteger": + case "Number & LiteralInteger": + this.pushState("building-float"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); + this.popState("building-float"); + break; + + case "LiteralInteger & Float": + case "LiteralInteger & Number": + if (this.isState("casting-to-integer")) { + this.pushState("building-integer"); + this.castLiteralToInteger(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToInteger(ast.right, retArr); + this.popState("building-integer"); + } else { + this.pushState("building-float"); + this.castLiteralToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState("casting-to-float"); + this.astGeneric(ast.right, retArr); + this.popState("casting-to-float"); + this.popState("building-float"); + } + break; + + case "LiteralInteger & Integer": + this.pushState("building-integer"); + this.castLiteralToInteger(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-integer"); + break; + + case "Boolean & Boolean": + this.pushState("building-boolean"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState("building-boolean"); + break; + + case "Float & Integer": + this.pushState("building-float"); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToFloat(ast.right, retArr); + this.popState("building-float"); + break; + + default: + throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast); + } + retArr.push(")"); + return retArr; + } + checkAndUpconvertOperator(ast, retArr) { + if (this.checkAndUpconvertBitwiseOperators(ast, retArr)) return retArr; + if (ast.operator !== "**") return null; + retArr.push("_pow"); + retArr.push("("); + switch (this.getType(ast.left)) { + case "Integer": + this.castValueToFloat(ast.left, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(ast.left, retArr); + break; + + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(","); + switch (this.getType(ast.right)) { + case "Integer": + this.castValueToFloat(ast.right, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(ast.right, retArr); + break; + + default: + this.astGeneric(ast.right, retArr); + } + retArr.push(")"); + return retArr; + } + checkAndUpconvertBitwiseOperators(ast, retArr) { + if (!{ + "&": true, + "|": true, + "^": true, + "<<": true, + ">>": true, + ">>>": true + }[ast.operator]) return null; + const emitAsInteger = side => { + switch (this.getType(side)) { + case "Number": + case "Float": + this.castValueToInteger(side, retArr); + break; + + case "LiteralInteger": + this.castLiteralToInteger(side, retArr); + break; + + default: + this.pushState("building-integer"); + this.astGeneric(side, retArr); + this.popState("building-integer"); + } + }; + retArr.push("("); + if (ast.operator === ">>>") { + retArr.push("bitcast(bitcast("); + emitAsInteger(ast.left); + retArr.push(") >> u32("); + emitAsInteger(ast.right); + retArr.push("))"); + } else if (ast.operator === "<<" || ast.operator === ">>") { + emitAsInteger(ast.left); + retArr.push(` ${ast.operator} u32(`); + emitAsInteger(ast.right); + retArr.push(")"); + } else { + emitAsInteger(ast.left); + retArr.push(` ${ast.operator} `); + emitAsInteger(ast.right); + } + retArr.push(")"); + return retArr; + } + checkAndUpconvertBitwiseUnary(ast, retArr) { + if (ast.operator !== "~") return null; + retArr.push("~("); + switch (this.getType(ast.argument)) { + case "Number": + case "Float": + this.castValueToInteger(ast.argument, retArr); + break; + + case "LiteralInteger": + this.castLiteralToInteger(ast.argument, retArr); + break; + + default: + this.astGeneric(ast.argument, retArr); + } + retArr.push(")"); + return retArr; + } + astUnaryExpression(uNode, retArr) { + if (this.checkAndUpconvertBitwiseUnary(uNode, retArr)) return retArr; + if (uNode.operator === "+") { + this.astGeneric(uNode.argument, retArr); + return retArr; + } + if (uNode.prefix) { + retArr.push(uNode.operator); + this.astGeneric(uNode.argument, retArr); + } else { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + } + return retArr; + } + castLiteralToInteger(ast, retArr) { + this.pushState("casting-to-integer"); + this.astGeneric(ast, retArr); + this.popState("casting-to-integer"); + return retArr; + } + castLiteralToFloat(ast, retArr) { + this.pushState("casting-to-float"); + this.astGeneric(ast, retArr); + this.popState("casting-to-float"); + return retArr; + } + castValueToInteger(ast, retArr) { + this.pushState("casting-to-integer"); + retArr.push("i32("); + this.astGeneric(ast, retArr); + retArr.push(")"); + this.popState("casting-to-integer"); + return retArr; + } + castValueToFloat(ast, retArr) { + this.pushState("casting-to-float"); + retArr.push("f32("); + this.astGeneric(ast, retArr); + retArr.push(")"); + this.popState("casting-to-float"); + return retArr; + } + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== "Identifier") throw this.astErrorOutput("IdentifierExpression - not an Identifier", idtNode); + const type = this.getType(idtNode); + const name = utils.sanitizeName(idtNode.name); + if (idtNode.name === "Infinity") { + retArr.push("0x1.fffffep+127"); + return retArr; + } + if (this.isRootKernel && this.argumentNames.indexOf(idtNode.name) !== -1 && (type === "Number" || type === "Float" || type === "Integer" || type === "Boolean")) { + if (type === "Boolean") retArr.push(`bool(params.user_${name})`); else retArr.push(`params.user_${name}`); + return retArr; + } + retArr.push(`user_${name}`); + return retArr; + } + astForStatement(forNode, retArr) { + if (forNode.type !== "ForStatement") throw this.astErrorOutput("Invalid for statement", forNode); + const initArr = []; + const testArr = []; + const updateArr = []; + const bodyArr = []; + let isSafe = null; + if (forNode.init) { + const {declarations: declarations} = forNode.init; + if (declarations.length > 1) isSafe = false; + this.astGeneric(forNode.init, initArr); + for (let i = 0; i < declarations.length; i++) if (declarations[i].init && declarations[i].init.type !== "Literal") isSafe = false; + } else isSafe = false; + if (forNode.test) this.astGeneric(forNode.test, testArr); else isSafe = false; + if (forNode.update) { + if (forNode.update.type === "AssignmentExpression") this.pushState("assignment-as-statement"); + this.astGeneric(forNode.update, updateArr); + } else isSafe = false; + if (forNode.body) { + this.pushState("loop-body"); + this.astGeneric(forNode.body, bodyArr); + this.popState("loop-body"); + } + if (isSafe === null) isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); + if (isSafe) { + const initString = initArr.join(""); + const initNeedsSemiColon = initString[initString.length - 1] !== ";"; + retArr.push(`for (${initString}${initNeedsSemiColon ? ";" : ""}${testArr.join("")};${updateArr.join("")}){\n`); + retArr.push(bodyArr.join("")); + retArr.push("}\n"); + } else { + const iVariableName = this.getInternalVariableName("safeI"); + if (initArr.length > 0) retArr.push(initArr.join(""), "\n"); + retArr.push(`for (var ${iVariableName} : i32 = 0;${iVariableName} 0) retArr.push(`if (!(${testArr.join("")})) { break; }\n`); + retArr.push(bodyArr.join("")); + retArr.push(`\n${updateArr.join("")};`); + retArr.push("}\n"); + } + return retArr; + } + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== "WhileStatement") throw this.astErrorOutput("Invalid while statement", whileNode); + const iVariableName = this.getInternalVariableName("safeI"); + retArr.push(`for (var ${iVariableName} : i32 = 0;${iVariableName} { + if (!node || typeof node !== "object") return false; + if (Array.isArray(node)) return node.some(containsBreak); + if (node.type === "BreakStatement") return true; + if (node.type === "ForStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement" || node.type === "SwitchStatement") return false; + for (const key in node) { + if (key === "loc" || key === "range" || key === "parent") continue; + if (containsBreak(node[key])) return true; + } + return false; + }; + if (containsBreak(statements[i])) throw this.astErrorOutput("break inside a switch case is only supported as the case terminator", statements[i]); + } + for (let i = 0; i < statements.length; i++) { + this.astGeneric(statements[i], retArr); + retArr.push("\n"); + } + return retArr; + } + astSwitchStatement(ast, retArr) { + if (ast.type !== "SwitchStatement") throw this.astErrorOutput("Invalid switch statement", ast); + const {discriminant: discriminant, cases: cases} = ast; + const type = this.getType(discriminant); + const varName = `switchDiscriminant${this.astKey(ast, "_")}`; + switch (type) { + case "Float": + case "Number": + retArr.push(`var ${varName} : f32 = `); + this.astGeneric(discriminant, retArr); + retArr.push(";\n"); + break; + + case "Integer": + retArr.push(`var ${varName} : i32 = `); + this.astGeneric(discriminant, retArr); + retArr.push(";\n"); + break; + + default: + throw this.astErrorOutput(`Unhandled switch discriminant type "${type}"`, ast); + } + if (cases.length === 1 && !cases[0].test) { + this.astSwitchCaseConsequent(cases[0].consequent, retArr); + return retArr; + } + let fallingThrough = false; + let defaultResult = []; + let movingDefaultToEnd = false; + let pastFirstIf = false; + for (let i = 0; i < cases.length; i++) { + if (!cases[i].test) if (cases.length > i + 1) { + movingDefaultToEnd = true; + this.astSwitchCaseConsequent(cases[i].consequent, defaultResult); + continue; + } else retArr.push(" else {\n"); else { + if (i === 0 || !pastFirstIf) { + pastFirstIf = true; + retArr.push(`if (${varName} == `); + } else if (fallingThrough) { + retArr.push(`${varName} == `); + fallingThrough = false; + } else retArr.push(` else if (${varName} == `); + if (type === "Integer") switch (this.getType(cases[i].test)) { + case "Number": + case "Float": + this.castValueToInteger(cases[i].test, retArr); + break; + + case "LiteralInteger": + this.castLiteralToInteger(cases[i].test, retArr); + break; + } else switch (this.getType(cases[i].test)) { + case "LiteralInteger": + this.castLiteralToFloat(cases[i].test, retArr); + break; + + case "Integer": + this.castValueToFloat(cases[i].test, retArr); + break; + + default: + this.astGeneric(cases[i].test, retArr); + } + if (!cases[i].consequent || cases[i].consequent.length === 0) { + fallingThrough = true; + retArr.push(" || "); + continue; + } + retArr.push(`) {\n`); + } + this.astSwitchCaseConsequent(cases[i].consequent, retArr); + retArr.push("\n}"); + } + if (movingDefaultToEnd) { + retArr.push(" else {"); + retArr.push(defaultResult.join("")); + retArr.push("}"); + } + retArr.push("\n"); + return retArr; + } + astThisExpression(tNode, retArr) { + retArr.push("this"); + return retArr; + } + astSequenceExpression(sNode, retArr) { + const {expressions: expressions} = sNode; + if (expressions.length === 1) { + this.astGeneric(expressions[0], retArr); + return retArr; + } + throw this.astErrorOutput("WebGPU backend does not yet support the comma operator", sNode); + } + astMemberExpression(mNode, retArr) { + const {property: property, name: name, signature: signature, origin: origin, type: type, xProperty: xProperty, yProperty: yProperty, zProperty: zProperty} = this.getMemberExpressionDetails(mNode); + switch (signature) { + case "value.thread.value": + case "this.thread.value": + if (name !== "x" && name !== "y" && name !== "z") throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`", mNode); + retArr.push(`i32(threadGid.${name})`); + return retArr; + + case "this.output.value": + { + const axisIndex = { + x: 0, + y: 1, + z: 2 + }[name]; + if (axisIndex === void 0) throw this.astErrorOutput("Unexpected expression", mNode); + if (this.dynamicOutput) { + const member = `params.output${name.toUpperCase()}`; + if (this.isState("casting-to-float")) retArr.push(`f32(${member})`); else retArr.push(`i32(${member})`); + } else if (this.isState("casting-to-integer")) retArr.push(`${this.output[axisIndex]}`); else retArr.push(`${this.output[axisIndex]}.0`); + return retArr; + } + + case "value": + throw this.astErrorOutput("Unexpected expression", mNode); + + case "value[]": + case "value[][]": + case "value[][][]": + case "value[][][][]": + case "value.value": + if (origin === "Math") { + retArr.push(this.wgslFloat(Math[name])); + return retArr; + } + switch (property) { + case "r": + retArr.push(`user_${utils.sanitizeName(name)}.x`); + return retArr; + + case "g": + retArr.push(`user_${utils.sanitizeName(name)}.y`); + return retArr; + + case "b": + retArr.push(`user_${utils.sanitizeName(name)}.z`); + return retArr; + + case "a": + retArr.push(`user_${utils.sanitizeName(name)}.w`); + return retArr; + } + break; + + case "this.constants.value": + { + const value = this.constants[name]; + switch (type) { + case "Integer": + if (this.isState("casting-to-float")) retArr.push(this.wgslFloat(value)); else retArr.push(this.wgslInt(value)); + return retArr; + + case "Number": + case "Float": + if (this.isState("casting-to-integer")) retArr.push(this.wgslInt(value)); else retArr.push(this.wgslFloat(value)); + return retArr; + + case "Boolean": + retArr.push(value ? "true" : "false"); + return retArr; + + case "Array(2)": + case "Array(3)": + case "Array(4)": + { + const n = parseInt(type.substring(6), 10); + const parts = []; + for (let i = 0; i < n; i++) parts.push(this.wgslFloat(value[i])); + retArr.push(`${typeMap[type]}(${parts.join(", ")})`); + return retArr; + } + + default: + throw this.astErrorOutput(`WebGPU backend does not yet support constant type ${type}`, mNode); + } + } + + case "this.constants.value[]": + case "this.constants.value[][]": + case "this.constants.value[][][]": + case "this.constants.value[][][][]": + break; + + case "fn()[]": + this.astCallExpression(mNode.object, retArr); + retArr.push("["); + retArr.push(this.memberExpressionPropertyMarkup(property)); + retArr.push("]"); + return retArr; + + default: + throw this.astErrorOutput(`WebGPU backend does not yet support expression signature "${signature}"`, mNode); + } + const markupName = `${origin}_${utils.sanitizeName(name)}`; + switch (type) { + case "Array(2)": + case "Array(3)": + case "Array(4)": + this.astGeneric(mNode.object, retArr); + retArr.push("["); + retArr.push(this.memberExpressionPropertyMarkup(xProperty)); + retArr.push("]"); + break; + + case "Array": + case "Array2D": + case "Array3D": + case "Input": + case "WebGPUBuffer": + case "Number": + case "Float": + case "Integer": + retArr.push(`get_${markupName}(`); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(")"); + break; + + case "Matrix(2)": + case "Matrix(3)": + case "Matrix(4)": + throw this.astErrorOutput("WebGPU backend does not yet support Matrix types", mNode); + + default: + throw this.astErrorOutput(`WebGPU backend does not yet support member expression type "${type}"`, mNode); + } + return retArr; + } + astCallExpression(ast, retArr) { + if (!ast.callee) throw this.astErrorOutput("Unknown CallExpression", ast); + let functionName = null; + const isMathFunction = this.isAstMathFunction(ast); + if (isMathFunction || ast.callee.object && ast.callee.object.type === "ThisExpression") functionName = ast.callee.property.name; else if (ast.callee.type === "SequenceExpression" && ast.callee.expressions[0].type === "Literal" && !isNaN(ast.callee.expressions[0].raw)) functionName = ast.callee.expressions[1].property.name; else functionName = ast.callee.name; + if (!functionName) throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast); + let emitName = functionName; + if (isMathFunction) { + if (functionName === "random") throw this.astErrorOutput("WebGPU backend does not yet support Math.random", ast); + if (mathFunctionRenames[functionName]) functionName = mathFunctionRenames[functionName]; + emitName = functionName; + } else emitName = this.mangleFunctionName(functionName); + if (this.calledFunctions.indexOf(functionName) < 0) this.calledFunctions.push(functionName); + if (this.onFunctionCall) this.onFunctionCall(this.name, functionName, ast.arguments); + const needsIntegerWrap = isMathFunction && integerResultMathFunctions[functionName] && this.isState("building-integer"); + if (needsIntegerWrap) retArr.push("i32("); + retArr.push(emitName); + retArr.push("("); + if (isMathFunction) for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + const argumentType = this.getType(argument); + if (i > 0) retArr.push(", "); + switch (argumentType) { + case "Integer": + this.castValueToFloat(argument, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(argument, retArr); + break; + + default: + this.astGeneric(argument, retArr); + break; + } + } else { + const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + let targetType = targetTypes[i]; + if (i > 0) retArr.push(", "); + const argumentType = this.getType(argument); + if (!targetType) { + this.triggerImplyArgumentType(functionName, i, argumentType, this); + targetType = argumentType; + } + switch (argumentType) { + case "Boolean": + this.astGeneric(argument, retArr); + continue; + + case "Number": + case "Float": + if (targetType === "Integer") { + retArr.push("i32("); + this.astGeneric(argument, retArr); + retArr.push(")"); + continue; + } else if (targetType === "Number" || targetType === "Float") { + this.astGeneric(argument, retArr); + continue; + } else if (targetType === "LiteralInteger") { + this.castLiteralToFloat(argument, retArr); + continue; + } + break; + + case "Integer": + if (targetType === "Number" || targetType === "Float") { + retArr.push("f32("); + this.astGeneric(argument, retArr); + retArr.push(")"); + continue; + } else if (targetType === "Integer") { + this.astGeneric(argument, retArr); + continue; + } + break; + + case "LiteralInteger": + if (targetType === "Integer") { + this.castLiteralToInteger(argument, retArr); + continue; + } else if (targetType === "Number" || targetType === "Float") { + this.castLiteralToFloat(argument, retArr); + continue; + } else if (targetType === "LiteralInteger") { + this.astGeneric(argument, retArr); + continue; + } + break; + + case "Array(2)": + case "Array(3)": + case "Array(4)": + if (targetType === argumentType) { + if (argument.type === "Identifier") retArr.push(`user_${utils.sanitizeName(argument.name)}`); else this.astGeneric(argument, retArr); + continue; + } + break; + + case "Array": + case "Array2D": + case "Array3D": + case "Input": + case "WebGPUBuffer": + throw this.astErrorOutput("WebGPU backend does not yet support array arguments to helper functions", ast); + } + throw this.astErrorOutput(`Unhandled argument combination of ${argumentType} and ${targetType} for argument named "${argument.name}"`, ast); + } + } + retArr.push(")"); + if (needsIntegerWrap) retArr.push(")"); + return retArr; + } + astArrayExpression(arrNode, retArr) { + switch (this.getType(arrNode)) { + case "Matrix(2)": + case "Matrix(3)": + case "Matrix(4)": + throw this.astErrorOutput("WebGPU backend does not yet support Matrix types", arrNode); + } + const arrLen = arrNode.elements.length; + retArr.push(`vec${arrLen}(`); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) retArr.push(", "); + const subNode = arrNode.elements[i]; + switch (this.getType(subNode)) { + case "Integer": + this.castValueToFloat(subNode, retArr); + break; + + case "LiteralInteger": + this.castLiteralToFloat(subNode, retArr); + break; + + default: + this.astGeneric(subNode, retArr); + } + } + retArr.push(")"); + return retArr; + } + memberExpressionXYZ(x, y, z, retArr) { + if (z) retArr.push(this.memberExpressionPropertyMarkup(z), ", "); else retArr.push("0, "); + if (y) retArr.push(this.memberExpressionPropertyMarkup(y), ", "); else retArr.push("0, "); + retArr.push(this.memberExpressionPropertyMarkup(x)); + return retArr; + } + memberExpressionPropertyMarkup(property) { + if (!property) throw new Error("Property not set"); + const type = this.getType(property); + const result = []; + switch (type) { + case "Number": + case "Float": + this.castValueToInteger(property, result); + break; + + case "LiteralInteger": + this.castLiteralToInteger(property, result); + break; + + case "Integer": + this.pushState("building-integer"); + result.push("i32("); + this.astGeneric(property, result); + result.push(")"); + this.popState("building-integer"); + break; + + default: + this.astGeneric(property, result); + } + return result.join(""); + } + }; + const typeMap = { + Number: "f32", + Float: "f32", + Integer: "i32", + LiteralInteger: "f32", + Boolean: "bool", + "Array(2)": "vec2", + "Array(3)": "vec3", + "Array(4)": "vec4" + }; + const operatorMap = { + "===": "==", + "!==": "!=" + }; + const vectorComponents = [ "x", "y", "z", "w" ]; + const mathFunctionRenames = { + pow: "_pow", + round: "_round" + }; + const integerResultMathFunctions = { + ceil: true, + floor: true, + _round: true + }; + const reservedNames = [ "alias", "break", "case", "const", "const_assert", "continue", "continuing", "default", "diagnostic", "discard", "else", "enable", "false", "fn", "for", "if", "let", "loop", "override", "requires", "return", "struct", "switch", "true", "var", "while", "main", "params", "result", "gid", "threadGid", "data_index", "select", "abs", "acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", "ceil", "clamp", "cos", "cosh", "cross", "degrees", "distance", "dot", "exp", "exp2", "floor", "fma", "fract", "inverseSqrt", "length", "log", "log2", "max", "min", "mix", "modf", "normalize", "pow", "radians", "round", "sign", "sin", "sinh", "smoothstep", "sqrt", "step", "tan", "tanh", "trunc", "cbrt", "expm1", "fround", "imul", "log10", "log1p", "clz32", "_pow", "_round", "LOOP_MAX", "bitcast", "ptr", "array", "vec2", "vec3", "vec4", "mat2x2", "mat3x3", "mat4x4", "f32", "i32", "u32", "bool" ]; + module.exports = { + WGSLFunctionNode: WGSLFunctionNode + }; + }); + var require_context = __commonJSMin((exports, module) => { + let contextPromise = null; + module.exports = { + WebGPUContext: class WebGPUContext { + static get isSupported() { + return typeof navigator !== "undefined" && !!navigator.gpu; + } + static acquire() { + if (contextPromise) return contextPromise; + const promise = (async () => { + if (!WebGPUContext.isSupported) throw new Error("WebGPU is not supported on this platform (navigator.gpu is missing)"); + const adapter = await navigator.gpu.requestAdapter(); + if (!adapter) throw new Error("WebGPU is present (navigator.gpu) but no adapter is available. On headless Chromium there is no adapter; run headed. Use `await GPU.isWebGPUAvailable()` to feature-detect."); + const device = await adapter.requestDevice({ + requiredLimits: { + maxStorageBufferBindingSize: adapter.limits.maxStorageBufferBindingSize, + maxBufferSize: adapter.limits.maxBufferSize + } + }); + const context = { + adapter: adapter, + device: device, + isLost: false + }; + device.lost.then(info => { + context.isLost = true; + if (info.reason !== "destroyed") console.error(`gpu.js [webgpu]: device lost: ${info.message}`); + if (contextPromise === promise) contextPromise = null; + }); + device.onuncapturederror = e => { + console.error(`gpu.js [webgpu]: ${e.error.message}`); + }; + return context; + })(); + promise.catch(() => { + if (contextPromise === promise) contextPromise = null; + }); + return contextPromise = promise; + } + static destroy() { + if (!contextPromise) return Promise.resolve(); + const promise = contextPromise; + contextPromise = null; + return promise.then(({device: device}) => { + device.destroy(); + }, () => {}); + } + } + }; + }); + var require_buffer_result = __commonJSMin((exports, module) => { + module.exports = { + WebGPUBufferResult: class WebGPUBufferResult { + constructor(settings) { + this.buffer = settings.buffer; + this.output = settings.output; + this.componentCount = settings.componentCount || 1; + this.context = settings.context; + this.kernel = settings.kernel; + this.type = "WebGPUBuffer"; + this._deleted = false; + if (this.buffer._refs) this.buffer._refs++; else this.buffer._refs = 1; + } + toArray() { + if (this._deleted) return Promise.reject(new Error("WebGPUBufferResult has been deleted")); + return this.kernel.readBufferResult(this); + } + delete() { + if (this._deleted) return; + this._deleted = true; + if (--this.buffer._refs === 0) this.buffer.destroy(); + } + clone() { + return new WebGPUBufferResult(this); + } + } + }; + }); + var require_kernel = __commonJSMin((exports, module) => { + const {Kernel: Kernel} = require_kernel$6(); + const {FunctionBuilder: FunctionBuilder} = require_function_builder(); + const {WGSLFunctionNode: WGSLFunctionNode} = require_function_node(); + const {WebGPUContext: WebGPUContext} = require_context(); + const {WebGPUBufferResult: WebGPUBufferResult} = require_buffer_result(); + const {utils: utils} = require_utils(); + const {Input: Input} = require_input(); + const USAGE_STORAGE = 128; + const MAP_MODE_READ = 1; + const features = Object.freeze({ + kernelMap: false, + isIntegerDivisionAccurate: true, + isSpeedTacticSupported: false, + isTextureFloat: true, + isDrawBuffers: false, + kernelMapSize: 0, + channelCount: 1, + maxTextureSize: Infinity, + isFloatRead: true + }); + const wgslHelpers = { + _pow: "fn _pow(v1 : f32, v2 : f32) -> f32 {\n if (v2 == 0.0) { return 1.0; }\n return pow(v1, v2);\n}", + _round: "fn _round(x : f32) -> f32 {\n return floor(x + 0.5);\n}", + cbrt: "fn cbrt(x : f32) -> f32 {\n return sign(x) * pow(abs(x), 1.0 / 3.0);\n}", + expm1: "fn expm1(x : f32) -> f32 {\n return exp(x) - 1.0;\n}", + fround: "fn fround(x : f32) -> f32 {\n return x;\n}", + imul: "fn imul(a : f32, b : f32) -> f32 {\n return f32(i32(a) * i32(b));\n}", + log10: `fn log10(x : f32) -> f32 {\n return log2(x) * ${1 / Math.log2(10)};\n}`, + log1p: "fn log1p(x : f32) -> f32 {\n return log(1.0 + x);\n}", + clz32: "fn clz32(x : f32) -> f32 {\n return f32(countLeadingZeros(u32(x)));\n}" + }; + var WebGPUKernel = class extends Kernel { + static get isSupported() { + return WebGPUContext.isSupported; + } + static get isAsync() { + return true; + } + static isContextMatch(context) { + return Boolean(context && typeof context.createShaderModule === "function" && typeof context.createComputePipeline === "function"); + } + static getFeatures() { + return features; + } + static get features() { + return features; + } + static get mode() { + return "webgpu"; + } + static getSignature(kernel, argumentTypes) { + return "webgpu" + (argumentTypes.length > 0 ? ":" + argumentTypes.join(",") : ""); + } + static destroyContext(context) {} + static nativeFunctionArguments() { + throw new Error("WebGPU backend does not yet support native functions"); + } + static nativeFunctionReturnType() { + throw new Error("WebGPU backend does not yet support native functions"); + } + static combineKernels() { + throw new Error("WebGPU backend does not yet support combineKernels; chain kernels with `await` and pipeline mode instead"); + } + constructor(source, settings) { + super(source, settings); + if (settings) { + if (settings.graphical) throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend"); + if (settings.precision === "unsigned") throw new Error(`WebGPU backend does not yet support precision: 'unsigned'; it is single precision only`); + if (settings.subKernels) throw new Error("WebGPU backend does not yet support createKernelMap"); + } + this.mergeSettings(source.settings || settings); + if (this.precision === null) this.precision = "single"; + this.asyncMode = true; + this.threadDim = null; + this.componentCount = 1; + this.compiledSource = null; + this.translatedBody = null; + this.translatedFunctions = null; + this.paramsLayout = null; + this._buildPromise = null; + this._device = null; + this.computePipeline = null; + this.bindGroupLayout = null; + this.bindGroup = null; + this.bindGroupDirty = true; + this.paramsBuffer = null; + this.paramsMirror = null; + this.outputBuffer = null; + this.argumentBuffers = null; + this.constantBuffers = null; + this.stagingPool = []; + } + initCanvas() { + return null; + } + initContext() { + return null; + } + initPlugins(settings) { + return []; + } + setGraphical(flag) { + if (flag) throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend"); + return super.setGraphical(flag); + } + setOutput(output) { + const newOutput = this.toKernelOutput(output); + if (this.built) { + if (!this.dynamicOutput) throw new Error("Resizing a kernel with dynamicOutput: false is not possible"); + if (newOutput.length !== this.output.length) throw new Error("WebGPU backend does not yet support changing the output rank of a built kernel; the workgroup shape is fixed at build"); + } + this.output = newOutput; + return this; + } + toString() { + throw new Error("WebGPU backend does not yet support toString"); + } + validateSettings(args) { + if (this.graphical) throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend"); + if (this.precision === "unsigned") throw new Error(`WebGPU backend does not yet support precision: 'unsigned'; it is single precision only`); + this.precision = "single"; + if (this.subKernels && this.subKernels.length > 0) throw new Error("WebGPU backend does not yet support createKernelMap"); + if (!this.output || this.output.length === 0) { + if (args.length !== 1) throw new Error("Auto output only supported for kernels with only one input"); + const argType = utils.getVariableType(args[0], this.strictIntegers); + if (argType === "Array") this.output = Array.from(utils.getDimensions(args[0])); else if (argType === "WebGPUBuffer") this.output = Array.from(args[0].output); else throw new Error("Auto output not supported for input type: " + argType); + } + this.checkOutput(); + } + setupArguments(args) { + super.setupArguments(args); + for (let i = 0; i < this.argumentTypes.length; i++) switch (this.argumentTypes[i]) { + case "Array": + case "Input": + case "WebGPUBuffer": + case "Number": + case "Float": + case "Integer": + case "Boolean": + continue; + + default: + throw new Error(`WebGPU backend does not yet support argument type ${this.argumentTypes[i]} (argument "${this.argumentNames[i]}")`); + } + } + setupConstants() { + super.setupConstants(); + for (const name in this.constantTypes) switch (this.constantTypes[name]) { + case "Array": + case "Input": + case "Number": + case "Float": + case "Integer": + case "Boolean": + case "Array(2)": + case "Array(3)": + case "Array(4)": + continue; + + default: + throw new Error(`WebGPU backend does not yet support constant type ${this.constantTypes[name]} (constant "${name}")`); + } + } + build() { + if (this.built) return Promise.resolve(); + if (this._buildPromise) return this._buildPromise; + this.setupConstants(); + this.setupArguments(arguments); + this.validateSettings(arguments); + const threadDim = this.threadDim = Array.from(this.output); + while (threadDim.length < 3) threadDim.push(1); + this.translateSource(); + this.paramsLayout = this.computeParamsLayout(); + this.compiledSource = this.assembleWGSL(); + if (this.debug) { + console.log("WGSL Shader Output:"); + console.log(this.compiledSource); + } + this.buildSignature(arguments); + return this._buildPromise = this._buildAsync(); + } + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WGSLFunctionNode); + const prototypes = functionBuilder.getPrototypes("kernel"); + this.translatedBody = prototypes[prototypes.length - 1]; + this.translatedFunctions = prototypes.slice(0, -1).join("\n"); + if (!this.returnType) this.returnType = functionBuilder.getKernelResultType(); + switch (this.returnType) { + case "Number": + case "Float": + case "Integer": + case "LiteralInteger": + this.componentCount = 1; + break; + + case "Array(2)": + this.componentCount = 2; + break; + + case "Array(3)": + this.componentCount = 3; + break; + + case "Array(4)": + this.componentCount = 4; + break; + + default: + throw new Error(`WebGPU backend does not yet support returning ${this.returnType}`); + } + } + computeParamsLayout() { + const arrayArgs = []; + const scalarArgs = []; + let offset = 16; + for (let i = 0; i < this.argumentTypes.length; i++) { + const type = this.argumentTypes[i]; + const name = utils.sanitizeName(this.argumentNames[i]); + if (type === "Array" || type === "Input" || type === "WebGPUBuffer") { + arrayArgs.push({ + name: name, + index: i, + type: type, + dimsOffset: offset, + buffer: null, + boundBuffer: null + }); + offset += 16; + } else scalarArgs.push({ + name: name, + index: i, + type: type, + offset: null + }); + } + for (let i = 0; i < scalarArgs.length; i++) { + scalarArgs[i].offset = offset; + offset += 4; + } + const bufferConstants = []; + if (this.constants) for (const name in this.constants) { + if (!this.constants.hasOwnProperty(name)) continue; + const type = this.constantTypes[name]; + if (type === "Array" || type === "Input") bufferConstants.push({ + name: utils.sanitizeName(name), + constantName: name, + buffer: null + }); + } + return { + arrayArgs: arrayArgs, + scalarArgs: scalarArgs, + bufferConstants: bufferConstants, + byteLength: Math.ceil(offset / 16) * 16 + }; + } + scalarWGSLType(type) { + switch (type) { + case "Integer": + return "i32"; + + case "Boolean": + return "u32"; + + default: + return "f32"; + } + } + assembleWGSL() { + const {arrayArgs: arrayArgs, scalarArgs: scalarArgs, bufferConstants: bufferConstants} = this.paramsLayout; + const wgsl = []; + const structMembers = [ " outputX : u32,", " outputY : u32,", " outputZ : u32,", " dispatchWidth : u32," ]; + for (let i = 0; i < arrayArgs.length; i++) structMembers.push(` user_${arrayArgs[i].name}_dims : vec4,`); + for (let i = 0; i < scalarArgs.length; i++) structMembers.push(` user_${scalarArgs[i].name} : ${this.scalarWGSLType(scalarArgs[i].type)},`); + wgsl.push("struct Params {", structMembers.join("\n"), "}"); + wgsl.push("@group(0) @binding(0) var params : Params;"); + for (let i = 0; i < arrayArgs.length; i++) wgsl.push(`@group(0) @binding(${1 + i}) var user_${arrayArgs[i].name} : array;`); + const outBinding = 1 + arrayArgs.length; + wgsl.push(`@group(0) @binding(${outBinding}) var result : array;`); + for (let i = 0; i < bufferConstants.length; i++) wgsl.push(`@group(0) @binding(${outBinding + 1 + i}) var constants_${bufferConstants[i].name} : array;`); + wgsl.push("var threadGid : vec3;"); + const translated = `${this.translatedFunctions}\n${this.translatedBody}`; + if (/\bLOOP_MAX\b/.test(translated)) wgsl.push(`const LOOP_MAX : i32 = ${parseInt(this.loopMaxIterations, 10) || 1e3};`); + for (const helperName in wgslHelpers) if (new RegExp(`\\b${helperName}\\(`).test(translated)) wgsl.push(wgslHelpers[helperName]); + for (let i = 0; i < arrayArgs.length; i++) { + const name = arrayArgs[i].name; + wgsl.push(`fn get_user_${name}(z : i32, y : i32, x : i32) -> f32 {\n return user_${name}[u32(x + i32(params.user_${name}_dims.x) * (y + i32(params.user_${name}_dims.y) * z))];\n}`); + } + for (let i = 0; i < bufferConstants.length; i++) { + const record = bufferConstants[i]; + const value = this.constants[record.constantName]; + const dims = this.constantDimensions(value); + wgsl.push(`fn get_constants_${record.name}(z : i32, y : i32, x : i32) -> f32 {\n return constants_${record.name}[u32(x + ${dims[0]} * (y + ${dims[1]} * z))];\n}`); + } + if (this.translatedFunctions) wgsl.push(this.translatedFunctions); + const workgroupSize = this.output.length === 1 ? [ 64, 1, 1 ] : [ 8, 8, 1 ]; + this.workgroupSize = workgroupSize; + if (this.output.length === 1) wgsl.push(`@compute @workgroup_size(${workgroupSize[0]}, ${workgroupSize[1]}, ${workgroupSize[2]})\nfn main(@builtin(global_invocation_id) gid : vec3) {\n let flat_index : u32 = gid.x + gid.y * params.dispatchWidth;\n threadGid = vec3(flat_index, 0u, 0u);\n if (flat_index >= params.outputX) { return; }\n let data_index : i32 = i32(flat_index);\n${this.translatedBody}\n}`); else wgsl.push(`@compute @workgroup_size(${workgroupSize[0]}, ${workgroupSize[1]}, ${workgroupSize[2]})\nfn main(@builtin(global_invocation_id) gid : vec3) {\n threadGid = gid;\n if (gid.x >= params.outputX || gid.y >= params.outputY || gid.z >= params.outputZ) { return; }\n let data_index : i32 = i32(gid.x + params.outputX * (gid.y + params.outputY * gid.z));\n${this.translatedBody}\n}`); + return wgsl.join("\n"); + } + constantDimensions(value) { + const dims = value instanceof Input ? Array.from(value.size) : Array.from(utils.getDimensions(value)); + while (dims.length < 3) dims.push(1); + return dims; + } + async _buildAsync() { + const context = await WebGPUContext.acquire(); + this.context = context; + const device = this._device = context.device; + const module$1 = device.createShaderModule({ + code: this.compiledSource + }); + const errors = (await module$1.getCompilationInfo()).messages.filter(message => message.type === "error"); + if (errors.length > 0) throw new Error("Error compiling WGSL compute shader:\n" + errors.map(message => ` ${message.lineNum}:${message.linePos} ${message.message}`).join("\n") + `\n--- generated WGSL ---\n${this.compiledSource}`); + const {arrayArgs: arrayArgs, bufferConstants: bufferConstants, byteLength: byteLength} = this.paramsLayout; + const layoutEntries = [ { + binding: 0, + visibility: 4, + buffer: { + type: "uniform" + } + } ]; + for (let i = 0; i < arrayArgs.length; i++) layoutEntries.push({ + binding: 1 + i, + visibility: 4, + buffer: { + type: "read-only-storage" + } + }); + const outBinding = 1 + arrayArgs.length; + layoutEntries.push({ + binding: outBinding, + visibility: 4, + buffer: { + type: "storage" + } + }); + for (let i = 0; i < bufferConstants.length; i++) layoutEntries.push({ + binding: outBinding + 1 + i, + visibility: 4, + buffer: { + type: "read-only-storage" + } + }); + this.bindGroupLayout = device.createBindGroupLayout({ + entries: layoutEntries + }); + device.pushErrorScope("validation"); + this.computePipeline = device.createComputePipeline({ + layout: device.createPipelineLayout({ + bindGroupLayouts: [ this.bindGroupLayout ] + }), + compute: { + module: module$1, + entryPoint: "main" + } + }); + const pipelineError = await device.popErrorScope(); + if (pipelineError) throw new Error(`Error creating WebGPU compute pipeline for kernel: ${pipelineError.message}`); + this.paramsBuffer = device.createBuffer({ + size: byteLength, + usage: 72 + }); + this.paramsMirror = new ArrayBuffer(byteLength); + this.paramsU32 = new Uint32Array(this.paramsMirror); + this.paramsI32 = new Int32Array(this.paramsMirror); + this.paramsF32 = new Float32Array(this.paramsMirror); + this.constantBuffers = []; + for (let i = 0; i < bufferConstants.length; i++) { + const record = bufferConstants[i]; + const value = this.constants[record.constantName]; + const dims = this.constantDimensions(value); + const flatLength = dims[0] * dims[1] * dims[2]; + this._checkBufferSize(flatLength * 4, `constant "${record.constantName}"`); + const buffer = device.createBuffer({ + size: Math.max(flatLength * 4, 4), + usage: USAGE_STORAGE, + mappedAtCreation: true + }); + const mapped = new Float32Array(buffer.getMappedRange()); + utils.flattenTo(value instanceof Input ? value.value : value, mapped.subarray(0, flatLength)); + buffer.unmap(); + record.buffer = buffer; + this.constantBuffers.push(buffer); + } + this._ensureOutputBuffer(); + this.bindGroupDirty = true; + this.built = true; + } + _computeDispatch(threadDim) { + const [wx, wy, wz] = this.workgroupSize; + const groups = [ Math.ceil(threadDim[0] / wx), Math.ceil(threadDim[1] / wy), Math.ceil(threadDim[2] / wz) ]; + const maxGroups = this._device.limits.maxComputeWorkgroupsPerDimension; + let dispatchWidth = 0; + if (this.output.length === 1) { + if (groups[0] > maxGroups) { + groups[1] = Math.ceil(groups[0] / maxGroups); + groups[0] = Math.ceil(groups[0] / groups[1]); + } + dispatchWidth = groups[0] * wx; + } + for (let i = 0; i < 3; i++) if (groups[i] > maxGroups) throw new Error(`output dimension ${i} needs ${groups[i]} workgroups, over this device's limit of ${maxGroups}`); + return { + groups: groups, + dispatchWidth: dispatchWidth + }; + } + _ensureOutputBuffer() { + const [tx, ty, tz] = this.threadDim; + const byteLength = tx * ty * tz * 4 * this.componentCount; + if (this.immutable && this.pipeline && this.outputBuffer) { + if (--this.outputBuffer._refs === 0) this.outputBuffer.destroy(); + this.outputBuffer = null; + this.bindGroupDirty = true; + } + if (this.outputBuffer && this.outputBuffer.size >= byteLength) return; + if (this.outputBuffer) { + if (--this.outputBuffer._refs === 0) this.outputBuffer.destroy(); + } + this._checkBufferSize(byteLength, `output [${this.output.join(", ")}]`); + this.outputBuffer = this._device.createBuffer({ + size: byteLength, + usage: 132 + }); + this.outputBuffer._refs = 1; + this.bindGroupDirty = true; + } + _checkBufferSize(byteLength, what) { + const limits = this._device.limits; + const max = Math.min(limits.maxStorageBufferBindingSize, limits.maxBufferSize); + if (byteLength > max) throw new Error(`WebGPU backend: ${what} needs ${byteLength} bytes but this device allows ${max} per storage buffer (maxStorageBufferBindingSize/maxBufferSize); reduce the output or split the work across kernels`); + } + _snapshotArguments(args) { + const snapshot = new Array(args.length); + for (let i = 0; i < args.length; i++) { + const value = args[i]; + const type = this.argumentTypes[i]; + if (value instanceof WebGPUBufferResult) { + snapshot[i] = { + kind: "buffer", + handle: value + }; + continue; + } + switch (type) { + case "Array": + { + const dims = Array.from(utils.getDimensions(value)); + while (dims.length < 3) dims.push(1); + const flat = new Float32Array(dims[0] * dims[1] * dims[2]); + utils.flattenTo(value, flat); + snapshot[i] = { + kind: "array", + dims: dims, + flat: flat + }; + break; + } + + case "Input": + { + const dims = Array.from(value.size); + while (dims.length < 3) dims.push(1); + const flat = new Float32Array(dims[0] * dims[1] * dims[2]); + utils.flattenTo(value.value, flat); + snapshot[i] = { + kind: "array", + dims: dims, + flat: flat + }; + break; + } + + case "WebGPUBuffer": + snapshot[i] = { + kind: "buffer", + handle: value + }; + break; + + case "Boolean": + snapshot[i] = { + kind: "scalar", + value: value ? 1 : 0 + }; + break; + + default: + snapshot[i] = { + kind: "scalar", + value: value + }; + } + } + return snapshot; + } + run() { + if (!this.built && !this._buildPromise) this.build.apply(this, arguments); + const snapshot = this._snapshotArguments(arguments); + if (!this.built) return this._buildPromise.then(() => this._runInternal(snapshot)); + return this._runInternal(snapshot); + } + _runInternal(snapshot) { + if (this.context && this.context.isLost) throw new Error("WebGPU device was lost; call kernel.destroy() (or gpu.destroy()) and run again to rebuild on a fresh device"); + const device = this._device; + const queue = device.queue; + const {arrayArgs: arrayArgs, scalarArgs: scalarArgs, bufferConstants: bufferConstants} = this.paramsLayout; + const threadDim = this.threadDim = Array.from(this.output); + while (threadDim.length < 3) threadDim.push(1); + this._ensureOutputBuffer(); + this.paramsU32[0] = threadDim[0]; + this.paramsU32[1] = threadDim[1]; + this.paramsU32[2] = threadDim[2]; + this.paramsU32[3] = this._computeDispatch(threadDim).dispatchWidth; + for (let i = 0; i < arrayArgs.length; i++) { + const record = arrayArgs[i]; + const snap = snapshot[record.index]; + let dims; + if (snap.kind === "buffer") { + const handle = snap.handle; + if (handle._deleted) throw new Error(`WebGPUBufferResult passed as argument "${this.argumentNames[record.index]}" has been deleted`); + if (handle.context !== this.context) throw new Error(`WebGPUBufferResult passed as argument "${this.argumentNames[record.index]}" is from a different WebGPU device`); + if (handle.buffer === this.outputBuffer) throw new Error(`WebGPUBufferResult passed as argument "${this.argumentNames[record.index]}" is this kernel's own output buffer; use a second kernel or clone the result`); + if (handle.componentCount !== 1) throw new Error(`WebGPU backend does not yet support Array(${handle.componentCount}) pipeline results as kernel arguments`); + dims = Array.from(handle.output); + while (dims.length < 3) dims.push(1); + if (record.boundBuffer !== handle.buffer) { + record.boundBuffer = handle.buffer; + this.bindGroupDirty = true; + } + } else { + dims = snap.dims; + const byteLength = snap.flat.byteLength; + if (!record.buffer || record.buffer.size < byteLength) { + if (record.buffer) { + if (!this.dynamicArguments) throw new Error(`argument "${this.argumentNames[record.index]}" grew from ${record.buffer.size / 4} to ${snap.flat.length} values; use dynamicArguments: true for varying input sizes`); + record.buffer.destroy(); + } + this._checkBufferSize(byteLength, `argument "${this.argumentNames[record.index]}"`); + record.buffer = device.createBuffer({ + size: byteLength, + usage: 136 + }); + this.bindGroupDirty = true; + } + queue.writeBuffer(record.buffer, 0, snap.flat); + if (record.boundBuffer !== record.buffer) { + record.boundBuffer = record.buffer; + this.bindGroupDirty = true; + } + } + const base = record.dimsOffset / 4; + this.paramsU32[base] = dims[0]; + this.paramsU32[base + 1] = dims[1]; + this.paramsU32[base + 2] = dims[2]; + this.paramsU32[base + 3] = dims[0] * dims[1] * dims[2]; + } + for (let i = 0; i < scalarArgs.length; i++) { + const record = scalarArgs[i]; + const slot = record.offset / 4; + switch (record.type) { + case "Integer": + this.paramsI32[slot] = snapshot[record.index].value; + break; + + case "Boolean": + this.paramsU32[slot] = snapshot[record.index].value; + break; + + default: + this.paramsF32[slot] = snapshot[record.index].value; + } + } + queue.writeBuffer(this.paramsBuffer, 0, this.paramsMirror); + if (this.bindGroupDirty) { + const entries = [ { + binding: 0, + resource: { + buffer: this.paramsBuffer + } + } ]; + for (let i = 0; i < arrayArgs.length; i++) entries.push({ + binding: 1 + i, + resource: { + buffer: arrayArgs[i].boundBuffer + } + }); + const outBinding = 1 + arrayArgs.length; + entries.push({ + binding: outBinding, + resource: { + buffer: this.outputBuffer + } + }); + for (let i = 0; i < bufferConstants.length; i++) entries.push({ + binding: outBinding + 1 + i, + resource: { + buffer: bufferConstants[i].buffer + } + }); + this.bindGroup = device.createBindGroup({ + layout: this.bindGroupLayout, + entries: entries + }); + this.bindGroupDirty = false; + } + const {groups: groups} = this._computeDispatch(threadDim); + const byteLength = threadDim[0] * threadDim[1] * threadDim[2] * 4 * this.componentCount; + const encoder = device.createCommandEncoder(); + const pass = encoder.beginComputePass(); + pass.setPipeline(this.computePipeline); + pass.setBindGroup(0, this.bindGroup); + pass.dispatchWorkgroups(groups[0], groups[1], groups[2]); + pass.end(); + if (this.pipeline) { + queue.submit([ encoder.finish() ]); + return Promise.resolve(new WebGPUBufferResult({ + buffer: this.outputBuffer, + output: Array.from(this.output), + componentCount: this.componentCount, + context: this.context, + kernel: this + })); + } + const staging = this._acquireStaging(byteLength); + encoder.copyBufferToBuffer(this.outputBuffer, 0, staging.buffer, 0, byteLength); + queue.submit([ encoder.finish() ]); + const output = Array.from(this.output); + return staging.buffer.mapAsync(MAP_MODE_READ, 0, byteLength).then(() => { + const data = new Float32Array(staging.buffer.getMappedRange(0, byteLength).slice(0)); + staging.buffer.unmap(); + this._releaseStaging(staging); + return this._shapeOutput(data, output, this.componentCount); + }, error => { + this._releaseStaging(staging); + throw error; + }); + } + _acquireStaging(byteLength) { + for (let i = 0; i < this.stagingPool.length; i++) { + const entry = this.stagingPool[i]; + if (!entry.busy && entry.size >= byteLength) { + entry.busy = true; + return entry; + } + } + const entry = { + buffer: this._device.createBuffer({ + size: byteLength, + usage: 9 + }), + size: byteLength, + busy: true, + pooled: this.stagingPool.length < 3 + }; + if (entry.pooled) this.stagingPool.push(entry); + return entry; + } + _releaseStaging(entry) { + if (entry.pooled) entry.busy = false; else entry.buffer.destroy(); + } + _shapeOutput(data, output, componentCount) { + const [width, height, depth] = [ output[0], output[1] || 1, output[2] || 1 ]; + if (componentCount === 1) switch (output.length) { + case 1: + return utils.erectMemoryOptimizedFloat(data, width); + + case 2: + return utils.erectMemoryOptimized2DFloat(data, width, height); + + default: + return utils.erectMemoryOptimized3DFloat(data, width, height, depth); + } + const n = componentCount; + const erectRow = offset => { + const row = new Array(width); + for (let x = 0; x < width; x++) row[x] = data.subarray(offset + x * n, offset + x * n + n); + return row; + }; + switch (output.length) { + case 1: + return erectRow(0); + + case 2: + { + const rows = new Array(height); + for (let y = 0; y < height; y++) rows[y] = erectRow(y * width * n); + return rows; + } + + default: + { + const layers = new Array(depth); + for (let z = 0; z < depth; z++) { + const rows = new Array(height); + for (let y = 0; y < height; y++) rows[y] = erectRow((z * height + y) * width * n); + layers[z] = rows; + } + return layers; + } + } + } + readBufferResult(handle) { + const device = this._device || handle.context && handle.context.device; + if (!device) return Promise.reject(new Error("no WebGPU device available to read this buffer")); + if (handle.context && handle.context.isLost) return Promise.reject(new Error("WebGPU device was lost; this buffer no longer holds data \u2014 rebuild the producing kernel and run again")); + const output = Array.from(handle.output); + const dims = Array.from(output); + while (dims.length < 3) dims.push(1); + const byteLength = dims[0] * dims[1] * dims[2] * 4 * handle.componentCount; + const staging = this._acquireStaging(byteLength); + const encoder = device.createCommandEncoder(); + encoder.copyBufferToBuffer(handle.buffer, 0, staging.buffer, 0, byteLength); + device.queue.submit([ encoder.finish() ]); + return staging.buffer.mapAsync(MAP_MODE_READ, 0, byteLength).then(() => { + const data = new Float32Array(staging.buffer.getMappedRange(0, byteLength).slice(0)); + staging.buffer.unmap(); + this._releaseStaging(staging); + return this._shapeOutput(data, output, handle.componentCount); + }, error => { + this._releaseStaging(staging); + throw error; + }); + } + destroy(removeCanvasReferences) { + if (this.paramsBuffer) { + this.paramsBuffer.destroy(); + this.paramsBuffer = null; + } + if (this.paramsLayout) for (let i = 0; i < this.paramsLayout.arrayArgs.length; i++) { + const record = this.paramsLayout.arrayArgs[i]; + if (record.buffer) { + record.buffer.destroy(); + record.buffer = null; + } + record.boundBuffer = null; + } + if (this.constantBuffers) { + for (let i = 0; i < this.constantBuffers.length; i++) this.constantBuffers[i].destroy(); + this.constantBuffers = null; + } + for (let i = 0; i < this.stagingPool.length; i++) this.stagingPool[i].buffer.destroy(); + this.stagingPool = []; + if (this.outputBuffer) { + if (--this.outputBuffer._refs === 0) this.outputBuffer.destroy(); + this.outputBuffer = null; + } + this.bindGroup = null; + this.bindGroupLayout = null; + this.computePipeline = null; + this.built = false; + this._buildPromise = null; + if (this.gpu && this.gpu.kernels) { + const index = this.gpu.kernels.indexOf(this); + if (index !== -1) this.gpu.kernels.splice(index, 1); + } + } + }; + module.exports = { + WebGPUKernel: WebGPUKernel + }; + }); + var require_kernel_run_shortcut = __commonJSMin((exports, module) => { + const {utils: utils} = require_utils(); + const {Input: Input} = require_input(); + function kernelRunShortcut(kernel) { + const MAX_SWITCHES = 4; + function syncBody(args) { + kernel.build.apply(kernel, args); + kernel.checkArgumentTypes(args); + let result = kernel.switchingKernels ? void 0 : kernel.run.apply(kernel, args); + for (let i = 0; kernel.switchingKernels; i++) { + if (i >= MAX_SWITCHES) { + const reasons = kernel.resetSwitchingKernels(); + throw new Error(`this kernel cannot run the arguments it was given (${describeReasons(reasons)}); it did not settle on a kernel for them after ${MAX_SWITCHES} attempts. Create a separate kernel for this call's argument types.`); + } + const reasons = kernel.resetSwitchingKernels(); + const newKernel = kernel.onRequestSwitchKernel(reasons, args, kernel); + shortcut.kernel = kernel = newKernel; + newKernel.checkArgumentTypes(args); + result = newKernel.switchingKernels ? void 0 : newKernel.run.apply(newKernel, args); + } + return result; + } + function describeReasons(reasons) { + if (!reasons || !reasons.length) return "unknown reason"; + return reasons.map(reason => { + if (reason.type === "argumentTypeMismatch") return `argument ${reason.index} is now ${reason.needed}`; + return reason.type; + }).join(", "); + } + function syncRun(args) { + const result = syncBody(args); + if (kernel.renderKernels) return kernel.renderKernels(); else if (kernel.renderOutput) return kernel.renderOutput(); else return result; + } + function asyncRun(args) { + if (kernel.onAsyncModeUpgrade) { + const upgrade = kernel.onAsyncModeUpgrade; + kernel.onAsyncModeUpgrade = null; + const snapped = snapshotArguments(args); + return upgrade(snapped, kernel).then(upgradedKernel => { + if (upgradedKernel) shortcut.replaceKernel(upgradedKernel); + return asyncRun(snapped); + }); + } + try { + if (kernel.constructor.isAsync === true) { + kernel.build.apply(kernel, args); + return Promise.resolve(kernel.run.apply(kernel, args)); + } + for (let i = 0; i < args.length; i++) if (isWebGPUHandle(args[i])) return resolveHandles(args).then(resolved => asyncRun(resolved)); + const result = syncBody(args); + if (kernel.renderKernels) return Promise.resolve(kernel.renderKernels()); else if (kernel.renderOutput) { + if (kernel.renderOutputAsync) return kernel.renderOutputAsync(); + return Promise.resolve(kernel.renderOutput()); + } else return Promise.resolve(result); + } catch (e) { + return Promise.reject(e); + } + } + function isWebGPUHandle(value) { + return Boolean(value) && value.type === "WebGPUBuffer"; + } + function resolveHandles(args) { + const snapped = snapshotArguments(args); + const pending = []; + for (let i = 0; i < snapped.length; i++) if (isWebGPUHandle(snapped[i])) { + const index = i; + pending.push(Promise.resolve(snapped[index].toArray()).then(value => { + snapped[index] = value; + })); + } + return Promise.all(pending).then(() => snapped); + } + function snapshotArguments(args) { + const copy = new Array(args.length); + for (let i = 0; i < args.length; i++) copy[i] = snapshotValue(args[i]); + return copy; + } + function snapshotValue(value) { + if (!value || typeof value !== "object") return value; + if (isWebGPUHandle(value) || typeof value.delete === "function") return value; + if (ArrayBuffer.isView(value)) return value.slice(0); + if (Array.isArray(value)) return value.map(snapshotValue); + if (value instanceof Input) return new Input(snapshotValue(value.value), value.size); + return value; + } + function run() { + if (kernel.constructor.isAsync === true || kernel.asyncMode === true) return asyncRun(arguments); + return syncRun(arguments); + } + const shortcut = function() { + return run.apply(kernel, arguments); + }; + shortcut.exec = function() { + return new Promise((accept, reject) => { + try { + accept(run.apply(this, arguments)); + } catch (e) { + reject(e); + } + }); + }; + shortcut.replaceKernel = function(replacementKernel) { + kernel = replacementKernel; + bindKernelToShortcut(kernel, shortcut); + }; + bindKernelToShortcut(kernel, shortcut); + return shortcut; + } + function bindKernelToShortcut(kernel, shortcut) { + if (shortcut.kernel) { + shortcut.kernel = kernel; + return; + } + const properties = utils.allPropertiesOf(kernel); + for (let i = 0; i < properties.length; i++) { + const property = properties[i]; + if (property[0] === "_" && property[1] === "_") continue; + if (typeof kernel[property] === "function") if (property.substring(0, 3) === "add" || property.substring(0, 3) === "set") shortcut[property] = function() { + shortcut.kernel[property].apply(shortcut.kernel, arguments); + return shortcut; + }; else shortcut[property] = function() { + return shortcut.kernel[property].apply(shortcut.kernel, arguments); + }; else { + shortcut.__defineGetter__(property, () => shortcut.kernel[property]); + shortcut.__defineSetter__(property, value => { + shortcut.kernel[property] = value; + }); + } + } + shortcut.kernel = kernel; + } + module.exports = { + kernelRunShortcut: kernelRunShortcut + }; + }); + var require_gpu = __commonJSMin((exports, module) => { + const {gpuMock: gpuMock} = require_gpu_mock_js(); + const {utils: utils} = require_utils(); + const {Kernel: Kernel} = require_kernel$6(); + const {CPUKernel: CPUKernel} = require_kernel$5(); + const {HeadlessGLKernel: HeadlessGLKernel} = require_kernel$2(); + const {WebGL2Kernel: WebGL2Kernel} = require_kernel$1(); + const {WebGLKernel: WebGLKernel} = require_kernel$3(); + const {WebGPUKernel: WebGPUKernel} = require_kernel(); + const {kernelRunShortcut: kernelRunShortcut} = require_kernel_run_shortcut(); + const kernelOrder = [ HeadlessGLKernel, WebGL2Kernel, WebGLKernel ]; + const kernelTypes = [ "gpu", "cpu" ]; + const internalKernels = { + headlessgl: HeadlessGLKernel, + webgl2: WebGL2Kernel, + webgl: WebGLKernel, + webgpu: WebGPUKernel + }; + let validate = true; + var GPU = class GPU { + static disableValidation() { + validate = false; + } + static enableValidation() { + validate = true; + } + static get isGPUSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported); + } + static get isKernelMapSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap); + } + static get isOffscreenCanvasSupported() { + return typeof Worker !== "undefined" && typeof OffscreenCanvas !== "undefined" || typeof importScripts !== "undefined"; + } + static get isWebGLSupported() { + return WebGLKernel.isSupported; + } + static get isWebGL2Supported() { + return WebGL2Kernel.isSupported; + } + static get isHeadlessGLSupported() { + return HeadlessGLKernel.isSupported; + } + static get isWebGPUSupported() { + return WebGPUKernel.isSupported; + } + static isWebGPUAvailable() { + if (!WebGPUKernel.isSupported) return Promise.resolve(false); + return navigator.gpu.requestAdapter().then(adapter => adapter !== null, () => false); + } + static get isCanvasSupported() { + return typeof HTMLCanvasElement !== "undefined"; + } + static get isGPUHTMLImageArraySupported() { + return WebGL2Kernel.isSupported; + } + static get isSinglePrecisionSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); + } + constructor(settings) { + settings = settings || {}; + this.canvas = settings.canvas || null; + this.context = settings.context || null; + this.mode = settings.mode; + this.Kernel = null; + this.kernels = []; + this.functions = []; + this.nativeFunctions = []; + this.injectedNative = null; + if (this.mode === "dev") return; + this.chooseKernel(); + if (settings.functions) for (let i = 0; i < settings.functions.length; i++) this.addFunction(settings.functions[i]); + if (settings.nativeFunctions) for (const p in settings.nativeFunctions) { + if (!settings.nativeFunctions.hasOwnProperty(p)) continue; + const s = settings.nativeFunctions[p]; + const {name: name, source: source} = s; + this.addNativeFunction(name, source, s); + } + } + chooseKernel() { + if (this.Kernel) return; + let Kernel = null; + if (this.context) { + for (let i = 0; i < kernelOrder.length; i++) { + const ExternalKernel = kernelOrder[i]; + if (ExternalKernel.isContextMatch(this.context)) { + if (!ExternalKernel.isSupported) throw new Error(`Kernel type ${ExternalKernel.name} not supported`); + Kernel = ExternalKernel; + break; + } + } + if (Kernel === null) throw new Error("unknown Context"); + } else if (this.mode) { + if (this.mode in internalKernels) { + if (!validate || internalKernels[this.mode].isSupported) Kernel = internalKernels[this.mode]; + } else if (this.mode === "gpu") { + for (let i = 0; i < kernelOrder.length; i++) if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } + } else if (this.mode === "async") { + for (let i = 0; i < kernelOrder.length; i++) if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } + if (!Kernel) Kernel = CPUKernel; + } else if (this.mode === "cpu") Kernel = CPUKernel; + if (!Kernel) throw new Error(`A requested mode of "${this.mode}" and is not supported`); + } else { + for (let i = 0; i < kernelOrder.length; i++) if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } + if (!Kernel) Kernel = CPUKernel; + } + if (!this.mode) this.mode = Kernel.mode; + this.Kernel = Kernel; + } + createKernel(source, settings) { + if (typeof source === "undefined") throw new Error("Missing source parameter"); + if (typeof source !== "object" && !utils.isFunction(source) && typeof source !== "string") throw new Error("source parameter not a function"); + const kernels = this.kernels; + if (this.mode === "dev") { + const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); + kernels.push(devKernel); + return devKernel; } source = typeof source === "function" ? source.toString() : source; const switchableKernels = {}; @@ -15452,7 +17680,8 @@ subKernels: kernelRun.subKernels, strictIntegers: kernelRun.strictIntegers, randomSeed: kernelRun.randomSeed, - debug: kernelRun.debug + debug: kernelRun.debug, + asyncMode: kernelRun.asyncMode }); fallbackKernel.build.apply(fallbackKernel, args); const result = fallbackKernel.run.apply(fallbackKernel, args); @@ -15498,6 +17727,7 @@ strictIntegers: _kernel.strictIntegers, randomSeed: _kernel.randomSeed, debug: _kernel.debug, + asyncMode: _kernel.asyncMode, gpu: _kernel.gpu, validate: validate, returnType: _kernel.returnType, @@ -15524,8 +17754,56 @@ onRequestFallback: onRequestFallback, onRequestSwitchKernel: onRequestSwitchKernel }, settingsCopy); + if (this.mode === "async") mergedSettings.asyncMode = true; const kernel = new this.Kernel(source, mergedSettings); const kernelRun = kernelRunShortcut(kernel); + if (this.mode === "async" && WebGPUKernel.isSupported && !(kernel instanceof WebGPUKernel)) { + const gpu = this; + kernel.onAsyncModeUpgrade = function onAsyncModeUpgrade(args, currentKernel) { + return GPU.isWebGPUAvailable().then(available => { + if (!available) return null; + let webGPUKernel; + try { + webGPUKernel = new WebGPUKernel(source, { + functions: currentKernel.functions, + nativeFunctions: currentKernel.nativeFunctions, + injectedNative: currentKernel.injectedNative, + gpu: gpu, + validate: validate, + asyncMode: true, + output: currentKernel.output, + pipeline: currentKernel.pipeline, + immutable: currentKernel.immutable, + dynamicOutput: currentKernel.dynamicOutput, + dynamicArguments: true, + loopMaxIterations: currentKernel.loopMaxIterations, + constants: currentKernel.constants, + constantTypes: currentKernel.constantTypes, + argumentTypes: currentKernel.argumentTypes, + precision: currentKernel.precision, + tactic: currentKernel.tactic, + strictIntegers: currentKernel.strictIntegers, + fixIntegerDivisionAccuracy: currentKernel.fixIntegerDivisionAccuracy, + subKernels: currentKernel.subKernels, + graphical: currentKernel.graphical, + debug: currentKernel.debug + }); + webGPUKernel.build.apply(webGPUKernel, args); + } catch (e) { + if (currentKernel.debug) console.warn("webgpu upgrade declined: " + e.message); + return null; + } + return webGPUKernel._buildPromise.then(() => { + kernels.push(webGPUKernel); + return webGPUKernel; + }, e => { + if (currentKernel.debug) console.warn("webgpu upgrade declined: " + e.message); + webGPUKernel.destroy(); + return null; + }); + }, () => null); + }; + } if (!this.canvas) this.canvas = kernel.canvas; if (!this.context) this.context = kernel.context; kernels.push(kernel); @@ -15541,6 +17819,7 @@ } else fn = arguments[arguments.length - 1]; if (this.mode !== "dev") { if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) { + if (this.Kernel.mode === "webgpu") throw new Error("WebGPU backend does not yet support createKernelMap"); if (this.mode && kernelTypes.indexOf(this.mode) < 0) throw new Error(`kernelMap not supported on ${this.Kernel.name}`); } } @@ -15577,7 +17856,9 @@ combineKernels() { const firstKernel = arguments[0]; const combinedKernel = arguments[arguments.length - 1]; + if (this.mode === "async" || firstKernel.kernel.asyncMode) throw new Error(`mode 'async' does not yet support combineKernels; chain kernels with \`await\` and pipeline mode instead`); if (firstKernel.kernel.constructor.mode === "cpu") return combinedKernel; + if (firstKernel.kernel.constructor.mode === "webgpu") throw new Error("WebGPU backend does not yet support combineKernels; chain kernels with `await` and pipeline mode instead"); const canvas = arguments[0].canvas; const context = arguments[0].context; const max = arguments.length - 1; @@ -15679,18 +17960,22 @@ const {Input: Input, input: input} = require_input(); const {Texture: Texture} = require_texture$1(); const {FunctionBuilder: FunctionBuilder} = require_function_builder(); - const {FunctionNode: FunctionNode} = require_function_node$3(); - const {CPUFunctionNode: CPUFunctionNode} = require_function_node$2(); - const {CPUKernel: CPUKernel} = require_kernel$4(); - const {HeadlessGLKernel: HeadlessGLKernel} = require_kernel$1(); - const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$1(); - const {WebGLKernel: WebGLKernel} = require_kernel$2(); + const {FunctionNode: FunctionNode} = require_function_node$4(); + const {CPUFunctionNode: CPUFunctionNode} = require_function_node$3(); + const {CPUKernel: CPUKernel} = require_kernel$5(); + const {HeadlessGLKernel: HeadlessGLKernel} = require_kernel$2(); + const {WebGLFunctionNode: WebGLFunctionNode} = require_function_node$2(); + const {WebGLKernel: WebGLKernel} = require_kernel$3(); const {kernelValueMaps: webGLKernelValueMaps} = require_kernel_value_maps$1(); - const {WebGL2FunctionNode: WebGL2FunctionNode} = require_function_node(); - const {WebGL2Kernel: WebGL2Kernel} = require_kernel(); + const {WebGL2FunctionNode: WebGL2FunctionNode} = require_function_node$1(); + const {WebGL2Kernel: WebGL2Kernel} = require_kernel$1(); const {kernelValueMaps: webGL2KernelValueMaps} = require_kernel_value_maps(); - const {GLKernel: GLKernel} = require_kernel$3(); - const {Kernel: Kernel} = require_kernel$5(); + const {WGSLFunctionNode: WGSLFunctionNode} = require_function_node(); + const {WebGPUKernel: WebGPUKernel} = require_kernel(); + const {WebGPUContext: WebGPUContext} = require_context(); + const {WebGPUBufferResult: WebGPUBufferResult} = require_buffer_result(); + const {GLKernel: GLKernel} = require_kernel$4(); + const {Kernel: Kernel} = require_kernel$6(); const {FunctionTracer: FunctionTracer} = require_function_tracer(); module.exports = { alias: alias, @@ -15710,6 +17995,10 @@ WebGLFunctionNode: WebGLFunctionNode, WebGLKernel: WebGLKernel, webGLKernelValueMaps: webGLKernelValueMaps, + WGSLFunctionNode: WGSLFunctionNode, + WebGPUKernel: WebGPUKernel, + WebGPUContext: WebGPUContext, + WebGPUBufferResult: WebGPUBufferResult, GLKernel: GLKernel, Kernel: Kernel, FunctionTracer: FunctionTracer, diff --git a/dist/gpu-browser.min.js b/dist/gpu-browser.min.js index 66d3848b..0d6a0883 100644 --- a/dist/gpu-browser.min.js +++ b/dist/gpu-browser.min.js @@ -1,11 +1,11 @@ /** * gpu.js - * http://gpu.rocks/ + * https://gpu.rocks/ * * GPU Accelerated JavaScript * * @version 2.19.9 - * @date Wed Jul 29 2026 05:05:56 GMT+0800 (Singapore Standard Time) + * @date Thu Jul 30 2026 13:21:39 GMT+0800 (Singapore Standard Time) * * @license MIT * The MIT License @@ -13,16 +13,16 @@ * Copyright (c) 2026 gpu.js Team *//** * gpu.js - * http://gpu.rocks/ + * https://gpu.rocks/ * * GPU Accelerated JavaScript * * @version 2.19.9 - * @date Wed Jul 29 2026 05:05:55 GMT+0800 (Singapore Standard Time) + * @date Thu Jul 30 2026 13:21:38 GMT+0800 (Singapore Standard Time) * * @license MIT * The MIT License * * Copyright (c) 2026 gpu.js Team */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):(e="undefined"!=typeof globalThis?globalThis:e||self).GPU=t()}(this,function(){var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),t=e((e,t)=>{function r(e){const t=new Array(e.length);for(let r=0;r{e.output=h(t),e.graphical&&u(e)},e.toJSON=()=>{throw new Error("Not usable with gpuMock")},e.setConstants=t=>(e.constants=t,e),e.setGraphical=t=>(e.graphical=t,e),e.setCanvas=t=>(e.canvas=t,e),e.setContext=t=>(e.context=t,e),e.destroy=()=>{},e.validateSettings=()=>{},e.graphical&&e.output&&u(e),e.exec=function(){return new Promise((t,r)=>{try{t(e.apply(e,arguments))}catch(e){r(e)}})},e.getPixels=t=>{const{x:r,y:n}=e.output;return t?function(e,t,r){const n=r/2|0,s=4*t,i=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee,r=["setWarnVarUsage","setArgumentTypes","setTactic","setOptimizeFloatMemory","setDebug","setLoopMaxIterations","setConstantTypes","setFunctions","setNativeFunctions","setInjectedNative","setPipeline","setPrecision","setOutputToTexture","setImmutable","setStrictIntegers","setDynamicOutput","setHardcodeConstants","setDynamicArguments","setUseLegacyEncoder","setWarnVarUsage","addSubKernel"];for(let n=0;n{var r,n;r=e,n=function(e){"use strict";var t=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,7,9,32,4,318,1,80,3,71,10,50,3,123,2,54,14,32,10,3,1,11,3,46,10,8,0,46,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,2,11,83,11,7,0,3,0,158,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,68,8,2,0,3,0,2,3,2,4,2,0,15,1,83,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,7,19,58,14,5,9,243,14,166,9,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,343,9,54,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,10,1,2,0,49,6,4,4,14,10,5350,0,7,14,11465,27,2343,9,87,9,39,4,60,6,26,9,535,9,470,0,2,54,8,3,82,0,12,1,19628,1,4178,9,519,45,3,22,543,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,101,0,161,6,10,9,357,0,62,13,499,13,245,1,2,9,726,6,110,6,6,9,4759,9,787719,239],r=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,13,10,2,14,2,6,2,1,2,10,2,14,2,6,2,1,4,51,13,310,10,21,11,7,25,5,2,41,2,8,70,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,39,27,10,22,251,41,7,1,17,2,60,28,11,0,9,21,43,17,47,20,28,22,13,52,58,1,3,0,14,44,33,24,27,35,30,0,3,0,9,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,20,1,64,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,31,9,2,0,3,0,2,37,2,0,26,0,2,0,45,52,19,3,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,38,6,186,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,19,72,200,32,32,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,16,0,2,12,2,33,125,0,80,921,103,110,18,195,2637,96,16,1071,18,5,26,3994,6,582,6842,29,1763,568,8,30,18,78,18,29,19,47,17,3,32,20,6,18,433,44,212,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,1237,42,9,8936,3,2,6,2,1,2,290,16,0,30,2,3,0,15,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,1845,30,7,5,262,61,147,44,11,6,17,0,322,29,19,43,485,27,229,29,3,0,496,6,2,3,2,1,2,14,2,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42719,33,4153,7,221,3,5761,15,7472,16,621,2467,541,1507,4938,6,4191],n="\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7cd\ua7d0\ua7d1\ua7d3\ua7d5-\ua7dc\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc",s={3:"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",5:"class enum extends super const export import",6:"enum",strict:"implements interface let package private protected public static yield",strictBind:"eval arguments"},i="break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this",a={5:i,"5module":i+" export import",6:i+" const class extends export import super"},o=/^in(stanceof)?$/,u=new RegExp("["+n+"]"),h=new RegExp("["+n+"\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65]");function l(e,t){for(var r=65536,n=0;ne)return!1;if((r+=t[n+1])>=e)return!0}return!1}function c(e,t){return e<65?36===e:e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&u.test(String.fromCharCode(e)):!1!==t&&l(e,r)))}function p(e,n){return e<48?36===e:e<58||!(e<65)&&(e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&h.test(String.fromCharCode(e)):!1!==n&&(l(e,r)||l(e,t)))))}var d=function(e,t){void 0===t&&(t={}),this.label=e,this.keyword=t.keyword,this.beforeExpr=!!t.beforeExpr,this.startsExpr=!!t.startsExpr,this.isLoop=!!t.isLoop,this.isAssign=!!t.isAssign,this.prefix=!!t.prefix,this.postfix=!!t.postfix,this.binop=t.binop||null,this.updateContext=null};function m(e,t){return new d(e,{beforeExpr:!0,binop:t})}var f={beforeExpr:!0},g={startsExpr:!0},x={};function y(e,t){return void 0===t&&(t={}),t.keyword=e,x[e]=new d(e,t)}var b={num:new d("num",g),regexp:new d("regexp",g),string:new d("string",g),name:new d("name",g),privateId:new d("privateId",g),eof:new d("eof"),bracketL:new d("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new d("]"),braceL:new d("{",{beforeExpr:!0,startsExpr:!0}),braceR:new d("}"),parenL:new d("(",{beforeExpr:!0,startsExpr:!0}),parenR:new d(")"),comma:new d(",",f),semi:new d(";",f),colon:new d(":",f),dot:new d("."),question:new d("?",f),questionDot:new d("?."),arrow:new d("=>",f),template:new d("template"),invalidTemplate:new d("invalidTemplate"),ellipsis:new d("...",f),backQuote:new d("`",g),dollarBraceL:new d("${",{beforeExpr:!0,startsExpr:!0}),eq:new d("=",{beforeExpr:!0,isAssign:!0}),assign:new d("_=",{beforeExpr:!0,isAssign:!0}),incDec:new d("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new d("!/~",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:m("||",1),logicalAND:m("&&",2),bitwiseOR:m("|",3),bitwiseXOR:m("^",4),bitwiseAND:m("&",5),equality:m("==/!=/===/!==",6),relational:m("/<=/>=",7),bitShift:m("<>/>>>",8),plusMin:new d("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:m("%",10),star:m("*",10),slash:m("/",10),starstar:new d("**",{beforeExpr:!0}),coalesce:m("??",1),_break:y("break"),_case:y("case",f),_catch:y("catch"),_continue:y("continue"),_debugger:y("debugger"),_default:y("default",f),_do:y("do",{isLoop:!0,beforeExpr:!0}),_else:y("else",f),_finally:y("finally"),_for:y("for",{isLoop:!0}),_function:y("function",g),_if:y("if"),_return:y("return",f),_switch:y("switch"),_throw:y("throw",f),_try:y("try"),_var:y("var"),_const:y("const"),_while:y("while",{isLoop:!0}),_with:y("with"),_new:y("new",{beforeExpr:!0,startsExpr:!0}),_this:y("this",g),_super:y("super",g),_class:y("class",g),_extends:y("extends",f),_export:y("export"),_import:y("import",g),_null:y("null",g),_true:y("true",g),_false:y("false",g),_in:y("in",{beforeExpr:!0,binop:7}),_instanceof:y("instanceof",{beforeExpr:!0,binop:7}),_typeof:y("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:y("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:y("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},T=/\r\n?|\n|\u2028|\u2029/,S=new RegExp(T.source,"g");function v(e){return 10===e||13===e||8232===e||8233===e}function A(e,t,r){void 0===r&&(r=e.length);for(var n=t;n>10),56320+(1023&e)))}var F=/(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/,N=function(e,t){this.line=e,this.column=t};N.prototype.offset=function(e){return new N(this.line,this.column+e)};var V=function(e,t,r){this.start=t,this.end=r,null!==e.sourceFile&&(this.source=e.sourceFile)};function M(e,t){for(var r=1,n=0;;){var s=A(e,n,t);if(s<0)return new N(r,t-n);++r,n=s}}var O={ecmaVersion:null,sourceType:"script",onInsertedSemicolon:null,onTrailingComma:null,allowReserved:null,allowReturnOutsideFunction:!1,allowImportExportEverywhere:!1,allowAwaitOutsideFunction:null,allowSuperOutsideMethod:null,allowHashBang:!1,checkPrivateFields:!0,locations:!1,onToken:null,onComment:null,ranges:!1,program:null,sourceFile:null,directSourceFile:null,preserveParens:!1},z=!1;function P(e){var t={};for(var r in O)t[r]=e&&C(e,r)?e[r]:O[r];if("latest"===t.ecmaVersion?t.ecmaVersion=1e8:null==t.ecmaVersion?(!z&&"object"==typeof console&&console.warn&&(z=!0,console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future.")),t.ecmaVersion=11):t.ecmaVersion>=2015&&(t.ecmaVersion-=2009),null==t.allowReserved&&(t.allowReserved=t.ecmaVersion<5),e&&null!=e.allowHashBang||(t.allowHashBang=t.ecmaVersion>=14),k(t.onToken)){var n=t.onToken;t.onToken=function(e){return n.push(e)}}return k(t.onComment)&&(t.onComment=function(e,t){return function(r,n,s,i,a,o){var u={type:r?"Block":"Line",value:n,start:s,end:i};e.locations&&(u.loc=new V(this,a,o)),e.ranges&&(u.range=[s,i]),t.push(u)}}(t,t.onComment)),t}var K=256;function G(e,t){return 2|(e?4:0)|(t?8:0)}var U=function(e,t,r){this.options=e=P(e),this.sourceFile=e.sourceFile,this.keywords=L(a[e.ecmaVersion>=6?6:"module"===e.sourceType?"5module":5]);var n="";!0!==e.allowReserved&&(n=s[e.ecmaVersion>=6?6:5===e.ecmaVersion?5:3],"module"===e.sourceType&&(n+=" await")),this.reservedWords=L(n);var i=(n?n+" ":"")+s.strict;this.reservedWordsStrict=L(i),this.reservedWordsStrictBind=L(i+" "+s.strictBind),this.input=String(t),this.containsEsc=!1,r?(this.pos=r,this.lineStart=this.input.lastIndexOf("\n",r-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(T).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=b.eof,this.value=null,this.start=this.end=this.pos,this.startLoc=this.endLoc=this.curPosition(),this.lastTokEndLoc=this.lastTokStartLoc=null,this.lastTokStart=this.lastTokEnd=this.pos,this.context=this.initialContext(),this.exprAllowed=!0,this.inModule="module"===e.sourceType,this.strict=this.inModule||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.potentialArrowInForAwait=!1,this.yieldPos=this.awaitPos=this.awaitIdentPos=0,this.labels=[],this.undefinedExports=Object.create(null),0===this.pos&&e.allowHashBang&&"#!"===this.input.slice(0,2)&&this.skipLineComment(2),this.scopeStack=[],this.enterScope(1),this.regexpState=null,this.privateNameStack=[]},B={inFunction:{configurable:!0},inGenerator:{configurable:!0},inAsync:{configurable:!0},canAwait:{configurable:!0},allowSuper:{configurable:!0},allowDirectSuper:{configurable:!0},treatFunctionsAsVar:{configurable:!0},allowNewDotTarget:{configurable:!0},inClassStaticBlock:{configurable:!0}};U.prototype.parse=function(){var e=this.options.program||this.startNode();return this.nextToken(),this.parseTopLevel(e)},B.inFunction.get=function(){return(2&this.currentVarScope().flags)>0},B.inGenerator.get=function(){return(8&this.currentVarScope().flags)>0&&!this.currentVarScope().inClassFieldInit},B.inAsync.get=function(){return(4&this.currentVarScope().flags)>0&&!this.currentVarScope().inClassFieldInit},B.canAwait.get=function(){for(var e=this.scopeStack.length-1;e>=0;e--){var t=this.scopeStack[e];if(t.inClassFieldInit||t.flags&K)return!1;if(2&t.flags)return(4&t.flags)>0}return this.inModule&&this.options.ecmaVersion>=13||this.options.allowAwaitOutsideFunction},B.allowSuper.get=function(){var e=this.currentThisScope(),t=e.flags,r=e.inClassFieldInit;return(64&t)>0||r||this.options.allowSuperOutsideMethod},B.allowDirectSuper.get=function(){return(128&this.currentThisScope().flags)>0},B.treatFunctionsAsVar.get=function(){return this.treatFunctionsAsVarInScope(this.currentScope())},B.allowNewDotTarget.get=function(){var e=this.currentThisScope(),t=e.flags,r=e.inClassFieldInit;return(258&t)>0||r},B.inClassStaticBlock.get=function(){return(this.currentVarScope().flags&K)>0},U.extend=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];for(var r=this,n=0;n=,?^&]/.test(s)||"!"===s&&"="===this.input.charAt(n+1))}e+=t[0].length,E.lastIndex=e,e+=E.exec(this.input)[0].length,";"===this.input[e]&&e++}},j.eat=function(e){return this.type===e&&(this.next(),!0)},j.isContextual=function(e){return this.type===b.name&&this.value===e&&!this.containsEsc},j.eatContextual=function(e){return!!this.isContextual(e)&&(this.next(),!0)},j.expectContextual=function(e){this.eatContextual(e)||this.unexpected()},j.canInsertSemicolon=function(){return this.type===b.eof||this.type===b.braceR||T.test(this.input.slice(this.lastTokEnd,this.start))},j.insertSemicolon=function(){if(this.canInsertSemicolon())return this.options.onInsertedSemicolon&&this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc),!0},j.semicolon=function(){this.eat(b.semi)||this.insertSemicolon()||this.unexpected()},j.afterTrailingComma=function(e,t){if(this.type===e)return this.options.onTrailingComma&&this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc),t||this.next(),!0},j.expect=function(e){this.eat(e)||this.unexpected()},j.unexpected=function(e){this.raise(null!=e?e:this.start,"Unexpected token")};var H=function(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=this.doubleProto=-1};j.checkPatternErrors=function(e,t){if(e){e.trailingComma>-1&&this.raiseRecoverable(e.trailingComma,"Comma is not permitted after the rest element");var r=t?e.parenthesizedAssign:e.parenthesizedBind;r>-1&&this.raiseRecoverable(r,t?"Assigning to rvalue":"Parenthesized pattern")}},j.checkExpressionErrors=function(e,t){if(!e)return!1;var r=e.shorthandAssign,n=e.doubleProto;if(!t)return r>=0||n>=0;r>=0&&this.raise(r,"Shorthand property assignments are valid only in destructuring patterns"),n>=0&&this.raiseRecoverable(n,"Redefinition of __proto__ property")},j.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos55295&&n<56320)return!0;if(c(n,!0)){for(var s=r+1;p(n=this.input.charCodeAt(s),!0);)++s;if(92===n||n>55295&&n<56320)return!0;var i=this.input.slice(r,s);if(!o.test(i))return!0}return!1},X.isAsyncFunction=function(){if(this.options.ecmaVersion<8||!this.isContextual("async"))return!1;E.lastIndex=this.pos;var e,t=E.exec(this.input),r=this.pos+t[0].length;return!(T.test(this.input.slice(this.pos,r))||"function"!==this.input.slice(r,r+8)||r+8!==this.input.length&&(p(e=this.input.charCodeAt(r+8))||e>55295&&e<56320))},X.parseStatement=function(e,t,r){var n,s=this.type,i=this.startNode();switch(this.isLet(e)&&(s=b._var,n="let"),s){case b._break:case b._continue:return this.parseBreakContinueStatement(i,s.keyword);case b._debugger:return this.parseDebuggerStatement(i);case b._do:return this.parseDoStatement(i);case b._for:return this.parseForStatement(i);case b._function:return e&&(this.strict||"if"!==e&&"label"!==e)&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(i,!1,!e);case b._class:return e&&this.unexpected(),this.parseClass(i,!0);case b._if:return this.parseIfStatement(i);case b._return:return this.parseReturnStatement(i);case b._switch:return this.parseSwitchStatement(i);case b._throw:return this.parseThrowStatement(i);case b._try:return this.parseTryStatement(i);case b._const:case b._var:return n=n||this.value,e&&"var"!==n&&this.unexpected(),this.parseVarStatement(i,n);case b._while:return this.parseWhileStatement(i);case b._with:return this.parseWithStatement(i);case b.braceL:return this.parseBlock(!0,i);case b.semi:return this.parseEmptyStatement(i);case b._export:case b._import:if(this.options.ecmaVersion>10&&s===b._import){E.lastIndex=this.pos;var a=E.exec(this.input),o=this.pos+a[0].length,u=this.input.charCodeAt(o);if(40===u||46===u)return this.parseExpressionStatement(i,this.parseExpression())}return this.options.allowImportExportEverywhere||(t||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),s===b._import?this.parseImport(i):this.parseExport(i,r);default:if(this.isAsyncFunction())return e&&this.unexpected(),this.next(),this.parseFunctionStatement(i,!0,!e);var h=this.value,l=this.parseExpression();return s===b.name&&"Identifier"===l.type&&this.eat(b.colon)?this.parseLabeledStatement(i,h,l,e):this.parseExpressionStatement(i,l)}},X.parseBreakContinueStatement=function(e,t){var r="break"===t;this.next(),this.eat(b.semi)||this.insertSemicolon()?e.label=null:this.type!==b.name?this.unexpected():(e.label=this.parseIdent(),this.semicolon());for(var n=0;n=6?this.eat(b.semi):this.semicolon(),this.finishNode(e,"DoWhileStatement")},X.parseForStatement=function(e){this.next();var t=this.options.ecmaVersion>=9&&this.canAwait&&this.eatContextual("await")?this.lastTokStart:-1;if(this.labels.push(q),this.enterScope(0),this.expect(b.parenL),this.type===b.semi)return t>-1&&this.unexpected(t),this.parseFor(e,null);var r=this.isLet();if(this.type===b._var||this.type===b._const||r){var n=this.startNode(),s=r?"let":this.value;return this.next(),this.parseVar(n,!0,s),this.finishNode(n,"VariableDeclaration"),(this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&1===n.declarations.length?(this.options.ecmaVersion>=9&&(this.type===b._in?t>-1&&this.unexpected(t):e.await=t>-1),this.parseForIn(e,n)):(t>-1&&this.unexpected(t),this.parseFor(e,n))}var i=this.isContextual("let"),a=!1,o=this.containsEsc,u=new H,h=this.start,l=t>-1?this.parseExprSubscripts(u,"await"):this.parseExpression(!0,u);return this.type===b._in||(a=this.options.ecmaVersion>=6&&this.isContextual("of"))?(t>-1?(this.type===b._in&&this.unexpected(t),e.await=!0):a&&this.options.ecmaVersion>=8&&(l.start!==h||o||"Identifier"!==l.type||"async"!==l.name?this.options.ecmaVersion>=9&&(e.await=!1):this.unexpected()),i&&a&&this.raise(l.start,"The left-hand side of a for-of loop may not start with 'let'."),this.toAssignable(l,!1,u),this.checkLValPattern(l),this.parseForIn(e,l)):(this.checkExpressionErrors(u,!0),t>-1&&this.unexpected(t),this.parseFor(e,l))},X.parseFunctionStatement=function(e,t,r){return this.next(),this.parseFunction(e,J|(r?0:Q),!1,t)},X.parseIfStatement=function(e){return this.next(),e.test=this.parseParenExpression(),e.consequent=this.parseStatement("if"),e.alternate=this.eat(b._else)?this.parseStatement("if"):null,this.finishNode(e,"IfStatement")},X.parseReturnStatement=function(e){return this.inFunction||this.options.allowReturnOutsideFunction||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(b.semi)||this.insertSemicolon()?e.argument=null:(e.argument=this.parseExpression(),this.semicolon()),this.finishNode(e,"ReturnStatement")},X.parseSwitchStatement=function(e){var t;this.next(),e.discriminant=this.parseParenExpression(),e.cases=[],this.expect(b.braceL),this.labels.push(Y),this.enterScope(0);for(var r=!1;this.type!==b.braceR;)if(this.type===b._case||this.type===b._default){var n=this.type===b._case;t&&this.finishNode(t,"SwitchCase"),e.cases.push(t=this.startNode()),t.consequent=[],this.next(),n?t.test=this.parseExpression():(r&&this.raiseRecoverable(this.lastTokStart,"Multiple default clauses"),r=!0,t.test=null),this.expect(b.colon)}else t||this.unexpected(),t.consequent.push(this.parseStatement(null));return this.exitScope(),t&&this.finishNode(t,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(e,"SwitchStatement")},X.parseThrowStatement=function(e){return this.next(),T.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),e.argument=this.parseExpression(),this.semicolon(),this.finishNode(e,"ThrowStatement")};var Z=[];X.parseCatchClauseParam=function(){var e=this.parseBindingAtom(),t="Identifier"===e.type;return this.enterScope(t?32:0),this.checkLValPattern(e,t?4:2),this.expect(b.parenR),e},X.parseTryStatement=function(e){if(this.next(),e.block=this.parseBlock(),e.handler=null,this.type===b._catch){var t=this.startNode();this.next(),this.eat(b.parenL)?t.param=this.parseCatchClauseParam():(this.options.ecmaVersion<10&&this.unexpected(),t.param=null,this.enterScope(0)),t.body=this.parseBlock(!1),this.exitScope(),e.handler=this.finishNode(t,"CatchClause")}return e.finalizer=this.eat(b._finally)?this.parseBlock():null,e.handler||e.finalizer||this.raise(e.start,"Missing catch or finally clause"),this.finishNode(e,"TryStatement")},X.parseVarStatement=function(e,t,r){return this.next(),this.parseVar(e,!1,t,r),this.semicolon(),this.finishNode(e,"VariableDeclaration")},X.parseWhileStatement=function(e){return this.next(),e.test=this.parseParenExpression(),this.labels.push(q),e.body=this.parseStatement("while"),this.labels.pop(),this.finishNode(e,"WhileStatement")},X.parseWithStatement=function(e){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),e.object=this.parseParenExpression(),e.body=this.parseStatement("with"),this.finishNode(e,"WithStatement")},X.parseEmptyStatement=function(e){return this.next(),this.finishNode(e,"EmptyStatement")},X.parseLabeledStatement=function(e,t,r,n){for(var s=0,i=this.labels;s=0;o--){var u=this.labels[o];if(u.statementStart!==e.start)break;u.statementStart=this.start,u.kind=a}return this.labels.push({name:t,kind:a,statementStart:this.start}),e.body=this.parseStatement(n?-1===n.indexOf("label")?n+"label":n:"label"),this.labels.pop(),e.label=r,this.finishNode(e,"LabeledStatement")},X.parseExpressionStatement=function(e,t){return e.expression=t,this.semicolon(),this.finishNode(e,"ExpressionStatement")},X.parseBlock=function(e,t,r){for(void 0===e&&(e=!0),void 0===t&&(t=this.startNode()),t.body=[],this.expect(b.braceL),e&&this.enterScope(0);this.type!==b.braceR;){var n=this.parseStatement(null);t.body.push(n)}return r&&(this.strict=!1),this.next(),e&&this.exitScope(),this.finishNode(t,"BlockStatement")},X.parseFor=function(e,t){return e.init=t,this.expect(b.semi),e.test=this.type===b.semi?null:this.parseExpression(),this.expect(b.semi),e.update=this.type===b.parenR?null:this.parseExpression(),this.expect(b.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,"ForStatement")},X.parseForIn=function(e,t){var r=this.type===b._in;return this.next(),"VariableDeclaration"===t.type&&null!=t.declarations[0].init&&(!r||this.options.ecmaVersion<8||this.strict||"var"!==t.kind||"Identifier"!==t.declarations[0].id.type)&&this.raise(t.start,(r?"for-in":"for-of")+" loop variable declaration may not have an initializer"),e.left=t,e.right=r?this.parseExpression():this.parseMaybeAssign(),this.expect(b.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,r?"ForInStatement":"ForOfStatement")},X.parseVar=function(e,t,r,n){for(e.declarations=[],e.kind=r;;){var s=this.startNode();if(this.parseVarId(s,r),this.eat(b.eq)?s.init=this.parseMaybeAssign(t):n||"const"!==r||this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of")?n||"Identifier"===s.id.type||t&&(this.type===b._in||this.isContextual("of"))?s.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.unexpected(),e.declarations.push(this.finishNode(s,"VariableDeclarator")),!this.eat(b.comma))break}return e},X.parseVarId=function(e,t){e.id=this.parseBindingAtom(),this.checkLValPattern(e.id,"var"===t?1:2,!1)};var J=1,Q=2;function ee(e,t){var r=t.key.name,n=e[r],s="true";return"MethodDefinition"!==t.type||"get"!==t.kind&&"set"!==t.kind||(s=(t.static?"s":"i")+t.kind),"iget"===n&&"iset"===s||"iset"===n&&"iget"===s||"sget"===n&&"sset"===s||"sset"===n&&"sget"===s?(e[r]="true",!1):!!n||(e[r]=s,!1)}function te(e,t){var r=e.computed,n=e.key;return!r&&("Identifier"===n.type&&n.name===t||"Literal"===n.type&&n.value===t)}X.parseFunction=function(e,t,r,n,s){this.initFunction(e),(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!n)&&(this.type===b.star&&t&Q&&this.unexpected(),e.generator=this.eat(b.star)),this.options.ecmaVersion>=8&&(e.async=!!n),t&J&&(e.id=4&t&&this.type!==b.name?null:this.parseIdent(),!e.id||t&Q||this.checkLValSimple(e.id,this.strict||e.generator||e.async?this.treatFunctionsAsVar?1:2:3));var i=this.yieldPos,a=this.awaitPos,o=this.awaitIdentPos;return this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(G(e.async,e.generator)),t&J||(e.id=this.type===b.name?this.parseIdent():null),this.parseFunctionParams(e),this.parseFunctionBody(e,r,!1,s),this.yieldPos=i,this.awaitPos=a,this.awaitIdentPos=o,this.finishNode(e,t&J?"FunctionDeclaration":"FunctionExpression")},X.parseFunctionParams=function(e){this.expect(b.parenL),e.params=this.parseBindingList(b.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams()},X.parseClass=function(e,t){this.next();var r=this.strict;this.strict=!0,this.parseClassId(e,t),this.parseClassSuper(e);var n=this.enterClassBody(),s=this.startNode(),i=!1;for(s.body=[],this.expect(b.braceL);this.type!==b.braceR;){var a=this.parseClassElement(null!==e.superClass);a&&(s.body.push(a),"MethodDefinition"===a.type&&"constructor"===a.kind?(i&&this.raiseRecoverable(a.start,"Duplicate constructor in the same class"),i=!0):a.key&&"PrivateIdentifier"===a.key.type&&ee(n,a)&&this.raiseRecoverable(a.key.start,"Identifier '#"+a.key.name+"' has already been declared"))}return this.strict=r,this.next(),e.body=this.finishNode(s,"ClassBody"),this.exitClassBody(),this.finishNode(e,t?"ClassDeclaration":"ClassExpression")},X.parseClassElement=function(e){if(this.eat(b.semi))return null;var t=this.options.ecmaVersion,r=this.startNode(),n="",s=!1,i=!1,a="method",o=!1;if(this.eatContextual("static")){if(t>=13&&this.eat(b.braceL))return this.parseClassStaticBlock(r),r;this.isClassElementNameStart()||this.type===b.star?o=!0:n="static"}if(r.static=o,!n&&t>=8&&this.eatContextual("async")&&(!this.isClassElementNameStart()&&this.type!==b.star||this.canInsertSemicolon()?n="async":i=!0),!n&&(t>=9||!i)&&this.eat(b.star)&&(s=!0),!n&&!i&&!s){var u=this.value;(this.eatContextual("get")||this.eatContextual("set"))&&(this.isClassElementNameStart()?a=u:n=u)}if(n?(r.computed=!1,r.key=this.startNodeAt(this.lastTokStart,this.lastTokStartLoc),r.key.name=n,this.finishNode(r.key,"Identifier")):this.parseClassElementName(r),t<13||this.type===b.parenL||"method"!==a||s||i){var h=!r.static&&te(r,"constructor"),l=h&&e;h&&"method"!==a&&this.raise(r.key.start,"Constructor can't have get/set modifier"),r.kind=h?"constructor":a,this.parseClassMethod(r,s,i,l)}else this.parseClassField(r);return r},X.isClassElementNameStart=function(){return this.type===b.name||this.type===b.privateId||this.type===b.num||this.type===b.string||this.type===b.bracketL||this.type.keyword},X.parseClassElementName=function(e){this.type===b.privateId?("constructor"===this.value&&this.raise(this.start,"Classes can't have an element named '#constructor'"),e.computed=!1,e.key=this.parsePrivateIdent()):this.parsePropertyName(e)},X.parseClassMethod=function(e,t,r,n){var s=e.key;"constructor"===e.kind?(t&&this.raise(s.start,"Constructor can't be a generator"),r&&this.raise(s.start,"Constructor can't be an async method")):e.static&&te(e,"prototype")&&this.raise(s.start,"Classes may not have a static property named prototype");var i=e.value=this.parseMethod(t,r,n);return"get"===e.kind&&0!==i.params.length&&this.raiseRecoverable(i.start,"getter should have no params"),"set"===e.kind&&1!==i.params.length&&this.raiseRecoverable(i.start,"setter should have exactly one param"),"set"===e.kind&&"RestElement"===i.params[0].type&&this.raiseRecoverable(i.params[0].start,"Setter cannot use rest params"),this.finishNode(e,"MethodDefinition")},X.parseClassField=function(e){if(te(e,"constructor")?this.raise(e.key.start,"Classes can't have a field named 'constructor'"):e.static&&te(e,"prototype")&&this.raise(e.key.start,"Classes can't have a static field named 'prototype'"),this.eat(b.eq)){var t=this.currentThisScope(),r=t.inClassFieldInit;t.inClassFieldInit=!0,e.value=this.parseMaybeAssign(),t.inClassFieldInit=r}else e.value=null;return this.semicolon(),this.finishNode(e,"PropertyDefinition")},X.parseClassStaticBlock=function(e){e.body=[];var t=this.labels;for(this.labels=[],this.enterScope(320);this.type!==b.braceR;){var r=this.parseStatement(null);e.body.push(r)}return this.next(),this.exitScope(),this.labels=t,this.finishNode(e,"StaticBlock")},X.parseClassId=function(e,t){this.type===b.name?(e.id=this.parseIdent(),t&&this.checkLValSimple(e.id,2,!1)):(!0===t&&this.unexpected(),e.id=null)},X.parseClassSuper=function(e){e.superClass=this.eat(b._extends)?this.parseExprSubscripts(null,!1):null},X.enterClassBody=function(){var e={declared:Object.create(null),used:[]};return this.privateNameStack.push(e),e.declared},X.exitClassBody=function(){var e=this.privateNameStack.pop(),t=e.declared,r=e.used;if(this.options.checkPrivateFields)for(var n=this.privateNameStack.length,s=0===n?null:this.privateNameStack[n-1],i=0;i=11&&(this.eatContextual("as")?(e.exported=this.parseModuleExportName(),this.checkExport(t,e.exported,this.lastTokStart)):e.exported=null),this.expectContextual("from"),this.type!==b.string&&this.unexpected(),e.source=this.parseExprAtom(),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause()),this.semicolon(),this.finishNode(e,"ExportAllDeclaration")},X.parseExport=function(e,t){if(this.next(),this.eat(b.star))return this.parseExportAllDeclaration(e,t);if(this.eat(b._default))return this.checkExport(t,"default",this.lastTokStart),e.declaration=this.parseExportDefaultDeclaration(),this.finishNode(e,"ExportDefaultDeclaration");if(this.shouldParseExportStatement())e.declaration=this.parseExportDeclaration(e),"VariableDeclaration"===e.declaration.type?this.checkVariableExport(t,e.declaration.declarations):this.checkExport(t,e.declaration.id,e.declaration.id.start),e.specifiers=[],e.source=null;else{if(e.declaration=null,e.specifiers=this.parseExportSpecifiers(t),this.eatContextual("from"))this.type!==b.string&&this.unexpected(),e.source=this.parseExprAtom(),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause());else{for(var r=0,n=e.specifiers;r=16&&(e.attributes=this.parseWithClause()),this.semicolon(),this.finishNode(e,"ImportDeclaration")},X.parseImportSpecifier=function(){var e=this.startNode();return e.imported=this.parseModuleExportName(),this.eatContextual("as")?e.local=this.parseIdent():(this.checkUnreserved(e.imported),e.local=e.imported),this.checkLValSimple(e.local,2),this.finishNode(e,"ImportSpecifier")},X.parseImportDefaultSpecifier=function(){var e=this.startNode();return e.local=this.parseIdent(),this.checkLValSimple(e.local,2),this.finishNode(e,"ImportDefaultSpecifier")},X.parseImportNamespaceSpecifier=function(){var e=this.startNode();return this.next(),this.expectContextual("as"),e.local=this.parseIdent(),this.checkLValSimple(e.local,2),this.finishNode(e,"ImportNamespaceSpecifier")},X.parseImportSpecifiers=function(){var e=[],t=!0;if(this.type===b.name&&(e.push(this.parseImportDefaultSpecifier()),!this.eat(b.comma)))return e;if(this.type===b.star)return e.push(this.parseImportNamespaceSpecifier()),e;for(this.expect(b.braceL);!this.eat(b.braceR);){if(t)t=!1;else if(this.expect(b.comma),this.afterTrailingComma(b.braceR))break;e.push(this.parseImportSpecifier())}return e},X.parseWithClause=function(){var e=[];if(!this.eat(b._with))return e;this.expect(b.braceL);for(var t={},r=!0;!this.eat(b.braceR);){if(r)r=!1;else if(this.expect(b.comma),this.afterTrailingComma(b.braceR))break;var n=this.parseImportAttribute(),s="Identifier"===n.key.type?n.key.name:n.key.value;C(t,s)&&this.raiseRecoverable(n.key.start,"Duplicate attribute key '"+s+"'"),t[s]=!0,e.push(n)}return e},X.parseImportAttribute=function(){var e=this.startNode();return e.key=this.type===b.string?this.parseExprAtom():this.parseIdent("never"!==this.options.allowReserved),this.expect(b.colon),this.type!==b.string&&this.unexpected(),e.value=this.parseExprAtom(),this.finishNode(e,"ImportAttribute")},X.parseModuleExportName=function(){if(this.options.ecmaVersion>=13&&this.type===b.string){var e=this.parseLiteral(this.value);return F.test(e.value)&&this.raise(e.start,"An export name cannot include a lone surrogate."),e}return this.parseIdent(!0)},X.adaptDirectivePrologue=function(e){for(var t=0;t=5&&"ExpressionStatement"===e.type&&"Literal"===e.expression.type&&"string"==typeof e.expression.value&&('"'===this.input[e.start]||"'"===this.input[e.start])};var re=U.prototype;re.toAssignable=function(e,t,r){if(this.options.ecmaVersion>=6&&e)switch(e.type){case"Identifier":this.inAsync&&"await"===e.name&&this.raise(e.start,"Cannot use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":case"RestElement":break;case"ObjectExpression":e.type="ObjectPattern",r&&this.checkPatternErrors(r,!0);for(var n=0,s=e.properties;n=8&&!o&&"async"===u.name&&!this.canInsertSemicolon()&&this.eat(b._function))return this.overrideContext(se.f_expr),this.parseFunction(this.startNodeAt(i,a),0,!1,!0,t);if(s&&!this.canInsertSemicolon()){if(this.eat(b.arrow))return this.parseArrowExpression(this.startNodeAt(i,a),[u],!1,t);if(this.options.ecmaVersion>=8&&"async"===u.name&&this.type===b.name&&!o&&(!this.potentialArrowInForAwait||"of"!==this.value||this.containsEsc))return u=this.parseIdent(!1),!this.canInsertSemicolon()&&this.eat(b.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAt(i,a),[u],!0,t)}return u;case b.regexp:var h=this.value;return(n=this.parseLiteral(h.value)).regex={pattern:h.pattern,flags:h.flags},n;case b.num:case b.string:return this.parseLiteral(this.value);case b._null:case b._true:case b._false:return(n=this.startNode()).value=this.type===b._null?null:this.type===b._true,n.raw=this.type.keyword,this.next(),this.finishNode(n,"Literal");case b.parenL:var l=this.start,c=this.parseParenAndDistinguishExpression(s,t);return e&&(e.parenthesizedAssign<0&&!this.isSimpleAssignTarget(c)&&(e.parenthesizedAssign=l),e.parenthesizedBind<0&&(e.parenthesizedBind=l)),c;case b.bracketL:return n=this.startNode(),this.next(),n.elements=this.parseExprList(b.bracketR,!0,!0,e),this.finishNode(n,"ArrayExpression");case b.braceL:return this.overrideContext(se.b_expr),this.parseObj(!1,e);case b._function:return n=this.startNode(),this.next(),this.parseFunction(n,0);case b._class:return this.parseClass(this.startNode(),!1);case b._new:return this.parseNew();case b.backQuote:return this.parseTemplate();case b._import:return this.options.ecmaVersion>=11?this.parseExprImport(r):this.unexpected();default:return this.parseExprAtomDefault()}},ae.parseExprAtomDefault=function(){this.unexpected()},ae.parseExprImport=function(e){var t=this.startNode();if(this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword import"),this.next(),this.type===b.parenL&&!e)return this.parseDynamicImport(t);if(this.type===b.dot){var r=this.startNodeAt(t.start,t.loc&&t.loc.start);return r.name="import",t.meta=this.finishNode(r,"Identifier"),this.parseImportMeta(t)}this.unexpected()},ae.parseDynamicImport=function(e){if(this.next(),e.source=this.parseMaybeAssign(),this.options.ecmaVersion>=16)this.eat(b.parenR)?e.options=null:(this.expect(b.comma),this.afterTrailingComma(b.parenR)?e.options=null:(e.options=this.parseMaybeAssign(),this.eat(b.parenR)||(this.expect(b.comma),this.afterTrailingComma(b.parenR)||this.unexpected())));else if(!this.eat(b.parenR)){var t=this.start;this.eat(b.comma)&&this.eat(b.parenR)?this.raiseRecoverable(t,"Trailing comma is not allowed in import()"):this.unexpected(t)}return this.finishNode(e,"ImportExpression")},ae.parseImportMeta=function(e){this.next();var t=this.containsEsc;return e.property=this.parseIdent(!0),"meta"!==e.property.name&&this.raiseRecoverable(e.property.start,"The only valid meta property for import is 'import.meta'"),t&&this.raiseRecoverable(e.start,"'import.meta' must not contain escaped characters"),"module"===this.options.sourceType||this.options.allowImportExportEverywhere||this.raiseRecoverable(e.start,"Cannot use 'import.meta' outside a module"),this.finishNode(e,"MetaProperty")},ae.parseLiteral=function(e){var t=this.startNode();return t.value=e,t.raw=this.input.slice(this.start,this.end),110===t.raw.charCodeAt(t.raw.length-1)&&(t.bigint=t.raw.slice(0,-1).replace(/_/g,"")),this.next(),this.finishNode(t,"Literal")},ae.parseParenExpression=function(){this.expect(b.parenL);var e=this.parseExpression();return this.expect(b.parenR),e},ae.shouldParseArrow=function(e){return!this.canInsertSemicolon()},ae.parseParenAndDistinguishExpression=function(e,t){var r,n=this.start,s=this.startLoc,i=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var a,o=this.start,u=this.startLoc,h=[],l=!0,c=!1,p=new H,d=this.yieldPos,m=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==b.parenR;){if(l?l=!1:this.expect(b.comma),i&&this.afterTrailingComma(b.parenR,!0)){c=!0;break}if(this.type===b.ellipsis){a=this.start,h.push(this.parseParenItem(this.parseRestBinding())),this.type===b.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element");break}h.push(this.parseMaybeAssign(!1,p,this.parseParenItem))}var f=this.lastTokEnd,g=this.lastTokEndLoc;if(this.expect(b.parenR),e&&this.shouldParseArrow(h)&&this.eat(b.arrow))return this.checkPatternErrors(p,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=d,this.awaitPos=m,this.parseParenArrowList(n,s,h,t);h.length&&!c||this.unexpected(this.lastTokStart),a&&this.unexpected(a),this.checkExpressionErrors(p,!0),this.yieldPos=d||this.yieldPos,this.awaitPos=m||this.awaitPos,h.length>1?((r=this.startNodeAt(o,u)).expressions=h,this.finishNodeAt(r,"SequenceExpression",f,g)):r=h[0]}else r=this.parseParenExpression();if(this.options.preserveParens){var x=this.startNodeAt(n,s);return x.expression=r,this.finishNode(x,"ParenthesizedExpression")}return r},ae.parseParenItem=function(e){return e},ae.parseParenArrowList=function(e,t,r,n){return this.parseArrowExpression(this.startNodeAt(e,t),r,!1,n)};var he=[];ae.parseNew=function(){this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword new");var e=this.startNode();if(this.next(),this.options.ecmaVersion>=6&&this.type===b.dot){var t=this.startNodeAt(e.start,e.loc&&e.loc.start);t.name="new",e.meta=this.finishNode(t,"Identifier"),this.next();var r=this.containsEsc;return e.property=this.parseIdent(!0),"target"!==e.property.name&&this.raiseRecoverable(e.property.start,"The only valid meta property for new is 'new.target'"),r&&this.raiseRecoverable(e.start,"'new.target' must not contain escaped characters"),this.allowNewDotTarget||this.raiseRecoverable(e.start,"'new.target' can only be used in functions and class static block"),this.finishNode(e,"MetaProperty")}var n=this.start,s=this.startLoc;return e.callee=this.parseSubscripts(this.parseExprAtom(null,!1,!0),n,s,!0,!1),this.eat(b.parenL)?e.arguments=this.parseExprList(b.parenR,this.options.ecmaVersion>=8,!1):e.arguments=he,this.finishNode(e,"NewExpression")},ae.parseTemplateElement=function(e){var t=e.isTagged,r=this.startNode();return this.type===b.invalidTemplate?(t||this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"),r.value={raw:this.value.replace(/\r\n?/g,"\n"),cooked:null}):r.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value},this.next(),r.tail=this.type===b.backQuote,this.finishNode(r,"TemplateElement")},ae.parseTemplate=function(e){void 0===e&&(e={});var t=e.isTagged;void 0===t&&(t=!1);var r=this.startNode();this.next(),r.expressions=[];var n=this.parseTemplateElement({isTagged:t});for(r.quasis=[n];!n.tail;)this.type===b.eof&&this.raise(this.pos,"Unterminated template literal"),this.expect(b.dollarBraceL),r.expressions.push(this.parseExpression()),this.expect(b.braceR),r.quasis.push(n=this.parseTemplateElement({isTagged:t}));return this.next(),this.finishNode(r,"TemplateLiteral")},ae.isAsyncProp=function(e){return!e.computed&&"Identifier"===e.key.type&&"async"===e.key.name&&(this.type===b.name||this.type===b.num||this.type===b.string||this.type===b.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===b.star)&&!T.test(this.input.slice(this.lastTokEnd,this.start))},ae.parseObj=function(e,t){var r=this.startNode(),n=!0,s={};for(r.properties=[],this.next();!this.eat(b.braceR);){if(n)n=!1;else if(this.expect(b.comma),this.options.ecmaVersion>=5&&this.afterTrailingComma(b.braceR))break;var i=this.parseProperty(e,t);e||this.checkPropClash(i,s,t),r.properties.push(i)}return this.finishNode(r,e?"ObjectPattern":"ObjectExpression")},ae.parseProperty=function(e,t){var r,n,s,i,a=this.startNode();if(this.options.ecmaVersion>=9&&this.eat(b.ellipsis))return e?(a.argument=this.parseIdent(!1),this.type===b.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element"),this.finishNode(a,"RestElement")):(a.argument=this.parseMaybeAssign(!1,t),this.type===b.comma&&t&&t.trailingComma<0&&(t.trailingComma=this.start),this.finishNode(a,"SpreadElement"));this.options.ecmaVersion>=6&&(a.method=!1,a.shorthand=!1,(e||t)&&(s=this.start,i=this.startLoc),e||(r=this.eat(b.star)));var o=this.containsEsc;return this.parsePropertyName(a),!e&&!o&&this.options.ecmaVersion>=8&&!r&&this.isAsyncProp(a)?(n=!0,r=this.options.ecmaVersion>=9&&this.eat(b.star),this.parsePropertyName(a)):n=!1,this.parsePropertyValue(a,e,r,n,s,i,t,o),this.finishNode(a,"Property")},ae.parseGetterSetter=function(e){e.kind=e.key.name,this.parsePropertyName(e),e.value=this.parseMethod(!1);var t="get"===e.kind?0:1;if(e.value.params.length!==t){var r=e.value.start;"get"===e.kind?this.raiseRecoverable(r,"getter should have no params"):this.raiseRecoverable(r,"setter should have exactly one param")}else"set"===e.kind&&"RestElement"===e.value.params[0].type&&this.raiseRecoverable(e.value.params[0].start,"Setter cannot use rest params")},ae.parsePropertyValue=function(e,t,r,n,s,i,a,o){(r||n)&&this.type===b.colon&&this.unexpected(),this.eat(b.colon)?(e.value=t?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,a),e.kind="init"):this.options.ecmaVersion>=6&&this.type===b.parenL?(t&&this.unexpected(),e.kind="init",e.method=!0,e.value=this.parseMethod(r,n)):t||o||!(this.options.ecmaVersion>=5)||e.computed||"Identifier"!==e.key.type||"get"!==e.key.name&&"set"!==e.key.name||this.type===b.comma||this.type===b.braceR||this.type===b.eq?this.options.ecmaVersion>=6&&!e.computed&&"Identifier"===e.key.type?((r||n)&&this.unexpected(),this.checkUnreserved(e.key),"await"!==e.key.name||this.awaitIdentPos||(this.awaitIdentPos=s),e.kind="init",t?e.value=this.parseMaybeDefault(s,i,this.copyNode(e.key)):this.type===b.eq&&a?(a.shorthandAssign<0&&(a.shorthandAssign=this.start),e.value=this.parseMaybeDefault(s,i,this.copyNode(e.key))):e.value=this.copyNode(e.key),e.shorthand=!0):this.unexpected():((r||n)&&this.unexpected(),this.parseGetterSetter(e))},ae.parsePropertyName=function(e){if(this.options.ecmaVersion>=6){if(this.eat(b.bracketL))return e.computed=!0,e.key=this.parseMaybeAssign(),this.expect(b.bracketR),e.key;e.computed=!1}return e.key=this.type===b.num||this.type===b.string?this.parseExprAtom():this.parseIdent("never"!==this.options.allowReserved)},ae.initFunction=function(e){e.id=null,this.options.ecmaVersion>=6&&(e.generator=e.expression=!1),this.options.ecmaVersion>=8&&(e.async=!1)},ae.parseMethod=function(e,t,r){var n=this.startNode(),s=this.yieldPos,i=this.awaitPos,a=this.awaitIdentPos;return this.initFunction(n),this.options.ecmaVersion>=6&&(n.generator=e),this.options.ecmaVersion>=8&&(n.async=!!t),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(64|G(t,n.generator)|(r?128:0)),this.expect(b.parenL),n.params=this.parseBindingList(b.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(n,!1,!0,!1),this.yieldPos=s,this.awaitPos=i,this.awaitIdentPos=a,this.finishNode(n,"FunctionExpression")},ae.parseArrowExpression=function(e,t,r,n){var s=this.yieldPos,i=this.awaitPos,a=this.awaitIdentPos;return this.enterScope(16|G(r,!1)),this.initFunction(e),this.options.ecmaVersion>=8&&(e.async=!!r),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,e.params=this.toAssignableList(t,!0),this.parseFunctionBody(e,!0,!1,n),this.yieldPos=s,this.awaitPos=i,this.awaitIdentPos=a,this.finishNode(e,"ArrowFunctionExpression")},ae.parseFunctionBody=function(e,t,r,n){var s=t&&this.type!==b.braceL,i=this.strict,a=!1;if(s)e.body=this.parseMaybeAssign(n),e.expression=!0,this.checkParams(e,!1);else{var o=this.options.ecmaVersion>=7&&!this.isSimpleParamList(e.params);i&&!o||(a=this.strictDirective(this.end))&&o&&this.raiseRecoverable(e.start,"Illegal 'use strict' directive in function with non-simple parameter list");var u=this.labels;this.labels=[],a&&(this.strict=!0),this.checkParams(e,!i&&!a&&!t&&!r&&this.isSimpleParamList(e.params)),this.strict&&e.id&&this.checkLValSimple(e.id,5),e.body=this.parseBlock(!1,void 0,a&&!i),e.expression=!1,this.adaptDirectivePrologue(e.body.body),this.labels=u}this.exitScope()},ae.isSimpleParamList=function(e){for(var t=0,r=e;t-1||s.functions.indexOf(e)>-1||s.var.indexOf(e)>-1,s.lexical.push(e),this.inModule&&1&s.flags&&delete this.undefinedExports[e]}else if(4===t)this.currentScope().lexical.push(e);else if(3===t){var i=this.currentScope();n=this.treatFunctionsAsVar?i.lexical.indexOf(e)>-1:i.lexical.indexOf(e)>-1||i.var.indexOf(e)>-1,i.functions.push(e)}else for(var a=this.scopeStack.length-1;a>=0;--a){var o=this.scopeStack[a];if(o.lexical.indexOf(e)>-1&&!(32&o.flags&&o.lexical[0]===e)||!this.treatFunctionsAsVarInScope(o)&&o.functions.indexOf(e)>-1){n=!0;break}if(o.var.push(e),this.inModule&&1&o.flags&&delete this.undefinedExports[e],259&o.flags)break}n&&this.raiseRecoverable(r,"Identifier '"+e+"' has already been declared")},ce.checkLocalExport=function(e){-1===this.scopeStack[0].lexical.indexOf(e.name)&&-1===this.scopeStack[0].var.indexOf(e.name)&&(this.undefinedExports[e.name]=e)},ce.currentScope=function(){return this.scopeStack[this.scopeStack.length-1]},ce.currentVarScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(259&t.flags)return t}},ce.currentThisScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(259&t.flags&&!(16&t.flags))return t}};var de=function(e,t,r){this.type="",this.start=t,this.end=0,e.options.locations&&(this.loc=new V(e,r)),e.options.directSourceFile&&(this.sourceFile=e.options.directSourceFile),e.options.ranges&&(this.range=[t,0])},me=U.prototype;function fe(e,t,r,n){return e.type=t,e.end=r,this.options.locations&&(e.loc.end=n),this.options.ranges&&(e.range[1]=r),e}me.startNode=function(){return new de(this,this.start,this.startLoc)},me.startNodeAt=function(e,t){return new de(this,e,t)},me.finishNode=function(e,t){return fe.call(this,e,t,this.lastTokEnd,this.lastTokEndLoc)},me.finishNodeAt=function(e,t,r,n){return fe.call(this,e,t,r,n)},me.copyNode=function(e){var t=new de(this,e.start,this.startLoc);for(var r in e)t[r]=e[r];return t};var ge="ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS",xe=ge+" Extended_Pictographic",ye=xe+" EBase EComp EMod EPres ExtPict",be={9:ge,10:xe,11:xe,12:ye,13:ye,14:ye},Te={9:"",10:"",11:"",12:"",13:"",14:"Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji"},Se="Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu",ve="Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb",Ae=ve+" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd",_e=Ae+" Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho",Ee=_e+" Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi",we=Ee+" Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith",Ie={9:ve,10:Ae,11:_e,12:Ee,13:we,14:we+" Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sunu Sunuwar Todhri Todr Tulu_Tigalari Tutg Unknown Zzzz"},De={};function Ce(e){var t=De[e]={binary:L(be[e]+" "+Se),binaryOfStrings:L(Te[e]),nonBinary:{General_Category:L(Se),Script:L(Ie[e])}};t.nonBinary.Script_Extensions=t.nonBinary.Script,t.nonBinary.gc=t.nonBinary.General_Category,t.nonBinary.sc=t.nonBinary.Script,t.nonBinary.scx=t.nonBinary.Script_Extensions}for(var ke=0,Re=[9,10,11,12,13,14];ke=6?"uy":"")+(e.options.ecmaVersion>=9?"s":"")+(e.options.ecmaVersion>=13?"d":"")+(e.options.ecmaVersion>=15?"v":""),this.unicodeProperties=De[e.options.ecmaVersion>=14?14:e.options.ecmaVersion],this.source="",this.flags="",this.start=0,this.switchU=!1,this.switchV=!1,this.switchN=!1,this.pos=0,this.lastIntValue=0,this.lastStringValue="",this.lastAssertionIsQuantifiable=!1,this.numCapturingParens=0,this.maxBackReference=0,this.groupNames=Object.create(null),this.backReferenceNames=[],this.branchID=null};function Ne(e){return 105===e||109===e||115===e}function Ve(e){return 36===e||e>=40&&e<=43||46===e||63===e||e>=91&&e<=94||e>=123&&e<=125}function Me(e){return e>=65&&e<=90||e>=97&&e<=122}function Oe(e){return Me(e)||95===e}function ze(e){return Oe(e)||Pe(e)}function Pe(e){return e>=48&&e<=57}function Ke(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function Ge(e){return e>=65&&e<=70?e-65+10:e>=97&&e<=102?e-97+10:e-48}function Ue(e){return e>=48&&e<=55}Fe.prototype.reset=function(e,t,r){var n=-1!==r.indexOf("v"),s=-1!==r.indexOf("u");this.start=0|e,this.source=t+"",this.flags=r,n&&this.parser.options.ecmaVersion>=15?(this.switchU=!0,this.switchV=!0,this.switchN=!0):(this.switchU=s&&this.parser.options.ecmaVersion>=6,this.switchV=!1,this.switchN=s&&this.parser.options.ecmaVersion>=9)},Fe.prototype.raise=function(e){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+e)},Fe.prototype.at=function(e,t){void 0===t&&(t=!1);var r=this.source,n=r.length;if(e>=n)return-1;var s=r.charCodeAt(e);if(!t&&!this.switchU||s<=55295||s>=57344||e+1>=n)return s;var i=r.charCodeAt(e+1);return i>=56320&&i<=57343?(s<<10)+i-56613888:s},Fe.prototype.nextIndex=function(e,t){void 0===t&&(t=!1);var r=this.source,n=r.length;if(e>=n)return n;var s,i=r.charCodeAt(e);return!t&&!this.switchU||i<=55295||i>=57344||e+1>=n||(s=r.charCodeAt(e+1))<56320||s>57343?e+1:e+2},Fe.prototype.current=function(e){return void 0===e&&(e=!1),this.at(this.pos,e)},Fe.prototype.lookahead=function(e){return void 0===e&&(e=!1),this.at(this.nextIndex(this.pos,e),e)},Fe.prototype.advance=function(e){void 0===e&&(e=!1),this.pos=this.nextIndex(this.pos,e)},Fe.prototype.eat=function(e,t){return void 0===t&&(t=!1),this.current(t)===e&&(this.advance(t),!0)},Fe.prototype.eatChars=function(e,t){void 0===t&&(t=!1);for(var r=this.pos,n=0,s=e;n-1&&this.raise(e.start,"Duplicate regular expression flag"),"u"===a&&(n=!0),"v"===a&&(s=!0)}this.options.ecmaVersion>=15&&n&&s&&this.raise(e.start,"Invalid regular expression flag")},Le.validateRegExpPattern=function(e){this.regexp_pattern(e),!e.switchN&&this.options.ecmaVersion>=9&&function(e){for(var t in e)return!0;return!1}(e.groupNames)&&(e.switchN=!0,this.regexp_pattern(e))},Le.regexp_pattern=function(e){e.pos=0,e.lastIntValue=0,e.lastStringValue="",e.lastAssertionIsQuantifiable=!1,e.numCapturingParens=0,e.maxBackReference=0,e.groupNames=Object.create(null),e.backReferenceNames.length=0,e.branchID=null,this.regexp_disjunction(e),e.pos!==e.source.length&&(e.eat(41)&&e.raise("Unmatched ')'"),(e.eat(93)||e.eat(125))&&e.raise("Lone quantifier brackets")),e.maxBackReference>e.numCapturingParens&&e.raise("Invalid escape");for(var t=0,r=e.backReferenceNames;t=16;for(t&&(e.branchID=new $e(e.branchID,null)),this.regexp_alternative(e);e.eat(124);)t&&(e.branchID=e.branchID.sibling()),this.regexp_alternative(e);t&&(e.branchID=e.branchID.parent),this.regexp_eatQuantifier(e,!0)&&e.raise("Nothing to repeat"),e.eat(123)&&e.raise("Lone quantifier brackets")},Le.regexp_alternative=function(e){for(;e.pos=9&&(r=e.eat(60)),e.eat(61)||e.eat(33))return this.regexp_disjunction(e),e.eat(41)||e.raise("Unterminated group"),e.lastAssertionIsQuantifiable=!r,!0}return e.pos=t,!1},Le.regexp_eatQuantifier=function(e,t){return void 0===t&&(t=!1),!!this.regexp_eatQuantifierPrefix(e,t)&&(e.eat(63),!0)},Le.regexp_eatQuantifierPrefix=function(e,t){return e.eat(42)||e.eat(43)||e.eat(63)||this.regexp_eatBracedQuantifier(e,t)},Le.regexp_eatBracedQuantifier=function(e,t){var r=e.pos;if(e.eat(123)){var n=0,s=-1;if(this.regexp_eatDecimalDigits(e)&&(n=e.lastIntValue,e.eat(44)&&this.regexp_eatDecimalDigits(e)&&(s=e.lastIntValue),e.eat(125)))return-1!==s&&s=16){var r=this.regexp_eatModifiers(e),n=e.eat(45);if(r||n){for(var s=0;s-1&&e.raise("Duplicate regular expression modifiers")}if(n){var a=this.regexp_eatModifiers(e);r||a||58!==e.current()||e.raise("Invalid regular expression modifiers");for(var o=0;o-1||r.indexOf(u)>-1)&&e.raise("Duplicate regular expression modifiers")}}}}if(e.eat(58)){if(this.regexp_disjunction(e),e.eat(41))return!0;e.raise("Unterminated group")}}e.pos=t}return!1},Le.regexp_eatCapturingGroup=function(e){if(e.eat(40)){if(this.options.ecmaVersion>=9?this.regexp_groupSpecifier(e):63===e.current()&&e.raise("Invalid group"),this.regexp_disjunction(e),e.eat(41))return e.numCapturingParens+=1,!0;e.raise("Unterminated group")}return!1},Le.regexp_eatModifiers=function(e){for(var t="",r=0;-1!==(r=e.current())&&Ne(r);)t+=$(r),e.advance();return t},Le.regexp_eatExtendedAtom=function(e){return e.eat(46)||this.regexp_eatReverseSolidusAtomEscape(e)||this.regexp_eatCharacterClass(e)||this.regexp_eatUncapturingGroup(e)||this.regexp_eatCapturingGroup(e)||this.regexp_eatInvalidBracedQuantifier(e)||this.regexp_eatExtendedPatternCharacter(e)},Le.regexp_eatInvalidBracedQuantifier=function(e){return this.regexp_eatBracedQuantifier(e,!0)&&e.raise("Nothing to repeat"),!1},Le.regexp_eatSyntaxCharacter=function(e){var t=e.current();return!!Ve(t)&&(e.lastIntValue=t,e.advance(),!0)},Le.regexp_eatPatternCharacters=function(e){for(var t=e.pos,r=0;-1!==(r=e.current())&&!Ve(r);)e.advance();return e.pos!==t},Le.regexp_eatExtendedPatternCharacter=function(e){var t=e.current();return!(-1===t||36===t||t>=40&&t<=43||46===t||63===t||91===t||94===t||124===t||(e.advance(),0))},Le.regexp_groupSpecifier=function(e){if(e.eat(63)){this.regexp_eatGroupName(e)||e.raise("Invalid group");var t=this.options.ecmaVersion>=16,r=e.groupNames[e.lastStringValue];if(r)if(t)for(var n=0,s=r;n=11,n=e.current(r);return e.advance(r),92===n&&this.regexp_eatRegExpUnicodeEscapeSequence(e,r)&&(n=e.lastIntValue),function(e){return c(e,!0)||36===e||95===e}(n)?(e.lastIntValue=n,!0):(e.pos=t,!1)},Le.regexp_eatRegExpIdentifierPart=function(e){var t=e.pos,r=this.options.ecmaVersion>=11,n=e.current(r);return e.advance(r),92===n&&this.regexp_eatRegExpUnicodeEscapeSequence(e,r)&&(n=e.lastIntValue),function(e){return p(e,!0)||36===e||95===e||8204===e||8205===e}(n)?(e.lastIntValue=n,!0):(e.pos=t,!1)},Le.regexp_eatAtomEscape=function(e){return!!(this.regexp_eatBackReference(e)||this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)||e.switchN&&this.regexp_eatKGroupName(e))||(e.switchU&&(99===e.current()&&e.raise("Invalid unicode escape"),e.raise("Invalid escape")),!1)},Le.regexp_eatBackReference=function(e){var t=e.pos;if(this.regexp_eatDecimalEscape(e)){var r=e.lastIntValue;if(e.switchU)return r>e.maxBackReference&&(e.maxBackReference=r),!0;if(r<=e.numCapturingParens)return!0;e.pos=t}return!1},Le.regexp_eatKGroupName=function(e){if(e.eat(107)){if(this.regexp_eatGroupName(e))return e.backReferenceNames.push(e.lastStringValue),!0;e.raise("Invalid named reference")}return!1},Le.regexp_eatCharacterEscape=function(e){return this.regexp_eatControlEscape(e)||this.regexp_eatCControlLetter(e)||this.regexp_eatZero(e)||this.regexp_eatHexEscapeSequence(e)||this.regexp_eatRegExpUnicodeEscapeSequence(e,!1)||!e.switchU&&this.regexp_eatLegacyOctalEscapeSequence(e)||this.regexp_eatIdentityEscape(e)},Le.regexp_eatCControlLetter=function(e){var t=e.pos;if(e.eat(99)){if(this.regexp_eatControlLetter(e))return!0;e.pos=t}return!1},Le.regexp_eatZero=function(e){return 48===e.current()&&!Pe(e.lookahead())&&(e.lastIntValue=0,e.advance(),!0)},Le.regexp_eatControlEscape=function(e){var t=e.current();return 116===t?(e.lastIntValue=9,e.advance(),!0):110===t?(e.lastIntValue=10,e.advance(),!0):118===t?(e.lastIntValue=11,e.advance(),!0):102===t?(e.lastIntValue=12,e.advance(),!0):114===t&&(e.lastIntValue=13,e.advance(),!0)},Le.regexp_eatControlLetter=function(e){var t=e.current();return!!Me(t)&&(e.lastIntValue=t%32,e.advance(),!0)},Le.regexp_eatRegExpUnicodeEscapeSequence=function(e,t){void 0===t&&(t=!1);var r,n=e.pos,s=t||e.switchU;if(e.eat(117)){if(this.regexp_eatFixedHexDigits(e,4)){var i=e.lastIntValue;if(s&&i>=55296&&i<=56319){var a=e.pos;if(e.eat(92)&&e.eat(117)&&this.regexp_eatFixedHexDigits(e,4)){var o=e.lastIntValue;if(o>=56320&&o<=57343)return e.lastIntValue=1024*(i-55296)+(o-56320)+65536,!0}e.pos=a,e.lastIntValue=i}return!0}if(s&&e.eat(123)&&this.regexp_eatHexDigits(e)&&e.eat(125)&&(r=e.lastIntValue)>=0&&r<=1114111)return!0;s&&e.raise("Invalid unicode escape"),e.pos=n}return!1},Le.regexp_eatIdentityEscape=function(e){if(e.switchU)return!!this.regexp_eatSyntaxCharacter(e)||!!e.eat(47)&&(e.lastIntValue=47,!0);var t=e.current();return!(99===t||e.switchN&&107===t||(e.lastIntValue=t,e.advance(),0))},Le.regexp_eatDecimalEscape=function(e){e.lastIntValue=0;var t=e.current();if(t>=49&&t<=57){do{e.lastIntValue=10*e.lastIntValue+(t-48),e.advance()}while((t=e.current())>=48&&t<=57);return!0}return!1},Le.regexp_eatCharacterClassEscape=function(e){var t=e.current();if(function(e){return 100===e||68===e||115===e||83===e||119===e||87===e}(t))return e.lastIntValue=-1,e.advance(),1;var r=!1;if(e.switchU&&this.options.ecmaVersion>=9&&((r=80===t)||112===t)){var n;if(e.lastIntValue=-1,e.advance(),e.eat(123)&&(n=this.regexp_eatUnicodePropertyValueExpression(e))&&e.eat(125))return r&&2===n&&e.raise("Invalid property name"),n;e.raise("Invalid property name")}return 0},Le.regexp_eatUnicodePropertyValueExpression=function(e){var t=e.pos;if(this.regexp_eatUnicodePropertyName(e)&&e.eat(61)){var r=e.lastStringValue;if(this.regexp_eatUnicodePropertyValue(e)){var n=e.lastStringValue;return this.regexp_validateUnicodePropertyNameAndValue(e,r,n),1}}if(e.pos=t,this.regexp_eatLoneUnicodePropertyNameOrValue(e)){var s=e.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(e,s)}return 0},Le.regexp_validateUnicodePropertyNameAndValue=function(e,t,r){C(e.unicodeProperties.nonBinary,t)||e.raise("Invalid property name"),e.unicodeProperties.nonBinary[t].test(r)||e.raise("Invalid property value")},Le.regexp_validateUnicodePropertyNameOrValue=function(e,t){return e.unicodeProperties.binary.test(t)?1:e.switchV&&e.unicodeProperties.binaryOfStrings.test(t)?2:void e.raise("Invalid property name")},Le.regexp_eatUnicodePropertyName=function(e){var t=0;for(e.lastStringValue="";Oe(t=e.current());)e.lastStringValue+=$(t),e.advance();return""!==e.lastStringValue},Le.regexp_eatUnicodePropertyValue=function(e){var t=0;for(e.lastStringValue="";ze(t=e.current());)e.lastStringValue+=$(t),e.advance();return""!==e.lastStringValue},Le.regexp_eatLoneUnicodePropertyNameOrValue=function(e){return this.regexp_eatUnicodePropertyValue(e)},Le.regexp_eatCharacterClass=function(e){if(e.eat(91)){var t=e.eat(94),r=this.regexp_classContents(e);return e.eat(93)||e.raise("Unterminated character class"),t&&2===r&&e.raise("Negated character class may contain strings"),!0}return!1},Le.regexp_classContents=function(e){return 93===e.current()?1:e.switchV?this.regexp_classSetExpression(e):(this.regexp_nonEmptyClassRanges(e),1)},Le.regexp_nonEmptyClassRanges=function(e){for(;this.regexp_eatClassAtom(e);){var t=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassAtom(e)){var r=e.lastIntValue;!e.switchU||-1!==t&&-1!==r||e.raise("Invalid character class"),-1!==t&&-1!==r&&t>r&&e.raise("Range out of order in character class")}}},Le.regexp_eatClassAtom=function(e){var t=e.pos;if(e.eat(92)){if(this.regexp_eatClassEscape(e))return!0;if(e.switchU){var r=e.current();(99===r||Ue(r))&&e.raise("Invalid class escape"),e.raise("Invalid escape")}e.pos=t}var n=e.current();return 93!==n&&(e.lastIntValue=n,e.advance(),!0)},Le.regexp_eatClassEscape=function(e){var t=e.pos;if(e.eat(98))return e.lastIntValue=8,!0;if(e.switchU&&e.eat(45))return e.lastIntValue=45,!0;if(!e.switchU&&e.eat(99)){if(this.regexp_eatClassControlLetter(e))return!0;e.pos=t}return this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)},Le.regexp_classSetExpression=function(e){var t,r=1;if(this.regexp_eatClassSetRange(e));else if(t=this.regexp_eatClassSetOperand(e)){2===t&&(r=2);for(var n=e.pos;e.eatChars([38,38]);)38!==e.current()&&(t=this.regexp_eatClassSetOperand(e))?2!==t&&(r=1):e.raise("Invalid character in character class");if(n!==e.pos)return r;for(;e.eatChars([45,45]);)this.regexp_eatClassSetOperand(e)||e.raise("Invalid character in character class");if(n!==e.pos)return r}else e.raise("Invalid character in character class");for(;;)if(!this.regexp_eatClassSetRange(e)){if(!(t=this.regexp_eatClassSetOperand(e)))return r;2===t&&(r=2)}},Le.regexp_eatClassSetRange=function(e){var t=e.pos;if(this.regexp_eatClassSetCharacter(e)){var r=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassSetCharacter(e)){var n=e.lastIntValue;return-1!==r&&-1!==n&&r>n&&e.raise("Range out of order in character class"),!0}e.pos=t}return!1},Le.regexp_eatClassSetOperand=function(e){return this.regexp_eatClassSetCharacter(e)?1:this.regexp_eatClassStringDisjunction(e)||this.regexp_eatNestedClass(e)},Le.regexp_eatNestedClass=function(e){var t=e.pos;if(e.eat(91)){var r=e.eat(94),n=this.regexp_classContents(e);if(e.eat(93))return r&&2===n&&e.raise("Negated character class may contain strings"),n;e.pos=t}if(e.eat(92)){var s=this.regexp_eatCharacterClassEscape(e);if(s)return s;e.pos=t}return null},Le.regexp_eatClassStringDisjunction=function(e){var t=e.pos;if(e.eatChars([92,113])){if(e.eat(123)){var r=this.regexp_classStringDisjunctionContents(e);if(e.eat(125))return r}else e.raise("Invalid escape");e.pos=t}return null},Le.regexp_classStringDisjunctionContents=function(e){for(var t=this.regexp_classString(e);e.eat(124);)2===this.regexp_classString(e)&&(t=2);return t},Le.regexp_classString=function(e){for(var t=0;this.regexp_eatClassSetCharacter(e);)t++;return 1===t?1:2},Le.regexp_eatClassSetCharacter=function(e){var t=e.pos;if(e.eat(92))return!(!this.regexp_eatCharacterEscape(e)&&!this.regexp_eatClassSetReservedPunctuator(e)&&(e.eat(98)?(e.lastIntValue=8,0):(e.pos=t,1)));var r=e.current();return!(r<0||r===e.lookahead()&&function(e){return 33===e||e>=35&&e<=38||e>=42&&e<=44||46===e||e>=58&&e<=64||94===e||96===e||126===e}(r)||function(e){return 40===e||41===e||45===e||47===e||e>=91&&e<=93||e>=123&&e<=125}(r)||(e.advance(),e.lastIntValue=r,0))},Le.regexp_eatClassSetReservedPunctuator=function(e){var t=e.current();return!!function(e){return 33===e||35===e||37===e||38===e||44===e||45===e||e>=58&&e<=62||64===e||96===e||126===e}(t)&&(e.lastIntValue=t,e.advance(),!0)},Le.regexp_eatClassControlLetter=function(e){var t=e.current();return!(!Pe(t)&&95!==t||(e.lastIntValue=t%32,e.advance(),0))},Le.regexp_eatHexEscapeSequence=function(e){var t=e.pos;if(e.eat(120)){if(this.regexp_eatFixedHexDigits(e,2))return!0;e.switchU&&e.raise("Invalid escape"),e.pos=t}return!1},Le.regexp_eatDecimalDigits=function(e){var t=e.pos,r=0;for(e.lastIntValue=0;Pe(r=e.current());)e.lastIntValue=10*e.lastIntValue+(r-48),e.advance();return e.pos!==t},Le.regexp_eatHexDigits=function(e){var t=e.pos,r=0;for(e.lastIntValue=0;Ke(r=e.current());)e.lastIntValue=16*e.lastIntValue+Ge(r),e.advance();return e.pos!==t},Le.regexp_eatLegacyOctalEscapeSequence=function(e){if(this.regexp_eatOctalDigit(e)){var t=e.lastIntValue;if(this.regexp_eatOctalDigit(e)){var r=e.lastIntValue;t<=3&&this.regexp_eatOctalDigit(e)?e.lastIntValue=64*t+8*r+e.lastIntValue:e.lastIntValue=8*t+r}else e.lastIntValue=t;return!0}return!1},Le.regexp_eatOctalDigit=function(e){var t=e.current();return Ue(t)?(e.lastIntValue=t-48,e.advance(),!0):(e.lastIntValue=0,!1)},Le.regexp_eatFixedHexDigits=function(e,t){var r=e.pos;e.lastIntValue=0;for(var n=0;n=this.input.length?this.finishToken(b.eof):e.override?e.override(this):void this.readToken(this.fullCharCodeAtPos())},je.readToken=function(e){return c(e,this.options.ecmaVersion>=6)||92===e?this.readWord():this.getTokenFromCode(e)},je.fullCharCodeAtPos=function(){var e=this.input.charCodeAt(this.pos);if(e<=55295||e>=56320)return e;var t=this.input.charCodeAt(this.pos+1);return t<=56319||t>=57344?e:(e<<10)+t-56613888},je.skipBlockComment=function(){var e=this.options.onComment&&this.curPosition(),t=this.pos,r=this.input.indexOf("*/",this.pos+=2);if(-1===r&&this.raise(this.pos-2,"Unterminated comment"),this.pos=r+2,this.options.locations)for(var n=void 0,s=t;(n=A(this.input,s,this.pos))>-1;)++this.curLine,s=this.lineStart=n;this.options.onComment&&this.options.onComment(!0,this.input.slice(t+2,r),t,this.pos,e,this.curPosition())},je.skipLineComment=function(e){for(var t=this.pos,r=this.options.onComment&&this.curPosition(),n=this.input.charCodeAt(this.pos+=e);this.pos8&&e<14||e>=5760&&_.test(String.fromCharCode(e))))break e;++this.pos}}},je.finishToken=function(e,t){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var r=this.type;this.type=e,this.value=t,this.updateContext(r)},je.readToken_dot=function(){var e=this.input.charCodeAt(this.pos+1);if(e>=48&&e<=57)return this.readNumber(!0);var t=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===e&&46===t?(this.pos+=3,this.finishToken(b.ellipsis)):(++this.pos,this.finishToken(b.dot))},je.readToken_slash=function(){var e=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===e?this.finishOp(b.assign,2):this.finishOp(b.slash,1)},je.readToken_mult_modulo_exp=function(e){var t=this.input.charCodeAt(this.pos+1),r=1,n=42===e?b.star:b.modulo;return this.options.ecmaVersion>=7&&42===e&&42===t&&(++r,n=b.starstar,t=this.input.charCodeAt(this.pos+2)),61===t?this.finishOp(b.assign,r+1):this.finishOp(n,r)},je.readToken_pipe_amp=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?this.options.ecmaVersion>=12&&61===this.input.charCodeAt(this.pos+2)?this.finishOp(b.assign,3):this.finishOp(124===e?b.logicalOR:b.logicalAND,2):61===t?this.finishOp(b.assign,2):this.finishOp(124===e?b.bitwiseOR:b.bitwiseAND,1)},je.readToken_caret=function(){return 61===this.input.charCodeAt(this.pos+1)?this.finishOp(b.assign,2):this.finishOp(b.bitwiseXOR,1)},je.readToken_plus_min=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?45!==t||this.inModule||62!==this.input.charCodeAt(this.pos+2)||0!==this.lastTokEnd&&!T.test(this.input.slice(this.lastTokEnd,this.pos))?this.finishOp(b.incDec,2):(this.skipLineComment(3),this.skipSpace(),this.nextToken()):61===t?this.finishOp(b.assign,2):this.finishOp(b.plusMin,1)},je.readToken_lt_gt=function(e){var t=this.input.charCodeAt(this.pos+1),r=1;return t===e?(r=62===e&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+r)?this.finishOp(b.assign,r+1):this.finishOp(b.bitShift,r)):33!==t||60!==e||this.inModule||45!==this.input.charCodeAt(this.pos+2)||45!==this.input.charCodeAt(this.pos+3)?(61===t&&(r=2),this.finishOp(b.relational,r)):(this.skipLineComment(4),this.skipSpace(),this.nextToken())},je.readToken_eq_excl=function(e){var t=this.input.charCodeAt(this.pos+1);return 61===t?this.finishOp(b.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===e&&62===t&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(b.arrow)):this.finishOp(61===e?b.eq:b.prefix,1)},je.readToken_question=function(){var e=this.options.ecmaVersion;if(e>=11){var t=this.input.charCodeAt(this.pos+1);if(46===t){var r=this.input.charCodeAt(this.pos+2);if(r<48||r>57)return this.finishOp(b.questionDot,2)}if(63===t)return e>=12&&61===this.input.charCodeAt(this.pos+2)?this.finishOp(b.assign,3):this.finishOp(b.coalesce,2)}return this.finishOp(b.question,1)},je.readToken_numberSign=function(){var e=35;if(this.options.ecmaVersion>=13&&(++this.pos,c(e=this.fullCharCodeAtPos(),!0)||92===e))return this.finishToken(b.privateId,this.readWord1());this.raise(this.pos,"Unexpected character '"+$(e)+"'")},je.getTokenFromCode=function(e){switch(e){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(b.parenL);case 41:return++this.pos,this.finishToken(b.parenR);case 59:return++this.pos,this.finishToken(b.semi);case 44:return++this.pos,this.finishToken(b.comma);case 91:return++this.pos,this.finishToken(b.bracketL);case 93:return++this.pos,this.finishToken(b.bracketR);case 123:return++this.pos,this.finishToken(b.braceL);case 125:return++this.pos,this.finishToken(b.braceR);case 58:return++this.pos,this.finishToken(b.colon);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(b.backQuote);case 48:var t=this.input.charCodeAt(this.pos+1);if(120===t||88===t)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===t||79===t)return this.readRadixNumber(8);if(98===t||66===t)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(e);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(e);case 124:case 38:return this.readToken_pipe_amp(e);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(e);case 60:case 62:return this.readToken_lt_gt(e);case 61:case 33:return this.readToken_eq_excl(e);case 63:return this.readToken_question();case 126:return this.finishOp(b.prefix,1);case 35:return this.readToken_numberSign()}this.raise(this.pos,"Unexpected character '"+$(e)+"'")},je.finishOp=function(e,t){var r=this.input.slice(this.pos,this.pos+t);return this.pos+=t,this.finishToken(e,r)},je.readRegexp=function(){for(var e,t,r=this.pos;;){this.pos>=this.input.length&&this.raise(r,"Unterminated regular expression");var n=this.input.charAt(this.pos);if(T.test(n)&&this.raise(r,"Unterminated regular expression"),e)e=!1;else{if("["===n)t=!0;else if("]"===n&&t)t=!1;else if("/"===n&&!t)break;e="\\"===n}++this.pos}var s=this.input.slice(r,this.pos);++this.pos;var i=this.pos,a=this.readWord1();this.containsEsc&&this.unexpected(i);var o=this.regexpState||(this.regexpState=new Fe(this));o.reset(r,s,a),this.validateRegExpFlags(o),this.validateRegExpPattern(o);var u=null;try{u=new RegExp(s,a)}catch(e){}return this.finishToken(b.regexp,{pattern:s,flags:a,value:u})},je.readInt=function(e,t,r){for(var n=this.options.ecmaVersion>=12&&void 0===t,s=r&&48===this.input.charCodeAt(this.pos),i=this.pos,a=0,o=0,u=0,h=null==t?1/0:t;u=97?l-97+10:l>=65?l-65+10:l>=48&&l<=57?l-48:1/0)>=e)break;o=l,a=a*e+c}}return n&&95===o&&this.raiseRecoverable(this.pos-1,"Numeric separator is not allowed at the last of digits"),this.pos===i||null!=t&&this.pos-i!==t?null:a},je.readRadixNumber=function(e){var t=this.pos;this.pos+=2;var r=this.readInt(e);return null==r&&this.raise(this.start+2,"Expected number in radix "+e),this.options.ecmaVersion>=11&&110===this.input.charCodeAt(this.pos)?(r=We(this.input.slice(t,this.pos)),++this.pos):c(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(b.num,r)},je.readNumber=function(e){var t=this.pos;e||null!==this.readInt(10,void 0,!0)||this.raise(t,"Invalid number");var r=this.pos-t>=2&&48===this.input.charCodeAt(t);r&&this.strict&&this.raise(t,"Invalid number");var n=this.input.charCodeAt(this.pos);if(!r&&!e&&this.options.ecmaVersion>=11&&110===n){var s=We(this.input.slice(t,this.pos));return++this.pos,c(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(b.num,s)}r&&/[89]/.test(this.input.slice(t,this.pos))&&(r=!1),46!==n||r||(++this.pos,this.readInt(10),n=this.input.charCodeAt(this.pos)),69!==n&&101!==n||r||(43!==(n=this.input.charCodeAt(++this.pos))&&45!==n||++this.pos,null===this.readInt(10)&&this.raise(t,"Invalid number")),c(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var i,a=(i=this.input.slice(t,this.pos),r?parseInt(i,8):parseFloat(i.replace(/_/g,"")));return this.finishToken(b.num,a)},je.readCodePoint=function(){var e;if(123===this.input.charCodeAt(this.pos)){this.options.ecmaVersion<6&&this.unexpected();var t=++this.pos;e=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,e>1114111&&this.invalidStringToken(t,"Code point out of bounds")}else e=this.readHexChar(4);return e},je.readString=function(e){for(var t="",r=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var n=this.input.charCodeAt(this.pos);if(n===e)break;92===n?(t+=this.input.slice(r,this.pos),t+=this.readEscapedChar(!1),r=this.pos):8232===n||8233===n?(this.options.ecmaVersion<10&&this.raise(this.start,"Unterminated string constant"),++this.pos,this.options.locations&&(this.curLine++,this.lineStart=this.pos)):(v(n)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return t+=this.input.slice(r,this.pos++),this.finishToken(b.string,t)};var He={};je.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(e){if(e!==He)throw e;this.readInvalidTemplateToken()}this.inTemplateElement=!1},je.invalidStringToken=function(e,t){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw He;this.raise(e,t)},je.readTmplToken=function(){for(var e="",t=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var r=this.input.charCodeAt(this.pos);if(96===r||36===r&&123===this.input.charCodeAt(this.pos+1))return this.pos!==this.start||this.type!==b.template&&this.type!==b.invalidTemplate?(e+=this.input.slice(t,this.pos),this.finishToken(b.template,e)):36===r?(this.pos+=2,this.finishToken(b.dollarBraceL)):(++this.pos,this.finishToken(b.backQuote));if(92===r)e+=this.input.slice(t,this.pos),e+=this.readEscapedChar(!0),t=this.pos;else if(v(r)){switch(e+=this.input.slice(t,this.pos),++this.pos,r){case 13:10===this.input.charCodeAt(this.pos)&&++this.pos;case 10:e+="\n";break;default:e+=String.fromCharCode(r)}this.options.locations&&(++this.curLine,this.lineStart=this.pos),t=this.pos}else++this.pos}},je.readInvalidTemplateToken=function(){for(;this.pos=48&&t<=55){var n=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],s=parseInt(n,8);return s>255&&(n=n.slice(0,-1),s=parseInt(n,8)),this.pos+=n.length-1,t=this.input.charCodeAt(this.pos),"0"===n&&56!==t&&57!==t||!this.strict&&!e||this.invalidStringToken(this.pos-1-n.length,e?"Octal literal in template string":"Octal literal in strict mode"),String.fromCharCode(s)}return v(t)?(this.options.locations&&(this.lineStart=this.pos,++this.curLine),""):String.fromCharCode(t)}},je.readHexChar=function(e){var t=this.pos,r=this.readInt(16,e);return null===r&&this.invalidStringToken(t,"Bad character escape sequence"),r},je.readWord1=function(){this.containsEsc=!1;for(var e="",t=!0,r=this.pos,n=this.options.ecmaVersion>=6;this.pos{var r=class{constructor(e,t){this.value=e,Array.isArray(t)?this.size=t:(this.size=new Int32Array(3),t.z?this.size=new Int32Array([t.x,t.y,t.z]):t.y?this.size=new Int32Array([t.x,t.y]):this.size=new Int32Array([t.x]));const[r,n,s]=this.size;if(s){if(this.value.length!==r*n*s)throw new Error(`Input size ${this.value.length} does not match ${r} * ${n} * ${s} = ${n*r*s}`)}else if(n){if(this.value.length!==r*n)throw new Error(`Input size ${this.value.length} does not match ${r} * ${n} = ${n*r}`)}else if(this.value.length!==r)throw new Error(`Input size ${this.value.length} does not match ${r}`)}toArray(){const{utils:e}=i(),[t,r,n]=this.size;return n?e.erectMemoryOptimized3DFloat(this.value.subarray?this.value:new Float32Array(this.value),t,r,n):r?e.erectMemoryOptimized2DFloat(this.value.subarray?this.value:new Float32Array(this.value),t,r):this.value}};t.exports={Input:r,input:function(e,t){return new r(e,t)}}}),s=e((e,t)=>{t.exports={Texture:class{constructor(e){const{texture:t,size:r,dimensions:n,output:s,context:i,type:a="NumberTexture",kernel:o,internalFormat:u,textureFormat:h}=e;if(!s)throw new Error('settings property "output" required.');if(!i)throw new Error('settings property "context" required.');if(!t)throw new Error('settings property "texture" required.');if(!o)throw new Error('settings property "kernel" required.');this.texture=t,t._refs?t._refs++:t._refs=1,this.size=r,this.dimensions=n,this.output=s,this.context=i,this.kernel=o,this.type=a,this._deleted=!1,this.internalFormat=u,this.textureFormat=h}toArray(){throw new Error(`Not implemented on ${this.constructor.name}`)}clone(){throw new Error(`Not implemented on ${this.constructor.name}`)}delete(){throw new Error(`Not implemented on ${this.constructor.name}`)}clear(){throw new Error(`Not implemented on ${this.constructor.name}`)}}}}),i=e((e,t)=>{const i=r(),{Input:a}=n(),{Texture:o}=s(),u=/function ([^(]*)/,h=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,l=/([^\s,]+)/g,c={systemEndianness:()=>f,getSystemEndianness(){const e=new ArrayBuffer(4),t=new Uint32Array(e),r=new Uint8Array(e);if(t[0]=3735928559,239===r[0])return"LE";if(222===r[0])return"BE";throw new Error("unknown endianness")},isFunction:e=>"function"==typeof e,isFunctionString:e=>"string"==typeof e&&"function"===e.slice(0,8).toLowerCase(),getFunctionNameFromString(e){const t=u.exec(e);return t&&0!==t.length?t[1].trim():null},getFunctionBodyFromString:e=>e.substring(e.indexOf("{")+1,e.lastIndexOf("}")),getArgumentNamesFromString(e){const t=e.replace(h,"");let r=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(l);return null===r&&(r=[]),r},clone(e){if(null===e||"object"!=typeof e||e.hasOwnProperty("isActiveClone"))return e;const t=e.constructor();for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(e.isActiveClone=null,t[r]=c.clone(e[r]),delete e.isActiveClone);return t},isArray:e=>!isNaN(e.length),getVariableType(e,t){if(c.isArray(e))return e.length>0&&"IMG"===e[0].nodeName?"HTMLImageArray":"Array";switch(e.constructor){case Boolean:return"Boolean";case Number:return t&&Number.isInteger(e)?"Integer":"Float";case o:return e.type;case a:return"Input"}if("nodeName"in e)switch(e.nodeName){case"IMG":case"CANVAS":return"HTMLImage";case"VIDEO":return"HTMLVideo"}else{if(e.hasOwnProperty("type"))return e.type;if("undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return"OffscreenCanvas";if("undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap)return"ImageBitmap";if("undefined"!=typeof ImageData&&e instanceof ImageData)return"ImageData"}return"Unknown"},getKernelTextureSize(e,t){let[r,n,s]=t,i=(r||1)*(n||1)*(s||1);return e.optimizeFloatMemory&&"single"===e.precision&&(r=i=Math.ceil(i/4)),n>1&&r*n===i?new Int32Array([r,n]):c.closestSquareDimensions(i)},closestSquareDimensions(e){const t=Math.sqrt(e);let r=Math.ceil(t),n=Math.floor(t);for(;r*nMath.floor((e+t-1)/t)*t,getDimensions(e,t){let r;if(c.isArray(e)){const t=[];let n=e;for(;c.isArray(n);)t.push(n.length),n=n[0];r=t.reverse()}else if(e instanceof o)r=e.output;else{if(!(e instanceof a))throw new Error(`Unknown dimensions of ${e}`);r=e.size}if(t)for(r=Array.from(r);r.length<3;)r.push(1);return new Int32Array(r)},flatten2dArrayTo(e,t){let r=0;for(let n=0;ne.length>0?e.join(";\n")+";\n":"\n",warnDeprecated(e,t,r){r?console.warn(`You are using a deprecated ${e} "${t}". It has been replaced with "${r}". Fixing, but please upgrade as it will soon be removed.`):console.warn(`You are using a deprecated ${e} "${t}". It has been removed. Fixing, but please upgrade as it will soon be removed.`)},flipPixels:(e,t,r)=>{const n=r/2|0,s=4*t,i=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee.subarray(0,t),erect2DPackedFloat:(e,t,r)=>{const n=new Array(r);for(let s=0;s{const s=new Array(n);for(let i=0;ie.subarray(0,t),erectMemoryOptimized2DFloat:(e,t,r)=>{const n=new Array(r);for(let s=0;s{const s=new Array(n);for(let i=0;i{const r=new Float32Array(t);let n=0;for(let s=0;s{const n=new Array(r);let s=0;for(let i=0;i{const s=new Array(n);let i=0;for(let a=0;a{const r=new Array(t),n=4*t;let s=0;for(let t=0;t{const n=new Array(r),s=4*t;for(let i=0;i{const s=4*t,i=new Array(n);for(let a=0;a{const r=new Array(t),n=4*t;let s=0;for(let t=0;t{const n=4*t,s=new Array(r);for(let i=0;i{const s=4*t,i=new Array(n);for(let a=0;a{const r=new Array(e),n=4*t;let s=0;for(let t=0;t{const n=4*t,s=new Array(r);for(let i=0;i{const s=4*t,i=new Array(n);for(let a=0;a{const{findDependency:r,thisLookup:n,doNotDefine:s}=t;let a=t.flattened;a||(a=t.flattened={});const o=i.parse(e,{ecmaVersion:2020}),u=[];let h=0;const l=function e(t){if(Array.isArray(t)){const r=[];for(let n=0;nnull!==e);return s.length<1?"":`${t.kind} ${s.join(",")}`;case"VariableDeclarator":return t.init?t.init.object&&"ThisExpression"===t.init.object.type?n(t.init.property.name,!0)?`${t.id.name} = ${e(t.init)}`:null:`${t.id.name} = ${e(t.init)}`:t.id.name;case"CallExpression":if("subarray"===t.callee.property.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("gl"===t.callee.object.name||"context"===t.callee.object.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("ThisExpression"===t.callee.object.type)return u.push(r("this",t.callee.property.name)),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;if(t.callee.object.name){const n=r(t.callee.object.name,t.callee.property.name);return null===n?`${t.callee.object.name}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`:(u.push(n),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`)}if("MemberExpression"===t.callee.object.type)return`${e(t.callee.object)}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;throw new Error("unknown ast.callee");case"ReturnStatement":return`return ${e(t.argument)}`;case"BinaryExpression":return`(${e(t.left)}${t.operator}${e(t.right)})`;case"UnaryExpression":return t.prefix?`${t.operator} ${e(t.argument)}`:`${e(t.argument)} ${t.operator}`;case"ExpressionStatement":return`${e(t.expression)}`;case"SequenceExpression":return`(${e(t.expressions)})`;case"ArrowFunctionExpression":return`(${t.params.map(e).join(", ")}) => ${e(t.body)}`;case"Literal":return t.raw;case"Identifier":return t.name;case"MemberExpression":return"ThisExpression"===t.object.type?n(t.property.name):t.computed?`${e(t.object)}[${e(t.property)}]`:e(t.object)+"."+e(t.property);case"ThisExpression":return"this";case"NewExpression":return`new ${e(t.callee)}(${t.arguments.map(t=>e(t)).join(", ")})`;case"ForStatement":return`for (${e(t.init)};${e(t.test)};${e(t.update)}) ${e(t.body)}`;case"AssignmentExpression":return`${e(t.left)}${t.operator}${e(t.right)}`;case"UpdateExpression":return`${e(t.argument)}${t.operator}`;case"IfStatement":{const r=e(t.consequent);if(!t.alternate)return`if (${e(t.test)}) ${r}`;const n="BlockStatement"===t.consequent.type?"":";";return`if (${e(t.test)}) ${r}${n} else ${e(t.alternate)}`}case"ThrowStatement":return`throw ${e(t.argument)}`;case"ObjectPattern":return t.properties.map(e).join(", ");case"ArrayPattern":return t.elements.map(e).join(", ");case"DebuggerStatement":return"debugger;";case"ConditionalExpression":return`${e(t.test)}?${e(t.consequent)}:${e(t.alternate)}`;case"Property":if("init"===t.kind)return e(t.key)}throw new Error(`unhandled ast.type of ${t.type}`)}(o);if(u.length>0){const e=[];for(let r=0;r{if("VariableDeclaration"!==e.type)throw new Error('Ast is not of type "VariableDeclaration"');const t=[];for(let r=0;r{const r=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].r},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),n=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].g},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),s=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].b},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),i=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].a},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),a=[r(t),n(t),s(t),i(t)];return a.rKernel=r,a.gKernel=n,a.bKernel=s,a.aKernel=i,a.gpu=e,a},splitRGBAToCanvases:(e,t,r,n)=>{const s=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(t.r/255,0,0,255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});s(t);const i=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(0,t.g/255,0,255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});i(t);const a=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(0,0,t.b/255,255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});a(t);const o=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(255,255,255,t.a/255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});return o(t),[s.canvas,i.canvas,a.canvas,o.canvas]},getMinifySafeName:e=>{try{const{init:t}=i.parse(`const value = ${e.toString()}`,{ecmaVersion:2020}).body[0].declarations[0];return t.body.name||t.body.body[0].argument.name}catch(e){throw new Error("Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }")}},sanitizeName:function(e){return p.test(e)&&(e=e.replace(p,"S_S")),d.test(e)?e=e.replace(d,"U_U"):m.test(e)&&(e=e.replace(m,"u_u")),e}},p=/\$/,d=/__/,m=/_/,f=c.getSystemEndianness();t.exports={utils:c}}),a=e((e,t)=>{const{utils:r}=i(),{Input:s}=n();t.exports={Kernel:class{static get isSupported(){throw new Error(`"isSupported" not implemented on ${this.name}`)}static isContextMatch(e){throw new Error(`"isContextMatch" not implemented on ${this.name}`)}static getFeatures(){throw new Error(`"getFeatures" not implemented on ${this.name}`)}static destroyContext(e){throw new Error(`"destroyContext" called on ${this.name}`)}static nativeFunctionArguments(){throw new Error(`"nativeFunctionArguments" called on ${this.name}`)}static nativeFunctionReturnType(){throw new Error(`"nativeFunctionReturnType" called on ${this.name}`)}static combineKernels(){throw new Error(`"combineKernels" called on ${this.name}`)}constructor(e,t){if("object"!=typeof e){if("string"!=typeof e)throw new Error("source not a string");if(!r.isFunctionString(e))throw new Error("source not a function string")}this.useLegacyEncoder=!1,this.fallbackRequested=!1,this.onRequestFallback=null,this.argumentNames="string"==typeof e?r.getArgumentNamesFromString(e):null,this.argumentTypes=null,this.argumentSizes=null,this.argumentBitRatios=null,this.kernelArguments=null,this.kernelConstants=null,this.forceUploadKernelConstants=null,this.source=e,this.output=null,this.debug=!1,this.graphical=!1,this.loopMaxIterations=0,this.constants=null,this.constantTypes=null,this.constantBitRatios=null,this.dynamicArguments=!1,this.dynamicOutput=!1,this.canvas=null,this.context=null,this.checkContext=null,this.gpu=null,this.functions=null,this.nativeFunctions=null,this.injectedNative=null,this.subKernels=null,this.validate=!0,this.immutable=!1,this.pipeline=!1,this.precision=null,this.tactic=null,this.plugins=null,this.returnType=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.optimizeFloatMemory=null,this.strictIntegers=!1,this.fixIntegerDivisionAccuracy=null,this.randomSeed=null,this.built=!1,this.signature=null}mergeSettings(e){for(let t in e)if(e.hasOwnProperty(t)&&this.hasOwnProperty(t)){switch(t){case"output":if(!Array.isArray(e.output)){this.setOutput(e.output);continue}break;case"functions":this.functions=[];for(let t=0;te.name):null,returnType:this.returnType}}}buildSignature(e){const t=this.constructor;this.signature=t.getSignature(this,t.getArgumentTypes(this,e))}static getArgumentTypes(e,t){const n=new Array(t.length);for(let s=0;st.argumentTypes[e])||[]:t.argumentTypes||[],{name:r.getFunctionNameFromString(n)||null,source:n,argumentTypes:s,returnType:t.returnType||null}}onActivate(e){}}}}),o=e((e,t)=>{t.exports={FunctionBuilder:class e{static fromKernel(t,r,n){const{kernelArguments:s,kernelConstants:i,argumentNames:a,argumentSizes:o,argumentBitRatios:u,constants:h,constantBitRatios:l,debug:c,loopMaxIterations:p,nativeFunctions:d,output:m,optimizeFloatMemory:f,precision:g,plugins:x,source:y,subKernels:b,functions:T,leadingReturnStatement:S,followingReturnStatement:v,dynamicArguments:A,dynamicOutput:_}=t,E=new Array(s.length),w={};for(let e=0;eG.needsArgumentType(e,t),D=(e,t,r)=>{G.assignArgumentType(e,t,r)},C=(e,t,r)=>G.lookupReturnType(e,t,r),k=e=>G.lookupFunctionArgumentTypes(e),R=(e,t)=>G.lookupFunctionArgumentName(e,t),L=(e,t)=>G.lookupFunctionArgumentBitRatio(e,t),$=(e,t,r,n)=>{G.assignArgumentType(e,t,r,n)},F=(e,t,r,n)=>{G.assignArgumentBitRatio(e,t,r,n)},N=(e,t,r)=>{G.trackFunctionCall(e,t,r)},V=(e,t)=>{const n=[];for(let t=0;tnew r(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:m,plugins:x,constants:h,constantTypes:w,constantBitRatios:l,optimizeFloatMemory:f,precision:g,lookupReturnType:C,lookupFunctionArgumentTypes:k,lookupFunctionArgumentName:R,lookupFunctionArgumentBitRatio:L,needsArgumentType:I,assignArgumentType:D,triggerImplyArgumentType:$,triggerImplyArgumentBitRatio:F,onFunctionCall:N,onNestedFunction:V})));let K=null;b&&(K=b.map(e=>{const{name:t,source:n}=e;return new r(n,Object.assign({},M,{name:t,isSubKernel:!0,isRootKernel:!1}))}));const G=new e({kernel:t,rootNode:z,functionNodes:P,nativeFunctions:d,subKernelNodes:K});return G}constructor(e){if(e=e||{},this.kernel=e.kernel,this.rootNode=e.rootNode,this.functionNodes=e.functionNodes||[],this.subKernelNodes=e.subKernelNodes||[],this.nativeFunctions=e.nativeFunctions||[],this.functionMap={},this.nativeFunctionNames=[],this.lookupChain=[],this.functionNodeDependencies={},this.functionCalls={},this.rootNode&&(this.functionMap.kernel=this.rootNode),this.functionNodes)for(let e=0;e-1){const r=t.indexOf(e);if(-1===r)t.push(e);else{const e=t.splice(r,1)[0];t.push(e)}return t}const r=this.functionMap[e];if(r){const n=t.indexOf(e);if(-1===n){t.push(e),r.toString();for(let e=0;e-1){t.push(this.nativeFunctions[s].source);continue}const i=this.functionMap[n];i&&t.push(i.toString())}return t}toJSON(){return this.traceFunctionCalls(this.rootNode.name).reverse().map(e=>{const t=this.nativeFunctions.indexOf(e);if(t>-1)return{name:e,source:this.nativeFunctions[t].source};if(this.functionMap[e])return this.functionMap[e].toJSON();throw new Error(`function ${e} not found`)})}fromJSON(e,t){this.functionMap={};for(let r=0;r0){const s=t.arguments;for(let t=0;t{const{utils:r}=i();function n(e){return e.length>0?e[e.length-1]:null}const s="trackIdentifiers",a="memberExpression",o="inForLoopInit";t.exports={FunctionTracer:class{constructor(e){this.runningContexts=[],this.functionContexts=[],this.contexts=[],this.functionCalls=[],this.declarations=[],this.identifiers=[],this.functions=[],this.returnStatements=[],this.trackedIdentifiers=null,this.states=[],this.newFunctionContext(),this.scan(e)}isState(e){return this.states[this.states.length-1]===e}hasState(e){return this.states.indexOf(e)>-1}pushState(e){this.states.push(e)}popState(e){if(!this.isState(e))throw new Error(`Cannot pop the non-active state "${e}"`);this.states.pop()}get currentFunctionContext(){return n(this.functionContexts)}get currentContext(){return n(this.runningContexts)}newFunctionContext(){const e={"@contextType":"function"};this.contexts.push(e),this.functionContexts.push(e)}newContext(e){const t=Object.assign({"@contextType":"const/let"},this.currentContext);this.contexts.push(t),this.runningContexts.push(t),e();const{currentFunctionContext:r}=this;for(const e in r)r.hasOwnProperty(e)&&!t.hasOwnProperty(e)&&(t[e]=r[e]);return this.runningContexts.pop(),t}useFunctionContext(e){const t=n(this.functionContexts);this.runningContexts.push(t),e(),this.runningContexts.pop()}getIdentifiers(e){const t=this.trackedIdentifiers=[];return this.pushState(s),e(),this.trackedIdentifiers=null,this.popState(s),t}getDeclaration(e){const{currentContext:t,currentFunctionContext:r,runningContexts:n}=this,s=t[e]||r[e]||null;if(!s&&t===r&&n.length>0){const t=n[n.length-2];if(t[e])return t[e]}return s}scan(e){if(e)if(Array.isArray(e))for(let t=0;t{this.scan(e.body)});break;case"BlockStatement":this.newContext(()=>{this.scan(e.body)});break;case"AssignmentExpression":case"LogicalExpression":case"BinaryExpression":this.scan(e.left),this.scan(e.right);break;case"UpdateExpression":if("++"===e.operator){const t=this.getDeclaration(e.argument.name);t&&(t.suggestedType="Integer")}this.scan(e.argument);break;case"UnaryExpression":this.scan(e.argument);break;case"VariableDeclaration":"var"===e.kind?this.useFunctionContext(()=>{e.declarations=r.normalizeDeclarations(e),this.scan(e.declarations)}):(e.declarations=r.normalizeDeclarations(e),this.scan(e.declarations));break;case"VariableDeclarator":{const{currentContext:t}=this,r=this.hasState(o),n={ast:e,context:t,name:e.id.name,origin:"declaration",inForLoopInit:r,inForLoopTest:null,assignable:t===this.currentFunctionContext||!r&&!t.hasOwnProperty(e.id.name),suggestedType:null,valueType:null,dependencies:null,isSafe:null};t[e.id.name]||(t[e.id.name]=n),this.declarations.push(n),this.scan(e.id),this.scan(e.init);break}case"FunctionExpression":case"FunctionDeclaration":0===this.runningContexts.length?this.scan(e.body):this.functions.push(e);break;case"IfStatement":this.scan(e.test),this.scan(e.consequent),e.alternate&&this.scan(e.alternate);break;case"ForStatement":{let t;const r=this.newContext(()=>{this.pushState(o),this.scan(e.init),this.popState(o),t=this.getIdentifiers(()=>{this.scan(e.test)}),this.scan(e.update),this.newContext(()=>{this.scan(e.body)})});if(t)for(const e in r)"@contextType"!==e&&t.indexOf(e)>-1&&(r[e].inForLoopTest=!0);break}case"DoWhileStatement":case"WhileStatement":this.newContext(()=>{this.scan(e.body),this.scan(e.test)});break;case"Identifier":this.isState(s)&&this.trackedIdentifiers.push(e.name),this.identifiers.push({context:this.currentContext,declaration:this.getDeclaration(e.name),ast:e});break;case"ReturnStatement":this.returnStatements.push(e),this.scan(e.argument);break;case"MemberExpression":this.pushState(a),this.scan(e.object),this.scan(e.property),this.popState(a);break;case"ExpressionStatement":this.scan(e.expression);break;case"SequenceExpression":this.scan(e.expressions);break;case"CallExpression":this.functionCalls.push({context:this.currentContext,ast:e}),this.scan(e.arguments);break;case"ArrayExpression":this.scan(e.elements);break;case"ConditionalExpression":this.scan(e.test),this.scan(e.alternate),this.scan(e.consequent);break;case"SwitchStatement":this.scan(e.discriminant),this.scan(e.cases);break;case"SwitchCase":this.scan(e.test),this.scan(e.consequent);break;case"ThisExpression":case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${e.type}"`)}}}}}),h=e((e,t)=>{const n=r(),{utils:s}=i(),{FunctionTracer:a}=u(),o=["E","PI","SQRT2","SQRT1_2","LN2","LN10","LOG2E","LOG10E"],h=["abs","acos","acosh","asin","asinh","atan","atan2","atanh","cbrt","ceil","clz32","cos","cosh","expm1","exp","floor","fround","imul","log","log2","log10","log1p","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc"],l=["value","value[]","value[][]","value[][][]","value[][][][]","value.value","value.thread.value","this.thread.value","this.output.value","this.constants.value","this.constants.value[]","this.constants.value[][]","this.constants.value[][][]","this.constants.value[][][][]","fn()[]","fn()[][]","fn()[][][]","[][]"];const c={Number:"Number",Float:"Float",Integer:"Integer",Array:"Number","Array(2)":"Number","Array(3)":"Number","Array(4)":"Number","Matrix(2)":"Number","Matrix(3)":"Number","Matrix(4)":"Number",Array2D:"Number",Array3D:"Number",Input:"Number",HTMLCanvas:"Array(4)",OffscreenCanvas:"Array(4)",HTMLImage:"Array(4)",ImageBitmap:"Array(4)",ImageData:"Array(4)",HTMLVideo:"Array(4)",HTMLImageArray:"Array(4)",NumberTexture:"Number",MemoryOptimizedNumberTexture:"Number","Array1D(2)":"Array(2)","Array1D(3)":"Array(3)","Array1D(4)":"Array(4)","Array2D(2)":"Array(2)","Array2D(3)":"Array(3)","Array2D(4)":"Array(4)","Array3D(2)":"Array(2)","Array3D(3)":"Array(3)","Array3D(4)":"Array(4)","ArrayTexture(1)":"Number","ArrayTexture(2)":"Array(2)","ArrayTexture(3)":"Array(3)","ArrayTexture(4)":"Array(4)"};t.exports={FunctionNode:class{constructor(e,t){if(!e&&!t.ast)throw new Error("source parameter is missing");if(t=t||{},this.source=e,this.ast=null,this.name="string"==typeof e?t.isRootKernel?"kernel":t.name||s.getFunctionNameFromString(e):null,this.calledFunctions=[],this.constants={},this.constantTypes={},this.constantBitRatios={},this.isRootKernel=!1,this.isSubKernel=!1,this.debug=null,this.functions=null,this.identifiers=null,this.contexts=null,this.functionCalls=null,this.states=[],this.needsArgumentType=null,this.assignArgumentType=null,this.lookupReturnType=null,this.lookupFunctionArgumentTypes=null,this.lookupFunctionArgumentBitRatio=null,this.triggerImplyArgumentType=null,this.triggerImplyArgumentBitRatio=null,this.onNestedFunction=null,this.onFunctionCall=null,this.optimizeFloatMemory=null,this.precision=null,this.loopMaxIterations=null,this.argumentNames="string"==typeof this.source?s.getArgumentNamesFromString(this.source):null,this.argumentTypes=[],this.argumentSizes=[],this.argumentBitRatios=null,this.returnType=null,this.output=[],this.plugins=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.dynamicOutput=null,this.dynamicArguments=null,this.strictTypingChecking=!1,this.fixIntegerDivisionAccuracy=null,t)for(const e in t)t.hasOwnProperty(e)&&this.hasOwnProperty(e)&&(this[e]=t[e]);this.literalTypes={},this.validate(),this._string=null,this._internalVariableNames={}}validate(){if("string"!=typeof this.source&&!this.ast)throw new Error("this.source not a string");if(!this.ast&&!s.isFunctionString(this.source))throw new Error("this.source not a function string");if(!this.name)throw new Error("this.name could not be set");if(this.argumentTypes.length>0&&this.argumentTypes.length!==this.argumentNames.length)throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`);if(this.output.length<1)throw new Error("this.output is not big enough")}isIdentifierConstant(e){return!!this.constants&&this.constants.hasOwnProperty(e)}isInput(e){return"Input"===this.argumentTypes[this.argumentNames.indexOf(e)]}pushState(e){this.states.push(e)}popState(e){if(this.state!==e)throw new Error(`Cannot popState ${e} when in ${this.state}`);this.states.pop()}isState(e){return this.state===e}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(e){if("Identifier"===e.type)return e.name;if("ThisExpression"===e.type)return"this";if("MemberExpression"===e.type&&e.object&&e.property)return e.object.hasOwnProperty("name")&&"Math"!==e.object.name?this.astMemberExpressionUnroll(e.property):this.astMemberExpressionUnroll(e.object)+"."+this.astMemberExpressionUnroll(e.property);if(e.hasOwnProperty("expressions")){const t=e.expressions[0];if("Literal"===t.type&&0===t.value&&2===e.expressions.length)return this.astMemberExpressionUnroll(e.expressions[1])}throw this.astErrorOutput("Unknown astMemberExpressionUnroll",e)}getJsAST(e){if(this.ast)return this.ast;if("object"==typeof this.source)return this.traceFunctionAST(this.source),this.ast=this.source;if(null===(e=e||n))throw new Error("Missing JS to AST parser");const t=Object.freeze(e.parse(`const parser_${this.name} = ${this.source};`,{locations:!0,ecmaVersion:2020})),r=t.body[0].declarations[0].init;if(this.traceFunctionAST(r),!t)throw new Error("Failed to parse JS code");return this.ast=r}traceFunctionAST(e){const{contexts:t,declarations:r,functions:n,identifiers:s,functionCalls:i}=new a(e);this.contexts=t,this.identifiers=s,this.functionCalls=i,this.functions=n;for(let e=0;e":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const r=this.getType(e.left);if(this.isState("skip-literal-correction"))return r;if("LiteralInteger"===r){const t=this.getType(e.right);return"LiteralInteger"===t?e.left.value%1==0?"Integer":"Float":t}return c[r]||r;case"UpdateExpression":case"ReturnStatement":return this.getType(e.argument);case"UnaryExpression":return"~"===e.operator?"Integer":this.getType(e.argument);case"VariableDeclaration":{const t=e.declarations;let r;for(let e=0;ee.isSafe)}getDependencies(e,t,r){if(t||(t=[]),!e)return null;if(Array.isArray(e)){for(let n=0;n-1/0&&e.value<1/0&&!isNaN(e.value))});break;case"VariableDeclarator":return this.getDependencies(e.init,t,r);case"Identifier":const n=this.getDeclaration(e);if(n)t.push({name:e.name,origin:"declaration",isSafe:!r&&this.isSafeDependencies(n.dependencies)});else if(this.argumentNames.indexOf(e.name)>-1)t.push({name:e.name,origin:"argument",isSafe:!1});else if(this.strictTypingChecking)throw new Error(`Cannot find identifier origin "${e.name}"`);break;case"FunctionDeclaration":return this.getDependencies(e.body.body[e.body.body.length-1],t,r);case"ReturnStatement":return this.getDependencies(e.argument,t);case"BinaryExpression":case"LogicalExpression":return r="/"===e.operator||"*"===e.operator,this.getDependencies(e.left,t,r),this.getDependencies(e.right,t,r),t;case"UnaryExpression":case"UpdateExpression":return this.getDependencies(e.argument,t,r);case"VariableDeclaration":return this.getDependencies(e.declarations,t,r);case"ArrayExpression":return t.push({origin:"declaration",isSafe:!0}),t;case"CallExpression":return t.push({origin:"function",isSafe:!0}),t;case"MemberExpression":const s=this.getMemberExpressionDetails(e);switch(s.signature){case"value[]":this.getDependencies(e.object,t,r);break;case"value[][]":this.getDependencies(e.object.object,t,r);break;case"value[][][]":this.getDependencies(e.object.object.object,t,r);break;case"this.output.value":this.dynamicOutput&&t.push({name:s.name,origin:"output",isSafe:!1})}if(s)return s.property&&this.getDependencies(s.property,t,r),s.xProperty&&this.getDependencies(s.xProperty,t,r),s.yProperty&&this.getDependencies(s.yProperty,t,r),s.zProperty&&this.getDependencies(s.zProperty,t,r),t;case"SequenceExpression":return this.getDependencies(e.expressions,t,r);default:throw this.astErrorOutput(`Unhandled type ${e.type} in getDependencies`,e)}return t}getVariableSignature(e,t){if(!this.isAstVariable(e))throw new Error(`ast of type "${e.type}" is not a variable signature`);if("Identifier"===e.type)return"value";const r=[];for(;e;)e.computed?r.push("[]"):"ThisExpression"===e.type?r.unshift("this"):e.property&&e.property.name?"x"===e.property.name||"y"===e.property.name||"z"===e.property.name?r.unshift(t?"."+e.property.name:".value"):"constants"===e.property.name||"thread"===e.property.name||"output"===e.property.name?r.unshift("."+e.property.name):r.unshift(t?"."+e.property.name:".value"):e.name?r.unshift(t?e.name:"value"):e.callee&&e.callee.name?r.unshift(t?e.callee.name+"()":"fn()"):e.elements?r.unshift("[]"):r.unshift("unknown"),e=e.object;const n=r.join("");return t||l.includes(n)?n:null}build(){return this.toString().length>0}astGeneric(e,t){if(null===e)throw this.astErrorOutput("NULL ast",e);if(Array.isArray(e)){for(let r=0;r0?n[n.length-1]:0;return new Error(`${e} on line ${n.length}, position ${i.length}:\n ${r}`)}astDebuggerStatement(e,t){return t}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);return t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t}astFunction(e,t){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}astFunctionExpression(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}isChildFunction(e){for(let t=0;t1?t.push("(",n.join(","),")"):t.push(n[0]),t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)||(e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator))),t}checkAndUpconvertBitwiseUnary(e,t){}astUpdateExpression(e,t){return e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t}astLogicalExpression(e,t){return t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t.push(")"),t}astMemberExpression(e,t){return t}astCallExpression(e,t){return t}astArrayExpression(e,t){return t}getMemberExpressionDetails(e){if("MemberExpression"!==e.type)throw this.astErrorOutput(`Expression ${e.type} not a MemberExpression`,e);let t=null,r=null;const n=this.getVariableSignature(e);switch(n){case"value":return null;case"value.thread.value":case"this.thread.value":case"this.output.value":return{signature:n,type:"Integer",name:e.property.name};case"value[]":if("string"!=typeof e.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object),xProperty:e.property};case"value[][]":if("string"!=typeof e.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object.object),yProperty:e.object.property,xProperty:e.property};case"value[][][]":if("string"!=typeof e.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value[][][][]":if("string"!=typeof e.object.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(this.isAstMathVariable(e))return t=e.property.name,{name:t,origin:"Math",type:"Number",signature:n};switch(e.property.name){case"r":case"g":case"b":case"a":return t=e.object.name,{name:t,property:e.property.name,origin:"user",signature:n,type:"Number"};default:throw this.astErrorOutput("Unexpected expression",e)}case"this.constants.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n};case"this.constants.value[]":if("string"!=typeof e.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,xProperty:e.property};case"this.constants.value[][]":if("string"!=typeof e.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,yProperty:e.object.property,xProperty:e.property};case"this.constants.value[][][]":if("string"!=typeof e.object.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.object.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"fn()[]":case"fn()[][]":case"[][]":return{signature:n,property:e.property};default:throw this.astErrorOutput("Unexpected expression",e)}}findIdentifierOrigin(e){const t=[this.ast];for(;t.length>0;){const r=t[0];if("VariableDeclarator"===r.type&&r.id&&r.id.name&&r.id.name===e.name)return r;if(t.shift(),r.argument)t.push(r.argument);else if(r.body)t.push(r.body);else if(r.declarations)t.push(r.declarations);else if(Array.isArray(r))for(let e=0;e0;){const e=t.pop();if("ReturnStatement"===e.type)return e;if("FunctionDeclaration"!==e.type)if(e.argument)t.push(e.argument);else if(e.body)t.push(e.body);else if(e.declarations)t.push(e.declarations);else if(Array.isArray(e))for(let r=0;r{const{FunctionNode:r}=h();t.exports={CPUFunctionNode:class extends r{astFunction(e,t){if(!this.isRootKernel){t.push("function"),t.push(" "),t.push(this.name),t.push("(");for(let e=0;e0&&t.push(", "),t.push("user_"),t.push(r)}t.push(") {\n")}for(let r=0;r0&&t.push(r.join(""),";\n"),t.push(`for (let ${e}=0;${e}0&&t.push(`if (!${n.join("")}) break;\n`),t.push(i.join("")),t.push(`\n${s.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),t.push("if ("),this.astGeneric(e.test,t),t.push(") {\n"),this.astGeneric(e.body,t),t.push("} else {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astDoWhileStatement(e,t){if("DoWhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),this.astGeneric(e.body,t),t.push("if (!"),this.astGeneric(e.test,t),t.push(") {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astAssignmentExpression(e,t){const r=this.getDeclaration(e.left);if(r&&!r.assignable)throw this.astErrorOutput(`Variable ${e.left.name} is not assignable here`,e);const n=this.isState("assignment-as-statement");return n?this.popState("assignment-as-statement"):t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),n||t.push(")"),t}astBlockStatement(e,t){if(this.isState("loop-body")){this.pushState("block-body");for(let r=0;r0&&t.push(",");const n=r[e],s=this.getDeclaration(n.id);s.valueType||(s.valueType=this.getType(n.init)),this.astGeneric(n,t)}return this.isState("in-for-loop-init")||t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchStatement(e,t){const{discriminant:r,cases:n}=e;t.push("switch ("),this.astGeneric(r,t),t.push(") {\n");for(let e=0;e0&&(this.astGeneric(n[e].consequent,t),t.push("break;\n"))):(t.push("default:\n"),this.astGeneric(n[e].consequent,t),n[e].consequent&&n[e].consequent.length>0&&t.push("break;\n"));t.push("\n}")}astThisExpression(e,t){return t.push("_this"),t}astMemberExpression(e,t){const{signature:r,type:n,property:s,xProperty:i,yProperty:a,zProperty:o,name:u,origin:h}=this.getMemberExpressionDetails(e);switch(r){case"this.thread.value":return t.push(`_this.thread.${u}`),t;case"this.output.value":switch(u){case"x":t.push("outputX");break;case"y":t.push("outputY");break;case"z":t.push("outputZ");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":default:throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value.value":if("Math"===h)return t.push(Math[u]),t;switch(s){case"r":return t.push(`user_${u}[0]`),t;case"g":return t.push(`user_${u}[1]`),t;case"b":return t.push(`user_${u}[2]`),t;case"a":return t.push(`user_${u}[3]`),t}break;case"this.constants.value":case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":break;case"fn()[]":return this.astGeneric(e.object,t),t.push("["),this.astGeneric(e.property,t),t.push("]"),t;case"fn()[][]":return this.astGeneric(e.object.object,t),t.push("["),this.astGeneric(e.object.property,t),t.push("]"),t.push("["),this.astGeneric(e.property,t),t.push("]"),t}if(!e.computed)switch(n){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${h}_${u}`),t}const l=`${h}_${u}`;{let e,r;if("constants"===h){const t=this.constants[u];r="Input"===this.constantTypes[u],e=r?t.size:null}else r=this.isInput(u),e=r?this.argumentSizes[this.argumentNames.indexOf(u)]:null;t.push(`${l}`),o&&a?r?(t.push("[("),this.astGeneric(o,t),t.push(`*${this.dynamicArguments?"(outputY * outputX)":e[1]*e[0]})+(`),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(i,t),t.push("]")):(t.push("["),this.astGeneric(o,t),t.push("]"),t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(i,t),t.push("]")):a?r?(t.push("[("),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(i,t),t.push("]")):(t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(i,t),t.push("]")):void 0!==i&&(t.push("["),this.astGeneric(i,t),t.push("]"))}return t}astCallExpression(e,t){if("CallExpression"!==e.type)throw this.astErrorOutput("Unknown CallExpression",e);let r=this.astMemberExpressionUnroll(e.callee);this.calledFunctions.indexOf(r)<0&&this.calledFunctions.push(r),this.isAstMathFunction(e),this.onFunctionCall&&this.onFunctionCall(this.name,r,e.arguments),t.push(r),t.push("(");const n=this.lookupFunctionArgumentTypes(r)||[];for(let s=0;s0&&t.push(", "),this.astGeneric(i,t)}return t.push(")"),t}astArrayExpression(e,t){const r=this.getType(e),n=e.elements.length,s=[];for(let t=0;t{const{utils:r}=i();t.exports={cpuKernelString:function(e,t){const n=[],s=[],i=[],a=!/^function/.test(e.color.toString());if(n.push(" const { context, canvas, constants: incomingConstants } = settings;",` const output = new Int32Array(${JSON.stringify(Array.from(e.output))});`,` const _constantTypes = ${JSON.stringify(e.constantTypes)};`,` const _constants = ${function(e,t){const r=[];for(const n in t){if(!t.hasOwnProperty(n))continue;const s=t[n],i=e[n];switch(s){case"Number":case"Integer":case"Float":case"Boolean":r.push(`${n}:${i}`);break;case"Array(2)":case"Array(3)":case"Array(4)":case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":r.push(`${n}:new ${i.constructor.name}(${JSON.stringify(Array.from(i))})`)}}return`{ ${r.join()} }`}(e.constants,e.constantTypes)};`),s.push(" constants: _constants,"," context,"," output,"," thread: {x: 0, y: 0, z: 0},"),e.graphical){n.push(` const _imageData = context.createImageData(${e.output[0]}, ${e.output[1]});`),n.push(` const _colorData = new Uint8ClampedArray(${e.output[0]} * ${e.output[1]} * 4);`);const t=r.flattenFunctionToString((a?"function ":"")+e.color.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:(e,t)=>null}),o=r.flattenFunctionToString((a?"function ":"")+e.getPixels.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:()=>null});s.push(" _imageData,"," _colorData,",` color: ${t},`),i.push(` kernel.getPixels = ${o};`)}const o=[],u=Object.keys(e.constantTypes);for(let t=0;t"this"===t?(a?"function ":"")+e[r].toString():null,thisLookup:e=>{switch(e){case"canvas":return;case"context":return"context"}}});i.push(t),s.push(" _mediaTo2DArray,"),s.push(" _imageTo3DArray,")}else if(-1!==e.argumentTypes.indexOf("HTMLImage")||-1!==o.indexOf("HTMLImage")){const t=r.flattenFunctionToString((a?"function ":"")+e._mediaTo2DArray.toString(),{findDependency:(e,t)=>null,thisLookup:e=>{switch(e){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});i.push(t),s.push(" _mediaTo2DArray,")}return`function(settings) {\n${n.join("\n")}\n for (const p in _constantTypes) {\n if (!_constantTypes.hasOwnProperty(p)) continue;\n const type = _constantTypes[p];\n switch (type) {\n case 'Number':\n case 'Integer':\n case 'Float':\n case 'Boolean':\n case 'Array(2)':\n case 'Array(3)':\n case 'Array(4)':\n case 'Matrix(2)':\n case 'Matrix(3)':\n case 'Matrix(4)':\n if (incomingConstants.hasOwnProperty(p)) {\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\n }\n continue;\n }\n if (!incomingConstants.hasOwnProperty(p)) {\n throw new Error('constant ' + p + ' not found');\n }\n _constants[p] = incomingConstants[p];\n }\n const kernel = (function() {\n${e._kernelString}\n })\n .apply({ ${s.join("\n")} });\n ${i.join("\n")}\n return kernel;\n}`}}}),p=e((e,t)=>{const{Kernel:r}=a(),{FunctionBuilder:n}=o(),{CPUFunctionNode:s}=l(),{utils:u}=i(),{cpuKernelString:h}=c();t.exports={CPUKernel:class extends r{static getFeatures(){return this.features}static get features(){return Object.freeze({kernelMap:!0,isIntegerDivisionAccurate:!0})}static get isSupported(){return!0}static isContextMatch(e){return!1}static get mode(){return"cpu"}static nativeFunctionArguments(){return null}static nativeFunctionReturnType(){throw new Error(`Looking up native function return type not supported on ${this.name}`)}static combineKernels(e){return e}static getSignature(e,t){return"cpu"+(t.length>0?":"+t.join(","):"")}constructor(e,t){super(e,t),this.mergeSettings(e.settings||t),this._imageData=null,this._colorData=null,this._kernelString=null,this._prependedString=[],this.thread={x:0,y:0,z:0},this.translatedSources=null}initCanvas(){return"undefined"!=typeof document?document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(0,0):void 0}initContext(){return this.canvas?this.canvas.getContext("2d",{willReadFrequently:!0}):null}initPlugins(e){return[]}validateSettings(e){if(!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=u.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=u.getDimensions(t);else{if("NumberTexture"!==t&&"ArrayTexture(4)"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=e[0].output}}if(this.graphical&&2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");this.checkOutput()}translateSource(){if(this.leadingReturnStatement=this.output.length>1?"resultX[x] = ":"result[x] = ",this.subKernels){const e=[];for(let t=0;t1?`resultX_${r}[x] = subKernelResult_${r};\n`:`result_${r}[x] = subKernelResult_${r};\n`)}this.followingReturnStatement=e.join("")}const e=n.fromKernel(this,s);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){if(this.built)return;if(null!==this.randomSeed&&console.warn("randomSeed is not supported in cpu mode; Math.random() will be unseeded"),this.setupConstants(),this.setupArguments(arguments),this.validateSettings(arguments),this.translateSource(),this.graphical){const{canvas:e,output:t}=this;if(!e)throw new Error("no canvas available for using graphical output");const r=t[0],n=t[1]||1;e.width=r,e.height=n,this._imageData=this.context.createImageData(r,n),this._colorData=new Uint8ClampedArray(r*n*4)}const e=this.getKernelString();this.kernelString=e,this.debug&&(console.log("Function output:"),console.log(e));try{this.run=new Function([],e).bind(this)()}catch(e){console.error("An error occurred compiling the javascript: ",e)}this.buildSignature(arguments),this.built=!0}color(e,t,r,n){void 0===n&&(n=1),e=Math.floor(255*e),t=Math.floor(255*t),r=Math.floor(255*r),n=Math.floor(255*n);const s=this.output[0],i=this.output[1],a=this.thread.x+(i-this.thread.y-1)*s;this._colorData[4*a+0]=e,this._colorData[4*a+1]=t,this._colorData[4*a+2]=r,this._colorData[4*a+3]=n}getKernelString(){if(null!==this._kernelString)return this._kernelString;let e=null,{translatedSources:t}=this;return t.length>1?t=t.filter(t=>/^function/.test(t)?t:(e=t,!1)):e=t.shift(),this._kernelString=` const LOOP_MAX = ${this._getLoopMaxString()};\n ${this.injectedNative||""}\n const _this = this;\n ${this._resultKernelHeader()}\n ${this._processConstants()}\n return (${this.argumentNames.map(e=>"user_"+e).join(", ")}) => {\n ${this._prependedString.join("")}\n ${this._earlyThrows()}\n ${this._processArguments()}\n ${this.graphical?this._graphicalKernelBody(e):this._resultKernelBody(e)}\n ${t.length>0?t.join("\n"):""}\n };`}toString(){return h(this)}_getLoopMaxString(){return this.loopMaxIterations?` ${parseInt(this.loopMaxIterations)};`:" 1000;"}_processConstants(){if(!this.constants)return"";const e=[];for(let t in this.constants)switch(this.constantTypes[t]){case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":e.push(` const constants_${t} = this._mediaTo2DArray(this.constants.${t});\n`);break;case"HTMLImageArray":e.push(` const constants_${t} = this._imageTo3DArray(this.constants.${t});\n`);break;case"Input":e.push(` const constants_${t} = this.constants.${t}.value;\n`);break;default:e.push(` const constants_${t} = this.constants.${t};\n`)}return e.join("")}_earlyThrows(){if(this.graphical)return"";if(this.immutable)return"";if(!this.pipeline)return"";const e=[];for(let t=0;t`user_${n} === result_${e.name}`).join(" || ");t.push(`user_${n} === result${s?` || ${s}`:""}`)}return`if (${t.join(" || ")}) throw new Error('Source and destination arrays are the same. Use immutable = true');`}_processArguments(){const e=[];for(let t=0;t0?e.width:e.videoWidth,n=e.height>0?e.height:e.videoHeight;t.width=0;e--){const t=a[e]=new Array(r);for(let e=0;e`const result_${e.name} = new ${t}(outputX);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_mutableKernel1DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const result = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const result_${t.name} = new ${e}(outputX);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}`}_resultMutableKernel1DLoop(e){return` const outputX = _this.output[0];\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_resultImmutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y] = new ${t}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_mutableKernel2DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n const resultX = result[y] = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const resultX_${t.name} = result_${t.name}[y] = new ${e}(outputX);\n`).join("")}\n }`}_resultMutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y];\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_graphicalKernel2DLoop(e){return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_resultImmutableKernel3DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputZ);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels(e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y] = new ${t}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = resultY_${e.name}[y] = new ${t}(outputX);\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_mutableKernel3DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputZ);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels(e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n const resultX = resultY[y] = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const resultX_${t.name} = resultY_${t.name}[y] = new ${e}(outputX);\n`).join(" ")}\n }\n }`}_resultMutableKernel3DLoop(e){return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z];\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y];\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_kernelOutput(){return this.subKernels?`\n return {\n result: result,\n ${this.subKernels.map(e=>`${e.property}: result_${e.name}`).join(",\n ")}\n };`:"\n return result;"}_mapSubKernels(e){return null===this.subKernels?[""]:this.subKernels.map(e)}destroy(e){e&&delete this.canvas}static destroyContext(e){}toJSON(){const e=super.toJSON();return e.functionNodes=n.fromKernel(this,s).toJSON(),e}setOutput(e){super.setOutput(e);const[t,r]=this.output;this.graphical&&(this._imageData=this.context.createImageData(t,r),this._colorData=new Uint8ClampedArray(t*r*4))}prependString(e){if(this._kernelString)throw new Error("Kernel already built");this._prependedString.push(e)}hasPrependString(e){return this._prependedString.indexOf(e)>-1}}}}),d=e((e,t)=>{t.exports={}}),m=e((e,t)=>{const{Texture:r}=s();function n(e,t){e.activeTexture(e.TEXTURE15),e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST)}t.exports={GLTexture:class extends r{get textureType(){throw new Error(`"textureType" not implemented on ${this.name}`)}clone(){return new this.constructor(this)}beforeMutate(){return this.texture._refs>1&&(this.newTexture(),!0)}cloneTexture(){this.texture._refs--;const{context:e,size:t,texture:r,kernel:s}=this;s.debug&&console.warn("cloning internal texture"),e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),n(e,r),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,r,0);const i=e.createTexture();n(e,i),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),e.copyTexSubImage2D(e.TEXTURE_2D,0,0,0,0,0,t[0],t[1]),i._refs=1,this.texture=i}newTexture(){this.texture._refs--;const e=this.context,t=this.size;this.kernel.debug&&console.warn("new internal texture");const r=e.createTexture();n(e,r),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),r._refs=1,this.texture=r}clear(){if(this.texture._refs){this.texture._refs--;const e=this.context,t=this.texture=e.createTexture();n(e,t);const r=this.size;t._refs=1,e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,r[0],r[1],0,this.textureFormat,this.textureType,null)}const{context:e,texture:t}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.bindTexture(e.TEXTURE_2D,t),n(e,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}delete(){this._deleted||(this._deleted=!0,this.texture._refs&&(this.texture._refs--,this.texture._refs)||(this.kernel&&this.kernel.deleteTexture?this.kernel.deleteTexture(this.texture):this.context.deleteTexture(this.texture)))}framebuffer(){return this._framebuffer||(this._framebuffer=this.kernel.getRawValueFramebuffer(this.size[0],this.size[1])),this._framebuffer}}}}),f=e((e,t)=>{const{utils:r}=i(),{GLTexture:n}=m();t.exports={GLTextureFloat:class extends n{get textureType(){return this.context.FLOAT}constructor(e){super(e),this.type="ArrayTexture(1)"}renderRawOutput(){const e=this.context,t=this.size;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const r=new Float32Array(t[0]*t[1]*4);return e.readPixels(0,0,t[0],t[1],e.RGBA,e.FLOAT,r),r}renderValues(){return this._deleted?null:this.renderRawOutput()}toArray(){return r.erectFloat(this.renderValues(),this.output[0])}}}}),g=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureArray2Float:class extends n{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erectArray2(this.renderValues(),this.output[0],this.output[1])}}}}),x=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureArray2Float2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erect2DArray2(this.renderValues(),this.output[0],this.output[1])}}}}),y=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureArray2Float3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erect3DArray2(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),b=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureArray3Float:class extends n{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erectArray3(this.renderValues(),this.output[0])}}}}),T=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureArray3Float2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erect2DArray3(this.renderValues(),this.output[0],this.output[1])}}}}),S=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureArray3Float3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erect3DArray3(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),v=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureArray4Float:class extends n{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erectArray4(this.renderValues(),this.output[0])}}}}),A=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureArray4Float2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erect2DArray4(this.renderValues(),this.output[0],this.output[1])}}}}),_=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureArray4Float3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erect3DArray4(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),E=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureFloat2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return r.erect2DFloat(this.renderValues(),this.output[0],this.output[1])}}}}),w=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureFloat3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return r.erect3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),I=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureMemoryOptimized:class extends n{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}}}),D=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureMemoryOptimized2D:class extends n{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}}}),C=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=f();t.exports={GLTextureMemoryOptimized3D:class extends n{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),k=e((e,t)=>{const{utils:r}=i(),{GLTexture:n}=m();t.exports={GLTextureUnsigned:class extends n{get textureType(){return this.context.UNSIGNED_BYTE}constructor(e){super(e),this.type="NumberTexture"}renderRawOutput(){const{context:e}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const t=new Uint8Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.UNSIGNED_BYTE,t),t}renderValues(){return this._deleted?null:new Float32Array(this.renderRawOutput().buffer)}toArray(){return r.erectPackedFloat(this.renderValues(),this.output[0])}}}}),R=e((e,t)=>{const{utils:r}=i(),{GLTextureUnsigned:n}=k();t.exports={GLTextureUnsigned2D:class extends n{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}}}),L=e((e,t)=>{const{utils:r}=i(),{GLTextureUnsigned:n}=k();t.exports={GLTextureUnsigned3D:class extends n{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),$=e((e,t)=>{const{GLTextureUnsigned:r}=k();t.exports={GLTextureGraphical:class extends r{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return this.renderValues()}}}}),F=e((e,t)=>{const{Kernel:r}=a(),{utils:n}=i(),{GLTextureArray2Float:s}=g(),{GLTextureArray2Float2D:o}=x(),{GLTextureArray2Float3D:u}=y(),{GLTextureArray3Float:h}=b(),{GLTextureArray3Float2D:l}=T(),{GLTextureArray3Float3D:c}=S(),{GLTextureArray4Float:p}=v(),{GLTextureArray4Float2D:d}=A(),{GLTextureArray4Float3D:m}=_(),{GLTextureFloat:F}=f(),{GLTextureFloat2D:N}=E(),{GLTextureFloat3D:V}=w(),{GLTextureMemoryOptimized:M}=I(),{GLTextureMemoryOptimized2D:O}=D(),{GLTextureMemoryOptimized3D:z}=C(),{GLTextureUnsigned:P}=k(),{GLTextureUnsigned2D:K}=R(),{GLTextureUnsigned3D:G}=L(),{GLTextureGraphical:U}=$();const B={int:"Integer",float:"Number",vec2:"Array(2)",vec3:"Array(3)",vec4:"Array(4)"};t.exports={GLKernel:class extends r{static get mode(){return"gpu"}static getIsFloatRead(){const e=new this("function kernelFunction() {\n return 1;\n }",{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[1],precision:"single",returnType:"Number",tactic:"speed"});e.build(),e.run();const t=e.renderOutput();return e.destroy(!0),1===t[0]}static getIsIntegerDivisionAccurate(){const e=new this(function(e,t){return e[this.thread.x]/t[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[2],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[6,6030401],[3,3991]];e.build.apply(e,t),e.run.apply(e,t);const r=e.renderOutput();return e.destroy(!0),2===r[0]&&1511===r[1]}static getIsSpeedTacticSupported(){const e=new this(function(e){return e[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[4],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[0,1,2,3]];e.build.apply(e,t),e.run.apply(e,t);const r=e.renderOutput();return e.destroy(!0),0===Math.round(r[0])&&1===Math.round(r[1])&&2===Math.round(r[2])&&3===Math.round(r[3])}static get testCanvas(){throw new Error(`"testCanvas" not defined on ${this.name}`)}static get testContext(){throw new Error(`"testContext" not defined on ${this.name}`)}static getFeatures(){const e=this.testContext,t=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isSpeedTacticSupported:this.getIsSpeedTacticSupported(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:t,kernelMap:t,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize(),lowIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT),lowFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT),mediumIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT),mediumFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT),highIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT),highFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)})}static setupFeatureChecks(){throw new Error(`"setupFeatureChecks" not defined on ${this.name}`)}static getSignature(e,t){return e.getVariablePrecisionString()+(t.length>0?":"+t.join(","):"")}setFixIntegerDivisionAccuracy(e){return this.fixIntegerDivisionAccuracy=e,this}setPrecision(e){return this.precision=e,this}setFloatTextures(e){return n.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],r=[],n=[],s=/^[a-zA-Z_]/,i=/[a-zA-Z_0-9]/;let a=0,o=null,u=null;for(;a0?n[n.length-1]:null;if("FUNCTION_ARGUMENTS"!==c||"/"!==h||"*"!==l)if("MULTI_LINE_COMMENT"!==c||"*"!==h||"/"!==l)if("FUNCTION_ARGUMENTS"!==c||"/"!==h||"/"!==l)if("COMMENT"!==c||"\n"!==h)if(null!==c||"("!==h){if("FUNCTION_ARGUMENTS"===c){if(")"===h){n.pop();break}if("f"===h&&"l"===l&&"o"===e[a+2]&&"a"===e[a+3]&&"t"===e[a+4]&&" "===e[a+5]){n.push("DECLARE_VARIABLE"),u="float",o="",a+=6;continue}if("i"===h&&"n"===l&&"t"===e[a+2]&&" "===e[a+3]){n.push("DECLARE_VARIABLE"),u="int",o="",a+=4;continue}if("v"===h&&"e"===l&&"c"===e[a+2]&&"2"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec2",o="",a+=5;continue}if("v"===h&&"e"===l&&"c"===e[a+2]&&"3"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec3",o="",a+=5;continue}if("v"===h&&"e"===l&&"c"===e[a+2]&&"4"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec4",o="",a+=5;continue}}else if("DECLARE_VARIABLE"===c){if(""===o){if(" "===h){a++;continue}if(!s.test(h))throw new Error("variable name is not expected string")}o+=h,i.test(l)||(n.pop(),r.push(o),t.push(B[u]))}a++}else n.push("FUNCTION_ARGUMENTS"),a++;else n.pop(),a++;else n.push("COMMENT"),a+=2;else n.pop(),a+=2;else n.push("MULTI_LINE_COMMENT"),a+=2}if(n.length>0)throw new Error("GLSL function was not parsable");return{argumentNames:r,argumentTypes:t}}static nativeFunctionReturnType(e){return B[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:r,context:s,threadDim:i}=t.texSize;let a;if("single"===t.precision){const e=r[0],t=Math.ceil(r[1]/4);a=new Float32Array(e*t*4*4),s.readPixels(0,0,e,4*t,s.RGBA,s.FLOAT,a)}else{const e=new Uint8Array(r[0]*r[1]*4);s.readPixels(0,0,r[0],r[1],s.RGBA,s.UNSIGNED_BYTE,e),a=new Float32Array(e.buffer)}return a=a.subarray(0,i[0]*i[1]*i[2]),1===t.output.length?a:2===t.output.length?n.splitArray(a,t.output[0]):3===t.output.length?n.splitArray(a,t.output[0]*t.output[1]).map(function(e){return n.splitArray(e,t.output[0])}):void 0}constructor(e,t){super(e,t),this.transferValues=null,this.formatValues=null,this.TextureConstructor=null,this.renderOutput=null,this.renderRawOutput=null,this.texSize=null,this.translatedSource=null,this.compiledFragmentShader=null,this.compiledVertexShader=null,this.switchingKernels=null,this._textureSwitched=null,this._mappedTextureSwitched=null}checkTextureSize(){const{features:e}=this.constructor;if(this.texSize[0]>e.maxTextureSize||this.texSize[1]>e.maxTextureSize)throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${e.maxTextureSize},${e.maxTextureSize}]`)}translateSource(){throw new Error(`"translateSource" not defined on ${this.constructor.name}`)}pickRenderStrategy(e){if(this.graphical)return this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=e=>e,this.TextureConstructor=U,null;if("unsigned"===this.precision)if(this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=this.readPackedPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=G,null):this.output[1]>0?(this.TextureConstructor=K,null):(this.TextureConstructor=P,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else switch(null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.renderOutput=this.renderValues,this.output[2]>0?(this.TextureConstructor=G,this.formatValues=n.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=K,this.formatValues=n.erect2DPackedFloat,null):(this.TextureConstructor=P,this.formatValues=n.erectPackedFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else{if("single"!==this.precision)throw new Error(`unhandled precision of "${this.precision}"`);if(this.renderRawOutput=this.readFloatPixelsToFloat32Array,this.transferValues=this.readFloatPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.optimizeFloatMemory?this.output[2]>0?(this.TextureConstructor=z,null):this.output[1]>0?(this.TextureConstructor=O,null):(this.TextureConstructor=M,null):this.output[2]>0?(this.TextureConstructor=V,null):this.output[1]>0?(this.TextureConstructor=N,null):(this.TextureConstructor=F,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,null):this.output[1]>0?(this.TextureConstructor=o,null):(this.TextureConstructor=s,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,null):this.output[1]>0?(this.TextureConstructor=l,null):(this.TextureConstructor=h,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=m,null):this.output[1]>0?(this.TextureConstructor=d,null):(this.TextureConstructor=p,null)}if(this.renderOutput=this.renderValues,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.optimizeFloatMemory)switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=z,this.formatValues=n.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=O,this.formatValues=n.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=M,this.formatValues=n.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.formatValues=n.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.formatValues=n.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=n.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,this.formatValues=n.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=n.erect2DArray3,null):(this.TextureConstructor=h,this.formatValues=n.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=m,this.formatValues=n.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=d,this.formatValues=n.erect2DArray4,null):(this.TextureConstructor=p,this.formatValues=n.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=V,this.formatValues=n.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=N,this.formatValues=n.erect2DFloat,null):(this.TextureConstructor=F,this.formatValues=n.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.formatValues=n.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.formatValues=n.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=n.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,this.formatValues=n.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=n.erect2DArray3,null):(this.TextureConstructor=h,this.formatValues=n.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=m,this.formatValues=n.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=d,this.formatValues=n.erect2DArray4,null):(this.TextureConstructor=p,this.formatValues=n.erectArray4,null)}}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error("abstract method call")}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error("abstract method call")}getMainResultSubKernelNumberTexture(){throw new Error("abstract method call")}getMainResultKernelArray2Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray2Texture(){throw new Error("abstract method call")}getMainResultKernelArray3Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray3Texture(){throw new Error("abstract method call")}getMainResultKernelArray4Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray4Texture(){throw new Error("abstract method call")}getMainResultGraphical(){throw new Error("abstract method call")}getMainResultMemoryOptimizedFloats(){throw new Error("abstract method call")}getMainResultPackedPixels(){throw new Error("abstract method call")}getMainResultString(){return this.graphical?this.getMainResultGraphical():"single"===this.precision?this.optimizeFloatMemory?this.getMainResultMemoryOptimizedFloats():this.getMainResultTexture():this.getMainResultPackedPixels()}getMainResultNumberTexture(){return n.linesToString(this.getMainResultKernelNumberTexture())+n.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return n.linesToString(this.getMainResultKernelArray2Texture())+n.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return n.linesToString(this.getMainResultKernelArray3Texture())+n.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return n.linesToString(this.getMainResultKernelArray4Texture())+n.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} float;\n`}getIntTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic,!0)} int;\n`}getSampler2DTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2D;\n`}getSampler2DArrayTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2DArray;\n`}renderTexture(){return this.immutable?this.texture.clone():this.texture}readPackedPixelsToUint8Array(){if("unsigned"!==this.precision)throw new Error('Requires this.precision to be "unsigned"');const{texSize:e,context:t}=this,r=new Uint8Array(e[0]*e[1]*4);return t.readPixels(0,0,e[0],e[1],t.RGBA,t.UNSIGNED_BYTE,r),r}readPackedPixelsToFloat32Array(){return new Float32Array(this.readPackedPixelsToUint8Array().buffer)}readFloatPixelsToFloat32Array(){if("single"!==this.precision)throw new Error('Requires this.precision to be "single"');const{texSize:e,context:t}=this,r=e[0],n=e[1],s=new Float32Array(r*n*4);return t.readPixels(0,0,r,n,t.RGBA,t.FLOAT,s),s}getPixels(e){const{context:t,output:r}=this,[s,i]=r,a=new Uint8Array(s*i*4);return t.readPixels(0,0,s,i,t.RGBA,t.UNSIGNED_BYTE,a),new Uint8ClampedArray((e?a:n.flipPixels(a,s,i)).buffer)}renderKernelsToArrays(){const e={result:this.renderOutput()};for(let t=0;t0){for(let e=0;e0){const{mappedTextures:r}=this;for(let n=0;n{const{utils:r}=i(),{FunctionNode:n}=h();function s(e){if(!e||"object"!=typeof e)return!0;if(Array.isArray(e))return e.every(s);if("UpdateExpression"===e.type||"AssignmentExpression"===e.type||"SequenceExpression"===e.type)return!1;for(const t in e)if("loc"!==t&&"range"!==t&&"parent"!==t&&!s(e[t]))return!1;return!0}function a(e){let t=!1;function r(e){if(!e||"object"!=typeof e||t)return!1;if(Array.isArray(e))return e.some(r);if("MemberExpression"===e.type&&e.computed)return!0;for(const t in e)if("loc"!==t&&"range"!==t&&"parent"!==t&&r(e[t]))return!0;return!1}return function e(n){if(n&&"object"==typeof n&&!t)if(Array.isArray(n))n.forEach(e);else if("MemberExpression"===n.type&&n.computed&&r(n.property))t=!0;else for(const t in n)"loc"!==t&&"range"!==t&&"parent"!==t&&e(n[t])}(e),t}function o(e,t){if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return e.some(e=>o(e,t));if("CallExpression"===e.type&&"Identifier"===e.callee.type&&e.callee.name===t)return!0;for(const r in e)if("loc"!==r&&"range"!==r&&"parent"!==r&&o(e[r],t))return!0;return!1}function u(e){let t=!1;return function e(r){if(r&&"object"==typeof r&&!t)if(Array.isArray(r))r.forEach(e);else if("CallExpression"===r.type&&"Identifier"===r.callee.type&&r.arguments.some(e=>o(e,r.callee.name)))t=!0;else for(const t in r)"loc"!==t&&"range"!==t&&"parent"!==t&&e(r[t])}(e),t}function l(e){const t="ExpressionStatement"===e.type&&"AssignmentExpression"===e.expression.type?e.expression:null;return function e(r){if(!r||"object"!=typeof r)return!0;if(Array.isArray(r))return r.every(e);if("string"==typeof r.type){if("UpdateExpression"===r.type||"SequenceExpression"===r.type)return!1;if("AssignmentExpression"===r.type&&r!==t)return!1}for(const t in r)if("loc"!==t&&"range"!==t&&"parent"!==t&&!e(r[t]))return!1;return!0}(e)}const c={"Matrix(2)":2,"Matrix(3)":3,"Matrix(4)":4},p={Array:"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4","Matrix(2)":"mat2","Matrix(3)":"mat3","Matrix(4)":"mat4",Array2D:"sampler2D",Array3D:"sampler2D",Boolean:"bool",Float:"float",Input:"sampler2D",Integer:"int",Number:"float",LiteralInteger:"float",NumberTexture:"sampler2D",MemoryOptimizedNumberTexture:"sampler2D","ArrayTexture(1)":"sampler2D","ArrayTexture(2)":"sampler2D","ArrayTexture(3)":"sampler2D","ArrayTexture(4)":"sampler2D",HTMLVideo:"sampler2D",HTMLCanvas:"sampler2D",OffscreenCanvas:"sampler2D",HTMLImage:"sampler2D",ImageBitmap:"sampler2D",ImageData:"sampler2D",HTMLImageArray:"sampler2DArray"},d={"===":"==","!==":"!="};t.exports={WebGLFunctionNode:class extends n{constructor(e,t){super(e,t),t&&t.hasOwnProperty("fixIntegerDivisionAccuracy")&&(this.fixIntegerDivisionAccuracy=t.fixIntegerDivisionAccuracy)}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);const r=this.getType(e.consequent),n=this.getType(e.alternate);return null===r&&null===n?(t.push("if ("),this.astGeneric(e.test,t),t.push(") {"),this.astGeneric(e.consequent,t),t.push(";"),t.push("} else {"),this.astGeneric(e.alternate,t),t.push(";"),t.push("}"),t):(t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t)}astFunction(e,t){if(this.isRootKernel)t.push("void");else{this.returnType||this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"));const{returnType:r}=this;if(r){const e=p[r];if(!e)throw new Error(`unknown type ${r}`);t.push(e)}else t.push("void")}if(t.push(" "),t.push(this.name),t.push("("),!this.isRootKernel)for(let n=0;n0&&t.push(", ");let i=this.argumentTypes[this.argumentNames.indexOf(s)];if(!i)throw this.astErrorOutput(`Unknown argument ${s} type`,e);"LiteralInteger"===i&&(this.argumentTypes[n]=i="Number");const a=p[i];if(!a)throw this.astErrorOutput("Unexpected expression",e);const o=r.sanitizeName(s);"sampler2D"===a||"sampler2DArray"===a?t.push(`${a} user_${o},ivec2 user_${o}Size,ivec3 user_${o}Dim`):t.push(`${a} user_${o}`)}t.push(") {\n");for(let r=0;r"===e.operator||"<"===e.operator&&"Literal"===e.right.type)&&!Number.isInteger(e.right.value)){this.pushState("building-float"),this.castValueToFloat(e.left,t),t.push(d[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-float");break}if(this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const r=[];if(this.astGeneric(e.right,r),"Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(r.join(""))}else t.push("int("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float");break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(d[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.pushState("casting-to-float"),this.astGeneric(e.right,t),this.popState("casting-to-float"),this.popState("building-float"));break;case"LiteralInteger & Integer":this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(d[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${s}`,e)}return t.push(")"),t}checkAndUpconvertOperator(e,t){const r=this.checkAndUpconvertBitwiseOperators(e,t);if(r)return r;const n={"%":this.fixIntegerDivisionAccuracy?"integerCorrectionModulo":"modulo","**":"pow"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){const r={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.left)){case"Number":case"Float":this.castValueToInteger(e.left,t);break;case"LiteralInteger":this.castLiteralToInteger(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Number":case"Float":this.castValueToInteger(e.right,t);break;case"LiteralInteger":this.castLiteralToInteger(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){const r={"~":"bitwiseNot"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("int("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("float("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),s=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===n&&this.argumentNames.indexOf(s)>-1?t.push(`bool(user_${s})`):t.push(`user_${s}`),t}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const r=[],n=[],s=[],i=[];let a=null;if(e.init){const{declarations:t}=e.init;t.length>1&&(a=!1),this.astGeneric(e.init,r);for(let e=0;e0&&t.push(r.join(""),"\n"),t.push(`for (int ${e}=0;${e}0&&t.push(`if (!${n.join("")}) break;\n`),t.push(i.join("")),t.push(`\n${s.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);const r=this.getInternalVariableName("safeI");return t.push(`for (int ${r}=0;${r}null!==e&&(a(e)||u(e))))return null;const i=e=>JSON.parse(JSON.stringify(e)),o=e=>({type:"IfStatement",test:{type:"UnaryExpression",operator:"!",prefix:!0,argument:e},consequent:{type:"BlockStatement",body:[{type:"BreakStatement",label:null}]},alternate:null}),h=e=>"VariableDeclaration"===e.type?e:{type:"ExpressionStatement",expression:e},l="BlockStatement"===e.body.type?e.body.body.slice():[e.body],c=(e,t)=>{const r=e=>{if(!e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map(r);switch(e.type){case"ContinueStatement":return{type:"BlockStatement",body:[...t(),e]};case"ForStatement":case"WhileStatement":case"DoWhileStatement":default:return e;case"IfStatement":return{...e,consequent:r(e.consequent),alternate:r(e.alternate)};case"BlockStatement":return{...e,body:e.body.map(r)};case"SwitchStatement":return{...e,cases:e.cases.map(e=>({...e,consequent:e.consequent.map(r)}))}}};return e.map(r)},p=[];"DoWhileStatement"===t?(p.push(...n?c(l,()=>[o(i(n))]):l),n&&p.push(o(n))):(n&&p.push(o(n)),p.push(...s?c(l,()=>[h(i(s))]):l),s&&p.push(h(s)));const d={type:"BlockStatement",body:[...r?[h(r)]:[],{type:"WhileStatement",test:{type:"Literal",value:!0,raw:"true"},body:{type:"BlockStatement",body:p}}]};let m=this.syntheticNodeId||1073741824;const f=e=>{if(e&&"object"==typeof e)if(Array.isArray(e))e.forEach(f);else{"string"==typeof e.type&&void 0===e.start&&(e.start=m,e.end=m+1,m+=2);for(const t in e)"loc"!==t&&"range"!==t&&"parent"!==t&&f(e[t])}};return f(d),this.syntheticNodeId=m,d}linearizeStatement(e){const t=[];let r=!1,n=this.linearTempId||0;const i=e=>({type:"Identifier",name:e}),a=(e,t,r)=>({type:"VariableDeclaration",kind:e,declarations:[{type:"VariableDeclarator",id:i(t),init:r}]}),u=(e,t)=>{const r="hoistSeq"+n++;return e.push(a("const",r,t)),i(r)},h=e=>!s(e),l=(e,t)=>{if(r||!e||"object"!=typeof e)return e;switch(e.type){case"Identifier":case"Literal":case"ThisExpression":return e;case"MemberExpression":{const r=l(e.object,t),n=e.computed?l(e.property,t):e.property;return{...e,object:r,property:n}}case"CallExpression":{const r=e.arguments.map(e=>l(e,t));if("Identifier"===e.callee.type)for(let n=0;nl(e,t))};case"UpdateExpression":{if("Identifier"!==e.argument.type)return r=!0,e;if(e.prefix)return t.push({type:"ExpressionStatement",expression:e}),u(t,e.argument);const n=u(t,e.argument);return t.push({type:"ExpressionStatement",expression:e}),n}case"AssignmentExpression":{if("Identifier"!==e.left.type)return r=!0,e;const n=l(e.right,t);return t.push({type:"ExpressionStatement",expression:{...e,right:n}}),u(t,e.left)}case"SequenceExpression":for(let r=0;r({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:i(e),right:t}});return o.push(d(s,c)),u.push(d(s,p)),t.push({type:"IfStatement",test:r,consequent:{type:"BlockStatement",body:o},alternate:{type:"BlockStatement",body:u}}),i(s)}case"LogicalExpression":{if(!h(e.right))return{...e,left:l(e.left,t)};const r=l(e.left,t),s="hoistSeq"+n++;t.push(a("let",s,r));const o=[],u=l(e.right,o);return o.push({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:i(s),right:u}}),t.push({type:"IfStatement",test:"&&"===e.operator?i(s):{type:"UnaryExpression",operator:"!",prefix:!0,argument:i(s)},consequent:{type:"BlockStatement",body:o},alternate:null}),i(s)}default:return r=!0,e}};switch(e.type){case"ExpressionStatement":{const r=e.expression;if("AssignmentExpression"===r.type&&"Identifier"===r.left.type){const e=l(r.right,t);t.push({type:"ExpressionStatement",expression:{...r,right:e}})}else{const e=l(r,t);"UpdateExpression"!==e.type&&"AssignmentExpression"!==e.type||t.push({type:"ExpressionStatement",expression:e})}break}case"VariableDeclaration":for(let r=0;r{if(e&&"object"==typeof e)if(Array.isArray(e))e.forEach(p);else{"string"==typeof e.type&&void 0===e.start&&(e.start=c,e.end=c+1,c+=2);for(const t in e)"loc"!==t&&"range"!==t&&"parent"!==t&&p(e[t])}};return p(t),this.syntheticNodeId=c,t}astStatementWithHoisting(e,t){switch(e.type){case"ExpressionStatement":case"VariableDeclaration":case"ReturnStatement":{if(!l(e))return this.astGeneric(e,t);const r=this.hoistedIndexReads,n=this.hoistedIndexReads=[],s=[];return this.astGeneric(e,s),this.hoistedIndexReads=r,t.push(...n,...s),t}default:return this.astGeneric(e,t)}}astVariableDeclaration(e,t){const n=e.declarations;if(!n||!n[0]||!n[0].init)throw this.astErrorOutput("Unexpected expression",e);const s=[];let i=null;const a=[];let o=[];for(let t=0;t0&&a.push(o.join(",")),s.push(a.join(";")),t.push(s.join("")),t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchCaseConsequent(e,t){const r=[];for(let t=0;t{if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return e.some(t);if("BreakStatement"===e.type)return!0;if("ForStatement"===e.type||"WhileStatement"===e.type||"DoWhileStatement"===e.type||"SwitchStatement"===e.type)return!1;for(const r in e)if("loc"!==r&&"range"!==r&&"parent"!==r&&t(e[r]))return!0;return!1};if(t(r[e]))throw this.astErrorOutput("break inside a switch case is only supported as the case terminator",r[e])}for(let e=0;er+1){u=!0,this.astSwitchCaseConsequent(n[r].consequent,o);continue}t.push(" else {\n")}this.astSwitchCaseConsequent(n[r].consequent,t),t.push("\n}")}return u&&(t.push(" else {"),t.push(o.join("")),t.push("}")),t}astThisExpression(e,t){return t.push("this"),t}astMemberExpression(e,t){const{property:n,name:s,signature:i,origin:a,type:o,xProperty:u,yProperty:h,zProperty:l}=this.getMemberExpressionDetails(e);switch(i){case"value.thread.value":case"this.thread.value":if("x"!==s&&"y"!==s&&"z"!==s)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`threadId.${s}`),t;case"this.output.value":if(this.dynamicOutput)switch(s){case"x":this.isState("casting-to-float")?t.push("float(uOutputDim.x)"):t.push("uOutputDim.x");break;case"y":this.isState("casting-to-float")?t.push("float(uOutputDim.y)"):t.push("uOutputDim.y");break;case"z":this.isState("casting-to-float")?t.push("float(uOutputDim.z)"):t.push("uOutputDim.z");break;default:throw this.astErrorOutput("Unexpected expression",e)}else switch(s){case"x":this.isState("casting-to-integer")?t.push(this.output[0]):t.push(this.output[0],".0");break;case"y":this.isState("casting-to-integer")?t.push(this.output[1]):t.push(this.output[1],".0");break;case"z":this.isState("casting-to-integer")?t.push(this.output[2]):t.push(this.output[2],".0");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if("Math"===a)return t.push(Math[s]),t;const i=r.sanitizeName(s);switch(n){case"r":return t.push(`user_${i}.r`),t;case"g":return t.push(`user_${i}.g`),t;case"b":return t.push(`user_${i}.b`),t;case"a":return t.push(`user_${i}.a`),t}break;case"this.constants.value":if(void 0===u)switch(o){case"Array(2)":case"Array(3)":case"Array(4)":return t.push(`constants_${r.sanitizeName(s)}`),t}case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":case"this.constants.value[][][][]":break;case"fn()[]":return this.astCallExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;case"fn()[][]":{const r=e.object.property,n=e.property,s=c[this.getType(e.object.object)],i=e=>"LiteralInteger"===this.getType(e);return!s||i(r)&&i(n)?(this.astCallExpression(e.object.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(r)),t.push("]"),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t):(t.push(`getMatrix${s}(`),this.astCallExpression(e.object.object,t),t.push(", "),t.push(this.memberExpressionPropertyMarkup(r)),t.push(", "),t.push(this.memberExpressionPropertyMarkup(n)),t.push(")"),t)}case"[][]":return this.astArrayExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;default:throw this.astErrorOutput("Unexpected expression",e)}if(!1===e.computed)switch(o){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${a}_${r.sanitizeName(s)}`),t}const p=`${a}_${r.sanitizeName(s)}`;switch(o){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(u)),t.push("]");break;case"HTMLImageArray":t.push(`getImage3D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":t.push(`getVec4FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if("single"===this.precision)t.push(`getMemoryOptimized32(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");else{const e="user"===a?this.lookupFunctionArgumentBitRatio(this.name,s):this.constantBitRatios[s];switch(e){case 1:t.push(`get8(${p}, ${p}Size, ${p}Dim, `);break;case 2:t.push(`get16(${p}, ${p}Size, ${p}Dim, `);break;case 4:case 0:t.push(`get32(${p}, ${p}Size, ${p}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${e}`)}this.memberExpressionXYZ(u,h,l,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`${p}[${this.memberExpressionPropertyMarkup(h)}]`),h&&t.push(`[${this.memberExpressionPropertyMarkup(u)}]`);break;default:throw new Error(`unhandled member expression "${o}"`)}return t}astCallExpression(e,t){if(!e.callee)throw this.astErrorOutput("Unknown CallExpression",e);let n=null;const s=this.isAstMathFunction(e);if(n=s||e.callee.object&&"ThisExpression"===e.callee.object.type?e.callee.property.name:"SequenceExpression"!==e.callee.type||"Literal"!==e.callee.expressions[0].type||isNaN(e.callee.expressions[0].raw)?e.callee.name:e.callee.expressions[1].property.name,!n)throw this.astErrorOutput("Unhandled function, couldn't find name",e);switch(n){case"pow":n="_pow";break;case"round":n="_round"}if(this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n),"random"===n&&this.plugins&&this.plugins.length>0)for(let e=0;e0&&t.push(", "),"Integer"===s)this.castValueToFloat(n,t);else this.astGeneric(n,t)}else{const s=this.lookupFunctionArgumentTypes(n)||[];for(let i=0;i0&&t.push(", ");const u=this.getType(a);switch(o||(this.triggerImplyArgumentType(n,i,u,this),o=u),u){case"Boolean":this.astGeneric(a,t);continue;case"Number":case"Float":if("Integer"===o){t.push("int("),this.astGeneric(a,t),t.push(")");continue}if("Number"===o||"Float"===o){this.astGeneric(a,t);continue}if("LiteralInteger"===o){this.castLiteralToFloat(a,t);continue}break;case"Integer":if("Number"===o||"Float"===o){t.push("float("),this.astGeneric(a,t),t.push(")");continue}if("Integer"===o){this.astGeneric(a,t);continue}break;case"LiteralInteger":if("Integer"===o){this.castLiteralToInteger(a,t);continue}if("Number"===o||"Float"===o){this.castLiteralToFloat(a,t);continue}if("LiteralInteger"===o){this.astGeneric(a,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(o===u){if("Identifier"===a.type)t.push(`user_${r.sanitizeName(a.name)}`);else{if("ArrayExpression"!==a.type&&"MemberExpression"!==a.type&&"CallExpression"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.astGeneric(a,t)}continue}break;case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(o===u){if("Identifier"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.triggerImplyArgumentBitRatio(this.name,a.name,n,i);const s=r.sanitizeName(a.name);t.push(`user_${s},user_${s}Size,user_${s}Dim`);continue}}throw this.astErrorOutput(`Unhandled argument combination of ${u} and ${o} for argument named "${a.name}"`,e)}}return t.push(")"),t}astArrayExpression(e,t){const r=this.getType(e),n=e.elements.length;switch(r){case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`mat${n}(`);break;default:t.push(`vec${n}(`)}for(let r=0;r0&&t.push(", ");const n=e.elements[r];this.astGeneric(n,t)}return t.push(")"),t}memberExpressionXYZ(e,t,r,n){return r?n.push(this.memberExpressionPropertyMarkup(r),", "):n.push("0, "),t?n.push(this.memberExpressionPropertyMarkup(t),", "):n.push("0, "),n.push(this.memberExpressionPropertyMarkup(e)),n}memberExpressionPropertyMarkup(e){if(!e)throw new Error("Property not set");const t=[];switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;default:this.astGeneric(e,t)}const n=t.join("");if(this.hoistedIndexReads&&/\b\w+\((user_|constants_)\w+, \1\w+Size/.test(n)){const e=`hoisted_${this.hoistedIndexReads.length}_${r.sanitizeName(this.name)}`,t=n.startsWith("int(");return this.hoistedIndexReads.push(`${t?"int":"float"} ${e}=${n};\n`),e}return n}}}}),V=e((e,t)=>{t.exports={name:"math-random-uniformly-distributed",onBeforeRun:e=>{if(null===e.randomSeed||void 0===e.randomSeed)return e.setUniform1f("randomSeed1",Math.random()),void e.setUniform1f("randomSeed2",Math.random());e._mathRandomGenerator&&e._mathRandomGeneratorSeed===e.randomSeed||(e._mathRandomGenerator=function(e){let t=e>>>0;return function(){t=t+1831565813>>>0;let e=t;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296}}(e.randomSeed),e._mathRandomGeneratorSeed=e.randomSeed),e.setUniform1f("randomSeed1",e._mathRandomGenerator()),e.setUniform1f("randomSeed2",e._mathRandomGenerator())},functionMatch:"Math.random()",functionReplace:"nrand(vTexCoord)",functionReturnType:"Number",source:"// https://www.shadertoy.com/view/4t2SDh\n//note: uniformly distributed, normalized rand, [0,1]\nhighp float randomSeedShift = 1.0;\nhighp float slide = 1.0;\nuniform highp float randomSeed1;\nuniform highp float randomSeed2;\n\nhighp float nrand(highp vec2 n) {\n highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453);\n randomSeedShift = result;\n if (randomSeedShift > 0.5) {\n slide += 0.00009; \n } else {\n slide += 0.0009;\n }\n return result;\n}"}}),M=e((e,t)=>{t.exports={fragmentShader:`__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nvarying vec2 vTexCoord;\n\nfloat acosh(float x) {\n return log(x + sqrt(x * x - 1.0));\n}\n\nfloat sinh(float x) {\n return (pow(${Math.E}, x) - pow(${Math.E}, -x)) / 2.0;\n}\n\nfloat asinh(float x) {\n return log(x + sqrt(x * x + 1.0));\n}\n\nfloat atan2(float v1, float v2) {\n if (v2 == 0.0) {\n if (v1 == 0.0) return 0.0;\n if (v1 > 0.0) return 1.5707963267948966;\n if (v1 < 0.0) return -1.5707963267948966;\n }\n return atan(v1, v2);\n}\n\nfloat atanh(float x) {\n x = (x + 1.0) / (x - 1.0);\n if (x < 0.0) {\n return 0.5 * log(-x);\n }\n return 0.5 * log(x);\n}\n\nfloat cbrt(float x) {\n if (x >= 0.0) {\n return pow(x, 1.0 / 3.0);\n } else {\n return -pow(x, 1.0 / 3.0);\n }\n}\n\nfloat cosh(float x) {\n return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0; \n}\n\nfloat expm1(float x) {\n return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n return x;\n}\n\nfloat imul(float v1, float v2) {\n return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n if (v2 == 0.0) return 1.0;\n return pow(v1, v2);\n}\n\nfloat tanh(float x) {\n float e = exp(2.0 * x);\n return (e - 1.0) / (e + 1.0);\n}\n\nfloat trunc(float x) {\n if (x >= 0.0) {\n return floor(x); \n } else {\n return ceil(x);\n }\n}\n\nvec4 _round(vec4 x) {\n return floor(x + 0.5);\n}\n\nfloat _round(float x) {\n return floor(x + 0.5);\n}\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n // ~a is identically -a - 1 in two's complement, for every value including\n // negatives. The previous bit-by-bit loop only worked for a >= 0, where it\n // leaned on 32-bit overflow wrapping to reach the negative answer; given a\n // negative input it computed ~abs(a), so ~(-1) gave -2 and ~~x never\n // returned x.\n return -a - 1;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\n// _pow2 is defined further down, alongside encode32/decode32\nfloat _pow2(float e);\nint bitwiseSignedRightShift(int num, int shifts) {\n // pow(2.0, n) is approximate on many GPUs, and landing 1 ulp high makes the\n // division fall just under a whole number, which floor() then rounds away:\n // 2 >> 1 came out 0, 8 >> 1 came out 3. Only exact left operands were\n // affected, odd ones having enough slack to survive. _pow2 is exact.\n return int(floor(float(num) / _pow2(float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x / y));\n}\n\n// GLSL ES 1.00 accepts only a constant or a loop symbol inside an index\n// expression, so m[y][x] does not compile when y and x come from kernel\n// arguments -- the error is "Index expression can only contain const or loop\n// symbols". Loop counters are legal indices, so walk the matrix with them\n// instead. These are 2x2 to 4x4, so it costs at most sixteen comparisons.\nfloat getMatrix2(mat2 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 2; i++) {\n for (int j = 0; j < 2; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix3(mat3 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 3; i++) {\n for (int j = 0; j < 3; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix4(mat4 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 4; i++) {\n for (int j = 0; j < 4; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\n// Exact powers of two built from exact constant multiplies: exp2/log2/pow\n// are approximate on some GPUs (notably Apple silicon), and 1-2 ulp there\n// corrupts the packed bytes (#659)\nfloat _pow2(float e) {\n float r = 1.0;\n float a = abs(e);\n bool n = e < 0.0;\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 32.0) { r *= n ? 2.3283064365386963e-10 : 4294967296.0; a -= 32.0; }\n if (a >= 16.0) { r *= n ? 0.0000152587890625 : 65536.0; a -= 16.0; }\n if (a >= 8.0) { r *= n ? 0.00390625 : 256.0; a -= 8.0; }\n if (a >= 4.0) { r *= n ? 0.0625 : 16.0; a -= 4.0; }\n if (a >= 2.0) { r *= n ? 0.25 : 4.0; a -= 2.0; }\n if (a >= 1.0) { r *= n ? 0.5 : 2.0; }\n return r;\n}\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = _pow2(_round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * _pow2(_round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\n return 0.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n if (channel == 0) return texel.r * 255.0;\n if (channel == 1) return texel.g * 255.0;\n if (channel == 2) return texel.b * 255.0;\n if (channel == 3) return texel.a * 255.0;\n return 0.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n float p2 = _pow2(exponent);\n // approximate log2 can land one off; correct by direct comparison\n if (p2 > value) { exponent -= 1.0; p2 *= 0.5; }\n else if (p2 * 2.0 <= value) { exponent += 1.0; p2 *= 2.0; }\n\n mantissa = value / p2 - 1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return texel.r;\n if (channel == 1) return texel.g;\n if (channel == 2) return texel.b;\n if (channel == 3) return texel.a;\n return 0.0;\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture2D(tex, st / vec2(texSize));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n \n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nvoid color(sampler2D image) {\n actualColor = texture2D(image, vTexCoord);\n}\n\nfloat modulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -mod(number, divisor);\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}`}}),O=e((e,t)=>{t.exports={vertexShader:"__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nattribute vec2 aPos;\nattribute vec2 aTexCoord;\n\nvarying vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"}}),z=e((e,t)=>{function r(e,t={}){const{contextName:r="gl",throwGetError:a,useTrackablePrimitives:o,recording:u=[],variables:h={},onReadPixels:l,onUnrecognizedArgumentLookup:c}=t,p=new Proxy(e,{get:function(t,p){switch(p){case"addComment":return A;case"checkThrowError":return _;case"getReadPixelsVariableName":return f;case"insertVariable":return b;case"reset":return y;case"setIndent":return S;case"toString":return x;case"getContextVariableName":return w}return"function"==typeof e[p]?function(){switch(p){case"getError":return a?u.push(`${g}if (${r}.getError() !== ${r}.NONE) throw new Error('error');`):u.push(`${g}${r}.getError();`),e.getError();case"getExtension":{const t=`${r}Variables${d.length}`;u.push(`${g}const ${t} = ${r}.getExtension('${arguments[0]}');`);const s=e.getExtension(arguments[0]);if(s&&"object"==typeof s){const e=n(s,{getEntity:T,useTrackablePrimitives:o,recording:u,contextName:t,contextVariables:d,variables:h,indent:g,onUnrecognizedArgumentLookup:c});return d.push(e),e}return d.push(null),s}case"readPixels":const t=d.indexOf(arguments[6]);let i;if(-1===t){const e=function(e){if(h)for(const t in h)if(h[t]===e)return t;return null}(arguments[6]);e?(i=e,u.push(`${g}${e}`)):(i=`${r}Variable${d.length}`,d.push(arguments[6]),u.push(`${g}const ${i} = new ${arguments[6].constructor.name}(${arguments[6].length});`))}else i=`${r}Variable${t}`;f=i;const p=[arguments[0],arguments[1],arguments[2],arguments[3],T(arguments[4]),T(arguments[5]),i];return u.push(`${g}${r}.readPixels(${p.join(", ")});`),l&&l(i,p),e.readPixels.apply(e,arguments);case"drawBuffers":return u.push(`${g}${r}.drawBuffers([${s(arguments[0],{contextName:r,contextVariables:d,getEntity:T,addVariable:v,variables:h,onUnrecognizedArgumentLookup:c})}]);`),e.drawBuffers(arguments[0])}let t=e[p].apply(e,arguments);switch(typeof t){case"undefined":return void u.push(`${g}${E(p,arguments)};`);case"number":case"boolean":if(o&&-1===d.indexOf(i(t))){u.push(`${g}const ${r}Variable${d.length} = ${E(p,arguments)};`),d.push(t=i(t));break}default:null===t?u.push(`${E(p,arguments)};`):u.push(`${g}const ${r}Variable${d.length} = ${E(p,arguments)};`),d.push(t)}return t}:(m[e[p]]=p,e[p])}}),d=[],m={};let f,g="";return p;function x(){return u.join("\n")}function y(){for(;u.length>0;)u.pop()}function b(e,t){h[e]=t}function T(e){const t=m[e];return t?r+"."+t:e}function S(e){g=" ".repeat(e)}function v(e,t){const n=`${r}Variable${d.length}`;return u.push(`${g}const ${n} = ${t};`),d.push(e),n}function A(e){u.push(`${g}// ${e}`)}function _(){u.push(`${g}(() => {\n${g}const error = ${r}.getError();\n${g}if (error !== ${r}.NONE) {\n${g} const names = Object.getOwnPropertyNames(gl);\n${g} for (let i = 0; i < names.length; i++) {\n${g} const name = names[i];\n${g} if (${r}[name] === error) {\n${g} throw new Error('${r} threw ' + name);\n${g} }\n${g} }\n${g}}\n${g}})();`)}function E(e,t){return`${r}.${e}(${s(t,{contextName:r,contextVariables:d,getEntity:T,addVariable:v,variables:h,onUnrecognizedArgumentLookup:c})})`}function w(e){const t=d.indexOf(e);return-1!==t?`${r}Variable${t}`:null}}function n(e,t){const r=new Proxy(e,{get:function(t,r){return"function"==typeof t[r]?function(){if("drawBuffersWEBGL"===r)return l.push(`${p}${a}.drawBuffersWEBGL([${s(arguments[0],{contextName:a,contextVariables:o,getEntity:m,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})}]);`),e.drawBuffersWEBGL(arguments[0]);let t=e[r].apply(e,arguments);switch(typeof t){case"undefined":return void l.push(`${p}${f(r,arguments)};`);case"number":case"boolean":h&&-1===o.indexOf(i(t))?(l.push(`${p}const ${a}Variable${o.length} = ${f(r,arguments)};`),o.push(t=i(t))):(l.push(`${p}const ${a}Variable${o.length} = ${f(r,arguments)};`),o.push(t));break;default:null===t?l.push(`${f(r,arguments)};`):l.push(`${p}const ${a}Variable${o.length} = ${f(r,arguments)};`),o.push(t)}return t}:(n[e[r]]=r,e[r])}}),n={},{contextName:a,contextVariables:o,getEntity:u,useTrackablePrimitives:h,recording:l,variables:c,indent:p,onUnrecognizedArgumentLookup:d}=t;return r;function m(e){return n.hasOwnProperty(e)?`${a}.${n[e]}`:u(e)}function f(e,t){return`${a}.${e}(${s(t,{contextName:a,contextVariables:o,getEntity:m,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})})`}function g(e,t){const r=`${a}Variable${o.length}`;return o.push(e),l.push(`${p}const ${r} = ${t};`),r}}function s(e,t){const{variables:r,onUnrecognizedArgumentLookup:n}=t;return Array.from(e).map(e=>{const s=function(e){if(r)for(const t in r)if(r.hasOwnProperty(t)&&r[t]===e)return t;return n?n(e):null}(e);return s||function(e,t){const{contextName:r,contextVariables:n,getEntity:s,addVariable:i,onUnrecognizedArgumentLookup:a}=t;if(void 0===e)return"undefined";if(null===e)return"null";const o=n.indexOf(e);if(o>-1)return`${r}Variable${o}`;switch(e.constructor.name){case"String":const t=/\n/.test(e),r=/'/.test(e),n=/"/.test(e);return t?"`"+e+"`":r&&!n?'"'+e+'"':"'"+e+"'";case"Number":case"Boolean":return s(e);case"Array":return i(e,`new ${e.constructor.name}([${Array.from(e).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return i(e,`new ${e.constructor.name}(${JSON.stringify(Array.from(e))})`);default:if(a){const t=a(e);if(t)return t}throw new Error(`unrecognized argument type ${e.constructor.name}`)}}(e,t)}).join(", ")}function i(e){return new e.constructor(e)}void 0!==t&&(t.exports={glWiretap:r,glExtensionWiretap:n}),"undefined"!=typeof window&&(r.glExtensionWiretap=n,window.glWiretap=r)}),P=e((e,t)=>{const{glWiretap:r}=z(),{utils:n}=i();function s(e){let t=e.toString().replace(/^function /,"");const r=t.indexOf("=>");if(-1!==r&&!/[{]|\bfunction\b/.test(t.slice(0,r))){const e=t.slice(0,r).trim(),n=t.slice(r+2).trim();t=n.startsWith("{")?`${e} ${n}`:`${e} { return ${n}; }`}return t.replace(/utils[.]/g,"/*utils.*/")}function a(e,t){const r="single"===t.precision?e:`new Float32Array(${e}.buffer)`;return t.output[2]?`renderOutput(${r}, ${t.output[0]}, ${t.output[1]}, ${t.output[2]})`:t.output[1]?`renderOutput(${r}, ${t.output[0]}, ${t.output[1]})`:`renderOutput(${r}, ${t.output[0]})`}function o(e,t){const r=e.toArray.toString(),s=!/^function/.test(r);return`() => {\n function framebuffer() { return getReadFramebuffer(); };\n ${n.flattenFunctionToString(`${s?"function ":""}${r}`,{findDependency:(t,r)=>{if("utils"===t)return`const ${r} = ${n[r].toString()};`;if("this"===t)return"framebuffer"===r?"":`${s?"function ":""}${e[r].toString()}`;throw new Error("unhandled fromObject")},thisLookup:(r,n)=>{if("texture"===r)return t;if("context"===r)return n?null:"gl";if(e.hasOwnProperty(r))return JSON.stringify(e[r]);throw new Error(`unhandled thisLookup ${r}`)}})}\n return toArray();\n }`}function u(e,t,r,n,s){if(null===e)return null;if(null===t)return null;switch(typeof e){case"boolean":case"number":return null}if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement)for(let s=0;s{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}}):null;const c=[],p=[],d=r(i.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if(N.subKernels){if(m){const t=N.subKernels[f++].property;p.push(` result${isNaN(t)?"."+t:`[${t}]`} = ${a(e,N)};`)}else p.push(` const result = { result: ${a(e,N)} };`),m=!0;f===N.subKernels.length&&p.push(" return result;")}else e?p.push(` return ${a(e,N)};`):p.push(" return null;")},onUnrecognizedArgumentLookup:e=>{const t=u(e,N.kernelArguments,[],d,c);if(t)return t;const r=u(e,N.kernelConstants,v?Object.keys(v).map(e=>v[e]):[],d,c);return r||null}});let m=!1,f=0;const{source:g,canvas:x,output:y,pipeline:b,graphical:T,loopMaxIterations:S,constants:v,optimizeFloatMemory:A,precision:_,fixIntegerDivisionAccuracy:E,functions:w,nativeFunctions:I,subKernels:D,immutable:C,argumentTypes:k,constantTypes:R,kernelArguments:L,kernelConstants:$,tactic:F}=i,N=new e(g,{canvas:x,context:d,checkContext:!1,output:y,pipeline:b,graphical:T,loopMaxIterations:S,constants:v,optimizeFloatMemory:A,precision:_,fixIntegerDivisionAccuracy:E,functions:w,nativeFunctions:I,subKernels:D,immutable:C,argumentTypes:k,constantTypes:R,tactic:F});let V=[];if(d.setIndent(2),N.build.apply(N,t),V.push(d.toString()),d.reset(),N.kernelArguments.forEach((e,r)=>{switch(e.type){case"Integer":case"Boolean":case"Number":case"Float":case"Array":case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":case"Input":d.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let n=0;ne.varName).join(", ")}) {`),d.setIndent(4),N.run.apply(N,t),N.renderKernels?N.renderKernels():N.renderOutput&&N.renderOutput(),V.push(" /** start setup uploads for kernel values **/"),N.kernelArguments.forEach(e=>{V.push(" "+e.getStringValueHandler().split("\n").join("\n "))}),V.push(" /** end setup uploads for kernel values **/"),V.push(d.toString()),N.renderOutput===N.renderTexture)if(d.reset(),N.renderKernels){const e=N.renderKernels(),t=d.getContextVariableName(N.texture.texture);V.push(` return {\n result: {\n texture: ${t},\n type: '${e.result.type}',\n toArray: ${o(e.result,t)}\n },`);const{subKernels:r,mappedTextures:n}=N;for(let t=0;t"utils"===e?`const ${t} = ${n[t].toString()};`:null,thisLookup:t=>{if("context"===t)return null;if(e.hasOwnProperty(t))return JSON.stringify(e[t]);throw new Error(`unhandled thisLookup ${t}`)}})}(N)),V.push(" innerKernel.getPixels = getPixels;")),V.push(" return innerKernel;");let M=[];return $.forEach(e=>{M.push(`${e.getStringValueHandler()}`)}),`function kernel(settings) {\n const { context, constants } = settings;\n ${M.join("")}\n ${h||""}\n${V.join("\n")}\n}`}}}),K=e((e,t)=>{t.exports={KernelValue:class{constructor(e,t){const{name:r,kernel:n,context:s,checkContext:i,onRequestContextHandle:a,onUpdateValueMismatch:o,origin:u,strictIntegers:h,type:l,tactic:c}=t;if(!r)throw new Error("name not set");if(!l)throw new Error("type not set");if(!u)throw new Error("origin not set");if("user"!==u&&"constants"!==u)throw new Error(`origin must be "user" or "constants" value is "${u}"`);if(!a)throw new Error("onRequestContextHandle is not set");this.name=r,this.origin=u,this.tactic=c,this.varName="constants"===u?`constants.${r}`:r,this.kernel=n,this.strictIntegers=h,this.type=e.type||l,this.size=e.size||null,this.index=null,this.context=s,this.checkContext=null==i||i,this.contextHandle=null,this.onRequestContextHandle=a,this.onUpdateValueMismatch=o,this.forceUploadEachRun=null}get id(){return`${this.origin}_${name}`}getSource(){throw new Error(`"getSource" not defined on ${this.constructor.name}`)}updateValue(e){throw new Error(`"updateValue" not defined on ${this.constructor.name}`)}}}}),G=e((e,t)=>{const{utils:r}=i(),{KernelValue:n}=K();t.exports={WebGLKernelValue:class extends n{constructor(e,t){super(e,t),this.dimensionsId=null,this.sizeId=null,this.initialValueConstructor=e.constructor,this.onRequestTexture=t.onRequestTexture,this.onRequestIndex=t.onRequestIndex,this.uploadValue=null,this.textureSize=null,this.bitRatio=null,this.prevArg=null}get id(){return`${this.origin}_${r.sanitizeName(this.name)}`}setup(){}getTransferArrayType(e){if(Array.isArray(e[0]))return this.getTransferArrayType(e[0]);switch(e.constructor){case Array:case Int32Array:case Int16Array:case Int8Array:return Float32Array;case Uint8ClampedArray:case Uint8Array:case Uint16Array:case Uint32Array:case Float32Array:case Float64Array:return e.constructor}return console.warn("Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros"),e.constructor}getStringValueHandler(){throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`)}getVariablePrecisionString(){return this.kernel.getVariablePrecisionString(this.textureSize||void 0,this.tactic||void 0)}destroy(){}}}}),U=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValue:n}=G();t.exports={WebGLKernelValueBoolean:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const bool ${this.id} = ${e};\n`:`uniform bool ${this.id};\n`}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),B=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValue:n}=G();t.exports={WebGLKernelValueFloat:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?Number.isInteger(e)?`const float ${this.id} = ${e}.0;\n`:`const float ${this.id} = ${e};\n`:`uniform float ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1f(this.id,this.uploadValue=e)}}}}),j=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValue:n}=G();t.exports={WebGLKernelValueInteger:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?`const int ${this.id} = ${parseInt(e)};\n`:`uniform int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),W=e((e,t)=>{const{WebGLKernelValue:r}=G(),{Input:s}=n();t.exports={WebGLKernelArray:class extends r{checkSize(e,t){if(!this.kernel.validate)return;const{maxTextureSize:r}=this.kernel.constructor.features;if(e>r||t>r)throw e>t?new Error(`Argument texture width of ${e} larger than maximum size of ${r} for your GPU`):e{const{utils:r}=i(),{WebGLKernelArray:n}=W();function s(e){return{width:e.width>0?e.width:e.videoWidth,height:e.height>0?e.height:e.videoHeight}}t.exports={WebGLKernelValueHTMLImage:class extends n{constructor(e,t){super(e,t);const{width:r,height:n}=s(e);this.checkSize(r,n),this.dimensions=[r,n,1],this.textureSize=[r,n],this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue=e),this.kernel.setUniform1i(this.id,this.index)}},mediaSize:s}}),X=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueHTMLImage:n,mediaSize:s}=H();t.exports={WebGLKernelValueDynamicHTMLImage:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:r}=s(e);this.checkSize(t,r),this.dimensions=[t,r,1],this.textureSize=[t,r],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),q=e((e,t)=>{const{WebGLKernelValueHTMLImage:r}=H();t.exports={WebGLKernelValueHTMLVideo:class extends r{}}}),Y=e((e,t)=>{const{WebGLKernelValueDynamicHTMLImage:r}=X();t.exports={WebGLKernelValueDynamicHTMLVideo:class extends r{}}}),Z=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueSingleInput:class extends n{constructor(e,t){super(e,t),this.bitRatio=4;let[n,s,i]=e.size;this.dimensions=new Int32Array([n||1,s||1,i||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}.value, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),J=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleInput:n}=Z();t.exports={WebGLKernelValueDynamicSingleInput:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,s]=e.size;this.dimensions=new Int32Array([t||1,n||1,s||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Q=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueUnsignedInput:class extends n{constructor(e,t){super(e,t),this.bitRatio=this.getBitRatio(e);const[n,s,i]=e.size;this.dimensions=new Int32Array([n||1,s||1,i||1]),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]),this.TranserArrayType=this.getTransferArrayType(e.value),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return r.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}.value, preUploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(value.constructor);const{context:t}=this;r.flattenTo(e.value,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ee=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedInput:n}=Q();t.exports={WebGLKernelValueDynamicUnsignedInput:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,s]=e.size;this.dimensions=new Int32Array([t||1,n||1,s||1]),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]);const i=this.getTransferArrayType(e.value);this.preUploadValue=new i(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),te=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W(),s="Source and destination textures are the same. Use immutable = true and manually cleanup kernel output texture memory with texture.delete()";t.exports={WebGLKernelValueMemoryOptimizedNumberTexture:class extends n{constructor(e,t){super(e,t);const[r,n]=e.size;this.checkSize(r,n),this.dimensions=e.dimensions,this.textureSize=e.size,this.uploadValue=e.texture,this.forceUploadEachRun=!0}setup(){this.setupTexture()}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{kernel:t,context:r}=this;if(t.pipeline)if(t.immutable)t.updateTextureArgumentRefs(this,e);else{if(t.texture&&t.texture.texture===e.texture)throw new Error(s);if(t.mappedTextures){const{mappedTextures:r}=t;for(let t=0;t{const{utils:r}=i(),{WebGLKernelValueMemoryOptimizedNumberTexture:n}=te();t.exports={WebGLKernelValueDynamicMemoryOptimizedNumberTexture:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ne=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W(),{sameError:s}=te();t.exports={WebGLKernelValueNumberTexture:class extends n{constructor(e,t){super(e,t);const[r,n]=e.size;this.checkSize(r,n);const{size:s,dimensions:i}=e;this.bitRatio=this.getBitRatio(e),this.dimensions=i,this.textureSize=s,this.uploadValue=e.texture,this.forceUploadEachRun=!0}setup(){this.setupTexture()}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{kernel:t,context:r}=this;if(t.pipeline)if(t.immutable)t.updateTextureArgumentRefs(this,e);else{if(t.texture&&t.texture.texture===e.texture)throw new Error(s);if(t.mappedTextures){const{mappedTextures:r}=t;for(let t=0;t{const{utils:r}=i(),{WebGLKernelValueNumberTexture:n}=ne();t.exports={WebGLKernelValueDynamicNumberTexture:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ie=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueSingleArray:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ae=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray:n}=ie();t.exports={WebGLKernelValueDynamicSingleArray:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),oe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueSingleArray1DI:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],1,1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flatten2dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ue=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray1DI:n}=oe();t.exports={WebGLKernelValueDynamicSingleArray1DI:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),he=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueSingleArray2DI:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flatten3dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),le=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray2DI:n}=he();t.exports={WebGLKernelValueDynamicSingleArray2DI:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ce=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueSingleArray3DI:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],t[3]]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flatten4dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),pe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray3DI:n}=ce();t.exports={WebGLKernelValueDynamicSingleArray3DI:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),de=e((e,t)=>{const{WebGLKernelValue:r}=G();t.exports={WebGLKernelValueArray2:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec2 ${this.id} = vec2(${e[0]},${e[1]});\n`:`uniform vec2 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform2fv(this.id,this.uploadValue=e)}}}}),me=e((e,t)=>{const{WebGLKernelValue:r}=G();t.exports={WebGLKernelValueArray3:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec3 ${this.id} = vec3(${e[0]},${e[1]},${e[2]});\n`:`uniform vec3 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform3fv(this.id,this.uploadValue=e)}}}}),fe=e((e,t)=>{const{WebGLKernelValue:r}=G();t.exports={WebGLKernelValueArray4:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec4 ${this.id} = vec4(${e[0]},${e[1]},${e[2]},${e[3]});\n`:`uniform vec4 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform4fv(this.id,this.uploadValue=e)}}}}),ge=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGLKernelValueUnsignedArray:class extends n{constructor(e,t){super(e,t),this.bitRatio=this.getBitRatio(e),this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]),this.TranserArrayType=this.getTransferArrayType(e),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return r.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}, preUploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),xe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedArray:n}=ge();t.exports={WebGLKernelValueDynamicUnsignedArray:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]);const t=this.getTransferArrayType(e);this.preUploadValue=new t(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ye=e((e,t)=>{const{WebGLKernelValueBoolean:r}=U(),{WebGLKernelValueFloat:n}=B(),{WebGLKernelValueInteger:s}=j(),{WebGLKernelValueHTMLImage:i}=H(),{WebGLKernelValueDynamicHTMLImage:a}=X(),{WebGLKernelValueHTMLVideo:o}=q(),{WebGLKernelValueDynamicHTMLVideo:u}=Y(),{WebGLKernelValueSingleInput:h}=Z(),{WebGLKernelValueDynamicSingleInput:l}=J(),{WebGLKernelValueUnsignedInput:c}=Q(),{WebGLKernelValueDynamicUnsignedInput:p}=ee(),{WebGLKernelValueMemoryOptimizedNumberTexture:d}=te(),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:m}=re(),{WebGLKernelValueNumberTexture:f}=ne(),{WebGLKernelValueDynamicNumberTexture:g}=se(),{WebGLKernelValueSingleArray:x}=ie(),{WebGLKernelValueDynamicSingleArray:y}=ae(),{WebGLKernelValueSingleArray1DI:b}=oe(),{WebGLKernelValueDynamicSingleArray1DI:T}=ue(),{WebGLKernelValueSingleArray2DI:S}=he(),{WebGLKernelValueDynamicSingleArray2DI:v}=le(),{WebGLKernelValueSingleArray3DI:A}=ce(),{WebGLKernelValueDynamicSingleArray3DI:_}=pe(),{WebGLKernelValueArray2:E}=de(),{WebGLKernelValueArray3:w}=me(),{WebGLKernelValueArray4:I}=fe(),{WebGLKernelValueUnsignedArray:D}=ge(),{WebGLKernelValueDynamicUnsignedArray:C}=xe(),k={unsigned:{dynamic:{Boolean:r,Integer:s,Float:n,Array:C,"Array(2)":E,"Array(3)":w,"Array(4)":I,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:p,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:m,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u},static:{Boolean:r,Float:n,Integer:s,Array:D,"Array(2)":E,"Array(3)":w,"Array(4)":I,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:c,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:d,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:!1,HTMLVideo:o}},single:{dynamic:{Boolean:r,Integer:s,Float:n,Array:y,"Array(2)":E,"Array(3)":w,"Array(4)":I,"Array1D(2)":T,"Array1D(3)":T,"Array1D(4)":T,"Array2D(2)":v,"Array2D(3)":v,"Array2D(4)":v,"Array3D(2)":_,"Array3D(3)":_,"Array3D(4)":_,Input:l,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:m,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u},static:{Boolean:r,Float:n,Integer:s,Array:x,"Array(2)":E,"Array(3)":w,"Array(4)":I,"Array1D(2)":b,"Array1D(3)":b,"Array1D(4)":b,"Array2D(2)":S,"Array2D(3)":S,"Array2D(4)":S,"Array3D(2)":A,"Array3D(3)":A,"Array3D(4)":A,Input:h,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:d,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:!1,HTMLVideo:o}}};t.exports={lookupKernelValueType:function(e,t,r,n){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!r)throw new Error("precision missing");n.type&&(e=n.type);const s=k[r][t];if(!1===s[e])return null;if(void 0===s[e])throw new Error(`Could not find a KernelValue for ${e}`);return s[e]},kernelValueMaps:k}}),be=e((e,t)=>{const{GLKernel:r}=F(),{FunctionBuilder:n}=o(),{WebGLFunctionNode:s}=N(),{utils:a}=i(),u=V(),{fragmentShader:h}=M(),{vertexShader:l}=O(),{glKernelString:c}=P(),{lookupKernelValueType:p}=ye();let d=null,m=null,f=null,g=null,x=null;const y=[u],b=[],T={};t.exports={WebGLKernel:class extends r{static get isSupported(){return null!==d||(this.setupFeatureChecks(),d=this.isContextMatch(f)),d}static setupFeatureChecks(){"undefined"!=typeof document?m=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(m=new OffscreenCanvas(0,0)),m&&(f=m.getContext("webgl"),f||m instanceof OffscreenCanvas||(f=m.getContext("experimental-webgl")),f&&f.getExtension&&(g={OES_texture_float:f.getExtension("OES_texture_float"),OES_texture_float_linear:f.getExtension("OES_texture_float_linear"),OES_element_index_uint:f.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:f.getExtension("WEBGL_draw_buffers")},x=this.getFeatures()))}static isContextMatch(e){return"undefined"!=typeof WebGLRenderingContext&&e instanceof WebGLRenderingContext}static getIsTextureFloat(){return Boolean(g.OES_texture_float)}static getIsDrawBuffers(){return Boolean(g.WEBGL_draw_buffers)}static getChannelCount(){return g.WEBGL_draw_buffers?f.getParameter(g.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return f.getParameter(f.MAX_TEXTURE_SIZE)}static lookupKernelValueType(e,t,r,n){return p(e,t,r,n)}static get testCanvas(){return m}static get testContext(){return f}static get features(){return x}static get fragmentShader(){return h}static get vertexShader(){return l}constructor(e,t){super(e,t),this.program=null,this.pipeline=t.pipeline,this.endianness=a.systemEndianness(),this.extensions={},this.argumentTextureCount=0,this.constantTextureCount=0,this.fragShader=null,this.vertShader=null,this.drawBuffersMap=null,this.maxTexSize=null,this.onRequestSwitchKernel=null,this.texture=null,this.mappedTextures=null,this.mergeSettings(e.settings||t),this.threadDim=null,this.framebuffer=null,this.buffer=null,this.textureCache=[],this.programUniformLocationCache={},this.uniform1fCache={},this.uniform1iCache={},this.uniform2fCache={},this.uniform2fvCache={},this.uniform2ivCache={},this.uniform3fvCache={},this.uniform3ivCache={},this.uniform4fvCache={},this.uniform4ivCache={}}initCanvas(){if("undefined"!=typeof document){const e=document.createElement("canvas");return e.width=2,e.height=2,e}if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(0,0)}initContext(){const e={alpha:!1,depth:!1,antialias:!1};return this.canvas.getContext("webgl",e)||this.canvas.getContext("experimental-webgl",e)}initPlugins(e){const t=[],{source:r}=this;if("string"==typeof r)for(let e=0;ee===n.name)&&t.push(n)}return t}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if(!0===this.optimizeFloatMemory&&!t.isTextureFloat)throw new Error("Float textures are not supported");if("single"===this.precision&&!t.isFloatRead)throw new Error("Single precision not supported");if(this.graphical||null!==this.precision||(this.precision=t.isTextureFloat&&t.isFloatRead?"single":"unsigned"),this.subKernels&&this.subKernels.length>0&&!this.extensions.WEBGL_draw_buffers)throw new Error("could not instantiate draw buffers extension");if(null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);switch(t){case"Array":this.output=a.getDimensions(t);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=e[0].output;break;default:throw new Error("Auto output not supported for input type: "+t)}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"precision"===this.precision&&(this.precision="unsigned",console.warn("Cannot use graphical mode and single precision at the same time")),void(this.texSize=a.clone(this.output))}null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}updateMaxTexSize(){const{texSize:e,canvas:t}=this;if(null===this.maxTexSize){let r=b.indexOf(t);-1===r&&(r=b.length,b.push(t),T[r]=[e[0],e[1]]),this.maxTexSize=T[r]}this.maxTexSize[0]this.argumentNames.length)throw new Error("too many arguments for kernel");const{context:r}=this;let n=0;const s=()=>this.createTexture(),i=()=>this.constantTextureCount+n++,o=e=>{this.switchKernels({type:"argumentMismatch",needed:e})},u=()=>r.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++;for(let n=0;nthis.createTexture(),onRequestIndex:()=>n++,onRequestContextHandle:()=>t.TEXTURE0+this.constantTextureCount++});this.constantBitRatios[s]=h.bitRatio,this.kernelConstants.push(h),h.setup(),h.forceUploadEachRun&&this.forceUploadKernelConstants.push(h)}}build(){if(this.built)return;if(this.initExtensions(),this.validateSettings(arguments),this.setupConstants(arguments),this.fallbackRequested)return;if(this.setupArguments(arguments),this.fallbackRequested)return;this.updateMaxTexSize(),this.translateSource();const e=this.pickRenderStrategy(arguments);if(e)return e;const{texSize:t,context:r,canvas:n}=this;r.enable(r.SCISSOR_TEST),this.pipeline&&this.precision,r.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]),n.width=this.maxTexSize[0],n.height=this.maxTexSize[1];const s=this.threadDim=Array.from(this.output);for(;s.length<3;)s.push(1);const i=this.getVertexShader(arguments),a=r.createShader(r.VERTEX_SHADER);r.shaderSource(a,i),r.compileShader(a),this.vertShader=a;const o=this.getFragmentShader(arguments),u=r.createShader(r.FRAGMENT_SHADER);if(r.shaderSource(u,o),r.compileShader(u),this.fragShader=u,this.debug&&(console.log("GLSL Shader Output:"),console.log(o)),!r.getShaderParameter(a,r.COMPILE_STATUS))throw new Error("Error compiling vertex shader: "+r.getShaderInfoLog(a));if(!r.getShaderParameter(u,r.COMPILE_STATUS))throw new Error("Error compiling fragment shader: "+r.getShaderInfoLog(u));const h=this.program=r.createProgram();r.attachShader(h,a),r.attachShader(h,u),r.linkProgram(h),this.framebuffer=r.createFramebuffer(),this.framebuffer.width=t[0],this.framebuffer.height=t[1],this.rawValueFramebuffers={};const l=new Float32Array([-1,-1,1,-1,-1,1,1,1]),c=new Float32Array([0,0,1,0,0,1,1,1]),p=l.byteLength;let d=this.buffer;d?r.bindBuffer(r.ARRAY_BUFFER,d):(d=this.buffer=r.createBuffer(),r.bindBuffer(r.ARRAY_BUFFER,d),r.bufferData(r.ARRAY_BUFFER,l.byteLength+c.byteLength,r.STATIC_DRAW)),r.bufferSubData(r.ARRAY_BUFFER,0,l),r.bufferSubData(r.ARRAY_BUFFER,p,c);const m=r.getAttribLocation(this.program,"aPos");-1!==m&&(r.enableVertexAttribArray(m),r.vertexAttribPointer(m,2,r.FLOAT,!1,0,0));const f=r.getAttribLocation(this.program,"aTexCoord");-1!==f&&(r.enableVertexAttribArray(f),r.vertexAttribPointer(f,2,r.FLOAT,!1,0,p)),r.bindFramebuffer(r.FRAMEBUFFER,this.framebuffer);let g=0;r.useProgram(this.program);for(let e in this.constants)this.kernelConstants[g++].updateValue(this.constants[e]);this._setupOutputTexture(),null!==this.subKernels&&this.subKernels.length>0&&(this._mappedTextureSwitched={},this._setupSubOutputTextures()),this.buildSignature(arguments),this.built=!0}translateSource(){const e=n.fromKernel(this,s,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=e.getPrototypeString("kernel"),this.setupReturnTypes(e)}setupReturnTypes(e){if(this.graphical||this.returnType||(this.returnType=e.getKernelResultType()),this.subKernels&&this.subKernels.length>0)for(let t=0;te.source&&this.source.match(e.functionMatch)?e.source:"").join("\n"):"\n"}_getConstantsString(){const e=[],{threadDim:t,texSize:r}=this;return this.dynamicOutput?e.push("uniform ivec3 uOutputDim","uniform ivec2 uTexSize"):e.push(`ivec3 uOutputDim = ivec3(${t[0]}, ${t[1]}, ${t[2]})`,`ivec2 uTexSize = ivec2(${r[0]}, ${r[1]})`),a.linesToString(e)}_getTextureCoordinate(){const e=this.subKernels;return null===e||e.length<1?"varying vec2 vTexCoord;\n":"out vec2 vTexCoord;\n"}_getDecode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getEncode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getDivideWithIntegerCheckString(){return this.fixIntegerDivisionAccuracy?"float divWithIntCheck(float x, float y) {\n if (floor(x) == x && floor(y) == y) {\n float q = floor(x / y + 0.5);\n if (y * q == x) {\n return q;\n }\n }\n return x / y;\n}\n\nfloat integerCorrectionModulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -(number - (divisor * floor(divWithIntCheck(number, divisor))));\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return number - (divisor * floor(divWithIntCheck(number, divisor)));\n}":""}_getMainArgumentsString(e){const t=[],{argumentNames:r}=this;for(let n=0;n{if(t.hasOwnProperty(r))return t[r];throw`unhandled artifact ${r}`})}getFragmentShader(e){return null!==this.compiledFragmentShader?this.compiledFragmentShader:this.compiledFragmentShader=this.replaceArtifacts(this.constructor.fragmentShader,this._getFragShaderArtifactMap(e))}getVertexShader(e){return null!==this.compiledVertexShader?this.compiledVertexShader:this.compiledVertexShader=this.replaceArtifacts(this.constructor.vertexShader,this._getVertShaderArtifactMap(e))}toString(){const e=a.linesToString(["const gl = context"]);return c(this.constructor,arguments,this,e)}destroy(e){if(!this.context)return;this.buffer&&this.context.deleteBuffer(this.buffer),this.framebuffer&&this.context.deleteFramebuffer(this.framebuffer);for(const e in this.rawValueFramebuffers){for(const t in this.rawValueFramebuffers[e])this.context.deleteFramebuffer(this.rawValueFramebuffers[e][t]),delete this.rawValueFramebuffers[e][t];delete this.rawValueFramebuffers[e]}if(this.vertShader&&this.context.deleteShader(this.vertShader),this.fragShader&&this.context.deleteShader(this.fragShader),this.program&&this.context.deleteProgram(this.program),this.texture){this.texture.delete();const e=this.textureCache.indexOf(this.texture.texture);e>-1&&this.textureCache.splice(e,1),this.texture=null}if(this.mappedTextures&&this.mappedTextures.length){for(let e=0;e-1&&this.textureCache.splice(r,1)}this.mappedTextures=null}if(this.kernelArguments)for(let e=0;e0;){const e=this.textureCache.pop();this.context.deleteTexture(e)}if(e){const e=b.indexOf(this.canvas);e>=0&&(b[e]=null,T[e]=null)}if(this.destroyExtensions(),delete this.context,delete this.canvas,!this.gpu)return;const t=this.gpu.kernels.indexOf(this);-1!==t&&this.gpu.kernels.splice(t,1)}destroyExtensions(){this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("WEBGL_lose_context");t&&t.loseContext()}toJSON(){const e=super.toJSON();return e.functionNodes=n.fromKernel(this,s).toJSON(),e.settings.threadDim=this.threadDim,e}}}}),Te=e((e,t)=>{const r=d(),{WebGLKernel:n}=be(),{glKernelString:s}=P();let i=null,a=null,o=null,u=null,h=null;t.exports={HeadlessGLKernel:class extends n{static get isSupported(){return null!==i||(this.setupFeatureChecks(),i=null!==o),i}static setupFeatureChecks(){if(a=null,u=null,"function"==typeof r)try{if(o=r(2,2,{preserveDrawingBuffer:!0}),!o||!o.getExtension)return;u={STACKGL_resize_drawingbuffer:o.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:o.getExtension("STACKGL_destroy_context"),OES_texture_float:o.getExtension("OES_texture_float"),OES_texture_float_linear:o.getExtension("OES_texture_float_linear"),OES_element_index_uint:o.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:o.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:o.getExtension("WEBGL_color_buffer_float")},h=this.getFeatures()}catch(e){console.warn(e)}}static isContextMatch(e){try{return"ANGLE"===e.getParameter(e.RENDERER)}catch(e){return!1}}static getIsTextureFloat(){return Boolean(u.OES_texture_float)}static getIsDrawBuffers(){return Boolean(u.WEBGL_draw_buffers)}static getChannelCount(){return u.WEBGL_draw_buffers?o.getParameter(u.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return o.getParameter(o.MAX_TEXTURE_SIZE)}static get testCanvas(){return a}static get testContext(){return o}static get features(){return h}initCanvas(){return{}}initContext(){return r(2,2,{preserveDrawingBuffer:!0})}initExtensions(){this.extensions={STACKGL_resize_drawingbuffer:this.context.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:this.context.getExtension("STACKGL_destroy_context"),OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers")}}build(){super.build.apply(this,arguments),this.fallbackRequested||this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}destroyExtensions(){this.extensions.STACKGL_resize_drawingbuffer=null,this.extensions.STACKGL_destroy_context=null,this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("STACKGL_destroy_context");t&&t.destroy&&t.destroy()}toString(){return s(this.constructor,arguments,this,"const gl = context || require('gl')(1, 1);\n"," if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n")}setOutput(e){return super.setOutput(e),this.graphical&&this.extensions.STACKGL_resize_drawingbuffer&&this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1]),this}}}}),Se=e((e,t)=>{const{utils:r}=i(),{WebGLFunctionNode:n}=N();t.exports={WebGL2FunctionNode:class extends n{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),s=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===n&&this.argumentNames.indexOf(s)>-1?t.push(`bool(user_${s})`):t.push(`user_${s}`),t}}}}),ve=e((e,t)=>{t.exports={fragmentShader:`#version 300 es\n__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nin vec2 vTexCoord;\n\nfloat atan2(float v1, float v2) {\n if (v2 == 0.0) {\n if (v1 == 0.0) return 0.0;\n if (v1 > 0.0) return 1.5707963267948966;\n if (v1 < 0.0) return -1.5707963267948966;\n }\n return atan(v1, v2);\n}\n\nfloat cbrt(float x) {\n if (x >= 0.0) {\n return pow(x, 1.0 / 3.0);\n } else {\n return -pow(x, 1.0 / 3.0);\n }\n}\n\nfloat expm1(float x) {\n return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n return x;\n}\n\nfloat imul(float v1, float v2) {\n return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n if (v2 == 0.0) return 1.0;\n return pow(v1, v2);\n}\n\nfloat _round(float x) {\n return floor(x + 0.5);\n}\n\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n // ~a is identically -a - 1 in two's complement, for every value including\n // negatives. The previous bit-by-bit loop only worked for a >= 0, where it\n // leaned on 32-bit overflow wrapping to reach the negative answer; given a\n // negative input it computed ~abs(a), so ~(-1) gave -2 and ~~x never\n // returned x.\n return -a - 1;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\n// _pow2 is defined further down, alongside encode32/decode32\nfloat _pow2(float e);\nint bitwiseSignedRightShift(int num, int shifts) {\n // pow(2.0, n) is approximate on many GPUs, and landing 1 ulp high makes the\n // division fall just under a whole number, which floor() then rounds away:\n // 2 >> 1 came out 0, 8 >> 1 came out 3. Only exact left operands were\n // affected, odd ones having enough slack to survive. _pow2 is exact.\n return int(floor(float(num) / _pow2(float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x/y));\n}\n\n// GLSL ES 1.00 accepts only a constant or a loop symbol inside an index\n// expression, so m[y][x] does not compile when y and x come from kernel\n// arguments -- the error is "Index expression can only contain const or loop\n// symbols". Loop counters are legal indices, so walk the matrix with them\n// instead. These are 2x2 to 4x4, so it costs at most sixteen comparisons.\nfloat getMatrix2(mat2 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 2; i++) {\n for (int j = 0; j < 2; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix3(mat3 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 3; i++) {\n for (int j = 0; j < 3; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix4(mat4 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 4; i++) {\n for (int j = 0; j < 4; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\n// Exact powers of two built from exact constant multiplies: exp2/log2/pow\n// are approximate on some GPUs (notably Apple silicon), and 1-2 ulp there\n// corrupts the packed bytes (#659)\nfloat _pow2(float e) {\n float r = 1.0;\n float a = abs(e);\n bool n = e < 0.0;\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 32.0) { r *= n ? 2.3283064365386963e-10 : 4294967296.0; a -= 32.0; }\n if (a >= 16.0) { r *= n ? 0.0000152587890625 : 65536.0; a -= 16.0; }\n if (a >= 8.0) { r *= n ? 0.00390625 : 256.0; a -= 8.0; }\n if (a >= 4.0) { r *= n ? 0.0625 : 16.0; a -= 4.0; }\n if (a >= 2.0) { r *= n ? 0.25 : 4.0; a -= 2.0; }\n if (a >= 1.0) { r *= n ? 0.5 : 2.0; }\n return r;\n}\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = _pow2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * _pow2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n return texel[channel] * 255.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n float p2 = _pow2(exponent);\n // approximate log2 can land one off; correct by direct comparison\n if (p2 > value) { exponent -= 1.0; p2 *= 0.5; }\n else if (p2 * 2.0 <= value) { exponent += 1.0; p2 *= 2.0; }\n\n mantissa = value / p2 - 1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n index = index / 4;\n vec4 texel = texture(tex, st / vec2(texSize));\n return texel[channel];\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, st / vec2(texSize));\n}\n\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, vec3(st / vec2(texSize), z));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n\n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nfloat modulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -mod(number, divisor);\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}`}}),Ae=e((e,t)=>{t.exports={vertexShader:"#version 300 es\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nin vec2 aPos;\nin vec2 aTexCoord;\n\nout vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"}}),_e=e((e,t)=>{const{WebGLKernelValueBoolean:r}=U();t.exports={WebGL2KernelValueBoolean:class extends r{}}}),Ee=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueFloat:n}=B();t.exports={WebGL2KernelValueFloat:class extends n{}}}),we=e((e,t)=>{const{WebGLKernelValueInteger:r}=j();t.exports={WebGL2KernelValueInteger:class extends r{getSource(e){const t=this.getVariablePrecisionString();return"constants"===this.origin?`const ${t} int ${this.id} = ${parseInt(e)};\n`:`uniform ${t} int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),Ie=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueHTMLImage:n}=H();t.exports={WebGL2KernelValueHTMLImage:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),De=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicHTMLImage:n}=X();t.exports={WebGL2KernelValueDynamicHTMLImage:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Ce=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=W();t.exports={WebGL2KernelValueHTMLImageArray:class extends n{constructor(e,t){super(e,t),this.checkSize(e[0].width,e[0].height),this.dimensions=[e[0].width,e[0].height,e.length],this.textureSize=[e[0].width,e[0].height]}defineTexture(){const{context:e}=this;e.activeTexture(this.contextHandle),e.bindTexture(e.TEXTURE_2D_ARRAY,this.texture),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MIN_FILTER,e.NEAREST)}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D_ARRAY,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage3D(t.TEXTURE_2D_ARRAY,0,t.RGBA,e[0].width,e[0].height,e.length,0,t.RGBA,t.UNSIGNED_BYTE,null);for(let r=0;r{const{utils:r}=i(),{WebGL2KernelValueHTMLImageArray:n}=Ce();t.exports={WebGL2KernelValueDynamicHTMLImageArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:r}=e[0];this.checkSize(t,r),this.dimensions=[t,r,e.length],this.textureSize=[t,r],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Re=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueHTMLImage:n}=Ie();t.exports={WebGL2KernelValueHTMLVideo:class extends n{}}}),Le=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueDynamicHTMLImage:n}=De();t.exports={WebGL2KernelValueDynamicHTMLVideo:class extends n{}}}),$e=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleInput:n}=Z();t.exports={WebGL2KernelValueSingleInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;r.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Fe=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleInput:n}=$e();t.exports={WebGL2KernelValueDynamicSingleInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,s]=e.size;this.dimensions=new Int32Array([t||1,n||1,s||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Ne=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedInput:n}=Q();t.exports={WebGL2KernelValueUnsignedInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),Ve=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicUnsignedInput:n}=ee();t.exports={WebGL2KernelValueDynamicUnsignedInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Me=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueMemoryOptimizedNumberTexture:n}=te();t.exports={WebGL2KernelValueMemoryOptimizedNumberTexture:class extends n{getSource(){const{id:e,sizeId:t,textureSize:n,dimensionsId:s,dimensions:i}=this,a=this.getVariablePrecisionString();return r.linesToString([`uniform sampler2D ${e}`,`${a} ivec2 ${t} = ivec2(${n[0]}, ${n[1]})`,`${a} ivec3 ${s} = ivec3(${i[0]}, ${i[1]}, ${i[2]})`])}}}}),Oe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:n}=re();t.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}}}),ze=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueNumberTexture:n}=ne();t.exports={WebGL2KernelValueNumberTexture:class extends n{getSource(){const{id:e,sizeId:t,textureSize:n,dimensionsId:s,dimensions:i}=this,a=this.getVariablePrecisionString();return r.linesToString([`uniform ${a} sampler2D ${e}`,`${a} ivec2 ${t} = ivec2(${n[0]}, ${n[1]})`,`${a} ivec3 ${s} = ivec3(${i[0]}, ${i[1]}, ${i[2]})`])}}}}),Pe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicNumberTexture:n}=se();t.exports={WebGL2KernelValueDynamicNumberTexture:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Ke=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray:n}=ie();t.exports={WebGL2KernelValueSingleArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Ge=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray:n}=Ke();t.exports={WebGL2KernelValueDynamicSingleArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Ue=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray1DI:n}=oe();t.exports={WebGL2KernelValueSingleArray1DI:class extends n{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Be=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray1DI:n}=Ue();t.exports={WebGL2KernelValueDynamicSingleArray1DI:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),je=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray2DI:n}=he();t.exports={WebGL2KernelValueSingleArray2DI:class extends n{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),We=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray2DI:n}=je();t.exports={WebGL2KernelValueDynamicSingleArray2DI:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),He=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray3DI:n}=ce();t.exports={WebGL2KernelValueSingleArray3DI:class extends n{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Xe=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray3DI:n}=He();t.exports={WebGL2KernelValueDynamicSingleArray3DI:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),qe=e((e,t)=>{const{WebGLKernelValueArray2:r}=de();t.exports={WebGL2KernelValueArray2:class extends r{}}}),Ye=e((e,t)=>{const{WebGLKernelValueArray3:r}=me();t.exports={WebGL2KernelValueArray3:class extends r{}}}),Ze=e((e,t)=>{const{WebGLKernelValueArray4:r}=fe();t.exports={WebGL2KernelValueArray4:class extends r{}}}),Je=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedArray:n}=ge();t.exports={WebGL2KernelValueUnsignedArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),Qe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicUnsignedArray:n}=xe();t.exports={WebGL2KernelValueDynamicUnsignedArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),et=e((e,t)=>{const{WebGL2KernelValueBoolean:r}=_e(),{WebGL2KernelValueFloat:n}=Ee(),{WebGL2KernelValueInteger:s}=we(),{WebGL2KernelValueHTMLImage:i}=Ie(),{WebGL2KernelValueDynamicHTMLImage:a}=De(),{WebGL2KernelValueHTMLImageArray:o}=Ce(),{WebGL2KernelValueDynamicHTMLImageArray:u}=ke(),{WebGL2KernelValueHTMLVideo:h}=Re(),{WebGL2KernelValueDynamicHTMLVideo:l}=Le(),{WebGL2KernelValueSingleInput:c}=$e(),{WebGL2KernelValueDynamicSingleInput:p}=Fe(),{WebGL2KernelValueUnsignedInput:d}=Ne(),{WebGL2KernelValueDynamicUnsignedInput:m}=Ve(),{WebGL2KernelValueMemoryOptimizedNumberTexture:f}=Me(),{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:g}=Oe(),{WebGL2KernelValueNumberTexture:x}=ze(),{WebGL2KernelValueDynamicNumberTexture:y}=Pe(),{WebGL2KernelValueSingleArray:b}=Ke(),{WebGL2KernelValueDynamicSingleArray:T}=Ge(),{WebGL2KernelValueSingleArray1DI:S}=Ue(),{WebGL2KernelValueDynamicSingleArray1DI:v}=Be(),{WebGL2KernelValueSingleArray2DI:A}=je(),{WebGL2KernelValueDynamicSingleArray2DI:_}=We(),{WebGL2KernelValueSingleArray3DI:E}=He(),{WebGL2KernelValueDynamicSingleArray3DI:w}=Xe(),{WebGL2KernelValueArray2:I}=qe(),{WebGL2KernelValueArray3:D}=Ye(),{WebGL2KernelValueArray4:C}=Ze(),{WebGL2KernelValueUnsignedArray:k}=Je(),{WebGL2KernelValueDynamicUnsignedArray:R}=Qe(),L={unsigned:{dynamic:{Boolean:r,Integer:s,Float:n,Array:R,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:m,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:g,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:l},static:{Boolean:r,Float:n,Integer:s,Array:k,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:d,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:o,HTMLVideo:h}},single:{dynamic:{Boolean:r,Integer:s,Float:n,Array:T,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":v,"Array1D(3)":v,"Array1D(4)":v,"Array2D(2)":_,"Array2D(3)":_,"Array2D(4)":_,"Array3D(2)":w,"Array3D(3)":w,"Array3D(4)":w,Input:p,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:g,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:l},static:{Boolean:r,Float:n,Integer:s,Array:b,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":S,"Array1D(3)":S,"Array1D(4)":S,"Array2D(2)":A,"Array2D(3)":A,"Array2D(4)":A,"Array3D(2)":E,"Array3D(3)":E,"Array3D(4)":E,Input:c,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:f,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:o,HTMLVideo:h}}};t.exports={kernelValueMaps:L,lookupKernelValueType:function(e,t,r,n){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!r)throw new Error("precision missing");n.type&&(e=n.type);const s=L[r][t];if(!1===s[e])return null;if(void 0===s[e])throw new Error(`Could not find a KernelValue for ${e}`);return s[e]}}}),tt=e((e,t)=>{const{WebGLKernel:r}=be(),{WebGL2FunctionNode:n}=Se(),{FunctionBuilder:s}=o(),{utils:a}=i(),{fragmentShader:u}=ve(),{vertexShader:h}=Ae(),{lookupKernelValueType:l}=et();let c=null,p=null,d=null,m=null;t.exports={WebGL2Kernel:class extends r{static get isSupported(){return null!==c||(this.setupFeatureChecks(),c=this.isContextMatch(d)),c}static setupFeatureChecks(){"undefined"!=typeof document?p=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(p=new OffscreenCanvas(0,0)),p&&(d=p.getContext("webgl2"),d&&d.getExtension&&(d.getExtension("EXT_color_buffer_float"),d.getExtension("OES_texture_float_linear"),m=this.getFeatures()))}static isContextMatch(e){return"undefined"!=typeof WebGL2RenderingContext&&e instanceof WebGL2RenderingContext}static getFeatures(){const e=this.testContext;return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isSpeedTacticSupported:this.getIsSpeedTacticSupported(),kernelMap:!0,isTextureFloat:!0,isDrawBuffers:!0,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize(),lowIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT),lowFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT),mediumIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT),mediumFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT),highIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT),highFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)})}static getIsTextureFloat(){return!0}static getChannelCount(){return d.getParameter(d.MAX_DRAW_BUFFERS)}static getMaxTextureSize(){return d.getParameter(d.MAX_TEXTURE_SIZE)}static lookupKernelValueType(e,t,r,n){return l(e,t,r,n)}static get testCanvas(){return p}static get testContext(){return d}static get features(){return m}static get fragmentShader(){return u}static get vertexShader(){return h}initContext(){return this.canvas.getContext("webgl2",{alpha:!1,depth:!1,antialias:!1})}initExtensions(){this.extensions={EXT_color_buffer_float:this.context.getExtension("EXT_color_buffer_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if("single"===this.precision&&!t.isFloatRead)throw new Error("Float texture outputs are not supported");if(this.graphical||null!==this.precision||(this.precision=t.isFloatRead?"single":"unsigned"),null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);switch(t){case"Array":this.output=a.getDimensions(t);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=e[0].output;break;default:throw new Error("Auto output not supported for input type: "+t)}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"single"===this.precision&&(console.warn("Cannot use graphical mode and single precision at the same time"),this.precision="unsigned"),void(this.texSize=a.clone(this.output))}!this.graphical&&null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}translateSource(){const e=s.fromKernel(this,n,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=e.getPrototypeString("kernel"),this.setupReturnTypes(e)}drawBuffers(){this.context.drawBuffers(this.drawBuffersMap)}getTextureFormat(){const{context:e}=this;switch(this.getInternalFormat()){case e.R32F:return e.RED;case e.RG32F:return e.RG;case e.RGBA32F:case e.RGBA:return e.RGBA;default:throw new Error("Unknown internal format")}}renderValues(){return void 0===this._tightRead&&this._detectTightRead(),super.renderValues()}renderKernelsToArrays(){return void 0===this._tightRead&&this._detectTightRead(),super.renderKernelsToArrays()}readFloatPixelsToFloat32Array(){if(!this._tightRead)return super.readFloatPixelsToFloat32Array();const{texSize:e,context:t}=this,r=e[0],n=e[1],s=new Float32Array(r*n);return t.readPixels(0,0,r,n,t.RED,t.FLOAT,s),s}_detectTightRead(){const e=this.context;this._tightRead=!1,e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer);const t="Number"===this.returnType||"Float"===this.returnType||"Integer"===this.returnType||"LiteralInteger"===this.returnType;if("single"===this.precision&&!this.optimizeFloatMemory&&!this.graphical&&t&&e.getParameter(e.IMPLEMENTATION_COLOR_READ_FORMAT)===e.RED&&e.getParameter(e.IMPLEMENTATION_COLOR_READ_TYPE)===e.FLOAT){if(this.formatValues===a.erectFloat)this.formatValues=a.erectMemoryOptimizedFloat;else if(this.formatValues===a.erect2DFloat)this.formatValues=a.erectMemoryOptimized2DFloat;else if(this.formatValues===a.erect3DFloat)this.formatValues=a.erectMemoryOptimized3DFloat;else if(this.formatValues!==a.erectMemoryOptimizedFloat&&this.formatValues!==a.erectMemoryOptimized2DFloat&&this.formatValues!==a.erectMemoryOptimized3DFloat)return;this._tightRead=!0}}getInternalFormat(){const{context:e}=this;if("single"===this.precision)switch(this.returnType){case"Number":case"Float":case"Integer":return this.optimizeFloatMemory?e.RGBA32F:e.R32F;case"Array(2)":return e.RG32F;case"Array(3)":case"Array(4)":return e.RGBA32F;default:throw new Error("Unhandled return type")}return e.RGBA}_setupOutputTexture(){const e=this.context;if(this.texture)return e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture.texture,0),void(this._tightRead=void 0);e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer);const t=e.createTexture(),r=this.texSize;e.activeTexture(e.TEXTURE0+this.constantTextureCount+this.argumentTextureCount),e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);const n=this.getInternalFormat();"single"===this.precision?e.texStorage2D(e.TEXTURE_2D,1,n,r[0],r[1]):e.texImage2D(e.TEXTURE_2D,0,n,r[0],r[1],0,n,e.UNSIGNED_BYTE,null),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),this.texture=new this.TextureConstructor({texture:t,size:r,dimensions:this.threadDim,output:this.output,context:this.context,internalFormat:this.getInternalFormat(),textureFormat:this.getTextureFormat(),kernel:this}),this._tightRead=void 0}_setupSubOutputTextures(){const e=this.context;if(this.mappedTextures){for(let t=0;t{const{utils:r}=i();function n(e,t){if(t.kernel)return void(t.kernel=e);const n=r.allPropertiesOf(e);for(let r=0;rt.kernel[s]),t.__defineSetter__(s,e=>{t.kernel[s]=e})))}t.kernel=e}t.exports={kernelRunShortcut:function(e){let t=function(){return e.build.apply(e,arguments),t=function(){let t=e.run.apply(e,arguments);if(e.switchingKernels){const n=e.resetSwitchingKernels(),s=e.onRequestSwitchKernel(n,arguments,e);r.kernel=e=s,t=s.run.apply(s,arguments)}return e.renderKernels?e.renderKernels():e.renderOutput?e.renderOutput():t},t.apply(e,arguments)};const r=function(){return t.apply(e,arguments)};return r.exec=function(){return new Promise((e,r)=>{try{e(t.apply(this,arguments))}catch(e){r(e)}})},r.replaceKernel=function(t){n(e=t,r)},n(e,r),r}}}),nt=e((e,r)=>{const{gpuMock:n}=t(),{utils:s}=i(),{Kernel:o}=a(),{CPUKernel:u}=p(),{HeadlessGLKernel:h}=Te(),{WebGL2Kernel:l}=tt(),{WebGLKernel:c}=be(),{kernelRunShortcut:d}=rt(),m=[h,l,c],f=["gpu","cpu"],g={headlessgl:h,webgl2:l,webgl:c};let x=!0;function y(e){if(!e)return{};const t=Object.assign({},e);return e.hasOwnProperty("floatOutput")&&(s.warnDeprecated("setting","floatOutput","precision"),t.precision=e.floatOutput?"single":"unsigned"),e.hasOwnProperty("outputToTexture")&&(s.warnDeprecated("setting","outputToTexture","pipeline"),t.pipeline=Boolean(e.outputToTexture)),e.hasOwnProperty("outputImmutable")&&(s.warnDeprecated("setting","outputImmutable","immutable"),t.immutable=Boolean(e.outputImmutable)),e.hasOwnProperty("floatTextures")&&(s.warnDeprecated("setting","floatTextures","optimizeFloatMemory"),t.optimizeFloatMemory=Boolean(e.floatTextures)),t}r.exports={GPU:class{static disableValidation(){x=!1}static enableValidation(){x=!0}static get isGPUSupported(){return m.some(e=>e.isSupported)}static get isKernelMapSupported(){return m.some(e=>e.isSupported&&e.features.kernelMap)}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return c.isSupported}static get isWebGL2Supported(){return l.isSupported}static get isHeadlessGLSupported(){return h.isSupported}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return l.isSupported}static get isSinglePrecisionSupported(){return m.some(e=>e.isSupported&&e.features.isFloatRead&&e.features.isTextureFloat)}constructor(e){if(e=e||{},this.canvas=e.canvas||null,this.context=e.context||null,this.mode=e.mode,this.Kernel=null,this.kernels=[],this.functions=[],this.nativeFunctions=[],this.injectedNative=null,"dev"!==this.mode){if(this.chooseKernel(),e.functions)for(let t=0;tt.argumentTypes[e]));const h=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate:x,onRequestFallback:o,onRequestSwitchKernel:function t(n,s,a){a.debug&&console.warn("Switching kernels");let u=null;if(a.signature&&!i[a.signature]&&(i[a.signature]=a),a.dynamicOutput)for(let e=n.length-1;e>=0;e--){const t=n[e];"outputPrecisionMismatch"===t.type&&(u=t.needed)}const h=a.constructor,l=h.getArgumentTypes(a,s),p=h.getSignature(a,l),d=i[p];if(d)return d.onActivate(a),d;const m=i[p]=new h(e,{argumentTypes:l,constantTypes:a.constantTypes,graphical:a.graphical,loopMaxIterations:a.loopMaxIterations,constants:a.constants,dynamicOutput:a.dynamicOutput,dynamicArgument:a.dynamicArguments,context:a.context,canvas:a.canvas,output:u||a.output,precision:a.precision,pipeline:a.pipeline,immutable:a.immutable,optimizeFloatMemory:a.optimizeFloatMemory,fixIntegerDivisionAccuracy:a.fixIntegerDivisionAccuracy,functions:a.functions,nativeFunctions:a.nativeFunctions,injectedNative:a.injectedNative,subKernels:a.subKernels,strictIntegers:a.strictIntegers,randomSeed:a.randomSeed,debug:a.debug,gpu:a.gpu,validate:x,returnType:a.returnType,tactic:a.tactic,onRequestFallback:o,onRequestSwitchKernel:t,texture:a.texture,mappedTextures:a.mappedTextures,drawBuffersMap:a.drawBuffersMap});return m.build.apply(m,s),c.replaceKernel(m),r.push(m),m}},a),l=new this.Kernel(e,h),c=d(l);return this.canvas||(this.canvas=l.canvas),this.context||(this.context=l.context),r.push(l),c}createKernelMap(){let e,t;const r=typeof arguments[arguments.length-2];if("function"===r||"string"===r?(e=arguments[arguments.length-2],t=arguments[arguments.length-1]):e=arguments[arguments.length-1],"dev"!==this.mode&&(!this.Kernel.isSupported||!this.Kernel.features.kernelMap)&&this.mode&&f.indexOf(this.mode)<0)throw new Error(`kernelMap not supported on ${this.Kernel.name}`);const n=y(t);if(t&&"object"==typeof t.argumentTypes&&(n.argumentTypes=Object.keys(t.argumentTypes).map(e=>t.argumentTypes[e])),Array.isArray(arguments[0])){n.subKernels=[];const e=arguments[0];for(let t=0;t0)throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');return this.nativeFunctions.push(Object.assign({name:e,source:t},r)),this}injectNative(e){return this.injectedNative=e,this}destroy(){return new Promise((e,t)=>{this.kernels||e(),setTimeout(()=>{try{const e=this.kernels.slice();for(let t=0;t{const{utils:r}=i();t.exports={alias:function(e,t){const n=t.toString();return new Function(`return function ${e} (${r.getArgumentNamesFromString(n).join(", ")}) {\n ${r.getFunctionBodyFromString(n)}\n}`)()}}}),it=e((e,t)=>{const{GPU:r}=nt(),{alias:c}=st(),{utils:d}=i(),{Input:m,input:f}=n(),{Texture:g}=s(),{FunctionBuilder:x}=o(),{FunctionNode:y}=h(),{CPUFunctionNode:b}=l(),{CPUKernel:T}=p(),{HeadlessGLKernel:S}=Te(),{WebGLFunctionNode:v}=N(),{WebGLKernel:A}=be(),{kernelValueMaps:_}=ye(),{WebGL2FunctionNode:E}=Se(),{WebGL2Kernel:w}=tt(),{kernelValueMaps:I}=et(),{GLKernel:D}=F(),{Kernel:C}=a(),{FunctionTracer:k}=u();t.exports={alias:c,CPUFunctionNode:b,CPUKernel:T,GPU:r,FunctionBuilder:x,FunctionNode:y,HeadlessGLKernel:S,Input:m,input:f,Texture:g,utils:d,WebGL2FunctionNode:E,WebGL2Kernel:w,webGL2KernelValueMaps:I,WebGLFunctionNode:v,WebGLKernel:A,webGLKernelValueMaps:_,GLKernel:D,Kernel:C,FunctionTracer:k,plugins:{mathRandom:V()}}});return e((e,t)=>{const r=it(),n=r.GPU;for(const e in r)r.hasOwnProperty(e)&&"GPU"!==e&&(n[e]=r[e]);function s(e){e.GPU&&e.GPU.prototype&&e.GPU.prototype.createKernel||Object.defineProperty(e,"GPU",{configurable:!0,get:()=>n,set(){}})}n.GPU=n,"undefined"!=typeof window&&s(window),"undefined"!=typeof self&&s(self),t.exports=n})()}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):(e="undefined"!=typeof globalThis?globalThis:e||self).GPU=t()}(this,function(){var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),t=e((e,t)=>{function r(e){const t=new Array(e.length);for(let r=0;r{e.output=h(t),e.graphical&&u(e)},e.toJSON=()=>{throw new Error("Not usable with gpuMock")},e.setConstants=t=>(e.constants=t,e),e.setGraphical=t=>(e.graphical=t,e),e.setCanvas=t=>(e.canvas=t,e),e.setContext=t=>(e.context=t,e),e.destroy=()=>{},e.validateSettings=()=>{},e.graphical&&e.output&&u(e),e.exec=function(){return new Promise((t,r)=>{try{t(e.apply(e,arguments))}catch(e){r(e)}})},e.getPixels=t=>{const{x:r,y:n}=e.output;return t?function(e,t,r){const n=r/2|0,s=4*t,i=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee,r=["setWarnVarUsage","setArgumentTypes","setTactic","setOptimizeFloatMemory","setDebug","setLoopMaxIterations","setConstantTypes","setFunctions","setNativeFunctions","setInjectedNative","setPipeline","setPrecision","setOutputToTexture","setImmutable","setStrictIntegers","setDynamicOutput","setHardcodeConstants","setDynamicArguments","setUseLegacyEncoder","setWarnVarUsage","addSubKernel"];for(let n=0;n{var r,n;r=e,n=function(e){"use strict";var t=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,7,9,32,4,318,1,80,3,71,10,50,3,123,2,54,14,32,10,3,1,11,3,46,10,8,0,46,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,2,11,83,11,7,0,3,0,158,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,68,8,2,0,3,0,2,3,2,4,2,0,15,1,83,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,7,19,58,14,5,9,243,14,166,9,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,343,9,54,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,10,1,2,0,49,6,4,4,14,10,5350,0,7,14,11465,27,2343,9,87,9,39,4,60,6,26,9,535,9,470,0,2,54,8,3,82,0,12,1,19628,1,4178,9,519,45,3,22,543,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,101,0,161,6,10,9,357,0,62,13,499,13,245,1,2,9,726,6,110,6,6,9,4759,9,787719,239],r=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,13,10,2,14,2,6,2,1,2,10,2,14,2,6,2,1,4,51,13,310,10,21,11,7,25,5,2,41,2,8,70,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,39,27,10,22,251,41,7,1,17,2,60,28,11,0,9,21,43,17,47,20,28,22,13,52,58,1,3,0,14,44,33,24,27,35,30,0,3,0,9,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,20,1,64,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,31,9,2,0,3,0,2,37,2,0,26,0,2,0,45,52,19,3,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,38,6,186,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,19,72,200,32,32,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,16,0,2,12,2,33,125,0,80,921,103,110,18,195,2637,96,16,1071,18,5,26,3994,6,582,6842,29,1763,568,8,30,18,78,18,29,19,47,17,3,32,20,6,18,433,44,212,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,1237,42,9,8936,3,2,6,2,1,2,290,16,0,30,2,3,0,15,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,1845,30,7,5,262,61,147,44,11,6,17,0,322,29,19,43,485,27,229,29,3,0,496,6,2,3,2,1,2,14,2,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42719,33,4153,7,221,3,5761,15,7472,16,621,2467,541,1507,4938,6,4191],n="\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7cd\ua7d0\ua7d1\ua7d3\ua7d5-\ua7dc\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc",s={3:"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",5:"class enum extends super const export import",6:"enum",strict:"implements interface let package private protected public static yield",strictBind:"eval arguments"},i="break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this",a={5:i,"5module":i+" export import",6:i+" const class extends export import super"},o=/^in(stanceof)?$/,u=new RegExp("["+n+"]"),h=new RegExp("["+n+"\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65]");function l(e,t){for(var r=65536,n=0;ne)return!1;if((r+=t[n+1])>=e)return!0}return!1}function c(e,t){return e<65?36===e:e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&u.test(String.fromCharCode(e)):!1!==t&&l(e,r)))}function p(e,n){return e<48?36===e:e<58||!(e<65)&&(e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&h.test(String.fromCharCode(e)):!1!==n&&(l(e,r)||l(e,t)))))}var d=function(e,t){void 0===t&&(t={}),this.label=e,this.keyword=t.keyword,this.beforeExpr=!!t.beforeExpr,this.startsExpr=!!t.startsExpr,this.isLoop=!!t.isLoop,this.isAssign=!!t.isAssign,this.prefix=!!t.prefix,this.postfix=!!t.postfix,this.binop=t.binop||null,this.updateContext=null};function f(e,t){return new d(e,{beforeExpr:!0,binop:t})}var m={beforeExpr:!0},g={startsExpr:!0},x={};function y(e,t){return void 0===t&&(t={}),t.keyword=e,x[e]=new d(e,t)}var b={num:new d("num",g),regexp:new d("regexp",g),string:new d("string",g),name:new d("name",g),privateId:new d("privateId",g),eof:new d("eof"),bracketL:new d("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new d("]"),braceL:new d("{",{beforeExpr:!0,startsExpr:!0}),braceR:new d("}"),parenL:new d("(",{beforeExpr:!0,startsExpr:!0}),parenR:new d(")"),comma:new d(",",m),semi:new d(";",m),colon:new d(":",m),dot:new d("."),question:new d("?",m),questionDot:new d("?."),arrow:new d("=>",m),template:new d("template"),invalidTemplate:new d("invalidTemplate"),ellipsis:new d("...",m),backQuote:new d("`",g),dollarBraceL:new d("${",{beforeExpr:!0,startsExpr:!0}),eq:new d("=",{beforeExpr:!0,isAssign:!0}),assign:new d("_=",{beforeExpr:!0,isAssign:!0}),incDec:new d("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new d("!/~",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:f("||",1),logicalAND:f("&&",2),bitwiseOR:f("|",3),bitwiseXOR:f("^",4),bitwiseAND:f("&",5),equality:f("==/!=/===/!==",6),relational:f("/<=/>=",7),bitShift:f("<>/>>>",8),plusMin:new d("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:f("%",10),star:f("*",10),slash:f("/",10),starstar:new d("**",{beforeExpr:!0}),coalesce:f("??",1),_break:y("break"),_case:y("case",m),_catch:y("catch"),_continue:y("continue"),_debugger:y("debugger"),_default:y("default",m),_do:y("do",{isLoop:!0,beforeExpr:!0}),_else:y("else",m),_finally:y("finally"),_for:y("for",{isLoop:!0}),_function:y("function",g),_if:y("if"),_return:y("return",m),_switch:y("switch"),_throw:y("throw",m),_try:y("try"),_var:y("var"),_const:y("const"),_while:y("while",{isLoop:!0}),_with:y("with"),_new:y("new",{beforeExpr:!0,startsExpr:!0}),_this:y("this",g),_super:y("super",g),_class:y("class",g),_extends:y("extends",m),_export:y("export"),_import:y("import",g),_null:y("null",g),_true:y("true",g),_false:y("false",g),_in:y("in",{beforeExpr:!0,binop:7}),_instanceof:y("instanceof",{beforeExpr:!0,binop:7}),_typeof:y("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:y("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:y("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},T=/\r\n?|\n|\u2028|\u2029/,S=new RegExp(T.source,"g");function v(e){return 10===e||13===e||8232===e||8233===e}function A(e,t,r){void 0===r&&(r=e.length);for(var n=t;n>10),56320+(1023&e)))}var R=/(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/,N=function(e,t){this.line=e,this.column=t};N.prototype.offset=function(e){return new N(this.line,this.column+e)};var V=function(e,t,r){this.start=t,this.end=r,null!==e.sourceFile&&(this.source=e.sourceFile)};function M(e,t){for(var r=1,n=0;;){var s=A(e,n,t);if(s<0)return new N(r,t-n);++r,n=s}}var O={ecmaVersion:null,sourceType:"script",onInsertedSemicolon:null,onTrailingComma:null,allowReserved:null,allowReturnOutsideFunction:!1,allowImportExportEverywhere:!1,allowAwaitOutsideFunction:null,allowSuperOutsideMethod:null,allowHashBang:!1,checkPrivateFields:!0,locations:!1,onToken:null,onComment:null,ranges:!1,program:null,sourceFile:null,directSourceFile:null,preserveParens:!1},P=!1;function G(e){var t={};for(var r in O)t[r]=e&&D(e,r)?e[r]:O[r];if("latest"===t.ecmaVersion?t.ecmaVersion=1e8:null==t.ecmaVersion?(!P&&"object"==typeof console&&console.warn&&(P=!0,console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future.")),t.ecmaVersion=11):t.ecmaVersion>=2015&&(t.ecmaVersion-=2009),null==t.allowReserved&&(t.allowReserved=t.ecmaVersion<5),e&&null!=e.allowHashBang||(t.allowHashBang=t.ecmaVersion>=14),C(t.onToken)){var n=t.onToken;t.onToken=function(e){return n.push(e)}}return C(t.onComment)&&(t.onComment=function(e,t){return function(r,n,s,i,a,o){var u={type:r?"Block":"Line",value:n,start:s,end:i};e.locations&&(u.loc=new V(this,a,o)),e.ranges&&(u.range=[s,i]),t.push(u)}}(t,t.onComment)),t}var z=256;function U(e,t){return 2|(e?4:0)|(t?8:0)}var K=function(e,t,r){this.options=e=G(e),this.sourceFile=e.sourceFile,this.keywords=$(a[e.ecmaVersion>=6?6:"module"===e.sourceType?"5module":5]);var n="";!0!==e.allowReserved&&(n=s[e.ecmaVersion>=6?6:5===e.ecmaVersion?5:3],"module"===e.sourceType&&(n+=" await")),this.reservedWords=$(n);var i=(n?n+" ":"")+s.strict;this.reservedWordsStrict=$(i),this.reservedWordsStrictBind=$(i+" "+s.strictBind),this.input=String(t),this.containsEsc=!1,r?(this.pos=r,this.lineStart=this.input.lastIndexOf("\n",r-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(T).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=b.eof,this.value=null,this.start=this.end=this.pos,this.startLoc=this.endLoc=this.curPosition(),this.lastTokEndLoc=this.lastTokStartLoc=null,this.lastTokStart=this.lastTokEnd=this.pos,this.context=this.initialContext(),this.exprAllowed=!0,this.inModule="module"===e.sourceType,this.strict=this.inModule||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.potentialArrowInForAwait=!1,this.yieldPos=this.awaitPos=this.awaitIdentPos=0,this.labels=[],this.undefinedExports=Object.create(null),0===this.pos&&e.allowHashBang&&"#!"===this.input.slice(0,2)&&this.skipLineComment(2),this.scopeStack=[],this.enterScope(1),this.regexpState=null,this.privateNameStack=[]},B={inFunction:{configurable:!0},inGenerator:{configurable:!0},inAsync:{configurable:!0},canAwait:{configurable:!0},allowSuper:{configurable:!0},allowDirectSuper:{configurable:!0},treatFunctionsAsVar:{configurable:!0},allowNewDotTarget:{configurable:!0},inClassStaticBlock:{configurable:!0}};K.prototype.parse=function(){var e=this.options.program||this.startNode();return this.nextToken(),this.parseTopLevel(e)},B.inFunction.get=function(){return(2&this.currentVarScope().flags)>0},B.inGenerator.get=function(){return(8&this.currentVarScope().flags)>0&&!this.currentVarScope().inClassFieldInit},B.inAsync.get=function(){return(4&this.currentVarScope().flags)>0&&!this.currentVarScope().inClassFieldInit},B.canAwait.get=function(){for(var e=this.scopeStack.length-1;e>=0;e--){var t=this.scopeStack[e];if(t.inClassFieldInit||t.flags&z)return!1;if(2&t.flags)return(4&t.flags)>0}return this.inModule&&this.options.ecmaVersion>=13||this.options.allowAwaitOutsideFunction},B.allowSuper.get=function(){var e=this.currentThisScope(),t=e.flags,r=e.inClassFieldInit;return(64&t)>0||r||this.options.allowSuperOutsideMethod},B.allowDirectSuper.get=function(){return(128&this.currentThisScope().flags)>0},B.treatFunctionsAsVar.get=function(){return this.treatFunctionsAsVarInScope(this.currentScope())},B.allowNewDotTarget.get=function(){var e=this.currentThisScope(),t=e.flags,r=e.inClassFieldInit;return(258&t)>0||r},B.inClassStaticBlock.get=function(){return(this.currentVarScope().flags&z)>0},K.extend=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];for(var r=this,n=0;n=,?^&]/.test(s)||"!"===s&&"="===this.input.charAt(n+1))}e+=t[0].length,w.lastIndex=e,e+=w.exec(this.input)[0].length,";"===this.input[e]&&e++}},W.eat=function(e){return this.type===e&&(this.next(),!0)},W.isContextual=function(e){return this.type===b.name&&this.value===e&&!this.containsEsc},W.eatContextual=function(e){return!!this.isContextual(e)&&(this.next(),!0)},W.expectContextual=function(e){this.eatContextual(e)||this.unexpected()},W.canInsertSemicolon=function(){return this.type===b.eof||this.type===b.braceR||T.test(this.input.slice(this.lastTokEnd,this.start))},W.insertSemicolon=function(){if(this.canInsertSemicolon())return this.options.onInsertedSemicolon&&this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc),!0},W.semicolon=function(){this.eat(b.semi)||this.insertSemicolon()||this.unexpected()},W.afterTrailingComma=function(e,t){if(this.type===e)return this.options.onTrailingComma&&this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc),t||this.next(),!0},W.expect=function(e){this.eat(e)||this.unexpected()},W.unexpected=function(e){this.raise(null!=e?e:this.start,"Unexpected token")};var H=function(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=this.doubleProto=-1};W.checkPatternErrors=function(e,t){if(e){e.trailingComma>-1&&this.raiseRecoverable(e.trailingComma,"Comma is not permitted after the rest element");var r=t?e.parenthesizedAssign:e.parenthesizedBind;r>-1&&this.raiseRecoverable(r,t?"Assigning to rvalue":"Parenthesized pattern")}},W.checkExpressionErrors=function(e,t){if(!e)return!1;var r=e.shorthandAssign,n=e.doubleProto;if(!t)return r>=0||n>=0;r>=0&&this.raise(r,"Shorthand property assignments are valid only in destructuring patterns"),n>=0&&this.raiseRecoverable(n,"Redefinition of __proto__ property")},W.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos55295&&n<56320)return!0;if(c(n,!0)){for(var s=r+1;p(n=this.input.charCodeAt(s),!0);)++s;if(92===n||n>55295&&n<56320)return!0;var i=this.input.slice(r,s);if(!o.test(i))return!0}return!1},X.isAsyncFunction=function(){if(this.options.ecmaVersion<8||!this.isContextual("async"))return!1;w.lastIndex=this.pos;var e,t=w.exec(this.input),r=this.pos+t[0].length;return!(T.test(this.input.slice(this.pos,r))||"function"!==this.input.slice(r,r+8)||r+8!==this.input.length&&(p(e=this.input.charCodeAt(r+8))||e>55295&&e<56320))},X.parseStatement=function(e,t,r){var n,s=this.type,i=this.startNode();switch(this.isLet(e)&&(s=b._var,n="let"),s){case b._break:case b._continue:return this.parseBreakContinueStatement(i,s.keyword);case b._debugger:return this.parseDebuggerStatement(i);case b._do:return this.parseDoStatement(i);case b._for:return this.parseForStatement(i);case b._function:return e&&(this.strict||"if"!==e&&"label"!==e)&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(i,!1,!e);case b._class:return e&&this.unexpected(),this.parseClass(i,!0);case b._if:return this.parseIfStatement(i);case b._return:return this.parseReturnStatement(i);case b._switch:return this.parseSwitchStatement(i);case b._throw:return this.parseThrowStatement(i);case b._try:return this.parseTryStatement(i);case b._const:case b._var:return n=n||this.value,e&&"var"!==n&&this.unexpected(),this.parseVarStatement(i,n);case b._while:return this.parseWhileStatement(i);case b._with:return this.parseWithStatement(i);case b.braceL:return this.parseBlock(!0,i);case b.semi:return this.parseEmptyStatement(i);case b._export:case b._import:if(this.options.ecmaVersion>10&&s===b._import){w.lastIndex=this.pos;var a=w.exec(this.input),o=this.pos+a[0].length,u=this.input.charCodeAt(o);if(40===u||46===u)return this.parseExpressionStatement(i,this.parseExpression())}return this.options.allowImportExportEverywhere||(t||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),s===b._import?this.parseImport(i):this.parseExport(i,r);default:if(this.isAsyncFunction())return e&&this.unexpected(),this.next(),this.parseFunctionStatement(i,!0,!e);var h=this.value,l=this.parseExpression();return s===b.name&&"Identifier"===l.type&&this.eat(b.colon)?this.parseLabeledStatement(i,h,l,e):this.parseExpressionStatement(i,l)}},X.parseBreakContinueStatement=function(e,t){var r="break"===t;this.next(),this.eat(b.semi)||this.insertSemicolon()?e.label=null:this.type!==b.name?this.unexpected():(e.label=this.parseIdent(),this.semicolon());for(var n=0;n=6?this.eat(b.semi):this.semicolon(),this.finishNode(e,"DoWhileStatement")},X.parseForStatement=function(e){this.next();var t=this.options.ecmaVersion>=9&&this.canAwait&&this.eatContextual("await")?this.lastTokStart:-1;if(this.labels.push(q),this.enterScope(0),this.expect(b.parenL),this.type===b.semi)return t>-1&&this.unexpected(t),this.parseFor(e,null);var r=this.isLet();if(this.type===b._var||this.type===b._const||r){var n=this.startNode(),s=r?"let":this.value;return this.next(),this.parseVar(n,!0,s),this.finishNode(n,"VariableDeclaration"),(this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&1===n.declarations.length?(this.options.ecmaVersion>=9&&(this.type===b._in?t>-1&&this.unexpected(t):e.await=t>-1),this.parseForIn(e,n)):(t>-1&&this.unexpected(t),this.parseFor(e,n))}var i=this.isContextual("let"),a=!1,o=this.containsEsc,u=new H,h=this.start,l=t>-1?this.parseExprSubscripts(u,"await"):this.parseExpression(!0,u);return this.type===b._in||(a=this.options.ecmaVersion>=6&&this.isContextual("of"))?(t>-1?(this.type===b._in&&this.unexpected(t),e.await=!0):a&&this.options.ecmaVersion>=8&&(l.start!==h||o||"Identifier"!==l.type||"async"!==l.name?this.options.ecmaVersion>=9&&(e.await=!1):this.unexpected()),i&&a&&this.raise(l.start,"The left-hand side of a for-of loop may not start with 'let'."),this.toAssignable(l,!1,u),this.checkLValPattern(l),this.parseForIn(e,l)):(this.checkExpressionErrors(u,!0),t>-1&&this.unexpected(t),this.parseFor(e,l))},X.parseFunctionStatement=function(e,t,r){return this.next(),this.parseFunction(e,J|(r?0:Q),!1,t)},X.parseIfStatement=function(e){return this.next(),e.test=this.parseParenExpression(),e.consequent=this.parseStatement("if"),e.alternate=this.eat(b._else)?this.parseStatement("if"):null,this.finishNode(e,"IfStatement")},X.parseReturnStatement=function(e){return this.inFunction||this.options.allowReturnOutsideFunction||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(b.semi)||this.insertSemicolon()?e.argument=null:(e.argument=this.parseExpression(),this.semicolon()),this.finishNode(e,"ReturnStatement")},X.parseSwitchStatement=function(e){var t;this.next(),e.discriminant=this.parseParenExpression(),e.cases=[],this.expect(b.braceL),this.labels.push(Y),this.enterScope(0);for(var r=!1;this.type!==b.braceR;)if(this.type===b._case||this.type===b._default){var n=this.type===b._case;t&&this.finishNode(t,"SwitchCase"),e.cases.push(t=this.startNode()),t.consequent=[],this.next(),n?t.test=this.parseExpression():(r&&this.raiseRecoverable(this.lastTokStart,"Multiple default clauses"),r=!0,t.test=null),this.expect(b.colon)}else t||this.unexpected(),t.consequent.push(this.parseStatement(null));return this.exitScope(),t&&this.finishNode(t,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(e,"SwitchStatement")},X.parseThrowStatement=function(e){return this.next(),T.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),e.argument=this.parseExpression(),this.semicolon(),this.finishNode(e,"ThrowStatement")};var Z=[];X.parseCatchClauseParam=function(){var e=this.parseBindingAtom(),t="Identifier"===e.type;return this.enterScope(t?32:0),this.checkLValPattern(e,t?4:2),this.expect(b.parenR),e},X.parseTryStatement=function(e){if(this.next(),e.block=this.parseBlock(),e.handler=null,this.type===b._catch){var t=this.startNode();this.next(),this.eat(b.parenL)?t.param=this.parseCatchClauseParam():(this.options.ecmaVersion<10&&this.unexpected(),t.param=null,this.enterScope(0)),t.body=this.parseBlock(!1),this.exitScope(),e.handler=this.finishNode(t,"CatchClause")}return e.finalizer=this.eat(b._finally)?this.parseBlock():null,e.handler||e.finalizer||this.raise(e.start,"Missing catch or finally clause"),this.finishNode(e,"TryStatement")},X.parseVarStatement=function(e,t,r){return this.next(),this.parseVar(e,!1,t,r),this.semicolon(),this.finishNode(e,"VariableDeclaration")},X.parseWhileStatement=function(e){return this.next(),e.test=this.parseParenExpression(),this.labels.push(q),e.body=this.parseStatement("while"),this.labels.pop(),this.finishNode(e,"WhileStatement")},X.parseWithStatement=function(e){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),e.object=this.parseParenExpression(),e.body=this.parseStatement("with"),this.finishNode(e,"WithStatement")},X.parseEmptyStatement=function(e){return this.next(),this.finishNode(e,"EmptyStatement")},X.parseLabeledStatement=function(e,t,r,n){for(var s=0,i=this.labels;s=0;o--){var u=this.labels[o];if(u.statementStart!==e.start)break;u.statementStart=this.start,u.kind=a}return this.labels.push({name:t,kind:a,statementStart:this.start}),e.body=this.parseStatement(n?-1===n.indexOf("label")?n+"label":n:"label"),this.labels.pop(),e.label=r,this.finishNode(e,"LabeledStatement")},X.parseExpressionStatement=function(e,t){return e.expression=t,this.semicolon(),this.finishNode(e,"ExpressionStatement")},X.parseBlock=function(e,t,r){for(void 0===e&&(e=!0),void 0===t&&(t=this.startNode()),t.body=[],this.expect(b.braceL),e&&this.enterScope(0);this.type!==b.braceR;){var n=this.parseStatement(null);t.body.push(n)}return r&&(this.strict=!1),this.next(),e&&this.exitScope(),this.finishNode(t,"BlockStatement")},X.parseFor=function(e,t){return e.init=t,this.expect(b.semi),e.test=this.type===b.semi?null:this.parseExpression(),this.expect(b.semi),e.update=this.type===b.parenR?null:this.parseExpression(),this.expect(b.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,"ForStatement")},X.parseForIn=function(e,t){var r=this.type===b._in;return this.next(),"VariableDeclaration"===t.type&&null!=t.declarations[0].init&&(!r||this.options.ecmaVersion<8||this.strict||"var"!==t.kind||"Identifier"!==t.declarations[0].id.type)&&this.raise(t.start,(r?"for-in":"for-of")+" loop variable declaration may not have an initializer"),e.left=t,e.right=r?this.parseExpression():this.parseMaybeAssign(),this.expect(b.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,r?"ForInStatement":"ForOfStatement")},X.parseVar=function(e,t,r,n){for(e.declarations=[],e.kind=r;;){var s=this.startNode();if(this.parseVarId(s,r),this.eat(b.eq)?s.init=this.parseMaybeAssign(t):n||"const"!==r||this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of")?n||"Identifier"===s.id.type||t&&(this.type===b._in||this.isContextual("of"))?s.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.unexpected(),e.declarations.push(this.finishNode(s,"VariableDeclarator")),!this.eat(b.comma))break}return e},X.parseVarId=function(e,t){e.id=this.parseBindingAtom(),this.checkLValPattern(e.id,"var"===t?1:2,!1)};var J=1,Q=2;function ee(e,t){var r=t.key.name,n=e[r],s="true";return"MethodDefinition"!==t.type||"get"!==t.kind&&"set"!==t.kind||(s=(t.static?"s":"i")+t.kind),"iget"===n&&"iset"===s||"iset"===n&&"iget"===s||"sget"===n&&"sset"===s||"sset"===n&&"sget"===s?(e[r]="true",!1):!!n||(e[r]=s,!1)}function te(e,t){var r=e.computed,n=e.key;return!r&&("Identifier"===n.type&&n.name===t||"Literal"===n.type&&n.value===t)}X.parseFunction=function(e,t,r,n,s){this.initFunction(e),(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!n)&&(this.type===b.star&&t&Q&&this.unexpected(),e.generator=this.eat(b.star)),this.options.ecmaVersion>=8&&(e.async=!!n),t&J&&(e.id=4&t&&this.type!==b.name?null:this.parseIdent(),!e.id||t&Q||this.checkLValSimple(e.id,this.strict||e.generator||e.async?this.treatFunctionsAsVar?1:2:3));var i=this.yieldPos,a=this.awaitPos,o=this.awaitIdentPos;return this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(U(e.async,e.generator)),t&J||(e.id=this.type===b.name?this.parseIdent():null),this.parseFunctionParams(e),this.parseFunctionBody(e,r,!1,s),this.yieldPos=i,this.awaitPos=a,this.awaitIdentPos=o,this.finishNode(e,t&J?"FunctionDeclaration":"FunctionExpression")},X.parseFunctionParams=function(e){this.expect(b.parenL),e.params=this.parseBindingList(b.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams()},X.parseClass=function(e,t){this.next();var r=this.strict;this.strict=!0,this.parseClassId(e,t),this.parseClassSuper(e);var n=this.enterClassBody(),s=this.startNode(),i=!1;for(s.body=[],this.expect(b.braceL);this.type!==b.braceR;){var a=this.parseClassElement(null!==e.superClass);a&&(s.body.push(a),"MethodDefinition"===a.type&&"constructor"===a.kind?(i&&this.raiseRecoverable(a.start,"Duplicate constructor in the same class"),i=!0):a.key&&"PrivateIdentifier"===a.key.type&&ee(n,a)&&this.raiseRecoverable(a.key.start,"Identifier '#"+a.key.name+"' has already been declared"))}return this.strict=r,this.next(),e.body=this.finishNode(s,"ClassBody"),this.exitClassBody(),this.finishNode(e,t?"ClassDeclaration":"ClassExpression")},X.parseClassElement=function(e){if(this.eat(b.semi))return null;var t=this.options.ecmaVersion,r=this.startNode(),n="",s=!1,i=!1,a="method",o=!1;if(this.eatContextual("static")){if(t>=13&&this.eat(b.braceL))return this.parseClassStaticBlock(r),r;this.isClassElementNameStart()||this.type===b.star?o=!0:n="static"}if(r.static=o,!n&&t>=8&&this.eatContextual("async")&&(!this.isClassElementNameStart()&&this.type!==b.star||this.canInsertSemicolon()?n="async":i=!0),!n&&(t>=9||!i)&&this.eat(b.star)&&(s=!0),!n&&!i&&!s){var u=this.value;(this.eatContextual("get")||this.eatContextual("set"))&&(this.isClassElementNameStart()?a=u:n=u)}if(n?(r.computed=!1,r.key=this.startNodeAt(this.lastTokStart,this.lastTokStartLoc),r.key.name=n,this.finishNode(r.key,"Identifier")):this.parseClassElementName(r),t<13||this.type===b.parenL||"method"!==a||s||i){var h=!r.static&&te(r,"constructor"),l=h&&e;h&&"method"!==a&&this.raise(r.key.start,"Constructor can't have get/set modifier"),r.kind=h?"constructor":a,this.parseClassMethod(r,s,i,l)}else this.parseClassField(r);return r},X.isClassElementNameStart=function(){return this.type===b.name||this.type===b.privateId||this.type===b.num||this.type===b.string||this.type===b.bracketL||this.type.keyword},X.parseClassElementName=function(e){this.type===b.privateId?("constructor"===this.value&&this.raise(this.start,"Classes can't have an element named '#constructor'"),e.computed=!1,e.key=this.parsePrivateIdent()):this.parsePropertyName(e)},X.parseClassMethod=function(e,t,r,n){var s=e.key;"constructor"===e.kind?(t&&this.raise(s.start,"Constructor can't be a generator"),r&&this.raise(s.start,"Constructor can't be an async method")):e.static&&te(e,"prototype")&&this.raise(s.start,"Classes may not have a static property named prototype");var i=e.value=this.parseMethod(t,r,n);return"get"===e.kind&&0!==i.params.length&&this.raiseRecoverable(i.start,"getter should have no params"),"set"===e.kind&&1!==i.params.length&&this.raiseRecoverable(i.start,"setter should have exactly one param"),"set"===e.kind&&"RestElement"===i.params[0].type&&this.raiseRecoverable(i.params[0].start,"Setter cannot use rest params"),this.finishNode(e,"MethodDefinition")},X.parseClassField=function(e){if(te(e,"constructor")?this.raise(e.key.start,"Classes can't have a field named 'constructor'"):e.static&&te(e,"prototype")&&this.raise(e.key.start,"Classes can't have a static field named 'prototype'"),this.eat(b.eq)){var t=this.currentThisScope(),r=t.inClassFieldInit;t.inClassFieldInit=!0,e.value=this.parseMaybeAssign(),t.inClassFieldInit=r}else e.value=null;return this.semicolon(),this.finishNode(e,"PropertyDefinition")},X.parseClassStaticBlock=function(e){e.body=[];var t=this.labels;for(this.labels=[],this.enterScope(320);this.type!==b.braceR;){var r=this.parseStatement(null);e.body.push(r)}return this.next(),this.exitScope(),this.labels=t,this.finishNode(e,"StaticBlock")},X.parseClassId=function(e,t){this.type===b.name?(e.id=this.parseIdent(),t&&this.checkLValSimple(e.id,2,!1)):(!0===t&&this.unexpected(),e.id=null)},X.parseClassSuper=function(e){e.superClass=this.eat(b._extends)?this.parseExprSubscripts(null,!1):null},X.enterClassBody=function(){var e={declared:Object.create(null),used:[]};return this.privateNameStack.push(e),e.declared},X.exitClassBody=function(){var e=this.privateNameStack.pop(),t=e.declared,r=e.used;if(this.options.checkPrivateFields)for(var n=this.privateNameStack.length,s=0===n?null:this.privateNameStack[n-1],i=0;i=11&&(this.eatContextual("as")?(e.exported=this.parseModuleExportName(),this.checkExport(t,e.exported,this.lastTokStart)):e.exported=null),this.expectContextual("from"),this.type!==b.string&&this.unexpected(),e.source=this.parseExprAtom(),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause()),this.semicolon(),this.finishNode(e,"ExportAllDeclaration")},X.parseExport=function(e,t){if(this.next(),this.eat(b.star))return this.parseExportAllDeclaration(e,t);if(this.eat(b._default))return this.checkExport(t,"default",this.lastTokStart),e.declaration=this.parseExportDefaultDeclaration(),this.finishNode(e,"ExportDefaultDeclaration");if(this.shouldParseExportStatement())e.declaration=this.parseExportDeclaration(e),"VariableDeclaration"===e.declaration.type?this.checkVariableExport(t,e.declaration.declarations):this.checkExport(t,e.declaration.id,e.declaration.id.start),e.specifiers=[],e.source=null;else{if(e.declaration=null,e.specifiers=this.parseExportSpecifiers(t),this.eatContextual("from"))this.type!==b.string&&this.unexpected(),e.source=this.parseExprAtom(),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause());else{for(var r=0,n=e.specifiers;r=16&&(e.attributes=this.parseWithClause()),this.semicolon(),this.finishNode(e,"ImportDeclaration")},X.parseImportSpecifier=function(){var e=this.startNode();return e.imported=this.parseModuleExportName(),this.eatContextual("as")?e.local=this.parseIdent():(this.checkUnreserved(e.imported),e.local=e.imported),this.checkLValSimple(e.local,2),this.finishNode(e,"ImportSpecifier")},X.parseImportDefaultSpecifier=function(){var e=this.startNode();return e.local=this.parseIdent(),this.checkLValSimple(e.local,2),this.finishNode(e,"ImportDefaultSpecifier")},X.parseImportNamespaceSpecifier=function(){var e=this.startNode();return this.next(),this.expectContextual("as"),e.local=this.parseIdent(),this.checkLValSimple(e.local,2),this.finishNode(e,"ImportNamespaceSpecifier")},X.parseImportSpecifiers=function(){var e=[],t=!0;if(this.type===b.name&&(e.push(this.parseImportDefaultSpecifier()),!this.eat(b.comma)))return e;if(this.type===b.star)return e.push(this.parseImportNamespaceSpecifier()),e;for(this.expect(b.braceL);!this.eat(b.braceR);){if(t)t=!1;else if(this.expect(b.comma),this.afterTrailingComma(b.braceR))break;e.push(this.parseImportSpecifier())}return e},X.parseWithClause=function(){var e=[];if(!this.eat(b._with))return e;this.expect(b.braceL);for(var t={},r=!0;!this.eat(b.braceR);){if(r)r=!1;else if(this.expect(b.comma),this.afterTrailingComma(b.braceR))break;var n=this.parseImportAttribute(),s="Identifier"===n.key.type?n.key.name:n.key.value;D(t,s)&&this.raiseRecoverable(n.key.start,"Duplicate attribute key '"+s+"'"),t[s]=!0,e.push(n)}return e},X.parseImportAttribute=function(){var e=this.startNode();return e.key=this.type===b.string?this.parseExprAtom():this.parseIdent("never"!==this.options.allowReserved),this.expect(b.colon),this.type!==b.string&&this.unexpected(),e.value=this.parseExprAtom(),this.finishNode(e,"ImportAttribute")},X.parseModuleExportName=function(){if(this.options.ecmaVersion>=13&&this.type===b.string){var e=this.parseLiteral(this.value);return R.test(e.value)&&this.raise(e.start,"An export name cannot include a lone surrogate."),e}return this.parseIdent(!0)},X.adaptDirectivePrologue=function(e){for(var t=0;t=5&&"ExpressionStatement"===e.type&&"Literal"===e.expression.type&&"string"==typeof e.expression.value&&('"'===this.input[e.start]||"'"===this.input[e.start])};var re=K.prototype;re.toAssignable=function(e,t,r){if(this.options.ecmaVersion>=6&&e)switch(e.type){case"Identifier":this.inAsync&&"await"===e.name&&this.raise(e.start,"Cannot use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":case"RestElement":break;case"ObjectExpression":e.type="ObjectPattern",r&&this.checkPatternErrors(r,!0);for(var n=0,s=e.properties;n=8&&!o&&"async"===u.name&&!this.canInsertSemicolon()&&this.eat(b._function))return this.overrideContext(se.f_expr),this.parseFunction(this.startNodeAt(i,a),0,!1,!0,t);if(s&&!this.canInsertSemicolon()){if(this.eat(b.arrow))return this.parseArrowExpression(this.startNodeAt(i,a),[u],!1,t);if(this.options.ecmaVersion>=8&&"async"===u.name&&this.type===b.name&&!o&&(!this.potentialArrowInForAwait||"of"!==this.value||this.containsEsc))return u=this.parseIdent(!1),!this.canInsertSemicolon()&&this.eat(b.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAt(i,a),[u],!0,t)}return u;case b.regexp:var h=this.value;return(n=this.parseLiteral(h.value)).regex={pattern:h.pattern,flags:h.flags},n;case b.num:case b.string:return this.parseLiteral(this.value);case b._null:case b._true:case b._false:return(n=this.startNode()).value=this.type===b._null?null:this.type===b._true,n.raw=this.type.keyword,this.next(),this.finishNode(n,"Literal");case b.parenL:var l=this.start,c=this.parseParenAndDistinguishExpression(s,t);return e&&(e.parenthesizedAssign<0&&!this.isSimpleAssignTarget(c)&&(e.parenthesizedAssign=l),e.parenthesizedBind<0&&(e.parenthesizedBind=l)),c;case b.bracketL:return n=this.startNode(),this.next(),n.elements=this.parseExprList(b.bracketR,!0,!0,e),this.finishNode(n,"ArrayExpression");case b.braceL:return this.overrideContext(se.b_expr),this.parseObj(!1,e);case b._function:return n=this.startNode(),this.next(),this.parseFunction(n,0);case b._class:return this.parseClass(this.startNode(),!1);case b._new:return this.parseNew();case b.backQuote:return this.parseTemplate();case b._import:return this.options.ecmaVersion>=11?this.parseExprImport(r):this.unexpected();default:return this.parseExprAtomDefault()}},ae.parseExprAtomDefault=function(){this.unexpected()},ae.parseExprImport=function(e){var t=this.startNode();if(this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword import"),this.next(),this.type===b.parenL&&!e)return this.parseDynamicImport(t);if(this.type===b.dot){var r=this.startNodeAt(t.start,t.loc&&t.loc.start);return r.name="import",t.meta=this.finishNode(r,"Identifier"),this.parseImportMeta(t)}this.unexpected()},ae.parseDynamicImport=function(e){if(this.next(),e.source=this.parseMaybeAssign(),this.options.ecmaVersion>=16)this.eat(b.parenR)?e.options=null:(this.expect(b.comma),this.afterTrailingComma(b.parenR)?e.options=null:(e.options=this.parseMaybeAssign(),this.eat(b.parenR)||(this.expect(b.comma),this.afterTrailingComma(b.parenR)||this.unexpected())));else if(!this.eat(b.parenR)){var t=this.start;this.eat(b.comma)&&this.eat(b.parenR)?this.raiseRecoverable(t,"Trailing comma is not allowed in import()"):this.unexpected(t)}return this.finishNode(e,"ImportExpression")},ae.parseImportMeta=function(e){this.next();var t=this.containsEsc;return e.property=this.parseIdent(!0),"meta"!==e.property.name&&this.raiseRecoverable(e.property.start,"The only valid meta property for import is 'import.meta'"),t&&this.raiseRecoverable(e.start,"'import.meta' must not contain escaped characters"),"module"===this.options.sourceType||this.options.allowImportExportEverywhere||this.raiseRecoverable(e.start,"Cannot use 'import.meta' outside a module"),this.finishNode(e,"MetaProperty")},ae.parseLiteral=function(e){var t=this.startNode();return t.value=e,t.raw=this.input.slice(this.start,this.end),110===t.raw.charCodeAt(t.raw.length-1)&&(t.bigint=t.raw.slice(0,-1).replace(/_/g,"")),this.next(),this.finishNode(t,"Literal")},ae.parseParenExpression=function(){this.expect(b.parenL);var e=this.parseExpression();return this.expect(b.parenR),e},ae.shouldParseArrow=function(e){return!this.canInsertSemicolon()},ae.parseParenAndDistinguishExpression=function(e,t){var r,n=this.start,s=this.startLoc,i=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var a,o=this.start,u=this.startLoc,h=[],l=!0,c=!1,p=new H,d=this.yieldPos,f=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==b.parenR;){if(l?l=!1:this.expect(b.comma),i&&this.afterTrailingComma(b.parenR,!0)){c=!0;break}if(this.type===b.ellipsis){a=this.start,h.push(this.parseParenItem(this.parseRestBinding())),this.type===b.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element");break}h.push(this.parseMaybeAssign(!1,p,this.parseParenItem))}var m=this.lastTokEnd,g=this.lastTokEndLoc;if(this.expect(b.parenR),e&&this.shouldParseArrow(h)&&this.eat(b.arrow))return this.checkPatternErrors(p,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=d,this.awaitPos=f,this.parseParenArrowList(n,s,h,t);h.length&&!c||this.unexpected(this.lastTokStart),a&&this.unexpected(a),this.checkExpressionErrors(p,!0),this.yieldPos=d||this.yieldPos,this.awaitPos=f||this.awaitPos,h.length>1?((r=this.startNodeAt(o,u)).expressions=h,this.finishNodeAt(r,"SequenceExpression",m,g)):r=h[0]}else r=this.parseParenExpression();if(this.options.preserveParens){var x=this.startNodeAt(n,s);return x.expression=r,this.finishNode(x,"ParenthesizedExpression")}return r},ae.parseParenItem=function(e){return e},ae.parseParenArrowList=function(e,t,r,n){return this.parseArrowExpression(this.startNodeAt(e,t),r,!1,n)};var he=[];ae.parseNew=function(){this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword new");var e=this.startNode();if(this.next(),this.options.ecmaVersion>=6&&this.type===b.dot){var t=this.startNodeAt(e.start,e.loc&&e.loc.start);t.name="new",e.meta=this.finishNode(t,"Identifier"),this.next();var r=this.containsEsc;return e.property=this.parseIdent(!0),"target"!==e.property.name&&this.raiseRecoverable(e.property.start,"The only valid meta property for new is 'new.target'"),r&&this.raiseRecoverable(e.start,"'new.target' must not contain escaped characters"),this.allowNewDotTarget||this.raiseRecoverable(e.start,"'new.target' can only be used in functions and class static block"),this.finishNode(e,"MetaProperty")}var n=this.start,s=this.startLoc;return e.callee=this.parseSubscripts(this.parseExprAtom(null,!1,!0),n,s,!0,!1),this.eat(b.parenL)?e.arguments=this.parseExprList(b.parenR,this.options.ecmaVersion>=8,!1):e.arguments=he,this.finishNode(e,"NewExpression")},ae.parseTemplateElement=function(e){var t=e.isTagged,r=this.startNode();return this.type===b.invalidTemplate?(t||this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"),r.value={raw:this.value.replace(/\r\n?/g,"\n"),cooked:null}):r.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value},this.next(),r.tail=this.type===b.backQuote,this.finishNode(r,"TemplateElement")},ae.parseTemplate=function(e){void 0===e&&(e={});var t=e.isTagged;void 0===t&&(t=!1);var r=this.startNode();this.next(),r.expressions=[];var n=this.parseTemplateElement({isTagged:t});for(r.quasis=[n];!n.tail;)this.type===b.eof&&this.raise(this.pos,"Unterminated template literal"),this.expect(b.dollarBraceL),r.expressions.push(this.parseExpression()),this.expect(b.braceR),r.quasis.push(n=this.parseTemplateElement({isTagged:t}));return this.next(),this.finishNode(r,"TemplateLiteral")},ae.isAsyncProp=function(e){return!e.computed&&"Identifier"===e.key.type&&"async"===e.key.name&&(this.type===b.name||this.type===b.num||this.type===b.string||this.type===b.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===b.star)&&!T.test(this.input.slice(this.lastTokEnd,this.start))},ae.parseObj=function(e,t){var r=this.startNode(),n=!0,s={};for(r.properties=[],this.next();!this.eat(b.braceR);){if(n)n=!1;else if(this.expect(b.comma),this.options.ecmaVersion>=5&&this.afterTrailingComma(b.braceR))break;var i=this.parseProperty(e,t);e||this.checkPropClash(i,s,t),r.properties.push(i)}return this.finishNode(r,e?"ObjectPattern":"ObjectExpression")},ae.parseProperty=function(e,t){var r,n,s,i,a=this.startNode();if(this.options.ecmaVersion>=9&&this.eat(b.ellipsis))return e?(a.argument=this.parseIdent(!1),this.type===b.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element"),this.finishNode(a,"RestElement")):(a.argument=this.parseMaybeAssign(!1,t),this.type===b.comma&&t&&t.trailingComma<0&&(t.trailingComma=this.start),this.finishNode(a,"SpreadElement"));this.options.ecmaVersion>=6&&(a.method=!1,a.shorthand=!1,(e||t)&&(s=this.start,i=this.startLoc),e||(r=this.eat(b.star)));var o=this.containsEsc;return this.parsePropertyName(a),!e&&!o&&this.options.ecmaVersion>=8&&!r&&this.isAsyncProp(a)?(n=!0,r=this.options.ecmaVersion>=9&&this.eat(b.star),this.parsePropertyName(a)):n=!1,this.parsePropertyValue(a,e,r,n,s,i,t,o),this.finishNode(a,"Property")},ae.parseGetterSetter=function(e){e.kind=e.key.name,this.parsePropertyName(e),e.value=this.parseMethod(!1);var t="get"===e.kind?0:1;if(e.value.params.length!==t){var r=e.value.start;"get"===e.kind?this.raiseRecoverable(r,"getter should have no params"):this.raiseRecoverable(r,"setter should have exactly one param")}else"set"===e.kind&&"RestElement"===e.value.params[0].type&&this.raiseRecoverable(e.value.params[0].start,"Setter cannot use rest params")},ae.parsePropertyValue=function(e,t,r,n,s,i,a,o){(r||n)&&this.type===b.colon&&this.unexpected(),this.eat(b.colon)?(e.value=t?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,a),e.kind="init"):this.options.ecmaVersion>=6&&this.type===b.parenL?(t&&this.unexpected(),e.kind="init",e.method=!0,e.value=this.parseMethod(r,n)):t||o||!(this.options.ecmaVersion>=5)||e.computed||"Identifier"!==e.key.type||"get"!==e.key.name&&"set"!==e.key.name||this.type===b.comma||this.type===b.braceR||this.type===b.eq?this.options.ecmaVersion>=6&&!e.computed&&"Identifier"===e.key.type?((r||n)&&this.unexpected(),this.checkUnreserved(e.key),"await"!==e.key.name||this.awaitIdentPos||(this.awaitIdentPos=s),e.kind="init",t?e.value=this.parseMaybeDefault(s,i,this.copyNode(e.key)):this.type===b.eq&&a?(a.shorthandAssign<0&&(a.shorthandAssign=this.start),e.value=this.parseMaybeDefault(s,i,this.copyNode(e.key))):e.value=this.copyNode(e.key),e.shorthand=!0):this.unexpected():((r||n)&&this.unexpected(),this.parseGetterSetter(e))},ae.parsePropertyName=function(e){if(this.options.ecmaVersion>=6){if(this.eat(b.bracketL))return e.computed=!0,e.key=this.parseMaybeAssign(),this.expect(b.bracketR),e.key;e.computed=!1}return e.key=this.type===b.num||this.type===b.string?this.parseExprAtom():this.parseIdent("never"!==this.options.allowReserved)},ae.initFunction=function(e){e.id=null,this.options.ecmaVersion>=6&&(e.generator=e.expression=!1),this.options.ecmaVersion>=8&&(e.async=!1)},ae.parseMethod=function(e,t,r){var n=this.startNode(),s=this.yieldPos,i=this.awaitPos,a=this.awaitIdentPos;return this.initFunction(n),this.options.ecmaVersion>=6&&(n.generator=e),this.options.ecmaVersion>=8&&(n.async=!!t),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(64|U(t,n.generator)|(r?128:0)),this.expect(b.parenL),n.params=this.parseBindingList(b.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(n,!1,!0,!1),this.yieldPos=s,this.awaitPos=i,this.awaitIdentPos=a,this.finishNode(n,"FunctionExpression")},ae.parseArrowExpression=function(e,t,r,n){var s=this.yieldPos,i=this.awaitPos,a=this.awaitIdentPos;return this.enterScope(16|U(r,!1)),this.initFunction(e),this.options.ecmaVersion>=8&&(e.async=!!r),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,e.params=this.toAssignableList(t,!0),this.parseFunctionBody(e,!0,!1,n),this.yieldPos=s,this.awaitPos=i,this.awaitIdentPos=a,this.finishNode(e,"ArrowFunctionExpression")},ae.parseFunctionBody=function(e,t,r,n){var s=t&&this.type!==b.braceL,i=this.strict,a=!1;if(s)e.body=this.parseMaybeAssign(n),e.expression=!0,this.checkParams(e,!1);else{var o=this.options.ecmaVersion>=7&&!this.isSimpleParamList(e.params);i&&!o||(a=this.strictDirective(this.end))&&o&&this.raiseRecoverable(e.start,"Illegal 'use strict' directive in function with non-simple parameter list");var u=this.labels;this.labels=[],a&&(this.strict=!0),this.checkParams(e,!i&&!a&&!t&&!r&&this.isSimpleParamList(e.params)),this.strict&&e.id&&this.checkLValSimple(e.id,5),e.body=this.parseBlock(!1,void 0,a&&!i),e.expression=!1,this.adaptDirectivePrologue(e.body.body),this.labels=u}this.exitScope()},ae.isSimpleParamList=function(e){for(var t=0,r=e;t-1||s.functions.indexOf(e)>-1||s.var.indexOf(e)>-1,s.lexical.push(e),this.inModule&&1&s.flags&&delete this.undefinedExports[e]}else if(4===t)this.currentScope().lexical.push(e);else if(3===t){var i=this.currentScope();n=this.treatFunctionsAsVar?i.lexical.indexOf(e)>-1:i.lexical.indexOf(e)>-1||i.var.indexOf(e)>-1,i.functions.push(e)}else for(var a=this.scopeStack.length-1;a>=0;--a){var o=this.scopeStack[a];if(o.lexical.indexOf(e)>-1&&!(32&o.flags&&o.lexical[0]===e)||!this.treatFunctionsAsVarInScope(o)&&o.functions.indexOf(e)>-1){n=!0;break}if(o.var.push(e),this.inModule&&1&o.flags&&delete this.undefinedExports[e],259&o.flags)break}n&&this.raiseRecoverable(r,"Identifier '"+e+"' has already been declared")},ce.checkLocalExport=function(e){-1===this.scopeStack[0].lexical.indexOf(e.name)&&-1===this.scopeStack[0].var.indexOf(e.name)&&(this.undefinedExports[e.name]=e)},ce.currentScope=function(){return this.scopeStack[this.scopeStack.length-1]},ce.currentVarScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(259&t.flags)return t}},ce.currentThisScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(259&t.flags&&!(16&t.flags))return t}};var de=function(e,t,r){this.type="",this.start=t,this.end=0,e.options.locations&&(this.loc=new V(e,r)),e.options.directSourceFile&&(this.sourceFile=e.options.directSourceFile),e.options.ranges&&(this.range=[t,0])},fe=K.prototype;function me(e,t,r,n){return e.type=t,e.end=r,this.options.locations&&(e.loc.end=n),this.options.ranges&&(e.range[1]=r),e}fe.startNode=function(){return new de(this,this.start,this.startLoc)},fe.startNodeAt=function(e,t){return new de(this,e,t)},fe.finishNode=function(e,t){return me.call(this,e,t,this.lastTokEnd,this.lastTokEndLoc)},fe.finishNodeAt=function(e,t,r,n){return me.call(this,e,t,r,n)},fe.copyNode=function(e){var t=new de(this,e.start,this.startLoc);for(var r in e)t[r]=e[r];return t};var ge="ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS",xe=ge+" Extended_Pictographic",ye=xe+" EBase EComp EMod EPres ExtPict",be={9:ge,10:xe,11:xe,12:ye,13:ye,14:ye},Te={9:"",10:"",11:"",12:"",13:"",14:"Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji"},Se="Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu",ve="Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb",Ae=ve+" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd",_e=Ae+" Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho",we=_e+" Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi",Ee=we+" Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith",Ie={9:ve,10:Ae,11:_e,12:we,13:Ee,14:Ee+" Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sunu Sunuwar Todhri Todr Tulu_Tigalari Tutg Unknown Zzzz"},ke={};function De(e){var t=ke[e]={binary:$(be[e]+" "+Se),binaryOfStrings:$(Te[e]),nonBinary:{General_Category:$(Se),Script:$(Ie[e])}};t.nonBinary.Script_Extensions=t.nonBinary.Script,t.nonBinary.gc=t.nonBinary.General_Category,t.nonBinary.sc=t.nonBinary.Script,t.nonBinary.scx=t.nonBinary.Script_Extensions}for(var Ce=0,Le=[9,10,11,12,13,14];Ce=6?"uy":"")+(e.options.ecmaVersion>=9?"s":"")+(e.options.ecmaVersion>=13?"d":"")+(e.options.ecmaVersion>=15?"v":""),this.unicodeProperties=ke[e.options.ecmaVersion>=14?14:e.options.ecmaVersion],this.source="",this.flags="",this.start=0,this.switchU=!1,this.switchV=!1,this.switchN=!1,this.pos=0,this.lastIntValue=0,this.lastStringValue="",this.lastAssertionIsQuantifiable=!1,this.numCapturingParens=0,this.maxBackReference=0,this.groupNames=Object.create(null),this.backReferenceNames=[],this.branchID=null};function Ne(e){return 105===e||109===e||115===e}function Ve(e){return 36===e||e>=40&&e<=43||46===e||63===e||e>=91&&e<=94||e>=123&&e<=125}function Me(e){return e>=65&&e<=90||e>=97&&e<=122}function Oe(e){return Me(e)||95===e}function Pe(e){return Oe(e)||Ge(e)}function Ge(e){return e>=48&&e<=57}function ze(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function Ue(e){return e>=65&&e<=70?e-65+10:e>=97&&e<=102?e-97+10:e-48}function Ke(e){return e>=48&&e<=55}Re.prototype.reset=function(e,t,r){var n=-1!==r.indexOf("v"),s=-1!==r.indexOf("u");this.start=0|e,this.source=t+"",this.flags=r,n&&this.parser.options.ecmaVersion>=15?(this.switchU=!0,this.switchV=!0,this.switchN=!0):(this.switchU=s&&this.parser.options.ecmaVersion>=6,this.switchV=!1,this.switchN=s&&this.parser.options.ecmaVersion>=9)},Re.prototype.raise=function(e){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+e)},Re.prototype.at=function(e,t){void 0===t&&(t=!1);var r=this.source,n=r.length;if(e>=n)return-1;var s=r.charCodeAt(e);if(!t&&!this.switchU||s<=55295||s>=57344||e+1>=n)return s;var i=r.charCodeAt(e+1);return i>=56320&&i<=57343?(s<<10)+i-56613888:s},Re.prototype.nextIndex=function(e,t){void 0===t&&(t=!1);var r=this.source,n=r.length;if(e>=n)return n;var s,i=r.charCodeAt(e);return!t&&!this.switchU||i<=55295||i>=57344||e+1>=n||(s=r.charCodeAt(e+1))<56320||s>57343?e+1:e+2},Re.prototype.current=function(e){return void 0===e&&(e=!1),this.at(this.pos,e)},Re.prototype.lookahead=function(e){return void 0===e&&(e=!1),this.at(this.nextIndex(this.pos,e),e)},Re.prototype.advance=function(e){void 0===e&&(e=!1),this.pos=this.nextIndex(this.pos,e)},Re.prototype.eat=function(e,t){return void 0===t&&(t=!1),this.current(t)===e&&(this.advance(t),!0)},Re.prototype.eatChars=function(e,t){void 0===t&&(t=!1);for(var r=this.pos,n=0,s=e;n-1&&this.raise(e.start,"Duplicate regular expression flag"),"u"===a&&(n=!0),"v"===a&&(s=!0)}this.options.ecmaVersion>=15&&n&&s&&this.raise(e.start,"Invalid regular expression flag")},$e.validateRegExpPattern=function(e){this.regexp_pattern(e),!e.switchN&&this.options.ecmaVersion>=9&&function(e){for(var t in e)return!0;return!1}(e.groupNames)&&(e.switchN=!0,this.regexp_pattern(e))},$e.regexp_pattern=function(e){e.pos=0,e.lastIntValue=0,e.lastStringValue="",e.lastAssertionIsQuantifiable=!1,e.numCapturingParens=0,e.maxBackReference=0,e.groupNames=Object.create(null),e.backReferenceNames.length=0,e.branchID=null,this.regexp_disjunction(e),e.pos!==e.source.length&&(e.eat(41)&&e.raise("Unmatched ')'"),(e.eat(93)||e.eat(125))&&e.raise("Lone quantifier brackets")),e.maxBackReference>e.numCapturingParens&&e.raise("Invalid escape");for(var t=0,r=e.backReferenceNames;t=16;for(t&&(e.branchID=new Fe(e.branchID,null)),this.regexp_alternative(e);e.eat(124);)t&&(e.branchID=e.branchID.sibling()),this.regexp_alternative(e);t&&(e.branchID=e.branchID.parent),this.regexp_eatQuantifier(e,!0)&&e.raise("Nothing to repeat"),e.eat(123)&&e.raise("Lone quantifier brackets")},$e.regexp_alternative=function(e){for(;e.pos=9&&(r=e.eat(60)),e.eat(61)||e.eat(33))return this.regexp_disjunction(e),e.eat(41)||e.raise("Unterminated group"),e.lastAssertionIsQuantifiable=!r,!0}return e.pos=t,!1},$e.regexp_eatQuantifier=function(e,t){return void 0===t&&(t=!1),!!this.regexp_eatQuantifierPrefix(e,t)&&(e.eat(63),!0)},$e.regexp_eatQuantifierPrefix=function(e,t){return e.eat(42)||e.eat(43)||e.eat(63)||this.regexp_eatBracedQuantifier(e,t)},$e.regexp_eatBracedQuantifier=function(e,t){var r=e.pos;if(e.eat(123)){var n=0,s=-1;if(this.regexp_eatDecimalDigits(e)&&(n=e.lastIntValue,e.eat(44)&&this.regexp_eatDecimalDigits(e)&&(s=e.lastIntValue),e.eat(125)))return-1!==s&&s=16){var r=this.regexp_eatModifiers(e),n=e.eat(45);if(r||n){for(var s=0;s-1&&e.raise("Duplicate regular expression modifiers")}if(n){var a=this.regexp_eatModifiers(e);r||a||58!==e.current()||e.raise("Invalid regular expression modifiers");for(var o=0;o-1||r.indexOf(u)>-1)&&e.raise("Duplicate regular expression modifiers")}}}}if(e.eat(58)){if(this.regexp_disjunction(e),e.eat(41))return!0;e.raise("Unterminated group")}}e.pos=t}return!1},$e.regexp_eatCapturingGroup=function(e){if(e.eat(40)){if(this.options.ecmaVersion>=9?this.regexp_groupSpecifier(e):63===e.current()&&e.raise("Invalid group"),this.regexp_disjunction(e),e.eat(41))return e.numCapturingParens+=1,!0;e.raise("Unterminated group")}return!1},$e.regexp_eatModifiers=function(e){for(var t="",r=0;-1!==(r=e.current())&&Ne(r);)t+=F(r),e.advance();return t},$e.regexp_eatExtendedAtom=function(e){return e.eat(46)||this.regexp_eatReverseSolidusAtomEscape(e)||this.regexp_eatCharacterClass(e)||this.regexp_eatUncapturingGroup(e)||this.regexp_eatCapturingGroup(e)||this.regexp_eatInvalidBracedQuantifier(e)||this.regexp_eatExtendedPatternCharacter(e)},$e.regexp_eatInvalidBracedQuantifier=function(e){return this.regexp_eatBracedQuantifier(e,!0)&&e.raise("Nothing to repeat"),!1},$e.regexp_eatSyntaxCharacter=function(e){var t=e.current();return!!Ve(t)&&(e.lastIntValue=t,e.advance(),!0)},$e.regexp_eatPatternCharacters=function(e){for(var t=e.pos,r=0;-1!==(r=e.current())&&!Ve(r);)e.advance();return e.pos!==t},$e.regexp_eatExtendedPatternCharacter=function(e){var t=e.current();return!(-1===t||36===t||t>=40&&t<=43||46===t||63===t||91===t||94===t||124===t||(e.advance(),0))},$e.regexp_groupSpecifier=function(e){if(e.eat(63)){this.regexp_eatGroupName(e)||e.raise("Invalid group");var t=this.options.ecmaVersion>=16,r=e.groupNames[e.lastStringValue];if(r)if(t)for(var n=0,s=r;n=11,n=e.current(r);return e.advance(r),92===n&&this.regexp_eatRegExpUnicodeEscapeSequence(e,r)&&(n=e.lastIntValue),function(e){return c(e,!0)||36===e||95===e}(n)?(e.lastIntValue=n,!0):(e.pos=t,!1)},$e.regexp_eatRegExpIdentifierPart=function(e){var t=e.pos,r=this.options.ecmaVersion>=11,n=e.current(r);return e.advance(r),92===n&&this.regexp_eatRegExpUnicodeEscapeSequence(e,r)&&(n=e.lastIntValue),function(e){return p(e,!0)||36===e||95===e||8204===e||8205===e}(n)?(e.lastIntValue=n,!0):(e.pos=t,!1)},$e.regexp_eatAtomEscape=function(e){return!!(this.regexp_eatBackReference(e)||this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)||e.switchN&&this.regexp_eatKGroupName(e))||(e.switchU&&(99===e.current()&&e.raise("Invalid unicode escape"),e.raise("Invalid escape")),!1)},$e.regexp_eatBackReference=function(e){var t=e.pos;if(this.regexp_eatDecimalEscape(e)){var r=e.lastIntValue;if(e.switchU)return r>e.maxBackReference&&(e.maxBackReference=r),!0;if(r<=e.numCapturingParens)return!0;e.pos=t}return!1},$e.regexp_eatKGroupName=function(e){if(e.eat(107)){if(this.regexp_eatGroupName(e))return e.backReferenceNames.push(e.lastStringValue),!0;e.raise("Invalid named reference")}return!1},$e.regexp_eatCharacterEscape=function(e){return this.regexp_eatControlEscape(e)||this.regexp_eatCControlLetter(e)||this.regexp_eatZero(e)||this.regexp_eatHexEscapeSequence(e)||this.regexp_eatRegExpUnicodeEscapeSequence(e,!1)||!e.switchU&&this.regexp_eatLegacyOctalEscapeSequence(e)||this.regexp_eatIdentityEscape(e)},$e.regexp_eatCControlLetter=function(e){var t=e.pos;if(e.eat(99)){if(this.regexp_eatControlLetter(e))return!0;e.pos=t}return!1},$e.regexp_eatZero=function(e){return 48===e.current()&&!Ge(e.lookahead())&&(e.lastIntValue=0,e.advance(),!0)},$e.regexp_eatControlEscape=function(e){var t=e.current();return 116===t?(e.lastIntValue=9,e.advance(),!0):110===t?(e.lastIntValue=10,e.advance(),!0):118===t?(e.lastIntValue=11,e.advance(),!0):102===t?(e.lastIntValue=12,e.advance(),!0):114===t&&(e.lastIntValue=13,e.advance(),!0)},$e.regexp_eatControlLetter=function(e){var t=e.current();return!!Me(t)&&(e.lastIntValue=t%32,e.advance(),!0)},$e.regexp_eatRegExpUnicodeEscapeSequence=function(e,t){void 0===t&&(t=!1);var r,n=e.pos,s=t||e.switchU;if(e.eat(117)){if(this.regexp_eatFixedHexDigits(e,4)){var i=e.lastIntValue;if(s&&i>=55296&&i<=56319){var a=e.pos;if(e.eat(92)&&e.eat(117)&&this.regexp_eatFixedHexDigits(e,4)){var o=e.lastIntValue;if(o>=56320&&o<=57343)return e.lastIntValue=1024*(i-55296)+(o-56320)+65536,!0}e.pos=a,e.lastIntValue=i}return!0}if(s&&e.eat(123)&&this.regexp_eatHexDigits(e)&&e.eat(125)&&(r=e.lastIntValue)>=0&&r<=1114111)return!0;s&&e.raise("Invalid unicode escape"),e.pos=n}return!1},$e.regexp_eatIdentityEscape=function(e){if(e.switchU)return!!this.regexp_eatSyntaxCharacter(e)||!!e.eat(47)&&(e.lastIntValue=47,!0);var t=e.current();return!(99===t||e.switchN&&107===t||(e.lastIntValue=t,e.advance(),0))},$e.regexp_eatDecimalEscape=function(e){e.lastIntValue=0;var t=e.current();if(t>=49&&t<=57){do{e.lastIntValue=10*e.lastIntValue+(t-48),e.advance()}while((t=e.current())>=48&&t<=57);return!0}return!1},$e.regexp_eatCharacterClassEscape=function(e){var t=e.current();if(function(e){return 100===e||68===e||115===e||83===e||119===e||87===e}(t))return e.lastIntValue=-1,e.advance(),1;var r=!1;if(e.switchU&&this.options.ecmaVersion>=9&&((r=80===t)||112===t)){var n;if(e.lastIntValue=-1,e.advance(),e.eat(123)&&(n=this.regexp_eatUnicodePropertyValueExpression(e))&&e.eat(125))return r&&2===n&&e.raise("Invalid property name"),n;e.raise("Invalid property name")}return 0},$e.regexp_eatUnicodePropertyValueExpression=function(e){var t=e.pos;if(this.regexp_eatUnicodePropertyName(e)&&e.eat(61)){var r=e.lastStringValue;if(this.regexp_eatUnicodePropertyValue(e)){var n=e.lastStringValue;return this.regexp_validateUnicodePropertyNameAndValue(e,r,n),1}}if(e.pos=t,this.regexp_eatLoneUnicodePropertyNameOrValue(e)){var s=e.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(e,s)}return 0},$e.regexp_validateUnicodePropertyNameAndValue=function(e,t,r){D(e.unicodeProperties.nonBinary,t)||e.raise("Invalid property name"),e.unicodeProperties.nonBinary[t].test(r)||e.raise("Invalid property value")},$e.regexp_validateUnicodePropertyNameOrValue=function(e,t){return e.unicodeProperties.binary.test(t)?1:e.switchV&&e.unicodeProperties.binaryOfStrings.test(t)?2:void e.raise("Invalid property name")},$e.regexp_eatUnicodePropertyName=function(e){var t=0;for(e.lastStringValue="";Oe(t=e.current());)e.lastStringValue+=F(t),e.advance();return""!==e.lastStringValue},$e.regexp_eatUnicodePropertyValue=function(e){var t=0;for(e.lastStringValue="";Pe(t=e.current());)e.lastStringValue+=F(t),e.advance();return""!==e.lastStringValue},$e.regexp_eatLoneUnicodePropertyNameOrValue=function(e){return this.regexp_eatUnicodePropertyValue(e)},$e.regexp_eatCharacterClass=function(e){if(e.eat(91)){var t=e.eat(94),r=this.regexp_classContents(e);return e.eat(93)||e.raise("Unterminated character class"),t&&2===r&&e.raise("Negated character class may contain strings"),!0}return!1},$e.regexp_classContents=function(e){return 93===e.current()?1:e.switchV?this.regexp_classSetExpression(e):(this.regexp_nonEmptyClassRanges(e),1)},$e.regexp_nonEmptyClassRanges=function(e){for(;this.regexp_eatClassAtom(e);){var t=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassAtom(e)){var r=e.lastIntValue;!e.switchU||-1!==t&&-1!==r||e.raise("Invalid character class"),-1!==t&&-1!==r&&t>r&&e.raise("Range out of order in character class")}}},$e.regexp_eatClassAtom=function(e){var t=e.pos;if(e.eat(92)){if(this.regexp_eatClassEscape(e))return!0;if(e.switchU){var r=e.current();(99===r||Ke(r))&&e.raise("Invalid class escape"),e.raise("Invalid escape")}e.pos=t}var n=e.current();return 93!==n&&(e.lastIntValue=n,e.advance(),!0)},$e.regexp_eatClassEscape=function(e){var t=e.pos;if(e.eat(98))return e.lastIntValue=8,!0;if(e.switchU&&e.eat(45))return e.lastIntValue=45,!0;if(!e.switchU&&e.eat(99)){if(this.regexp_eatClassControlLetter(e))return!0;e.pos=t}return this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)},$e.regexp_classSetExpression=function(e){var t,r=1;if(this.regexp_eatClassSetRange(e));else if(t=this.regexp_eatClassSetOperand(e)){2===t&&(r=2);for(var n=e.pos;e.eatChars([38,38]);)38!==e.current()&&(t=this.regexp_eatClassSetOperand(e))?2!==t&&(r=1):e.raise("Invalid character in character class");if(n!==e.pos)return r;for(;e.eatChars([45,45]);)this.regexp_eatClassSetOperand(e)||e.raise("Invalid character in character class");if(n!==e.pos)return r}else e.raise("Invalid character in character class");for(;;)if(!this.regexp_eatClassSetRange(e)){if(!(t=this.regexp_eatClassSetOperand(e)))return r;2===t&&(r=2)}},$e.regexp_eatClassSetRange=function(e){var t=e.pos;if(this.regexp_eatClassSetCharacter(e)){var r=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassSetCharacter(e)){var n=e.lastIntValue;return-1!==r&&-1!==n&&r>n&&e.raise("Range out of order in character class"),!0}e.pos=t}return!1},$e.regexp_eatClassSetOperand=function(e){return this.regexp_eatClassSetCharacter(e)?1:this.regexp_eatClassStringDisjunction(e)||this.regexp_eatNestedClass(e)},$e.regexp_eatNestedClass=function(e){var t=e.pos;if(e.eat(91)){var r=e.eat(94),n=this.regexp_classContents(e);if(e.eat(93))return r&&2===n&&e.raise("Negated character class may contain strings"),n;e.pos=t}if(e.eat(92)){var s=this.regexp_eatCharacterClassEscape(e);if(s)return s;e.pos=t}return null},$e.regexp_eatClassStringDisjunction=function(e){var t=e.pos;if(e.eatChars([92,113])){if(e.eat(123)){var r=this.regexp_classStringDisjunctionContents(e);if(e.eat(125))return r}else e.raise("Invalid escape");e.pos=t}return null},$e.regexp_classStringDisjunctionContents=function(e){for(var t=this.regexp_classString(e);e.eat(124);)2===this.regexp_classString(e)&&(t=2);return t},$e.regexp_classString=function(e){for(var t=0;this.regexp_eatClassSetCharacter(e);)t++;return 1===t?1:2},$e.regexp_eatClassSetCharacter=function(e){var t=e.pos;if(e.eat(92))return!(!this.regexp_eatCharacterEscape(e)&&!this.regexp_eatClassSetReservedPunctuator(e)&&(e.eat(98)?(e.lastIntValue=8,0):(e.pos=t,1)));var r=e.current();return!(r<0||r===e.lookahead()&&function(e){return 33===e||e>=35&&e<=38||e>=42&&e<=44||46===e||e>=58&&e<=64||94===e||96===e||126===e}(r)||function(e){return 40===e||41===e||45===e||47===e||e>=91&&e<=93||e>=123&&e<=125}(r)||(e.advance(),e.lastIntValue=r,0))},$e.regexp_eatClassSetReservedPunctuator=function(e){var t=e.current();return!!function(e){return 33===e||35===e||37===e||38===e||44===e||45===e||e>=58&&e<=62||64===e||96===e||126===e}(t)&&(e.lastIntValue=t,e.advance(),!0)},$e.regexp_eatClassControlLetter=function(e){var t=e.current();return!(!Ge(t)&&95!==t||(e.lastIntValue=t%32,e.advance(),0))},$e.regexp_eatHexEscapeSequence=function(e){var t=e.pos;if(e.eat(120)){if(this.regexp_eatFixedHexDigits(e,2))return!0;e.switchU&&e.raise("Invalid escape"),e.pos=t}return!1},$e.regexp_eatDecimalDigits=function(e){var t=e.pos,r=0;for(e.lastIntValue=0;Ge(r=e.current());)e.lastIntValue=10*e.lastIntValue+(r-48),e.advance();return e.pos!==t},$e.regexp_eatHexDigits=function(e){var t=e.pos,r=0;for(e.lastIntValue=0;ze(r=e.current());)e.lastIntValue=16*e.lastIntValue+Ue(r),e.advance();return e.pos!==t},$e.regexp_eatLegacyOctalEscapeSequence=function(e){if(this.regexp_eatOctalDigit(e)){var t=e.lastIntValue;if(this.regexp_eatOctalDigit(e)){var r=e.lastIntValue;t<=3&&this.regexp_eatOctalDigit(e)?e.lastIntValue=64*t+8*r+e.lastIntValue:e.lastIntValue=8*t+r}else e.lastIntValue=t;return!0}return!1},$e.regexp_eatOctalDigit=function(e){var t=e.current();return Ke(t)?(e.lastIntValue=t-48,e.advance(),!0):(e.lastIntValue=0,!1)},$e.regexp_eatFixedHexDigits=function(e,t){var r=e.pos;e.lastIntValue=0;for(var n=0;n=this.input.length?this.finishToken(b.eof):e.override?e.override(this):void this.readToken(this.fullCharCodeAtPos())},We.readToken=function(e){return c(e,this.options.ecmaVersion>=6)||92===e?this.readWord():this.getTokenFromCode(e)},We.fullCharCodeAtPos=function(){var e=this.input.charCodeAt(this.pos);if(e<=55295||e>=56320)return e;var t=this.input.charCodeAt(this.pos+1);return t<=56319||t>=57344?e:(e<<10)+t-56613888},We.skipBlockComment=function(){var e=this.options.onComment&&this.curPosition(),t=this.pos,r=this.input.indexOf("*/",this.pos+=2);if(-1===r&&this.raise(this.pos-2,"Unterminated comment"),this.pos=r+2,this.options.locations)for(var n=void 0,s=t;(n=A(this.input,s,this.pos))>-1;)++this.curLine,s=this.lineStart=n;this.options.onComment&&this.options.onComment(!0,this.input.slice(t+2,r),t,this.pos,e,this.curPosition())},We.skipLineComment=function(e){for(var t=this.pos,r=this.options.onComment&&this.curPosition(),n=this.input.charCodeAt(this.pos+=e);this.pos8&&e<14||e>=5760&&_.test(String.fromCharCode(e))))break e;++this.pos}}},We.finishToken=function(e,t){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var r=this.type;this.type=e,this.value=t,this.updateContext(r)},We.readToken_dot=function(){var e=this.input.charCodeAt(this.pos+1);if(e>=48&&e<=57)return this.readNumber(!0);var t=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===e&&46===t?(this.pos+=3,this.finishToken(b.ellipsis)):(++this.pos,this.finishToken(b.dot))},We.readToken_slash=function(){var e=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===e?this.finishOp(b.assign,2):this.finishOp(b.slash,1)},We.readToken_mult_modulo_exp=function(e){var t=this.input.charCodeAt(this.pos+1),r=1,n=42===e?b.star:b.modulo;return this.options.ecmaVersion>=7&&42===e&&42===t&&(++r,n=b.starstar,t=this.input.charCodeAt(this.pos+2)),61===t?this.finishOp(b.assign,r+1):this.finishOp(n,r)},We.readToken_pipe_amp=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?this.options.ecmaVersion>=12&&61===this.input.charCodeAt(this.pos+2)?this.finishOp(b.assign,3):this.finishOp(124===e?b.logicalOR:b.logicalAND,2):61===t?this.finishOp(b.assign,2):this.finishOp(124===e?b.bitwiseOR:b.bitwiseAND,1)},We.readToken_caret=function(){return 61===this.input.charCodeAt(this.pos+1)?this.finishOp(b.assign,2):this.finishOp(b.bitwiseXOR,1)},We.readToken_plus_min=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?45!==t||this.inModule||62!==this.input.charCodeAt(this.pos+2)||0!==this.lastTokEnd&&!T.test(this.input.slice(this.lastTokEnd,this.pos))?this.finishOp(b.incDec,2):(this.skipLineComment(3),this.skipSpace(),this.nextToken()):61===t?this.finishOp(b.assign,2):this.finishOp(b.plusMin,1)},We.readToken_lt_gt=function(e){var t=this.input.charCodeAt(this.pos+1),r=1;return t===e?(r=62===e&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+r)?this.finishOp(b.assign,r+1):this.finishOp(b.bitShift,r)):33!==t||60!==e||this.inModule||45!==this.input.charCodeAt(this.pos+2)||45!==this.input.charCodeAt(this.pos+3)?(61===t&&(r=2),this.finishOp(b.relational,r)):(this.skipLineComment(4),this.skipSpace(),this.nextToken())},We.readToken_eq_excl=function(e){var t=this.input.charCodeAt(this.pos+1);return 61===t?this.finishOp(b.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===e&&62===t&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(b.arrow)):this.finishOp(61===e?b.eq:b.prefix,1)},We.readToken_question=function(){var e=this.options.ecmaVersion;if(e>=11){var t=this.input.charCodeAt(this.pos+1);if(46===t){var r=this.input.charCodeAt(this.pos+2);if(r<48||r>57)return this.finishOp(b.questionDot,2)}if(63===t)return e>=12&&61===this.input.charCodeAt(this.pos+2)?this.finishOp(b.assign,3):this.finishOp(b.coalesce,2)}return this.finishOp(b.question,1)},We.readToken_numberSign=function(){var e=35;if(this.options.ecmaVersion>=13&&(++this.pos,c(e=this.fullCharCodeAtPos(),!0)||92===e))return this.finishToken(b.privateId,this.readWord1());this.raise(this.pos,"Unexpected character '"+F(e)+"'")},We.getTokenFromCode=function(e){switch(e){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(b.parenL);case 41:return++this.pos,this.finishToken(b.parenR);case 59:return++this.pos,this.finishToken(b.semi);case 44:return++this.pos,this.finishToken(b.comma);case 91:return++this.pos,this.finishToken(b.bracketL);case 93:return++this.pos,this.finishToken(b.bracketR);case 123:return++this.pos,this.finishToken(b.braceL);case 125:return++this.pos,this.finishToken(b.braceR);case 58:return++this.pos,this.finishToken(b.colon);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(b.backQuote);case 48:var t=this.input.charCodeAt(this.pos+1);if(120===t||88===t)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===t||79===t)return this.readRadixNumber(8);if(98===t||66===t)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(e);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(e);case 124:case 38:return this.readToken_pipe_amp(e);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(e);case 60:case 62:return this.readToken_lt_gt(e);case 61:case 33:return this.readToken_eq_excl(e);case 63:return this.readToken_question();case 126:return this.finishOp(b.prefix,1);case 35:return this.readToken_numberSign()}this.raise(this.pos,"Unexpected character '"+F(e)+"'")},We.finishOp=function(e,t){var r=this.input.slice(this.pos,this.pos+t);return this.pos+=t,this.finishToken(e,r)},We.readRegexp=function(){for(var e,t,r=this.pos;;){this.pos>=this.input.length&&this.raise(r,"Unterminated regular expression");var n=this.input.charAt(this.pos);if(T.test(n)&&this.raise(r,"Unterminated regular expression"),e)e=!1;else{if("["===n)t=!0;else if("]"===n&&t)t=!1;else if("/"===n&&!t)break;e="\\"===n}++this.pos}var s=this.input.slice(r,this.pos);++this.pos;var i=this.pos,a=this.readWord1();this.containsEsc&&this.unexpected(i);var o=this.regexpState||(this.regexpState=new Re(this));o.reset(r,s,a),this.validateRegExpFlags(o),this.validateRegExpPattern(o);var u=null;try{u=new RegExp(s,a)}catch(e){}return this.finishToken(b.regexp,{pattern:s,flags:a,value:u})},We.readInt=function(e,t,r){for(var n=this.options.ecmaVersion>=12&&void 0===t,s=r&&48===this.input.charCodeAt(this.pos),i=this.pos,a=0,o=0,u=0,h=null==t?1/0:t;u=97?l-97+10:l>=65?l-65+10:l>=48&&l<=57?l-48:1/0)>=e)break;o=l,a=a*e+c}}return n&&95===o&&this.raiseRecoverable(this.pos-1,"Numeric separator is not allowed at the last of digits"),this.pos===i||null!=t&&this.pos-i!==t?null:a},We.readRadixNumber=function(e){var t=this.pos;this.pos+=2;var r=this.readInt(e);return null==r&&this.raise(this.start+2,"Expected number in radix "+e),this.options.ecmaVersion>=11&&110===this.input.charCodeAt(this.pos)?(r=je(this.input.slice(t,this.pos)),++this.pos):c(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(b.num,r)},We.readNumber=function(e){var t=this.pos;e||null!==this.readInt(10,void 0,!0)||this.raise(t,"Invalid number");var r=this.pos-t>=2&&48===this.input.charCodeAt(t);r&&this.strict&&this.raise(t,"Invalid number");var n=this.input.charCodeAt(this.pos);if(!r&&!e&&this.options.ecmaVersion>=11&&110===n){var s=je(this.input.slice(t,this.pos));return++this.pos,c(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(b.num,s)}r&&/[89]/.test(this.input.slice(t,this.pos))&&(r=!1),46!==n||r||(++this.pos,this.readInt(10),n=this.input.charCodeAt(this.pos)),69!==n&&101!==n||r||(43!==(n=this.input.charCodeAt(++this.pos))&&45!==n||++this.pos,null===this.readInt(10)&&this.raise(t,"Invalid number")),c(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var i,a=(i=this.input.slice(t,this.pos),r?parseInt(i,8):parseFloat(i.replace(/_/g,"")));return this.finishToken(b.num,a)},We.readCodePoint=function(){var e;if(123===this.input.charCodeAt(this.pos)){this.options.ecmaVersion<6&&this.unexpected();var t=++this.pos;e=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,e>1114111&&this.invalidStringToken(t,"Code point out of bounds")}else e=this.readHexChar(4);return e},We.readString=function(e){for(var t="",r=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var n=this.input.charCodeAt(this.pos);if(n===e)break;92===n?(t+=this.input.slice(r,this.pos),t+=this.readEscapedChar(!1),r=this.pos):8232===n||8233===n?(this.options.ecmaVersion<10&&this.raise(this.start,"Unterminated string constant"),++this.pos,this.options.locations&&(this.curLine++,this.lineStart=this.pos)):(v(n)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return t+=this.input.slice(r,this.pos++),this.finishToken(b.string,t)};var He={};We.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(e){if(e!==He)throw e;this.readInvalidTemplateToken()}this.inTemplateElement=!1},We.invalidStringToken=function(e,t){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw He;this.raise(e,t)},We.readTmplToken=function(){for(var e="",t=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var r=this.input.charCodeAt(this.pos);if(96===r||36===r&&123===this.input.charCodeAt(this.pos+1))return this.pos!==this.start||this.type!==b.template&&this.type!==b.invalidTemplate?(e+=this.input.slice(t,this.pos),this.finishToken(b.template,e)):36===r?(this.pos+=2,this.finishToken(b.dollarBraceL)):(++this.pos,this.finishToken(b.backQuote));if(92===r)e+=this.input.slice(t,this.pos),e+=this.readEscapedChar(!0),t=this.pos;else if(v(r)){switch(e+=this.input.slice(t,this.pos),++this.pos,r){case 13:10===this.input.charCodeAt(this.pos)&&++this.pos;case 10:e+="\n";break;default:e+=String.fromCharCode(r)}this.options.locations&&(++this.curLine,this.lineStart=this.pos),t=this.pos}else++this.pos}},We.readInvalidTemplateToken=function(){for(;this.pos=48&&t<=55){var n=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],s=parseInt(n,8);return s>255&&(n=n.slice(0,-1),s=parseInt(n,8)),this.pos+=n.length-1,t=this.input.charCodeAt(this.pos),"0"===n&&56!==t&&57!==t||!this.strict&&!e||this.invalidStringToken(this.pos-1-n.length,e?"Octal literal in template string":"Octal literal in strict mode"),String.fromCharCode(s)}return v(t)?(this.options.locations&&(this.lineStart=this.pos,++this.curLine),""):String.fromCharCode(t)}},We.readHexChar=function(e){var t=this.pos,r=this.readInt(16,e);return null===r&&this.invalidStringToken(t,"Bad character escape sequence"),r},We.readWord1=function(){this.containsEsc=!1;for(var e="",t=!0,r=this.pos,n=this.options.ecmaVersion>=6;this.pos{var r=class{constructor(e,t){this.value=e,Array.isArray(t)?this.size=t:(this.size=new Int32Array(3),t.z?this.size=new Int32Array([t.x,t.y,t.z]):t.y?this.size=new Int32Array([t.x,t.y]):this.size=new Int32Array([t.x]));const[r,n,s]=this.size;if(s){if(this.value.length!==r*n*s)throw new Error(`Input size ${this.value.length} does not match ${r} * ${n} * ${s} = ${n*r*s}`)}else if(n){if(this.value.length!==r*n)throw new Error(`Input size ${this.value.length} does not match ${r} * ${n} = ${n*r}`)}else if(this.value.length!==r)throw new Error(`Input size ${this.value.length} does not match ${r}`)}toArray(){const{utils:e}=i(),[t,r,n]=this.size;return n?e.erectMemoryOptimized3DFloat(this.value.subarray?this.value:new Float32Array(this.value),t,r,n):r?e.erectMemoryOptimized2DFloat(this.value.subarray?this.value:new Float32Array(this.value),t,r):this.value}};t.exports={Input:r,input:function(e,t){return new r(e,t)}}}),s=e((e,t)=>{t.exports={Texture:class{constructor(e){const{texture:t,size:r,dimensions:n,output:s,context:i,type:a="NumberTexture",kernel:o,internalFormat:u,textureFormat:h}=e;if(!s)throw new Error('settings property "output" required.');if(!i)throw new Error('settings property "context" required.');if(!t)throw new Error('settings property "texture" required.');if(!o)throw new Error('settings property "kernel" required.');this.texture=t,t._refs?t._refs++:t._refs=1,this.size=r,this.dimensions=n,this.output=s,this.context=i,this.kernel=o,this.type=a,this._deleted=!1,this.internalFormat=u,this.textureFormat=h}toArray(){throw new Error(`Not implemented on ${this.constructor.name}`)}clone(){throw new Error(`Not implemented on ${this.constructor.name}`)}delete(){throw new Error(`Not implemented on ${this.constructor.name}`)}clear(){throw new Error(`Not implemented on ${this.constructor.name}`)}}}}),i=e((e,t)=>{const i=r(),{Input:a}=n(),{Texture:o}=s(),u=/function ([^(]*)/,h=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,l=/([^\s,]+)/g,c={systemEndianness:()=>m,getSystemEndianness(){const e=new ArrayBuffer(4),t=new Uint32Array(e),r=new Uint8Array(e);if(t[0]=3735928559,239===r[0])return"LE";if(222===r[0])return"BE";throw new Error("unknown endianness")},isFunction:e=>"function"==typeof e,isFunctionString:e=>"string"==typeof e&&"function"===e.slice(0,8).toLowerCase(),getFunctionNameFromString(e){const t=u.exec(e);return t&&0!==t.length?t[1].trim():null},getFunctionBodyFromString:e=>e.substring(e.indexOf("{")+1,e.lastIndexOf("}")),getArgumentNamesFromString(e){const t=e.replace(h,"");let r=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(l);return null===r&&(r=[]),r},clone(e){if(null===e||"object"!=typeof e||e.hasOwnProperty("isActiveClone"))return e;const t=e.constructor();for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(e.isActiveClone=null,t[r]=c.clone(e[r]),delete e.isActiveClone);return t},isArray:e=>!isNaN(e.length),typeFitsValue(e,t){if("string"!=typeof e||null==t)return!0;if(t.type)return!0;switch(e){case"Input":return t instanceof a;case"Boolean":return"boolean"==typeof t;case"Number":case"Integer":case"Float":return"number"==typeof t}return-1!==e.indexOf("Texture")?Boolean(t.type):0!==e.indexOf("Array")||c.isArray(t)},getVariableType(e,t){if(c.isArray(e))return e.length>0&&"IMG"===e[0].nodeName?"HTMLImageArray":"Array";switch(e.constructor){case Boolean:return"Boolean";case Number:return t&&Number.isInteger(e)?"Integer":"Float";case o:return e.type;case a:return"Input"}if("nodeName"in e)switch(e.nodeName){case"IMG":case"CANVAS":return"HTMLImage";case"VIDEO":return"HTMLVideo"}else{if(e.hasOwnProperty("type"))return e.type;if("undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return"OffscreenCanvas";if("undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap)return"ImageBitmap";if("undefined"!=typeof ImageData&&e instanceof ImageData)return"ImageData"}return"Unknown"},getKernelTextureSize(e,t){let[r,n,s]=t,i=(r||1)*(n||1)*(s||1);return e.optimizeFloatMemory&&"single"===e.precision&&(r=i=Math.ceil(i/4)),n>1&&r*n===i?new Int32Array([r,n]):c.closestSquareDimensions(i)},closestSquareDimensions(e){const t=Math.sqrt(e);let r=Math.ceil(t),n=Math.floor(t);for(;r*nMath.floor((e+t-1)/t)*t,getDimensions(e,t){let r;if(c.isArray(e)){const t=[];let n=e;for(;c.isArray(n);)t.push(n.length),n=n[0];r=t.reverse()}else if(e instanceof o)r=e.output;else{if(!(e instanceof a))throw new Error(`Unknown dimensions of ${e}`);r=e.size}if(t)for(r=Array.from(r);r.length<3;)r.push(1);return new Int32Array(r)},flatten2dArrayTo(e,t){let r=0;for(let n=0;ne.length>0?e.join(";\n")+";\n":"\n",warnDeprecated(e,t,r){r?console.warn(`You are using a deprecated ${e} "${t}". It has been replaced with "${r}". Fixing, but please upgrade as it will soon be removed.`):console.warn(`You are using a deprecated ${e} "${t}". It has been removed. Fixing, but please upgrade as it will soon be removed.`)},flipPixels:(e,t,r)=>{const n=r/2|0,s=4*t,i=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee.subarray(0,t),erect2DPackedFloat:(e,t,r)=>{const n=new Array(r);for(let s=0;s{const s=new Array(n);for(let i=0;ie.subarray(0,t),erectMemoryOptimized2DFloat:(e,t,r)=>{const n=new Array(r);for(let s=0;s{const s=new Array(n);for(let i=0;i{const r=new Float32Array(t);let n=0;for(let s=0;s{const n=new Array(r);let s=0;for(let i=0;i{const s=new Array(n);let i=0;for(let a=0;a{const r=new Array(t),n=4*t;let s=0;for(let t=0;t{const n=new Array(r),s=4*t;for(let i=0;i{const s=4*t,i=new Array(n);for(let a=0;a{const r=new Array(t),n=4*t;let s=0;for(let t=0;t{const n=4*t,s=new Array(r);for(let i=0;i{const s=4*t,i=new Array(n);for(let a=0;a{const r=new Array(e),n=4*t;let s=0;for(let t=0;t{const n=4*t,s=new Array(r);for(let i=0;i{const s=4*t,i=new Array(n);for(let a=0;a{const{findDependency:r,thisLookup:n,doNotDefine:s}=t;let a=t.flattened;a||(a=t.flattened={});const o=i.parse(e,{ecmaVersion:2020}),u=[];let h=0;const l=function e(t){if(Array.isArray(t)){const r=[];for(let n=0;nnull!==e);return s.length<1?"":`${t.kind} ${s.join(",")}`;case"VariableDeclarator":return t.init?t.init.object&&"ThisExpression"===t.init.object.type?n(t.init.property.name,!0)?`${t.id.name} = ${e(t.init)}`:null:`${t.id.name} = ${e(t.init)}`:t.id.name;case"CallExpression":if("subarray"===t.callee.property.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("gl"===t.callee.object.name||"context"===t.callee.object.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("ThisExpression"===t.callee.object.type)return u.push(r("this",t.callee.property.name)),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;if(t.callee.object.name){const n=r(t.callee.object.name,t.callee.property.name);return null===n?`${t.callee.object.name}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`:(u.push(n),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`)}if("MemberExpression"===t.callee.object.type)return`${e(t.callee.object)}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;throw new Error("unknown ast.callee");case"ReturnStatement":return`return ${e(t.argument)}`;case"BinaryExpression":return`(${e(t.left)}${t.operator}${e(t.right)})`;case"UnaryExpression":return t.prefix?`${t.operator} ${e(t.argument)}`:`${e(t.argument)} ${t.operator}`;case"ExpressionStatement":return`${e(t.expression)}`;case"SequenceExpression":return`(${e(t.expressions)})`;case"ArrowFunctionExpression":return`(${t.params.map(e).join(", ")}) => ${e(t.body)}`;case"Literal":return t.raw;case"Identifier":return t.name;case"MemberExpression":return"ThisExpression"===t.object.type?n(t.property.name):t.computed?`${e(t.object)}[${e(t.property)}]`:e(t.object)+"."+e(t.property);case"ThisExpression":return"this";case"NewExpression":return`new ${e(t.callee)}(${t.arguments.map(t=>e(t)).join(", ")})`;case"ForStatement":return`for (${e(t.init)};${e(t.test)};${e(t.update)}) ${e(t.body)}`;case"AssignmentExpression":return`${e(t.left)}${t.operator}${e(t.right)}`;case"UpdateExpression":return`${e(t.argument)}${t.operator}`;case"IfStatement":{const r=e(t.consequent);if(!t.alternate)return`if (${e(t.test)}) ${r}`;const n="BlockStatement"===t.consequent.type?"":";";return`if (${e(t.test)}) ${r}${n} else ${e(t.alternate)}`}case"ThrowStatement":return`throw ${e(t.argument)}`;case"ObjectPattern":return t.properties.map(e).join(", ");case"ArrayPattern":return t.elements.map(e).join(", ");case"DebuggerStatement":return"debugger;";case"ConditionalExpression":return`${e(t.test)}?${e(t.consequent)}:${e(t.alternate)}`;case"Property":if("init"===t.kind)return e(t.key)}throw new Error(`unhandled ast.type of ${t.type}`)}(o);if(u.length>0){const e=[];for(let r=0;r{if("VariableDeclaration"!==e.type)throw new Error('Ast is not of type "VariableDeclaration"');const t=[];for(let r=0;r{const r=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].r},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),n=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].g},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),s=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].b},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),i=e.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].a},{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),a=[r(t),n(t),s(t),i(t)];return a.rKernel=r,a.gKernel=n,a.bKernel=s,a.aKernel=i,a.gpu=e,a},splitRGBAToCanvases:(e,t,r,n)=>{const s=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(t.r/255,0,0,255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});s(t);const i=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(0,t.g/255,0,255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});i(t);const a=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(0,0,t.b/255,255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});a(t);const o=e.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(255,255,255,t.a/255)},{output:[r,n],graphical:!0,argumentTypes:{v:"Array2D(4)"}});return o(t),[s.canvas,i.canvas,a.canvas,o.canvas]},getMinifySafeName:e=>{try{const{init:t}=i.parse(`const value = ${e.toString()}`,{ecmaVersion:2020}).body[0].declarations[0];return t.body.name||t.body.body[0].argument.name}catch(e){throw new Error("Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }")}},sanitizeName:function(e){return p.test(e)&&(e=e.replace(p,"S_S")),d.test(e)?e=e.replace(d,"U_U"):f.test(e)&&(e=e.replace(f,"u_u")),e}},p=/\$/,d=/__/,f=/_/,m=c.getSystemEndianness();t.exports={utils:c}}),a=e((e,t)=>{const{utils:r}=i(),{Input:s}=n();t.exports={Kernel:class{static get isSupported(){throw new Error(`"isSupported" not implemented on ${this.name}`)}static isContextMatch(e){throw new Error(`"isContextMatch" not implemented on ${this.name}`)}static getFeatures(){throw new Error(`"getFeatures" not implemented on ${this.name}`)}static destroyContext(e){throw new Error(`"destroyContext" called on ${this.name}`)}static nativeFunctionArguments(){throw new Error(`"nativeFunctionArguments" called on ${this.name}`)}static nativeFunctionReturnType(){throw new Error(`"nativeFunctionReturnType" called on ${this.name}`)}static combineKernels(){throw new Error(`"combineKernels" called on ${this.name}`)}constructor(e,t){if("object"!=typeof e){if("string"!=typeof e)throw new Error("source not a string");if(!r.isFunctionString(e))throw new Error("source not a function string")}this.useLegacyEncoder=!1,this.fallbackRequested=!1,this.onRequestFallback=null,this.onRequestSwitchKernel=null,this.argumentNames="string"==typeof e?r.getArgumentNamesFromString(e):null,this.argumentTypes=null,this.argumentSizes=null,this.argumentBitRatios=null,this.kernelArguments=null,this.kernelConstants=null,this.forceUploadKernelConstants=null,this.source=e,this.output=null,this.debug=!1,this.graphical=!1,this.loopMaxIterations=0,this.constants=null,this.constantTypes=null,this.constantBitRatios=null,this.dynamicArguments=!1,this.dynamicOutput=!1,this.canvas=null,this.context=null,this.checkContext=null,this.gpu=null,this.functions=null,this.nativeFunctions=null,this.injectedNative=null,this.subKernels=null,this.validate=!0,this.immutable=!1,this.pipeline=!1,this.asyncMode=!1,this.precision=null,this.tactic=null,this.plugins=null,this.returnType=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.optimizeFloatMemory=null,this.strictIntegers=!1,this.fixIntegerDivisionAccuracy=null,this.randomSeed=null,this.built=!1,this.signature=null,this.switchingKernels=null}mergeSettings(e){for(let t in e)if(e.hasOwnProperty(t)&&this.hasOwnProperty(t)){switch(t){case"output":if(!Array.isArray(e.output)){this.setOutput(e.output);continue}break;case"functions":this.functions=[];for(let t=0;te.name):null,returnType:this.returnType}}}buildSignature(e){const t=this.constructor;this.signature=t.getSignature(this,t.getArgumentTypes(this,e))}static getArgumentTypes(e,t){const n=new Array(t.length);for(let s=0;st.argumentTypes[e])||[]:t.argumentTypes||[],{name:r.getFunctionNameFromString(n)||null,source:n,argumentTypes:s,returnType:t.returnType||null}}onActivate(e){}switchKernels(e){this.switchingKernels?this.switchingKernels.push(e):this.switchingKernels=[e]}resetSwitchingKernels(){const e=this.switchingKernels;return this.switchingKernels=null,e}checkArgumentTypes(e){if(!this.argumentTypes)return;const t=Math.min(e.length,this.argumentTypes.length);for(let n=0;n{t.exports={FunctionBuilder:class e{static fromKernel(t,r,n){const{kernelArguments:s,kernelConstants:i,argumentNames:a,argumentSizes:o,argumentBitRatios:u,constants:h,constantBitRatios:l,debug:c,loopMaxIterations:p,nativeFunctions:d,output:f,optimizeFloatMemory:m,precision:g,plugins:x,source:y,subKernels:b,functions:T,leadingReturnStatement:S,followingReturnStatement:v,dynamicArguments:A,dynamicOutput:_}=t,w=new Array(s.length),E={};for(let e=0;eU.needsArgumentType(e,t),k=(e,t,r)=>{U.assignArgumentType(e,t,r)},D=(e,t,r)=>U.lookupReturnType(e,t,r),C=e=>U.lookupFunctionArgumentTypes(e),L=(e,t)=>U.lookupFunctionArgumentName(e,t),$=(e,t)=>U.lookupFunctionArgumentBitRatio(e,t),F=(e,t,r,n)=>{U.assignArgumentType(e,t,r,n)},R=(e,t,r,n)=>{U.assignArgumentBitRatio(e,t,r,n)},N=(e,t,r)=>{U.trackFunctionCall(e,t,r)},V=(e,t)=>{const n=[];for(let t=0;tnew r(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:f,plugins:x,constants:h,constantTypes:E,constantBitRatios:l,optimizeFloatMemory:m,precision:g,lookupReturnType:D,lookupFunctionArgumentTypes:C,lookupFunctionArgumentName:L,lookupFunctionArgumentBitRatio:$,needsArgumentType:I,assignArgumentType:k,triggerImplyArgumentType:F,triggerImplyArgumentBitRatio:R,onFunctionCall:N,onNestedFunction:V})));let z=null;b&&(z=b.map(e=>{const{name:t,source:n}=e;return new r(n,Object.assign({},M,{name:t,isSubKernel:!0,isRootKernel:!1}))}));const U=new e({kernel:t,rootNode:P,functionNodes:G,nativeFunctions:d,subKernelNodes:z});return U}constructor(e){if(e=e||{},this.kernel=e.kernel,this.rootNode=e.rootNode,this.functionNodes=e.functionNodes||[],this.subKernelNodes=e.subKernelNodes||[],this.nativeFunctions=e.nativeFunctions||[],this.functionMap={},this.nativeFunctionNames=[],this.lookupChain=[],this.functionNodeDependencies={},this.functionCalls={},this.rootNode&&(this.functionMap.kernel=this.rootNode),this.functionNodes)for(let e=0;e-1){const r=t.indexOf(e);if(-1===r)t.push(e);else{const e=t.splice(r,1)[0];t.push(e)}return t}const r=this.functionMap[e];if(r){const n=t.indexOf(e);if(-1===n){t.push(e),r.toString();for(let e=0;e-1){t.push(this.nativeFunctions[s].source);continue}const i=this.functionMap[n];i&&t.push(i.toString())}return t}toJSON(){return this.traceFunctionCalls(this.rootNode.name).reverse().map(e=>{const t=this.nativeFunctions.indexOf(e);if(t>-1)return{name:e,source:this.nativeFunctions[t].source};if(this.functionMap[e])return this.functionMap[e].toJSON();throw new Error(`function ${e} not found`)})}fromJSON(e,t){this.functionMap={};for(let r=0;r0){const s=t.arguments;for(let t=0;t{const{utils:r}=i();function n(e){return e.length>0?e[e.length-1]:null}const s="trackIdentifiers",a="memberExpression",o="inForLoopInit";t.exports={FunctionTracer:class{constructor(e){this.runningContexts=[],this.functionContexts=[],this.contexts=[],this.functionCalls=[],this.declarations=[],this.identifiers=[],this.functions=[],this.returnStatements=[],this.trackedIdentifiers=null,this.states=[],this.newFunctionContext(),this.scan(e)}isState(e){return this.states[this.states.length-1]===e}hasState(e){return this.states.indexOf(e)>-1}pushState(e){this.states.push(e)}popState(e){if(!this.isState(e))throw new Error(`Cannot pop the non-active state "${e}"`);this.states.pop()}get currentFunctionContext(){return n(this.functionContexts)}get currentContext(){return n(this.runningContexts)}newFunctionContext(){const e={"@contextType":"function"};this.contexts.push(e),this.functionContexts.push(e)}newContext(e){const t=Object.assign({"@contextType":"const/let"},this.currentContext);this.contexts.push(t),this.runningContexts.push(t),e();const{currentFunctionContext:r}=this;for(const e in r)r.hasOwnProperty(e)&&!t.hasOwnProperty(e)&&(t[e]=r[e]);return this.runningContexts.pop(),t}useFunctionContext(e){const t=n(this.functionContexts);this.runningContexts.push(t),e(),this.runningContexts.pop()}getIdentifiers(e){const t=this.trackedIdentifiers=[];return this.pushState(s),e(),this.trackedIdentifiers=null,this.popState(s),t}getDeclaration(e){const{currentContext:t,currentFunctionContext:r,runningContexts:n}=this,s=t[e]||r[e]||null;if(!s&&t===r&&n.length>0){const t=n[n.length-2];if(t[e])return t[e]}return s}scan(e){if(e)if(Array.isArray(e))for(let t=0;t{this.scan(e.body)});break;case"BlockStatement":this.newContext(()=>{this.scan(e.body)});break;case"AssignmentExpression":case"LogicalExpression":case"BinaryExpression":this.scan(e.left),this.scan(e.right);break;case"UpdateExpression":if("++"===e.operator){const t=this.getDeclaration(e.argument.name);t&&(t.suggestedType="Integer")}this.scan(e.argument);break;case"UnaryExpression":this.scan(e.argument);break;case"VariableDeclaration":"var"===e.kind?this.useFunctionContext(()=>{e.declarations=r.normalizeDeclarations(e),this.scan(e.declarations)}):(e.declarations=r.normalizeDeclarations(e),this.scan(e.declarations));break;case"VariableDeclarator":{const{currentContext:t}=this,r=this.hasState(o),n={ast:e,context:t,name:e.id.name,origin:"declaration",inForLoopInit:r,inForLoopTest:null,assignable:t===this.currentFunctionContext||!r&&!t.hasOwnProperty(e.id.name),suggestedType:null,valueType:null,dependencies:null,isSafe:null};t[e.id.name]||(t[e.id.name]=n),this.declarations.push(n),this.scan(e.id),this.scan(e.init);break}case"FunctionExpression":case"FunctionDeclaration":0===this.runningContexts.length?this.scan(e.body):this.functions.push(e);break;case"IfStatement":this.scan(e.test),this.scan(e.consequent),e.alternate&&this.scan(e.alternate);break;case"ForStatement":{let t;const r=this.newContext(()=>{this.pushState(o),this.scan(e.init),this.popState(o),t=this.getIdentifiers(()=>{this.scan(e.test)}),this.scan(e.update),this.newContext(()=>{this.scan(e.body)})});if(t)for(const e in r)"@contextType"!==e&&t.indexOf(e)>-1&&(r[e].inForLoopTest=!0);break}case"DoWhileStatement":case"WhileStatement":this.newContext(()=>{this.scan(e.body),this.scan(e.test)});break;case"Identifier":this.isState(s)&&this.trackedIdentifiers.push(e.name),this.identifiers.push({context:this.currentContext,declaration:this.getDeclaration(e.name),ast:e});break;case"ReturnStatement":this.returnStatements.push(e),this.scan(e.argument);break;case"MemberExpression":this.pushState(a),this.scan(e.object),this.scan(e.property),this.popState(a);break;case"ExpressionStatement":this.scan(e.expression);break;case"SequenceExpression":this.scan(e.expressions);break;case"CallExpression":this.functionCalls.push({context:this.currentContext,ast:e}),this.scan(e.arguments);break;case"ArrayExpression":this.scan(e.elements);break;case"ConditionalExpression":this.scan(e.test),this.scan(e.alternate),this.scan(e.consequent);break;case"SwitchStatement":this.scan(e.discriminant),this.scan(e.cases);break;case"SwitchCase":this.scan(e.test),this.scan(e.consequent);break;case"ThisExpression":case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${e.type}"`)}}}}}),h=e((e,t)=>{const n=r(),{utils:s}=i(),{FunctionTracer:a}=u(),o=["E","PI","SQRT2","SQRT1_2","LN2","LN10","LOG2E","LOG10E"],h=["abs","acos","acosh","asin","asinh","atan","atan2","atanh","cbrt","ceil","clz32","cos","cosh","expm1","exp","floor","fround","imul","log","log2","log10","log1p","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc"],l=["value","value[]","value[][]","value[][][]","value[][][][]","value.value","value.thread.value","this.thread.value","this.output.value","this.constants.value","this.constants.value[]","this.constants.value[][]","this.constants.value[][][]","this.constants.value[][][][]","fn()[]","fn()[][]","fn()[][][]","[][]"];const c={Number:"Number",Float:"Float",Integer:"Integer",Array:"Number","Array(2)":"Number","Array(3)":"Number","Array(4)":"Number","Matrix(2)":"Number","Matrix(3)":"Number","Matrix(4)":"Number",Array2D:"Number",Array3D:"Number",Input:"Number",HTMLCanvas:"Array(4)",OffscreenCanvas:"Array(4)",HTMLImage:"Array(4)",ImageBitmap:"Array(4)",ImageData:"Array(4)",HTMLVideo:"Array(4)",HTMLImageArray:"Array(4)",NumberTexture:"Number",MemoryOptimizedNumberTexture:"Number","Array1D(2)":"Array(2)","Array1D(3)":"Array(3)","Array1D(4)":"Array(4)","Array2D(2)":"Array(2)","Array2D(3)":"Array(3)","Array2D(4)":"Array(4)","Array3D(2)":"Array(2)","Array3D(3)":"Array(3)","Array3D(4)":"Array(4)","ArrayTexture(1)":"Number","ArrayTexture(2)":"Array(2)","ArrayTexture(3)":"Array(3)","ArrayTexture(4)":"Array(4)"};t.exports={FunctionNode:class{constructor(e,t){if(!e&&!t.ast)throw new Error("source parameter is missing");if(t=t||{},this.source=e,this.ast=null,this.name="string"==typeof e?t.isRootKernel?"kernel":t.name||s.getFunctionNameFromString(e):null,this.calledFunctions=[],this.constants={},this.constantTypes={},this.constantBitRatios={},this.isRootKernel=!1,this.isSubKernel=!1,this.debug=null,this.functions=null,this.identifiers=null,this.contexts=null,this.functionCalls=null,this.states=[],this.needsArgumentType=null,this.assignArgumentType=null,this.lookupReturnType=null,this.lookupFunctionArgumentTypes=null,this.lookupFunctionArgumentBitRatio=null,this.triggerImplyArgumentType=null,this.triggerImplyArgumentBitRatio=null,this.onNestedFunction=null,this.onFunctionCall=null,this.optimizeFloatMemory=null,this.precision=null,this.loopMaxIterations=null,this.argumentNames="string"==typeof this.source?s.getArgumentNamesFromString(this.source):null,this.argumentTypes=[],this.argumentSizes=[],this.argumentBitRatios=null,this.returnType=null,this.output=[],this.plugins=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.dynamicOutput=null,this.dynamicArguments=null,this.strictTypingChecking=!1,this.fixIntegerDivisionAccuracy=null,t)for(const e in t)t.hasOwnProperty(e)&&this.hasOwnProperty(e)&&(this[e]=t[e]);this.literalTypes={},this.validate(),this._string=null,this._internalVariableNames={}}validate(){if("string"!=typeof this.source&&!this.ast)throw new Error("this.source not a string");if(!this.ast&&!s.isFunctionString(this.source))throw new Error("this.source not a function string");if(!this.name)throw new Error("this.name could not be set");if(this.argumentTypes.length>0&&this.argumentTypes.length!==this.argumentNames.length)throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`);if(this.output.length<1)throw new Error("this.output is not big enough")}isIdentifierConstant(e){return!!this.constants&&this.constants.hasOwnProperty(e)}isInput(e){return"Input"===this.argumentTypes[this.argumentNames.indexOf(e)]}pushState(e){this.states.push(e)}popState(e){if(this.state!==e)throw new Error(`Cannot popState ${e} when in ${this.state}`);this.states.pop()}isState(e){return this.state===e}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(e){if("Identifier"===e.type)return e.name;if("ThisExpression"===e.type)return"this";if("MemberExpression"===e.type&&e.object&&e.property)return e.object.hasOwnProperty("name")&&"Math"!==e.object.name?this.astMemberExpressionUnroll(e.property):this.astMemberExpressionUnroll(e.object)+"."+this.astMemberExpressionUnroll(e.property);if(e.hasOwnProperty("expressions")){const t=e.expressions[0];if("Literal"===t.type&&0===t.value&&2===e.expressions.length)return this.astMemberExpressionUnroll(e.expressions[1])}throw this.astErrorOutput("Unknown astMemberExpressionUnroll",e)}getJsAST(e){if(this.ast)return this.ast;if("object"==typeof this.source)return this.traceFunctionAST(this.source),this.ast=this.source;if(null===(e=e||n))throw new Error("Missing JS to AST parser");const t=Object.freeze(e.parse(`const parser_${this.name} = ${this.source};`,{locations:!0,ecmaVersion:2020})),r=t.body[0].declarations[0].init;if(this.traceFunctionAST(r),!t)throw new Error("Failed to parse JS code");return this.ast=r}traceFunctionAST(e){const{contexts:t,declarations:r,functions:n,identifiers:s,functionCalls:i}=new a(e);this.contexts=t,this.identifiers=s,this.functionCalls=i,this.functions=n;for(let e=0;e":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const r=this.getType(e.left);if(this.isState("skip-literal-correction"))return r;if("LiteralInteger"===r){const t=this.getType(e.right);return"LiteralInteger"===t?e.left.value%1==0?"Integer":"Float":t}return c[r]||r;case"UpdateExpression":case"ReturnStatement":return this.getType(e.argument);case"UnaryExpression":return"~"===e.operator?"Integer":this.getType(e.argument);case"VariableDeclaration":{const t=e.declarations;let r;for(let e=0;ee.isSafe)}getDependencies(e,t,r){if(t||(t=[]),!e)return null;if(Array.isArray(e)){for(let n=0;n-1/0&&e.value<1/0&&!isNaN(e.value))});break;case"VariableDeclarator":return this.getDependencies(e.init,t,r);case"Identifier":const n=this.getDeclaration(e);if(n)t.push({name:e.name,origin:"declaration",isSafe:!r&&this.isSafeDependencies(n.dependencies)});else if(this.argumentNames.indexOf(e.name)>-1)t.push({name:e.name,origin:"argument",isSafe:!1});else if(this.strictTypingChecking)throw new Error(`Cannot find identifier origin "${e.name}"`);break;case"FunctionDeclaration":return this.getDependencies(e.body.body[e.body.body.length-1],t,r);case"ReturnStatement":return this.getDependencies(e.argument,t);case"BinaryExpression":case"LogicalExpression":return r="/"===e.operator||"*"===e.operator,this.getDependencies(e.left,t,r),this.getDependencies(e.right,t,r),t;case"UnaryExpression":case"UpdateExpression":return this.getDependencies(e.argument,t,r);case"VariableDeclaration":return this.getDependencies(e.declarations,t,r);case"ArrayExpression":return t.push({origin:"declaration",isSafe:!0}),t;case"CallExpression":return t.push({origin:"function",isSafe:!0}),t;case"MemberExpression":const s=this.getMemberExpressionDetails(e);switch(s.signature){case"value[]":this.getDependencies(e.object,t,r);break;case"value[][]":this.getDependencies(e.object.object,t,r);break;case"value[][][]":this.getDependencies(e.object.object.object,t,r);break;case"this.output.value":this.dynamicOutput&&t.push({name:s.name,origin:"output",isSafe:!1})}if(s)return s.property&&this.getDependencies(s.property,t,r),s.xProperty&&this.getDependencies(s.xProperty,t,r),s.yProperty&&this.getDependencies(s.yProperty,t,r),s.zProperty&&this.getDependencies(s.zProperty,t,r),t;case"SequenceExpression":return this.getDependencies(e.expressions,t,r);default:throw this.astErrorOutput(`Unhandled type ${e.type} in getDependencies`,e)}return t}getVariableSignature(e,t){if(!this.isAstVariable(e))throw new Error(`ast of type "${e.type}" is not a variable signature`);if("Identifier"===e.type)return"value";const r=[];for(;e;)e.computed?r.push("[]"):"ThisExpression"===e.type?r.unshift("this"):e.property&&e.property.name?"x"===e.property.name||"y"===e.property.name||"z"===e.property.name?r.unshift(t?"."+e.property.name:".value"):"constants"===e.property.name||"thread"===e.property.name||"output"===e.property.name?r.unshift("."+e.property.name):r.unshift(t?"."+e.property.name:".value"):e.name?r.unshift(t?e.name:"value"):e.callee&&e.callee.name?r.unshift(t?e.callee.name+"()":"fn()"):e.elements?r.unshift("[]"):r.unshift("unknown"),e=e.object;const n=r.join("");return t||l.includes(n)?n:null}build(){return this.toString().length>0}astGeneric(e,t){if(null===e)throw this.astErrorOutput("NULL ast",e);if(Array.isArray(e)){for(let r=0;r0?n[n.length-1]:0;return new Error(`${e} on line ${n.length}, position ${i.length}:\n ${r}`)}astDebuggerStatement(e,t){return t}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);return t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t}astFunction(e,t){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}astFunctionExpression(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}isChildFunction(e){for(let t=0;t1?t.push("(",n.join(","),")"):t.push(n[0]),t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)||(e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator))),t}checkAndUpconvertBitwiseUnary(e,t){}astUpdateExpression(e,t){return e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t}astLogicalExpression(e,t){return t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t.push(")"),t}astMemberExpression(e,t){return t}astCallExpression(e,t){return t}astArrayExpression(e,t){return t}getMemberExpressionDetails(e){if("MemberExpression"!==e.type)throw this.astErrorOutput(`Expression ${e.type} not a MemberExpression`,e);let t=null,r=null;const n=this.getVariableSignature(e);switch(n){case"value":return null;case"value.thread.value":case"this.thread.value":case"this.output.value":return{signature:n,type:"Integer",name:e.property.name};case"value[]":if("string"!=typeof e.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object),xProperty:e.property};case"value[][]":if("string"!=typeof e.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object.object),yProperty:e.object.property,xProperty:e.property};case"value[][][]":if("string"!=typeof e.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value[][][][]":if("string"!=typeof e.object.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.object.name,{name:t,origin:"user",signature:n,type:this.getVariableType(e.object.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(this.isAstMathVariable(e))return t=e.property.name,{name:t,origin:"Math",type:"Number",signature:n};switch(e.property.name){case"r":case"g":case"b":case"a":return t=e.object.name,{name:t,property:e.property.name,origin:"user",signature:n,type:"Number"};default:throw this.astErrorOutput("Unexpected expression",e)}case"this.constants.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n};case"this.constants.value[]":if("string"!=typeof e.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,xProperty:e.property};case"this.constants.value[][]":if("string"!=typeof e.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,yProperty:e.object.property,xProperty:e.property};case"this.constants.value[][][]":if("string"!=typeof e.object.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.object.property.name,r=this.getConstantType(t),!r)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"fn()[]":case"fn()[][]":case"[][]":return{signature:n,property:e.property};default:throw this.astErrorOutput("Unexpected expression",e)}}findIdentifierOrigin(e){const t=[this.ast];for(;t.length>0;){const r=t[0];if("VariableDeclarator"===r.type&&r.id&&r.id.name&&r.id.name===e.name)return r;if(t.shift(),r.argument)t.push(r.argument);else if(r.body)t.push(r.body);else if(r.declarations)t.push(r.declarations);else if(Array.isArray(r))for(let e=0;e0;){const e=t.pop();if("ReturnStatement"===e.type)return e;if("FunctionDeclaration"!==e.type)if(e.argument)t.push(e.argument);else if(e.body)t.push(e.body);else if(e.declarations)t.push(e.declarations);else if(Array.isArray(e))for(let r=0;r{const{FunctionNode:r}=h();t.exports={CPUFunctionNode:class extends r{astFunction(e,t){if(!this.isRootKernel){t.push("function"),t.push(" "),t.push(this.name),t.push("(");for(let e=0;e0&&t.push(", "),t.push("user_"),t.push(r)}t.push(") {\n")}for(let r=0;r0&&t.push(r.join(""),";\n"),t.push(`for (let ${e}=0;${e}0&&t.push(`if (!${n.join("")}) break;\n`),t.push(i.join("")),t.push(`\n${s.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),t.push("if ("),this.astGeneric(e.test,t),t.push(") {\n"),this.astGeneric(e.body,t),t.push("} else {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astDoWhileStatement(e,t){if("DoWhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),this.astGeneric(e.body,t),t.push("if (!"),this.astGeneric(e.test,t),t.push(") {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astAssignmentExpression(e,t){const r=this.getDeclaration(e.left);if(r&&!r.assignable)throw this.astErrorOutput(`Variable ${e.left.name} is not assignable here`,e);const n=this.isState("assignment-as-statement");return n?this.popState("assignment-as-statement"):t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),n||t.push(")"),t}astBlockStatement(e,t){if(this.isState("loop-body")){this.pushState("block-body");for(let r=0;r0&&t.push(",");const n=r[e],s=this.getDeclaration(n.id);s.valueType||(s.valueType=this.getType(n.init)),this.astGeneric(n,t)}return this.isState("in-for-loop-init")||t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchStatement(e,t){const{discriminant:r,cases:n}=e;t.push("switch ("),this.astGeneric(r,t),t.push(") {\n");for(let e=0;e0&&(this.astGeneric(n[e].consequent,t),t.push("break;\n"))):(t.push("default:\n"),this.astGeneric(n[e].consequent,t),n[e].consequent&&n[e].consequent.length>0&&t.push("break;\n"));t.push("\n}")}astThisExpression(e,t){return t.push("_this"),t}astMemberExpression(e,t){const{signature:r,type:n,property:s,xProperty:i,yProperty:a,zProperty:o,name:u,origin:h}=this.getMemberExpressionDetails(e);switch(r){case"this.thread.value":return t.push(`_this.thread.${u}`),t;case"this.output.value":switch(u){case"x":t.push("outputX");break;case"y":t.push("outputY");break;case"z":t.push("outputZ");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":default:throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value.value":if("Math"===h)return t.push(Math[u]),t;switch(s){case"r":return t.push(`user_${u}[0]`),t;case"g":return t.push(`user_${u}[1]`),t;case"b":return t.push(`user_${u}[2]`),t;case"a":return t.push(`user_${u}[3]`),t}break;case"this.constants.value":case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":break;case"fn()[]":return this.astGeneric(e.object,t),t.push("["),this.astGeneric(e.property,t),t.push("]"),t;case"fn()[][]":return this.astGeneric(e.object.object,t),t.push("["),this.astGeneric(e.object.property,t),t.push("]"),t.push("["),this.astGeneric(e.property,t),t.push("]"),t}if(!e.computed)switch(n){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${h}_${u}`),t}const l=`${h}_${u}`;{let e,r;if("constants"===h){const t=this.constants[u];r="Input"===this.constantTypes[u],e=r?t.size:null}else r=this.isInput(u),e=r?this.argumentSizes[this.argumentNames.indexOf(u)]:null;t.push(`${l}`),o&&a?r?(t.push("[("),this.astGeneric(o,t),t.push(`*${this.dynamicArguments?"(outputY * outputX)":e[1]*e[0]})+(`),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(i,t),t.push("]")):(t.push("["),this.astGeneric(o,t),t.push("]"),t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(i,t),t.push("]")):a?r?(t.push("[("),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(i,t),t.push("]")):(t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(i,t),t.push("]")):void 0!==i&&(t.push("["),this.astGeneric(i,t),t.push("]"))}return t}astCallExpression(e,t){if("CallExpression"!==e.type)throw this.astErrorOutput("Unknown CallExpression",e);let r=this.astMemberExpressionUnroll(e.callee);this.calledFunctions.indexOf(r)<0&&this.calledFunctions.push(r),this.isAstMathFunction(e),this.onFunctionCall&&this.onFunctionCall(this.name,r,e.arguments),t.push(r),t.push("(");const n=this.lookupFunctionArgumentTypes(r)||[];for(let s=0;s0&&t.push(", "),this.astGeneric(i,t)}return t.push(")"),t}astArrayExpression(e,t){const r=this.getType(e),n=e.elements.length,s=[];for(let t=0;t{const{utils:r}=i();t.exports={cpuKernelString:function(e,t){const n=[],s=[],i=[],a=!/^function/.test(e.color.toString());if(n.push(" const { context, canvas, constants: incomingConstants } = settings;",` const output = new Int32Array(${JSON.stringify(Array.from(e.output))});`,` const _constantTypes = ${JSON.stringify(e.constantTypes)};`,` const _constants = ${function(e,t){const r=[];for(const n in t){if(!t.hasOwnProperty(n))continue;const s=t[n],i=e[n];switch(s){case"Number":case"Integer":case"Float":case"Boolean":r.push(`${n}:${i}`);break;case"Array(2)":case"Array(3)":case"Array(4)":case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":r.push(`${n}:new ${i.constructor.name}(${JSON.stringify(Array.from(i))})`)}}return`{ ${r.join()} }`}(e.constants,e.constantTypes)};`),s.push(" constants: _constants,"," context,"," output,"," thread: {x: 0, y: 0, z: 0},"),e.graphical){n.push(` const _imageData = context.createImageData(${e.output[0]}, ${e.output[1]});`),n.push(` const _colorData = new Uint8ClampedArray(${e.output[0]} * ${e.output[1]} * 4);`);const t=r.flattenFunctionToString((a?"function ":"")+e.color.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:(e,t)=>null}),o=r.flattenFunctionToString((a?"function ":"")+e.getPixels.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:()=>null});s.push(" _imageData,"," _colorData,",` color: ${t},`),i.push(` kernel.getPixels = ${o};`)}const o=[],u=Object.keys(e.constantTypes);for(let t=0;t"this"===t?(a?"function ":"")+e[r].toString():null,thisLookup:e=>{switch(e){case"canvas":return;case"context":return"context"}}});i.push(t),s.push(" _mediaTo2DArray,"),s.push(" _imageTo3DArray,")}else if(-1!==e.argumentTypes.indexOf("HTMLImage")||-1!==o.indexOf("HTMLImage")){const t=r.flattenFunctionToString((a?"function ":"")+e._mediaTo2DArray.toString(),{findDependency:(e,t)=>null,thisLookup:e=>{switch(e){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});i.push(t),s.push(" _mediaTo2DArray,")}return`function(settings) {\n${n.join("\n")}\n for (const p in _constantTypes) {\n if (!_constantTypes.hasOwnProperty(p)) continue;\n const type = _constantTypes[p];\n switch (type) {\n case 'Number':\n case 'Integer':\n case 'Float':\n case 'Boolean':\n case 'Array(2)':\n case 'Array(3)':\n case 'Array(4)':\n case 'Matrix(2)':\n case 'Matrix(3)':\n case 'Matrix(4)':\n if (incomingConstants.hasOwnProperty(p)) {\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\n }\n continue;\n }\n if (!incomingConstants.hasOwnProperty(p)) {\n throw new Error('constant ' + p + ' not found');\n }\n _constants[p] = incomingConstants[p];\n }\n const kernel = (function() {\n${e._kernelString}\n })\n .apply({ ${s.join("\n")} });\n ${i.join("\n")}\n return kernel;\n}`}}}),p=e((e,t)=>{const{Kernel:r}=a(),{FunctionBuilder:n}=o(),{CPUFunctionNode:s}=l(),{utils:u}=i(),{cpuKernelString:h}=c();t.exports={CPUKernel:class extends r{static getFeatures(){return this.features}static get features(){return Object.freeze({kernelMap:!0,isIntegerDivisionAccurate:!0})}static get isSupported(){return!0}static isContextMatch(e){return!1}static get mode(){return"cpu"}static nativeFunctionArguments(){return null}static nativeFunctionReturnType(){throw new Error(`Looking up native function return type not supported on ${this.name}`)}static combineKernels(e){return e}static getSignature(e,t){return"cpu"+(t.length>0?":"+t.join(","):"")}constructor(e,t){super(e,t),this.mergeSettings(e.settings||t),this._imageData=null,this._colorData=null,this._kernelString=null,this._prependedString=[],this.thread={x:0,y:0,z:0},this.translatedSources=null}initCanvas(){return"undefined"!=typeof document?document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(0,0):void 0}initContext(){return this.canvas?this.canvas.getContext("2d",{willReadFrequently:!0}):null}initPlugins(e){return[]}validateSettings(e){if(!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=u.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=u.getDimensions(t);else{if("NumberTexture"!==t&&"ArrayTexture(4)"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=e[0].output}}if(this.graphical&&2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");this.checkOutput()}translateSource(){if(this.leadingReturnStatement=this.output.length>1?"resultX[x] = ":"result[x] = ",this.subKernels){const e=[];for(let t=0;t1?`resultX_${r}[x] = subKernelResult_${r};\n`:`result_${r}[x] = subKernelResult_${r};\n`)}this.followingReturnStatement=e.join("")}const e=n.fromKernel(this,s);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){if(this.built)return;if(null!==this.randomSeed&&console.warn("randomSeed is not supported in cpu mode; Math.random() will be unseeded"),this.setupConstants(),this.setupArguments(arguments),this.validateSettings(arguments),this.translateSource(),this.graphical){const{canvas:e,output:t}=this;if(!e)throw new Error("no canvas available for using graphical output");const r=t[0],n=t[1]||1;e.width=r,e.height=n,this._imageData=this.context.createImageData(r,n),this._colorData=new Uint8ClampedArray(r*n*4)}const e=this.getKernelString();this.kernelString=e,this.debug&&(console.log("Function output:"),console.log(e));try{this.run=new Function([],e).bind(this)()}catch(e){console.error("An error occurred compiling the javascript: ",e)}this.buildSignature(arguments),this.built=!0}color(e,t,r,n){void 0===n&&(n=1),e=Math.floor(255*e),t=Math.floor(255*t),r=Math.floor(255*r),n=Math.floor(255*n);const s=this.output[0],i=this.output[1],a=this.thread.x+(i-this.thread.y-1)*s;this._colorData[4*a+0]=e,this._colorData[4*a+1]=t,this._colorData[4*a+2]=r,this._colorData[4*a+3]=n}getKernelString(){if(null!==this._kernelString)return this._kernelString;let e=null,{translatedSources:t}=this;return t.length>1?t=t.filter(t=>/^function/.test(t)?t:(e=t,!1)):e=t.shift(),this._kernelString=` const LOOP_MAX = ${this._getLoopMaxString()};\n ${this.injectedNative||""}\n const _this = this;\n ${this._resultKernelHeader()}\n ${this._processConstants()}\n return (${this.argumentNames.map(e=>"user_"+e).join(", ")}) => {\n ${this._prependedString.join("")}\n ${this._earlyThrows()}\n ${this._processArguments()}\n ${this.graphical?this._graphicalKernelBody(e):this._resultKernelBody(e)}\n ${t.length>0?t.join("\n"):""}\n };`}toString(){return h(this)}_getLoopMaxString(){return this.loopMaxIterations?` ${parseInt(this.loopMaxIterations)};`:" 1000;"}_processConstants(){if(!this.constants)return"";const e=[];for(let t in this.constants)switch(this.constantTypes[t]){case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":e.push(` const constants_${t} = this._mediaTo2DArray(this.constants.${t});\n`);break;case"HTMLImageArray":e.push(` const constants_${t} = this._imageTo3DArray(this.constants.${t});\n`);break;case"Input":e.push(` const constants_${t} = this.constants.${t}.value;\n`);break;default:e.push(` const constants_${t} = this.constants.${t};\n`)}return e.join("")}_earlyThrows(){if(this.graphical)return"";if(this.immutable)return"";if(!this.pipeline)return"";const e=[];for(let t=0;t`user_${n} === result_${e.name}`).join(" || ");t.push(`user_${n} === result${s?` || ${s}`:""}`)}return`if (${t.join(" || ")}) throw new Error('Source and destination arrays are the same. Use immutable = true');`}_processArguments(){const e=[];for(let t=0;t0?e.width:e.videoWidth,n=e.height>0?e.height:e.videoHeight;t.width=0;e--){const t=a[e]=new Array(r);for(let e=0;e`const result_${e.name} = new ${t}(outputX);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_mutableKernel1DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const result = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const result_${t.name} = new ${e}(outputX);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}`}_resultMutableKernel1DLoop(e){return` const outputX = _this.output[0];\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_resultImmutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y] = new ${t}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_mutableKernel2DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n const resultX = result[y] = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const resultX_${t.name} = result_${t.name}[y] = new ${e}(outputX);\n`).join("")}\n }`}_resultMutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y];\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_graphicalKernel2DLoop(e){return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_resultImmutableKernel3DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputZ);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels(e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y] = new ${t}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = resultY_${e.name}[y] = new ${t}(outputX);\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_mutableKernel3DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputZ);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels(e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n const resultX = resultY[y] = new ${e}(outputX);\n ${this._mapSubKernels(t=>`const resultX_${t.name} = resultY_${t.name}[y] = new ${e}(outputX);\n`).join(" ")}\n }\n }`}_resultMutableKernel3DLoop(e){return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z];\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y];\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_kernelOutput(){return this.subKernels?`\n return {\n result: result,\n ${this.subKernels.map(e=>`${e.property}: result_${e.name}`).join(",\n ")}\n };`:"\n return result;"}_mapSubKernels(e){return null===this.subKernels?[""]:this.subKernels.map(e)}destroy(e){e&&delete this.canvas}static destroyContext(e){}toJSON(){const e=super.toJSON();return e.functionNodes=n.fromKernel(this,s).toJSON(),e}setOutput(e){super.setOutput(e);const[t,r]=this.output;this.graphical&&(this._imageData=this.context.createImageData(t,r),this._colorData=new Uint8ClampedArray(t*r*4))}prependString(e){if(this._kernelString)throw new Error("Kernel already built");this._prependedString.push(e)}hasPrependString(e){return this._prependedString.indexOf(e)>-1}}}}),d=e((e,t)=>{t.exports={}}),f=e((e,t)=>{const{Texture:r}=s();function n(e,t){e.activeTexture(e.TEXTURE15),e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST)}t.exports={GLTexture:class extends r{get textureType(){throw new Error(`"textureType" not implemented on ${this.name}`)}clone(){return new this.constructor(this)}beforeMutate(){return this.texture._refs>1&&(this.newTexture(),!0)}cloneTexture(){this.texture._refs--;const{context:e,size:t,texture:r,kernel:s}=this;s.debug&&console.warn("cloning internal texture"),e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),n(e,r),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,r,0);const i=e.createTexture();n(e,i),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),e.copyTexSubImage2D(e.TEXTURE_2D,0,0,0,0,0,t[0],t[1]),i._refs=1,this.texture=i}newTexture(){this.texture._refs--;const e=this.context,t=this.size;this.kernel.debug&&console.warn("new internal texture");const r=e.createTexture();n(e,r),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),r._refs=1,this.texture=r}clear(){if(this.texture._refs){this.texture._refs--;const e=this.context,t=this.texture=e.createTexture();n(e,t);const r=this.size;t._refs=1,e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,r[0],r[1],0,this.textureFormat,this.textureType,null)}const{context:e,texture:t}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.bindTexture(e.TEXTURE_2D,t),n(e,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}delete(){this._deleted||(this._deleted=!0,this.texture._refs&&(this.texture._refs--,this.texture._refs)||(this.kernel&&this.kernel.deleteTexture?this.kernel.deleteTexture(this.texture):this.context.deleteTexture(this.texture)))}framebuffer(){return this._framebuffer||(this._framebuffer=this.kernel.getRawValueFramebuffer(this.size[0],this.size[1])),this._framebuffer}}}}),m=e((e,t)=>{const{utils:r}=i(),{GLTexture:n}=f();t.exports={GLTextureFloat:class extends n{get textureType(){return this.context.FLOAT}constructor(e){super(e),this.type="ArrayTexture(1)"}renderRawOutput(){const e=this.context,t=this.size;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const r=new Float32Array(t[0]*t[1]*4);return e.readPixels(0,0,t[0],t[1],e.RGBA,e.FLOAT,r),r}renderValues(){return this._deleted?null:this.renderRawOutput()}toArray(){return r.erectFloat(this.renderValues(),this.output[0])}}}}),g=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray2Float:class extends n{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erectArray2(this.renderValues(),this.output[0],this.output[1])}}}}),x=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray2Float2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erect2DArray2(this.renderValues(),this.output[0],this.output[1])}}}}),y=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray2Float3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erect3DArray2(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),b=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray3Float:class extends n{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erectArray3(this.renderValues(),this.output[0])}}}}),T=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray3Float2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erect2DArray3(this.renderValues(),this.output[0],this.output[1])}}}}),S=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray3Float3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erect3DArray3(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),v=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray4Float:class extends n{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erectArray4(this.renderValues(),this.output[0])}}}}),A=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray4Float2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erect2DArray4(this.renderValues(),this.output[0],this.output[1])}}}}),_=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureArray4Float3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erect3DArray4(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),w=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureFloat2D:class extends n{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return r.erect2DFloat(this.renderValues(),this.output[0],this.output[1])}}}}),E=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureFloat3D:class extends n{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return r.erect3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),I=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureMemoryOptimized:class extends n{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}}}),k=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureMemoryOptimized2D:class extends n{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}}}),D=e((e,t)=>{const{utils:r}=i(),{GLTextureFloat:n}=m();t.exports={GLTextureMemoryOptimized3D:class extends n{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),C=e((e,t)=>{const{utils:r}=i(),{GLTexture:n}=f();t.exports={GLTextureUnsigned:class extends n{get textureType(){return this.context.UNSIGNED_BYTE}constructor(e){super(e),this.type="NumberTexture"}renderRawOutput(){const{context:e}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const t=new Uint8Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.UNSIGNED_BYTE,t),t}renderValues(){return this._deleted?null:new Float32Array(this.renderRawOutput().buffer)}toArray(){return r.erectPackedFloat(this.renderValues(),this.output[0])}}}}),L=e((e,t)=>{const{utils:r}=i(),{GLTextureUnsigned:n}=C();t.exports={GLTextureUnsigned2D:class extends n{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}}}),$=e((e,t)=>{const{utils:r}=i(),{GLTextureUnsigned:n}=C();t.exports={GLTextureUnsigned3D:class extends n{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}}),F=e((e,t)=>{const{GLTextureUnsigned:r}=C();t.exports={GLTextureGraphical:class extends r{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return this.renderValues()}}}}),R=e((e,t)=>{const{Kernel:r}=a(),{utils:n}=i(),{GLTextureArray2Float:s}=g(),{GLTextureArray2Float2D:o}=x(),{GLTextureArray2Float3D:u}=y(),{GLTextureArray3Float:h}=b(),{GLTextureArray3Float2D:l}=T(),{GLTextureArray3Float3D:c}=S(),{GLTextureArray4Float:p}=v(),{GLTextureArray4Float2D:d}=A(),{GLTextureArray4Float3D:f}=_(),{GLTextureFloat:R}=m(),{GLTextureFloat2D:N}=w(),{GLTextureFloat3D:V}=E(),{GLTextureMemoryOptimized:M}=I(),{GLTextureMemoryOptimized2D:O}=k(),{GLTextureMemoryOptimized3D:P}=D(),{GLTextureUnsigned:G}=C(),{GLTextureUnsigned2D:z}=L(),{GLTextureUnsigned3D:U}=$(),{GLTextureGraphical:K}=F();const B={int:"Integer",float:"Number",vec2:"Array(2)",vec3:"Array(3)",vec4:"Array(4)"};t.exports={GLKernel:class extends r{static get mode(){return"gpu"}static getIsFloatRead(){const e=new this("function kernelFunction() {\n return 1;\n }",{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[1],precision:"single",returnType:"Number",tactic:"speed"});e.build(),e.run();const t=e.renderOutput();return e.destroy(!0),1===t[0]}static getIsIntegerDivisionAccurate(){const e=new this(function(e,t){return e[this.thread.x]/t[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[2],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[6,6030401],[3,3991]];e.build.apply(e,t),e.run.apply(e,t);const r=e.renderOutput();return e.destroy(!0),2===r[0]&&1511===r[1]}static getIsSpeedTacticSupported(){const e=new this(function(e){return e[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[4],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[0,1,2,3]];e.build.apply(e,t),e.run.apply(e,t);const r=e.renderOutput();return e.destroy(!0),0===Math.round(r[0])&&1===Math.round(r[1])&&2===Math.round(r[2])&&3===Math.round(r[3])}static get testCanvas(){throw new Error(`"testCanvas" not defined on ${this.name}`)}static get testContext(){throw new Error(`"testContext" not defined on ${this.name}`)}static getFeatures(){const e=this.testContext,t=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isSpeedTacticSupported:this.getIsSpeedTacticSupported(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:t,kernelMap:t,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize(),lowIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT),lowFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT),mediumIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT),mediumFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT),highIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT),highFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)})}static setupFeatureChecks(){throw new Error(`"setupFeatureChecks" not defined on ${this.name}`)}static getSignature(e,t){return e.getVariablePrecisionString()+(t.length>0?":"+t.join(","):"")}setFixIntegerDivisionAccuracy(e){return this.fixIntegerDivisionAccuracy=e,this}setPrecision(e){return this.precision=e,this}setFloatTextures(e){return n.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],r=[],n=[],s=/^[a-zA-Z_]/,i=/[a-zA-Z_0-9]/;let a=0,o=null,u=null;for(;a0?n[n.length-1]:null;if("FUNCTION_ARGUMENTS"!==c||"/"!==h||"*"!==l)if("MULTI_LINE_COMMENT"!==c||"*"!==h||"/"!==l)if("FUNCTION_ARGUMENTS"!==c||"/"!==h||"/"!==l)if("COMMENT"!==c||"\n"!==h)if(null!==c||"("!==h){if("FUNCTION_ARGUMENTS"===c){if(")"===h){n.pop();break}if("f"===h&&"l"===l&&"o"===e[a+2]&&"a"===e[a+3]&&"t"===e[a+4]&&" "===e[a+5]){n.push("DECLARE_VARIABLE"),u="float",o="",a+=6;continue}if("i"===h&&"n"===l&&"t"===e[a+2]&&" "===e[a+3]){n.push("DECLARE_VARIABLE"),u="int",o="",a+=4;continue}if("v"===h&&"e"===l&&"c"===e[a+2]&&"2"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec2",o="",a+=5;continue}if("v"===h&&"e"===l&&"c"===e[a+2]&&"3"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec3",o="",a+=5;continue}if("v"===h&&"e"===l&&"c"===e[a+2]&&"4"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec4",o="",a+=5;continue}}else if("DECLARE_VARIABLE"===c){if(""===o){if(" "===h){a++;continue}if(!s.test(h))throw new Error("variable name is not expected string")}o+=h,i.test(l)||(n.pop(),r.push(o),t.push(B[u]))}a++}else n.push("FUNCTION_ARGUMENTS"),a++;else n.pop(),a++;else n.push("COMMENT"),a+=2;else n.pop(),a+=2;else n.push("MULTI_LINE_COMMENT"),a+=2}if(n.length>0)throw new Error("GLSL function was not parsable");return{argumentNames:r,argumentTypes:t}}static nativeFunctionReturnType(e){return B[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:r,context:s,threadDim:i}=t.texSize;let a;if("single"===t.precision){const e=r[0],t=Math.ceil(r[1]/4);a=new Float32Array(e*t*4*4),s.readPixels(0,0,e,4*t,s.RGBA,s.FLOAT,a)}else{const e=new Uint8Array(r[0]*r[1]*4);s.readPixels(0,0,r[0],r[1],s.RGBA,s.UNSIGNED_BYTE,e),a=new Float32Array(e.buffer)}return a=a.subarray(0,i[0]*i[1]*i[2]),1===t.output.length?a:2===t.output.length?n.splitArray(a,t.output[0]):3===t.output.length?n.splitArray(a,t.output[0]*t.output[1]).map(function(e){return n.splitArray(e,t.output[0])}):void 0}constructor(e,t){super(e,t),this.transferValues=null,this.formatValues=null,this.TextureConstructor=null,this.renderOutput=null,this.renderRawOutput=null,this.texSize=null,this.translatedSource=null,this.compiledFragmentShader=null,this.compiledVertexShader=null,this.switchingKernels=null,this._textureSwitched=null,this._mappedTextureSwitched=null}checkTextureSize(){const{features:e}=this.constructor;if(this.texSize[0]>e.maxTextureSize||this.texSize[1]>e.maxTextureSize)throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${e.maxTextureSize},${e.maxTextureSize}]`)}translateSource(){throw new Error(`"translateSource" not defined on ${this.constructor.name}`)}pickRenderStrategy(e){if(this.graphical)return this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=e=>e,this.TextureConstructor=K,null;if("unsigned"===this.precision)if(this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=this.readPackedPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=U,null):this.output[1]>0?(this.TextureConstructor=z,null):(this.TextureConstructor=G,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else switch(null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.renderOutput=this.renderValues,this.output[2]>0?(this.TextureConstructor=U,this.formatValues=n.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=z,this.formatValues=n.erect2DPackedFloat,null):(this.TextureConstructor=G,this.formatValues=n.erectPackedFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else{if("single"!==this.precision)throw new Error(`unhandled precision of "${this.precision}"`);if(this.renderRawOutput=this.readFloatPixelsToFloat32Array,this.transferValues=this.readFloatPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.optimizeFloatMemory?this.output[2]>0?(this.TextureConstructor=P,null):this.output[1]>0?(this.TextureConstructor=O,null):(this.TextureConstructor=M,null):this.output[2]>0?(this.TextureConstructor=V,null):this.output[1]>0?(this.TextureConstructor=N,null):(this.TextureConstructor=R,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,null):this.output[1]>0?(this.TextureConstructor=o,null):(this.TextureConstructor=s,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,null):this.output[1]>0?(this.TextureConstructor=l,null):(this.TextureConstructor=h,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=f,null):this.output[1]>0?(this.TextureConstructor=d,null):(this.TextureConstructor=p,null)}if(this.renderOutput=this.renderValues,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.optimizeFloatMemory)switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=P,this.formatValues=n.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=O,this.formatValues=n.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=M,this.formatValues=n.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.formatValues=n.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.formatValues=n.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=n.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,this.formatValues=n.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=n.erect2DArray3,null):(this.TextureConstructor=h,this.formatValues=n.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=f,this.formatValues=n.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=d,this.formatValues=n.erect2DArray4,null):(this.TextureConstructor=p,this.formatValues=n.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=V,this.formatValues=n.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=N,this.formatValues=n.erect2DFloat,null):(this.TextureConstructor=R,this.formatValues=n.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.formatValues=n.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.formatValues=n.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=n.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=c,this.formatValues=n.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=n.erect2DArray3,null):(this.TextureConstructor=h,this.formatValues=n.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=f,this.formatValues=n.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=d,this.formatValues=n.erect2DArray4,null):(this.TextureConstructor=p,this.formatValues=n.erectArray4,null)}}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error("abstract method call")}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error("abstract method call")}getMainResultSubKernelNumberTexture(){throw new Error("abstract method call")}getMainResultKernelArray2Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray2Texture(){throw new Error("abstract method call")}getMainResultKernelArray3Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray3Texture(){throw new Error("abstract method call")}getMainResultKernelArray4Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray4Texture(){throw new Error("abstract method call")}getMainResultGraphical(){throw new Error("abstract method call")}getMainResultMemoryOptimizedFloats(){throw new Error("abstract method call")}getMainResultPackedPixels(){throw new Error("abstract method call")}getMainResultString(){return this.graphical?this.getMainResultGraphical():"single"===this.precision?this.optimizeFloatMemory?this.getMainResultMemoryOptimizedFloats():this.getMainResultTexture():this.getMainResultPackedPixels()}getMainResultNumberTexture(){return n.linesToString(this.getMainResultKernelNumberTexture())+n.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return n.linesToString(this.getMainResultKernelArray2Texture())+n.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return n.linesToString(this.getMainResultKernelArray3Texture())+n.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return n.linesToString(this.getMainResultKernelArray4Texture())+n.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} float;\n`}getIntTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic,!0)} int;\n`}getSampler2DTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2D;\n`}getSampler2DArrayTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2DArray;\n`}renderTexture(){return this.immutable?this.texture.clone():this.texture}readPackedPixelsToUint8Array(){if("unsigned"!==this.precision)throw new Error('Requires this.precision to be "unsigned"');const{texSize:e,context:t}=this,r=new Uint8Array(e[0]*e[1]*4);return t.readPixels(0,0,e[0],e[1],t.RGBA,t.UNSIGNED_BYTE,r),r}readPackedPixelsToFloat32Array(){return new Float32Array(this.readPackedPixelsToUint8Array().buffer)}readFloatPixelsToFloat32Array(){if("single"!==this.precision)throw new Error('Requires this.precision to be "single"');const{texSize:e,context:t}=this,r=e[0],n=e[1],s=new Float32Array(r*n*4);return t.readPixels(0,0,r,n,t.RGBA,t.FLOAT,s),s}getPixels(e){const{context:t,output:r}=this,[s,i]=r,a=new Uint8Array(s*i*4);return t.readPixels(0,0,s,i,t.RGBA,t.UNSIGNED_BYTE,a),new Uint8ClampedArray((e?a:n.flipPixels(a,s,i)).buffer)}renderKernelsToArrays(){const e={result:this.renderOutput()};for(let t=0;t0){for(let e=0;e0){const{mappedTextures:r}=this;for(let n=0;n{const{utils:r}=i(),{FunctionNode:n}=h();function s(e){if(!e||"object"!=typeof e)return!0;if(Array.isArray(e))return e.every(s);if("UpdateExpression"===e.type||"AssignmentExpression"===e.type||"SequenceExpression"===e.type)return!1;for(const t in e)if("loc"!==t&&"range"!==t&&"parent"!==t&&!s(e[t]))return!1;return!0}function a(e){let t=!1;function r(e){if(!e||"object"!=typeof e||t)return!1;if(Array.isArray(e))return e.some(r);if("MemberExpression"===e.type&&e.computed)return!0;for(const t in e)if("loc"!==t&&"range"!==t&&"parent"!==t&&r(e[t]))return!0;return!1}return function e(n){if(n&&"object"==typeof n&&!t)if(Array.isArray(n))n.forEach(e);else if("MemberExpression"===n.type&&n.computed&&r(n.property))t=!0;else for(const t in n)"loc"!==t&&"range"!==t&&"parent"!==t&&e(n[t])}(e),t}function o(e,t){if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return e.some(e=>o(e,t));if("CallExpression"===e.type&&"Identifier"===e.callee.type&&e.callee.name===t)return!0;for(const r in e)if("loc"!==r&&"range"!==r&&"parent"!==r&&o(e[r],t))return!0;return!1}function u(e){let t=!1;return function e(r){if(r&&"object"==typeof r&&!t)if(Array.isArray(r))r.forEach(e);else if("CallExpression"===r.type&&"Identifier"===r.callee.type&&r.arguments.some(e=>o(e,r.callee.name)))t=!0;else for(const t in r)"loc"!==t&&"range"!==t&&"parent"!==t&&e(r[t])}(e),t}function l(e){const t="ExpressionStatement"===e.type&&"AssignmentExpression"===e.expression.type?e.expression:null;return function e(r){if(!r||"object"!=typeof r)return!0;if(Array.isArray(r))return r.every(e);if("string"==typeof r.type){if("UpdateExpression"===r.type||"SequenceExpression"===r.type)return!1;if("AssignmentExpression"===r.type&&r!==t)return!1}for(const t in r)if("loc"!==t&&"range"!==t&&"parent"!==t&&!e(r[t]))return!1;return!0}(e)}const c={"Matrix(2)":2,"Matrix(3)":3,"Matrix(4)":4},p={Array:"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4","Matrix(2)":"mat2","Matrix(3)":"mat3","Matrix(4)":"mat4",Array2D:"sampler2D",Array3D:"sampler2D",Boolean:"bool",Float:"float",Input:"sampler2D",Integer:"int",Number:"float",LiteralInteger:"float",NumberTexture:"sampler2D",MemoryOptimizedNumberTexture:"sampler2D","ArrayTexture(1)":"sampler2D","ArrayTexture(2)":"sampler2D","ArrayTexture(3)":"sampler2D","ArrayTexture(4)":"sampler2D",HTMLVideo:"sampler2D",HTMLCanvas:"sampler2D",OffscreenCanvas:"sampler2D",HTMLImage:"sampler2D",ImageBitmap:"sampler2D",ImageData:"sampler2D",HTMLImageArray:"sampler2DArray"},d={"===":"==","!==":"!="};t.exports={WebGLFunctionNode:class extends n{constructor(e,t){super(e,t),t&&t.hasOwnProperty("fixIntegerDivisionAccuracy")&&(this.fixIntegerDivisionAccuracy=t.fixIntegerDivisionAccuracy)}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);const r=this.getType(e.consequent),n=this.getType(e.alternate);return null===r&&null===n?(t.push("if ("),this.astGeneric(e.test,t),t.push(") {"),this.astGeneric(e.consequent,t),t.push(";"),t.push("} else {"),this.astGeneric(e.alternate,t),t.push(";"),t.push("}"),t):(t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t)}astFunction(e,t){if(this.isRootKernel)t.push("void");else{this.returnType||this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"));const{returnType:r}=this;if(r){const e=p[r];if(!e)throw new Error(`unknown type ${r}`);t.push(e)}else t.push("void")}if(t.push(" "),t.push(this.name),t.push("("),!this.isRootKernel)for(let n=0;n0&&t.push(", ");let i=this.argumentTypes[this.argumentNames.indexOf(s)];if(!i)throw this.astErrorOutput(`Unknown argument ${s} type`,e);"LiteralInteger"===i&&(this.argumentTypes[n]=i="Number");const a=p[i];if(!a)throw this.astErrorOutput("Unexpected expression",e);const o=r.sanitizeName(s);"sampler2D"===a||"sampler2DArray"===a?t.push(`${a} user_${o},ivec2 user_${o}Size,ivec3 user_${o}Dim`):t.push(`${a} user_${o}`)}t.push(") {\n");for(let r=0;r"===e.operator||"<"===e.operator&&"Literal"===e.right.type)&&!Number.isInteger(e.right.value)){this.pushState("building-float"),this.castValueToFloat(e.left,t),t.push(d[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-float");break}if(this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const r=[];if(this.astGeneric(e.right,r),"Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(r.join(""))}else t.push("int("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float");break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(d[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.pushState("casting-to-float"),this.astGeneric(e.right,t),this.popState("casting-to-float"),this.popState("building-float"));break;case"LiteralInteger & Integer":this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(d[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean"),this.astGeneric(e.left,t),t.push(d[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${s}`,e)}return t.push(")"),t}checkAndUpconvertOperator(e,t){const r=this.checkAndUpconvertBitwiseOperators(e,t);if(r)return r;const n={"%":this.fixIntegerDivisionAccuracy?"integerCorrectionModulo":"modulo","**":"pow"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){const r={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.left)){case"Number":case"Float":this.castValueToInteger(e.left,t);break;case"LiteralInteger":this.castLiteralToInteger(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Number":case"Float":this.castValueToInteger(e.right,t);break;case"LiteralInteger":this.castLiteralToInteger(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){const r={"~":"bitwiseNot"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("int("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("float("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),s=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===n&&this.argumentNames.indexOf(s)>-1?t.push(`bool(user_${s})`):t.push(`user_${s}`),t}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const r=[],n=[],s=[],i=[];let a=null;if(e.init){const{declarations:t}=e.init;t.length>1&&(a=!1),this.astGeneric(e.init,r);for(let e=0;e0&&t.push(r.join(""),"\n"),t.push(`for (int ${e}=0;${e}0&&t.push(`if (!${n.join("")}) break;\n`),t.push(i.join("")),t.push(`\n${s.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);const r=this.getInternalVariableName("safeI");return t.push(`for (int ${r}=0;${r}null!==e&&(a(e)||u(e))))return null;const i=e=>JSON.parse(JSON.stringify(e)),o=e=>({type:"IfStatement",test:{type:"UnaryExpression",operator:"!",prefix:!0,argument:e},consequent:{type:"BlockStatement",body:[{type:"BreakStatement",label:null}]},alternate:null}),h=e=>"VariableDeclaration"===e.type?e:{type:"ExpressionStatement",expression:e},l="BlockStatement"===e.body.type?e.body.body.slice():[e.body],c=(e,t)=>{const r=e=>{if(!e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map(r);switch(e.type){case"ContinueStatement":return{type:"BlockStatement",body:[...t(),e]};case"ForStatement":case"WhileStatement":case"DoWhileStatement":default:return e;case"IfStatement":return{...e,consequent:r(e.consequent),alternate:r(e.alternate)};case"BlockStatement":return{...e,body:e.body.map(r)};case"SwitchStatement":return{...e,cases:e.cases.map(e=>({...e,consequent:e.consequent.map(r)}))}}};return e.map(r)},p=[];"DoWhileStatement"===t?(p.push(...n?c(l,()=>[o(i(n))]):l),n&&p.push(o(n))):(n&&p.push(o(n)),p.push(...s?c(l,()=>[h(i(s))]):l),s&&p.push(h(s)));const d={type:"BlockStatement",body:[...r?[h(r)]:[],{type:"WhileStatement",test:{type:"Literal",value:!0,raw:"true"},body:{type:"BlockStatement",body:p}}]};let f=this.syntheticNodeId||1073741824;const m=e=>{if(e&&"object"==typeof e)if(Array.isArray(e))e.forEach(m);else{"string"==typeof e.type&&void 0===e.start&&(e.start=f,e.end=f+1,f+=2);for(const t in e)"loc"!==t&&"range"!==t&&"parent"!==t&&m(e[t])}};return m(d),this.syntheticNodeId=f,d}linearizeStatement(e){const t=[];let r=!1,n=this.linearTempId||0;const i=e=>({type:"Identifier",name:e}),a=(e,t,r)=>({type:"VariableDeclaration",kind:e,declarations:[{type:"VariableDeclarator",id:i(t),init:r}]}),u=(e,t)=>{const r="hoistSeq"+n++;return e.push(a("const",r,t)),i(r)},h=e=>!s(e),l=(e,t)=>{if(r||!e||"object"!=typeof e)return e;switch(e.type){case"Identifier":case"Literal":case"ThisExpression":return e;case"MemberExpression":{const r=l(e.object,t),n=e.computed?l(e.property,t):e.property;return{...e,object:r,property:n}}case"CallExpression":{const r=e.arguments.map(e=>l(e,t));if("Identifier"===e.callee.type)for(let n=0;nl(e,t))};case"UpdateExpression":{if("Identifier"!==e.argument.type)return r=!0,e;if(e.prefix)return t.push({type:"ExpressionStatement",expression:e}),u(t,e.argument);const n=u(t,e.argument);return t.push({type:"ExpressionStatement",expression:e}),n}case"AssignmentExpression":{if("Identifier"!==e.left.type)return r=!0,e;const n=l(e.right,t);return t.push({type:"ExpressionStatement",expression:{...e,right:n}}),u(t,e.left)}case"SequenceExpression":for(let r=0;r({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:i(e),right:t}});return o.push(d(s,c)),u.push(d(s,p)),t.push({type:"IfStatement",test:r,consequent:{type:"BlockStatement",body:o},alternate:{type:"BlockStatement",body:u}}),i(s)}case"LogicalExpression":{if(!h(e.right))return{...e,left:l(e.left,t)};const r=l(e.left,t),s="hoistSeq"+n++;t.push(a("let",s,r));const o=[],u=l(e.right,o);return o.push({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:i(s),right:u}}),t.push({type:"IfStatement",test:"&&"===e.operator?i(s):{type:"UnaryExpression",operator:"!",prefix:!0,argument:i(s)},consequent:{type:"BlockStatement",body:o},alternate:null}),i(s)}default:return r=!0,e}};switch(e.type){case"ExpressionStatement":{const r=e.expression;if("AssignmentExpression"===r.type&&"Identifier"===r.left.type){const e=l(r.right,t);t.push({type:"ExpressionStatement",expression:{...r,right:e}})}else{const e=l(r,t);"UpdateExpression"!==e.type&&"AssignmentExpression"!==e.type||t.push({type:"ExpressionStatement",expression:e})}break}case"VariableDeclaration":for(let r=0;r{if(e&&"object"==typeof e)if(Array.isArray(e))e.forEach(p);else{"string"==typeof e.type&&void 0===e.start&&(e.start=c,e.end=c+1,c+=2);for(const t in e)"loc"!==t&&"range"!==t&&"parent"!==t&&p(e[t])}};return p(t),this.syntheticNodeId=c,t}astStatementWithHoisting(e,t){switch(e.type){case"ExpressionStatement":case"VariableDeclaration":case"ReturnStatement":{if(!l(e))return this.astGeneric(e,t);const r=this.hoistedIndexReads,n=this.hoistedIndexReads=[],s=[];return this.astGeneric(e,s),this.hoistedIndexReads=r,t.push(...n,...s),t}default:return this.astGeneric(e,t)}}astVariableDeclaration(e,t){const n=e.declarations;if(!n||!n[0]||!n[0].init)throw this.astErrorOutput("Unexpected expression",e);const s=[];let i=null;const a=[];let o=[];for(let t=0;t0&&a.push(o.join(",")),s.push(a.join(";")),t.push(s.join("")),t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchCaseConsequent(e,t){const r=[];for(let t=0;t{if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return e.some(t);if("BreakStatement"===e.type)return!0;if("ForStatement"===e.type||"WhileStatement"===e.type||"DoWhileStatement"===e.type||"SwitchStatement"===e.type)return!1;for(const r in e)if("loc"!==r&&"range"!==r&&"parent"!==r&&t(e[r]))return!0;return!1};if(t(r[e]))throw this.astErrorOutput("break inside a switch case is only supported as the case terminator",r[e])}for(let e=0;er+1){u=!0,this.astSwitchCaseConsequent(n[r].consequent,o);continue}t.push(" else {\n")}this.astSwitchCaseConsequent(n[r].consequent,t),t.push("\n}")}return u&&(t.push(" else {"),t.push(o.join("")),t.push("}")),t}astThisExpression(e,t){return t.push("this"),t}astMemberExpression(e,t){const{property:n,name:s,signature:i,origin:a,type:o,xProperty:u,yProperty:h,zProperty:l}=this.getMemberExpressionDetails(e);switch(i){case"value.thread.value":case"this.thread.value":if("x"!==s&&"y"!==s&&"z"!==s)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`threadId.${s}`),t;case"this.output.value":if(this.dynamicOutput)switch(s){case"x":this.isState("casting-to-float")?t.push("float(uOutputDim.x)"):t.push("uOutputDim.x");break;case"y":this.isState("casting-to-float")?t.push("float(uOutputDim.y)"):t.push("uOutputDim.y");break;case"z":this.isState("casting-to-float")?t.push("float(uOutputDim.z)"):t.push("uOutputDim.z");break;default:throw this.astErrorOutput("Unexpected expression",e)}else switch(s){case"x":this.isState("casting-to-integer")?t.push(this.output[0]):t.push(this.output[0],".0");break;case"y":this.isState("casting-to-integer")?t.push(this.output[1]):t.push(this.output[1],".0");break;case"z":this.isState("casting-to-integer")?t.push(this.output[2]):t.push(this.output[2],".0");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if("Math"===a)return t.push(Math[s]),t;const i=r.sanitizeName(s);switch(n){case"r":return t.push(`user_${i}.r`),t;case"g":return t.push(`user_${i}.g`),t;case"b":return t.push(`user_${i}.b`),t;case"a":return t.push(`user_${i}.a`),t}break;case"this.constants.value":if(void 0===u)switch(o){case"Array(2)":case"Array(3)":case"Array(4)":return t.push(`constants_${r.sanitizeName(s)}`),t}case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":case"this.constants.value[][][][]":break;case"fn()[]":return this.astCallExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;case"fn()[][]":{const r=e.object.property,n=e.property,s=c[this.getType(e.object.object)],i=e=>"LiteralInteger"===this.getType(e);return!s||i(r)&&i(n)?(this.astCallExpression(e.object.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(r)),t.push("]"),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t):(t.push(`getMatrix${s}(`),this.astCallExpression(e.object.object,t),t.push(", "),t.push(this.memberExpressionPropertyMarkup(r)),t.push(", "),t.push(this.memberExpressionPropertyMarkup(n)),t.push(")"),t)}case"[][]":return this.astArrayExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;default:throw this.astErrorOutput("Unexpected expression",e)}if(!1===e.computed)switch(o){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${a}_${r.sanitizeName(s)}`),t}const p=`${a}_${r.sanitizeName(s)}`;switch(o){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(u)),t.push("]");break;case"HTMLImageArray":t.push(`getImage3D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":t.push(`getVec4FromSampler2D(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if("single"===this.precision)t.push(`getMemoryOptimized32(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");else{const e="user"===a?this.lookupFunctionArgumentBitRatio(this.name,s):this.constantBitRatios[s];switch(e){case 1:t.push(`get8(${p}, ${p}Size, ${p}Dim, `);break;case 2:t.push(`get16(${p}, ${p}Size, ${p}Dim, `);break;case 4:case 0:t.push(`get32(${p}, ${p}Size, ${p}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${e}`)}this.memberExpressionXYZ(u,h,l,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${p}, ${p}Size, ${p}Dim, `),this.memberExpressionXYZ(u,h,l,t),t.push(")");break;case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`${p}[${this.memberExpressionPropertyMarkup(h)}]`),h&&t.push(`[${this.memberExpressionPropertyMarkup(u)}]`);break;default:throw new Error(`unhandled member expression "${o}"`)}return t}astCallExpression(e,t){if(!e.callee)throw this.astErrorOutput("Unknown CallExpression",e);let n=null;const s=this.isAstMathFunction(e);if(n=s||e.callee.object&&"ThisExpression"===e.callee.object.type?e.callee.property.name:"SequenceExpression"!==e.callee.type||"Literal"!==e.callee.expressions[0].type||isNaN(e.callee.expressions[0].raw)?e.callee.name:e.callee.expressions[1].property.name,!n)throw this.astErrorOutput("Unhandled function, couldn't find name",e);switch(n){case"pow":n="_pow";break;case"round":n="_round"}if(this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n),"random"===n&&this.plugins&&this.plugins.length>0)for(let e=0;e0&&t.push(", "),"Integer"===s)this.castValueToFloat(n,t);else this.astGeneric(n,t)}else{const s=this.lookupFunctionArgumentTypes(n)||[];for(let i=0;i0&&t.push(", ");const u=this.getType(a);switch(o||(this.triggerImplyArgumentType(n,i,u,this),o=u),u){case"Boolean":this.astGeneric(a,t);continue;case"Number":case"Float":if("Integer"===o){t.push("int("),this.astGeneric(a,t),t.push(")");continue}if("Number"===o||"Float"===o){this.astGeneric(a,t);continue}if("LiteralInteger"===o){this.castLiteralToFloat(a,t);continue}break;case"Integer":if("Number"===o||"Float"===o){t.push("float("),this.astGeneric(a,t),t.push(")");continue}if("Integer"===o){this.astGeneric(a,t);continue}break;case"LiteralInteger":if("Integer"===o){this.castLiteralToInteger(a,t);continue}if("Number"===o||"Float"===o){this.castLiteralToFloat(a,t);continue}if("LiteralInteger"===o){this.astGeneric(a,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(o===u){if("Identifier"===a.type)t.push(`user_${r.sanitizeName(a.name)}`);else{if("ArrayExpression"!==a.type&&"MemberExpression"!==a.type&&"CallExpression"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.astGeneric(a,t)}continue}break;case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(o===u){if("Identifier"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.triggerImplyArgumentBitRatio(this.name,a.name,n,i);const s=r.sanitizeName(a.name);t.push(`user_${s},user_${s}Size,user_${s}Dim`);continue}}throw this.astErrorOutput(`Unhandled argument combination of ${u} and ${o} for argument named "${a.name}"`,e)}}return t.push(")"),t}astArrayExpression(e,t){const r=this.getType(e),n=e.elements.length;switch(r){case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`mat${n}(`);break;default:t.push(`vec${n}(`)}for(let r=0;r0&&t.push(", ");const n=e.elements[r];this.astGeneric(n,t)}return t.push(")"),t}memberExpressionXYZ(e,t,r,n){return r?n.push(this.memberExpressionPropertyMarkup(r),", "):n.push("0, "),t?n.push(this.memberExpressionPropertyMarkup(t),", "):n.push("0, "),n.push(this.memberExpressionPropertyMarkup(e)),n}memberExpressionPropertyMarkup(e){if(!e)throw new Error("Property not set");const t=[];switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;default:this.astGeneric(e,t)}const n=t.join("");if(this.hoistedIndexReads&&/\b\w+\((user_|constants_)\w+, \1\w+Size/.test(n)){const e=`hoisted_${this.hoistedIndexReads.length}_${r.sanitizeName(this.name)}`,t=n.startsWith("int(");return this.hoistedIndexReads.push(`${t?"int":"float"} ${e}=${n};\n`),e}return n}}}}),V=e((e,t)=>{t.exports={name:"math-random-uniformly-distributed",onBeforeRun:e=>{if(null===e.randomSeed||void 0===e.randomSeed)return e.setUniform1f("randomSeed1",Math.random()),void e.setUniform1f("randomSeed2",Math.random());e._mathRandomGenerator&&e._mathRandomGeneratorSeed===e.randomSeed||(e._mathRandomGenerator=function(e){let t=e>>>0;return function(){t=t+1831565813>>>0;let e=t;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296}}(e.randomSeed),e._mathRandomGeneratorSeed=e.randomSeed),e.setUniform1f("randomSeed1",e._mathRandomGenerator()),e.setUniform1f("randomSeed2",e._mathRandomGenerator())},functionMatch:"Math.random()",functionReplace:"nrand(vTexCoord)",functionReturnType:"Number",source:"// https://www.shadertoy.com/view/4t2SDh\n//note: uniformly distributed, normalized rand, [0,1]\nhighp float randomSeedShift = 1.0;\nhighp float slide = 1.0;\nuniform highp float randomSeed1;\nuniform highp float randomSeed2;\n\nhighp float nrand(highp vec2 n) {\n highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453);\n randomSeedShift = result;\n if (randomSeedShift > 0.5) {\n slide += 0.00009; \n } else {\n slide += 0.0009;\n }\n return result;\n}"}}),M=e((e,t)=>{t.exports={fragmentShader:`__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nvarying vec2 vTexCoord;\n\nfloat acosh(float x) {\n return log(x + sqrt(x * x - 1.0));\n}\n\nfloat sinh(float x) {\n return (pow(${Math.E}, x) - pow(${Math.E}, -x)) / 2.0;\n}\n\nfloat asinh(float x) {\n return log(x + sqrt(x * x + 1.0));\n}\n\nfloat atan2(float v1, float v2) {\n if (v2 == 0.0) {\n if (v1 == 0.0) return 0.0;\n if (v1 > 0.0) return 1.5707963267948966;\n if (v1 < 0.0) return -1.5707963267948966;\n }\n return atan(v1, v2);\n}\n\nfloat atanh(float x) {\n x = (x + 1.0) / (x - 1.0);\n if (x < 0.0) {\n return 0.5 * log(-x);\n }\n return 0.5 * log(x);\n}\n\nfloat cbrt(float x) {\n if (x >= 0.0) {\n return pow(x, 1.0 / 3.0);\n } else {\n return -pow(x, 1.0 / 3.0);\n }\n}\n\nfloat cosh(float x) {\n return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0; \n}\n\nfloat expm1(float x) {\n return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n return x;\n}\n\nfloat imul(float v1, float v2) {\n return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n if (v2 == 0.0) return 1.0;\n return pow(v1, v2);\n}\n\nfloat tanh(float x) {\n float e = exp(2.0 * x);\n return (e - 1.0) / (e + 1.0);\n}\n\nfloat trunc(float x) {\n if (x >= 0.0) {\n return floor(x); \n } else {\n return ceil(x);\n }\n}\n\nvec4 _round(vec4 x) {\n return floor(x + 0.5);\n}\n\nfloat _round(float x) {\n return floor(x + 0.5);\n}\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n // ~a is identically -a - 1 in two's complement, for every value including\n // negatives. The previous bit-by-bit loop only worked for a >= 0, where it\n // leaned on 32-bit overflow wrapping to reach the negative answer; given a\n // negative input it computed ~abs(a), so ~(-1) gave -2 and ~~x never\n // returned x.\n return -a - 1;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\n// _pow2 is defined further down, alongside encode32/decode32\nfloat _pow2(float e);\nint bitwiseSignedRightShift(int num, int shifts) {\n // pow(2.0, n) is approximate on many GPUs, and landing 1 ulp high makes the\n // division fall just under a whole number, which floor() then rounds away:\n // 2 >> 1 came out 0, 8 >> 1 came out 3. Only exact left operands were\n // affected, odd ones having enough slack to survive. _pow2 is exact.\n return int(floor(float(num) / _pow2(float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x / y));\n}\n\n// GLSL ES 1.00 accepts only a constant or a loop symbol inside an index\n// expression, so m[y][x] does not compile when y and x come from kernel\n// arguments -- the error is "Index expression can only contain const or loop\n// symbols". Loop counters are legal indices, so walk the matrix with them\n// instead. These are 2x2 to 4x4, so it costs at most sixteen comparisons.\nfloat getMatrix2(mat2 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 2; i++) {\n for (int j = 0; j < 2; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix3(mat3 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 3; i++) {\n for (int j = 0; j < 3; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix4(mat4 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 4; i++) {\n for (int j = 0; j < 4; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\n// Exact powers of two built from exact constant multiplies: exp2/log2/pow\n// are approximate on some GPUs (notably Apple silicon), and 1-2 ulp there\n// corrupts the packed bytes (#659)\nfloat _pow2(float e) {\n float r = 1.0;\n float a = abs(e);\n bool n = e < 0.0;\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 32.0) { r *= n ? 2.3283064365386963e-10 : 4294967296.0; a -= 32.0; }\n if (a >= 16.0) { r *= n ? 0.0000152587890625 : 65536.0; a -= 16.0; }\n if (a >= 8.0) { r *= n ? 0.00390625 : 256.0; a -= 8.0; }\n if (a >= 4.0) { r *= n ? 0.0625 : 16.0; a -= 4.0; }\n if (a >= 2.0) { r *= n ? 0.25 : 4.0; a -= 2.0; }\n if (a >= 1.0) { r *= n ? 0.5 : 2.0; }\n return r;\n}\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = _pow2(_round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * _pow2(_round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\n return 0.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n if (channel == 0) return texel.r * 255.0;\n if (channel == 1) return texel.g * 255.0;\n if (channel == 2) return texel.b * 255.0;\n if (channel == 3) return texel.a * 255.0;\n return 0.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n float p2 = _pow2(exponent);\n // approximate log2 can land one off; correct by direct comparison\n if (p2 > value) { exponent -= 1.0; p2 *= 0.5; }\n else if (p2 * 2.0 <= value) { exponent += 1.0; p2 *= 2.0; }\n\n mantissa = value / p2 - 1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return texel.r;\n if (channel == 1) return texel.g;\n if (channel == 2) return texel.b;\n if (channel == 3) return texel.a;\n return 0.0;\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture2D(tex, st / vec2(texSize));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n \n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nvoid color(sampler2D image) {\n actualColor = texture2D(image, vTexCoord);\n}\n\nfloat modulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -mod(number, divisor);\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}`}}),O=e((e,t)=>{t.exports={vertexShader:"__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nattribute vec2 aPos;\nattribute vec2 aTexCoord;\n\nvarying vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"}}),P=e((e,t)=>{function r(e,t={}){const{contextName:r="gl",throwGetError:a,useTrackablePrimitives:o,recording:u=[],variables:h={},onReadPixels:l,onUnrecognizedArgumentLookup:c}=t,p=new Proxy(e,{get:function(t,p){switch(p){case"addComment":return A;case"checkThrowError":return _;case"getReadPixelsVariableName":return m;case"insertVariable":return b;case"reset":return y;case"setIndent":return S;case"toString":return x;case"getContextVariableName":return E}return"function"==typeof e[p]?function(){switch(p){case"getError":return a?u.push(`${g}if (${r}.getError() !== ${r}.NONE) throw new Error('error');`):u.push(`${g}${r}.getError();`),e.getError();case"getExtension":{const t=`${r}Variables${d.length}`;u.push(`${g}const ${t} = ${r}.getExtension('${arguments[0]}');`);const s=e.getExtension(arguments[0]);if(s&&"object"==typeof s){const e=n(s,{getEntity:T,useTrackablePrimitives:o,recording:u,contextName:t,contextVariables:d,variables:h,indent:g,onUnrecognizedArgumentLookup:c});return d.push(e),e}return d.push(null),s}case"readPixels":const t=d.indexOf(arguments[6]);let i;if(-1===t){const e=function(e){if(h)for(const t in h)if(h[t]===e)return t;return null}(arguments[6]);e?(i=e,u.push(`${g}${e}`)):(i=`${r}Variable${d.length}`,d.push(arguments[6]),u.push(`${g}const ${i} = new ${arguments[6].constructor.name}(${arguments[6].length});`))}else i=`${r}Variable${t}`;m=i;const p=[arguments[0],arguments[1],arguments[2],arguments[3],T(arguments[4]),T(arguments[5]),i];return u.push(`${g}${r}.readPixels(${p.join(", ")});`),l&&l(i,p),e.readPixels.apply(e,arguments);case"drawBuffers":return u.push(`${g}${r}.drawBuffers([${s(arguments[0],{contextName:r,contextVariables:d,getEntity:T,addVariable:v,variables:h,onUnrecognizedArgumentLookup:c})}]);`),e.drawBuffers(arguments[0])}let t=e[p].apply(e,arguments);switch(typeof t){case"undefined":return void u.push(`${g}${w(p,arguments)};`);case"number":case"boolean":if(o&&-1===d.indexOf(i(t))){u.push(`${g}const ${r}Variable${d.length} = ${w(p,arguments)};`),d.push(t=i(t));break}default:null===t?u.push(`${w(p,arguments)};`):u.push(`${g}const ${r}Variable${d.length} = ${w(p,arguments)};`),d.push(t)}return t}:(f[e[p]]=p,e[p])}}),d=[],f={};let m,g="";return p;function x(){return u.join("\n")}function y(){for(;u.length>0;)u.pop()}function b(e,t){h[e]=t}function T(e){const t=f[e];return t?r+"."+t:e}function S(e){g=" ".repeat(e)}function v(e,t){const n=`${r}Variable${d.length}`;return u.push(`${g}const ${n} = ${t};`),d.push(e),n}function A(e){u.push(`${g}// ${e}`)}function _(){u.push(`${g}(() => {\n${g}const error = ${r}.getError();\n${g}if (error !== ${r}.NONE) {\n${g} const names = Object.getOwnPropertyNames(gl);\n${g} for (let i = 0; i < names.length; i++) {\n${g} const name = names[i];\n${g} if (${r}[name] === error) {\n${g} throw new Error('${r} threw ' + name);\n${g} }\n${g} }\n${g}}\n${g}})();`)}function w(e,t){return`${r}.${e}(${s(t,{contextName:r,contextVariables:d,getEntity:T,addVariable:v,variables:h,onUnrecognizedArgumentLookup:c})})`}function E(e){const t=d.indexOf(e);return-1!==t?`${r}Variable${t}`:null}}function n(e,t){const r=new Proxy(e,{get:function(t,r){return"function"==typeof t[r]?function(){if("drawBuffersWEBGL"===r)return l.push(`${p}${a}.drawBuffersWEBGL([${s(arguments[0],{contextName:a,contextVariables:o,getEntity:f,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})}]);`),e.drawBuffersWEBGL(arguments[0]);let t=e[r].apply(e,arguments);switch(typeof t){case"undefined":return void l.push(`${p}${m(r,arguments)};`);case"number":case"boolean":h&&-1===o.indexOf(i(t))?(l.push(`${p}const ${a}Variable${o.length} = ${m(r,arguments)};`),o.push(t=i(t))):(l.push(`${p}const ${a}Variable${o.length} = ${m(r,arguments)};`),o.push(t));break;default:null===t?l.push(`${m(r,arguments)};`):l.push(`${p}const ${a}Variable${o.length} = ${m(r,arguments)};`),o.push(t)}return t}:(n[e[r]]=r,e[r])}}),n={},{contextName:a,contextVariables:o,getEntity:u,useTrackablePrimitives:h,recording:l,variables:c,indent:p,onUnrecognizedArgumentLookup:d}=t;return r;function f(e){return n.hasOwnProperty(e)?`${a}.${n[e]}`:u(e)}function m(e,t){return`${a}.${e}(${s(t,{contextName:a,contextVariables:o,getEntity:f,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})})`}function g(e,t){const r=`${a}Variable${o.length}`;return o.push(e),l.push(`${p}const ${r} = ${t};`),r}}function s(e,t){const{variables:r,onUnrecognizedArgumentLookup:n}=t;return Array.from(e).map(e=>{const s=function(e){if(r)for(const t in r)if(r.hasOwnProperty(t)&&r[t]===e)return t;return n?n(e):null}(e);return s||function(e,t){const{contextName:r,contextVariables:n,getEntity:s,addVariable:i,onUnrecognizedArgumentLookup:a}=t;if(void 0===e)return"undefined";if(null===e)return"null";const o=n.indexOf(e);if(o>-1)return`${r}Variable${o}`;switch(e.constructor.name){case"String":const t=/\n/.test(e),r=/'/.test(e),n=/"/.test(e);return t?"`"+e+"`":r&&!n?'"'+e+'"':"'"+e+"'";case"Number":case"Boolean":return s(e);case"Array":return i(e,`new ${e.constructor.name}([${Array.from(e).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return i(e,`new ${e.constructor.name}(${JSON.stringify(Array.from(e))})`);default:if(a){const t=a(e);if(t)return t}throw new Error(`unrecognized argument type ${e.constructor.name}`)}}(e,t)}).join(", ")}function i(e){return new e.constructor(e)}void 0!==t&&(t.exports={glWiretap:r,glExtensionWiretap:n}),"undefined"!=typeof window&&(r.glExtensionWiretap=n,window.glWiretap=r)}),G=e((e,t)=>{const{glWiretap:r}=P(),{utils:n}=i();function s(e){let t=e.toString().replace(/^function /,"");const r=t.indexOf("=>");if(-1!==r&&!/[{]|\bfunction\b/.test(t.slice(0,r))){const e=t.slice(0,r).trim(),n=t.slice(r+2).trim();t=n.startsWith("{")?`${e} ${n}`:`${e} { return ${n}; }`}return t.replace(/utils[.]/g,"/*utils.*/")}function a(e,t){const r="single"===t.precision?e:`new Float32Array(${e}.buffer)`;return t.output[2]?`renderOutput(${r}, ${t.output[0]}, ${t.output[1]}, ${t.output[2]})`:t.output[1]?`renderOutput(${r}, ${t.output[0]}, ${t.output[1]})`:`renderOutput(${r}, ${t.output[0]})`}function o(e,t){const r=e.toArray.toString(),s=!/^function/.test(r);return`() => {\n function framebuffer() { return getReadFramebuffer(); };\n ${n.flattenFunctionToString(`${s?"function ":""}${r}`,{findDependency:(t,r)=>{if("utils"===t)return`const ${r} = ${n[r].toString()};`;if("this"===t)return"framebuffer"===r?"":`${s?"function ":""}${e[r].toString()}`;throw new Error("unhandled fromObject")},thisLookup:(r,n)=>{if("texture"===r)return t;if("context"===r)return n?null:"gl";if(e.hasOwnProperty(r))return JSON.stringify(e[r]);throw new Error(`unhandled thisLookup ${r}`)}})}\n return toArray();\n }`}function u(e,t,r,n,s){if(null===e)return null;if(null===t)return null;switch(typeof e){case"boolean":case"number":return null}if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement)for(let s=0;s{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}}):null;const c=[],p=[],d=r(i.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if(N.subKernels){if(f){const t=N.subKernels[m++].property;p.push(` result${isNaN(t)?"."+t:`[${t}]`} = ${a(e,N)};`)}else p.push(` const result = { result: ${a(e,N)} };`),f=!0;m===N.subKernels.length&&p.push(" return result;")}else e?p.push(` return ${a(e,N)};`):p.push(" return null;")},onUnrecognizedArgumentLookup:e=>{const t=u(e,N.kernelArguments,[],d,c);if(t)return t;const r=u(e,N.kernelConstants,v?Object.keys(v).map(e=>v[e]):[],d,c);return r||null}});let f=!1,m=0;const{source:g,canvas:x,output:y,pipeline:b,graphical:T,loopMaxIterations:S,constants:v,optimizeFloatMemory:A,precision:_,fixIntegerDivisionAccuracy:w,functions:E,nativeFunctions:I,subKernels:k,immutable:D,argumentTypes:C,constantTypes:L,kernelArguments:$,kernelConstants:F,tactic:R}=i,N=new e(g,{canvas:x,context:d,checkContext:!1,output:y,pipeline:b,graphical:T,loopMaxIterations:S,constants:v,optimizeFloatMemory:A,precision:_,fixIntegerDivisionAccuracy:w,functions:E,nativeFunctions:I,subKernels:k,immutable:D,argumentTypes:C,constantTypes:L,tactic:R});let V=[];if(d.setIndent(2),N.build.apply(N,t),V.push(d.toString()),d.reset(),N.kernelArguments.forEach((e,r)=>{switch(e.type){case"Integer":case"Boolean":case"Number":case"Float":case"Array":case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":case"Input":d.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let n=0;ne.varName).join(", ")}) {`),d.setIndent(4),N.run.apply(N,t),N.renderKernels?N.renderKernels():N.renderOutput&&N.renderOutput(),V.push(" /** start setup uploads for kernel values **/"),N.kernelArguments.forEach(e=>{V.push(" "+e.getStringValueHandler().split("\n").join("\n "))}),V.push(" /** end setup uploads for kernel values **/"),V.push(d.toString()),N.renderOutput===N.renderTexture)if(d.reset(),N.renderKernels){const e=N.renderKernels(),t=d.getContextVariableName(N.texture.texture);V.push(` return {\n result: {\n texture: ${t},\n type: '${e.result.type}',\n toArray: ${o(e.result,t)}\n },`);const{subKernels:r,mappedTextures:n}=N;for(let t=0;t"utils"===e?`const ${t} = ${n[t].toString()};`:null,thisLookup:t=>{if("context"===t)return null;if(e.hasOwnProperty(t))return JSON.stringify(e[t]);throw new Error(`unhandled thisLookup ${t}`)}})}(N)),V.push(" innerKernel.getPixels = getPixels;")),V.push(" return innerKernel;");let M=[];return F.forEach(e=>{M.push(`${e.getStringValueHandler()}`)}),`function kernel(settings) {\n const { context, constants } = settings;\n ${M.join("")}\n ${h||""}\n${V.join("\n")}\n}`}}}),z=e((e,t)=>{t.exports={KernelValue:class{constructor(e,t){const{name:r,kernel:n,context:s,checkContext:i,onRequestContextHandle:a,onUpdateValueMismatch:o,origin:u,strictIntegers:h,type:l,tactic:c}=t;if(!r)throw new Error("name not set");if(!l)throw new Error("type not set");if(!u)throw new Error("origin not set");if("user"!==u&&"constants"!==u)throw new Error(`origin must be "user" or "constants" value is "${u}"`);if(!a)throw new Error("onRequestContextHandle is not set");this.name=r,this.origin=u,this.tactic=c,this.varName="constants"===u?`constants.${r}`:r,this.kernel=n,this.strictIntegers=h,this.type=e.type||l,this.size=e.size||null,this.index=null,this.context=s,this.checkContext=null==i||i,this.contextHandle=null,this.onRequestContextHandle=a,this.onUpdateValueMismatch=o,this.forceUploadEachRun=null}get id(){return`${this.origin}_${name}`}getSource(){throw new Error(`"getSource" not defined on ${this.constructor.name}`)}updateValue(e){throw new Error(`"updateValue" not defined on ${this.constructor.name}`)}}}}),U=e((e,t)=>{const{utils:r}=i(),{KernelValue:n}=z();t.exports={WebGLKernelValue:class extends n{constructor(e,t){super(e,t),this.dimensionsId=null,this.sizeId=null,this.initialValueConstructor=e.constructor,this.onRequestTexture=t.onRequestTexture,this.onRequestIndex=t.onRequestIndex,this.uploadValue=null,this.textureSize=null,this.bitRatio=null,this.prevArg=null}get id(){return`${this.origin}_${r.sanitizeName(this.name)}`}setup(){}getTransferArrayType(e){if(Array.isArray(e[0]))return this.getTransferArrayType(e[0]);switch(e.constructor){case Array:case Int32Array:case Int16Array:case Int8Array:return Float32Array;case Uint8ClampedArray:case Uint8Array:case Uint16Array:case Uint32Array:case Float32Array:case Float64Array:return e.constructor}return console.warn("Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros"),e.constructor}getStringValueHandler(){throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`)}getVariablePrecisionString(){return this.kernel.getVariablePrecisionString(this.textureSize||void 0,this.tactic||void 0)}destroy(){}}}}),K=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValue:n}=U();t.exports={WebGLKernelValueBoolean:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const bool ${this.id} = ${e};\n`:`uniform bool ${this.id};\n`}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),B=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValue:n}=U();t.exports={WebGLKernelValueFloat:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?Number.isInteger(e)?`const float ${this.id} = ${e}.0;\n`:`const float ${this.id} = ${e};\n`:`uniform float ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1f(this.id,this.uploadValue=e)}}}}),W=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValue:n}=U();t.exports={WebGLKernelValueInteger:class extends n{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?`const int ${this.id} = ${parseInt(e)};\n`:`uniform int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),j=e((e,t)=>{const{WebGLKernelValue:r}=U(),{Input:s}=n();t.exports={WebGLKernelArray:class extends r{checkSize(e,t){if(!this.kernel.validate)return;const{maxTextureSize:r}=this.kernel.constructor.features;if(e>r||t>r)throw e>t?new Error(`Argument texture width of ${e} larger than maximum size of ${r} for your GPU`):e{const{utils:r}=i(),{WebGLKernelArray:n}=j();function s(e){return{width:e.width>0?e.width:e.videoWidth,height:e.height>0?e.height:e.videoHeight}}t.exports={WebGLKernelValueHTMLImage:class extends n{constructor(e,t){super(e,t);const{width:r,height:n}=s(e);this.checkSize(r,n),this.dimensions=[r,n,1],this.textureSize=[r,n],this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue=e),this.kernel.setUniform1i(this.id,this.index)}},mediaSize:s}}),X=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueHTMLImage:n,mediaSize:s}=H();t.exports={WebGLKernelValueDynamicHTMLImage:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:r}=s(e);this.checkSize(t,r),this.dimensions=[t,r,1],this.textureSize=[t,r],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),q=e((e,t)=>{const{WebGLKernelValueHTMLImage:r}=H();t.exports={WebGLKernelValueHTMLVideo:class extends r{}}}),Y=e((e,t)=>{const{WebGLKernelValueDynamicHTMLImage:r}=X();t.exports={WebGLKernelValueDynamicHTMLVideo:class extends r{}}}),Z=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=j();t.exports={WebGLKernelValueSingleInput:class extends n{constructor(e,t){super(e,t),this.bitRatio=4;let[n,s,i]=e.size;this.dimensions=new Int32Array([n||1,s||1,i||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}.value, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),J=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleInput:n}=Z();t.exports={WebGLKernelValueDynamicSingleInput:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,s]=e.size;this.dimensions=new Int32Array([t||1,n||1,s||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Q=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=j();t.exports={WebGLKernelValueUnsignedInput:class extends n{constructor(e,t){super(e,t),this.bitRatio=this.getBitRatio(e);const[n,s,i]=e.size;this.dimensions=new Int32Array([n||1,s||1,i||1]),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]),this.TranserArrayType=this.getTransferArrayType(e.value),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return r.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}.value, preUploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(value.constructor);const{context:t}=this;r.flattenTo(e.value,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ee=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedInput:n}=Q();t.exports={WebGLKernelValueDynamicUnsignedInput:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,s]=e.size;this.dimensions=new Int32Array([t||1,n||1,s||1]),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]);const i=this.getTransferArrayType(e.value);this.preUploadValue=new i(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),te=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=j(),s="Source and destination textures are the same. Use immutable = true and manually cleanup kernel output texture memory with texture.delete()";t.exports={WebGLKernelValueMemoryOptimizedNumberTexture:class extends n{constructor(e,t){super(e,t);const[r,n]=e.size;this.checkSize(r,n),this.dimensions=e.dimensions,this.textureSize=e.size,this.uploadValue=e.texture,this.forceUploadEachRun=!0}setup(){this.setupTexture()}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{kernel:t,context:r}=this;if(t.pipeline)if(t.immutable)t.updateTextureArgumentRefs(this,e);else{if(t.texture&&t.texture.texture===e.texture)throw new Error(s);if(t.mappedTextures){const{mappedTextures:r}=t;for(let t=0;t{const{utils:r}=i(),{WebGLKernelValueMemoryOptimizedNumberTexture:n}=te();t.exports={WebGLKernelValueDynamicMemoryOptimizedNumberTexture:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ne=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=j(),{sameError:s}=te();t.exports={WebGLKernelValueNumberTexture:class extends n{constructor(e,t){super(e,t);const[r,n]=e.size;this.checkSize(r,n);const{size:s,dimensions:i}=e;this.bitRatio=this.getBitRatio(e),this.dimensions=i,this.textureSize=s,this.uploadValue=e.texture,this.forceUploadEachRun=!0}setup(){this.setupTexture()}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{kernel:t,context:r}=this;if(t.pipeline)if(t.immutable)t.updateTextureArgumentRefs(this,e);else{if(t.texture&&t.texture.texture===e.texture)throw new Error(s);if(t.mappedTextures){const{mappedTextures:r}=t;for(let t=0;t{const{utils:r}=i(),{WebGLKernelValueNumberTexture:n}=ne();t.exports={WebGLKernelValueDynamicNumberTexture:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ie=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=j();t.exports={WebGLKernelValueSingleArray:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ae=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray:n}=ie();t.exports={WebGLKernelValueDynamicSingleArray:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),oe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=j();t.exports={WebGLKernelValueSingleArray1DI:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],1,1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flatten2dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),ue=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray1DI:n}=oe();t.exports={WebGLKernelValueDynamicSingleArray1DI:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),he=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=j();t.exports={WebGLKernelValueSingleArray2DI:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flatten3dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),le=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray2DI:n}=he();t.exports={WebGLKernelValueDynamicSingleArray2DI:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ce=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=j();t.exports={WebGLKernelValueSingleArray3DI:class extends n{constructor(e,t){super(e,t),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],t[3]]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flatten4dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),pe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray3DI:n}=ce();t.exports={WebGLKernelValueDynamicSingleArray3DI:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),de=e((e,t)=>{const{WebGLKernelValue:r}=U();t.exports={WebGLKernelValueArray2:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec2 ${this.id} = vec2(${e[0]},${e[1]});\n`:`uniform vec2 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform2fv(this.id,this.uploadValue=e)}}}}),fe=e((e,t)=>{const{WebGLKernelValue:r}=U();t.exports={WebGLKernelValueArray3:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec3 ${this.id} = vec3(${e[0]},${e[1]},${e[2]});\n`:`uniform vec3 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform3fv(this.id,this.uploadValue=e)}}}}),me=e((e,t)=>{const{WebGLKernelValue:r}=U();t.exports={WebGLKernelValueArray4:class extends r{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec4 ${this.id} = vec4(${e[0]},${e[1]},${e[2]},${e[3]});\n`:`uniform vec4 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform4fv(this.id,this.uploadValue=e)}}}}),ge=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=j();t.exports={WebGLKernelValueUnsignedArray:class extends n{constructor(e,t){super(e,t),this.bitRatio=this.getBitRatio(e),this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]),this.TranserArrayType=this.getTransferArrayType(e),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return r.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}, preUploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),xe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedArray:n}=ge();t.exports={WebGLKernelValueDynamicUnsignedArray:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0],this.textureSize[1]);const t=this.getTransferArrayType(e);this.preUploadValue=new t(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),ye=e((e,t)=>{const{WebGLKernelValueBoolean:r}=K(),{WebGLKernelValueFloat:n}=B(),{WebGLKernelValueInteger:s}=W(),{WebGLKernelValueHTMLImage:i}=H(),{WebGLKernelValueDynamicHTMLImage:a}=X(),{WebGLKernelValueHTMLVideo:o}=q(),{WebGLKernelValueDynamicHTMLVideo:u}=Y(),{WebGLKernelValueSingleInput:h}=Z(),{WebGLKernelValueDynamicSingleInput:l}=J(),{WebGLKernelValueUnsignedInput:c}=Q(),{WebGLKernelValueDynamicUnsignedInput:p}=ee(),{WebGLKernelValueMemoryOptimizedNumberTexture:d}=te(),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:f}=re(),{WebGLKernelValueNumberTexture:m}=ne(),{WebGLKernelValueDynamicNumberTexture:g}=se(),{WebGLKernelValueSingleArray:x}=ie(),{WebGLKernelValueDynamicSingleArray:y}=ae(),{WebGLKernelValueSingleArray1DI:b}=oe(),{WebGLKernelValueDynamicSingleArray1DI:T}=ue(),{WebGLKernelValueSingleArray2DI:S}=he(),{WebGLKernelValueDynamicSingleArray2DI:v}=le(),{WebGLKernelValueSingleArray3DI:A}=ce(),{WebGLKernelValueDynamicSingleArray3DI:_}=pe(),{WebGLKernelValueArray2:w}=de(),{WebGLKernelValueArray3:E}=fe(),{WebGLKernelValueArray4:I}=me(),{WebGLKernelValueUnsignedArray:k}=ge(),{WebGLKernelValueDynamicUnsignedArray:D}=xe(),C={unsigned:{dynamic:{Boolean:r,Integer:s,Float:n,Array:D,"Array(2)":w,"Array(3)":E,"Array(4)":I,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:p,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:f,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u},static:{Boolean:r,Float:n,Integer:s,Array:k,"Array(2)":w,"Array(3)":E,"Array(4)":I,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:c,NumberTexture:m,"ArrayTexture(1)":m,"ArrayTexture(2)":m,"ArrayTexture(3)":m,"ArrayTexture(4)":m,MemoryOptimizedNumberTexture:d,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:!1,HTMLVideo:o}},single:{dynamic:{Boolean:r,Integer:s,Float:n,Array:y,"Array(2)":w,"Array(3)":E,"Array(4)":I,"Array1D(2)":T,"Array1D(3)":T,"Array1D(4)":T,"Array2D(2)":v,"Array2D(3)":v,"Array2D(4)":v,"Array3D(2)":_,"Array3D(3)":_,"Array3D(4)":_,Input:l,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:f,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u},static:{Boolean:r,Float:n,Integer:s,Array:x,"Array(2)":w,"Array(3)":E,"Array(4)":I,"Array1D(2)":b,"Array1D(3)":b,"Array1D(4)":b,"Array2D(2)":S,"Array2D(3)":S,"Array2D(4)":S,"Array3D(2)":A,"Array3D(3)":A,"Array3D(4)":A,Input:h,NumberTexture:m,"ArrayTexture(1)":m,"ArrayTexture(2)":m,"ArrayTexture(3)":m,"ArrayTexture(4)":m,MemoryOptimizedNumberTexture:d,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:!1,HTMLVideo:o}}};t.exports={lookupKernelValueType:function(e,t,r,n){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!r)throw new Error("precision missing");n.type&&(e=n.type);const s=C[r][t];if("WebGPUBuffer"===e)throw new Error("this kernel runs on WebGL but received a WebGPU pipeline buffer; await handle.toArray() first, or give this kernel the async contract (asyncMode: true / mode: 'async') so the readback happens for you");if(!1===s[e])return null;if(void 0===s[e])throw new Error(`Could not find a KernelValue for ${e}`);return s[e]},kernelValueMaps:C}}),be=e((e,t)=>{const{GLKernel:r}=R(),{FunctionBuilder:n}=o(),{WebGLFunctionNode:s}=N(),{utils:a}=i(),u=V(),{fragmentShader:h}=M(),{vertexShader:l}=O(),{glKernelString:c}=G(),{lookupKernelValueType:p}=ye();let d=null,f=null,m=null,g=null,x=null;const y=[u],b=[],T={};t.exports={WebGLKernel:class extends r{static get isSupported(){return null!==d||(this.setupFeatureChecks(),d=this.isContextMatch(m)),d}static setupFeatureChecks(){"undefined"!=typeof document?f=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(f=new OffscreenCanvas(0,0)),f&&(m=f.getContext("webgl"),m||f instanceof OffscreenCanvas||(m=f.getContext("experimental-webgl")),m&&m.getExtension&&(g={OES_texture_float:m.getExtension("OES_texture_float"),OES_texture_float_linear:m.getExtension("OES_texture_float_linear"),OES_element_index_uint:m.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:m.getExtension("WEBGL_draw_buffers")},x=this.getFeatures()))}static isContextMatch(e){return"undefined"!=typeof WebGLRenderingContext&&e instanceof WebGLRenderingContext}static getIsTextureFloat(){return Boolean(g.OES_texture_float)}static getIsDrawBuffers(){return Boolean(g.WEBGL_draw_buffers)}static getChannelCount(){return g.WEBGL_draw_buffers?m.getParameter(g.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return m.getParameter(m.MAX_TEXTURE_SIZE)}static lookupKernelValueType(e,t,r,n){return p(e,t,r,n)}static get testCanvas(){return f}static get testContext(){return m}static get features(){return x}static get fragmentShader(){return h}static get vertexShader(){return l}constructor(e,t){super(e,t),this.program=null,this.pipeline=t.pipeline,this.endianness=a.systemEndianness(),this.extensions={},this.argumentTextureCount=0,this.constantTextureCount=0,this.fragShader=null,this.vertShader=null,this.drawBuffersMap=null,this.maxTexSize=null,this.onRequestSwitchKernel=null,this.texture=null,this.mappedTextures=null,this.mergeSettings(e.settings||t),this.threadDim=null,this.framebuffer=null,this.buffer=null,this.textureCache=[],this.programUniformLocationCache={},this.uniform1fCache={},this.uniform1iCache={},this.uniform2fCache={},this.uniform2fvCache={},this.uniform2ivCache={},this.uniform3fvCache={},this.uniform3ivCache={},this.uniform4fvCache={},this.uniform4ivCache={}}initCanvas(){if("undefined"!=typeof document){const e=document.createElement("canvas");return e.width=2,e.height=2,e}if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(0,0)}initContext(){const e={alpha:!1,depth:!1,antialias:!1};return this.canvas.getContext("webgl",e)||this.canvas.getContext("experimental-webgl",e)}initPlugins(e){const t=[],{source:r}=this;if("string"==typeof r)for(let e=0;ee===n.name)&&t.push(n)}return t}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if(!0===this.optimizeFloatMemory&&!t.isTextureFloat)throw new Error("Float textures are not supported");if("single"===this.precision&&!t.isFloatRead)throw new Error("Single precision not supported");if(this.graphical||null!==this.precision||(this.precision=t.isTextureFloat&&t.isFloatRead?"single":"unsigned"),this.subKernels&&this.subKernels.length>0&&!this.extensions.WEBGL_draw_buffers)throw new Error("could not instantiate draw buffers extension");if(null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);switch(t){case"Array":this.output=a.getDimensions(t);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=e[0].output;break;default:throw new Error("Auto output not supported for input type: "+t)}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"precision"===this.precision&&(this.precision="unsigned",console.warn("Cannot use graphical mode and single precision at the same time")),void(this.texSize=a.clone(this.output))}null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}updateMaxTexSize(){const{texSize:e,canvas:t}=this;if(null===this.maxTexSize){let r=b.indexOf(t);-1===r&&(r=b.length,b.push(t),T[r]=[e[0],e[1]]),this.maxTexSize=T[r]}this.maxTexSize[0]this.argumentNames.length)throw new Error("too many arguments for kernel");const{context:r}=this;let n=0;const s=()=>this.createTexture(),i=()=>this.constantTextureCount+n++,o=e=>{this.switchKernels({type:"argumentMismatch",needed:e})},u=()=>r.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++;for(let n=0;nthis.createTexture(),onRequestIndex:()=>n++,onRequestContextHandle:()=>t.TEXTURE0+this.constantTextureCount++});this.constantBitRatios[s]=h.bitRatio,this.kernelConstants.push(h),h.setup(),h.forceUploadEachRun&&this.forceUploadKernelConstants.push(h)}}build(){if(this.built)return;if(this.initExtensions(),this.validateSettings(arguments),this.setupConstants(arguments),this.fallbackRequested)return;if(this.setupArguments(arguments),this.fallbackRequested)return;this.updateMaxTexSize(),this.translateSource();const e=this.pickRenderStrategy(arguments);if(e)return e;const{texSize:t,context:r,canvas:n}=this;r.enable(r.SCISSOR_TEST),this.pipeline&&this.precision,r.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]),n.width=this.maxTexSize[0],n.height=this.maxTexSize[1];const s=this.threadDim=Array.from(this.output);for(;s.length<3;)s.push(1);const i=this.getVertexShader(arguments),a=r.createShader(r.VERTEX_SHADER);r.shaderSource(a,i),r.compileShader(a),this.vertShader=a;const o=this.getFragmentShader(arguments),u=r.createShader(r.FRAGMENT_SHADER);if(r.shaderSource(u,o),r.compileShader(u),this.fragShader=u,this.debug&&(console.log("GLSL Shader Output:"),console.log(o)),!r.getShaderParameter(a,r.COMPILE_STATUS))throw new Error("Error compiling vertex shader: "+r.getShaderInfoLog(a));if(!r.getShaderParameter(u,r.COMPILE_STATUS))throw new Error("Error compiling fragment shader: "+r.getShaderInfoLog(u));const h=this.program=r.createProgram();r.attachShader(h,a),r.attachShader(h,u),r.linkProgram(h),this.framebuffer=r.createFramebuffer(),this.framebuffer.width=t[0],this.framebuffer.height=t[1],this.rawValueFramebuffers={};const l=new Float32Array([-1,-1,1,-1,-1,1,1,1]),c=new Float32Array([0,0,1,0,0,1,1,1]),p=l.byteLength;let d=this.buffer;d?r.bindBuffer(r.ARRAY_BUFFER,d):(d=this.buffer=r.createBuffer(),r.bindBuffer(r.ARRAY_BUFFER,d),r.bufferData(r.ARRAY_BUFFER,l.byteLength+c.byteLength,r.STATIC_DRAW)),r.bufferSubData(r.ARRAY_BUFFER,0,l),r.bufferSubData(r.ARRAY_BUFFER,p,c);const f=r.getAttribLocation(this.program,"aPos");-1!==f&&(r.enableVertexAttribArray(f),r.vertexAttribPointer(f,2,r.FLOAT,!1,0,0));const m=r.getAttribLocation(this.program,"aTexCoord");-1!==m&&(r.enableVertexAttribArray(m),r.vertexAttribPointer(m,2,r.FLOAT,!1,0,p)),r.bindFramebuffer(r.FRAMEBUFFER,this.framebuffer);let g=0;r.useProgram(this.program);for(let e in this.constants)this.kernelConstants[g++].updateValue(this.constants[e]);this._setupOutputTexture(),null!==this.subKernels&&this.subKernels.length>0&&(this._mappedTextureSwitched={},this._setupSubOutputTextures()),this.buildSignature(arguments),this.built=!0}translateSource(){const e=n.fromKernel(this,s,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=e.getPrototypeString("kernel"),this.setupReturnTypes(e)}setupReturnTypes(e){if(this.graphical||this.returnType||(this.returnType=e.getKernelResultType()),this.subKernels&&this.subKernels.length>0)for(let t=0;te.source&&this.source.match(e.functionMatch)?e.source:"").join("\n"):"\n"}_getConstantsString(){const e=[],{threadDim:t,texSize:r}=this;return this.dynamicOutput?e.push("uniform ivec3 uOutputDim","uniform ivec2 uTexSize"):e.push(`ivec3 uOutputDim = ivec3(${t[0]}, ${t[1]}, ${t[2]})`,`ivec2 uTexSize = ivec2(${r[0]}, ${r[1]})`),a.linesToString(e)}_getTextureCoordinate(){const e=this.subKernels;return null===e||e.length<1?"varying vec2 vTexCoord;\n":"out vec2 vTexCoord;\n"}_getDecode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getEncode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getDivideWithIntegerCheckString(){return this.fixIntegerDivisionAccuracy?"float divWithIntCheck(float x, float y) {\n if (floor(x) == x && floor(y) == y) {\n float q = floor(x / y + 0.5);\n if (y * q == x) {\n return q;\n }\n }\n return x / y;\n}\n\nfloat integerCorrectionModulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -(number - (divisor * floor(divWithIntCheck(number, divisor))));\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return number - (divisor * floor(divWithIntCheck(number, divisor)));\n}":""}_getMainArgumentsString(e){const t=[],{argumentNames:r}=this;for(let n=0;n{if(t.hasOwnProperty(r))return t[r];throw`unhandled artifact ${r}`})}getFragmentShader(e){return null!==this.compiledFragmentShader?this.compiledFragmentShader:this.compiledFragmentShader=this.replaceArtifacts(this.constructor.fragmentShader,this._getFragShaderArtifactMap(e))}getVertexShader(e){return null!==this.compiledVertexShader?this.compiledVertexShader:this.compiledVertexShader=this.replaceArtifacts(this.constructor.vertexShader,this._getVertShaderArtifactMap(e))}toString(){const e=a.linesToString(["const gl = context"]);return c(this.constructor,arguments,this,e)}destroy(e){if(!this.context)return;this.buffer&&this.context.deleteBuffer(this.buffer),this.framebuffer&&this.context.deleteFramebuffer(this.framebuffer);for(const e in this.rawValueFramebuffers){for(const t in this.rawValueFramebuffers[e])this.context.deleteFramebuffer(this.rawValueFramebuffers[e][t]),delete this.rawValueFramebuffers[e][t];delete this.rawValueFramebuffers[e]}if(this.vertShader&&this.context.deleteShader(this.vertShader),this.fragShader&&this.context.deleteShader(this.fragShader),this.program&&this.context.deleteProgram(this.program),this.texture){this.texture.delete();const e=this.textureCache.indexOf(this.texture.texture);e>-1&&this.textureCache.splice(e,1),this.texture=null}if(this.mappedTextures&&this.mappedTextures.length){for(let e=0;e-1&&this.textureCache.splice(r,1)}this.mappedTextures=null}if(this.kernelArguments)for(let e=0;e0;){const e=this.textureCache.pop();this.context.deleteTexture(e)}if(e){const e=b.indexOf(this.canvas);e>=0&&(b[e]=null,T[e]=null)}if(this.destroyExtensions(),delete this.context,delete this.canvas,!this.gpu)return;const t=this.gpu.kernels.indexOf(this);-1!==t&&this.gpu.kernels.splice(t,1)}destroyExtensions(){this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("WEBGL_lose_context");t&&t.loseContext()}toJSON(){const e=super.toJSON();return e.functionNodes=n.fromKernel(this,s).toJSON(),e.settings.threadDim=this.threadDim,e}}}}),Te=e((e,t)=>{const r=d(),{WebGLKernel:n}=be(),{glKernelString:s}=G();let i=null,a=null,o=null,u=null,h=null;t.exports={HeadlessGLKernel:class extends n{static get isSupported(){return null!==i||(this.setupFeatureChecks(),i=null!==o),i}static setupFeatureChecks(){if(a=null,u=null,"function"==typeof r)try{if(o=r(2,2,{preserveDrawingBuffer:!0}),!o||!o.getExtension)return;u={STACKGL_resize_drawingbuffer:o.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:o.getExtension("STACKGL_destroy_context"),OES_texture_float:o.getExtension("OES_texture_float"),OES_texture_float_linear:o.getExtension("OES_texture_float_linear"),OES_element_index_uint:o.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:o.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:o.getExtension("WEBGL_color_buffer_float")},h=this.getFeatures()}catch(e){console.warn(e)}}static isContextMatch(e){try{return"ANGLE"===e.getParameter(e.RENDERER)}catch(e){return!1}}static getIsTextureFloat(){return Boolean(u.OES_texture_float)}static getIsDrawBuffers(){return Boolean(u.WEBGL_draw_buffers)}static getChannelCount(){return u.WEBGL_draw_buffers?o.getParameter(u.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return o.getParameter(o.MAX_TEXTURE_SIZE)}static get testCanvas(){return a}static get testContext(){return o}static get features(){return h}initCanvas(){return{}}initContext(){return r(2,2,{preserveDrawingBuffer:!0})}initExtensions(){this.extensions={STACKGL_resize_drawingbuffer:this.context.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:this.context.getExtension("STACKGL_destroy_context"),OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers")}}build(){super.build.apply(this,arguments),this.fallbackRequested||this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}destroyExtensions(){this.extensions.STACKGL_resize_drawingbuffer=null,this.extensions.STACKGL_destroy_context=null,this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("STACKGL_destroy_context");t&&t.destroy&&t.destroy()}toString(){return s(this.constructor,arguments,this,"const gl = context || require('gl')(1, 1);\n"," if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n")}setOutput(e){return super.setOutput(e),this.graphical&&this.extensions.STACKGL_resize_drawingbuffer&&this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1]),this}}}}),Se=e((e,t)=>{const{utils:r}=i(),{WebGLFunctionNode:n}=N();t.exports={WebGL2FunctionNode:class extends n{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),s=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===n&&this.argumentNames.indexOf(s)>-1?t.push(`bool(user_${s})`):t.push(`user_${s}`),t}}}}),ve=e((e,t)=>{t.exports={fragmentShader:`#version 300 es\n__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nin vec2 vTexCoord;\n\nfloat atan2(float v1, float v2) {\n if (v2 == 0.0) {\n if (v1 == 0.0) return 0.0;\n if (v1 > 0.0) return 1.5707963267948966;\n if (v1 < 0.0) return -1.5707963267948966;\n }\n return atan(v1, v2);\n}\n\nfloat cbrt(float x) {\n if (x >= 0.0) {\n return pow(x, 1.0 / 3.0);\n } else {\n return -pow(x, 1.0 / 3.0);\n }\n}\n\nfloat expm1(float x) {\n return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n return x;\n}\n\nfloat imul(float v1, float v2) {\n return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n if (v2 == 0.0) return 1.0;\n return pow(v1, v2);\n}\n\nfloat _round(float x) {\n return floor(x + 0.5);\n}\n\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n // ~a is identically -a - 1 in two's complement, for every value including\n // negatives. The previous bit-by-bit loop only worked for a >= 0, where it\n // leaned on 32-bit overflow wrapping to reach the negative answer; given a\n // negative input it computed ~abs(a), so ~(-1) gave -2 and ~~x never\n // returned x.\n return -a - 1;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\n// _pow2 is defined further down, alongside encode32/decode32\nfloat _pow2(float e);\nint bitwiseSignedRightShift(int num, int shifts) {\n // pow(2.0, n) is approximate on many GPUs, and landing 1 ulp high makes the\n // division fall just under a whole number, which floor() then rounds away:\n // 2 >> 1 came out 0, 8 >> 1 came out 3. Only exact left operands were\n // affected, odd ones having enough slack to survive. _pow2 is exact.\n return int(floor(float(num) / _pow2(float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x/y));\n}\n\n// GLSL ES 1.00 accepts only a constant or a loop symbol inside an index\n// expression, so m[y][x] does not compile when y and x come from kernel\n// arguments -- the error is "Index expression can only contain const or loop\n// symbols". Loop counters are legal indices, so walk the matrix with them\n// instead. These are 2x2 to 4x4, so it costs at most sixteen comparisons.\nfloat getMatrix2(mat2 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 2; i++) {\n for (int j = 0; j < 2; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix3(mat3 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 3; i++) {\n for (int j = 0; j < 3; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\nfloat getMatrix4(mat4 m, int y, int x) {\n float result = 0.0;\n for (int i = 0; i < 4; i++) {\n for (int j = 0; j < 4; j++) {\n if (i == y && j == x) result = m[i][j];\n }\n }\n return result;\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\n// Exact powers of two built from exact constant multiplies: exp2/log2/pow\n// are approximate on some GPUs (notably Apple silicon), and 1-2 ulp there\n// corrupts the packed bytes (#659)\nfloat _pow2(float e) {\n float r = 1.0;\n float a = abs(e);\n bool n = e < 0.0;\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 64.0) { r *= n ? 5.421010862427522e-20 : 18446744073709551616.0; a -= 64.0; }\n if (a >= 32.0) { r *= n ? 2.3283064365386963e-10 : 4294967296.0; a -= 32.0; }\n if (a >= 16.0) { r *= n ? 0.0000152587890625 : 65536.0; a -= 16.0; }\n if (a >= 8.0) { r *= n ? 0.00390625 : 256.0; a -= 8.0; }\n if (a >= 4.0) { r *= n ? 0.0625 : 16.0; a -= 4.0; }\n if (a >= 2.0) { r *= n ? 0.25 : 4.0; a -= 2.0; }\n if (a >= 1.0) { r *= n ? 0.5 : 2.0; }\n return r;\n}\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = _pow2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * _pow2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n return texel[channel] * 255.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n float p2 = _pow2(exponent);\n // approximate log2 can land one off; correct by direct comparison\n if (p2 > value) { exponent -= 1.0; p2 *= 0.5; }\n else if (p2 * 2.0 <= value) { exponent += 1.0; p2 *= 2.0; }\n\n mantissa = value / p2 - 1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n index = index / 4;\n vec4 texel = texture(tex, st / vec2(texSize));\n return texel[channel];\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, st / vec2(texSize));\n}\n\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, vec3(st / vec2(texSize), z));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n\n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nfloat modulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -mod(number, divisor);\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}`}}),Ae=e((e,t)=>{t.exports={vertexShader:"#version 300 es\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nin vec2 aPos;\nin vec2 aTexCoord;\n\nout vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"}}),_e=e((e,t)=>{const{WebGLKernelValueBoolean:r}=K();t.exports={WebGL2KernelValueBoolean:class extends r{}}}),we=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueFloat:n}=B();t.exports={WebGL2KernelValueFloat:class extends n{}}}),Ee=e((e,t)=>{const{WebGLKernelValueInteger:r}=W();t.exports={WebGL2KernelValueInteger:class extends r{getSource(e){const t=this.getVariablePrecisionString();return"constants"===this.origin?`const ${t} int ${this.id} = ${parseInt(e)};\n`:`uniform ${t} int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}}),Ie=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueHTMLImage:n}=H();t.exports={WebGL2KernelValueHTMLImage:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),ke=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicHTMLImage:n}=X();t.exports={WebGL2KernelValueDynamicHTMLImage:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),De=e((e,t)=>{const{utils:r}=i(),{WebGLKernelArray:n}=j();t.exports={WebGL2KernelValueHTMLImageArray:class extends n{constructor(e,t){super(e,t),this.checkSize(e[0].width,e[0].height),this.dimensions=[e[0].width,e[0].height,e.length],this.textureSize=[e[0].width,e[0].height]}defineTexture(){const{context:e}=this;e.activeTexture(this.contextHandle),e.bindTexture(e.TEXTURE_2D_ARRAY,this.texture),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MIN_FILTER,e.NEAREST)}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D_ARRAY,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage3D(t.TEXTURE_2D_ARRAY,0,t.RGBA,e[0].width,e[0].height,e.length,0,t.RGBA,t.UNSIGNED_BYTE,null);for(let r=0;r{const{utils:r}=i(),{WebGL2KernelValueHTMLImageArray:n}=De();t.exports={WebGL2KernelValueDynamicHTMLImageArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:r}=e[0];this.checkSize(t,r),this.dimensions=[t,r,e.length],this.textureSize=[t,r],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Le=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueHTMLImage:n}=Ie();t.exports={WebGL2KernelValueHTMLVideo:class extends n{}}}),$e=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueDynamicHTMLImage:n}=ke();t.exports={WebGL2KernelValueDynamicHTMLVideo:class extends n{}}}),Fe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleInput:n}=Z();t.exports={WebGL2KernelValueSingleInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;r.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Re=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleInput:n}=Fe();t.exports={WebGL2KernelValueDynamicSingleInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,s]=e.size;this.dimensions=new Int32Array([t||1,n||1,s||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Ne=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedInput:n}=Q();t.exports={WebGL2KernelValueUnsignedInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),Ve=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicUnsignedInput:n}=ee();t.exports={WebGL2KernelValueDynamicUnsignedInput:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),Me=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueMemoryOptimizedNumberTexture:n}=te();t.exports={WebGL2KernelValueMemoryOptimizedNumberTexture:class extends n{getSource(){const{id:e,sizeId:t,textureSize:n,dimensionsId:s,dimensions:i}=this,a=this.getVariablePrecisionString();return r.linesToString([`uniform sampler2D ${e}`,`${a} ivec2 ${t} = ivec2(${n[0]}, ${n[1]})`,`${a} ivec3 ${s} = ivec3(${i[0]}, ${i[1]}, ${i[2]})`])}}}}),Oe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:n}=re();t.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:class extends n{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}}}),Pe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueNumberTexture:n}=ne();t.exports={WebGL2KernelValueNumberTexture:class extends n{getSource(){const{id:e,sizeId:t,textureSize:n,dimensionsId:s,dimensions:i}=this,a=this.getVariablePrecisionString();return r.linesToString([`uniform ${a} sampler2D ${e}`,`${a} ivec2 ${t} = ivec2(${n[0]}, ${n[1]})`,`${a} ivec3 ${s} = ivec3(${i[0]}, ${i[1]}, ${i[2]})`])}}}}),Ge=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicNumberTexture:n}=se();t.exports={WebGL2KernelValueDynamicNumberTexture:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),ze=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray:n}=ie();t.exports={WebGL2KernelValueSingleArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Ue=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray:n}=ze();t.exports={WebGL2KernelValueDynamicSingleArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),Ke=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray1DI:n}=oe();t.exports={WebGL2KernelValueSingleArray1DI:class extends n{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Be=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray1DI:n}=Ke();t.exports={WebGL2KernelValueDynamicSingleArray1DI:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),We=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray2DI:n}=he();t.exports={WebGL2KernelValueSingleArray2DI:class extends n{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),je=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray2DI:n}=We();t.exports={WebGL2KernelValueDynamicSingleArray2DI:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),He=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueSingleArray3DI:n}=ce();t.exports={WebGL2KernelValueSingleArray3DI:class extends n{updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch(e.constructor);const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}}),Xe=e((e,t)=>{const{utils:r}=i(),{WebGL2KernelValueSingleArray3DI:n}=He();t.exports={WebGL2KernelValueDynamicSingleArray3DI:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}}),qe=e((e,t)=>{const{WebGLKernelValueArray2:r}=de();t.exports={WebGL2KernelValueArray2:class extends r{}}}),Ye=e((e,t)=>{const{WebGLKernelValueArray3:r}=fe();t.exports={WebGL2KernelValueArray3:class extends r{}}}),Ze=e((e,t)=>{const{WebGLKernelValueArray4:r}=me();t.exports={WebGL2KernelValueArray4:class extends r{}}}),Je=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueUnsignedArray:n}=ge();t.exports={WebGL2KernelValueUnsignedArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}}}),Qe=e((e,t)=>{const{utils:r}=i(),{WebGLKernelValueDynamicUnsignedArray:n}=xe();t.exports={WebGL2KernelValueDynamicUnsignedArray:class extends n{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}}),et=e((e,t)=>{const{WebGL2KernelValueBoolean:r}=_e(),{WebGL2KernelValueFloat:n}=we(),{WebGL2KernelValueInteger:s}=Ee(),{WebGL2KernelValueHTMLImage:i}=Ie(),{WebGL2KernelValueDynamicHTMLImage:a}=ke(),{WebGL2KernelValueHTMLImageArray:o}=De(),{WebGL2KernelValueDynamicHTMLImageArray:u}=Ce(),{WebGL2KernelValueHTMLVideo:h}=Le(),{WebGL2KernelValueDynamicHTMLVideo:l}=$e(),{WebGL2KernelValueSingleInput:c}=Fe(),{WebGL2KernelValueDynamicSingleInput:p}=Re(),{WebGL2KernelValueUnsignedInput:d}=Ne(),{WebGL2KernelValueDynamicUnsignedInput:f}=Ve(),{WebGL2KernelValueMemoryOptimizedNumberTexture:m}=Me(),{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:g}=Oe(),{WebGL2KernelValueNumberTexture:x}=Pe(),{WebGL2KernelValueDynamicNumberTexture:y}=Ge(),{WebGL2KernelValueSingleArray:b}=ze(),{WebGL2KernelValueDynamicSingleArray:T}=Ue(),{WebGL2KernelValueSingleArray1DI:S}=Ke(),{WebGL2KernelValueDynamicSingleArray1DI:v}=Be(),{WebGL2KernelValueSingleArray2DI:A}=We(),{WebGL2KernelValueDynamicSingleArray2DI:_}=je(),{WebGL2KernelValueSingleArray3DI:w}=He(),{WebGL2KernelValueDynamicSingleArray3DI:E}=Xe(),{WebGL2KernelValueArray2:I}=qe(),{WebGL2KernelValueArray3:k}=Ye(),{WebGL2KernelValueArray4:D}=Ze(),{WebGL2KernelValueUnsignedArray:C}=Je(),{WebGL2KernelValueDynamicUnsignedArray:L}=Qe(),$={unsigned:{dynamic:{Boolean:r,Integer:s,Float:n,Array:L,"Array(2)":I,"Array(3)":k,"Array(4)":D,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:f,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:g,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:l},static:{Boolean:r,Float:n,Integer:s,Array:C,"Array(2)":I,"Array(3)":k,"Array(4)":D,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:d,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:o,HTMLVideo:h}},single:{dynamic:{Boolean:r,Integer:s,Float:n,Array:T,"Array(2)":I,"Array(3)":k,"Array(4)":D,"Array1D(2)":v,"Array1D(3)":v,"Array1D(4)":v,"Array2D(2)":_,"Array2D(3)":_,"Array2D(4)":_,"Array3D(2)":E,"Array3D(3)":E,"Array3D(4)":E,Input:p,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:g,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:l},static:{Boolean:r,Float:n,Integer:s,Array:b,"Array(2)":I,"Array(3)":k,"Array(4)":D,"Array1D(2)":S,"Array1D(3)":S,"Array1D(4)":S,"Array2D(2)":A,"Array2D(3)":A,"Array2D(4)":A,"Array3D(2)":w,"Array3D(3)":w,"Array3D(4)":w,Input:c,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:m,HTMLCanvas:i,OffscreenCanvas:i,HTMLImage:i,ImageBitmap:i,ImageData:i,HTMLImageArray:o,HTMLVideo:h}}};t.exports={kernelValueMaps:$,lookupKernelValueType:function(e,t,r,n){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!r)throw new Error("precision missing");n.type&&(e=n.type);const s=$[r][t];if("WebGPUBuffer"===e)throw new Error("this kernel runs on WebGL but received a WebGPU pipeline buffer; await handle.toArray() first, or give this kernel the async contract (asyncMode: true / mode: 'async') so the readback happens for you");if(!1===s[e])return null;if(void 0===s[e])throw new Error(`Could not find a KernelValue for ${e}`);return s[e]}}}),tt=e((e,t)=>{const{WebGLKernel:r}=be(),{WebGL2FunctionNode:n}=Se(),{FunctionBuilder:s}=o(),{utils:a}=i(),{fragmentShader:u}=ve(),{vertexShader:h}=Ae(),{lookupKernelValueType:l}=et();let c=null,p=null,d=null,f=null;t.exports={WebGL2Kernel:class extends r{static get isSupported(){return null!==c||(this.setupFeatureChecks(),c=this.isContextMatch(d)),c}static setupFeatureChecks(){"undefined"!=typeof document?p=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(p=new OffscreenCanvas(0,0)),p&&(d=p.getContext("webgl2"),d&&d.getExtension&&(d.getExtension("EXT_color_buffer_float"),d.getExtension("OES_texture_float_linear"),f=this.getFeatures()))}static isContextMatch(e){return"undefined"!=typeof WebGL2RenderingContext&&e instanceof WebGL2RenderingContext}static getFeatures(){const e=this.testContext;return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isSpeedTacticSupported:this.getIsSpeedTacticSupported(),kernelMap:!0,isTextureFloat:!0,isDrawBuffers:!0,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize(),lowIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT),lowFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT),mediumIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT),mediumFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT),highIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT),highFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)})}static getIsTextureFloat(){return!0}static getChannelCount(){return d.getParameter(d.MAX_DRAW_BUFFERS)}static getMaxTextureSize(){return d.getParameter(d.MAX_TEXTURE_SIZE)}static lookupKernelValueType(e,t,r,n){return l(e,t,r,n)}static get testCanvas(){return p}static get testContext(){return d}static get features(){return f}static get fragmentShader(){return u}static get vertexShader(){return h}initContext(){return this.canvas.getContext("webgl2",{alpha:!1,depth:!1,antialias:!1})}initExtensions(){this.extensions={EXT_color_buffer_float:this.context.getExtension("EXT_color_buffer_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if("single"===this.precision&&!t.isFloatRead)throw new Error("Float texture outputs are not supported");if(this.graphical||null!==this.precision||(this.precision=t.isFloatRead?"single":"unsigned"),null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);switch(t){case"Array":this.output=a.getDimensions(t);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=e[0].output;break;default:throw new Error("Auto output not supported for input type: "+t)}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"single"===this.precision&&(console.warn("Cannot use graphical mode and single precision at the same time"),this.precision="unsigned"),void(this.texSize=a.clone(this.output))}!this.graphical&&null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}translateSource(){const e=s.fromKernel(this,n,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=e.getPrototypeString("kernel"),this.setupReturnTypes(e)}drawBuffers(){this.context.drawBuffers(this.drawBuffersMap)}getTextureFormat(){const{context:e}=this;switch(this.getInternalFormat()){case e.R32F:return e.RED;case e.RG32F:return e.RG;case e.RGBA32F:case e.RGBA:return e.RGBA;default:throw new Error("Unknown internal format")}}renderValues(){return void 0===this._tightRead&&this._detectTightRead(),super.renderValues()}renderKernelsToArrays(){return void 0===this._tightRead&&this._detectTightRead(),super.renderKernelsToArrays()}readFloatPixelsToFloat32Array(){if(!this._tightRead)return super.readFloatPixelsToFloat32Array();const{texSize:e,context:t}=this,r=e[0],n=e[1],s=new Float32Array(r*n);return t.readPixels(0,0,r,n,t.RED,t.FLOAT,s),s}renderOutputAsync(){return this.renderOutput!==this.renderValues?Promise.resolve(this.renderOutput()):this.renderValuesAsync()}renderValuesAsync(){void 0===this._tightRead&&this._detectTightRead();const e=this.formatValues,[t,r,n]=this.output;return this.transferValuesAsync().then(s=>e(s,t,r,n))}transferValuesAsync(){const{texSize:e,context:t}=this,r=e[0],n=e[1];let s,i,a;"single"===this.precision?(s=this._tightRead?t.RED:t.RGBA,i=t.FLOAT,a=new Float32Array(r*n*(this._tightRead?1:4))):(s=t.RGBA,i=t.UNSIGNED_BYTE,a=new Uint8Array(r*n*4));const o=t.createBuffer();t.bindBuffer(t.PIXEL_PACK_BUFFER,o),t.bufferData(t.PIXEL_PACK_BUFFER,a.byteLength,t.STREAM_READ),t.readPixels(0,0,r,n,s,i,0),t.bindBuffer(t.PIXEL_PACK_BUFFER,null);const u=t.fenceSync(t.SYNC_GPU_COMMANDS_COMPLETE,0);return t.flush(),this._pollFence(u).then(()=>(t.bindBuffer(t.PIXEL_PACK_BUFFER,o),t.getBufferSubData(t.PIXEL_PACK_BUFFER,0,a),t.bindBuffer(t.PIXEL_PACK_BUFFER,null),t.deleteBuffer(o),"single"===this.precision?a:new Float32Array(a.buffer)),e=>{throw t.deleteBuffer(o),e})}_pollFence(e){const t=this.context;return new Promise((r,n)=>{let s,i=null;"undefined"!=typeof MessageChannel?(i=new MessageChannel,i.port1.onmessage=()=>o(),s=()=>i.port2.postMessage(0)):s=()=>setTimeout(o,0);const a=(r,n)=>{t.deleteSync(e),i&&(i.port1.close(),i.port2.close()),r(n)},o=()=>{if(t.isContextLost())return a(n,new Error("WebGL context lost while awaiting kernel result"));const i=t.clientWaitSync(e,0,0);return i===t.ALREADY_SIGNALED||i===t.CONDITION_SATISFIED?a(r):i===t.WAIT_FAILED?a(n,new Error("clientWaitSync failed while awaiting kernel result")):void s()};o()})}_detectTightRead(){const e=this.context;this._tightRead=!1,e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer);const t="Number"===this.returnType||"Float"===this.returnType||"Integer"===this.returnType||"LiteralInteger"===this.returnType;if("single"===this.precision&&!this.optimizeFloatMemory&&!this.graphical&&t&&e.getParameter(e.IMPLEMENTATION_COLOR_READ_FORMAT)===e.RED&&e.getParameter(e.IMPLEMENTATION_COLOR_READ_TYPE)===e.FLOAT){if(this.formatValues===a.erectFloat)this.formatValues=a.erectMemoryOptimizedFloat;else if(this.formatValues===a.erect2DFloat)this.formatValues=a.erectMemoryOptimized2DFloat;else if(this.formatValues===a.erect3DFloat)this.formatValues=a.erectMemoryOptimized3DFloat;else if(this.formatValues!==a.erectMemoryOptimizedFloat&&this.formatValues!==a.erectMemoryOptimized2DFloat&&this.formatValues!==a.erectMemoryOptimized3DFloat)return;this._tightRead=!0}}getInternalFormat(){const{context:e}=this;if("single"===this.precision)switch(this.returnType){case"Number":case"Float":case"Integer":return this.optimizeFloatMemory?e.RGBA32F:e.R32F;case"Array(2)":return e.RG32F;case"Array(3)":case"Array(4)":return e.RGBA32F;default:throw new Error("Unhandled return type")}return e.RGBA}_setupOutputTexture(){const e=this.context;if(this.texture)return e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture.texture,0),void(this._tightRead=void 0);e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer);const t=e.createTexture(),r=this.texSize;e.activeTexture(e.TEXTURE0+this.constantTextureCount+this.argumentTextureCount),e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);const n=this.getInternalFormat();"single"===this.precision?e.texStorage2D(e.TEXTURE_2D,1,n,r[0],r[1]):e.texImage2D(e.TEXTURE_2D,0,n,r[0],r[1],0,n,e.UNSIGNED_BYTE,null),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),this.texture=new this.TextureConstructor({texture:t,size:r,dimensions:this.threadDim,output:this.output,context:this.context,internalFormat:this.getInternalFormat(),textureFormat:this.getTextureFormat(),kernel:this}),this._tightRead=void 0}_setupSubOutputTextures(){const e=this.context;if(this.mappedTextures){for(let t=0;t{const{utils:r}=i(),{FunctionNode:n}=h();const s={Number:"f32",Float:"f32",Integer:"i32",LiteralInteger:"f32",Boolean:"bool","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4"},a={"===":"==","!==":"!="},o=["x","y","z","w"],u={pow:"_pow",round:"_round"},l={ceil:!0,floor:!0,_round:!0},c=["alias","break","case","const","const_assert","continue","continuing","default","diagnostic","discard","else","enable","false","fn","for","if","let","loop","override","requires","return","struct","switch","true","var","while","main","params","result","gid","threadGid","data_index","select","abs","acos","acosh","asin","asinh","atan","atan2","atanh","ceil","clamp","cos","cosh","cross","degrees","distance","dot","exp","exp2","floor","fma","fract","inverseSqrt","length","log","log2","max","min","mix","modf","normalize","pow","radians","round","sign","sin","sinh","smoothstep","sqrt","step","tan","tanh","trunc","cbrt","expm1","fround","imul","log10","log1p","clz32","_pow","_round","LOOP_MAX","bitcast","ptr","array","vec2","vec3","vec4","mat2x2","mat3x3","mat4x4","f32","i32","u32","bool"];t.exports={WGSLFunctionNode:class extends n{wgslFloat(e){if(e===1/0)return"0x1.fffffep+127";if(e===-1/0)return"-0x1.fffffep+127";if(e>34028234663852886e22)return"0x1.fffffep+127";if(e<-34028234663852886e22)return"-0x1.fffffep+127";const t=`${e}`;return-1!==t.indexOf(".")||-1!==t.indexOf("e")||-1!==t.indexOf("E")?t:`${t}.0`}wgslInt(e){return`${Math.round(e)}`}mangleFunctionName(e){return-1!==c.indexOf(e)?`fn_${e}`:r.sanitizeName(e)}getLookupType(e){return"WebGPUBuffer"===e?"Number":super.getLookupType(e)}astUpdateExpression(e,t){return this.astGeneric(e.argument,t),t.push(e.operator),t}getType(e){if(e&&"ConditionalExpression"===e.type){const t=this.getType(e.consequent);if("Integer"===t||"LiteralInteger"===t){const t=this.getType(e.alternate);if("Number"===t||"Float"===t)return"Number"}}return super.getType(e)}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);const r=this.getType(e.consequent),n=this.getType(e.alternate);if(null===r&&null===n)return t.push("if ("),this.astGeneric(e.test,t),t.push(") {"),this.astGeneric(e.consequent,t),t.push(";"),t.push("} else {"),this.astGeneric(e.alternate,t),t.push(";"),t.push("}"),t;let s="LiteralInteger"===r?"Number":r;"Integer"!==s||"Number"!==n&&"Float"!==n||(s="Number");const i=e=>{const r=this.getType(e);switch(s){case"Number":case"Float":"Integer"===r?this.castValueToFloat(e,t):"LiteralInteger"===r?this.castLiteralToFloat(e,t):this.astGeneric(e,t);break;case"Integer":"Number"===r||"Float"===r?this.castValueToInteger(e,t):"LiteralInteger"===r?this.castLiteralToInteger(e,t):this.astGeneric(e,t);break;default:this.astGeneric(e,t)}};return t.push("select("),i(e.alternate),t.push(", "),i(e.consequent),t.push(", "),this.astGeneric(e.test,t),t.push(")"),t}astFunction(e,t){if(this.isRootKernel){for(let r=0;r0&&t.push(", ");let a=this.argumentTypes[this.argumentNames.indexOf(i)];if(!a)throw this.astErrorOutput(`Unknown argument ${i} type`,e);"LiteralInteger"===a&&(this.argumentTypes[n]=a="Number");const o=s[a];if(!o)throw this.astErrorOutput(`WebGPU backend does not yet support ${a} arguments to helper functions`,e);t.push(`user_${r.sanitizeName(i)} : ${o}`)}t.push(")"),i&&t.push(` -> ${i}`),t.push(" {\n");for(let r=0;r"===e.operator||"<"===e.operator)&&"Literal"===e.right.type&&!Number.isInteger(e.right.value)){this.pushState("building-float"),this.castValueToFloat(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-float");break}if(this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const r=[];if(this.astGeneric(e.right,r),"Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(r.join(""))}else t.push("i32("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float");break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.castLiteralToFloat(e.left,t),t.push(a[e.operator]||e.operator),this.pushState("casting-to-float"),this.astGeneric(e.right,t),this.popState("casting-to-float"),this.popState("building-float"));break;case"LiteralInteger & Integer":this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${r}`,e)}return t.push(")"),t}checkAndUpconvertOperator(e,t){if(this.checkAndUpconvertBitwiseOperators(e,t))return t;if("**"!==e.operator)return null;switch(t.push("_pow"),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){if(!{"&":!0,"|":!0,"^":!0,"<<":!0,">>":!0,">>>":!0}[e.operator])return null;const r=e=>{switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;default:this.pushState("building-integer"),this.astGeneric(e,t),this.popState("building-integer")}};return t.push("("),">>>"===e.operator?(t.push("bitcast(bitcast("),r(e.left),t.push(") >> u32("),r(e.right),t.push("))")):"<<"===e.operator||">>"===e.operator?(r(e.left),t.push(` ${e.operator} u32(`),r(e.right),t.push(")")):(r(e.left),t.push(` ${e.operator} `),r(e.right)),t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){if("~"!==e.operator)return null;switch(t.push("~("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)?t:"+"===e.operator?(this.astGeneric(e.argument,t),t):(e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t)}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("i32("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("f32("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),s=r.sanitizeName(e.name);return"Infinity"===e.name?(t.push("0x1.fffffep+127"),t):!this.isRootKernel||-1===this.argumentNames.indexOf(e.name)||"Number"!==n&&"Float"!==n&&"Integer"!==n&&"Boolean"!==n?(t.push(`user_${s}`),t):("Boolean"===n?t.push(`bool(params.user_${s})`):t.push(`params.user_${s}`),t)}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const r=[],n=[],s=[],i=[];let a=null;if(e.init){const{declarations:t}=e.init;t.length>1&&(a=!1),this.astGeneric(e.init,r);for(let e=0;e0&&t.push(r.join(""),"\n"),t.push(`for (var ${e} : i32 = 0;${e}0&&t.push(`if (!(${n.join("")})) { break; }\n`),t.push(i.join("")),t.push(`\n${s.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);const r=this.getInternalVariableName("safeI");return t.push(`for (var ${r} : i32 = 0;${r}{if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return e.some(t);if("BreakStatement"===e.type)return!0;if("ForStatement"===e.type||"WhileStatement"===e.type||"DoWhileStatement"===e.type||"SwitchStatement"===e.type)return!1;for(const r in e)if("loc"!==r&&"range"!==r&&"parent"!==r&&t(e[r]))return!0;return!1};if(t(r[e]))throw this.astErrorOutput("break inside a switch case is only supported as the case terminator",r[e])}for(let e=0;ee+1){u=!0,this.astSwitchCaseConsequent(n[e].consequent,o);continue}t.push(" else {\n")}this.astSwitchCaseConsequent(n[e].consequent,t),t.push("\n}")}return u&&(t.push(" else {"),t.push(o.join("")),t.push("}")),t.push("\n"),t}astThisExpression(e,t){return t.push("this"),t}astSequenceExpression(e,t){const{expressions:r}=e;if(1===r.length)return this.astGeneric(r[0],t),t;throw this.astErrorOutput("WebGPU backend does not yet support the comma operator",e)}astMemberExpression(e,t){const{property:n,name:i,signature:a,origin:o,type:u,xProperty:h,yProperty:l,zProperty:c}=this.getMemberExpressionDetails(e);switch(a){case"value.thread.value":case"this.thread.value":if("x"!==i&&"y"!==i&&"z"!==i)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`i32(threadGid.${i})`),t;case"this.output.value":{const r={x:0,y:1,z:2}[i];if(void 0===r)throw this.astErrorOutput("Unexpected expression",e);if(this.dynamicOutput){const e=`params.output${i.toUpperCase()}`;this.isState("casting-to-float")?t.push(`f32(${e})`):t.push(`i32(${e})`)}else this.isState("casting-to-integer")?t.push(`${this.output[r]}`):t.push(`${this.output[r]}.0`);return t}case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if("Math"===o)return t.push(this.wgslFloat(Math[i])),t;switch(n){case"r":return t.push(`user_${r.sanitizeName(i)}.x`),t;case"g":return t.push(`user_${r.sanitizeName(i)}.y`),t;case"b":return t.push(`user_${r.sanitizeName(i)}.z`),t;case"a":return t.push(`user_${r.sanitizeName(i)}.w`),t}break;case"this.constants.value":{const r=this.constants[i];switch(u){case"Integer":return this.isState("casting-to-float")?t.push(this.wgslFloat(r)):t.push(this.wgslInt(r)),t;case"Number":case"Float":return this.isState("casting-to-integer")?t.push(this.wgslInt(r)):t.push(this.wgslFloat(r)),t;case"Boolean":return t.push(r?"true":"false"),t;case"Array(2)":case"Array(3)":case"Array(4)":{const e=parseInt(u.substring(6),10),n=[];for(let t=0;t0&&t.push(", "),s){case"Integer":this.castValueToFloat(n,t);break;case"LiteralInteger":this.castLiteralToFloat(n,t);break;default:this.astGeneric(n,t)}}else{const s=this.lookupFunctionArgumentTypes(n)||[];for(let i=0;i0&&t.push(", ");const u=this.getType(a);switch(o||(this.triggerImplyArgumentType(n,i,u,this),o=u),u){case"Boolean":this.astGeneric(a,t);continue;case"Number":case"Float":if("Integer"===o){t.push("i32("),this.astGeneric(a,t),t.push(")");continue}if("Number"===o||"Float"===o){this.astGeneric(a,t);continue}if("LiteralInteger"===o){this.castLiteralToFloat(a,t);continue}break;case"Integer":if("Number"===o||"Float"===o){t.push("f32("),this.astGeneric(a,t),t.push(")");continue}if("Integer"===o){this.astGeneric(a,t);continue}break;case"LiteralInteger":if("Integer"===o){this.castLiteralToInteger(a,t);continue}if("Number"===o||"Float"===o){this.castLiteralToFloat(a,t);continue}if("LiteralInteger"===o){this.astGeneric(a,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(o===u){"Identifier"===a.type?t.push(`user_${r.sanitizeName(a.name)}`):this.astGeneric(a,t);continue}break;case"Array":case"Array2D":case"Array3D":case"Input":case"WebGPUBuffer":throw this.astErrorOutput("WebGPU backend does not yet support array arguments to helper functions",e)}throw this.astErrorOutput(`Unhandled argument combination of ${u} and ${o} for argument named "${a.name}"`,e)}}return t.push(")"),a&&t.push(")"),t}astArrayExpression(e,t){switch(this.getType(e)){case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":throw this.astErrorOutput("WebGPU backend does not yet support Matrix types",e)}const r=e.elements.length;t.push(`vec${r}(`);for(let n=0;n0&&t.push(", ");const r=e.elements[n];switch(this.getType(r)){case"Integer":this.castValueToFloat(r,t);break;case"LiteralInteger":this.castLiteralToFloat(r,t);break;default:this.astGeneric(r,t)}}return t.push(")"),t}memberExpressionXYZ(e,t,r,n){return r?n.push(this.memberExpressionPropertyMarkup(r),", "):n.push("0, "),t?n.push(this.memberExpressionPropertyMarkup(t),", "):n.push("0, "),n.push(this.memberExpressionPropertyMarkup(e)),n}memberExpressionPropertyMarkup(e){if(!e)throw new Error("Property not set");const t=[];switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;case"Integer":this.pushState("building-integer"),t.push("i32("),this.astGeneric(e,t),t.push(")"),this.popState("building-integer");break;default:this.astGeneric(e,t)}return t.join("")}}}}),nt=e((e,t)=>{let r=null;t.exports={WebGPUContext:class e{static get isSupported(){return"undefined"!=typeof navigator&&!!navigator.gpu}static acquire(){if(r)return r;const t=(async()=>{if(!e.isSupported)throw new Error("WebGPU is not supported on this platform (navigator.gpu is missing)");const n=await navigator.gpu.requestAdapter();if(!n)throw new Error("WebGPU is present (navigator.gpu) but no adapter is available. On headless Chromium there is no adapter; run headed. Use `await GPU.isWebGPUAvailable()` to feature-detect.");const s=await n.requestDevice({requiredLimits:{maxStorageBufferBindingSize:n.limits.maxStorageBufferBindingSize,maxBufferSize:n.limits.maxBufferSize}}),i={adapter:n,device:s,isLost:!1};return s.lost.then(e=>{i.isLost=!0,"destroyed"!==e.reason&&console.error(`gpu.js [webgpu]: device lost: ${e.message}`),r===t&&(r=null)}),s.onuncapturederror=e=>{console.error(`gpu.js [webgpu]: ${e.error.message}`)},i})();return t.catch(()=>{r===t&&(r=null)}),r=t}static destroy(){if(!r)return Promise.resolve();const e=r;return r=null,e.then(({device:e})=>{e.destroy()},()=>{})}}}}),st=e((e,t)=>{t.exports={WebGPUBufferResult:class e{constructor(e){this.buffer=e.buffer,this.output=e.output,this.componentCount=e.componentCount||1,this.context=e.context,this.kernel=e.kernel,this.type="WebGPUBuffer",this._deleted=!1,this.buffer._refs?this.buffer._refs++:this.buffer._refs=1}toArray(){return this._deleted?Promise.reject(new Error("WebGPUBufferResult has been deleted")):this.kernel.readBufferResult(this)}delete(){this._deleted||(this._deleted=!0,0===--this.buffer._refs&&this.buffer.destroy())}clone(){return new e(this)}}}}),it=e((e,t)=>{const{Kernel:r}=a(),{FunctionBuilder:s}=o(),{WGSLFunctionNode:u}=rt(),{WebGPUContext:h}=nt(),{WebGPUBufferResult:l}=st(),{utils:c}=i(),{Input:p}=n(),d=Object.freeze({kernelMap:!1,isIntegerDivisionAccurate:!0,isSpeedTacticSupported:!1,isTextureFloat:!0,isDrawBuffers:!1,kernelMapSize:0,channelCount:1,maxTextureSize:1/0,isFloatRead:!0}),f={_pow:"fn _pow(v1 : f32, v2 : f32) -> f32 {\n if (v2 == 0.0) { return 1.0; }\n return pow(v1, v2);\n}",_round:"fn _round(x : f32) -> f32 {\n return floor(x + 0.5);\n}",cbrt:"fn cbrt(x : f32) -> f32 {\n return sign(x) * pow(abs(x), 1.0 / 3.0);\n}",expm1:"fn expm1(x : f32) -> f32 {\n return exp(x) - 1.0;\n}",fround:"fn fround(x : f32) -> f32 {\n return x;\n}",imul:"fn imul(a : f32, b : f32) -> f32 {\n return f32(i32(a) * i32(b));\n}",log10:`fn log10(x : f32) -> f32 {\n return log2(x) * ${1/Math.log2(10)};\n}`,log1p:"fn log1p(x : f32) -> f32 {\n return log(1.0 + x);\n}",clz32:"fn clz32(x : f32) -> f32 {\n return f32(countLeadingZeros(u32(x)));\n}"};t.exports={WebGPUKernel:class extends r{static get isSupported(){return h.isSupported}static get isAsync(){return!0}static isContextMatch(e){return Boolean(e&&"function"==typeof e.createShaderModule&&"function"==typeof e.createComputePipeline)}static getFeatures(){return d}static get features(){return d}static get mode(){return"webgpu"}static getSignature(e,t){return"webgpu"+(t.length>0?":"+t.join(","):"")}static destroyContext(e){}static nativeFunctionArguments(){throw new Error("WebGPU backend does not yet support native functions")}static nativeFunctionReturnType(){throw new Error("WebGPU backend does not yet support native functions")}static combineKernels(){throw new Error("WebGPU backend does not yet support combineKernels; chain kernels with `await` and pipeline mode instead")}constructor(e,t){if(super(e,t),t){if(t.graphical)throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend");if("unsigned"===t.precision)throw new Error("WebGPU backend does not yet support precision: 'unsigned'; it is single precision only");if(t.subKernels)throw new Error("WebGPU backend does not yet support createKernelMap")}this.mergeSettings(e.settings||t),null===this.precision&&(this.precision="single"),this.asyncMode=!0,this.threadDim=null,this.componentCount=1,this.compiledSource=null,this.translatedBody=null,this.translatedFunctions=null,this.paramsLayout=null,this._buildPromise=null,this._device=null,this.computePipeline=null,this.bindGroupLayout=null,this.bindGroup=null,this.bindGroupDirty=!0,this.paramsBuffer=null,this.paramsMirror=null,this.outputBuffer=null,this.argumentBuffers=null,this.constantBuffers=null,this.stagingPool=[]}initCanvas(){return null}initContext(){return null}initPlugins(e){return[]}setGraphical(e){if(e)throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend");return super.setGraphical(e)}setOutput(e){const t=this.toKernelOutput(e);if(this.built){if(!this.dynamicOutput)throw new Error("Resizing a kernel with dynamicOutput: false is not possible");if(t.length!==this.output.length)throw new Error("WebGPU backend does not yet support changing the output rank of a built kernel; the workgroup shape is fixed at build")}return this.output=t,this}toString(){throw new Error("WebGPU backend does not yet support toString")}validateSettings(e){if(this.graphical)throw new Error("WebGPU backend does not yet support graphical mode; use the webgl backend");if("unsigned"===this.precision)throw new Error("WebGPU backend does not yet support precision: 'unsigned'; it is single precision only");if(this.precision="single",this.subKernels&&this.subKernels.length>0)throw new Error("WebGPU backend does not yet support createKernelMap");if(!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=c.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=Array.from(c.getDimensions(e[0]));else{if("WebGPUBuffer"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=Array.from(e[0].output)}}this.checkOutput()}setupArguments(e){super.setupArguments(e);for(let e=0;e,`);for(let e=0;e params : Params;");for(let t=0;t user_${e[t].name} : array;`);const i=1+e.length;n.push(`@group(0) @binding(${i}) var result : array;`);for(let e=0;e constants_${r[e].name} : array;`);n.push("var threadGid : vec3;");const a=`${this.translatedFunctions}\n${this.translatedBody}`;/\bLOOP_MAX\b/.test(a)&&n.push(`const LOOP_MAX : i32 = ${parseInt(this.loopMaxIterations,10)||1e3};`);for(const e in f)new RegExp(`\\b${e}\\(`).test(a)&&n.push(f[e]);for(let t=0;t f32 {\n return user_${r}[u32(x + i32(params.user_${r}_dims.x) * (y + i32(params.user_${r}_dims.y) * z))];\n}`)}for(let e=0;e f32 {\n return constants_${t.name}[u32(x + ${i[0]} * (y + ${i[1]} * z))];\n}`)}this.translatedFunctions&&n.push(this.translatedFunctions);const o=1===this.output.length?[64,1,1]:[8,8,1];return this.workgroupSize=o,1===this.output.length?n.push(`@compute @workgroup_size(${o[0]}, ${o[1]}, ${o[2]})\nfn main(@builtin(global_invocation_id) gid : vec3) {\n let flat_index : u32 = gid.x + gid.y * params.dispatchWidth;\n threadGid = vec3(flat_index, 0u, 0u);\n if (flat_index >= params.outputX) { return; }\n let data_index : i32 = i32(flat_index);\n${this.translatedBody}\n}`):n.push(`@compute @workgroup_size(${o[0]}, ${o[1]}, ${o[2]})\nfn main(@builtin(global_invocation_id) gid : vec3) {\n threadGid = gid;\n if (gid.x >= params.outputX || gid.y >= params.outputY || gid.z >= params.outputZ) { return; }\n let data_index : i32 = i32(gid.x + params.outputX * (gid.y + params.outputY * gid.z));\n${this.translatedBody}\n}`),n.join("\n")}constantDimensions(e){const t=e instanceof p?Array.from(e.size):Array.from(c.getDimensions(e));for(;t.length<3;)t.push(1);return t}async _buildAsync(){const e=await h.acquire();this.context=e;const t=this._device=e.device,r=t.createShaderModule({code:this.compiledSource}),n=(await r.getCompilationInfo()).messages.filter(e=>"error"===e.type);if(n.length>0)throw new Error("Error compiling WGSL compute shader:\n"+n.map(e=>` ${e.lineNum}:${e.linePos} ${e.message}`).join("\n")+`\n--- generated WGSL ---\n${this.compiledSource}`);const{arrayArgs:s,bufferConstants:i,byteLength:a}=this.paramsLayout,o=[{binding:0,visibility:4,buffer:{type:"uniform"}}];for(let e=0;ei&&(s[1]=Math.ceil(s[0]/i),s[0]=Math.ceil(s[0]/s[1])),a=s[0]*t);for(let e=0;e<3;e++)if(s[e]>i)throw new Error(`output dimension ${e} needs ${s[e]} workgroups, over this device's limit of ${i}`);return{groups:s,dispatchWidth:a}}_ensureOutputBuffer(){const[e,t,r]=this.threadDim,n=e*t*r*4*this.componentCount;this.immutable&&this.pipeline&&this.outputBuffer&&(0===--this.outputBuffer._refs&&this.outputBuffer.destroy(),this.outputBuffer=null,this.bindGroupDirty=!0),this.outputBuffer&&this.outputBuffer.size>=n||(this.outputBuffer&&0===--this.outputBuffer._refs&&this.outputBuffer.destroy(),this._checkBufferSize(n,`output [${this.output.join(", ")}]`),this.outputBuffer=this._device.createBuffer({size:n,usage:132}),this.outputBuffer._refs=1,this.bindGroupDirty=!0)}_checkBufferSize(e,t){const r=this._device.limits,n=Math.min(r.maxStorageBufferBindingSize,r.maxBufferSize);if(e>n)throw new Error(`WebGPU backend: ${t} needs ${e} bytes but this device allows ${n} per storage buffer (maxStorageBufferBindingSize/maxBufferSize); reduce the output or split the work across kernels`)}_snapshotArguments(e){const t=new Array(e.length);for(let r=0;rthis._runInternal(e))}_runInternal(e){if(this.context&&this.context.isLost)throw new Error("WebGPU device was lost; call kernel.destroy() (or gpu.destroy()) and run again to rebuild on a fresh device");const t=this._device,r=t.queue,{arrayArgs:n,scalarArgs:s,bufferConstants:i}=this.paramsLayout,a=this.threadDim=Array.from(this.output);for(;a.length<3;)a.push(1);this._ensureOutputBuffer(),this.paramsU32[0]=a[0],this.paramsU32[1]=a[1],this.paramsU32[2]=a[2],this.paramsU32[3]=this._computeDispatch(a).dispatchWidth;for(let s=0;s{const e=new Float32Array(p.buffer.getMappedRange(0,u).slice(0));return p.buffer.unmap(),this._releaseStaging(p),this._shapeOutput(e,d,this.componentCount)},e=>{throw this._releaseStaging(p),e})}_acquireStaging(e){for(let t=0;t=e)return r.busy=!0,r}const t={buffer:this._device.createBuffer({size:e,usage:9}),size:e,busy:!0,pooled:this.stagingPool.length<3};return t.pooled&&this.stagingPool.push(t),t}_releaseStaging(e){e.pooled?e.busy=!1:e.buffer.destroy()}_shapeOutput(e,t,r){const[n,s,i]=[t[0],t[1]||1,t[2]||1];if(1===r)switch(t.length){case 1:return c.erectMemoryOptimizedFloat(e,n);case 2:return c.erectMemoryOptimized2DFloat(e,n,s);default:return c.erectMemoryOptimized3DFloat(e,n,s,i)}const a=r,o=t=>{const r=new Array(n);for(let s=0;s{const t=new Float32Array(i.buffer.getMappedRange(0,s).slice(0));return i.buffer.unmap(),this._releaseStaging(i),this._shapeOutput(t,r,e.componentCount)},e=>{throw this._releaseStaging(i),e})}destroy(e){if(this.paramsBuffer&&(this.paramsBuffer.destroy(),this.paramsBuffer=null),this.paramsLayout)for(let e=0;e{const{utils:r}=i(),{Input:s}=n();function a(e,t){if(t.kernel)return void(t.kernel=e);const n=r.allPropertiesOf(e);for(let r=0;rt.kernel[s]),t.__defineSetter__(s,e=>{t.kernel[s]=e})))}t.kernel=e}t.exports={kernelRunShortcut:function(e){function t(t){e.build.apply(e,t),e.checkArgumentTypes(t);let n=e.switchingKernels?void 0:e.run.apply(e,t);for(let s=0;e.switchingKernels;s++){if(s>=4){const t=e.resetSwitchingKernels();throw new Error(`this kernel cannot run the arguments it was given (${r(t)}); it did not settle on a kernel for them after 4 attempts. Create a separate kernel for this call's argument types.`)}const i=e.resetSwitchingKernels(),a=e.onRequestSwitchKernel(i,t,e);c.kernel=e=a,a.checkArgumentTypes(t),n=a.switchingKernels?void 0:a.run.apply(a,t)}return n}function r(e){return e&&e.length?e.map(e=>"argumentTypeMismatch"===e.type?`argument ${e.index} is now ${e.needed}`:e.type).join(", "):"unknown reason"}function n(r){if(e.onAsyncModeUpgrade){const t=e.onAsyncModeUpgrade;e.onAsyncModeUpgrade=null;const s=u(r);return t(s,e).then(e=>(e&&c.replaceKernel(e),n(s)))}try{if(!0===e.constructor.isAsync)return e.build.apply(e,r),Promise.resolve(e.run.apply(e,r));for(let e=0;en(e));const s=t(r);return e.renderKernels?Promise.resolve(e.renderKernels()):e.renderOutput?e.renderOutputAsync?e.renderOutputAsync():Promise.resolve(e.renderOutput()):Promise.resolve(s)}catch(e){return Promise.reject(e)}}function i(e){return Boolean(e)&&"WebGPUBuffer"===e.type}function o(e){const t=u(e),r=[];for(let e=0;e{t[n]=e}))}return Promise.all(r).then(()=>t)}function u(e){const t=new Array(e.length);for(let r=0;r{try{e(l.apply(this,arguments))}catch(e){t(e)}})},c.replaceKernel=function(t){a(e=t,c)},a(e,c),c}}}),ot=e((e,r)=>{const{gpuMock:n}=t(),{utils:s}=i(),{Kernel:o}=a(),{CPUKernel:u}=p(),{HeadlessGLKernel:h}=Te(),{WebGL2Kernel:l}=tt(),{WebGLKernel:c}=be(),{WebGPUKernel:d}=it(),{kernelRunShortcut:f}=at(),m=[h,l,c],g=["gpu","cpu"],x={headlessgl:h,webgl2:l,webgl:c,webgpu:d};let y=!0;function b(e){if(!e)return{};const t=Object.assign({},e);return e.hasOwnProperty("floatOutput")&&(s.warnDeprecated("setting","floatOutput","precision"),t.precision=e.floatOutput?"single":"unsigned"),e.hasOwnProperty("outputToTexture")&&(s.warnDeprecated("setting","outputToTexture","pipeline"),t.pipeline=Boolean(e.outputToTexture)),e.hasOwnProperty("outputImmutable")&&(s.warnDeprecated("setting","outputImmutable","immutable"),t.immutable=Boolean(e.outputImmutable)),e.hasOwnProperty("floatTextures")&&(s.warnDeprecated("setting","floatTextures","optimizeFloatMemory"),t.optimizeFloatMemory=Boolean(e.floatTextures)),t}r.exports={GPU:class e{static disableValidation(){y=!1}static enableValidation(){y=!0}static get isGPUSupported(){return m.some(e=>e.isSupported)}static get isKernelMapSupported(){return m.some(e=>e.isSupported&&e.features.kernelMap)}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return c.isSupported}static get isWebGL2Supported(){return l.isSupported}static get isHeadlessGLSupported(){return h.isSupported}static get isWebGPUSupported(){return d.isSupported}static isWebGPUAvailable(){return d.isSupported?navigator.gpu.requestAdapter().then(e=>null!==e,()=>!1):Promise.resolve(!1)}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return l.isSupported}static get isSinglePrecisionSupported(){return m.some(e=>e.isSupported&&e.features.isFloatRead&&e.features.isTextureFloat)}constructor(e){if(e=e||{},this.canvas=e.canvas||null,this.context=e.context||null,this.mode=e.mode,this.Kernel=null,this.kernels=[],this.functions=[],this.nativeFunctions=[],this.injectedNative=null,"dev"!==this.mode){if(this.chooseKernel(),e.functions)for(let t=0;tr.argumentTypes[e]));const l=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate:y,onRequestFallback:h,onRequestSwitchKernel:function e(r,n,s){s.debug&&console.warn("Switching kernels");let o=null;if(s.signature&&!a[s.signature]&&(a[s.signature]=s),s.dynamicOutput)for(let e=r.length-1;e>=0;e--){const t=r[e];"outputPrecisionMismatch"===t.type&&(o=t.needed)}const u=s.constructor,l=u.getArgumentTypes(s,n),c=u.getSignature(s,l),d=a[c];if(d)return d.onActivate(s),d;const f=a[c]=new u(t,{argumentTypes:l,constantTypes:s.constantTypes,graphical:s.graphical,loopMaxIterations:s.loopMaxIterations,constants:s.constants,dynamicOutput:s.dynamicOutput,dynamicArgument:s.dynamicArguments,context:s.context,canvas:s.canvas,output:o||s.output,precision:s.precision,pipeline:s.pipeline,immutable:s.immutable,optimizeFloatMemory:s.optimizeFloatMemory,fixIntegerDivisionAccuracy:s.fixIntegerDivisionAccuracy,functions:s.functions,nativeFunctions:s.nativeFunctions,injectedNative:s.injectedNative,subKernels:s.subKernels,strictIntegers:s.strictIntegers,randomSeed:s.randomSeed,debug:s.debug,asyncMode:s.asyncMode,gpu:s.gpu,validate:y,returnType:s.returnType,tactic:s.tactic,onRequestFallback:h,onRequestSwitchKernel:e,texture:s.texture,mappedTextures:s.mappedTextures,drawBuffersMap:s.drawBuffersMap});return f.build.apply(f,n),p.replaceKernel(f),i.push(f),f}},o);"async"===this.mode&&(l.asyncMode=!0);const c=new this.Kernel(t,l),p=f(c);if("async"===this.mode&&d.isSupported&&!(c instanceof d)){const r=this;c.onAsyncModeUpgrade=function(n,s){return e.isWebGPUAvailable().then(e=>{if(!e)return null;let a;try{a=new d(t,{functions:s.functions,nativeFunctions:s.nativeFunctions,injectedNative:s.injectedNative,gpu:r,validate:y,asyncMode:!0,output:s.output,pipeline:s.pipeline,immutable:s.immutable,dynamicOutput:s.dynamicOutput,dynamicArguments:!0,loopMaxIterations:s.loopMaxIterations,constants:s.constants,constantTypes:s.constantTypes,argumentTypes:s.argumentTypes,precision:s.precision,tactic:s.tactic,strictIntegers:s.strictIntegers,fixIntegerDivisionAccuracy:s.fixIntegerDivisionAccuracy,subKernels:s.subKernels,graphical:s.graphical,debug:s.debug}),a.build.apply(a,n)}catch(e){return s.debug&&console.warn("webgpu upgrade declined: "+e.message),null}return a._buildPromise.then(()=>(i.push(a),a),e=>(s.debug&&console.warn("webgpu upgrade declined: "+e.message),a.destroy(),null))},()=>null)}}return this.canvas||(this.canvas=c.canvas),this.context||(this.context=c.context),i.push(c),p}createKernelMap(){let e,t;const r=typeof arguments[arguments.length-2];if("function"===r||"string"===r?(e=arguments[arguments.length-2],t=arguments[arguments.length-1]):e=arguments[arguments.length-1],!("dev"===this.mode||this.Kernel.isSupported&&this.Kernel.features.kernelMap)){if("webgpu"===this.Kernel.mode)throw new Error("WebGPU backend does not yet support createKernelMap");if(this.mode&&g.indexOf(this.mode)<0)throw new Error(`kernelMap not supported on ${this.Kernel.name}`)}const n=b(t);if(t&&"object"==typeof t.argumentTypes&&(n.argumentTypes=Object.keys(t.argumentTypes).map(e=>t.argumentTypes[e])),Array.isArray(arguments[0])){n.subKernels=[];const e=arguments[0];for(let t=0;t0)throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');return this.nativeFunctions.push(Object.assign({name:e,source:t},r)),this}injectNative(e){return this.injectedNative=e,this}destroy(){return new Promise((e,t)=>{this.kernels||e(),setTimeout(()=>{try{const e=this.kernels.slice();for(let t=0;t{const{utils:r}=i();t.exports={alias:function(e,t){const n=t.toString();return new Function(`return function ${e} (${r.getArgumentNamesFromString(n).join(", ")}) {\n ${r.getFunctionBodyFromString(n)}\n}`)()}}}),ht=e((e,t)=>{const{GPU:r}=ot(),{alias:c}=ut(),{utils:d}=i(),{Input:f,input:m}=n(),{Texture:g}=s(),{FunctionBuilder:x}=o(),{FunctionNode:y}=h(),{CPUFunctionNode:b}=l(),{CPUKernel:T}=p(),{HeadlessGLKernel:S}=Te(),{WebGLFunctionNode:v}=N(),{WebGLKernel:A}=be(),{kernelValueMaps:_}=ye(),{WebGL2FunctionNode:w}=Se(),{WebGL2Kernel:E}=tt(),{kernelValueMaps:I}=et(),{WGSLFunctionNode:k}=rt(),{WebGPUKernel:D}=it(),{WebGPUContext:C}=nt(),{WebGPUBufferResult:L}=st(),{GLKernel:$}=R(),{Kernel:F}=a(),{FunctionTracer:M}=u();t.exports={alias:c,CPUFunctionNode:b,CPUKernel:T,GPU:r,FunctionBuilder:x,FunctionNode:y,HeadlessGLKernel:S,Input:f,input:m,Texture:g,utils:d,WebGL2FunctionNode:w,WebGL2Kernel:E,webGL2KernelValueMaps:I,WebGLFunctionNode:v,WebGLKernel:A,webGLKernelValueMaps:_,WGSLFunctionNode:k,WebGPUKernel:D,WebGPUContext:C,WebGPUBufferResult:L,GLKernel:$,Kernel:F,FunctionTracer:M,plugins:{mathRandom:V()}}});return e((e,t)=>{const r=ht(),n=r.GPU;for(const e in r)r.hasOwnProperty(e)&&"GPU"!==e&&(n[e]=r[e]);function s(e){e.GPU&&e.GPU.prototype&&e.GPU.prototype.createKernel||Object.defineProperty(e,"GPU",{configurable:!0,get:()=>n,set(){}})}n.GPU=n,"undefined"!=typeof window&&s(window),"undefined"!=typeof self&&s(self),t.exports=n})()}); \ No newline at end of file diff --git a/examples/parallel-raytracer.html b/examples/parallel-raytracer.html index 59c0fbce..93ae8072 100644 --- a/examples/parallel-raytracer.html +++ b/examples/parallel-raytracer.html @@ -41,7 +41,7 @@
-

A parallel raytracer built with TypeScript and GPU.js (WebGL/GLSL).

+

A parallel raytracer built with TypeScript and GPU.js (WebGL/GLSL).

GitHub: http://github.com/jin/raytracer

Press W, A, S, D to move the camera around.

diff --git a/examples/raytracer.html b/examples/raytracer.html index 274d598a..b57d8d18 100644 --- a/examples/raytracer.html +++ b/examples/raytracer.html @@ -30,7 +30,7 @@

From https://staceytay.com/raytracer/. A simple ray tracer with Lambertian and specular reflection, - built with GPU.js. Read more + built with GPU.js. Read more about ray tracing and GPU.js in my blog post. Code available diff --git a/package.json b/package.json index 678e6082..8f8df27f 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "bugs": { "url": "https://github.com/gpujs/gpu.js/issues" }, - "homepage": "http://gpu.rocks/", + "homepage": "https://gpu.rocks/", "typings": "./src/index.d.ts", "overrides": { "gl": { diff --git a/scripts/benchmark-async.mjs b/scripts/benchmark-async.mjs new file mode 100644 index 00000000..0a5ee5bf --- /dev/null +++ b/scripts/benchmark-async.mjs @@ -0,0 +1,164 @@ +#!/usr/bin/env node +// Measures what asyncMode actually buys: main-thread availability while +// kernel results are read back. Throughput is benchmark-webgpu.mjs's job; +// this one holds the workload fixed and asks how badly the readback loop +// starves everything else sharing the thread. +// +// npm run build && node scripts/benchmark-async.mjs +// +// A 4 ms setTimeout heartbeat runs beside a loop of matmul dispatches, each +// awaited (a no-op for the sync modes). Blocked time is every inter-beat gap +// beyond the interval — time the event loop wanted to run and could not. +// Headed Chromium for the same reason as benchmark-webgpu.mjs: headless has +// no WebGPU adapter and falls to SwiftShader for GL. + +import net from 'node:net'; +import path from 'node:path'; +import { spawn } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import { chromium } from '@playwright/test'; + +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +const PORT = 8099; + +function portListening(port) { + return new Promise(resolve => { + const socket = net.connect({ port, host: '127.0.0.1' }); + socket.once('connect', () => { socket.destroy(); resolve(true); }); + socket.once('error', () => resolve(false)); + }); +} + +// Runs inside the page; must stay closure-free (Playwright serializes it). +async function benchInPage() { + const G = window.GPU; + const SIZE = 512; + const ROUNDS = 30; + const BEAT_MS = 4; + + function matmulSource(a, b) { + let sum = 0; + for (let i = 0; i < 512; i++) { + sum += a[this.thread.y][i] * b[i][this.thread.x]; + } + return sum; + } + + function makeMatrix(seed) { + const m = []; + for (let y = 0; y < SIZE; y++) { + const row = new Float32Array(SIZE); + for (let x = 0; x < SIZE; x++) row[x] = ((x * 31 + y * 17 + seed) % 100) / 100; + m.push(row); + } + return m; + } + const a0 = makeMatrix(1), b0 = makeMatrix(2), a1 = makeMatrix(3), b1 = makeMatrix(4); + + async function measure(mode, asyncMode) { + const gpu = new G({ mode }); + const kernel = gpu.createKernel(matmulSource).setOutput([SIZE, SIZE]).setPrecision('single'); + if (asyncMode) kernel.setAsyncMode(true); + // warmup + ensure any webgpu upgrade settles before timing + await kernel(a0, b0); + await kernel(a1, b1); + + let beats = 0; + let blockedMs = 0; + let worstGapMs = 0; + let last = performance.now(); + let alive = true; + (function beat() { + if (!alive) return; + const now = performance.now(); + const gap = now - last; + last = now; + if (gap > BEAT_MS) { + blockedMs += gap - BEAT_MS; + if (gap > worstGapMs) worstGapMs = gap; + } + beats++; + setTimeout(beat, BEAT_MS); + })(); + + const start = performance.now(); + let sink = 0; + for (let i = 0; i < ROUNDS; i++) { + const result = await kernel(i % 2 ? a1 : b1, i % 2 ? b0 : a0); + sink += result[1][1]; + } + const end = performance.now(); + const elapsed = end - start; + alive = false; + // the interval from the last beat to the end is starvation too -- in the + // fully-blocking case the heartbeat never fires at all and every ms of + // the loop lives in this final gap + const finalGap = end - last; + if (finalGap > BEAT_MS) { + blockedMs += finalGap - BEAT_MS; + if (finalGap > worstGapMs) worstGapMs = finalGap; + } + await gpu.destroy(); + const backend = kernel.kernel.constructor.name; + return { + label: mode + (asyncMode ? ' + asyncMode' : ''), + backend, + elapsedMs: +elapsed.toFixed(1), + blockedMs: +blockedMs.toFixed(1), + blockedPct: +(100 * blockedMs / elapsed).toFixed(1), + worstGapMs: +worstGapMs.toFixed(1), + beats, + sink, + }; + } + + const rows = []; + rows.push(await measure('webgl2', false)); + rows.push(await measure('webgl2', true)); + if (G.isWebGPUSupported && await G.isWebGPUAvailable()) { + rows.push(await measure('webgpu', false)); + } + rows.push(await measure('async', false)); + return rows; +} + +async function main() { + if (!(await portListening(PORT))) { + process.stderr.write('starting dev server on :' + PORT + '\n'); + spawn(process.execPath, [path.join(ROOT, 'scripts', 'dev.js')], { + env: { ...process.env, PORT: String(PORT) }, + stdio: 'ignore', + detached: true, + }).unref(); + const deadline = Date.now() + 15000; + while (!(await portListening(PORT))) { + if (Date.now() > deadline) throw new Error('dev server did not start on :' + PORT); + await new Promise(r => setTimeout(r, 250)); + } + } else { + process.stderr.write('dev server already listening on :' + PORT + '\n'); + } + + const browser = await chromium.launch({ headless: false, args: ['--use-angle=metal'] }); + try { + const page = await browser.newPage(); + await page.goto('http://localhost:' + PORT + '/test/', { waitUntil: 'domcontentloaded' }); + await page.addScriptTag({ url: '/dist/gpu-browser.js' }); + const rows = await page.evaluate(benchInPage); + + console.log('\n30 × matmul 512×512 with readback, 4 ms heartbeat beside it\n'); + console.log('| configuration | backend | wall time | main thread blocked | worst single stall |'); + console.log('|---|---|---|---|---|'); + for (const r of rows) { + console.log(`| ${r.label} | ${r.backend} | ${r.elapsedMs} ms | ${r.blockedMs} ms (${r.blockedPct}%) | ${r.worstGapMs} ms |`); + } + console.log('\n' + JSON.stringify(rows, null, 2)); + } finally { + await browser.close(); + } +} + +main().catch(error => { + console.error(error); + process.exit(1); +}); diff --git a/scripts/benchmark-webgpu.mjs b/scripts/benchmark-webgpu.mjs new file mode 100644 index 00000000..38227016 --- /dev/null +++ b/scripts/benchmark-webgpu.mjs @@ -0,0 +1,359 @@ +#!/usr/bin/env node +// Benchmarks cpu vs webgl2 vs webgpu over identical kernel sources against +// dist/gpu-browser.js, in headed Chromium — headless Chromium exposes +// navigator.gpu but requestAdapter() resolves null, so headed is mandatory. +// Prints a GitHub-markdown table plus the raw JSON to stdout (progress goes +// to stderr, nothing is written to disk). +// +// npm run build && node scripts/benchmark-webgpu.mjs +// +// Methodology (see scratchpad webgpu/test-bench-plan.md §3): +// - wall clock only; GPU timer queries report garbage on ANGLE Metal +// - every timed run is synced by reading back its own result — gl.finish() +// is not a sync on Metal +// - timed runs ping-pong between two input sets so no driver can elide a +// repeated dispatch (Apple TBDR elides redundant identical draws) +// - median of >= 10 runs, warmup excluded; cpu capped to 3 runs when a +// single run exceeds 2 s +// - every mode's results are cross-checked against cpu (relative 1e-4) +// before timing; a mismatch aborts the whole run +// - webgpu is attempted last: while the backend is absent (or the platform +// has no adapter) it reports "unavailable" and the cpu/webgl2 numbers +// still print; once src/backend/web-gpu lands, the column activates with +// no harness changes (kernel() returns a Promise there — every call site +// awaits, which is a no-op for the sync modes). + +import net from 'node:net'; +import path from 'node:path'; +import { spawn } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import { chromium } from '@playwright/test'; + +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +const PORT = 8099; + +function portListening(port) { + return new Promise(resolve => { + const socket = net.connect({ port, host: '127.0.0.1' }); + socket.once('connect', () => { socket.destroy(); resolve(true); }); + socket.once('error', () => resolve(false)); + }); +} + +// Everything below runs inside the page in ONE session: gpu.js parses kernel +// sources via Function.prototype.toString, so the kernels must be defined +// here, not passed in. Must stay closure-free — Playwright serializes it. +async function benchInPage() { + const G = window.GPU; + if (!G || !G.prototype || typeof G.prototype.createKernel !== 'function') { + throw new Error('dist/gpu-browser.js did not expose GPU — run npm run build first'); + } + const log = (...a) => console.log(a.join(' ')); + + // -- deterministic inputs, two sets per workload for ping-ponging -------- + function rng(seed) { + let s = seed >>> 0; + return function () { + s = (s + 0x6d2b79f5) >>> 0; + let t = s; + t = Math.imul(t ^ (t >>> 15), t | 1); + t ^= t + Math.imul(t ^ (t >>> 7), t | 61); + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; + }; + } + function matrix(n, seed) { + const r = rng(seed); + const m = new Array(n); + for (let y = 0; y < n; y++) { + const row = (m[y] = new Float32Array(n)); + for (let x = 0; x < n; x++) row[x] = r(); + } + return m; + } + function vector(n, seed) { + const r = rng(seed); + const v = new Float32Array(n); + for (let i = 0; i < n; i++) v[i] = r(); + return v; + } + const MAP_N = 4194304; + const inputs = { + mm512: { a: [matrix(512, 1), matrix(512, 3)], b: [matrix(512, 2), matrix(512, 4)] }, + mm1024: { a: [matrix(1024, 5), matrix(1024, 7)], b: [matrix(1024, 6), matrix(1024, 8)] }, + map: [vector(MAP_N, 9), vector(MAP_N, 10)], + }; + + // -- kernel sources, identical across all modes -------------------------- + function matmulSource(a, b) { + let sum = 0; + for (let i = 0; i < this.constants.size; i++) { + sum += a[this.thread.y][i] * b[i][this.thread.x]; + } + return sum; + } + function chain1Source(a) { + return a[this.thread.x] * 2 + 1; + } + function chain2Source(a) { + return a[this.thread.x] * 0.5 + 3; + } + function chain3Source(a) { + return a[this.thread.x] * 1.5 - 2; + } + // the 4M map reuses chain1Source — same source object is fine, each mode + // gets its own kernel instance + + // -- helpers ------------------------------------------------------------- + function median(sorted) { + const m = sorted.length >> 1; + return sorted.length % 2 ? sorted[m] : (sorted[m - 1] + sorted[m]) / 2; + } + function flatten(result) { + if (result.length && typeof result[0] !== 'number') { + const rows = Array.from(result); + const flat = new Float32Array(rows.length * rows[0].length); + for (let y = 0; y < rows.length; y++) flat.set(rows[y], y * rows[0].length); + return flat; + } + return result; + } + const refs = {}; + function gate(key, mode, result) { + const flat = flatten(result); + if (mode === 'cpu') { + refs[key] = flat.slice(); + return; + } + const ref = refs[key]; + if (!ref) throw new Error('RESULT MISMATCH: no cpu reference for ' + key); + if (flat.length !== ref.length) { + throw new Error('RESULT MISMATCH in ' + key + ' (' + mode + '): length ' + flat.length + ' vs cpu ' + ref.length); + } + let worst = 0, worstI = -1; + for (let i = 0; i < ref.length; i++) { + const d = Math.abs(flat[i] - ref[i]) / Math.max(1, Math.abs(ref[i])); + if (d > worst) { worst = d; worstI = i; } + } + if (worst > 1e-4) { + throw new Error('RESULT MISMATCH in ' + key + ' (' + mode + '): relative error ' + worst + + ' at index ' + worstI + ' (got ' + flat[worstI] + ', cpu says ' + ref[worstI] + ')'); + } + log(' ', key, mode, 'matches cpu (worst rel err ' + worst.toExponential(2) + ')'); + } + // fn(i) must materialize its result (that readback is the sync) + async function timeRuns(fn, { warmup, n, capMs }) { + for (let i = 0; i < warmup; i++) await fn(i); + const times = []; + let target = n; + while (times.length < target) { + const i = times.length; + const t0 = performance.now(); + await fn(i); + times.push(performance.now() - t0); + if (capMs && times.length === 1 && times[0] > capMs) target = Math.min(target, 3); + } + times.sort((a, b) => a - b); + return { median: median(times), min: times[0], max: times[times.length - 1], n: times.length, times }; + } + + // -- one mode, all workloads --------------------------------------------- + async function runMode(mode) { + const gpu = new G({ mode }); + const isCpu = mode === 'cpu'; + const warmup = isCpu ? 1 : mode === 'webgpu' ? 5 : 3; + const capMs = isCpu ? 2000 : 0; + const out = {}; + try { + for (const size of [512, 1024]) { + const key = 'matmul' + size; + const k = gpu.createKernel(matmulSource, { output: [size, size], constants: { size }, precision: 'single' }); + const mm = inputs['mm' + size]; + const once = async i => await k(mm.a[i % 2], mm.b[i % 2]); + gate(key, mode, await once(0)); + out[key] = await timeRuns(once, { warmup, n: 12, capMs }); + log(mode, key, out[key].median.toFixed(2), 'ms median of', out[key].n); + } + + const mk = gpu.createKernel(chain1Source, { output: [MAP_N], precision: 'single' }); + const mapOnce = async i => await mk(inputs.map[i % 2]); + gate('map4m', mode, await mapOnce(0)); + out.map4m = await timeRuns(mapOnce, { warmup, n: 12, capMs }); + log(mode, 'map4m', out.map4m.median.toFixed(2), 'ms median of', out.map4m.n); + + // 3-kernel chain: pipelined modes keep intermediates GPU-resident and + // read back only the final handle + const pipeline = !isCpu; + const kOpts = { output: [MAP_N], precision: 'single', pipeline }; + const c1 = gpu.createKernel(chain1Source, kOpts); + const c2 = gpu.createKernel(chain2Source, kOpts); + const c3 = gpu.createKernel(chain3Source, kOpts); + const chainOnce = async i => { + const h1 = await c1(inputs.map[i % 2]); + const h2 = await c2(h1); + const h3 = await c3(h2); + return { out: pipeline ? await h3.toArray() : h3, h3 }; + }; + gate('chain', mode, (await chainOnce(0)).out); + out.chainIncl = await timeRuns(async i => (await chainOnce(i)).out, { warmup, n: 12, capMs }); + log(mode, 'chainIncl', out.chainIncl.median.toFixed(2), 'ms median of', out.chainIncl.n); + + if (pipeline) { + // excl-readback is derived: readback of the result is the only + // reliable sync on Metal, so we measure the standalone toArray() + // cost on a settled handle and subtract its median + const { h3 } = await chainOnce(0); + out.readback = await timeRuns(async () => await h3.toArray(), { warmup: 2, n: 10, capMs: 0 }); + out.chainExcl = { + median: Math.max(0, out.chainIncl.median - out.readback.median), + derived: 'chainIncl.median - readback.median', + }; + log(mode, 'chainExcl', out.chainExcl.median.toFixed(2), 'ms (readback', out.readback.median.toFixed(2), 'ms)'); + } + } finally { + const d = gpu.destroy(); + if (d && typeof d.then === 'function') await d; + } + return out; + } + + // -- environment identification ------------------------------------------ + const env = { userAgent: navigator.userAgent, webgl2Renderer: null, webgpuAdapter: null }; + try { + const gl = document.createElement('canvas').getContext('webgl2'); + const ext = gl.getExtension('WEBGL_debug_renderer_info'); + env.webgl2Renderer = gl.getParameter(ext ? ext.UNMASKED_RENDERER_WEBGL : gl.RENDERER); + } catch (e) { + env.webgl2Renderer = 'unavailable: ' + e.message; + } + try { + if (!navigator.gpu) { + env.webgpuAdapter = 'navigator.gpu absent'; + } else { + const adapter = await navigator.gpu.requestAdapter(); + if (!adapter) { + env.webgpuAdapter = 'no adapter (headless or blocklisted)'; + } else { + const info = adapter.info || (adapter.requestAdapterInfo ? await adapter.requestAdapterInfo() : null); + env.webgpuAdapter = info + ? [info.vendor, info.architecture, info.device, info.description].filter(Boolean).join(' / ') + : 'adapter present (no info)'; + } + } + } catch (e) { + env.webgpuAdapter = 'error: ' + e.message; + } + + // -- the matrix: cpu first (builds references), webgpu last -------------- + const modes = {}; + modes.cpu = await runMode('cpu'); + modes.webgl2 = await runMode('webgl2'); + let webgpuStatus; + try { + if (G.isWebGPUSupported === false) { + throw new Error('GPU.isWebGPUSupported is false on this platform'); + } + modes.webgpu = await runMode('webgpu'); + webgpuStatus = 'ok'; + } catch (e) { + const msg = (e && e.message) || String(e); + // wrong answers abort loudly; a missing backend/adapter degrades cleanly + if (msg.indexOf('RESULT MISMATCH') !== -1) throw e; + modes.webgpu = null; + webgpuStatus = 'unavailable: ' + msg; + log('webgpu:', webgpuStatus); + } + + return { env, modes, webgpuStatus }; +} + +// -- report ---------------------------------------------------------------- +const ROWS = [ + ['matmul512', 'matmul 512×512 (incl. readback)'], + ['matmul1024', 'matmul 1024×1024 (incl. readback)'], + ['map4m', '4M-element map (incl. readback)'], + ['chainIncl', '3-kernel pipeline chain, final readback only'], + ['chainExcl', '3-kernel pipeline chain, excl. final readback \\*'], +]; + +function fmtMs(ms) { + return (ms >= 100 ? ms.toFixed(0) : ms >= 10 ? ms.toFixed(1) : ms.toFixed(2)) + ' ms'; +} + +function printReport(data, chromiumVersion) { + const { env, modes, webgpuStatus } = data; + const lines = []; + lines.push('### Benchmarks — cpu vs webgl2 vs webgpu'); + lines.push(''); + lines.push('- Chromium ' + chromiumVersion + ' (headed)'); + lines.push('- WebGL2 renderer: ' + env.webgl2Renderer); + lines.push('- WebGPU adapter: ' + env.webgpuAdapter); + if (webgpuStatus !== 'ok') lines.push('- webgpu mode: ' + webgpuStatus); + lines.push('- median, warmup excluded; every timed run synced by reading back its own result; inputs ping-ponged between two sets so no dispatch is elidable'); + lines.push(''); + lines.push('| Workload | cpu | webgl2 (single) | webgpu |'); + lines.push('|---|---|---|---|'); + for (const [key, label] of ROWS) { + // chainExcl has no cpu leg; its speedup is quoted vs the cpu chain incl readback + const cpuBase = modes.cpu[key === 'chainExcl' ? 'chainIncl' : key]; + const cells = ['cpu', 'webgl2', 'webgpu'].map(mode => { + const m = modes[mode]; + if (!m) return 'unavailable'; + const r = m[key]; + if (!r) return '—'; + if (mode === 'cpu') return fmtMs(r.median); + const speedup = cpuBase ? ' (' + (cpuBase.median / r.median).toFixed(1) + '× vs cpu)' : ''; + return fmtMs(r.median) + speedup; + }); + lines.push('| ' + [label, ...cells].join(' | ') + ' |'); + } + lines.push(''); + lines.push('\\* derived: chain median minus the median cost of a standalone `toArray()` on the settled final handle — readback of the result is the only trustworthy sync on Metal; speedup quoted vs the cpu chain including readback.'); + lines.push(''); + lines.push('

Raw results (JSON)'); + lines.push(''); + lines.push('```json'); + lines.push(JSON.stringify(data, null, 2)); + lines.push('```'); + lines.push(''); + lines.push('
'); + process.stdout.write(lines.join('\n') + '\n'); +} + +// -- driver ---------------------------------------------------------------- +async function main() { + let devServer = null; + if (await portListening(PORT)) { + process.stderr.write('dev server already listening on :' + PORT + '\n'); + } else { + process.stderr.write('starting dev server on :' + PORT + '\n'); + devServer = spawn(process.execPath, [path.join(ROOT, 'scripts', 'dev.js')], { + cwd: ROOT, + env: { ...process.env, PORT: String(PORT) }, + stdio: ['ignore', 'ignore', 'inherit'], + }); + const deadline = Date.now() + 10000; + while (!(await portListening(PORT))) { + if (Date.now() > deadline) throw new Error('dev server did not start on :' + PORT); + await new Promise(r => setTimeout(r, 200)); + } + } + + const browser = await chromium.launch({ headless: false, args: ['--use-angle=metal'] }); + try { + const page = await browser.newPage(); + page.on('console', msg => process.stderr.write('[page] ' + msg.text() + '\n')); + page.on('pageerror', err => process.stderr.write('[pageerror] ' + err.message + '\n')); + await page.goto('http://localhost:' + PORT + '/test/'); + await page.addScriptTag({ url: '/dist/gpu-browser.js' }); + const data = await page.evaluate(benchInPage); + printReport(data, browser.version()); + } finally { + await browser.close(); + if (devServer) devServer.kill(); + } +} + +main().catch(err => { + process.stderr.write('\nBENCHMARK ABORTED: ' + (err && err.stack || err) + '\n'); + process.exit(1); +}); diff --git a/src/backend/gl/kernel.js b/src/backend/gl/kernel.js index e2e55478..7ef5192a 100644 --- a/src/backend/gl/kernel.js +++ b/src/backend/gl/kernel.js @@ -888,11 +888,6 @@ class GLKernel extends Kernel { return result; } - resetSwitchingKernels() { - const existingValue = this.switchingKernels; - this.switchingKernels = null; - return existingValue; - } setOutput(output) { const newOutput = this.toKernelOutput(output); @@ -957,13 +952,6 @@ class GLKernel extends Kernel { this.output[2] ); } - switchKernels(reason) { - if (this.switchingKernels) { - this.switchingKernels.push(reason); - } else { - this.switchingKernels = [reason]; - } - } getVariablePrecisionString(textureSize = this.texSize, tactic = this.tactic, isInt = false) { if (!tactic) { if (!this.constructor.features.isSpeedTacticSupported) return 'highp'; diff --git a/src/backend/kernel.js b/src/backend/kernel.js index c6d9903f..8438044e 100644 --- a/src/backend/kernel.js +++ b/src/backend/kernel.js @@ -59,6 +59,15 @@ class Kernel { this.fallbackRequested = false; this.onRequestFallback = null; + /** + * Supplied by GPU.createKernel; swaps in a kernel compiled for the + * arguments this one was handed. Declared here rather than on the GL + * kernel so mergeSettings carries it onto every backend -- the cpu + * kernel needs it for the same argument-type changes. + * @type {Function|null} + */ + this.onRequestSwitchKernel = null; + /** * Name of the arguments found from parsing source argument * @type {String[]} @@ -198,6 +207,15 @@ class Kernel { */ this.pipeline = false; + /** + * Makes the kernel return a Promise of its result on every backend. + * Backends with a genuinely non-blocking readback (webgl2 fences, + * webgpu natively) use it; the rest resolve their synchronous result, + * so the calling contract is uniform either way. + * @type {Boolean} + */ + this.asyncMode = false; + /** * Make GPU use single precision or unsigned. Acceptable values: 'single' or 'unsigned' * @type {String|null} @@ -228,6 +246,13 @@ class Kernel { this.randomSeed = null; this.built = false; this.signature = null; + + /** + * Reasons this kernel cannot serve the call it was handed, collected for + * the caller's switch; null when it can. + * @type {IReason[]|null} + */ + this.switchingKernels = null; } /** @@ -567,6 +592,16 @@ class Kernel { return this; } + /** + * Set Promise-returning mode on/off + * @param {Boolean} flag + * @return {this} + */ + setAsyncMode(flag) { + this.asyncMode = flag; + return this; + } + /** * Set precision to 'unsigned' or 'single' * @param {String} flag 'unsigned' or 'single' @@ -896,10 +931,17 @@ class Kernel { case 'Integer': case 'Float': case 'ArrayTexture(1)': - argumentTypes[i] = utils.getVariableType(arg); + argumentTypes[i] = utils.getVariableType(arg, kernel.strictIntegers); break; default: - argumentTypes[i] = type; + // The recorded type only describes this value while the value + // still fits it. Keeping it for a value it cannot describe gives + // the switched-to kernel the same signature as the one that just + // rejected the value, so the switch resolves to a kernel that + // rejects it too -- and the run ends with no result at all. + argumentTypes[i] = utils.typeFitsValue(type, arg) ? + type : + utils.getVariableType(arg, kernel.strictIntegers); } } } @@ -950,6 +992,51 @@ class Kernel { * @abstract */ onActivate(previousKernel) {} + + /** + * @desc Flags that this kernel cannot serve the call it was just handed, so + * the caller swaps in one compiled for these arguments. + * @param {IReason} reason + */ + switchKernels(reason) { + if (this.switchingKernels) { + this.switchingKernels.push(reason); + } else { + this.switchingKernels = [reason]; + } + } + + resetSwitchingKernels() { + const existingValue = this.switchingKernels; + this.switchingKernels = null; + return existingValue; + } + + /** + * @desc A kernel is compiled for the argument types it first saw. Reusing + * the instance with a fundamentally different type (an Input where an array + * was, a number where an array was) needs a differently-compiled kernel, so + * ask for the switch before running rather than computing from a value the + * compiled code cannot read. + * + * The GL backends also detect this inside their kernel values, but only for + * the types that implement the check, and never on the cpu backend; this is + * the one place every backend passes through. + * @param {IArguments|Array} args + */ + checkArgumentTypes(args) { + if (!this.argumentTypes) return; + const length = Math.min(args.length, this.argumentTypes.length); + for (let i = 0; i < length; i++) { + if (!utils.typeFitsValue(this.argumentTypes[i], args[i])) { + this.switchKernels({ + type: 'argumentTypeMismatch', + index: i, + needed: utils.getVariableType(args[i], this.strictIntegers), + }); + } + } + } } function splitArgumentTypes(argumentTypesObject) { diff --git a/src/backend/web-gl/kernel-value-maps.js b/src/backend/web-gl/kernel-value-maps.js index 843164a7..07a6302a 100644 --- a/src/backend/web-gl/kernel-value-maps.js +++ b/src/backend/web-gl/kernel-value-maps.js @@ -188,6 +188,15 @@ function lookupKernelValueType(type, dynamic, precision, value) { type = value.type; } const types = kernelValueMaps[precision][dynamic]; + if (type === 'WebGPUBuffer') { + // a webgpu pipeline handle reached a GL kernel: possible when backends + // mix (a webgpu producer feeding a kernel that stayed on GL). The async + // contract converts these transparently; the sync path cannot. + throw new Error( + `this kernel runs on WebGL but received a WebGPU pipeline buffer; ` + + `await handle.toArray() first, or give this kernel the async contract (asyncMode: true / mode: 'async') ` + + `so the readback happens for you`); + } if (types[type] === false) { return null; } else if (types[type] === undefined) { diff --git a/src/backend/web-gl2/kernel-value-maps.js b/src/backend/web-gl2/kernel-value-maps.js index 728f592c..b6619dc0 100644 --- a/src/backend/web-gl2/kernel-value-maps.js +++ b/src/backend/web-gl2/kernel-value-maps.js @@ -191,6 +191,15 @@ function lookupKernelValueType(type, dynamic, precision, value) { type = value.type; } const types = kernelValueMaps[precision][dynamic]; + if (type === 'WebGPUBuffer') { + // a webgpu pipeline handle reached a GL kernel: possible when backends + // mix (a webgpu producer feeding a kernel that stayed on GL). The async + // contract converts these transparently; the sync path cannot. + throw new Error( + `this kernel runs on WebGL but received a WebGPU pipeline buffer; ` + + `await handle.toArray() first, or give this kernel the async contract (asyncMode: true / mode: 'async') ` + + `so the readback happens for you`); + } if (types[type] === false) { return null; } else if (types[type] === undefined) { diff --git a/src/backend/web-gl2/kernel.js b/src/backend/web-gl2/kernel.js index f4988e9f..a7d6675a 100644 --- a/src/backend/web-gl2/kernel.js +++ b/src/backend/web-gl2/kernel.js @@ -290,6 +290,110 @@ class WebGL2Kernel extends WebGLKernel { return result; } + /** + * @desc The genuinely non-blocking readback: readPixels into a + * PIXEL_PACK_BUFFER returns immediately, a fence marks when the GPU has + * caught up, and getBufferSubData after the fence signals is a plain copy. + * The read is issued here, synchronously after the draw while the kernel's + * framebuffer is still bound -- later draws on the shared context cannot + * affect it, because pack reads are ordered with the commands before them. + */ + renderOutputAsync() { + if (this.renderOutput !== this.renderValues) { + // pipeline textures (and inherited strategies) involve no transfer; + // resolving the synchronous render keeps the contract uniform + return Promise.resolve(this.renderOutput()); + } + return this.renderValuesAsync(); + } + + renderValuesAsync() { + if (this._tightRead === undefined) { + this._detectTightRead(); + } + const formatValues = this.formatValues; + const [x, y, z] = this.output; + return this.transferValuesAsync().then(pixels => formatValues(pixels, x, y, z)); + } + + transferValuesAsync() { + const { texSize, context: gl } = this; + const w = texSize[0]; + const h = texSize[1]; + let format, type, result; + if (this.precision === 'single') { + format = this._tightRead ? gl.RED : gl.RGBA; + type = gl.FLOAT; + result = new Float32Array(w * h * (this._tightRead ? 1 : 4)); + } else { + format = gl.RGBA; + type = gl.UNSIGNED_BYTE; + result = new Uint8Array(w * h * 4); + } + const pbo = gl.createBuffer(); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo); + gl.bufferData(gl.PIXEL_PACK_BUFFER, result.byteLength, gl.STREAM_READ); + gl.readPixels(0, 0, w, h, format, type, 0); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); + const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0); + // fences are queued, not submitted; without a flush the poll can spin + // forever waiting on commands the driver never dispatched + gl.flush(); + return this._pollFence(sync).then(() => { + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo); + gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, result); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); + gl.deleteBuffer(pbo); + return this.precision === 'single' ? result : new Float32Array(result.buffer); + }, (error) => { + gl.deleteBuffer(pbo); + throw error; + }); + } + + _pollFence(sync) { + const gl = this.context; + return new Promise((resolve, reject) => { + // repolling through a MessageChannel task rather than setTimeout: each + // check is its own event-loop turn (other work interleaves freely) but + // skips the nested-timeout clamp, which would tax every readback with + // multiple 4 ms waits after the GPU had already finished + let schedule; + let channel = null; + if (typeof MessageChannel !== 'undefined') { + channel = new MessageChannel(); + channel.port1.onmessage = () => poll(); + schedule = () => channel.port2.postMessage(0); + } else { + schedule = () => setTimeout(poll, 0); + } + const settle = (fn, value) => { + gl.deleteSync(sync); + if (channel) { + channel.port1.close(); + channel.port2.close(); + } + fn(value); + }; + const poll = () => { + if (gl.isContextLost()) { + return settle(reject, new Error('WebGL context lost while awaiting kernel result')); + } + // always zero timeout: a wait would block the very thread this exists + // to keep free + const status = gl.clientWaitSync(sync, 0, 0); + if (status === gl.ALREADY_SIGNALED || status === gl.CONDITION_SATISFIED) { + return settle(resolve); + } + if (status === gl.WAIT_FAILED) { + return settle(reject, new Error('clientWaitSync failed while awaiting kernel result')); + } + schedule(); + }; + poll(); + }); + } + _detectTightRead() { const gl = this.context; this._tightRead = false; diff --git a/src/backend/web-gpu/buffer-result.js b/src/backend/web-gpu/buffer-result.js new file mode 100644 index 00000000..066c35fa --- /dev/null +++ b/src/backend/web-gpu/buffer-result.js @@ -0,0 +1,57 @@ +/** + * @desc The pipeline-mode handle: wraps the kernel's GPU-resident output + * buffer the way Texture wraps a GL texture. Refcounted on the raw buffer + * (texture.js's `_refs` model) so clones and the owning kernel can each + * release independently; the buffer dies at zero. + */ +class WebGPUBufferResult { + /** + * @param {Object} settings + * @param {GPUBuffer} settings.buffer + * @param {number[]} settings.output logical dims, e.g. [512, 512] + * @param {number} [settings.componentCount] 1 for scalar returns, 2/3/4 for Array(n) + * @param {Object} settings.context the `{adapter, device}` pair from WebGPUContext + * @param {Object} settings.kernel owning WebGPUKernel, used for readback + shaping + */ + constructor(settings) { + this.buffer = settings.buffer; + this.output = settings.output; + this.componentCount = settings.componentCount || 1; + this.context = settings.context; + this.kernel = settings.kernel; + this.type = 'WebGPUBuffer'; + this._deleted = false; + if (this.buffer._refs) { + this.buffer._refs++; + } else { + this.buffer._refs = 1; + } + } + + /** + * @returns {Promise} values shaped exactly as a + * non-pipeline run of the producing kernel would resolve them + */ + toArray() { + if (this._deleted) { + return Promise.reject(new Error('WebGPUBufferResult has been deleted')); + } + return this.kernel.readBufferResult(this); + } + + delete() { + if (this._deleted) return; + this._deleted = true; + if (--this.buffer._refs === 0) { + this.buffer.destroy(); + } + } + + clone() { + return new WebGPUBufferResult(this); + } +} + +module.exports = { + WebGPUBufferResult +}; \ No newline at end of file diff --git a/src/backend/web-gpu/context.js b/src/backend/web-gpu/context.js new file mode 100644 index 00000000..1f9368b0 --- /dev/null +++ b/src/backend/web-gpu/context.js @@ -0,0 +1,88 @@ +/** + * @desc Module-level WebGPU device singleton. One GPUDevice serves every + * GPU instance in webgpu mode, the way all GL kernels share one context. + * `acquire()` is idempotent and caches the in-flight promise; a failed + * acquisition clears the cache so a later call can retry. + */ +let contextPromise = null; + +class WebGPUContext { + /** + * Sync, optimistic: the API surface exists. `navigator.gpu` can be present + * while `requestAdapter()` resolves null (headless Chromium does exactly + * this), so a true here does not promise a kernel will run — that is what + * `GPU.isWebGPUAvailable()` answers. + * @returns {boolean} + */ + static get isSupported() { + return typeof navigator !== 'undefined' && !!navigator.gpu; + } + + /** + * @returns {Promise<{adapter: GPUAdapter, device: GPUDevice}>} cached and shared + */ + static acquire() { + if (contextPromise) return contextPromise; + const promise = (async () => { + if (!WebGPUContext.isSupported) { + throw new Error('WebGPU is not supported on this platform (navigator.gpu is missing)'); + } + const adapter = await navigator.gpu.requestAdapter(); + if (!adapter) { + throw new Error( + 'WebGPU is present (navigator.gpu) but no adapter is available. ' + + 'On headless Chromium there is no adapter; run headed. ' + + 'Use `await GPU.isWebGPUAvailable()` to feature-detect.'); + } + // the spec defaults cap storage bindings at 128 MiB regardless of the + // hardware; ask for everything the adapter can actually give, so large + // outputs are limited by the device, not by a default + const device = await adapter.requestDevice({ + requiredLimits: { + maxStorageBufferBindingSize: adapter.limits.maxStorageBufferBindingSize, + maxBufferSize: adapter.limits.maxBufferSize, + }, + }); + const context = { adapter, device, isLost: false }; + device.lost.then(info => { + // every built kernel holds this context object; the flag is how they + // learn their device died instead of resolving empty results forever + context.isLost = true; + if (info.reason !== 'destroyed') { + console.error(`gpu.js [webgpu]: device lost: ${ info.message }`); + } + if (contextPromise === promise) { + contextPromise = null; + } + }); + device.onuncapturederror = e => { + console.error(`gpu.js [webgpu]: ${ e.error.message }`); + }; + return context; + })(); + promise.catch(() => { + if (contextPromise === promise) { + contextPromise = null; + } + }); + return contextPromise = promise; + } + + /** + * Destroys the shared device. `gpu.destroy()` does NOT call this — the + * device outlives any one GPU instance; this is the page-level teardown. + * @returns {Promise} + */ + static destroy() { + if (!contextPromise) return Promise.resolve(); + const promise = contextPromise; + contextPromise = null; + return promise.then(({ device }) => { + device.destroy(); + }, () => {}); + } +} + +module.exports = { + WebGPUContext +}; \ No newline at end of file diff --git a/src/backend/web-gpu/function-node.js b/src/backend/web-gpu/function-node.js new file mode 100644 index 00000000..3f3814f6 --- /dev/null +++ b/src/backend/web-gpu/function-node.js @@ -0,0 +1,1580 @@ +const { utils } = require('../../utils'); +const { FunctionNode } = require('../function-node'); + +/** + * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo + * required to toString its respective WGSL code. Extends the base + * FunctionNode directly (not the WebGL node): WGSL shares GLSL's numeric + * strictness — the casting-state discipline is ported — but none of its + * texture machinery. + * + * Names this emitter shares with the kernel assembler (kernel.js): + * `gid` (root entry's global_invocation_id), `threadGid` (module-private + * mirror of gid for helper functions), `data_index`, `params`, `result`, + * `get_user_X`/`get_constants_X` flat accessors, `constants_X` bindings and + * `LOOP_MAX`. + */ +class WGSLFunctionNode extends FunctionNode { + /** + * WGSL rejects float literals that overflow f32 (GLSL forgave them), and + * JS toString of an integral double has no decimal point. Every float + * literal goes through here so the emitted text is always a committed, + * in-range WGSL float. + * @param {number} value + * @returns {String} + */ + wgslFloat(value) { + if (value === Infinity) return '0x1.fffffep+127'; + if (value === -Infinity) return '-0x1.fffffep+127'; + if (value > 3.4028234663852886e38) return '0x1.fffffep+127'; + if (value < -3.4028234663852886e38) return '-0x1.fffffep+127'; + const str = `${ value }`; + if (str.indexOf('.') !== -1 || str.indexOf('e') !== -1 || str.indexOf('E') !== -1) { + return str; + } + return `${ str }.0`; + } + + /** + * @param {number} value + * @returns {String} + */ + wgslInt(value) { + return `${ Math.round(value) }`; + } + + /** + * User function names collide with WGSL keywords and builtins where GLSL + * names did not; mangle rather than reject. + * @param {String} name + * @returns {String} + */ + mangleFunctionName(name) { + if (reservedNames.indexOf(name) !== -1) { + return `fn_${ name }`; + } + return utils.sanitizeName(name); + } + + /** + * A WebGPUBufferResult argument reads like a flat storage array; the base + * typeLookupMap does not know the type, so value lookup is resolved here. + */ + getLookupType(type) { + if (type === 'WebGPUBuffer') { + return 'Number'; + } + return super.getLookupType(type); + } + + /** + * WGSL has no ternary. Pure-value case lowers to `select(false, true, cond)` + * — both sides evaluate eagerly, which is observationally safe in the + * side-effect-free kernel language. Void (minified) case lowers to if/else. + */ + astUpdateExpression(uNode, retArr) { + // WGSL has only the postfix increment/decrement statement form; at the + // statement and for-update positions -- the only places WGSL allows an + // increment at all -- prefix and postfix are indistinguishable, so both + // emit postfix rather than the invalid `++x` + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + return retArr; + } + + getType(ast) { + // a ternary with an integer consequent but a float alternate emits as + // f32 (see astConditionalExpression); the type system must agree or the + // enclosing expression casts the wrong way + if (ast && ast.type === 'ConditionalExpression') { + const consequentType = this.getType(ast.consequent); + if (consequentType === 'Integer' || consequentType === 'LiteralInteger') { + const alternateType = this.getType(ast.alternate); + if (alternateType === 'Number' || alternateType === 'Float') { + return 'Number'; + } + } + } + return super.getType(ast); + } + + astConditionalExpression(ast, retArr) { + if (ast.type !== 'ConditionalExpression') { + throw this.astErrorOutput('Not a conditional expression', ast); + } + const consequentType = this.getType(ast.consequent); + const alternateType = this.getType(ast.alternate); + if (consequentType === null && alternateType === null) { + retArr.push('if ('); + this.astGeneric(ast.test, retArr); + retArr.push(') {'); + this.astGeneric(ast.consequent, retArr); + retArr.push(';'); + retArr.push('} else {'); + this.astGeneric(ast.alternate, retArr); + retArr.push(';'); + retArr.push('}'); + return retArr; + } + // the consequent's type wins, matching getType's ConditionalExpression rule + let targetType = consequentType === 'LiteralInteger' ? 'Number' : consequentType; + // mixed int/float branches promote to float: coercing the float branch to + // integer would silently round it away from JS semantics. getType's + // ConditionalExpression override reports the same promotion. + if (targetType === 'Integer' && (alternateType === 'Number' || alternateType === 'Float')) { + targetType = 'Number'; + } + const emitBranch = (branch) => { + const branchType = this.getType(branch); + switch (targetType) { + case 'Number': + case 'Float': + if (branchType === 'Integer') { + this.castValueToFloat(branch, retArr); + } else if (branchType === 'LiteralInteger') { + this.castLiteralToFloat(branch, retArr); + } else { + this.astGeneric(branch, retArr); + } + break; + case 'Integer': + if (branchType === 'Number' || branchType === 'Float') { + this.castValueToInteger(branch, retArr); + } else if (branchType === 'LiteralInteger') { + this.castLiteralToInteger(branch, retArr); + } else { + this.astGeneric(branch, retArr); + } + break; + default: + this.astGeneric(branch, retArr); + } + }; + // select(falseValue, trueValue, condition) + retArr.push('select('); + emitBranch(ast.alternate); + retArr.push(', '); + emitBranch(ast.consequent); + retArr.push(', '); + this.astGeneric(ast.test, retArr); + retArr.push(')'); + return retArr; + } + + /** + * Root kernel: emits only body statements — the kernel class assembles the + * `@compute` entry, guard and `data_index` around them. Non-root: a full + * `fn name(args) -> type { ... }` declaration. + */ + astFunction(ast, retArr) { + if (this.isRootKernel) { + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push('\n'); + } + return retArr; + } + + if (!this.returnType) { + const lastReturn = this.findLastReturn(); + if (lastReturn) { + this.returnType = this.getType(ast.body); + if (this.returnType === 'LiteralInteger') { + this.returnType = 'Number'; + } + } + } + + const { returnType } = this; + let type = null; + if (returnType) { + type = typeMap[returnType]; + if (!type) { + throw this.astErrorOutput(`unknown return type ${ returnType }`, ast); + } + } + + retArr.push(`fn ${ this.mangleFunctionName(this.name) }(`); + for (let i = 0; i < this.argumentNames.length; ++i) { + const argumentName = this.argumentNames[i]; + if (i > 0) { + retArr.push(', '); + } + let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)]; + if (!argumentType) { + throw this.astErrorOutput(`Unknown argument ${ argumentName } type`, ast); + } + if (argumentType === 'LiteralInteger') { + this.argumentTypes[i] = argumentType = 'Number'; + } + const wgslType = typeMap[argumentType]; + if (!wgslType) { + throw this.astErrorOutput(`WebGPU backend does not yet support ${ argumentType } arguments to helper functions`, ast); + } + retArr.push(`user_${ utils.sanitizeName(argumentName) } : ${ wgslType }`); + } + retArr.push(')'); + if (type) { + retArr.push(` -> ${ type }`); + } + retArr.push(' {\n'); + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push('\n'); + } + retArr.push('}\n'); + return retArr; + } + + astReturnStatement(ast, retArr) { + if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast); + this.pushState('skip-literal-correction'); + const type = this.getType(ast.argument); + this.popState('skip-literal-correction'); + + const result = []; + + if (!this.returnType) { + if (type === 'LiteralInteger' || type === 'Integer') { + this.returnType = 'Number'; + } else { + this.returnType = type; + } + } + + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Float': + switch (type) { + case 'Integer': + result.push('f32('); + this.astGeneric(ast.argument, result); + result.push(')'); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.argument, result); + // if constraints forced the literal to pick integer anyway, cast it + if (this.getType(ast.argument) === 'Integer') { + result.unshift('f32('); + result.push(')'); + } + break; + default: + this.astGeneric(ast.argument, result); + } + break; + case 'Integer': + switch (type) { + case 'Float': + case 'Number': + this.castValueToInteger(ast.argument, result); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.argument, result); + break; + default: + this.astGeneric(ast.argument, result); + } + break; + case 'Boolean': + case 'Array(4)': + case 'Array(3)': + case 'Array(2)': + this.astGeneric(ast.argument, result); + break; + default: + throw this.astErrorOutput(`unhandled return type ${ this.returnType }`, ast); + } + + if (this.isRootKernel) { + switch (this.returnType) { + case 'Array(4)': + case 'Array(3)': + case 'Array(2)': { + const n = parseInt(this.returnType.substring(6), 10); + const temp = this.getInternalVariableName('kernelResultVec'); + retArr.push(`let ${ temp } : ${ typeMap[this.returnType] } = ${ result.join('') };\n`); + for (let c = 0; c < n; c++) { + retArr.push(`result[data_index * ${ n } + ${ c }] = ${ temp }.${ vectorComponents[c] };\n`); + } + retArr.push('return;'); + break; + } + case 'Integer': + retArr.push(`result[data_index] = f32(${ result.join('') });`); + retArr.push('return;'); + break; + default: + retArr.push(`result[data_index] = ${ result.join('') };`); + retArr.push('return;'); + } + } else if (this.isSubKernel) { + throw this.astErrorOutput('WebGPU backend does not yet support createKernelMap', ast); + } else { + retArr.push(`return ${ result.join('') };`); + } + return retArr; + } + + astLiteral(ast, retArr) { + if (ast.value === true || ast.value === false) { + retArr.push(ast.value ? 'true' : 'false'); + return retArr; + } + if (isNaN(ast.value)) { + throw this.astErrorOutput('Non-numeric literal not supported : ' + ast.value, ast); + } + + const key = this.astKey(ast); + if (Number.isInteger(ast.value)) { + if (this.isState('casting-to-integer') || this.isState('building-integer')) { + this.literalTypes[key] = 'Integer'; + retArr.push(this.wgslInt(ast.value)); + } else { + this.literalTypes[key] = 'Number'; + retArr.push(this.wgslFloat(ast.value)); + } + } else if (this.isState('casting-to-integer') || this.isState('building-integer')) { + this.literalTypes[key] = 'Integer'; + retArr.push(this.wgslInt(ast.value)); + } else { + this.literalTypes[key] = 'Number'; + retArr.push(this.wgslFloat(ast.value)); + } + return retArr; + } + + astBinaryExpression(ast, retArr) { + if (this.checkAndUpconvertOperator(ast, retArr)) { + return retArr; + } + + // `/` and `%` are always fractional in JavaScript; WGSL i32/i32 truncates + // exactly like GLSL, so both operands go to float whatever their own + // types are. WGSL's `%` is truncated for f32 and i32 alike — identical to + // JS — so unlike GLSL no helper function is needed, just the same casts. + if (ast.operator === '/' || ast.operator === '%') { + retArr.push('('); + this.pushState('building-float'); + switch (this.getType(ast.left)) { + case 'Integer': + this.castValueToFloat(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(ast.operator); + switch (this.getType(ast.right)) { + case 'Integer': + this.castValueToFloat(ast.right, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.right, retArr); + break; + default: + this.astGeneric(ast.right, retArr); + } + this.popState('building-float'); + retArr.push(')'); + return retArr; + } + + retArr.push('('); + const leftType = this.getType(ast.left) || 'Number'; + const rightType = this.getType(ast.right) || 'Number'; + const key = leftType + ' & ' + rightType; + switch (key) { + case 'Integer & Integer': + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-integer'); + break; + case 'Number & Float': + case 'Float & Number': + case 'Float & Float': + case 'Number & Number': + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-float'); + break; + case 'LiteralInteger & LiteralInteger': + if (this.isState('casting-to-integer') || this.isState('building-integer')) { + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.castLiteralToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); + this.popState('building-float'); + } + break; + case 'Integer & Float': + case 'Integer & Number': + if ((ast.operator === '>' || ast.operator === '<') && ast.right.type === 'Literal') { + // a fractional literal must not truncate: cast left to float instead + if (!Number.isInteger(ast.right.value)) { + this.pushState('building-float'); + this.castValueToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-float'); + break; + } + } + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState('casting-to-integer'); + if (ast.right.type === 'Literal') { + const literalResult = []; + this.astGeneric(ast.right, literalResult); + const literalType = this.getType(ast.right); + if (literalType === 'Integer') { + retArr.push(literalResult.join('')); + } else { + throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); + } + } else { + retArr.push('i32('); + this.astGeneric(ast.right, retArr); + retArr.push(')'); + } + this.popState('casting-to-integer'); + this.popState('building-integer'); + break; + case 'Integer & LiteralInteger': + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToInteger(ast.right, retArr); + this.popState('building-integer'); + break; + case 'Number & Integer': + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToFloat(ast.right, retArr); + this.popState('building-float'); + break; + case 'Float & LiteralInteger': + case 'Number & LiteralInteger': + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); + this.popState('building-float'); + break; + case 'LiteralInteger & Float': + case 'LiteralInteger & Number': + if (this.isState('casting-to-integer')) { + this.pushState('building-integer'); + this.castLiteralToInteger(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToInteger(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.castLiteralToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState('casting-to-float'); + this.astGeneric(ast.right, retArr); + this.popState('casting-to-float'); + this.popState('building-float'); + } + break; + case 'LiteralInteger & Integer': + this.pushState('building-integer'); + this.castLiteralToInteger(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-integer'); + break; + case 'Boolean & Boolean': + this.pushState('building-boolean'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-boolean'); + break; + case 'Float & Integer': + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToFloat(ast.right, retArr); + this.popState('building-float'); + break; + default: + throw this.astErrorOutput(`Unhandled binary expression between ${ key }`, ast); + } + retArr.push(')'); + return retArr; + } + + /** + * `**` upconverts to pow(f32, f32); bitwise operators are native in WGSL + * (GLSL ES 1.00 needed helper functions) and need only operand casts. + */ + checkAndUpconvertOperator(ast, retArr) { + if (this.checkAndUpconvertBitwiseOperators(ast, retArr)) { + return retArr; + } + if (ast.operator !== '**') return null; + retArr.push('_pow'); + retArr.push('('); + switch (this.getType(ast.left)) { + case 'Integer': + this.castValueToFloat(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(','); + switch (this.getType(ast.right)) { + case 'Integer': + this.castValueToFloat(ast.right, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.right, retArr); + break; + default: + this.astGeneric(ast.right, retArr); + } + retArr.push(')'); + return retArr; + } + + checkAndUpconvertBitwiseOperators(ast, retArr) { + const bitwiseOperators = { + '&': true, + '|': true, + '^': true, + '<<': true, + '>>': true, + '>>>': true, + }; + if (!bitwiseOperators[ast.operator]) return null; + const emitAsInteger = (side) => { + switch (this.getType(side)) { + case 'Number': + case 'Float': + this.castValueToInteger(side, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(side, retArr); + break; + default: + this.pushState('building-integer'); + this.astGeneric(side, retArr); + this.popState('building-integer'); + } + }; + retArr.push('('); + if (ast.operator === '>>>') { + // JS >>> through the i32 pipe: shift as u32, bitcast back + retArr.push('bitcast(bitcast('); + emitAsInteger(ast.left); + retArr.push(') >> u32('); + emitAsInteger(ast.right); + retArr.push('))'); + } else if (ast.operator === '<<' || ast.operator === '>>') { + // WGSL requires the shift amount to be u32; >> on i32 is arithmetic = JS + emitAsInteger(ast.left); + retArr.push(` ${ ast.operator } u32(`); + emitAsInteger(ast.right); + retArr.push(')'); + } else { + emitAsInteger(ast.left); + retArr.push(` ${ ast.operator } `); + emitAsInteger(ast.right); + } + retArr.push(')'); + return retArr; + } + + checkAndUpconvertBitwiseUnary(ast, retArr) { + if (ast.operator !== '~') return null; + retArr.push('~('); + switch (this.getType(ast.argument)) { + case 'Number': + case 'Float': + this.castValueToInteger(ast.argument, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.argument, retArr); + break; + default: + this.astGeneric(ast.argument, retArr); + } + retArr.push(')'); + return retArr; + } + + astUnaryExpression(uNode, retArr) { + const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr); + if (unaryResult) { + return retArr; + } + // WGSL has no unary `+` + if (uNode.operator === '+') { + this.astGeneric(uNode.argument, retArr); + return retArr; + } + if (uNode.prefix) { + retArr.push(uNode.operator); + this.astGeneric(uNode.argument, retArr); + } else { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + } + return retArr; + } + + castLiteralToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + this.astGeneric(ast, retArr); + this.popState('casting-to-integer'); + return retArr; + } + + castLiteralToFloat(ast, retArr) { + this.pushState('casting-to-float'); + this.astGeneric(ast, retArr); + this.popState('casting-to-float'); + return retArr; + } + + castValueToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + retArr.push('i32('); + this.astGeneric(ast, retArr); + retArr.push(')'); + this.popState('casting-to-integer'); + return retArr; + } + + castValueToFloat(ast, retArr) { + this.pushState('casting-to-float'); + retArr.push('f32('); + this.astGeneric(ast, retArr); + retArr.push(')'); + this.popState('casting-to-float'); + return retArr; + } + + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode); + } + + const type = this.getType(idtNode); + const name = utils.sanitizeName(idtNode.name); + if (idtNode.name === 'Infinity') { + retArr.push('0x1.fffffep+127'); + return retArr; + } + + // scalar kernel arguments live in the uniform Params struct; everything + // else (locals, helper-function parameters) is a plain user_ variable + const isRootScalarArgument = this.isRootKernel && + this.argumentNames.indexOf(idtNode.name) !== -1 && + (type === 'Number' || type === 'Float' || type === 'Integer' || type === 'Boolean'); + if (isRootScalarArgument) { + if (type === 'Boolean') { + // booleans are not host-shareable; they arrive as u32 and rehydrate + retArr.push(`bool(params.user_${ name })`); + } else { + retArr.push(`params.user_${ name }`); + } + return retArr; + } + retArr.push(`user_${ name }`); + return retArr; + } + + astForStatement(forNode, retArr) { + if (forNode.type !== 'ForStatement') { + throw this.astErrorOutput('Invalid for statement', forNode); + } + + const initArr = []; + const testArr = []; + const updateArr = []; + const bodyArr = []; + let isSafe = null; + + if (forNode.init) { + const { declarations } = forNode.init; + if (declarations.length > 1) { + isSafe = false; + } + this.astGeneric(forNode.init, initArr); + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init && declarations[i].init.type !== 'Literal') { + isSafe = false; + } + } + } else { + isSafe = false; + } + + if (forNode.test) { + this.astGeneric(forNode.test, testArr); + } else { + isSafe = false; + } + + if (forNode.update) { + if (forNode.update.type === 'AssignmentExpression') { + this.pushState('assignment-as-statement'); + } + this.astGeneric(forNode.update, updateArr); + } else { + isSafe = false; + } + + if (forNode.body) { + this.pushState('loop-body'); + this.astGeneric(forNode.body, bodyArr); + this.popState('loop-body'); + } + + if (isSafe === null) { + isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); + } + + if (isSafe) { + const initString = initArr.join(''); + const initNeedsSemiColon = initString[initString.length - 1] !== ';'; + retArr.push(`for (${ initString }${ initNeedsSemiColon ? ';' : '' }${ testArr.join('') };${ updateArr.join('') }){\n`); + retArr.push(bodyArr.join('')); + retArr.push('}\n'); + } else { + const iVariableName = this.getInternalVariableName('safeI'); + if (initArr.length > 0) { + retArr.push(initArr.join(''), '\n'); + } + retArr.push(`for (var ${ iVariableName } : i32 = 0;${ iVariableName } 0) { + // WGSL requires braces on every if + retArr.push(`if (!(${ testArr.join('') })) { break; }\n`); + } + retArr.push(bodyArr.join('')); + retArr.push(`\n${ updateArr.join('') };`); + retArr.push('}\n'); + } + return retArr; + } + + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== 'WhileStatement') { + throw this.astErrorOutput('Invalid while statement', whileNode); + } + const iVariableName = this.getInternalVariableName('safeI'); + retArr.push(`for (var ${ iVariableName } : i32 = 0;${ iVariableName } { + if (!node || typeof node !== 'object') return false; + if (Array.isArray(node)) return node.some(containsBreak); + if (node.type === 'BreakStatement') return true; + if ( + node.type === 'ForStatement' || + node.type === 'WhileStatement' || + node.type === 'DoWhileStatement' || + node.type === 'SwitchStatement' + ) { + return false; + } + for (const key in node) { + if (key === 'loc' || key === 'range' || key === 'parent') continue; + if (containsBreak(node[key])) return true; + } + return false; + }; + if (containsBreak(statements[i])) { + throw this.astErrorOutput( + 'break inside a switch case is only supported as the case terminator', + statements[i] + ); + } + } + for (let i = 0; i < statements.length; i++) { + this.astGeneric(statements[i], retArr); + retArr.push('\n'); + } + return retArr; + } + + astSwitchStatement(ast, retArr) { + if (ast.type !== 'SwitchStatement') { + throw this.astErrorOutput('Invalid switch statement', ast); + } + const { discriminant, cases } = ast; + const type = this.getType(discriminant); + const varName = `switchDiscriminant${ this.astKey(ast, '_') }`; + switch (type) { + case 'Float': + case 'Number': + retArr.push(`var ${ varName } : f32 = `); + this.astGeneric(discriminant, retArr); + retArr.push(';\n'); + break; + case 'Integer': + retArr.push(`var ${ varName } : i32 = `); + this.astGeneric(discriminant, retArr); + retArr.push(';\n'); + break; + default: + throw this.astErrorOutput(`Unhandled switch discriminant type "${ type }"`, ast); + } + if (cases.length === 1 && !cases[0].test) { + this.astSwitchCaseConsequent(cases[0].consequent, retArr); + return retArr; + } + + let fallingThrough = false; + let defaultResult = []; + let movingDefaultToEnd = false; + let pastFirstIf = false; + for (let i = 0; i < cases.length; i++) { + if (!cases[i].test) { + if (cases.length > i + 1) { + movingDefaultToEnd = true; + this.astSwitchCaseConsequent(cases[i].consequent, defaultResult); + continue; + } else { + retArr.push(' else {\n'); + } + } else { + if (i === 0 || !pastFirstIf) { + pastFirstIf = true; + retArr.push(`if (${ varName } == `); + } else { + if (fallingThrough) { + retArr.push(`${ varName } == `); + fallingThrough = false; + } else { + retArr.push(` else if (${ varName } == `); + } + } + if (type === 'Integer') { + const testType = this.getType(cases[i].test); + switch (testType) { + case 'Number': + case 'Float': + this.castValueToInteger(cases[i].test, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(cases[i].test, retArr); + break; + } + } else { + const testType = this.getType(cases[i].test); + switch (testType) { + case 'LiteralInteger': + this.castLiteralToFloat(cases[i].test, retArr); + break; + case 'Integer': + this.castValueToFloat(cases[i].test, retArr); + break; + default: + this.astGeneric(cases[i].test, retArr); + } + } + if (!cases[i].consequent || cases[i].consequent.length === 0) { + fallingThrough = true; + retArr.push(' || '); + continue; + } + retArr.push(`) {\n`); + } + this.astSwitchCaseConsequent(cases[i].consequent, retArr); + retArr.push('\n}'); + } + if (movingDefaultToEnd) { + retArr.push(' else {'); + retArr.push(defaultResult.join('')); + retArr.push('}'); + } + retArr.push('\n'); + return retArr; + } + + astThisExpression(tNode, retArr) { + retArr.push('this'); + return retArr; + } + + astSequenceExpression(sNode, retArr) { + // WGSL has no comma operator; only single-expression sequences (and the + // babel `(0, fn)(...)` pattern, which astCallExpression consumes before + // reaching here) can be emitted + const { expressions } = sNode; + if (expressions.length === 1) { + this.astGeneric(expressions[0], retArr); + return retArr; + } + throw this.astErrorOutput('WebGPU backend does not yet support the comma operator', sNode); + } + + astMemberExpression(mNode, retArr) { + const { + property, + name, + signature, + origin, + type, + xProperty, + yProperty, + zProperty + } = this.getMemberExpressionDetails(mNode); + switch (signature) { + case 'value.thread.value': + case 'this.thread.value': + if (name !== 'x' && name !== 'y' && name !== 'z') { + throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode); + } + // gid only exists in the entry function; helpers read the private mirror + // always through threadGid: main derives it from the folded flat + // index for large 1D dispatches, so raw gid is wrong there + retArr.push(`i32(threadGid.${ name })`); + return retArr; + case 'this.output.value': { + const axisIndex = { x: 0, y: 1, z: 2 } [name]; + if (axisIndex === undefined) { + throw this.astErrorOutput('Unexpected expression', mNode); + } + if (this.dynamicOutput) { + const member = `params.output${ name.toUpperCase() }`; + if (this.isState('casting-to-float')) { + retArr.push(`f32(${ member })`); + } else { + retArr.push(`i32(${ member })`); + } + } else { + if (this.isState('casting-to-integer')) { + retArr.push(`${ this.output[axisIndex] }`); + } else { + retArr.push(`${ this.output[axisIndex] }.0`); + } + } + return retArr; + } + case 'value': + throw this.astErrorOutput('Unexpected expression', mNode); + case 'value[]': + case 'value[][]': + case 'value[][][]': + case 'value[][][][]': + case 'value.value': + if (origin === 'Math') { + retArr.push(this.wgslFloat(Math[name])); + return retArr; + } + switch (property) { + // WGSL vectors accept rgba swizzles too, but xyzw reads clearer + case 'r': + retArr.push(`user_${ utils.sanitizeName(name) }.x`); + return retArr; + case 'g': + retArr.push(`user_${ utils.sanitizeName(name) }.y`); + return retArr; + case 'b': + retArr.push(`user_${ utils.sanitizeName(name) }.z`); + return retArr; + case 'a': + retArr.push(`user_${ utils.sanitizeName(name) }.w`); + return retArr; + } + break; + case 'this.constants.value': { + // constants are fixed at build; scalars bake straight into the source + const value = this.constants[name]; + switch (type) { + case 'Integer': + if (this.isState('casting-to-float')) { + retArr.push(this.wgslFloat(value)); + } else { + retArr.push(this.wgslInt(value)); + } + return retArr; + case 'Number': + case 'Float': + if (this.isState('casting-to-integer')) { + retArr.push(this.wgslInt(value)); + } else { + retArr.push(this.wgslFloat(value)); + } + return retArr; + case 'Boolean': + retArr.push(value ? 'true' : 'false'); + return retArr; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': { + const n = parseInt(type.substring(6), 10); + const parts = []; + for (let i = 0; i < n; i++) { + parts.push(this.wgslFloat(value[i])); + } + retArr.push(`${ typeMap[type] }(${ parts.join(', ') })`); + return retArr; + } + default: + throw this.astErrorOutput(`WebGPU backend does not yet support constant type ${ type }`, mNode); + } + } + case 'this.constants.value[]': + case 'this.constants.value[][]': + case 'this.constants.value[][][]': + case 'this.constants.value[][][][]': + break; + case 'fn()[]': + this.astCallExpression(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(property)); + retArr.push(']'); + return retArr; + default: + throw this.astErrorOutput(`WebGPU backend does not yet support expression signature "${ signature }"`, mNode); + } + + const markupName = `${ origin }_${ utils.sanitizeName(name) }`; + + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + // local vector with dynamic index + this.astGeneric(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(xProperty)); + retArr.push(']'); + break; + case 'Array': + case 'Array2D': + case 'Array3D': + case 'Input': + case 'WebGPUBuffer': + case 'Number': + case 'Float': + case 'Integer': + // monomorphized flat accessor per buffer; z,y,x order with zero-fill + retArr.push(`get_${ markupName }(`); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'Matrix(2)': + case 'Matrix(3)': + case 'Matrix(4)': + throw this.astErrorOutput('WebGPU backend does not yet support Matrix types', mNode); + default: + throw this.astErrorOutput(`WebGPU backend does not yet support member expression type "${ type }"`, mNode); + } + return retArr; + } + + astCallExpression(ast, retArr) { + if (!ast.callee) { + throw this.astErrorOutput('Unknown CallExpression', ast); + } + + let functionName = null; + const isMathFunction = this.isAstMathFunction(ast); + + if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) { + functionName = ast.callee.property.name; + } else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) { + functionName = ast.callee.expressions[1].property.name; + } else { + functionName = ast.callee.name; + } + + if (!functionName) { + throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast); + } + + // FunctionBuilder's functionMap and the type-inference tables are keyed + // by the ORIGINAL function name; only the emitted WGSL uses the mangled + // one. Mangling before the registry traffic would silently drop the + // helper's definition from the assembled shader. + let emitName = functionName; + if (isMathFunction) { + if (functionName === 'random') { + throw this.astErrorOutput('WebGPU backend does not yet support Math.random', ast); + } + if (mathFunctionRenames[functionName]) { + functionName = mathFunctionRenames[functionName]; + } + emitName = functionName; + } else { + emitName = this.mangleFunctionName(functionName); + } + + if (this.calledFunctions.indexOf(functionName) < 0) { + this.calledFunctions.push(functionName); + } + + if (this.onFunctionCall) { + this.onFunctionCall(this.name, functionName, ast.arguments); + } + + // the WGSL result of floor/ceil/round is f32, but the type system calls + // it Integer; a call consumed while building an integer expression needs + // the cast the type system believes is already there + const needsIntegerWrap = isMathFunction && + integerResultMathFunctions[functionName] && + this.isState('building-integer'); + if (needsIntegerWrap) { + retArr.push('i32('); + } + + retArr.push(emitName); + retArr.push('('); + + if (isMathFunction) { + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + const argumentType = this.getType(argument); + if (i > 0) { + retArr.push(', '); + } + switch (argumentType) { + case 'Integer': + this.castValueToFloat(argument, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(argument, retArr); + break; + default: + this.astGeneric(argument, retArr); + break; + } + } + } else { + const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + let targetType = targetTypes[i]; + if (i > 0) { + retArr.push(', '); + } + const argumentType = this.getType(argument); + if (!targetType) { + this.triggerImplyArgumentType(functionName, i, argumentType, this); + targetType = argumentType; + } + switch (argumentType) { + case 'Boolean': + this.astGeneric(argument, retArr); + continue; + case 'Number': + case 'Float': + if (targetType === 'Integer') { + retArr.push('i32('); + this.astGeneric(argument, retArr); + retArr.push(')'); + continue; + } else if (targetType === 'Number' || targetType === 'Float') { + this.astGeneric(argument, retArr); + continue; + } else if (targetType === 'LiteralInteger') { + this.castLiteralToFloat(argument, retArr); + continue; + } + break; + case 'Integer': + if (targetType === 'Number' || targetType === 'Float') { + retArr.push('f32('); + this.astGeneric(argument, retArr); + retArr.push(')'); + continue; + } else if (targetType === 'Integer') { + this.astGeneric(argument, retArr); + continue; + } + break; + case 'LiteralInteger': + if (targetType === 'Integer') { + this.castLiteralToInteger(argument, retArr); + continue; + } else if (targetType === 'Number' || targetType === 'Float') { + this.castLiteralToFloat(argument, retArr); + continue; + } else if (targetType === 'LiteralInteger') { + this.astGeneric(argument, retArr); + continue; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + if (targetType === argumentType) { + if (argument.type === 'Identifier') { + retArr.push(`user_${ utils.sanitizeName(argument.name) }`); + } else { + this.astGeneric(argument, retArr); + } + continue; + } + break; + case 'Array': + case 'Array2D': + case 'Array3D': + case 'Input': + case 'WebGPUBuffer': + throw this.astErrorOutput('WebGPU backend does not yet support array arguments to helper functions', ast); + } + throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast); + } + } + retArr.push(')'); + if (needsIntegerWrap) { + retArr.push(')'); + } + return retArr; + } + + astArrayExpression(arrNode, retArr) { + const returnType = this.getType(arrNode); + switch (returnType) { + case 'Matrix(2)': + case 'Matrix(3)': + case 'Matrix(4)': + throw this.astErrorOutput('WebGPU backend does not yet support Matrix types', arrNode); + } + const arrLen = arrNode.elements.length; + retArr.push(`vec${ arrLen }(`); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) { + retArr.push(', '); + } + const subNode = arrNode.elements[i]; + // WGSL will not implicitly convert an i32 element; force the float ladder + switch (this.getType(subNode)) { + case 'Integer': + this.castValueToFloat(subNode, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(subNode, retArr); + break; + default: + this.astGeneric(subNode, retArr); + } + } + retArr.push(')'); + return retArr; + } + + memberExpressionXYZ(x, y, z, retArr) { + if (z) { + retArr.push(this.memberExpressionPropertyMarkup(z), ', '); + } else { + retArr.push('0, '); + } + if (y) { + retArr.push(this.memberExpressionPropertyMarkup(y), ', '); + } else { + retArr.push('0, '); + } + retArr.push(this.memberExpressionPropertyMarkup(x)); + return retArr; + } + + memberExpressionPropertyMarkup(property) { + if (!property) { + throw new Error('Property not set'); + } + const type = this.getType(property); + const result = []; + switch (type) { + case 'Number': + case 'Float': + this.castValueToInteger(property, result); + break; + case 'LiteralInteger': + this.castLiteralToInteger(property, result); + break; + case 'Integer': + // Integer-typed expressions can still carry f32 spellings (Math.floor + // emits WGSL's f32 floor); i32() of an i32 is free, so always wrap + this.pushState('building-integer'); + result.push('i32('); + this.astGeneric(property, result); + result.push(')'); + this.popState('building-integer'); + break; + default: + this.astGeneric(property, result); + } + return result.join(''); + } +} + +const typeMap = { + 'Number': 'f32', + 'Float': 'f32', + 'Integer': 'i32', + 'LiteralInteger': 'f32', + 'Boolean': 'bool', + 'Array(2)': 'vec2', + 'Array(3)': 'vec3', + 'Array(4)': 'vec4', +}; + +const operatorMap = { + '===': '==', + '!==': '!=' +}; + +const vectorComponents = ['x', 'y', 'z', 'w']; + +// JS Math.* whose WGSL spelling differs; everything else maps by name +const mathFunctionRenames = { + 'pow': '_pow', // pow(x, 0) must be 1 for all x, like JS + 'round': '_round', // WGSL round is half-to-even; JS is half-up +}; + +// inference types these as Integer (function-node.js getType), but their +// WGSL builtins return f32 +const integerResultMathFunctions = { + 'ceil': true, + 'floor': true, + '_round': true, +}; + +// WGSL keywords, reserved words and the builtin/helper names this backend +// emits; user function names colliding with these are prefixed +const reservedNames = [ + 'alias', 'break', 'case', 'const', 'const_assert', 'continue', 'continuing', + 'default', 'diagnostic', 'discard', 'else', 'enable', 'false', 'fn', 'for', + 'if', 'let', 'loop', 'override', 'requires', 'return', 'struct', 'switch', + 'true', 'var', 'while', 'main', 'params', 'result', 'gid', 'threadGid', + 'data_index', 'select', 'abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', + 'atan2', 'atanh', 'ceil', 'clamp', 'cos', 'cosh', 'cross', 'degrees', + 'distance', 'dot', 'exp', 'exp2', 'floor', 'fma', 'fract', 'inverseSqrt', + 'length', 'log', 'log2', 'max', 'min', 'mix', 'modf', 'normalize', 'pow', + 'radians', 'round', 'sign', 'sin', 'sinh', 'smoothstep', 'sqrt', 'step', + 'tan', 'tanh', 'trunc', 'cbrt', 'expm1', 'fround', 'imul', 'log10', 'log1p', + 'clz32', '_pow', '_round', 'LOOP_MAX', 'bitcast', 'ptr', 'array', 'vec2', + 'vec3', 'vec4', 'mat2x2', 'mat3x3', 'mat4x4', 'f32', 'i32', 'u32', 'bool', +]; + +module.exports = { + WGSLFunctionNode +}; \ No newline at end of file diff --git a/src/backend/web-gpu/kernel.js b/src/backend/web-gpu/kernel.js new file mode 100644 index 00000000..3dd9eb8e --- /dev/null +++ b/src/backend/web-gpu/kernel.js @@ -0,0 +1,1027 @@ +const { Kernel } = require('../kernel'); +const { FunctionBuilder } = require('../function-builder'); +const { WGSLFunctionNode } = require('./function-node'); +const { WebGPUContext } = require('./context'); +const { WebGPUBufferResult } = require('./buffer-result'); +const { utils } = require('../../utils'); +const { Input } = require('../../input'); + +// GPUBufferUsage/GPUMapMode are globals only where WebGPU exists; the +// numeric values are pinned by the spec, so carrying them keeps this module +// loadable (and the deferred-feature errors reachable) everywhere else +const USAGE_UNIFORM = 0x0040; +const USAGE_STORAGE = 0x0080; +const USAGE_COPY_SRC = 0x0004; +const USAGE_COPY_DST = 0x0008; +const USAGE_MAP_READ = 0x0001; +const MAP_MODE_READ = 0x0001; + +const features = Object.freeze({ + kernelMap: false, + isIntegerDivisionAccurate: true, + isSpeedTacticSupported: false, + isTextureFloat: true, + isDrawBuffers: false, + kernelMapSize: 0, + channelCount: 1, + maxTextureSize: Infinity, + isFloatRead: true, +}); + +// module-scope fn helpers, injected only when the translated source calls them +const wgslHelpers = { + '_pow': 'fn _pow(v1 : f32, v2 : f32) -> f32 {\n if (v2 == 0.0) { return 1.0; }\n return pow(v1, v2);\n}', + '_round': 'fn _round(x : f32) -> f32 {\n return floor(x + 0.5);\n}', + 'cbrt': 'fn cbrt(x : f32) -> f32 {\n return sign(x) * pow(abs(x), 1.0 / 3.0);\n}', + 'expm1': 'fn expm1(x : f32) -> f32 {\n return exp(x) - 1.0;\n}', + 'fround': 'fn fround(x : f32) -> f32 {\n return x;\n}', + 'imul': 'fn imul(a : f32, b : f32) -> f32 {\n return f32(i32(a) * i32(b));\n}', + 'log10': `fn log10(x : f32) -> f32 {\n return log2(x) * ${ 1 / Math.log2(10) };\n}`, + 'log1p': 'fn log1p(x : f32) -> f32 {\n return log(1.0 + x);\n}', + 'clz32': 'fn clz32(x : f32) -> f32 {\n return f32(countLeadingZeros(u32(x)));\n}', +}; + +/** + * @desc Kernel implementation for WebGPU compute shaders over storage + * buffers. `run()` returns a Promise — readback requires `mapAsync` and + * there is no honest synchronous alternative — which `kernelRunShortcut` + * passes through untouched (keyed on `isAsync`). + */ +class WebGPUKernel extends Kernel { + static get isSupported() { + return WebGPUContext.isSupported; + } + + /** + * Marks run() as Promise-returning for kernelRunShortcut. + */ + static get isAsync() { + return true; + } + + static isContextMatch(context) { + return Boolean(context && typeof context.createShaderModule === 'function' && typeof context.createComputePipeline === 'function'); + } + + static getFeatures() { + return features; + } + + static get features() { + return features; + } + + static get mode() { + return 'webgpu'; + } + + static getSignature(kernel, argumentTypes) { + return 'webgpu' + (argumentTypes.length > 0 ? ':' + argumentTypes.join(',') : ''); + } + + /** + * The shared device is a module singleton that outlives any one GPU + * instance; page-level teardown goes through WebGPUContext.destroy(). + */ + static destroyContext(context) {} + + static nativeFunctionArguments() { + throw new Error('WebGPU backend does not yet support native functions'); + } + + static nativeFunctionReturnType() { + throw new Error('WebGPU backend does not yet support native functions'); + } + + static combineKernels() { + throw new Error('WebGPU backend does not yet support combineKernels; chain kernels with `await` and pipeline mode instead'); + } + + constructor(source, settings) { + super(source, settings); + if (settings) { + if (settings.graphical) { + throw new Error('WebGPU backend does not yet support graphical mode; use the webgl backend'); + } + if (settings.precision === 'unsigned') { + throw new Error(`WebGPU backend does not yet support precision: 'unsigned'; it is single precision only`); + } + if (settings.subKernels) { + throw new Error('WebGPU backend does not yet support createKernelMap'); + } + } + this.mergeSettings(source.settings || settings); + if (this.precision === null) { + this.precision = 'single'; + } + // natively async: every run returns a Promise regardless of the setting + this.asyncMode = true; + + this.threadDim = null; + this.componentCount = 1; + this.compiledSource = null; + this.translatedBody = null; + this.translatedFunctions = null; + this.paramsLayout = null; + + this._buildPromise = null; + this._device = null; + this.computePipeline = null; + this.bindGroupLayout = null; + this.bindGroup = null; + this.bindGroupDirty = true; + this.paramsBuffer = null; + this.paramsMirror = null; + this.outputBuffer = null; + this.argumentBuffers = null; + this.constantBuffers = null; + this.stagingPool = []; + } + + initCanvas() { + return null; + } + + initContext() { + // the device is acquired asynchronously on first run; nothing synchronous + // to hand the base class here + return null; + } + + initPlugins(settings) { + return []; + } + + setGraphical(flag) { + if (flag) { + throw new Error('WebGPU backend does not yet support graphical mode; use the webgl backend'); + } + return super.setGraphical(flag); + } + + setOutput(output) { + const newOutput = this.toKernelOutput(output); + if (this.built) { + if (!this.dynamicOutput) { + throw new Error('Resizing a kernel with dynamicOutput: false is not possible'); + } + if (newOutput.length !== this.output.length) { + throw new Error('WebGPU backend does not yet support changing the output rank of a built kernel; the workgroup shape is fixed at build'); + } + } + this.output = newOutput; + return this; + } + + toString() { + throw new Error('WebGPU backend does not yet support toString'); + } + + validateSettings(args) { + if (this.graphical) { + throw new Error('WebGPU backend does not yet support graphical mode; use the webgl backend'); + } + if (this.precision === 'unsigned') { + throw new Error(`WebGPU backend does not yet support precision: 'unsigned'; it is single precision only`); + } + this.precision = 'single'; + if (this.subKernels && this.subKernels.length > 0) { + throw new Error('WebGPU backend does not yet support createKernelMap'); + } + + if (!this.output || this.output.length === 0) { + if (args.length !== 1) { + throw new Error('Auto output only supported for kernels with only one input'); + } + const argType = utils.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = Array.from(utils.getDimensions(args[0])); + } else if (argType === 'WebGPUBuffer') { + this.output = Array.from(args[0].output); + } else { + throw new Error('Auto output not supported for input type: ' + argType); + } + } + this.checkOutput(); + } + + setupArguments(args) { + super.setupArguments(args); + for (let i = 0; i < this.argumentTypes.length; i++) { + switch (this.argumentTypes[i]) { + case 'Array': + case 'Input': + case 'WebGPUBuffer': + case 'Number': + case 'Float': + case 'Integer': + case 'Boolean': + continue; + default: + throw new Error(`WebGPU backend does not yet support argument type ${ this.argumentTypes[i] } (argument "${ this.argumentNames[i] }")`); + } + } + } + + setupConstants() { + super.setupConstants(); + for (const name in this.constantTypes) { + switch (this.constantTypes[name]) { + case 'Array': + case 'Input': + case 'Number': + case 'Float': + case 'Integer': + case 'Boolean': + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + continue; + default: + throw new Error(`WebGPU backend does not yet support constant type ${ this.constantTypes[name] } (constant "${ name }")`); + } + } + } + + /** + * Everything device-independent — validation, JS→WGSL translation, module + * assembly — happens synchronously here, so unsupported constructs throw at + * the first call rather than rejecting; the device round trip continues in + * _buildAsync and run() chains on its promise. + */ + build() { + if (this.built) return Promise.resolve(); + if (this._buildPromise) return this._buildPromise; + this.setupConstants(); + this.setupArguments(arguments); + this.validateSettings(arguments); + const threadDim = this.threadDim = Array.from(this.output); + while (threadDim.length < 3) { + threadDim.push(1); + } + this.translateSource(); + this.paramsLayout = this.computeParamsLayout(); + this.compiledSource = this.assembleWGSL(); + if (this.debug) { + console.log('WGSL Shader Output:'); + console.log(this.compiledSource); + } + this.buildSignature(arguments); + return this._buildPromise = this._buildAsync(); + } + + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WGSLFunctionNode); + // dependencies first, the root kernel's bare body statements last + const prototypes = functionBuilder.getPrototypes('kernel'); + this.translatedBody = prototypes[prototypes.length - 1]; + this.translatedFunctions = prototypes.slice(0, -1).join('\n'); + if (!this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + case 'LiteralInteger': + this.componentCount = 1; + break; + case 'Array(2)': + this.componentCount = 2; + break; + case 'Array(3)': + this.componentCount = 3; + break; + case 'Array(4)': + this.componentCount = 4; + break; + default: + throw new Error(`WebGPU backend does not yet support returning ${ this.returnType }`); + } + } + + /** + * Params struct, matching the WGSL struct member for member: + * outputX/outputY/outputZ/_pad0, one vec4 [sizeX, sizeY, sizeZ, total] + * per array argument, then scalar arguments as f32/i32/u32, the whole + * buffer padded to a 16-byte multiple. + */ + computeParamsLayout() { + const arrayArgs = []; + const scalarArgs = []; + let offset = 16; + for (let i = 0; i < this.argumentTypes.length; i++) { + const type = this.argumentTypes[i]; + const name = utils.sanitizeName(this.argumentNames[i]); + if (type === 'Array' || type === 'Input' || type === 'WebGPUBuffer') { + arrayArgs.push({ + name, + index: i, + type, + dimsOffset: offset, + buffer: null, + boundBuffer: null, + }); + offset += 16; + } else { + scalarArgs.push({ + name, + index: i, + type, + offset: null, // assigned below; scalars pack after the vec4 rows + }); + } + } + for (let i = 0; i < scalarArgs.length; i++) { + scalarArgs[i].offset = offset; + offset += 4; + } + const bufferConstants = []; + if (this.constants) { + for (const name in this.constants) { + if (!this.constants.hasOwnProperty(name)) continue; + const type = this.constantTypes[name]; + if (type === 'Array' || type === 'Input') { + bufferConstants.push({ + name: utils.sanitizeName(name), + constantName: name, + buffer: null, + }); + } + } + } + return { + arrayArgs, + scalarArgs, + bufferConstants, + byteLength: Math.ceil(offset / 16) * 16, + }; + } + + scalarWGSLType(type) { + switch (type) { + case 'Integer': + return 'i32'; + case 'Boolean': + return 'u32'; // bool is not host-shareable; rehydrated with bool() + default: + return 'f32'; + } + } + + assembleWGSL() { + const { arrayArgs, scalarArgs, bufferConstants } = this.paramsLayout; + const wgsl = []; + + const structMembers = [ + ' outputX : u32,', + ' outputY : u32,', + ' outputZ : u32,', + ' dispatchWidth : u32,', + ]; + for (let i = 0; i < arrayArgs.length; i++) { + structMembers.push(` user_${ arrayArgs[i].name }_dims : vec4,`); + } + for (let i = 0; i < scalarArgs.length; i++) { + structMembers.push(` user_${ scalarArgs[i].name } : ${ this.scalarWGSLType(scalarArgs[i].type) },`); + } + wgsl.push('struct Params {', structMembers.join('\n'), '}'); + wgsl.push('@group(0) @binding(0) var params : Params;'); + + for (let i = 0; i < arrayArgs.length; i++) { + wgsl.push(`@group(0) @binding(${ 1 + i }) var user_${ arrayArgs[i].name } : array;`); + } + const outBinding = 1 + arrayArgs.length; + wgsl.push(`@group(0) @binding(${ outBinding }) var result : array;`); + for (let i = 0; i < bufferConstants.length; i++) { + wgsl.push(`@group(0) @binding(${ outBinding + 1 + i }) var constants_${ bufferConstants[i].name } : array;`); + } + + // helper functions can read the invocation id through this mirror; the + // entry parameter itself is scoped to main + wgsl.push('var threadGid : vec3;'); + + const translated = `${ this.translatedFunctions }\n${ this.translatedBody }`; + if (/\bLOOP_MAX\b/.test(translated)) { + wgsl.push(`const LOOP_MAX : i32 = ${ parseInt(this.loopMaxIterations, 10) || 1000 };`); + } + for (const helperName in wgslHelpers) { + if (new RegExp(`\\b${ helperName }\\(`).test(translated)) { + wgsl.push(wgslHelpers[helperName]); + } + } + + // flat row-major accessors, index = x + sizeX * (y + sizeY * z) — the + // exact formula the GL path's get32 uses, so layouts agree by construction + for (let i = 0; i < arrayArgs.length; i++) { + const name = arrayArgs[i].name; + wgsl.push( + `fn get_user_${ name }(z : i32, y : i32, x : i32) -> f32 {\n` + + ` return user_${ name }[u32(x + i32(params.user_${ name }_dims.x) * (y + i32(params.user_${ name }_dims.y) * z))];\n` + + `}`); + } + for (let i = 0; i < bufferConstants.length; i++) { + const record = bufferConstants[i]; + const value = this.constants[record.constantName]; + const dims = this.constantDimensions(value); + // constants never change shape after build; dims bake straight in + wgsl.push( + `fn get_constants_${ record.name }(z : i32, y : i32, x : i32) -> f32 {\n` + + ` return constants_${ record.name }[u32(x + ${ dims[0] } * (y + ${ dims[1] } * z))];\n` + + `}`); + } + + if (this.translatedFunctions) { + wgsl.push(this.translatedFunctions); + } + + const workgroupSize = this.output.length === 1 ? [64, 1, 1] : [8, 8, 1]; + this.workgroupSize = workgroupSize; + if (this.output.length === 1) { + // A 1D dispatch folds across Y once it would exceed the per-dimension + // workgroup limit (65535 groups of 64 = ~4.19M threads); the flat index + // is reconstructed from the dispatch width the runtime used. + wgsl.push( + `@compute @workgroup_size(${ workgroupSize[0] }, ${ workgroupSize[1] }, ${ workgroupSize[2] })\n` + + `fn main(@builtin(global_invocation_id) gid : vec3) {\n` + + ` let flat_index : u32 = gid.x + gid.y * params.dispatchWidth;\n` + + ` threadGid = vec3(flat_index, 0u, 0u);\n` + + ` if (flat_index >= params.outputX) { return; }\n` + + ` let data_index : i32 = i32(flat_index);\n` + + `${ this.translatedBody }\n` + + `}`); + } else { + wgsl.push( + `@compute @workgroup_size(${ workgroupSize[0] }, ${ workgroupSize[1] }, ${ workgroupSize[2] })\n` + + `fn main(@builtin(global_invocation_id) gid : vec3) {\n` + + ` threadGid = gid;\n` + + ` if (gid.x >= params.outputX || gid.y >= params.outputY || gid.z >= params.outputZ) { return; }\n` + + ` let data_index : i32 = i32(gid.x + params.outputX * (gid.y + params.outputY * gid.z));\n` + + `${ this.translatedBody }\n` + + `}`); + } + + return wgsl.join('\n'); + } + + constantDimensions(value) { + const dims = value instanceof Input ? + Array.from(value.size) : + Array.from(utils.getDimensions(value)); + while (dims.length < 3) { + dims.push(1); + } + return dims; + } + + async _buildAsync() { + const context = await WebGPUContext.acquire(); + this.context = context; + const device = this._device = context.device; + + const module = device.createShaderModule({ code: this.compiledSource }); + const info = await module.getCompilationInfo(); + const errors = info.messages.filter(message => message.type === 'error'); + if (errors.length > 0) { + // same shape as the GL path's shader-info-log throw: the line numbers + // index into the generated WGSL, which is appended for debugging + throw new Error( + 'Error compiling WGSL compute shader:\n' + + errors.map(message => ` ${ message.lineNum }:${ message.linePos } ${ message.message }`).join('\n') + + `\n--- generated WGSL ---\n${ this.compiledSource }`); + } + + const { arrayArgs, bufferConstants, byteLength } = this.paramsLayout; + const layoutEntries = [{ + binding: 0, + visibility: 4, // GPUShaderStage.COMPUTE + buffer: { type: 'uniform' }, + }]; + for (let i = 0; i < arrayArgs.length; i++) { + layoutEntries.push({ + binding: 1 + i, + visibility: 4, + buffer: { type: 'read-only-storage' }, + }); + } + const outBinding = 1 + arrayArgs.length; + layoutEntries.push({ + binding: outBinding, + visibility: 4, + buffer: { type: 'storage' }, + }); + for (let i = 0; i < bufferConstants.length; i++) { + layoutEntries.push({ + binding: outBinding + 1 + i, + visibility: 4, + buffer: { type: 'read-only-storage' }, + }); + } + this.bindGroupLayout = device.createBindGroupLayout({ entries: layoutEntries }); + + device.pushErrorScope('validation'); + this.computePipeline = device.createComputePipeline({ + layout: device.createPipelineLayout({ bindGroupLayouts: [this.bindGroupLayout] }), + compute: { module, entryPoint: 'main' }, + }); + const pipelineError = await device.popErrorScope(); + if (pipelineError) { + throw new Error(`Error creating WebGPU compute pipeline for kernel: ${ pipelineError.message }`); + } + + this.paramsBuffer = device.createBuffer({ + size: byteLength, + usage: USAGE_UNIFORM | USAGE_COPY_DST, + }); + this.paramsMirror = new ArrayBuffer(byteLength); + this.paramsU32 = new Uint32Array(this.paramsMirror); + this.paramsI32 = new Int32Array(this.paramsMirror); + this.paramsF32 = new Float32Array(this.paramsMirror); + + // array constants upload exactly once — mappedAtCreation avoids the + // staging hop and there is no lifecycle to manage + this.constantBuffers = []; + for (let i = 0; i < bufferConstants.length; i++) { + const record = bufferConstants[i]; + const value = this.constants[record.constantName]; + const dims = this.constantDimensions(value); + const flatLength = dims[0] * dims[1] * dims[2]; + this._checkBufferSize(flatLength * 4, `constant "${ record.constantName }"`); + const buffer = device.createBuffer({ + size: Math.max(flatLength * 4, 4), + usage: USAGE_STORAGE, + mappedAtCreation: true, + }); + const mapped = new Float32Array(buffer.getMappedRange()); + utils.flattenTo(value instanceof Input ? value.value : value, mapped.subarray(0, flatLength)); + buffer.unmap(); + record.buffer = buffer; + this.constantBuffers.push(buffer); + } + + this._ensureOutputBuffer(); + this.bindGroupDirty = true; + this.built = true; + } + + /** + * @desc Workgroup counts for the current thread dimensions, folding a 1D + * dispatch across Y when X alone would exceed the device's per-dimension + * limit. dispatchWidth is the thread count per dispatch row, which the 1D + * shader uses to reconstruct the flat index; 0 for 2D/3D shapes. + * @param {number[]} threadDim + * @returns {{groups: number[], dispatchWidth: number}} + */ + _computeDispatch(threadDim) { + const [wx, wy, wz] = this.workgroupSize; + const groups = [ + Math.ceil(threadDim[0] / wx), + Math.ceil(threadDim[1] / wy), + Math.ceil(threadDim[2] / wz), + ]; + const maxGroups = this._device.limits.maxComputeWorkgroupsPerDimension; + let dispatchWidth = 0; + if (this.output.length === 1) { + if (groups[0] > maxGroups) { + groups[1] = Math.ceil(groups[0] / maxGroups); + groups[0] = Math.ceil(groups[0] / groups[1]); + } + dispatchWidth = groups[0] * wx; + } + for (let i = 0; i < 3; i++) { + if (groups[i] > maxGroups) { + throw new Error(`output dimension ${ i } needs ${ groups[i] } workgroups, over this device's limit of ${ maxGroups }`); + } + } + return { groups, dispatchWidth }; + } + + _ensureOutputBuffer() { + const [tx, ty, tz] = this.threadDim; + const byteLength = tx * ty * tz * 4 * this.componentCount; + // immutable pipeline kernels hand each result its own buffer -- reusing + // it would let this call overwrite the previous call's handle, and + // feeding a kernel its own prior output (the reason immutable exists) + // would read and write the same buffer in one dispatch + if (this.immutable && this.pipeline && this.outputBuffer) { + if (--this.outputBuffer._refs === 0) { + this.outputBuffer.destroy(); + } + this.outputBuffer = null; + this.bindGroupDirty = true; + } + if (this.outputBuffer && this.outputBuffer.size >= byteLength) return; + if (this.outputBuffer) { + if (--this.outputBuffer._refs === 0) { + this.outputBuffer.destroy(); + } + } + this._checkBufferSize(byteLength, `output [${ this.output.join(', ') }]`); + this.outputBuffer = this._device.createBuffer({ + size: byteLength, + usage: USAGE_STORAGE | USAGE_COPY_SRC, + }); + this.outputBuffer._refs = 1; + this.bindGroupDirty = true; + } + + /** + * Oversized bindings must throw here: past the device limit, bind-group + * validation fails asynchronously, the submit is dropped, and the zero- + * initialized staging buffer would resolve a fully-shaped all-zeros + * result — silent wrong data instead of an error. + */ + _checkBufferSize(byteLength, what) { + const limits = this._device.limits; + const max = Math.min(limits.maxStorageBufferBindingSize, limits.maxBufferSize); + if (byteLength > max) { + throw new Error( + `WebGPU backend: ${ what } needs ${ byteLength } bytes but this device allows ` + + `${ max } per storage buffer (maxStorageBufferBindingSize/maxBufferSize); ` + + `reduce the output or split the work across kernels`); + } + } + + /** + * The mutation-sensitive step: array arguments are flattened into fresh + * Float32Arrays synchronously inside run(), before any await, preserving + * the GL path's snapshot semantics. + */ + _snapshotArguments(args) { + const snapshot = new Array(args.length); + for (let i = 0; i < args.length; i++) { + const value = args[i]; + const type = this.argumentTypes[i]; + // a pipeline handle is bindable wherever an array was declared: the + // storage layout is identical, so no recompilation is involved + if (value instanceof WebGPUBufferResult) { + snapshot[i] = { kind: 'buffer', handle: value }; + continue; + } + switch (type) { + case 'Array': { + const dims = Array.from(utils.getDimensions(value)); + while (dims.length < 3) dims.push(1); + const flat = new Float32Array(dims[0] * dims[1] * dims[2]); + utils.flattenTo(value, flat); + snapshot[i] = { kind: 'array', dims, flat }; + break; + } + case 'Input': { + const dims = Array.from(value.size); + while (dims.length < 3) dims.push(1); + const flat = new Float32Array(dims[0] * dims[1] * dims[2]); + utils.flattenTo(value.value, flat); + snapshot[i] = { kind: 'array', dims, flat }; + break; + } + case 'WebGPUBuffer': + snapshot[i] = { kind: 'buffer', handle: value }; + break; + case 'Boolean': + snapshot[i] = { kind: 'scalar', value: value ? 1 : 0 }; + break; + default: + snapshot[i] = { kind: 'scalar', value }; + } + } + return snapshot; + } + + run() { + if (!this.built && !this._buildPromise) { + this.build.apply(this, arguments); + } + const snapshot = this._snapshotArguments(arguments); + if (!this.built) { + return this._buildPromise.then(() => this._runInternal(snapshot)); + } + return this._runInternal(snapshot); + } + + /** + * Steady state is synchronous through queue.submit — writeBuffer copies its + * data at call time and one queue executes submits in order, so overlapping + * un-awaited calls cannot race; only the readback awaits, on a staging + * buffer of its own. + */ + _runInternal(snapshot) { + if (this.context && this.context.isLost) { + // without this check a lost device "succeeds": submits are no-ops and + // pipeline handles resolve over dead buffers + throw new Error( + 'WebGPU device was lost; call kernel.destroy() (or gpu.destroy()) and run again to rebuild on a fresh device'); + } + const device = this._device; + const queue = device.queue; + const { arrayArgs, scalarArgs, bufferConstants } = this.paramsLayout; + + const threadDim = this.threadDim = Array.from(this.output); + while (threadDim.length < 3) { + threadDim.push(1); + } + this._ensureOutputBuffer(); + + this.paramsU32[0] = threadDim[0]; + this.paramsU32[1] = threadDim[1]; + this.paramsU32[2] = threadDim[2]; + this.paramsU32[3] = this._computeDispatch(threadDim).dispatchWidth; + + for (let i = 0; i < arrayArgs.length; i++) { + const record = arrayArgs[i]; + const snap = snapshot[record.index]; + let dims; + if (snap.kind === 'buffer') { + const handle = snap.handle; + if (handle._deleted) { + throw new Error(`WebGPUBufferResult passed as argument "${ this.argumentNames[record.index] }" has been deleted`); + } + if (handle.context !== this.context) { + throw new Error(`WebGPUBufferResult passed as argument "${ this.argumentNames[record.index] }" is from a different WebGPU device`); + } + if (handle.buffer === this.outputBuffer) { + throw new Error(`WebGPUBufferResult passed as argument "${ this.argumentNames[record.index] }" is this kernel's own output buffer; use a second kernel or clone the result`); + } + if (handle.componentCount !== 1) { + throw new Error(`WebGPU backend does not yet support Array(${ handle.componentCount }) pipeline results as kernel arguments`); + } + dims = Array.from(handle.output); + while (dims.length < 3) dims.push(1); + if (record.boundBuffer !== handle.buffer) { + record.boundBuffer = handle.buffer; + this.bindGroupDirty = true; + } + } else { + dims = snap.dims; + const byteLength = snap.flat.byteLength; + if (!record.buffer || record.buffer.size < byteLength) { + if (record.buffer) { + if (!this.dynamicArguments) { + throw new Error(`argument "${ this.argumentNames[record.index] }" grew from ${ record.buffer.size / 4 } to ${ snap.flat.length } values; use dynamicArguments: true for varying input sizes`); + } + record.buffer.destroy(); + } + this._checkBufferSize(byteLength, `argument "${ this.argumentNames[record.index] }"`); + record.buffer = device.createBuffer({ + size: byteLength, + usage: USAGE_STORAGE | USAGE_COPY_DST, + }); + this.bindGroupDirty = true; + } + queue.writeBuffer(record.buffer, 0, snap.flat); + if (record.boundBuffer !== record.buffer) { + record.boundBuffer = record.buffer; + this.bindGroupDirty = true; + } + } + const base = record.dimsOffset / 4; + this.paramsU32[base] = dims[0]; + this.paramsU32[base + 1] = dims[1]; + this.paramsU32[base + 2] = dims[2]; + this.paramsU32[base + 3] = dims[0] * dims[1] * dims[2]; + } + + for (let i = 0; i < scalarArgs.length; i++) { + const record = scalarArgs[i]; + const slot = record.offset / 4; + switch (record.type) { + case 'Integer': + this.paramsI32[slot] = snapshot[record.index].value; + break; + case 'Boolean': + this.paramsU32[slot] = snapshot[record.index].value; + break; + default: + this.paramsF32[slot] = snapshot[record.index].value; + } + } + + queue.writeBuffer(this.paramsBuffer, 0, this.paramsMirror); + + if (this.bindGroupDirty) { + const entries = [{ binding: 0, resource: { buffer: this.paramsBuffer } }]; + for (let i = 0; i < arrayArgs.length; i++) { + entries.push({ binding: 1 + i, resource: { buffer: arrayArgs[i].boundBuffer } }); + } + const outBinding = 1 + arrayArgs.length; + entries.push({ binding: outBinding, resource: { buffer: this.outputBuffer } }); + for (let i = 0; i < bufferConstants.length; i++) { + entries.push({ binding: outBinding + 1 + i, resource: { buffer: bufferConstants[i].buffer } }); + } + this.bindGroup = device.createBindGroup({ + layout: this.bindGroupLayout, + entries, + }); + this.bindGroupDirty = false; + } + + const { groups } = this._computeDispatch(threadDim); + + const byteLength = threadDim[0] * threadDim[1] * threadDim[2] * 4 * this.componentCount; + const encoder = device.createCommandEncoder(); + const pass = encoder.beginComputePass(); + pass.setPipeline(this.computePipeline); + pass.setBindGroup(0, this.bindGroup); + pass.dispatchWorkgroups(groups[0], groups[1], groups[2]); + pass.end(); + + if (this.pipeline) { + queue.submit([encoder.finish()]); + return Promise.resolve(new WebGPUBufferResult({ + buffer: this.outputBuffer, + output: Array.from(this.output), + componentCount: this.componentCount, + context: this.context, + kernel: this, + })); + } + + const staging = this._acquireStaging(byteLength); + encoder.copyBufferToBuffer(this.outputBuffer, 0, staging.buffer, 0, byteLength); + queue.submit([encoder.finish()]); + + const output = Array.from(this.output); + return staging.buffer.mapAsync(MAP_MODE_READ, 0, byteLength).then(() => { + // unmap detaches the range; the copy has to happen first + const data = new Float32Array(staging.buffer.getMappedRange(0, byteLength).slice(0)); + staging.buffer.unmap(); + this._releaseStaging(staging); + return this._shapeOutput(data, output, this.componentCount); + }, (error) => { + // a rejected map (device loss mid-read) must not strand the pooled + // staging entry as busy forever + this._releaseStaging(staging); + throw error; + }); + } + + /** + * A staging buffer is unusable from mapAsync until unmap, so overlapping + * un-awaited calls each need their own; sequential awaited calls reuse one + * buffer forever. Capped so a burst cannot ratchet memory. + */ + _acquireStaging(byteLength) { + for (let i = 0; i < this.stagingPool.length; i++) { + const entry = this.stagingPool[i]; + if (!entry.busy && entry.size >= byteLength) { + entry.busy = true; + return entry; + } + } + const entry = { + buffer: this._device.createBuffer({ + size: byteLength, + usage: USAGE_MAP_READ | USAGE_COPY_DST, + }), + size: byteLength, + busy: true, + pooled: this.stagingPool.length < 3, + }; + if (entry.pooled) { + this.stagingPool.push(entry); + } + return entry; + } + + _releaseStaging(entry) { + if (entry.pooled) { + entry.busy = false; + } else { + entry.buffer.destroy(); + } + } + + /** + * Readback is tightly packed, so scalar returns reuse the + * memory-optimized erectors; Array(n) returns are stride n (not the GL + * texel stride 4), shaped locally. + */ + _shapeOutput(data, output, componentCount) { + const [width, height, depth] = [output[0], output[1] || 1, output[2] || 1]; + if (componentCount === 1) { + switch (output.length) { + case 1: + return utils.erectMemoryOptimizedFloat(data, width); + case 2: + return utils.erectMemoryOptimized2DFloat(data, width, height); + default: + return utils.erectMemoryOptimized3DFloat(data, width, height, depth); + } + } + const n = componentCount; + const erectRow = (offset) => { + const row = new Array(width); + for (let x = 0; x < width; x++) { + row[x] = data.subarray(offset + x * n, offset + x * n + n); + } + return row; + }; + switch (output.length) { + case 1: + return erectRow(0); + case 2: { + const rows = new Array(height); + for (let y = 0; y < height; y++) { + rows[y] = erectRow(y * width * n); + } + return rows; + } + default: { + const layers = new Array(depth); + for (let z = 0; z < depth; z++) { + const rows = new Array(height); + for (let y = 0; y < height; y++) { + rows[y] = erectRow((z * height + y) * width * n); + } + layers[z] = rows; + } + return layers; + } + } + } + + /** + * Readback for a pipeline handle: copy → map → shape, same conventions as + * a non-pipeline run of the producing kernel. + * @param {WebGPUBufferResult} handle + * @returns {Promise} + */ + readBufferResult(handle) { + const device = this._device || (handle.context && handle.context.device); + if (!device) { + return Promise.reject(new Error('no WebGPU device available to read this buffer')); + } + if (handle.context && handle.context.isLost) { + return Promise.reject(new Error( + 'WebGPU device was lost; this buffer no longer holds data — rebuild the producing kernel and run again')); + } + const output = Array.from(handle.output); + const dims = Array.from(output); + while (dims.length < 3) dims.push(1); + const byteLength = dims[0] * dims[1] * dims[2] * 4 * handle.componentCount; + const staging = this._acquireStaging(byteLength); + const encoder = device.createCommandEncoder(); + encoder.copyBufferToBuffer(handle.buffer, 0, staging.buffer, 0, byteLength); + device.queue.submit([encoder.finish()]); + return staging.buffer.mapAsync(MAP_MODE_READ, 0, byteLength).then(() => { + const data = new Float32Array(staging.buffer.getMappedRange(0, byteLength).slice(0)); + staging.buffer.unmap(); + this._releaseStaging(staging); + return this._shapeOutput(data, output, handle.componentCount); + }, (error) => { + this._releaseStaging(staging); + throw error; + }); + } + + destroy(removeCanvasReferences) { + // tolerate a kernel that was never built (or is mid-build) + if (this.paramsBuffer) { + this.paramsBuffer.destroy(); + this.paramsBuffer = null; + } + if (this.paramsLayout) { + for (let i = 0; i < this.paramsLayout.arrayArgs.length; i++) { + const record = this.paramsLayout.arrayArgs[i]; + if (record.buffer) { + record.buffer.destroy(); + record.buffer = null; + } + record.boundBuffer = null; + } + } + if (this.constantBuffers) { + for (let i = 0; i < this.constantBuffers.length; i++) { + this.constantBuffers[i].destroy(); + } + this.constantBuffers = null; + } + for (let i = 0; i < this.stagingPool.length; i++) { + // destroying a map-pending buffer is legal; the pending mapAsync rejects + this.stagingPool[i].buffer.destroy(); + } + this.stagingPool = []; + if (this.outputBuffer) { + // pipeline handles handed to the user share this buffer; it dies at zero + if (--this.outputBuffer._refs === 0) { + this.outputBuffer.destroy(); + } + this.outputBuffer = null; + } + this.bindGroup = null; + this.bindGroupLayout = null; + this.computePipeline = null; + this.built = false; + this._buildPromise = null; + if (this.gpu && this.gpu.kernels) { + const index = this.gpu.kernels.indexOf(this); + if (index !== -1) { + this.gpu.kernels.splice(index, 1); + } + } + } +} + +module.exports = { + WebGPUKernel +}; \ No newline at end of file diff --git a/src/gpu.js b/src/gpu.js index 98b7b0f3..e979edf0 100644 --- a/src/gpu.js +++ b/src/gpu.js @@ -5,6 +5,7 @@ const { CPUKernel } = require('./backend/cpu/kernel'); const { HeadlessGLKernel } = require('./backend/headless-gl/kernel'); const { WebGL2Kernel } = require('./backend/web-gl2/kernel'); const { WebGLKernel } = require('./backend/web-gl/kernel'); +const { WebGPUKernel } = require('./backend/web-gpu/kernel'); const { kernelRunShortcut } = require('./kernel-run-shortcut'); @@ -24,6 +25,10 @@ const internalKernels = { 'headlessgl': HeadlessGLKernel, 'webgl2': WebGL2Kernel, 'webgl': WebGLKernel, + // deliberately NOT in kernelOrder: the sync isSupported check + // (navigator.gpu presence) does not prove an adapter exists, so webgpu is + // explicit opt-in via `new GPU({ mode: 'webgpu' })` only + 'webgpu': WebGPUKernel, }; let validate = true; @@ -82,6 +87,25 @@ class GPU { return HeadlessGLKernel.isSupported; } + /** + * @desc TRUE if the WebGPU API surface exists (navigator.gpu). Optimistic: + * an adapter may still be unavailable — use `await GPU.isWebGPUAvailable()` + * for the authoritative answer. + */ + static get isWebGPUSupported() { + return WebGPUKernel.isSupported; + } + + /** + * @desc Actually requests an adapter; resolves whether a webgpu kernel + * could run here. + * @returns {Promise} + */ + static isWebGPUAvailable() { + if (!WebGPUKernel.isSupported) return Promise.resolve(false); + return navigator.gpu.requestAdapter().then(adapter => adapter !== null, () => false); + } + /** * * @desc TRUE if platform supports Canvas @@ -178,6 +202,21 @@ class GPU { break; } } + } else if (this.mode === 'async') { + // auto-selection under the Promise contract: pick the best + // synchronously-provable backend now (its readback runs non-blocking + // where the platform allows), and let the first kernel call upgrade + // to webgpu once an adapter has actually answered -- the async + // contract is exactly what buys the room to probe + for (let i = 0; i < kernelOrder.length; i++) { + if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } + } + if (!Kernel) { + Kernel = CPUKernel; + } } else if (this.mode === 'cpu') { Kernel = CPUKernel; } @@ -254,6 +293,7 @@ class GPU { strictIntegers: kernelRun.strictIntegers, randomSeed: kernelRun.randomSeed, debug: kernelRun.debug, + asyncMode: kernelRun.asyncMode, }); fallbackKernel.build.apply(fallbackKernel, args); const result = fallbackKernel.run.apply(fallbackKernel, args); @@ -317,6 +357,7 @@ class GPU { strictIntegers: _kernel.strictIntegers, randomSeed: _kernel.randomSeed, debug: _kernel.debug, + asyncMode: _kernel.asyncMode, gpu: _kernel.gpu, validate, returnType: _kernel.returnType, @@ -343,10 +384,85 @@ class GPU { onRequestFallback, onRequestSwitchKernel }, settingsCopy); + if (this.mode === 'async') { + mergedSettings.asyncMode = true; + } const kernel = new this.Kernel(source, mergedSettings); const kernelRun = kernelRunShortcut(kernel); + if (this.mode === 'async' && WebGPUKernel.isSupported && !(kernel instanceof WebGPUKernel)) { + const gpu = this; + // consulted (and cleared) by the shortcut on the first call, before the + // chosen kernel builds; every setter chained onto the shortcut lands on + // the kernel instance first, so its settings are harvested here rather + // than from settingsCopy + kernel.onAsyncModeUpgrade = function onAsyncModeUpgrade(args, currentKernel) { + return GPU.isWebGPUAvailable().then(available => { + if (!available) return null; + let webGPUKernel; + try { + webGPUKernel = new WebGPUKernel(source, { + // from the kernel instance, not the GPU: per-kernel functions + // (createKernel settings, addFunction on the shortcut) live + // only on the kernel, and losing them here would silently + // decline the upgrade forever + functions: currentKernel.functions, + nativeFunctions: currentKernel.nativeFunctions, + injectedNative: currentKernel.injectedNative, + gpu, + validate, + asyncMode: true, + output: currentKernel.output, + pipeline: currentKernel.pipeline, + immutable: currentKernel.immutable, + dynamicOutput: currentKernel.dynamicOutput, + // always dynamic: the GL backends absorb argument-size changes + // by switching kernels, so a faithful harvest here would make + // the upgrade stricter than the backend it replaced. The WGSL + // side reads every array's dimensions from the params buffer + // regardless, so the leniency costs nothing. + dynamicArguments: true, + loopMaxIterations: currentKernel.loopMaxIterations, + constants: currentKernel.constants, + constantTypes: currentKernel.constantTypes, + argumentTypes: currentKernel.argumentTypes, + precision: currentKernel.precision, + tactic: currentKernel.tactic, + strictIntegers: currentKernel.strictIntegers, + fixIntegerDivisionAccuracy: currentKernel.fixIntegerDivisionAccuracy, + subKernels: currentKernel.subKernels, + graphical: currentKernel.graphical, + debug: currentKernel.debug, + }); + // deferred features (graphical, kernel maps, unsigned precision, + // Math.random) throw synchronously here: the proven backend keeps + // the kernel and nothing was lost but the probe + webGPUKernel.build.apply(webGPUKernel, args); + } catch (e) { + if (currentKernel.debug) { + console.warn('webgpu upgrade declined: ' + e.message); + } + return null; + } + // WGSL compilation and pipeline validation reject asynchronously; + // awaiting the full build here means the kernel only ever swaps to + // a webgpu kernel that is proven to build, and a declined upgrade + // keeps the real reason instead of masking it behind a re-run + return webGPUKernel._buildPromise.then(() => { + kernels.push(webGPUKernel); + return webGPUKernel; + }, (e) => { + if (currentKernel.debug) { + console.warn('webgpu upgrade declined: ' + e.message); + } + webGPUKernel.destroy(); + return null; + }); + }, () => null); + }; + } + //if canvas didn't come from this, propagate from kernel if (!this.canvas) { this.canvas = kernel.canvas; @@ -405,6 +521,9 @@ class GPU { if (this.mode !== 'dev') { if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) { + if (this.Kernel.mode === 'webgpu') { + throw new Error('WebGPU backend does not yet support createKernelMap'); + } if (this.mode && kernelTypes.indexOf(this.mode) < 0) { throw new Error(`kernelMap not supported on ${this.Kernel.name}`); } @@ -470,7 +589,16 @@ class GPU { combineKernels() { const firstKernel = arguments[0]; const combinedKernel = arguments[arguments.length - 1]; + // before the cpu early-return: the cpu arm of mode 'async' is equally + // Promise-returning, and the combiner would feed those Promises into the + // next kernel as arguments + if (this.mode === 'async' || firstKernel.kernel.asyncMode) { + throw new Error(`mode 'async' does not yet support combineKernels; chain kernels with \`await\` and pipeline mode instead`); + } if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel; + if (firstKernel.kernel.constructor.mode === 'webgpu') { + throw new Error('WebGPU backend does not yet support combineKernels; chain kernels with `await` and pipeline mode instead'); + } const canvas = arguments[0].canvas; const context = arguments[0].context; const max = arguments.length - 1; diff --git a/src/index.d.ts b/src/index.d.ts index 158185de..29461bea 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -8,6 +8,9 @@ export class GPU { static isOffscreenCanvasSupported: boolean; static isGPUHTMLImageArraySupported: boolean; static isSinglePrecisionSupported: boolean; + /** WebGPU API surface exists (navigator.gpu); an adapter may still be absent — await isWebGPUAvailable() for the authoritative answer */ + static isWebGPUSupported: boolean; + static isWebGPUAvailable(): Promise; constructor(settings?: IGPUSettings); functions: GPUFunction[]; nativeFunctions: IGPUNativeFunction[]; @@ -100,8 +103,8 @@ export interface INativeFunctionList { [name: string]: INativeFunction } -export type GPUMode = 'gpu' | 'cpu' | 'dev'; -export type GPUInternalMode = 'webgl' | 'webgl2' | 'headlessgl'; +export type GPUMode = 'gpu' | 'cpu' | 'dev' | 'async'; +export type GPUInternalMode = 'webgl' | 'webgl2' | 'headlessgl' | 'webgpu'; export interface IGPUSettings { mode?: GPUMode | GPUInternalMode; @@ -209,6 +212,7 @@ export class Kernel { setPipeline(flag: boolean): this; setPrecision(flag: Precision): this; setImmutable(flag: boolean): this; + setAsyncMode(flag: boolean): this; setCanvas(flag: any): this; setContext(flag: any): this; addFunction(flag: GPUFunction, settings?: IFunctionSettings): this; @@ -337,6 +341,8 @@ export interface IKernelSettings { pipeline?: boolean; immutable?: boolean; graphical?: boolean; + /** every call returns a Promise of the result; non-blocking readback where the backend supports it (webgl2, webgpu) */ + asyncMode?: boolean; onRequestFallback?: () => Kernel; optimizeFloatMemory?: boolean; dynamicOutput?: boolean; diff --git a/src/index.js b/src/index.js index 3f6b2ba6..2d74696c 100644 --- a/src/index.js +++ b/src/index.js @@ -18,6 +18,11 @@ const { WebGL2FunctionNode } = require('./backend/web-gl2/function-node'); const { WebGL2Kernel } = require('./backend/web-gl2/kernel'); const { kernelValueMaps: webGL2KernelValueMaps } = require('./backend/web-gl2/kernel-value-maps'); +const { WGSLFunctionNode } = require('./backend/web-gpu/function-node'); +const { WebGPUKernel } = require('./backend/web-gpu/kernel'); +const { WebGPUContext } = require('./backend/web-gpu/context'); +const { WebGPUBufferResult } = require('./backend/web-gpu/buffer-result'); + const { GLKernel } = require('./backend/gl/kernel'); const { Kernel } = require('./backend/kernel'); @@ -47,6 +52,11 @@ module.exports = { WebGLKernel, webGLKernelValueMaps, + WGSLFunctionNode, + WebGPUKernel, + WebGPUContext, + WebGPUBufferResult, + GLKernel, Kernel, FunctionTracer, diff --git a/src/kernel-run-shortcut.js b/src/kernel-run-shortcut.js index b878c569..ec2d1bd1 100644 --- a/src/kernel-run-shortcut.js +++ b/src/kernel-run-shortcut.js @@ -1,4 +1,5 @@ const { utils } = require('./utils'); +const { Input } = require('./input'); /** * Makes kernels easier for mortals (including me) @@ -6,26 +7,159 @@ const { utils } = require('./utils'); * @returns {function()} */ function kernelRunShortcut(kernel) { - let run = function() { - kernel.build.apply(kernel, arguments); - run = function() { - let result = kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { + // A switch can legitimately cascade (an argument type change that also + // changes the output precision), but it must terminate: a kernel that keeps + // asking to switch would otherwise fall through with no result at all, and + // the GL backends answer that with whatever is still in the framebuffer -- + // silently, the previous call's values. + const MAX_SWITCHES = 4; + + function syncBody(args) { + // build() is guarded on kernel.built across every backend, so calling it + // per run costs one boolean check and stays correct through replaceKernel + kernel.build.apply(kernel, args); + kernel.checkArgumentTypes(args); + let result = kernel.switchingKernels ? undefined : kernel.run.apply(kernel, args); + for (let i = 0; kernel.switchingKernels; i++) { + if (i >= MAX_SWITCHES) { const reasons = kernel.resetSwitchingKernels(); - const newKernel = kernel.onRequestSwitchKernel(reasons, arguments, kernel); - shortcut.kernel = kernel = newKernel; - result = newKernel.run.apply(newKernel, arguments); + throw new Error( + `this kernel cannot run the arguments it was given (${ describeReasons(reasons) }); ` + + `it did not settle on a kernel for them after ${ MAX_SWITCHES } attempts. ` + + `Create a separate kernel for this call's argument types.`); + } + const reasons = kernel.resetSwitchingKernels(); + const newKernel = kernel.onRequestSwitchKernel(reasons, args, kernel); + shortcut.kernel = kernel = newKernel; + newKernel.checkArgumentTypes(args); + result = newKernel.switchingKernels ? undefined : newKernel.run.apply(newKernel, args); + } + return result; + } + + function describeReasons(reasons) { + if (!reasons || !reasons.length) return 'unknown reason'; + return reasons.map(reason => { + if (reason.type === 'argumentTypeMismatch') { + return `argument ${ reason.index } is now ${ reason.needed }`; } + return reason.type; + }).join(', '); + } + + function syncRun(args) { + const result = syncBody(args); + if (kernel.renderKernels) { + return kernel.renderKernels(); + } else if (kernel.renderOutput) { + return kernel.renderOutput(); + } else { + return result; + } + } + + // The async contract must not change WHEN arguments are read: every path + // below either executes synchronously at call time (deferring only the + // readback) or snapshots mutable arguments before its first await, so + // `const p = k(buf); buf[0] = 9;` still computes on the value buf held at + // the call, exactly like the sync contract. + function asyncRun(args) { + // mode 'async' upgrade opportunity, consumed exactly once: the adapter + // probe and the webgpu kernel's full async build resolve before anything + // on the proven kernel is built. Arguments are snapshotted across the + // probe. The hook only ever returns a kernel whose build succeeded, so + // there is no failed-first-run fallback to mask errors with; a declined + // upgrade logs its reason under debug inside the hook. + if (kernel.onAsyncModeUpgrade) { + const upgrade = kernel.onAsyncModeUpgrade; + kernel.onAsyncModeUpgrade = null; + const snapped = snapshotArguments(args); + return upgrade(snapped, kernel).then(upgradedKernel => { + if (upgradedKernel) { + shortcut.replaceKernel(upgradedKernel); + } + return asyncRun(snapped); + }); + } + try { + if (kernel.constructor.isAsync === true) { + // natively async: run() snapshots its arguments synchronously before + // any internal await + kernel.build.apply(kernel, args); + return Promise.resolve(kernel.run.apply(kernel, args)); + } + // a webgpu pipeline handle can reach a GL/CPU kernel under mode + // 'async' when the producer upgraded and this kernel declined; the + // async contract already owns this call, so read the handle back and + // feed the values through + for (let i = 0; i < args.length; i++) { + if (isWebGPUHandle(args[i])) { + return resolveHandles(args).then(resolved => asyncRun(resolved)); + } + } + const result = syncBody(args); if (kernel.renderKernels) { - return kernel.renderKernels(); + // no non-blocking path for mapped outputs yet; resolving the + // synchronous read keeps the contract uniform + return Promise.resolve(kernel.renderKernels()); } else if (kernel.renderOutput) { - return kernel.renderOutput(); + if (kernel.renderOutputAsync) { + return kernel.renderOutputAsync(); + } + return Promise.resolve(kernel.renderOutput()); } else { - return result; + return Promise.resolve(result); } - }; - return run.apply(kernel, arguments); - }; + } catch (e) { + return Promise.reject(e); + } + } + + function isWebGPUHandle(value) { + return Boolean(value) && value.type === 'WebGPUBuffer'; + } + + function resolveHandles(args) { + // the handle readback forces an await, so mutable arguments are + // snapshotted first to keep call-time sampling + const snapped = snapshotArguments(args); + const pending = []; + for (let i = 0; i < snapped.length; i++) { + if (isWebGPUHandle(snapped[i])) { + const index = i; + pending.push(Promise.resolve(snapped[index].toArray()).then(value => { + snapped[index] = value; + })); + } + } + return Promise.all(pending).then(() => snapped); + } + + function snapshotArguments(args) { + const copy = new Array(args.length); + for (let i = 0; i < args.length; i++) { + copy[i] = snapshotValue(args[i]); + } + return copy; + } + + function snapshotValue(value) { + if (!value || typeof value !== 'object') return value; + // GPU-resident values cannot be mutated from JS between now and the run + if (isWebGPUHandle(value) || typeof value.delete === 'function') return value; + if (ArrayBuffer.isView(value)) return value.slice(0); + if (Array.isArray(value)) return value.map(snapshotValue); + if (value instanceof Input) return new Input(snapshotValue(value.value), value.size); + // canvases, images, videos: sampled when uploaded, nothing to copy + return value; + } + + function run() { + if (kernel.constructor.isAsync === true || kernel.asyncMode === true) { + return asyncRun(arguments); + } + return syncRun(arguments); + } const shortcut = function() { return run.apply(kernel, arguments); }; diff --git a/src/utils.js b/src/utils.js index 5cc6107e..63b5c90b 100644 --- a/src/utils.js +++ b/src/utils.js @@ -122,6 +122,45 @@ const utils = { * @param {boolean} [strictIntegers] * @returns {String} Argument type Array/Number/Float/Texture/Unknown */ + /** + * @desc Can a value still be used as the argument type a kernel was built + * for? Deliberately loose: a declared type is often more specific than + * detection can be (Array1D(2) reads as a plain Array), so this only + * reports the fundamental mismatches -- a number where an array is + * expected, an Input where a plain array is, a plain array where a texture + * is. Those are the changes that need a differently-compiled kernel. + * @param {String} type + * @param {*} value + * @returns {Boolean} + */ + typeFitsValue(type, value) { + if (typeof type !== 'string' || value === null || value === undefined) return true; + // a value that names its own type (textures, pipeline buffers) is already + // re-mapped over the declared type by the kernel-value lookup and by the + // GL backends' own mismatch detection; the declared type does not govern + // it and second-guessing that here only fights machinery that works + if (value.type) return true; + switch (type) { + case 'Input': + return value instanceof Input; + case 'Boolean': + return typeof value === 'boolean'; + case 'Number': + case 'Integer': + case 'Float': + return typeof value === 'number'; + } + if (type.indexOf('Texture') !== -1) { + return Boolean(value.type); + } + if (type.indexOf('Array') === 0) { + return utils.isArray(value); + } + // HTMLImage, HTMLVideo, ImageBitmap, OffscreenCanvas, Unknown: detection + // adds nothing the declared type does not already say + return true; + }, + getVariableType(value, strictIntegers) { if (utils.isArray(value)) { if (value.length > 0 && value[0].nodeName === 'IMG') { diff --git a/test/all.html b/test/all.html index 273d1011..7f53b408 100644 --- a/test/all.html +++ b/test/all.html @@ -139,8 +139,10 @@ + + @@ -237,6 +239,7 @@ + @@ -296,6 +299,15 @@ + + + + + + + + + diff --git a/test/features/argument-type-changes.js b/test/features/argument-type-changes.js new file mode 100644 index 00000000..aac89691 --- /dev/null +++ b/test/features/argument-type-changes.js @@ -0,0 +1,104 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU, input } = require('../../src'); + +describe('features: argument type changes'); + +// A kernel is compiled for the argument types it first saw. Reusing the +// instance with a fundamentally different type must produce the same answer +// as a kernel that only ever saw those types -- the library switches to a +// kernel compiled for them. Before this was handled centrally the GL +// backends could return the PREVIOUS call's values, silently. + +const MODES = [ + ['cpu', true], + ['webgl', GPU.isWebGLSupported], + ['webgl2', GPU.isWebGL2Supported], + ['headlessgl', GPU.isHeadlessGLSupported], +]; + +function eachMode(name, run) { + for (const [mode, supported] of MODES) { + (supported ? test : skip)(`${ name } ${ mode }`, assert => run(assert, mode)); + } +} + +function doubler(gpu) { + return gpu.createKernel(function (a) { + return a[this.thread.x] * 2; + }).setOutput([2]); +} + +eachMode('an Input after an Array reads the Input', (assert, mode) => { + const gpu = new GPU({ mode }); + const kernel = doubler(gpu); + assert.deepEqual(Array.from(kernel([1, 2])), [2, 4], 'the array call'); + const result = kernel(input(new Float32Array([7, 8]), [2])); + assert.deepEqual(Array.from(result), [14, 16], 'the Input call, not the array call again'); + gpu.destroy(); +}); + +eachMode('an Array after an Input reads the Array', (assert, mode) => { + const gpu = new GPU({ mode }); + const kernel = doubler(gpu); + assert.deepEqual(Array.from(kernel(input(new Float32Array([1, 2]), [2]))), [2, 4], 'the Input call'); + assert.deepEqual(Array.from(kernel([7, 8])), [14, 16], 'the array call'); + gpu.destroy(); +}); + +eachMode('alternating types stay correct across many calls', (assert, mode) => { + // the switched-to kernels are cached by signature, so this also covers + // reactivating a kernel rather than building a fresh one every time + const gpu = new GPU({ mode }); + const kernel = doubler(gpu); + for (let i = 1; i <= 3; i++) { + assert.deepEqual(Array.from(kernel([i, i])), [i * 2, i * 2], `array round ${ i }`); + assert.deepEqual( + Array.from(kernel(input(new Float32Array([i * 10, i * 10]), [2]))), + [i * 20, i * 20], + `Input round ${ i }`); + } + gpu.destroy(); +}); + +eachMode('a number after an array does not read the array', (assert, mode) => { + // the kernel body only makes sense for one of the two, so this asserts the + // failure mode: a clear error or a value derived from the number -- never + // the previous call's result + const gpu = new GPU({ mode }); + const kernel = gpu.createKernel(function (a) { + return a[this.thread.x] * 2; + }).setOutput([2]); + assert.deepEqual(Array.from(kernel([3, 3])), [6, 6], 'the array call'); + let result = null; + try { + result = kernel(5); + } catch (e) { + assert.ok(true, `refused with an error: ${ e.message.split('\n')[0].slice(0, 60) }`); + gpu.destroy(); + return; + } + assert.notDeepEqual(Array.from(result), [6, 6], 'did not silently repeat the array call'); + gpu.destroy(); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('a pipeline texture after an array reads the texture', assert => { + const gpu = new GPU({ mode: 'headlessgl' }); + const producer = gpu.createKernel(function () { + return (this.thread.x + 1) * 100; + }).setOutput([2]).setPipeline(true); + const kernel = doubler(gpu); + assert.deepEqual(Array.from(kernel([1, 2])), [2, 4], 'the array call'); + const result = kernel(producer()); + assert.deepEqual(Array.from(result), [200, 400], 'the texture call'); + gpu.destroy(); +}); + +test('asyncMode keeps the contract across an argument type change', async assert => { + const gpu = new GPU({ mode: 'cpu' }); + const kernel = doubler(gpu).setAsyncMode(true); + assert.deepEqual(Array.from(await kernel([1, 2])), [2, 4]); + const pending = kernel(input(new Float32Array([7, 8]), [2])); + assert.ok(pending instanceof Promise, 'still a Promise after the switch'); + assert.deepEqual(Array.from(await pending), [14, 16]); + gpu.destroy(); +}); diff --git a/test/features/async-mode.js b/test/features/async-mode.js new file mode 100644 index 00000000..3fef01ff --- /dev/null +++ b/test/features/async-mode.js @@ -0,0 +1,372 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU } = require('../../src'); + +describe('features: async mode'); + +// asyncMode makes a kernel return a Promise of its result on every backend -- +// the calling contract is uniform whether the backend reads back without +// blocking (webgl2 fences, webgpu natively) or resolves its synchronous +// result (cpu, webgl, headlessgl). mode: 'async' auto-selects a backend +// under that contract and upgrades to webgpu when an adapter answers. + +function contract(mode, assert) { + const gpu = new GPU({ mode }); + const kernel = gpu + .createKernel(function (value) { + return this.thread.x + value[this.thread.x]; + }) + .setOutput([4]) + .setAsyncMode(true); + const pending = kernel([10, 20, 30, 40]); + assert.ok(pending instanceof Promise, 'call returned a Promise'); + return pending.then(result => { + assert.deepEqual(Array.from(result), [10, 21, 32, 43]); + gpu.destroy(); + }); +} + +test('asyncMode contract cpu', assert => contract('cpu', assert)); + +(GPU.isWebGLSupported ? test : skip)('asyncMode contract webgl', assert => contract('webgl', assert)); + +(GPU.isWebGL2Supported ? test : skip)('asyncMode contract webgl2', assert => contract('webgl2', assert)); + +(GPU.isHeadlessGLSupported ? test : skip)('asyncMode contract headlessgl', assert => contract('headlessgl', assert)); + +test('asyncMode as a createKernel setting', async assert => { + const gpu = new GPU({ mode: 'cpu' }); + const kernel = gpu.createKernel( + function () { + return this.thread.x; + }, { + output: [3], + asyncMode: true, + } + ); + const result = await kernel(); + assert.deepEqual(Array.from(result), [0, 1, 2]); + gpu.destroy(); +}); + +test('asyncMode can be turned on and back off between calls', async assert => { + const gpu = new GPU({ mode: 'cpu' }); + const kernel = gpu + .createKernel(function () { + return this.thread.x * 2; + }) + .setOutput([3]); + const syncResult = kernel(); + assert.notOk(syncResult instanceof Promise, 'off by default'); + kernel.setAsyncMode(true); + const asyncResult = kernel(); + assert.ok(asyncResult instanceof Promise, 'on after the setter'); + assert.deepEqual(Array.from(await asyncResult), [0, 2, 4]); + kernel.setAsyncMode(false); + assert.deepEqual(Array.from(kernel()), [0, 2, 4], 'and off again'); + gpu.destroy(); +}); + +test('asyncMode rejects instead of throwing', assert => { + const done = assert.async(); + const gpu = new GPU({ mode: 'cpu' }); + const kernel = gpu + .createKernel(function (v) { + return thisFunctionDoesNotExist(v[this.thread.x]); + }) + .setOutput([1]) + .setAsyncMode(true); + // the build fails on the unknown function, and the contract says that + // surfaces as a rejection, never a synchronous throw + let threw = false; + let pending; + try { + pending = kernel([1]); + } catch (e) { + threw = true; + } + assert.notOk(threw, 'nothing thrown synchronously'); + pending.then( + () => { + assert.ok(false, 'should have rejected'); + gpu.destroy(); + done(); + }, + () => { + assert.ok(true, 'rejected'); + gpu.destroy(); + done(); + } + ); +}); + +test('mode async resolves values on every platform', async assert => { + const gpu = new GPU({ mode: 'async' }); + const kernel = gpu + .createKernel(function (a, b) { + let sum = 0; + for (let i = 0; i < 16; i++) { + sum += a[this.thread.y][i] * b[i][this.thread.x]; + } + return sum; + }) + .setOutput([16, 16]); + const a = [], b = []; + for (let y = 0; y < 16; y++) { + a.push([]); + b.push([]); + for (let x = 0; x < 16; x++) { + a[y].push(y + 1); + b[y].push(x + 1); + } + } + const result = await kernel(a, b); + assert.equal(result.length, 16); + assert.equal(result[0].length, 16); + // sum over i of (y+1)(x+1) = 16 (y+1)(x+1) + assert.equal(result[2][3], 16 * 3 * 4); + assert.equal(result[15][15], 16 * 16 * 16); + await gpu.destroy(); +}); + +test('mode async upgrades to webgpu exactly when an adapter answers', async assert => { + const gpu = new GPU({ mode: 'async' }); + const kernel = gpu + .createKernel(function () { + return this.thread.x + 1; + }) + .setOutput([8]); + const result = await kernel(); + assert.deepEqual(Array.from(result), [1, 2, 3, 4, 5, 6, 7, 8]); + const adapterAnswered = GPU.isWebGPUSupported ? await GPU.isWebGPUAvailable() : false; + if (adapterAnswered) { + assert.equal(kernel.kernel.constructor.name, 'WebGPUKernel', 'upgraded'); + } else { + assert.notEqual(kernel.kernel.constructor.name, 'WebGPUKernel', 'stayed on the proven backend'); + } + // the contract holds across repeat calls on whatever was chosen + const again = await kernel(); + assert.deepEqual(Array.from(again), [1, 2, 3, 4, 5, 6, 7, 8]); + await gpu.destroy(); +}); + +test('mode async chained setters land before the upgrade decision', async assert => { + const gpu = new GPU({ mode: 'async' }); + const kernel = gpu + .createKernel(function (v) { + return v[this.thread.x] * 3; + }) + .setOutput([2]) + .setDynamicOutput(true); + assert.deepEqual(Array.from(await kernel([1, 2])), [3, 6]); + kernel.setOutput([4]); + assert.deepEqual(Array.from(await kernel([1, 2, 3, 4])), [3, 6, 9, 12]); + await gpu.destroy(); +}); + +test('mode async pipeline resolves a handle any downstream kernel accepts', async assert => { + const gpu = new GPU({ mode: 'async' }); + const producer = gpu + .createKernel(function () { + return this.thread.x * 10; + }) + .setOutput([4]) + .setPipeline(true); + const consumer = gpu + .createKernel(function (v) { + return v[this.thread.x] + 1; + }) + .setOutput([4]); + const handle = await producer(); + const result = await consumer(handle); + assert.deepEqual(Array.from(result), [1, 11, 21, 31]); + const direct = await Promise.resolve(handle.toArray()); + assert.deepEqual(Array.from(direct), [0, 10, 20, 30]); + await gpu.destroy(); +}); + +// the fence-and-pack-buffer readback is webgl2's own; exercise each of its +// three transfer shapes (tight RED/FLOAT scalar, RGBA/FLOAT vector, +// RGBA/UNSIGNED_BYTE packed) against the synchronous read of the same kernel + +function webgl2Compare(assert, build, args) { + const gpuSync = new GPU({ mode: 'webgl2' }); + const gpuAsync = new GPU({ mode: 'webgl2' }); + const syncKernel = build(gpuSync); + const asyncKernel = build(gpuAsync).setAsyncMode(true); + const expected = syncKernel.apply(null, args); + return asyncKernel.apply(null, args).then(actual => { + assert.deepEqual(JSON.parse(JSON.stringify(actual)), JSON.parse(JSON.stringify(expected))); + gpuSync.destroy(); + gpuAsync.destroy(); + }); +} + +(GPU.isWebGL2Supported ? test : skip)('webgl2 async readback matches sync: scalar tight read', assert => { + return webgl2Compare(assert, gpu => gpu.createKernel(function (v) { + return v[this.thread.x] * 2; + }).setOutput([1024]).setPrecision('single'), [new Float32Array(1024).map((_, i) => i)]); +}); + +(GPU.isWebGL2Supported ? test : skip)('webgl2 async readback matches sync: 2d', assert => { + return webgl2Compare(assert, gpu => gpu.createKernel(function () { + return this.thread.y * 100 + this.thread.x; + }).setOutput([33, 17]).setPrecision('single'), []); +}); + +(GPU.isWebGL2Supported ? test : skip)('webgl2 async readback matches sync: Array(2) rgba read', assert => { + return webgl2Compare(assert, gpu => gpu.createKernel(function () { + return [this.thread.x, this.thread.x * 2]; + }).setOutput([64]).setPrecision('single'), []); +}); + +(GPU.isWebGL2Supported ? test : skip)('webgl2 async readback matches sync: unsigned packed', assert => { + return webgl2Compare(assert, gpu => gpu.createKernel(function (v) { + return v[this.thread.x] + 0.25; + }).setOutput([256]).setPrecision('unsigned'), [new Float32Array(256).map((_, i) => i)]); +}); + +function samplingBackend(mode) { + return (assert) => { + // the async contract must not change WHEN arguments are read: mutating + // an input after the call but before the await cannot affect the result + const gpu = new GPU({ mode }); + const kernel = gpu + .createKernel(function (v) { + return v[this.thread.x] * 2; + }) + .setOutput([4]) + .setAsyncMode(true); + const buf = new Float32Array([1, 2, 3, 4]); + const pending = kernel(buf); + buf[0] = 999; + return pending.then(result => { + assert.equal(result[0], 2, 'computed on the value held at call time'); + gpu.destroy(); + }); + }; +} + +test('arguments are sampled at call time cpu', assert => samplingBackend('cpu')(assert)); + +(GPU.isHeadlessGLSupported ? test : skip)('arguments are sampled at call time headlessgl', assert => samplingBackend('headlessgl')(assert)); + +(GPU.isWebGL2Supported ? test : skip)('arguments are sampled at call time webgl2', assert => samplingBackend('webgl2')(assert)); + +(GPU.isHeadlessGLSupported ? test : skip)('a kernel switch keeps the Promise contract', async assert => { + // argument-signature changes rebuild the kernel through + // onRequestSwitchKernel; the replacement must inherit asyncMode or the + // contract silently flip-flops per signature + const gpu = new GPU({ mode: 'headlessgl' }); + const producer = gpu.createKernel(function () { + return this.thread.x; + }).setOutput([4]).setPipeline(true); + const texture = producer(); + const kernel = gpu + .createKernel(function (v) { + return v[this.thread.x] + 1; + }) + .setOutput([4]) + .setAsyncMode(true) + .setDynamicArguments(true); + const first = kernel([1, 2, 3, 4]); + assert.ok(first instanceof Promise, 'array call is a Promise'); + await first; + const second = kernel(texture); + assert.ok(second instanceof Promise, 'texture call (switched kernel) is a Promise'); + await second; + const third = kernel([5, 6, 7, 8]); + assert.ok(third instanceof Promise, 'switching back is a Promise'); + assert.deepEqual(Array.from(await third), [6, 7, 8, 9]); + gpu.destroy(); +}); + +test('combineKernels refuses the async contract with a clear error', assert => { + const gpu = new GPU({ mode: 'async' }); + const add = gpu.createKernel(function (a, b) { + return a[this.thread.x] + b[this.thread.x]; + }).setOutput([4]); + const multiply = gpu.createKernel(function (a, b) { + return a[this.thread.x] * b[this.thread.x]; + }).setOutput([4]); + assert.throws(() => { + gpu.combineKernels(add, multiply, function (a, b, c) { + return multiply(add(a, b), c); + }); + }, /mode 'async' does not yet support combineKernels/); + return gpu.destroy(); +}); + +test('mode async upgrades kernels that carry per-kernel functions', async assert => { + // the upgrade harvest must read functions off the kernel instance; reading + // the GPU instance's empty list makes the webgpu build fail and silently + // pins the kernel to the fallback forever + const gpu = new GPU({ mode: 'async' }); + const kernel = gpu.createKernel(function (v) { + return twice(v[this.thread.x]); + }, { + output: [4], + functions: [function twice(x) { return x * 2; }], + }); + const result = await kernel([1, 2, 3, 4]); + assert.deepEqual(Array.from(result), [2, 4, 6, 8]); + const adapterAnswered = GPU.isWebGPUSupported ? await GPU.isWebGPUAvailable() : false; + if (adapterAnswered) { + assert.equal(kernel.kernel.constructor.name, 'WebGPUKernel', 'helper did not block the upgrade'); + } else { + assert.ok(true, 'no adapter here; upgrade path not reachable'); + } + await gpu.destroy(); +}); + +test('a webgpu pipeline handle feeds a kernel that declined its upgrade', async assert => { + // producer upgrades, consumer declines (Math.random is deferred); the + // async contract converts the handle transparently instead of crashing on + // an unknown KernelValue + const gpu = new GPU({ mode: 'async' }); + const producer = gpu.createKernel(function () { + return this.thread.x * 10; + }).setOutput([4]).setPipeline(true); + const consumer = gpu.createKernel(function (v) { + return v[this.thread.x] + Math.random() * 0; + }).setOutput([4]); + const handle = await producer(); + const result = await consumer(handle); + assert.deepEqual(Array.from(result), [0, 10, 20, 30]); + await gpu.destroy(); +}); + +(GPU.isWebGL2Supported ? test : skip)('webgl2 asyncMode leaves the main thread free between issue and resolve', async assert => { + // a wrapped-but-blocking read resolves within the task that issued it, so + // an already-queued macrotask could never run first; the fence path yields + // to the event loop while the GPU works. Several heavy rounds so a fence + // signalling instantly on some driver cannot fail the whole claim. + const gpu = new GPU({ mode: 'webgl2' }); + const kernel = gpu + .createKernel(function (a) { + let sum = 0; + for (let i = 0; i < 512; i++) { + sum += a[i] * (this.thread.x % 7); + } + return sum; + }) + .setOutput([1024 * 512]) + .setAsyncMode(true); + const data = new Float32Array(512).fill(1); + let firedBeforeResolve = 0; + for (let round = 0; round < 4; round++) { + const pending = kernel(data); + let resolved = false; + // queued before the poll loop's own timers, so with a blocking read the + // resolution microtasks all beat this macrotask and it observes resolved + const timer = new Promise(resolve => setTimeout(() => { + if (!resolved) firedBeforeResolve++; + resolve(); + }, 0)); + const result = await pending; + resolved = true; + assert.equal(result[1], 512, `round ${round} correct`); + await timer; + } + assert.ok(firedBeforeResolve > 0, 'a queued macrotask ran while at least one readback was in flight'); + gpu.destroy(); +}); diff --git a/test/features/webgpu/arguments.js b/test/features/webgpu/arguments.js new file mode 100644 index 00000000..e2852807 --- /dev/null +++ b/test/features/webgpu/arguments.js @@ -0,0 +1,140 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU, input } = require('../../../src'); + +describe('features: webgpu arguments'); + +// navigator.gpu can be present with no adapter (headless Chromium, blocklisted +// GPUs); QUnit cannot skip at runtime, so an adapterless environment records a +// pass with an explicit message and bumps a counter the headed canary rejects. +let adapterPromise = null; +async function webgpuAdapter(assert) { + if (!adapterPromise) adapterPromise = navigator.gpu.requestAdapter(); + const adapter = await adapterPromise; + if (!adapter) { + if (typeof window !== 'undefined') { + window.__webgpuRuntimeSkips = (window.__webgpuRuntimeSkips || 0) + 1; + } + assert.ok(true, 'navigator.gpu present but no adapter (headless/blocklisted) — runtime skip'); + } + return adapter; +} + +// One kernel per input flavor: v1 throws on argument-type changes after build, +// so the same kernel must not be fed Array then Float32Array. +(GPU.isWebGPUSupported ? test : skip)('plain array and Float32Array agree webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const source = function(v) { + return v[this.thread.x] * 2; + }; + const plainKernel = gpu.createKernel(source, { output: [8] }); + const typedKernel = gpu.createKernel(source, { output: [8] }); + const values = [1, 2, 3, 4, 5, 6, 7, 8]; + const fromPlain = await plainKernel(values); + const fromTyped = await typedKernel(new Float32Array(values)); + assert.deepEqual(Array.from(fromPlain), [2, 4, 6, 8, 10, 12, 14, 16]); + assert.deepEqual(Array.from(fromTyped), Array.from(fromPlain)); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('array of Float32Array rows webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(m) { + return m[this.thread.y][this.thread.x] + 1; + }, { output: [3, 2] }); + const result = await kernel([ + new Float32Array([1, 2, 3]), + new Float32Array([4, 5, 6]), + ]); + assert.deepEqual(result.map(row => Array.from(row)), [ + [2, 3, 4], + [5, 6, 7], + ]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('nested plain arrays 2d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(m) { + return m[this.thread.y][this.thread.x] * 10; + }, { output: [3, 2] }); + const result = await kernel([ + [1, 2, 3], + [4, 5, 6], + ]); + assert.deepEqual(result.map(row => Array.from(row)), [ + [10, 20, 30], + [40, 50, 60], + ]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('nested plain arrays 3d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(m) { + return m[this.thread.z][this.thread.y][this.thread.x] + 1; + }, { output: [2, 2, 2] }); + const result = await kernel([ + [[1, 2], [3, 4]], + [[5, 6], [7, 8]], + ]); + assert.deepEqual(result.map(z => z.map(row => Array.from(row))), [ + [[2, 3], [4, 5]], + [[6, 7], [8, 9]], + ]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('input-wrapped flat data webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(m) { + return m[this.thread.y][this.thread.x]; + }, { output: [3, 3] }); + const flat = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8, 9]); + const result = await kernel(input(flat, [3, 3])); + assert.deepEqual(result.map(row => Array.from(row)), [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9], + ]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('negative and fractional number arguments webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v, scale, offset) { + return v[this.thread.x] * scale + offset; + }, { output: [4] }); + const result = await kernel([1, 2, 3, 4], -2.5, 0.5); + assert.deepEqual(Array.from(result), [-2, -4.5, -7, -9.5]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('boolean argument in a condition webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v, negate) { + if (negate) { + return -v[this.thread.x]; + } + return v[this.thread.x]; + }, { output: [4] }); + const values = [1, 2, 3, 4]; + const kept = await kernel(values, false); + assert.deepEqual(Array.from(kept), [1, 2, 3, 4]); + const negated = await kernel(values, true); + assert.deepEqual(Array.from(negated), [-1, -2, -3, -4]); + await gpu.destroy(); +}); diff --git a/test/features/webgpu/basics.js b/test/features/webgpu/basics.js new file mode 100644 index 00000000..3a46e4ee --- /dev/null +++ b/test/features/webgpu/basics.js @@ -0,0 +1,153 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU } = require('../../../src'); + +describe('features: webgpu basics'); + +// navigator.gpu can be present with no adapter (headless Chromium, blocklisted +// GPUs); QUnit cannot skip at runtime, so an adapterless environment records a +// pass with an explicit message and bumps a counter the headed canary rejects. +let adapterPromise = null; +async function webgpuAdapter(assert) { + if (!adapterPromise) adapterPromise = navigator.gpu.requestAdapter(); + const adapter = await adapterPromise; + if (!adapter) { + if (typeof window !== 'undefined') { + window.__webgpuRuntimeSkips = (window.__webgpuRuntimeSkips || 0) + 1; + } + assert.ok(true, 'navigator.gpu present but no adapter (headless/blocklisted) — runtime skip'); + } + return adapter; +} + +(GPU.isWebGPUSupported ? test : skip)('returns a constant 1d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(3); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return 42; + }, { output: [8] }); + const result = await kernel(); + assert.equal(result.constructor, Float32Array); + assert.equal(result.length, 8); + assert.deepEqual(Array.from(result), [42, 42, 42, 42, 42, 42, 42, 42]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('scalar map 1d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return this.thread.x; + }, { output: [8] }); + const first = await kernel(); + assert.deepEqual(Array.from(first), [0, 1, 2, 3, 4, 5, 6, 7]); + // second call must reuse the built pipeline, not rebuild + const second = await kernel(); + assert.deepEqual(Array.from(second), [0, 1, 2, 3, 4, 5, 6, 7]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('scalar map 2d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(3); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return this.thread.y * 100 + this.thread.x; + }, { output: [4, 3] }); + const result = await kernel(); + assert.equal(result.length, 3); + assert.equal(result[0].constructor, Float32Array); + assert.deepEqual(result.map(row => Array.from(row)), [ + [0, 1, 2, 3], + [100, 101, 102, 103], + [200, 201, 202, 203], + ]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('scalar map 3d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(4); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return this.thread.z * 100 + this.thread.y * 10 + this.thread.x; + }, { output: [3, 2, 2] }); + const result = await kernel(); + assert.equal(result.length, 2); + assert.equal(result[0].length, 2); + assert.equal(result[0][0].constructor, Float32Array); + assert.deepEqual(result.map(z => z.map(row => Array.from(row))), [ + [[0, 1, 2], [10, 11, 12]], + [[100, 101, 102], [110, 111, 112]], + ]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('two array arguments webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(a, b) { + return a[this.thread.x] + b[this.thread.x]; + }, { output: [6] }); + const result = await kernel([1, 2, 3, 5, 6, 7], [4, 5, 6, 1, 2, 3]); + assert.deepEqual(Array.from(result), [5, 7, 9, 6, 8, 10]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('five mixed arguments webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(a, b, scale, offset, flip) { + if (flip) { + return (b[this.thread.x] - a[this.thread.x]) * scale + offset; + } + return (a[this.thread.x] + b[this.thread.x]) * scale + offset; + }, { output: [4] }); + const a = [1, 2, 3, 4]; + const b = [5, 6, 7, 8]; + const summed = await kernel(a, b, 2, 0.5, false); + assert.deepEqual(Array.from(summed), [12.5, 16.5, 20.5, 24.5]); + const flipped = await kernel(a, b, 2, 0.5, true); + assert.deepEqual(Array.from(flipped), [8.5, 8.5, 8.5, 8.5]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('kernel call returns a thenable, cpu stays sync webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(4); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return 7; + }, { output: [2] }); + const pending = kernel(); + assert.equal(typeof pending.then, 'function', 'webgpu mode returns a Promise'); + const result = await pending; + assert.deepEqual(Array.from(result), [7, 7]); + const cpu = new GPU({ mode: 'cpu' }); + const cpuKernel = cpu.createKernel(function() { + return 7; + }, { output: [2] }); + const cpuResult = cpuKernel(); + assert.equal(typeof cpuResult.then, 'undefined', 'cpu mode returns the value synchronously'); + assert.deepEqual(Array.from(cpuResult), [7, 7]); + await cpu.destroy(); + await gpu.destroy(); +}); + +// No adapter guard: kernelOrder must be unchanged even where webgpu cannot run. +(GPU.isWebGPUSupported ? test : skip)('auto mode does not select webgpu webgpu', async assert => { + assert.expect(1); + const gpu = new GPU(); + assert.notEqual(gpu.mode, 'webgpu', 'webgpu is opt-in only; auto selection is unchanged'); + await gpu.destroy(); +}); + +// No adapter guard: isWebGPUAvailable must resolve false where there is no adapter. +(GPU.isWebGPUSupported ? test : skip)('isWebGPUAvailable resolves a boolean webgpu', async assert => { + assert.expect(1); + const available = await GPU.isWebGPUAvailable(); + assert.equal(typeof available, 'boolean'); +}); diff --git a/test/features/webgpu/constants.js b/test/features/webgpu/constants.js new file mode 100644 index 00000000..0c5a5f3a --- /dev/null +++ b/test/features/webgpu/constants.js @@ -0,0 +1,89 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU } = require('../../../src'); + +describe('features: webgpu constants'); + +// navigator.gpu can be present with no adapter (headless Chromium, blocklisted +// GPUs); QUnit cannot skip at runtime, so an adapterless environment records a +// pass with an explicit message and bumps a counter the headed canary rejects. +let adapterPromise = null; +async function webgpuAdapter(assert) { + if (!adapterPromise) adapterPromise = navigator.gpu.requestAdapter(); + const adapter = await adapterPromise; + if (!adapter) { + if (typeof window !== 'undefined') { + window.__webgpuRuntimeSkips = (window.__webgpuRuntimeSkips || 0) + 1; + } + assert.ok(true, 'navigator.gpu present but no adapter (headless/blocklisted) — runtime skip'); + } + return adapter; +} + +(GPU.isWebGPUSupported ? test : skip)('float constant webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return this.constants.f + this.thread.x; + }, { output: [3], constants: { f: 1.5 } }); + const result = await kernel(); + assert.deepEqual(Array.from(result), [1.5, 2.5, 3.5]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('integer constant webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return this.constants.n * this.thread.x; + }, { output: [3], constants: { n: 3 } }); + const result = await kernel(); + assert.deepEqual(Array.from(result), [0, 3, 6]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('boolean constant webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const source = function() { + if (this.constants.flag) { + return 1; + } + return 0; + }; + const onKernel = gpu.createKernel(source, { output: [2], constants: { flag: true } }); + const offKernel = gpu.createKernel(source, { output: [2], constants: { flag: false } }); + assert.deepEqual(Array.from(await onKernel()), [1, 1]); + assert.deepEqual(Array.from(await offKernel()), [0, 0]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('array constant webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return this.constants.arr[this.thread.x]; + }, { output: [4], constants: { arr: [10, 20, 30, 40] } }); + const result = await kernel(); + assert.deepEqual(Array.from(result), [10, 20, 30, 40]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('constant as loop bound webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + let sum = 0; + for (let i = 0; i < this.constants.size; i++) { + sum += v[i]; + } + return sum; + }, { output: [2], constants: { size: 4 } }); + const result = await kernel([1, 2, 3, 4]); + assert.deepEqual(Array.from(result), [10, 10]); + await gpu.destroy(); +}); diff --git a/test/features/webgpu/control-flow.js b/test/features/webgpu/control-flow.js new file mode 100644 index 00000000..94abae7f --- /dev/null +++ b/test/features/webgpu/control-flow.js @@ -0,0 +1,140 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU } = require('../../../src'); + +describe('features: webgpu control flow'); + +// navigator.gpu can be present with no adapter (headless Chromium, blocklisted +// GPUs); QUnit cannot skip at runtime, so an adapterless environment records a +// pass with an explicit message and bumps a counter the headed canary rejects. +let adapterPromise = null; +async function webgpuAdapter(assert) { + if (!adapterPromise) adapterPromise = navigator.gpu.requestAdapter(); + const adapter = await adapterPromise; + if (!adapter) { + if (typeof window !== 'undefined') { + window.__webgpuRuntimeSkips = (window.__webgpuRuntimeSkips || 0) + 1; + } + assert.ok(true, 'navigator.gpu present but no adapter (headless/blocklisted) — runtime skip'); + } + return adapter; +} + +(GPU.isWebGPUSupported ? test : skip)('fixed-bound for loop webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + let sum = 0; + for (let i = 0; i < 10; i++) { + sum += i; + } + return sum + this.thread.x; + }, { output: [3] }); + const result = await kernel(); + assert.deepEqual(Array.from(result), [45, 46, 47]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('loop bound from argument webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v, n) { + let sum = 0; + for (let i = 0; i < n; i++) { + sum += v[i]; + } + return sum; + }, { output: [2] }); + const values = [1, 2, 3, 4, 5, 6]; + const partial = await kernel(values, 3); + assert.deepEqual(Array.from(partial), [6, 6]); + const full = await kernel(values, 6); + assert.deepEqual(Array.from(full), [21, 21]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('loop bound from constants webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + let sum = 0; + for (let i = 0; i < this.constants.limit; i++) { + sum += v[i] * 2; + } + return sum; + }, { output: [2], constants: { limit: 3 } }); + const result = await kernel([1, 2, 3, 4]); + assert.deepEqual(Array.from(result), [12, 12]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('nested loops webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + let sum = 0; + for (let i = 0; i < 3; i++) { + for (let j = 0; j < 4; j++) { + sum += i * j; + } + } + return sum; + }, { output: [2] }); + const result = await kernel(); + assert.deepEqual(Array.from(result), [18, 18]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('if else on thread.x webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + let value = 0; + if (this.thread.x < 2) { + value = 1; + } else { + value = 2; + } + return value; + }, { output: [4] }); + const result = await kernel(); + assert.deepEqual(Array.from(result), [1, 1, 2, 2]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('if else-if else webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + if (this.thread.x < 2) { + return 10; + } else if (this.thread.x < 4) { + return 20; + } else { + return 30; + } + }, { output: [6] }); + const result = await kernel(); + assert.deepEqual(Array.from(result), [10, 10, 20, 20, 30, 30]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('early return inside a branch webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + if (this.thread.x === 0) { + return -1; + } + return this.thread.x; + }, { output: [4] }); + const result = await kernel(); + assert.deepEqual(Array.from(result), [-1, 1, 2, 3]); + await gpu.destroy(); +}); diff --git a/test/features/webgpu/dynamic-output.js b/test/features/webgpu/dynamic-output.js new file mode 100644 index 00000000..c49db16b --- /dev/null +++ b/test/features/webgpu/dynamic-output.js @@ -0,0 +1,112 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU } = require('../../../src'); + +describe('features: webgpu dynamic output'); + +// navigator.gpu can be present with no adapter (headless Chromium, blocklisted +// GPUs); QUnit cannot skip at runtime, so an adapterless environment records a +// pass with an explicit message and bumps a counter the headed canary rejects. +let adapterPromise = null; +async function webgpuAdapter(assert) { + if (!adapterPromise) adapterPromise = navigator.gpu.requestAdapter(); + const adapter = await adapterPromise; + if (!adapter) { + if (typeof window !== 'undefined') { + window.__webgpuRuntimeSkips = (window.__webgpuRuntimeSkips || 0) + 1; + } + assert.ok(true, 'navigator.gpu present but no adapter (headless/blocklisted) — runtime skip'); + } + return adapter; +} + +(GPU.isWebGPUSupported ? test : skip)('dynamic output 1d grows webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(6); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return this.output.x + this.thread.x; + }, { dynamicOutput: true }); + + kernel.setOutput([5]); + let result = await kernel(); + assert.equal(result.length, 5); + assert.deepEqual(Array.from(result), [5, 6, 7, 8, 9]); + assert.deepEqual(Array.from(kernel.output), [5]); + + kernel.setOutput([10]); + result = await kernel(); + assert.equal(result.length, 10); + assert.deepEqual(Array.from(result), [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]); + assert.deepEqual(Array.from(kernel.output), [10]); + + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('dynamic output 1d shrinks webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(4); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return this.output.x + this.thread.x; + }, { dynamicOutput: true }); + + kernel.setOutput([10]); + let result = await kernel(); + assert.equal(result.length, 10); + assert.deepEqual(Array.from(result), [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]); + + kernel.setOutput([5]); + result = await kernel(); + assert.equal(result.length, 5); + assert.deepEqual(Array.from(result), [5, 6, 7, 8, 9]); + + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('dynamic output 2d resize webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(4); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return this.thread.y * 10 + this.thread.x; + }, { dynamicOutput: true }); + + kernel.setOutput([3, 2]); + let result = await kernel(); + assert.equal(result.length, 2); + assert.deepEqual(result.map(row => Array.from(row)), [ + [0, 1, 2], + [10, 11, 12], + ]); + + kernel.setOutput([2, 4]); + result = await kernel(); + assert.equal(result.length, 4); + assert.deepEqual(result.map(row => Array.from(row)), [ + [0, 1], + [10, 11], + [20, 21], + [30, 31], + ]); + + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('dynamic arguments across calls webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + return v[this.thread.x] * 2; + }, { dynamicOutput: true, dynamicArguments: true }); + + kernel.setOutput([3]); + const small = await kernel([1, 2, 3]); + assert.deepEqual(Array.from(small), [2, 4, 6]); + + kernel.setOutput([6]); + const large = await kernel([1, 2, 3, 4, 5, 6]); + assert.deepEqual(Array.from(large), [2, 4, 6, 8, 10, 12]); + + await gpu.destroy(); +}); diff --git a/test/features/webgpu/errors.js b/test/features/webgpu/errors.js new file mode 100644 index 00000000..8d1d91d9 --- /dev/null +++ b/test/features/webgpu/errors.js @@ -0,0 +1,206 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU } = require('../../../src'); + +describe('features: webgpu errors'); + +// Deferred features must throw messages starting with this prefix +// (INTEGRATION-CONTRACT.md) +const DEFERRED = /^WebGPU backend does not yet support/; + +// navigator.gpu can be present with no adapter (headless Chromium, blocklisted +// GPUs); QUnit cannot skip at runtime, so an adapterless environment records a +// pass with an explicit message and bumps a counter the headed canary rejects. +let adapterPromise = null; +async function webgpuAdapter(assert) { + if (!adapterPromise) adapterPromise = navigator.gpu.requestAdapter(); + const adapter = await adapterPromise; + if (!adapter) { + if (typeof window !== 'undefined') { + window.__webgpuRuntimeSkips = (window.__webgpuRuntimeSkips || 0) + 1; + } + assert.ok(true, 'navigator.gpu present but no adapter (headless/blocklisted) — runtime skip'); + } + return adapter; +} + +(GPU.isWebGPUSupported ? test : skip)('createKernelMap throws deferred webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + let error = null; + try { + const kernel = gpu.createKernelMap({ + doubled: function double(x) { + return x * 2; + }, + }, function(v) { + return double(v[this.thread.x]); + }, { output: [4] }); + await kernel([1, 2, 3, 4]); + } catch (e) { + error = e; + } + assert.ok(error && DEFERRED.test(error.message), `deferred prefix, got: ${error && error.message}`); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('graphical throws deferred webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + let error = null; + try { + const kernel = gpu.createKernel(function() { + this.color(1, 0, 0, 1); + }, { output: [4, 4], graphical: true }); + await kernel(); + } catch (e) { + error = e; + } + assert.ok(error && DEFERRED.test(error.message), `deferred prefix, got: ${error && error.message}`); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('precision unsigned throws deferred webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + let error = null; + try { + const kernel = gpu.createKernel(function() { + return 1; + }, { output: [4], precision: 'unsigned' }); + await kernel(); + } catch (e) { + error = e; + } + assert.ok(error && DEFERRED.test(error.message), `deferred prefix, got: ${error && error.message}`); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('precision single is accepted webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return 1.5; + }, { output: [2], precision: 'single' }); + const result = await kernel(); + assert.deepEqual(Array.from(result), [1.5, 1.5]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('toString throws deferred webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return 1; + }, { output: [2] }); + const result = await kernel(); + assert.equal(result.length, 2); + let error = null; + try { + kernel.toString(); + } catch (e) { + error = e; + } + assert.ok(error && DEFERRED.test(error.message), `deferred prefix, got: ${error && error.message}`); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('Math.random throws deferred webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + let error = null; + try { + const kernel = gpu.createKernel(function() { + return Math.random(); + }, { output: [4] }); + await kernel(); + } catch (e) { + error = e; + } + assert.ok(error && DEFERRED.test(error.message), `deferred prefix, got: ${error && error.message}`); + await gpu.destroy(); +}); + +// message not pinned by the contract; only the throw is +(GPU.isWebGPUSupported ? test : skip)('combineKernels throws webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + let error = null; + try { + const k1 = gpu.createKernel(function(v) { + return v[this.thread.x] + 1; + }, { output: [4], pipeline: true }); + const k2 = gpu.createKernel(function(v) { + return v[this.thread.x] * 2; + }, { output: [4] }); + const combined = gpu.combineKernels(k1, k2, function(v) { + return k2(k1(v)); + }); + await combined([1, 2, 3, 4]); + } catch (e) { + error = e; + } + assert.ok(error instanceof Error, `combineKernels is deferred, got: ${error && error.message}`); + await gpu.destroy(); +}); + +// build failures must reject the kernel promise, never resolve with garbage +(GPU.isWebGPUSupported ? test : skip)('build failure rejects the kernel promise webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + return notARealFunction(v[this.thread.x]); // eslint-disable-line no-undef + }, { output: [4] }); + let error = null; + try { + await kernel([1, 2, 3, 4]); + } catch (e) { + error = e; + } + assert.ok(error instanceof Error, 'build failure surfaces as an Error'); + assert.ok(error && error.message.length > 0, 'rejection carries a message'); + await gpu.destroy(); +}); + +// Inverted guard: runs under Node and non-WebGPU browsers, where requesting +// webgpu mode must fail loudly at construction, not at first kernel call. +(!GPU.isWebGPUSupported ? test : skip)('mode webgpu throws where unsupported', assert => { + assert.expect(1); + let error = null; + try { + const gpu = new GPU({ mode: 'webgpu' }); + gpu.createKernel(function() { + return 1; + }, { output: [1] }); + } catch (e) { + error = e; + } + assert.ok(error instanceof Error && /webgpu/i.test(error.message), `explains why: ${error && error.message}`); +}); + +(GPU.isWebGPUSupported ? test : skip)('an output past the device buffer limit throws, never zeros', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + // past the limit, bind-group validation fails asynchronously and the + // zero-initialized staging buffer would resolve an all-zeros result; the + // backend must throw before any of that + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function () { + return 1; + }, { output: [100000, 100000] }); + let message = ''; + try { + await kernel(); + } catch (e) { + message = String(e && e.message || e); + } + assert.ok(/maxStorageBufferBindingSize/.test(message), `names the limit: ${ message.slice(0, 90) }`); + await gpu.destroy(); +}); diff --git a/test/features/webgpu/math.js b/test/features/webgpu/math.js new file mode 100644 index 00000000..ffd353f6 --- /dev/null +++ b/test/features/webgpu/math.js @@ -0,0 +1,168 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU } = require('../../../src'); + +describe('features: webgpu math'); + +// navigator.gpu can be present with no adapter (headless Chromium, blocklisted +// GPUs); QUnit cannot skip at runtime, so an adapterless environment records a +// pass with an explicit message and bumps a counter the headed canary rejects. +let adapterPromise = null; +async function webgpuAdapter(assert) { + if (!adapterPromise) adapterPromise = navigator.gpu.requestAdapter(); + const adapter = await adapterPromise; + if (!adapter) { + if (typeof window !== 'undefined') { + window.__webgpuRuntimeSkips = (window.__webgpuRuntimeSkips || 0) + 1; + } + assert.ok(true, 'navigator.gpu present but no adapter (headless/blocklisted) — runtime skip'); + } + return adapter; +} + +// fp32 results cannot be compared exactly against fp64 JS references +function closeTo(assert, actual, expected, epsilon, message) { + assert.ok(Math.abs(actual - expected) < epsilon, `${message}: expected ${expected}, got ${actual}`); +} + +(GPU.isWebGPUSupported ? test : skip)('abs floor ceil sqrt combined webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(4); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + let x = v[this.thread.x]; + return Math.sqrt(Math.abs(x)) + Math.floor(x) + Math.ceil(x / 2); + }, { output: [4] }); + const values = [-2.25, 0.5, 3.75, 9]; + const result = await kernel(values); + for (let i = 0; i < values.length; i++) { + const x = values[i]; + const expected = Math.sqrt(Math.abs(x)) + Math.floor(x) + Math.ceil(x / 2); + closeTo(assert, result[i], expected, 1e-4, `index ${i}`); + } + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('sin cos exp combined webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(4); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + let x = v[this.thread.x]; + return Math.sin(x) + Math.cos(x) + Math.exp(x / 4); + }, { output: [4] }); + const values = [0, 0.5, 1.25, 3]; + const result = await kernel(values); + for (let i = 0; i < values.length; i++) { + const x = values[i]; + const expected = Math.sin(x) + Math.cos(x) + Math.exp(x / 4); + closeTo(assert, result[i], expected, 1e-4, `index ${i}`); + } + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('min max pow atan2 combined webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(4); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(a, b) { + let x = a[this.thread.x]; + let y = b[this.thread.x]; + return Math.pow(Math.max(x, y), 2) + Math.min(x, y) + Math.atan2(x, y); + }, { output: [4] }); + const a = [1, 3, 2, 0.5]; + const b = [2, 1, 4, 0.25]; + const result = await kernel(a, b); + for (let i = 0; i < a.length; i++) { + const expected = Math.pow(Math.max(a[i], b[i]), 2) + Math.min(a[i], b[i]) + Math.atan2(a[i], b[i]); + closeTo(assert, result[i], expected, 1e-3, `index ${i}`); + } + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('Math.PI webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return Math.PI; + }, { output: [1] }); + const result = await kernel(); + closeTo(assert, result[0], Math.PI, 1e-6, 'Math.PI'); + await gpu.destroy(); +}); + +// division of number literals and of this.thread.x must be fractional, as in +// JS — pins the WGSL i32/f32 typing decisions against GLSL-backend behavior +(GPU.isWebGPUSupported ? test : skip)('literal and thread division are fractional webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(5); + const gpu = new GPU({ mode: 'webgpu' }); + const literalKernel = gpu.createKernel(function() { + return 7 / 2; + }, { output: [1] }); + const literalResult = await literalKernel(); + closeTo(assert, literalResult[0], 3.5, 1e-3, 'literal 7 / 2'); + const threadKernel = gpu.createKernel(function() { + return this.thread.x / 64; + }, { output: [4] }); + const threadResult = await threadKernel(); + for (let i = 0; i < 4; i++) { + closeTo(assert, threadResult[i], i / 64, 1e-3, `thread.x ${i} / 64`); + } + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('Math.floor on division webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(a, b) { + return Math.floor(a[this.thread.x] / b[this.thread.x]); + }, { output: [4] }); + const result = await kernel([7, 9, 10, 100], [2, 4, 3, 7]); + assert.deepEqual(Array.from(result), [3, 2, 3, 14]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('Math.floor on negatives webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + return Math.floor(v[this.thread.x]); + }, { output: [4] }); + const result = await kernel([-2.5, -0.5, 2.5, -3]); + assert.deepEqual(Array.from(result), [-3, -1, 2, -3]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('modulo webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(4); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(a, b) { + return a[this.thread.x] % b[this.thread.x]; + }, { output: [4] }); + const result = await kernel([5, 7.5, 9, 10], [3, 2, 4, 4]); + const expected = [2, 1.5, 1, 2]; + for (let i = 0; i < expected.length; i++) { + closeTo(assert, result[i], expected[i], 1e-4, `index ${i}`); + } + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('integer loop counter arithmetic webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + let sum = 0; + for (let i = 0; i < 5; i++) { + sum += i * 2; + } + return sum + this.thread.x; + }, { output: [2] }); + const result = await kernel(); + assert.deepEqual(Array.from(result), [20, 21]); + await gpu.destroy(); +}); diff --git a/test/features/webgpu/pipeline.js b/test/features/webgpu/pipeline.js new file mode 100644 index 00000000..bdb5ce2c --- /dev/null +++ b/test/features/webgpu/pipeline.js @@ -0,0 +1,112 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU } = require('../../../src'); + +describe('features: webgpu pipeline'); + +// navigator.gpu can be present with no adapter (headless Chromium, blocklisted +// GPUs); QUnit cannot skip at runtime, so an adapterless environment records a +// pass with an explicit message and bumps a counter the headed canary rejects. +let adapterPromise = null; +async function webgpuAdapter(assert) { + if (!adapterPromise) adapterPromise = navigator.gpu.requestAdapter(); + const adapter = await adapterPromise; + if (!adapter) { + if (typeof window !== 'undefined') { + window.__webgpuRuntimeSkips = (window.__webgpuRuntimeSkips || 0) + 1; + } + assert.ok(true, 'navigator.gpu present but no adapter (headless/blocklisted) — runtime skip'); + } + return adapter; +} + +(GPU.isWebGPUSupported ? test : skip)('pipeline handle shape and toArray webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(6); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + return v[this.thread.x] * 2; + }, { output: [8], pipeline: true }); + const handle = await kernel([1, 2, 3, 4, 5, 6, 7, 8]); + assert.equal(handle.type, 'WebGPUBuffer'); + assert.ok(handle.buffer, 'handle exposes the GPUBuffer'); + assert.deepEqual(Array.from(handle.output), [8]); + assert.equal(typeof handle.toArray, 'function'); + assert.equal(typeof handle.delete, 'function'); + const values = await handle.toArray(); + assert.deepEqual(Array.from(values), [2, 4, 6, 8, 10, 12, 14, 16]); + handle.delete(); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('handle feeds a second kernel webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const producer = gpu.createKernel(function(v) { + return v[this.thread.x] * 2; + }, { output: [4], pipeline: true }); + const consumer = gpu.createKernel(function(v) { + return v[this.thread.x] + 1; + }, { output: [4] }); + const handle = await producer([1, 2, 3, 4]); + const result = await consumer(handle); + assert.equal(result.constructor, Float32Array); + assert.deepEqual(Array.from(result), [3, 5, 7, 9]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('handle reused by the same kernel webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(1); + const gpu = new GPU({ mode: 'webgpu' }); + // immutable: feeding a kernel its own prior output needs a fresh output + // buffer per call, same discipline as the GL backends' immutable textures + const kernel = gpu.createKernel(function(v) { + return v[this.thread.x] + 1; + }, { output: [4], pipeline: true, immutable: true }); + const first = await kernel([1, 2, 3, 4]); + const second = await kernel(first); + const values = await second.toArray(); + assert.deepEqual(Array.from(values), [3, 4, 5, 6]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('three-kernel chain ends in plain values webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(2); + const gpu = new GPU({ mode: 'webgpu' }); + const k1 = gpu.createKernel(function(v) { + return v[this.thread.x] * 2; + }, { output: [4], pipeline: true }); + const k2 = gpu.createKernel(function(v) { + return v[this.thread.x] + 1; + }, { output: [4], pipeline: true }); + const k3 = gpu.createKernel(function(v) { + return v[this.thread.x] * 10; + }, { output: [4] }); + const h1 = await k1([1, 2, 3, 4]); + const h2 = await k2(h1); + const result = await k3(h2); + assert.equal(result.constructor, Float32Array); + assert.deepEqual(Array.from(result), [30, 50, 70, 90]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('destroy resolves after a chain webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(3); + const gpu = new GPU({ mode: 'webgpu' }); + const producer = gpu.createKernel(function(v) { + return v[this.thread.x] + 1; + }, { output: [4], pipeline: true }); + const consumer = gpu.createKernel(function(v) { + return v[this.thread.x] * 3; + }, { output: [4] }); + const handle = await producer([1, 2, 3, 4]); + const result = await consumer(handle); + assert.deepEqual(Array.from(result), [6, 9, 12, 15]); + const destroyed = gpu.destroy(); + assert.equal(typeof destroyed.then, 'function', 'destroy returns a Promise'); + await destroyed; + assert.ok(true, 'destroy resolved'); +}); diff --git a/test/features/webgpu/returns.js b/test/features/webgpu/returns.js new file mode 100644 index 00000000..55204d71 --- /dev/null +++ b/test/features/webgpu/returns.js @@ -0,0 +1,109 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU } = require('../../../src'); + +describe('features: webgpu return types'); + +// navigator.gpu can be present with no adapter (headless Chromium, blocklisted +// GPUs); QUnit cannot skip at runtime, so an adapterless environment records a +// pass with an explicit message and bumps a counter the headed canary rejects. +let adapterPromise = null; +async function webgpuAdapter(assert) { + if (!adapterPromise) adapterPromise = navigator.gpu.requestAdapter(); + const adapter = await adapterPromise; + if (!adapter) { + if (typeof window !== 'undefined') { + window.__webgpuRuntimeSkips = (window.__webgpuRuntimeSkips || 0) + 1; + } + assert.ok(true, 'navigator.gpu present but no adapter (headless/blocklisted) — runtime skip'); + } + return adapter; +} + +(GPU.isWebGPUSupported ? test : skip)('Array(2) return 1d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(3); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + return [v[this.thread.x], v[this.thread.x] + 10]; + }, { output: [4] }); + const result = await kernel([1, 2, 3, 4]); + assert.equal(result.length, 4); + assert.equal(result[0].constructor, Float32Array); + assert.deepEqual(result.map(pair => Array.from(pair)), [ + [1, 11], + [2, 12], + [3, 13], + [4, 14], + ]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('Array(3) return 1d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(3); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + return [v[this.thread.x], v[this.thread.x] + 10, v[this.thread.x] + 20]; + }, { output: [3] }); + const result = await kernel([1, 2, 3]); + assert.equal(result.length, 3); + assert.equal(result[0].length, 3); + assert.deepEqual(result.map(triple => Array.from(triple)), [ + [1, 11, 21], + [2, 12, 22], + [3, 13, 23], + ]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('Array(4) return 1d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(3); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function(v) { + return [v[this.thread.x], v[this.thread.x] + 10, v[this.thread.x] + 20, v[this.thread.x] + 30]; + }, { output: [3] }); + const result = await kernel([1, 2, 3]); + assert.equal(result.length, 3); + assert.equal(result[0].length, 4); + assert.deepEqual(result.map(quad => Array.from(quad)), [ + [1, 11, 21, 31], + [2, 12, 22, 32], + [3, 13, 23, 33], + ]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('Array(2) return 2d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(3); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return [this.thread.x, this.thread.y]; + }, { output: [3, 2] }); + const result = await kernel(); + assert.equal(result.length, 2); + assert.equal(result[0].length, 3); + assert.deepEqual(result.map(row => row.map(pair => Array.from(pair))), [ + [[0, 0], [1, 0], [2, 0]], + [[0, 1], [1, 1], [2, 1]], + ]); + await gpu.destroy(); +}); + +(GPU.isWebGPUSupported ? test : skip)('Array(4) return 2d webgpu', async assert => { + if (!(await webgpuAdapter(assert))) return; + assert.expect(3); + const gpu = new GPU({ mode: 'webgpu' }); + const kernel = gpu.createKernel(function() { + return [this.thread.x, this.thread.y, this.thread.x + this.thread.y, 1]; + }, { output: [2, 2] }); + const result = await kernel(); + assert.equal(result.length, 2); + assert.equal(result[0].length, 2); + assert.deepEqual(result.map(row => row.map(quad => Array.from(quad))), [ + [[0, 0, 0, 1], [1, 0, 1, 1]], + [[0, 1, 1, 1], [1, 1, 2, 1]], + ]); + await gpu.destroy(); +}); diff --git a/test/internal/wgsl-codegen.js b/test/internal/wgsl-codegen.js new file mode 100644 index 00000000..687a4ea5 --- /dev/null +++ b/test/internal/wgsl-codegen.js @@ -0,0 +1,116 @@ +const { assert, skip, test, module: describe } = require('qunit'); +const { WebGPUKernel } = require('../../src'); + +describe('internal: wgsl codegen'); + +// The WGSL translation runs entirely in Node -- no device is needed until +// build -- so the generator's JS-to-WGSL semantics are pinned here, where +// every platform's CI can watch them. + +function translate(source, settings) { + settings = settings || {}; + const args = settings.args || []; + delete settings.args; + const kernel = new WebGPUKernel(source.toString(), Object.assign({ + output: [4], + precision: 'single', + functions: [], + nativeFunctions: [], + }, settings)); + // the pre-device slice of build(): argument/constant records feed + // FunctionBuilder, then translation is pure Node + kernel.setupConstants(); + kernel.setupArguments(args); + kernel.translateSource(); + return `${ kernel.translatedFunctions }\n${ kernel.translatedBody }`; +} + +test('a break behind an if inside a switch case throws', t => { + // WGSL would read the emitted break as breaking the enclosing loop -- + // silently wrong results -- so the translator must reject it, exactly as + // the GL backends do + t.throws(() => { + translate(function (v) { + let s = 0; + for (let i = 0; i < 4; i++) { + switch (i) { + case 0: + if (v[0] > 0) break; + s += 100; + break; + default: + s += 1; + } + } + return s; + }, { argumentTypes: ['Array'], args: [[1, 2, 3, 4]] }); + }, /only supported as the case terminator/); +}); + +test('a case-terminating break is consumed, not emitted', t => { + const wgsl = translate(function () { + let s = 0; + switch (this.thread.x) { + case 0: + s = 5; + break; + default: + s = 1; + } + return s; + }); + t.notOk(/break/.test(wgsl), 'no break survives the if-chain lowering'); +}); + +test('a mixed int/float ternary promotes to float instead of rounding', t => { + const wgsl = translate(function () { + return this.thread.x > 2 ? this.thread.x : 0.5; + }); + t.ok(/select\([^;]*0\.5/.test(wgsl), 'the fractional alternate survives'); + t.notOk(/select\(i32\(1\)/.test(wgsl), 'and is not rounded to an integer'); +}); + +test('a promoted ternary type-checks in its enclosing expression', t => { + const wgsl = translate(function () { + const value = (this.thread.x > 2 ? this.thread.x : 0.5) * 2.0; + return value; + }); + t.ok(/select\([^;]*0\.5/.test(wgsl), 'promotion holds under an enclosing float product'); +}); + +test('prefix increment emits the postfix statement form', t => { + const wgsl = translate(function () { + let s = 0; + for (let i = 0; i < 10; ++i) { + s += 1; + } + return s; + }); + t.ok(/user_i\+\+/.test(wgsl), 'postfix form emitted'); + t.notOk(/\+\+user_i/.test(wgsl), 'prefix form (invalid WGSL) not emitted'); +}); + +test('a helper named after a WGSL builtin keeps its definition', t => { + const wgsl = translate(function (v) { + return cross(v[this.thread.x], 2); + }, { + argumentTypes: ['Array'], + args: [[1, 2, 3, 4]], + functions: [function cross(a, b) { return a * b; }], + }); + t.ok(/fn fn_cross\(/.test(wgsl), 'the mangled definition is present'); + t.ok(/fn_cross\(/.test(wgsl.split('fn fn_cross')[1] || ''), 'and the call site uses it'); +}); + +test('helper argument types still infer through the original name', t => { + // type inference tables are keyed by the original name; a mangled lookup + // returns nothing and the argument arrives untyped + const wgsl = translate(function (v) { + return cross(v[this.thread.x], 2); + }, { + argumentTypes: ['Array'], + args: [[1, 2, 3, 4]], + functions: [function cross(a, b) { return a * b; }], + }); + t.ok(/fn fn_cross\(user_a : f32, user_b : f32\)/.test(wgsl), 'both parameters typed f32'); +});